Resto·Ka — tous les restaurants du Québec, menus complets et prix réels (famille ·Ka)
Python 69.3%
TypeScript 16.7%
CSS 7.9%
JavaScript 4.7%
HTML 1.4%
1// KA Tabbar v1 — canonique ka-ui.git/nav/KaTabbar.tsx2// Barre de navigation mobile commune Groupe KA (voir TABBAR-STANDARD.md).3// Copier dans src/ka/ avec ka-tabbar.css. Apps react-router uniquement ;4// pour Next.js (vrai-prix), adapter Link/usePathname — voir le standard.5import type { CSSProperties, ReactElement } from "react";6import { Link } from "react-router-dom";7import "./ka-tabbar.css";89export type KaTabIcon =10 | "compass" | "search" | "heart" | "user" | "map" | "pin" | "tag"11 | "home" | "grid" | "store" | "basket" | "target" | "trendup"12 | "receipt" | "book" | "chart" | "calendar";1314const ICONS: Record<KaTabIcon, ReactElement> = {15 compass: (16 <>17 <circle cx="12" cy="12" r="9" />18 <path d="m15.5 8.5-2.2 5-4.8 2 2.2-5 4.8-2z" />19 </>20 ),21 search: (22 <>23 <circle cx="11" cy="11" r="7" />24 <path d="m20.5 20.5-4.2-4.2" />25 </>26 ),27 heart: (28 <path d="M12 20.5S4.5 15.8 2.6 11.4A5.3 5.3 0 0 1 12 6.6a5.3 5.3 0 0 1 9.4 4.8C19.5 15.8 12 20.5 12 20.5z" />29 ),30 user: (31 <>32 <circle cx="12" cy="8.2" r="3.7" />33 <path d="M4.5 20.2a7.5 7.5 0 0 1 15 0" />34 </>35 ),36 map: (37 <>38 <path d="M9 4 3.5 6v14L9 18l6 2 5.5-2V4L15 6 9 4z" />39 <path d="M9 4v14M15 6v14" />40 </>41 ),42 pin: (43 <>44 <path d="M12 21s-7-5.6-7-11a7 7 0 0 1 14 0c0 5.4-7 11-7 11z" />45 <circle cx="12" cy="10" r="2.6" />46 </>47 ),48 tag: (49 <>50 <path d="M20.6 13.4 12 22 2 12V2h10l8.6 8.6a2 2 0 0 1 0 2.8z" />51 <circle cx="7" cy="7" r="1.6" />52 </>53 ),54 home: (55 <>56 <path d="m3.5 10.5 8.5-7 8.5 7" />57 <path d="M5.5 9v11h13V9" />58 </>59 ),60 grid: (61 <>62 <rect x="4" y="4" width="7" height="7" rx="1.5" />63 <rect x="13" y="4" width="7" height="7" rx="1.5" />64 <rect x="4" y="13" width="7" height="7" rx="1.5" />65 <rect x="13" y="13" width="7" height="7" rx="1.5" />66 </>67 ),68 store: (69 <>70 <path d="M4.5 9.5 6 4.5h12l1.5 5" />71 <path d="M5 9.5h14V20H5V9.5z" />72 <path d="M10 20v-5h4v5" />73 </>74 ),75 basket: (76 <>77 <path d="M4 9h16l-1.6 10a2 2 0 0 1-2 1.7H7.6a2 2 0 0 1-2-1.7L4 9z" />78 <path d="M8.5 9 12 3l3.5 6" />79 </>80 ),81 target: (82 <>83 <circle cx="12" cy="12" r="8.5" />84 <circle cx="12" cy="12" r="4.5" />85 <circle cx="12" cy="12" r="0.8" />86 </>87 ),88 trendup: (89 <>90 <path d="m3.5 16.5 5.5-5.5 3.5 3.5 7.5-7.5" />91 <path d="M14.5 7H20v5.5" />92 </>93 ),94 receipt: (95 <>96 <path d="M6 3.5h12V21l-2-1.4-2 1.4-2-1.4-2 1.4-2-1.4L6 21V3.5z" />97 <path d="M9 8h6M9 11.5h6M9 15h4" />98 </>99 ),100 book: (101 <>102 <path d="M12 6.5C10.5 5 8.5 4.5 5.5 4.5H3.5V19h2c3 0 5 .5 6.5 2 1.5-1.5 3.5-2 6.5-2h2V4.5h-2c-3 0-5 .5-6.5 2z" />103 <path d="M12 6.5V21" />104 </>105 ),106 chart: (107 <>108 <path d="M4 20h16" />109 <path d="M7.5 20v-6M12 20V9M16.5 20v-4" />110 </>111 ),112 calendar: (113 <>114 <rect x="3.5" y="5" width="17" height="15.5" rx="2" />115 <path d="M8 3v4M16 3v4M3.5 10h17" />116 </>117 ),118};119120export function KaTabIco({ name, size = 21 }: { name: KaTabIcon; size?: number }) {121 return (122 <svg123 width={size}124 height={size}125 viewBox="0 0 24 24"126 fill="none"127 stroke="currentColor"128 strokeWidth={1.7}129 strokeLinecap="round"130 strokeLinejoin="round"131 aria-hidden="true"132 >133 {ICONS[name]}134 </svg>135 );136}137138export type KaTab = {139 label: string;140 icon: KaTabIcon;141 /** route interne (react-router Link) */142 to?: string;143 /** lien externe (ex. hub univers KA) */144 href?: string;145 /** action locale (ex. ouvrir la recherche) — rend un <button> */146 onPress?: () => void;147 /** complément d'un lien `to` (ex. focus d'un champ une fois arrivé) */148 onClick?: () => void;149 active?: boolean;150};151152export default function KaTabbar({153 tabs,154 theme = "light",155 accent,156 className,157}: {158 tabs: KaTab[];159 theme?: "light" | "dark";160 /** couleur signature de la marque (défaut : var(--accent) du site) */161 accent?: string;162 className?: string;163}) {164 const cls =165 "ka-tabbar" +166 (theme === "dark" ? " ka-tabbar--dark" : "") +167 (className ? " " + className : "");168 const style = accent ? ({ "--ktb-accent": accent } as CSSProperties) : undefined;169 return (170 <nav className={cls} style={style} aria-label="Navigation mobile">171 {tabs.map((t) => {172 const inner = (173 <>174 <KaTabIco name={t.icon} />175 {t.label}176 </>177 );178 const c = t.active ? "active" : "";179 if (t.to)180 return (181 <Link182 key={t.label}183 to={t.to}184 className={c}185 onClick={t.onClick}186 aria-current={t.active ? "page" : undefined}187 >188 {inner}189 </Link>190 );191 if (t.href)192 return (193 <a key={t.label} href={t.href} className={c} target="_blank" rel="noreferrer">194 {inner}195 </a>196 );197 return (198 <button key={t.label} type="button" className={c} onClick={t.onPress}>199 {inner}200 </button>201 );202 })}203 </nav>204 );205}206