@bearmenu/ui 0.8.13 → 0.8.15
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/README.md +0 -1
- package/dist/{chunk-66MAPLXS.js → chunk-2ADCZXZJ.js} +1 -1
- package/dist/{chunk-2DEIXTBN.js → chunk-2ZXIXQIU.js} +1 -1
- package/dist/{chunk-YOKHBAIH.js → chunk-4OF4T4AI.js} +12 -11
- package/dist/{chunk-MZL7CGCL.js → chunk-4XDJXMLF.js} +2 -2
- package/dist/{chunk-VAXOQS7W.js → chunk-5FCC5L5F.js} +3 -3
- package/dist/{chunk-YYGB4G4Q.js → chunk-CZK2MRS2.js} +1 -1
- package/dist/chunk-DJD3EMPK.js +126 -0
- package/dist/chunk-EZG2NELX.js +5 -0
- package/dist/{chunk-VG3PND3D.js → chunk-FMTJGO76.js} +1 -1
- package/dist/{chunk-UXWAOISG.js → chunk-FVSKGCK3.js} +2 -2
- package/dist/{chunk-2XCZJWTV.js → chunk-GNCWJWFE.js} +1 -1
- package/dist/{chunk-X3WMRKOW.js → chunk-HDR7V6IZ.js} +1 -1
- package/dist/{chunk-HSIYYA2E.js → chunk-HQU6QVAN.js} +5 -5
- package/dist/chunk-I5V446BX.js +27 -0
- package/dist/{chunk-WCTHZKU7.js → chunk-ICOU5QHT.js} +1 -1
- package/dist/{chunk-G7IFL4Z4.js → chunk-L3VEMP5A.js} +57 -9
- package/dist/chunk-LQWGZIYA.js +5 -0
- package/dist/{chunk-XNA2INVQ.js → chunk-MCOHLWRS.js} +2 -2
- package/dist/{chunk-3GWWZKX7.js → chunk-MMUBH76A.js} +21 -1
- package/dist/{chunk-ZDAHKI3A.js → chunk-MWB7S54O.js} +1 -1
- package/dist/{chunk-D5QHEHXJ.js → chunk-NMEVJT5Q.js} +1 -1
- package/dist/{chunk-3TNPSN4D.js → chunk-NSNEANOQ.js} +2 -2
- package/dist/{chunk-WSRWFA6K.js → chunk-NWZGSLPU.js} +1 -1
- package/dist/{chunk-LEAYBICI.js → chunk-OIV7B44M.js} +1 -1
- package/dist/{chunk-2CXU5WZO.js → chunk-P43B3ONY.js} +1 -1
- package/dist/{chunk-FRPPIXMY.js → chunk-PDTPO6NG.js} +1 -1
- package/dist/{chunk-6XMYEZVR.js → chunk-PX6RICS5.js} +1 -1
- package/dist/{chunk-6TEEY5YA.js → chunk-S33K4RC5.js} +1 -1
- package/dist/{chunk-3VMDCCCX.js → chunk-SC2VUTUI.js} +1 -1
- package/dist/{chunk-3NMG3KNA.js → chunk-SXQZ7DLH.js} +3 -3
- package/dist/{chunk-UDTG3RSE.js → chunk-T6S2ZBV6.js} +2 -2
- package/dist/{chunk-R47NEOSI.js → chunk-V4E333QS.js} +29 -4
- package/dist/{chunk-FKNBZF5T.js → chunk-WYTJR2YU.js} +1 -1
- package/dist/{chunk-QXHMPJ35.js → chunk-XBBEX4SF.js} +1 -1
- package/dist/chunk-XCB3F6SF.js +16 -0
- package/dist/{chunk-7BWTYWM3.js → chunk-ZLMRVBD7.js} +1 -1
- package/dist/{chunk-P7XTW2CG.js → chunk-ZLPWEHZO.js} +1 -1
- package/dist/components/accordion.js +1 -1
- package/dist/components/alert-dialog.js +3 -3
- package/dist/components/alert.js +2 -2
- package/dist/components/aspect-ratio.js +2 -2
- package/dist/components/avatar.js +1 -1
- package/dist/components/badge.js +2 -2
- package/dist/components/breadcrumb.js +1 -1
- package/dist/components/button-group.js +1 -1
- package/dist/components/button.d.ts +4 -0
- package/dist/components/button.js +3 -3
- package/dist/components/calendar.js +3 -3
- package/dist/components/card.js +3 -3
- package/dist/components/carousel.js +3 -3
- package/dist/components/category-deck.js +2 -2
- package/dist/components/checkbox.js +2 -2
- package/dist/components/circular-progress.js +1 -1
- package/dist/components/collapsible.js +1 -1
- package/dist/components/combobox.js +6 -6
- package/dist/components/command.js +3 -3
- package/dist/components/concept-card.js +2 -2
- package/dist/components/concept-compare-rail.js +3 -3
- package/dist/components/concept-compare.d.ts +2 -1
- package/dist/components/concept-compare.js +5 -5
- package/dist/components/concept-convergence.js +4 -4
- package/dist/components/convergence.js +3 -3
- package/dist/components/coverflow.js +1 -1
- package/dist/components/currency-input.js +2 -2
- package/dist/components/date-input.js +2 -2
- package/dist/components/day-rail-chip.js +2 -2
- package/dist/components/description-list.js +1 -1
- package/dist/components/dialog.js +2 -2
- package/dist/components/doorway-tiles.d.ts +57 -0
- package/dist/components/doorway-tiles.js +86 -0
- package/dist/components/drawer.js +1 -1
- package/dist/components/drift-rail.js +1 -1
- package/dist/components/dropdown-menu.js +1 -1
- package/dist/components/empty-state.js +4 -4
- package/dist/components/event-card.js +4 -4
- package/dist/components/event-compact-row.js +4 -4
- package/dist/components/event-day-header.js +2 -2
- package/dist/components/event-day-separator.js +3 -3
- package/dist/components/event-detail-panel.js +5 -5
- package/dist/components/event-hub-hero.js +2 -2
- package/dist/components/event-index-row.js +4 -4
- package/dist/components/event-list-row-wide.js +6 -6
- package/dist/components/event-list-row.js +5 -5
- package/dist/components/event-poster-fallback.js +1 -1
- package/dist/components/event-types.js +1 -1
- package/dist/components/events-empty-state.js +1 -1
- package/dist/components/explainer-steps.js +1 -1
- package/dist/components/facet-group.js +2 -2
- package/dist/components/featured-rail-item.js +2 -2
- package/dist/components/field.js +2 -2
- package/dist/components/filter-category-row.js +3 -3
- package/dist/components/form.js +2 -2
- package/dist/components/glass-ground.js +2 -2
- package/dist/components/grade-atom.d.ts +3 -0
- package/dist/components/grade-atom.js +4 -0
- package/dist/components/hour-band.js +4 -4
- package/dist/components/hour-group.js +4 -4
- package/dist/components/hub-surface.js +1 -1
- package/dist/components/hue-chip.js +1 -1
- package/dist/components/icon.js +1 -1
- package/dist/components/input-group.js +1 -1
- package/dist/components/input-otp.js +1 -1
- package/dist/components/input.js +2 -2
- package/dist/components/item.js +1 -1
- package/dist/components/kbd.js +1 -1
- package/dist/components/kitchen-dossier.d.ts +2 -1
- package/dist/components/kitchen-dossier.js +4 -4
- package/dist/components/label.js +2 -2
- package/dist/components/lazy-markdown.js +1 -1
- package/dist/components/link-button.js +3 -3
- package/dist/components/markdown-renderer.js +1 -1
- package/dist/components/menu-dead-end.d.ts +2 -1
- package/dist/components/menu-dead-end.js +1 -1
- package/dist/components/menu-family-block.d.ts +2 -1
- package/dist/components/menu-family-block.js +15 -9
- package/dist/components/menu-family-card.d.ts +2 -1
- package/dist/components/menu-family-card.js +1 -1
- package/dist/components/menu-field.js +1 -1
- package/dist/components/menu-filter-chips.d.ts +2 -1
- package/dist/components/menu-filter-chips.js +3 -3
- package/dist/components/menu-group-rows.d.ts +2 -1
- package/dist/components/menu-group-rows.js +2 -2
- package/dist/components/menu-hub-hero.js +1 -1
- package/dist/components/menu-index-header.d.ts +2 -1
- package/dist/components/menu-index-header.js +2 -2
- package/dist/components/menu-index-list.d.ts +2 -1
- package/dist/components/menu-index-list.js +5 -5
- package/dist/components/menu-intent-hero.d.ts +3 -2
- package/dist/components/menu-intent-hero.js +1 -1
- package/dist/components/menu-item.d.ts +2 -1
- package/dist/components/menu-item.js +4 -4
- package/dist/components/menu-kitchen-list.d.ts +2 -1
- package/dist/components/menu-kitchen-list.js +4 -4
- package/dist/components/menu-mocks.d.ts +16 -5
- package/dist/components/menu-mocks.js +23 -2
- package/dist/components/menu-types.d.ts +21 -34
- package/dist/components/motion-icon-actions.d.ts +27 -0
- package/dist/components/motion-icon-actions.js +336 -0
- package/dist/components/motion-icon-controls.js +3 -3
- package/dist/components/motion-icon-set.d.ts +13 -1
- package/dist/components/motion-icon-set.js +197 -6
- package/dist/components/motion-icon.d.ts +15 -1
- package/dist/components/motion-icon.js +2 -2
- package/dist/components/multi-select-combobox.js +8 -8
- package/dist/components/multi-select-menu.js +2 -2
- package/dist/components/native-select.js +1 -1
- package/dist/components/open-now-list.d.ts +2 -1
- package/dist/components/open-now-list.js +2 -2
- package/dist/components/pagination.js +3 -3
- package/dist/components/phone-frame.js +1 -1
- package/dist/components/photo-ground.js +1 -1
- package/dist/components/place-about-tab.d.ts +2 -1
- package/dist/components/place-about-tab.js +6 -6
- package/dist/components/place-card.d.ts +94 -12
- package/dist/components/place-card.js +203 -128
- package/dist/components/place-details-mobile.d.ts +2 -1
- package/dist/components/place-details-mobile.js +7 -7
- package/dist/components/place-schedule-week.d.ts +2 -1
- package/dist/components/place-schedule-week.js +3 -3
- package/dist/components/place-types.d.ts +3 -265
- package/dist/components/popover.js +2 -2
- package/dist/components/poster-stack.js +1 -1
- package/dist/components/poster-tape.js +1 -1
- package/dist/components/poster-wall.d.ts +22 -6
- package/dist/components/poster-wall.js +197 -12
- package/dist/components/progress.js +1 -1
- package/dist/components/qa-block.d.ts +2 -1
- package/dist/components/qa-block.js +1 -1
- package/dist/components/quiet-stretch.js +1 -1
- package/dist/components/radio-group.js +1 -1
- package/dist/components/rating.js +1 -1
- package/dist/components/scroll-area.js +1 -1
- package/dist/components/scroll-fade.js +2 -2
- package/dist/components/search-bar.js +1 -1
- package/dist/components/searchable-select.js +6 -6
- package/dist/components/section-header.js +2 -2
- package/dist/components/segmented-nav.d.ts +24 -4
- package/dist/components/segmented-nav.js +11 -2
- package/dist/components/select.js +1 -1
- package/dist/components/selection-bar.js +1 -1
- package/dist/components/separator.js +2 -2
- package/dist/components/sheet.js +1 -1
- package/dist/components/signature-chip.js +3 -3
- package/dist/components/skeleton-card.js +3 -3
- package/dist/components/skeleton.js +2 -2
- package/dist/components/slider.js +1 -1
- package/dist/components/sliding-panels.js +3 -3
- package/dist/components/snap-rail.js +2 -2
- package/dist/components/sonner.js +1 -1
- package/dist/components/sort-option-list.js +1 -1
- package/dist/components/spinner.js +1 -1
- package/dist/components/stat-banner.js +1 -1
- package/dist/components/stepper.js +1 -1
- package/dist/components/sticky-container.js +1 -1
- package/dist/components/story.js +1 -1
- package/dist/components/switch.js +1 -1
- package/dist/components/table.js +1 -1
- package/dist/components/tabs.js +2 -2
- package/dist/components/tag-group.js +2 -2
- package/dist/components/tag.js +2 -2
- package/dist/components/text.js +2 -2
- package/dist/components/textarea.js +1 -1
- package/dist/components/timeline-band.js +4 -4
- package/dist/components/timeline-playhead.js +4 -4
- package/dist/components/toggle-group.js +2 -2
- package/dist/components/toggle.js +2 -2
- package/dist/components/tooltip.js +1 -1
- package/dist/components/top-comparison.d.ts +2 -1
- package/dist/components/top-comparison.js +1 -1
- package/dist/components/top-cross-link.d.ts +2 -1
- package/dist/components/top-cross-link.js +1 -1
- package/dist/components/top-ranking-entry.d.ts +2 -1
- package/dist/components/top-ranking-entry.js +6 -6
- package/dist/components/top-ranking-hero.d.ts +2 -1
- package/dist/components/top-ranking-hero.js +1 -1
- package/dist/components/top-ranking-legend.js +1 -1
- package/dist/components/top-types.d.ts +3 -1
- package/dist/components/use-mobile.js +1 -1
- package/dist/components/venue-events-block.js +5 -5
- package/dist/components/venue-grade-dimensions.d.ts +2 -1
- package/dist/components/venue-grade-dimensions.js +1 -1
- package/dist/components/venue-quotes.d.ts +2 -1
- package/dist/components/venue-quotes.js +1 -1
- package/dist/components/venue-wall.d.ts +2 -1
- package/dist/components/venue-wall.js +1 -1
- package/dist/components/weekday-theme-banner.js +1 -1
- package/dist/components/weekend-panel.js +4 -4
- package/dist/hooks/use-drag-swipe.js +1 -1
- package/dist/hooks/use-haptic.js +2 -2
- package/dist/hooks/use-media-query.js +1 -1
- package/dist/hooks/use-mobile.js +1 -1
- package/dist/hooks/use-mounted-theme.js +1 -1
- package/dist/hooks/use-sticky.js +1 -1
- package/dist/lib/card-hover.js +2 -18
- package/dist/lib/grade.d.ts +54 -0
- package/dist/lib/grade.js +2 -0
- package/dist/lib/icon-depth.d.ts +35 -0
- package/dist/lib/icon-depth.js +2 -0
- package/dist/lib/icon-registry.js +1 -1
- package/dist/lib/motion.js +2 -2
- package/dist/lib/overlay-pill.d.ts +30 -0
- package/dist/lib/overlay-pill.js +2 -0
- package/dist/lib/utils.js +1 -1
- package/dist/place-types-BHdeMMiG.d.ts +317 -0
- package/package.json +1 -1
- package/src/components/button.tsx +5 -1
- package/src/components/colour-dictionary.stories.tsx +268 -82
- package/src/components/doorway-tiles.stories.tsx +83 -0
- package/src/components/doorway-tiles.test.tsx +51 -0
- package/src/components/doorway-tiles.tsx +225 -0
- package/src/components/grade-atom.stories.tsx +81 -0
- package/src/components/grade-atom.tsx +256 -0
- package/src/components/hue-chip.stories.tsx +2 -2
- package/src/components/menu-family-block.stories.tsx +29 -0
- package/src/components/menu-family-block.test.tsx +51 -0
- package/src/components/menu-family-block.tsx +20 -4
- package/src/components/menu-intent-hero.tsx +1 -1
- package/src/components/menu-mocks.ts +39 -3
- package/src/components/menu-types.ts +17 -33
- package/src/components/motion-icon-actions.test.tsx +115 -0
- package/src/components/motion-icon-actions.tsx +580 -0
- package/src/components/motion-icon-controls.test.tsx +1 -0
- package/src/components/motion-icon-controls.tsx +18 -13
- package/src/components/motion-icon-set.stories.tsx +62 -3
- package/src/components/motion-icon-set.tsx +349 -2
- package/src/components/motion-icon.test.tsx +180 -1
- package/src/components/motion-icon.tsx +97 -8
- package/src/components/place-card.stories.tsx +66 -76
- package/src/components/place-card.test.tsx +188 -100
- package/src/components/place-card.tsx +356 -148
- package/src/components/place-types.ts +17 -4
- package/src/components/poster-wall.stories.tsx +84 -0
- package/src/components/poster-wall.test.tsx +94 -3
- package/src/components/poster-wall.tsx +257 -9
- package/src/components/segmented-nav.stories.tsx +72 -1
- package/src/components/segmented-nav.test.tsx +96 -0
- package/src/components/segmented-nav.tsx +36 -4
- package/src/globals.css +26 -0
- package/src/hooks/use-haptic.test.tsx +80 -0
- package/src/hooks/use-haptic.ts +45 -4
- package/src/lib/grade.test.ts +82 -0
- package/src/lib/grade.ts +76 -0
- package/src/lib/icon-depth.ts +35 -0
- package/src/lib/overlay-pill.ts +29 -0
- package/dist/components/haptic-button.d.ts +0 -12
- package/dist/components/haptic-button.js +0 -17
- package/dist/components/menu-family-tiles.d.ts +0 -19
- package/dist/components/menu-family-tiles.js +0 -57
- package/src/components/haptic-button.stories.tsx +0 -41
- package/src/components/haptic-button.tsx +0 -19
- package/src/components/menu-family-tiles.stories.tsx +0 -54
- package/src/components/menu-family-tiles.test.tsx +0 -30
- package/src/components/menu-family-tiles.tsx +0 -132
package/dist/hooks/use-sticky.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { useSticky } from '../chunk-EUHEIWHZ.js';
|
|
2
|
-
import '../chunk-
|
|
2
|
+
import '../chunk-MMUBH76A.js';
|
package/dist/lib/card-hover.js
CHANGED
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// src/lib/card-hover.ts
|
|
4
|
-
var HOVER_DURATION = "duration-[320ms]";
|
|
5
|
-
var HOVER_EASE = "ease-[cubic-bezier(0.4,0,0.2,1)]";
|
|
6
|
-
var HOVER_MOTION = `transition-transform ${HOVER_DURATION} ${HOVER_EASE} motion-reduce:transition-none will-change-transform`;
|
|
7
|
-
var HOVER_SHADOW_MOTION = `transition-shadow ${HOVER_DURATION} ${HOVER_EASE}`;
|
|
8
|
-
var HOVER_LIFT_GRID = "[@media(hover:hover)]:hover:-translate-y-1";
|
|
9
|
-
var HOVER_LIFT_GRID_GROUP = "[@media(hover:hover)]:group-hover/card:-translate-y-1";
|
|
10
|
-
var HOVER_LIFT_LIST = "[@media(hover:hover)]:hover:-translate-y-0.5";
|
|
11
|
-
var HOVER_IMAGE_SCALE = "group-hover:scale-[1.05]";
|
|
12
|
-
var HOVER_IMAGE_MOTION = `${HOVER_MOTION} ${HOVER_IMAGE_SCALE}`;
|
|
13
|
-
var HOVER_IMAGE_SHADOW = "shadow-[var(--shadow-card-image)] [@media(hover:hover)]:group-hover:shadow-[var(--shadow-card-image-hover)]";
|
|
14
|
-
var HOVER_IMAGE_SHADOW_INSET = "shadow-[var(--shadow-menu-cover-inset),var(--shadow-card-image)] [@media(hover:hover)]:group-hover:shadow-[var(--shadow-menu-cover-inset),var(--shadow-card-image-hover)]";
|
|
15
|
-
var HOVER_IMAGE_WRAPPER = `${HOVER_SHADOW_MOTION} ${HOVER_IMAGE_SHADOW}`;
|
|
16
|
-
var HOVER_IMAGE_WRAPPER_INSET = `${HOVER_SHADOW_MOTION} ${HOVER_IMAGE_SHADOW_INSET}`;
|
|
17
|
-
|
|
18
|
-
export { HOVER_DURATION, HOVER_EASE, HOVER_IMAGE_MOTION, HOVER_IMAGE_SCALE, HOVER_IMAGE_SHADOW, HOVER_IMAGE_SHADOW_INSET, HOVER_IMAGE_WRAPPER, HOVER_IMAGE_WRAPPER_INSET, HOVER_LIFT_GRID, HOVER_LIFT_GRID_GROUP, HOVER_LIFT_LIST, HOVER_MOTION, HOVER_SHADOW_MOTION };
|
|
1
|
+
export { HOVER_DURATION, HOVER_EASE, HOVER_IMAGE_MOTION, HOVER_IMAGE_SCALE, HOVER_IMAGE_SHADOW, HOVER_IMAGE_SHADOW_INSET, HOVER_IMAGE_WRAPPER, HOVER_IMAGE_WRAPPER_INSET, HOVER_LIFT_GRID, HOVER_LIFT_GRID_GROUP, HOVER_LIFT_LIST, HOVER_MOTION, HOVER_SHADOW_MOTION } from '../chunk-XCB3F6SF.js';
|
|
2
|
+
import '../chunk-MMUBH76A.js';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for the ReviewsDigest `grade` (1–10 Romanian school scale,
|
|
3
|
+
* food-anchored). Shared by `<GradeAtom>` and any surface that demotes the
|
|
4
|
+
* Google star in favour of the grade.
|
|
5
|
+
*/
|
|
6
|
+
/** Colour/quality band, derived from `grade.overall`. The label text comes
|
|
7
|
+
* from the caller's `GradeAtomLabels`; the band only drives the visual tone. */
|
|
8
|
+
type GradeBand = "exceptional" | "great" | "good" | "decent" | "weak";
|
|
9
|
+
/** Map a 1–10 overall score to its band. Boundaries are inclusive at the low end
|
|
10
|
+
* (9.0 → exceptional, 7.5 → great, 6.0 → good, 5.0 → decent, below 5 → weak). */
|
|
11
|
+
declare function resolveGradeBand(overall: number): GradeBand;
|
|
12
|
+
/** Format a grade for display: clamp to the 1–10 scale, keep one decimal of
|
|
13
|
+
* precision, and drop a trailing `.0` so whole grades read as "7" not "7.0". */
|
|
14
|
+
declare function formatGrade(overall: number): string;
|
|
15
|
+
/** The backend `show_number` is a display recommendation: when explicitly
|
|
16
|
+
* false, fall back to the soft state instead of the number. Unspecified → show. */
|
|
17
|
+
declare function shouldShowGradeNumber(grade: {
|
|
18
|
+
show_number?: boolean;
|
|
19
|
+
}): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Whether `<GradeAtom>` will render anything for this grade at this size — the
|
|
22
|
+
* predicate every caller must gate on before choosing the grade over its own
|
|
23
|
+
* Google-star fallback.
|
|
24
|
+
*
|
|
25
|
+
* `overall == null` has always meant "no grade, show the star". The `xs` rule
|
|
26
|
+
* is newer: at card size the right-hand slot is a 2–3 glyph METRIC slot, and
|
|
27
|
+
* the soft state is a two-word sentence ("Worth exploring" / "Merită
|
|
28
|
+
* explorat"). Rendered there it wrapped inside its own fixed-height pill and
|
|
29
|
+
* pushed the title into a hard truncation. The sentence still renders at `sm`+
|
|
30
|
+
* (drawer, hero) where there is room for it.
|
|
31
|
+
*
|
|
32
|
+
* Callers used to gate on `grade?.overall != null` directly, which is why this
|
|
33
|
+
* exists as a shared function: with the size rule added, that check no longer
|
|
34
|
+
* predicts whether the atom renders, and a caller using the old one lands on
|
|
35
|
+
* an empty slot instead of falling through to its star.
|
|
36
|
+
*
|
|
37
|
+
* Lives here rather than in `grade-atom.tsx` so SERVER components can call it —
|
|
38
|
+
* everything exported from a `"use client"` module is a client reference.
|
|
39
|
+
*
|
|
40
|
+
* A type predicate, so the true branch also narrows away the `undefined` that
|
|
41
|
+
* `place.reviews_digest?.grade` carries and the caller can pass it straight to
|
|
42
|
+
* `<GradeAtom grade={...}>`.
|
|
43
|
+
*/
|
|
44
|
+
declare function showsGradeAtom<T extends {
|
|
45
|
+
overall?: number | null;
|
|
46
|
+
show_number?: boolean;
|
|
47
|
+
}>(grade: T | null | undefined, size: "xs" | "sm" | "md" | "lg"): grade is T;
|
|
48
|
+
/** Tone for a single 0–100 dimension score, driving the page dimension-bar
|
|
49
|
+
* colour: strong (≥75) = accent, adequate (50–74) = muted, low (<50) = amber
|
|
50
|
+
* (a soft "fair warning", never error-red). */
|
|
51
|
+
type DimensionTone = "strong" | "adequate" | "low";
|
|
52
|
+
declare function resolveDimensionTone(score: number): DimensionTone;
|
|
53
|
+
|
|
54
|
+
export { type DimensionTone, type GradeBand, formatGrade, resolveDimensionTone, resolveGradeBand, shouldShowGradeNumber, showsGradeAtom };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layered drop-shadow filter that "raises" a flat icon off a tinted surface.
|
|
3
|
+
*
|
|
4
|
+
* Two stops stacked: a tight 1px close shadow welds the icon to the surface
|
|
5
|
+
* (so it doesn't float disconnected), then a wider 3px/8px lift gives it
|
|
6
|
+
* presence. The combo is what makes the homepage cuisine tiles read as
|
|
7
|
+
* embossed plaques instead of stickers — reuse it anywhere an icon sits on
|
|
8
|
+
* a warm gradient (entity-card photo fallbacks, etc).
|
|
9
|
+
*
|
|
10
|
+
* Designed for white / light icons on the warm `--gradient-primary` family.
|
|
11
|
+
* Don't apply to icons on light surfaces — the dark drop-shadow stops will
|
|
12
|
+
* read as muddy outlines instead of depth.
|
|
13
|
+
*/
|
|
14
|
+
declare const RAISED_ICON_FILTER = "drop-shadow(0 1px 1px oklch(0 0 0 / 0.6)) drop-shadow(0 3px 8px oklch(0 0 0 / 0.4))";
|
|
15
|
+
/**
|
|
16
|
+
* The light-surface counterpart, for glyphs on the neutral placeholder panel
|
|
17
|
+
* (`from-muted to-border`) that entity-card photo fallbacks share.
|
|
18
|
+
*
|
|
19
|
+
* `RAISED_ICON_FILTER` is black and wide — correct under a white icon on the
|
|
20
|
+
* brown gradient, wrong everywhere else. On a near-white panel its 8px black
|
|
21
|
+
* stop pools under the glyph and reads as grime rather than lift.
|
|
22
|
+
*
|
|
23
|
+
* What fixes that is hue and spread, not just less shadow: this one is a deep
|
|
24
|
+
* brown (same 45° hue as `--shadow-card`) capped at a 4px lift. Halving the
|
|
25
|
+
* spread is what kills the smudge, which then buys enough headroom on alpha
|
|
26
|
+
* for the glyph to still read as raised rather than washed out — a warm
|
|
27
|
+
* shadow tolerates far more opacity than a black one before it looks dirty.
|
|
28
|
+
*
|
|
29
|
+
* Resolves through a token (`--icon-depth-neutral` in `globals.css`), so dark
|
|
30
|
+
* mode gets its own value — there the panel is already dark and a halo does
|
|
31
|
+
* nothing, so it collapses to one contact stop.
|
|
32
|
+
*/
|
|
33
|
+
declare const NEUTRAL_ICON_FILTER = "var(--icon-depth-neutral)";
|
|
34
|
+
|
|
35
|
+
export { NEUTRAL_ICON_FILTER, RAISED_ICON_FILTER };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import '../chunk-
|
|
1
|
+
import '../chunk-MMUBH76A.js';
|
|
2
2
|
import { Info, Flag, Phone, RefreshCw, Trash2, Plus, Check, Bookmark, Heart, Share2, Search, ArrowUpDown, SlidersHorizontal, ChevronDown, XCircle, X, ExternalLink, Navigation, ChevronRight, ChevronLeft, ArrowRight, ArrowLeft } from 'lucide-react';
|
|
3
3
|
|
|
4
4
|
var iconFor = {
|
package/dist/lib/motion.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { archetype, contentSwapVariants, duration, ease, listRevealVariants, skeletonSwapVariants, springGentle, springSmooth, springSnappy, springSoft, stagger } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { archetype, contentSwapVariants, duration, ease, listRevealVariants, skeletonSwapVariants, springGentle, springSmooth, springSnappy, springSoft, stagger } from '../chunk-OIV7B44M.js';
|
|
2
|
+
import '../chunk-MMUBH76A.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE geometry for every pill that sits on a card image — places and events.
|
|
3
|
+
*
|
|
4
|
+
* These had drifted into four different sizes on the event card (hype at
|
|
5
|
+
* `min-h-8`, Free at `text-xs px-2.5 py-1`, concept and tags at `text-[10px]
|
|
6
|
+
* px-2 py-0.5`) and three more on the place card (Trending at `min-h-8`, the
|
|
7
|
+
* Closed pill at `text-xs py-0.5`, the open dot at `h-2`), so corners of the
|
|
8
|
+
* same card — and cards sitting in the same rail — read as unrelated systems.
|
|
9
|
+
*
|
|
10
|
+
* An explicit `h-6` rather than a padding-derived height is what actually
|
|
11
|
+
* guarantees they match: the hype pill contains a gauge glyph, Trending
|
|
12
|
+
* contains a flame, and the rest contain 12px icons, so equal padding would
|
|
13
|
+
* still produce unequal heights.
|
|
14
|
+
*
|
|
15
|
+
* 24px is deliberate over the 32px `heatPillVariants` `md`. The only argument
|
|
16
|
+
* for 32 was the tap target on the interactive Trending pill, and that pill
|
|
17
|
+
* already carries an `after:-inset-2` hit-area expander (~40px effective)
|
|
18
|
+
* which solves it independently of the visual size. 24px is also exactly the
|
|
19
|
+
* WCAG 2.5.8 (AA) minimum on its own, before the expander.
|
|
20
|
+
*
|
|
21
|
+
* Pair with `Badge` (`variant="overlay"` is the scrim: `bg-foreground/80
|
|
22
|
+
* text-background`) rather than hand-rolled spans, which is what let these
|
|
23
|
+
* drift in the first place. Only the radius is overridden — the `Badge`
|
|
24
|
+
* default is `rounded-lg` and pills on photography read better fully round.
|
|
25
|
+
*/
|
|
26
|
+
declare const OVERLAY_PILL = "h-6 gap-1 rounded-full px-2 text-2xs font-semibold shadow-sm";
|
|
27
|
+
/** Icon size inside an `OVERLAY_PILL`. */
|
|
28
|
+
declare const OVERLAY_ICON = "h-3 w-3 shrink-0";
|
|
29
|
+
|
|
30
|
+
export { OVERLAY_ICON, OVERLAY_PILL };
|
package/dist/lib/utils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { cn } from '../chunk-FEK5XGZW.js';
|
|
2
|
-
import '../chunk-
|
|
2
|
+
import '../chunk-MMUBH76A.js';
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { GradeBand } from './lib/grade.js';
|
|
3
|
+
|
|
4
|
+
type GradeAtomSize = "xs" | "sm" | "md" | "lg";
|
|
5
|
+
/** Labels passed to `<GradeAtom>`. All translation happens in the caller. */
|
|
6
|
+
type GradeAtomLabels = {
|
|
7
|
+
/** The `show_number=false` state, e.g. "Worth exploring". */
|
|
8
|
+
soft: string;
|
|
9
|
+
/** Band → descriptor shown beside the number from `sm` up, e.g. "Great". */
|
|
10
|
+
bands: Record<GradeBand, string>;
|
|
11
|
+
/** Accessible name for the pill, e.g. "Grade 8.2 out of 10". */
|
|
12
|
+
aria: (value: string) => string;
|
|
13
|
+
/** Title + aria suffix when `grade.capped`, e.g. "Capped for low confidence". */
|
|
14
|
+
capped: string;
|
|
15
|
+
};
|
|
16
|
+
type GradeAtomProps = {
|
|
17
|
+
grade: PlaceGrade;
|
|
18
|
+
labels: GradeAtomLabels;
|
|
19
|
+
/** xs = card chip · sm = chat/compact · md = drawer · lg = page hero. */
|
|
20
|
+
size?: GradeAtomSize;
|
|
21
|
+
/** Force-hide the descriptor even at sizes that would show it (tight rows). */
|
|
22
|
+
hideDescriptor?: boolean;
|
|
23
|
+
/** Rendered over a photo (e.g. the page hero). Switches to a frosted-dark
|
|
24
|
+
* shell with the band hue on the number + ring, so it stays legible and
|
|
25
|
+
* band-recognizable on any image. */
|
|
26
|
+
onPhoto?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Adds a trailing `Info` glyph, for the one caller where the chip IS the
|
|
29
|
+
* disclosure trigger (the place hero, wrapped in a grade explainer).
|
|
30
|
+
*
|
|
31
|
+
* Off by default and it must stay that way: on cards this atom is a readout,
|
|
32
|
+
* and an affordance marker on something that doesn't open would be a lie. The
|
|
33
|
+
* glyph goes INSIDE the pill rather than beside it — outside, it would be a
|
|
34
|
+
* bare icon on unpredictable photo luminance, and it would read as a second
|
|
35
|
+
* control next to the chip instead of part of it.
|
|
36
|
+
*/
|
|
37
|
+
showInfo?: boolean;
|
|
38
|
+
className?: string;
|
|
39
|
+
};
|
|
40
|
+
declare function GradeAtom({ grade, labels, size, hideDescriptor, onPhoto, showInfo, className, }: GradeAtomProps): react_jsx_runtime.JSX.Element | null;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Structural mirror of the openapi `Place` schema, decoupled from any one app's
|
|
44
|
+
* generated types. Both FE and admin map their domain shapes into this type
|
|
45
|
+
* before passing data to `<PlaceCard>` / `<PlaceAboutTab>`.
|
|
46
|
+
*/
|
|
47
|
+
type PlacePreview = {
|
|
48
|
+
id: string;
|
|
49
|
+
slug: string;
|
|
50
|
+
name: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
generative_summary?: string;
|
|
53
|
+
review_summary?: string;
|
|
54
|
+
open_now?: boolean;
|
|
55
|
+
rating?: {
|
|
56
|
+
rating: number;
|
|
57
|
+
count: number;
|
|
58
|
+
};
|
|
59
|
+
review_count?: number;
|
|
60
|
+
hours?: PlaceHourBlock[];
|
|
61
|
+
today_schedule?: PlaceHourBlock[];
|
|
62
|
+
schedule?: PlaceSchedule;
|
|
63
|
+
location?: {
|
|
64
|
+
address?: string;
|
|
65
|
+
geolocation?: {
|
|
66
|
+
lat: number | string;
|
|
67
|
+
lon: number | string;
|
|
68
|
+
};
|
|
69
|
+
distance?: {
|
|
70
|
+
meters?: number;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
price_dishes?: PlacePriceRange;
|
|
74
|
+
price_drinks?: PlacePriceRange;
|
|
75
|
+
cuisines?: string[];
|
|
76
|
+
amenities?: string[];
|
|
77
|
+
payment_options?: string[];
|
|
78
|
+
accessibility_features?: string[];
|
|
79
|
+
parking_options?: string[];
|
|
80
|
+
landmarks?: Array<{
|
|
81
|
+
name: string;
|
|
82
|
+
distance_meters?: number;
|
|
83
|
+
}>;
|
|
84
|
+
areas?: Array<{
|
|
85
|
+
name: string;
|
|
86
|
+
}>;
|
|
87
|
+
busyness?: Array<{
|
|
88
|
+
hour: number;
|
|
89
|
+
score: number;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* The review distillation. Drives every menu-hub surface that speaks for a
|
|
93
|
+
* venue — `<KitchenDossier>`, `<MenuKitchenList>`, `<OpenNowList>` —
|
|
94
|
+
* because the signature dish, the pull-quotes and the graded dimensions all
|
|
95
|
+
* live here rather than on the menu itself.
|
|
96
|
+
*/
|
|
97
|
+
reviews_digest?: PlaceReviewsDigest;
|
|
98
|
+
type?: string;
|
|
99
|
+
business_status?: 'operational' | 'closed_temporarily' | 'closed_permanently';
|
|
100
|
+
phone?: string;
|
|
101
|
+
website_url?: string;
|
|
102
|
+
socials?: {
|
|
103
|
+
instagram_url?: string;
|
|
104
|
+
facebook_url?: string;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Pre-resolved thumbnail URL. Callers compute this themselves
|
|
108
|
+
* (FE: `https://cdn.bear.menu/places/${slug}-thumbnail.jpg`,
|
|
109
|
+
* admin: form's primary photo URL or blob URL).
|
|
110
|
+
*/
|
|
111
|
+
thumbnail_url?: string;
|
|
112
|
+
/**
|
|
113
|
+
* The card's cover photo. What `<PlaceCard>` renders in its 4:3 slot; with
|
|
114
|
+
* the default plain `<img>` this must be a loadable URL, with an injected
|
|
115
|
+
* `imageComponent` it is whatever that component accepts (fe passes the
|
|
116
|
+
* bare storage key straight to `next/image`'s loader).
|
|
117
|
+
*/
|
|
118
|
+
cover_url?: string;
|
|
119
|
+
};
|
|
120
|
+
type PlaceHourBlock = {
|
|
121
|
+
opens_at: number;
|
|
122
|
+
closes_at: number;
|
|
123
|
+
};
|
|
124
|
+
type WeekdayKey = 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
|
|
125
|
+
type PlaceSchedule = Record<WeekdayKey, PlaceHourBlock[]>;
|
|
126
|
+
type PlacePriceRange = {
|
|
127
|
+
price_range_low?: number;
|
|
128
|
+
price_range_high?: number;
|
|
129
|
+
/** Median price across the place's menu, in the local currency. */
|
|
130
|
+
median_price?: number;
|
|
131
|
+
/** 1–4 price level, rendered as `$` glyphs on `<PlaceCard>`. 0 / absent = no signal. */
|
|
132
|
+
price_score?: number;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Menu items are priced per size; a single-size item still ships one entry.
|
|
136
|
+
*
|
|
137
|
+
* Defined here rather than in `menu-types.ts` because `PlaceMustTry` carries
|
|
138
|
+
* it, and `menu-types.ts` already imports from this file — keeping the
|
|
139
|
+
* definition here leaves that import one-directional. `menu-types.ts`
|
|
140
|
+
* re-exports it, so menu code never reaches into place types for it.
|
|
141
|
+
*/
|
|
142
|
+
type MenuSizeAndPrice = {
|
|
143
|
+
/** Grams or millilitres. */
|
|
144
|
+
size: number;
|
|
145
|
+
price: number;
|
|
146
|
+
discounted_price?: number;
|
|
147
|
+
discount_percentage?: number;
|
|
148
|
+
};
|
|
149
|
+
/** A digest string with the reviews that back it. `review_ids.length` is the mention count. */
|
|
150
|
+
type CitedText = {
|
|
151
|
+
text: string;
|
|
152
|
+
review_ids?: string[];
|
|
153
|
+
};
|
|
154
|
+
/** A digest enum value with the reviews that back it. The value is a language-neutral code. */
|
|
155
|
+
type CitedValue = {
|
|
156
|
+
value: string;
|
|
157
|
+
review_ids?: string[];
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* One dish or drink the reviews single out.
|
|
161
|
+
*
|
|
162
|
+
* `mentions` and `score` come from the item census and are only served by the
|
|
163
|
+
* place DETAIL endpoint — a listing carries the item without them. Surfaces
|
|
164
|
+
* that need a count from a list fall back to `review_ids.length`, which is
|
|
165
|
+
* present in both. `strength`, `why` and `review_ids` are absent for census
|
|
166
|
+
* items the prose digest never mentioned, so none of them can be assumed.
|
|
167
|
+
*/
|
|
168
|
+
type PlaceMustTry = {
|
|
169
|
+
name: string;
|
|
170
|
+
why?: string;
|
|
171
|
+
strength?: 'signature' | 'frequent' | 'occasional';
|
|
172
|
+
/** Deep-link slug. Present only when the item matched a live menu row. */
|
|
173
|
+
slug?: string;
|
|
174
|
+
sizes_and_prices?: MenuSizeAndPrice[];
|
|
175
|
+
review_ids?: string[];
|
|
176
|
+
/** 0–100 census sentiment. Detail endpoint only; 3+ mentions required. */
|
|
177
|
+
score?: number;
|
|
178
|
+
/** Censused review mentions of this item. Detail endpoint only. */
|
|
179
|
+
mentions?: number;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Per-dimension 0–100 review scores.
|
|
183
|
+
*
|
|
184
|
+
* A dimension the reviews never mention is ABSENT, not zero — so a surface
|
|
185
|
+
* drawing these must render what it is given rather than a fixed row of seven.
|
|
186
|
+
* Exactly one of `food` / `coffee_quality` / `drinks_quality` is scored per
|
|
187
|
+
* place: a coffee bar has no food score and a restaurant has no coffee one.
|
|
188
|
+
*/
|
|
189
|
+
type PlaceGradeDimensions = {
|
|
190
|
+
food?: number;
|
|
191
|
+
coffee_quality?: number;
|
|
192
|
+
drinks_quality?: number;
|
|
193
|
+
value?: number;
|
|
194
|
+
service?: number;
|
|
195
|
+
cleanliness?: number;
|
|
196
|
+
ambiance?: number;
|
|
197
|
+
portion?: number;
|
|
198
|
+
consistency?: number;
|
|
199
|
+
};
|
|
200
|
+
type PlaceGrade = {
|
|
201
|
+
/** 1.0–10.0. */
|
|
202
|
+
overall?: number;
|
|
203
|
+
/**
|
|
204
|
+
* Backend recommendation to show the number at all. When false the caller
|
|
205
|
+
* should draw a "building confidence" state instead — the DS renders what it
|
|
206
|
+
* is told, it does not apply the rule.
|
|
207
|
+
*/
|
|
208
|
+
show_number?: boolean;
|
|
209
|
+
/** Locale-resolved band label, e.g. "Foarte bun". Already translated upstream. */
|
|
210
|
+
descriptor?: string;
|
|
211
|
+
confidence?: 'low' | 'medium' | 'high';
|
|
212
|
+
capped?: boolean;
|
|
213
|
+
dimensions?: PlaceGradeDimensions;
|
|
214
|
+
};
|
|
215
|
+
type PlaceReviewsDigest = {
|
|
216
|
+
grade?: PlaceGrade;
|
|
217
|
+
grade_note?: string;
|
|
218
|
+
tagline?: CitedText;
|
|
219
|
+
verdict?: CitedText;
|
|
220
|
+
caveat?: CitedText;
|
|
221
|
+
/** 1–3 standout positives. The pull-quotes on `<KitchenDossier>`. */
|
|
222
|
+
highlights?: CitedText[];
|
|
223
|
+
must_try?: PlaceMustTry[];
|
|
224
|
+
/** Vibe codes (cozy, quiet, family_friendly, …). Localised by the caller. */
|
|
225
|
+
tags?: CitedValue[];
|
|
226
|
+
dietary?: CitedValue[];
|
|
227
|
+
/** small | moderate | generous */
|
|
228
|
+
portion_size?: CitedValue;
|
|
229
|
+
/** cheap | fair | mid_range | splurge */
|
|
230
|
+
value?: CitedValue;
|
|
231
|
+
/** quiet | moderate | loud */
|
|
232
|
+
noise_level?: CitedValue;
|
|
233
|
+
/** Text reviews behind the digest. */
|
|
234
|
+
review_count?: number;
|
|
235
|
+
};
|
|
236
|
+
/** Labels passed to `<PlaceCard>`. All translation happens in the caller. */
|
|
237
|
+
type PlaceCardLabels = {
|
|
238
|
+
/** The frosted pill on the photo when `open_now === false`. */
|
|
239
|
+
closed: string;
|
|
240
|
+
/** Accessible name of the whole card, e.g. "View details for Casa Gri". */
|
|
241
|
+
viewDetails: (name: string) => string;
|
|
242
|
+
/** Accessible name of the `$` price glyphs, e.g. "Price level 2 of 4". */
|
|
243
|
+
priceLevel: (level: number) => string;
|
|
244
|
+
grade: GradeAtomLabels;
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Labels passed to `<PlaceAboutTab>`. All translation happens in the caller.
|
|
248
|
+
*
|
|
249
|
+
* Dynamic suffix maps (`amenityLabels`, etc.) translate API enum values like
|
|
250
|
+
* `wheelchair_accessible_entrance` into human strings. Missing keys fall back
|
|
251
|
+
* to the raw enum value (with underscores → spaces).
|
|
252
|
+
*/
|
|
253
|
+
type PlaceAboutTabLabels = {
|
|
254
|
+
/** Section heading for the editorial prose block (generative summary + review summary + description). */
|
|
255
|
+
description: string;
|
|
256
|
+
contactAndLocation: string;
|
|
257
|
+
instagram: string;
|
|
258
|
+
facebook: string;
|
|
259
|
+
/** Section heading for the inline weekly schedule. */
|
|
260
|
+
todayHours: string;
|
|
261
|
+
/** Used by the inline schedule's closed-day line-through. */
|
|
262
|
+
statusClosed: string;
|
|
263
|
+
typicalBusyness: string;
|
|
264
|
+
cuisines: string;
|
|
265
|
+
amenities: string;
|
|
266
|
+
paymentOptions: string;
|
|
267
|
+
accessibility: string;
|
|
268
|
+
parking: string;
|
|
269
|
+
nearbyLandmarks: string;
|
|
270
|
+
/** Weekday key → translated day name, consumed by the inline `<PlaceScheduleWeek>`. */
|
|
271
|
+
scheduleDays: Record<WeekdayKey, string>;
|
|
272
|
+
/** Fallback shown by `<PlaceScheduleWeek>` when no schedule data is present. */
|
|
273
|
+
noHoursAvailable: string;
|
|
274
|
+
amenityLabels: Record<string, string>;
|
|
275
|
+
paymentLabels: Record<string, string>;
|
|
276
|
+
accessibilityLabels: Record<string, string>;
|
|
277
|
+
parkingLabels: Record<string, string>;
|
|
278
|
+
typeLabels: Record<string, string>;
|
|
279
|
+
statusLabels: Record<string, string>;
|
|
280
|
+
};
|
|
281
|
+
/** Discriminator for `<PlaceAboutTab>`'s `onLinkClick` callback. */
|
|
282
|
+
type PlaceLinkKind = 'phone' | 'website' | 'instagram' | 'facebook' | 'address';
|
|
283
|
+
/** Labels passed to `<PlaceScheduleWeek>`. */
|
|
284
|
+
type PlaceScheduleWeekLabels = {
|
|
285
|
+
days: Record<WeekdayKey, string>;
|
|
286
|
+
closed: string;
|
|
287
|
+
/** Shown when the `schedule` prop is missing or empty. */
|
|
288
|
+
noHoursAvailable: string;
|
|
289
|
+
};
|
|
290
|
+
/**
|
|
291
|
+
* Labels passed to `<PlaceDetailsMobile>`. Extends `PlaceAboutTabLabels` with
|
|
292
|
+
* the header/tab-strip strings unique to the mobile place-details surface.
|
|
293
|
+
*/
|
|
294
|
+
type PlaceDetailsMobileLabels = PlaceAboutTabLabels & {
|
|
295
|
+
/** Tab strip — "About" is highlighted, the rest are visual placeholders. */
|
|
296
|
+
tabs: {
|
|
297
|
+
menu: string;
|
|
298
|
+
about: string;
|
|
299
|
+
reviews: string;
|
|
300
|
+
events: string;
|
|
301
|
+
};
|
|
302
|
+
/** Status badge over the hero image and the inline open/closed pill in the info row. */
|
|
303
|
+
statusBadge: {
|
|
304
|
+
openNow: string;
|
|
305
|
+
closed: string;
|
|
306
|
+
/** Inserted with surrounding " · " separators. e.g. "Closes at" */
|
|
307
|
+
closesAt: string;
|
|
308
|
+
opensAt: string;
|
|
309
|
+
opensTomorrow: string;
|
|
310
|
+
};
|
|
311
|
+
/** Review count formatter. Pass a translator that handles ICU pluralization. */
|
|
312
|
+
reviewCount: (count: number) => string;
|
|
313
|
+
/** "No image available" fallback shown when no thumbnail is set. */
|
|
314
|
+
noImageAvailable: string;
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
export { type CitedText as C, GradeAtom as G, type MenuSizeAndPrice as M, type PlacePreview as P, type WeekdayKey as W, type PlaceGradeDimensions as a, type PlaceAboutTabLabels as b, type PlaceLinkKind as c, type PlaceCardLabels as d, type PlaceDetailsMobileLabels as e, type PlaceSchedule as f, type PlaceScheduleWeekLabels as g, type GradeAtomLabels as h, type GradeAtomProps as i, type GradeAtomSize as j, type CitedValue as k, type PlaceGrade as l, type PlaceHourBlock as m, type PlaceMustTry as n, type PlacePriceRange as o, type PlaceReviewsDigest as p };
|
package/package.json
CHANGED
|
@@ -79,6 +79,10 @@ const buttonVariants = cva(
|
|
|
79
79
|
export interface ButtonProps
|
|
80
80
|
extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
81
81
|
asChild?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Off by default. Haptics are for actions that change state — a save, a
|
|
84
|
+
* toggle, a destructive confirm — not for every button, so each site opts in.
|
|
85
|
+
*/
|
|
82
86
|
haptic?: boolean;
|
|
83
87
|
hapticStyle?: "light" | "medium" | "heavy";
|
|
84
88
|
isLoading?: boolean;
|
|
@@ -92,7 +96,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
92
96
|
size,
|
|
93
97
|
fullWidth,
|
|
94
98
|
asChild = false,
|
|
95
|
-
haptic =
|
|
99
|
+
haptic = false,
|
|
96
100
|
hapticStyle = "light",
|
|
97
101
|
isLoading = false,
|
|
98
102
|
disabled,
|