@bearmenu/ui 0.8.9 → 0.8.11

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.
Files changed (225) hide show
  1. package/dist/chunk-24RFI4RQ.js +167 -0
  2. package/dist/{chunk-UKBNQO6Q.js → chunk-2CXU5WZO.js} +1 -1
  3. package/dist/chunk-2XCZJWTV.js +121 -0
  4. package/dist/{chunk-62ES6N32.js → chunk-43RC7MHY.js} +1 -1
  5. package/dist/chunk-5RWTOT5Y.js +72 -0
  6. package/dist/{chunk-Q6QH52LJ.js → chunk-6TEEY5YA.js} +2 -2
  7. package/dist/{chunk-AXV5O2IZ.js → chunk-AKQ57NXY.js} +3 -3
  8. package/dist/chunk-CLLY6XB3.js +41 -0
  9. package/dist/chunk-DTXNDLSE.js +125 -0
  10. package/dist/chunk-F6FMZJDG.js +113 -0
  11. package/dist/{chunk-2WDJR6K7.js → chunk-G7IFL4Z4.js} +4 -1
  12. package/dist/chunk-H3ZZDX5L.js +61 -0
  13. package/dist/{chunk-H3BV4VAG.js → chunk-JS3EINZD.js} +2 -2
  14. package/dist/chunk-MZL7CGCL.js +109 -0
  15. package/dist/{chunk-TH6W2PWG.js → chunk-UDTG3RSE.js} +1 -1
  16. package/dist/chunk-WCTHZKU7.js +37 -0
  17. package/dist/{chunk-TT3WFS6S.js → chunk-YOKHBAIH.js} +11 -11
  18. package/dist/components/alert-dialog.js +1 -1
  19. package/dist/components/alert.d.ts +2 -2
  20. package/dist/components/avatar.d.ts +3 -3
  21. package/dist/components/badge.d.ts +1 -1
  22. package/dist/components/badge.js +1 -1
  23. package/dist/components/button.d.ts +2 -2
  24. package/dist/components/button.js +1 -1
  25. package/dist/components/calendar.js +1 -1
  26. package/dist/components/card.d.ts +4 -4
  27. package/dist/components/carousel.js +1 -1
  28. package/dist/components/combobox.js +1 -1
  29. package/dist/components/command.d.ts +2 -2
  30. package/dist/components/concept-compare-rail.d.ts +50 -0
  31. package/dist/components/concept-compare-rail.js +5 -0
  32. package/dist/components/concept-compare.d.ts +75 -38
  33. package/dist/components/concept-compare.js +209 -133
  34. package/dist/components/concept-convergence.d.ts +41 -0
  35. package/dist/components/concept-convergence.js +53 -0
  36. package/dist/components/convergence.d.ts +25 -0
  37. package/dist/components/convergence.js +4 -0
  38. package/dist/components/dialog.d.ts +2 -2
  39. package/dist/components/empty-state.js +1 -1
  40. package/dist/components/event-card.js +1 -1
  41. package/dist/components/event-compact-row.js +1 -1
  42. package/dist/components/event-detail-panel.js +2 -2
  43. package/dist/components/event-index-row.js +1 -1
  44. package/dist/components/event-list-row-wide.js +2 -2
  45. package/dist/components/event-list-row.js +2 -2
  46. package/dist/components/explainer-steps.d.ts +34 -0
  47. package/dist/components/explainer-steps.js +36 -0
  48. package/dist/components/filter-category-row.js +1 -1
  49. package/dist/components/glass-ground.d.ts +61 -0
  50. package/dist/components/glass-ground.js +3 -0
  51. package/dist/components/haptic-button.js +1 -1
  52. package/dist/components/hub-surface.js +11 -1
  53. package/dist/components/hue-chip.d.ts +70 -0
  54. package/dist/components/hue-chip.js +3 -0
  55. package/dist/components/input-group.d.ts +2 -2
  56. package/dist/components/input.d.ts +1 -1
  57. package/dist/components/item.d.ts +4 -4
  58. package/dist/components/kbd.d.ts +2 -2
  59. package/dist/components/kitchen-dossier.d.ts +88 -0
  60. package/dist/components/kitchen-dossier.js +186 -0
  61. package/dist/components/link-button.js +1 -1
  62. package/dist/components/menu-dead-end.d.ts +56 -0
  63. package/dist/components/menu-dead-end.js +49 -0
  64. package/dist/components/menu-family-block.d.ts +98 -0
  65. package/dist/components/menu-family-block.js +153 -0
  66. package/dist/components/menu-family-card.d.ts +33 -27
  67. package/dist/components/menu-family-card.js +41 -85
  68. package/dist/components/menu-field.js +92 -2
  69. package/dist/components/menu-filter-chips.d.ts +86 -0
  70. package/dist/components/menu-filter-chips.js +122 -0
  71. package/dist/components/menu-group-rows.d.ts +53 -0
  72. package/dist/components/menu-group-rows.js +67 -0
  73. package/dist/components/menu-hub-hero.js +10 -5
  74. package/dist/components/menu-index-header.d.ts +37 -0
  75. package/dist/components/menu-index-header.js +68 -0
  76. package/dist/components/menu-index-list.d.ts +48 -0
  77. package/dist/components/menu-index-list.js +96 -0
  78. package/dist/components/menu-intent-hero.d.ts +69 -0
  79. package/dist/components/menu-intent-hero.js +87 -0
  80. package/dist/components/menu-item.js +3 -3
  81. package/dist/components/menu-kitchen-list.d.ts +82 -0
  82. package/dist/components/menu-kitchen-list.js +5 -0
  83. package/dist/components/menu-mocks.d.ts +37 -2
  84. package/dist/components/menu-mocks.js +152 -27
  85. package/dist/components/menu-types.d.ts +182 -6
  86. package/dist/components/motion-icon-controls.js +2 -2
  87. package/dist/components/motion-icon-set.js +6 -6
  88. package/dist/components/motion-icon.d.ts +22 -1
  89. package/dist/components/motion-icon.js +1 -1
  90. package/dist/components/multi-select-combobox.js +2 -2
  91. package/dist/components/native-select.d.ts +2 -2
  92. package/dist/components/pagination.js +1 -1
  93. package/dist/components/photo-ground.d.ts +64 -0
  94. package/dist/components/photo-ground.js +3 -0
  95. package/dist/components/place-about-tab.js +2 -2
  96. package/dist/components/place-details-mobile.js +3 -3
  97. package/dist/components/place-types.d.ts +2 -2
  98. package/dist/components/qa-block.d.ts +36 -0
  99. package/dist/components/qa-block.js +24 -0
  100. package/dist/components/scroll-fade.js +3 -121
  101. package/dist/components/searchable-select.js +1 -1
  102. package/dist/components/select.d.ts +1 -1
  103. package/dist/components/signature-chip.d.ts +2 -2
  104. package/dist/components/signature-chip.js +2 -2
  105. package/dist/components/sliding-panels.js +1 -1
  106. package/dist/components/snap-rail.d.ts +26 -3
  107. package/dist/components/snap-rail.js +3 -109
  108. package/dist/components/spinner.d.ts +4 -4
  109. package/dist/components/story.d.ts +34 -0
  110. package/dist/components/story.js +3 -0
  111. package/dist/components/tag.d.ts +4 -4
  112. package/dist/components/text.d.ts +5 -5
  113. package/dist/components/toggle.d.ts +1 -1
  114. package/dist/components/top-comparison.d.ts +28 -0
  115. package/dist/components/top-comparison.js +76 -0
  116. package/dist/components/top-cross-link.d.ts +34 -0
  117. package/dist/components/top-cross-link.js +101 -0
  118. package/dist/components/top-ranking-entry.d.ts +53 -0
  119. package/dist/components/top-ranking-entry.js +217 -0
  120. package/dist/components/top-ranking-hero.d.ts +61 -0
  121. package/dist/components/top-ranking-hero.js +99 -0
  122. package/dist/components/top-ranking-legend.d.ts +69 -0
  123. package/dist/components/top-ranking-legend.js +124 -0
  124. package/dist/components/top-types.d.ts +109 -0
  125. package/dist/components/top-types.js +1 -0
  126. package/dist/components/venue-grade-dimensions.d.ts +3 -1
  127. package/dist/components/venue-grade-dimensions.js +1 -1
  128. package/dist/components/venue-quotes.d.ts +1 -1
  129. package/dist/components/venue-quotes.js +1 -1
  130. package/dist/components/venue-wall.js +5 -3
  131. package/dist/components/weekday-theme-banner.js +1 -1
  132. package/dist/components/weekend-panel.js +2 -2
  133. package/package.json +1 -1
  134. package/src/components/badge.tsx +1 -1
  135. package/src/components/button.tsx +2 -2
  136. package/src/components/concept-compare-rail.tsx +132 -0
  137. package/src/components/concept-compare.stories.tsx +122 -54
  138. package/src/components/concept-compare.tsx +368 -196
  139. package/src/components/concept-convergence.stories.tsx +53 -0
  140. package/src/components/concept-convergence.tsx +90 -0
  141. package/src/components/convergence.stories.tsx +54 -0
  142. package/src/components/convergence.tsx +177 -0
  143. package/src/components/explainer-steps.stories.tsx +46 -0
  144. package/src/components/explainer-steps.tsx +74 -0
  145. package/src/components/glass-ground.tsx +104 -0
  146. package/src/components/hub-surface.tsx +11 -1
  147. package/src/components/hue-chip.stories.tsx +76 -0
  148. package/src/components/hue-chip.test.tsx +62 -0
  149. package/src/components/hue-chip.tsx +99 -0
  150. package/src/components/kitchen-dossier.stories.tsx +108 -0
  151. package/src/components/kitchen-dossier.tsx +321 -0
  152. package/src/components/menu-dead-end.stories.tsx +67 -0
  153. package/src/components/menu-dead-end.tsx +127 -0
  154. package/src/components/menu-family-block.stories.tsx +91 -0
  155. package/src/components/menu-family-block.tsx +303 -0
  156. package/src/components/menu-family-card.stories.tsx +43 -35
  157. package/src/components/menu-family-card.tsx +115 -142
  158. package/src/components/menu-filter-chips.stories.tsx +107 -0
  159. package/src/components/menu-filter-chips.tsx +238 -0
  160. package/src/components/menu-group-rows.stories.tsx +54 -0
  161. package/src/components/menu-group-rows.tsx +133 -0
  162. package/src/components/menu-hub-hero.test.tsx +39 -0
  163. package/src/components/menu-hub-hero.tsx +17 -5
  164. package/src/components/menu-index-header.stories.tsx +72 -0
  165. package/src/components/menu-index-header.tsx +125 -0
  166. package/src/components/menu-index-list.stories.tsx +50 -0
  167. package/src/components/menu-index-list.tsx +149 -0
  168. package/src/components/menu-intent-hero.stories.tsx +67 -0
  169. package/src/components/menu-intent-hero.tsx +189 -0
  170. package/src/components/menu-kitchen-list.stories.tsx +67 -0
  171. package/src/components/menu-kitchen-list.test.tsx +78 -0
  172. package/src/components/menu-kitchen-list.tsx +284 -0
  173. package/src/components/menu-mocks.ts +198 -23
  174. package/src/components/menu-types.ts +189 -6
  175. package/src/components/motion-icon-controls.tsx +11 -11
  176. package/src/components/motion-icon-set.tsx +6 -5
  177. package/src/components/motion-icon.test.tsx +23 -1
  178. package/src/components/motion-icon.tsx +20 -0
  179. package/src/components/photo-ground.tsx +147 -0
  180. package/src/components/place-types.ts +2 -2
  181. package/src/components/qa-block.stories.tsx +43 -0
  182. package/src/components/qa-block.tsx +60 -0
  183. package/src/components/signature-chip.tsx +3 -3
  184. package/src/components/snap-rail.tsx +58 -15
  185. package/src/components/story.tsx +225 -0
  186. package/src/components/top-comparison.stories.tsx +78 -0
  187. package/src/components/top-comparison.tsx +151 -0
  188. package/src/components/top-cross-link.stories.tsx +84 -0
  189. package/src/components/top-cross-link.tsx +171 -0
  190. package/src/components/top-ranking-entry.stories.tsx +171 -0
  191. package/src/components/top-ranking-entry.test.tsx +105 -0
  192. package/src/components/top-ranking-entry.tsx +425 -0
  193. package/src/components/top-ranking-hero.stories.tsx +76 -0
  194. package/src/components/top-ranking-hero.tsx +218 -0
  195. package/src/components/top-ranking-legend.stories.tsx +78 -0
  196. package/src/components/top-ranking-legend.tsx +239 -0
  197. package/src/components/top-types.ts +110 -0
  198. package/src/components/venue-grade-dimensions.tsx +2 -2
  199. package/src/components/venue-quotes.stories.tsx +1 -1
  200. package/src/components/venue-quotes.tsx +4 -2
  201. package/src/components/venue-wall.tsx +9 -4
  202. package/src/components/weekday-theme-banner.tsx +1 -1
  203. package/dist/chunk-THOVPZNN.js +0 -37
  204. package/dist/chunk-YS6BHKZO.js +0 -92
  205. package/dist/components/ranked-venue-list.d.ts +0 -49
  206. package/dist/components/ranked-venue-list.js +0 -87
  207. package/dist/components/signature-line-list.d.ts +0 -45
  208. package/dist/components/signature-line-list.js +0 -99
  209. package/dist/components/venue-busyness-strip.d.ts +0 -35
  210. package/dist/components/venue-busyness-strip.js +0 -37
  211. package/dist/components/venue-signature-block.d.ts +0 -39
  212. package/dist/components/venue-signature-block.js +0 -6
  213. package/dist/components/venue-spotlight.d.ts +0 -74
  214. package/dist/components/venue-spotlight.js +0 -138
  215. package/src/components/ranked-venue-list.stories.tsx +0 -80
  216. package/src/components/ranked-venue-list.tsx +0 -177
  217. package/src/components/signature-line-list.stories.tsx +0 -85
  218. package/src/components/signature-line-list.tsx +0 -136
  219. package/src/components/venue-busyness-strip.stories.tsx +0 -66
  220. package/src/components/venue-busyness-strip.tsx +0 -64
  221. package/src/components/venue-signature-block.stories.tsx +0 -68
  222. package/src/components/venue-signature-block.tsx +0 -71
  223. package/src/components/venue-spotlight.stories.tsx +0 -141
  224. package/src/components/venue-spotlight.tsx +0 -236
  225. package/dist/{chunk-XWMRABZW.js → chunk-HSIYYA2E.js} +1 -1
@@ -0,0 +1,36 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { QaItem } from './menu-types.js';
3
+ import 'react';
4
+ import './place-types.js';
5
+
6
+ /**
7
+ * QaBlock — questions answered from the numbers, as static prose.
8
+ *
9
+ * ## Never an accordion
10
+ *
11
+ * This block exists to be crawled as much as read: it is the visible half of
12
+ * the page's `FAQPage` markup, and the rule is that structured data must mirror
13
+ * content the reader can actually see. Collapsing it hides every answer from
14
+ * the crawler's first paint and buys nothing — three short answers are cheaper
15
+ * to scroll past than to expand.
16
+ *
17
+ * The caller renders the JSON-LD from the SAME array it passes here, so the
18
+ * markup and the visible answers cannot drift.
19
+ *
20
+ * ## Three across, then one
21
+ *
22
+ * Answers are two or three lines each, so a single column wastes the desktop
23
+ * measure and a two-column grid leaves an orphan. On the phone it is one
24
+ * column, in order.
25
+ */
26
+ type QaBlockProps = {
27
+ items: QaItem[];
28
+ /** Section heading, e.g. "Questions people ask". Omit where the page supplies one. */
29
+ heading?: string;
30
+ /** Heading level for the questions. Defaults to `h3`, under a page's `h2`. */
31
+ questionAs?: "h3" | "h4";
32
+ className?: string;
33
+ };
34
+ declare function QaBlock({ items, heading, questionAs: Question, className }: QaBlockProps): react_jsx_runtime.JSX.Element;
35
+
36
+ export { QaBlock, type QaBlockProps };
@@ -0,0 +1,24 @@
1
+ import { cn } from '../chunk-FEK5XGZW.js';
2
+ import '../chunk-3GWWZKX7.js';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ function QaBlock({ items, heading, questionAs: Question = "h3", className }) {
6
+ return /* @__PURE__ */ jsxs("section", { className: cn(className), children: [
7
+ heading && /* @__PURE__ */ jsx("h2", { className: "text-[15px] font-bold leading-tight tracking-[-0.01em]", children: heading }),
8
+ /* @__PURE__ */ jsx(
9
+ "div",
10
+ {
11
+ className: cn(
12
+ "grid grid-cols-1 gap-[18px] lg:grid-cols-3 lg:gap-[26px]",
13
+ heading && "mt-3.5"
14
+ ),
15
+ children: items.map((item) => /* @__PURE__ */ jsxs("div", { children: [
16
+ /* @__PURE__ */ jsx(Question, { className: "text-sm font-bold leading-[1.35] tracking-[-0.01em] lg:text-[15px]", children: item.question }),
17
+ /* @__PURE__ */ jsx("p", { className: "mt-[7px] text-[13px] leading-[1.65] text-muted-foreground [text-wrap:pretty] lg:text-[13.5px]", children: item.answer })
18
+ ] }, item.question))
19
+ }
20
+ )
21
+ ] });
22
+ }
23
+
24
+ export { QaBlock };
@@ -1,121 +1,3 @@
1
- import { cn } from '../chunk-FEK5XGZW.js';
2
- import { __objRest, __spreadProps, __spreadValues } from '../chunk-3GWWZKX7.js';
3
- import * as React from 'react';
4
- import { jsxs, jsx } from 'react/jsx-runtime';
5
-
6
- var fromMap = {
7
- background: "from-background",
8
- card: "from-card",
9
- muted: "from-muted"
10
- };
11
- var sizeMap = {
12
- vertical: { sm: "h-6", md: "h-12", lg: "h-20" },
13
- horizontal: { sm: "w-8", md: "w-16", lg: "w-28" }
14
- };
15
- var ScrollFade = React.forwardRef(
16
- (_a, ref) => {
17
- var _b = _a, {
18
- orientation = "vertical",
19
- fadeColor = "background",
20
- size = "md",
21
- className,
22
- scrollClassName,
23
- children
24
- } = _b, props = __objRest(_b, [
25
- "orientation",
26
- "fadeColor",
27
- "size",
28
- "className",
29
- "scrollClassName",
30
- "children"
31
- ]);
32
- const innerRef = React.useRef(null);
33
- React.useImperativeHandle(ref, () => innerRef.current);
34
- const [atStart, setAtStart] = React.useState(true);
35
- const [atEnd, setAtEnd] = React.useState(true);
36
- const update = React.useCallback(() => {
37
- const el = innerRef.current;
38
- if (!el) return;
39
- if (orientation === "vertical") {
40
- const overflow = el.scrollHeight - el.clientHeight;
41
- setAtStart(el.scrollTop <= 1);
42
- setAtEnd(overflow <= 1 || el.scrollTop >= overflow - 1);
43
- } else {
44
- const overflow = el.scrollWidth - el.clientWidth;
45
- setAtStart(el.scrollLeft <= 1);
46
- setAtEnd(overflow <= 1 || el.scrollLeft >= overflow - 1);
47
- }
48
- }, [orientation]);
49
- React.useEffect(() => {
50
- const el = innerRef.current;
51
- if (!el) return;
52
- update();
53
- el.addEventListener("scroll", update, { passive: true });
54
- const ro = new ResizeObserver(update);
55
- ro.observe(el);
56
- return () => {
57
- el.removeEventListener("scroll", update);
58
- ro.disconnect();
59
- };
60
- }, [update]);
61
- const fromClass = fromMap[fadeColor];
62
- const fadeSize = sizeMap[orientation][size];
63
- return /* @__PURE__ */ jsxs(
64
- "div",
65
- {
66
- className: cn(
67
- "relative isolate flex",
68
- orientation === "vertical" ? "flex-col" : "flex-row",
69
- className
70
- ),
71
- children: [
72
- /* @__PURE__ */ jsx(
73
- "div",
74
- __spreadProps(__spreadValues({
75
- ref: innerRef,
76
- className: cn(
77
- "min-h-0 min-w-0 flex-1",
78
- orientation === "vertical" ? "overflow-y-auto" : "overflow-x-auto",
79
- scrollClassName
80
- )
81
- }, props), {
82
- children
83
- })
84
- ),
85
- /* @__PURE__ */ jsx(
86
- "div",
87
- {
88
- "aria-hidden": true,
89
- className: cn(
90
- "pointer-events-none absolute z-10 transition-opacity duration-300",
91
- // `from-30%` adds a solid plateau before the gradient starts
92
- // fading — without it the gradient is a pure linear ramp and only
93
- // the very top pixel reads as solid, leaving the cut edge visible.
94
- // -4px inset pulls the fade past the container edge so the very
95
- // edge of clipped content is covered by the solid plateau.
96
- orientation === "vertical" ? `inset-x-0 -top-1 ${fadeSize} bg-gradient-to-b from-30%` : `inset-y-0 -left-1 ${fadeSize} bg-gradient-to-r from-30%`,
97
- fromClass,
98
- atStart ? "opacity-0" : "opacity-100"
99
- )
100
- }
101
- ),
102
- /* @__PURE__ */ jsx(
103
- "div",
104
- {
105
- "aria-hidden": true,
106
- className: cn(
107
- "pointer-events-none absolute z-10 transition-opacity duration-300",
108
- orientation === "vertical" ? `inset-x-0 -bottom-1 ${fadeSize} bg-gradient-to-t from-30%` : `inset-y-0 -right-1 ${fadeSize} bg-gradient-to-l from-30%`,
109
- fromClass,
110
- atEnd ? "opacity-0" : "opacity-100"
111
- )
112
- }
113
- )
114
- ]
115
- }
116
- );
117
- }
118
- );
119
- ScrollFade.displayName = "ScrollFade";
120
-
121
- export { ScrollFade };
1
+ export { ScrollFade } from '../chunk-2XCZJWTV.js';
2
+ import '../chunk-FEK5XGZW.js';
3
+ import '../chunk-3GWWZKX7.js';
@@ -1,7 +1,7 @@
1
1
  import { Popover, PopoverTrigger, PopoverContent } from '../chunk-66MAPLXS.js';
2
2
  import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from '../chunk-XNA2INVQ.js';
3
3
  import '../chunk-FRPPIXMY.js';
4
- import { Button } from '../chunk-H3BV4VAG.js';
4
+ import { Button } from '../chunk-JS3EINZD.js';
5
5
  import '../chunk-R47NEOSI.js';
6
6
  import { cn } from '../chunk-FEK5XGZW.js';
7
7
  import '../chunk-3GWWZKX7.js';
@@ -7,7 +7,7 @@ declare const Select: React.FC<SelectPrimitive.SelectProps>;
7
7
  declare const SelectGroup: React.ForwardRefExoticComponent<SelectPrimitive.SelectGroupProps & React.RefAttributes<HTMLDivElement>>;
8
8
  declare const SelectValue: React.ForwardRefExoticComponent<SelectPrimitive.SelectValueProps & React.RefAttributes<HTMLSpanElement>>;
9
9
  declare const SelectTrigger: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
10
- size?: "default" | "sm" | "lg" | null | undefined;
10
+ size?: "sm" | "default" | "lg" | null | undefined;
11
11
  } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLButtonElement>>;
12
12
  declare const SelectScrollUpButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollUpButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
13
13
  declare const SelectScrollDownButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollDownButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -18,8 +18,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
18
18
  *
19
19
  * `surface="image"` is for card covers, where the chip sits over the photo
20
20
  * rather than in the caption block. The accent-on-canvas palette has no
21
- * contrast guarantee over an arbitrary photo, so it swaps to the same frosted
22
- * fill the place badge uses there and keeps the dashed edge — which is what
21
+ * contrast guarantee over an arbitrary photo, so it swaps to the same solid
22
+ * ink fill the place badge uses there and keeps the dashed edge — which is what
23
23
  * says "there is evidence behind this" — in the inverted colour.
24
24
  *
25
25
  * The label is passed in: the DS owns no translation keys.
@@ -1,4 +1,4 @@
1
- export { SignatureChip } from '../chunk-Q6QH52LJ.js';
2
- import '../chunk-UKBNQO6Q.js';
1
+ export { SignatureChip } from '../chunk-6TEEY5YA.js';
2
+ import '../chunk-2CXU5WZO.js';
3
3
  import '../chunk-FEK5XGZW.js';
4
4
  import '../chunk-3GWWZKX7.js';
@@ -1,4 +1,4 @@
1
- import { Button } from '../chunk-H3BV4VAG.js';
1
+ import { Button } from '../chunk-JS3EINZD.js';
2
2
  import '../chunk-R47NEOSI.js';
3
3
  import { cn } from '../chunk-FEK5XGZW.js';
4
4
  import '../chunk-3GWWZKX7.js';
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as class_variance_authority_types from 'class-variance-authority/types';
2
3
  import * as React from 'react';
3
4
  import { VariantProps } from 'class-variance-authority';
@@ -21,7 +22,7 @@ import { VariantProps } from 'class-variance-authority';
21
22
  */
22
23
  declare const snapRailVariants: (props?: ({
23
24
  itemWidth?: "sm" | "lg" | "full" | "md" | null | undefined;
24
- gap?: "default" | "sm" | null | undefined;
25
+ gap?: "sm" | "default" | null | undefined;
25
26
  bleed?: "none" | "page" | "card" | null | undefined;
26
27
  } & class_variance_authority_types.ClassProp) | undefined) => string;
27
28
  type SnapRailProps = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof snapRailVariants> & {
@@ -34,10 +35,16 @@ type SnapRailProps = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof
34
35
  dots?: boolean;
35
36
  /** Classes for the dots row, e.g. `lg:hidden` where the rail becomes a grid. */
36
37
  dotsClassName?: string;
38
+ /**
39
+ * Reports the current page whenever it changes — for a caller that wants
40
+ * to react to the swipe beyond the dots, e.g. a backdrop that follows the
41
+ * active card. Tracking runs whenever this or `dots` is set.
42
+ */
43
+ onActiveChange?: (index: number) => void;
37
44
  };
38
45
  declare const SnapRail: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
39
46
  itemWidth?: "sm" | "lg" | "full" | "md" | null | undefined;
40
- gap?: "default" | "sm" | null | undefined;
47
+ gap?: "sm" | "default" | null | undefined;
41
48
  bleed?: "none" | "page" | "card" | null | undefined;
42
49
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
43
50
  /**
@@ -49,6 +56,22 @@ declare const SnapRail: React.ForwardRefExoticComponent<React.HTMLAttributes<HTM
49
56
  dots?: boolean;
50
57
  /** Classes for the dots row, e.g. `lg:hidden` where the rail becomes a grid. */
51
58
  dotsClassName?: string;
59
+ /**
60
+ * Reports the current page whenever it changes — for a caller that wants
61
+ * to react to the swipe beyond the dots, e.g. a backdrop that follows the
62
+ * active card. Tracking runs whenever this or `dots` is set.
63
+ */
64
+ onActiveChange?: (index: number) => void;
52
65
  } & React.RefAttributes<HTMLDivElement>>;
66
+ /**
67
+ * The page dots on their own, for a caller that tracks the rail through
68
+ * `onActiveChange` and wants the dots somewhere other than directly under it —
69
+ * inside a foot band, say. Decorative, as on the rail: the rail is the control.
70
+ */
71
+ declare function SnapRailDots({ count, active, className, }: {
72
+ count: number;
73
+ active: number;
74
+ className?: string;
75
+ }): react_jsx_runtime.JSX.Element;
53
76
 
54
- export { SnapRail, type SnapRailProps };
77
+ export { SnapRail, SnapRailDots, type SnapRailProps };
@@ -1,109 +1,3 @@
1
- import { cn } from '../chunk-FEK5XGZW.js';
2
- import { __objRest, __spreadProps, __spreadValues } from '../chunk-3GWWZKX7.js';
3
- import * as React from 'react';
4
- import { cva } from 'class-variance-authority';
5
- import { jsx, jsxs } from 'react/jsx-runtime';
6
-
7
- var snapRailVariants = cva(
8
- cn(
9
- "flex snap-x snap-mandatory overflow-x-auto pb-0.5 scrollbar-hide",
10
- "[&>*]:shrink-0 [&>*]:snap-start"
11
- ),
12
- {
13
- variants: {
14
- itemWidth: {
15
- sm: "[&>*]:w-[46%]",
16
- md: "[&>*]:w-[60%]",
17
- lg: "[&>*]:w-[80%]",
18
- /** One card per view — pair with `dots` so the reader knows there is more. */
19
- full: "[&>*]:w-full"
20
- },
21
- gap: {
22
- sm: "gap-2",
23
- default: "gap-3"
24
- },
25
- bleed: {
26
- none: "",
27
- card: "-mx-3.5 px-3.5 scroll-px-3.5",
28
- page: "-mx-4 px-4 scroll-px-4"
29
- }
30
- },
31
- defaultVariants: {
32
- itemWidth: "sm",
33
- gap: "default",
34
- bleed: "none"
35
- }
36
- }
37
- );
38
- var SnapRail = React.forwardRef(
39
- (_a, ref) => {
40
- var _b = _a, { className, itemWidth, gap, bleed, dots, dotsClassName, children } = _b, props = __objRest(_b, ["className", "itemWidth", "gap", "bleed", "dots", "dotsClassName", "children"]);
41
- const railRef = React.useRef(null);
42
- const [active, setActive] = React.useState(0);
43
- const count = React.Children.count(children);
44
- const setRefs = React.useCallback(
45
- (node) => {
46
- railRef.current = node;
47
- if (typeof ref === "function") ref(node);
48
- else if (ref) ref.current = node;
49
- },
50
- [ref]
51
- );
52
- React.useEffect(() => {
53
- if (!dots) return;
54
- const rail2 = railRef.current;
55
- if (!rail2) return;
56
- let frame = 0;
57
- const sync = () => {
58
- frame = 0;
59
- const origin = rail2.scrollLeft + parseFloat(getComputedStyle(rail2).scrollPaddingLeft || "0");
60
- let best = 0;
61
- let bestDistance = Number.POSITIVE_INFINITY;
62
- Array.from(rail2.children).forEach((child, index) => {
63
- const distance = Math.abs(child.offsetLeft - origin);
64
- if (distance < bestDistance) {
65
- bestDistance = distance;
66
- best = index;
67
- }
68
- });
69
- setActive(best);
70
- };
71
- const onScroll = () => {
72
- if (!frame) frame = requestAnimationFrame(sync);
73
- };
74
- sync();
75
- rail2.addEventListener("scroll", onScroll, { passive: true });
76
- return () => {
77
- if (frame) cancelAnimationFrame(frame);
78
- rail2.removeEventListener("scroll", onScroll);
79
- };
80
- }, [dots, count]);
81
- const rail = /* @__PURE__ */ jsx(
82
- "div",
83
- __spreadProps(__spreadValues({
84
- ref: setRefs,
85
- "data-slot": "snap-rail",
86
- className: cn(snapRailVariants({ itemWidth, gap, bleed }), className)
87
- }, props), {
88
- children
89
- })
90
- );
91
- if (!dots) return rail;
92
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
93
- rail,
94
- /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: cn("flex justify-center gap-1.5", dotsClassName), children: Array.from({ length: count }, (_, index) => /* @__PURE__ */ jsx(
95
- "span",
96
- {
97
- className: cn(
98
- "h-1.5 rounded-full transition-[width,background-color] duration-200 motion-reduce:transition-none",
99
- index === active ? "w-4 bg-foreground" : "w-1.5 bg-foreground/25"
100
- )
101
- },
102
- index
103
- )) })
104
- ] });
105
- }
106
- );
107
- SnapRail.displayName = "SnapRail";
108
-
109
- export { SnapRail };
1
+ export { SnapRail, SnapRailDots } from '../chunk-DTXNDLSE.js';
2
+ import '../chunk-FEK5XGZW.js';
3
+ import '../chunk-3GWWZKX7.js';
@@ -3,12 +3,12 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const spinnerVariants: (props?: ({
6
- size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
7
- tone?: "default" | "destructive" | "inherit" | "primary" | null | undefined;
6
+ size?: "xs" | "sm" | "default" | "lg" | "xl" | null | undefined;
7
+ tone?: "default" | "inherit" | "destructive" | "primary" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  declare const Spinner: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
10
- size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
11
- tone?: "default" | "destructive" | "inherit" | "primary" | null | undefined;
10
+ size?: "xs" | "sm" | "default" | "lg" | "xl" | null | undefined;
11
+ tone?: "default" | "inherit" | "destructive" | "primary" | null | undefined;
12
12
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
13
13
  /** Visually-hidden label for screen readers. Defaults to "Loading". */
14
14
  label?: string;
@@ -0,0 +1,34 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ type StoryProviderProps = {
5
+ /** How many parts the story has. */
6
+ count: number;
7
+ /** How long each part shows. */
8
+ durationMs?: number;
9
+ /** Accessible name of the tap-to-advance, e.g. "Next". */
10
+ nextLabel: string;
11
+ className?: string;
12
+ children: React.ReactNode;
13
+ };
14
+ declare function StoryProvider({ count, durationMs, nextLabel, className, children, }: StoryProviderProps): react_jsx_runtime.JSX.Element;
15
+ type StorySegmentsProps = {
16
+ /**
17
+ * Accessible name per segment, one per part, e.g. `["Part 1 of 3", …]`.
18
+ * Strings rather than a function: a server component renders this and a
19
+ * function cannot cross into a client one.
20
+ */
21
+ labels: string[];
22
+ className?: string;
23
+ };
24
+ /** The segments: one per part, the active one filling on the timer. */
25
+ declare function StorySegments({ labels, className }: StorySegmentsProps): react_jsx_runtime.JSX.Element | null;
26
+ type StoryPanelProps = {
27
+ /** The parts, in order. Rendered by the caller; shown one at a time. */
28
+ parts: React.ReactNode[];
29
+ className?: string;
30
+ };
31
+ /** The panel: every part in one cell, the active one visible. */
32
+ declare function StoryPanel({ parts, className }: StoryPanelProps): react_jsx_runtime.JSX.Element;
33
+
34
+ export { StoryPanel, type StoryPanelProps, StoryProvider, type StoryProviderProps, StorySegments, type StorySegmentsProps };
@@ -0,0 +1,3 @@
1
+ export { StoryPanel, StoryProvider, StorySegments } from '../chunk-F6FMZJDG.js';
2
+ import '../chunk-FEK5XGZW.js';
3
+ import '../chunk-3GWWZKX7.js';
@@ -3,12 +3,12 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const tagVariants: (props?: ({
6
- variant?: "default" | "destructive" | "outline" | "success" | "warning" | "primary" | "quiet" | null | undefined;
7
- size?: "default" | "sm" | "lg" | null | undefined;
6
+ variant?: "default" | "success" | "warning" | "destructive" | "outline" | "primary" | "quiet" | null | undefined;
7
+ size?: "sm" | "default" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  declare const Tag: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
10
- variant?: "default" | "destructive" | "outline" | "success" | "warning" | "primary" | "quiet" | null | undefined;
11
- size?: "default" | "sm" | "lg" | null | undefined;
10
+ variant?: "default" | "success" | "warning" | "destructive" | "outline" | "primary" | "quiet" | null | undefined;
11
+ size?: "sm" | "default" | "lg" | null | undefined;
12
12
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
13
13
  onRemove?: () => void;
14
14
  removeLabel?: string;
@@ -22,11 +22,11 @@ import { VariantProps } from 'class-variance-authority';
22
22
  * Weights are 400 / 600 / 700. 500 is not in the system.
23
23
  */
24
24
  declare const textVariants: (props?: ({
25
- variant?: "small" | "display" | "h2" | "h3" | "label" | "body" | "caption" | "h1" | "h4" | "body-lg" | "body-sm" | "overline" | null | undefined;
26
- color?: "default" | "destructive" | "inherit" | "muted" | "primary" | "primary-foreground" | null | undefined;
27
- weight?: "medium" | "bold" | "normal" | "semibold" | null | undefined;
28
- leading?: "none" | "normal" | "tight" | "snug" | "relaxed" | "loose" | null | undefined;
29
- tracking?: "normal" | "tight" | "wide" | "wider" | null | undefined;
25
+ variant?: "h2" | "h3" | "label" | "body" | "caption" | "h1" | "h4" | "small" | "display" | "body-lg" | "body-sm" | "overline" | null | undefined;
26
+ color?: "default" | "inherit" | "destructive" | "muted" | "primary" | "primary-foreground" | null | undefined;
27
+ weight?: "bold" | "medium" | "normal" | "semibold" | null | undefined;
28
+ leading?: "none" | "tight" | "loose" | "normal" | "snug" | "relaxed" | null | undefined;
29
+ tracking?: "tight" | "normal" | "wide" | "wider" | null | undefined;
30
30
  wrap?: "balance" | "pretty" | "nowrap" | null | undefined;
31
31
  } & class_variance_authority_types.ClassProp) | undefined) => string;
32
32
  type TextTag = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "div" | "label" | "strong" | "em" | "small" | "li" | "dt" | "dd";
@@ -6,7 +6,7 @@ import { VariantProps } from 'class-variance-authority';
6
6
 
7
7
  declare const toggleVariants: (props?: ({
8
8
  variant?: "default" | "outline" | null | undefined;
9
- size?: "default" | "sm" | "lg" | null | undefined;
9
+ size?: "sm" | "default" | "lg" | null | undefined;
10
10
  } & class_variance_authority_types.ClassProp) | undefined) => string;
11
11
  declare function Toggle({ className, variant, size, ...props }: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>): react_jsx_runtime.JSX.Element;
12
12
 
@@ -0,0 +1,28 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { MenuLinkComponent } from './menu-types.js';
3
+ import { TopComparisonRow } from './top-types.js';
4
+ import 'react';
5
+ import './place-types.js';
6
+
7
+ type TopComparisonLabels = {
8
+ venue: string;
9
+ grade: string;
10
+ signature: string;
11
+ price: string;
12
+ late: string;
13
+ terrace: string;
14
+ /** Screen-reader text for a "no" cell — never an empty cell. */
15
+ no: string;
16
+ yes: string;
17
+ };
18
+ type TopComparisonProps = {
19
+ rows: TopComparisonRow[];
20
+ labels: TopComparisonLabels;
21
+ /** Accessible name for the table. */
22
+ caption: string;
23
+ linkComponent?: MenuLinkComponent;
24
+ className?: string;
25
+ };
26
+ declare function TopComparison({ rows, labels, caption, linkComponent: LinkComponent, className, }: TopComparisonProps): react_jsx_runtime.JSX.Element;
27
+
28
+ export { TopComparison, type TopComparisonLabels, type TopComparisonProps };
@@ -0,0 +1,76 @@
1
+ import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
2
+ import { Moon, Sun } from 'lucide-react';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ function DefaultLink(_a) {
6
+ var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
7
+ return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
8
+ }
9
+ function TopComparison({
10
+ rows,
11
+ labels,
12
+ caption,
13
+ linkComponent: LinkComponent = DefaultLink,
14
+ className
15
+ }) {
16
+ return /* @__PURE__ */ jsxs("div", { className, children: [
17
+ /* @__PURE__ */ jsx("div", { className: "hidden overflow-x-auto lg:block", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-[13px]", children: [
18
+ /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }),
19
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-border text-left text-[11px] font-bold uppercase tracking-[0.07em] text-muted-foreground", children: [
20
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "w-10 py-2 font-bold", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "#" }) }),
21
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.venue }),
22
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.grade }),
23
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.signature }),
24
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.price }),
25
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.late }),
26
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "py-2 font-bold", children: labels.terrace })
27
+ ] }) }),
28
+ /* @__PURE__ */ jsx("tbody", { children: rows.map((row) => {
29
+ var _a, _b, _c;
30
+ return /* @__PURE__ */ jsxs("tr", { className: "border-b border-border/60", children: [
31
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 tabular-nums text-muted-foreground", children: String(row.rank).padStart(2, "0") }),
32
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 font-semibold", children: /* @__PURE__ */ jsx(
33
+ LinkComponent,
34
+ {
35
+ href: row.href,
36
+ className: "hover:text-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
37
+ children: row.name
38
+ }
39
+ ) }),
40
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 font-bold tabular-nums text-accent", children: (_a = row.gradeLabel) != null ? _a : "\u2014" }),
41
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 text-muted-foreground", children: (_b = row.signature) != null ? _b : "\u2014" }),
42
+ /* @__PURE__ */ jsx("td", { className: "py-2.5 tabular-nums", children: (_c = row.priceLabel) != null ? _c : "\u2014" }),
43
+ /* @__PURE__ */ jsx("td", { className: "py-2.5", children: /* @__PURE__ */ jsx(Mark, { on: row.late, yes: labels.yes, no: labels.no }) }),
44
+ /* @__PURE__ */ jsx("td", { className: "py-2.5", children: /* @__PURE__ */ jsx(Mark, { on: row.terrace, yes: labels.yes, no: labels.no }) })
45
+ ] }, row.name);
46
+ }) })
47
+ ] }) }),
48
+ /* @__PURE__ */ jsx("ul", { className: "lg:hidden", children: rows.map((row) => /* @__PURE__ */ jsx("li", { className: "border-t border-border first:border-t-0", children: /* @__PURE__ */ jsxs(
49
+ LinkComponent,
50
+ {
51
+ href: row.href,
52
+ className: "flex items-center gap-3 py-2.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
53
+ children: [
54
+ /* @__PURE__ */ jsx("span", { className: "w-6 shrink-0 text-[13px] font-bold tabular-nums text-muted-foreground", children: String(row.rank).padStart(2, "0") }),
55
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
56
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-[13.5px] font-bold", children: row.name }),
57
+ (row.signature || row.priceLabel) && /* @__PURE__ */ jsx("span", { className: "block truncate text-[11.5px] text-muted-foreground", children: [row.signature, row.priceLabel].filter(Boolean).join(" \xB7 ") })
58
+ ] }),
59
+ /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-muted-foreground", children: [
60
+ row.late && /* @__PURE__ */ jsx(Moon, { className: "h-3.5 w-3.5", "aria-label": labels.late }),
61
+ row.terrace && /* @__PURE__ */ jsx(Sun, { className: "h-3.5 w-3.5", "aria-label": labels.terrace })
62
+ ] }),
63
+ row.gradeLabel && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[13px] font-extrabold tabular-nums text-accent", children: row.gradeLabel })
64
+ ]
65
+ }
66
+ ) }, row.name)) })
67
+ ] });
68
+ }
69
+ function Mark({ on, yes, no }) {
70
+ return on ? /* @__PURE__ */ jsx("span", { className: "font-semibold text-[color:var(--free,oklch(0.45_0.13_155))]", children: yes }) : /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
71
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\u2014" }),
72
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: no })
73
+ ] });
74
+ }
75
+
76
+ export { TopComparison };