@bearmenu/ui 0.8.7 → 0.8.9
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-637L7XQ3.js → chunk-3TNPSN4D.js} +28 -9
- package/dist/chunk-62ES6N32.js +27 -0
- package/dist/chunk-AHL45DD2.js +145 -0
- package/dist/chunk-AXV5O2IZ.js +58 -0
- package/dist/chunk-IYDH5IU6.js +66 -0
- package/dist/chunk-OPVKL4VS.js +18 -0
- package/dist/chunk-Q6QH52LJ.js +38 -0
- package/dist/chunk-TH6W2PWG.js +213 -0
- package/dist/chunk-THOVPZNN.js +37 -0
- package/dist/chunk-YS6BHKZO.js +92 -0
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/category-deck.js +10 -1
- package/dist/components/command.d.ts +7 -7
- package/dist/components/concept-compare.d.ts +73 -0
- package/dist/components/concept-compare.js +162 -0
- package/dist/components/coverflow.d.ts +11 -3
- package/dist/components/coverflow.js +34 -51
- package/dist/components/date-input.d.ts +1 -1
- package/dist/components/drift-rail.d.ts +24 -10
- package/dist/components/drift-rail.js +1 -1
- package/dist/components/event-card.d.ts +8 -0
- package/dist/components/event-card.js +64 -34
- package/dist/components/event-compact-row.d.ts +33 -6
- package/dist/components/event-compact-row.js +120 -39
- package/dist/components/event-day-header.js +3 -1
- package/dist/components/event-day-separator.d.ts +7 -1
- package/dist/components/event-day-separator.js +3 -2
- package/dist/components/event-detail-panel.d.ts +171 -25
- package/dist/components/event-detail-panel.js +471 -174
- package/dist/components/event-hub-hero.d.ts +25 -4
- package/dist/components/event-hub-hero.js +89 -19
- package/dist/components/event-list-row-wide.js +1 -1
- package/dist/components/event-list-row.d.ts +19 -6
- package/dist/components/event-list-row.js +79 -35
- package/dist/components/hour-band.d.ts +38 -40
- package/dist/components/hour-band.js +55 -27
- package/dist/components/hour-group.js +1 -1
- package/dist/components/hub-surface.d.ts +27 -0
- package/dist/components/hub-surface.js +20 -0
- package/dist/components/menu-family-card.d.ts +59 -0
- package/dist/components/menu-family-card.js +121 -0
- package/dist/components/menu-field.d.ts +57 -0
- package/dist/components/menu-field.js +3 -0
- package/dist/components/menu-hub-hero.d.ts +65 -0
- package/dist/components/menu-hub-hero.js +103 -0
- package/dist/components/menu-intent-tiles.d.ts +31 -0
- package/dist/components/menu-intent-tiles.js +50 -0
- package/dist/components/menu-item.d.ts +127 -0
- package/dist/components/menu-item.js +5 -0
- package/dist/components/menu-mocks.d.ts +55 -0
- package/dist/components/menu-mocks.js +379 -0
- package/dist/components/menu-types.d.ts +245 -0
- package/dist/components/menu-types.js +1 -0
- package/dist/components/motion-icon-set.js +15 -3
- package/dist/components/open-now-list.d.ts +40 -0
- package/dist/components/open-now-list.js +69 -0
- package/dist/components/place-types.d.ts +112 -1
- package/dist/components/poster-tape.js +1 -1
- package/dist/components/poster-wall.d.ts +3 -3
- package/dist/components/poster-wall.js +73 -17
- package/dist/components/ranked-venue-list.d.ts +49 -0
- package/dist/components/ranked-venue-list.js +87 -0
- package/dist/components/section-header.d.ts +16 -1
- package/dist/components/section-header.js +26 -7
- package/dist/components/signature-chip.d.ts +37 -0
- package/dist/components/signature-chip.js +4 -0
- package/dist/components/signature-line-list.d.ts +45 -0
- package/dist/components/signature-line-list.js +99 -0
- package/dist/components/snap-rail.d.ts +54 -0
- package/dist/components/snap-rail.js +109 -0
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/stat-banner.d.ts +47 -0
- package/dist/components/stat-banner.js +61 -0
- package/dist/components/text.d.ts +3 -3
- package/dist/components/timeline-band.d.ts +20 -2
- package/dist/components/timeline-band.js +1 -1
- package/dist/components/timeline-playhead.d.ts +26 -0
- package/dist/components/timeline-playhead.js +25 -0
- package/dist/components/venue-busyness-strip.d.ts +35 -0
- package/dist/components/venue-busyness-strip.js +37 -0
- package/dist/components/venue-grade-dimensions.d.ts +36 -0
- package/dist/components/venue-grade-dimensions.js +3 -0
- package/dist/components/venue-quotes.d.ts +32 -0
- package/dist/components/venue-quotes.js +3 -0
- package/dist/components/venue-signature-block.d.ts +39 -0
- package/dist/components/venue-signature-block.js +6 -0
- package/dist/components/venue-spotlight.d.ts +74 -0
- package/dist/components/venue-spotlight.js +138 -0
- package/dist/components/venue-wall.d.ts +41 -0
- package/dist/components/venue-wall.js +118 -0
- package/dist/components/weekday-theme-banner.d.ts +70 -0
- package/dist/components/weekday-theme-banner.js +127 -0
- package/dist/components/weekend-panel.d.ts +5 -4
- package/dist/components/weekend-panel.js +85 -71
- package/dist/hooks/use-drag-swipe.d.ts +44 -0
- package/dist/hooks/use-drag-swipe.js +2 -0
- package/dist/hooks/use-media-query.d.ts +17 -0
- package/dist/hooks/use-media-query.js +2 -0
- package/package.json +1 -1
- package/src/components/category-deck.tsx +19 -8
- package/src/components/colour-dictionary.stories.tsx +227 -0
- package/src/components/concept-compare.stories.tsx +104 -0
- package/src/components/concept-compare.tsx +276 -0
- package/src/components/coverflow.test.tsx +28 -1
- package/src/components/coverflow.tsx +37 -43
- package/src/components/drift-rail.tsx +167 -42
- package/src/components/event-card.tsx +55 -10
- package/src/components/event-compact-row.stories.tsx +30 -0
- package/src/components/event-compact-row.test.tsx +49 -0
- package/src/components/event-compact-row.tsx +162 -38
- package/src/components/event-day-header.tsx +3 -1
- package/src/components/event-day-separator.tsx +8 -1
- package/src/components/event-detail-panel.stories.tsx +205 -97
- package/src/components/event-detail-panel.test.tsx +181 -0
- package/src/components/event-detail-panel.tsx +703 -185
- package/src/components/event-hub-hero.stories.tsx +30 -0
- package/src/components/event-hub-hero.tsx +102 -30
- package/src/components/event-list-row.stories.tsx +34 -0
- package/src/components/event-list-row.test.tsx +53 -0
- package/src/components/event-list-row.tsx +135 -87
- package/src/components/hour-band.stories.tsx +28 -5
- package/src/components/hour-band.tsx +90 -70
- package/src/components/hub-surface.stories.tsx +68 -0
- package/src/components/hub-surface.tsx +40 -0
- package/src/components/menu-family-card.stories.tsx +112 -0
- package/src/components/menu-family-card.tsx +211 -0
- package/src/components/menu-field.stories.tsx +74 -0
- package/src/components/menu-field.tsx +199 -0
- package/src/components/menu-hub-hero.stories.tsx +92 -0
- package/src/components/menu-hub-hero.tsx +187 -0
- package/src/components/menu-intent-tiles.stories.tsx +54 -0
- package/src/components/menu-intent-tiles.tsx +76 -0
- package/src/components/menu-item.tsx +416 -0
- package/src/components/menu-mocks.ts +417 -0
- package/src/components/menu-types.ts +259 -0
- package/src/components/motion-icon-set.tsx +30 -3
- package/src/components/open-now-list.stories.tsx +76 -0
- package/src/components/open-now-list.tsx +127 -0
- package/src/components/place-types.ts +112 -0
- package/src/components/poster-wall.test.tsx +28 -0
- package/src/components/poster-wall.tsx +96 -23
- package/src/components/ranked-venue-list.stories.tsx +80 -0
- package/src/components/ranked-venue-list.tsx +177 -0
- package/src/components/section-header.stories.tsx +24 -0
- package/src/components/section-header.test.tsx +28 -0
- package/src/components/section-header.tsx +45 -7
- package/src/components/signature-chip.tsx +77 -0
- package/src/components/signature-line-list.stories.tsx +85 -0
- package/src/components/signature-line-list.tsx +136 -0
- package/src/components/snap-rail.stories.tsx +79 -0
- package/src/components/snap-rail.test.tsx +18 -0
- package/src/components/snap-rail.tsx +148 -0
- package/src/components/stat-banner.stories.tsx +100 -0
- package/src/components/stat-banner.tsx +117 -0
- package/src/components/timeline-band.tsx +52 -12
- package/src/components/timeline-playhead.stories.tsx +30 -0
- package/src/components/timeline-playhead.test.tsx +11 -0
- package/src/components/timeline-playhead.tsx +46 -0
- package/src/components/venue-busyness-strip.stories.tsx +66 -0
- package/src/components/venue-busyness-strip.tsx +64 -0
- package/src/components/venue-grade-dimensions.stories.tsx +83 -0
- package/src/components/venue-grade-dimensions.tsx +91 -0
- package/src/components/venue-quotes.stories.tsx +59 -0
- package/src/components/venue-quotes.tsx +64 -0
- package/src/components/venue-signature-block.stories.tsx +68 -0
- package/src/components/venue-signature-block.tsx +71 -0
- package/src/components/venue-spotlight.stories.tsx +141 -0
- package/src/components/venue-spotlight.tsx +236 -0
- package/src/components/venue-wall.stories.tsx +78 -0
- package/src/components/venue-wall.tsx +185 -0
- package/src/components/weekday-theme-banner.stories.tsx +113 -0
- package/src/components/weekday-theme-banner.tsx +231 -0
- package/src/components/weekend-panel.test.tsx +43 -0
- package/src/components/weekend-panel.tsx +142 -108
- package/src/hooks/use-drag-swipe.test.tsx +66 -0
- package/src/hooks/use-drag-swipe.ts +105 -0
- package/src/hooks/use-media-query.ts +31 -0
- package/dist/chunk-GPH6L4DX.js +0 -55
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { Separator } from './chunk-WSRWFA6K.js';
|
|
2
2
|
import { Skeleton } from './chunk-QXHMPJ35.js';
|
|
3
3
|
import { cn } from './chunk-FEK5XGZW.js';
|
|
4
|
+
import { Radio } from 'lucide-react';
|
|
4
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
7
|
var LIVE_PUCK_PULSE_CLASS = "bm-timeline-live-puck-pulse";
|
|
7
|
-
|
|
8
|
+
var TIMELINE_MOBILE_GUTTER_CLASS = "w-[58px]";
|
|
9
|
+
function TimelineHourPuck({
|
|
10
|
+
time,
|
|
11
|
+
isLive,
|
|
12
|
+
liveLabel,
|
|
13
|
+
variant = "station",
|
|
14
|
+
className
|
|
15
|
+
}) {
|
|
16
|
+
const isChip = variant === "chip";
|
|
8
17
|
return /* @__PURE__ */ jsxs("span", { className: cn("relative flex justify-center", className), children: [
|
|
9
18
|
isLive && /* @__PURE__ */ jsx("style", { children: `
|
|
10
19
|
@keyframes ${LIVE_PUCK_PULSE_CLASS} {
|
|
@@ -18,23 +27,33 @@ function TimelineHourPuck({ time, isLive, liveLabel, className }) {
|
|
|
18
27
|
.${LIVE_PUCK_PULSE_CLASS} { animation: none; }
|
|
19
28
|
}
|
|
20
29
|
` }),
|
|
21
|
-
/* @__PURE__ */
|
|
30
|
+
/* @__PURE__ */ jsxs(
|
|
22
31
|
"span",
|
|
23
32
|
{
|
|
24
33
|
className: cn(
|
|
25
|
-
"whitespace-nowrap
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
"whitespace-nowrap font-mono tabular-nums",
|
|
35
|
+
isChip ? cn(
|
|
36
|
+
"inline-flex h-6 min-w-[58px] items-center justify-center gap-1 rounded-[7px] px-1 text-[12px] font-medium",
|
|
37
|
+
isLive ? cn("bg-success/10 text-success", LIVE_PUCK_PULSE_CLASS) : "bg-muted text-foreground"
|
|
38
|
+
) : cn(
|
|
39
|
+
"rounded-[7px] border bg-background px-[7px] py-[3px] text-[12.5px] font-medium",
|
|
40
|
+
isLive ? cn("border-success/40 text-success", LIVE_PUCK_PULSE_CLASS) : "border-border text-foreground"
|
|
41
|
+
)
|
|
28
42
|
),
|
|
29
|
-
children:
|
|
43
|
+
children: [
|
|
44
|
+
isChip && isLive && /* @__PURE__ */ jsx(Radio, { className: "h-2.5 w-2.5 shrink-0", "aria-hidden": true }),
|
|
45
|
+
time
|
|
46
|
+
]
|
|
30
47
|
}
|
|
31
48
|
),
|
|
32
49
|
isLive && !!liveLabel && /* @__PURE__ */ jsx(
|
|
33
50
|
"span",
|
|
34
51
|
{
|
|
35
52
|
className: cn(
|
|
36
|
-
|
|
37
|
-
|
|
53
|
+
isChip ? "sr-only" : cn(
|
|
54
|
+
"absolute top-[calc(100%+6px)] whitespace-nowrap bg-background px-1",
|
|
55
|
+
"text-[9.5px] font-extrabold tracking-[0.08em] text-success"
|
|
56
|
+
)
|
|
38
57
|
),
|
|
39
58
|
children: liveLabel
|
|
40
59
|
}
|
|
@@ -82,4 +101,4 @@ function TimelineBandSkeleton({ className }) {
|
|
|
82
101
|
] });
|
|
83
102
|
}
|
|
84
103
|
|
|
85
|
-
export { TimelineBand, TimelineBandSkeleton, TimelineHourPuck };
|
|
104
|
+
export { TIMELINE_MOBILE_GUTTER_CLASS, TimelineBand, TimelineBandSkeleton, TimelineHourPuck };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
function VenueQuotes({ quotes, onCite, citeLabel, limit, className }) {
|
|
5
|
+
const shown = typeof limit === "number" ? quotes.slice(0, limit) : quotes;
|
|
6
|
+
if (shown.length === 0) return null;
|
|
7
|
+
return /* @__PURE__ */ jsx("div", { className: cn("grid gap-3 lg:grid-cols-2", className), children: shown.map((quote, index) => {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
const citations = (_b = (_a = quote.review_ids) == null ? void 0 : _a.length) != null ? _b : 0;
|
|
10
|
+
const canCite = !!onCite && citations > 0;
|
|
11
|
+
const text = /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 border-border pl-3 font-serif text-[13px] italic leading-[1.45] text-muted-foreground", children: `\u201C${quote.text}\u201D` });
|
|
12
|
+
if (!canCite) return /* @__PURE__ */ jsx("div", { children: text }, index);
|
|
13
|
+
return /* @__PURE__ */ jsx(
|
|
14
|
+
"button",
|
|
15
|
+
{
|
|
16
|
+
type: "button",
|
|
17
|
+
onClick: () => onCite(quote),
|
|
18
|
+
"aria-label": citeLabel == null ? void 0 : citeLabel(citations),
|
|
19
|
+
className: "rounded-md text-left transition-colors hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
20
|
+
children: text
|
|
21
|
+
},
|
|
22
|
+
index
|
|
23
|
+
);
|
|
24
|
+
}) });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { VenueQuotes };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
2
|
+
import { useRef, useState, useEffect } from 'react';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var DRIFT_RAIL_DEFAULT_DURATION_SECONDS = 42;
|
|
6
|
+
var DRIFT_RAIL_RESUME_DELAY_MS = 3e3;
|
|
7
|
+
function DriftRail({
|
|
8
|
+
children,
|
|
9
|
+
reverse = false,
|
|
10
|
+
durationSeconds = DRIFT_RAIL_DEFAULT_DURATION_SECONDS,
|
|
11
|
+
pauseOnHover = true,
|
|
12
|
+
className
|
|
13
|
+
}) {
|
|
14
|
+
const scrollerRef = useRef(null);
|
|
15
|
+
const trackRef = useRef(null);
|
|
16
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
17
|
+
const [inView, setInView] = useState(true);
|
|
18
|
+
const [reducedMotion, setReducedMotion] = useState(false);
|
|
19
|
+
const heldUntil = useRef(0);
|
|
20
|
+
const mouseDrag = useRef(null);
|
|
21
|
+
const position = useRef(0);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
24
|
+
const query = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
25
|
+
setReducedMotion(query.matches);
|
|
26
|
+
const onChange = () => setReducedMotion(query.matches);
|
|
27
|
+
query.addEventListener("change", onChange);
|
|
28
|
+
return () => query.removeEventListener("change", onChange);
|
|
29
|
+
}, []);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const node = scrollerRef.current;
|
|
32
|
+
if (!node || typeof IntersectionObserver === "undefined") return void 0;
|
|
33
|
+
const observer = new IntersectionObserver(([entry]) => setInView(entry.isIntersecting), {
|
|
34
|
+
threshold: 0
|
|
35
|
+
});
|
|
36
|
+
observer.observe(node);
|
|
37
|
+
return () => observer.disconnect();
|
|
38
|
+
}, []);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const scroller = scrollerRef.current;
|
|
41
|
+
const track = trackRef.current;
|
|
42
|
+
if (!scroller || !track) return void 0;
|
|
43
|
+
let frame = 0;
|
|
44
|
+
let last = performance.now();
|
|
45
|
+
const drifting = !reducedMotion && inView && !(pauseOnHover && isHovered);
|
|
46
|
+
if (reverse && scroller.scrollLeft === 0) scroller.scrollLeft = track.scrollWidth / 2;
|
|
47
|
+
position.current = scroller.scrollLeft;
|
|
48
|
+
const tick = (now) => {
|
|
49
|
+
const half = track.scrollWidth / 2;
|
|
50
|
+
if (half > 0) {
|
|
51
|
+
const driftingNow = drifting && now >= heldUntil.current;
|
|
52
|
+
if (driftingNow) {
|
|
53
|
+
const perSecond = half / durationSeconds;
|
|
54
|
+
const delta = perSecond * (now - last) / 1e3;
|
|
55
|
+
position.current += reverse ? -delta : delta;
|
|
56
|
+
} else {
|
|
57
|
+
position.current = scroller.scrollLeft;
|
|
58
|
+
}
|
|
59
|
+
let wrapped = false;
|
|
60
|
+
if (position.current >= half) {
|
|
61
|
+
position.current -= half;
|
|
62
|
+
wrapped = true;
|
|
63
|
+
} else if (position.current < 0) {
|
|
64
|
+
position.current += half;
|
|
65
|
+
wrapped = true;
|
|
66
|
+
}
|
|
67
|
+
if (driftingNow || wrapped) scroller.scrollLeft = position.current;
|
|
68
|
+
}
|
|
69
|
+
last = now;
|
|
70
|
+
frame = requestAnimationFrame(tick);
|
|
71
|
+
};
|
|
72
|
+
frame = requestAnimationFrame(tick);
|
|
73
|
+
return () => cancelAnimationFrame(frame);
|
|
74
|
+
}, [durationSeconds, inView, isHovered, pauseOnHover, reducedMotion, reverse]);
|
|
75
|
+
const hold = () => {
|
|
76
|
+
heldUntil.current = Number.POSITIVE_INFINITY;
|
|
77
|
+
};
|
|
78
|
+
const release = () => {
|
|
79
|
+
heldUntil.current = performance.now() + DRIFT_RAIL_RESUME_DELAY_MS;
|
|
80
|
+
};
|
|
81
|
+
const onPointerDown = (event) => {
|
|
82
|
+
hold();
|
|
83
|
+
if (event.pointerType !== "mouse" || event.button !== 0 || !scrollerRef.current) return;
|
|
84
|
+
mouseDrag.current = {
|
|
85
|
+
startX: event.clientX,
|
|
86
|
+
startScroll: scrollerRef.current.scrollLeft,
|
|
87
|
+
pointerId: event.pointerId
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
const onPointerMove = (event) => {
|
|
91
|
+
var _a, _b, _c, _d;
|
|
92
|
+
const drag = mouseDrag.current;
|
|
93
|
+
if (!drag || event.pointerId !== drag.pointerId || !scrollerRef.current) return;
|
|
94
|
+
const dx = event.clientX - drag.startX;
|
|
95
|
+
if (Math.abs(dx) > 4 && !((_b = (_a = event.currentTarget).hasPointerCapture) == null ? void 0 : _b.call(_a, event.pointerId))) {
|
|
96
|
+
(_d = (_c = event.currentTarget).setPointerCapture) == null ? void 0 : _d.call(_c, event.pointerId);
|
|
97
|
+
event.currentTarget.dataset.dragging = "true";
|
|
98
|
+
}
|
|
99
|
+
scrollerRef.current.scrollLeft = drag.startScroll - dx;
|
|
100
|
+
};
|
|
101
|
+
const onPointerEnd = (event) => {
|
|
102
|
+
var _a, _b;
|
|
103
|
+
release();
|
|
104
|
+
const drag = mouseDrag.current;
|
|
105
|
+
mouseDrag.current = null;
|
|
106
|
+
if (drag && ((_b = (_a = event.currentTarget).hasPointerCapture) == null ? void 0 : _b.call(_a, event.pointerId))) {
|
|
107
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
108
|
+
}
|
|
109
|
+
delete event.currentTarget.dataset.dragging;
|
|
110
|
+
};
|
|
111
|
+
const onClickCapture = (event) => {
|
|
112
|
+
if (event.currentTarget.dataset.dragging === "true") {
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
event.stopPropagation();
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
return /* @__PURE__ */ jsx(
|
|
118
|
+
"div",
|
|
119
|
+
{
|
|
120
|
+
ref: scrollerRef,
|
|
121
|
+
onMouseEnter: () => setIsHovered(true),
|
|
122
|
+
onMouseLeave: () => setIsHovered(false),
|
|
123
|
+
onPointerDown,
|
|
124
|
+
onPointerMove,
|
|
125
|
+
onPointerUp: onPointerEnd,
|
|
126
|
+
onPointerCancel: onPointerEnd,
|
|
127
|
+
onWheel: () => {
|
|
128
|
+
release();
|
|
129
|
+
},
|
|
130
|
+
onDragStart: (event) => event.preventDefault(),
|
|
131
|
+
onClickCapture,
|
|
132
|
+
className: cn(
|
|
133
|
+
"overflow-x-auto overflow-y-hidden py-1.5 scrollbar-hide [touch-action:pan-x]",
|
|
134
|
+
"cursor-grab select-none data-[dragging=true]:cursor-grabbing",
|
|
135
|
+
className
|
|
136
|
+
),
|
|
137
|
+
children: /* @__PURE__ */ jsxs("div", { ref: trackRef, className: "flex w-max items-stretch gap-3.5", children: [
|
|
138
|
+
children,
|
|
139
|
+
/* @__PURE__ */ jsx("div", { className: "contents", "aria-hidden": "true", children })
|
|
140
|
+
] })
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export { DriftRail };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
var DEFAULT_ORDER = [
|
|
5
|
+
"food",
|
|
6
|
+
"coffee_quality",
|
|
7
|
+
"drinks_quality",
|
|
8
|
+
"service",
|
|
9
|
+
"value",
|
|
10
|
+
"ambiance",
|
|
11
|
+
"portion",
|
|
12
|
+
"consistency",
|
|
13
|
+
"cleanliness"
|
|
14
|
+
];
|
|
15
|
+
function VenueGradeDimensions({
|
|
16
|
+
dimensions,
|
|
17
|
+
labels,
|
|
18
|
+
order = DEFAULT_ORDER,
|
|
19
|
+
formatScore,
|
|
20
|
+
className
|
|
21
|
+
}) {
|
|
22
|
+
const present = order.map((key) => ({ key, value: dimensions[key] })).filter(
|
|
23
|
+
(entry) => typeof entry.value === "number"
|
|
24
|
+
);
|
|
25
|
+
if (present.length === 0) return null;
|
|
26
|
+
return /* @__PURE__ */ jsx(
|
|
27
|
+
"dl",
|
|
28
|
+
{
|
|
29
|
+
className: cn(
|
|
30
|
+
"grid grid-cols-3 gap-2.5 sm:grid-cols-4 lg:flex lg:gap-2.5",
|
|
31
|
+
className
|
|
32
|
+
),
|
|
33
|
+
children: present.map(({ key, value }) => {
|
|
34
|
+
var _a;
|
|
35
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 lg:flex-1", children: [
|
|
36
|
+
/* @__PURE__ */ jsx("dd", { className: "text-[15px] font-extrabold tracking-[-0.02em] tabular-nums", children: formatScore(value) }),
|
|
37
|
+
/* @__PURE__ */ jsx(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
"aria-hidden": true,
|
|
41
|
+
className: "relative block h-[3px] overflow-hidden rounded-full bg-muted",
|
|
42
|
+
children: /* @__PURE__ */ jsx(
|
|
43
|
+
"span",
|
|
44
|
+
{
|
|
45
|
+
className: "absolute inset-y-0 left-0 rounded-full bg-[var(--gradient-primary,currentColor)]",
|
|
46
|
+
style: { width: `${Math.min(100, Math.max(0, value))}%` }
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
),
|
|
51
|
+
/* @__PURE__ */ jsx("dt", { className: "text-[10.5px] text-muted-foreground", children: (_a = labels[key]) != null ? _a : key })
|
|
52
|
+
] }, key);
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { VenueGradeDimensions };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { useState, useRef, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
function useDragSwipe({ threshold = 40, onSwipe, disabled }) {
|
|
4
|
+
const [dragX, setDragX] = useState(0);
|
|
5
|
+
const startX = useRef(null);
|
|
6
|
+
const pointerId = useRef(null);
|
|
7
|
+
const didDrag = useRef(false);
|
|
8
|
+
const onPointerDown = useCallback(
|
|
9
|
+
(event) => {
|
|
10
|
+
if (disabled || event.button !== 0) return;
|
|
11
|
+
startX.current = event.clientX;
|
|
12
|
+
pointerId.current = event.pointerId;
|
|
13
|
+
didDrag.current = false;
|
|
14
|
+
},
|
|
15
|
+
[disabled]
|
|
16
|
+
);
|
|
17
|
+
const onPointerMove = useCallback((event) => {
|
|
18
|
+
var _a, _b;
|
|
19
|
+
if (startX.current === null || event.pointerId !== pointerId.current) return;
|
|
20
|
+
const dx = event.clientX - startX.current;
|
|
21
|
+
if (!didDrag.current && Math.abs(dx) > 6) {
|
|
22
|
+
didDrag.current = true;
|
|
23
|
+
(_b = (_a = event.currentTarget).setPointerCapture) == null ? void 0 : _b.call(_a, event.pointerId);
|
|
24
|
+
}
|
|
25
|
+
if (didDrag.current) setDragX(dx);
|
|
26
|
+
}, []);
|
|
27
|
+
const end = useCallback(
|
|
28
|
+
(event, cancelled) => {
|
|
29
|
+
var _a, _b;
|
|
30
|
+
if (startX.current === null || event.pointerId !== pointerId.current) return;
|
|
31
|
+
const dx = event.clientX - startX.current;
|
|
32
|
+
startX.current = null;
|
|
33
|
+
pointerId.current = null;
|
|
34
|
+
if ((_b = (_a = event.currentTarget).hasPointerCapture) == null ? void 0 : _b.call(_a, event.pointerId)) {
|
|
35
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
36
|
+
}
|
|
37
|
+
setDragX(0);
|
|
38
|
+
if (!cancelled && didDrag.current && Math.abs(dx) >= threshold) {
|
|
39
|
+
onSwipe(dx < 0 ? 1 : -1);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
[onSwipe, threshold]
|
|
43
|
+
);
|
|
44
|
+
const onPointerUp = useCallback((event) => end(event, false), [end]);
|
|
45
|
+
const onPointerCancel = useCallback(
|
|
46
|
+
(event) => end(event, true),
|
|
47
|
+
[end]
|
|
48
|
+
);
|
|
49
|
+
const onDragStart = useCallback((event) => {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
}, []);
|
|
52
|
+
const onClickCapture = useCallback((event) => {
|
|
53
|
+
if (didDrag.current) {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
event.stopPropagation();
|
|
56
|
+
didDrag.current = false;
|
|
57
|
+
}
|
|
58
|
+
}, []);
|
|
59
|
+
return {
|
|
60
|
+
dragX,
|
|
61
|
+
isDragging: dragX !== 0,
|
|
62
|
+
handlers: { onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onClickCapture, onDragStart }
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { useDragSwipe };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useSyncExternalStore } from 'react';
|
|
2
|
+
|
|
3
|
+
function useMediaQuery(query) {
|
|
4
|
+
return useSyncExternalStore(
|
|
5
|
+
(onChange) => {
|
|
6
|
+
if (typeof window.matchMedia !== "function") return () => {
|
|
7
|
+
};
|
|
8
|
+
const mql = window.matchMedia(query);
|
|
9
|
+
mql.addEventListener("change", onChange);
|
|
10
|
+
return () => mql.removeEventListener("change", onChange);
|
|
11
|
+
},
|
|
12
|
+
() => typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false,
|
|
13
|
+
() => false
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
var DESKTOP_MEDIA_QUERY = "(min-width: 1024px)";
|
|
17
|
+
|
|
18
|
+
export { DESKTOP_MEDIA_QUERY, useMediaQuery };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Badge } from './chunk-UKBNQO6Q.js';
|
|
2
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
function SignatureChip({
|
|
6
|
+
label,
|
|
7
|
+
onEvidence,
|
|
8
|
+
surface = "canvas",
|
|
9
|
+
className
|
|
10
|
+
}) {
|
|
11
|
+
const shared = "h-4 shrink-0 px-1.5 text-[10px] font-medium uppercase tracking-wider";
|
|
12
|
+
const onImage = surface === "image";
|
|
13
|
+
if (!onEvidence) {
|
|
14
|
+
return /* @__PURE__ */ jsx(Badge, { variant: onImage ? "overlay" : "secondary", className: cn(shared, className), children: label });
|
|
15
|
+
}
|
|
16
|
+
return /* @__PURE__ */ jsx(
|
|
17
|
+
"button",
|
|
18
|
+
{
|
|
19
|
+
type: "button",
|
|
20
|
+
onClick: (event) => {
|
|
21
|
+
event.stopPropagation();
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
onEvidence();
|
|
24
|
+
},
|
|
25
|
+
className: cn(
|
|
26
|
+
shared,
|
|
27
|
+
"inline-flex items-center rounded-full border border-dashed",
|
|
28
|
+
onImage ? "border-background/70 bg-foreground/70 text-background backdrop-blur-sm hover:bg-foreground/85" : "border-accent/40 text-accent hover:bg-accent/10",
|
|
29
|
+
"focus-visible:outline-none focus-visible:ring-2",
|
|
30
|
+
onImage ? "focus-visible:ring-background/70" : "focus-visible:ring-accent/40",
|
|
31
|
+
className
|
|
32
|
+
),
|
|
33
|
+
children: label
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { SignatureChip };
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { SignatureChip } from './chunk-Q6QH52LJ.js';
|
|
2
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
3
|
+
import { __objRest, __spreadValues } from './chunk-3GWWZKX7.js';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import { MessageSquareQuote } from 'lucide-react';
|
|
6
|
+
import { jsxs, jsx } 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 MentionSignal({
|
|
13
|
+
label,
|
|
14
|
+
count,
|
|
15
|
+
onMentions,
|
|
16
|
+
formatCount = String
|
|
17
|
+
}) {
|
|
18
|
+
const content = /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-0.5", children: [
|
|
19
|
+
/* @__PURE__ */ jsx(MessageSquareQuote, { className: "h-3.5 w-3.5 opacity-60", "aria-hidden": true }),
|
|
20
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formatCount(count) })
|
|
21
|
+
] });
|
|
22
|
+
const shared = cn(
|
|
23
|
+
// `relative z-[2]` keeps this above the row's stretched link overlay.
|
|
24
|
+
"relative z-[2] inline-flex shrink-0 items-center text-accent",
|
|
25
|
+
// Same size and weight as the price at the other end of the meta row — keep
|
|
26
|
+
// these two in step if the price's type changes.
|
|
27
|
+
"text-[15px] font-bold",
|
|
28
|
+
// `min-h-6` holds the tap target at the 24px WCAG 2.5.8 floor; `px-1.5
|
|
29
|
+
// -mx-1.5` buys the horizontal half without moving the pair on screen.
|
|
30
|
+
"min-h-6 px-1.5 -mx-1.5"
|
|
31
|
+
);
|
|
32
|
+
if (!onMentions) {
|
|
33
|
+
return /* @__PURE__ */ jsx("span", { className: shared, "aria-label": label, children: content });
|
|
34
|
+
}
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
"button",
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
"data-slot": "mentions",
|
|
40
|
+
"aria-label": label,
|
|
41
|
+
onClick: (event) => {
|
|
42
|
+
event.stopPropagation();
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
onMentions();
|
|
45
|
+
},
|
|
46
|
+
className: cn(
|
|
47
|
+
shared,
|
|
48
|
+
"rounded-sm hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
49
|
+
),
|
|
50
|
+
children: content
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
var MenuItem = memo(function MenuItem2({
|
|
55
|
+
item,
|
|
56
|
+
labels,
|
|
57
|
+
formatPrice,
|
|
58
|
+
formatCount = String,
|
|
59
|
+
onOpen,
|
|
60
|
+
showSignatureBadge = false,
|
|
61
|
+
signatureTier = "strong",
|
|
62
|
+
onSignatureEvidence,
|
|
63
|
+
onMentions,
|
|
64
|
+
markGradient,
|
|
65
|
+
venueName,
|
|
66
|
+
subtitle,
|
|
67
|
+
href,
|
|
68
|
+
linkLabel,
|
|
69
|
+
linkComponent: LinkComponent = DefaultLink,
|
|
70
|
+
disabled = false,
|
|
71
|
+
className
|
|
72
|
+
}) {
|
|
73
|
+
var _a, _b, _c, _d, _e;
|
|
74
|
+
const firstEntry = (_a = item.sizes_and_prices) == null ? void 0 : _a[0];
|
|
75
|
+
const quantity = firstEntry == null ? void 0 : firstEntry.size;
|
|
76
|
+
const hasQuantity = quantity != null && quantity > 0;
|
|
77
|
+
const allPrices = (_c = (_b = item.sizes_and_prices) == null ? void 0 : _b.map((entry) => entry.price).filter((price) => typeof price === "number" && price > 0)) != null ? _c : [];
|
|
78
|
+
const minPrice = allPrices.length > 0 ? Math.min(...allPrices) : null;
|
|
79
|
+
const maxPrice = allPrices.length > 0 ? Math.max(...allPrices) : null;
|
|
80
|
+
const isPriceRange = minPrice != null && maxPrice != null && minPrice !== maxPrice;
|
|
81
|
+
const mentionCount = (_e = (_d = item.mentions) != null ? _d : item.review_count) != null ? _e : 0;
|
|
82
|
+
const isInert = !href && !onOpen;
|
|
83
|
+
const isActionable = !disabled && !isInert;
|
|
84
|
+
const handleRowClick = () => {
|
|
85
|
+
if (disabled) return;
|
|
86
|
+
onOpen == null ? void 0 : onOpen();
|
|
87
|
+
};
|
|
88
|
+
const handleKeyDown = (event) => {
|
|
89
|
+
if (disabled) return;
|
|
90
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
onOpen == null ? void 0 : onOpen();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
return /* @__PURE__ */ jsxs(
|
|
96
|
+
"div",
|
|
97
|
+
{
|
|
98
|
+
role: href || isInert ? void 0 : "button",
|
|
99
|
+
tabIndex: href || isInert ? void 0 : disabled ? -1 : 0,
|
|
100
|
+
"aria-disabled": disabled || void 0,
|
|
101
|
+
onClick: href || isInert ? void 0 : handleRowClick,
|
|
102
|
+
onKeyDown: href || isInert ? void 0 : handleKeyDown,
|
|
103
|
+
className: cn(
|
|
104
|
+
"group relative flex min-h-[72px] items-start gap-3 px-4 py-3",
|
|
105
|
+
// Radius only where the row is a grid cell. Full-bleed rows run edge to
|
|
106
|
+
// edge, where a corner radius would round against the viewport.
|
|
107
|
+
"md:rounded-xl",
|
|
108
|
+
// 180ms is the EXIT; `hover:duration-*` overrides it to 120ms on the
|
|
109
|
+
// way in. A hover that leaves as fast as it arrives reads as a flicker
|
|
110
|
+
// when the pointer crosses a list.
|
|
111
|
+
!isInert && [
|
|
112
|
+
"transition-[background-color,box-shadow,transform] duration-[180ms] ease-out motion-reduce:transition-none",
|
|
113
|
+
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
|
|
114
|
+
],
|
|
115
|
+
isActionable && [
|
|
116
|
+
"cursor-pointer hover:duration-[120ms]",
|
|
117
|
+
// Opaque, never alpha: `hover:bg-muted/40` composited to a lightness
|
|
118
|
+
// delta of 0.004 on the light canvas — a hover state that measured as
|
|
119
|
+
// nothing.
|
|
120
|
+
"hover:bg-card dark:hover:bg-surface-2",
|
|
121
|
+
// Grid cells only. On a full-bleed row the shadow runs off both
|
|
122
|
+
// viewport edges and reads as a smear; that row widens its tab instead.
|
|
123
|
+
"md:hover:shadow-[var(--shadow-row-hover)]",
|
|
124
|
+
// Hover lifts, press sinks — the two must not read as one gesture.
|
|
125
|
+
"active:scale-[0.985] active:duration-[90ms] active:ease-in active:shadow-none",
|
|
126
|
+
"active:bg-muted",
|
|
127
|
+
"motion-reduce:active:scale-100",
|
|
128
|
+
// The mention count is a button inside a button. While the pointer is
|
|
129
|
+
// on it the row stops claiming the hover, so only one target is lit.
|
|
130
|
+
"has-[[data-slot=mentions]:hover]:bg-transparent has-[[data-slot=mentions]:hover]:shadow-none"
|
|
131
|
+
],
|
|
132
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
133
|
+
className
|
|
134
|
+
),
|
|
135
|
+
children: [
|
|
136
|
+
href && /* @__PURE__ */ jsx(
|
|
137
|
+
LinkComponent,
|
|
138
|
+
{
|
|
139
|
+
href,
|
|
140
|
+
"aria-label": linkLabel != null ? linkLabel : item.name,
|
|
141
|
+
className: "absolute inset-0 z-[1] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent md:rounded-xl"
|
|
142
|
+
}
|
|
143
|
+
),
|
|
144
|
+
/* @__PURE__ */ jsx(
|
|
145
|
+
"div",
|
|
146
|
+
{
|
|
147
|
+
"aria-hidden": true,
|
|
148
|
+
className: cn(
|
|
149
|
+
"-ml-4 w-2 shrink-0 self-stretch rounded-r-full bg-muted",
|
|
150
|
+
// The full-bleed row's hover signal, since it cannot take a shadow.
|
|
151
|
+
// `-mr-1` absorbs the extra 4px so the text column does not shift as
|
|
152
|
+
// the mark grows. Grid cells get the shadow instead and hold the mark
|
|
153
|
+
// still — the tab encodes which section you are in, so the less it
|
|
154
|
+
// moves, the better it does that job.
|
|
155
|
+
!isInert && [
|
|
156
|
+
"transition-[width] duration-[120ms] ease-out motion-reduce:transition-none",
|
|
157
|
+
"group-hover:-mr-1 group-hover:w-3 md:group-hover:mr-0 md:group-hover:w-2"
|
|
158
|
+
]
|
|
159
|
+
),
|
|
160
|
+
style: markGradient ? { backgroundImage: markGradient } : void 0
|
|
161
|
+
}
|
|
162
|
+
),
|
|
163
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
164
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-1.5", children: [
|
|
165
|
+
/* @__PURE__ */ jsx("h3", { className: "text-[15px] font-semibold leading-snug text-foreground", children: item.name }),
|
|
166
|
+
showSignatureBadge && /* @__PURE__ */ jsx(
|
|
167
|
+
SignatureChip,
|
|
168
|
+
{
|
|
169
|
+
label: signatureTier === "weak" ? labels.mentioned : labels.signature,
|
|
170
|
+
onEvidence: onSignatureEvidence,
|
|
171
|
+
className: "mt-0.5"
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
] }),
|
|
175
|
+
venueName && /* @__PURE__ */ jsx("p", { className: "mt-0.5 truncate text-[12px] font-medium text-foreground/70", children: venueName }),
|
|
176
|
+
subtitle ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 line-clamp-2 text-xs italic leading-snug text-muted-foreground", children: subtitle }) : item.description && /* @__PURE__ */ jsx(
|
|
177
|
+
"p",
|
|
178
|
+
{
|
|
179
|
+
className: cn(
|
|
180
|
+
"mt-0.5 text-xs text-muted-foreground",
|
|
181
|
+
venueName ? "line-clamp-1" : "line-clamp-2"
|
|
182
|
+
),
|
|
183
|
+
children: item.description
|
|
184
|
+
}
|
|
185
|
+
),
|
|
186
|
+
(minPrice != null || hasQuantity || mentionCount > 0) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex items-baseline justify-between gap-x-2 gap-y-1", children: [
|
|
187
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-baseline gap-x-2", children: [
|
|
188
|
+
minPrice != null && /* @__PURE__ */ jsxs("span", { className: "flex items-baseline gap-1", children: [
|
|
189
|
+
/* @__PURE__ */ jsx("span", { className: "text-[15px] font-bold tabular-nums text-foreground", children: isPriceRange ? `${formatPrice(minPrice)}\u2013${formatPrice(maxPrice)}` : formatPrice(minPrice) }),
|
|
190
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: labels.currency })
|
|
191
|
+
] }),
|
|
192
|
+
hasQuantity && /* @__PURE__ */ jsxs("span", { className: "text-[12px] tabular-nums text-muted-foreground", children: [
|
|
193
|
+
quantity,
|
|
194
|
+
item.kind === "dish" ? "g" : "ml"
|
|
195
|
+
] })
|
|
196
|
+
] }),
|
|
197
|
+
mentionCount > 0 && /* @__PURE__ */ jsx(
|
|
198
|
+
MentionSignal,
|
|
199
|
+
{
|
|
200
|
+
label: labels.mentions(mentionCount),
|
|
201
|
+
count: mentionCount,
|
|
202
|
+
onMentions,
|
|
203
|
+
formatCount
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
] })
|
|
207
|
+
] })
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
export { MentionSignal, MenuItem };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { MenuItem } from './chunk-TH6W2PWG.js';
|
|
2
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
function VenueSignatureBlock({
|
|
6
|
+
item,
|
|
7
|
+
labels,
|
|
8
|
+
formatPrice,
|
|
9
|
+
formatCount,
|
|
10
|
+
kicker,
|
|
11
|
+
markGradient,
|
|
12
|
+
subtitle,
|
|
13
|
+
href,
|
|
14
|
+
linkComponent,
|
|
15
|
+
className
|
|
16
|
+
}) {
|
|
17
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("overflow-hidden rounded-xl bg-accent-subtle py-1", className), children: [
|
|
18
|
+
/* @__PURE__ */ jsx("span", { className: "block px-4 pt-2 text-[9.5px] font-bold uppercase tracking-[0.09em] text-muted-foreground", children: kicker }),
|
|
19
|
+
/* @__PURE__ */ jsx(
|
|
20
|
+
MenuItem,
|
|
21
|
+
{
|
|
22
|
+
item,
|
|
23
|
+
labels,
|
|
24
|
+
formatPrice,
|
|
25
|
+
formatCount,
|
|
26
|
+
markGradient,
|
|
27
|
+
subtitle,
|
|
28
|
+
showSignatureBadge: false,
|
|
29
|
+
href,
|
|
30
|
+
linkComponent,
|
|
31
|
+
className: "min-h-0 md:rounded-none md:hover:bg-transparent md:hover:shadow-none"
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
] });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { VenueSignatureBlock };
|