SPB Git

spb/fabri-ka Public

Agrégateur de produits québécois — www.fabri-ka.com

HTML 57% Python 19.9% TypeScript 15.3% CSS 7.7%
6.7 KB · 254 lines tsx
Raw Blame History
1// ---------------------------------------------------------------------------2// Fabri-Ka — inline SVG icon set (no runtime dependency)3// ---------------------------------------------------------------------------4import { ReactElement, SVGProps } from 'react'56type IconProps = SVGProps<SVGSVGElement> & { size?: number }78function Svg({ size = 20, children, ...rest }: IconProps) {9  return (10    <svg11      width={size}12      height={size}13      viewBox="0 0 24 24"14      fill="none"15      stroke="currentColor"16      strokeWidth={1.8}17      strokeLinecap="round"18      strokeLinejoin="round"19      aria-hidden="true"20      focusable="false"21      {...rest}22    >23      {children}24    </svg>25  )26}2728export function IconHome(props: IconProps) {29  return (30    <Svg {...props}>31      <path d="M3 10.5 12 3l9 7.5" />32      <path d="M5.5 9.5V20a1 1 0 0 0 1 1h11a1 1 0 0 0 1-1V9.5" />33      <path d="M9.5 21v-6h5v6" />34    </Svg>35  )36}3738export function IconGrid(props: IconProps) {39  return (40    <Svg {...props}>41      <rect x="3.5" y="3.5" width="7" height="7" rx="1.5" />42      <rect x="13.5" y="3.5" width="7" height="7" rx="1.5" />43      <rect x="3.5" y="13.5" width="7" height="7" rx="1.5" />44      <rect x="13.5" y="13.5" width="7" height="7" rx="1.5" />45    </Svg>46  )47}4849export function IconStore(props: IconProps) {50  return (51    <Svg {...props}>52      <path d="M4 9.5 5.4 4h13.2L20 9.5" />53      <path d="M4 9.5a2.6 2.6 0 0 0 5.3 0 2.65 2.65 0 0 0 5.4 0 2.6 2.6 0 0 0 5.3 0" />54      <path d="M5 12.5V20a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-7.5" />55      <path d="M9.5 21v-5.5h5V21" />56    </Svg>57  )58}5960export function IconSearch(props: IconProps) {61  return (62    <Svg {...props}>63      <circle cx="11" cy="11" r="6.5" />64      <path d="m20.5 20.5-4.9-4.9" />65    </Svg>66  )67}6869export function IconFilter(props: IconProps) {70  return (71    <Svg {...props}>72      <path d="M4 7h10M18 7h2" />73      <circle cx="16" cy="7" r="2" />74      <path d="M4 17h2M10 17h10" />75      <circle cx="8" cy="17" r="2" />76    </Svg>77  )78}7980export function IconClose(props: IconProps) {81  return (82    <Svg {...props}>83      <path d="M6 6l12 12M18 6 6 18" />84    </Svg>85  )86}8788export function IconChevronDown(props: IconProps) {89  return (90    <Svg {...props}>91      <path d="m6 9 6 6 6-6" />92    </Svg>93  )94}9596export function IconArrowRight(props: IconProps) {97  return (98    <Svg {...props}>99      <path d="M4.5 12h15" />100      <path d="m13.5 6 6 6-6 6" />101    </Svg>102  )103}104105export function IconExternal(props: IconProps) {106  return (107    <Svg {...props}>108      <path d="M13.5 5H19v5.5" />109      <path d="M19 5 10.5 13.5" />110      <path d="M19 13.5V19H5V5h5.5" />111    </Svg>112  )113}114115export function IconLeaf(props: IconProps) {116  return (117    <Svg {...props}>118      <path d="M5.5 20.5C5.5 11.5 10 4.5 20 4.5c0 10-5.5 14-14.5 16z" />119      <path d="M5.5 20.5C8 15 11.5 11 16 8.5" />120    </Svg>121  )122}123124export function IconAlert(props: IconProps) {125  return (126    <Svg {...props}>127      <circle cx="12" cy="12" r="9" />128      <path d="M12 7.5V13" />129      <path d="M12 16.5h.01" />130    </Svg>131  )132}133134export function IconMapPin(props: IconProps) {135  return (136    <Svg {...props}>137      <path d="M12 21s-7-5.5-7-11a7 7 0 0 1 14 0c0 5.5-7 11-7 11z" />138      <circle cx="12" cy="10" r="2.5" />139    </Svg>140  )141}142143export function IconDrop(props: IconProps) {144  return (145    <Svg {...props}>146      <path d="M12 3.5s6.5 7.2 6.5 11.3a6.5 6.5 0 0 1-13 0C5.5 10.7 12 3.5 12 3.5z" />147    </Svg>148  )149}150151export function IconShirt(props: IconProps) {152  return (153    <Svg {...props}>154      <path d="m8.5 4-5 3 2 4 2.5-1V20h8v-10l2.5 1 2-4-5-3a3.5 3.5 0 0 1-7 0z" />155    </Svg>156  )157}158159export function IconGem(props: IconProps) {160  return (161    <Svg {...props}>162      <path d="M7 4h10l4 5.5L12 20.5 3 9.5 7 4z" />163      <path d="M3 9.5h18M12 20.5 8.5 9.5 12 4l3.5 5.5L12 20.5z" />164    </Svg>165  )166}167168export function IconPalette(props: IconProps) {169  return (170    <Svg {...props}>171      <path d="M12 3a9 9 0 1 0 0 18c1.4 0 2.2-.9 2.2-2 0-1-.7-1.4-.7-2.3 0-.9.8-1.7 2-1.7h1.7A3.8 3.8 0 0 0 21 11.2C21 6.7 16.9 3 12 3z" />172      <circle cx="7.5" cy="10.5" r="0.5" fill="currentColor" />173      <circle cx="11" cy="7.5" r="0.5" fill="currentColor" />174      <circle cx="15.5" cy="8.5" r="0.5" fill="currentColor" />175    </Svg>176  )177}178179export function IconSparkle(props: IconProps) {180  return (181    <Svg {...props}>182      <path d="M12 3.5 14 9.5l6 2-6 2-2 6-2-6-6-2 6-2 2-6z" />183    </Svg>184  )185}186187export function IconCandle(props: IconProps) {188  return (189    <Svg {...props}>190      <path d="M12 3c1.2 1.6 2 2.7 2 3.8a2 2 0 0 1-4 0C10 5.7 10.8 4.6 12 3z" />191      <path d="M8.5 11h7V21h-7V11z" />192    </Svg>193  )194}195196export function IconInstagram(props: IconProps) {197  return (198    <Svg {...props}>199      <rect x="4" y="4" width="16" height="16" rx="4.5" />200      <circle cx="12" cy="12" r="3.6" />201      <circle cx="16.9" cy="7.1" r="0.55" fill="currentColor" />202    </Svg>203  )204}205206export function IconFacebook(props: IconProps) {207  return (208    <Svg {...props}>209      <path d="M13.5 20.5v-6.8h2.6l.4-3.1h-3V8.5c0-.9.45-1.6 1.7-1.6h1.5v-2.8c-.65-.1-1.4-.2-2.2-.2-2.3 0-3.9 1.4-3.9 4v2.7H8v3.1h2.6v6.8" />210    </Svg>211  )212}213214export function IconDownload(props: IconProps) {215  return (216    <Svg {...props}>217      <path d="M12 3.5v11" />218      <path d="m7.5 10 4.5 4.5 4.5-4.5" />219      <path d="M4.5 19.5h15" />220    </Svg>221  )222}223224export function IconTag(props: IconProps) {225  return (226    <Svg {...props}>227      <path d="M3.5 3.5h8l9 9-8 8-9-9v-8z" />228      <circle cx="8" cy="8" r="1.2" />229    </Svg>230  )231}232233// ---------------------------------------------------------------------------234// Category label → icon235// ---------------------------------------------------------------------------236237const CATEGORY_ICONS: { keywords: string[]; icon: (p: IconProps) => ReactElement }[] = [238  { keywords: ['érable', 'erable', 'miel', 'aliment', 'gourmand', 'épicerie', 'epicerie', 'café', 'cafe', 'thé', 'the ', 'boisson'], icon: IconLeaf },239  { keywords: ['beauté', 'beaute', 'soin', 'savon', 'cosmét', 'cosmet', 'corps'], icon: IconDrop },240  { keywords: ['maison', 'déco', 'deco', 'cuisine', 'meuble'], icon: IconHome },241  { keywords: ['vêtement', 'vetement', 'mode', 'accessoire', 'textile'], icon: IconShirt },242  { keywords: ['bijou', 'joaill'], icon: IconGem },243  { keywords: ['art', 'papeterie', 'illustration', 'création', 'creation'], icon: IconPalette },244  { keywords: ['bougie', 'chandelle', 'ambiance'], icon: IconCandle },245  { keywords: ['enfant', 'jouet', 'bébé', 'bebe'], icon: IconSparkle },246]247248export function categoryIcon(label: string, size = 16): ReactElement {249  const l = label.toLowerCase()250  const match = CATEGORY_ICONS.find((c) => c.keywords.some((k) => l.includes(k)))251  const Icon = match?.icon ?? IconTag252  return <Icon size={size} />253}254