@bearmenu/ui 0.8.4 → 0.8.7
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-637L7XQ3.js +85 -0
- package/dist/chunk-6XMYEZVR.js +26 -0
- package/dist/chunk-DNSXMHYX.js +8 -0
- package/dist/chunk-FDITZ2VM.js +16 -0
- package/dist/chunk-GPH6L4DX.js +55 -0
- package/dist/{chunk-N2KNBPAQ.js → chunk-QXHMPJ35.js} +1 -0
- package/dist/chunk-TT3WFS6S.js +379 -0
- package/dist/chunk-UXWAOISG.js +170 -0
- package/dist/{chunk-UZ3PCIE5.js → chunk-XWMRABZW.js} +2 -2
- package/dist/{chunk-VBA45GLP.js → chunk-ZDAHKI3A.js} +12 -2
- package/dist/components/card.d.ts +2 -2
- package/dist/components/card.js +4 -127
- package/dist/components/category-deck.d.ts +50 -0
- package/dist/components/category-deck.js +128 -0
- package/dist/components/concept-card.d.ts +43 -0
- package/dist/components/concept-card.js +81 -0
- package/dist/components/coverflow.d.ts +123 -0
- package/dist/components/coverflow.js +300 -0
- package/dist/components/day-rail-chip.d.ts +82 -0
- package/dist/components/day-rail-chip.js +105 -0
- package/dist/components/drift-rail.d.ts +28 -0
- package/dist/components/drift-rail.js +3 -0
- package/dist/components/event-card.d.ts +97 -0
- package/dist/components/event-card.js +164 -0
- package/dist/components/event-compact-row.d.ts +73 -0
- package/dist/components/event-compact-row.js +134 -0
- package/dist/components/event-day-header.d.ts +65 -0
- package/dist/components/event-day-header.js +95 -0
- package/dist/components/event-day-separator.d.ts +46 -0
- package/dist/components/event-day-separator.js +50 -0
- package/dist/components/event-detail-panel.d.ts +80 -0
- package/dist/components/event-detail-panel.js +251 -0
- package/dist/components/event-hub-hero.d.ts +34 -0
- package/dist/components/event-hub-hero.js +57 -0
- package/dist/components/event-index-row.d.ts +68 -0
- package/dist/components/event-index-row.js +84 -0
- package/dist/components/event-list-row-wide.d.ts +101 -0
- package/dist/components/event-list-row-wide.js +218 -0
- package/dist/components/event-list-row.d.ts +82 -0
- package/dist/components/event-list-row.js +173 -0
- package/dist/components/event-poster-fallback.d.ts +20 -0
- package/dist/components/event-poster-fallback.js +3 -0
- package/dist/components/event-types.d.ts +122 -0
- package/dist/components/event-types.js +2 -0
- package/dist/components/events-empty-state.d.ts +44 -0
- package/dist/components/events-empty-state.js +73 -0
- package/dist/components/facet-group.d.ts +93 -0
- package/dist/components/facet-group.js +222 -0
- package/dist/components/featured-rail-item.d.ts +42 -0
- package/dist/components/featured-rail-item.js +88 -0
- package/dist/components/hour-band.d.ts +68 -0
- package/dist/components/hour-band.js +53 -0
- package/dist/components/hour-group.d.ts +67 -0
- package/dist/components/hour-group.js +59 -0
- package/dist/components/motion-icon-controls.js +3 -379
- package/dist/components/multi-select-combobox.js +1 -1
- package/dist/components/place-about-tab.js +3 -3
- package/dist/components/place-details-mobile.js +3 -3
- package/dist/components/poster-stack.d.ts +30 -0
- package/dist/components/poster-stack.js +104 -0
- package/dist/components/poster-tape.d.ts +36 -0
- package/dist/components/poster-tape.js +64 -0
- package/dist/components/poster-wall.d.ts +25 -0
- package/dist/components/poster-wall.js +183 -0
- package/dist/components/quiet-stretch.d.ts +43 -0
- package/dist/components/quiet-stretch.js +54 -0
- package/dist/components/section-header.d.ts +53 -0
- package/dist/components/section-header.js +63 -0
- package/dist/components/segmented-nav.d.ts +62 -0
- package/dist/components/segmented-nav.js +54 -0
- package/dist/components/skeleton-card.js +1 -1
- package/dist/components/skeleton.d.ts +17 -0
- package/dist/components/skeleton.js +1 -1
- package/dist/components/tag-group.js +3 -26
- package/dist/components/tag.d.ts +2 -2
- package/dist/components/tag.js +1 -1
- package/dist/components/timeline-band.d.ts +46 -0
- package/dist/components/timeline-band.js +5 -0
- package/dist/components/venue-events-block.d.ts +143 -0
- package/dist/components/venue-events-block.js +222 -0
- package/dist/components/weekend-panel.d.ts +44 -0
- package/dist/components/weekend-panel.js +231 -0
- package/package.json +1 -1
- package/src/components/card.tsx +44 -1
- package/src/components/category-deck.stories.tsx +96 -0
- package/src/components/category-deck.tsx +227 -0
- package/src/components/concept-card.stories.tsx +80 -0
- package/src/components/concept-card.tsx +143 -0
- package/src/components/coverflow.stories.tsx +240 -0
- package/src/components/coverflow.test.tsx +193 -0
- package/src/components/coverflow.tsx +550 -0
- package/src/components/day-rail-chip.stories.tsx +145 -0
- package/src/components/day-rail-chip.tsx +201 -0
- package/src/components/drift-rail.stories.tsx +92 -0
- package/src/components/drift-rail.tsx +86 -0
- package/src/components/event-card.stories.tsx +248 -0
- package/src/components/event-card.test.tsx +188 -0
- package/src/components/event-card.tsx +329 -0
- package/src/components/event-compact-row.stories.tsx +221 -0
- package/src/components/event-compact-row.test.tsx +51 -0
- package/src/components/event-compact-row.tsx +270 -0
- package/src/components/event-day-header.stories.tsx +124 -0
- package/src/components/event-day-header.tsx +180 -0
- package/src/components/event-day-separator.stories.tsx +70 -0
- package/src/components/event-day-separator.tsx +95 -0
- package/src/components/event-detail-panel.stories.tsx +191 -0
- package/src/components/event-detail-panel.tsx +360 -0
- package/src/components/event-hub-hero.stories.tsx +66 -0
- package/src/components/event-hub-hero.tsx +110 -0
- package/src/components/event-index-row.stories.tsx +116 -0
- package/src/components/event-index-row.tsx +181 -0
- package/src/components/event-list-row-wide.stories.tsx +204 -0
- package/src/components/event-list-row-wide.tsx +386 -0
- package/src/components/event-list-row.stories.tsx +159 -0
- package/src/components/event-list-row.tsx +335 -0
- package/src/components/event-poster-fallback.stories.tsx +52 -0
- package/src/components/event-poster-fallback.tsx +31 -0
- package/src/components/event-types.ts +137 -0
- package/src/components/events-empty-state.stories.tsx +59 -0
- package/src/components/events-empty-state.tsx +131 -0
- package/src/components/facet-group.stories.tsx +247 -0
- package/src/components/facet-group.test.tsx +225 -0
- package/src/components/facet-group.tsx +352 -0
- package/src/components/featured-rail-item.stories.tsx +86 -0
- package/src/components/featured-rail-item.tsx +153 -0
- package/src/components/hour-band.stories.tsx +159 -0
- package/src/components/hour-band.tsx +126 -0
- package/src/components/hour-group.stories.tsx +100 -0
- package/src/components/hour-group.tsx +124 -0
- package/src/components/poster-stack.stories.tsx +68 -0
- package/src/components/poster-stack.tsx +155 -0
- package/src/components/poster-tape.stories.tsx +70 -0
- package/src/components/poster-tape.tsx +122 -0
- package/src/components/poster-wall.stories.tsx +95 -0
- package/src/components/poster-wall.tsx +220 -0
- package/src/components/quiet-stretch.stories.tsx +62 -0
- package/src/components/quiet-stretch.tsx +115 -0
- package/src/components/section-header.stories.tsx +70 -0
- package/src/components/section-header.tsx +134 -0
- package/src/components/segmented-nav.stories.tsx +118 -0
- package/src/components/segmented-nav.tsx +113 -0
- package/src/components/skeleton.tsx +18 -0
- package/src/components/tag.tsx +11 -1
- package/src/components/timeline-band.stories.tsx +206 -0
- package/src/components/timeline-band.tsx +207 -0
- package/src/components/venue-events-block.stories.tsx +216 -0
- package/src/components/venue-events-block.tsx +408 -0
- package/src/components/weekend-panel.stories.tsx +92 -0
- package/src/components/weekend-panel.tsx +322 -0
- package/src/globals.css +19 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Separator } from '../chunk-WSRWFA6K.js';
|
|
2
|
+
import { TagGroup } from '../chunk-6XMYEZVR.js';
|
|
3
|
+
import { Tag } from '../chunk-ZDAHKI3A.js';
|
|
4
|
+
import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
|
|
5
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
6
|
+
import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
7
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function DefaultLink(_a) {
|
|
10
|
+
var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
|
|
11
|
+
return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
|
|
12
|
+
}
|
|
13
|
+
function EventIndexRow({
|
|
14
|
+
title,
|
|
15
|
+
as: Heading = "h3",
|
|
16
|
+
href,
|
|
17
|
+
when,
|
|
18
|
+
venue,
|
|
19
|
+
venueHref,
|
|
20
|
+
fee,
|
|
21
|
+
tags,
|
|
22
|
+
description,
|
|
23
|
+
posterUrl,
|
|
24
|
+
fallback = /* @__PURE__ */ jsx(EventPosterFallback, {}),
|
|
25
|
+
hideRule,
|
|
26
|
+
linkComponent: LinkComponent = DefaultLink,
|
|
27
|
+
className
|
|
28
|
+
}) {
|
|
29
|
+
const dot = /* @__PURE__ */ jsx("span", { className: "px-1 text-border", "aria-hidden": true, children: "\xB7" });
|
|
30
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
|
|
31
|
+
!hideRule && /* @__PURE__ */ jsx(Separator, { className: "absolute inset-x-0 top-0" }),
|
|
32
|
+
/* @__PURE__ */ jsxs("div", { className: "relative -mx-3 flex gap-3 rounded-lg px-3 py-4 transition-colors duration-150 hover:bg-card/60 motion-reduce:transition-none md:gap-4 md:py-5", children: [
|
|
33
|
+
/* @__PURE__ */ jsxs("div", { className: "relative aspect-square w-[72px] shrink-0 overflow-hidden rounded-[9px] bg-muted md:w-[104px]", children: [
|
|
34
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: fallback }),
|
|
35
|
+
posterUrl && // eslint-disable-next-line @next/next/no-img-element
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
"img",
|
|
38
|
+
{
|
|
39
|
+
src: posterUrl,
|
|
40
|
+
alt: "",
|
|
41
|
+
loading: "lazy",
|
|
42
|
+
decoding: "async",
|
|
43
|
+
className: "absolute inset-0 h-full w-full object-cover"
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
] }),
|
|
47
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
48
|
+
/* @__PURE__ */ jsx(Heading, { className: "text-[15px] font-bold leading-snug tracking-[-0.01em] text-foreground md:text-[16.5px]", children: /* @__PURE__ */ jsx(
|
|
49
|
+
LinkComponent,
|
|
50
|
+
{
|
|
51
|
+
href,
|
|
52
|
+
className: "rounded-sm transition-colors duration-150 after:absolute after:inset-0 hover:text-primary motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
53
|
+
children: title
|
|
54
|
+
}
|
|
55
|
+
) }),
|
|
56
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-1 text-[12px] leading-5 text-muted-foreground md:text-[12.5px]", children: [
|
|
57
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold tabular-nums text-foreground", children: when }),
|
|
58
|
+
venue && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
59
|
+
dot,
|
|
60
|
+
venueHref ? /* @__PURE__ */ jsx(
|
|
61
|
+
LinkComponent,
|
|
62
|
+
{
|
|
63
|
+
href: venueHref,
|
|
64
|
+
className: "relative z-10 rounded-sm font-semibold text-foreground/85 underline decoration-border underline-offset-2 transition-colors duration-150 hover:text-primary hover:decoration-primary motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
65
|
+
children: venue
|
|
66
|
+
}
|
|
67
|
+
) : /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground/85", children: venue })
|
|
68
|
+
] }),
|
|
69
|
+
fee && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
70
|
+
dot,
|
|
71
|
+
fee
|
|
72
|
+
] })
|
|
73
|
+
] }),
|
|
74
|
+
tags && tags.length > 0 && // `outline`, not the default: default `Tag` is `bg-muted`, and this
|
|
75
|
+
// row's surface is a `bg-muted/50` band — a 0.019-L delta in light
|
|
76
|
+
// mode, which is invisible. `outline` reads on both.
|
|
77
|
+
/* @__PURE__ */ jsx(TagGroup, { className: "mt-2", children: tags.map((tag) => /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "outline", children: tag }, tag)) }),
|
|
78
|
+
description && /* @__PURE__ */ jsx("p", { className: "mt-2 line-clamp-3 max-w-[620px] text-[13px] leading-[1.6] text-muted-foreground md:line-clamp-2 md:text-[13.5px] md:leading-[1.55]", children: description })
|
|
79
|
+
] })
|
|
80
|
+
] })
|
|
81
|
+
] });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { EventIndexRow };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React$1 from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
import { EventPreview, EventListRowLabels, EventDateBadgeFormatters } from './event-types.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* EventListRowWide — the desktop counterpart to `<EventListRow>`.
|
|
8
|
+
*
|
|
9
|
+
* Denser than `<EventCard>`, richer than the mobile `<EventListRow>`: desktop
|
|
10
|
+
* has the width to spare for a description and a dedicated action column, so
|
|
11
|
+
* this adds both rather than just scaling up the mobile row's type sizes.
|
|
12
|
+
*
|
|
13
|
+
* NESTED-LINK PATTERN, not the mobile row's single anchor: the row root is a
|
|
14
|
+
* plain, non-interactive container. The event TITLE is the primary link and
|
|
15
|
+
* gets a stretched overlay (`after:absolute after:inset-0`) so the whole row
|
|
16
|
+
* stays one big click target; "See the menu" (when `menuHref` is supplied) is
|
|
17
|
+
* a second, real link, `relative` with a higher `z-index` than the overlay so
|
|
18
|
+
* it wins the click in its own area — nesting it inside the title's anchor
|
|
19
|
+
* would be invalid HTML, which is why this uses two siblings instead. The
|
|
20
|
+
* title's `onClick` still fires for the caller (e.g. to `preventDefault()`
|
|
21
|
+
* into a detail sheet); modifier/middle-clicks still fall through to the
|
|
22
|
+
* anchor since nothing calls `preventDefault()` here.
|
|
23
|
+
*
|
|
24
|
+
* `event-list-row.tsx` (the mobile row) keeps the single-anchor shape and has
|
|
25
|
+
* no action column at all — the two were reconciled in favour of a real
|
|
26
|
+
* action here and none there, since a nested inert CTA inside a single-anchor
|
|
27
|
+
* row is a control that only looks like one. See that file's header.
|
|
28
|
+
*
|
|
29
|
+
* WEIGHT: the family tops out at 600, and after that pass the `Button` in this
|
|
30
|
+
* row's action column is the only 700-class element left in it — correct,
|
|
31
|
+
* since it is the only real action. Density sets weight, width sets size:
|
|
32
|
+
* both row titles are 600, and 15px vs 16.5px is what separates them.
|
|
33
|
+
*
|
|
34
|
+
* Same contract as the rest of the family: DS-owned view model, injected
|
|
35
|
+
* labels and formatters, plain `<img>`, anchor whenever `href` is given.
|
|
36
|
+
*/
|
|
37
|
+
type EventListRowWideLinkProps = {
|
|
38
|
+
href: string;
|
|
39
|
+
className?: string;
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
onClick?: (mouseEvent: React.MouseEvent) => void;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Extends the mobile row's labels with the strings only the wide row needs —
|
|
45
|
+
* the action column included, since this is the only row in the family that
|
|
46
|
+
* has one.
|
|
47
|
+
*/
|
|
48
|
+
type EventListRowWideLabels = EventListRowLabels & {
|
|
49
|
+
/** Primary row action, e.g. "Reserve". */
|
|
50
|
+
reserve: string;
|
|
51
|
+
/** Row action for a sold-out event. */
|
|
52
|
+
notifyMe: string;
|
|
53
|
+
/** Secondary link in the action column, e.g. "See the menu". */
|
|
54
|
+
seeMenu: string;
|
|
55
|
+
};
|
|
56
|
+
type EventListRowWideProps = {
|
|
57
|
+
event: EventPreview;
|
|
58
|
+
labels: EventListRowWideLabels;
|
|
59
|
+
formatters: EventDateBadgeFormatters;
|
|
60
|
+
/** Currently running — tints the date badge and shows the on-air chip. */
|
|
61
|
+
isLive?: boolean;
|
|
62
|
+
/** Sold out or otherwise closed — dims the row and swaps the CTA. */
|
|
63
|
+
isSoldOut?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Caller-resolved tag display labels, rendered as chips after the venue.
|
|
66
|
+
* The DS holds no taxonomy display names, so resolving AND capping them is
|
|
67
|
+
* the caller's job — three is what the desktop meta line carries. Same
|
|
68
|
+
* contract as `EventListRowProps.tags`; this replaced a `tagsText` prose
|
|
69
|
+
* string, which was the only place in the family tags were not chips.
|
|
70
|
+
*/
|
|
71
|
+
tags?: string[];
|
|
72
|
+
href?: string;
|
|
73
|
+
/** Destination for the "See the menu" affordance. Omit to not render it at all. */
|
|
74
|
+
menuHref?: string;
|
|
75
|
+
linkComponent?: React.ComponentType<EventListRowWideLinkProps>;
|
|
76
|
+
onClick?: (event: EventPreview, mouseEvent: React.MouseEvent) => void;
|
|
77
|
+
className?: string;
|
|
78
|
+
priority?: boolean;
|
|
79
|
+
/** Rendered instead of the thumbnail when it's absent or failed to load. Defaults to `<EventPosterFallback />`. */
|
|
80
|
+
fallback?: ReactNode;
|
|
81
|
+
/**
|
|
82
|
+
* Drops this row's top rule. Pass it on the FIRST row under a day heading:
|
|
83
|
+
* the heading already ends the block above it, so the row's own rule lands
|
|
84
|
+
* immediately beneath it and draws two dividers a few pixels apart. The gap
|
|
85
|
+
* is the separator there — whitespace does the same job without the second
|
|
86
|
+
* line. Same prop and same reason as `EventIndexRow`.
|
|
87
|
+
*/
|
|
88
|
+
hideRule?: boolean;
|
|
89
|
+
};
|
|
90
|
+
declare const EventListRowWide: React$1.NamedExoticComponent<EventListRowWideProps>;
|
|
91
|
+
type EventListRowWideSkeletonProps = {
|
|
92
|
+
/** Matches `EventListRowWideProps` shape: show the description block by default, drop it for `NoDescription`-style rows. */
|
|
93
|
+
showDescription?: boolean;
|
|
94
|
+
/** Matches `EventListRowWideProps["hideRule"]` — drop the top rule on the first row of a day group. */
|
|
95
|
+
hideRule?: boolean;
|
|
96
|
+
className?: string;
|
|
97
|
+
};
|
|
98
|
+
/** Mirrors `<EventListRowWide>`'s geometry exactly so nothing shifts when data lands. */
|
|
99
|
+
declare function EventListRowWideSkeleton({ showDescription, hideRule, className, }: EventListRowWideSkeletonProps): react_jsx_runtime.JSX.Element;
|
|
100
|
+
|
|
101
|
+
export { EventListRowWide, type EventListRowWideLabels, type EventListRowWideLinkProps, type EventListRowWideProps, EventListRowWideSkeleton, type EventListRowWideSkeletonProps };
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { Separator } from '../chunk-WSRWFA6K.js';
|
|
2
|
+
import { Tag } from '../chunk-ZDAHKI3A.js';
|
|
3
|
+
import { resolveEventEntryFee } from '../chunk-DNSXMHYX.js';
|
|
4
|
+
import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
|
|
5
|
+
import { Skeleton } from '../chunk-QXHMPJ35.js';
|
|
6
|
+
import { buttonVariants } from '../chunk-H3BV4VAG.js';
|
|
7
|
+
import '../chunk-R47NEOSI.js';
|
|
8
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
9
|
+
import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
10
|
+
import { memo, useState } from 'react';
|
|
11
|
+
import { Radio, MapPin } from 'lucide-react';
|
|
12
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
13
|
+
|
|
14
|
+
function DefaultLink(_a) {
|
|
15
|
+
var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
|
|
16
|
+
return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
|
|
17
|
+
}
|
|
18
|
+
var EventListRowWide = memo(function EventListRowWide2({
|
|
19
|
+
event,
|
|
20
|
+
labels,
|
|
21
|
+
formatters,
|
|
22
|
+
isLive,
|
|
23
|
+
isSoldOut,
|
|
24
|
+
tags,
|
|
25
|
+
href,
|
|
26
|
+
menuHref,
|
|
27
|
+
linkComponent: LinkComponent = DefaultLink,
|
|
28
|
+
onClick,
|
|
29
|
+
className,
|
|
30
|
+
priority,
|
|
31
|
+
fallback = /* @__PURE__ */ jsx(EventPosterFallback, {}),
|
|
32
|
+
hideRule
|
|
33
|
+
}) {
|
|
34
|
+
var _a, _b;
|
|
35
|
+
const [imgError, setImgError] = useState(false);
|
|
36
|
+
const fee = resolveEventEntryFee(event);
|
|
37
|
+
const showPoster = !!event.poster_url && !imgError;
|
|
38
|
+
const venue = (_a = event.place_name) != null ? _a : event.location;
|
|
39
|
+
const description = (_b = event.description) != null ? _b : event.short_description;
|
|
40
|
+
const priceText = fee.kind === "free" ? labels.free : fee.kind === "paid" ? formatters.price(fee.amountRon) : void 0;
|
|
41
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
42
|
+
!hideRule && /* @__PURE__ */ jsx(Separator, { className: "absolute inset-x-0 top-0" }),
|
|
43
|
+
/* @__PURE__ */ jsxs(
|
|
44
|
+
"div",
|
|
45
|
+
{
|
|
46
|
+
className: cn("w-[52px] shrink-0 rounded-[10px] py-[7px] text-center", isLive && "bg-success/10"),
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
className: cn(
|
|
52
|
+
"text-[19px] font-semibold leading-none tracking-[-0.02em] tabular-nums",
|
|
53
|
+
isLive ? "text-success" : "text-foreground"
|
|
54
|
+
),
|
|
55
|
+
children: formatters.dayNumber(event.starts_at)
|
|
56
|
+
}
|
|
57
|
+
),
|
|
58
|
+
/* @__PURE__ */ jsx(
|
|
59
|
+
"div",
|
|
60
|
+
{
|
|
61
|
+
className: cn(
|
|
62
|
+
"mt-[3px] text-[10.5px] font-semibold tracking-[0.06em]",
|
|
63
|
+
isLive ? "text-success" : "text-muted-foreground"
|
|
64
|
+
),
|
|
65
|
+
children: formatters.monthShort(event.starts_at)
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
/* @__PURE__ */ jsx("div", { className: "aspect-square w-[104px] shrink-0 overflow-hidden rounded-[10px] bg-muted", children: showPoster ? (
|
|
72
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
"img",
|
|
75
|
+
{
|
|
76
|
+
src: event.poster_url,
|
|
77
|
+
alt: "",
|
|
78
|
+
loading: priority ? "eager" : "lazy",
|
|
79
|
+
decoding: "async",
|
|
80
|
+
className: "h-full w-full object-cover",
|
|
81
|
+
onError: () => setImgError(true)
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
) : fallback }),
|
|
85
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
86
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
87
|
+
href ? /* @__PURE__ */ jsx(
|
|
88
|
+
LinkComponent,
|
|
89
|
+
{
|
|
90
|
+
href,
|
|
91
|
+
className: "rounded-sm text-[16.5px] font-semibold tracking-[-0.01em] after:absolute after:inset-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
92
|
+
onClick: onClick ? (mouseEvent) => onClick(event, mouseEvent) : void 0,
|
|
93
|
+
children: event.title
|
|
94
|
+
}
|
|
95
|
+
) : onClick ? /* @__PURE__ */ jsx(
|
|
96
|
+
"button",
|
|
97
|
+
{
|
|
98
|
+
type: "button",
|
|
99
|
+
className: "relative cursor-pointer rounded-sm bg-transparent p-0 text-left text-[16.5px] font-semibold tracking-[-0.01em] after:absolute after:inset-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
100
|
+
onClick: (mouseEvent) => onClick(event, mouseEvent),
|
|
101
|
+
children: event.title
|
|
102
|
+
}
|
|
103
|
+
) : /* @__PURE__ */ jsx("span", { className: "text-[16.5px] font-semibold tracking-[-0.01em]", children: event.title }),
|
|
104
|
+
isLive && /* @__PURE__ */ jsxs(Tag, { size: "sm", variant: "success", className: "shrink-0 whitespace-nowrap", children: [
|
|
105
|
+
/* @__PURE__ */ jsx(Radio, { className: "h-2.5 w-2.5", "aria-hidden": true }),
|
|
106
|
+
labels.liveNow
|
|
107
|
+
] }),
|
|
108
|
+
isSoldOut && /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "quiet", className: "shrink-0 whitespace-nowrap", children: labels.soldOut })
|
|
109
|
+
] }),
|
|
110
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-[5px] flex items-center gap-2 text-[12.5px] text-muted-foreground", children: [
|
|
111
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 tabular-nums text-foreground", children: formatters.time(event.starts_at) }),
|
|
112
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1", children: [
|
|
113
|
+
/* @__PURE__ */ jsx(MapPin, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
|
|
114
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: venue })
|
|
115
|
+
] }),
|
|
116
|
+
tags == null ? void 0 : tags.map((tag) => /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "quiet", className: "shrink-0 whitespace-nowrap", children: tag }, tag))
|
|
117
|
+
] }),
|
|
118
|
+
description && /* @__PURE__ */ jsx("p", { className: "mt-2 line-clamp-2 max-w-[620px] text-[13.5px] leading-[1.55] text-muted-foreground", children: description })
|
|
119
|
+
] }),
|
|
120
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-[150px] shrink-0 flex-col items-end gap-[9px]", children: [
|
|
121
|
+
priceText && /* @__PURE__ */ jsx(
|
|
122
|
+
"span",
|
|
123
|
+
{
|
|
124
|
+
className: cn("text-[15px] font-semibold tabular-nums", fee.kind === "free" && "text-success"),
|
|
125
|
+
children: priceText
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsx(
|
|
129
|
+
"span",
|
|
130
|
+
{
|
|
131
|
+
className: buttonVariants({
|
|
132
|
+
variant: isSoldOut ? "outline" : "default",
|
|
133
|
+
size: "sm"
|
|
134
|
+
}),
|
|
135
|
+
children: isSoldOut ? labels.notifyMe : labels.reserve
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
menuHref && /* @__PURE__ */ jsx(
|
|
139
|
+
LinkComponent,
|
|
140
|
+
{
|
|
141
|
+
href: menuHref,
|
|
142
|
+
className: "relative z-10 cursor-pointer rounded-sm text-xs font-semibold text-primary underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
143
|
+
children: labels.seeMenu
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
] })
|
|
147
|
+
] });
|
|
148
|
+
const rootClasses = cn(
|
|
149
|
+
"relative flex w-full items-start gap-[18px] py-[18px] text-left",
|
|
150
|
+
// The row is a click target — its title carries an `after:inset-0` overlay
|
|
151
|
+
// that makes the WHOLE row the link — and it had no hover response at all,
|
|
152
|
+
// so a pointer user got no confirmation the thing under the cursor was
|
|
153
|
+
// interactive until they had already clicked it.
|
|
154
|
+
//
|
|
155
|
+
// The tint bleeds past the text edges (`-mx-3 px-3`) so the fill reads as
|
|
156
|
+
// one row rather than a box drawn around the copy, and the row keeps its
|
|
157
|
+
// full-bleed separator. Sold-out rows are excluded: they are dimmed and
|
|
158
|
+
// inert, and lighting one up on hover promises an action that is not there.
|
|
159
|
+
//
|
|
160
|
+
// TEXT-KEYED, not surface-keyed — the same reasoning as `EventCompactRow`.
|
|
161
|
+
// This shipped as `bg-muted/50` and the numbers are why it did not stay:
|
|
162
|
+
// composited, that lands 0.0155 L from `--background` in light mode, which
|
|
163
|
+
// is the case this row actually renders in, and 0.0075 from `--card` in
|
|
164
|
+
// dark, which is invisible. `--foreground` at 5% holds 0.038-0.041 L across
|
|
165
|
+
// all four surface/mode combinations, so the wash is the same strength
|
|
166
|
+
// wherever the row is dropped and cannot be silently cancelled by the
|
|
167
|
+
// surface beneath it.
|
|
168
|
+
!isSoldOut && "-mx-3 rounded-xl px-3 transition-colors duration-150 hover:bg-foreground/5 motion-reduce:transition-none",
|
|
169
|
+
isSoldOut && "opacity-60",
|
|
170
|
+
className
|
|
171
|
+
);
|
|
172
|
+
return /* @__PURE__ */ jsx("div", { className: rootClasses, children: body });
|
|
173
|
+
});
|
|
174
|
+
function EventListRowWideSkeleton({
|
|
175
|
+
showDescription = true,
|
|
176
|
+
hideRule,
|
|
177
|
+
className
|
|
178
|
+
}) {
|
|
179
|
+
return /* @__PURE__ */ jsxs(
|
|
180
|
+
"div",
|
|
181
|
+
{
|
|
182
|
+
"aria-hidden": "true",
|
|
183
|
+
className: cn(
|
|
184
|
+
"relative flex w-full items-start gap-[18px] py-[18px] text-left",
|
|
185
|
+
className
|
|
186
|
+
),
|
|
187
|
+
children: [
|
|
188
|
+
!hideRule && /* @__PURE__ */ jsx(Separator, { className: "absolute inset-x-0 top-0" }),
|
|
189
|
+
/* @__PURE__ */ jsxs("div", { className: "w-[52px] shrink-0 rounded-[10px] py-[7px] text-center", children: [
|
|
190
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mx-auto h-5 w-6" }),
|
|
191
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mx-auto mt-[3px] h-[10px] w-7" })
|
|
192
|
+
] }),
|
|
193
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "aspect-square w-[104px] shrink-0 rounded-[10px]" }),
|
|
194
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
195
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[16.5px] w-3/5" }),
|
|
196
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-[5px] flex items-center gap-2", children: [
|
|
197
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-10" }),
|
|
198
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-3 shrink-0 rounded-full" }),
|
|
199
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" }),
|
|
200
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[22px] w-16 rounded-full" }),
|
|
201
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[22px] w-12 rounded-full" })
|
|
202
|
+
] }),
|
|
203
|
+
showDescription && /* @__PURE__ */ jsxs("div", { className: "mt-2 max-w-[620px] space-y-1.5", children: [
|
|
204
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[13.5px] w-full" }),
|
|
205
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[13.5px] w-2/3" })
|
|
206
|
+
] })
|
|
207
|
+
] }),
|
|
208
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-[150px] shrink-0 flex-col items-end gap-[9px]", children: [
|
|
209
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[15px] w-16" }),
|
|
210
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-20 rounded-full" }),
|
|
211
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-20" })
|
|
212
|
+
] })
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export { EventListRowWide, EventListRowWideSkeleton };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React$1 from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
import { EventPreview, EventListRowLabels, EventDateBadgeFormatters } from './event-types.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* EventListRow — the dense row used by the list view at phone width.
|
|
8
|
+
*
|
|
9
|
+
* Roughly eight events per screen against the poster card's two, which is the
|
|
10
|
+
* whole reason the list view exists: fourteen days of inventory is punishing to
|
|
11
|
+
* scan in posters.
|
|
12
|
+
*
|
|
13
|
+
* NOTE ON THE ROW ACTION: this row used to carry a trailing "Reserve" CTA that
|
|
14
|
+
* `<EventCard>` deliberately does not, and an earlier version of this comment
|
|
15
|
+
* asked for the two surfaces to be reconciled rather than for the CTA to be
|
|
16
|
+
* quietly dropped. This is that reconciliation, and it lands differently per
|
|
17
|
+
* width. At phone width the CTA is gone: it was an inert `<span>` inside the
|
|
18
|
+
* row's own anchor, so it was drawn like a booking control (`text-primary`,
|
|
19
|
+
* bold) while doing nothing that a tap anywhere else on the row did not
|
|
20
|
+
* already do. `<EventListRowWide>` keeps a real action column, because desktop
|
|
21
|
+
* has the width for one and its row root is a container rather than a single
|
|
22
|
+
* anchor. If a CTA comes back here, it has to be a real one, not a span.
|
|
23
|
+
*
|
|
24
|
+
* NOTE ON WEIGHT: nothing in this row is heavier than 600, and only the title
|
|
25
|
+
* and the date badge reach it. Eight of these stack per screen, and at that
|
|
26
|
+
* density hierarchy comes from size and ink tier, not from weight — a field of
|
|
27
|
+
* bold text has no foreground. `Free` is the one exception (600 plus
|
|
28
|
+
* `text-success`), because it is an inducement rather than an attribute.
|
|
29
|
+
*
|
|
30
|
+
* Same contract as the rest: DS-owned view model, injected labels and
|
|
31
|
+
* formatters, plain `<img>`, anchor whenever `href` is given.
|
|
32
|
+
*/
|
|
33
|
+
type EventListRowLinkProps = {
|
|
34
|
+
href: string;
|
|
35
|
+
className?: string;
|
|
36
|
+
children: React.ReactNode;
|
|
37
|
+
onClick?: (mouseEvent: React.MouseEvent) => void;
|
|
38
|
+
};
|
|
39
|
+
type EventListRowProps = {
|
|
40
|
+
event: EventPreview;
|
|
41
|
+
labels: EventListRowLabels;
|
|
42
|
+
formatters: EventDateBadgeFormatters;
|
|
43
|
+
/** Currently running — fills the date badge and shows the on-air chip. */
|
|
44
|
+
isLive?: boolean;
|
|
45
|
+
/** Sold out or otherwise closed — dims the row and replaces the fee. */
|
|
46
|
+
isSoldOut?: boolean;
|
|
47
|
+
href?: string;
|
|
48
|
+
linkComponent?: React.ComponentType<EventListRowLinkProps>;
|
|
49
|
+
onClick?: (event: EventPreview, mouseEvent: React.MouseEvent) => void;
|
|
50
|
+
className?: string;
|
|
51
|
+
priority?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Caller-resolved tag display labels for the chip line, e.g.
|
|
54
|
+
* `["Rock", "Terrace"]`. Same contract as `EventCompactRowProps.tags`: the
|
|
55
|
+
* DS holds no taxonomy display names, so the caller resolves AND caps them
|
|
56
|
+
* — two is what fits beside the live chip at 375px. Anything that does not
|
|
57
|
+
* fit is clipped whole rather than counted; see the chip line below.
|
|
58
|
+
*/
|
|
59
|
+
tags?: string[];
|
|
60
|
+
/** Rendered instead of the thumbnail when it's absent or failed to load. Defaults to `<EventPosterFallback />`. */
|
|
61
|
+
fallback?: ReactNode;
|
|
62
|
+
/**
|
|
63
|
+
* Drops this row's top rule. Pass it on the FIRST row under a day heading:
|
|
64
|
+
* the heading already ends the block above it, so the row's own rule lands
|
|
65
|
+
* immediately beneath it and draws two dividers a few pixels apart. The gap
|
|
66
|
+
* is the separator there — whitespace does the same job without the second
|
|
67
|
+
* line. Same prop and same reason as `EventListRowWide` and `EventIndexRow`.
|
|
68
|
+
*/
|
|
69
|
+
hideRule?: boolean;
|
|
70
|
+
};
|
|
71
|
+
declare const EventListRow: React$1.NamedExoticComponent<EventListRowProps>;
|
|
72
|
+
type EventListRowSkeletonProps = {
|
|
73
|
+
/** Matches `EventListRowProps["hideRule"]` — drop the top rule on the first row of a day group. */
|
|
74
|
+
hideRule?: boolean;
|
|
75
|
+
/** Reserve the chip line. Matches the real row, where it collapses on events with no live status and no tags. */
|
|
76
|
+
showTags?: boolean;
|
|
77
|
+
className?: string;
|
|
78
|
+
};
|
|
79
|
+
/** Mirrors `<EventListRow>`'s geometry exactly so nothing shifts when data lands. */
|
|
80
|
+
declare function EventListRowSkeleton({ hideRule, showTags, className, }: EventListRowSkeletonProps): react_jsx_runtime.JSX.Element;
|
|
81
|
+
|
|
82
|
+
export { EventListRow, type EventListRowLinkProps, type EventListRowProps, EventListRowSkeleton, type EventListRowSkeletonProps };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { Separator } from '../chunk-WSRWFA6K.js';
|
|
2
|
+
import { TagGroup } from '../chunk-6XMYEZVR.js';
|
|
3
|
+
import { Tag } from '../chunk-ZDAHKI3A.js';
|
|
4
|
+
import { resolveEventEntryFee } from '../chunk-DNSXMHYX.js';
|
|
5
|
+
import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
|
|
6
|
+
import { Skeleton } from '../chunk-QXHMPJ35.js';
|
|
7
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
8
|
+
import { __objRest, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
9
|
+
import { memo, useState } from 'react';
|
|
10
|
+
import { MapPin, Radio } from 'lucide-react';
|
|
11
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
12
|
+
|
|
13
|
+
function DefaultLink(_a) {
|
|
14
|
+
var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
|
|
15
|
+
return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
|
|
16
|
+
}
|
|
17
|
+
var EventListRow = memo(function EventListRow2({
|
|
18
|
+
event,
|
|
19
|
+
labels,
|
|
20
|
+
formatters,
|
|
21
|
+
isLive,
|
|
22
|
+
isSoldOut,
|
|
23
|
+
href,
|
|
24
|
+
linkComponent: LinkComponent = DefaultLink,
|
|
25
|
+
onClick,
|
|
26
|
+
className,
|
|
27
|
+
priority,
|
|
28
|
+
tags,
|
|
29
|
+
fallback = /* @__PURE__ */ jsx(EventPosterFallback, {}),
|
|
30
|
+
hideRule
|
|
31
|
+
}) {
|
|
32
|
+
var _a;
|
|
33
|
+
const [imgError, setImgError] = useState(false);
|
|
34
|
+
const fee = resolveEventEntryFee(event);
|
|
35
|
+
const showPoster = !!event.poster_url && !imgError;
|
|
36
|
+
const venue = (_a = event.place_name) != null ? _a : event.location;
|
|
37
|
+
const priceText = fee.kind === "free" ? labels.free : fee.kind === "paid" ? formatters.price(fee.amountRon) : void 0;
|
|
38
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
39
|
+
!hideRule && /* @__PURE__ */ jsx(Separator, { className: "absolute inset-x-0 top-0" }),
|
|
40
|
+
/* @__PURE__ */ jsxs(
|
|
41
|
+
"div",
|
|
42
|
+
{
|
|
43
|
+
className: cn("w-[42px] shrink-0 rounded-[9px] py-1.5 text-center", isLive && "bg-success/10"),
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
"div",
|
|
47
|
+
{
|
|
48
|
+
className: cn(
|
|
49
|
+
"text-sm font-semibold leading-none tabular-nums",
|
|
50
|
+
isLive ? "text-success" : "text-foreground"
|
|
51
|
+
),
|
|
52
|
+
children: formatters.dayNumber(event.starts_at)
|
|
53
|
+
}
|
|
54
|
+
),
|
|
55
|
+
/* @__PURE__ */ jsx(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
className: cn(
|
|
59
|
+
"mt-[3px] text-[10px] font-semibold tracking-[0.06em]",
|
|
60
|
+
isLive ? "text-success" : "text-muted-foreground"
|
|
61
|
+
),
|
|
62
|
+
children: formatters.monthShort(event.starts_at)
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
/* @__PURE__ */ jsx("div", { className: "aspect-square w-[72px] shrink-0 overflow-hidden rounded-[9px] bg-muted", children: showPoster ? (
|
|
69
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
"img",
|
|
72
|
+
{
|
|
73
|
+
src: event.poster_url,
|
|
74
|
+
alt: "",
|
|
75
|
+
loading: priority ? "eager" : "lazy",
|
|
76
|
+
decoding: "async",
|
|
77
|
+
className: "h-full w-full object-cover",
|
|
78
|
+
onError: () => setImgError(true)
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
) : fallback }),
|
|
82
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
83
|
+
/* @__PURE__ */ jsx("div", { className: "text-[15px] font-semibold leading-[1.3] tracking-[-0.01em]", children: event.title }),
|
|
84
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
85
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 tabular-nums text-foreground", children: formatters.time(event.starts_at) }),
|
|
86
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1", children: [
|
|
87
|
+
/* @__PURE__ */ jsx(MapPin, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
|
|
88
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: venue })
|
|
89
|
+
] }),
|
|
90
|
+
isSoldOut ? /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "quiet", className: "shrink-0 whitespace-nowrap", children: labels.soldOut }) : priceText && /* @__PURE__ */ jsx(
|
|
91
|
+
"span",
|
|
92
|
+
{
|
|
93
|
+
className: cn(
|
|
94
|
+
"shrink-0 tabular-nums",
|
|
95
|
+
fee.kind === "free" && "font-semibold text-success"
|
|
96
|
+
),
|
|
97
|
+
children: priceText
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
] }),
|
|
101
|
+
(isLive || tags && tags.length > 0) && /* @__PURE__ */ jsxs(TagGroup, { className: "mt-1.5 h-[22px] overflow-hidden", children: [
|
|
102
|
+
isLive && /* @__PURE__ */ jsxs(Tag, { size: "sm", variant: "success", className: "shrink-0 whitespace-nowrap", children: [
|
|
103
|
+
/* @__PURE__ */ jsx(Radio, { className: "h-2.5 w-2.5", "aria-hidden": true }),
|
|
104
|
+
labels.liveNow
|
|
105
|
+
] }),
|
|
106
|
+
tags == null ? void 0 : tags.map((tag) => /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "quiet", className: "shrink-0 whitespace-nowrap", children: tag }, tag))
|
|
107
|
+
] })
|
|
108
|
+
] })
|
|
109
|
+
] });
|
|
110
|
+
const rootClasses = cn(
|
|
111
|
+
// `py-3`, not `py-3.5`: the chip line adds a third line back, and 8px of
|
|
112
|
+
// padding pays for most of it. Rows with a one-line title and no chips are
|
|
113
|
+
// still poster-driven and end up SHORTER than before.
|
|
114
|
+
"relative flex w-full items-start gap-3 py-3 text-left",
|
|
115
|
+
isSoldOut && "opacity-60",
|
|
116
|
+
(href || onClick) && "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
117
|
+
className
|
|
118
|
+
);
|
|
119
|
+
if (href) {
|
|
120
|
+
return /* @__PURE__ */ jsx(
|
|
121
|
+
LinkComponent,
|
|
122
|
+
{
|
|
123
|
+
href,
|
|
124
|
+
className: rootClasses,
|
|
125
|
+
onClick: onClick ? (mouseEvent) => onClick(event, mouseEvent) : void 0,
|
|
126
|
+
children: body
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
if (onClick) {
|
|
131
|
+
return /* @__PURE__ */ jsx("button", { type: "button", className: rootClasses, onClick: (e) => onClick(event, e), children: body });
|
|
132
|
+
}
|
|
133
|
+
return /* @__PURE__ */ jsx("div", { className: rootClasses, children: body });
|
|
134
|
+
});
|
|
135
|
+
function EventListRowSkeleton({
|
|
136
|
+
hideRule,
|
|
137
|
+
showTags = true,
|
|
138
|
+
className
|
|
139
|
+
}) {
|
|
140
|
+
return /* @__PURE__ */ jsxs(
|
|
141
|
+
"div",
|
|
142
|
+
{
|
|
143
|
+
"aria-hidden": "true",
|
|
144
|
+
className: cn("relative flex w-full items-start gap-3 py-3 text-left", className),
|
|
145
|
+
children: [
|
|
146
|
+
!hideRule && /* @__PURE__ */ jsx(Separator, { className: "absolute inset-x-0 top-0" }),
|
|
147
|
+
/* @__PURE__ */ jsxs("div", { className: "w-[42px] shrink-0 rounded-[9px] py-1.5 text-center", children: [
|
|
148
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mx-auto h-4 w-5" }),
|
|
149
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mx-auto mt-[3px] h-[10px] w-6" })
|
|
150
|
+
] }),
|
|
151
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "aspect-square w-[72px] shrink-0 rounded-[9px]" }),
|
|
152
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
153
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
154
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[15px] w-full" }),
|
|
155
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[15px] w-2/3" })
|
|
156
|
+
] }),
|
|
157
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-2", children: [
|
|
158
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-10" }),
|
|
159
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-3 shrink-0 rounded-full" }),
|
|
160
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24" }),
|
|
161
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ml-auto h-3 w-12" })
|
|
162
|
+
] }),
|
|
163
|
+
showTags && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex items-center gap-1.5", children: [
|
|
164
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[22px] w-14 rounded-full" }),
|
|
165
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-[22px] w-11 rounded-full" })
|
|
166
|
+
] })
|
|
167
|
+
] })
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export { EventListRow, EventListRowSkeleton };
|