@astryxdesign/cli 0.7.12-canary.9a690d5 → 0.7.12-canary.f543ec7

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.
@@ -247,9 +247,9 @@ useAutoMediaMode useAutoMediaMode hooks/useAnimatedLayout.doc.mjs hooks/useAutoM
247
247
  useBackdropPress useBackdropPress Layer/Layer.doc.mjs Layer/useBackdropPress.ts
248
248
  useBaseTablePlugins useBaseTablePlugins Table/Table.doc.mjs Table/useBaseTablePlugins.ts
249
249
  useBusyAnnouncement useBusyAnnouncement hooks/useAnimatedLayout.doc.mjs hooks/useBusyAnnouncement.ts
250
- useCalendarConstraints useCalendarConstraints Calendar/Calendar.doc.mjs Calendar/hooks/useCalendarConstraints.ts
250
+ useCalendarConstraints useCalendarConstraints Calendar/useCalendarConstraints.doc.mjs Calendar/hooks/useCalendarConstraints.ts
251
251
  useCalendarDays useCalendarDays Calendar/useCalendarDays.doc.mjs Calendar/hooks/useCalendarDays.ts
252
- useCalendarNavigation useCalendarNavigation Calendar/Calendar.doc.mjs Calendar/hooks/useCalendarNavigation.ts
252
+ useCalendarNavigation useCalendarNavigation Calendar/useCalendarNavigation.doc.mjs Calendar/hooks/useCalendarNavigation.ts
253
253
  useChatComposerTokens useChatComposerTokens Chat/Chat.doc.mjs Chat/useChatComposerTokens.ts
254
254
  useChatDictation useChatDictation Chat/Chat.doc.mjs Chat/useChatDictation.ts
255
255
  useChatNewMessages useChatNewMessages Chat/Chat.doc.mjs Chat/useChatNewMessages.ts
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('@astryxdesign/cli/authoring').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'useCalendarConstraints',
7
+ name: 'useCalendarConstraints — Hotel Booking Range',
8
+ displayName: 'useCalendarConstraints — Hotel Booking Range',
9
+ description:
10
+ 'A hotel booking range picker enforcing season min/max dates, a 7-night maximum stay once check-in is picked, and a custom rule disabling closed Mondays.',
11
+ isReady: true,
12
+ aspectRatio: 4 / 3,
13
+ componentsUsed: ['Button', 'Layout', 'Text'],
14
+ };
@@ -0,0 +1,146 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {useState} from 'react';
6
+ import {
7
+ useCalendarConstraints,
8
+ useCalendarDays,
9
+ type CalendarDay,
10
+ } from '@astryxdesign/core/Calendar';
11
+ import {Button} from '@astryxdesign/core/Button';
12
+ import {HStack, VStack} from '@astryxdesign/core/Layout';
13
+ import {Text} from '@astryxdesign/core/Text';
14
+
15
+ // Hotel closed on Mondays (day === 1)
16
+ const isNotMonday = (date: Date) => date.getDay() !== 1;
17
+
18
+ export default function UseCalendarConstraintsHookUsage() {
19
+ const [checkIn, setCheckIn] = useState<CalendarDay['date'] | null>(null);
20
+ const [checkOut, setCheckOut] = useState<CalendarDay['date'] | null>(null);
21
+
22
+ // June 2026 season: open Jun 5 – Jun 25, max 7 nights (8-day span), closed Mondays.
23
+ // When checkOut is already chosen, clear rangeAnchor so full season remains viewable without lingering span restrictions.
24
+ const {isDateDisabled} = useCalendarConstraints({
25
+ min: '2026-06-05',
26
+ max: '2026-06-25',
27
+ maxRangeSpan: 8,
28
+ rangeAnchor: checkOut ? null : checkIn,
29
+ dateConstraints: [isNotMonday],
30
+ });
31
+
32
+ const {weeks, dayNames} = useCalendarDays({
33
+ year: 2026,
34
+ month: 6,
35
+ weekStartsOn: 0,
36
+ hasVariableRowCount: true,
37
+ });
38
+
39
+ const handleSelect = (day: CalendarDay) => {
40
+ if (day.isOutside || isDateDisabled(day.date)) {
41
+ return;
42
+ }
43
+ // If no check-in yet, or already booked, or clicking on/before current check-in: start new check-in
44
+ if (!checkIn || checkOut || day.date.day <= checkIn.day) {
45
+ setCheckIn(day.date);
46
+ setCheckOut(null);
47
+ } else {
48
+ // Pick is after checkIn: set as check-out
49
+ setCheckOut(day.date);
50
+ }
51
+ };
52
+
53
+ const handleReset = () => {
54
+ setCheckIn(null);
55
+ setCheckOut(null);
56
+ };
57
+
58
+ return (
59
+ <VStack gap={3}>
60
+ <VStack gap={1}>
61
+ <Text type="body" weight="bold">
62
+ Hotel Booking — June 2026
63
+ </Text>
64
+ <Text type="supporting" color="secondary">
65
+ Season: Jun 5 – Jun 25 · Max stay: 7 nights · Closed Mondays
66
+ </Text>
67
+ </VStack>
68
+ <HStack gap={2} vAlign="center">
69
+ <Text type="supporting">
70
+ {checkIn
71
+ ? checkOut
72
+ ? `Booked: Jun ${checkIn.day} – Jun ${checkOut.day}`
73
+ : `Check-in: Jun ${checkIn.day} (pick check-out)`
74
+ : 'Pick a check-in date'}
75
+ </Text>
76
+ {checkIn && (
77
+ <Button
78
+ label="Reset"
79
+ size="sm"
80
+ variant="secondary"
81
+ onClick={handleReset}
82
+ />
83
+ )}
84
+ </HStack>
85
+ <table style={{tableLayout: 'fixed', width: 280}}>
86
+ <thead>
87
+ <tr>
88
+ {dayNames.map((name, i) => (
89
+ <th key={i} scope="col">
90
+ <Text type="supporting" color="secondary">
91
+ {name}
92
+ </Text>
93
+ </th>
94
+ ))}
95
+ </tr>
96
+ </thead>
97
+ <tbody>
98
+ {weeks.map(week => (
99
+ <tr key={week[0].iso}>
100
+ {week.map(day => {
101
+ if (day.isOutside) {
102
+ return <td key={day.iso} align="center" />;
103
+ }
104
+
105
+ const disabled = isDateDisabled(day.date);
106
+ const isSelected =
107
+ (checkIn &&
108
+ checkIn.day === day.date.day &&
109
+ checkIn.month === day.date.month) ||
110
+ (checkOut &&
111
+ checkOut.day === day.date.day &&
112
+ checkOut.month === day.date.month);
113
+
114
+ return (
115
+ <td key={day.iso} align="center">
116
+ <button
117
+ type="button"
118
+ disabled={disabled}
119
+ onClick={() => handleSelect(day)}
120
+ aria-pressed={isSelected ? 'true' : 'false'}
121
+ aria-label={`June ${day.dayNumber}`}
122
+ style={{
123
+ width: 32,
124
+ height: 32,
125
+ borderRadius: 6,
126
+ border: isSelected ? '1px solid currentColor' : 'none',
127
+ background: 'transparent',
128
+ opacity: disabled ? 0.35 : 1,
129
+ cursor: disabled ? 'not-allowed' : 'pointer',
130
+ }}>
131
+ <Text
132
+ type="body"
133
+ color={disabled ? 'secondary' : 'primary'}>
134
+ {day.dayNumber}
135
+ </Text>
136
+ </button>
137
+ </td>
138
+ );
139
+ })}
140
+ </tr>
141
+ ))}
142
+ </tbody>
143
+ </table>
144
+ </VStack>
145
+ );
146
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('@astryxdesign/cli/authoring').TemplateDoc} */
4
+ export const doc = {
5
+ type: 'block',
6
+ exampleFor: 'useCalendarNavigation',
7
+ name: 'useCalendarNavigation — Month Pager',
8
+ displayName: 'useCalendarNavigation — Month Pager',
9
+ description:
10
+ 'A calendar month pager with previous/next navigation buttons, localized month-year label, and cross-month arrow key navigation using pendingFocus.',
11
+ isReady: true,
12
+ aspectRatio: 4 / 3,
13
+ componentsUsed: ['Button', 'Layout', 'Text'],
14
+ };
@@ -0,0 +1,173 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ import {useEffect, useRef, useState} from 'react';
6
+ import {
7
+ useCalendarDays,
8
+ useCalendarNavigation,
9
+ type CalendarDay,
10
+ type ISODateString,
11
+ } from '@astryxdesign/core/Calendar';
12
+ import {Button} from '@astryxdesign/core/Button';
13
+ import {HStack, VStack} from '@astryxdesign/core/Layout';
14
+ import {Text} from '@astryxdesign/core/Text';
15
+
16
+ export default function UseCalendarNavigationHookUsage() {
17
+ const [focusDate, setFocusDate] = useState<ISODateString>(
18
+ '2026-06-01' as ISODateString,
19
+ );
20
+
21
+ const {
22
+ monthYearLabel,
23
+ visibleCalendarMonths,
24
+ navigateMonth,
25
+ pendingFocus,
26
+ clearPendingFocus,
27
+ } = useCalendarNavigation({
28
+ focusDate,
29
+ onFocusDateChange: setFocusDate,
30
+ numberOfMonths: 1,
31
+ });
32
+
33
+ const {weeks, dayNames} = useCalendarDays({
34
+ ...visibleCalendarMonths[0],
35
+ weekStartsOn: 0,
36
+ hasVariableRowCount: true,
37
+ });
38
+
39
+ const dayButtonRefs = useRef<Map<string, HTMLButtonElement>>(new Map());
40
+
41
+ // Move focus to target date when navigating across month boundaries
42
+ useEffect(() => {
43
+ if (pendingFocus) {
44
+ const el = dayButtonRefs.current.get(pendingFocus);
45
+ if (el) {
46
+ el.focus();
47
+ clearPendingFocus();
48
+ }
49
+ }
50
+ }, [pendingFocus, clearPendingFocus, weeks]);
51
+
52
+ // Arrow key navigation moving across days and month boundaries with RTL awareness (DR6, DR11)
53
+ const handleKeyDown = (
54
+ e: React.KeyboardEvent<HTMLButtonElement>,
55
+ day: CalendarDay,
56
+ ) => {
57
+ if (day.isOutside) {
58
+ return;
59
+ }
60
+
61
+ const isRtl =
62
+ typeof window !== 'undefined' &&
63
+ getComputedStyle(e.currentTarget).direction === 'rtl';
64
+
65
+ const isNext = isRtl ? e.key === 'ArrowLeft' : e.key === 'ArrowRight';
66
+ const isPrev = isRtl ? e.key === 'ArrowRight' : e.key === 'ArrowLeft';
67
+
68
+ if (isNext) {
69
+ e.preventDefault();
70
+ const inMonthDays = weeks.flatMap(w => w.filter(d => !d.isOutside));
71
+ const currentIndex = inMonthDays.findIndex(d => d.iso === day.iso);
72
+ if (currentIndex === inMonthDays.length - 1) {
73
+ // Last day of month: advance month and focus next day across boundary
74
+ navigateMonth(1, day.iso, 1);
75
+ } else {
76
+ const nextDay = inMonthDays[currentIndex + 1];
77
+ dayButtonRefs.current.get(nextDay.iso)?.focus();
78
+ }
79
+ } else if (isPrev) {
80
+ e.preventDefault();
81
+ const inMonthDays = weeks.flatMap(w => w.filter(d => !d.isOutside));
82
+ const currentIndex = inMonthDays.findIndex(d => d.iso === day.iso);
83
+ if (currentIndex === 0) {
84
+ // First day of month: step back month and focus previous day across boundary
85
+ navigateMonth(-1, day.iso, 1);
86
+ } else {
87
+ const prevDay = inMonthDays[currentIndex - 1];
88
+ dayButtonRefs.current.get(prevDay.iso)?.focus();
89
+ }
90
+ }
91
+ };
92
+
93
+ return (
94
+ <VStack gap={3} style={{width: 280}}>
95
+ <HStack gap={2} vAlign="center" hAlign="between">
96
+ <Button
97
+ label="Previous"
98
+ size="sm"
99
+ variant="secondary"
100
+ onClick={() => navigateMonth(-1)}
101
+ aria-label="Previous month"
102
+ />
103
+ <Text type="body" weight="bold">
104
+ {monthYearLabel}
105
+ </Text>
106
+ <Button
107
+ label="Next"
108
+ size="sm"
109
+ variant="secondary"
110
+ onClick={() => navigateMonth(1)}
111
+ aria-label="Next month"
112
+ />
113
+ </HStack>
114
+
115
+ <table style={{tableLayout: 'fixed', width: 280}}>
116
+ <thead>
117
+ <tr>
118
+ {dayNames.map((name, i) => (
119
+ <th key={i} scope="col">
120
+ <Text type="supporting" color="secondary">
121
+ {name}
122
+ </Text>
123
+ </th>
124
+ ))}
125
+ </tr>
126
+ </thead>
127
+ <tbody>
128
+ {weeks.map(week => (
129
+ <tr key={week[0].iso}>
130
+ {week.map(day => (
131
+ <td key={day.iso} align="center">
132
+ <button
133
+ type="button"
134
+ ref={el => {
135
+ if (el) {
136
+ dayButtonRefs.current.set(day.iso, el);
137
+ } else {
138
+ dayButtonRefs.current.delete(day.iso);
139
+ }
140
+ }}
141
+ disabled={day.isOutside}
142
+ aria-hidden={day.isOutside || undefined}
143
+ onKeyDown={e => handleKeyDown(e, day)}
144
+ aria-label={
145
+ day.isOutside
146
+ ? undefined
147
+ : `${monthYearLabel} ${day.dayNumber}`
148
+ }
149
+ tabIndex={day.isOutside ? -1 : 0}
150
+ style={{
151
+ width: 32,
152
+ height: 32,
153
+ borderRadius: 6,
154
+ border: 'none',
155
+ background: 'transparent',
156
+ opacity: day.isOutside ? 0.35 : 1,
157
+ cursor: day.isOutside ? 'not-allowed' : 'pointer',
158
+ }}>
159
+ <Text
160
+ type="body"
161
+ color={day.isOutside ? 'secondary' : 'primary'}>
162
+ {day.dayNumber}
163
+ </Text>
164
+ </button>
165
+ </td>
166
+ ))}
167
+ </tr>
168
+ ))}
169
+ </tbody>
170
+ </table>
171
+ </VStack>
172
+ );
173
+ }
@@ -260,7 +260,7 @@ export const butterTheme = defineTheme({
260
260
  '--color-tint-hover': [neutral.light[0], neutral.dark[100]],
261
261
 
262
262
  // Typography override
263
- '--text-supporting-size': '12px',
263
+ '--text-supporting-size': '0.75rem', // 12px at the default root size
264
264
 
265
265
  // Element sizes — slightly taller defaults so the new input padding
266
266
  // (--spacing-2 block) has room to breathe.
@@ -240,7 +240,7 @@ export const stoneTheme = defineTheme({
240
240
  '--color-tint-hover': [neutral.light[0], neutral.dark[100]],
241
241
 
242
242
  // Typography override
243
- '--text-supporting-size': '12px',
243
+ '--text-supporting-size': '0.75rem', // 12px at the default root size
244
244
 
245
245
  // Categorical
246
246
  // Light mode pairs pastel stop 90 surfaces with stop 30 foregrounds.
@@ -236,7 +236,7 @@ export const y2kTheme = defineTheme({
236
236
  '--color-tint-hover': [neutral.light[15], neutral.dark[95]],
237
237
 
238
238
  // Typography override
239
- '--text-supporting-size': '12px',
239
+ '--text-supporting-size': '0.75rem', // 12px at the default root size
240
240
 
241
241
  // Categorical colors
242
242
  '--color-background-green': [green.light[80], green.dark[80]],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/cli",
3
- "version": "0.7.12-canary.9a690d5",
3
+ "version": "0.7.12-canary.f543ec7",
4
4
  "displayName": "CLI",
5
5
  "description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
6
6
  "author": "Meta Open Source",
@@ -124,7 +124,7 @@
124
124
  "zod": "^4.4.3"
125
125
  },
126
126
  "peerDependencies": {
127
- "@astryxdesign/core": "0.7.12-canary.9a690d5"
127
+ "@astryxdesign/core": "0.7.12-canary.f543ec7"
128
128
  },
129
129
  "peerDependenciesMeta": {
130
130
  "@astryxdesign/core": {
@@ -132,10 +132,10 @@
132
132
  }
133
133
  },
134
134
  "devDependencies": {
135
- "@astryxdesign/charts": "0.7.12-canary.9a690d5",
136
- "@astryxdesign/core": "0.7.12-canary.9a690d5",
137
- "@astryxdesign/lab": "0.7.12-canary.9a690d5",
138
- "@astryxdesign/theme-neutral": "0.7.12-canary.9a690d5",
135
+ "@astryxdesign/charts": "0.7.12-canary.f543ec7",
136
+ "@astryxdesign/core": "0.7.12-canary.f543ec7",
137
+ "@astryxdesign/lab": "0.7.12-canary.f543ec7",
138
+ "@astryxdesign/theme-neutral": "0.7.12-canary.f543ec7",
139
139
  "@heroicons/react": "^2.2.0",
140
140
  "@stylexjs/stylex": "^0.19.0",
141
141
  "@types/babel__core": "^7.20.5",