mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Icon: Simplify and remove wrapping <div>
(#76819)
* remove wrapping div * update tests, just gotta figure out how to handle fontawesome :( * add spinner.svg which matches the font-awesome spinner * add mock for react-inlinesvg * update mock and fix some tests * fix FormField test * fix CorrelationsPage tests * increase timeout
This commit is contained in:
parent
cad3c43bb1
commit
07cc7504ee
@ -28,6 +28,7 @@ module.exports = {
|
||||
moduleNameMapper: {
|
||||
'\\.svg': '<rootDir>/public/test/mocks/svg.ts',
|
||||
'\\.css': '<rootDir>/public/test/mocks/style.ts',
|
||||
'react-inlinesvg': '<rootDir>/public/test/mocks/react-inlinesvg.tsx',
|
||||
'monaco-editor/esm/vs/editor/editor.api': '<rootDir>/public/test/mocks/monaco.ts',
|
||||
// near-membrane-dom won't work in a nodejs environment.
|
||||
'@locker/near-membrane-dom': '<rootDir>/public/test/mocks/nearMembraneDom.ts',
|
||||
|
@ -93,6 +93,7 @@ export const availableIconsIndex = {
|
||||
eye: true,
|
||||
'eye-slash': true,
|
||||
'ellipsis-h': true,
|
||||
/* @deprecated, use 'spinner' instead */
|
||||
'fa fa-spinner': true,
|
||||
favorite: true,
|
||||
'file-alt': true,
|
||||
@ -198,6 +199,7 @@ export const availableIconsIndex = {
|
||||
sitemap: true,
|
||||
slack: true,
|
||||
'sliders-v-alt': true,
|
||||
spinner: true,
|
||||
'sort-amount-down': true,
|
||||
'sort-amount-up': true,
|
||||
'square-shape': true,
|
||||
|
@ -84,7 +84,6 @@ describe('DataLinksListItem', () => {
|
||||
setupTestContext({ link });
|
||||
|
||||
expect(screen.getByText(/data link url not provided/i)).toBeInTheDocument();
|
||||
expect(screen.getByTitle('')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@ -109,7 +108,6 @@ describe('DataLinksListItem', () => {
|
||||
setupTestContext({ link });
|
||||
|
||||
expect(screen.getByText(/data link url not provided/i)).toBeInTheDocument();
|
||||
expect(screen.getByTitle('')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -68,7 +68,7 @@ export const TimeRangeInput = ({
|
||||
onChange(timeRange);
|
||||
};
|
||||
|
||||
const onRangeClear = (event: MouseEvent<HTMLDivElement>) => {
|
||||
const onRangeClear = (event: MouseEvent<SVGElement>) => {
|
||||
event.stopPropagation();
|
||||
const from = dateTime(null);
|
||||
const to = dateTime(null);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
@ -42,8 +42,6 @@ describe('FormField', () => {
|
||||
screen.getAllByRole('textbox')[0].focus();
|
||||
await userEvent.tab();
|
||||
|
||||
await waitFor(() => {
|
||||
screen.getByText(tooltip);
|
||||
});
|
||||
expect(await screen.findByText(tooltip)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -37,7 +37,7 @@ export const FormLabel = ({
|
||||
{children}
|
||||
{tooltip && (
|
||||
<Tooltip placement="top" content={tooltip} theme={'info'} interactive={interactive}>
|
||||
<Icon tabIndex={0} name="info-circle" size="sm" style={{ marginLeft: '10px' }} />
|
||||
<Icon name="info-circle" size="sm" style={{ marginLeft: '10px' }} />
|
||||
</Tooltip>
|
||||
)}
|
||||
</label>
|
||||
|
@ -9,7 +9,7 @@ import { IconName, IconType, IconSize } from '../../types/icon';
|
||||
|
||||
import { getIconRoot, getIconSubDir, getSvgSize } from './utils';
|
||||
|
||||
export interface IconProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
export interface IconProps extends Omit<React.SVGProps<SVGElement>, 'onLoad' | 'onError' | 'ref'> {
|
||||
name: IconName;
|
||||
size?: IconSize;
|
||||
type?: IconType;
|
||||
@ -18,16 +18,14 @@ export interface IconProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
|
||||
const getIconStyles = (theme: GrafanaTheme2) => {
|
||||
return {
|
||||
// line-height: 0; is needed for correct icon alignment in Safari
|
||||
container: css({
|
||||
label: 'Icon',
|
||||
display: 'inline-block',
|
||||
lineHeight: 0,
|
||||
}),
|
||||
icon: css({
|
||||
verticalAlign: 'middle',
|
||||
display: 'inline-block',
|
||||
fill: 'currentColor',
|
||||
flexShrink: 0,
|
||||
label: 'Icon',
|
||||
// line-height: 0; is needed for correct icon alignment in Safari
|
||||
lineHeight: 0,
|
||||
verticalAlign: 'middle',
|
||||
}),
|
||||
orange: css({
|
||||
fill: theme.v1.palette.orange,
|
||||
@ -35,53 +33,44 @@ const getIconStyles = (theme: GrafanaTheme2) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const Icon = React.forwardRef<HTMLDivElement, IconProps>(
|
||||
({ size = 'md', type = 'default', name, className, style, title = '', ...divElementProps }, ref) => {
|
||||
export const Icon = React.forwardRef<SVGElement, IconProps>(
|
||||
({ size = 'md', type = 'default', name, className, style, title = '', ...rest }, ref) => {
|
||||
const styles = useStyles2(getIconStyles);
|
||||
|
||||
/* Temporary solution to display also font awesome icons */
|
||||
if (name?.startsWith('fa fa-')) {
|
||||
return <i className={getFontAwesomeIconStyles(name, className)} {...divElementProps} style={style} />;
|
||||
}
|
||||
|
||||
if (!isIconName(name)) {
|
||||
console.warn('Icon component passed an invalid icon name', name);
|
||||
}
|
||||
|
||||
if (!name || name.includes('..')) {
|
||||
return <div ref={ref}>invalid icon name</div>;
|
||||
}
|
||||
// handle the deprecated 'fa fa-spinner'
|
||||
const iconName: IconName = name === 'fa fa-spinner' ? 'spinner' : name;
|
||||
|
||||
const iconRoot = getIconRoot();
|
||||
const svgSize = getSvgSize(size);
|
||||
const svgHgt = svgSize;
|
||||
const svgWid = name.startsWith('gf-bar-align') ? 16 : name.startsWith('gf-interp') ? 30 : svgSize;
|
||||
const subDir = getIconSubDir(name, type);
|
||||
const svgPath = `${iconRoot}${subDir}/${name}.svg`;
|
||||
const subDir = getIconSubDir(iconName, type);
|
||||
const svgPath = `${iconRoot}${subDir}/${iconName}.svg`;
|
||||
|
||||
return (
|
||||
<div className={styles.container} {...divElementProps} ref={ref}>
|
||||
<SVG
|
||||
src={svgPath}
|
||||
width={svgWid}
|
||||
height={svgHgt}
|
||||
title={title}
|
||||
className={cx(styles.icon, className, type === 'mono' ? { [styles.orange]: name === 'favorite' } : '')}
|
||||
style={style}
|
||||
/>
|
||||
</div>
|
||||
<SVG
|
||||
innerRef={ref}
|
||||
src={svgPath}
|
||||
width={svgWid}
|
||||
height={svgHgt}
|
||||
title={title}
|
||||
className={cx(
|
||||
styles.icon,
|
||||
{
|
||||
'fa-spin': iconName === 'spinner',
|
||||
},
|
||||
className,
|
||||
type === 'mono' ? { [styles.orange]: name === 'favorite' } : ''
|
||||
)}
|
||||
style={style}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Icon.displayName = 'Icon';
|
||||
|
||||
function getFontAwesomeIconStyles(iconName: string, className?: string): string {
|
||||
return cx(
|
||||
iconName,
|
||||
{
|
||||
'fa-spin': iconName === 'fa fa-spinner',
|
||||
},
|
||||
className
|
||||
);
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ export class RefreshPicker extends PureComponent<Props> {
|
||||
tooltip={tooltip}
|
||||
onClick={onRefresh}
|
||||
variant={variant}
|
||||
icon={isLoading ? 'fa fa-spinner' : 'sync'}
|
||||
icon={isLoading ? 'spinner' : 'sync'}
|
||||
style={width ? { width } : undefined}
|
||||
data-testid={selectors.components.RefreshPicker.runButtonV2}
|
||||
>
|
||||
|
@ -28,7 +28,7 @@ export const Spinner = ({ className, inline = false, iconClassName, style, size
|
||||
const styles = getStyles(size, inline);
|
||||
return (
|
||||
<div data-testid="Spinner" style={style} className={cx(styles, className)}>
|
||||
<Icon className={cx('fa-spin', iconClassName)} name="fa fa-spinner" aria-label="loading spinner" />
|
||||
<Icon className={cx('fa-spin', iconClassName)} name="spinner" aria-label="loading spinner" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -6,7 +6,7 @@ export interface Props {
|
||||
label: string;
|
||||
removeIcon: boolean;
|
||||
count: number;
|
||||
onClick?: React.MouseEventHandler<HTMLDivElement>;
|
||||
onClick?: React.MouseEventHandler<SVGElement>;
|
||||
}
|
||||
|
||||
export class TagBadge extends React.Component<Props> {
|
||||
|
@ -91,7 +91,7 @@ export const GlobalConfigForm = ({ config, alertManagerSourceName }: Props) => {
|
||||
{!readOnly && (
|
||||
<>
|
||||
{loading && (
|
||||
<Button disabled={true} icon="fa fa-spinner" variant="primary">
|
||||
<Button disabled={true} icon="spinner" variant="primary">
|
||||
Saving...
|
||||
</Button>
|
||||
)}
|
||||
|
@ -203,7 +203,7 @@ export const TemplateForm = ({ existing, alertManagerSourceName, config, provena
|
||||
</Field>
|
||||
<div className={styles.buttons}>
|
||||
{loading && (
|
||||
<Button disabled={true} icon="fa fa-spinner" variant="primary">
|
||||
<Button disabled={true} icon="spinner" variant="primary">
|
||||
Saving...
|
||||
</Button>
|
||||
)}
|
||||
|
@ -159,7 +159,7 @@ export function ChannelSubForm<R extends ChannelValues>({
|
||||
variant="secondary"
|
||||
type="button"
|
||||
onClick={() => handleTest()}
|
||||
icon={testingReceiver ? 'fa fa-spinner' : 'message'}
|
||||
icon={testingReceiver ? 'spinner' : 'message'}
|
||||
>
|
||||
Test
|
||||
</Button>
|
||||
|
@ -186,7 +186,7 @@ export function ReceiverForm<R extends ChannelValues>({
|
||||
{isEditable && (
|
||||
<>
|
||||
{isSubmitting && (
|
||||
<Button disabled={true} icon="fa fa-spinner" variant="primary">
|
||||
<Button disabled={true} icon="spinner" variant="primary">
|
||||
Saving...
|
||||
</Button>
|
||||
)}
|
||||
|
@ -488,7 +488,7 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange }: P
|
||||
{config.expressionsEnabled && <TypeSelectorButton onClickType={onClickType} />}
|
||||
|
||||
{isPreviewLoading && (
|
||||
<Button icon="fa fa-spinner" type="button" variant="destructive" onClick={cancelQueries}>
|
||||
<Button icon="spinner" type="button" variant="destructive" onClick={cancelQueries}>
|
||||
Cancel
|
||||
</Button>
|
||||
)}
|
||||
|
@ -242,7 +242,7 @@ export const SilencesEditor = ({ silence, alertManagerSourceName }: Props) => {
|
||||
</FieldSet>
|
||||
<div className={styles.flexRow}>
|
||||
{loading && (
|
||||
<Button disabled={true} icon="fa fa-spinner" variant="primary">
|
||||
<Button disabled={true} icon="spinner" variant="primary">
|
||||
Saving...
|
||||
</Button>
|
||||
)}
|
||||
|
@ -292,7 +292,9 @@ describe('CorrelationsPage', () => {
|
||||
|
||||
await userEvent.click(await screen.findByRole('button', { name: /add$/i }));
|
||||
|
||||
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added');
|
||||
await waitFor(() => {
|
||||
expect(mocks.reportInteraction).toHaveBeenCalledWith('grafana_correlations_added');
|
||||
});
|
||||
|
||||
// the table showing correlations should have appeared
|
||||
expect(await screen.findByRole('table')).toBeInTheDocument();
|
||||
@ -439,7 +441,9 @@ describe('CorrelationsPage', () => {
|
||||
|
||||
await userEvent.click(screen.getByRole('button', { name: /add$/i }));
|
||||
|
||||
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added');
|
||||
await waitFor(() => {
|
||||
expect(mocks.reportInteraction).toHaveBeenCalledWith('grafana_correlations_added');
|
||||
});
|
||||
|
||||
// the table showing correlations should have appeared
|
||||
expect(await screen.findByRole('table')).toBeInTheDocument();
|
||||
@ -474,7 +478,9 @@ describe('CorrelationsPage', () => {
|
||||
|
||||
expect(screen.queryByRole('cell', { name: /some label$/i })).not.toBeInTheDocument();
|
||||
|
||||
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_deleted');
|
||||
await waitFor(() => {
|
||||
expect(mocks.reportInteraction).toHaveBeenCalledWith('grafana_correlations_deleted');
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly edits correlations', async () => {
|
||||
@ -486,7 +492,9 @@ describe('CorrelationsPage', () => {
|
||||
const rowExpanderButton = within(tableRows[0]).getByRole('button', { name: /toggle row expanded/i });
|
||||
await userEvent.click(rowExpanderButton);
|
||||
|
||||
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_details_expanded');
|
||||
await waitFor(() => {
|
||||
expect(mocks.reportInteraction).toHaveBeenCalledWith('grafana_correlations_details_expanded');
|
||||
});
|
||||
|
||||
await userEvent.clear(screen.getByRole('textbox', { name: /label/i }));
|
||||
await userEvent.type(screen.getByRole('textbox', { name: /label/i }), 'edited label');
|
||||
@ -500,9 +508,11 @@ describe('CorrelationsPage', () => {
|
||||
|
||||
await userEvent.click(screen.getByRole('button', { name: /save$/i }));
|
||||
|
||||
expect(await screen.findByRole('cell', { name: /edited label$/i })).toBeInTheDocument();
|
||||
expect(await screen.findByRole('cell', { name: /edited label$/i }, { timeout: 5000 })).toBeInTheDocument();
|
||||
|
||||
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_edited');
|
||||
await waitFor(() => {
|
||||
expect(mocks.reportInteraction).toHaveBeenCalledWith('grafana_correlations_edited');
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly edits transformations', async () => {
|
||||
@ -553,7 +563,9 @@ describe('CorrelationsPage', () => {
|
||||
expect(screen.getByText('Please define an expression')).toBeInTheDocument();
|
||||
await userEvent.type(screen.getByLabelText(/expression/i), 'test expression');
|
||||
await userEvent.click(screen.getByRole('button', { name: /save$/i }));
|
||||
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_edited');
|
||||
await waitFor(() => {
|
||||
expect(mocks.reportInteraction).toHaveBeenCalledWith('grafana_correlations_edited');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -684,7 +696,9 @@ describe('CorrelationsPage', () => {
|
||||
|
||||
await userEvent.click(rowExpanderButton);
|
||||
|
||||
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_details_expanded');
|
||||
await waitFor(() => {
|
||||
expect(mocks.reportInteraction).toHaveBeenCalledWith('grafana_correlations_details_expanded');
|
||||
});
|
||||
|
||||
// form elements should be readonly
|
||||
const labelInput = await screen.findByRole('textbox', { name: /label/i });
|
||||
|
@ -11,7 +11,7 @@ export const CorrelationFormNavigation = () => {
|
||||
const { readOnly, loading, correlation } = useCorrelationsFormContext();
|
||||
|
||||
const LastPageNext = !readOnly && (
|
||||
<Button variant="primary" icon={loading ? 'fa fa-spinner' : 'save'} type="submit" disabled={loading}>
|
||||
<Button variant="primary" icon={loading ? 'spinner' : 'save'} type="submit" disabled={loading}>
|
||||
{correlation === undefined ? 'Add' : 'Save'}
|
||||
</Button>
|
||||
);
|
||||
|
@ -45,7 +45,7 @@ export const SaveDashboardForm = ({ dashboard, onCancel, onSubmit, onSuccess, sa
|
||||
<Button variant="secondary" onClick={onCancel} fill="outline">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={!hasChanges} icon={saving ? 'fa fa-spinner' : undefined}>
|
||||
<Button type="submit" disabled={!hasChanges} icon={saving ? 'spinner' : undefined}>
|
||||
Save
|
||||
</Button>
|
||||
{!hasChanges && <div>No changes to save</div>}
|
||||
|
@ -126,7 +126,7 @@ export const SaveDashboardForm = ({
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={!saveModel.hasChanges || isLoading}
|
||||
icon={saving ? 'fa fa-spinner' : undefined}
|
||||
icon={saving ? 'spinner' : undefined}
|
||||
aria-label={selectors.pages.SaveDashboardModal.save}
|
||||
>
|
||||
{isLoading ? 'Saving...' : 'Save'}
|
||||
|
@ -92,12 +92,7 @@ export const PlaylistForm = ({ onSubmit, playlist }: Props) => {
|
||||
</div>
|
||||
|
||||
<HorizontalGroup>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
disabled={isDisabled}
|
||||
icon={saving ? 'fa fa-spinner' : undefined}
|
||||
>
|
||||
<Button type="submit" variant="primary" disabled={isDisabled} icon={saving ? 'spinner' : undefined}>
|
||||
<Trans i18nKey="playlist-edit.form.save">Save</Trans>
|
||||
</Button>
|
||||
<LinkButton variant="secondary" href={`${config.appSubUrl}/playlists`}>
|
||||
|
@ -132,7 +132,7 @@ export const MoveToFolderModal = ({ results, onMoveItems, onDismiss }: Props) =>
|
||||
<Button variant="secondary" onClick={onDismiss} fill="outline">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button icon={moving ? 'fa fa-spinner' : undefined} variant="primary" onClick={moveTo}>
|
||||
<Button icon={moving ? 'spinner' : undefined} variant="primary" onClick={moveTo}>
|
||||
Move
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
|
@ -138,7 +138,9 @@ describe('VisualMetricQueryEditor', () => {
|
||||
expect(screen.getByText('metric.test_label')).toBeInTheDocument();
|
||||
const service = await screen.findByLabelText('Service');
|
||||
openMenu(service);
|
||||
await select(service, 'Srv 2', { container: document.body });
|
||||
await act(async () => {
|
||||
await select(service, 'Srv 2', { container: document.body });
|
||||
});
|
||||
expect(onChange).toBeCalledWith(expect.objectContaining({ filters: ['metric.type', '=', 'type2'] }));
|
||||
expect(query).toEqual(defaultQuery);
|
||||
expect(screen.queryByText('metric.test_label')).not.toBeInTheDocument();
|
||||
|
@ -88,8 +88,12 @@ exports[`VariableQueryEditor renders correctly 1`] = `
|
||||
<div
|
||||
className="css-zyjsuv-input-suffix"
|
||||
>
|
||||
<div
|
||||
className="css-1j2891d-Icon"
|
||||
<svg
|
||||
className="css-1d3xu67-Icon"
|
||||
height={16}
|
||||
id="public/img/icons/unicons/angle-down.svg"
|
||||
title=""
|
||||
width={16}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -107,7 +107,7 @@ const QueryHeader = ({
|
||||
variant={dataIsStale ? 'primary' : 'secondary'}
|
||||
size="sm"
|
||||
onClick={onRunQuery}
|
||||
icon={data?.state === LoadingState.Loading ? 'fa fa-spinner' : undefined}
|
||||
icon={data?.state === LoadingState.Loading ? 'spinner' : undefined}
|
||||
disabled={data?.state === LoadingState.Loading || emptyLogsExpression}
|
||||
>
|
||||
Run queries
|
||||
|
@ -285,7 +285,7 @@ describe('LogGroupsSelector', () => {
|
||||
/>
|
||||
);
|
||||
await userEvent.click(screen.getByText('Select log groups'));
|
||||
await screen.getByRole('button', { name: 'select-clear-value' }).click();
|
||||
await userEvent.click(screen.getByRole('button', { name: 'select-clear-value' }));
|
||||
await userEvent.click(screen.getByText('Add log groups'));
|
||||
expect(onChange).toHaveBeenCalledWith([
|
||||
{
|
||||
|
@ -176,7 +176,7 @@ export const LokiQueryEditor = React.memo<LokiQueryEditorProps>((props) => {
|
||||
variant={dataIsStale ? 'primary' : 'secondary'}
|
||||
size="sm"
|
||||
onClick={onRunQuery}
|
||||
icon={data?.state === LoadingState.Loading ? 'fa fa-spinner' : undefined}
|
||||
icon={data?.state === LoadingState.Loading ? 'spinner' : undefined}
|
||||
disabled={data?.state === LoadingState.Loading}
|
||||
>
|
||||
{queries && queries.length > 1 ? `Run queries` : `Run query`}
|
||||
|
@ -130,7 +130,7 @@ export const PromQueryEditorSelector = React.memo<Props>((props) => {
|
||||
variant={dataIsStale ? 'primary' : 'secondary'}
|
||||
size="sm"
|
||||
onClick={onRunQuery}
|
||||
icon={data?.state === LoadingState.Loading ? 'fa fa-spinner' : undefined}
|
||||
icon={data?.state === LoadingState.Loading ? 'spinner' : undefined}
|
||||
disabled={data?.state === LoadingState.Loading}
|
||||
>
|
||||
Run queries
|
||||
|
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 24 24"><path d="M6.8042,15A.99956.99956,0,0,0,5.438,14.63379l-1.73242,1a1.00016,1.00016,0,0,0,1,1.73242l1.73242-1A1.00073,1.00073,0,0,0,6.8042,15ZM3.70557,8.36621l1.73242,1a1.00016,1.00016,0,1,0,1-1.73242l-1.73242-1a1.00016,1.00016,0,0,0-1,1.73242ZM6,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H5A1,1,0,0,0,6,12ZM17.1958,9a1.0006,1.0006,0,0,0,1.36621.36621l1.73242-1a1.00016,1.00016,0,1,0-1-1.73242l-1.73242,1A1.00073,1.00073,0,0,0,17.1958,9ZM15,6.8042A1.0006,1.0006,0,0,0,16.36621,6.438l1-1.73242a1.00016,1.00016,0,1,0-1.73242-1l-1,1.73242A1.00073,1.00073,0,0,0,15,6.8042Zm5.29443,8.82959-1.73242-1a1.00016,1.00016,0,1,0-1,1.73242l1.73242,1a1.00016,1.00016,0,0,0,1-1.73242ZM16.36621,17.562a1.00016,1.00016,0,1,0-1.73242,1l1,1.73242a1.00016,1.00016,0,1,0,1.73242-1ZM21,11H19a1,1,0,0,0,0,2h2a1,1,0,0,0,0-2Zm-9,7a1,1,0,0,0-1,1v2a1,1,0,0,0,2,0V19A1,1,0,0,0,12,18Zm-3-.8042a.99954.99954,0,0,0-1.36621.36621l-1,1.73242a1.00016,1.00016,0,0,0,1.73242,1l1-1.73242A1.00073,1.00073,0,0,0,9,17.1958ZM12,2a1,1,0,0,0-1,1V5a1,1,0,0,0,2,0V3A1,1,0,0,0,12,2Z"/></svg>
|
Before Width: | Height: | Size: 1.1 KiB |
@ -1 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24"><path d="M5.1,16c-0.3-0.5-0.9-0.6-1.4-0.4c-0.5,0.3-0.6,0.9-0.4,1.4c0.3,0.5,0.9,0.6,1.4,0.4C5.2,17.1,5.3,16.5,5.1,16C5.1,16,5.1,16,5.1,16z M4.7,6.6C4.2,6.4,3.6,6.5,3.3,7C3.1,7.5,3.2,8.1,3.7,8.4C4.2,8.6,4.8,8.5,5.1,8C5.3,7.5,5.2,6.9,4.7,6.6z M20.3,8.4c0.5-0.3,0.6-0.9,0.4-1.4c-0.3-0.5-0.9-0.6-1.4-0.4c-0.5,0.3-0.6,0.9-0.4,1.4C19.2,8.5,19.8,8.6,20.3,8.4z M4,12c0-0.6-0.4-1-1-1s-1,0.4-1,1s0.4,1,1,1S4,12.6,4,12z M7.2,18.8c-0.5,0.1-0.9,0.7-0.7,1.2c0.1,0.5,0.7,0.9,1.2,0.7c0.5-0.1,0.9-0.7,0.7-1.2C8.3,19,7.8,18.7,7.2,18.8z M21,11c-0.6,0-1,0.4-1,1s0.4,1,1,1s1-0.4,1-1S21.6,11,21,11z M20.3,15.6c-0.5-0.3-1.1-0.1-1.4,0.4c-0.3,0.5-0.1,1.1,0.4,1.4c0.5,0.3,1.1,0.1,1.4-0.4c0,0,0,0,0,0C20.9,16.5,20.8,15.9,20.3,15.6z M17,3.3c-0.5-0.3-1.1-0.1-1.4,0.4c-0.3,0.5-0.1,1.1,0.4,1.4c0.5,0.3,1.1,0.1,1.4-0.4c0,0,0,0,0,0C17.6,4.2,17.5,3.6,17,3.3z M16.8,18.8c-0.5-0.1-1.1,0.2-1.2,0.7c-0.1,0.5,0.2,1.1,0.7,1.2c0.5,0.1,1.1-0.2,1.2-0.7C17.6,19.5,17.3,19,16.8,18.8z M12,20c-0.6,0-1,0.4-1,1s0.4,1,1,1s1-0.4,1-1S12.6,20,12,20z M12,2c-0.6,0-1,0.4-1,1s0.4,1,1,1s1-0.4,1-1S12.6,2,12,2z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1664" height="1728" viewBox="0 0 1664 1728">
|
||||
<path fill="currentColor" d="M462 1394q0 53-37.5 90.5T334 1522q-52 0-90-38t-38-90q0-53 37.5-90.5T334 1266t90.5 37.5T462 1394zm498 206q0 53-37.5 90.5T832 1728t-90.5-37.5T704 1600t37.5-90.5T832 1472t90.5 37.5T960 1600zM256 896q0 53-37.5 90.5T128 1024t-90.5-37.5T0 896t37.5-90.5T128 768t90.5 37.5T256 896zm1202 498q0 52-38 90t-90 38q-53 0-90.5-37.5T1202 1394t37.5-90.5t90.5-37.5t90.5 37.5t37.5 90.5zM494 398q0 66-47 113t-113 47t-113-47t-47-113t47-113t113-47t113 47t47 113zm1170 498q0 53-37.5 90.5T1536 1024t-90.5-37.5T1408 896t37.5-90.5T1536 768t90.5 37.5T1664 896zm-640-704q0 80-56 136t-136 56t-136-56t-56-136t56-136T832 0t136 56t56 136zm530 206q0 93-66 158.5T1330 622q-93 0-158.5-65.5T1106 398q0-92 65.5-158t158.5-66q92 0 158 66t66 158z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 840 B |
7
public/test/mocks/react-inlinesvg.tsx
Normal file
7
public/test/mocks/react-inlinesvg.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function ReactInlineSVG({ src, innerRef, cacheRequests, preProcessor, ...rest }) {
|
||||
return <svg id={src} ref={innerRef} {...rest} />;
|
||||
}
|
||||
|
||||
export const cacheStore = {};
|
Loading…
Reference in New Issue
Block a user