SPB Git forge

spb/vrai-prix

Public

Vrai-Prix — l'évaluation du vrai prix des propriétés résidentielles au Québec.

60commits 1branches 0releases
12.3 MBsize
maindefault branch
17 days agolast push
TypeScript 90.2% JavaScript 3.5% Python 3.4% CSS 1.9% HTML 0.6%
4.9 KB · 204 lines tsx
Raw Blame History
1"use client";2// KA Tabbar v1 — variante Next.js du canonique ka-ui.git/nav/KaTabbar.tsx3// (Link next/link ; le CSS global ka-tabbar.css est importé par layout.tsx).4import type { CSSProperties, ReactElement } from "react";5import Link from "next/link";67export type KaTabIcon =8  | "compass" | "search" | "heart" | "user" | "map" | "pin" | "tag"9  | "home" | "grid" | "store" | "basket" | "target" | "trendup"10  | "receipt" | "book" | "chart" | "calendar";1112const ICONS: Record<KaTabIcon, ReactElement> = {13  compass: (14    <>15      <circle cx="12" cy="12" r="9" />16      <path d="m15.5 8.5-2.2 5-4.8 2 2.2-5 4.8-2z" />17    </>18  ),19  search: (20    <>21      <circle cx="11" cy="11" r="7" />22      <path d="m20.5 20.5-4.2-4.2" />23    </>24  ),25  heart: (26    <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" />27  ),28  user: (29    <>30      <circle cx="12" cy="8.2" r="3.7" />31      <path d="M4.5 20.2a7.5 7.5 0 0 1 15 0" />32    </>33  ),34  map: (35    <>36      <path d="M9 4 3.5 6v14L9 18l6 2 5.5-2V4L15 6 9 4z" />37      <path d="M9 4v14M15 6v14" />38    </>39  ),40  pin: (41    <>42      <path d="M12 21s-7-5.6-7-11a7 7 0 0 1 14 0c0 5.4-7 11-7 11z" />43      <circle cx="12" cy="10" r="2.6" />44    </>45  ),46  tag: (47    <>48      <path d="M20.6 13.4 12 22 2 12V2h10l8.6 8.6a2 2 0 0 1 0 2.8z" />49      <circle cx="7" cy="7" r="1.6" />50    </>51  ),52  home: (53    <>54      <path d="m3.5 10.5 8.5-7 8.5 7" />55      <path d="M5.5 9v11h13V9" />56    </>57  ),58  grid: (59    <>60      <rect x="4" y="4" width="7" height="7" rx="1.5" />61      <rect x="13" y="4" width="7" height="7" rx="1.5" />62      <rect x="4" y="13" width="7" height="7" rx="1.5" />63      <rect x="13" y="13" width="7" height="7" rx="1.5" />64    </>65  ),66  store: (67    <>68      <path d="M4.5 9.5 6 4.5h12l1.5 5" />69      <path d="M5 9.5h14V20H5V9.5z" />70      <path d="M10 20v-5h4v5" />71    </>72  ),73  basket: (74    <>75      <path d="M4 9h16l-1.6 10a2 2 0 0 1-2 1.7H7.6a2 2 0 0 1-2-1.7L4 9z" />76      <path d="M8.5 9 12 3l3.5 6" />77    </>78  ),79  target: (80    <>81      <circle cx="12" cy="12" r="8.5" />82      <circle cx="12" cy="12" r="4.5" />83      <circle cx="12" cy="12" r="0.8" />84    </>85  ),86  trendup: (87    <>88      <path d="m3.5 16.5 5.5-5.5 3.5 3.5 7.5-7.5" />89      <path d="M14.5 7H20v5.5" />90    </>91  ),92  receipt: (93    <>94      <path d="M6 3.5h12V21l-2-1.4-2 1.4-2-1.4-2 1.4-2-1.4L6 21V3.5z" />95      <path d="M9 8h6M9 11.5h6M9 15h4" />96    </>97  ),98  book: (99    <>100      <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" />101      <path d="M12 6.5V21" />102    </>103  ),104  chart: (105    <>106      <path d="M4 20h16" />107      <path d="M7.5 20v-6M12 20V9M16.5 20v-4" />108    </>109  ),110  calendar: (111    <>112      <rect x="3.5" y="5" width="17" height="15.5" rx="2" />113      <path d="M8 3v4M16 3v4M3.5 10h17" />114    </>115  ),116};117118export function KaTabIco({ name, size = 21 }: { name: KaTabIcon; size?: number }) {119  return (120    <svg121      width={size}122      height={size}123      viewBox="0 0 24 24"124      fill="none"125      stroke="currentColor"126      strokeWidth={1.7}127      strokeLinecap="round"128      strokeLinejoin="round"129      aria-hidden="true"130    >131      {ICONS[name]}132    </svg>133  );134}135136export type KaTab = {137  label: string;138  icon: KaTabIcon;139  /** route interne (react-router Link) */140  to?: string;141  /** lien externe (ex. hub univers KA) */142  href?: string;143  /** action locale (ex. ouvrir la recherche) — rend un <button> */144  onPress?: () => void;145  /** complément d'un lien `to` (ex. focus d'un champ une fois arrivé) */146  onClick?: () => void;147  active?: boolean;148};149150export default function KaTabbar({151  tabs,152  theme = "light",153  accent,154  className,155}: {156  tabs: KaTab[];157  theme?: "light" | "dark";158  /** couleur signature de la marque (défaut : var(--accent) du site) */159  accent?: string;160  className?: string;161}) {162  const cls =163    "ka-tabbar" +164    (theme === "dark" ? " ka-tabbar--dark" : "") +165    (className ? " " + className : "");166  const style = accent ? ({ "--ktb-accent": accent } as CSSProperties) : undefined;167  return (168    <nav className={cls} style={style} aria-label="Navigation mobile">169      {tabs.map((t) => {170        const inner = (171          <>172            <KaTabIco name={t.icon} />173            {t.label}174          </>175        );176        const c = t.active ? "active" : "";177        if (t.to)178          return (179            <Link180              key={t.label}181              href={t.to}182              className={c}183              onClick={t.onClick}184              aria-current={t.active ? "page" : undefined}185            >186              {inner}187            </Link>188          );189        if (t.href)190          return (191            <a key={t.label} href={t.href} className={c} target="_blank" rel="noreferrer">192              {inner}193            </a>194          );195        return (196          <button key={t.label} type="button" className={c} onClick={t.onPress}>197            {inner}198          </button>199        );200      })}201    </nav>202  );203}204