@bearmenu/ui 0.8.24 → 0.8.26
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-I4RUOAU7.js → chunk-AHL45DD2.js} +11 -38
- package/dist/{chunk-TIQNM4XD.js → chunk-F3XK34DV.js} +25 -1
- package/dist/{chunk-5XREWOBB.js → chunk-IEIJP73R.js} +14 -1
- package/dist/chunk-L3CDXVEP.js +56 -0
- package/dist/{chunk-BKKQ7GCZ.js → chunk-QG6I2ILT.js} +1 -1
- package/dist/{chunk-CZK2MRS2.js → chunk-VEFKZIK6.js} +13 -3
- package/dist/components/alert-dialog.js +1 -1
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/banner.d.ts +36 -0
- package/dist/components/banner.js +29 -0
- 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/checkbox.d.ts +9 -2
- package/dist/components/checkbox.js +1 -1
- package/dist/components/coach-marks.js +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/concept-convergence.js +2 -2
- package/dist/components/currency-input.js +1 -1
- package/dist/components/date-input.js +1 -1
- package/dist/components/drift-rail.d.ts +2 -29
- package/dist/components/drift-rail.js +1 -3
- 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 +2 -2
- package/dist/components/event-index-row.js +1 -1
- package/dist/components/event-list-row-wide.js +3 -3
- package/dist/components/event-list-row.js +2 -2
- package/dist/components/field.d.ts +15 -1
- package/dist/components/field.js +62 -21
- 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/input.d.ts +1 -0
- package/dist/components/input.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 +3 -3
- package/dist/components/multi-select-menu.js +1 -1
- 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 +1 -1
- package/dist/components/place-details-mobile.js +1 -1
- package/dist/components/poster-tape.d.ts +2 -15
- package/dist/components/poster-tape.js +3 -12
- 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/textarea.d.ts +10 -3
- package/dist/components/textarea.js +21 -6
- 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 +207 -23
- package/src/components/badge.stories.tsx +17 -0
- package/src/components/badge.tsx +15 -0
- package/src/components/banner.stories.tsx +36 -0
- package/src/components/banner.tsx +58 -0
- package/src/components/booking-details-primitives.test.tsx +75 -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/checkbox.tsx +49 -23
- package/src/components/drift-rail.stories.tsx +1 -29
- package/src/components/drift-rail.tsx +4 -71
- package/src/components/field.stories.tsx +51 -1
- package/src/components/field.tsx +68 -9
- package/src/components/hold-countdown.stories.tsx +68 -0
- package/src/components/hold-countdown.tsx +140 -0
- package/src/components/input.tsx +13 -2
- 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/poster-tape.stories.tsx +0 -29
- package/src/components/poster-tape.tsx +5 -21
- package/src/components/textarea.tsx +25 -7
- 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 +24 -0
- package/src/components/weekday-chip.stories.tsx +54 -0
- package/src/components/weekday-chip.tsx +75 -0
- package/dist/chunk-NMEVJT5Q.js +0 -26
- package/src/components/drift-rail.test.tsx +0 -125
- package/src/components/poster-tape.test.tsx +0 -42
package/dist/components/field.js
CHANGED
|
@@ -5,46 +5,80 @@ import * as React from 'react';
|
|
|
5
5
|
import { Slot } from '@radix-ui/react-slot';
|
|
6
6
|
import { jsx } from 'react/jsx-runtime';
|
|
7
7
|
|
|
8
|
-
var FieldContext = React.createContext({ id: "", descriptionId: "", errorId: "", hasError: false });
|
|
8
|
+
var FieldContext = React.createContext({ id: "", descriptionId: "", errorId: "", hasError: false, appearance: "default" });
|
|
9
9
|
var Field = React.forwardRef(
|
|
10
10
|
(_a, ref) => {
|
|
11
|
-
var _b = _a, {
|
|
11
|
+
var _b = _a, {
|
|
12
|
+
id: providedId,
|
|
13
|
+
invalid,
|
|
14
|
+
orientation = "vertical",
|
|
15
|
+
appearance = "default",
|
|
16
|
+
className,
|
|
17
|
+
children
|
|
18
|
+
} = _b, props = __objRest(_b, [
|
|
19
|
+
"id",
|
|
20
|
+
"invalid",
|
|
21
|
+
"orientation",
|
|
22
|
+
"appearance",
|
|
23
|
+
"className",
|
|
24
|
+
"children"
|
|
25
|
+
]);
|
|
12
26
|
const generatedId = React.useId();
|
|
13
27
|
const id = providedId != null ? providedId : generatedId;
|
|
14
28
|
const descriptionId = `${id}-description`;
|
|
15
29
|
const errorId = `${id}-error`;
|
|
16
|
-
return /* @__PURE__ */ jsx(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
FieldContext.Provider,
|
|
32
|
+
{
|
|
33
|
+
value: { id, descriptionId, errorId, hasError: !!invalid, appearance },
|
|
34
|
+
children: /* @__PURE__ */ jsx(
|
|
35
|
+
"div",
|
|
36
|
+
__spreadProps(__spreadValues({
|
|
37
|
+
ref,
|
|
38
|
+
"data-slot": "field",
|
|
39
|
+
"data-invalid": invalid || void 0,
|
|
40
|
+
className: cn(
|
|
41
|
+
"flex",
|
|
42
|
+
appearance === "booking" ? "gap-[5px]" : "gap-2",
|
|
43
|
+
orientation === "vertical" ? "flex-col" : "flex-row items-center",
|
|
44
|
+
className
|
|
45
|
+
)
|
|
46
|
+
}, props), {
|
|
47
|
+
children
|
|
48
|
+
})
|
|
26
49
|
)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
})
|
|
30
|
-
) });
|
|
50
|
+
}
|
|
51
|
+
);
|
|
31
52
|
}
|
|
32
53
|
);
|
|
33
54
|
Field.displayName = "Field";
|
|
34
55
|
var FieldLabel = React.forwardRef((_a, ref) => {
|
|
35
56
|
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
36
|
-
const { id, hasError } = React.useContext(FieldContext);
|
|
57
|
+
const { id, hasError, appearance } = React.useContext(FieldContext);
|
|
37
58
|
return /* @__PURE__ */ jsx(
|
|
38
59
|
Label,
|
|
39
60
|
__spreadValues({
|
|
40
61
|
ref,
|
|
41
62
|
"data-slot": "field-label",
|
|
42
63
|
htmlFor: id,
|
|
43
|
-
className: cn(
|
|
64
|
+
className: cn(
|
|
65
|
+
appearance === "booking" ? "text-[10.5px] leading-[1.2] font-semibold tracking-[0.04em] text-muted-foreground uppercase" : hasError && "text-destructive",
|
|
66
|
+
className
|
|
67
|
+
)
|
|
44
68
|
}, props)
|
|
45
69
|
);
|
|
46
70
|
});
|
|
47
71
|
FieldLabel.displayName = "FieldLabel";
|
|
72
|
+
function FieldOptional(_a) {
|
|
73
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
74
|
+
return /* @__PURE__ */ jsx(
|
|
75
|
+
"span",
|
|
76
|
+
__spreadValues({
|
|
77
|
+
"data-slot": "field-optional",
|
|
78
|
+
className: cn("font-normal normal-case opacity-70", className)
|
|
79
|
+
}, props)
|
|
80
|
+
);
|
|
81
|
+
}
|
|
48
82
|
var FieldControl = React.forwardRef(
|
|
49
83
|
(_a, ref) => {
|
|
50
84
|
var props = __objRest(_a, []);
|
|
@@ -81,7 +115,7 @@ FieldDescription.displayName = "FieldDescription";
|
|
|
81
115
|
var FieldError = React.forwardRef(
|
|
82
116
|
(_a, ref) => {
|
|
83
117
|
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
84
|
-
const { errorId, hasError } = React.useContext(FieldContext);
|
|
118
|
+
const { errorId, hasError, appearance } = React.useContext(FieldContext);
|
|
85
119
|
if (!hasError || !children) return null;
|
|
86
120
|
return /* @__PURE__ */ jsx(
|
|
87
121
|
"p",
|
|
@@ -90,7 +124,14 @@ var FieldError = React.forwardRef(
|
|
|
90
124
|
id: errorId,
|
|
91
125
|
role: "alert",
|
|
92
126
|
"data-slot": "field-error",
|
|
93
|
-
className: cn(
|
|
127
|
+
className: cn(
|
|
128
|
+
appearance === "booking" ? (
|
|
129
|
+
// The design's error ink: the solid token is too bright for AA
|
|
130
|
+
// at 11.5px on white; dark mode's lifted token already clears it.
|
|
131
|
+
"m-0 text-[11.5px] leading-[1.2] text-[oklch(0.52_0.16_25)] dark:text-destructive"
|
|
132
|
+
) : "text-sm text-destructive",
|
|
133
|
+
className
|
|
134
|
+
)
|
|
94
135
|
}, props), {
|
|
95
136
|
children
|
|
96
137
|
})
|
|
@@ -127,4 +168,4 @@ var FieldLegend = React.forwardRef(
|
|
|
127
168
|
);
|
|
128
169
|
FieldLegend.displayName = "FieldLegend";
|
|
129
170
|
|
|
130
|
-
export { Field, FieldControl, FieldDescription, FieldError, FieldLabel, FieldLegend, FieldSet };
|
|
171
|
+
export { Field, FieldControl, FieldDescription, FieldError, FieldLabel, FieldLegend, FieldOptional, FieldSet };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HoldCountdown — "HELD FOR YOU 09:41": how long a table offered from the
|
|
6
|
+
* waitlist stays reserved for this guest (the booking flow's "A table opened
|
|
7
|
+
* up").
|
|
8
|
+
*
|
|
9
|
+
* Measured from the booking design: a card with a warning-colour hairline,
|
|
10
|
+
* 14px radius, 15px inset.
|
|
11
|
+
* - `stacked` (mobile): centred. The label at 10.5px uppercase with 0.06em
|
|
12
|
+
* tracking, muted; the remaining time in mono at 34px bold; a muted
|
|
13
|
+
* 11.5px line under it ("then it goes to the next person").
|
|
14
|
+
* - `inline` (desktop): one row, 18px gaps. The label over the time at
|
|
15
|
+
* 30px, then the explanation at 12.5px muted taking the free width, then
|
|
16
|
+
* the action.
|
|
17
|
+
*
|
|
18
|
+
* Counts down from `expiresAt` once a second and calls `onExpire` once, at
|
|
19
|
+
* zero. It never shows a negative time.
|
|
20
|
+
*/
|
|
21
|
+
type HoldCountdownLabels = {
|
|
22
|
+
/** "Held for you" */
|
|
23
|
+
held: string;
|
|
24
|
+
/** Stacked: "then it goes to the next person". Inline: "After the countdown the table goes to the next person on the list." */
|
|
25
|
+
explanation: string;
|
|
26
|
+
/** Spoken form for assistive tech — "9 minutes 41 seconds left". */
|
|
27
|
+
remaining: (minutes: number, seconds: number) => string;
|
|
28
|
+
};
|
|
29
|
+
type HoldCountdownProps = {
|
|
30
|
+
/** When the hold ends — ISO string or epoch milliseconds. */
|
|
31
|
+
expiresAt: string | number;
|
|
32
|
+
labels: HoldCountdownLabels;
|
|
33
|
+
layout?: "stacked" | "inline";
|
|
34
|
+
/** The inline layout's action, typically a `Button variant="cta" size="cta-sm"`. */
|
|
35
|
+
action?: React.ReactNode;
|
|
36
|
+
onExpire?: () => void;
|
|
37
|
+
/** Clock override for stories and tests. */
|
|
38
|
+
now?: () => number;
|
|
39
|
+
className?: string;
|
|
40
|
+
};
|
|
41
|
+
declare function HoldCountdown({ expiresAt, labels, layout, action, onExpire, now, className, }: HoldCountdownProps): react_jsx_runtime.JSX.Element;
|
|
42
|
+
|
|
43
|
+
export { HoldCountdown, type HoldCountdownLabels, type HoldCountdownProps };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
2
|
+
import '../chunk-MMUBH76A.js';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var HOLD_BORDER = "border-[oklch(0.62_0.15_70)] dark:border-warning";
|
|
7
|
+
function remainingSeconds(expiresAt, now) {
|
|
8
|
+
const end = typeof expiresAt === "number" ? expiresAt : Date.parse(expiresAt);
|
|
9
|
+
return Math.max(0, Math.ceil((end - now) / 1e3));
|
|
10
|
+
}
|
|
11
|
+
function HoldCountdown({
|
|
12
|
+
expiresAt,
|
|
13
|
+
labels,
|
|
14
|
+
layout = "stacked",
|
|
15
|
+
action,
|
|
16
|
+
onExpire,
|
|
17
|
+
now = Date.now,
|
|
18
|
+
className
|
|
19
|
+
}) {
|
|
20
|
+
const [left, setLeft] = React.useState(() => remainingSeconds(expiresAt, now()));
|
|
21
|
+
const expired = React.useRef(false);
|
|
22
|
+
const onExpireRef = React.useRef(onExpire);
|
|
23
|
+
onExpireRef.current = onExpire;
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
expired.current = false;
|
|
26
|
+
const tick = () => {
|
|
27
|
+
var _a;
|
|
28
|
+
const next = remainingSeconds(expiresAt, now());
|
|
29
|
+
setLeft(next);
|
|
30
|
+
if (next === 0 && !expired.current) {
|
|
31
|
+
expired.current = true;
|
|
32
|
+
(_a = onExpireRef.current) == null ? void 0 : _a.call(onExpireRef);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
tick();
|
|
36
|
+
const id = window.setInterval(tick, 1e3);
|
|
37
|
+
return () => window.clearInterval(id);
|
|
38
|
+
}, [expiresAt, now]);
|
|
39
|
+
const minutes = Math.floor(left / 60);
|
|
40
|
+
const seconds = left % 60;
|
|
41
|
+
const display = `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
|
|
42
|
+
const label = /* @__PURE__ */ jsx("div", { className: "text-[10.5px] leading-[13px] tracking-[0.06em] text-muted-foreground uppercase", children: labels.held });
|
|
43
|
+
const time = /* @__PURE__ */ jsx(
|
|
44
|
+
"div",
|
|
45
|
+
{
|
|
46
|
+
role: "timer",
|
|
47
|
+
"aria-label": labels.remaining(minutes, seconds),
|
|
48
|
+
className: cn(
|
|
49
|
+
"font-mono font-bold tabular-nums text-foreground",
|
|
50
|
+
layout === "stacked" ? "mt-[5px] text-[34px] leading-[40px]" : "text-[30px] leading-[35px]"
|
|
51
|
+
),
|
|
52
|
+
children: display
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
if (layout === "inline") {
|
|
56
|
+
return /* @__PURE__ */ jsxs(
|
|
57
|
+
"div",
|
|
58
|
+
{
|
|
59
|
+
"data-slot": "hold-countdown",
|
|
60
|
+
className: cn(
|
|
61
|
+
"flex items-center gap-[18px] rounded-[14px] border bg-card p-[15px] text-left",
|
|
62
|
+
HOLD_BORDER,
|
|
63
|
+
className
|
|
64
|
+
),
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ jsxs("div", { className: "shrink-0", children: [
|
|
67
|
+
label,
|
|
68
|
+
time
|
|
69
|
+
] }),
|
|
70
|
+
/* @__PURE__ */ jsx("p", { className: "flex-1 text-[12.5px] leading-[15px] text-muted-foreground", children: labels.explanation }),
|
|
71
|
+
action
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
return /* @__PURE__ */ jsxs(
|
|
77
|
+
"div",
|
|
78
|
+
{
|
|
79
|
+
"data-slot": "hold-countdown",
|
|
80
|
+
className: cn("rounded-[14px] border bg-card p-[15px] text-center", HOLD_BORDER, className),
|
|
81
|
+
children: [
|
|
82
|
+
label,
|
|
83
|
+
time,
|
|
84
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-[11.5px] leading-[14px] text-muted-foreground", children: labels.explanation })
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { HoldCountdown };
|
|
@@ -5,6 +5,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
5
5
|
declare const inputVariants: (props?: ({
|
|
6
6
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
7
7
|
shape?: "pill" | "rounded" | null | undefined;
|
|
8
|
+
appearance?: "default" | "booking" | null | undefined;
|
|
8
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
10
|
interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof inputVariants> {
|
|
10
11
|
}
|
package/dist/components/input.js
CHANGED
|
@@ -3,7 +3,7 @@ import { HueChip } from '../chunk-6VOWT4YR.js';
|
|
|
3
3
|
import { Separator } from '../chunk-NWZGSLPU.js';
|
|
4
4
|
import { PhotoGround, PHOTO_GROUND } from '../chunk-SWD6CJ35.js';
|
|
5
5
|
import { Skeleton } from '../chunk-XBBEX4SF.js';
|
|
6
|
-
import { buttonVariants } from '../chunk-
|
|
6
|
+
import { buttonVariants } from '../chunk-5HHRVJOT.js';
|
|
7
7
|
import '../chunk-RIH2IS7X.js';
|
|
8
8
|
import '../chunk-5YNIQ2BL.js';
|
|
9
9
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Separator } from '../chunk-NWZGSLPU.js';
|
|
2
2
|
import { Skeleton } from '../chunk-XBBEX4SF.js';
|
|
3
|
-
import { Button } from '../chunk-
|
|
3
|
+
import { Button } from '../chunk-5HHRVJOT.js';
|
|
4
4
|
import '../chunk-RIH2IS7X.js';
|
|
5
5
|
import '../chunk-5YNIQ2BL.js';
|
|
6
6
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { MentionSignal, MenuItem } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { MentionSignal, MenuItem } from '../chunk-AHHDC7ML.js';
|
|
2
|
+
import '../chunk-QG6I2ILT.js';
|
|
3
|
+
import '../chunk-IEIJP73R.js';
|
|
4
4
|
import '../chunk-FEK5XGZW.js';
|
|
5
5
|
import '../chunk-MMUBH76A.js';
|
|
@@ -15,6 +15,7 @@ declare function MotionHouse(props: MotionIconProps): react_jsx_runtime.JSX.Elem
|
|
|
15
15
|
* the silhouette alone.
|
|
16
16
|
*/
|
|
17
17
|
declare function MotionUtensils(props: MotionIconProps): react_jsx_runtime.JSX.Element;
|
|
18
|
+
declare function MotionCompass(props: MotionIconProps): react_jsx_runtime.JSX.Element;
|
|
18
19
|
declare function MotionMapPin(props: MotionIconProps): react_jsx_runtime.JSX.Element;
|
|
19
20
|
/**
|
|
20
21
|
* Lucide's calendar has no pages — it is a box, a rule and six dots, and
|
|
@@ -36,4 +37,4 @@ declare function MotionFlame(props: MotionIconProps): react_jsx_runtime.JSX.Elem
|
|
|
36
37
|
declare function MotionCalendarClock(props: MotionIconProps): react_jsx_runtime.JSX.Element;
|
|
37
38
|
declare function MotionList(props: MotionIconProps): react_jsx_runtime.JSX.Element;
|
|
38
39
|
|
|
39
|
-
export { MotionCalendar, MotionCalendarClock, MotionFlame, MotionHouse, MotionLayoutGrid, MotionList, MotionMap, MotionMapPin, MotionUtensils, MotionWine };
|
|
40
|
+
export { MotionCalendar, MotionCalendarClock, MotionCompass, MotionFlame, MotionHouse, MotionLayoutGrid, MotionList, MotionMap, MotionMapPin, MotionUtensils, MotionWine };
|
|
@@ -87,6 +87,32 @@ function MotionUtensils(props) {
|
|
|
87
87
|
] })
|
|
88
88
|
] }));
|
|
89
89
|
}
|
|
90
|
+
var COMPASS_TIMES = [0, 0.14, 0.58, 0.76, 0.9, 1];
|
|
91
|
+
var compassNeedle = {
|
|
92
|
+
rest: { rotate: 360, fillOpacity: 0, transition: returnTransition },
|
|
93
|
+
active: { rotate: 360, fillOpacity: 1, transition: returnTransition },
|
|
94
|
+
play: {
|
|
95
|
+
rotate: [0, -24, 380, 352, 364, 360],
|
|
96
|
+
// The fill lands with the needle: it takes as the swing dies.
|
|
97
|
+
fillOpacity: [0, 0, 0, 0.6, 1, 1],
|
|
98
|
+
transition: beats(COMPASS_TIMES, 0.7)
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
function MotionCompass(props) {
|
|
102
|
+
return /* @__PURE__ */ jsxs(MotionIcon, __spreadProps(__spreadValues({}, props), { children: [
|
|
103
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
motion.path,
|
|
106
|
+
{
|
|
107
|
+
variants: compassNeedle,
|
|
108
|
+
style: pivot(12, 12),
|
|
109
|
+
fill: "currentColor",
|
|
110
|
+
fillOpacity: 0,
|
|
111
|
+
d: "m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
] }));
|
|
115
|
+
}
|
|
90
116
|
var PIN_TIMES = [0, 0.16, 0.44, 0.72, 1];
|
|
91
117
|
var pinBody = {
|
|
92
118
|
rest: { y: 0, scaleY: 1, transition: returnTransition },
|
|
@@ -339,4 +365,4 @@ function MotionList(props) {
|
|
|
339
365
|
] }));
|
|
340
366
|
}
|
|
341
367
|
|
|
342
|
-
export { MotionCalendar, MotionCalendarClock, MotionFlame, MotionHouse, MotionLayoutGrid, MotionList, MotionMap, MotionMapPin, MotionUtensils, MotionWine };
|
|
368
|
+
export { MotionCalendar, MotionCalendarClock, MotionCompass, MotionFlame, MotionHouse, MotionLayoutGrid, MotionList, MotionMap, MotionMapPin, MotionUtensils, MotionWine };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { Checkbox } from '../chunk-L3CDXVEP.js';
|
|
1
2
|
import { Popover, PopoverTrigger, PopoverContent } from '../chunk-2ADCZXZJ.js';
|
|
2
3
|
import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from '../chunk-MCOHLWRS.js';
|
|
3
4
|
import '../chunk-PDTPO6NG.js';
|
|
4
|
-
import {
|
|
5
|
-
import { Button } from '../chunk-5LTILG3L.js';
|
|
5
|
+
import { Button } from '../chunk-5HHRVJOT.js';
|
|
6
6
|
import '../chunk-RIH2IS7X.js';
|
|
7
7
|
import '../chunk-5YNIQ2BL.js';
|
|
8
|
-
import { Badge } from '../chunk-
|
|
8
|
+
import { Badge } from '../chunk-IEIJP73R.js';
|
|
9
9
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
10
10
|
import '../chunk-MMUBH76A.js';
|
|
11
11
|
import * as React from 'react';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PartyCounter — how many people, in the booking flow's "When are you
|
|
5
|
+
* coming?" and "Change party size" screens.
|
|
6
|
+
*
|
|
7
|
+
* Measured from the booking design (`.stepper`): a 52px bordered field on the
|
|
8
|
+
* card ground, 12px radius, 8px side inset. A round 36px minus on the muted
|
|
9
|
+
* surface at the left, a round 36px plus filled with `--gradient-primary` at
|
|
10
|
+
* the right — the plus is the direction the screen is asking about — and the
|
|
11
|
+
* count between them at 19px bold with its unit at 12px muted.
|
|
12
|
+
*
|
|
13
|
+
* At an end the button is disabled, not hidden, so the value never shifts.
|
|
14
|
+
* The value is announced politely on change; the buttons carry their own
|
|
15
|
+
* localised names, because a lone "−" reads as nothing to a screen reader.
|
|
16
|
+
*/
|
|
17
|
+
type PartyCounterLabels = {
|
|
18
|
+
/** "Fewer people" */
|
|
19
|
+
decrease: string;
|
|
20
|
+
/** "More people" */
|
|
21
|
+
increase: string;
|
|
22
|
+
/** The unit after the number: "people" / "person" — already pluralised by the caller. */
|
|
23
|
+
unit: (count: number) => string;
|
|
24
|
+
};
|
|
25
|
+
type PartyCounterProps = {
|
|
26
|
+
value: number;
|
|
27
|
+
onValueChange: (value: number) => void;
|
|
28
|
+
min?: number;
|
|
29
|
+
max?: number;
|
|
30
|
+
labels: PartyCounterLabels;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
className?: string;
|
|
33
|
+
};
|
|
34
|
+
declare function PartyCounter({ value, onValueChange, min, max, labels, disabled, className, }: PartyCounterProps): react_jsx_runtime.JSX.Element;
|
|
35
|
+
|
|
36
|
+
export { PartyCounter, type PartyCounterLabels, type PartyCounterProps };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
2
|
+
import '../chunk-MMUBH76A.js';
|
|
3
|
+
import { Minus, Plus } from 'lucide-react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function PartyCounter({
|
|
7
|
+
value,
|
|
8
|
+
onValueChange,
|
|
9
|
+
min = 1,
|
|
10
|
+
max = 20,
|
|
11
|
+
labels,
|
|
12
|
+
disabled,
|
|
13
|
+
className
|
|
14
|
+
}) {
|
|
15
|
+
const atMin = value <= min;
|
|
16
|
+
const atMax = value >= max;
|
|
17
|
+
const roundButton = "grid size-9 shrink-0 cursor-pointer place-items-center rounded-full transition-[filter,background-color,opacity] duration-150 motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card disabled:cursor-not-allowed disabled:opacity-40 [&_svg]:size-4";
|
|
18
|
+
return /* @__PURE__ */ jsxs(
|
|
19
|
+
"div",
|
|
20
|
+
{
|
|
21
|
+
"data-slot": "party-counter",
|
|
22
|
+
className: cn(
|
|
23
|
+
"flex h-[52px] items-center justify-between gap-2.5 rounded-xl border border-border bg-card px-2",
|
|
24
|
+
className
|
|
25
|
+
),
|
|
26
|
+
children: [
|
|
27
|
+
/* @__PURE__ */ jsx(
|
|
28
|
+
"button",
|
|
29
|
+
{
|
|
30
|
+
type: "button",
|
|
31
|
+
"aria-label": labels.decrease,
|
|
32
|
+
disabled: disabled || atMin,
|
|
33
|
+
onClick: () => onValueChange(Math.max(min, value - 1)),
|
|
34
|
+
className: cn(roundButton, "bg-surface-2 text-foreground hover:bg-muted"),
|
|
35
|
+
children: /* @__PURE__ */ jsx(Minus, { "aria-hidden": true })
|
|
36
|
+
}
|
|
37
|
+
),
|
|
38
|
+
/* @__PURE__ */ jsxs("output", { "aria-live": "polite", className: "flex-1 text-center", children: [
|
|
39
|
+
/* @__PURE__ */ jsx("b", { className: "text-[19px] font-bold tabular-nums text-foreground", children: value }),
|
|
40
|
+
/* @__PURE__ */ jsx("span", { className: "ml-1 text-xs text-muted-foreground", children: labels.unit(value) })
|
|
41
|
+
] }),
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
"button",
|
|
44
|
+
{
|
|
45
|
+
type: "button",
|
|
46
|
+
"aria-label": labels.increase,
|
|
47
|
+
disabled: disabled || atMax,
|
|
48
|
+
onClick: () => onValueChange(Math.min(max, value + 1)),
|
|
49
|
+
className: cn(
|
|
50
|
+
roundButton,
|
|
51
|
+
"bg-[image:var(--gradient-primary)] text-white hover:brightness-[0.94]"
|
|
52
|
+
),
|
|
53
|
+
children: /* @__PURE__ */ jsx(Plus, { "aria-hidden": true })
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { PartyCounter };
|
|
@@ -6,7 +6,7 @@ import { showsGradeAtom } from '../chunk-I5V446BX.js';
|
|
|
6
6
|
import { Separator } from '../chunk-NWZGSLPU.js';
|
|
7
7
|
import { springSnappy } from '../chunk-OIV7B44M.js';
|
|
8
8
|
import { Skeleton } from '../chunk-XBBEX4SF.js';
|
|
9
|
-
import { Badge } from '../chunk-
|
|
9
|
+
import { Badge } from '../chunk-IEIJP73R.js';
|
|
10
10
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
11
11
|
import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
|
|
12
12
|
import { forwardRef, memo, useState, useMemo } from 'react';
|
|
@@ -3,7 +3,7 @@ import '../chunk-FMTJGO76.js';
|
|
|
3
3
|
import '../chunk-MWB7S54O.js';
|
|
4
4
|
import '../chunk-NWZGSLPU.js';
|
|
5
5
|
import { Text } from '../chunk-ZLMRVBD7.js';
|
|
6
|
-
import { Badge } from '../chunk-
|
|
6
|
+
import { Badge } from '../chunk-IEIJP73R.js';
|
|
7
7
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
8
8
|
import '../chunk-MMUBH76A.js';
|
|
9
9
|
import { useState } from 'react';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { DriftRailLabels } from './drift-rail.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* PosterTape — the closing marquee: small 4:5 posters drifting past at a
|
|
@@ -13,18 +12,8 @@ import { DriftRailLabels } from './drift-rail.js';
|
|
|
13
12
|
type PosterTapeItem = {
|
|
14
13
|
id: string;
|
|
15
14
|
title: string;
|
|
16
|
-
/**
|
|
17
|
-
* Caller-composed, e.g. "Sat 5" — or "Sat 5 · 20:00" when `time` is not
|
|
18
|
-
* given. Rendered as mono, small, and truncated at the tape's width.
|
|
19
|
-
*/
|
|
15
|
+
/** Caller-composed, e.g. "Sat 5 · 20:00". Rendered as mono, small. */
|
|
20
16
|
meta: string;
|
|
21
|
-
/**
|
|
22
|
-
* The time, e.g. "20:00", rendered after `meta` and never truncated. The
|
|
23
|
-
* tape is 132px wide and a long localised date ("sâm., 5 sept. · 17:00")
|
|
24
|
-
* used to clip to "17:…" — the one figure the reader came for. Split it out
|
|
25
|
-
* and the date is what gives way.
|
|
26
|
-
*/
|
|
27
|
-
time?: string;
|
|
28
17
|
posterUrl?: string;
|
|
29
18
|
href?: string;
|
|
30
19
|
/** Rendered instead of the poster when it's absent or failed to load. Defaults to `<EventPosterFallback />`. */
|
|
@@ -40,10 +29,8 @@ type PosterTapeProps = {
|
|
|
40
29
|
/** Defaults to a plain `<a>`. Pass `next/link` in a Next app. */
|
|
41
30
|
linkComponent?: React.ComponentType<PosterTapeLinkProps>;
|
|
42
31
|
durationSeconds?: number;
|
|
43
|
-
/** Forwarded to `<DriftRail>`: names for its pause/play toggle, which renders only when given. */
|
|
44
|
-
labels?: DriftRailLabels;
|
|
45
32
|
className?: string;
|
|
46
33
|
};
|
|
47
|
-
declare function PosterTape({ items, linkComponent: LinkComponent, durationSeconds,
|
|
34
|
+
declare function PosterTape({ items, linkComponent: LinkComponent, durationSeconds, className, }: PosterTapeProps): react_jsx_runtime.JSX.Element;
|
|
48
35
|
|
|
49
36
|
export { PosterTape, type PosterTapeItem, type PosterTapeLinkProps, type PosterTapeProps };
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { DriftRail } from '../chunk-
|
|
2
|
-
import '../chunk-4OF4T4AI.js';
|
|
3
|
-
import '../chunk-L3VEMP5A.js';
|
|
1
|
+
import { DriftRail } from '../chunk-AHL45DD2.js';
|
|
4
2
|
import { EventPosterFallback } from '../chunk-FDITZ2VM.js';
|
|
5
3
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
6
4
|
import { __objRest, __spreadValues } from '../chunk-MMUBH76A.js';
|
|
@@ -36,13 +34,7 @@ function PosterTapeItemCard({
|
|
|
36
34
|
)
|
|
37
35
|
) : (_a = item.fallback) != null ? _a : /* @__PURE__ */ jsx(EventPosterFallback, {}) }),
|
|
38
36
|
/* @__PURE__ */ jsx("div", { className: "mt-1.5 text-[11px] font-semibold leading-[1.3] sm:mt-[7px] sm:text-[11.5px]", children: item.title }),
|
|
39
|
-
/* @__PURE__ */
|
|
40
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: item.meta }),
|
|
41
|
-
item.time && /* @__PURE__ */ jsxs("span", { className: "shrink-0", children: [
|
|
42
|
-
"\xB7 ",
|
|
43
|
-
item.time
|
|
44
|
-
] })
|
|
45
|
-
] })
|
|
37
|
+
/* @__PURE__ */ jsx("div", { className: "mt-0.5 truncate font-mono text-[10px] text-muted-foreground sm:text-[10.5px]", children: item.meta })
|
|
46
38
|
] });
|
|
47
39
|
const itemClasses = "block w-[132px] shrink-0";
|
|
48
40
|
if (item.href) {
|
|
@@ -64,10 +56,9 @@ function PosterTape({
|
|
|
64
56
|
items,
|
|
65
57
|
linkComponent: LinkComponent = DefaultLink,
|
|
66
58
|
durationSeconds = POSTER_TAPE_DEFAULT_DURATION_SECONDS,
|
|
67
|
-
labels,
|
|
68
59
|
className
|
|
69
60
|
}) {
|
|
70
|
-
return /* @__PURE__ */ jsx(DriftRail, { durationSeconds,
|
|
61
|
+
return /* @__PURE__ */ jsx(DriftRail, { durationSeconds, className, children: items.map((item) => /* @__PURE__ */ jsx(PosterTapeItemCard, { item, LinkComponent }, item.id)) });
|
|
71
62
|
}
|
|
72
63
|
|
|
73
64
|
export { PosterTape };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Popover, PopoverTrigger, PopoverContent } from '../chunk-2ADCZXZJ.js';
|
|
2
2
|
import { Command, CommandInput, CommandList, 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';
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
1
2
|
import * as React from 'react';
|
|
3
|
+
import { VariantProps } from 'class-variance-authority';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
declare const textareaVariants: (props?: ({
|
|
6
|
+
appearance?: "default" | "booking" | null | undefined;
|
|
7
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
8
|
+
type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> & VariantProps<typeof textareaVariants>;
|
|
9
|
+
declare const Textarea: React.ForwardRefExoticComponent<React.TextareaHTMLAttributes<HTMLTextAreaElement> & VariantProps<(props?: ({
|
|
10
|
+
appearance?: "default" | "booking" | null | undefined;
|
|
11
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLTextAreaElement>>;
|
|
5
12
|
|
|
6
|
-
export { Textarea, type TextareaProps };
|
|
13
|
+
export { Textarea, type TextareaProps, textareaVariants };
|