@bearmenu/ui 0.8.23 → 0.8.25
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-5LTILG3L.js → chunk-5HHRVJOT.js} +14 -1
- package/dist/{chunk-SDWN6L4O.js → chunk-AHHDC7ML.js} +1 -1
- package/dist/{chunk-5XREWOBB.js → chunk-IEIJP73R.js} +14 -1
- package/dist/{chunk-BKKQ7GCZ.js → chunk-QG6I2ILT.js} +1 -1
- package/dist/{chunk-TIQNM4XD.js → chunk-VEGFQSZA.js} +17 -1
- package/dist/components/alert-dialog.js +1 -1
- package/dist/components/alert.d.ts +2 -2
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/booking-row.d.ts +60 -0
- package/dist/components/booking-row.js +103 -0
- package/dist/components/booking-summary-card.d.ts +38 -0
- package/dist/components/booking-summary-card.js +67 -0
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.js +1 -1
- package/dist/components/calendar.d.ts +17 -3
- package/dist/components/calendar.js +100 -12
- package/dist/components/carousel.js +1 -1
- package/dist/components/coach-marks.js +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/command.d.ts +7 -7
- package/dist/components/concept-convergence.js +2 -2
- package/dist/components/empty-state.js +1 -1
- package/dist/components/event-card.js +1 -1
- package/dist/components/event-compact-row.js +1 -1
- package/dist/components/event-detail-panel.js +1 -1
- package/dist/components/event-list-row-wide.js +2 -2
- package/dist/components/event-list-row.js +1 -1
- package/dist/components/filter-category-row.js +1 -1
- package/dist/components/hold-countdown.d.ts +43 -0
- package/dist/components/hold-countdown.js +90 -0
- package/dist/components/kitchen-dossier.js +1 -1
- package/dist/components/link-button.js +1 -1
- package/dist/components/menu-family-block.js +1 -1
- package/dist/components/menu-index-list.js +1 -1
- package/dist/components/menu-item.js +3 -3
- package/dist/components/motion-icon-set.d.ts +2 -1
- package/dist/components/motion-icon-set.js +27 -1
- package/dist/components/multi-select-combobox.js +2 -2
- package/dist/components/pagination.js +1 -1
- package/dist/components/party-counter.d.ts +36 -0
- package/dist/components/party-counter.js +61 -0
- package/dist/components/place-card.js +2 -2
- package/dist/components/place-details-mobile.js +1 -1
- package/dist/components/searchable-select.js +1 -1
- package/dist/components/signature-chip.js +2 -2
- package/dist/components/sliding-panels.js +1 -1
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/tag.d.ts +2 -2
- package/dist/components/text.d.ts +3 -3
- package/dist/components/time-slot.d.ts +73 -0
- package/dist/components/time-slot.js +106 -0
- package/dist/components/toggle-group.js +15 -2
- package/dist/components/toggle.d.ts +1 -1
- package/dist/components/toggle.js +1 -1
- package/dist/components/top-ranking-entry.js +3 -3
- package/dist/components/weekday-chip.d.ts +33 -0
- package/dist/components/weekday-chip.js +48 -0
- package/package.json +1 -1
- package/src/components/badge.stories.tsx +17 -0
- package/src/components/badge.tsx +15 -0
- package/src/components/booking-primitives.test.tsx +180 -0
- package/src/components/booking-row.stories.tsx +66 -0
- package/src/components/booking-row.tsx +168 -0
- package/src/components/booking-summary-card.stories.tsx +41 -0
- package/src/components/booking-summary-card.tsx +109 -0
- package/src/components/button.stories.tsx +23 -0
- package/src/components/button.tsx +13 -0
- package/src/components/calendar.stories.tsx +27 -0
- package/src/components/calendar.tsx +110 -3
- package/src/components/hold-countdown.stories.tsx +68 -0
- package/src/components/hold-countdown.tsx +140 -0
- package/src/components/motion-icon-set.stories.tsx +2 -0
- package/src/components/motion-icon-set.tsx +42 -0
- package/src/components/party-counter.stories.tsx +57 -0
- package/src/components/party-counter.tsx +93 -0
- package/src/components/time-slot.stories.tsx +85 -0
- package/src/components/time-slot.tsx +186 -0
- package/src/components/toggle-group.stories.tsx +27 -0
- package/src/components/toggle-group.tsx +14 -1
- package/src/components/toggle.tsx +16 -0
- package/src/components/weekday-chip.stories.tsx +54 -0
- package/src/components/weekday-chip.tsx +75 -0
|
@@ -56,7 +56,16 @@ var buttonVariants = cva(
|
|
|
56
56
|
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",
|
|
57
57
|
brown: "bg-brown text-brown-foreground shadow-sm hover:bg-brown/85 hover:shadow",
|
|
58
58
|
/** An ON state that is not the primary — a toggled mode, a guide running. */
|
|
59
|
-
warning: "bg-warning text-warning-foreground shadow-sm hover:bg-warning/90 hover:shadow"
|
|
59
|
+
warning: "bg-warning text-warning-foreground shadow-sm hover:bg-warning/90 hover:shadow",
|
|
60
|
+
/**
|
|
61
|
+
* The committing action of a flow: "Continue · 19:30", "Confirm
|
|
62
|
+
* booking", "Reserve", "See booking". The booking design draws every
|
|
63
|
+
* one of them on `--gradient-primary` with white type, in both themes —
|
|
64
|
+
* the gradient is warm in dark too, so the ink never inverts.
|
|
65
|
+
* `bg-[image:…]`, not `bg-[…]`: the token is a gradient, and only
|
|
66
|
+
* `background-image` accepts it. Pair with `size="cta"` / `"cta-sm"`.
|
|
67
|
+
*/
|
|
68
|
+
cta: "bg-[image:var(--gradient-primary)] text-white hover:brightness-[0.94] active:brightness-90"
|
|
60
69
|
},
|
|
61
70
|
size: {
|
|
62
71
|
xs: "h-8 rounded-lg px-3 text-xs [&_svg]:size-3.5",
|
|
@@ -65,6 +74,10 @@ var buttonVariants = cva(
|
|
|
65
74
|
lg: "h-12 rounded-2xl px-8",
|
|
66
75
|
/** The `ink` action's shape. Owns the radius so no variant fights it. */
|
|
67
76
|
pill: "h-11 rounded-full px-5 text-[13.5px] font-bold",
|
|
77
|
+
/** The booking design's action: 46px, 12px radius, 15px semibold. */
|
|
78
|
+
cta: "h-[46px] rounded-xl px-5 text-[15px] font-semibold",
|
|
79
|
+
/** Its compact form, in dense footers and inline rows: 38px, 10px radius. */
|
|
80
|
+
"cta-sm": "h-[38px] rounded-[10px] px-4 text-[13.5px] font-semibold",
|
|
68
81
|
icon: "h-11 w-11 rounded-full",
|
|
69
82
|
"icon-xs": "h-8 w-8 rounded-full [&_svg]:size-3.5",
|
|
70
83
|
"icon-sm": "h-9 w-9 rounded-full",
|
|
@@ -18,7 +18,20 @@ var badgeVariants = cva(
|
|
|
18
18
|
warning: "border-transparent bg-warning text-warning-foreground",
|
|
19
19
|
brown: "border-transparent bg-brown text-brown-foreground",
|
|
20
20
|
/** A count sitting INSIDE a primary-filled control: its own ink, lifted a notch. */
|
|
21
|
-
onPrimary: "border-transparent bg-primary-foreground/20 text-primary-foreground"
|
|
21
|
+
onPrimary: "border-transparent bg-primary-foreground/20 text-primary-foreground",
|
|
22
|
+
/**
|
|
23
|
+
* Status pills of a booking — "Confirmed", "Pending" — and its code
|
|
24
|
+
* chip ("BM-8421"). A full pill at 10.5px bold, as the booking design
|
|
25
|
+
* draws them. The status type is darker than the solid tokens: `success`
|
|
26
|
+
* and `warning` sit at 0.48 / 0.72 lightness, which on their own 15–20%
|
|
27
|
+
* wash fall short of AA at this size, so light mode uses the design's
|
|
28
|
+
* 0.38 / 0.42 inks and dark mode the lifted tokens.
|
|
29
|
+
*/
|
|
30
|
+
// `border-0`: the base's transparent hairline would add 2px to each
|
|
31
|
+
// side the design does not have.
|
|
32
|
+
confirmed: "rounded-full border-0 bg-success/15 px-[9px] py-[3px] text-[10.5px] leading-[1.2] font-bold text-[oklch(0.38_0.1_155)] dark:text-success",
|
|
33
|
+
pending: "rounded-full border-0 bg-warning/20 px-[9px] py-[3px] text-[10.5px] leading-[1.2] font-bold text-[oklch(0.42_0.1_70)] dark:text-warning",
|
|
34
|
+
code: "rounded-full border-0 bg-surface-2 px-[9px] py-[3px] font-mono text-[10.5px] leading-[1.2] font-bold tabular-nums text-ink-secondary"
|
|
22
35
|
},
|
|
23
36
|
// v1.0 motion: "live" surface signal — applies `live-pulse` archetype.
|
|
24
37
|
// Pair with a colored variant (e.g. variant="destructive" live).
|
|
@@ -17,7 +17,23 @@ var toggleVariants = cva(
|
|
|
17
17
|
* (`ToggleGroup variant="segmented"`) supplies the capsule; the cell
|
|
18
18
|
* never fills with the accent, which would read as a primary button.
|
|
19
19
|
*/
|
|
20
|
-
segmented: "h-10 w-11 rounded-full text-muted-foreground hover:bg-transparent hover:text-foreground data-[state=on]:bg-card data-[state=on]:text-foreground data-[state=on]:shadow-[var(--shadow-card)]"
|
|
20
|
+
segmented: "h-10 w-11 rounded-full text-muted-foreground hover:bg-transparent hover:text-foreground data-[state=on]:bg-card data-[state=on]:text-foreground data-[state=on]:shadow-[var(--shadow-card)]",
|
|
21
|
+
/**
|
|
22
|
+
* A choice among a few named options that sit in a wrapping row —
|
|
23
|
+
* the booking flow's seating preference ("No preference", "Terrace",
|
|
24
|
+
* "By the window"). Off: a card pill with a hairline. On: the accent
|
|
25
|
+
* hairline over an 8% accent wash and accent type — a selection, not
|
|
26
|
+
* a button, so it never fills.
|
|
27
|
+
*/
|
|
28
|
+
chip: "h-auto min-w-0 rounded-full border border-border bg-card px-[13px] py-[7px] text-[12.5px] leading-[1.2] font-normal text-foreground hover:border-accent/40 hover:bg-card hover:text-foreground data-[state=on]:border-accent data-[state=on]:bg-accent/[0.08] data-[state=on]:font-semibold data-[state=on]:text-accent",
|
|
29
|
+
/**
|
|
30
|
+
* One tab of a two-or-three-way switch that shares the width — My
|
|
31
|
+
* bookings' Upcoming / Past. The group (`ToggleGroup variant="tab"`)
|
|
32
|
+
* supplies the muted capsule; the ON tab is a raised card. The type
|
|
33
|
+
* does not change colour between on and off — as drawn, the raised
|
|
34
|
+
* card alone says which tab is current.
|
|
35
|
+
*/
|
|
36
|
+
tab: "h-auto min-w-0 flex-1 rounded-full px-3 py-[7px] text-[12.5px] leading-[1.2] font-semibold text-ink-secondary hover:bg-transparent hover:text-foreground data-[state=on]:bg-card data-[state=on]:text-ink-secondary data-[state=on]:shadow-[0_1px_2px_oklch(0.5_0_0/0.12)] dark:data-[state=on]:bg-surface-2 dark:data-[state=on]:text-foreground"
|
|
21
37
|
},
|
|
22
38
|
size: {
|
|
23
39
|
default: "h-9 px-2 min-w-9",
|
|
@@ -3,10 +3,10 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const alertVariants: (props?: ({
|
|
6
|
-
variant?: "default" | "destructive" | "
|
|
6
|
+
variant?: "default" | "destructive" | "warning" | "success" | null | undefined;
|
|
7
7
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
8
8
|
declare const Alert: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
9
|
-
variant?: "default" | "destructive" | "
|
|
9
|
+
variant?: "default" | "destructive" | "warning" | "success" | null | undefined;
|
|
10
10
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
|
|
11
11
|
declare const AlertTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
12
12
|
declare const AlertDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
6
6
|
declare const badgeVariants: (props?: ({
|
|
7
|
-
variant?: "
|
|
7
|
+
variant?: "code" | "default" | "destructive" | "outline" | "secondary" | "glass" | "overlay" | "brown" | "warning" | "success" | "onPrimary" | "confirmed" | "pending" | null | undefined;
|
|
8
8
|
live?: boolean | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
|
package/dist/components/badge.js
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* BookingRow and BookingRowList — the guest's bookings in "My bookings".
|
|
6
|
+
*
|
|
7
|
+
* Measured from the booking design (`.bkrow`, and the desktop list):
|
|
8
|
+
*
|
|
9
|
+
* Mobile (below `md`): rows 14px tall-padded, 12px gap, divided by a
|
|
10
|
+
* `line-soft` hairline. A 50px thumb with an 11px radius. Line one: the venue
|
|
11
|
+
* at 14px bold, the code chip pushed right. Line two: the venue type at 11.5px
|
|
12
|
+
* muted. Line three, 7px gaps: when at 12.5px medium, the party at 12px muted,
|
|
13
|
+
* then the status pill.
|
|
14
|
+
*
|
|
15
|
+
* Desktop (`md` and up): one card (14px radius, no inset), rows 14px × 18px
|
|
16
|
+
* with 14px gaps, divided by the same hairline. A 46px thumb, then the venue
|
|
17
|
+
* (bold) with its type inline and muted over "when · party" in the secondary
|
|
18
|
+
* ink, then the status pill, the code chip and a muted chevron. The row that
|
|
19
|
+
* is next up gets a 5% accent wash.
|
|
20
|
+
*
|
|
21
|
+
* The whole row is one link. Strings arrive formatted and localised; the thumb
|
|
22
|
+
* arrives rendered, so the app picks its own image component.
|
|
23
|
+
*/
|
|
24
|
+
type BookingRowStatus = "confirmed" | "pending";
|
|
25
|
+
type BookingRowLinkProps = {
|
|
26
|
+
href: string;
|
|
27
|
+
className?: string;
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
};
|
|
30
|
+
type BookingRowProps = {
|
|
31
|
+
venueName: string;
|
|
32
|
+
/** "Bistro", "Cocktail bar" */
|
|
33
|
+
venueType?: string;
|
|
34
|
+
/** "Fri 14 Aug · 19:30" */
|
|
35
|
+
when: string;
|
|
36
|
+
/** "2 people" */
|
|
37
|
+
party: string;
|
|
38
|
+
status: BookingRowStatus;
|
|
39
|
+
/** "Confirmed", "Pending" — already localised. */
|
|
40
|
+
statusLabel: string;
|
|
41
|
+
code: string;
|
|
42
|
+
href: string;
|
|
43
|
+
/** The venue photo, rendered by the app; a quiet placeholder when absent. */
|
|
44
|
+
thumbnail?: React.ReactNode;
|
|
45
|
+
/** The next booking up — tinted on desktop. */
|
|
46
|
+
highlighted?: boolean;
|
|
47
|
+
linkComponent?: React.ComponentType<BookingRowLinkProps>;
|
|
48
|
+
className?: string;
|
|
49
|
+
};
|
|
50
|
+
declare function BookingRow({ venueName, venueType, when, party, status, statusLabel, code, href, thumbnail, highlighted, linkComponent: LinkComponent, className, }: BookingRowProps): react_jsx_runtime.JSX.Element;
|
|
51
|
+
type BookingRowListProps = {
|
|
52
|
+
children: React.ReactNode;
|
|
53
|
+
/** "Upcoming bookings" — names the list for assistive tech. */
|
|
54
|
+
"aria-label"?: string;
|
|
55
|
+
className?: string;
|
|
56
|
+
};
|
|
57
|
+
/** The list around the rows: hairlines between them on mobile, one card on desktop. */
|
|
58
|
+
declare function BookingRowList({ children, "aria-label": ariaLabel, className }: BookingRowListProps): react_jsx_runtime.JSX.Element;
|
|
59
|
+
|
|
60
|
+
export { BookingRow, type BookingRowLinkProps, BookingRowList, type BookingRowListProps, type BookingRowProps, type BookingRowStatus };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Badge } from '../chunk-IEIJP73R.js';
|
|
2
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
3
|
+
import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { ChevronRight } from 'lucide-react';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function DefaultLink(_a) {
|
|
9
|
+
var _b = _a, { href } = _b, props = __objRest(_b, ["href"]);
|
|
10
|
+
return /* @__PURE__ */ jsx("a", __spreadValues({ href }, props));
|
|
11
|
+
}
|
|
12
|
+
function Thumb({ children, className }) {
|
|
13
|
+
return /* @__PURE__ */ jsx(
|
|
14
|
+
"span",
|
|
15
|
+
{
|
|
16
|
+
"aria-hidden": true,
|
|
17
|
+
className: cn(
|
|
18
|
+
// Dark: `surface-2` sits a notch from the card and vanishes; the
|
|
19
|
+
// accent-tinted step reads as a photo slot.
|
|
20
|
+
"block shrink-0 overflow-hidden rounded-[11px] bg-surface-2 dark:bg-accent-subtle [&_img]:size-full [&_img]:object-cover",
|
|
21
|
+
className
|
|
22
|
+
),
|
|
23
|
+
children
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
function BookingRow({
|
|
28
|
+
venueName,
|
|
29
|
+
venueType,
|
|
30
|
+
when,
|
|
31
|
+
party,
|
|
32
|
+
status,
|
|
33
|
+
statusLabel,
|
|
34
|
+
code,
|
|
35
|
+
href,
|
|
36
|
+
thumbnail,
|
|
37
|
+
highlighted,
|
|
38
|
+
linkComponent: LinkComponent = DefaultLink,
|
|
39
|
+
className
|
|
40
|
+
}) {
|
|
41
|
+
const statusPill = /* @__PURE__ */ jsx(Badge, { as: "span", variant: status, children: statusLabel });
|
|
42
|
+
const codeChip = /* @__PURE__ */ jsx(Badge, { as: "span", variant: "code", children: code });
|
|
43
|
+
return /* @__PURE__ */ jsxs(
|
|
44
|
+
LinkComponent,
|
|
45
|
+
{
|
|
46
|
+
href,
|
|
47
|
+
className: cn(
|
|
48
|
+
"flex gap-3 py-3.5 leading-[1.2] text-foreground",
|
|
49
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
|
|
50
|
+
"md:items-center md:gap-3.5 md:px-[18px] md:hover:bg-accent/[0.03]",
|
|
51
|
+
highlighted && "md:bg-accent/5 md:hover:bg-accent/5",
|
|
52
|
+
className
|
|
53
|
+
),
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ jsx(Thumb, { className: "size-[50px] md:size-[46px]", children: thumbnail }),
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 md:hidden", children: [
|
|
57
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
58
|
+
/* @__PURE__ */ jsx("b", { className: "truncate text-sm font-bold", children: venueName }),
|
|
59
|
+
codeChip
|
|
60
|
+
] }),
|
|
61
|
+
venueType && /* @__PURE__ */ jsx("div", { className: "text-[11.5px] text-muted-foreground", children: venueType }),
|
|
62
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-[7px]", children: [
|
|
63
|
+
/* @__PURE__ */ jsx("span", { className: "text-[12.5px] font-medium", children: when }),
|
|
64
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: party }),
|
|
65
|
+
statusPill
|
|
66
|
+
] })
|
|
67
|
+
] }),
|
|
68
|
+
/* @__PURE__ */ jsxs("div", { className: "hidden min-w-0 flex-1 md:block", children: [
|
|
69
|
+
/* @__PURE__ */ jsxs("div", { className: "truncate", children: [
|
|
70
|
+
/* @__PURE__ */ jsx("b", { className: "text-sm font-bold", children: venueName }),
|
|
71
|
+
venueType && /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-xs text-muted-foreground", children: venueType })
|
|
72
|
+
] }),
|
|
73
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-0.5 truncate text-[12.5px] text-ink-secondary", children: [
|
|
74
|
+
when,
|
|
75
|
+
" \xB7 ",
|
|
76
|
+
party
|
|
77
|
+
] })
|
|
78
|
+
] }),
|
|
79
|
+
/* @__PURE__ */ jsxs("span", { className: "hidden md:contents", children: [
|
|
80
|
+
statusPill,
|
|
81
|
+
codeChip,
|
|
82
|
+
/* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-[15px] shrink-0 text-muted-foreground" })
|
|
83
|
+
] })
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function BookingRowList({ children, "aria-label": ariaLabel, className }) {
|
|
89
|
+
return /* @__PURE__ */ jsx(
|
|
90
|
+
"ul",
|
|
91
|
+
{
|
|
92
|
+
"aria-label": ariaLabel,
|
|
93
|
+
className: cn(
|
|
94
|
+
"divide-y divide-line-soft",
|
|
95
|
+
"md:overflow-hidden md:rounded-[14px] md:border md:border-border md:bg-card",
|
|
96
|
+
className
|
|
97
|
+
),
|
|
98
|
+
children: React.Children.map(children, (child) => child ? /* @__PURE__ */ jsx("li", { children: child }) : null)
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { BookingRow, BookingRowList };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BookingSummaryCard — the booking at a glance on the confirmation screen
|
|
5
|
+
* ("Your table is booked"): the venue, then when, how many, where you asked
|
|
6
|
+
* to sit and the address, then the booking code.
|
|
7
|
+
*
|
|
8
|
+
* Measured from the booking design (`.cardx` + `.rowi`): a card with a 1px
|
|
9
|
+
* hairline, 14px radius, 15px inset and a 1px/3px shadow. The venue at 16px
|
|
10
|
+
* bold. Rows 11px below it, 7px apart: a 14px icon (1.8 stroke, muted) in a
|
|
11
|
+
* 16px column, 10px gap, text at 13px in the secondary ink. Then a
|
|
12
|
+
* `line-soft` divider 13px below with 13px above the code row: "BOOKING CODE"
|
|
13
|
+
* at 10.5px uppercase, muted, and the code in mono at 15px bold, pushed right.
|
|
14
|
+
*
|
|
15
|
+
* Every string arrives formatted and localised; the card only lays them out.
|
|
16
|
+
*/
|
|
17
|
+
type BookingSummaryCardLabels = {
|
|
18
|
+
/** "Booking code" */
|
|
19
|
+
code: string;
|
|
20
|
+
};
|
|
21
|
+
type BookingSummaryCardProps = {
|
|
22
|
+
venueName: string;
|
|
23
|
+
/** "Fri 14 August" */
|
|
24
|
+
date: string;
|
|
25
|
+
/** "19:30 · 2 people" */
|
|
26
|
+
timeAndParty: string;
|
|
27
|
+
/** "Terrace (requested)" — omitted when there is no preference. */
|
|
28
|
+
seating?: string;
|
|
29
|
+
/** "Strada Iuliu Maniu 12" */
|
|
30
|
+
address?: string;
|
|
31
|
+
/** "BM-8421" */
|
|
32
|
+
code: string;
|
|
33
|
+
labels: BookingSummaryCardLabels;
|
|
34
|
+
className?: string;
|
|
35
|
+
};
|
|
36
|
+
declare function BookingSummaryCard({ venueName, date, timeAndParty, seating, address, code, labels, className, }: BookingSummaryCardProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
|
|
38
|
+
export { BookingSummaryCard, type BookingSummaryCardLabels, type BookingSummaryCardProps };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
2
|
+
import '../chunk-MMUBH76A.js';
|
|
3
|
+
import { CalendarDays, Clock, MapPin } from 'lucide-react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function Row({ icon, children }) {
|
|
7
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 text-[13px] leading-4 text-ink-secondary [&+&]:mt-[7px]", children: [
|
|
8
|
+
/* @__PURE__ */ jsx("span", { className: "flex w-4 shrink-0 justify-center text-muted-foreground", "aria-hidden": true, children: icon }),
|
|
9
|
+
/* @__PURE__ */ jsx("span", { children })
|
|
10
|
+
] });
|
|
11
|
+
}
|
|
12
|
+
var ICON = "size-3.5 [stroke-width:1.8]";
|
|
13
|
+
function SeatIcon({ className }) {
|
|
14
|
+
return /* @__PURE__ */ jsxs(
|
|
15
|
+
"svg",
|
|
16
|
+
{
|
|
17
|
+
viewBox: "0 0 24 24",
|
|
18
|
+
fill: "none",
|
|
19
|
+
stroke: "currentColor",
|
|
20
|
+
strokeLinecap: "round",
|
|
21
|
+
strokeLinejoin: "round",
|
|
22
|
+
className,
|
|
23
|
+
"aria-hidden": true,
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsx("path", { d: "M5 11V7a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v4" }),
|
|
26
|
+
/* @__PURE__ */ jsx("path", { d: "M5 11a2 2 0 0 0 0 4h14a2 2 0 0 0 0-4" }),
|
|
27
|
+
/* @__PURE__ */ jsx("path", { d: "M6 15v3M18 15v3M7 15h10" })
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
function BookingSummaryCard({
|
|
33
|
+
venueName,
|
|
34
|
+
date,
|
|
35
|
+
timeAndParty,
|
|
36
|
+
seating,
|
|
37
|
+
address,
|
|
38
|
+
code,
|
|
39
|
+
labels,
|
|
40
|
+
className
|
|
41
|
+
}) {
|
|
42
|
+
return /* @__PURE__ */ jsxs(
|
|
43
|
+
"div",
|
|
44
|
+
{
|
|
45
|
+
"data-slot": "booking-summary-card",
|
|
46
|
+
className: cn(
|
|
47
|
+
"rounded-[14px] border border-border bg-card p-[15px] leading-[1.2] shadow-[0_1px_3px_oklch(0.5_0_0/0.1)]",
|
|
48
|
+
className
|
|
49
|
+
),
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ jsx("b", { className: "text-base leading-5 font-bold text-foreground", children: venueName }),
|
|
52
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-[11px]", children: [
|
|
53
|
+
/* @__PURE__ */ jsx(Row, { icon: /* @__PURE__ */ jsx(CalendarDays, { className: ICON }), children: date }),
|
|
54
|
+
/* @__PURE__ */ jsx(Row, { icon: /* @__PURE__ */ jsx(Clock, { className: ICON }), children: timeAndParty }),
|
|
55
|
+
seating && /* @__PURE__ */ jsx(Row, { icon: /* @__PURE__ */ jsx(SeatIcon, { className: ICON }), children: seating }),
|
|
56
|
+
address && /* @__PURE__ */ jsx(Row, { icon: /* @__PURE__ */ jsx(MapPin, { className: ICON }), children: address })
|
|
57
|
+
] }),
|
|
58
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-[13px] flex items-center justify-between border-t border-line-soft pt-[13px]", children: [
|
|
59
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10.5px] tracking-[0.05em] text-muted-foreground uppercase", children: labels.code }),
|
|
60
|
+
/* @__PURE__ */ jsx("b", { className: "font-mono text-[15px] font-bold tabular-nums text-foreground", children: code })
|
|
61
|
+
] })
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { BookingSummaryCard };
|
|
@@ -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?: "
|
|
7
|
-
size?: "default" | "xs" | "sm" | "lg" | "pill" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "glass" | "overlay" | "ink" | "brown" | "warning" | "cta" | null | undefined;
|
|
7
|
+
size?: "default" | "cta" | "xs" | "sm" | "lg" | "pill" | "cta-sm" | "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,13 +1,27 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { DayButton, DayPicker } from 'react-day-picker';
|
|
4
4
|
import { Button } from './button.js';
|
|
5
5
|
import 'class-variance-authority/types';
|
|
6
6
|
import 'class-variance-authority';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* `appearance="booking"` is the month grid of the booking flow's "When are you
|
|
10
|
+
* coming?" (desktop), measured from its design (`.cal`): seven equal columns
|
|
11
|
+
* 3px apart; single-letter weekdays at 9.5px bold, muted; days as 32px round
|
|
12
|
+
* cells in mono 12.5px medium, secondary ink; the chosen day filled with
|
|
13
|
+
* `--gradient-primary`, white and bold; past days at 30%; a day the venue is
|
|
14
|
+
* closed struck through in a lighter ink. No outside days. Mark closed days
|
|
15
|
+
* with `modifiers={{ closed: … }}` — the appearance styles the `closed`
|
|
16
|
+
* modifier; `disabled` covers past days and the booking window.
|
|
17
|
+
*/
|
|
18
|
+
type CalendarAppearance = "default" | "booking";
|
|
19
|
+
declare function Calendar({ className, classNames, showOutsideDays, captionLayout, buttonVariant, appearance, formatters, components, modifiersClassNames, ...props }: React.ComponentProps<typeof DayPicker> & {
|
|
9
20
|
buttonVariant?: React.ComponentProps<typeof Button>["variant"];
|
|
21
|
+
appearance?: CalendarAppearance;
|
|
10
22
|
}): react_jsx_runtime.JSX.Element;
|
|
11
23
|
declare function CalendarDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>): react_jsx_runtime.JSX.Element;
|
|
24
|
+
/** The booking appearance's day: a 32px round cell, see `BOOKING_CLASSNAMES`. */
|
|
25
|
+
declare function BookingDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>): react_jsx_runtime.JSX.Element;
|
|
12
26
|
|
|
13
|
-
export { Calendar, CalendarDayButton };
|
|
27
|
+
export { BookingDayButton, Calendar, CalendarDayButton };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buttonVariants, Button } from '../chunk-
|
|
1
|
+
import { buttonVariants, Button } from '../chunk-5HHRVJOT.js';
|
|
2
2
|
import '../chunk-RIH2IS7X.js';
|
|
3
3
|
import '../chunk-5YNIQ2BL.js';
|
|
4
4
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
@@ -8,29 +8,80 @@ import { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from 'lucide-react
|
|
|
8
8
|
import { getDefaultClassNames, DayPicker } from 'react-day-picker';
|
|
9
9
|
import { jsx } from 'react/jsx-runtime';
|
|
10
10
|
|
|
11
|
+
var BOOKING_CLASSNAMES = {
|
|
12
|
+
root: "w-full",
|
|
13
|
+
months: "relative flex flex-col",
|
|
14
|
+
month: "flex w-full flex-col",
|
|
15
|
+
// The caption row is 15px with 7px under it; the chevrons sit in that row.
|
|
16
|
+
nav: "absolute inset-x-0 top-0 flex h-[15px] w-full items-center justify-between",
|
|
17
|
+
button_previous: "grid size-6 -m-[4.5px] cursor-pointer place-items-center rounded-full text-muted-foreground hover:bg-surface-2 hover:text-foreground aria-disabled:pointer-events-none aria-disabled:opacity-30 [&_svg]:size-3.5",
|
|
18
|
+
button_next: "grid size-6 -m-[4.5px] cursor-pointer place-items-center rounded-full text-muted-foreground hover:bg-surface-2 hover:text-foreground aria-disabled:pointer-events-none aria-disabled:opacity-30 [&_svg]:size-3.5",
|
|
19
|
+
month_caption: "mb-[7px] flex h-[15px] w-full items-center justify-center",
|
|
20
|
+
caption_label: "text-[12.5px] leading-[15px] font-bold text-foreground select-none",
|
|
21
|
+
month_grid: "w-full border-collapse",
|
|
22
|
+
weekdays: "grid grid-cols-7 gap-[3px]",
|
|
23
|
+
weekday: "pb-[3px] text-center text-[9.5px] font-bold text-muted-foreground select-none",
|
|
24
|
+
week: "mt-[3px] grid grid-cols-7 gap-[3px]",
|
|
25
|
+
day: "p-0 text-center select-none",
|
|
26
|
+
today: "",
|
|
27
|
+
outside: "invisible",
|
|
28
|
+
disabled: "",
|
|
29
|
+
hidden: "invisible"
|
|
30
|
+
};
|
|
11
31
|
function Calendar(_a) {
|
|
12
32
|
var _b = _a, {
|
|
13
33
|
className,
|
|
14
34
|
classNames,
|
|
15
|
-
showOutsideDays
|
|
35
|
+
showOutsideDays,
|
|
16
36
|
captionLayout = "label",
|
|
17
37
|
buttonVariant = "ghost",
|
|
38
|
+
appearance = "default",
|
|
18
39
|
formatters,
|
|
19
|
-
components
|
|
40
|
+
components,
|
|
41
|
+
modifiersClassNames
|
|
20
42
|
} = _b, props = __objRest(_b, [
|
|
21
43
|
"className",
|
|
22
44
|
"classNames",
|
|
23
45
|
"showOutsideDays",
|
|
24
46
|
"captionLayout",
|
|
25
47
|
"buttonVariant",
|
|
48
|
+
"appearance",
|
|
26
49
|
"formatters",
|
|
27
|
-
"components"
|
|
50
|
+
"components",
|
|
51
|
+
"modifiersClassNames"
|
|
28
52
|
]);
|
|
29
53
|
const defaultClassNames = getDefaultClassNames();
|
|
54
|
+
if (appearance === "booking") {
|
|
55
|
+
return /* @__PURE__ */ jsx(
|
|
56
|
+
DayPicker,
|
|
57
|
+
__spreadValues({
|
|
58
|
+
showOutsideDays: showOutsideDays != null ? showOutsideDays : false,
|
|
59
|
+
className: cn("group/calendar w-full", className),
|
|
60
|
+
captionLayout: "label",
|
|
61
|
+
formatters: __spreadValues({
|
|
62
|
+
formatWeekdayName: (date) => date.toLocaleString("default", { weekday: "narrow" })
|
|
63
|
+
}, formatters),
|
|
64
|
+
classNames: __spreadValues(__spreadValues({}, BOOKING_CLASSNAMES), classNames),
|
|
65
|
+
modifiersClassNames: __spreadValues({ closed: "is-closed" }, modifiersClassNames),
|
|
66
|
+
components: __spreadValues({
|
|
67
|
+
Root: (_a2) => {
|
|
68
|
+
var _b2 = _a2, { className: className2, rootRef } = _b2, rootProps = __objRest(_b2, ["className", "rootRef"]);
|
|
69
|
+
return /* @__PURE__ */ jsx("div", __spreadValues({ "data-slot": "calendar", "data-appearance": "booking", ref: rootRef, className: cn(className2) }, rootProps));
|
|
70
|
+
},
|
|
71
|
+
Chevron: (_c) => {
|
|
72
|
+
var _d = _c, { className: className2, orientation } = _d, chevronProps = __objRest(_d, ["className", "orientation"]);
|
|
73
|
+
return orientation === "left" ? /* @__PURE__ */ jsx(ChevronLeftIcon, __spreadValues({ className: cn("size-4", className2) }, chevronProps)) : /* @__PURE__ */ jsx(ChevronRightIcon, __spreadValues({ className: cn("size-4", className2) }, chevronProps));
|
|
74
|
+
},
|
|
75
|
+
DayButton: BookingDayButton
|
|
76
|
+
}, components)
|
|
77
|
+
}, props)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
30
80
|
return /* @__PURE__ */ jsx(
|
|
31
81
|
DayPicker,
|
|
32
82
|
__spreadValues({
|
|
33
|
-
showOutsideDays,
|
|
83
|
+
showOutsideDays: showOutsideDays != null ? showOutsideDays : true,
|
|
84
|
+
modifiersClassNames,
|
|
34
85
|
className: cn(
|
|
35
86
|
"group/calendar bg-background p-3 [--cell-size:--spacing(9)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
36
87
|
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
@@ -109,12 +160,12 @@ function Calendar(_a) {
|
|
|
109
160
|
hidden: cn("invisible", defaultClassNames.hidden)
|
|
110
161
|
}, classNames),
|
|
111
162
|
components: __spreadValues({
|
|
112
|
-
Root: (
|
|
113
|
-
var
|
|
163
|
+
Root: (_e) => {
|
|
164
|
+
var _f = _e, { className: className2, rootRef } = _f, props2 = __objRest(_f, ["className", "rootRef"]);
|
|
114
165
|
return /* @__PURE__ */ jsx("div", __spreadValues({ "data-slot": "calendar", ref: rootRef, className: cn(className2) }, props2));
|
|
115
166
|
},
|
|
116
|
-
Chevron: (
|
|
117
|
-
var
|
|
167
|
+
Chevron: (_g) => {
|
|
168
|
+
var _h = _g, { className: className2, orientation } = _h, props2 = __objRest(_h, ["className", "orientation"]);
|
|
118
169
|
if (orientation === "left") {
|
|
119
170
|
return /* @__PURE__ */ jsx(ChevronLeftIcon, __spreadValues({ className: cn("size-4", className2) }, props2));
|
|
120
171
|
}
|
|
@@ -124,8 +175,8 @@ function Calendar(_a) {
|
|
|
124
175
|
return /* @__PURE__ */ jsx(ChevronDownIcon, __spreadValues({ className: cn("size-4", className2) }, props2));
|
|
125
176
|
},
|
|
126
177
|
DayButton: CalendarDayButton,
|
|
127
|
-
WeekNumber: (
|
|
128
|
-
var
|
|
178
|
+
WeekNumber: (_i) => {
|
|
179
|
+
var _j = _i, { children } = _j, props2 = __objRest(_j, ["children"]);
|
|
129
180
|
return /* @__PURE__ */ jsx("td", __spreadProps(__spreadValues({}, props2), { children: /* @__PURE__ */ jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) }));
|
|
130
181
|
}
|
|
131
182
|
}, components)
|
|
@@ -167,5 +218,42 @@ function CalendarDayButton(_a) {
|
|
|
167
218
|
}, props)
|
|
168
219
|
);
|
|
169
220
|
}
|
|
221
|
+
function BookingDayButton(_a) {
|
|
222
|
+
var _b = _a, {
|
|
223
|
+
className,
|
|
224
|
+
day,
|
|
225
|
+
modifiers
|
|
226
|
+
} = _b, props = __objRest(_b, [
|
|
227
|
+
"className",
|
|
228
|
+
"day",
|
|
229
|
+
"modifiers"
|
|
230
|
+
]);
|
|
231
|
+
const ref = React.useRef(null);
|
|
232
|
+
React.useEffect(() => {
|
|
233
|
+
var _a2;
|
|
234
|
+
if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
|
|
235
|
+
}, [modifiers.focused]);
|
|
236
|
+
const closed = Boolean(modifiers.closed);
|
|
237
|
+
return /* @__PURE__ */ jsx(
|
|
238
|
+
"button",
|
|
239
|
+
__spreadValues({
|
|
240
|
+
ref,
|
|
241
|
+
type: "button",
|
|
242
|
+
"data-day": day.date.toLocaleDateString(),
|
|
243
|
+
"data-selected": modifiers.selected || void 0,
|
|
244
|
+
"data-closed": closed || void 0,
|
|
245
|
+
className: cn(
|
|
246
|
+
"grid h-8 w-full cursor-pointer place-items-center rounded-full font-mono text-[12.5px] leading-none font-medium text-ink-secondary tabular-nums",
|
|
247
|
+
"transition-colors duration-150 hover:bg-surface-2 motion-reduce:transition-none",
|
|
248
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
249
|
+
modifiers.selected && "bg-[image:var(--gradient-primary)] font-bold text-white hover:bg-transparent hover:brightness-[0.94]",
|
|
250
|
+
modifiers.disabled && !closed && "cursor-not-allowed opacity-30 hover:bg-transparent",
|
|
251
|
+
// A closed day is also disabled; it reads as closed, not as past.
|
|
252
|
+
closed && "cursor-not-allowed text-[oklch(0.7_0_0)] line-through hover:bg-transparent dark:text-ink-tertiary",
|
|
253
|
+
className
|
|
254
|
+
)
|
|
255
|
+
}, props)
|
|
256
|
+
);
|
|
257
|
+
}
|
|
170
258
|
|
|
171
|
-
export { Calendar, CalendarDayButton };
|
|
259
|
+
export { BookingDayButton, Calendar, CalendarDayButton };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Popover, PopoverTrigger, PopoverContent } from '../chunk-2ADCZXZJ.js';
|
|
2
2
|
import { Command, CommandInput, CommandList, CommandLoading, CommandEmpty, CommandGroup, CommandItem } from '../chunk-MCOHLWRS.js';
|
|
3
3
|
import '../chunk-PDTPO6NG.js';
|
|
4
|
-
import { Button } from '../chunk-
|
|
4
|
+
import { Button } from '../chunk-5HHRVJOT.js';
|
|
5
5
|
import '../chunk-RIH2IS7X.js';
|
|
6
6
|
import '../chunk-5YNIQ2BL.js';
|
|
7
7
|
import { cn } from '../chunk-FEK5XGZW.js';
|