@bearmenu/ui 0.8.51 → 0.8.52
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-H4ORZT2D.js +14 -0
- package/dist/{chunk-S5GDARLW.js → chunk-WY2FP76J.js} +28 -5
- package/dist/components/alert.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/category-deck.d.ts +6 -1
- package/dist/components/category-deck.js +39 -35
- package/dist/components/command.d.ts +15 -15
- package/dist/components/empty-state.d.ts +2 -2
- package/dist/components/event-card.d.ts +7 -0
- package/dist/components/event-card.js +9 -0
- package/dist/components/event-compact-row.d.ts +6 -0
- package/dist/components/event-compact-row.js +5 -3
- package/dist/components/event-hub-hero.d.ts +5 -0
- package/dist/components/event-hub-hero.js +14 -3
- package/dist/components/event-list-row-wide.d.ts +6 -0
- package/dist/components/event-list-row-wide.js +5 -3
- package/dist/components/event-tonight-strip.d.ts +3 -1
- package/dist/components/event-tonight-strip.js +3 -2
- package/dist/components/featured-rail-item.d.ts +3 -1
- package/dist/components/featured-rail-item.js +3 -1
- package/dist/components/kitchen-dossier.d.ts +7 -1
- package/dist/components/kitchen-dossier.js +2 -1
- package/dist/components/menu-hub-hero.d.ts +7 -1
- package/dist/components/menu-hub-hero.js +2 -0
- package/dist/components/place-card.d.ts +7 -0
- package/dist/components/place-card.js +10 -2
- package/dist/components/poster-stack.d.ts +2 -0
- package/dist/components/poster-stack.js +2 -1
- package/dist/components/section-header.d.ts +6 -1
- package/dist/components/section-header.js +4 -2
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/tag.d.ts +2 -2
- package/dist/components/text.d.ts +2 -2
- package/dist/components/timeline-day.js +1 -1
- package/dist/components/timeline-hour.d.ts +13 -1
- package/dist/components/timeline-hour.js +1 -1
- package/dist/components/toggle.d.ts +1 -1
- package/package.json +217 -23
- package/src/components/category-deck.tsx +11 -0
- package/src/components/event-card.test.tsx +6 -0
- package/src/components/event-card.tsx +17 -0
- package/src/components/event-compact-row.tsx +34 -24
- package/src/components/event-hub-hero.tsx +15 -1
- package/src/components/event-list-row-wide.tsx +25 -15
- package/src/components/event-tonight-strip.test.tsx +12 -0
- package/src/components/event-tonight-strip.tsx +8 -1
- package/src/components/featured-rail-item.tsx +5 -0
- package/src/components/kitchen-dossier.tsx +14 -1
- package/src/components/menu-hub-hero.tsx +13 -0
- package/src/components/place-card.stories.tsx +10 -0
- package/src/components/place-card.test.tsx +31 -0
- package/src/components/place-card.tsx +22 -6
- package/src/components/poster-stack.tsx +3 -0
- package/src/components/section-header.tsx +8 -1
- package/src/components/timeline-day.stories.tsx +30 -0
- package/src/components/timeline-day.test.tsx +24 -0
- package/src/components/timeline-hour.tsx +40 -6
- package/src/lib/poster-overlay-frame.tsx +26 -0
|
@@ -32,6 +32,7 @@ function KitchenDossier({
|
|
|
32
32
|
formatScore,
|
|
33
33
|
partDurationMs,
|
|
34
34
|
action,
|
|
35
|
+
openIndicator,
|
|
35
36
|
linkComponent: LinkComponent = DefaultLink,
|
|
36
37
|
className
|
|
37
38
|
}) {
|
|
@@ -129,7 +130,7 @@ function KitchenDossier({
|
|
|
129
130
|
}
|
|
130
131
|
),
|
|
131
132
|
/* @__PURE__ */ jsx("div", { className: "relative min-h-[184px] flex-1", children: labels.openUntil && /* @__PURE__ */ jsxs("span", { className: "absolute left-0 top-3 inline-flex h-[30px] items-center gap-[7px] rounded-full bg-[oklch(0.16_0.012_55_/_0.78)] px-3 text-[11.5px] font-bold text-white", children: [
|
|
132
|
-
/* @__PURE__ */ jsx("i", { className: "h-[7px] w-[7px] rounded-full bg-success", "aria-hidden": true }),
|
|
133
|
+
openIndicator ? /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center justify-center", "aria-hidden": true, children: openIndicator }) : /* @__PURE__ */ jsx("i", { className: "h-[7px] w-[7px] rounded-full bg-success", "aria-hidden": true }),
|
|
133
134
|
labels.openUntil
|
|
134
135
|
] }) }),
|
|
135
136
|
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col gap-3.5", children: [
|
|
@@ -64,8 +64,14 @@ type MenuHubHeroProps = {
|
|
|
64
64
|
* `h2` so the document has one h1, not two.
|
|
65
65
|
*/
|
|
66
66
|
headingLevel?: "h1" | "h2";
|
|
67
|
+
/**
|
|
68
|
+
* A decorative layer over the photographs and their scrim, under the text:
|
|
69
|
+
* fill the banner with `absolute inset-0`. Clipped by the banner's rounded
|
|
70
|
+
* edge. Decorative and `aria-hidden`.
|
|
71
|
+
*/
|
|
72
|
+
sceneOverlay?: React.ReactNode;
|
|
67
73
|
className?: string;
|
|
68
74
|
};
|
|
69
|
-
declare function MenuHubHero({ kicker, kickerIcon, headline, body, figures, proof, proofIcon, action, backgroundUrl, tileUrls, headingLevel: Heading, className, }: MenuHubHeroProps): react_jsx_runtime.JSX.Element;
|
|
75
|
+
declare function MenuHubHero({ kicker, kickerIcon, headline, body, figures, proof, proofIcon, action, backgroundUrl, tileUrls, headingLevel: Heading, sceneOverlay, className, }: MenuHubHeroProps): react_jsx_runtime.JSX.Element;
|
|
70
76
|
|
|
71
77
|
export { MenuHubHero, type MenuHubHeroFigure, type MenuHubHeroProps };
|
|
@@ -16,6 +16,7 @@ function MenuHubHero({
|
|
|
16
16
|
backgroundUrl,
|
|
17
17
|
tileUrls,
|
|
18
18
|
headingLevel: Heading = "h1",
|
|
19
|
+
sceneOverlay,
|
|
19
20
|
className
|
|
20
21
|
}) {
|
|
21
22
|
return /* @__PURE__ */ jsxs(
|
|
@@ -81,6 +82,7 @@ function MenuHubHero({
|
|
|
81
82
|
)
|
|
82
83
|
}
|
|
83
84
|
),
|
|
85
|
+
sceneOverlay && /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-0", children: sceneOverlay }),
|
|
84
86
|
/* @__PURE__ */ jsxs("div", { className: "relative z-[1] flex w-full flex-col justify-center gap-3 p-5 text-white lg:gap-4 lg:px-12 lg:py-11", children: [
|
|
85
87
|
kicker && /* @__PURE__ */ jsxs("span", { className: "inline-flex w-max items-center gap-[7px] rounded-full bg-white/15 px-3 py-1.5 text-[11px] font-extrabold tracking-[0.11em]", children: [
|
|
86
88
|
kickerIcon,
|
|
@@ -81,6 +81,13 @@ type PlaceCardProps = {
|
|
|
81
81
|
* trending badge on the API's `trending` flag).
|
|
82
82
|
*/
|
|
83
83
|
photoOverlay?: ReactNode;
|
|
84
|
+
/**
|
|
85
|
+
* Drawn in place of the green open-now dot, in the dot's top-right slot
|
|
86
|
+
* (roughly 16-20px square). Decorative: it is only rendered when
|
|
87
|
+
* `place.open_now === true` and should be `aria-hidden`. The closed badge is
|
|
88
|
+
* untouched.
|
|
89
|
+
*/
|
|
90
|
+
openIndicator?: ReactNode;
|
|
84
91
|
className?: string;
|
|
85
92
|
};
|
|
86
93
|
declare const PlaceCard: React$1.NamedExoticComponent<PlaceCardProps>;
|
|
@@ -74,6 +74,7 @@ var PlaceCard = memo(function PlaceCard2({
|
|
|
74
74
|
onOpen,
|
|
75
75
|
footer,
|
|
76
76
|
photoOverlay,
|
|
77
|
+
openIndicator,
|
|
77
78
|
className
|
|
78
79
|
}) {
|
|
79
80
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
@@ -132,13 +133,20 @@ var PlaceCard = memo(function PlaceCard2({
|
|
|
132
133
|
}
|
|
133
134
|
) })
|
|
134
135
|
),
|
|
135
|
-
place.open_now === true && /* @__PURE__ */ jsx(
|
|
136
|
+
place.open_now === true && (openIndicator ? /* @__PURE__ */ jsx(
|
|
137
|
+
"span",
|
|
138
|
+
{
|
|
139
|
+
className: "pointer-events-none absolute right-2 top-2 flex items-center justify-center",
|
|
140
|
+
"aria-hidden": true,
|
|
141
|
+
children: openIndicator
|
|
142
|
+
}
|
|
143
|
+
) : /* @__PURE__ */ jsx(
|
|
136
144
|
"span",
|
|
137
145
|
{
|
|
138
146
|
className: "absolute right-2.5 top-2.5 h-2 w-2 rounded-full bg-green-500 ring-2 ring-white/70",
|
|
139
147
|
"aria-hidden": true
|
|
140
148
|
}
|
|
141
|
-
),
|
|
149
|
+
)),
|
|
142
150
|
place.open_now === false && /* `Badge variant="overlay"` + the shared cover geometry: this pill and
|
|
143
151
|
the caller's `photoOverlay` sit on the same photo and must match. */
|
|
144
152
|
/* @__PURE__ */ jsx(Badge, { variant: "overlay", className: cn(OVERLAY_PILL, "absolute right-2 top-2"), children: labels.closed })
|
|
@@ -50,6 +50,8 @@ type PosterStackPoster = {
|
|
|
50
50
|
caption?: string;
|
|
51
51
|
/** Rendered when `src` is absent or fails. Defaults to `<EventPosterFallback />`. */
|
|
52
52
|
fallback?: React.ReactNode;
|
|
53
|
+
/** Decorative overlay on the poster face (it tilts and floats with the poster): an absolutely positioned, `aria-hidden` ornament. */
|
|
54
|
+
overlay?: React.ReactNode;
|
|
53
55
|
/** Load now at high priority instead of lazily. For the poster that is the
|
|
54
56
|
* page's LCP element; every other poster stays lazy. */
|
|
55
57
|
eager?: boolean;
|
|
@@ -96,7 +96,8 @@ function PosterStack({
|
|
|
96
96
|
}
|
|
97
97
|
)
|
|
98
98
|
) : (_a = poster.fallback) != null ? _a : /* @__PURE__ */ jsx(EventPosterFallback, {}),
|
|
99
|
-
poster.caption && /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 to-transparent px-2 pb-2 pt-6", children: /* @__PURE__ */ jsx("span", { className: "line-clamp-2 text-[11px] font-semibold leading-[1.25] text-white md:text-[12.5px]", children: poster.caption }) })
|
|
99
|
+
poster.caption && /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 to-transparent px-2 pb-2 pt-6", children: /* @__PURE__ */ jsx("span", { className: "line-clamp-2 text-[11px] font-semibold leading-[1.25] text-white md:text-[12.5px]", children: poster.caption }) }),
|
|
100
|
+
poster.overlay
|
|
100
101
|
] });
|
|
101
102
|
return /* @__PURE__ */ jsx(
|
|
102
103
|
"div",
|
|
@@ -56,9 +56,14 @@ type SectionHeaderProps = {
|
|
|
56
56
|
* behaviour; it only holds the slot.
|
|
57
57
|
*/
|
|
58
58
|
trailing?: React.ReactNode;
|
|
59
|
+
/**
|
|
60
|
+
* Absolute decoration anchored to the title group's own box. Takes no
|
|
61
|
+
* layout; the group is `relative` for it. Decorative and `aria-hidden`.
|
|
62
|
+
*/
|
|
63
|
+
titleAdornment?: React.ReactNode;
|
|
59
64
|
className?: string;
|
|
60
65
|
};
|
|
61
|
-
declare function SectionHeader({ title, count, subtitle, action, actionHref, actionTone, subtitleFrom, linkComponent: LinkComponent, onAction, as: Heading, trailing, className, }: SectionHeaderProps): react_jsx_runtime.JSX.Element;
|
|
66
|
+
declare function SectionHeader({ title, count, subtitle, action, actionHref, actionTone, subtitleFrom, linkComponent: LinkComponent, onAction, as: Heading, trailing, titleAdornment, className, }: SectionHeaderProps): react_jsx_runtime.JSX.Element;
|
|
62
67
|
type SectionHeaderSkeletonProps = {
|
|
63
68
|
/** Shows the inline count placeholder, matching `SectionHeaderProps["count"]`. */
|
|
64
69
|
showCount?: boolean;
|
|
@@ -32,15 +32,17 @@ function SectionHeader({
|
|
|
32
32
|
onAction,
|
|
33
33
|
as: Heading = "h2",
|
|
34
34
|
trailing,
|
|
35
|
+
titleAdornment,
|
|
35
36
|
className
|
|
36
37
|
}) {
|
|
37
38
|
const actionIcon = /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5", "aria-hidden": true });
|
|
38
39
|
const actionClasses = cn(ACTION_BASE_CLASSES, ACTION_TONE_CLASSES[actionTone]);
|
|
39
40
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col mb-3.5", className), children: [
|
|
40
41
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
41
|
-
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-baseline", children: [
|
|
42
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex min-w-0 items-baseline", children: [
|
|
42
43
|
/* @__PURE__ */ jsx(Heading, { className: "truncate text-[17px] font-bold tracking-[-0.01em] text-foreground md:text-[18px]", children: title }),
|
|
43
|
-
count !== void 0 && /* @__PURE__ */ jsx("span", { className: "ml-1.5 shrink-0 text-[12px] tabular-nums text-muted-foreground lg:ml-0.5", children: count })
|
|
44
|
+
count !== void 0 && /* @__PURE__ */ jsx("span", { className: "ml-1.5 shrink-0 text-[12px] tabular-nums text-muted-foreground lg:ml-0.5", children: count }),
|
|
45
|
+
titleAdornment
|
|
44
46
|
] }),
|
|
45
47
|
(action || trailing) && /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [
|
|
46
48
|
action && (actionHref ? /* @__PURE__ */ jsxs(LinkComponent, { href: actionHref, className: actionClasses, onClick: onAction, children: [
|
|
@@ -4,11 +4,11 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
4
4
|
|
|
5
5
|
declare const spinnerVariants: (props?: ({
|
|
6
6
|
size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
|
|
7
|
-
tone?: "
|
|
7
|
+
tone?: "primary" | "default" | "inherit" | "destructive" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
declare const Spinner: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
|
|
10
10
|
size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
|
|
11
|
-
tone?: "
|
|
11
|
+
tone?: "primary" | "default" | "inherit" | "destructive" | null | undefined;
|
|
12
12
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & {
|
|
13
13
|
/** Visually-hidden label for screen readers. Defaults to "Loading". */
|
|
14
14
|
label?: string;
|
package/dist/components/tag.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const tagVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "primary" | "default" | "success" | "warning" | "destructive" | "outline" | "quiet" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
declare const Tag: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
|
|
10
|
-
variant?: "
|
|
10
|
+
variant?: "primary" | "default" | "success" | "warning" | "destructive" | "outline" | "quiet" | null | undefined;
|
|
11
11
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
12
12
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & {
|
|
13
13
|
onRemove?: () => void;
|
|
@@ -22,8 +22,8 @@ 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?: "
|
|
25
|
+
variant?: "small" | "body" | "display" | "h2" | "h3" | "label" | "caption" | "h1" | "h4" | "body-lg" | "body-sm" | "overline" | null | undefined;
|
|
26
|
+
color?: "primary" | "default" | "inherit" | "destructive" | "muted" | "primary-foreground" | null | undefined;
|
|
27
27
|
weight?: "bold" | "medium" | "normal" | "semibold" | null | undefined;
|
|
28
28
|
leading?: "none" | "normal" | "tight" | "snug" | "relaxed" | "loose" | null | undefined;
|
|
29
29
|
tracking?: "normal" | "tight" | "wide" | "wider" | null | undefined;
|
|
@@ -46,6 +46,15 @@ import * as React from 'react';
|
|
|
46
46
|
* label, a rule, the count) at both widths, after the day's
|
|
47
47
|
* real programme.
|
|
48
48
|
*
|
|
49
|
+
* `tone="live"` (with `unscheduled` only) is the same off-axis group for
|
|
50
|
+
* events that are ON NOW but have no slot on today's axis — last night's set
|
|
51
|
+
* still running at 02:00, day three of a festival. It leads the day, so the
|
|
52
|
+
* quiet mono heading ("time to be confirmed") would dress "on right now" as
|
|
53
|
+
* "we don't know when": the label goes sans, semibold and success-tinted
|
|
54
|
+
* behind a pulsing dot, the rule takes the live hairline's tint, and the
|
|
55
|
+
* phone keeps the hours' gutter inset so its cards line up with the cards
|
|
56
|
+
* below instead of running 70px wider and reading as the day's feature.
|
|
57
|
+
*
|
|
49
58
|
* `layout`: `cards` stacks posters with a gap (a card is its own frame, a
|
|
50
59
|
* hairline between two posters reads as a third object) and from `lg` lays
|
|
51
60
|
* them on a two/three-up grid; `rows` is the same gapped stack on the phone
|
|
@@ -60,6 +69,9 @@ type TimelineHourProps = {
|
|
|
60
69
|
* the caller's label for the group ("Time to be confirmed"). */
|
|
61
70
|
time: string;
|
|
62
71
|
role?: TimelineHourRole;
|
|
72
|
+
/** `live`: an `unscheduled` group whose events are on now. Ignored on
|
|
73
|
+
* other roles, which say "live" through `isLive`. */
|
|
74
|
+
tone?: "default" | "live";
|
|
63
75
|
/** Marks this as the hour currently in progress. */
|
|
64
76
|
isLive?: boolean;
|
|
65
77
|
/** Under the station when live, e.g. "NOW ON"; screen-reader-only in the chip. */
|
|
@@ -81,7 +93,7 @@ type TimelineHourProps = {
|
|
|
81
93
|
overflow?: React.ReactNode;
|
|
82
94
|
className?: string;
|
|
83
95
|
};
|
|
84
|
-
declare function TimelineHour({ time, role, isLive, liveLabel, countLabel, note, layout, children, overflow, className, }: TimelineHourProps): react_jsx_runtime.JSX.Element;
|
|
96
|
+
declare function TimelineHour({ time, role, tone, isLive, liveLabel, countLabel, note, layout, children, overflow, className, }: TimelineHourProps): react_jsx_runtime.JSX.Element;
|
|
85
97
|
type TimelineHourSkeletonProps = {
|
|
86
98
|
/** Cards to reserve space for. */
|
|
87
99
|
cardCount?: number;
|
|
@@ -11,7 +11,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
11
11
|
* `data-[state=on]:` utilities sort after `hover:` and still win while on.
|
|
12
12
|
*/
|
|
13
13
|
declare const toggleVariants: (props?: ({
|
|
14
|
-
variant?: "
|
|
14
|
+
variant?: "default" | "tab" | "outline" | "chip" | "segmented" | null | undefined;
|
|
15
15
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
16
16
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
17
17
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bearmenu/ui",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.52",
|
|
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
|
+
}
|
|
@@ -105,6 +105,11 @@ export type CategoryDeckProps = {
|
|
|
105
105
|
/** Defaults to a plain `<a>`. Pass `next/link` in a Next app. */
|
|
106
106
|
linkComponent?: React.ComponentType<CategoryDeckLinkProps>;
|
|
107
107
|
onClick?: (mouseEvent: React.MouseEvent) => void;
|
|
108
|
+
/**
|
|
109
|
+
* Decoration laid over the fan's box, unclipped (it may cross the box's
|
|
110
|
+
* edge), above the cards. Absolutely positioned, `aria-hidden`, no layout.
|
|
111
|
+
*/
|
|
112
|
+
overlay?: React.ReactNode;
|
|
108
113
|
className?: string;
|
|
109
114
|
};
|
|
110
115
|
|
|
@@ -115,6 +120,7 @@ export function CategoryDeck({
|
|
|
115
120
|
href,
|
|
116
121
|
linkComponent: LinkComponent = DefaultLink,
|
|
117
122
|
onClick,
|
|
123
|
+
overlay,
|
|
118
124
|
className,
|
|
119
125
|
}: CategoryDeckProps) {
|
|
120
126
|
const slots = Array.from(
|
|
@@ -160,6 +166,11 @@ export function CategoryDeck({
|
|
|
160
166
|
</div>
|
|
161
167
|
);
|
|
162
168
|
})}
|
|
169
|
+
{overlay && (
|
|
170
|
+
<span className="pointer-events-none absolute inset-0 z-[3] block" aria-hidden>
|
|
171
|
+
{overlay}
|
|
172
|
+
</span>
|
|
173
|
+
)}
|
|
163
174
|
</div>
|
|
164
175
|
|
|
165
176
|
<div className="flex items-center gap-[9px] pt-3.5">
|
|
@@ -185,4 +185,10 @@ describe("EventCard", () => {
|
|
|
185
185
|
renderCard({ liveStatus: "Live now · ends around 23:00" });
|
|
186
186
|
expect(screen.getByText("Live now · ends around 23:00")).toBeInTheDocument();
|
|
187
187
|
});
|
|
188
|
+
|
|
189
|
+
it("renders posterOverlay inside a real, pointer-transparent box over the poster", () => {
|
|
190
|
+
renderCard({ posterOverlay: <i data-testid="overlay" /> });
|
|
191
|
+
const box = screen.getByTestId("overlay").parentElement;
|
|
192
|
+
expect(box).toHaveClass("absolute", "inset-0", "pointer-events-none");
|
|
193
|
+
});
|
|
188
194
|
});
|
|
@@ -75,6 +75,13 @@ export type EventCardProps = {
|
|
|
75
75
|
badge?: React.ReactNode;
|
|
76
76
|
/** Bottom-left overlay pill naming the category. Include its icon. */
|
|
77
77
|
tagLabel?: React.ReactNode;
|
|
78
|
+
/**
|
|
79
|
+
* Decorative overlay inside the poster box (which is `relative` and clips),
|
|
80
|
+
* for a caller's absolutely positioned ornament. Rendered after the pills,
|
|
81
|
+
* hidden on the compact row's 64px poster. Must be `aria-hidden` and
|
|
82
|
+
* pointer-transparent; it never takes layout.
|
|
83
|
+
*/
|
|
84
|
+
posterOverlay?: React.ReactNode;
|
|
78
85
|
/**
|
|
79
86
|
* Caller-supplied display labels, rendered as small chips in the text area
|
|
80
87
|
* beneath the venue/meta line. `EventPreview.tags` is taxonomy coordinates
|
|
@@ -132,6 +139,7 @@ export const EventCard = memo(function EventCard({
|
|
|
132
139
|
density = "card",
|
|
133
140
|
badge,
|
|
134
141
|
tagLabel,
|
|
142
|
+
posterOverlay,
|
|
135
143
|
tags,
|
|
136
144
|
liveStatus,
|
|
137
145
|
hideWhen,
|
|
@@ -228,6 +236,15 @@ export const EventCard = memo(function EventCard({
|
|
|
228
236
|
</span>
|
|
229
237
|
</div>
|
|
230
238
|
)}
|
|
239
|
+
|
|
240
|
+
{posterOverlay && (
|
|
241
|
+
<div
|
|
242
|
+
className={cn("pointer-events-none absolute inset-0", isRowLg && "lg:hidden")}
|
|
243
|
+
aria-hidden="true"
|
|
244
|
+
>
|
|
245
|
+
{posterOverlay}
|
|
246
|
+
</div>
|
|
247
|
+
)}
|
|
231
248
|
</div>
|
|
232
249
|
|
|
233
250
|
{/* The text column — a wrapper so `row-lg` can lay it beside the poster. */}
|