@alfadocs/ui-kit-debug 0.15.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,12 @@ const X = C(
28
28
  "ds:data-[stuck=true]:shadow-[var(--shadow-md)]",
29
29
  "ds:forced-colors:border-b ds:forced-colors:border-[CanvasText]"
30
30
  ].join(" "),
31
- dark: "ds:bg-[var(--color-blue-800)] ds:text-[var(--primary-foreground)]"
31
+ // `dark` flips its own scope into the dark token set so nav
32
+ // links + buttons inside read off-white text on the blue-800
33
+ // surface. Without the `theme-dark` scope the children inherit
34
+ // the light-theme `--foreground` (blue-500) and fail
35
+ // color-contrast at ~1.3:1.
36
+ dark: "theme-dark ds:bg-[var(--color-blue-800)] ds:text-[var(--foreground)]"
32
37
  },
33
38
  sticky: {
34
39
  none: "",
@@ -68,7 +73,7 @@ function G() {
68
73
  }, []), e;
69
74
  }
70
75
  function J(e, d, r) {
71
- const [n, a] = b(!1), [m, o] = b(!1), l = L(0), u = L(!1);
76
+ const [n, a] = b(!1), [p, o] = b(!1), l = L(0), u = L(!1);
72
77
  return j(() => {
73
78
  if (!e || typeof window > "u") return;
74
79
  l.current = window.scrollY;
@@ -79,13 +84,13 @@ function J(e, d, r) {
79
84
  v > 4 && t > r ? o(!0) : (v < -4 || t <= r) && o(!1);
80
85
  }
81
86
  l.current = t, u.current = !1;
82
- }, p = () => {
87
+ }, m = () => {
83
88
  u.current || (u.current = !0, window.requestAnimationFrame(f));
84
89
  };
85
- return window.addEventListener("scroll", p, { passive: !0 }), f(), () => {
86
- window.removeEventListener("scroll", p);
90
+ return window.addEventListener("scroll", m, { passive: !0 }), f(), () => {
91
+ window.removeEventListener("scroll", m);
87
92
  };
88
- }, [e, d, r]), { stuck: n, hidden: m };
93
+ }, [e, d, r]), { stuck: n, hidden: p };
89
94
  }
90
95
  const I = P(
91
96
  ({
@@ -94,28 +99,28 @@ const I = P(
94
99
  homeLabel: r,
95
100
  navSlot: n,
96
101
  actionsSlot: a,
97
- variant: m = "default",
102
+ variant: p = "default",
98
103
  sticky: o = "none",
99
104
  stickyOffset: l = 80,
100
105
  menuLabel: u,
101
106
  navLabel: f,
102
- id: p,
107
+ id: m,
103
108
  className: t,
104
109
  ...v
105
110
  }, E) => {
106
- const { t: h } = S(), y = G(), O = Y(), H = `${p ?? O}-sheet`, [i, w] = b(!1), _ = m === "transparent" || o === "scroll-up", { stuck: z, hidden: T } = J(
111
+ const { t: h } = S(), y = G(), O = Y(), H = `${m ?? O}-sheet`, [i, w] = b(!1), _ = p === "transparent" || o === "scroll-up", { stuck: z, hidden: T } = J(
107
112
  _,
108
113
  o,
109
114
  l
110
- ), A = y ? !1 : T, M = N(() => w(!0), []), k = N(() => w(!1), []);
115
+ ), A = y ? !1 : T, k = N(() => w(!0), []), M = N(() => w(!1), []);
111
116
  q(
112
117
  E,
113
118
  () => ({
114
- openMenu: M,
115
- closeMenu: k,
119
+ openMenu: k,
120
+ closeMenu: M,
116
121
  getMenuOpen: () => i
117
122
  }),
118
- [M, k, i]
123
+ [k, M, i]
119
124
  );
120
125
  const B = r ?? h("publicHeader.homeLabel", "AlfaDocs — home"), x = f ?? h("publicHeader.primaryNavLabel", "Primary"), V = u ?? (i ? h("publicHeader.closeMenu", "Close menu") : h("publicHeader.openMenu", "Open menu"));
121
126
  return /* @__PURE__ */ g(
@@ -123,11 +128,11 @@ const I = P(
123
128
  {
124
129
  ...v,
125
130
  "data-component": "public-header",
126
- "data-component-id": p,
131
+ "data-component-id": m,
127
132
  "data-stuck": z ? "true" : void 0,
128
133
  "data-hidden": A ? "true" : void 0,
129
134
  "data-state": y ? "reduced-motion" : void 0,
130
- className: X({ variant: m, sticky: o, className: t }),
135
+ className: X({ variant: p, sticky: o, className: t }),
131
136
  children: [
132
137
  /* @__PURE__ */ s(
133
138
  "a",
@@ -234,4 +239,4 @@ export {
234
239
  de as P,
235
240
  ae as p
236
241
  };
237
- //# sourceMappingURL=public-header.agent-AzJSINlU.js.map
242
+ //# sourceMappingURL=public-header.agent-ZLBAQ30j.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-header.agent-ZLBAQ30j.js","sources":["../../src/components/public-header/public-header.tsx","../../src/components/public-header/public-header.agent.ts"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* PublicHeader — anonymous / pre-auth site header. */\n/* */\n/* Distinct from the kit's `<Header>` (authenticated app shell): this */\n/* one is for booking-website, signature-website, marketing surfaces — */\n/* anywhere the chrome should read as continuous with `alfadocs.com`, */\n/* not as the logged-in app. */\n/* */\n/* DOM: */\n/* <header role=banner data-component=public-header data-stuck=…> */\n/* <a aria-label=homeLabel>{logo}</a> */\n/* <nav aria-label=primaryNav>{navSlot}</nav> ≥ md only */\n/* <div class=actions>{actionsSlot}</div> ≥ md only */\n/* <IconButton menu trigger /> ↔ Sheet (partial drawer) < md only */\n/* </header> */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Menu, X } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { IconButton } from '../button/icon-button';\nimport { Sheet } from '../sheet';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface PublicHeaderHandle {\n openMenu: () => void;\n closeMenu: () => void;\n getMenuOpen: () => boolean;\n}\n\nexport interface PublicHeaderProps\n extends\n Omit<ComponentPropsWithoutRef<'header'>, 'children'>,\n VariantProps<typeof rootVariants> {\n /** Logo lockup, typically `<Logo variant=\"wordmark\" tone=\"primary\" size=\"md\" />`. */\n logo: ReactNode;\n /** Optional href for the logo link. Defaults to `/`. */\n homeHref?: string;\n /** Accessible label for the logo link (falls back to `t('publicHeader.homeLabel')`). */\n homeLabel?: string;\n /** Primary nav links rendered inline ≥ md, collapsed into the mobile sheet below md. */\n navSlot?: ReactNode;\n /** Right-side actions (sign-in / register / role-switch CTAs). */\n actionsSlot?: ReactNode;\n /** Sticky behaviour. Default `none`. */\n sticky?: 'none' | 'top' | 'scroll-up';\n /** Pixel offset above which `sticky=\"scroll-up\"` engages and `transparent` fades to default. */\n stickyOffset?: number;\n /** Override the mobile menu trigger's accessible label (`t('publicHeader.openMenu')`). */\n menuLabel?: string;\n /** Override the navigation landmark label (`t('publicHeader.primaryNavLabel')`). */\n navLabel?: string;\n /** Consumer-supplied instance id, surfaced as `data-component-id`. */\n id?: string;\n}\n\nexport interface PublicHeaderNavLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n 'children'\n> {\n href: string;\n active?: boolean;\n children: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-md)]',\n 'ds:w-full ds:z-[var(--z-sticky)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:sm:ps-[var(--spacing-lg)] ds:sm:pe-[var(--spacing-lg)]',\n 'ds:h-14 ds:md:h-16',\n 'ds:transition-[background-color,box-shadow,transform] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n variant: {\n default:\n 'ds:bg-[var(--card)] ds:text-[var(--foreground)] ds:border-b ds:border-[color:var(--border)]',\n // Transparent fades to default once data-stuck=\"true\" (set by the\n // rAF scroll listener). The fade is handled via the same\n // background utility so `data-stuck` swaps cleanly between states.\n transparent: [\n 'ds:bg-transparent ds:text-[var(--foreground)]',\n 'ds:data-[stuck=true]:bg-[var(--card)]',\n 'ds:data-[stuck=true]:shadow-[var(--shadow-md)]',\n 'ds:forced-colors:border-b ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n // `dark` flips its own scope into the dark token set so nav\n // links + buttons inside read off-white text on the blue-800\n // surface. Without the `theme-dark` scope the children inherit\n // the light-theme `--foreground` (blue-500) and fail\n // color-contrast at ~1.3:1.\n dark: 'theme-dark ds:bg-[var(--color-blue-800)] ds:text-[var(--foreground)]',\n },\n sticky: {\n none: '',\n top: 'ds:sticky ds:top-0',\n // `scroll-up` is sticky but translates off-screen when scrolling\n // down past `stickyOffset` (handled by data-hidden=\"true\") and\n // slides back in when scrolling up.\n 'scroll-up': [\n 'ds:sticky ds:top-0',\n 'ds:data-[hidden=true]:-translate-y-full',\n ].join(' '),\n },\n },\n defaultVariants: { variant: 'default', sticky: 'none' },\n },\n);\n\nconst navLinkVariants = cva(\n [\n 'ds:inline-flex ds:items-center',\n 'ds:type-body-sm ds:font-medium',\n 'ds:text-[var(--foreground)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)] ds:py-[var(--spacing-2xs)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:hover:text-[var(--primary)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:data-[active=true]:text-[var(--primary)]',\n 'ds:data-[active=true]:[box-shadow:inset_0_-2px_0_var(--primary)]',\n ].join(' '),\n);\n\n/* ------------------------------------------------------------------ */\n/* Reduced motion */\n/* ------------------------------------------------------------------ */\n\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return false;\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n });\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return;\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)');\n const onChange = (): void => setReduced(mq.matches);\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n return reduced;\n}\n\n/* ------------------------------------------------------------------ */\n/* Scroll listener */\n/* */\n/* rAF-throttled tracker for two flags on the header root: */\n/* - `data-stuck`: scrollY > stickyOffset (drives the transparent → */\n/* solid fade + the scroll-up shadow lift). */\n/* - `data-hidden`: scrolling DOWN past stickyOffset hides the header */\n/* via transform; scrolling UP slides it back. Only emitted when */\n/* `sticky === 'scroll-up'`. */\n/* ------------------------------------------------------------------ */\n\nfunction useHeaderScrollState(\n enabled: boolean,\n sticky: NonNullable<PublicHeaderProps['sticky']>,\n stickyOffset: number,\n): {\n stuck: boolean;\n hidden: boolean;\n} {\n const [stuck, setStuck] = useState(false);\n const [hidden, setHidden] = useState(false);\n const lastYRef = useRef(0);\n const tickingRef = useRef(false);\n\n useEffect(() => {\n if (!enabled || typeof window === 'undefined') return;\n lastYRef.current = window.scrollY;\n\n const update = (): void => {\n const y = window.scrollY;\n setStuck(y > stickyOffset);\n if (sticky === 'scroll-up') {\n const delta = y - lastYRef.current;\n // Hide on a meaningful downward delta past the offset; show on\n // any upward delta. 4px deadband keeps minor wheel inertia from\n // flapping the bar.\n if (delta > 4 && y > stickyOffset) setHidden(true);\n else if (delta < -4 || y <= stickyOffset) setHidden(false);\n }\n lastYRef.current = y;\n tickingRef.current = false;\n };\n const onScroll = (): void => {\n if (tickingRef.current) return;\n tickingRef.current = true;\n window.requestAnimationFrame(update);\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n // Initial sync so we don't miss state when mounted past the offset.\n update();\n return () => {\n window.removeEventListener('scroll', onScroll);\n };\n }, [enabled, sticky, stickyOffset]);\n\n return { stuck, hidden };\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderRoot = forwardRef<HTMLElement, PublicHeaderProps>(\n (\n {\n logo,\n homeHref = '/',\n homeLabel,\n navSlot,\n actionsSlot,\n variant = 'default',\n sticky = 'none',\n stickyOffset = 80,\n menuLabel,\n navLabel,\n id,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const reduced = usePrefersReducedMotion();\n const autoId = useId();\n const sheetId = `${id ?? autoId}-sheet`;\n const [menuOpen, setMenuOpen] = useState(false);\n\n // Scroll listener is only active when `transparent` or `scroll-up`\n // need it. Hidden state is disabled under reduced motion (the bar\n // stays visible — translating off-screen is precisely the motion\n // class of user the preference targets).\n const scrollEnabled = variant === 'transparent' || sticky === 'scroll-up';\n const { stuck, hidden } = useHeaderScrollState(\n scrollEnabled,\n sticky,\n stickyOffset,\n );\n const effectiveHidden = reduced ? false : hidden;\n\n const openMenu = useCallback((): void => setMenuOpen(true), []);\n const closeMenu = useCallback((): void => setMenuOpen(false), []);\n\n useImperativeHandle(\n ref as React.Ref<PublicHeaderHandle> | null | undefined,\n () => ({\n openMenu,\n closeMenu,\n getMenuOpen: () => menuOpen,\n }),\n [openMenu, closeMenu, menuOpen],\n );\n\n const resolvedHomeLabel =\n homeLabel ?? t('publicHeader.homeLabel', 'AlfaDocs — home');\n const resolvedNavLabel =\n navLabel ?? t('publicHeader.primaryNavLabel', 'Primary');\n const resolvedMenuLabel =\n menuLabel ??\n (menuOpen\n ? t('publicHeader.closeMenu', 'Close menu')\n : t('publicHeader.openMenu', 'Open menu'));\n\n return (\n <header\n {...rest}\n data-component=\"public-header\"\n data-component-id={id}\n data-stuck={stuck ? 'true' : undefined}\n data-hidden={effectiveHidden ? 'true' : undefined}\n data-state={reduced ? 'reduced-motion' : undefined}\n className={rootVariants({ variant, sticky, className })}\n >\n <a\n href={homeHref}\n aria-label={resolvedHomeLabel}\n className=\"ds:inline-flex ds:items-center ds:rounded-[var(--radius-sm)] ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]\"\n >\n {logo}\n </a>\n\n {navSlot ? (\n <nav\n aria-label={resolvedNavLabel}\n className=\"ds:hidden ds:md:flex ds:items-center ds:gap-[var(--spacing-md)] ds:ms-[var(--spacing-lg)]\"\n >\n {navSlot}\n </nav>\n ) : null}\n\n {actionsSlot ? (\n <div className=\"ds:hidden ds:md:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:ms-auto\">\n {actionsSlot}\n </div>\n ) : null}\n\n {/* Mobile menu trigger (< md). Wired to a Sheet (partial drawer\n from inline-end) so navSlot + actionsSlot collapse there. */}\n <Sheet open={menuOpen} onOpenChange={setMenuOpen}>\n <Sheet.Trigger asChild>\n <IconButton\n size=\"md\"\n intent=\"ghost\"\n className=\"ds:ms-auto ds:md:hidden\"\n icon={\n menuOpen ? (\n <X aria-hidden=\"true\" />\n ) : (\n <Menu aria-hidden=\"true\" />\n )\n }\n aria-controls={sheetId}\n aria-expanded={menuOpen}\n aria-label={resolvedMenuLabel}\n />\n </Sheet.Trigger>\n <Sheet.Content side=\"end\" size=\"md\" id={sheetId}>\n <Sheet.Header>\n <Sheet.Title>{resolvedNavLabel}</Sheet.Title>\n </Sheet.Header>\n <Sheet.Body>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {navSlot ? (\n <nav\n aria-label={resolvedNavLabel}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n {navSlot}\n </nav>\n ) : null}\n {actionsSlot ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:mt-[var(--spacing-md)]\">\n {actionsSlot}\n </div>\n ) : null}\n </div>\n </Sheet.Body>\n </Sheet.Content>\n </Sheet>\n </header>\n );\n },\n);\nPublicHeaderRoot.displayName = 'PublicHeader';\n\n/* ------------------------------------------------------------------ */\n/* NavLink */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderNavLink = forwardRef<\n HTMLAnchorElement,\n PublicHeaderNavLinkProps\n>(({ active, className, children, ...rest }, ref) => (\n <a\n ref={ref}\n {...rest}\n data-active={active ? 'true' : undefined}\n aria-current={active ? 'page' : undefined}\n className={[navLinkVariants(), className].filter(Boolean).join(' ')}\n >\n {children}\n </a>\n));\nPublicHeaderNavLink.displayName = 'PublicHeader.NavLink';\n\n/* ------------------------------------------------------------------ */\n/* Public surface */\n/* ------------------------------------------------------------------ */\n\nexport const PublicHeader = Object.assign(PublicHeaderRoot, {\n NavLink: PublicHeaderNavLink,\n});\n","import type { AgentAdapter } from '../../agent/types';\nimport type { PublicHeaderHandle } from './public-header';\n\nexport const publicHeaderAgent: AgentAdapter<PublicHeaderHandle> = {\n id: 'public-header',\n capabilities: ['open', 'close'],\n state: {\n menuOpen: {\n type: 'boolean',\n description: 'Whether the mobile drawer is currently open.',\n read: (handle) => handle.getMenuOpen(),\n },\n },\n actions: {\n open_menu: {\n safety: 'read',\n description: 'Open the mobile drawer.',\n invoke: (handle) => {\n handle.openMenu();\n },\n },\n close_menu: {\n safety: 'read',\n description: 'Close the mobile drawer.',\n invoke: (handle) => {\n handle.closeMenu();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'public-header' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on PublicHeader.',\n },\n },\n};\n"],"names":["rootVariants","cva","navLinkVariants","usePrefersReducedMotion","reduced","setReduced","useState","useEffect","mq","onChange","useHeaderScrollState","enabled","sticky","stickyOffset","stuck","setStuck","hidden","setHidden","lastYRef","useRef","tickingRef","update","y","delta","onScroll","PublicHeaderRoot","forwardRef","logo","homeHref","homeLabel","navSlot","actionsSlot","variant","menuLabel","navLabel","id","className","rest","ref","t","useTranslation","autoId","useId","sheetId","menuOpen","setMenuOpen","scrollEnabled","effectiveHidden","openMenu","useCallback","closeMenu","useImperativeHandle","resolvedHomeLabel","resolvedNavLabel","resolvedMenuLabel","jsxs","jsx","Sheet","IconButton","X","Menu","PublicHeaderNavLink","active","children","PublicHeader","publicHeaderAgent","handle"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { jsxs as z, jsx as i } from "react/jsx-runtime";
2
2
  import { forwardRef as Q, useId as X, useCallback as L, useRef as Z, useMemo as tt } from "react";
3
- import { c as S } from "./index-D2ZczOXr.js";
3
+ import { c as V } from "./index-D2ZczOXr.js";
4
4
  import { useTranslation as U } from "react-i18next";
5
5
  import { u as et } from "./use-count-up-BLLetaZ8.js";
6
- const O = S("ds:flex ds:flex-col", {
6
+ const O = V("ds:flex ds:flex-col", {
7
7
  variants: {
8
8
  variant: {
9
9
  default: "ds:gap-[var(--spacing-xs)]",
@@ -48,7 +48,7 @@ const O = S("ds:flex ds:flex-col", {
48
48
  size: "md",
49
49
  align: "start"
50
50
  }
51
- }), P = S("type-metric ds:text-[var(--foreground)]", {
51
+ }), P = V("type-metric ds:text-[var(--foreground)]", {
52
52
  variants: {
53
53
  size: {
54
54
  sm: "ds:[--type-metric-size:var(--font-size-xl)]",
@@ -83,7 +83,7 @@ const O = S("ds:flex ds:flex-col", {
83
83
  size: "md",
84
84
  variant: "default"
85
85
  }
86
- }), st = S(
86
+ }), st = V(
87
87
  "ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-label",
88
88
  {
89
89
  variants: {
@@ -127,21 +127,21 @@ function it(d, t) {
127
127
  l && (o = l[0], e = e.slice(0, -1).trimEnd());
128
128
  let m = "", u = ".";
129
129
  try {
130
- const h = new Intl.NumberFormat(t).formatToParts(12345.6);
131
- for (const n of h)
130
+ const b = new Intl.NumberFormat(t).formatToParts(12345.6);
131
+ for (const n of b)
132
132
  n.type === "group" ? m = n.value : n.type === "decimal" && (u = n.value);
133
133
  } catch {
134
134
  }
135
- const v = e.match(/^(\d+)\.(\d+)$/);
136
- if (v && !(v[2].length === 3 && m === ".")) {
135
+ const g = e.match(/^(\d+)\.(\d+)$/);
136
+ if (g && !(g[2].length === 3 && m === ".")) {
137
137
  const n = Number.parseFloat(e);
138
138
  if (Number.isFinite(n))
139
139
  return { target: n, sign: a, suffix: o };
140
140
  }
141
141
  let s = e;
142
142
  m !== "" && (s = s.split(m).join("")), u !== "." && (s = s.split(u).join(".")), s = s.replace(/[\s\u00A0\u202F]/g, "");
143
- const b = Number.parseFloat(s);
144
- return Number.isFinite(b) ? { target: b, sign: a, suffix: o } : null;
143
+ const v = Number.parseFloat(s);
144
+ return Number.isFinite(v) ? { target: v, sign: a, suffix: o } : null;
145
145
  }
146
146
  const dt = Q(
147
147
  ({
@@ -154,12 +154,12 @@ const dt = Q(
154
154
  delta: l,
155
155
  deltaFormat: m = "decimal",
156
156
  icon: u,
157
- loading: v = !1,
157
+ loading: g = !1,
158
158
  animate: s = !1,
159
- animateOnEveryView: b = !1,
160
- animateDurationMs: h = 1600,
159
+ animateOnEveryView: v = !1,
160
+ animateDurationMs: b = 1600,
161
161
  animateLocale: n,
162
- animateSeparators: p,
162
+ animateSeparators: h,
163
163
  variant: x = "default",
164
164
  size: y = "md",
165
165
  align: I = "start",
@@ -191,46 +191,45 @@ const dt = Q(
191
191
  (w) => {
192
192
  const C = (() => {
193
193
  try {
194
- return new Intl.NumberFormat(
195
- N,
196
- p ? { useGrouping: !0 } : void 0
197
- );
194
+ return new Intl.NumberFormat(N, {
195
+ useGrouping: !0
196
+ });
198
197
  } catch {
199
198
  return null;
200
199
  }
201
200
  })();
202
- let g;
201
+ let p;
203
202
  if (C)
204
- if (p) {
205
- const W = Math.abs(w), A = Math.trunc(W), D = W - A, H = p.thousand ?? "", V = String(A).replace(
203
+ if (h) {
204
+ const W = Math.abs(w), A = Math.trunc(W), D = W - A, H = h.thousand ?? "", S = String(A).replace(
206
205
  /\B(?=(\d{3})+(?!\d))/g,
207
206
  H
208
207
  );
209
208
  if (D === 0)
210
- g = V;
209
+ p = S;
211
210
  else {
212
- const G = D.toFixed(6).replace(/0+$/, "").slice(2), J = p.decimal ?? ".";
213
- g = G ? V + J + G : V;
211
+ const G = D.toFixed(6).replace(/0+$/, "").slice(2), J = h.decimal ?? ".";
212
+ p = G ? S + J + G : S;
214
213
  }
215
214
  } else
216
- g = C.format(Math.abs(w));
215
+ p = C.format(Math.abs(w));
217
216
  else
218
- g = String(Math.abs(w));
217
+ p = String(Math.abs(w));
219
218
  let E = F;
220
- return F === "" && w < 0 && (E = "-"), `${E}${g}${T}`;
219
+ return F === "" && w < 0 && (E = "-"), `${E}${p}${T}`;
221
220
  },
222
- [N, p, F, T]
221
+ [N, h, F, T]
223
222
  ), $ = et({
224
223
  to: _,
225
224
  from: 0,
226
- durationMs: h,
225
+ durationMs: b,
227
226
  startOnVisible: !0,
228
- retriggerOnReEntry: b,
227
+ retriggerOnReEntry: v,
229
228
  // `formatter` is the only path we use — it owns both the locale
230
229
  // formatting and the sign/suffix re-application.
231
230
  formatter: q
232
231
  });
233
- return v ? /* @__PURE__ */ z(
232
+ return g ? /* @__PURE__ */ z(
234
233
  "div",
235
234
  {
236
235
  ref: k,
@@ -315,4 +314,4 @@ dt.displayName = "Stat";
315
314
  export {
316
315
  dt as S
317
316
  };
318
- //# sourceMappingURL=stat-DEkZx0Mx.js.map
317
+ //# sourceMappingURL=stat-CYEx8sIR.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stat-DEkZx0Mx.js","sources":["../../src/components/stat/stat.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useId,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { useCountUp } from '../../hooks/use-count-up';\n\n/* ------------------------------------------------------------------ */\n/* CVA — stat root */\n/* ------------------------------------------------------------------ */\n\nconst statVariants = cva('ds:flex ds:flex-col', {\n variants: {\n variant: {\n default: 'ds:gap-[var(--spacing-xs)]',\n outlined: [\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n ].join(' '),\n // White card surface with the shared card shadow — matches\n // `Card variant=\"elevated\"` tokens (`--card` + `--shadow-card`) so\n // a grid of elevated Stats reads as a set of shaded panels without\n // nesting a Card around each one.\n elevated: [\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:bg-[var(--card)]',\n 'ds:text-[var(--card-foreground)]',\n 'ds:shadow-[var(--shadow-card)]',\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n // Forced-colors: UA strips shadow, so render a border as the\n // separation cue — mirrors Card's forced-colors behaviour.\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n compact: 'ds:gap-[var(--spacing-none)]',\n },\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n align: {\n start: 'ds:items-start ds:text-start',\n center: 'ds:items-center ds:text-center',\n end: 'ds:items-end ds:text-end',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n align: 'start',\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — value element */\n/* ------------------------------------------------------------------ */\n\nconst valueVariants = cva('type-metric ds:text-[var(--foreground)]', {\n variants: {\n size: {\n sm: 'ds:[--type-metric-size:var(--font-size-xl)]',\n md: 'ds:[--type-metric-size:var(--font-size-3xl)]',\n lg: 'ds:[--type-metric-size:var(--font-size-5xl)]',\n },\n variant: {\n default: '',\n outlined: '',\n elevated: '',\n compact: '',\n },\n },\n compoundVariants: [\n {\n variant: 'compact',\n size: 'sm',\n className: 'ds:[--type-metric-size:var(--font-size-lg)]',\n },\n {\n variant: 'compact',\n size: 'md',\n className: 'ds:[--type-metric-size:var(--font-size-xl)]',\n },\n {\n variant: 'compact',\n size: 'lg',\n className: 'ds:[--type-metric-size:var(--font-size-2xl)]',\n },\n ],\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — trend element */\n/* ------------------------------------------------------------------ */\n\nconst trendVariants = cva(\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-label',\n {\n variants: {\n trend: {\n up: 'ds:text-[var(--success)]',\n down: 'ds:text-[var(--destructive)]',\n flat: 'ds:text-[var(--muted-foreground)]',\n },\n },\n defaultVariants: {\n trend: 'flat',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* StatTrend (internal — not exported) */\n/* ------------------------------------------------------------------ */\n\ninterface StatTrendProps {\n trend: 'up' | 'down' | 'flat';\n delta: number | string;\n deltaFormat?: 'decimal' | 'percent';\n locale?: string;\n}\n\nconst ARROW = { up: '↑', down: '↓', flat: '→' } as const;\nconst TREND_KEY = {\n up: 'stat.trend.up',\n down: 'stat.trend.down',\n flat: 'stat.trend.flat',\n} as const;\n\nfunction StatTrend({\n trend,\n delta,\n deltaFormat = 'decimal',\n locale,\n}: StatTrendProps) {\n const { t, i18n } = useTranslation();\n\n const formattedDelta =\n typeof delta === 'string'\n ? delta\n : new Intl.NumberFormat(locale ?? i18n.language, {\n style: deltaFormat === 'percent' ? 'percent' : 'decimal',\n }).format(deltaFormat === 'percent' ? delta / 100 : delta);\n\n return (\n <span className={trendVariants({ trend })}>\n <span aria-hidden=\"true\">{ARROW[trend]}</span>\n <span className=\"ds:sr-only\">{t(TREND_KEY[trend])}</span>\n {formattedDelta}\n </span>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Parse a string value into a numeric target for the count-up */\n/* ------------------------------------------------------------------ */\n\ntype ParsedValue = {\n /** Numeric target for the count-up. */\n target: number;\n /** Leading sign captured from the input string (e.g. \"+\" / \"-\"). */\n sign: '' | '+' | '-';\n /** Trailing shorthand suffix (e.g. \"K\" / \"M\" / \"B\") to re-append. */\n suffix: string;\n};\n\n/**\n * Strip locale-aware separators, a leading sign, and the K/M/B\n * shorthand suffix from a pre-formatted string so the count-up has a\n * pure numeric target to animate towards. Returns `null` for any input\n * that can't be parsed — the caller short-circuits to static rendering\n * in that case.\n */\nfunction parseStatValue(raw: string, locale: string): ParsedValue | null {\n const trimmed = raw.trim();\n if (trimmed === '') return null;\n\n // Capture leading sign so we can re-attach it every frame. Stat's\n // marketing usage (\"+500.000\", \"-12\") often relies on it.\n let sign: '' | '+' | '-' = '';\n let body = trimmed;\n if (body.startsWith('+')) {\n sign = '+';\n body = body.slice(1).trimStart();\n } else if (body.startsWith('-') || body.startsWith('−')) {\n // Hyphen-minus or the typographic minus sign — both treated as -.\n sign = '-';\n body = body.slice(1).trimStart();\n }\n\n // Trailing K / M / B shorthand (case-insensitive). Re-append verbatim\n // so \"+1.5K\" renders as \"+1.5K\" at every frame.\n let suffix = '';\n const suffixMatch = body.match(/[KMB]$/i);\n if (suffixMatch) {\n suffix = suffixMatch[0];\n body = body.slice(0, -1).trimEnd();\n }\n\n // Discover the locale's group + decimal glyphs from a probe value.\n // formatToParts is the canonical way; we fall back to `.` decimal /\n // `,` group if Intl can't tell us (no-locale envs).\n let group = '';\n let decimal = '.';\n try {\n const probe = new Intl.NumberFormat(locale).formatToParts(12345.6);\n for (const part of probe) {\n if (part.type === 'group') group = part.value;\n else if (part.type === 'decimal') decimal = part.value;\n }\n } catch {\n /* swallow — defaults already set */\n }\n\n // Heuristic for input strings that look like JS-native decimals\n // (e.g. `\"1500.25\"`) regardless of the requested locale: if the body\n // is a clean US-style decimal AND the fraction after the `.` is NOT\n // a three-digit thousands group in a locale that uses `.` as the\n // group separator, treat it as a direct numeric literal. This covers\n // the common case where a caller types `value=\"1500.25\"` and expects\n // the count-up to land on 1500.25 even though the output locale is\n // it-IT (which uses `.` for thousands).\n const usStyleMatch = body.match(/^(\\d+)\\.(\\d+)$/);\n if (usStyleMatch) {\n const fractionLen = usStyleMatch[2].length;\n if (!(fractionLen === 3 && group === '.')) {\n const direct = Number.parseFloat(body);\n if (Number.isFinite(direct)) {\n return { target: direct, sign, suffix };\n }\n }\n }\n\n // Strip every group separator we discovered, then normalise the\n // decimal separator to `.` so JS can parseFloat the result.\n // Note: when the locale's group separator is empty (e.g. some\n // numbering systems) the replace is a no-op.\n let normalised = body;\n if (group !== '') {\n normalised = normalised.split(group).join('');\n }\n if (decimal !== '.') {\n normalised = normalised.split(decimal).join('.');\n }\n\n // Defence-in-depth: strip whitespace plus NBSP (U+00A0) and NARROW\n // NO-BREAK SPACE (U+202F) that some locales (fr-FR, it-IT) use as\n // thousand separators. Hex escapes keep this source ASCII-clean.\n normalised = normalised.replace(/[\\s\\u00A0\\u202F]/g, '');\n\n const numeric = Number.parseFloat(normalised);\n if (!Number.isFinite(numeric)) return null;\n\n return { target: numeric, sign, suffix };\n}\n\n/* ------------------------------------------------------------------ */\n/* StatProps */\n/* ------------------------------------------------------------------ */\n\nexport interface StatProps\n extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof statVariants> {\n /** Metric label rendered above the value. */\n label: string;\n /** Numeric or pre-formatted string value. */\n value: number | string;\n /** Number formatting style. Omit to use default decimal formatting. */\n format?: 'decimal' | 'currency' | 'percent';\n /** ISO 4217 currency code — required when format=\"currency\". */\n currency?: string;\n /** BCP 47 locale override. Defaults to the active i18n language. */\n locale?: string;\n /** Trend direction. Requires `delta` to render the trend row. */\n trend?: 'up' | 'down' | 'flat';\n /** Trend delta magnitude, e.g. 12 for \"↑ 12%\". */\n delta?: number | string;\n /** Number formatting style for the delta. Default \"decimal\". */\n deltaFormat?: 'decimal' | 'percent';\n /** Optional leading icon rendered at the start of the label row. */\n icon?: ReactNode;\n /** Renders animated skeleton placeholders instead of content. */\n loading?: boolean;\n /**\n * Animate the numeric value from 0 (or from the captured leading\n * sign) to the final value when the Stat first scrolls into view.\n * Default `false`. Marketing surfaces opt in; dashboards leave it\n * off so live metrics render immediately.\n */\n animate?: boolean;\n /**\n * When `true`, the count-up re-plays every time the Stat scrolls\n * out of view and back in. Default `false` — animate once per\n * element per session, matching the booking-website hero pattern.\n * Ignored under `prefers-reduced-motion: reduce`.\n */\n animateOnEveryView?: boolean;\n /** Animation duration in milliseconds. Default 1600. */\n animateDurationMs?: number;\n /**\n * BCP 47 locale used for the per-frame count-up formatting. Falls\n * back to `locale`, then to the active i18n language.\n */\n animateLocale?: string;\n /**\n * Override the locale's thousand / decimal glyphs for the count-up.\n * Wins over locale defaults. Pass partial overrides — `decimal`\n * alone is valid; the unspecified separator stays at the locale\n * default.\n */\n animateSeparators?: {\n thousand?: string;\n decimal?: string;\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Stat */\n/* ------------------------------------------------------------------ */\n\nexport const Stat = forwardRef<HTMLDivElement, StatProps>(\n (\n {\n label,\n value,\n format,\n currency,\n locale,\n trend,\n delta,\n deltaFormat = 'decimal',\n icon,\n loading = false,\n animate = false,\n animateOnEveryView = false,\n animateDurationMs = 1600,\n animateLocale,\n animateSeparators,\n variant = 'default',\n size = 'md',\n align = 'start',\n className,\n ...props\n },\n ref,\n ) => {\n const { i18n } = useTranslation();\n const labelId = useId();\n const lang = locale ?? i18n.language;\n\n /* -------------------------------------------------- */\n /* Static formatting — the value as it would appear */\n /* in the non-animated (or post-animation) state. */\n /* -------------------------------------------------- */\n\n const formatValue = useCallback((): string => {\n if (typeof value === 'string') return value;\n\n switch (format) {\n case 'currency':\n return new Intl.NumberFormat(lang, {\n style: 'currency',\n currency: currency ?? 'USD',\n }).format(value);\n case 'percent':\n return new Intl.NumberFormat(lang, { style: 'percent' }).format(\n value,\n );\n case 'decimal':\n return new Intl.NumberFormat(lang, { style: 'decimal' }).format(\n value,\n );\n default:\n return new Intl.NumberFormat(lang).format(value);\n }\n }, [value, format, lang, currency]);\n\n const staticValue = formatValue();\n\n /* -------------------------------------------------- */\n /* Parse the value into a numeric target for the */\n /* count-up. Numeric values use `value` directly; */\n /* string values are stripped of sign / shorthand / */\n /* locale separators and re-decorated each frame. */\n /* -------------------------------------------------- */\n\n const animationLocale = animateLocale ?? lang;\n const hasWarnedRef = useRef<boolean>(false);\n\n const parsed = useMemo<ParsedValue | null>(() => {\n if (!animate) return null;\n if (typeof value === 'number') {\n // Numeric: target is the number itself; no sign / suffix to\n // re-attach.\n return Number.isFinite(value)\n ? { target: value, sign: '', suffix: '' }\n : null;\n }\n return parseStatValue(value, animationLocale);\n }, [animate, value, animationLocale]);\n\n // Dev-mode warning when an animate-flagged Stat has an unparseable\n // string value. Render static, no throw — one warn per component.\n if (\n animate &&\n typeof value === 'string' &&\n parsed === null &&\n import.meta.env.DEV &&\n !hasWarnedRef.current\n ) {\n hasWarnedRef.current = true;\n console.warn(\n `Stat: value=\"${value}\" couldn't be parsed for the count-up animation. Rendering static.`,\n );\n }\n\n const shouldAnimate = animate && parsed !== null;\n\n /* -------------------------------------------------- */\n /* Wire the hook unconditionally — rules-of-hooks. */\n /* When `shouldAnimate` is false the hook still runs */\n /* but `to === from` so it's a no-op visually. */\n /* -------------------------------------------------- */\n\n const target = parsed?.target ?? 0;\n const sign = parsed?.sign ?? '';\n const suffix = parsed?.suffix ?? '';\n\n // Wrap the count-up formatter so the captured sign + suffix are\n // re-applied every frame. The hook hands us the locale-formatted\n // magnitude; we own the decoration around it.\n const formatter = useCallback(\n (n: number) => {\n // Use the absolute value for the magnitude so the captured\n // sign is the sole source of the rendered sign. Negative\n // numbers passed in (e.g. `to: -12`) come through unsigned;\n // we re-apply via `sign`. When the caller asked for explicit\n // separators, force `useGrouping: true` so the locale's default\n // `min2`/auto behaviour doesn't suppress the thousand glyph.\n const magnitudeNF = (() => {\n try {\n return new Intl.NumberFormat(\n animationLocale,\n animateSeparators ? { useGrouping: true } : undefined,\n );\n } catch {\n return null;\n }\n })();\n\n let magnitudeStr: string;\n if (magnitudeNF) {\n if (animateSeparators) {\n // Hand-build the grouped magnitude so we don't depend on\n // ICU's locale-by-locale grouping defaults (which differ\n // between engines and can drop the group at 4-digit\n // thresholds even with `useGrouping: true`). Locale only\n // influences sign handling, which we apply separately.\n const abs = Math.abs(n);\n const intPart = Math.trunc(abs);\n const fracPart = abs - intPart;\n const groupGlyph = animateSeparators.thousand ?? '';\n const intStr = String(intPart).replace(\n /\\B(?=(\\d{3})+(?!\\d))/g,\n groupGlyph,\n );\n if (fracPart === 0) {\n magnitudeStr = intStr;\n } else {\n const fracStr = fracPart.toFixed(6).replace(/0+$/, '').slice(2);\n const decimalGlyph = animateSeparators.decimal ?? '.';\n magnitudeStr = fracStr ? intStr + decimalGlyph + fracStr : intStr;\n }\n } else {\n magnitudeStr = magnitudeNF.format(Math.abs(n));\n }\n } else {\n magnitudeStr = String(Math.abs(n));\n }\n\n // Re-derive the sign every frame: the captured sign wins, but\n // a negative `to` with no leading sign in the source still\n // renders with a leading \"-\" so the final formatted output\n // matches locale conventions.\n let resolvedSign: string = sign;\n if (sign === '' && n < 0) resolvedSign = '-';\n\n return `${resolvedSign}${magnitudeStr}${suffix}`;\n },\n [animationLocale, animateSeparators, sign, suffix],\n );\n\n const countUp = useCountUp({\n to: target,\n from: 0,\n durationMs: animateDurationMs,\n startOnVisible: true,\n retriggerOnReEntry: animateOnEveryView,\n // `formatter` is the only path we use — it owns both the locale\n // formatting and the sign/suffix re-application.\n formatter,\n });\n\n /* -------------------------------------------------- */\n /* Loading state */\n /* -------------------------------------------------- */\n\n if (loading) {\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-busy=\"true\"\n aria-label={label}\n data-component=\"stat\"\n className={statVariants({ variant, size, align, className })}\n {...props}\n >\n <div className=\"ds:h-[var(--skeleton-label-h)] ds:w-[var(--skeleton-label-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]\" />\n <div className=\"ds:h-[var(--skeleton-value-h)] ds:w-[var(--skeleton-value-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]\" />\n </div>\n );\n }\n\n /* -------------------------------------------------- */\n /* Render */\n /* -------------------------------------------------- */\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-labelledby={labelId}\n data-component=\"stat\"\n className={statVariants({ variant, size, align, className })}\n {...props}\n >\n <span className=\"ds:inline-flex ds:items-center\">\n {icon && (\n <span\n aria-hidden=\"true\"\n className={[\n 'ds:me-[var(--spacing-xs)] ds:inline-flex ds:shrink-0',\n // Accent tint on the leading icon. The icon is decorative\n // (aria-hidden), so magenta-500's 3.2:1 contrast on white\n // is acceptable here — the Stat label + value still\n // carry the accessible name at `--foreground`.\n 'ds:text-[color:var(--accent)]',\n 'ds:forced-colors:text-[CanvasText]',\n ].join(' ')}\n >\n {icon}\n </span>\n )}\n <span\n id={labelId}\n className=\"type-label ds:text-[var(--muted-foreground)]\"\n >\n {label}\n </span>\n </span>\n {shouldAnimate ? (\n // The animated number is wrapped in an `aria-live=\"off\"` span\n // so screen readers don't announce every interpolated frame.\n // The `role=\"group\"` ancestor (with `aria-labelledby` pointing\n // at the label) carries the final accessible reading — the\n // animated frames are decorative only.\n <span\n ref={countUp.ref}\n aria-live=\"off\"\n className={valueVariants({ size, variant })}\n >\n {countUp.value}\n </span>\n ) : (\n <span className={valueVariants({ size, variant })}>\n {staticValue}\n </span>\n )}\n {trend != null && delta != null && (\n <StatTrend\n trend={trend}\n delta={delta}\n deltaFormat={deltaFormat}\n locale={locale}\n />\n )}\n </div>\n );\n },\n);\n\nStat.displayName = 'Stat';\n"],"names":["statVariants","cva","valueVariants","trendVariants","ARROW","TREND_KEY","StatTrend","trend","delta","deltaFormat","locale","t","i18n","useTranslation","formattedDelta","jsx","parseStatValue","raw","trimmed","sign","body","suffix","suffixMatch","group","decimal","probe","part","usStyleMatch","direct","normalised","numeric","Stat","forwardRef","label","value","format","currency","icon","loading","animate","animateOnEveryView","animateDurationMs","animateLocale","animateSeparators","variant","size","align","className","props","ref","labelId","useId","lang","staticValue","useCallback","animationLocale","useRef","parsed","useMemo","shouldAnimate","target","formatter","n","magnitudeNF","magnitudeStr","abs","intPart","fracPart","groupGlyph","intStr","fracStr","decimalGlyph","resolvedSign","countUp","useCountUp","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"stat-CYEx8sIR.js","sources":["../../src/components/stat/stat.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useId,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { useCountUp } from '../../hooks/use-count-up';\n\n/* ------------------------------------------------------------------ */\n/* CVA — stat root */\n/* ------------------------------------------------------------------ */\n\nconst statVariants = cva('ds:flex ds:flex-col', {\n variants: {\n variant: {\n default: 'ds:gap-[var(--spacing-xs)]',\n outlined: [\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n ].join(' '),\n // White card surface with the shared card shadow — matches\n // `Card variant=\"elevated\"` tokens (`--card` + `--shadow-card`) so\n // a grid of elevated Stats reads as a set of shaded panels without\n // nesting a Card around each one.\n elevated: [\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:bg-[var(--card)]',\n 'ds:text-[var(--card-foreground)]',\n 'ds:shadow-[var(--shadow-card)]',\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n // Forced-colors: UA strips shadow, so render a border as the\n // separation cue — mirrors Card's forced-colors behaviour.\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n compact: 'ds:gap-[var(--spacing-none)]',\n },\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n align: {\n start: 'ds:items-start ds:text-start',\n center: 'ds:items-center ds:text-center',\n end: 'ds:items-end ds:text-end',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n align: 'start',\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — value element */\n/* ------------------------------------------------------------------ */\n\nconst valueVariants = cva('type-metric ds:text-[var(--foreground)]', {\n variants: {\n size: {\n sm: 'ds:[--type-metric-size:var(--font-size-xl)]',\n md: 'ds:[--type-metric-size:var(--font-size-3xl)]',\n lg: 'ds:[--type-metric-size:var(--font-size-5xl)]',\n },\n variant: {\n default: '',\n outlined: '',\n elevated: '',\n compact: '',\n },\n },\n compoundVariants: [\n {\n variant: 'compact',\n size: 'sm',\n className: 'ds:[--type-metric-size:var(--font-size-lg)]',\n },\n {\n variant: 'compact',\n size: 'md',\n className: 'ds:[--type-metric-size:var(--font-size-xl)]',\n },\n {\n variant: 'compact',\n size: 'lg',\n className: 'ds:[--type-metric-size:var(--font-size-2xl)]',\n },\n ],\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — trend element */\n/* ------------------------------------------------------------------ */\n\nconst trendVariants = cva(\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-label',\n {\n variants: {\n trend: {\n up: 'ds:text-[var(--success)]',\n down: 'ds:text-[var(--destructive)]',\n flat: 'ds:text-[var(--muted-foreground)]',\n },\n },\n defaultVariants: {\n trend: 'flat',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* StatTrend (internal — not exported) */\n/* ------------------------------------------------------------------ */\n\ninterface StatTrendProps {\n trend: 'up' | 'down' | 'flat';\n delta: number | string;\n deltaFormat?: 'decimal' | 'percent';\n locale?: string;\n}\n\nconst ARROW = { up: '↑', down: '↓', flat: '→' } as const;\nconst TREND_KEY = {\n up: 'stat.trend.up',\n down: 'stat.trend.down',\n flat: 'stat.trend.flat',\n} as const;\n\nfunction StatTrend({\n trend,\n delta,\n deltaFormat = 'decimal',\n locale,\n}: StatTrendProps) {\n const { t, i18n } = useTranslation();\n\n const formattedDelta =\n typeof delta === 'string'\n ? delta\n : new Intl.NumberFormat(locale ?? i18n.language, {\n style: deltaFormat === 'percent' ? 'percent' : 'decimal',\n }).format(deltaFormat === 'percent' ? delta / 100 : delta);\n\n return (\n <span className={trendVariants({ trend })}>\n <span aria-hidden=\"true\">{ARROW[trend]}</span>\n <span className=\"ds:sr-only\">{t(TREND_KEY[trend])}</span>\n {formattedDelta}\n </span>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Parse a string value into a numeric target for the count-up */\n/* ------------------------------------------------------------------ */\n\ntype ParsedValue = {\n /** Numeric target for the count-up. */\n target: number;\n /** Leading sign captured from the input string (e.g. \"+\" / \"-\"). */\n sign: '' | '+' | '-';\n /** Trailing shorthand suffix (e.g. \"K\" / \"M\" / \"B\") to re-append. */\n suffix: string;\n};\n\n/**\n * Strip locale-aware separators, a leading sign, and the K/M/B\n * shorthand suffix from a pre-formatted string so the count-up has a\n * pure numeric target to animate towards. Returns `null` for any input\n * that can't be parsed — the caller short-circuits to static rendering\n * in that case.\n */\nfunction parseStatValue(raw: string, locale: string): ParsedValue | null {\n const trimmed = raw.trim();\n if (trimmed === '') return null;\n\n // Capture leading sign so we can re-attach it every frame. Stat's\n // marketing usage (\"+500.000\", \"-12\") often relies on it.\n let sign: '' | '+' | '-' = '';\n let body = trimmed;\n if (body.startsWith('+')) {\n sign = '+';\n body = body.slice(1).trimStart();\n } else if (body.startsWith('-') || body.startsWith('−')) {\n // Hyphen-minus or the typographic minus sign — both treated as -.\n sign = '-';\n body = body.slice(1).trimStart();\n }\n\n // Trailing K / M / B shorthand (case-insensitive). Re-append verbatim\n // so \"+1.5K\" renders as \"+1.5K\" at every frame.\n let suffix = '';\n const suffixMatch = body.match(/[KMB]$/i);\n if (suffixMatch) {\n suffix = suffixMatch[0];\n body = body.slice(0, -1).trimEnd();\n }\n\n // Discover the locale's group + decimal glyphs from a probe value.\n // formatToParts is the canonical way; we fall back to `.` decimal /\n // `,` group if Intl can't tell us (no-locale envs).\n let group = '';\n let decimal = '.';\n try {\n const probe = new Intl.NumberFormat(locale).formatToParts(12345.6);\n for (const part of probe) {\n if (part.type === 'group') group = part.value;\n else if (part.type === 'decimal') decimal = part.value;\n }\n } catch {\n /* swallow — defaults already set */\n }\n\n // Heuristic for input strings that look like JS-native decimals\n // (e.g. `\"1500.25\"`) regardless of the requested locale: if the body\n // is a clean US-style decimal AND the fraction after the `.` is NOT\n // a three-digit thousands group in a locale that uses `.` as the\n // group separator, treat it as a direct numeric literal. This covers\n // the common case where a caller types `value=\"1500.25\"` and expects\n // the count-up to land on 1500.25 even though the output locale is\n // it-IT (which uses `.` for thousands).\n const usStyleMatch = body.match(/^(\\d+)\\.(\\d+)$/);\n if (usStyleMatch) {\n const fractionLen = usStyleMatch[2].length;\n if (!(fractionLen === 3 && group === '.')) {\n const direct = Number.parseFloat(body);\n if (Number.isFinite(direct)) {\n return { target: direct, sign, suffix };\n }\n }\n }\n\n // Strip every group separator we discovered, then normalise the\n // decimal separator to `.` so JS can parseFloat the result.\n // Note: when the locale's group separator is empty (e.g. some\n // numbering systems) the replace is a no-op.\n let normalised = body;\n if (group !== '') {\n normalised = normalised.split(group).join('');\n }\n if (decimal !== '.') {\n normalised = normalised.split(decimal).join('.');\n }\n\n // Defence-in-depth: strip whitespace plus NBSP (U+00A0) and NARROW\n // NO-BREAK SPACE (U+202F) that some locales (fr-FR, it-IT) use as\n // thousand separators. Hex escapes keep this source ASCII-clean.\n normalised = normalised.replace(/[\\s\\u00A0\\u202F]/g, '');\n\n const numeric = Number.parseFloat(normalised);\n if (!Number.isFinite(numeric)) return null;\n\n return { target: numeric, sign, suffix };\n}\n\n/* ------------------------------------------------------------------ */\n/* StatProps */\n/* ------------------------------------------------------------------ */\n\nexport interface StatProps\n extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof statVariants> {\n /** Metric label rendered above the value. */\n label: string;\n /** Numeric or pre-formatted string value. */\n value: number | string;\n /** Number formatting style. Omit to use default decimal formatting. */\n format?: 'decimal' | 'currency' | 'percent';\n /** ISO 4217 currency code — required when format=\"currency\". */\n currency?: string;\n /** BCP 47 locale override. Defaults to the active i18n language. */\n locale?: string;\n /** Trend direction. Requires `delta` to render the trend row. */\n trend?: 'up' | 'down' | 'flat';\n /** Trend delta magnitude, e.g. 12 for \"↑ 12%\". */\n delta?: number | string;\n /** Number formatting style for the delta. Default \"decimal\". */\n deltaFormat?: 'decimal' | 'percent';\n /** Optional leading icon rendered at the start of the label row. */\n icon?: ReactNode;\n /** Renders animated skeleton placeholders instead of content. */\n loading?: boolean;\n /**\n * Animate the numeric value from 0 (or from the captured leading\n * sign) to the final value when the Stat first scrolls into view.\n * Default `false`. Marketing surfaces opt in; dashboards leave it\n * off so live metrics render immediately.\n */\n animate?: boolean;\n /**\n * When `true`, the count-up re-plays every time the Stat scrolls\n * out of view and back in. Default `false` — animate once per\n * element per session, matching the booking-website hero pattern.\n * Ignored under `prefers-reduced-motion: reduce`.\n */\n animateOnEveryView?: boolean;\n /** Animation duration in milliseconds. Default 1600. */\n animateDurationMs?: number;\n /**\n * BCP 47 locale used for the per-frame count-up formatting. Falls\n * back to `locale`, then to the active i18n language.\n */\n animateLocale?: string;\n /**\n * Override the locale's thousand / decimal glyphs for the count-up.\n * Wins over locale defaults. Pass partial overrides — `decimal`\n * alone is valid; the unspecified separator stays at the locale\n * default.\n */\n animateSeparators?: {\n thousand?: string;\n decimal?: string;\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Stat */\n/* ------------------------------------------------------------------ */\n\nexport const Stat = forwardRef<HTMLDivElement, StatProps>(\n (\n {\n label,\n value,\n format,\n currency,\n locale,\n trend,\n delta,\n deltaFormat = 'decimal',\n icon,\n loading = false,\n animate = false,\n animateOnEveryView = false,\n animateDurationMs = 1600,\n animateLocale,\n animateSeparators,\n variant = 'default',\n size = 'md',\n align = 'start',\n className,\n ...props\n },\n ref,\n ) => {\n const { i18n } = useTranslation();\n const labelId = useId();\n const lang = locale ?? i18n.language;\n\n /* -------------------------------------------------- */\n /* Static formatting — the value as it would appear */\n /* in the non-animated (or post-animation) state. */\n /* -------------------------------------------------- */\n\n const formatValue = useCallback((): string => {\n if (typeof value === 'string') return value;\n\n switch (format) {\n case 'currency':\n return new Intl.NumberFormat(lang, {\n style: 'currency',\n currency: currency ?? 'USD',\n }).format(value);\n case 'percent':\n return new Intl.NumberFormat(lang, { style: 'percent' }).format(\n value,\n );\n case 'decimal':\n return new Intl.NumberFormat(lang, { style: 'decimal' }).format(\n value,\n );\n default:\n return new Intl.NumberFormat(lang).format(value);\n }\n }, [value, format, lang, currency]);\n\n const staticValue = formatValue();\n\n /* -------------------------------------------------- */\n /* Parse the value into a numeric target for the */\n /* count-up. Numeric values use `value` directly; */\n /* string values are stripped of sign / shorthand / */\n /* locale separators and re-decorated each frame. */\n /* -------------------------------------------------- */\n\n const animationLocale = animateLocale ?? lang;\n const hasWarnedRef = useRef<boolean>(false);\n\n const parsed = useMemo<ParsedValue | null>(() => {\n if (!animate) return null;\n if (typeof value === 'number') {\n // Numeric: target is the number itself; no sign / suffix to\n // re-attach.\n return Number.isFinite(value)\n ? { target: value, sign: '', suffix: '' }\n : null;\n }\n return parseStatValue(value, animationLocale);\n }, [animate, value, animationLocale]);\n\n // Dev-mode warning when an animate-flagged Stat has an unparseable\n // string value. Render static, no throw — one warn per component.\n if (\n animate &&\n typeof value === 'string' &&\n parsed === null &&\n import.meta.env.DEV &&\n !hasWarnedRef.current\n ) {\n hasWarnedRef.current = true;\n console.warn(\n `Stat: value=\"${value}\" couldn't be parsed for the count-up animation. Rendering static.`,\n );\n }\n\n const shouldAnimate = animate && parsed !== null;\n\n /* -------------------------------------------------- */\n /* Wire the hook unconditionally — rules-of-hooks. */\n /* When `shouldAnimate` is false the hook still runs */\n /* but `to === from` so it's a no-op visually. */\n /* -------------------------------------------------- */\n\n const target = parsed?.target ?? 0;\n const sign = parsed?.sign ?? '';\n const suffix = parsed?.suffix ?? '';\n\n // Wrap the count-up formatter so the captured sign + suffix are\n // re-applied every frame. The hook hands us the locale-formatted\n // magnitude; we own the decoration around it.\n const formatter = useCallback(\n (n: number) => {\n // Use the absolute value for the magnitude so the captured\n // sign is the sole source of the rendered sign. Negative\n // numbers passed in (e.g. `to: -12`) come through unsigned;\n // we re-apply via `sign`. Always force `useGrouping: true` so\n // ICU's locale-default `min2` doesn't suppress the thousand\n // glyph on 4-digit values like 1.000 (it-IT). The user wrote\n // a stat value — they want it grouped.\n const magnitudeNF = (() => {\n try {\n return new Intl.NumberFormat(animationLocale, {\n useGrouping: true,\n });\n } catch {\n return null;\n }\n })();\n\n let magnitudeStr: string;\n if (magnitudeNF) {\n if (animateSeparators) {\n // Hand-build the grouped magnitude so we don't depend on\n // ICU's locale-by-locale grouping defaults (which differ\n // between engines and can drop the group at 4-digit\n // thresholds even with `useGrouping: true`). Locale only\n // influences sign handling, which we apply separately.\n const abs = Math.abs(n);\n const intPart = Math.trunc(abs);\n const fracPart = abs - intPart;\n const groupGlyph = animateSeparators.thousand ?? '';\n const intStr = String(intPart).replace(\n /\\B(?=(\\d{3})+(?!\\d))/g,\n groupGlyph,\n );\n if (fracPart === 0) {\n magnitudeStr = intStr;\n } else {\n const fracStr = fracPart.toFixed(6).replace(/0+$/, '').slice(2);\n const decimalGlyph = animateSeparators.decimal ?? '.';\n magnitudeStr = fracStr ? intStr + decimalGlyph + fracStr : intStr;\n }\n } else {\n magnitudeStr = magnitudeNF.format(Math.abs(n));\n }\n } else {\n magnitudeStr = String(Math.abs(n));\n }\n\n // Re-derive the sign every frame: the captured sign wins, but\n // a negative `to` with no leading sign in the source still\n // renders with a leading \"-\" so the final formatted output\n // matches locale conventions.\n let resolvedSign: string = sign;\n if (sign === '' && n < 0) resolvedSign = '-';\n\n return `${resolvedSign}${magnitudeStr}${suffix}`;\n },\n [animationLocale, animateSeparators, sign, suffix],\n );\n\n const countUp = useCountUp({\n to: target,\n from: 0,\n durationMs: animateDurationMs,\n startOnVisible: true,\n retriggerOnReEntry: animateOnEveryView,\n // `formatter` is the only path we use — it owns both the locale\n // formatting and the sign/suffix re-application.\n formatter,\n });\n\n /* -------------------------------------------------- */\n /* Loading state */\n /* -------------------------------------------------- */\n\n if (loading) {\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-busy=\"true\"\n aria-label={label}\n data-component=\"stat\"\n className={statVariants({ variant, size, align, className })}\n {...props}\n >\n <div className=\"ds:h-[var(--skeleton-label-h)] ds:w-[var(--skeleton-label-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]\" />\n <div className=\"ds:h-[var(--skeleton-value-h)] ds:w-[var(--skeleton-value-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]\" />\n </div>\n );\n }\n\n /* -------------------------------------------------- */\n /* Render */\n /* -------------------------------------------------- */\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-labelledby={labelId}\n data-component=\"stat\"\n className={statVariants({ variant, size, align, className })}\n {...props}\n >\n <span className=\"ds:inline-flex ds:items-center\">\n {icon && (\n <span\n aria-hidden=\"true\"\n className={[\n 'ds:me-[var(--spacing-xs)] ds:inline-flex ds:shrink-0',\n // Accent tint on the leading icon. The icon is decorative\n // (aria-hidden), so magenta-500's 3.2:1 contrast on white\n // is acceptable here — the Stat label + value still\n // carry the accessible name at `--foreground`.\n 'ds:text-[color:var(--accent)]',\n 'ds:forced-colors:text-[CanvasText]',\n ].join(' ')}\n >\n {icon}\n </span>\n )}\n <span\n id={labelId}\n className=\"type-label ds:text-[var(--muted-foreground)]\"\n >\n {label}\n </span>\n </span>\n {shouldAnimate ? (\n // The animated number is wrapped in an `aria-live=\"off\"` span\n // so screen readers don't announce every interpolated frame.\n // The `role=\"group\"` ancestor (with `aria-labelledby` pointing\n // at the label) carries the final accessible reading — the\n // animated frames are decorative only.\n <span\n ref={countUp.ref}\n aria-live=\"off\"\n className={valueVariants({ size, variant })}\n >\n {countUp.value}\n </span>\n ) : (\n <span className={valueVariants({ size, variant })}>\n {staticValue}\n </span>\n )}\n {trend != null && delta != null && (\n <StatTrend\n trend={trend}\n delta={delta}\n deltaFormat={deltaFormat}\n locale={locale}\n />\n )}\n </div>\n );\n },\n);\n\nStat.displayName = 'Stat';\n"],"names":["statVariants","cva","valueVariants","trendVariants","ARROW","TREND_KEY","StatTrend","trend","delta","deltaFormat","locale","t","i18n","useTranslation","formattedDelta","jsx","parseStatValue","raw","trimmed","sign","body","suffix","suffixMatch","group","decimal","probe","part","usStyleMatch","direct","normalised","numeric","Stat","forwardRef","label","value","format","currency","icon","loading","animate","animateOnEveryView","animateDurationMs","animateLocale","animateSeparators","variant","size","align","className","props","ref","labelId","useId","lang","staticValue","useCallback","animationLocale","useRef","parsed","useMemo","shouldAnimate","target","formatter","n","magnitudeNF","magnitudeStr","abs","intPart","fracPart","groupGlyph","intStr","fracStr","decimalGlyph","resolvedSign","countUp","useCountUp","jsxs"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "packageVersion": "0.15.0",
3
+ "packageVersion": "0.15.1",
4
4
  "components": [
5
5
  {
6
6
  "kind": "component",
@@ -1 +1 @@
1
- {"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../../../src/components/carousel/carousel.tsx"],"names":[],"mappings":"AA0BA,OAAO,EAaL,KAAK,wBAAwB,EAE7B,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAWlE,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8CAA8C;IAC9C,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,yBAAyB;IACzB,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,kDAAkD;IAClD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,aACf,SACE,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,EACrD,YAAY,CAAC,OAAO,YAAY,CAAC;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,yEAAyE;IACzE,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IACjC,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAkB,SAAQ,wBAAwB,CAAC,KAAK,CAAC;IACxE,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,mBAAoB,SAAQ,wBAAwB,CAAC,KAAK,CAAC;IAC1E,QAAQ,EAAE,SAAS,CAAC;CACrB;AAMD,QAAA,MAAM,YAAY;;8EAYjB,CAAC;AA4kBF,eAAO,MAAM,QAAQ;;;;CAInB,CAAC"}
1
+ {"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../../../src/components/carousel/carousel.tsx"],"names":[],"mappings":"AA0BA,OAAO,EAaL,KAAK,wBAAwB,EAE7B,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAWlE,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8CAA8C;IAC9C,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,yBAAyB;IACzB,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,kDAAkD;IAClD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,aACf,SACE,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,EACrD,YAAY,CAAC,OAAO,YAAY,CAAC;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,yEAAyE;IACzE,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IACjC,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAkB,SAAQ,wBAAwB,CAAC,KAAK,CAAC;IACxE,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,mBAAoB,SAAQ,wBAAwB,CAAC,KAAK,CAAC;IAC1E,QAAQ,EAAE,SAAS,CAAC;CACrB;AAMD,QAAA,MAAM,YAAY;;8EAYjB,CAAC;AAglBF,eAAO,MAAM,QAAQ;;;;CAInB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { C as o, c as r } from "../../_chunks/carousel.agent-2dXpQoqp.js";
1
+ import { C as o, c as r } from "../../_chunks/carousel.agent-OTn-kMQg.js";
2
2
  export {
3
3
  o as Carousel,
4
4
  r as carouselAgent
@@ -1,4 +1,4 @@
1
- import { P as r, p } from "../../_chunks/public-header.agent-AzJSINlU.js";
1
+ import { P as r, p } from "../../_chunks/public-header.agent-ZLBAQ30j.js";
2
2
  export {
3
3
  r as PublicHeader,
4
4
  p as publicHeaderAgent
@@ -1 +1 @@
1
- {"version":3,"file":"public-header.d.ts","sourceRoot":"","sources":["../../../src/components/public-header/public-header.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAQL,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAUlE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,iBACf,SACE,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,EACpD,YAAY,CAAC,OAAO,YAAY,CAAC;IACnC,qFAAqF;IACrF,IAAI,EAAE,SAAS,CAAC;IAChB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wFAAwF;IACxF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,kEAAkE;IAClE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,WAAW,CAAC;IACtC,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,UAAU,CACX;IACC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAMD,QAAA,MAAM,YAAY;;;8EAuCjB,CAAC;AAyQF,eAAO,MAAM,YAAY;;CAEvB,CAAC"}
1
+ {"version":3,"file":"public-header.d.ts","sourceRoot":"","sources":["../../../src/components/public-header/public-header.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAQL,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAUlE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,iBACf,SACE,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,EACpD,YAAY,CAAC,OAAO,YAAY,CAAC;IACnC,qFAAqF;IACrF,IAAI,EAAE,SAAS,CAAC;IAChB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wFAAwF;IACxF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,kEAAkE;IAClE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,WAAW,CAAC;IACtC,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,UAAU,CACX;IACC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAMD,QAAA,MAAM,YAAY;;;8EA4CjB,CAAC;AAyQF,eAAO,MAAM,YAAY;;CAEvB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { S as o } from "../../_chunks/stat-DEkZx0Mx.js";
1
+ import { S as o } from "../../_chunks/stat-CYEx8sIR.js";
2
2
  export {
3
3
  o as Stat
4
4
  };
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ import { A as ge, a as ce, b as xe, c as ue, d as Ae } from "./_chunks/accordion
40
40
  import { A as Te, g as Ce, n as be } from "./_chunks/avatar-I10iCDs8.js";
41
41
  import { B as he } from "./_chunks/badge-cLYVGlMh.js";
42
42
  import { C as Re } from "./_chunks/card-CWzuTLYE.js";
43
- import { C as Le, c as Ee } from "./_chunks/carousel.agent-2dXpQoqp.js";
43
+ import { C as Le, c as Ee } from "./_chunks/carousel.agent-OTn-kMQg.js";
44
44
  import { C as Ne } from "./_chunks/contact-card-DTQUMetD.js";
45
45
  import { A as Be, B as ye, C as we, a as Ve, D as De, b as ve, L as He, S as Oe, T as _e, c as Ge, d as We, e as Ue, U as Ke, f as Ye, u as je } from "./_chunks/balance-cell-renderer-DWWtX-VM.js";
46
46
  import { D as qe } from "./_chunks/description-list-y7Hk51KI.js";
@@ -54,7 +54,7 @@ import { M as dr } from "./_chunks/map-view-DVP-Kp9l.js";
54
54
  import { R as cr } from "./_chunks/rating-BRD7O74e.js";
55
55
  import { S as ur } from "./_chunks/skeleton-CZbwyJAA.js";
56
56
  import { S as Sr, s as Tr, u as Cr } from "./_chunks/sparkline-B5Ms55PZ.js";
57
- import { S as Pr } from "./_chunks/stat-DEkZx0Mx.js";
57
+ import { S as Pr } from "./_chunks/stat-CYEx8sIR.js";
58
58
  import { T as Ir } from "./_chunks/tag-CQmHRM4Y.js";
59
59
  import { T as kr, t as Lr } from "./_chunks/timeline-rmls7dIh.js";
60
60
  import { T as Fr } from "./_chunks/timestamp-BV2lC-wV.js";
@@ -65,7 +65,7 @@ import { N as po, a as mo, b as lo, c as fo, d as go, e as co, f as xo, g as uo,
65
65
  import { S as To } from "./_chunks/skip-link-BaSMtPwB.js";
66
66
  import { L as bo } from "./_chunks/link-DmM5IevO.js";
67
67
  import { P as ho, a as Io, b as Ro, c as ko, d as Lo, e as Eo, f as Fo, g as No, p as Mo } from "./_chunks/pagination-OQBlnb1H.js";
68
- import { P as yo, p as wo } from "./_chunks/public-header.agent-AzJSINlU.js";
68
+ import { P as yo, p as wo } from "./_chunks/public-header.agent-ZLBAQ30j.js";
69
69
  import { S as Do, f as vo, s as Ho } from "./_chunks/search-bar-DORSAzNt.js";
70
70
  import { S as _o, a as Go, b as Wo, c as Uo, d as Ko, e as Yo, f as jo, g as zo, h as qo, i as Qo, j as Jo, k as Xo, l as Zo, m as $o, n as at, o as et, p as rt, s as ot, u as tt, q as st } from "./_chunks/sidebar-D8Lq065m.js";
71
71
  import { S as it, s as pt } from "./_chunks/stepper-accordion.agent-ckKYZCIP.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfadocs/ui-kit-debug",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "type": "module",
5
5
  "description": "AlfaDocs shared design system — tokens, components, patterns, and translations for platform, booking, and alfascribe. (debug build — identical runtime to @alfadocs/ui-kit, ships source maps for symbolication).",
6
6
  "license": "BUSL-1.1",
@@ -1 +0,0 @@
1
- {"version":3,"file":"public-header.agent-AzJSINlU.js","sources":["../../src/components/public-header/public-header.tsx","../../src/components/public-header/public-header.agent.ts"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* PublicHeader — anonymous / pre-auth site header. */\n/* */\n/* Distinct from the kit's `<Header>` (authenticated app shell): this */\n/* one is for booking-website, signature-website, marketing surfaces — */\n/* anywhere the chrome should read as continuous with `alfadocs.com`, */\n/* not as the logged-in app. */\n/* */\n/* DOM: */\n/* <header role=banner data-component=public-header data-stuck=…> */\n/* <a aria-label=homeLabel>{logo}</a> */\n/* <nav aria-label=primaryNav>{navSlot}</nav> ≥ md only */\n/* <div class=actions>{actionsSlot}</div> ≥ md only */\n/* <IconButton menu trigger /> ↔ Sheet (partial drawer) < md only */\n/* </header> */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Menu, X } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { IconButton } from '../button/icon-button';\nimport { Sheet } from '../sheet';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface PublicHeaderHandle {\n openMenu: () => void;\n closeMenu: () => void;\n getMenuOpen: () => boolean;\n}\n\nexport interface PublicHeaderProps\n extends\n Omit<ComponentPropsWithoutRef<'header'>, 'children'>,\n VariantProps<typeof rootVariants> {\n /** Logo lockup, typically `<Logo variant=\"wordmark\" tone=\"primary\" size=\"md\" />`. */\n logo: ReactNode;\n /** Optional href for the logo link. Defaults to `/`. */\n homeHref?: string;\n /** Accessible label for the logo link (falls back to `t('publicHeader.homeLabel')`). */\n homeLabel?: string;\n /** Primary nav links rendered inline ≥ md, collapsed into the mobile sheet below md. */\n navSlot?: ReactNode;\n /** Right-side actions (sign-in / register / role-switch CTAs). */\n actionsSlot?: ReactNode;\n /** Sticky behaviour. Default `none`. */\n sticky?: 'none' | 'top' | 'scroll-up';\n /** Pixel offset above which `sticky=\"scroll-up\"` engages and `transparent` fades to default. */\n stickyOffset?: number;\n /** Override the mobile menu trigger's accessible label (`t('publicHeader.openMenu')`). */\n menuLabel?: string;\n /** Override the navigation landmark label (`t('publicHeader.primaryNavLabel')`). */\n navLabel?: string;\n /** Consumer-supplied instance id, surfaced as `data-component-id`. */\n id?: string;\n}\n\nexport interface PublicHeaderNavLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n 'children'\n> {\n href: string;\n active?: boolean;\n children: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-md)]',\n 'ds:w-full ds:z-[var(--z-sticky)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:sm:ps-[var(--spacing-lg)] ds:sm:pe-[var(--spacing-lg)]',\n 'ds:h-14 ds:md:h-16',\n 'ds:transition-[background-color,box-shadow,transform] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n variant: {\n default:\n 'ds:bg-[var(--card)] ds:text-[var(--foreground)] ds:border-b ds:border-[color:var(--border)]',\n // Transparent fades to default once data-stuck=\"true\" (set by the\n // rAF scroll listener). The fade is handled via the same\n // background utility so `data-stuck` swaps cleanly between states.\n transparent: [\n 'ds:bg-transparent ds:text-[var(--foreground)]',\n 'ds:data-[stuck=true]:bg-[var(--card)]',\n 'ds:data-[stuck=true]:shadow-[var(--shadow-md)]',\n 'ds:forced-colors:border-b ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n dark: 'ds:bg-[var(--color-blue-800)] ds:text-[var(--primary-foreground)]',\n },\n sticky: {\n none: '',\n top: 'ds:sticky ds:top-0',\n // `scroll-up` is sticky but translates off-screen when scrolling\n // down past `stickyOffset` (handled by data-hidden=\"true\") and\n // slides back in when scrolling up.\n 'scroll-up': [\n 'ds:sticky ds:top-0',\n 'ds:data-[hidden=true]:-translate-y-full',\n ].join(' '),\n },\n },\n defaultVariants: { variant: 'default', sticky: 'none' },\n },\n);\n\nconst navLinkVariants = cva(\n [\n 'ds:inline-flex ds:items-center',\n 'ds:type-body-sm ds:font-medium',\n 'ds:text-[var(--foreground)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)] ds:py-[var(--spacing-2xs)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:hover:text-[var(--primary)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:data-[active=true]:text-[var(--primary)]',\n 'ds:data-[active=true]:[box-shadow:inset_0_-2px_0_var(--primary)]',\n ].join(' '),\n);\n\n/* ------------------------------------------------------------------ */\n/* Reduced motion */\n/* ------------------------------------------------------------------ */\n\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return false;\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n });\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return;\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)');\n const onChange = (): void => setReduced(mq.matches);\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n return reduced;\n}\n\n/* ------------------------------------------------------------------ */\n/* Scroll listener */\n/* */\n/* rAF-throttled tracker for two flags on the header root: */\n/* - `data-stuck`: scrollY > stickyOffset (drives the transparent → */\n/* solid fade + the scroll-up shadow lift). */\n/* - `data-hidden`: scrolling DOWN past stickyOffset hides the header */\n/* via transform; scrolling UP slides it back. Only emitted when */\n/* `sticky === 'scroll-up'`. */\n/* ------------------------------------------------------------------ */\n\nfunction useHeaderScrollState(\n enabled: boolean,\n sticky: NonNullable<PublicHeaderProps['sticky']>,\n stickyOffset: number,\n): {\n stuck: boolean;\n hidden: boolean;\n} {\n const [stuck, setStuck] = useState(false);\n const [hidden, setHidden] = useState(false);\n const lastYRef = useRef(0);\n const tickingRef = useRef(false);\n\n useEffect(() => {\n if (!enabled || typeof window === 'undefined') return;\n lastYRef.current = window.scrollY;\n\n const update = (): void => {\n const y = window.scrollY;\n setStuck(y > stickyOffset);\n if (sticky === 'scroll-up') {\n const delta = y - lastYRef.current;\n // Hide on a meaningful downward delta past the offset; show on\n // any upward delta. 4px deadband keeps minor wheel inertia from\n // flapping the bar.\n if (delta > 4 && y > stickyOffset) setHidden(true);\n else if (delta < -4 || y <= stickyOffset) setHidden(false);\n }\n lastYRef.current = y;\n tickingRef.current = false;\n };\n const onScroll = (): void => {\n if (tickingRef.current) return;\n tickingRef.current = true;\n window.requestAnimationFrame(update);\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n // Initial sync so we don't miss state when mounted past the offset.\n update();\n return () => {\n window.removeEventListener('scroll', onScroll);\n };\n }, [enabled, sticky, stickyOffset]);\n\n return { stuck, hidden };\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderRoot = forwardRef<HTMLElement, PublicHeaderProps>(\n (\n {\n logo,\n homeHref = '/',\n homeLabel,\n navSlot,\n actionsSlot,\n variant = 'default',\n sticky = 'none',\n stickyOffset = 80,\n menuLabel,\n navLabel,\n id,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const reduced = usePrefersReducedMotion();\n const autoId = useId();\n const sheetId = `${id ?? autoId}-sheet`;\n const [menuOpen, setMenuOpen] = useState(false);\n\n // Scroll listener is only active when `transparent` or `scroll-up`\n // need it. Hidden state is disabled under reduced motion (the bar\n // stays visible — translating off-screen is precisely the motion\n // class of user the preference targets).\n const scrollEnabled = variant === 'transparent' || sticky === 'scroll-up';\n const { stuck, hidden } = useHeaderScrollState(\n scrollEnabled,\n sticky,\n stickyOffset,\n );\n const effectiveHidden = reduced ? false : hidden;\n\n const openMenu = useCallback((): void => setMenuOpen(true), []);\n const closeMenu = useCallback((): void => setMenuOpen(false), []);\n\n useImperativeHandle(\n ref as React.Ref<PublicHeaderHandle> | null | undefined,\n () => ({\n openMenu,\n closeMenu,\n getMenuOpen: () => menuOpen,\n }),\n [openMenu, closeMenu, menuOpen],\n );\n\n const resolvedHomeLabel =\n homeLabel ?? t('publicHeader.homeLabel', 'AlfaDocs — home');\n const resolvedNavLabel =\n navLabel ?? t('publicHeader.primaryNavLabel', 'Primary');\n const resolvedMenuLabel =\n menuLabel ??\n (menuOpen\n ? t('publicHeader.closeMenu', 'Close menu')\n : t('publicHeader.openMenu', 'Open menu'));\n\n return (\n <header\n {...rest}\n data-component=\"public-header\"\n data-component-id={id}\n data-stuck={stuck ? 'true' : undefined}\n data-hidden={effectiveHidden ? 'true' : undefined}\n data-state={reduced ? 'reduced-motion' : undefined}\n className={rootVariants({ variant, sticky, className })}\n >\n <a\n href={homeHref}\n aria-label={resolvedHomeLabel}\n className=\"ds:inline-flex ds:items-center ds:rounded-[var(--radius-sm)] ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]\"\n >\n {logo}\n </a>\n\n {navSlot ? (\n <nav\n aria-label={resolvedNavLabel}\n className=\"ds:hidden ds:md:flex ds:items-center ds:gap-[var(--spacing-md)] ds:ms-[var(--spacing-lg)]\"\n >\n {navSlot}\n </nav>\n ) : null}\n\n {actionsSlot ? (\n <div className=\"ds:hidden ds:md:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:ms-auto\">\n {actionsSlot}\n </div>\n ) : null}\n\n {/* Mobile menu trigger (< md). Wired to a Sheet (partial drawer\n from inline-end) so navSlot + actionsSlot collapse there. */}\n <Sheet open={menuOpen} onOpenChange={setMenuOpen}>\n <Sheet.Trigger asChild>\n <IconButton\n size=\"md\"\n intent=\"ghost\"\n className=\"ds:ms-auto ds:md:hidden\"\n icon={\n menuOpen ? (\n <X aria-hidden=\"true\" />\n ) : (\n <Menu aria-hidden=\"true\" />\n )\n }\n aria-controls={sheetId}\n aria-expanded={menuOpen}\n aria-label={resolvedMenuLabel}\n />\n </Sheet.Trigger>\n <Sheet.Content side=\"end\" size=\"md\" id={sheetId}>\n <Sheet.Header>\n <Sheet.Title>{resolvedNavLabel}</Sheet.Title>\n </Sheet.Header>\n <Sheet.Body>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {navSlot ? (\n <nav\n aria-label={resolvedNavLabel}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n {navSlot}\n </nav>\n ) : null}\n {actionsSlot ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:mt-[var(--spacing-md)]\">\n {actionsSlot}\n </div>\n ) : null}\n </div>\n </Sheet.Body>\n </Sheet.Content>\n </Sheet>\n </header>\n );\n },\n);\nPublicHeaderRoot.displayName = 'PublicHeader';\n\n/* ------------------------------------------------------------------ */\n/* NavLink */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderNavLink = forwardRef<\n HTMLAnchorElement,\n PublicHeaderNavLinkProps\n>(({ active, className, children, ...rest }, ref) => (\n <a\n ref={ref}\n {...rest}\n data-active={active ? 'true' : undefined}\n aria-current={active ? 'page' : undefined}\n className={[navLinkVariants(), className].filter(Boolean).join(' ')}\n >\n {children}\n </a>\n));\nPublicHeaderNavLink.displayName = 'PublicHeader.NavLink';\n\n/* ------------------------------------------------------------------ */\n/* Public surface */\n/* ------------------------------------------------------------------ */\n\nexport const PublicHeader = Object.assign(PublicHeaderRoot, {\n NavLink: PublicHeaderNavLink,\n});\n","import type { AgentAdapter } from '../../agent/types';\nimport type { PublicHeaderHandle } from './public-header';\n\nexport const publicHeaderAgent: AgentAdapter<PublicHeaderHandle> = {\n id: 'public-header',\n capabilities: ['open', 'close'],\n state: {\n menuOpen: {\n type: 'boolean',\n description: 'Whether the mobile drawer is currently open.',\n read: (handle) => handle.getMenuOpen(),\n },\n },\n actions: {\n open_menu: {\n safety: 'read',\n description: 'Open the mobile drawer.',\n invoke: (handle) => {\n handle.openMenu();\n },\n },\n close_menu: {\n safety: 'read',\n description: 'Close the mobile drawer.',\n invoke: (handle) => {\n handle.closeMenu();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'public-header' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on PublicHeader.',\n },\n },\n};\n"],"names":["rootVariants","cva","navLinkVariants","usePrefersReducedMotion","reduced","setReduced","useState","useEffect","mq","onChange","useHeaderScrollState","enabled","sticky","stickyOffset","stuck","setStuck","hidden","setHidden","lastYRef","useRef","tickingRef","update","y","delta","onScroll","PublicHeaderRoot","forwardRef","logo","homeHref","homeLabel","navSlot","actionsSlot","variant","menuLabel","navLabel","id","className","rest","ref","t","useTranslation","autoId","useId","sheetId","menuOpen","setMenuOpen","scrollEnabled","effectiveHidden","openMenu","useCallback","closeMenu","useImperativeHandle","resolvedHomeLabel","resolvedNavLabel","resolvedMenuLabel","jsxs","jsx","Sheet","IconButton","X","Menu","PublicHeaderNavLink","active","children","PublicHeader","publicHeaderAgent","handle"],"mappings":"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"}