@trypattern/sdk 0.1.11 → 0.1.13

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.
Files changed (87) hide show
  1. package/README.md +73 -12
  2. package/dist/access.d.ts +0 -4
  3. package/dist/access.js +0 -5
  4. package/dist/api.d.ts +3 -1
  5. package/dist/api.js +5 -17
  6. package/dist/app.d.ts +20 -5
  7. package/dist/app.js +32 -2
  8. package/dist/blocks.d.ts +18 -0
  9. package/dist/blocks.js +36 -0
  10. package/dist/bookings.d.ts +400 -0
  11. package/dist/bookings.js +300 -0
  12. package/dist/bookingsMemory.d.ts +9 -0
  13. package/dist/bookingsMemory.js +79 -0
  14. package/dist/bookingsStore.d.ts +698 -0
  15. package/dist/bookingsStore.js +129 -0
  16. package/dist/cli/app.js +143 -59
  17. package/dist/cli/publishing.d.ts +3 -1
  18. package/dist/cli/publishing.js +33 -5
  19. package/dist/cli/starter.d.ts +17 -0
  20. package/dist/cli/starter.js +140 -0
  21. package/dist/components/Button.d.ts +2 -24
  22. package/dist/components/Button.js +4 -251
  23. package/dist/components/ButtonBody.d.ts +25 -0
  24. package/dist/components/ButtonBody.js +266 -0
  25. package/dist/components/Calendar.d.ts +20 -0
  26. package/dist/components/Calendar.js +195 -0
  27. package/dist/components/Card.d.ts +1 -1
  28. package/dist/components/Card.js +7 -29
  29. package/dist/components/Choice.js +27 -13
  30. package/dist/components/ChoiceGroup.d.ts +3 -1
  31. package/dist/components/ChoiceGroup.js +3 -4
  32. package/dist/components/ContinueWithGoogle.d.ts +11 -0
  33. package/dist/components/ContinueWithGoogle.js +5 -0
  34. package/dist/components/Dialog.d.ts +1 -1
  35. package/dist/components/Dialog.js +3 -1
  36. package/dist/components/Icon.js +1 -1
  37. package/dist/components/ListRow.js +2 -1
  38. package/dist/components/RadioGroup.d.ts +2 -1
  39. package/dist/components/RadioGroup.js +10 -2
  40. package/dist/components/Text.d.ts +1 -1
  41. package/dist/components/Text.js +43 -2
  42. package/dist/components/calendarDates.d.ts +14 -0
  43. package/dist/components/calendarDates.js +84 -0
  44. package/dist/components/controlLook.js +11 -11
  45. package/dist/components/icons.d.ts +9 -0
  46. package/dist/components/icons.js +17 -1
  47. package/dist/components/interaction.d.ts +1 -1
  48. package/dist/flows/browser.d.ts +7 -1
  49. package/dist/flows/browser.js +25 -7
  50. package/dist/flows/flowBrowser.d.ts +2 -2
  51. package/dist/flows/flowBrowser.js +2 -2
  52. package/dist/flows/flows.js +8 -2
  53. package/dist/index.d.ts +4 -1
  54. package/dist/index.js +1 -0
  55. package/dist/media.d.ts +11 -1
  56. package/dist/patternAccess.d.ts +11 -2
  57. package/dist/patternAccess.js +8 -4
  58. package/dist/publishWire.d.ts +24 -2
  59. package/dist/publishWire.js +22 -2
  60. package/dist/react.d.ts +3 -0
  61. package/dist/react.js +2 -0
  62. package/dist/rules/checkAllFiles.js +16 -2
  63. package/dist/rules/lintPlugin.js +1 -0
  64. package/dist/schema.d.ts +3 -1
  65. package/dist/schema.js +1 -0
  66. package/dist/server/bookings.d.ts +12 -0
  67. package/dist/server/bookings.js +142 -0
  68. package/dist/server/createServer.d.ts +3 -2
  69. package/dist/server/createServer.js +13 -4
  70. package/dist/server/env.d.ts +8 -0
  71. package/dist/server/index.d.ts +3 -1
  72. package/dist/server/index.js +1 -0
  73. package/dist/server/media.d.ts +16 -3
  74. package/dist/server/media.js +72 -23
  75. package/dist/server/patternViewer.js +16 -10
  76. package/dist/server/tables.d.ts +2 -0
  77. package/dist/server/tables.js +17 -1
  78. package/dist/start.js +12 -0
  79. package/dist/table.js +9 -3
  80. package/dist/theme/scales.d.ts +1 -1
  81. package/dist/theme/scales.js +1 -0
  82. package/dist/theme/tokens.stylex.d.ts +18 -0
  83. package/dist/theme/tokens.stylex.js +19 -1
  84. package/dist/vite/localWorker.d.ts +2 -0
  85. package/dist/vite/localWorker.js +48 -3
  86. package/dist/vite/vite.js +5 -1
  87. package/package.json +1 -1
@@ -0,0 +1,266 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button as BaseButton } from '@base-ui/react/button';
3
+ import { Link as RouterLink } from 'react-router';
4
+ import * as stylex from '@stylexjs/stylex';
5
+ import { colors, controls, fontWeights, iconSizes, motion, shadows } from "../theme/tokens.stylex.js";
6
+ import { controlSizes, focusRing } from "./controlLook.js";
7
+ import { Icon } from "./Icon.js";
8
+ import { interact, textOf } from "./interaction.js";
9
+ import { Kbd } from "./Kbd.js";
10
+ import { Spinner } from "./Spinner.js";
11
+ export function ButtonBody({ children, variant = 'primary', tone = variant === 'primary' ? 'brand' : 'neutral', size = 'md', to, href, icon, trailingIcon, shortcut, type = 'button', disabled = false, isPending = false, isFullWidth = false, onClick, style, isIconPinned = false }) {
12
+ const isDisabled = disabled || isPending;
13
+ const report = () => {
14
+ interact({ primitive: 'Button', event: 'click', label: textOf(children) });
15
+ onClick?.();
16
+ };
17
+ const className = stylex.props(styles.button, controlSizes[size], icon !== undefined && !isIconPinned && leadingIconSizes[size], trailingIcon !== undefined && trailingIconSizes[size], looks[`${variant}${toneKeys[tone]}`], !isDisabled && hovers[`${variant}${toneKeys[tone]}`], isDisabled && styles.disabled, isDisabled && variant === 'transparent' && styles.disabledTransparent, isFullWidth && styles.fullWidth, focusRing.visible, style).className;
18
+ const content = (_jsxs("span", { ...stylex.props(styles.stack), children: [_jsxs("span", { ...stylex.props(styles.content, isIconPinned && styles.pinnedContent, isPending && styles.hidden), children: [icon === undefined ? null : _jsx(Icon, { name: icon, size: size }), _jsx("span", { ...stylex.props(styles.label, shortcut !== undefined && styles.labelBeforeShortcut, isIconPinned && styles.labelBetweenPins), children: children }), isIconPinned ? (_jsx("span", { "aria-hidden": "true", ...stylex.props(pinBalances[size]) })) : null, trailingIcon === undefined ? null : (_jsx(Icon, { name: trailingIcon, size: size })), shortcut === undefined ? null : _jsx(Kbd, { keys: shortcut })] }), isPending ? (_jsx("span", { "aria-hidden": "true", ...stylex.props(styles.pending), children: _jsx(Spinner, { size: size }) })) : null] }));
19
+ if (href !== undefined) {
20
+ return (_jsx("a", { href: href, target: "_blank", rel: "noreferrer", onClick: report, className: className, children: content }));
21
+ }
22
+ if (to !== undefined) {
23
+ return (_jsx(RouterLink, { to: to, onClick: report, className: className, children: content }));
24
+ }
25
+ return (_jsx(BaseButton, { type: type, disabled: isDisabled, focusableWhenDisabled: true, "aria-busy": isPending || undefined, onClick: report, className: className, children: content }));
26
+ }
27
+ const toneKeys = {
28
+ neutral: 'Neutral',
29
+ brand: 'Brand',
30
+ danger: 'Danger'
31
+ };
32
+ const styles = stylex.create({
33
+ button: {
34
+ position: 'relative',
35
+ display: 'flex',
36
+ flexShrink: 0,
37
+ alignItems: 'center',
38
+ justifyContent: 'center',
39
+ minWidth: 0,
40
+ fontWeight: fontWeights.medium,
41
+ whiteSpace: 'nowrap',
42
+ textDecoration: 'none',
43
+ touchAction: 'manipulation',
44
+ outlineOffset: 0,
45
+ transitionTimingFunction: motion.easeOut,
46
+ transitionDuration: motion.fast,
47
+ transitionProperty: 'color, background-color, transform'
48
+ },
49
+ fullWidth: {
50
+ justifyContent: 'flex-start',
51
+ width: '100%'
52
+ },
53
+ stack: {
54
+ display: 'grid',
55
+ flexGrow: 1,
56
+ gridTemplateColumns: 'minmax(0, 1fr)',
57
+ gap: 'inherit',
58
+ justifyContent: 'inherit',
59
+ minWidth: 0,
60
+ overflow: 'clip'
61
+ },
62
+ content: {
63
+ display: 'flex',
64
+ gridRowStart: 1,
65
+ gridColumnStart: 1,
66
+ gap: 'inherit',
67
+ alignItems: 'center',
68
+ justifyContent: 'inherit',
69
+ minWidth: 0,
70
+ transitionTimingFunction: motion.easeOut,
71
+ transitionDuration: motion.base,
72
+ transitionProperty: 'opacity, transform'
73
+ },
74
+ hidden: {
75
+ opacity: 0,
76
+ transform: 'translateY(24px)'
77
+ },
78
+ pending: {
79
+ display: 'flex',
80
+ gridRowStart: 1,
81
+ gridColumnStart: 1,
82
+ alignItems: 'center',
83
+ justifyContent: 'center',
84
+ pointerEvents: 'none'
85
+ },
86
+ label: {
87
+ overflow: 'hidden',
88
+ textOverflow: 'ellipsis'
89
+ },
90
+ labelBeforeShortcut: {
91
+ flexGrow: 1,
92
+ textAlign: 'start'
93
+ },
94
+ pinnedContent: {
95
+ justifyContent: 'flex-start'
96
+ },
97
+ labelBetweenPins: {
98
+ flexGrow: 1,
99
+ textAlign: 'center'
100
+ },
101
+ disabled: {
102
+ color: colors.disabledForeground,
103
+ backgroundColor: colors.disabled,
104
+ boxShadow: 'none'
105
+ },
106
+ disabledTransparent: {
107
+ backgroundColor: 'transparent'
108
+ }
109
+ });
110
+ const leadingIconSizes = stylex.create({
111
+ xs: { paddingInlineStart: `calc(${controls.paddingXs} - 2px)` },
112
+ sm: { paddingInlineStart: `calc(${controls.paddingSm} - 2px)` },
113
+ md: { paddingInlineStart: `calc(${controls.paddingMd} - 4px)` },
114
+ lg: { paddingInlineStart: `calc(${controls.paddingLg} - 2px)` },
115
+ xl: { paddingInlineStart: `calc(${controls.paddingXl} - 4px)` }
116
+ });
117
+ const trailingIconSizes = stylex.create({
118
+ xs: { paddingInlineEnd: `calc(${controls.paddingXs} - 2px)` },
119
+ sm: { paddingInlineEnd: `calc(${controls.paddingSm} - 2px)` },
120
+ md: { paddingInlineEnd: `calc(${controls.paddingMd} - 4px)` },
121
+ lg: { paddingInlineEnd: `calc(${controls.paddingLg} - 2px)` },
122
+ xl: { paddingInlineEnd: `calc(${controls.paddingXl} - 4px)` }
123
+ });
124
+ const looks = stylex.create({
125
+ primaryNeutral: {
126
+ color: colors.onInvertedForeground,
127
+ backgroundColor: colors.invertedSolid
128
+ },
129
+ primaryBrand: {
130
+ color: colors.onBrandSolidForeground,
131
+ backgroundColor: colors.brandSolid
132
+ },
133
+ primaryDanger: {
134
+ color: colors.onDangerSolidForeground,
135
+ backgroundColor: colors.dangerSolid
136
+ },
137
+ secondaryNeutral: {
138
+ color: colors.primaryForeground,
139
+ backgroundColor: colors.componentOnContainerStrong,
140
+ boxShadow: shadows.default
141
+ },
142
+ secondaryBrand: {
143
+ color: colors.brandForeground,
144
+ backgroundColor: colors.componentOnContainerStrong,
145
+ boxShadow: shadows.default
146
+ },
147
+ secondaryDanger: {
148
+ color: colors.dangerForeground,
149
+ backgroundColor: colors.componentOnContainerStrong,
150
+ boxShadow: shadows.default
151
+ },
152
+ tertiaryNeutral: {
153
+ color: colors.secondaryForeground,
154
+ backgroundColor: colors.component
155
+ },
156
+ tertiaryBrand: {
157
+ color: colors.onBrandSubtleForeground,
158
+ backgroundColor: colors.brandSubtle
159
+ },
160
+ tertiaryDanger: {
161
+ color: colors.dangerForeground,
162
+ backgroundColor: colors.dangerSubtle
163
+ },
164
+ transparentNeutral: {
165
+ color: colors.secondaryForeground,
166
+ backgroundColor: 'transparent'
167
+ },
168
+ transparentBrand: {
169
+ color: colors.brandForeground,
170
+ backgroundColor: 'transparent'
171
+ },
172
+ transparentDanger: {
173
+ color: colors.dangerForeground,
174
+ backgroundColor: 'transparent'
175
+ }
176
+ });
177
+ const hovers = stylex.create({
178
+ primaryNeutral: {
179
+ backgroundColor: {
180
+ default: colors.invertedSolid,
181
+ ':hover': colors.invertedSolidHover,
182
+ ':active': colors.invertedSolidActive
183
+ }
184
+ },
185
+ primaryBrand: {
186
+ backgroundColor: {
187
+ default: colors.brandSolid,
188
+ ':hover': colors.brandSolidHover,
189
+ ':active': colors.brandSolidActive
190
+ }
191
+ },
192
+ primaryDanger: {
193
+ backgroundColor: {
194
+ default: colors.dangerSolid,
195
+ ':hover': colors.dangerSolidHover,
196
+ ':active': colors.dangerSolidActive
197
+ }
198
+ },
199
+ secondaryNeutral: {
200
+ backgroundColor: {
201
+ default: colors.componentOnContainerStrong,
202
+ ':hover': colors.componentOnContainerStrongHover
203
+ }
204
+ },
205
+ secondaryBrand: {
206
+ backgroundColor: {
207
+ default: colors.componentOnContainerStrong,
208
+ ':hover': colors.componentOnContainerStrongHover
209
+ }
210
+ },
211
+ secondaryDanger: {
212
+ backgroundColor: {
213
+ default: colors.componentOnContainerStrong,
214
+ ':hover': colors.componentOnContainerStrongHover
215
+ }
216
+ },
217
+ tertiaryNeutral: {
218
+ backgroundColor: {
219
+ default: colors.component,
220
+ ':hover': colors.componentHover,
221
+ ':active': colors.componentActive
222
+ }
223
+ },
224
+ tertiaryBrand: {
225
+ backgroundColor: {
226
+ default: colors.brandSubtle,
227
+ ':hover': colors.brandSubtleHover
228
+ }
229
+ },
230
+ tertiaryDanger: {
231
+ backgroundColor: {
232
+ default: colors.dangerSubtle,
233
+ ':hover': colors.dangerSubtleHover,
234
+ ':active': colors.dangerSubtleActive
235
+ }
236
+ },
237
+ transparentNeutral: {
238
+ color: {
239
+ default: colors.secondaryForeground,
240
+ ':hover': colors.primaryForeground
241
+ },
242
+ backgroundColor: {
243
+ default: 'transparent',
244
+ ':hover': colors.transparentHover
245
+ }
246
+ },
247
+ transparentBrand: {
248
+ backgroundColor: {
249
+ default: 'transparent',
250
+ ':hover': colors.transparentHover
251
+ }
252
+ },
253
+ transparentDanger: {
254
+ backgroundColor: {
255
+ default: 'transparent',
256
+ ':hover': colors.dangerSubtleHover
257
+ }
258
+ }
259
+ });
260
+ const pinBalances = stylex.create({
261
+ xs: { flexShrink: 0, width: iconSizes.xs },
262
+ sm: { flexShrink: 0, width: iconSizes.sm },
263
+ md: { flexShrink: 0, width: iconSizes.md },
264
+ lg: { flexShrink: 0, width: iconSizes.lg },
265
+ xl: { flexShrink: 0, width: iconSizes.xl }
266
+ });
@@ -0,0 +1,20 @@
1
+ import type { Placement } from './Placement.ts';
2
+ export type CalendarDay = {
3
+ date: string;
4
+ state: 'open' | 'closed' | 'full';
5
+ };
6
+ type CalendarProps = {
7
+ label: string;
8
+ month: string;
9
+ onMonthChange: (month: string) => void;
10
+ days: readonly CalendarDay[];
11
+ value: string | null;
12
+ onPick: (date: string) => void;
13
+ firstMonth?: string;
14
+ lastMonth?: string;
15
+ today?: string;
16
+ locale?: string;
17
+ style?: Placement;
18
+ };
19
+ export declare function Calendar({ label, month, onMonthChange, days, value, onPick, firstMonth, lastMonth, today, locale, style }: CalendarProps): import("react").JSX.Element;
20
+ export {};
@@ -0,0 +1,195 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button as BaseButton } from '@base-ui/react/button';
3
+ import * as stylex from '@stylexjs/stylex';
4
+ import { useEffect, useRef, useState } from 'react';
5
+ import { borders, colors, controls, fontSizes, fontWeights, lineHeights, motion, radii, space } from "../theme/tokens.stylex.js";
6
+ import { addDays, addMonths, dayLabel, dayNumber, localToday, monthOf, monthTitle, weekdayIndex, weekdayNames, weeksOf } from "./calendarDates.js";
7
+ import { focusRing } from "./controlLook.js";
8
+ import { Icon } from "./Icon.js";
9
+ import { interact } from "./interaction.js";
10
+ export function Calendar({ label, month, onMonthChange, days, value, onPick, firstMonth, lastMonth, today = localToday(), locale, style }) {
11
+ const states = new Map(days.map((day) => [day.date, day.state]));
12
+ const [moved, setMoved] = useState(null);
13
+ const grid = useRef(null);
14
+ const shouldFocus = useRef(false);
15
+ const focused = moved !== null && monthOf(moved) === month
16
+ ? moved
17
+ : startingFocus(month, value, today, states);
18
+ const previous = addMonths(`${month}-01`, -1).slice(0, 7);
19
+ const next = addMonths(`${month}-01`, 1).slice(0, 7);
20
+ const canGoBack = firstMonth === undefined || previous >= firstMonth;
21
+ const canGoOn = lastMonth === undefined || next <= lastMonth;
22
+ useEffect(() => {
23
+ if (!shouldFocus.current)
24
+ return;
25
+ shouldFocus.current = false;
26
+ grid.current
27
+ ?.querySelector(`[data-date="${focused}"]`)
28
+ ?.focus();
29
+ });
30
+ const goTo = (target) => {
31
+ interact({
32
+ primitive: 'Calendar',
33
+ event: 'change',
34
+ label: `${label}: ${monthTitle(target, locale)}`
35
+ });
36
+ onMonthChange(target);
37
+ };
38
+ const pick = (date) => {
39
+ if ((states.get(date) ?? 'closed') !== 'open')
40
+ return;
41
+ interact({ primitive: 'Calendar', event: 'select', label });
42
+ onPick(date);
43
+ };
44
+ const move = (event, date) => {
45
+ const step = MOVES[event.key];
46
+ if (step === undefined)
47
+ return;
48
+ event.preventDefault();
49
+ const target = step(date);
50
+ const targetMonth = monthOf(target);
51
+ if (firstMonth !== undefined && targetMonth < firstMonth)
52
+ return;
53
+ if (lastMonth !== undefined && targetMonth > lastMonth)
54
+ return;
55
+ setMoved(target);
56
+ shouldFocus.current = true;
57
+ if (targetMonth !== month)
58
+ goTo(targetMonth);
59
+ };
60
+ return (_jsxs("div", { ...stylex.props(styles.calendar, style), children: [_jsxs("div", { ...stylex.props(styles.header), children: [_jsx("span", { ...stylex.props(styles.title), "aria-live": "polite", children: monthTitle(month, locale) }), _jsxs("span", { ...stylex.props(styles.nav), children: [_jsx(BaseButton, { "aria-label": monthTitle(previous, locale), disabled: !canGoBack, onClick: () => goTo(previous), className: stylex.props(styles.navButton, canGoBack ? styles.navEnabled : styles.navDisabled, focusRing.visible).className, children: _jsx(Icon, { name: "previous" }) }), _jsx(BaseButton, { "aria-label": monthTitle(next, locale), disabled: !canGoOn, onClick: () => goTo(next), className: stylex.props(styles.navButton, canGoOn ? styles.navEnabled : styles.navDisabled, focusRing.visible).className, children: _jsx(Icon, { name: "next" }) })] })] }), _jsxs("div", { ref: grid, role: "grid", "aria-label": `${label}, ${monthTitle(month, locale)}`, ...stylex.props(styles.grid), children: [_jsx("div", { role: "row", ...stylex.props(styles.row), children: weekdayNames(locale).map((weekday) => (_jsx("span", { role: "columnheader", "aria-label": weekday.long, ...stylex.props(styles.weekday), children: weekday.short }, weekday.long))) }), weeksOf(month).map((week, index) => (_jsx("div", { role: "row", ...stylex.props(styles.row), children: week.map((date, column) => {
61
+ if (date === null) {
62
+ return (_jsx("span", { role: "gridcell", ...stylex.props(styles.cell) }, `blank-${column}`));
63
+ }
64
+ const state = states.get(date) ?? 'closed';
65
+ const isOpen = state === 'open';
66
+ const isPicked = date === value;
67
+ return (_jsx("span", { role: "gridcell", "aria-selected": isPicked, ...stylex.props(styles.cell), children: _jsx("button", { type: "button", "data-date": date, tabIndex: date === focused ? 0 : -1, "aria-label": dayLabel(date, locale), "aria-disabled": !isOpen, "aria-current": date === today ? 'date' : undefined, onClick: () => pick(date), onKeyDown: (event) => move(event, date), ...stylex.props(styles.day, isOpen && styles.open, !isOpen && styles.unavailable, state === 'full' && styles.full, date === today && !isPicked && styles.today, isPicked && styles.picked, focusRing.visible), children: dayNumber(date, locale) }) }, date));
68
+ }) }, week.find((date) => date !== null) ?? index)))] })] }));
69
+ }
70
+ const MOVES = {
71
+ ArrowLeft: (date) => addDays(date, -1),
72
+ ArrowRight: (date) => addDays(date, 1),
73
+ ArrowUp: (date) => addDays(date, -7),
74
+ ArrowDown: (date) => addDays(date, 7),
75
+ Home: (date) => addDays(date, -weekdayIndex(date)),
76
+ End: (date) => addDays(date, 6 - weekdayIndex(date)),
77
+ PageUp: (date) => addMonths(date, -1),
78
+ PageDown: (date) => addMonths(date, 1)
79
+ };
80
+ function startingFocus(month, value, today, states) {
81
+ if (value !== null && monthOf(value) === month)
82
+ return value;
83
+ if (monthOf(today) === month)
84
+ return today;
85
+ const open = [...states].find(([date, state]) => monthOf(date) === month && state === 'open');
86
+ return open?.[0] ?? `${month}-01`;
87
+ }
88
+ const styles = stylex.create({
89
+ calendar: {
90
+ display: 'flex',
91
+ flexDirection: 'column',
92
+ gap: space.xxs,
93
+ width: `calc(7 * (${space.xxxl} - ${space.xs}))`
94
+ },
95
+ header: {
96
+ display: 'flex',
97
+ alignItems: 'center',
98
+ justifyContent: 'space-between',
99
+ paddingInline: space.xs,
100
+ paddingBottom: space.sm
101
+ },
102
+ title: {
103
+ fontSize: fontSizes.bodyBase,
104
+ fontWeight: fontWeights.medium,
105
+ lineHeight: lineHeights.body,
106
+ color: colors.primaryForeground
107
+ },
108
+ nav: {
109
+ display: 'flex',
110
+ gap: space.xs
111
+ },
112
+ navButton: {
113
+ display: 'flex',
114
+ flexShrink: 0,
115
+ alignItems: 'center',
116
+ justifyContent: 'center',
117
+ width: controls.heightMd,
118
+ height: controls.heightMd,
119
+ outlineOffset: 0,
120
+ borderRadius: radii.full,
121
+ transitionTimingFunction: motion.easeOut,
122
+ transitionDuration: motion.fast,
123
+ transitionProperty: 'color, background-color'
124
+ },
125
+ navEnabled: {
126
+ color: colors.primaryForeground,
127
+ backgroundColor: {
128
+ default: 'transparent',
129
+ ':hover': colors.transparentHover
130
+ }
131
+ },
132
+ navDisabled: {
133
+ color: colors.disabledForeground
134
+ },
135
+ grid: {
136
+ display: 'flex',
137
+ flexDirection: 'column',
138
+ gap: space.xxs
139
+ },
140
+ row: {
141
+ display: 'grid',
142
+ gridTemplateColumns: `repeat(7, calc(${space.xxxl} - ${space.xs}))`
143
+ },
144
+ weekday: {
145
+ display: 'flex',
146
+ alignItems: 'center',
147
+ justifyContent: 'center',
148
+ height: controls.heightMd,
149
+ fontSize: fontSizes.captionLg,
150
+ lineHeight: lineHeights.bodySm,
151
+ color: colors.secondaryForeground,
152
+ textAlign: 'center'
153
+ },
154
+ cell: {
155
+ display: 'flex',
156
+ width: `calc(${space.xxxl} - ${space.xs})`,
157
+ height: `calc(${space.xxxl} - ${space.xs})`
158
+ },
159
+ day: {
160
+ display: 'flex',
161
+ alignItems: 'center',
162
+ justifyContent: 'center',
163
+ width: '100%',
164
+ height: '100%',
165
+ fontSize: fontSizes.bodyMd,
166
+ lineHeight: lineHeights.bodySm,
167
+ outlineOffset: 0,
168
+ borderRadius: radii.full,
169
+ transitionTimingFunction: motion.easeOut,
170
+ transitionDuration: motion.fast,
171
+ transitionProperty: 'color, background-color'
172
+ },
173
+ open: {
174
+ color: colors.primaryForeground,
175
+ backgroundColor: {
176
+ default: 'transparent',
177
+ ':hover': colors.transparentHover
178
+ }
179
+ },
180
+ unavailable: {
181
+ color: colors.disabledForeground
182
+ },
183
+ full: {
184
+ textDecorationLine: 'line-through',
185
+ textDecorationThickness: borders.thin
186
+ },
187
+ today: {
188
+ boxShadow: `inset 0 0 0 ${borders.thin} ${colors.borderStrong}`
189
+ },
190
+ picked: {
191
+ fontWeight: fontWeights.medium,
192
+ color: colors.onInvertedForeground,
193
+ backgroundColor: colors.invertedSolid
194
+ }
195
+ });
@@ -2,7 +2,7 @@ import type { ReactNode } from 'react';
2
2
  import type { AppPath } from '../registered.ts';
3
3
  import type { Placement } from './Placement.ts';
4
4
  type CardPadding = 'none' | 'sm' | 'md' | 'lg';
5
- type CardSurface = 'subtle' | 'strong' | 'container';
5
+ type CardSurface = 'subtle' | 'strong' | 'container' | 'none';
6
6
  type CardProps = {
7
7
  children: ReactNode;
8
8
  surface?: CardSurface;
@@ -2,12 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Button as BaseButton } from '@base-ui/react/button';
3
3
  import * as stylex from '@stylexjs/stylex';
4
4
  import { Link as RouterLink } from 'react-router';
5
- import { colors, motion, radii, shadows, space } from "../theme/tokens.stylex.js";
5
+ import { colors, radii, shadows, space } from "../theme/tokens.stylex.js";
6
6
  import { focusRing } from "./controlLook.js";
7
7
  import { interact, textOf } from "./interaction.js";
8
8
  export function Card({ children, surface = 'subtle', padding = 'lg', paddingBlock, to, href, onClick, style }) {
9
9
  const isInteractive = to !== undefined || href !== undefined || onClick !== undefined;
10
- const className = stylex.props(styles.card, surfaces[surface], paddings[padding], paddingBlock !== undefined && paddingBlocks[paddingBlock], isInteractive && styles.interactive, isInteractive && hovers[surface], isInteractive && focusRing.visible, style).className;
10
+ const className = stylex.props(styles.card, surfaces[surface], paddings[padding], paddingBlock !== undefined && paddingBlocks[paddingBlock], isInteractive && styles.interactive, isInteractive && focusRing.visible, style).className;
11
11
  const report = (event) => {
12
12
  interact({
13
13
  primitive: 'Card',
@@ -39,14 +39,7 @@ const styles = stylex.create({
39
39
  color: 'inherit',
40
40
  textAlign: 'start',
41
41
  textDecoration: 'none',
42
- outlineOffset: 0,
43
- boxShadow: {
44
- default: shadows.default,
45
- ':hover': shadows.large
46
- },
47
- transitionTimingFunction: motion.easeOut,
48
- transitionDuration: motion.fast,
49
- transitionProperty: 'background-color, box-shadow'
42
+ outlineOffset: 0
50
43
  }
51
44
  });
52
45
  const surfaces = stylex.create({
@@ -58,26 +51,11 @@ const surfaces = stylex.create({
58
51
  },
59
52
  container: {
60
53
  backgroundColor: colors.container
61
- }
62
- });
63
- const hovers = stylex.create({
64
- subtle: {
65
- backgroundColor: {
66
- default: colors.componentOnContainerSubtle,
67
- ':hover': colors.componentOnContainerSubtleHover
68
- }
69
54
  },
70
- strong: {
71
- backgroundColor: {
72
- default: colors.componentOnContainerStrong,
73
- ':hover': colors.componentOnContainerStrongHover
74
- }
75
- },
76
- container: {
77
- backgroundColor: {
78
- default: colors.container,
79
- ':hover': colors.componentOnContainerStrongHover
80
- }
55
+ none: {
56
+ overflow: 'visible',
57
+ borderRadius: 0,
58
+ boxShadow: 'none'
81
59
  }
82
60
  });
83
61
  const paddings = stylex.create({
@@ -8,36 +8,37 @@ export function Choice({ value, title, label, subline, isDisabled = false, child
8
8
  const chosen = useChosen();
9
9
  const isFaded = chosen !== null && chosen !== value;
10
10
  const hasWords = title !== undefined || subline !== undefined;
11
- return (_jsxs(BaseRadio.Root, { value: value, disabled: isDisabled, "aria-label": label, className: (state) => stylex.props(styles.choice, children !== undefined && !hasWords && styles.media, !state.disabled && styles.enabled, state.checked && styles.checked, isFaded && !state.checked && !state.disabled && styles.faded, state.disabled && styles.disabled, focusRing.visible).className, children: [children === undefined ? null : (_jsx("span", { ...stylex.props(styles.content), children: children })), title === undefined ? null : (_jsx("span", { ...stylex.props(styles.title), children: title })), subline === undefined ? null : (_jsx("span", { ...stylex.props(styles.subline, isDisabled && styles.sublineDisabled), children: subline }))] }));
11
+ const isPhoto = children !== undefined && !hasWords;
12
+ return (_jsxs(BaseRadio.Root, { value: value, disabled: isDisabled, "aria-label": label, className: (state) => stylex.props(styles.choice, !state.disabled && styles.enabled, state.checked && styles.checked, isPhoto &&
13
+ isFaded &&
14
+ !state.checked &&
15
+ !state.disabled &&
16
+ styles.faded, state.disabled && styles.disabled, isPhoto && styles.photo, focusRing.visible).className, children: [children === undefined ? null : (_jsx("span", { ...stylex.props(styles.content, isPhoto && styles.photoContent), children: children })), title === undefined ? null : (_jsx("span", { ...stylex.props(styles.title), children: title })), subline === undefined ? null : (_jsx("span", { ...stylex.props(styles.subline, isDisabled && styles.sublineDisabled), children: subline }))] }));
12
17
  }
13
18
  const checkedRing = `inset 0 0 0 ${borders.thin} ${colors.borderInverted}, 0 0 0 ${borders.thin} ${colors.borderInverted}`;
14
19
  const styles = stylex.create({
15
20
  choice: {
16
21
  display: 'flex',
22
+ flexGrow: 1,
23
+ flexBasis: `calc(2 * ${space.xxxl})`,
17
24
  flexDirection: 'column',
18
- gap: space.xxs,
19
25
  alignItems: 'flex-start',
20
26
  minWidth: 0,
21
- paddingBlock: space.sm,
27
+ paddingBlock: `calc(${space.sm} + ${space.xxs})`,
22
28
  paddingInline: space.md,
23
- fontSize: fontSizes.bodySm,
29
+ fontSize: fontSizes.bodyMd,
24
30
  fontWeight: fontWeights.medium,
25
31
  lineHeight: lineHeights.bodySm,
26
32
  color: colors.primaryForeground,
27
33
  textAlign: 'start',
28
34
  outlineOffset: 0,
29
35
  backgroundColor: colors.componentOnContainerStrong,
30
- borderRadius: radii.lg,
36
+ borderRadius: radii.xl,
31
37
  boxShadow: shadows.default,
32
38
  transitionTimingFunction: motion.easeOut,
33
39
  transitionDuration: motion.fast,
34
40
  transitionProperty: 'background-color, box-shadow, opacity'
35
41
  },
36
- media: {
37
- flexShrink: 0,
38
- width: `calc(2 * ${space.xxxl})`,
39
- padding: space.xs
40
- },
41
42
  enabled: {
42
43
  backgroundColor: {
43
44
  default: colors.componentOnContainerStrong,
@@ -49,10 +50,20 @@ const styles = stylex.create({
49
50
  },
50
51
  faded: {
51
52
  opacity: {
52
- default: 0.56,
53
+ default: 0.5,
53
54
  ':hover': 1
54
55
  }
55
56
  },
57
+ photo: {
58
+ flexGrow: 1,
59
+ flexBasis: 0,
60
+ paddingBlock: 0,
61
+ paddingInline: 0,
62
+ overflow: 'hidden',
63
+ backgroundColor: 'transparent',
64
+ borderRadius: radii.lg,
65
+ boxShadow: 'none'
66
+ },
56
67
  disabled: {
57
68
  color: colors.disabledForeground,
58
69
  backgroundColor: colors.disabled,
@@ -65,13 +76,16 @@ const styles = stylex.create({
65
76
  overflow: 'hidden',
66
77
  borderRadius: radii.md
67
78
  },
79
+ photoContent: {
80
+ borderRadius: radii.lg
81
+ },
68
82
  title: {
69
83
  minWidth: 0
70
84
  },
71
85
  subline: {
72
- fontSize: fontSizes.captionLg,
86
+ fontSize: fontSizes.bodySm,
73
87
  fontWeight: fontWeights.normal,
74
- lineHeight: lineHeights.caption,
88
+ lineHeight: lineHeights.bodySm,
75
89
  color: colors.secondaryForeground
76
90
  },
77
91
  sublineDisabled: {
@@ -1,11 +1,13 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { Placement } from './Placement.ts';
3
+ import type { SpaceName } from './spacing.ts';
3
4
  type ChoiceGroupProps<Value extends string> = {
4
5
  label: string;
5
6
  value: Value | null;
6
7
  onChange: (value: Value) => void;
7
8
  children: ReactNode;
9
+ gap?: SpaceName;
8
10
  style?: Placement;
9
11
  };
10
- export declare function ChoiceGroup<Value extends string>({ label, value, onChange, children, style }: ChoiceGroupProps<Value>): import("react").JSX.Element;
12
+ export declare function ChoiceGroup<Value extends string>({ label, value, onChange, children, gap, style }: ChoiceGroupProps<Value>): import("react").JSX.Element;
11
13
  export {};