d7fb7b7a7b
Build & Deploy / Build & Push Docker Image (push) Failing after 47s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Failing after 4m55s
Test / Admin Unit Tests (push) Successful in 9m37s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s
140 lines
3.5 KiB
TypeScript
140 lines
3.5 KiB
TypeScript
import { classNames } from '@/lib/components/classNames';
|
|
import type { ReactNode, SVGProps } from 'react';
|
|
import styles from './Icon.module.css';
|
|
|
|
export const approvedIconNames = [
|
|
'arrow-back',
|
|
'arrow-forward',
|
|
'calendar',
|
|
'car',
|
|
'check',
|
|
'chevron-down',
|
|
'chevron-forward',
|
|
'close',
|
|
'error',
|
|
'external',
|
|
'globe',
|
|
'info',
|
|
'menu',
|
|
'minus',
|
|
'plus',
|
|
'search',
|
|
'settings',
|
|
'spinner',
|
|
'warning',
|
|
] as const;
|
|
|
|
export type ApprovedIconName = (typeof approvedIconNames)[number];
|
|
export type IconSize = 'sm' | 'md' | 'lg';
|
|
export type IconDirectionBehavior = 'fixed' | 'mirror';
|
|
|
|
interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'name'> {
|
|
name: ApprovedIconName;
|
|
size?: IconSize;
|
|
decorative?: boolean;
|
|
label?: string;
|
|
directionBehavior?: IconDirectionBehavior;
|
|
}
|
|
|
|
const paths: Record<ApprovedIconName, ReactNode> = {
|
|
'arrow-back': <path d="m15 18-6-6 6-6M9 12h10" />,
|
|
'arrow-forward': <path d="m9 18 6-6-6-6m6 6H5" />,
|
|
calendar: (
|
|
<>
|
|
<rect x="3" y="5" width="18" height="16" rx="2" />
|
|
<path d="M16 3v4M8 3v4M3 10h18" />
|
|
</>
|
|
),
|
|
car: (
|
|
<>
|
|
<path d="m5 11 2-5h10l2 5" />
|
|
<path d="M3 11h18v7H3zM6 18v2m12-2v2M7 14h.01M17 14h.01" />
|
|
</>
|
|
),
|
|
check: <path d="m5 12 4 4L19 6" />,
|
|
'chevron-down': <path d="m6 9 6 6 6-6" />,
|
|
'chevron-forward': <path d="m9 18 6-6-6-6" />,
|
|
close: <path d="M6 6l12 12M18 6 6 18" />,
|
|
error: (
|
|
<>
|
|
<circle cx="12" cy="12" r="9" />
|
|
<path d="M12 7v6m0 4h.01" />
|
|
</>
|
|
),
|
|
external: (
|
|
<>
|
|
<path d="M14 4h6v6M20 4l-9 9" />
|
|
<path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6" />
|
|
</>
|
|
),
|
|
globe: (
|
|
<>
|
|
<circle cx="12" cy="12" r="9" />
|
|
<path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18" />
|
|
</>
|
|
),
|
|
info: (
|
|
<>
|
|
<circle cx="12" cy="12" r="9" />
|
|
<path d="M12 11v6m0-10h.01" />
|
|
</>
|
|
),
|
|
menu: <path d="M4 7h16M4 12h16M4 17h16" />,
|
|
minus: <path d="M5 12h14" />,
|
|
plus: <path d="M12 5v14M5 12h14" />,
|
|
search: (
|
|
<>
|
|
<circle cx="11" cy="11" r="7" />
|
|
<path d="m16 16 5 5" />
|
|
</>
|
|
),
|
|
settings: (
|
|
<>
|
|
<circle cx="12" cy="12" r="3" />
|
|
<path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H2.8v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1A1.7 1.7 0 0 0 9 4.6 1.7 1.7 0 0 0 10 3V2.8h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6 1Z" />
|
|
</>
|
|
),
|
|
spinner: <path d="M21 12a9 9 0 1 1-9-9" />,
|
|
warning: (
|
|
<>
|
|
<path d="M12 3 2.5 20h19L12 3Z" />
|
|
<path d="M12 9v5m0 3h.01" />
|
|
</>
|
|
),
|
|
};
|
|
|
|
export function Icon({
|
|
name,
|
|
size = 'md',
|
|
decorative = true,
|
|
label,
|
|
directionBehavior = 'fixed',
|
|
className,
|
|
...props
|
|
}: IconProps) {
|
|
const accessibleProps = decorative
|
|
? ({ 'aria-hidden': true } as const)
|
|
: ({ role: 'img', 'aria-label': label ?? name } as const);
|
|
return (
|
|
<svg
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
focusable="false"
|
|
className={classNames(
|
|
styles.icon,
|
|
styles[size],
|
|
directionBehavior === 'mirror' && styles.mirror,
|
|
className,
|
|
)}
|
|
{...accessibleProps}
|
|
{...props}
|
|
>
|
|
{paths[name]}
|
|
</svg>
|
|
);
|
|
}
|