@bearmenu/ui 0.8.10 → 0.8.12
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-UKBNQO6Q.js → chunk-2CXU5WZO.js} +1 -1
- package/dist/{chunk-62ES6N32.js → chunk-43RC7MHY.js} +1 -1
- package/dist/{chunk-Q6QH52LJ.js → chunk-6TEEY5YA.js} +2 -2
- package/dist/{chunk-UDN7UHJW.js → chunk-7A42J73Q.js} +3 -2
- package/dist/{chunk-5RWTOT5Y.js → chunk-CNJQUHCU.js} +11 -1
- package/dist/{chunk-TH6W2PWG.js → chunk-UDTG3RSE.js} +1 -1
- package/dist/{chunk-H3BV4VAG.js → chunk-VAXOQS7W.js} +14 -2
- package/dist/{chunk-SY6RV476.js → chunk-WCTHZKU7.js} +10 -21
- package/dist/{chunk-AKQ57NXY.js → chunk-ZQ53AGML.js} +2 -2
- package/dist/components/alert-dialog.js +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.js +1 -1
- package/dist/components/calendar.js +1 -1
- package/dist/components/carousel.js +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/concept-compare-rail.js +2 -2
- package/dist/components/concept-compare.d.ts +1 -1
- package/dist/components/concept-compare.js +31 -10
- package/dist/components/concept-convergence.js +2 -2
- package/dist/components/empty-state.js +1 -1
- package/dist/components/event-detail-panel.js +1 -1
- package/dist/components/event-list-row-wide.js +1 -1
- package/dist/components/filter-category-row.js +1 -1
- package/dist/components/glass-ground.d.ts +26 -31
- package/dist/components/glass-ground.js +1 -1
- package/dist/components/haptic-button.js +1 -1
- package/dist/components/input-group.d.ts +2 -2
- package/dist/components/input.d.ts +1 -1
- package/dist/components/item.d.ts +15 -5
- package/dist/components/item.js +15 -10
- package/dist/components/kitchen-dossier.d.ts +9 -7
- package/dist/components/kitchen-dossier.js +31 -25
- package/dist/components/link-button.js +1 -1
- package/dist/components/menu-family-block.d.ts +22 -17
- package/dist/components/menu-family-block.js +62 -61
- package/dist/components/menu-family-card.js +2 -4
- package/dist/components/menu-family-tiles.d.ts +19 -0
- package/dist/components/menu-family-tiles.js +57 -0
- package/dist/components/menu-hub-hero.js +18 -11
- package/dist/components/menu-index-list.d.ts +31 -12
- package/dist/components/menu-index-list.js +68 -31
- package/dist/components/menu-intent-hero.d.ts +1 -1
- package/dist/components/menu-item.js +3 -3
- package/dist/components/menu-mocks.d.ts +10 -3
- package/dist/components/menu-mocks.js +21 -9
- package/dist/components/menu-types.d.ts +33 -10
- package/dist/components/multi-select-combobox.js +2 -2
- package/dist/components/pagination.js +1 -1
- package/dist/components/photo-ground.d.ts +8 -2
- package/dist/components/photo-ground.js +1 -1
- package/dist/components/place-details-mobile.js +1 -1
- package/dist/components/searchable-select.js +1 -1
- package/dist/components/signature-chip.d.ts +2 -2
- package/dist/components/signature-chip.js +2 -2
- package/dist/components/sliding-panels.js +1 -1
- package/dist/components/top-ranking-entry.js +3 -3
- package/dist/components/venue-grade-dimensions.js +1 -1
- package/dist/components/venue-quotes.d.ts +1 -1
- package/dist/components/venue-quotes.js +1 -1
- package/dist/components/venue-wall.js +5 -3
- package/dist/components/weekday-theme-banner.d.ts +24 -3
- package/dist/components/weekday-theme-banner.js +63 -15
- package/package.json +1 -1
- package/src/components/badge.tsx +1 -1
- package/src/components/button.stories.tsx +25 -2
- package/src/components/button.tsx +14 -2
- package/src/components/colour-dictionary.stories.tsx +1 -1
- package/src/components/concept-compare-rail.tsx +2 -1
- package/src/components/concept-compare.stories.tsx +3 -3
- package/src/components/concept-compare.tsx +50 -14
- package/src/components/glass-ground.tsx +31 -56
- package/src/components/item.tsx +69 -45
- package/src/components/kitchen-dossier.stories.tsx +1 -1
- package/src/components/kitchen-dossier.tsx +60 -40
- package/src/components/menu-family-block.stories.tsx +3 -3
- package/src/components/menu-family-block.tsx +94 -98
- package/src/components/menu-family-card.stories.tsx +2 -2
- package/src/components/menu-family-card.tsx +6 -13
- package/src/components/menu-family-tiles.stories.tsx +54 -0
- package/src/components/menu-family-tiles.test.tsx +30 -0
- package/src/components/menu-family-tiles.tsx +132 -0
- package/src/components/menu-hub-hero.test.tsx +39 -0
- package/src/components/menu-hub-hero.tsx +30 -12
- package/src/components/menu-index-list.stories.tsx +6 -1
- package/src/components/menu-index-list.tsx +101 -54
- package/src/components/menu-intent-hero.tsx +1 -1
- package/src/components/menu-mocks.ts +32 -9
- package/src/components/menu-types.ts +32 -9
- package/src/components/photo-ground.tsx +14 -2
- package/src/components/signature-chip.tsx +3 -3
- package/src/components/venue-grade-dimensions.tsx +9 -2
- package/src/components/venue-quotes.stories.tsx +1 -1
- package/src/components/venue-quotes.tsx +4 -2
- package/src/components/venue-wall.tsx +9 -4
- package/src/components/weekday-theme-banner.stories.tsx +43 -4
- package/src/components/weekday-theme-banner.tsx +95 -18
- package/dist/components/menu-intent-tiles.d.ts +0 -31
- package/dist/components/menu-intent-tiles.js +0 -50
- package/src/components/menu-intent-tiles.stories.tsx +0 -54
- package/src/components/menu-intent-tiles.tsx +0 -76
|
@@ -12,7 +12,7 @@ var badgeVariants = cva(
|
|
|
12
12
|
secondary: "border-transparent bg-secondary text-secondary-foreground",
|
|
13
13
|
destructive: "border-transparent bg-destructive text-destructive-foreground",
|
|
14
14
|
outline: "text-foreground border-border",
|
|
15
|
-
overlay: "border-transparent bg-foreground/
|
|
15
|
+
overlay: "border-transparent bg-foreground/80 text-background",
|
|
16
16
|
glass: "glass text-foreground border-border/50",
|
|
17
17
|
success: "border-transparent bg-success text-success-foreground",
|
|
18
18
|
warning: "border-transparent bg-warning text-warning-foreground",
|
|
@@ -8,7 +8,7 @@ function VenueQuotes({ quotes, onCite, citeLabel, limit, className }) {
|
|
|
8
8
|
var _a, _b;
|
|
9
9
|
const citations = (_b = (_a = quote.review_ids) == null ? void 0 : _a.length) != null ? _b : 0;
|
|
10
10
|
const canCite = !!onCite && citations > 0;
|
|
11
|
-
const text = /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 border-border pl-3 font-serif text-[13px]
|
|
11
|
+
const text = /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 border-border pl-3 font-serif text-[13px] leading-[1.45] text-muted-foreground", children: `\u201C${quote.text}\u201D` });
|
|
12
12
|
if (!canCite) return /* @__PURE__ */ jsx("div", { children: text }, index);
|
|
13
13
|
return /* @__PURE__ */ jsx(
|
|
14
14
|
"button",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Badge } from './chunk-
|
|
1
|
+
import { Badge } from './chunk-2CXU5WZO.js';
|
|
2
2
|
import { cn } from './chunk-FEK5XGZW.js';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -25,7 +25,7 @@ function SignatureChip({
|
|
|
25
25
|
className: cn(
|
|
26
26
|
shared,
|
|
27
27
|
"inline-flex items-center rounded-full border border-dashed",
|
|
28
|
-
onImage ? "border-background/70 bg-foreground/
|
|
28
|
+
onImage ? "border-background/70 bg-foreground/80 text-background hover:bg-foreground/90" : "border-accent/40 text-accent hover:bg-accent/10",
|
|
29
29
|
"focus-visible:outline-none focus-visible:ring-2",
|
|
30
30
|
onImage ? "focus-visible:ring-background/70" : "focus-visible:ring-accent/40",
|
|
31
31
|
className
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { SnapRail, SnapRailDots } from './chunk-DTXNDLSE.js';
|
|
2
|
-
import { PhotoGround } from './chunk-
|
|
2
|
+
import { PhotoGround } from './chunk-CNJQUHCU.js';
|
|
3
3
|
import { cn } from './chunk-FEK5XGZW.js';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
var FOOT_GLASS = cn(
|
|
8
|
-
|
|
8
|
+
// Ink only — no backdrop-blur; see `GlassGround` for the measurement.
|
|
9
|
+
"before:pointer-events-none before:absolute before:inset-0 before:-z-10 before:content-['']",
|
|
9
10
|
"before:bg-[oklch(0.16_0.012_55_/_0.9)]",
|
|
10
11
|
"lg:before:[mask-image:linear-gradient(to_top,black_60%,transparent_100%)] lg:before:bg-[linear-gradient(to_top,oklch(0.16_0.012_55_/_0.88)_0%,oklch(0.16_0.012_55_/_0.84)_60%,oklch(0.16_0.012_55_/_0.4)_85%,oklch(0.16_0.012_55_/_0)_100%)]"
|
|
11
12
|
);
|
|
@@ -14,6 +14,7 @@ function PhotoGround({
|
|
|
14
14
|
overlay,
|
|
15
15
|
overlayClassName,
|
|
16
16
|
loading = "lazy",
|
|
17
|
+
glyphClassName,
|
|
17
18
|
className
|
|
18
19
|
}) {
|
|
19
20
|
const initialOf = (index) => {
|
|
@@ -39,7 +40,16 @@ function PhotoGround({
|
|
|
39
40
|
/* Never a grey box: the ground with the venue's initial. A missing
|
|
40
41
|
photograph is not a broken image, and drawing one as a placeholder
|
|
41
42
|
makes a real city look unfinished. */
|
|
42
|
-
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
43
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
44
|
+
"span",
|
|
45
|
+
{
|
|
46
|
+
className: cn(
|
|
47
|
+
"font-serif text-[64px] font-semibold leading-none text-white/15",
|
|
48
|
+
glyphClassName
|
|
49
|
+
),
|
|
50
|
+
children: initialOf(index)
|
|
51
|
+
}
|
|
52
|
+
) })
|
|
43
53
|
) }, index);
|
|
44
54
|
};
|
|
45
55
|
return /* @__PURE__ */ jsxs("span", { "aria-hidden": true, className: cn("absolute inset-0 block", PHOTO_GROUND, className), children: [
|
|
@@ -26,13 +26,23 @@ var buttonVariants = cva(
|
|
|
26
26
|
* into a dark photo.
|
|
27
27
|
*
|
|
28
28
|
* Deliberately NOT theme-aware, and so deliberately different from
|
|
29
|
-
* `Badge`'s `overlay` (`bg-foreground/
|
|
29
|
+
* `Badge`'s `overlay` (`bg-foreground/80 text-background`, which
|
|
30
30
|
* inverts). A photo is equally a photo in both themes — this chrome has
|
|
31
31
|
* to contrast with the image beneath it, not with the app canvas, so it
|
|
32
32
|
* stays dark-on-light-glyph either way. Reconcile Badge to this, not the
|
|
33
33
|
* reverse, if the two are ever unified.
|
|
34
34
|
*/
|
|
35
|
-
overlay: "bg-black/
|
|
35
|
+
overlay: "bg-black/50 text-white hover:bg-black/65 focus-visible:ring-white/70",
|
|
36
|
+
/**
|
|
37
|
+
* The LABELLED action on a photo surface — "Open the menu", "See all
|
|
38
|
+
* 46 bars", "How we read menus" — where `overlay` is the unlabelled
|
|
39
|
+
* chrome. Glass on the ink: translucent white with a hairline, white
|
|
40
|
+
* type. Same reasoning as `overlay`: not theme-aware, because it
|
|
41
|
+
* contrasts with the photograph, not the canvas. Pair with `size="pill"`.
|
|
42
|
+
* Icons trail, never lead: `ArrowRight` when it navigates to a page,
|
|
43
|
+
* `ChevronRight` when it opens a sheet or drawer.
|
|
44
|
+
*/
|
|
45
|
+
ink: "border border-white/20 bg-white/[0.16] text-white hover:bg-white/25 focus-visible:ring-white/70 focus-visible:ring-offset-0",
|
|
36
46
|
brown: "bg-brown text-brown-foreground shadow-sm hover:bg-brown/85 hover:shadow",
|
|
37
47
|
antagonist: "bg-primary-foreground text-primary shadow-sm hover:bg-accent hover:text-accent-foreground border border-border hover:border-accent"
|
|
38
48
|
},
|
|
@@ -41,6 +51,8 @@ var buttonVariants = cva(
|
|
|
41
51
|
sm: "h-9 rounded-lg px-4",
|
|
42
52
|
default: "h-11 px-6 py-2",
|
|
43
53
|
lg: "h-12 rounded-2xl px-8",
|
|
54
|
+
/** The `ink` action's shape. Owns the radius so no variant fights it. */
|
|
55
|
+
pill: "h-11 rounded-full px-5 text-[13.5px] font-bold",
|
|
44
56
|
icon: "h-11 w-11 rounded-full",
|
|
45
57
|
"icon-xs": "h-8 w-8 rounded-full [&_svg]:size-3.5",
|
|
46
58
|
"icon-sm": "h-9 w-9 rounded-full",
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import { cn } from './chunk-FEK5XGZW.js';
|
|
2
2
|
import { __spreadProps, __spreadValues } from './chunk-3GWWZKX7.js';
|
|
3
|
-
import {
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
var STOPS = [0, 0.25, 0.5, 0.75, 1];
|
|
6
6
|
var EASE = [0, 0.06, 0.25, 0.56, 1];
|
|
7
|
-
var FROST_SOFT = "[mask-image:linear-gradient(var(--glass-dir),transparent_var(--glass-s0),rgba(0,0,0,0.25)_var(--glass-s1),black_var(--glass-s2))] lg:[mask-image:linear-gradient(var(--glass-lg-dir),transparent_var(--glass-lg-s0),rgba(0,0,0,0.25)_var(--glass-lg-s1),black_var(--glass-lg-s2))]";
|
|
8
|
-
var FROST_HEAVY = "[mask-image:linear-gradient(var(--glass-dir),transparent_var(--glass-s1),rgba(0,0,0,0.25)_var(--glass-s2),rgba(0,0,0,0.6)_var(--glass-s3),black_var(--glass-s4))] lg:[mask-image:linear-gradient(var(--glass-lg-dir),transparent_var(--glass-lg-s1),rgba(0,0,0,0.25)_var(--glass-lg-s2),rgba(0,0,0,0.6)_var(--glass-lg-s3),black_var(--glass-lg-s4))]";
|
|
9
7
|
var INK = "bg-[linear-gradient(var(--glass-dir),oklch(0.16_0.012_55_/_0)_var(--glass-s0),oklch(0.16_0.012_55_/_var(--glass-a1))_var(--glass-s1),oklch(0.16_0.012_55_/_var(--glass-a2))_var(--glass-s2),oklch(0.16_0.012_55_/_var(--glass-a3))_var(--glass-s3),oklch(0.16_0.012_55_/_var(--glass-a4))_var(--glass-s4),oklch(0.16_0.012_55_/_var(--glass-a-peak))_100%)] lg:bg-[linear-gradient(var(--glass-lg-dir),oklch(0.16_0.012_55_/_0)_var(--glass-lg-s0),oklch(0.16_0.012_55_/_var(--glass-a1))_var(--glass-lg-s1),oklch(0.16_0.012_55_/_var(--glass-a2))_var(--glass-lg-s2),oklch(0.16_0.012_55_/_var(--glass-a3))_var(--glass-lg-s3),oklch(0.16_0.012_55_/_var(--glass-a4))_var(--glass-lg-s4),oklch(0.16_0.012_55_/_var(--glass-a-peak))_100%)]";
|
|
10
|
-
var BLUR = {
|
|
11
|
-
sm: ["backdrop-blur-[2px]", "backdrop-blur-sm"],
|
|
12
|
-
md: ["backdrop-blur-sm", "backdrop-blur-md"],
|
|
13
|
-
lg: ["backdrop-blur-md", "backdrop-blur-lg"],
|
|
14
|
-
xl: ["backdrop-blur-lg", "backdrop-blur-xl"]
|
|
15
|
-
};
|
|
16
8
|
function measure(value) {
|
|
17
9
|
const match = value.trim().match(/^(-?\d*\.?\d+)\s*([a-z%]*)$/i);
|
|
18
10
|
if (!match) throw new Error(`GlassGround: cannot read stop "${value}"`);
|
|
@@ -23,13 +15,7 @@ function positions(clear, full) {
|
|
|
23
15
|
const [to] = measure(full);
|
|
24
16
|
return STOPS.map((fraction) => `${from + (to - from) * fraction}${unit}`);
|
|
25
17
|
}
|
|
26
|
-
function GlassGround({
|
|
27
|
-
stops,
|
|
28
|
-
lgStops = stops,
|
|
29
|
-
peak = 0.96,
|
|
30
|
-
blur = "xl",
|
|
31
|
-
className
|
|
32
|
-
}) {
|
|
18
|
+
function GlassGround({ stops, lgStops = stops, peak = 0.96, className }) {
|
|
33
19
|
const base = positions(stops.clear, stops.full);
|
|
34
20
|
const lg = positions(lgStops.clear, lgStops.full);
|
|
35
21
|
const style = __spreadProps(__spreadValues(__spreadValues(__spreadValues({
|
|
@@ -38,11 +24,14 @@ function GlassGround({
|
|
|
38
24
|
}, Object.fromEntries(base.map((position, index) => [`--glass-s${index}`, position]))), Object.fromEntries(lg.map((position, index) => [`--glass-lg-s${index}`, position]))), Object.fromEntries(EASE.slice(1).map((share, index) => [`--glass-a${index + 1}`, String(peak * 0.8 * share)]))), {
|
|
39
25
|
"--glass-a-peak": String(peak)
|
|
40
26
|
});
|
|
41
|
-
return /* @__PURE__ */
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
27
|
+
return /* @__PURE__ */ jsx(
|
|
28
|
+
"span",
|
|
29
|
+
{
|
|
30
|
+
"aria-hidden": true,
|
|
31
|
+
className: cn("pointer-events-none absolute inset-0 block", INK, className),
|
|
32
|
+
style
|
|
33
|
+
}
|
|
34
|
+
);
|
|
46
35
|
}
|
|
47
36
|
|
|
48
37
|
export { GlassGround };
|
|
@@ -38,11 +38,11 @@ function VenueGradeDimensions({
|
|
|
38
38
|
"div",
|
|
39
39
|
{
|
|
40
40
|
"aria-hidden": true,
|
|
41
|
-
className: "relative block h-[3px] overflow-hidden rounded-full bg-
|
|
41
|
+
className: "relative block h-[3px] overflow-hidden rounded-full bg-current/15",
|
|
42
42
|
children: /* @__PURE__ */ jsx(
|
|
43
43
|
"span",
|
|
44
44
|
{
|
|
45
|
-
className: "absolute inset-y-0 left-0 rounded-full bg-[var(--gradient-primary
|
|
45
|
+
className: "absolute inset-y-0 left-0 rounded-full bg-current bg-[image:var(--gradient-primary)]",
|
|
46
46
|
style: { width: `${Math.min(100, Math.max(0, value))}%` }
|
|
47
47
|
}
|
|
48
48
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buttonVariants } from '../chunk-
|
|
1
|
+
import { buttonVariants } from '../chunk-VAXOQS7W.js';
|
|
2
2
|
import '../chunk-R47NEOSI.js';
|
|
3
3
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
4
4
|
import { __objRest, __spreadProps, __spreadValues } from '../chunk-3GWWZKX7.js';
|
package/dist/components/badge.js
CHANGED
|
@@ -3,8 +3,8 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "glass" | "overlay" | "brown" | "antagonist" | null | undefined;
|
|
7
|
-
size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "glass" | "overlay" | "ink" | "brown" | "antagonist" | null | undefined;
|
|
7
|
+
size?: "default" | "xs" | "sm" | "lg" | "pill" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
8
8
|
fullWidth?: boolean | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buttonVariants, Button } from '../chunk-
|
|
1
|
+
import { buttonVariants, Button } from '../chunk-VAXOQS7W.js';
|
|
2
2
|
import '../chunk-R47NEOSI.js';
|
|
3
3
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
4
4
|
import { __objRest, __spreadValues, __spreadProps } from '../chunk-3GWWZKX7.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Popover, PopoverTrigger, PopoverContent } from '../chunk-66MAPLXS.js';
|
|
2
2
|
import { Command, CommandInput, CommandList, CommandLoading, CommandEmpty, CommandGroup, CommandItem } from '../chunk-XNA2INVQ.js';
|
|
3
3
|
import '../chunk-FRPPIXMY.js';
|
|
4
|
-
import { Button } from '../chunk-
|
|
4
|
+
import { Button } from '../chunk-VAXOQS7W.js';
|
|
5
5
|
import '../chunk-R47NEOSI.js';
|
|
6
6
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
7
7
|
import '../chunk-3GWWZKX7.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { ConceptCompareRail } from '../chunk-
|
|
1
|
+
export { ConceptCompareRail } from '../chunk-7A42J73Q.js';
|
|
2
2
|
import '../chunk-DTXNDLSE.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-CNJQUHCU.js';
|
|
4
4
|
import '../chunk-FEK5XGZW.js';
|
|
5
5
|
import '../chunk-3GWWZKX7.js';
|
|
@@ -69,7 +69,7 @@ type ConceptCompareFigure = {
|
|
|
69
69
|
type ConceptCompareLabels = {
|
|
70
70
|
/** Small caps kicker, e.g. "DISH CONCEPT". */
|
|
71
71
|
kind: string;
|
|
72
|
-
/** The badge on the lowest-priced room, e.g. "CHEAPEST"
|
|
72
|
+
/** The badge on the lowest-priced room, e.g. "CHEAPEST" — the fallback when a row carries no `badge`. */
|
|
73
73
|
cheapest: string;
|
|
74
74
|
/** The badge on every other room, e.g. "#2". Defaults to `#${rank}`. */
|
|
75
75
|
rank?: (rank: number) => string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Separator } from '../chunk-WSRWFA6K.js';
|
|
2
|
-
import { ConceptCompareRail } from '../chunk-
|
|
2
|
+
import { ConceptCompareRail } from '../chunk-7A42J73Q.js';
|
|
3
3
|
import '../chunk-DTXNDLSE.js';
|
|
4
|
-
import { PhotoGround, PHOTO_GROUND } from '../chunk-
|
|
4
|
+
import { PhotoGround, PHOTO_GROUND } from '../chunk-CNJQUHCU.js';
|
|
5
5
|
import { Skeleton } from '../chunk-QXHMPJ35.js';
|
|
6
6
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
7
7
|
import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
@@ -20,7 +20,7 @@ var initialOf = (name) => {
|
|
|
20
20
|
var GROUND = PHOTO_GROUND;
|
|
21
21
|
var PHOTO_OVERLAY_HOVER = "transition-opacity duration-300 group-hover/room:opacity-0 motion-reduce:transition-none";
|
|
22
22
|
var ROOM_SCRIM = "absolute inset-0 bg-[linear-gradient(to_bottom,oklch(0.16_0.012_55_/_0)_0%,oklch(0.16_0.012_55_/_0)_30%,oklch(0.16_0.012_55_/_0.55)_58%,oklch(0.16_0.012_55_/_0.9)_100%)]";
|
|
23
|
-
var HEAD_GLASS = "before:pointer-events-none before:absolute before:inset-0 before:-z-10 before:content-[''] before:
|
|
23
|
+
var HEAD_GLASS = "before:pointer-events-none before:absolute before:inset-0 before:-z-10 before:content-[''] before:bg-[linear-gradient(to_bottom,oklch(0.16_0.012_55_/_0.86)_0%,oklch(0.16_0.012_55_/_0.7)_35%,oklch(0.16_0.012_55_/_0.28)_75%,oklch(0.16_0.012_55_/_0)_100%)]";
|
|
24
24
|
var COLUMNS = {
|
|
25
25
|
1: "lg:grid-cols-1",
|
|
26
26
|
2: "lg:grid-cols-2",
|
|
@@ -106,8 +106,11 @@ function ConceptCompare({
|
|
|
106
106
|
actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 [&>*]:w-full lg:[&>*]:w-auto", children: actions })
|
|
107
107
|
] }) : void 0,
|
|
108
108
|
children: rooms.map((room, index) => {
|
|
109
|
+
var _a2, _b2;
|
|
109
110
|
const href = hrefs == null ? void 0 : hrefs[room.place_slug];
|
|
110
|
-
const
|
|
111
|
+
const badge = (_a2 = room.badge) != null ? _a2 : room.price === cheapest ? labels.cheapest : rankOf(index + 1);
|
|
112
|
+
const isCheapest = badge === labels.cheapest;
|
|
113
|
+
const lead = (_b2 = room.lead) != null ? _b2 : isCheapest ? "price" : void 0;
|
|
111
114
|
const roomClass = cn(
|
|
112
115
|
/* Transparent on the phone — the card behind it is the room's
|
|
113
116
|
photograph — with only its scrim and its line. A photograph of
|
|
@@ -136,26 +139,35 @@ function ConceptCompare({
|
|
|
136
139
|
{
|
|
137
140
|
className: cn(
|
|
138
141
|
"inline-flex h-[22px] w-max items-center gap-1 rounded-full px-2 text-[10px] font-extrabold uppercase tracking-[0.08em]",
|
|
139
|
-
isCheapest ? "bg-success text-white" : "bg-white/
|
|
142
|
+
isCheapest ? "bg-success text-white" : "bg-white/20 text-white/85"
|
|
140
143
|
),
|
|
141
144
|
children: [
|
|
142
145
|
isCheapest && /* @__PURE__ */ jsx(ArrowDown, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
|
|
143
|
-
|
|
146
|
+
badge
|
|
144
147
|
]
|
|
145
148
|
}
|
|
146
149
|
),
|
|
147
150
|
/* @__PURE__ */ jsxs("span", { className: "mt-2.5 flex items-center gap-1.5 text-white", children: [
|
|
148
151
|
/* @__PURE__ */ jsx(MapPin, { className: "h-3.5 w-3.5 shrink-0 text-white/70", "aria-hidden": true }),
|
|
149
152
|
/* @__PURE__ */ jsx("b", { className: "min-w-0 flex-1 truncate text-[15px] font-bold leading-tight", children: room.place_name }),
|
|
150
|
-
room.
|
|
153
|
+
room.grade ? /* @__PURE__ */ jsx(
|
|
154
|
+
"span",
|
|
155
|
+
{
|
|
156
|
+
className: cn(
|
|
157
|
+
"shrink-0 text-[14px] font-extrabold leading-none tabular-nums text-[oklch(0.82_0.15_85)]",
|
|
158
|
+
lead === "grade" && "text-[16px]"
|
|
159
|
+
),
|
|
160
|
+
children: room.grade
|
|
161
|
+
}
|
|
162
|
+
) : room.rating !== void 0 && /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-[12px] text-white/70", children: [
|
|
151
163
|
/* @__PURE__ */ jsx(Star, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
|
|
152
164
|
/* @__PURE__ */ jsx("span", { className: "tabular-nums", children: room.rating })
|
|
153
165
|
] })
|
|
154
166
|
] }),
|
|
155
167
|
room.place_area && /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-[12px] text-white/70", children: room.place_area }),
|
|
156
|
-
/* @__PURE__ */ jsx("span", { className: "mt-2 block truncate font-serif text-[14px]
|
|
168
|
+
/* @__PURE__ */ jsx("span", { className: "mt-2 block truncate font-serif text-[14px] text-white/90", children: room.alias }),
|
|
157
169
|
/* @__PURE__ */ jsx(Separator, { className: "my-2.5 via-white/20" }),
|
|
158
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-baseline gap-2", children: [
|
|
170
|
+
/* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
|
|
159
171
|
/* @__PURE__ */ jsx(
|
|
160
172
|
"b",
|
|
161
173
|
{
|
|
@@ -166,7 +178,16 @@ function ConceptCompare({
|
|
|
166
178
|
children: formatPrice(room.price)
|
|
167
179
|
}
|
|
168
180
|
),
|
|
169
|
-
room.mentions !== void 0 && room.mentions > 0 && /* @__PURE__ */ jsx(
|
|
181
|
+
room.mentions !== void 0 && room.mentions > 0 && /* @__PURE__ */ jsx(
|
|
182
|
+
"span",
|
|
183
|
+
{
|
|
184
|
+
className: cn(
|
|
185
|
+
"text-[11.5px]",
|
|
186
|
+
lead === "mentions" ? "font-bold text-white" : "text-white/65"
|
|
187
|
+
),
|
|
188
|
+
children: labels.mentions(room.mentions)
|
|
189
|
+
}
|
|
190
|
+
)
|
|
170
191
|
] })
|
|
171
192
|
] });
|
|
172
193
|
return href ? /* @__PURE__ */ jsx(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { PhotoGround } from '../chunk-
|
|
1
|
+
import { PhotoGround } from '../chunk-CNJQUHCU.js';
|
|
2
2
|
import { Convergence } from '../chunk-MZL7CGCL.js';
|
|
3
3
|
import '../chunk-LEAYBICI.js';
|
|
4
|
-
import { Badge } from '../chunk-
|
|
4
|
+
import { Badge } from '../chunk-2CXU5WZO.js';
|
|
5
5
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
6
6
|
import '../chunk-3GWWZKX7.js';
|
|
7
7
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -2,7 +2,7 @@ import { resolveEventEntryFee } from '../chunk-DNSXMHYX.js';
|
|
|
2
2
|
import { Separator } from '../chunk-WSRWFA6K.js';
|
|
3
3
|
import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
|
|
4
4
|
import { Skeleton } from '../chunk-QXHMPJ35.js';
|
|
5
|
-
import { Button } from '../chunk-
|
|
5
|
+
import { Button } from '../chunk-VAXOQS7W.js';
|
|
6
6
|
import '../chunk-R47NEOSI.js';
|
|
7
7
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
8
8
|
import { __spreadProps, __spreadValues, __objRest } from '../chunk-3GWWZKX7.js';
|
|
@@ -3,7 +3,7 @@ import { Tag } from '../chunk-ZDAHKI3A.js';
|
|
|
3
3
|
import { Separator } from '../chunk-WSRWFA6K.js';
|
|
4
4
|
import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
|
|
5
5
|
import { Skeleton } from '../chunk-QXHMPJ35.js';
|
|
6
|
-
import { buttonVariants } from '../chunk-
|
|
6
|
+
import { buttonVariants } from '../chunk-VAXOQS7W.js';
|
|
7
7
|
import '../chunk-R47NEOSI.js';
|
|
8
8
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
9
9
|
import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* GlassGround —
|
|
5
|
-
* photograph.
|
|
4
|
+
* GlassGround — an inked caption rising out of one edge of a photograph.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* One layer over a `PhotoGround`: an ink gradient running in one direction —
|
|
7
|
+
* absent where the photograph is the subject, solid where the type is.
|
|
8
|
+
* `MenuFamilyBlock` drew this first; this is the same idea with the stops as
|
|
9
|
+
* data, so a card can say "clear for 128px, then ink" without a sixth copy of
|
|
10
|
+
* the gradient string.
|
|
12
11
|
*
|
|
13
|
-
* ## Why
|
|
12
|
+
* ## Why there is no blur any more
|
|
14
13
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
14
|
+
* This used to be two masked `backdrop-blur`s under the ink — a progressive
|
|
15
|
+
* frost. Measured on `/menu` in production (2026-09-14): the page carried 73
|
|
16
|
+
* backdrop-filter composited layers, six dossiers' worth of these among them,
|
|
17
|
+
* and the main thread spent 9 ms per scrolled frame re-layerising them
|
|
18
|
+
* (2.7 s over a six-second fling; 56 ms with backdrop-filter disabled). A
|
|
19
|
+
* frost is not worth a page that cannot scroll on a phone, so the caption
|
|
20
|
+
* rests on the ink alone, eased through five stops so the ramp has no crease.
|
|
21
|
+
* See `docs/audits/audit-menu-page-performance-2026-09-14.md` in the app.
|
|
22
22
|
*
|
|
23
23
|
* ## Why the stops are custom properties
|
|
24
24
|
*
|
|
25
|
-
* Tailwind emits only the classes it can read verbatim, so the
|
|
26
|
-
* cannot be assembled from props into a class. The
|
|
27
|
-
*
|
|
25
|
+
* Tailwind emits only the classes it can read verbatim, so the gradient
|
|
26
|
+
* cannot be assembled from props into a class. The class below is literal and
|
|
27
|
+
* reads `--glass-*` variables; the component writes those inline, having
|
|
28
28
|
* interpolated the quarter stops in JS (`clear` and `full` must share a
|
|
29
29
|
* unit). Same mechanism as `HueChip`'s hue. The ink's colour is the
|
|
30
30
|
* package's one scrim literal, `oklch(0.16 0.012 55)`, never `var(--scrim)`.
|
|
31
31
|
*
|
|
32
32
|
* ## The ramp ends where the type begins
|
|
33
33
|
*
|
|
34
|
-
* `clear` is where the
|
|
35
|
-
*
|
|
36
|
-
* the
|
|
34
|
+
* `clear` is where the ink starts, `full` where it is solid. Set `full` to
|
|
35
|
+
* the exact seam the content starts at — a ramp that runs past the seam puts
|
|
36
|
+
* the first row of type on half-ink.
|
|
37
37
|
*/
|
|
38
38
|
type GlassStops = {
|
|
39
39
|
/** Which way the ink runs — toward the type. */
|
|
40
40
|
direction: "to bottom" | "to right";
|
|
41
|
-
/** Where the
|
|
41
|
+
/** Where the ink begins, e.g. `"0px"` or `"24%"`. */
|
|
42
42
|
clear: string;
|
|
43
|
-
/** Where
|
|
43
|
+
/** Where the ink is solid — the seam the content starts at. Same unit as `clear`. */
|
|
44
44
|
full: string;
|
|
45
45
|
};
|
|
46
46
|
type GlassGroundProps = {
|
|
@@ -49,18 +49,13 @@ type GlassGroundProps = {
|
|
|
49
49
|
lgStops?: GlassStops;
|
|
50
50
|
/**
|
|
51
51
|
* How dark the ink gets at the far edge, 0–1. `0.96` is a caption the
|
|
52
|
-
* photograph is only a texture under; `0.
|
|
52
|
+
* photograph is only a texture under; `0.6` is a photograph the caption is
|
|
53
53
|
* drawn on — the type is lifted, the room stays a room.
|
|
54
54
|
*/
|
|
55
55
|
peak?: number;
|
|
56
|
-
/**
|
|
57
|
-
* How much the frost softens the photograph where it is solid. `xl` turns
|
|
58
|
-
* a room into colour; `sm` keeps it a room and only takes the edge off the
|
|
59
|
-
* detail behind the type.
|
|
60
|
-
*/
|
|
61
|
-
blur?: "sm" | "md" | "lg" | "xl";
|
|
56
|
+
/** Placement only. The ink is a `bg-*` on this same element, so a background here would replace it. */
|
|
62
57
|
className?: string;
|
|
63
58
|
};
|
|
64
|
-
declare function GlassGround({ stops, lgStops, peak,
|
|
59
|
+
declare function GlassGround({ stops, lgStops, peak, className }: GlassGroundProps): react_jsx_runtime.JSX.Element;
|
|
65
60
|
|
|
66
61
|
export { GlassGround, type GlassGroundProps, type GlassStops };
|
|
@@ -4,11 +4,11 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
4
4
|
|
|
5
5
|
declare const inputGroupVariants: (props?: ({
|
|
6
6
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
7
|
-
shape?: "
|
|
7
|
+
shape?: "pill" | "rounded" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
declare const InputGroup: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
10
10
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
11
|
-
shape?: "
|
|
11
|
+
shape?: "pill" | "rounded" | null | undefined;
|
|
12
12
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
|
|
13
13
|
declare const InputGroupInput: React.ForwardRefExoticComponent<React.InputHTMLAttributes<HTMLInputElement> & React.RefAttributes<HTMLInputElement>>;
|
|
14
14
|
declare const InputGroupAddon: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
@@ -4,7 +4,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
4
4
|
|
|
5
5
|
declare const inputVariants: (props?: ({
|
|
6
6
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
7
|
-
shape?: "
|
|
7
|
+
shape?: "pill" | "rounded" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof inputVariants> {
|
|
10
10
|
}
|
|
@@ -14,10 +14,20 @@ declare const Item: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDiv
|
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & {
|
|
15
15
|
asChild?: boolean;
|
|
16
16
|
} & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
-
declare const ItemMedia: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> &
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
declare const
|
|
21
|
-
|
|
17
|
+
declare const ItemMedia: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
18
|
+
asChild?: boolean;
|
|
19
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
20
|
+
declare const ItemContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
21
|
+
asChild?: boolean;
|
|
22
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
23
|
+
declare const ItemTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
24
|
+
asChild?: boolean;
|
|
25
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
26
|
+
declare const ItemDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
27
|
+
asChild?: boolean;
|
|
28
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
29
|
+
declare const ItemActions: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
30
|
+
asChild?: boolean;
|
|
31
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
22
32
|
|
|
23
33
|
export { Item, ItemActions, ItemContent, ItemDescription, ItemMedia, ItemTitle, itemVariants };
|