@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.
- package/README.md +73 -12
- package/dist/access.d.ts +0 -4
- package/dist/access.js +0 -5
- package/dist/api.d.ts +3 -1
- package/dist/api.js +5 -17
- package/dist/app.d.ts +20 -5
- package/dist/app.js +32 -2
- package/dist/blocks.d.ts +18 -0
- package/dist/blocks.js +36 -0
- package/dist/bookings.d.ts +400 -0
- package/dist/bookings.js +300 -0
- package/dist/bookingsMemory.d.ts +9 -0
- package/dist/bookingsMemory.js +79 -0
- package/dist/bookingsStore.d.ts +698 -0
- package/dist/bookingsStore.js +129 -0
- package/dist/cli/app.js +143 -59
- package/dist/cli/publishing.d.ts +3 -1
- package/dist/cli/publishing.js +33 -5
- package/dist/cli/starter.d.ts +17 -0
- package/dist/cli/starter.js +140 -0
- package/dist/components/Button.d.ts +2 -24
- package/dist/components/Button.js +4 -251
- package/dist/components/ButtonBody.d.ts +25 -0
- package/dist/components/ButtonBody.js +266 -0
- package/dist/components/Calendar.d.ts +20 -0
- package/dist/components/Calendar.js +195 -0
- package/dist/components/Card.d.ts +1 -1
- package/dist/components/Card.js +7 -29
- package/dist/components/Choice.js +27 -13
- package/dist/components/ChoiceGroup.d.ts +3 -1
- package/dist/components/ChoiceGroup.js +3 -4
- package/dist/components/ContinueWithGoogle.d.ts +11 -0
- package/dist/components/ContinueWithGoogle.js +5 -0
- package/dist/components/Dialog.d.ts +1 -1
- package/dist/components/Dialog.js +3 -1
- package/dist/components/Icon.js +1 -1
- package/dist/components/ListRow.js +2 -1
- package/dist/components/RadioGroup.d.ts +2 -1
- package/dist/components/RadioGroup.js +10 -2
- package/dist/components/Text.d.ts +1 -1
- package/dist/components/Text.js +43 -2
- package/dist/components/calendarDates.d.ts +14 -0
- package/dist/components/calendarDates.js +84 -0
- package/dist/components/controlLook.js +11 -11
- package/dist/components/icons.d.ts +9 -0
- package/dist/components/icons.js +17 -1
- package/dist/components/interaction.d.ts +1 -1
- package/dist/flows/browser.d.ts +7 -1
- package/dist/flows/browser.js +25 -7
- package/dist/flows/flowBrowser.d.ts +2 -2
- package/dist/flows/flowBrowser.js +2 -2
- package/dist/flows/flows.js +8 -2
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -0
- package/dist/media.d.ts +11 -1
- package/dist/patternAccess.d.ts +11 -2
- package/dist/patternAccess.js +8 -4
- package/dist/publishWire.d.ts +24 -2
- package/dist/publishWire.js +22 -2
- package/dist/react.d.ts +3 -0
- package/dist/react.js +2 -0
- package/dist/rules/checkAllFiles.js +16 -2
- package/dist/rules/lintPlugin.js +1 -0
- package/dist/schema.d.ts +3 -1
- package/dist/schema.js +1 -0
- package/dist/server/bookings.d.ts +12 -0
- package/dist/server/bookings.js +142 -0
- package/dist/server/createServer.d.ts +3 -2
- package/dist/server/createServer.js +13 -4
- package/dist/server/env.d.ts +8 -0
- package/dist/server/index.d.ts +3 -1
- package/dist/server/index.js +1 -0
- package/dist/server/media.d.ts +16 -3
- package/dist/server/media.js +72 -23
- package/dist/server/patternViewer.js +16 -10
- package/dist/server/tables.d.ts +2 -0
- package/dist/server/tables.js +17 -1
- package/dist/start.js +12 -0
- package/dist/table.js +9 -3
- package/dist/theme/scales.d.ts +1 -1
- package/dist/theme/scales.js +1 -0
- package/dist/theme/tokens.stylex.d.ts +18 -0
- package/dist/theme/tokens.stylex.js +19 -1
- package/dist/vite/localWorker.d.ts +2 -0
- package/dist/vite/localWorker.js +48 -3
- package/dist/vite/vite.js +5 -1
- 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;
|
package/dist/components/Card.js
CHANGED
|
@@ -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,
|
|
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 &&
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
86
|
+
fontSize: fontSizes.bodySm,
|
|
73
87
|
fontWeight: fontWeights.normal,
|
|
74
|
-
lineHeight: lineHeights.
|
|
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 {};
|