@bearmenu/ui 0.8.9 → 0.8.10
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-2XCZJWTV.js +121 -0
- package/dist/chunk-5RWTOT5Y.js +72 -0
- 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-MZL7CGCL.js +109 -0
- package/dist/chunk-SY6RV476.js +48 -0
- package/dist/chunk-UDN7UHJW.js +60 -0
- package/dist/{chunk-TT3WFS6S.js → chunk-YOKHBAIH.js} +11 -11
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/command.d.ts +7 -7
- 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/date-input.d.ts +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 +1 -1
- package/dist/components/event-index-row.js +1 -1
- package/dist/components/event-list-row-wide.js +1 -1
- 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/glass-ground.d.ts +66 -0
- package/dist/components/glass-ground.js +3 -0
- 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/kitchen-dossier.d.ts +88 -0
- package/dist/components/kitchen-dossier.js +187 -0
- 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 +99 -0
- package/dist/components/menu-family-block.js +155 -0
- package/dist/components/menu-family-card.d.ts +33 -27
- package/dist/components/menu-family-card.js +43 -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-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-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/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 +2 -2
- 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/snap-rail.d.ts +24 -1
- package/dist/components/snap-rail.js +3 -109
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/story.d.ts +34 -0
- package/dist/components/story.js +3 -0
- package/dist/components/text.d.ts +3 -3
- 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/weekend-panel.js +2 -2
- package/package.json +1 -1
- package/src/components/concept-compare-rail.tsx +131 -0
- package/src/components/concept-compare.stories.tsx +122 -54
- package/src/components/concept-compare.tsx +363 -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 +129 -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 +322 -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 +314 -0
- package/src/components/menu-family-card.stories.tsx +43 -35
- package/src/components/menu-family-card.tsx +122 -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-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/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/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,155 @@
|
|
|
1
|
+
import { MenuKitchenList } from '../chunk-24RFI4RQ.js';
|
|
2
|
+
import { HueChip } from '../chunk-CLLY6XB3.js';
|
|
3
|
+
import { Separator } from '../chunk-WSRWFA6K.js';
|
|
4
|
+
import { PhotoGround, PHOTO_GROUND } from '../chunk-5RWTOT5Y.js';
|
|
5
|
+
import { Skeleton } from '../chunk-QXHMPJ35.js';
|
|
6
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
7
|
+
import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
8
|
+
import { Wallet } from 'lucide-react';
|
|
9
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
|
+
|
|
11
|
+
function DefaultLink(_a) {
|
|
12
|
+
var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
|
|
13
|
+
return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
|
|
14
|
+
}
|
|
15
|
+
var MOSAIC_TILES = 6;
|
|
16
|
+
var PHONE_TILES = 4;
|
|
17
|
+
var GROUND = PHOTO_GROUND;
|
|
18
|
+
var FROST = "backdrop-blur-xl [mask-image:linear-gradient(to_bottom,transparent_0%,black_42%)] lg:[mask-image:linear-gradient(to_right,transparent_36%,black_54%)]";
|
|
19
|
+
var INK = "bg-[linear-gradient(to_bottom,oklch(0.16_0.012_55_/_0.42)_0%,oklch(0.16_0.012_55_/_0.6)_30%,oklch(0.16_0.012_55_/_0.9)_48%,oklch(0.16_0.012_55_/_0.96)_100%)] lg:bg-[linear-gradient(to_right,oklch(0.16_0.012_55_/_0.38)_0%,oklch(0.16_0.012_55_/_0.6)_30%,oklch(0.16_0.012_55_/_0.92)_46%,oklch(0.16_0.012_55_/_0.96)_100%)]";
|
|
20
|
+
var TEXT_SCRIM = (
|
|
21
|
+
/* `isolate` + `before:-z-10`: a positioned pseudo-element paints ABOVE the
|
|
22
|
+
column's in-flow text unless the column is its own stacking context and
|
|
23
|
+
the layer is ordered beneath. Without `isolate`, `-z-10` would instead
|
|
24
|
+
drop it behind the card's mosaic — inside the article's context. */
|
|
25
|
+
"isolate before:pointer-events-none before:absolute before:inset-x-0 before:bottom-0 before:top-[30%] before:-z-10 before:bg-[linear-gradient(to_bottom,oklch(0.16_0.012_55_/_0)_0%,oklch(0.16_0.012_55_/_0.55)_45%,oklch(0.16_0.012_55_/_0.8)_100%)] before:content-['']"
|
|
26
|
+
);
|
|
27
|
+
function MenuFamilyBlock({
|
|
28
|
+
family,
|
|
29
|
+
labels,
|
|
30
|
+
formatCount = String,
|
|
31
|
+
hue,
|
|
32
|
+
gradient,
|
|
33
|
+
linkComponent: LinkComponent = DefaultLink,
|
|
34
|
+
className
|
|
35
|
+
}) {
|
|
36
|
+
var _a, _b, _c, _d, _e;
|
|
37
|
+
const photos = ((_a = family.photoUrls) != null ? _a : []).slice(0, MOSAIC_TILES);
|
|
38
|
+
const overflow = Math.max(family.venueCount - photos.length, 0);
|
|
39
|
+
const initial = ((_c = (_b = family.name.match(new RegExp("\\p{L}", "u"))) == null ? void 0 : _b[0]) != null ? _c : "").toLocaleUpperCase();
|
|
40
|
+
const venues = (_d = family.venues) != null ? _d : [];
|
|
41
|
+
return /* @__PURE__ */ jsxs(
|
|
42
|
+
"article",
|
|
43
|
+
{
|
|
44
|
+
className: cn(
|
|
45
|
+
/* `isolate` confines the blend and the backdrop-filter to this card.
|
|
46
|
+
`dark` scopes every token inside to its dark-theme value. */
|
|
47
|
+
"dark relative isolate overflow-hidden rounded-[14px] text-foreground",
|
|
48
|
+
GROUND,
|
|
49
|
+
className
|
|
50
|
+
),
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
PhotoGround,
|
|
54
|
+
{
|
|
55
|
+
photos: photos.length > 0 ? photos : [void 0],
|
|
56
|
+
initials: initial,
|
|
57
|
+
mosaicClassName: photos.length > 0 ? "grid-cols-2 grid-rows-2 lg:grid-cols-3" : "grid-cols-1",
|
|
58
|
+
phoneTiles: PHONE_TILES,
|
|
59
|
+
gradient
|
|
60
|
+
}
|
|
61
|
+
),
|
|
62
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute inset-0", FROST) }),
|
|
63
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute inset-0", INK) }),
|
|
64
|
+
/* @__PURE__ */ jsxs("div", { className: "relative grid grid-cols-1 lg:grid-cols-[38%_1fr]", children: [
|
|
65
|
+
/* @__PURE__ */ jsxs("div", { className: cn("relative flex flex-col p-3.5 lg:min-h-[320px] lg:justify-end lg:p-5", TEXT_SCRIM), children: [
|
|
66
|
+
overflow > 0 && /* @__PURE__ */ jsx("span", { className: "mb-16 self-end rounded-full bg-[oklch(0.16_0.012_55_/_0.72)] px-2.5 py-1 text-[11px] font-semibold text-white backdrop-blur-[2px] lg:mb-3 lg:self-start", children: labels.more(overflow) }),
|
|
67
|
+
/* @__PURE__ */ jsx("h3", { className: "text-balance font-serif text-[26px] font-semibold leading-tight tracking-[-0.02em] text-white lg:text-[30px]", children: family.name }),
|
|
68
|
+
/* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-[13px] font-medium tabular-nums text-white/70", children: labels.venueUnit(family.venueCount) }),
|
|
69
|
+
/* @__PURE__ */ jsx(
|
|
70
|
+
LinkComponent,
|
|
71
|
+
{
|
|
72
|
+
href: family.href,
|
|
73
|
+
className: "mt-3.5 inline-flex h-10 w-max items-center rounded-full border border-white/20 bg-white/[0.12] px-4 text-[13.5px] font-bold text-white backdrop-blur-md transition-colors hover:bg-white/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white motion-reduce:transition-none",
|
|
74
|
+
children: labels.browse
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
] }),
|
|
78
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col px-3.5 pb-3.5 lg:p-5", children: [
|
|
79
|
+
/* @__PURE__ */ jsxs("ul", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
80
|
+
family.priceBandLabel && /* No hue: a fact about money, not about the family. In the dark
|
|
81
|
+
scope `HueChip`'s `--muted` fallback is the dark pill the design
|
|
82
|
+
draws. */
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
HueChip,
|
|
85
|
+
{
|
|
86
|
+
as: "li",
|
|
87
|
+
className: "font-bold tabular-nums",
|
|
88
|
+
"aria-label": `${labels.priceBand}: ${family.priceBandLabel}`,
|
|
89
|
+
icon: /* @__PURE__ */ jsx(Wallet, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
90
|
+
children: family.priceBandLabel
|
|
91
|
+
}
|
|
92
|
+
),
|
|
93
|
+
(_e = family.chips) == null ? void 0 : _e.map((chip) => (
|
|
94
|
+
/* Label only. The counts are VENUES beside a dish group's name,
|
|
95
|
+
which every reader takes for dishes. */
|
|
96
|
+
/* @__PURE__ */ jsx(HueChip, { as: "li", hue, children: chip.label }, chip.slug)
|
|
97
|
+
))
|
|
98
|
+
] }),
|
|
99
|
+
venues.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
100
|
+
/* @__PURE__ */ jsx(Separator, { className: "my-3" }),
|
|
101
|
+
/* @__PURE__ */ jsx(
|
|
102
|
+
MenuKitchenList,
|
|
103
|
+
{
|
|
104
|
+
kitchens: venues,
|
|
105
|
+
labels: labels.kitchens,
|
|
106
|
+
linkComponent: LinkComponent
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
] })
|
|
110
|
+
] })
|
|
111
|
+
] })
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
function MenuFamilyBlockSkeleton({
|
|
117
|
+
venues = 3,
|
|
118
|
+
className
|
|
119
|
+
}) {
|
|
120
|
+
return /* @__PURE__ */ jsx(
|
|
121
|
+
"div",
|
|
122
|
+
{
|
|
123
|
+
className: cn("dark relative overflow-hidden rounded-[14px]", GROUND, className),
|
|
124
|
+
"aria-hidden": true,
|
|
125
|
+
children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-[38%_1fr]", children: [
|
|
126
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col p-3.5 lg:min-h-[320px] lg:justify-end lg:p-5", children: [
|
|
127
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mb-16 h-6 w-[72px] self-end rounded-full lg:mb-3 lg:self-start" }),
|
|
128
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-[60%]" }),
|
|
129
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mt-2 h-3.5 w-[90px]" }),
|
|
130
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mt-3.5 h-10 w-[160px] rounded-full" })
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col px-3.5 pb-3.5 lg:p-5", children: [
|
|
133
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
|
|
134
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-[86px] rounded-full" }),
|
|
135
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-[74px] rounded-full" }),
|
|
136
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-[66px] rounded-full" })
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ jsx(Separator, { className: "my-3" }),
|
|
139
|
+
Array.from({ length: venues }, (_, index) => /* @__PURE__ */ jsxs("div", { children: [
|
|
140
|
+
index > 0 && /* @__PURE__ */ jsx(Separator, {}),
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 py-2.5", children: [
|
|
142
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[46px] w-[46px] rounded-[11px]" }),
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
|
|
144
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-[46%]" }),
|
|
145
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-[58%]" })
|
|
146
|
+
] })
|
|
147
|
+
] })
|
|
148
|
+
] }, index))
|
|
149
|
+
] })
|
|
150
|
+
] })
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export { MenuFamilyBlock, MenuFamilyBlockSkeleton };
|
|
@@ -1,59 +1,65 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { MenuItemLabels } from './menu-item.js';
|
|
3
2
|
import { MenuFamilyPreview, MenuLinkComponent, MenuLinkProps } from './menu-types.js';
|
|
4
3
|
import 'react';
|
|
5
4
|
import './place-types.js';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* MenuFamilyCard — a browsable grouping of venues: a cuisine on the dishes tab,
|
|
9
|
-
* a drink family on the drinks tab.
|
|
8
|
+
* a drink family on the drinks tab. The hub's doorway to a family.
|
|
10
9
|
*
|
|
11
|
-
* ##
|
|
10
|
+
* ## A doorway, not a summary
|
|
12
11
|
*
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
12
|
+
* The cuisines index's `MenuFamilyBlock` is the family's SUMMARY: photography,
|
|
13
|
+
* chips, a price band and three venues. This card is the same family drawn
|
|
14
|
+
* one step earlier, in a row of three on the hub, where the reader is choosing
|
|
15
|
+
* a family and not yet a venue — so it carries the same photography, the same
|
|
16
|
+
* chips and the same "Browse" action, and lists no venue. A venue on the hub
|
|
17
|
+
* card was tried and it was the first venue's signature relabelled as the
|
|
18
|
+
* family's most named, which was a lie at three-card width.
|
|
19
19
|
*
|
|
20
|
-
* ##
|
|
20
|
+
* ## The count does the scanning
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
22
|
+
* The card is one number, one name and the groups the family consists of,
|
|
23
|
+
* over a mosaic of its venues. The count is VENUES: cuisine exists on places
|
|
24
|
+
* and nowhere else — no listing endpoint will tell you how many dishes are
|
|
25
|
+
* Italian — so a card counting dishes cannot be built and this one does not
|
|
26
|
+
* try. The chips are plain labels: at three cards across, chips carrying
|
|
27
|
+
* numbers turned the panel into a table, and the numbers were kitchens, which
|
|
28
|
+
* nobody reads a chip as.
|
|
27
29
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
30
|
+
* ## One link
|
|
31
|
+
*
|
|
32
|
+
* The whole card is the link and the "Browse" pill is its visible affordance,
|
|
33
|
+
* not a second link — a pill inside a link is a nested anchor, and a pill that
|
|
34
|
+
* is the only link leaves the photography, the number and the name inert.
|
|
31
35
|
*/
|
|
32
36
|
/** @deprecated Alias of `MenuLinkProps`; kept so existing imports keep working. */
|
|
33
37
|
type MenuFamilyCardLinkProps = MenuLinkProps;
|
|
34
38
|
type MenuFamilyCardLabels = {
|
|
35
39
|
/** Unit under the count, e.g. "KITCHENS". */
|
|
36
40
|
venueUnit: string;
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Price-band caption, e.g. "kitchen price band". Never drawn — it names the
|
|
43
|
+
* pill for a screen reader, which would otherwise be read two numbers and a
|
|
44
|
+
* currency.
|
|
45
|
+
*/
|
|
40
46
|
priceBand: string;
|
|
47
|
+
/** The action pill, e.g. "Browse Italian". Sits on the photography — keep it short. */
|
|
48
|
+
browse: string;
|
|
41
49
|
};
|
|
42
50
|
type MenuFamilyCardProps = {
|
|
43
51
|
family: MenuFamilyPreview;
|
|
44
52
|
labels: MenuFamilyCardLabels;
|
|
45
|
-
/** Passed through to the featured `<MenuItem>`. */
|
|
46
|
-
itemLabels: MenuItemLabels;
|
|
47
|
-
formatPrice: (amount: number) => string;
|
|
48
|
-
formatCount?: (value: number) => string;
|
|
49
53
|
href: string;
|
|
50
|
-
/** Finished CSS colour for the
|
|
54
|
+
/** Finished CSS colour for the chips. */
|
|
51
55
|
hue?: string;
|
|
56
|
+
/** Finished CSS gradient — the family's colour over the mosaic. */
|
|
57
|
+
gradient?: string;
|
|
52
58
|
/** Composed price band, e.g. "32–84 lei". */
|
|
53
59
|
priceBandLabel?: string;
|
|
54
60
|
linkComponent?: MenuLinkComponent;
|
|
55
61
|
className?: string;
|
|
56
62
|
};
|
|
57
|
-
declare function MenuFamilyCard({ family, labels,
|
|
63
|
+
declare function MenuFamilyCard({ family, labels, href, hue, gradient, priceBandLabel, linkComponent: LinkComponent, className, }: MenuFamilyCardProps): react_jsx_runtime.JSX.Element;
|
|
58
64
|
|
|
59
65
|
export { MenuFamilyCard, type MenuFamilyCardLabels, type MenuFamilyCardLinkProps, type MenuFamilyCardProps };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-UKBNQO6Q.js';
|
|
1
|
+
import { HueChip } from '../chunk-CLLY6XB3.js';
|
|
2
|
+
import { PhotoGround, PHOTO_GROUND } from '../chunk-5RWTOT5Y.js';
|
|
4
3
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
5
4
|
import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
6
5
|
import { Wallet } from 'lucide-react';
|
|
@@ -11,107 +10,66 @@ function DefaultLink(_a) {
|
|
|
11
10
|
return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
|
|
12
11
|
}
|
|
13
12
|
var MOSAIC_CELLS = 4;
|
|
13
|
+
var GROUND = PHOTO_GROUND;
|
|
14
|
+
var FROST = "backdrop-blur-xl [mask-image:linear-gradient(to_bottom,transparent_28%,black_58%)]";
|
|
15
|
+
var INK = "bg-[linear-gradient(to_bottom,oklch(0.16_0.012_55_/_0.78)_0%,oklch(0.16_0.012_55_/_0.5)_34%,oklch(0.16_0.012_55_/_0.86)_62%,oklch(0.16_0.012_55_/_0.96)_100%)]";
|
|
14
16
|
function MenuFamilyCard({
|
|
15
17
|
family,
|
|
16
18
|
labels,
|
|
17
|
-
itemLabels,
|
|
18
|
-
formatPrice,
|
|
19
|
-
formatCount,
|
|
20
19
|
href,
|
|
21
20
|
hue,
|
|
21
|
+
gradient,
|
|
22
22
|
priceBandLabel,
|
|
23
23
|
linkComponent: LinkComponent = DefaultLink,
|
|
24
24
|
className
|
|
25
25
|
}) {
|
|
26
|
-
var _a, _b, _c;
|
|
26
|
+
var _a, _b, _c, _d;
|
|
27
27
|
const photos = (_a = family.venue_photo_urls) != null ? _a : [];
|
|
28
|
-
const
|
|
28
|
+
const tiles = photos.length ? Array.from({ length: MOSAIC_CELLS }, (_, cell) => photos[cell % photos.length]) : [void 0];
|
|
29
29
|
return /* @__PURE__ */ jsxs(
|
|
30
|
-
|
|
30
|
+
LinkComponent,
|
|
31
31
|
{
|
|
32
|
+
href,
|
|
32
33
|
className: cn(
|
|
33
|
-
"flex h-
|
|
34
|
+
"group dark relative isolate flex min-h-[280px] flex-col justify-between overflow-hidden rounded-[14px] border border-border p-3.5",
|
|
35
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-white",
|
|
36
|
+
GROUND,
|
|
34
37
|
className
|
|
35
38
|
),
|
|
36
39
|
children: [
|
|
37
|
-
/* @__PURE__ */
|
|
38
|
-
|
|
40
|
+
/* @__PURE__ */ jsx(
|
|
41
|
+
PhotoGround,
|
|
39
42
|
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
(_, cell) => photos.length ? (
|
|
46
|
-
// eslint-disable-next-line @next/next/no-img-element
|
|
47
|
-
/* @__PURE__ */ jsx(
|
|
48
|
-
"img",
|
|
49
|
-
{
|
|
50
|
-
src: photos[cell % photos.length],
|
|
51
|
-
alt: "",
|
|
52
|
-
loading: "lazy",
|
|
53
|
-
decoding: "async",
|
|
54
|
-
className: "h-full w-full object-cover"
|
|
55
|
-
},
|
|
56
|
-
cell
|
|
57
|
-
)
|
|
58
|
-
) : /* @__PURE__ */ jsx(
|
|
59
|
-
"span",
|
|
60
|
-
{
|
|
61
|
-
className: "bg-[repeating-linear-gradient(135deg,oklch(0.6_0.02_55)_0_9px,oklch(0.68_0.016_58)_9px_18px)] opacity-[0.18]"
|
|
62
|
-
},
|
|
63
|
-
cell
|
|
64
|
-
)
|
|
65
|
-
) }),
|
|
66
|
-
hue && /* @__PURE__ */ jsx(
|
|
67
|
-
"span",
|
|
68
|
-
{
|
|
69
|
-
"aria-hidden": true,
|
|
70
|
-
className: "absolute inset-0 opacity-90 mix-blend-color",
|
|
71
|
-
style: { backgroundColor: hue }
|
|
72
|
-
}
|
|
73
|
-
),
|
|
74
|
-
/* @__PURE__ */ jsx(
|
|
75
|
-
"span",
|
|
76
|
-
{
|
|
77
|
-
"aria-hidden": true,
|
|
78
|
-
className: "absolute inset-0 bg-[linear-gradient(180deg,oklch(0.16_0.012_55_/_0.9)_0%,oklch(0.16_0.012_55_/_0.62)_45%,oklch(0.16_0.012_55_/_0.94)_100%)]"
|
|
79
|
-
}
|
|
80
|
-
),
|
|
81
|
-
/* @__PURE__ */ jsxs("span", { className: "relative flex min-h-[260px] flex-col justify-between p-3.5 text-white", children: [
|
|
82
|
-
/* @__PURE__ */ jsxs("span", { className: "block", children: [
|
|
83
|
-
/* @__PURE__ */ jsx("b", { className: "block text-[34px] font-extrabold leading-none tracking-[-0.03em] tabular-nums", children: family.venue_count }),
|
|
84
|
-
/* @__PURE__ */ jsx("span", { className: "mt-1 block text-[9.5px] font-bold tracking-[0.12em] opacity-80", children: labels.venueUnit })
|
|
85
|
-
] }),
|
|
86
|
-
/* @__PURE__ */ jsxs("span", { className: "block", children: [
|
|
87
|
-
/* @__PURE__ */ jsx("span", { className: "block text-[17px] font-bold tracking-[-0.01em]", children: family.name }),
|
|
88
|
-
groups.length > 0 && /* @__PURE__ */ jsx("span", { className: "mt-0.5 block truncate text-[11.5px] opacity-75", children: groups.join(" \xB7 ") }),
|
|
89
|
-
priceBandLabel && /* @__PURE__ */ jsxs("span", { className: "mt-2 inline-flex items-center gap-1.5 rounded-full bg-white/15 px-2.5 py-1 text-[11px] backdrop-blur-[2px]", children: [
|
|
90
|
-
/* @__PURE__ */ jsx(Wallet, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
|
|
91
|
-
/* @__PURE__ */ jsx("span", { className: "opacity-80", children: labels.priceBand }),
|
|
92
|
-
/* @__PURE__ */ jsx("b", { className: "font-semibold tabular-nums", children: priceBandLabel })
|
|
93
|
-
] })
|
|
94
|
-
] })
|
|
95
|
-
] })
|
|
96
|
-
]
|
|
43
|
+
className: "-z-30",
|
|
44
|
+
photos: tiles,
|
|
45
|
+
initials: family.name.charAt(0),
|
|
46
|
+
mosaicClassName: photos.length ? "grid-cols-2 grid-rows-2" : "grid-cols-1",
|
|
47
|
+
gradient
|
|
97
48
|
}
|
|
98
49
|
),
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
50
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute inset-0 -z-20", FROST) }),
|
|
51
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("absolute inset-0 -z-10", INK) }),
|
|
52
|
+
/* @__PURE__ */ jsxs("span", { className: "block text-white", children: [
|
|
53
|
+
/* @__PURE__ */ jsx("b", { className: "block text-[34px] font-extrabold leading-none tracking-[-0.03em] tabular-nums", children: family.venue_count }),
|
|
54
|
+
/* @__PURE__ */ jsx("span", { className: "mt-1 block text-[9.5px] font-bold uppercase tracking-[0.12em] opacity-80", children: labels.venueUnit })
|
|
55
|
+
] }),
|
|
56
|
+
/* @__PURE__ */ jsxs("span", { className: "block", children: [
|
|
57
|
+
/* @__PURE__ */ jsx("span", { className: "block text-balance font-serif text-[24px] font-semibold leading-tight tracking-[-0.02em] text-white", children: family.name }),
|
|
58
|
+
(priceBandLabel || ((_c = (_b = family.chips) == null ? void 0 : _b.length) != null ? _c : 0) > 0) && /* @__PURE__ */ jsxs("span", { className: "mt-2.5 flex flex-wrap items-center gap-1.5", children: [
|
|
59
|
+
priceBandLabel && /* No hue: a fact about money, not about the family. In the dark
|
|
60
|
+
scope `HueChip`'s `--muted` fallback is the dark pill. */
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
HueChip,
|
|
63
|
+
{
|
|
64
|
+
className: "font-bold tabular-nums",
|
|
65
|
+
"aria-label": `${labels.priceBand}: ${priceBandLabel}`,
|
|
66
|
+
icon: /* @__PURE__ */ jsx(Wallet, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
67
|
+
children: priceBandLabel
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
(_d = family.chips) == null ? void 0 : _d.map((chip) => /* @__PURE__ */ jsx(HueChip, { hue, children: chip.label }, chip.slug))
|
|
71
|
+
] }),
|
|
72
|
+
/* @__PURE__ */ jsx("span", { className: "mt-3.5 inline-flex h-10 items-center rounded-full border border-white/20 bg-white/[0.12] px-4 text-[13.5px] font-bold text-white backdrop-blur-md transition-colors group-hover:bg-white/20 motion-reduce:transition-none", children: labels.browse })
|
|
115
73
|
] })
|
|
116
74
|
]
|
|
117
75
|
}
|
|
@@ -1,3 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
import '../chunk-FEK5XGZW.js';
|
|
1
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
3
2
|
import '../chunk-3GWWZKX7.js';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var GHOST_ROWS = 13;
|
|
6
|
+
var GHOST_CENTRE = (GHOST_ROWS - 1) / 2;
|
|
7
|
+
var ALPHA_PEAK = 0.44;
|
|
8
|
+
var ALPHA_EDGE = 0;
|
|
9
|
+
var FALLOFF_EXPONENT = 3.4;
|
|
10
|
+
var GHOST_LINE_CHARS = 56;
|
|
11
|
+
function hashString(input) {
|
|
12
|
+
let hash = 5381;
|
|
13
|
+
for (let i = 0; i < input.length; i++) hash = hash * 33 ^ input.charCodeAt(i);
|
|
14
|
+
return Math.abs(hash);
|
|
15
|
+
}
|
|
16
|
+
function MenuField({
|
|
17
|
+
name,
|
|
18
|
+
gradient,
|
|
19
|
+
seedKey,
|
|
20
|
+
variant = "repeat",
|
|
21
|
+
className
|
|
22
|
+
}) {
|
|
23
|
+
if (variant === "display") {
|
|
24
|
+
const words = name.trim().split(/\s+/).filter(Boolean);
|
|
25
|
+
const longestWord = Math.max(1, ...words.map((word) => word.length));
|
|
26
|
+
const lineCount = Math.max(1, words.length);
|
|
27
|
+
const byWidth = (96 / (longestWord * 0.62)).toFixed(1);
|
|
28
|
+
const byHeight = (90 / (lineCount * 0.9)).toFixed(1);
|
|
29
|
+
const fontSize = `clamp(9cqw, min(19cqw, ${byWidth}cqw, ${byHeight}cqh), 19cqw)`;
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
"div",
|
|
32
|
+
{
|
|
33
|
+
className: cn("relative isolate overflow-hidden", className),
|
|
34
|
+
style: { backgroundImage: gradient, containerType: "size" },
|
|
35
|
+
children: /* @__PURE__ */ jsx(
|
|
36
|
+
"span",
|
|
37
|
+
{
|
|
38
|
+
"aria-hidden": true,
|
|
39
|
+
className: "pointer-events-none absolute inset-0 flex select-none items-center justify-center p-[4cqw] text-center font-black uppercase leading-[0.9] tracking-[-0.03em] text-white/[0.26]",
|
|
40
|
+
style: { fontSize },
|
|
41
|
+
children: name
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
const unit = `${name} \xB7 `;
|
|
48
|
+
const repeats = Math.max(2, Math.ceil(GHOST_LINE_CHARS / Math.max(unit.length, 1)));
|
|
49
|
+
const ghostLine = unit.repeat(repeats);
|
|
50
|
+
const seed = hashString(seedKey != null ? seedKey : name);
|
|
51
|
+
const rows = Array.from({ length: GHOST_ROWS }, (_, row) => {
|
|
52
|
+
const distance = Math.abs(row - GHOST_CENTRE) / GHOST_CENTRE;
|
|
53
|
+
const alpha = ALPHA_EDGE + (ALPHA_PEAK - ALPHA_EDGE) * Math.pow(1 - distance, FALLOFF_EXPONENT);
|
|
54
|
+
return { row, alpha, offset: (seed >> row % 12) % 90 - 45 };
|
|
55
|
+
});
|
|
56
|
+
return /* @__PURE__ */ jsx(
|
|
57
|
+
"div",
|
|
58
|
+
{
|
|
59
|
+
className: cn("relative isolate overflow-hidden", className),
|
|
60
|
+
style: { backgroundImage: gradient },
|
|
61
|
+
children: /* @__PURE__ */ jsx(
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
"aria-hidden": true,
|
|
65
|
+
className: "pointer-events-none absolute left-1/2 top-1/2 flex h-[180%] w-[180%] -translate-x-1/2 -translate-y-1/2 -rotate-[11deg] select-none flex-col justify-center",
|
|
66
|
+
children: rows.map(({ row, alpha, offset }) => /* @__PURE__ */ jsx(
|
|
67
|
+
"span",
|
|
68
|
+
{
|
|
69
|
+
className: "block whitespace-nowrap text-center text-[15px] font-bold leading-[1.45] tracking-[-0.01em]",
|
|
70
|
+
style: {
|
|
71
|
+
color: `oklch(1 0 0 / ${alpha.toFixed(3)})`,
|
|
72
|
+
// Emboss, both edges scaled by this row's alpha: a dark edge below
|
|
73
|
+
// cuts the letterform into the field, a light edge above lifts its
|
|
74
|
+
// top. The dark edge is kept well under the fill — at parity it
|
|
75
|
+
// ringed every glyph and dragged the type back toward grey, which
|
|
76
|
+
// is the opposite of what the fill is doing.
|
|
77
|
+
textShadow: [
|
|
78
|
+
`0 1px 1px oklch(0 0 0 / ${(alpha * 0.4).toFixed(3)})`,
|
|
79
|
+
`0 -1px 0 oklch(1 0 0 / ${(alpha * 0.4).toFixed(3)})`
|
|
80
|
+
].join(", "),
|
|
81
|
+
transform: `translateX(${offset}px)`
|
|
82
|
+
},
|
|
83
|
+
children: ghostLine
|
|
84
|
+
},
|
|
85
|
+
row
|
|
86
|
+
))
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { MenuField };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { MenuFilterChip } from './menu-types.js';
|
|
3
|
+
import 'react';
|
|
4
|
+
import './place-types.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* MenuFilterChips — the intent page's filter row.
|
|
8
|
+
*
|
|
9
|
+
* ## One unit, one list that moves
|
|
10
|
+
*
|
|
11
|
+
* Every chip counts KITCHENS, whatever facet is behind it. A dietary chip reads
|
|
12
|
+
* "has a vegetarian dish" and counts venues; a dish-group chip reads "has a
|
|
13
|
+
* pizza" and counts venues. The earlier version mixed venue counts and dish
|
|
14
|
+
* counts in one row and became unreadable — you could not tell what a number
|
|
15
|
+
* was counting without reading the label that produced it. The unit is stated
|
|
16
|
+
* once, at the head of the row (`unitLabel`, e.g. "KITCHENS · 247"), and never
|
|
17
|
+
* again.
|
|
18
|
+
*
|
|
19
|
+
* ## A zero-count chip is dimmed, not disabled
|
|
20
|
+
*
|
|
21
|
+
* `empty` chips stay tappable. Pressing one swaps it in and drops whichever
|
|
22
|
+
* active filter conflicts with it, and the caller says which in a line beneath.
|
|
23
|
+
* Disabling it would refuse the reader the thing they asked for and give no
|
|
24
|
+
* reason; this way the row answers the question by being pressed. Facets the
|
|
25
|
+
* API says are unavailable for this intent are not passed in at all — not
|
|
26
|
+
* drawn, rather than drawn dead.
|
|
27
|
+
*
|
|
28
|
+
* ## The row scrolls; the escape hatch does not
|
|
29
|
+
*
|
|
30
|
+
* One line in every state. Chips scroll horizontally under a `<ScrollFade>`,
|
|
31
|
+
* and "More filters" is pinned opposite the unit label rather than wrapping,
|
|
32
|
+
* so the way out of a full row is always in the same place.
|
|
33
|
+
*
|
|
34
|
+
* Interactive: the consumer marks its own module `"use client"`.
|
|
35
|
+
*/
|
|
36
|
+
type MenuFilterChipsProps = {
|
|
37
|
+
chips: MenuFilterChip[];
|
|
38
|
+
onToggle: (key: string) => void;
|
|
39
|
+
/** The unit and the current total, composed by the caller, e.g. "KITCHENS · 247". */
|
|
40
|
+
unitLabel?: string;
|
|
41
|
+
/** Opens the full filter sheet. Omit for a row where every facet is a chip. */
|
|
42
|
+
onMore?: () => void;
|
|
43
|
+
moreLabel?: string;
|
|
44
|
+
/**
|
|
45
|
+
* A glyph for the phone's icon-only "more filters" button.
|
|
46
|
+
*
|
|
47
|
+
* The label is the widest fixed element in the row — "More filters" is ~80px
|
|
48
|
+
* of a 358px viewport, and it is the one thing that never scrolls, so it eats
|
|
49
|
+
* the chips' runway on every phone. Given an icon, the button collapses to a
|
|
50
|
+
* square below `lg` and keeps `moreLabel` as its accessible name.
|
|
51
|
+
*
|
|
52
|
+
* A node rather than a name because the app owns its iconography, and this
|
|
53
|
+
* one is animated on press — the DS neither knows the glyph nor drives it.
|
|
54
|
+
*/
|
|
55
|
+
moreIcon?: React.ReactNode;
|
|
56
|
+
/** Press handler for the icon button, e.g. to replay the glyph's animation. */
|
|
57
|
+
onMorePointerDown?: () => void;
|
|
58
|
+
/** Locale-aware integer formatter for the counts. Defaults to `String`. */
|
|
59
|
+
formatCount?: (value: number) => string;
|
|
60
|
+
/** Accessible name for the row. */
|
|
61
|
+
ariaLabel?: string;
|
|
62
|
+
className?: string;
|
|
63
|
+
};
|
|
64
|
+
declare function MenuFilterChips({ chips, onToggle, unitLabel, onMore, moreLabel, moreIcon, onMorePointerDown, formatCount, ariaLabel, className, }: MenuFilterChipsProps): react_jsx_runtime.JSX.Element;
|
|
65
|
+
/**
|
|
66
|
+
* MenuFilterSummary — what the active filters did, and the way out.
|
|
67
|
+
*
|
|
68
|
+
* Sits under the row whenever anything is on. The sentence is composed by the
|
|
69
|
+
* caller because it is a real sentence in two languages ("Three filters · 34 of
|
|
70
|
+
* 247 kitchens are mid-range, have a vegetarian Italian dish, and are open
|
|
71
|
+
* now") and assembling it from fragments here would produce translated
|
|
72
|
+
* word-salad in one of them.
|
|
73
|
+
*/
|
|
74
|
+
type MenuFilterSummaryProps = {
|
|
75
|
+
/** The composed sentence. */
|
|
76
|
+
summary: React.ReactNode;
|
|
77
|
+
clearLabel: string;
|
|
78
|
+
onClear: () => void;
|
|
79
|
+
className?: string;
|
|
80
|
+
};
|
|
81
|
+
declare function MenuFilterSummary({ summary, clearLabel, onClear, className, }: MenuFilterSummaryProps): react_jsx_runtime.JSX.Element;
|
|
82
|
+
declare function MenuFilterChipsSkeleton({ className }: {
|
|
83
|
+
className?: string;
|
|
84
|
+
}): react_jsx_runtime.JSX.Element;
|
|
85
|
+
|
|
86
|
+
export { MenuFilterChips, type MenuFilterChipsProps, MenuFilterChipsSkeleton, MenuFilterSummary, type MenuFilterSummaryProps };
|