@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.
- package/dist/chunk-24RFI4RQ.js +167 -0
- package/dist/{chunk-UKBNQO6Q.js → chunk-2CXU5WZO.js} +1 -1
- package/dist/chunk-2XCZJWTV.js +121 -0
- package/dist/{chunk-62ES6N32.js → chunk-43RC7MHY.js} +1 -1
- package/dist/chunk-5RWTOT5Y.js +72 -0
- package/dist/{chunk-Q6QH52LJ.js → chunk-6TEEY5YA.js} +2 -2
- package/dist/{chunk-AXV5O2IZ.js → chunk-AKQ57NXY.js} +3 -3
- package/dist/chunk-CLLY6XB3.js +41 -0
- package/dist/chunk-DTXNDLSE.js +125 -0
- package/dist/chunk-F6FMZJDG.js +113 -0
- package/dist/{chunk-2WDJR6K7.js → chunk-G7IFL4Z4.js} +4 -1
- package/dist/chunk-H3ZZDX5L.js +61 -0
- package/dist/{chunk-H3BV4VAG.js → chunk-JS3EINZD.js} +2 -2
- package/dist/chunk-MZL7CGCL.js +109 -0
- package/dist/{chunk-TH6W2PWG.js → chunk-UDTG3RSE.js} +1 -1
- package/dist/chunk-WCTHZKU7.js +37 -0
- package/dist/{chunk-TT3WFS6S.js → chunk-YOKHBAIH.js} +11 -11
- package/dist/components/alert-dialog.js +1 -1
- package/dist/components/alert.d.ts +2 -2
- package/dist/components/avatar.d.ts +3 -3
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.js +1 -1
- package/dist/components/calendar.js +1 -1
- package/dist/components/card.d.ts +4 -4
- package/dist/components/carousel.js +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/command.d.ts +2 -2
- package/dist/components/concept-compare-rail.d.ts +50 -0
- package/dist/components/concept-compare-rail.js +5 -0
- package/dist/components/concept-compare.d.ts +75 -38
- package/dist/components/concept-compare.js +209 -133
- package/dist/components/concept-convergence.d.ts +41 -0
- package/dist/components/concept-convergence.js +53 -0
- package/dist/components/convergence.d.ts +25 -0
- package/dist/components/convergence.js +4 -0
- package/dist/components/dialog.d.ts +2 -2
- package/dist/components/empty-state.js +1 -1
- package/dist/components/event-card.js +1 -1
- package/dist/components/event-compact-row.js +1 -1
- package/dist/components/event-detail-panel.js +2 -2
- package/dist/components/event-index-row.js +1 -1
- package/dist/components/event-list-row-wide.js +2 -2
- package/dist/components/event-list-row.js +2 -2
- package/dist/components/explainer-steps.d.ts +34 -0
- package/dist/components/explainer-steps.js +36 -0
- package/dist/components/filter-category-row.js +1 -1
- package/dist/components/glass-ground.d.ts +61 -0
- package/dist/components/glass-ground.js +3 -0
- package/dist/components/haptic-button.js +1 -1
- package/dist/components/hub-surface.js +11 -1
- package/dist/components/hue-chip.d.ts +70 -0
- package/dist/components/hue-chip.js +3 -0
- package/dist/components/input-group.d.ts +2 -2
- package/dist/components/input.d.ts +1 -1
- package/dist/components/item.d.ts +4 -4
- package/dist/components/kbd.d.ts +2 -2
- package/dist/components/kitchen-dossier.d.ts +88 -0
- package/dist/components/kitchen-dossier.js +186 -0
- package/dist/components/link-button.js +1 -1
- package/dist/components/menu-dead-end.d.ts +56 -0
- package/dist/components/menu-dead-end.js +49 -0
- package/dist/components/menu-family-block.d.ts +98 -0
- package/dist/components/menu-family-block.js +153 -0
- package/dist/components/menu-family-card.d.ts +33 -27
- package/dist/components/menu-family-card.js +41 -85
- package/dist/components/menu-field.js +92 -2
- package/dist/components/menu-filter-chips.d.ts +86 -0
- package/dist/components/menu-filter-chips.js +122 -0
- package/dist/components/menu-group-rows.d.ts +53 -0
- package/dist/components/menu-group-rows.js +67 -0
- package/dist/components/menu-hub-hero.js +10 -5
- package/dist/components/menu-index-header.d.ts +37 -0
- package/dist/components/menu-index-header.js +68 -0
- package/dist/components/menu-index-list.d.ts +48 -0
- package/dist/components/menu-index-list.js +96 -0
- package/dist/components/menu-intent-hero.d.ts +69 -0
- package/dist/components/menu-intent-hero.js +87 -0
- package/dist/components/menu-item.js +3 -3
- package/dist/components/menu-kitchen-list.d.ts +82 -0
- package/dist/components/menu-kitchen-list.js +5 -0
- package/dist/components/menu-mocks.d.ts +37 -2
- package/dist/components/menu-mocks.js +152 -27
- package/dist/components/menu-types.d.ts +182 -6
- package/dist/components/motion-icon-controls.js +2 -2
- package/dist/components/motion-icon-set.js +6 -6
- package/dist/components/motion-icon.d.ts +22 -1
- package/dist/components/motion-icon.js +1 -1
- package/dist/components/multi-select-combobox.js +2 -2
- package/dist/components/native-select.d.ts +2 -2
- package/dist/components/pagination.js +1 -1
- package/dist/components/photo-ground.d.ts +64 -0
- package/dist/components/photo-ground.js +3 -0
- package/dist/components/place-about-tab.js +2 -2
- package/dist/components/place-details-mobile.js +3 -3
- package/dist/components/place-types.d.ts +2 -2
- package/dist/components/qa-block.d.ts +36 -0
- package/dist/components/qa-block.js +24 -0
- package/dist/components/scroll-fade.js +3 -121
- package/dist/components/searchable-select.js +1 -1
- package/dist/components/select.d.ts +1 -1
- package/dist/components/signature-chip.d.ts +2 -2
- package/dist/components/signature-chip.js +2 -2
- package/dist/components/sliding-panels.js +1 -1
- package/dist/components/snap-rail.d.ts +26 -3
- package/dist/components/snap-rail.js +3 -109
- package/dist/components/spinner.d.ts +4 -4
- package/dist/components/story.d.ts +34 -0
- package/dist/components/story.js +3 -0
- package/dist/components/tag.d.ts +4 -4
- package/dist/components/text.d.ts +5 -5
- package/dist/components/toggle.d.ts +1 -1
- package/dist/components/top-comparison.d.ts +28 -0
- package/dist/components/top-comparison.js +76 -0
- package/dist/components/top-cross-link.d.ts +34 -0
- package/dist/components/top-cross-link.js +101 -0
- package/dist/components/top-ranking-entry.d.ts +53 -0
- package/dist/components/top-ranking-entry.js +217 -0
- package/dist/components/top-ranking-hero.d.ts +61 -0
- package/dist/components/top-ranking-hero.js +99 -0
- package/dist/components/top-ranking-legend.d.ts +69 -0
- package/dist/components/top-ranking-legend.js +124 -0
- package/dist/components/top-types.d.ts +109 -0
- package/dist/components/top-types.js +1 -0
- package/dist/components/venue-grade-dimensions.d.ts +3 -1
- package/dist/components/venue-grade-dimensions.js +1 -1
- package/dist/components/venue-quotes.d.ts +1 -1
- package/dist/components/venue-quotes.js +1 -1
- package/dist/components/venue-wall.js +5 -3
- package/dist/components/weekday-theme-banner.js +1 -1
- package/dist/components/weekend-panel.js +2 -2
- package/package.json +1 -1
- package/src/components/badge.tsx +1 -1
- package/src/components/button.tsx +2 -2
- package/src/components/concept-compare-rail.tsx +132 -0
- package/src/components/concept-compare.stories.tsx +122 -54
- package/src/components/concept-compare.tsx +368 -196
- package/src/components/concept-convergence.stories.tsx +53 -0
- package/src/components/concept-convergence.tsx +90 -0
- package/src/components/convergence.stories.tsx +54 -0
- package/src/components/convergence.tsx +177 -0
- package/src/components/explainer-steps.stories.tsx +46 -0
- package/src/components/explainer-steps.tsx +74 -0
- package/src/components/glass-ground.tsx +104 -0
- package/src/components/hub-surface.tsx +11 -1
- package/src/components/hue-chip.stories.tsx +76 -0
- package/src/components/hue-chip.test.tsx +62 -0
- package/src/components/hue-chip.tsx +99 -0
- package/src/components/kitchen-dossier.stories.tsx +108 -0
- package/src/components/kitchen-dossier.tsx +321 -0
- package/src/components/menu-dead-end.stories.tsx +67 -0
- package/src/components/menu-dead-end.tsx +127 -0
- package/src/components/menu-family-block.stories.tsx +91 -0
- package/src/components/menu-family-block.tsx +303 -0
- package/src/components/menu-family-card.stories.tsx +43 -35
- package/src/components/menu-family-card.tsx +115 -142
- package/src/components/menu-filter-chips.stories.tsx +107 -0
- package/src/components/menu-filter-chips.tsx +238 -0
- package/src/components/menu-group-rows.stories.tsx +54 -0
- package/src/components/menu-group-rows.tsx +133 -0
- package/src/components/menu-hub-hero.test.tsx +39 -0
- package/src/components/menu-hub-hero.tsx +17 -5
- package/src/components/menu-index-header.stories.tsx +72 -0
- package/src/components/menu-index-header.tsx +125 -0
- package/src/components/menu-index-list.stories.tsx +50 -0
- package/src/components/menu-index-list.tsx +149 -0
- package/src/components/menu-intent-hero.stories.tsx +67 -0
- package/src/components/menu-intent-hero.tsx +189 -0
- package/src/components/menu-kitchen-list.stories.tsx +67 -0
- package/src/components/menu-kitchen-list.test.tsx +78 -0
- package/src/components/menu-kitchen-list.tsx +284 -0
- package/src/components/menu-mocks.ts +198 -23
- package/src/components/menu-types.ts +189 -6
- package/src/components/motion-icon-controls.tsx +11 -11
- package/src/components/motion-icon-set.tsx +6 -5
- package/src/components/motion-icon.test.tsx +23 -1
- package/src/components/motion-icon.tsx +20 -0
- package/src/components/photo-ground.tsx +147 -0
- package/src/components/place-types.ts +2 -2
- package/src/components/qa-block.stories.tsx +43 -0
- package/src/components/qa-block.tsx +60 -0
- package/src/components/signature-chip.tsx +3 -3
- package/src/components/snap-rail.tsx +58 -15
- package/src/components/story.tsx +225 -0
- package/src/components/top-comparison.stories.tsx +78 -0
- package/src/components/top-comparison.tsx +151 -0
- package/src/components/top-cross-link.stories.tsx +84 -0
- package/src/components/top-cross-link.tsx +171 -0
- package/src/components/top-ranking-entry.stories.tsx +171 -0
- package/src/components/top-ranking-entry.test.tsx +105 -0
- package/src/components/top-ranking-entry.tsx +425 -0
- package/src/components/top-ranking-hero.stories.tsx +76 -0
- package/src/components/top-ranking-hero.tsx +218 -0
- package/src/components/top-ranking-legend.stories.tsx +78 -0
- package/src/components/top-ranking-legend.tsx +239 -0
- package/src/components/top-types.ts +110 -0
- package/src/components/venue-grade-dimensions.tsx +2 -2
- package/src/components/venue-quotes.stories.tsx +1 -1
- package/src/components/venue-quotes.tsx +4 -2
- package/src/components/venue-wall.tsx +9 -4
- package/src/components/weekday-theme-banner.tsx +1 -1
- package/dist/chunk-THOVPZNN.js +0 -37
- package/dist/chunk-YS6BHKZO.js +0 -92
- package/dist/components/ranked-venue-list.d.ts +0 -49
- package/dist/components/ranked-venue-list.js +0 -87
- package/dist/components/signature-line-list.d.ts +0 -45
- package/dist/components/signature-line-list.js +0 -99
- package/dist/components/venue-busyness-strip.d.ts +0 -35
- package/dist/components/venue-busyness-strip.js +0 -37
- package/dist/components/venue-signature-block.d.ts +0 -39
- package/dist/components/venue-signature-block.js +0 -6
- package/dist/components/venue-spotlight.d.ts +0 -74
- package/dist/components/venue-spotlight.js +0 -138
- package/src/components/ranked-venue-list.stories.tsx +0 -80
- package/src/components/ranked-venue-list.tsx +0 -177
- package/src/components/signature-line-list.stories.tsx +0 -85
- package/src/components/signature-line-list.tsx +0 -136
- package/src/components/venue-busyness-strip.stories.tsx +0 -66
- package/src/components/venue-busyness-strip.tsx +0 -64
- package/src/components/venue-signature-block.stories.tsx +0 -68
- package/src/components/venue-signature-block.tsx +0 -71
- package/src/components/venue-spotlight.stories.tsx +0 -141
- package/src/components/venue-spotlight.tsx +0 -236
- package/dist/{chunk-XWMRABZW.js → chunk-HSIYYA2E.js} +1 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { Separator } from './chunk-WSRWFA6K.js';
|
|
2
|
+
import { Skeleton } from './chunk-QXHMPJ35.js';
|
|
3
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
4
|
+
import { __objRest, __spreadValues } from './chunk-3GWWZKX7.js';
|
|
5
|
+
import { Star, Clock, Check, MessageSquare, ChevronRight } from 'lucide-react';
|
|
6
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function DefaultLink(_a) {
|
|
9
|
+
var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
|
|
10
|
+
return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
|
|
11
|
+
}
|
|
12
|
+
function MenuKitchenList({
|
|
13
|
+
kitchens,
|
|
14
|
+
labels,
|
|
15
|
+
onShowMore,
|
|
16
|
+
linkComponent = DefaultLink,
|
|
17
|
+
className
|
|
18
|
+
}) {
|
|
19
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col", className), children: [
|
|
20
|
+
/* @__PURE__ */ jsx("ol", { children: kitchens.map((kitchen, index) => /* @__PURE__ */ jsxs("li", { className: "[&:first-child>div]:pt-0", children: [
|
|
21
|
+
index > 0 && /* @__PURE__ */ jsx(Separator, {}),
|
|
22
|
+
/* @__PURE__ */ jsx(KitchenRow, { kitchen, labels, linkComponent })
|
|
23
|
+
] }, kitchen.place.slug)) }),
|
|
24
|
+
onShowMore && labels.showMore && /* @__PURE__ */ jsx(
|
|
25
|
+
"button",
|
|
26
|
+
{
|
|
27
|
+
type: "button",
|
|
28
|
+
onClick: onShowMore,
|
|
29
|
+
className: "mt-2 self-start rounded-md py-2 text-[13px] font-bold text-accent transition-colors hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none",
|
|
30
|
+
children: labels.showMore
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
] });
|
|
34
|
+
}
|
|
35
|
+
function KitchenRow({
|
|
36
|
+
kitchen,
|
|
37
|
+
labels,
|
|
38
|
+
linkComponent: LinkComponent
|
|
39
|
+
}) {
|
|
40
|
+
const { place, dish } = kitchen;
|
|
41
|
+
const openNow = place.open_now === true;
|
|
42
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative flex flex-wrap items-center gap-[11px] py-3 transition-colors hover:bg-muted/30 motion-reduce:transition-none lg:flex-nowrap lg:gap-4 lg:py-3.5", children: [
|
|
43
|
+
/* @__PURE__ */ jsx(
|
|
44
|
+
LinkComponent,
|
|
45
|
+
{
|
|
46
|
+
href: kitchen.href,
|
|
47
|
+
"aria-label": labels.openVenue(place.name),
|
|
48
|
+
className: "absolute inset-0 z-[1] rounded-xl focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
|
|
49
|
+
}
|
|
50
|
+
),
|
|
51
|
+
/* @__PURE__ */ jsxs("span", { className: "relative h-[46px] w-[46px] shrink-0 overflow-hidden rounded-[11px] bg-[repeating-linear-gradient(135deg,oklch(0.78_0.018_55)_0_8px,oklch(0.84_0.012_58)_8px_16px)] lg:h-[58px] lg:w-[58px] lg:rounded-[13px]", children: [
|
|
52
|
+
place.thumbnail_url && // eslint-disable-next-line @next/next/no-img-element
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
"img",
|
|
55
|
+
{
|
|
56
|
+
src: place.thumbnail_url,
|
|
57
|
+
alt: "",
|
|
58
|
+
loading: "lazy",
|
|
59
|
+
decoding: "async",
|
|
60
|
+
className: "h-full w-full object-cover"
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
/* @__PURE__ */ jsx(
|
|
64
|
+
"span",
|
|
65
|
+
{
|
|
66
|
+
title: openNow ? labels.openNow : void 0,
|
|
67
|
+
className: cn(
|
|
68
|
+
"absolute right-[5px] top-[5px] h-[7px] w-[7px] rounded-full ring-2 ring-white/85",
|
|
69
|
+
openNow ? "bg-[var(--free,oklch(0.55_0.13_155))]" : "bg-[oklch(0.8_0.01_60)]"
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
] }),
|
|
74
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5 lg:w-[226px] lg:flex-none", children: [
|
|
75
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-[14.5px] font-bold tracking-[-0.01em] lg:text-[15.5px]", children: place.name }),
|
|
76
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 truncate text-xs text-muted-foreground", children: [
|
|
77
|
+
place.rating && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
78
|
+
/* @__PURE__ */ jsx(Star, { className: "h-[11px] w-[11px] shrink-0", "aria-hidden": true }),
|
|
79
|
+
place.rating.rating,
|
|
80
|
+
kitchen.metaLabel && " \xB7 "
|
|
81
|
+
] }),
|
|
82
|
+
kitchen.metaLabel
|
|
83
|
+
] }),
|
|
84
|
+
kitchen.hoursLabel && /* @__PURE__ */ jsxs(
|
|
85
|
+
"span",
|
|
86
|
+
{
|
|
87
|
+
className: cn(
|
|
88
|
+
"mt-[3px] inline-flex h-[21px] w-max items-center gap-[5px] rounded-md px-2 text-[10.5px] font-bold",
|
|
89
|
+
openNow ? "bg-[oklch(0.96_0.02_155)] text-[var(--free,oklch(0.45_0.13_155))]" : "bg-muted text-muted-foreground"
|
|
90
|
+
),
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsx(Clock, { className: "h-2.5 w-2.5 shrink-0", "aria-hidden": true }),
|
|
93
|
+
kitchen.hoursLabel
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
] }),
|
|
98
|
+
dish && /* DESKTOP ONLY, where it is a column of its own beside the venue.
|
|
99
|
+
On the phone it wrapped to a third line under the row — kicker, dish,
|
|
100
|
+
mention count — which turned a four-line venue row into a seven-line
|
|
101
|
+
block and, ten rows down, buried the venue names the list exists to
|
|
102
|
+
be scanned for. The dish is not what a reader is choosing here; it is
|
|
103
|
+
one tap away on the venue's own page, with room to state it.
|
|
104
|
+
|
|
105
|
+
`order-5` puts it last in the visual order without moving it in the
|
|
106
|
+
DOM, where it belongs to the venue. */
|
|
107
|
+
/* @__PURE__ */ jsxs("div", { className: "hidden min-w-0 basis-full pl-[57px] lg:order-none lg:block lg:flex-1 lg:basis-auto lg:pl-0", children: [
|
|
108
|
+
/* @__PURE__ */ jsxs(
|
|
109
|
+
"span",
|
|
110
|
+
{
|
|
111
|
+
className: cn(
|
|
112
|
+
"flex items-center gap-1.5 text-[9px] font-extrabold uppercase tracking-[0.1em]",
|
|
113
|
+
dish.matched ? "text-accent" : "text-[oklch(0.72_0.01_60)]"
|
|
114
|
+
),
|
|
115
|
+
children: [
|
|
116
|
+
dish.kicker,
|
|
117
|
+
dish.matched && dish.matchLabel && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-[5px] bg-accent-subtle px-1.5 py-px text-[10.5px] font-bold normal-case tracking-normal text-accent", children: [
|
|
118
|
+
/* @__PURE__ */ jsx(Check, { className: "h-2.5 w-2.5 shrink-0", "aria-hidden": true }),
|
|
119
|
+
dish.matchLabel
|
|
120
|
+
] })
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
),
|
|
124
|
+
dish.href ? /* @__PURE__ */ jsx(
|
|
125
|
+
LinkComponent,
|
|
126
|
+
{
|
|
127
|
+
href: dish.href,
|
|
128
|
+
"aria-label": labels.openDish(dish.name),
|
|
129
|
+
className: "relative z-[2] mt-0.5 block truncate font-serif text-[13.5px] italic underline decoration-[oklch(0.84_0.01_60)] decoration-1 underline-offset-[3px] transition-colors hover:text-accent hover:decoration-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none lg:text-[15px]",
|
|
130
|
+
children: dish.name
|
|
131
|
+
}
|
|
132
|
+
) : /* @__PURE__ */ jsx("span", { className: "mt-0.5 block truncate font-serif text-[13.5px] italic lg:text-[15px]", children: dish.name }),
|
|
133
|
+
dish.meta && /* @__PURE__ */ jsxs("span", { className: "mt-[3px] flex items-center gap-1 text-[11.5px] text-muted-foreground", children: [
|
|
134
|
+
!dish.matched && /* @__PURE__ */ jsx(MessageSquare, { className: "h-2.5 w-2.5 shrink-0", "aria-hidden": true }),
|
|
135
|
+
dish.meta
|
|
136
|
+
] })
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex shrink-0 items-center gap-[11px] lg:ml-0", children: [
|
|
139
|
+
kitchen.priceLabel && /* @__PURE__ */ jsx("span", { className: "text-base font-extrabold tabular-nums text-accent", children: kitchen.priceLabel }),
|
|
140
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "h-[15px] w-[15px] shrink-0 text-muted-foreground", "aria-hidden": true })
|
|
141
|
+
] })
|
|
142
|
+
] });
|
|
143
|
+
}
|
|
144
|
+
function MenuKitchenListSkeleton({
|
|
145
|
+
rows = 10,
|
|
146
|
+
className
|
|
147
|
+
}) {
|
|
148
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, index) => /* @__PURE__ */ jsxs("div", { children: [
|
|
149
|
+
index > 0 && /* @__PURE__ */ jsx(Separator, {}),
|
|
150
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-[11px] py-3 lg:flex-nowrap lg:gap-4 lg:py-3.5", children: [
|
|
151
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[46px] w-[46px] rounded-[11px] lg:h-[58px] lg:w-[58px] lg:rounded-[13px]" }),
|
|
152
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5 lg:w-[226px] lg:flex-none", children: [
|
|
153
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-[60%]" }),
|
|
154
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-[45%]" }),
|
|
155
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[21px] w-[120px] rounded-md" })
|
|
156
|
+
] }),
|
|
157
|
+
/* @__PURE__ */ jsxs("div", { className: "hidden min-w-0 basis-full pl-[57px] lg:order-none lg:block lg:flex-1 lg:basis-auto lg:pl-0", children: [
|
|
158
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-2.5 w-[90px]" }),
|
|
159
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mt-1.5 h-4 w-[70%]" }),
|
|
160
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mt-1.5 h-3 w-[40%]" })
|
|
161
|
+
] }),
|
|
162
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ml-auto h-5 w-[56px] lg:ml-0" })
|
|
163
|
+
] })
|
|
164
|
+
] }, index)) });
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export { MenuKitchenList, MenuKitchenListSkeleton };
|
|
@@ -12,7 +12,7 @@ var badgeVariants = cva(
|
|
|
12
12
|
secondary: "border-transparent bg-secondary text-secondary-foreground",
|
|
13
13
|
destructive: "border-transparent bg-destructive text-destructive-foreground",
|
|
14
14
|
outline: "text-foreground border-border",
|
|
15
|
-
overlay: "border-transparent bg-foreground/
|
|
15
|
+
overlay: "border-transparent bg-foreground/80 text-background",
|
|
16
16
|
glass: "glass text-foreground border-border/50",
|
|
17
17
|
success: "border-transparent bg-success text-success-foreground",
|
|
18
18
|
warning: "border-transparent bg-warning text-warning-foreground",
|
|
@@ -0,0 +1,121 @@
|
|
|
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 };
|
|
@@ -8,7 +8,7 @@ function VenueQuotes({ quotes, onCite, citeLabel, limit, className }) {
|
|
|
8
8
|
var _a, _b;
|
|
9
9
|
const citations = (_b = (_a = quote.review_ids) == null ? void 0 : _a.length) != null ? _b : 0;
|
|
10
10
|
const canCite = !!onCite && citations > 0;
|
|
11
|
-
const text = /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 border-border pl-3 font-serif text-[13px]
|
|
11
|
+
const text = /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 border-border pl-3 font-serif text-[13px] leading-[1.45] text-muted-foreground", children: `\u201C${quote.text}\u201D` });
|
|
12
12
|
if (!canCite) return /* @__PURE__ */ jsx("div", { children: text }, index);
|
|
13
13
|
return /* @__PURE__ */ jsx(
|
|
14
14
|
"button",
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
var PHOTO_GROUND = "bg-[oklch(0.21_0.012_55)]";
|
|
5
|
+
var OVERLAY = "absolute inset-0 bg-[oklch(0.16_0.012_55_/_0.5)]";
|
|
6
|
+
function PhotoGround({
|
|
7
|
+
photos,
|
|
8
|
+
initials,
|
|
9
|
+
mode = "mosaic",
|
|
10
|
+
active = 0,
|
|
11
|
+
mosaicClassName,
|
|
12
|
+
phoneTiles,
|
|
13
|
+
gradient,
|
|
14
|
+
overlay,
|
|
15
|
+
overlayClassName,
|
|
16
|
+
loading = "lazy",
|
|
17
|
+
className
|
|
18
|
+
}) {
|
|
19
|
+
const initialOf = (index) => {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
return typeof initials === "string" ? initials : (_b = (_a = initials[index]) != null ? _a : initials[0]) != null ? _b : "";
|
|
22
|
+
};
|
|
23
|
+
const hasAnyPhoto = photos.some(Boolean);
|
|
24
|
+
const slot = (index, extra) => {
|
|
25
|
+
const src = photos[index];
|
|
26
|
+
return /* @__PURE__ */ jsx("span", { className: cn("relative block overflow-hidden", extra), children: src ? (
|
|
27
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
28
|
+
/* @__PURE__ */ jsx(
|
|
29
|
+
"img",
|
|
30
|
+
{
|
|
31
|
+
src,
|
|
32
|
+
alt: "",
|
|
33
|
+
loading: index === 0 ? loading : "lazy",
|
|
34
|
+
decoding: "async",
|
|
35
|
+
className: "absolute inset-0 h-full w-full object-cover"
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
) : (
|
|
39
|
+
/* Never a grey box: the ground with the venue's initial. A missing
|
|
40
|
+
photograph is not a broken image, and drawing one as a placeholder
|
|
41
|
+
makes a real city look unfinished. */
|
|
42
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "font-serif text-[64px] font-semibold leading-none text-white/15", children: initialOf(index) }) })
|
|
43
|
+
) }, index);
|
|
44
|
+
};
|
|
45
|
+
return /* @__PURE__ */ jsxs("span", { "aria-hidden": true, className: cn("absolute inset-0 block", PHOTO_GROUND, className), children: [
|
|
46
|
+
mode === "mosaic" ? /* @__PURE__ */ jsx("span", { className: cn("absolute inset-0 grid gap-px", mosaicClassName), children: photos.map(
|
|
47
|
+
(_, index) => slot(index, phoneTiles !== void 0 && index >= phoneTiles ? "hidden lg:block" : void 0)
|
|
48
|
+
) }) : (
|
|
49
|
+
/* Stacked, not swapped, so the change is a cross-fade and not a flash
|
|
50
|
+
of ground between two images. */
|
|
51
|
+
photos.map(
|
|
52
|
+
(_, index) => slot(
|
|
53
|
+
index,
|
|
54
|
+
cn(
|
|
55
|
+
"absolute inset-0 transition-opacity duration-500 motion-reduce:transition-none",
|
|
56
|
+
index === active ? "opacity-100" : "opacity-0"
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
),
|
|
61
|
+
gradient && hasAnyPhoto && /* @__PURE__ */ jsx(
|
|
62
|
+
"span",
|
|
63
|
+
{
|
|
64
|
+
className: "absolute inset-0 opacity-[0.85] mix-blend-color",
|
|
65
|
+
style: { backgroundImage: gradient }
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
overlay && /* @__PURE__ */ jsx("span", { className: cn(OVERLAY, overlayClassName) })
|
|
69
|
+
] });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { PHOTO_GROUND, PhotoGround };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Badge } from './chunk-
|
|
1
|
+
import { Badge } from './chunk-2CXU5WZO.js';
|
|
2
2
|
import { cn } from './chunk-FEK5XGZW.js';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -25,7 +25,7 @@ function SignatureChip({
|
|
|
25
25
|
className: cn(
|
|
26
26
|
shared,
|
|
27
27
|
"inline-flex items-center rounded-full border border-dashed",
|
|
28
|
-
onImage ? "border-background/70 bg-foreground/
|
|
28
|
+
onImage ? "border-background/70 bg-foreground/80 text-background hover:bg-foreground/90" : "border-accent/40 text-accent hover:bg-accent/10",
|
|
29
29
|
"focus-visible:outline-none focus-visible:ring-2",
|
|
30
30
|
onImage ? "focus-visible:ring-background/70" : "focus-visible:ring-accent/40",
|
|
31
31
|
className
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from './chunk-FEK5XGZW.js';
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var DIMENSION_ORDER = [
|
|
5
5
|
"food",
|
|
6
6
|
"coffee_quality",
|
|
7
7
|
"drinks_quality",
|
|
@@ -15,7 +15,7 @@ var DEFAULT_ORDER = [
|
|
|
15
15
|
function VenueGradeDimensions({
|
|
16
16
|
dimensions,
|
|
17
17
|
labels,
|
|
18
|
-
order =
|
|
18
|
+
order = DIMENSION_ORDER,
|
|
19
19
|
formatScore,
|
|
20
20
|
className
|
|
21
21
|
}) {
|
|
@@ -55,4 +55,4 @@ function VenueGradeDimensions({
|
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export { VenueGradeDimensions };
|
|
58
|
+
export { DIMENSION_ORDER, VenueGradeDimensions };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
2
|
+
import { jsxs } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
var STRENGTH = {
|
|
5
|
+
/** A labelled facet: readable at 11.5px, still clearly the family's colour. */
|
|
6
|
+
chip: 20,
|
|
7
|
+
/** A quieter wash, for a chip that sits beside a stronger one. */
|
|
8
|
+
subtle: 12
|
|
9
|
+
};
|
|
10
|
+
function hueTint(hue, tone = "chip", base = "var(--card)") {
|
|
11
|
+
return `color-mix(in oklab, ${hue} ${STRENGTH[tone]}%, ${base})`;
|
|
12
|
+
}
|
|
13
|
+
function HueChip({
|
|
14
|
+
hue,
|
|
15
|
+
tone = "chip",
|
|
16
|
+
base = "var(--card)",
|
|
17
|
+
icon,
|
|
18
|
+
as: Tag = "span",
|
|
19
|
+
children,
|
|
20
|
+
className,
|
|
21
|
+
"aria-label": ariaLabel
|
|
22
|
+
}) {
|
|
23
|
+
return /* @__PURE__ */ jsxs(
|
|
24
|
+
Tag,
|
|
25
|
+
{
|
|
26
|
+
"aria-label": ariaLabel,
|
|
27
|
+
className: cn(
|
|
28
|
+
"inline-flex h-7 items-center gap-1.5 rounded-full px-2.5 text-[11.5px] text-foreground",
|
|
29
|
+
!hue && "bg-muted",
|
|
30
|
+
className
|
|
31
|
+
),
|
|
32
|
+
style: hue ? { backgroundColor: hueTint(hue, tone, base) } : void 0,
|
|
33
|
+
children: [
|
|
34
|
+
icon,
|
|
35
|
+
children
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { HueChip, hueTint };
|
|
@@ -0,0 +1,125 @@
|
|
|
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, onActiveChange, children } = _b, props = __objRest(_b, ["className", "itemWidth", "gap", "bleed", "dots", "dotsClassName", "onActiveChange", "children"]);
|
|
41
|
+
const railRef = React.useRef(null);
|
|
42
|
+
const [active, setActive] = React.useState(0);
|
|
43
|
+
const count = React.Children.count(children);
|
|
44
|
+
const tracks = Boolean(dots || onActiveChange);
|
|
45
|
+
const onActiveChangeRef = React.useRef(onActiveChange);
|
|
46
|
+
onActiveChangeRef.current = onActiveChange;
|
|
47
|
+
const setRefs = React.useCallback(
|
|
48
|
+
(node) => {
|
|
49
|
+
railRef.current = node;
|
|
50
|
+
if (typeof ref === "function") ref(node);
|
|
51
|
+
else if (ref) ref.current = node;
|
|
52
|
+
},
|
|
53
|
+
[ref]
|
|
54
|
+
);
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
if (!tracks) return;
|
|
57
|
+
const rail2 = railRef.current;
|
|
58
|
+
if (!rail2) return;
|
|
59
|
+
let frame = 0;
|
|
60
|
+
let last = -1;
|
|
61
|
+
const sync = () => {
|
|
62
|
+
var _a2;
|
|
63
|
+
frame = 0;
|
|
64
|
+
const origin = rail2.scrollLeft + (parseFloat(getComputedStyle(rail2).scrollPaddingLeft) || 0);
|
|
65
|
+
let best = 0;
|
|
66
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
67
|
+
Array.from(rail2.children).forEach((child, index) => {
|
|
68
|
+
const distance = Math.abs(child.offsetLeft - origin);
|
|
69
|
+
if (distance < bestDistance) {
|
|
70
|
+
bestDistance = distance;
|
|
71
|
+
best = index;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
setActive(best);
|
|
75
|
+
if (best !== last) {
|
|
76
|
+
last = best;
|
|
77
|
+
(_a2 = onActiveChangeRef.current) == null ? void 0 : _a2.call(onActiveChangeRef, best);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const onScroll = () => {
|
|
81
|
+
if (!frame) frame = requestAnimationFrame(sync);
|
|
82
|
+
};
|
|
83
|
+
sync();
|
|
84
|
+
rail2.addEventListener("scroll", onScroll, { passive: true });
|
|
85
|
+
return () => {
|
|
86
|
+
if (frame) cancelAnimationFrame(frame);
|
|
87
|
+
rail2.removeEventListener("scroll", onScroll);
|
|
88
|
+
};
|
|
89
|
+
}, [tracks, count]);
|
|
90
|
+
const rail = /* @__PURE__ */ jsx(
|
|
91
|
+
"div",
|
|
92
|
+
__spreadProps(__spreadValues({
|
|
93
|
+
ref: setRefs,
|
|
94
|
+
"data-slot": "snap-rail",
|
|
95
|
+
className: cn(snapRailVariants({ itemWidth, gap, bleed }), className)
|
|
96
|
+
}, props), {
|
|
97
|
+
children
|
|
98
|
+
})
|
|
99
|
+
);
|
|
100
|
+
if (!dots) return rail;
|
|
101
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
102
|
+
rail,
|
|
103
|
+
/* @__PURE__ */ jsx(SnapRailDots, { count, active, className: dotsClassName })
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
SnapRail.displayName = "SnapRail";
|
|
108
|
+
function SnapRailDots({
|
|
109
|
+
count,
|
|
110
|
+
active,
|
|
111
|
+
className
|
|
112
|
+
}) {
|
|
113
|
+
return /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: cn("flex justify-center gap-1.5", className), children: Array.from({ length: count }, (_, index) => /* @__PURE__ */ jsx(
|
|
114
|
+
"span",
|
|
115
|
+
{
|
|
116
|
+
className: cn(
|
|
117
|
+
"h-1.5 rounded-full transition-[width,background-color] duration-200 motion-reduce:transition-none",
|
|
118
|
+
index === active ? "w-4 bg-foreground" : "w-1.5 bg-foreground/25"
|
|
119
|
+
)
|
|
120
|
+
},
|
|
121
|
+
index
|
|
122
|
+
)) });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { SnapRail, SnapRailDots };
|