@bearmenu/ui 0.8.48 → 0.8.50
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-QY66ME5B.js → chunk-CZ2HC7WY.js} +24 -6
- package/dist/components/alert.d.ts +2 -2
- package/dist/components/avatar.d.ts +2 -2
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/banner.d.ts +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/card.d.ts +2 -2
- package/dist/components/command.d.ts +3 -3
- package/dist/components/concept-compare.d.ts +1 -1
- package/dist/components/doorway-tiles.d.ts +1 -1
- package/dist/components/empty-state.d.ts +2 -2
- package/dist/components/event-detail-panel.d.ts +12 -2
- package/dist/components/event-detail-panel.js +15 -3
- package/dist/components/grade-atom.d.ts +1 -1
- package/dist/components/item.d.ts +2 -2
- package/dist/components/kitchen-dossier.d.ts +1 -1
- package/dist/components/menu-dead-end.d.ts +1 -1
- package/dist/components/menu-family-block.d.ts +2 -2
- package/dist/components/menu-family-block.js +3 -1
- package/dist/components/menu-family-card.d.ts +1 -1
- package/dist/components/menu-filter-chips.d.ts +1 -1
- package/dist/components/menu-group-rows.d.ts +1 -1
- package/dist/components/menu-index-header.d.ts +1 -1
- package/dist/components/menu-index-list.d.ts +1 -1
- package/dist/components/menu-intent-hero.d.ts +1 -1
- package/dist/components/menu-item.d.ts +1 -1
- package/dist/components/menu-kitchen-list.d.ts +9 -2
- package/dist/components/menu-kitchen-list.js +3 -1
- package/dist/components/menu-mocks.d.ts +1 -1
- package/dist/components/menu-types.d.ts +1 -1
- package/dist/components/open-now-list.d.ts +1 -1
- package/dist/components/place-about-tab.d.ts +1 -1
- package/dist/components/place-card.d.ts +1 -1
- package/dist/components/place-card.js +13 -5
- package/dist/components/place-details-mobile.d.ts +1 -1
- package/dist/components/place-schedule-week.d.ts +1 -1
- package/dist/components/place-types.d.ts +1 -1
- package/dist/components/qa-block.d.ts +1 -1
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/tag.d.ts +2 -2
- package/dist/components/text.d.ts +3 -3
- package/dist/components/top-comparison.d.ts +1 -1
- package/dist/components/top-cross-link.d.ts +1 -1
- package/dist/components/top-ranking-entry.d.ts +1 -1
- package/dist/components/top-ranking-hero.d.ts +1 -1
- package/dist/components/top-types.d.ts +1 -1
- package/dist/components/venue-grade-dimensions.d.ts +1 -1
- package/dist/components/venue-quotes.d.ts +1 -1
- package/dist/components/venue-wall.d.ts +1 -1
- package/dist/{place-types-C4rR3LTs.d.ts → place-types-Dzy6FH67.d.ts} +12 -1
- package/package.json +217 -23
- package/src/components/event-detail-panel.test.tsx +35 -0
- package/src/components/event-detail-panel.tsx +32 -10
- package/src/components/menu-kitchen-list.test.tsx +39 -0
- package/src/components/menu-kitchen-list.tsx +36 -7
- package/src/components/place-card.stories.tsx +36 -0
- package/src/components/place-card.test.tsx +29 -0
- package/src/components/place-card.tsx +24 -5
- package/src/components/place-types.ts +11 -0
|
@@ -22,9 +22,9 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
22
22
|
* Weights are 400 / 600 / 700. 500 is not in the system.
|
|
23
23
|
*/
|
|
24
24
|
declare const textVariants: (props?: ({
|
|
25
|
-
variant?: "
|
|
26
|
-
color?: "default" | "
|
|
27
|
-
weight?: "bold" | "
|
|
25
|
+
variant?: "small" | "display" | "h1" | "h2" | "h3" | "h4" | "body-lg" | "body" | "body-sm" | "caption" | "label" | "overline" | null | undefined;
|
|
26
|
+
color?: "default" | "destructive" | "inherit" | "muted" | "primary" | "primary-foreground" | null | undefined;
|
|
27
|
+
weight?: "bold" | "normal" | "medium" | "semibold" | null | undefined;
|
|
28
28
|
leading?: "none" | "normal" | "tight" | "snug" | "relaxed" | "loose" | null | undefined;
|
|
29
29
|
tracking?: "normal" | "tight" | "wide" | "wider" | null | undefined;
|
|
30
30
|
wrap?: "balance" | "pretty" | "nowrap" | null | undefined;
|
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { MenuLinkComponent } from './menu-types.js';
|
|
3
3
|
import { TopComparisonRow } from './top-types.js';
|
|
4
4
|
import 'react';
|
|
5
|
-
import '../place-types-
|
|
5
|
+
import '../place-types-Dzy6FH67.js';
|
|
6
6
|
import '../lib/grade.js';
|
|
7
7
|
|
|
8
8
|
type TopComparisonLabels = {
|
|
@@ -3,7 +3,7 @@ import { MenuItemLabels } from './menu-item.js';
|
|
|
3
3
|
import { MenuItemPreview, MenuLinkComponent } from './menu-types.js';
|
|
4
4
|
import { TopRankEntry } from './top-types.js';
|
|
5
5
|
import 'react';
|
|
6
|
-
import '../place-types-
|
|
6
|
+
import '../place-types-Dzy6FH67.js';
|
|
7
7
|
import '../lib/grade.js';
|
|
8
8
|
|
|
9
9
|
type TopRankingEntryLabels = {
|
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { MenuLinkComponent } from './menu-types.js';
|
|
3
3
|
import { TopExit } from './top-types.js';
|
|
4
4
|
import 'react';
|
|
5
|
-
import '../place-types-
|
|
5
|
+
import '../place-types-Dzy6FH67.js';
|
|
6
6
|
import '../lib/grade.js';
|
|
7
7
|
|
|
8
8
|
type TopRankingHeroProps = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { MenuLinkComponent, MenuLinkProps } from './menu-types.js';
|
|
3
|
-
import { P as PlacePreview } from '../place-types-
|
|
3
|
+
import { P as PlacePreview } from '../place-types-Dzy6FH67.js';
|
|
4
4
|
import 'react';
|
|
5
5
|
import '../lib/grade.js';
|
|
6
6
|
|
|
@@ -123,6 +123,12 @@ type PlacePreview = {
|
|
|
123
123
|
* bare storage key straight to `next/image`'s loader).
|
|
124
124
|
*/
|
|
125
125
|
cover_url?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Year and month the place launched (`YYYY-MM`), as the schema ships it.
|
|
128
|
+
* The backend approximates it from the earliest review it holds, so it is a
|
|
129
|
+
* floor rather than a founding date. `<PlaceCard>` shows the year only.
|
|
130
|
+
*/
|
|
131
|
+
launched_at?: string;
|
|
126
132
|
};
|
|
127
133
|
type PlaceHourBlock = {
|
|
128
134
|
opens_at: number;
|
|
@@ -248,6 +254,11 @@ type PlaceCardLabels = {
|
|
|
248
254
|
viewDetails: (name: string) => string;
|
|
249
255
|
/** Accessible name of the `$` price glyphs, e.g. "Price level 2 of 4". */
|
|
250
256
|
priceLevel: (level: number) => string;
|
|
257
|
+
/**
|
|
258
|
+
* The launch year on the meta line, e.g. "Est. 2020" / "Din 2020". Optional:
|
|
259
|
+
* without it the card shows no year even when `launched_at` is set.
|
|
260
|
+
*/
|
|
261
|
+
established?: (year: number) => string;
|
|
251
262
|
grade: GradeAtomLabels;
|
|
252
263
|
};
|
|
253
264
|
/**
|
|
@@ -321,4 +332,4 @@ type PlaceDetailsMobileLabels = PlaceAboutTabLabels & {
|
|
|
321
332
|
noImageAvailable: string;
|
|
322
333
|
};
|
|
323
334
|
|
|
324
|
-
export { type CitedText as C,
|
|
335
|
+
export { type CitedText as C, type GradeAtomLabels as G, type MenuSizeAndPrice as M, type PlacePreview as P, type WeekdayKey as W, type PlaceGrade as a, type PlaceGradeDimensions as b, type PlaceAboutTabLabels as c, type PlaceLinkKind as d, type PlaceCardLabels as e, type PlaceDetailsMobileLabels as f, type PlaceSchedule as g, type PlaceScheduleWeekLabels as h, GradeAtom as i, type GradeAtomProps as j, type GradeAtomSize as k, type CitedValue as l, type PlaceHourBlock as m, type PlaceMustTry as n, type PlacePriceRange as o, type PlaceReviewsDigest as p };
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bearmenu/ui",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.50",
|
|
4
|
+
"packageManager": "pnpm@10.28.1",
|
|
4
5
|
"description": "BearMenu design system — shared UI tokens, primitives, and components",
|
|
5
6
|
"license": "UNLICENSED",
|
|
6
7
|
"repository": {
|
|
@@ -16,20 +17,223 @@
|
|
|
16
17
|
"src"
|
|
17
18
|
],
|
|
18
19
|
"exports": {
|
|
20
|
+
"./components/accordion": "./src/components/accordion.tsx",
|
|
21
|
+
"./components/action-bar": "./src/components/action-bar.tsx",
|
|
22
|
+
"./components/activity-row": "./src/components/activity-row.tsx",
|
|
23
|
+
"./components/alert": "./src/components/alert.tsx",
|
|
24
|
+
"./components/alert-dialog": "./src/components/alert-dialog.tsx",
|
|
25
|
+
"./components/aspect-ratio": "./src/components/aspect-ratio.tsx",
|
|
26
|
+
"./components/avatar": "./src/components/avatar.tsx",
|
|
27
|
+
"./components/badge": "./src/components/badge.tsx",
|
|
28
|
+
"./components/banner": "./src/components/banner.tsx",
|
|
29
|
+
"./components/booking-row": "./src/components/booking-row.tsx",
|
|
30
|
+
"./components/booking-summary-card": "./src/components/booking-summary-card.tsx",
|
|
31
|
+
"./components/breadcrumb": "./src/components/breadcrumb.tsx",
|
|
32
|
+
"./components/button": "./src/components/button.tsx",
|
|
33
|
+
"./components/button-group": "./src/components/button-group.tsx",
|
|
34
|
+
"./components/calendar": "./src/components/calendar.tsx",
|
|
35
|
+
"./components/card": "./src/components/card.tsx",
|
|
36
|
+
"./components/carousel": "./src/components/carousel.tsx",
|
|
37
|
+
"./components/category-deck": "./src/components/category-deck.tsx",
|
|
38
|
+
"./components/checkbox": "./src/components/checkbox.tsx",
|
|
39
|
+
"./components/circular-progress": "./src/components/circular-progress.tsx",
|
|
40
|
+
"./components/coach-marks": "./src/components/coach-marks.tsx",
|
|
41
|
+
"./components/collapsible": "./src/components/collapsible.tsx",
|
|
42
|
+
"./components/combobox": "./src/components/combobox.tsx",
|
|
43
|
+
"./components/command": "./src/components/command.tsx",
|
|
44
|
+
"./components/concept-card": "./src/components/concept-card.tsx",
|
|
45
|
+
"./components/concept-compare": "./src/components/concept-compare.tsx",
|
|
46
|
+
"./components/concept-compare-rail": "./src/components/concept-compare-rail.tsx",
|
|
47
|
+
"./components/concept-convergence": "./src/components/concept-convergence.tsx",
|
|
48
|
+
"./components/convergence": "./src/components/convergence.tsx",
|
|
49
|
+
"./components/coverflow": "./src/components/coverflow.tsx",
|
|
50
|
+
"./components/currency-input": "./src/components/currency-input.tsx",
|
|
51
|
+
"./components/date-input": "./src/components/date-input.tsx",
|
|
52
|
+
"./components/day-rail-chip": "./src/components/day-rail-chip.tsx",
|
|
53
|
+
"./components/description-list": "./src/components/description-list.tsx",
|
|
54
|
+
"./components/dialog": "./src/components/dialog.tsx",
|
|
55
|
+
"./components/doorway-tiles": "./src/components/doorway-tiles.tsx",
|
|
56
|
+
"./components/drawer": "./src/components/drawer.tsx",
|
|
57
|
+
"./components/drift-rail": "./src/components/drift-rail.tsx",
|
|
58
|
+
"./components/dropdown-menu": "./src/components/dropdown-menu.tsx",
|
|
59
|
+
"./components/empty-state": "./src/components/empty-state.tsx",
|
|
60
|
+
"./components/event-card": "./src/components/event-card.tsx",
|
|
61
|
+
"./components/event-compact-row": "./src/components/event-compact-row.tsx",
|
|
62
|
+
"./components/event-day-header": "./src/components/event-day-header.tsx",
|
|
63
|
+
"./components/event-day-separator": "./src/components/event-day-separator.tsx",
|
|
64
|
+
"./components/event-detail-panel": "./src/components/event-detail-panel.tsx",
|
|
65
|
+
"./components/event-hub-hero": "./src/components/event-hub-hero.tsx",
|
|
66
|
+
"./components/event-index-row": "./src/components/event-index-row.tsx",
|
|
67
|
+
"./components/event-list-row": "./src/components/event-list-row.tsx",
|
|
68
|
+
"./components/event-list-row-wide": "./src/components/event-list-row-wide.tsx",
|
|
69
|
+
"./components/event-poster-fallback": "./src/components/event-poster-fallback.tsx",
|
|
70
|
+
"./components/event-tonight-strip": "./src/components/event-tonight-strip.tsx",
|
|
71
|
+
"./components/event-types": "./src/components/event-types.ts",
|
|
72
|
+
"./components/events-empty-state": "./src/components/events-empty-state.tsx",
|
|
73
|
+
"./components/explainer-steps": "./src/components/explainer-steps.tsx",
|
|
74
|
+
"./components/facet-group": "./src/components/facet-group.tsx",
|
|
75
|
+
"./components/featured-rail-item": "./src/components/featured-rail-item.tsx",
|
|
76
|
+
"./components/field": "./src/components/field.tsx",
|
|
77
|
+
"./components/filter-category-row": "./src/components/filter-category-row.tsx",
|
|
78
|
+
"./components/form": "./src/components/form.tsx",
|
|
79
|
+
"./components/glass-ground": "./src/components/glass-ground.tsx",
|
|
80
|
+
"./components/grade-atom": "./src/components/grade-atom.tsx",
|
|
81
|
+
"./components/haptic-switch": "./src/components/haptic-switch.tsx",
|
|
82
|
+
"./components/hold-countdown": "./src/components/hold-countdown.tsx",
|
|
83
|
+
"./components/hub-surface": "./src/components/hub-surface.tsx",
|
|
84
|
+
"./components/hue-chip": "./src/components/hue-chip.tsx",
|
|
85
|
+
"./components/icon": "./src/components/icon.tsx",
|
|
86
|
+
"./components/input": "./src/components/input.tsx",
|
|
87
|
+
"./components/input-group": "./src/components/input-group.tsx",
|
|
88
|
+
"./components/input-otp": "./src/components/input-otp.tsx",
|
|
89
|
+
"./components/item": "./src/components/item.tsx",
|
|
90
|
+
"./components/kbd": "./src/components/kbd.tsx",
|
|
91
|
+
"./components/label": "./src/components/label.tsx",
|
|
92
|
+
"./components/kitchen-dossier": "./src/components/kitchen-dossier.tsx",
|
|
93
|
+
"./components/lazy-markdown": "./src/components/lazy-markdown.tsx",
|
|
94
|
+
"./components/link-button": "./src/components/link-button.tsx",
|
|
95
|
+
"./components/markdown-renderer": "./src/components/markdown-renderer.tsx",
|
|
96
|
+
"./components/menu-dead-end": "./src/components/menu-dead-end.tsx",
|
|
97
|
+
"./components/menu-family-block": "./src/components/menu-family-block.tsx",
|
|
98
|
+
"./components/menu-family-card": "./src/components/menu-family-card.tsx",
|
|
99
|
+
"./components/menu-field": "./src/components/menu-field.tsx",
|
|
100
|
+
"./components/menu-filter-chips": "./src/components/menu-filter-chips.tsx",
|
|
101
|
+
"./components/menu-group-rows": "./src/components/menu-group-rows.tsx",
|
|
102
|
+
"./components/menu-hub-hero": "./src/components/menu-hub-hero.tsx",
|
|
103
|
+
"./components/menu-index-header": "./src/components/menu-index-header.tsx",
|
|
104
|
+
"./components/menu-index-list": "./src/components/menu-index-list.tsx",
|
|
105
|
+
"./components/menu-intent-hero": "./src/components/menu-intent-hero.tsx",
|
|
106
|
+
"./components/menu-item": "./src/components/menu-item.tsx",
|
|
107
|
+
"./components/menu-pick-row": "./src/components/menu-pick-row.tsx",
|
|
108
|
+
"./components/menu-kitchen-list": "./src/components/menu-kitchen-list.tsx",
|
|
109
|
+
"./components/menu-mocks": "./src/components/menu-mocks.ts",
|
|
110
|
+
"./components/menu-types": "./src/components/menu-types.ts",
|
|
111
|
+
"./components/motion-icon": "./src/components/motion-icon.tsx",
|
|
112
|
+
"./components/motion-icon-actions": "./src/components/motion-icon-actions.tsx",
|
|
113
|
+
"./components/motion-icon-controls": "./src/components/motion-icon-controls.tsx",
|
|
114
|
+
"./components/motion-icon-set": "./src/components/motion-icon-set.tsx",
|
|
115
|
+
"./components/multi-select-combobox": "./src/components/multi-select-combobox.tsx",
|
|
116
|
+
"./components/multi-select-menu": "./src/components/multi-select-menu.tsx",
|
|
117
|
+
"./components/native-select": "./src/components/native-select.tsx",
|
|
118
|
+
"./components/open-now-list": "./src/components/open-now-list.tsx",
|
|
119
|
+
"./components/pagination": "./src/components/pagination.tsx",
|
|
120
|
+
"./components/pan-zoom-viewport": "./src/components/pan-zoom-viewport.tsx",
|
|
121
|
+
"./components/party-counter": "./src/components/party-counter.tsx",
|
|
122
|
+
"./components/phone-frame": "./src/components/phone-frame.tsx",
|
|
123
|
+
"./components/photo-ground": "./src/components/photo-ground.tsx",
|
|
124
|
+
"./components/place-about-tab": "./src/components/place-about-tab.tsx",
|
|
125
|
+
"./components/place-card": "./src/components/place-card.tsx",
|
|
126
|
+
"./components/place-details-mobile": "./src/components/place-details-mobile.tsx",
|
|
127
|
+
"./components/place-schedule-week": "./src/components/place-schedule-week.tsx",
|
|
128
|
+
"./components/place-types": "./src/components/place-types.ts",
|
|
129
|
+
"./components/popover": "./src/components/popover.tsx",
|
|
130
|
+
"./components/poster-stack": "./src/components/poster-stack.tsx",
|
|
131
|
+
"./components/poster-tape": "./src/components/poster-tape.tsx",
|
|
132
|
+
"./components/poster-wall": "./src/components/poster-wall.tsx",
|
|
133
|
+
"./components/progress": "./src/components/progress.tsx",
|
|
134
|
+
"./components/qa-block": "./src/components/qa-block.tsx",
|
|
135
|
+
"./components/qr-panel": "./src/components/qr-panel.tsx",
|
|
136
|
+
"./components/quiet-stretch": "./src/components/quiet-stretch.tsx",
|
|
137
|
+
"./components/radio-group": "./src/components/radio-group.tsx",
|
|
138
|
+
"./components/reconcile-bar": "./src/components/reconcile-bar.tsx",
|
|
139
|
+
"./components/responsive-overlay": "./src/components/responsive-overlay.tsx",
|
|
140
|
+
"./components/rating": "./src/components/rating.tsx",
|
|
141
|
+
"./components/scroll-area": "./src/components/scroll-area.tsx",
|
|
142
|
+
"./components/scroll-fade": "./src/components/scroll-fade.tsx",
|
|
143
|
+
"./components/search-bar": "./src/components/search-bar.tsx",
|
|
144
|
+
"./components/searchable-select": "./src/components/searchable-select.tsx",
|
|
145
|
+
"./components/section-header": "./src/components/section-header.tsx",
|
|
146
|
+
"./components/segmented-nav": "./src/components/segmented-nav.tsx",
|
|
147
|
+
"./components/select": "./src/components/select.tsx",
|
|
148
|
+
"./components/selection-bar": "./src/components/selection-bar.tsx",
|
|
149
|
+
"./components/separator": "./src/components/separator.tsx",
|
|
150
|
+
"./components/sheet": "./src/components/sheet.tsx",
|
|
151
|
+
"./components/signature-chip": "./src/components/signature-chip.tsx",
|
|
152
|
+
"./components/skeleton": "./src/components/skeleton.tsx",
|
|
153
|
+
"./components/skeleton-card": "./src/components/skeleton-card.tsx",
|
|
154
|
+
"./components/slider": "./src/components/slider.tsx",
|
|
155
|
+
"./components/sliding-panels": "./src/components/sliding-panels.tsx",
|
|
156
|
+
"./components/sonner": "./src/components/sonner.tsx",
|
|
157
|
+
"./components/sort-option-list": "./src/components/sort-option-list.tsx",
|
|
158
|
+
"./components/spinner": "./src/components/spinner.tsx",
|
|
159
|
+
"./components/split-share-row": "./src/components/split-share-row.tsx",
|
|
160
|
+
"./components/stat-banner": "./src/components/stat-banner.tsx",
|
|
161
|
+
"./components/stepper": "./src/components/stepper.tsx",
|
|
162
|
+
"./components/sticky-container": "./src/components/sticky-container.tsx",
|
|
163
|
+
"./components/story": "./src/components/story.tsx",
|
|
164
|
+
"./components/switch": "./src/components/switch.tsx",
|
|
165
|
+
"./components/table": "./src/components/table.tsx",
|
|
166
|
+
"./components/table-ledger-card": "./src/components/table-ledger-card.tsx",
|
|
167
|
+
"./components/table-trigger-band": "./src/components/table-trigger-band.tsx",
|
|
168
|
+
"./components/tabs": "./src/components/tabs.tsx",
|
|
169
|
+
"./components/tag": "./src/components/tag.tsx",
|
|
170
|
+
"./components/tag-group": "./src/components/tag-group.tsx",
|
|
171
|
+
"./components/text": "./src/components/text.tsx",
|
|
172
|
+
"./components/textarea": "./src/components/textarea.tsx",
|
|
173
|
+
"./components/time-slot": "./src/components/time-slot.tsx",
|
|
174
|
+
"./components/timeline-day": "./src/components/timeline-day.tsx",
|
|
175
|
+
"./components/timeline-hour": "./src/components/timeline-hour.tsx",
|
|
176
|
+
"./components/timeline-hour-puck": "./src/components/timeline-hour-puck.tsx",
|
|
177
|
+
"./components/toggle": "./src/components/toggle.tsx",
|
|
178
|
+
"./components/toggle-group": "./src/components/toggle-group.tsx",
|
|
179
|
+
"./components/tooltip": "./src/components/tooltip.tsx",
|
|
180
|
+
"./components/top-comparison": "./src/components/top-comparison.tsx",
|
|
181
|
+
"./components/top-cross-link": "./src/components/top-cross-link.tsx",
|
|
182
|
+
"./components/top-ranking-entry": "./src/components/top-ranking-entry.tsx",
|
|
183
|
+
"./components/top-ranking-hero": "./src/components/top-ranking-hero.tsx",
|
|
184
|
+
"./components/top-ranking-legend": "./src/components/top-ranking-legend.tsx",
|
|
185
|
+
"./components/top-types": "./src/components/top-types.ts",
|
|
186
|
+
"./components/use-mobile": "./src/components/use-mobile.tsx",
|
|
187
|
+
"./components/venue-events-block": "./src/components/venue-events-block.tsx",
|
|
188
|
+
"./components/venue-grade-dimensions": "./src/components/venue-grade-dimensions.tsx",
|
|
189
|
+
"./components/venue-quotes": "./src/components/venue-quotes.tsx",
|
|
190
|
+
"./components/venue-wall": "./src/components/venue-wall.tsx",
|
|
191
|
+
"./components/weekday-chip": "./src/components/weekday-chip.tsx",
|
|
192
|
+
"./components/weekday-theme-banner": "./src/components/weekday-theme-banner.tsx",
|
|
193
|
+
"./components/weekend-panel": "./src/components/weekend-panel.tsx",
|
|
19
194
|
"./globals.css": "./src/globals.css",
|
|
20
|
-
"./
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"./hooks
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"./lib
|
|
29
|
-
|
|
30
|
-
|
|
195
|
+
"./hooks/use-drag-swipe": "./src/hooks/use-drag-swipe.ts",
|
|
196
|
+
"./hooks/use-haptic": "./src/hooks/use-haptic.ts",
|
|
197
|
+
"./hooks/use-media-query": "./src/hooks/use-media-query.ts",
|
|
198
|
+
"./hooks/use-mobile": "./src/hooks/use-mobile.ts",
|
|
199
|
+
"./hooks/use-mounted-theme": "./src/hooks/use-mounted-theme.ts",
|
|
200
|
+
"./hooks/use-sticky": "./src/hooks/use-sticky.ts",
|
|
201
|
+
"./lib/card-hover": "./src/lib/card-hover.ts",
|
|
202
|
+
"./lib/grade": "./src/lib/grade.ts",
|
|
203
|
+
"./lib/icon-depth": "./src/lib/icon-depth.ts",
|
|
204
|
+
"./lib/icon-registry": "./src/lib/icon-registry.ts",
|
|
205
|
+
"./lib/motion": "./src/lib/motion.ts",
|
|
206
|
+
"./lib/overlay-pill": "./src/lib/overlay-pill.ts",
|
|
207
|
+
"./lib/utils": "./src/lib/utils.ts"
|
|
208
|
+
},
|
|
209
|
+
"publishConfig": {
|
|
210
|
+
"exports": {
|
|
211
|
+
"./globals.css": "./src/globals.css",
|
|
212
|
+
"./components/*": {
|
|
213
|
+
"types": "./dist/components/*.d.ts",
|
|
214
|
+
"import": "./dist/components/*.js"
|
|
215
|
+
},
|
|
216
|
+
"./hooks/*": {
|
|
217
|
+
"types": "./dist/hooks/*.d.ts",
|
|
218
|
+
"import": "./dist/hooks/*.js"
|
|
219
|
+
},
|
|
220
|
+
"./lib/*": {
|
|
221
|
+
"types": "./dist/lib/*.d.ts",
|
|
222
|
+
"import": "./dist/lib/*.js"
|
|
223
|
+
}
|
|
31
224
|
}
|
|
32
225
|
},
|
|
226
|
+
"scripts": {
|
|
227
|
+
"storybook": "storybook dev -p 6006",
|
|
228
|
+
"build-storybook": "storybook build",
|
|
229
|
+
"build": "tsup",
|
|
230
|
+
"dev": "tsup --watch",
|
|
231
|
+
"typecheck": "tsc --noEmit",
|
|
232
|
+
"test": "vitest run",
|
|
233
|
+
"test:watch": "vitest",
|
|
234
|
+
"clean": "rm -rf dist",
|
|
235
|
+
"prepublishOnly": "pnpm run build"
|
|
236
|
+
},
|
|
33
237
|
"peerDependencies": {
|
|
34
238
|
"@hookform/resolvers": "^3.0.0 || ^5.0.0",
|
|
35
239
|
"@radix-ui/react-accordion": "*",
|
|
@@ -138,15 +342,5 @@
|
|
|
138
342
|
"vaul": "^1.1.2",
|
|
139
343
|
"vitest": "^4.1.5",
|
|
140
344
|
"zod": "^3.25.67"
|
|
141
|
-
},
|
|
142
|
-
"scripts": {
|
|
143
|
-
"storybook": "storybook dev -p 6006",
|
|
144
|
-
"build-storybook": "storybook build",
|
|
145
|
-
"build": "tsup",
|
|
146
|
-
"dev": "tsup --watch",
|
|
147
|
-
"typecheck": "tsc --noEmit",
|
|
148
|
-
"test": "vitest run",
|
|
149
|
-
"test:watch": "vitest",
|
|
150
|
-
"clean": "rm -rf dist"
|
|
151
345
|
}
|
|
152
|
-
}
|
|
346
|
+
}
|
|
@@ -84,6 +84,41 @@ describe("EventDetailPanel", () => {
|
|
|
84
84
|
expect(screen.getByText(labels.venueNoPage)).toBeInTheDocument();
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
+
it("shows the venue's BearMenu grade instead of the Google star when given", () => {
|
|
88
|
+
const venue = {
|
|
89
|
+
name: "Sophie",
|
|
90
|
+
address: "Str. 5",
|
|
91
|
+
ratingLabel: "4.7",
|
|
92
|
+
href: "/places/sophie",
|
|
93
|
+
grade: { overall: 8.7, show_number: true },
|
|
94
|
+
};
|
|
95
|
+
const gradeLabels = {
|
|
96
|
+
soft: "Few reviews",
|
|
97
|
+
bands: {
|
|
98
|
+
exceptional: "Exceptional",
|
|
99
|
+
great: "Great",
|
|
100
|
+
good: "Good",
|
|
101
|
+
decent: "Decent",
|
|
102
|
+
weak: "Weak",
|
|
103
|
+
},
|
|
104
|
+
aria: (value: string) => `Grade ${value}`,
|
|
105
|
+
capped: "Capped",
|
|
106
|
+
};
|
|
107
|
+
const { container, rerender } = render(
|
|
108
|
+
<EventDetailPanel
|
|
109
|
+
{...base}
|
|
110
|
+
labels={{ ...labels, grade: gradeLabels }}
|
|
111
|
+
venue={venue}
|
|
112
|
+
/>,
|
|
113
|
+
);
|
|
114
|
+
expect(container.textContent).toMatch(/8[.,]7/);
|
|
115
|
+
expect(container.textContent).not.toContain("4.7");
|
|
116
|
+
|
|
117
|
+
// No grade labels: exactly the old card.
|
|
118
|
+
rerender(<EventDetailPanel {...base} venue={venue} />);
|
|
119
|
+
expect(container.textContent).toContain("4.7");
|
|
120
|
+
});
|
|
121
|
+
|
|
87
122
|
it("previews five performers and reveals the rest on request", () => {
|
|
88
123
|
const performers = ["A", "B", "C", "D", "E", "F", "G"];
|
|
89
124
|
render(
|
|
@@ -14,7 +14,10 @@ import {
|
|
|
14
14
|
Unplug,
|
|
15
15
|
User,
|
|
16
16
|
} from "lucide-react";
|
|
17
|
+
import { showsGradeAtom } from "../lib/grade";
|
|
17
18
|
import { cn } from "../lib/utils";
|
|
19
|
+
import { GradeAtom, type GradeAtomLabels } from "./grade-atom";
|
|
20
|
+
import type { PlaceGrade } from "./place-types";
|
|
18
21
|
import { Button } from "./button";
|
|
19
22
|
import { EventPosterFallback } from "./event-poster-fallback";
|
|
20
23
|
import { Separator } from "./separator";
|
|
@@ -81,7 +84,13 @@ export type EventDetailVenue = {
|
|
|
81
84
|
name: string;
|
|
82
85
|
/** Address line, e.g. "Str. Iuliu Maniu 5". */
|
|
83
86
|
address?: string;
|
|
84
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* The venue's BearMenu grade. Shown as the grade pill in the rating's place
|
|
89
|
+
* when `labels.grade` is given; the star `ratingLabel` then stays only for a
|
|
90
|
+
* venue without a grade.
|
|
91
|
+
*/
|
|
92
|
+
grade?: PlaceGrade;
|
|
93
|
+
/** e.g. "4.7" — Google's rating, rendered with a star. The fallback for an ungraded venue. */
|
|
85
94
|
ratingLabel?: string;
|
|
86
95
|
/** e.g. "open until 20:00" — appended to the meta row when given. */
|
|
87
96
|
openLabel?: string;
|
|
@@ -97,6 +106,8 @@ export type EventDetailVenue = {
|
|
|
97
106
|
};
|
|
98
107
|
|
|
99
108
|
export type EventDetailPanelLabels = {
|
|
109
|
+
/** The venue's grade pill. Optional: without it the venue shows the star, as before. */
|
|
110
|
+
grade?: GradeAtomLabels;
|
|
100
111
|
free: string;
|
|
101
112
|
liveNow: string;
|
|
102
113
|
/** The ended chip, e.g. "Ended". */
|
|
@@ -752,7 +763,7 @@ export function EventDetailChipRow({
|
|
|
752
763
|
|
|
753
764
|
export type EventDetailVenueCardProps = {
|
|
754
765
|
venue: EventDetailVenue;
|
|
755
|
-
labels: Pick<EventDetailPanelLabels, "venueNoPage">;
|
|
766
|
+
labels: Pick<EventDetailPanelLabels, "venueNoPage" | "grade">;
|
|
756
767
|
linkComponent?: React.ComponentType<EventDetailPanelLinkProps>;
|
|
757
768
|
/** Thumbnail size in px: 52 in the sheet, 64 on the page. */
|
|
758
769
|
thumbnailSize?: 52 | 64;
|
|
@@ -774,8 +785,10 @@ export function EventDetailVenueCard({
|
|
|
774
785
|
action,
|
|
775
786
|
className,
|
|
776
787
|
}: EventDetailVenueCardProps) {
|
|
777
|
-
const
|
|
778
|
-
|
|
788
|
+
const showGrade =
|
|
789
|
+
labels.grade !== undefined && showsGradeAtom(venue.grade, "xs");
|
|
790
|
+
const hasRating = showGrade || Boolean(venue.ratingLabel);
|
|
791
|
+
const meta = venue.href && (venue.address || hasRating || venue.openLabel);
|
|
779
792
|
// The main area (thumb, name, meta, chevron) is the link; `action` sits
|
|
780
793
|
// BESIDE it, never inside — an anchor cannot contain another control, and a
|
|
781
794
|
// page's "Open in Maps" must not navigate to the venue instead.
|
|
@@ -816,16 +829,25 @@ export function EventDetailVenueCard({
|
|
|
816
829
|
{venue.address && (
|
|
817
830
|
<span className="truncate">{venue.address}</span>
|
|
818
831
|
)}
|
|
819
|
-
{venue.address &&
|
|
832
|
+
{venue.address && hasRating && (
|
|
820
833
|
<span aria-hidden className="text-border">
|
|
821
834
|
·
|
|
822
835
|
</span>
|
|
823
836
|
)}
|
|
824
|
-
{
|
|
825
|
-
<
|
|
826
|
-
|
|
827
|
-
{
|
|
828
|
-
|
|
837
|
+
{showGrade && labels.grade && venue.grade ? (
|
|
838
|
+
<GradeAtom
|
|
839
|
+
grade={venue.grade}
|
|
840
|
+
labels={labels.grade}
|
|
841
|
+
size="xs"
|
|
842
|
+
className="shrink-0"
|
|
843
|
+
/>
|
|
844
|
+
) : (
|
|
845
|
+
venue.ratingLabel && (
|
|
846
|
+
<span className="inline-flex shrink-0 items-center gap-1">
|
|
847
|
+
<Star className="h-[11px] w-[11px]" aria-hidden />
|
|
848
|
+
{venue.ratingLabel}
|
|
849
|
+
</span>
|
|
850
|
+
)
|
|
829
851
|
)}
|
|
830
852
|
{venue.openLabel && (
|
|
831
853
|
<>
|
|
@@ -24,6 +24,45 @@ const kitchen: MenuKitchenPreview = {
|
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
const gradeLabels = {
|
|
28
|
+
soft: "Few reviews",
|
|
29
|
+
bands: { exceptional: "Exceptional", great: "Great", good: "Good", decent: "Decent", weak: "Weak" },
|
|
30
|
+
aria: (value: string) => `Grade ${value}`,
|
|
31
|
+
capped: "Capped",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
describe("MenuKitchenList rating", () => {
|
|
35
|
+
const graded = {
|
|
36
|
+
...kitchen,
|
|
37
|
+
place: {
|
|
38
|
+
...kitchen.place,
|
|
39
|
+
rating: { rating: 4.8, count: 900 },
|
|
40
|
+
reviews_digest: { grade: { overall: 8.7, show_number: true } },
|
|
41
|
+
},
|
|
42
|
+
} as MenuKitchenPreview;
|
|
43
|
+
|
|
44
|
+
it("shows the BearMenu grade instead of the Google star when the venue has one", () => {
|
|
45
|
+
const { container } = render(
|
|
46
|
+
<MenuKitchenList kitchens={[graded]} labels={{ ...labels, grade: gradeLabels }} />
|
|
47
|
+
);
|
|
48
|
+
expect(container.textContent).toMatch(/8[.,]7/);
|
|
49
|
+
expect(container.textContent).not.toContain("4.8");
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("keeps the star for a venue with no grade", () => {
|
|
53
|
+
const ungraded = { ...graded, place: { ...graded.place, reviews_digest: undefined } };
|
|
54
|
+
const { container } = render(
|
|
55
|
+
<MenuKitchenList kitchens={[ungraded]} labels={{ ...labels, grade: gradeLabels }} />
|
|
56
|
+
);
|
|
57
|
+
expect(container.textContent).toContain("4.8");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("keeps the star for callers that pass no grade labels", () => {
|
|
61
|
+
const { container } = render(<MenuKitchenList kitchens={[graded]} labels={labels} />);
|
|
62
|
+
expect(container.textContent).toContain("4.8");
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
27
66
|
describe("MenuKitchenList", () => {
|
|
28
67
|
/**
|
|
29
68
|
* The reason this component exists rather than a flag on `RankedVenueList`.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Check, ChevronRight, Clock, MessageSquare, Star } from "lucide-react";
|
|
2
|
+
import { showsGradeAtom } from "../lib/grade";
|
|
2
3
|
import { cn } from "../lib/utils";
|
|
4
|
+
import { GradeAtom, type GradeAtomLabels } from "./grade-atom";
|
|
3
5
|
import { Separator } from "./separator";
|
|
4
6
|
import { Skeleton } from "./skeleton";
|
|
5
7
|
import type { MenuKitchenPreview, MenuLinkComponent, MenuLinkProps } from "./menu-types";
|
|
@@ -59,6 +61,13 @@ export type MenuKitchenListLabels = {
|
|
|
59
61
|
openNow: string;
|
|
60
62
|
/** Reveals the next page of rows, e.g. "Show 10 more". */
|
|
61
63
|
showMore?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The grade pill's labels. With them, a graded venue shows its BearMenu
|
|
66
|
+
* grade where the Google star was; the star stays only for a venue with no
|
|
67
|
+
* grade. Optional so existing callers keep compiling — without it every row
|
|
68
|
+
* shows the star, as before.
|
|
69
|
+
*/
|
|
70
|
+
grade?: GradeAtomLabels;
|
|
62
71
|
};
|
|
63
72
|
|
|
64
73
|
/**
|
|
@@ -127,6 +136,31 @@ export function MenuKitchenList({
|
|
|
127
136
|
);
|
|
128
137
|
}
|
|
129
138
|
|
|
139
|
+
function gradeShown(place: MenuKitchenPreview["place"], labels: MenuKitchenListLabels) {
|
|
140
|
+
return labels.grade !== undefined && showsGradeAtom(place.reviews_digest?.grade, "xs");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** BearMenu's grade when the venue has one; Google's star only without it. */
|
|
144
|
+
function KitchenRating({
|
|
145
|
+
place,
|
|
146
|
+
labels,
|
|
147
|
+
}: {
|
|
148
|
+
place: MenuKitchenPreview["place"];
|
|
149
|
+
labels: MenuKitchenListLabels;
|
|
150
|
+
}) {
|
|
151
|
+
const grade = place.reviews_digest?.grade;
|
|
152
|
+
if (labels.grade && showsGradeAtom(grade, "xs")) {
|
|
153
|
+
return <GradeAtom grade={grade} labels={labels.grade} size="xs" className="shrink-0" />;
|
|
154
|
+
}
|
|
155
|
+
if (!place.rating) return null;
|
|
156
|
+
return (
|
|
157
|
+
<>
|
|
158
|
+
<Star className="h-[11px] w-[11px] shrink-0" aria-hidden />
|
|
159
|
+
{place.rating.rating}
|
|
160
|
+
</>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
130
164
|
function KitchenRow({
|
|
131
165
|
kitchen,
|
|
132
166
|
labels,
|
|
@@ -189,13 +223,8 @@ function KitchenRow({
|
|
|
189
223
|
{place.name}
|
|
190
224
|
</span>
|
|
191
225
|
<span className="flex items-center gap-1 truncate text-xs text-muted-foreground">
|
|
192
|
-
{place
|
|
193
|
-
|
|
194
|
-
<Star className="h-[11px] w-[11px] shrink-0" aria-hidden />
|
|
195
|
-
{place.rating.rating}
|
|
196
|
-
{kitchen.metaLabel && " · "}
|
|
197
|
-
</>
|
|
198
|
-
)}
|
|
226
|
+
<KitchenRating place={place} labels={labels} />
|
|
227
|
+
{kitchen.metaLabel && (gradeShown(place, labels) || place.rating) && " · "}
|
|
199
228
|
{kitchen.metaLabel}
|
|
200
229
|
</span>
|
|
201
230
|
{kitchen.hoursLabel && (
|