chrona-react 0.1.0 → 0.2.1

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/AGENTS.md ADDED
@@ -0,0 +1,68 @@
1
+ # chrona-react for agents
2
+
3
+ Headless React date/time primitives over the Temporal proposal. Full docs:
4
+ https://github.com/devlinduldulao/chrona#readme
5
+
6
+ ## Setup that is easy to get wrong
7
+
8
+ 1. **Runtime.** Chrona reads `globalThis.Temporal` and never installs it. Where
9
+ Temporal is not native, `import "temporal-polyfill/global"` before rendering.
10
+ 2. **Types.** No extra import is needed. `chrona-core`'s declarations reference
11
+ `temporal-spec/global`, so `Temporal.PlainDate` resolves as an ambient global
12
+ in any file that imports from Chrona. A file that uses Temporal types without
13
+ importing Chrona needs `import "temporal-spec/global"` of its own.
14
+ 3. **Server Components.** These components hold state: mark their module
15
+ `"use client"`. The polyfill import is a side effect, so it must reach the
16
+ client bundle — put it at the top of a `"use client"` module that always
17
+ loads (a providers file), not in a Server Component. That covers hydration.
18
+ 4. **SSR module init.** The providers import does not order Node module
19
+ evaluation. If another `"use client"` file reads `Temporal` at module scope
20
+ (`const reference = Temporal.PlainDate.from(...)` at the top of `page.tsx`),
21
+ Next.js may evaluate that file during SSR before `providers.tsx` has run and
22
+ throw `ReferenceError: Temporal is not defined`. Import the polyfill at the
23
+ top of *that* file too, or move the call inside the component body.
24
+ 5. **Values are Temporal objects.** Strings and `Date` are rejected with a
25
+ `ChronaError`; there is no parsing layer.
26
+
27
+ ## Anatomy
28
+
29
+ ```tsx
30
+ <Calendar.Root value={value} onChange={setValue} placeholderValue={reference}>
31
+ <Calendar.Header><Calendar.PrevButton /><Calendar.Heading /><Calendar.NextButton /></Calendar.Header>
32
+ <Calendar.Grid><Calendar.GridHeader /><Calendar.GridBody /></Calendar.Grid>
33
+ </Calendar.Root>
34
+ ```
35
+
36
+ `Calendar.Cell` is the `role="gridcell"` wrapper and `Calendar.CellTrigger` the
37
+ button inside it; a cell with no children renders its trigger. Style the
38
+ interactive element as `[data-part="cell-trigger"]`. Paging buttons render a
39
+ default chevron when given no children, and `DatePicker.Trigger` a calendar
40
+ glyph.
41
+
42
+ `DatePicker` takes every `DateField` prop, `placeholderValue` included — it is
43
+ what the field and calendar open on before a value exists.
44
+
45
+ ## Field behavior
46
+
47
+ - Blank segments read `mm/dd/yyyy` and `hh:mm`; filled numeric segments other
48
+ than the year are zero-padded.
49
+ - Typed digits are literal, stepping clamps. 29 February is reachable before the
50
+ year is typed; a finished date that cannot exist reports
51
+ `onInvalid("nonexistent")` rather than clamping to the 28th.
52
+ - Validation waits for a segment to finish. A half-typed year emits nothing
53
+ until it is complete or the field blurs.
54
+ - Empty fields are `null`. Partial drafts stay internal; `onChange` only sees
55
+ complete, valid values.
56
+
57
+ ## SSR determinism
58
+
59
+ Pass the same reference date, value, locale, and `timeZone` on server and
60
+ client — today is resolved at render time. Segment literals are normalized
61
+ (U+202F and U+00A0 collapse to a plain space), so a 12-hour `TimeField` hydrates
62
+ cleanly across differing ICU versions; `hourCycle="h23"` is not a requirement.
63
+
64
+ ## Not implemented
65
+
66
+ MonthPicker/YearPicker, DateTimeField, DateTimePicker, TimePicker,
67
+ DateRangePicker, zoned fields/pickers, TimeZoneSelect. Public APIs are
68
+ experimental at 0.x and not frozen for v1.
package/README.md CHANGED
@@ -6,9 +6,10 @@ values, no free-form date parsing, and no CSS — you own every pixel.
6
6
  Part of [Chrona](https://github.com/devlinduldulao/chrona). Built on
7
7
  [`chrona-core`](https://www.npmjs.com/package/chrona-core).
8
8
 
9
- > **Status: experimental 0.1.0.** Public APIs and styling attributes are not
10
- > frozen for v1. Automated axe checks pass, but no screen-reader compatibility
11
- > certification is claimed.
9
+ > **Status: experimental 0.2.1.** Public APIs and styling attributes are not
10
+ > frozen for v1; 0.2.0 changes the Calendar cell anatomy. See the
11
+ > [changelog](./CHANGELOG.md). Automated axe checks pass, but no screen-reader
12
+ > compatibility certification is claimed.
12
13
 
13
14
  ## Install
14
15
 
@@ -27,6 +28,10 @@ it is not native, load a polyfill before rendering:
27
28
  import "temporal-polyfill/global";
28
29
  ```
29
30
 
31
+ The TypeScript types come along for free: `chrona-core`'s declarations reference
32
+ `temporal-spec/global`, so importing anything from this package puts the ambient
33
+ `Temporal` namespace in scope, exactly as the examples below assume.
34
+
30
35
  ## Calendar
31
36
 
32
37
  ```tsx
@@ -64,6 +69,14 @@ covers arrows, Home/End, PageUp/PageDown, Shift+PageUp/PageDown, and
64
69
  Enter/Space, with RTL and locale week starts. Unavailable dates stay focusable
65
70
  but unselectable; hard-disabled dates are not interactive.
66
71
 
72
+ `Calendar.Cell` renders the `role="gridcell"` wrapper and `Calendar.CellTrigger`
73
+ the button inside it, so the control keeps its button role in the accessibility
74
+ tree; a cell given no children renders its trigger for you. Style the
75
+ interactive element as `[data-part="cell-trigger"]`. `PrevButton` and
76
+ `NextButton` render a default chevron, pointing the way they page in the
77
+ resolved reading direction, when you give them no children; `DatePicker.Trigger`
78
+ does the same with a calendar glyph.
79
+
67
80
  ## DatePicker
68
81
 
69
82
  ```tsx
@@ -78,6 +91,11 @@ but unselectable; hard-disabled dates are not interactive.
78
91
  </DatePicker.Root>
79
92
  ```
80
93
 
94
+ `DatePicker` accepts every `DateField` prop. `placeholderValue` is one of them,
95
+ and it decides the reference date the segments and the calendar open on before a
96
+ value exists — supply it (or `value`/`defaultValue`) rather than falling back to
97
+ today.
98
+
81
99
  The popover is a native `<dialog>`, modal by default. It anchors to its trigger,
82
100
  flips above when that fits, shifts to stay in the viewport, and scrolls
83
101
  internally when oversized. Escape, outside pointer dismissal, and selection all
@@ -105,6 +123,11 @@ Style via `data-scope`, `data-part`, and state attributes: `data-selected`,
105
123
  `data-outside-month`, `data-in-range`, `data-range-start`, `data-range-end`,
106
124
  `data-preview`, `data-invalid`, `data-placeholder`.
107
125
 
126
+ Date cells are two parts: `cell` is the `role="gridcell"` wrapper, `cell-trigger`
127
+ is the button that takes focus, hover, and the click. Both carry the state
128
+ attributes. The default icons are `data-part="chevron"` on the paging buttons
129
+ and `data-part="trigger-icon"` on the picker trigger.
130
+
108
131
  Layout and button parts accept `asChild` with event and ref composition. Input
109
132
  segments, hidden inputs, and the dialog keep their HTML elements.
110
133
 
@@ -119,12 +142,61 @@ incomplete, or invalid values in your form layer before submission.
119
142
 
120
143
  - ESM with declarations and source maps, targeting ES2022.
121
144
  - Size budgets, minified + gzip, excluding React: Calendar 6 kB, DatePicker 12 kB.
122
- - For deterministic SSR, pass the same reference date, value, locale, and time
123
- zone on server and client. In Server Component frameworks, consume this
124
- package from a client component.
145
+ - Blank segments read `mm/dd/yyyy` and `hh:mm`; filled numeric segments except
146
+ the year are zero-padded, so a field keeps one width as it fills.
147
+ - Typed digits are literal and stepping clamps: 29 February is reachable before
148
+ the year is typed, and a finished date the calendar cannot hold reports
149
+ `onInvalid("nonexistent")` instead of sliding to the 28th. Validation waits for
150
+ a segment to finish, so a half-typed year raises nothing until blur.
125
151
  - Use `value`/`onChange` or `defaultValue`/`onChange` — do not switch modes
126
152
  during a component's lifetime.
127
153
 
154
+ ## Server Rendering
155
+
156
+ These are client components: mark the module that renders them `"use client"`.
157
+
158
+ The polyfill import is a side effect, so it has to reach the *client* bundle.
159
+ Importing `temporal-polyfill/global` from a Server Component file installs
160
+ Temporal on the server only. Put it at the top of a `"use client"` module that
161
+ always loads — a providers file, for example — so it runs before hydration:
162
+
163
+ ```tsx
164
+ // app/providers.tsx
165
+ "use client";
166
+
167
+ import "temporal-polyfill/global";
168
+ import { ChronaProvider } from "chrona-react";
169
+
170
+ export function Providers({ children }: { children: React.ReactNode }) {
171
+ return <ChronaProvider locale="en-US" timeZone="Europe/Copenhagen">{children}</ChronaProvider>;
172
+ }
173
+ ```
174
+
175
+ That covers the client bundle before hydration. It does not order Node module
176
+ evaluation. If another `"use client"` file reads `Temporal` at module scope
177
+ (`const reference = Temporal.PlainDate.from(...)` at the top of `page.tsx`),
178
+ Next.js may evaluate that file during SSR before `providers.tsx` has run and
179
+ throw `ReferenceError: Temporal is not defined`. Import the polyfill at the top
180
+ of that file too, or move the call inside the component body:
181
+
182
+ ```tsx
183
+ "use client";
184
+
185
+ import "temporal-polyfill/global";
186
+ import { Calendar } from "chrona-react";
187
+
188
+ const REFERENCE = Temporal.PlainDate.from({ year: 2026, month: 9, day: 16 });
189
+ ```
190
+
191
+ Pass the same reference date, value, locale, and time zone on server and client.
192
+ `timeZone` matters because today is resolved at render time, and a server in
193
+ another zone marks a different cell.
194
+
195
+ Segment literals are normalized before they reach the DOM: `Intl` emits U+202F
196
+ before AM/PM on newer ICU data and a plain space on older data, and Node and the
197
+ browser rarely ship the same ICU. Chrona collapses both to a plain space, so a
198
+ 12-hour `TimeField` hydrates cleanly without forcing `hourCycle="h23"`.
199
+
128
200
  Full documentation lives in the [repository README](https://github.com/devlinduldulao/chrona#readme).
129
201
 
130
202
  ## License
@@ -35,13 +35,20 @@ declare function useCalendar(props?: CalendarProps): {
35
35
  "data-part": string;
36
36
  };
37
37
  getCellProps: (date: PlainDate, month?: temporal_spec.Temporal.PlainDate) => {
38
- id: string;
38
+ "data-date": string;
39
+ "data-selected": string | undefined;
40
+ "data-focused": string | undefined;
41
+ "data-disabled": string | undefined;
42
+ "data-unavailable": string | undefined;
43
+ "data-outside-month": string | undefined;
44
+ "data-today": string | undefined;
39
45
  role: "gridcell";
40
- tabIndex: number;
41
- "aria-label": string;
42
46
  "aria-selected": boolean;
43
47
  "aria-disabled": true | undefined;
44
- "aria-current": "date" | undefined;
48
+ "data-scope": string;
49
+ "data-part": string;
50
+ };
51
+ getCellTriggerProps: (date: PlainDate, month?: temporal_spec.Temporal.PlainDate) => {
45
52
  "data-date": string;
46
53
  "data-selected": string | undefined;
47
54
  "data-focused": string | undefined;
@@ -49,6 +56,12 @@ declare function useCalendar(props?: CalendarProps): {
49
56
  "data-unavailable": string | undefined;
50
57
  "data-outside-month": string | undefined;
51
58
  "data-today": string | undefined;
59
+ id: string;
60
+ type: "button";
61
+ tabIndex: number;
62
+ "aria-label": string;
63
+ "aria-disabled": true | undefined;
64
+ "aria-current": "date" | undefined;
52
65
  "data-scope": string;
53
66
  "data-part": string;
54
67
  };
@@ -109,11 +122,14 @@ declare const Calendar: {
109
122
  GridBody: React.ForwardRefExoticComponent<Omit<PartProps, "children"> & {
110
123
  children?: (date: PlainDate) => React.ReactNode;
111
124
  } & React.RefAttributes<HTMLElement>>;
112
- Cell: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
125
+ Cell: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
113
126
  asChild?: boolean;
114
127
  } & {
115
128
  date: PlainDate;
116
129
  } & React.RefAttributes<HTMLElement>>;
130
+ CellTrigger: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
131
+ asChild?: boolean;
132
+ } & React.RefAttributes<HTMLElement>>;
117
133
  LiveRegion: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
118
134
  asChild?: boolean;
119
135
  } & React.RefAttributes<HTMLElement>>;
package/dist/calendar.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  CalendarRoot,
4
4
  CalendarSurface,
5
5
  useCalendar
6
- } from "./chunk-EFN32TNK.js";
6
+ } from "./chunk-RCWVBOO6.js";
7
7
  import "./chunk-GN2YCKFZ.js";
8
8
  export {
9
9
  Calendar,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createFieldComponents,
3
3
  useField
4
- } from "./chunk-VSD2IX3U.js";
4
+ } from "./chunk-JNQXKZO3.js";
5
5
 
6
6
  // src/date-field.tsx
7
7
  var DateField = createFieldComponents("date");
@@ -13,4 +13,4 @@ export {
13
13
  DateField,
14
14
  useDateField
15
15
  };
16
- //# sourceMappingURL=chunk-ZN4FZDUQ.js.map
16
+ //# sourceMappingURL=chunk-2GZMCFFY.js.map
@@ -34,7 +34,8 @@ function useField(kind, props) {
34
34
  }, [configuration, state, store]);
35
35
  const groupRef = React.useRef(null);
36
36
  const [invalidReason, setInvalidReason] = React.useState(null);
37
- const announcement = invalidReason === null ? "" : invalidReason === "range" ? options.translations?.invalidRange ?? translations.invalidRange : options.translations?.unavailable ?? translations.unavailable;
37
+ const announcementKey = { range: "invalidRange", unavailable: "unavailable", nonexistent: "nonexistentDate" };
38
+ const announcement = invalidReason === null ? "" : options.translations?.[announcementKey[invalidReason]] ?? translations[announcementKey[invalidReason]];
38
39
  function moveFocus(segment, offset) {
39
40
  const elements = Array.from(groupRef.current?.querySelectorAll("input[data-segment]") ?? []);
40
41
  const index = elements.findIndex((element) => element.dataset.segment === segment);
@@ -180,4 +181,4 @@ export {
180
181
  useField,
181
182
  createFieldComponents
182
183
  };
183
- //# sourceMappingURL=chunk-VSD2IX3U.js.map
184
+ //# sourceMappingURL=chunk-JNQXKZO3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/field.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { connectField, createField, createStore, digitValue, fieldHourCycle, transitionField, translations, type FieldEvent, type FieldInvalidReason, type FieldKind, type FieldOptions, type FieldValue, type SegmentType } from \"chrona-core\";\nimport { Part, composeEvent, type PartProps } from \"./part\";\nimport { useChronaConfig } from \"./provider\";\nimport { useFormReset, type HiddenInputProps } from \"./form\";\n\nexport interface FieldProps<Kind extends FieldKind> extends FieldOptions<Kind> {\n defaultValue?: FieldValue<Kind> | null;\n onChange?: (value: FieldValue<Kind> | null) => void;\n onInvalid?: (reason: FieldInvalidReason) => void;\n id?: string;\n describedBy?: string;\n}\n\nfunction equalValues(first: { equals: (other: never) => boolean } | null, second: { equals: (other: never) => boolean } | null) {\n return first === null || second === null ? first === second : first.equals(second as never);\n}\n\nexport function useField<Kind extends FieldKind>(kind: Kind, props: FieldProps<Kind>) {\n const options = useChronaConfig(props);\n const generatedId = React.useId();\n const id = props.id ?? generatedId;\n const [store] = React.useState(() => createStore(createField(kind, { ...options, value: props.value !== undefined ? props.value : props.defaultValue })));\n const snapshot = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n const value = props.value !== undefined ? props.value : snapshot.value;\n const placeholderValue = options.placeholderValue ?? snapshot.reference;\n const { minValue, maxValue, locale, hourCycle, granularity } = options;\n const configured = React.useMemo(() => createField(kind, { value, placeholderValue, minValue, maxValue, locale, hourCycle, granularity }), [kind, value, placeholderValue, minValue, maxValue, locale, hourCycle, granularity]);\n const cycle = fieldHourCycle(options);\n const configuration = `${cycle}:${props.granularity ?? \"minute\"}`;\n const previousConfiguration = React.useRef(configuration);\n const state = props.value !== undefined && !equalValues(snapshot.value, props.value)\n ? configured\n : kind === \"time\" && configuration !== previousConfiguration.current\n ? configured\n : snapshot;\n React.useEffect(() => {\n if (previousConfiguration.current !== configuration) {\n previousConfiguration.current = configuration;\n store.setState(state);\n }\n }, [configuration, state, store]);\n const groupRef = React.useRef<HTMLElement | null>(null);\n const [invalidReason, setInvalidReason] = React.useState<FieldInvalidReason | null>(null);\n const announcementKey = { range: \"invalidRange\", unavailable: \"unavailable\", nonexistent: \"nonexistentDate\" } as const;\n const announcement = invalidReason === null ? \"\" : options.translations?.[announcementKey[invalidReason]] ?? translations[announcementKey[invalidReason]];\n\n function moveFocus(segment: SegmentType, offset: number) {\n const elements = Array.from(groupRef.current?.querySelectorAll<HTMLInputElement>(\"input[data-segment]\") ?? []);\n const index = elements.findIndex((element) => element.dataset.segment === segment);\n elements[index + offset]?.focus();\n }\n\n function send(event: FieldEvent) {\n const result = transitionField(state, event, options);\n store.setState(result.state);\n if (!result.state.invalid) setInvalidReason(null);\n for (const effect of result.effects) {\n if (effect.type === \"change\") props.onChange?.(effect.value);\n if (effect.type === \"invalid\") { setInvalidReason(effect.reason); props.onInvalid?.(effect.reason); }\n if (effect.type === \"advance\") queueMicrotask(() => moveFocus(effect.segment, 1));\n }\n }\n\n function reset() {\n setInvalidReason(null);\n const value = props.defaultValue ?? null;\n store.setState(createField(kind, { ...options, value }));\n if (!equalValues(state.value, value)) props.onChange?.(value);\n }\n\n const [labelled, setLabelled] = React.useState(false);\n return { id, state, options, send, reset, moveFocus, groupRef, announcement, registerLabel: setLabelled, api: connectField(state, { ...options, id, labelId: labelled ? `${id}-label` : undefined }) };\n}\n\nexport function createFieldComponents<Kind extends FieldKind>(kind: Kind) {\n const Context = React.createContext<ReturnType<typeof useField<Kind>> | null>(null);\n function useContext() {\n const context = React.useContext(Context);\n if (!context) throw new Error(`${kind === \"date\" ? \"DateField\" : \"TimeField\"} parts must be inside their Root.`);\n return context;\n }\n\n function Root({ children, asChild, className, style, ...props }: FieldProps<Kind> & Pick<PartProps, \"children\" | \"asChild\" | \"className\" | \"style\">) {\n const context = useField(kind, props);\n return <Context.Provider value={context}><Part asChild={asChild} className={className} style={style} id={props.id} dir={context.options.dir} data-scope={`${kind}-field`} data-part=\"root\">{children}</Part></Context.Provider>;\n }\n\n const Label = React.forwardRef<HTMLElement, PartProps>(function Label(props, ref) {\n const { id, registerLabel } = useContext();\n React.useEffect(() => {\n registerLabel(true);\n return () => registerLabel(false);\n }, [registerLabel]);\n return <Part as=\"span\" {...props} ref={ref} id={`${id}-label`} data-scope={`${kind}-field`} data-part=\"label\" />;\n });\n\n const Segment = React.forwardRef<HTMLInputElement, Omit<React.ComponentPropsWithoutRef<\"input\">, \"type\" | \"value\" | \"defaultValue\" | \"onChange\" | \"children\"> & { type: SegmentType }>(function Segment({ type, onKeyDown, onFocus, onBlur, onPaste, onDrop, ...props }, ref) {\n const { state, api, options, send, moveFocus, groupRef } = useContext();\n if (!(type in state.parts)) throw new Error(`The ${type} segment is not enabled in this field.`);\n const { display, ...segmentProps } = api.getSegmentProps(type);\n return <input {...props} {...segmentProps} ref={ref} type=\"text\" inputMode={type === \"dayPeriod\" ? \"text\" : \"numeric\"} autoComplete=\"off\" spellCheck={false} value={display} disabled={options.disabled} readOnly={options.readOnly}\n onFocus={composeEvent(onFocus, (event) => { event.currentTarget.select(); })}\n onBlur={composeEvent(onBlur, () => send({ type: \"BLUR\" }))}\n onPaste={composeEvent(onPaste, (event) => event.preventDefault())}\n onDrop={composeEvent(onDrop, (event) => event.preventDefault())}\n onChange={(event) => {\n const native = event.nativeEvent as InputEvent;\n const digit = digitValue(native.data ?? \"\", options.locale);\n event.currentTarget.value = display;\n if (native.inputType === \"insertText\" && digit !== null) send({ type: \"DIGIT\", segment: type, digit });\n else if (native.inputType === \"deleteContentBackward\" || native.inputType === \"deleteContentForward\") send({ type: \"CLEAR\", segment: type });\n }}\n onKeyDown={composeEvent(onKeyDown, (event) => {\n if (event.altKey || event.ctrlKey || event.metaKey || event.nativeEvent.isComposing) return;\n const digit = digitValue(event.key, options.locale);\n const dir = options.dir ?? (groupRef.current?.closest(\"[dir]\")?.getAttribute(\"dir\") === \"rtl\" ? \"rtl\" : \"ltr\");\n if (digit !== null) { event.preventDefault(); send({ type: \"DIGIT\", segment: type, digit }); return; }\n switch (event.key) {\n case \"ArrowUp\": case \"ArrowDown\": event.preventDefault(); send({ type: \"STEP\", segment: type, direction: event.key === \"ArrowUp\" ? 1 : -1 }); break;\n case \"Home\": case \"End\": event.preventDefault(); send({ type: \"EDGE\", segment: type, edge: event.key === \"Home\" ? \"min\" : \"max\" }); break;\n case \"Backspace\": case \"Delete\": event.preventDefault(); send({ type: \"CLEAR\", segment: type }); break;\n case \"ArrowLeft\": case \"ArrowRight\": event.preventDefault(); moveFocus(type, (event.key === \"ArrowRight\" ? 1 : -1) * (dir === \"rtl\" ? -1 : 1)); break;\n default:\n if (type === \"dayPeriod\" && [\"a\", \"p\"].includes(event.key.toLowerCase())) {\n event.preventDefault(); send({ type: \"PERIOD\", value: event.key.toLowerCase() === \"a\" ? 0 : 1 });\n }\n }\n })} />;\n });\n\n const Field = React.forwardRef<HTMLElement, PartProps>(function Field({ children, ...props }, ref) {\n const { api, groupRef } = useContext();\n return <Part {...props} {...api.getGroupProps()} ref={(node) => {\n groupRef.current = node;\n if (typeof ref === \"function\") ref(node); else if (ref) ref.current = node;\n }}>{children ?? api.segments.map((segment, index) => segment.type === \"literal\" ? <span key={index} aria-hidden=\"true\" data-scope={`${kind}-field`} data-part=\"literal\">{segment.value}</span> : <Segment key={segment.type} type={segment.type} />)}</Part>;\n });\n\n function HiddenInput(props: HiddenInputProps) {\n const { state, options, reset } = useContext();\n const input = React.useRef<HTMLInputElement>(null);\n useFormReset(input, props.form, reset);\n return <input {...props} ref={input} type=\"hidden\" value={state.value?.toString() ?? \"\"} disabled={options.disabled || props.disabled} data-scope={`${kind}-field`} data-part=\"hidden-input\" />;\n }\n\n const ClearButton = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<\"button\"> & { asChild?: boolean }>(function ClearButton({ onClick, ...props }, ref) {\n const { options, send } = useContext();\n return <Part as=\"button\" {...props} ref={ref} type=\"button\" aria-label={options.translations?.clear ?? translations.clear} disabled={options.disabled || options.readOnly} data-scope={`${kind}-field`} data-part=\"clear-button\" onClick={composeEvent(onClick, () => send({ type: \"CLEAR\" }))} />;\n });\n\n const LiveRegion = React.forwardRef<HTMLElement, PartProps>(function LiveRegion(props, ref) {\n const { announcement } = useContext();\n return <Part {...props} ref={ref} role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" data-scope={`${kind}-field`} data-part=\"live-region\">{announcement}</Part>;\n });\n\n return { Root, Label, Field, Segment, HiddenInput, ClearButton, LiveRegion };\n}"],"mappings":"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","names":["value","useContext","Label","Segment","Field","ClearButton","LiveRegion"]}
@@ -2,7 +2,7 @@ import {
2
2
  Calendar,
3
3
  CalendarSurface,
4
4
  useCalendar
5
- } from "./chunk-EFN32TNK.js";
5
+ } from "./chunk-RCWVBOO6.js";
6
6
  import {
7
7
  Part,
8
8
  composeEvent,
@@ -12,7 +12,7 @@ import {
12
12
 
13
13
  // src/range-calendar.tsx
14
14
  import * as React from "react";
15
- import { createRange, createStore, formatDate, getRangeCellProps, transitionRange, translations, validateRange } from "chrona-core";
15
+ import { createRange, createStore, formatDate, getRangeCellProps, getRangeCellTriggerProps, transitionRange, translations, validateRange } from "chrona-core";
16
16
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
17
17
  function useRangeCalendar(input = {}) {
18
18
  const props = useChronaConfig(input);
@@ -46,7 +46,11 @@ function useRangeCalendar(input = {}) {
46
46
  if (state.anchor) send({ type: "PREVIEW", date });
47
47
  } });
48
48
  const baseApi = calendar.api;
49
- const api = { ...baseApi, getCellProps: (date, month) => ({ ...baseApi.getCellProps(date, month), ...getRangeCellProps(state, date) }) };
49
+ const api = {
50
+ ...baseApi,
51
+ getCellProps: (date, month) => ({ ...baseApi.getCellProps(date, month), ...getRangeCellProps(state, date) }),
52
+ getCellTriggerProps: (date, month) => ({ ...baseApi.getCellTriggerProps(date, month), ...getRangeCellTriggerProps(state, date) })
53
+ };
50
54
  return {
51
55
  state,
52
56
  send,
@@ -109,4 +113,4 @@ export {
109
113
  useRangeCalendar,
110
114
  RangeCalendar
111
115
  };
112
- //# sourceMappingURL=chunk-XNVORQQ5.js.map
116
+ //# sourceMappingURL=chunk-QQANBK5G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/range-calendar.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { createRange, createStore, formatDate, getRangeCellProps, getRangeCellTriggerProps, transitionRange, translations, validateRange, type DateRange, type PlainDate, type RangeEvent } from \"chrona-core\";\nimport { Calendar, CalendarSurface, useCalendar, type CalendarProps } from \"./calendar\";\nimport { Part, composeEvent, type PartProps } from \"./part\";\nimport { useFormReset, type HiddenInputProps } from \"./form\";\nimport { useChronaConfig } from \"./provider\";\n\nexport interface RangeCalendarProps extends Omit<CalendarProps, \"value\" | \"defaultValue\" | \"onChange\"> {\n value?: DateRange | null;\n defaultValue?: DateRange | null;\n onChange?: (value: DateRange | null) => void;\n onRangeStartChange?: (value: PlainDate | null) => void;\n onInvalid?: () => void;\n}\n\nexport function useRangeCalendar(input: RangeCalendarProps = {}) {\n const props = useChronaConfig(input);\n const [store] = React.useState(() => createStore(createRange(props.value !== undefined ? props.value : props.defaultValue)));\n const snapshot = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n if (props.value) validateRange(props.value);\n const state = { ...snapshot, value: props.value === undefined ? snapshot.value : props.value };\n const [announcement, setAnnouncement] = React.useState(\"\");\n function send(event: RangeEvent) {\n const result = transitionRange(state, event, props);\n store.setState(result.state);\n for (const effect of result.effects) {\n if (effect.type === \"change\") {\n props.onChange?.(effect.value);\n setAnnouncement(effect.value ? [effect.value.start, effect.value.end].map((date) => formatDate(date, props.locale, { dateStyle: \"long\" })).join(props.translations?.rangeSeparator ?? translations.rangeSeparator) : \"\");\n }\n if (effect.type === \"rangeStart\") {\n props.onRangeStartChange?.(effect.value);\n if (effect.value) setAnnouncement(formatDate(effect.value, props.locale, { dateStyle: \"long\" }));\n }\n if (effect.type === \"invalid\") { props.onInvalid?.(); setAnnouncement(props.translations?.unavailable ?? translations.unavailable); }\n }\n }\n const calendar = useCalendar({ ...props, value: null, defaultValue: null, placeholderValue: props.placeholderValue ?? state.value?.start, onChange: (date) => { if (date) send({ type: \"SELECT\", date }); }, onFocusedValueChange: (date) => { props.onFocusedValueChange?.(date); if (state.anchor) send({ type: \"PREVIEW\", date }); } });\n const baseApi = calendar.api;\n const api = {\n ...baseApi,\n getCellProps: (date: PlainDate, month?: PlainDate) => ({ ...baseApi.getCellProps(date, month), ...getRangeCellProps(state, date) }),\n getCellTriggerProps: (date: PlainDate, month?: PlainDate) => ({ ...baseApi.getCellTriggerProps(date, month), ...getRangeCellTriggerProps(state, date) }),\n };\n return {\n state, send, announcement, props, options: props, api, rootRef: calendar.rootRef, months: calendar.months,\n reset() { const value = props.defaultValue ?? null; store.setState(createRange(value)); props.onChange?.(value); },\n calendar: { ...calendar, api },\n };\n}\n\nconst Context = React.createContext<ReturnType<typeof useRangeCalendar> | null>(null);\nfunction useContext() {\n const value = React.useContext(Context);\n if (!value) throw new Error(\"RangeCalendar parts must be inside RangeCalendar.Root.\");\n return value;\n}\n\nfunction Root({ children, asChild, className, style, ...props }: RangeCalendarProps & Pick<PartProps, \"children\" | \"asChild\" | \"className\" | \"style\">) {\n const context = useRangeCalendar(props);\n return <Context.Provider value={context}><CalendarSurface calendar={context.calendar} asChild={asChild} className={className} style={style} data-scope=\"range-calendar\" onKeyDown={(event) => { if (event.key === \"Escape\" && context.state.anchor) { event.preventDefault(); context.send({ type: \"CANCEL\" }); } }}>{children}</CalendarSurface></Context.Provider>;\n}\n\nconst Cell = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<typeof Calendar.Cell>>(function Cell({ date, onPointerEnter, ...props }, ref) {\n const { send } = useContext();\n return <Calendar.Cell {...props} ref={ref} date={date} onPointerEnter={composeEvent(onPointerEnter, () => send({ type: \"PREVIEW\", date }))} />;\n});\n\nconst GridBody = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<typeof Calendar.GridBody>>(function GridBody({ children, ...props }, ref) {\n return <Calendar.GridBody {...props} ref={ref}>{children ?? ((date) => <Cell date={date} />)}</Calendar.GridBody>;\n});\n\nconst LiveRegion = React.forwardRef<HTMLElement, PartProps>(function LiveRegion(props, ref) {\n const { announcement } = useContext();\n return <Part {...props} ref={ref} role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" data-scope=\"range-calendar\" data-part=\"live-region\">{announcement}</Part>;\n});\n\nconst ClearButton = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<typeof Calendar.ClearButton>>(function ClearButton({ onClick, ...props }, ref) {\n const { send, props: options } = useContext();\n return <Part as=\"button\" {...props} ref={ref} type=\"button\" disabled={options.disabled || options.readOnly} aria-label={options.translations?.clear ?? translations.clear} data-scope=\"range-calendar\" data-part=\"clear-button\" onClick={composeEvent(onClick, () => send({ type: \"CLEAR\" }))} />;\n});\n\nfunction HiddenInput({ name, form, id, disabled, ...inputProps }: HiddenInputProps & { name: string }) {\n const { state, props, reset } = useContext();\n const input = React.useRef<HTMLInputElement>(null);\n useFormReset(input, form, reset);\n return <><input {...inputProps} id={id ? `${id}-start` : undefined} ref={input} type=\"hidden\" name={`${name}.start`} form={form} value={state.value?.start.toString() ?? \"\"} disabled={props.disabled || disabled} data-scope=\"range-calendar\" data-part=\"hidden-input\" /><input {...inputProps} id={id ? `${id}-end` : undefined} type=\"hidden\" name={`${name}.end`} form={form} value={state.value?.end.toString() ?? \"\"} disabled={props.disabled || disabled} data-scope=\"range-calendar\" data-part=\"hidden-input\" /></>;\n}\n\nexport const RangeCalendar = { ...Calendar, Root, Cell, GridBody, LiveRegion, ClearButton, HiddenInput };"],"mappings":"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","names":["useContext","Cell","GridBody","LiveRegion","ClearButton"]}
@@ -25,7 +25,7 @@ function useCalendar(props = {}) {
25
25
  React.useEffect(() => {
26
26
  if (pendingFocus.current) {
27
27
  pendingFocus.current = false;
28
- rootRef.current?.querySelector('[data-part="cell"][tabindex="0"]')?.focus();
28
+ rootRef.current?.querySelector('[data-part="cell-trigger"][tabindex="0"]')?.focus();
29
29
  }
30
30
  });
31
31
  function send(event) {
@@ -76,13 +76,17 @@ var Heading = React.forwardRef(function Heading2({ children, ...props }, ref) {
76
76
  const month = React.useContext(MonthContext);
77
77
  return /* @__PURE__ */ jsx(Part, { as: "h2", ...props, ref, "data-scope": "calendar", "data-part": "heading", "aria-live": "polite", "aria-atomic": "true", children: children ?? (month ? [month] : months).map((date) => formatDate(date, options.locale, { month: "long", year: "numeric" })).join(options.translations?.rangeSeparator ?? translations.rangeSeparator) });
78
78
  });
79
- var PrevButton = React.forwardRef(function PrevButton2({ onClick, ...props }, ref) {
80
- const { api, send } = useContext2();
81
- return /* @__PURE__ */ jsx(Part, { as: "button", ...props, ...api.getPrevButtonProps(), ref, onClick: composeEvent(onClick, () => send({ type: "PAGE", direction: -1 })) });
79
+ function Chevron({ towards }) {
80
+ const points = towards === "start" ? "15 4 7 12 15 20" : "9 4 17 12 9 20";
81
+ return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "data-scope": "calendar", "data-part": "chevron", children: /* @__PURE__ */ jsx("polyline", { points }) });
82
+ }
83
+ var PrevButton = React.forwardRef(function PrevButton2({ onClick, children, ...props }, ref) {
84
+ const { api, send, options } = useContext2();
85
+ return /* @__PURE__ */ jsx(Part, { as: "button", ...props, ...api.getPrevButtonProps(), ref, onClick: composeEvent(onClick, () => send({ type: "PAGE", direction: -1 })), children: children ?? /* @__PURE__ */ jsx(Chevron, { towards: options.dir === "rtl" ? "end" : "start" }) });
82
86
  });
83
- var NextButton = React.forwardRef(function NextButton2({ onClick, ...props }, ref) {
84
- const { api, send } = useContext2();
85
- return /* @__PURE__ */ jsx(Part, { as: "button", ...props, ...api.getNextButtonProps(), ref, onClick: composeEvent(onClick, () => send({ type: "PAGE", direction: 1 })) });
87
+ var NextButton = React.forwardRef(function NextButton2({ onClick, children, ...props }, ref) {
88
+ const { api, send, options } = useContext2();
89
+ return /* @__PURE__ */ jsx(Part, { as: "button", ...props, ...api.getNextButtonProps(), ref, onClick: composeEvent(onClick, () => send({ type: "PAGE", direction: 1 })), children: children ?? /* @__PURE__ */ jsx(Chevron, { towards: options.dir === "rtl" ? "start" : "end" }) });
86
90
  });
87
91
  var Grid = React.forwardRef(function Grid2({ monthIndex = 0, children, ...props }, ref) {
88
92
  const { api, months } = useContext2();
@@ -110,16 +114,17 @@ var GridBody = React.forwardRef(function GridBody2({ children, ...props }, ref)
110
114
  const { weeks } = useMonth();
111
115
  return /* @__PURE__ */ jsx(Part, { ...props, ref, role: "rowgroup", "data-scope": "calendar", "data-part": "grid-body", children: weeks.map((week) => /* @__PURE__ */ jsx("div", { role: "row", "data-scope": "calendar", "data-part": "row", children: week.map((date) => /* @__PURE__ */ jsx(React.Fragment, { children: children ? children(date) : /* @__PURE__ */ jsx(Cell, { date }) }, date.toString())) }, week[0].toString())) });
112
116
  });
113
- var Cell = React.forwardRef(function Cell2({ date, children, onClick, onKeyDown, onFocus, ...props }, ref) {
117
+ var CellContext = React.createContext(null);
118
+ var CellTrigger = React.forwardRef(function CellTrigger2({ children, onClick, onKeyDown, onFocus, ...props }, ref) {
114
119
  const { api, send, month, options } = useMonth();
115
- const cellProps = api.getCellProps(date, month);
120
+ const date = React.useContext(CellContext);
121
+ if (!date) throw new Error("Calendar.CellTrigger must be inside Calendar.Cell.");
116
122
  return /* @__PURE__ */ jsx(
117
123
  Part,
118
124
  {
119
125
  as: "button",
120
126
  ...props,
121
- ...cellProps,
122
- type: "button",
127
+ ...api.getCellTriggerProps(date, month),
123
128
  ref,
124
129
  onFocus: composeEvent(onFocus, () => {
125
130
  if (!options.disabled) send({ type: "FOCUS", date });
@@ -134,6 +139,10 @@ var Cell = React.forwardRef(function Cell2({ date, children, onClick, onKeyDown,
134
139
  }
135
140
  );
136
141
  });
142
+ var Cell = React.forwardRef(function Cell2({ date, children, ...props }, ref) {
143
+ const { api, month } = useMonth();
144
+ return /* @__PURE__ */ jsx(CellContext.Provider, { value: date, children: /* @__PURE__ */ jsx(Part, { ...props, ...api.getCellProps(date, month), ref, children: children ?? /* @__PURE__ */ jsx(CellTrigger, {}) }) });
145
+ });
137
146
  var LiveRegion = React.forwardRef(function LiveRegion2(props, ref) {
138
147
  const { announcement } = useContext2();
139
148
  return /* @__PURE__ */ jsx(Part, { ...props, ref, role: "status", "aria-live": "polite", "aria-atomic": "true", "data-scope": "calendar", "data-part": "live-region", children: announcement });
@@ -148,7 +157,7 @@ function HiddenInput(props) {
148
157
  useFormReset(input, props.form, () => send({ type: "RESET", value: options.defaultValue ?? null }));
149
158
  return /* @__PURE__ */ jsx("input", { ...props, ref: input, type: "hidden", disabled: options.disabled || props.disabled, value: state.value?.toString() ?? "", "data-scope": "calendar", "data-part": "hidden-input" });
150
159
  }
151
- var Calendar = { Root: CalendarRoot, Header, Heading, PrevButton, NextButton, Grid, GridHeader, HeaderCell, GridBody, Cell, LiveRegion, ClearButton, HiddenInput };
160
+ var Calendar = { Root: CalendarRoot, Header, Heading, PrevButton, NextButton, Grid, GridHeader, HeaderCell, GridBody, Cell, CellTrigger, LiveRegion, ClearButton, HiddenInput };
152
161
 
153
162
  export {
154
163
  useCalendar,
@@ -156,4 +165,4 @@ export {
156
165
  CalendarSurface,
157
166
  Calendar
158
167
  };
159
- //# sourceMappingURL=chunk-EFN32TNK.js.map
168
+ //# sourceMappingURL=chunk-RCWVBOO6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/calendar.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { calendarKeys, connectCalendar, createCalendar, createStore, formatDate, getNumberFormatter, resolveWeekStart, sameDate, syncCalendar, temporal, transitionCalendar, translations, weeksInMonthView, type CalendarEvent, type CalendarOptions, type PlainDate } from \"chrona-core\";\nimport { Part, composeEvent, type PartProps } from \"./part\";\nimport { useChronaConfig } from \"./provider\";\nimport { useFormReset, type HiddenInputProps } from \"./form\";\n\nexport interface CalendarProps extends CalendarOptions {\n defaultValue?: PlainDate | null;\n defaultFocusedValue?: PlainDate;\n onChange?: (value: PlainDate | null) => void;\n onSelect?: (value: PlainDate) => void;\n onFocusedValueChange?: (value: PlainDate) => void;\n id?: string;\n}\n\nexport function useCalendar(props: CalendarProps = {}) {\n const options = useChronaConfig(props);\n const generatedId = React.useId();\n const id = props.id ?? generatedId;\n const [store] = React.useState(() => createStore(createCalendar({ ...options, value: props.value !== undefined ? props.value : props.defaultValue, focusedValue: props.focusedValue ?? props.defaultFocusedValue })));\n const snapshot = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n // The store is the single source of truth; controlled props are reconciled into it by syncCalendar.\n const state = syncCalendar(snapshot, { ...options, value: props.value, focusedValue: props.focusedValue });\n React.useEffect(() => { store.setState(state); });\n const rootRef = React.useRef<HTMLElement | null>(null);\n const pendingFocus = React.useRef(false);\n const [announcement, setAnnouncement] = React.useState(\"\");\n\n React.useEffect(() => {\n if (pendingFocus.current) {\n pendingFocus.current = false;\n rootRef.current?.querySelector<HTMLElement>('[data-part=\"cell-trigger\"][tabindex=\"0\"]')?.focus();\n }\n });\n\n function send(event: CalendarEvent) {\n const dir = options.dir ?? (rootRef.current?.closest(\"[dir]\")?.getAttribute(\"dir\") === \"rtl\" ? \"rtl\" : \"ltr\");\n const result = transitionCalendar(state, event, { ...options, dir });\n store.setState(result.state);\n for (const effect of result.effects) {\n if (effect.type === \"focus\") {\n pendingFocus.current = true;\n if (!sameDate(effect.value, state.focusedValue)) props.onFocusedValueChange?.(effect.value);\n } else if (effect.type === \"change\") {\n props.onChange?.(effect.value);\n setAnnouncement(effect.value ? (options.translations?.selected ?? translations.selected)(formatDate(effect.value, options.locale, { dateStyle: \"full\" })) : \"\");\n } else {\n props.onSelect?.(effect.value);\n }\n }\n }\n\n return {\n state, options, send, rootRef, announcement,\n api: connectCalendar(state, { ...options, id, today: temporal().Now.plainDateISO(options.timeZone) }),\n months: Array.from({ length: options.numberOfMonths ?? 1 }, (_, index) => state.visibleMonth.add({ months: index })),\n };\n}\n\ntype CalendarContextValue = ReturnType<typeof useCalendar>;\nconst Context = React.createContext<CalendarContextValue | null>(null);\nconst MonthContext = React.createContext<PlainDate | null>(null);\n\nfunction useContext() {\n const value = React.useContext(Context);\n if (!value) throw new Error(\"Calendar parts must be inside Calendar.Root.\");\n return value;\n}\n\nexport function CalendarRoot({ children, asChild, className, style, ...props }: CalendarProps & Pick<PartProps, \"children\" | \"asChild\" | \"className\" | \"style\">) {\n const calendar = useCalendar(props);\n return <CalendarSurface calendar={calendar} id={props.id} asChild={asChild} className={className} style={style}>{children}</CalendarSurface>;\n}\n\nexport function CalendarSurface({ calendar, ...props }: PartProps & { calendar: CalendarContextValue }) {\n return <Context.Provider value={calendar}><Part {...calendar.api.getRootProps()} {...props} ref={calendar.rootRef} /></Context.Provider>;\n}\n\nconst Header = React.forwardRef<HTMLElement, PartProps>(function Header(props, ref) {\n return <Part {...props} ref={ref} data-scope=\"calendar\" data-part=\"header\" />;\n});\n\nconst Heading = React.forwardRef<HTMLElement, PartProps>(function Heading({ children, ...props }, ref) {\n const { months, options } = useContext();\n const month = React.useContext(MonthContext);\n return <Part as=\"h2\" {...props} ref={ref} data-scope=\"calendar\" data-part=\"heading\" aria-live=\"polite\" aria-atomic=\"true\">{children ?? (month ? [month] : months).map((date) => formatDate(date, options.locale, { month: \"long\", year: \"numeric\" })).join(options.translations?.rangeSeparator ?? translations.rangeSeparator)}</Part>;\n});\n\ntype ButtonProps = React.ComponentPropsWithoutRef<\"button\"> & { asChild?: boolean };\n\n/**\n * Paging buttons carry an `aria-label` but no text, so without a default they render as blank\n * chrome for sighted users. The arrow points the way the button pages in the resolved direction.\n */\nfunction Chevron({ towards }: { towards: \"start\" | \"end\" }) {\n const points = towards === \"start\" ? \"15 4 7 12 15 20\" : \"9 4 17 12 9 20\";\n return <svg aria-hidden=\"true\" focusable=\"false\" viewBox=\"0 0 24 24\" width=\"1em\" height=\"1em\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" data-scope=\"calendar\" data-part=\"chevron\"><polyline points={points} /></svg>;\n}\n\nconst PrevButton = React.forwardRef<HTMLElement, ButtonProps>(function PrevButton({ onClick, children, ...props }, ref) {\n const { api, send, options } = useContext();\n return <Part as=\"button\" {...props} {...api.getPrevButtonProps()} ref={ref} onClick={composeEvent(onClick, () => send({ type: \"PAGE\", direction: -1 }))}>{children ?? <Chevron towards={options.dir === \"rtl\" ? \"end\" : \"start\"} />}</Part>;\n});\n\nconst NextButton = React.forwardRef<HTMLElement, ButtonProps>(function NextButton({ onClick, children, ...props }, ref) {\n const { api, send, options } = useContext();\n return <Part as=\"button\" {...props} {...api.getNextButtonProps()} ref={ref} onClick={composeEvent(onClick, () => send({ type: \"PAGE\", direction: 1 }))}>{children ?? <Chevron towards={options.dir === \"rtl\" ? \"start\" : \"end\"} />}</Part>;\n});\n\nconst Grid = React.forwardRef<HTMLElement, PartProps & { monthIndex?: number }>(function Grid({ monthIndex = 0, children, ...props }, ref) {\n const { api, months } = useContext();\n const month = months[monthIndex];\n if (!month) throw new Error(\"Calendar.Grid monthIndex is outside numberOfMonths.\");\n return <MonthContext.Provider value={month}><Part {...props} {...api.getGridProps(month)} ref={ref}>{children}</Part></MonthContext.Provider>;\n});\n\nfunction useMonth() {\n const context = useContext();\n const month = React.useContext(MonthContext) ?? context.state.visibleMonth;\n return { ...context, month, weeks: weeksInMonthView(month.toPlainYearMonth(), resolveWeekStart(context.options.locale, context.options.firstDayOfWeek), context.options.fixedWeeks) };\n}\n\nexport interface Weekday { date: PlainDate; label: string }\n\nconst GridHeader = React.forwardRef<HTMLElement, Omit<PartProps, \"children\"> & { children?: (day: Weekday) => React.ReactNode }>(function GridHeader({ children, ...props }, ref) {\n const { weeks, options } = useMonth();\n return <Part {...props} ref={ref} role=\"row\" data-scope=\"calendar\" data-part=\"grid-header\">{weeks[0]!.map((date) => {\n const day = { date, label: formatDate(date, options.locale, { weekday: \"short\" }) };\n return <React.Fragment key={date.toString()}>{children ? children(day) : <HeaderCell day={day} />}</React.Fragment>;\n })}</Part>;\n});\n\nconst HeaderCell = React.forwardRef<HTMLElement, PartProps & { day: Weekday }>(function HeaderCell({ day, children, ...props }, ref) {\n const { options } = useContext();\n return <Part {...props} ref={ref} role=\"columnheader\" aria-label={formatDate(day.date, options.locale, { weekday: \"long\" })} data-scope=\"calendar\" data-part=\"header-cell\">{children ?? day.label}</Part>;\n});\n\nconst GridBody = React.forwardRef<HTMLElement, Omit<PartProps, \"children\"> & { children?: (date: PlainDate) => React.ReactNode }>(function GridBody({ children, ...props }, ref) {\n const { weeks } = useMonth();\n return <Part {...props} ref={ref} role=\"rowgroup\" data-scope=\"calendar\" data-part=\"grid-body\">{weeks.map((week) => <div key={week[0]!.toString()} role=\"row\" data-scope=\"calendar\" data-part=\"row\">{week.map((date) => <React.Fragment key={date.toString()}>{children ? children(date) : <Cell date={date} />}</React.Fragment>)}</div>)}</Part>;\n});\n\nconst CellContext = React.createContext<PlainDate | null>(null);\n\nconst CellTrigger = React.forwardRef<HTMLElement, ButtonProps>(function CellTrigger({ children, onClick, onKeyDown, onFocus, ...props }, ref) {\n const { api, send, month, options } = useMonth();\n const date = React.useContext(CellContext);\n if (!date) throw new Error(\"Calendar.CellTrigger must be inside Calendar.Cell.\");\n // aria-disabled instead of native disabled keeps out-of-range dates discoverable by screen readers.\n return <Part as=\"button\" {...props} {...api.getCellTriggerProps(date, month)} ref={ref}\n onFocus={composeEvent(onFocus, () => { if (!options.disabled) send({ type: \"FOCUS\", date }); })}\n onClick={composeEvent(onClick, () => send({ type: \"SELECT\", date }))}\n onKeyDown={composeEvent(onKeyDown, (event) => {\n if (!calendarKeys.has(event.key) || event.altKey || event.ctrlKey || event.metaKey) return;\n event.preventDefault();\n send({ type: \"KEY_DOWN\", key: event.key, shiftKey: event.shiftKey });\n })}>{children ?? getNumberFormatter(options.locale, { useGrouping: false }).format(date.day)}</Part>;\n});\n\n/** The grid semantics live on the cell; the button inside it stays a button. */\nconst Cell = React.forwardRef<HTMLElement, PartProps & { date: PlainDate }>(function Cell({ date, children, ...props }, ref) {\n const { api, month } = useMonth();\n return <CellContext.Provider value={date}><Part {...props} {...api.getCellProps(date, month)} ref={ref}>{children ?? <CellTrigger />}</Part></CellContext.Provider>;\n});\n\nconst LiveRegion = React.forwardRef<HTMLElement, PartProps>(function LiveRegion(props, ref) {\n const { announcement } = useContext();\n return <Part {...props} ref={ref} role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" data-scope=\"calendar\" data-part=\"live-region\">{announcement}</Part>;\n});\n\nconst ClearButton = React.forwardRef<HTMLElement, ButtonProps>(function ClearButton({ onClick, ...props }, ref) {\n const { options, send, state } = useContext();\n return <Part as=\"button\" {...props} ref={ref} type=\"button\" data-scope=\"calendar\" data-part=\"clear-button\" aria-label={options.translations?.clear ?? translations.clear} disabled={options.disabled || options.readOnly || state.value === null} onClick={composeEvent(onClick, () => send({ type: \"CLEAR\" }))} />;\n});\n\nfunction HiddenInput(props: HiddenInputProps) {\n const { state, options, send } = useContext();\n const input = React.useRef<HTMLInputElement>(null);\n useFormReset(input, props.form, () => send({ type: \"RESET\", value: options.defaultValue ?? null }));\n return <input {...props} ref={input} type=\"hidden\" disabled={options.disabled || props.disabled} value={state.value?.toString() ?? \"\"} data-scope=\"calendar\" data-part=\"hidden-input\" />;\n}\n\nexport const Calendar = { Root: CalendarRoot, Header, Heading, PrevButton, NextButton, Grid, GridHeader, HeaderCell, GridBody, Cell, CellTrigger, LiveRegion, ClearButton, HiddenInput };"],"mappings":"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","names":["useContext","Header","Heading","PrevButton","NextButton","Grid","GridHeader","HeaderCell","GridBody","CellTrigger","Cell","LiveRegion","ClearButton"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createFieldComponents,
3
3
  useField
4
- } from "./chunk-VSD2IX3U.js";
4
+ } from "./chunk-JNQXKZO3.js";
5
5
 
6
6
  // src/time-field.tsx
7
7
  var TimeField = createFieldComponents("time");
@@ -13,4 +13,4 @@ export {
13
13
  TimeField,
14
14
  useTimeField
15
15
  };
16
- //# sourceMappingURL=chunk-6QRNDYNF.js.map
16
+ //# sourceMappingURL=chunk-ROJQDSGQ.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  DateField
3
- } from "./chunk-ZN4FZDUQ.js";
3
+ } from "./chunk-2GZMCFFY.js";
4
4
  import {
5
5
  Calendar
6
- } from "./chunk-EFN32TNK.js";
6
+ } from "./chunk-RCWVBOO6.js";
7
7
  import {
8
8
  Part,
9
9
  composeEvent,
@@ -55,13 +55,19 @@ var Label = React.forwardRef(function Label2(props, ref) {
55
55
  }, [registerLabel]);
56
56
  return /* @__PURE__ */ jsx(DateField.Label, { ...props, ref });
57
57
  });
58
- var Trigger = React.forwardRef(function Trigger2({ onClick, ...props }, ref) {
58
+ function CalendarGlyph() {
59
+ return /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "data-scope": "date-picker", "data-part": "trigger-icon", children: [
60
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "5", width: "18", height: "16", rx: "2" }),
61
+ /* @__PURE__ */ jsx("path", { d: "M3 10h18M8 3v4M16 3v4" })
62
+ ] });
63
+ }
64
+ var Trigger = React.forwardRef(function Trigger2({ onClick, children, ...props }, ref) {
59
65
  const picker = usePicker();
60
66
  return /* @__PURE__ */ jsx(Part, { as: "button", ...props, type: "button", ref: (node) => {
61
67
  picker.trigger.current = node;
62
68
  if (typeof ref === "function") ref(node);
63
69
  else if (ref) ref.current = node;
64
- }, "aria-label": props["aria-label"] ?? picker.props.translations?.chooseDate ?? translations.chooseDate, "aria-haspopup": "dialog", "aria-expanded": picker.open, "aria-controls": `${picker.id}-dialog`, disabled: picker.props.disabled, "data-scope": "date-picker", "data-part": "trigger", onClick: composeEvent(onClick, () => picker.send({ type: "TOGGLE" })) });
70
+ }, "aria-label": props["aria-label"] ?? picker.props.translations?.chooseDate ?? translations.chooseDate, "aria-haspopup": "dialog", "aria-expanded": picker.open, "aria-controls": `${picker.id}-dialog`, disabled: picker.props.disabled, "data-scope": "date-picker", "data-part": "trigger", onClick: composeEvent(onClick, () => picker.send({ type: "TOGGLE" })), children: children ?? /* @__PURE__ */ jsx(CalendarGlyph, {}) });
65
71
  });
66
72
  var Popover = React.forwardRef(function Popover2({ children, anchored = true, onCancel, onClose, onKeyDown, ...props }, ref) {
67
73
  const picker = usePicker();
@@ -74,7 +80,7 @@ var Popover = React.forwardRef(function Popover2({ children, anchored = true, on
74
80
  if (picker.open && !element.open) {
75
81
  if (picker.props.modal === false) element.show();
76
82
  else element.showModal();
77
- element.querySelector('[data-part="cell"][tabindex="0"]')?.focus();
83
+ element.querySelector('[data-part="cell-trigger"][tabindex="0"]')?.focus();
78
84
  } else if (!picker.open && element.open) {
79
85
  element.close();
80
86
  picker.trigger.current?.focus();
@@ -157,6 +163,8 @@ var Popover = React.forwardRef(function Popover2({ children, anchored = true, on
157
163
  element.ownerDocument.addEventListener("pointerdown", dismiss);
158
164
  return () => element.ownerDocument.removeEventListener("pointerdown", dismiss);
159
165
  }, [picker.open]);
166
+ const labelledBy = props["aria-labelledby"] ?? (props["aria-label"] || !picker.labelled ? void 0 : `${picker.id}-field-label`);
167
+ const label = props["aria-label"] ?? (labelledBy === void 0 ? picker.props.translations?.chooseDate ?? translations.chooseDate : void 0);
160
168
  return /* @__PURE__ */ jsx(
161
169
  "dialog",
162
170
  {
@@ -167,8 +175,8 @@ var Popover = React.forwardRef(function Popover2({ children, anchored = true, on
167
175
  else if (ref) ref.current = node;
168
176
  },
169
177
  id: `${picker.id}-dialog`,
170
- "aria-label": props["aria-label"] ?? picker.props.translations?.chooseDate ?? translations.chooseDate,
171
- "aria-labelledby": props["aria-labelledby"] ?? (props["aria-label"] || !picker.labelled ? void 0 : `${picker.id}-field-label`),
178
+ "aria-label": label,
179
+ "aria-labelledby": labelledBy,
172
180
  "aria-modal": picker.props.modal !== false || void 0,
173
181
  "data-scope": "date-picker",
174
182
  "data-part": "popover",
@@ -208,4 +216,4 @@ export {
208
216
  useDatePicker,
209
217
  DatePicker
210
218
  };
211
- //# sourceMappingURL=chunk-5426MN2K.js.map
219
+ //# sourceMappingURL=chunk-U4LLSRIH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/date-picker.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { computeAnchorPosition, containTabFocus, transitionPicker, translations, type PlainDate, type PickerEvent } from \"chrona-core\";\nimport { Calendar, type CalendarProps } from \"./calendar\";\nimport { DateField, type DateFieldProps } from \"./date-field\";\nimport { Part, composeEvent, type PartProps } from \"./part\";\nimport { useChronaConfig } from \"./provider\";\n\nexport interface DatePickerProps extends DateFieldProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n modal?: boolean;\n timeZone?: string;\n firstDayOfWeek?: number;\n fixedWeeks?: boolean;\n numberOfMonths?: number;\n pagedNavigation?: boolean;\n}\n\ninterface PickerContext {\n props: DatePickerProps;\n options: DatePickerProps;\n state: { value: PlainDate | null; open: boolean };\n id: string;\n value: PlainDate | null;\n change: (value: PlainDate | null) => void;\n open: boolean;\n send: (event: PickerEvent) => void;\n trigger: { current: HTMLElement | null };\n labelled: boolean;\n registerLabel: (present: boolean) => void;\n}\n\nconst Context = React.createContext<PickerContext | null>(null);\nfunction usePicker() {\n const value = React.useContext(Context);\n if (!value) throw new Error(\"DatePicker parts must be inside DatePicker.Root.\");\n return value;\n}\n\nfunction Root({ children, asChild, className, style, ...input }: DatePickerProps & Pick<PartProps, \"children\" | \"asChild\" | \"className\" | \"style\">) {\n const picker = useDatePicker(input);\n return <Context.Provider value={picker}><Part asChild={asChild} className={className} style={style} dir={picker.props.dir} data-scope=\"date-picker\" data-part=\"root\"><DateField.Root {...picker.props} id={`${picker.id}-field`} value={picker.value} onChange={picker.change}>{children}</DateField.Root></Part></Context.Provider>;\n}\n\nexport function useDatePicker(input: DatePickerProps = {}): PickerContext {\n const props = useChronaConfig(input);\n const generatedId = React.useId();\n const id = props.id ?? generatedId;\n const [uncontrolledValue, setValue] = React.useState(props.defaultValue ?? null);\n const [uncontrolledOpen, setOpen] = React.useState(props.defaultOpen ?? false);\n const value = props.value === undefined ? uncontrolledValue : props.value;\n const open = props.open ?? uncontrolledOpen;\n const trigger = React.useRef<HTMLElement | null>(null);\n const [labelled, registerLabel] = React.useState(false);\n function change(next: PlainDate | null) {\n if (props.value === undefined) setValue(next);\n props.onChange?.(next);\n }\n function send(event: PickerEvent) {\n const result = transitionPicker({ open }, event, props);\n for (const effect of result.effects) if (effect.type === \"openChange\") {\n if (props.open === undefined) setOpen(effect.open);\n props.onOpenChange?.(effect.open);\n }\n }\n return { props, options: props, state: { value, open }, id, value, change, open, send, trigger, labelled, registerLabel };\n}\n\nconst Label = React.forwardRef<HTMLElement, PartProps>(function Label(props, ref) {\n const { registerLabel } = usePicker();\n React.useEffect(() => {\n registerLabel(true);\n return () => registerLabel(false);\n }, [registerLabel]);\n return <DateField.Label {...props} ref={ref} />;\n});\n\n/** Like the paging buttons, the trigger is labelled but has no text of its own to show. */\nfunction CalendarGlyph() {\n return <svg aria-hidden=\"true\" focusable=\"false\" viewBox=\"0 0 24 24\" width=\"1em\" height=\"1em\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" data-scope=\"date-picker\" data-part=\"trigger-icon\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"M3 10h18M8 3v4M16 3v4\" /></svg>;\n}\n\nconst Trigger = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<\"button\"> & { asChild?: boolean }>(function Trigger({ onClick, children, ...props }, ref) {\n const picker = usePicker();\n return <Part as=\"button\" {...props} type=\"button\" ref={(node) => {\n picker.trigger.current = node;\n if (typeof ref === \"function\") ref(node); else if (ref) ref.current = node;\n }} aria-label={props[\"aria-label\"] ?? picker.props.translations?.chooseDate ?? translations.chooseDate} aria-haspopup=\"dialog\" aria-expanded={picker.open} aria-controls={`${picker.id}-dialog`} disabled={picker.props.disabled} data-scope=\"date-picker\" data-part=\"trigger\" onClick={composeEvent(onClick, () => picker.send({ type: \"TOGGLE\" }))}>{children ?? <CalendarGlyph />}</Part>;\n});\n\nconst Popover = React.forwardRef<HTMLDialogElement, Omit<React.ComponentPropsWithoutRef<\"dialog\">, \"open\"> & { anchored?: boolean }>(function Popover({ children, anchored = true, onCancel, onClose, onKeyDown, ...props }, ref) {\n const picker = usePicker();\n const dialog = React.useRef<HTMLDialogElement | null>(null);\n const latest = React.useRef(picker);\n latest.current = picker;\n\n React.useEffect(() => {\n const element = dialog.current;\n if (!element) return;\n if (picker.open && !element.open) {\n if (picker.props.modal === false) element.show(); else element.showModal();\n element.querySelector<HTMLElement>('[data-part=\"cell-trigger\"][tabindex=\"0\"]')?.focus();\n } else if (!picker.open && element.open) {\n element.close();\n picker.trigger.current?.focus();\n }\n }, [picker.open, picker.props.modal, picker.trigger]);\n\n React.useEffect(() => {\n if (!picker.open || !anchored) return;\n const element = dialog.current;\n const anchor = picker.trigger.current;\n const window = element?.ownerDocument.defaultView;\n if (!element || !anchor || !window) return;\n const properties = [\"position\", \"margin\", \"top\", \"left\", \"max-width\", \"max-height\", \"min-width\", \"min-height\", \"box-sizing\", \"overflow\"];\n const original = properties.map((property) => ({ property, value: element.style.getPropertyValue(property), priority: element.style.getPropertyPriority(property) }));\n const originalPlacement = element.getAttribute(\"data-placement\");\n const position = () => {\n const viewport = window.visualViewport;\n const width = viewport?.width ?? element.ownerDocument.documentElement.clientWidth;\n const height = viewport?.height ?? element.ownerDocument.documentElement.clientHeight;\n const offsetTop = viewport?.offsetTop ?? 0;\n const offsetLeft = viewport?.offsetLeft ?? 0;\n Object.assign(element.style, {\n position: \"fixed\", margin: \"0\", boxSizing: \"border-box\", overflow: \"auto\",\n minWidth: \"0\", minHeight: \"0\", maxWidth: `${Math.max(0, width - 8)}px`, maxHeight: `${Math.max(0, height - 8)}px`,\n });\n const rect = anchor.getBoundingClientRect();\n const { top, left, placement } = computeAnchorPosition(\n { top: rect.top - offsetTop, left: rect.left - offsetLeft, width: rect.width, height: rect.height },\n { width: element.offsetWidth, height: element.offsetHeight }, { width, height },\n );\n Object.assign(element.style, { top: `${top + offsetTop}px`, left: `${left + offsetLeft}px` });\n element.setAttribute(\"data-placement\", placement);\n };\n position();\n let frame: number | undefined;\n const schedulePosition = () => {\n if (frame !== undefined) return;\n frame = window.requestAnimationFrame(() => {\n frame = undefined;\n position();\n });\n };\n const observer = window.ResizeObserver ? new window.ResizeObserver(schedulePosition) : undefined;\n observer?.observe(element);\n observer?.observe(anchor);\n window.addEventListener(\"resize\", schedulePosition);\n window.addEventListener(\"scroll\", schedulePosition, true);\n window.visualViewport?.addEventListener(\"resize\", schedulePosition);\n window.visualViewport?.addEventListener(\"scroll\", schedulePosition);\n return () => {\n if (frame !== undefined) window.cancelAnimationFrame(frame);\n observer?.disconnect();\n window.removeEventListener(\"resize\", schedulePosition);\n window.removeEventListener(\"scroll\", schedulePosition, true);\n window.visualViewport?.removeEventListener(\"resize\", schedulePosition);\n window.visualViewport?.removeEventListener(\"scroll\", schedulePosition);\n for (const { property, value, priority } of original) {\n if (value) element.style.setProperty(property, value, priority);\n else element.style.removeProperty(property);\n }\n if (originalPlacement === null) element.removeAttribute(\"data-placement\");\n else element.setAttribute(\"data-placement\", originalPlacement);\n };\n }, [picker.open, anchored, picker.trigger]);\n\n React.useEffect(() => {\n const element = dialog.current;\n if (!picker.open || !element) return;\n const dismiss = (event: PointerEvent) => {\n if (!(event.target instanceof Node) || latest.current.trigger.current?.contains(event.target)) return;\n const rect = element.getBoundingClientRect();\n const onBackdrop = event.target === element && (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom);\n if (!element.contains(event.target) || onBackdrop) latest.current.send({ type: \"CLOSE\" });\n };\n element.ownerDocument.addEventListener(\"pointerdown\", dismiss);\n return () => element.ownerDocument.removeEventListener(\"pointerdown\", dismiss);\n }, [picker.open]);\n\n // aria-labelledby wins wherever both are present, so the fallback name is only applied when\n // nothing else names the dialog.\n const labelledBy = props[\"aria-labelledby\"] ?? (props[\"aria-label\"] || !picker.labelled ? undefined : `${picker.id}-field-label`);\n const label = props[\"aria-label\"] ?? (labelledBy === undefined ? picker.props.translations?.chooseDate ?? translations.chooseDate : undefined);\n\n return <dialog {...props} ref={(node) => {\n dialog.current = node;\n if (typeof ref === \"function\") ref(node); else if (ref) ref.current = node;\n }} id={`${picker.id}-dialog`} aria-label={label} aria-labelledby={labelledBy} aria-modal={picker.props.modal !== false || undefined} data-scope=\"date-picker\" data-part=\"popover\"\n onKeyDown={composeEvent(onKeyDown, (event) => { if (picker.props.modal !== false) containTabFocus(event.currentTarget, event); })}\n onCancel={(event) => { onCancel?.(event); const canceled = event.defaultPrevented; event.preventDefault(); if (!canceled) picker.send({ type: \"CLOSE\" }); }}\n onClose={composeEvent(onClose, () => { if (picker.open) picker.send({ type: \"CLOSE\" }); })}>{picker.open ? children : null}</dialog>;\n});\n\nfunction PickerCalendar({ children, ...props }: Omit<CalendarProps, \"value\" | \"defaultValue\" | \"onChange\"> & Pick<PartProps, \"children\" | \"className\" | \"style\">) {\n const picker = usePicker();\n return <Calendar.Root {...picker.props} {...props} value={picker.value} onChange={picker.change} onSelect={() => picker.send({ type: \"SELECT\" })}>{children ?? <><Calendar.Header><Calendar.PrevButton /><Calendar.Heading /><Calendar.NextButton /></Calendar.Header><Calendar.Grid><Calendar.GridHeader /><Calendar.GridBody /></Calendar.Grid></>}</Calendar.Root>;\n}\n\nexport const DatePicker = { Root, Label, Field: DateField.Field, Segment: DateField.Segment, HiddenInput: DateField.HiddenInput, ClearButton: DateField.ClearButton, LiveRegion: DateField.LiveRegion, Trigger, Popover, Calendar: PickerCalendar };"],"mappings":"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","names":["Label","Trigger","Popover"]}
@@ -1,7 +1,7 @@
1
1
  import { P as PartProps, H as HiddenInputProps, C as ChronaConfig } from './form-BCAGbNh-.js';
2
2
  import * as chrona_core from 'chrona-core';
3
3
  import * as React from 'react';
4
- import { F as FieldProps } from './field-CQjoX8QG.js';
4
+ import { F as FieldProps } from './field-DayikvR6.js';
5
5
 
6
6
  type DateFieldProps = FieldProps<"date">;
7
7
  declare const DateField: {
@@ -12,7 +12,7 @@ declare const DateField: {
12
12
  Field: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
13
13
  asChild?: boolean;
14
14
  } & React.RefAttributes<HTMLElement>>;
15
- Segment: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "value" | "defaultValue" | "onChange" | "children" | "type"> & {
15
+ Segment: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "children" | "defaultValue" | "onChange" | "value" | "type"> & {
16
16
  type: chrona_core.SegmentType;
17
17
  } & React.RefAttributes<HTMLInputElement>>;
18
18
  HiddenInput: (props: HiddenInputProps) => React.JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  DateField,
3
3
  useDateField
4
- } from "./chunk-ZN4FZDUQ.js";
5
- import "./chunk-VSD2IX3U.js";
4
+ } from "./chunk-2GZMCFFY.js";
5
+ import "./chunk-JNQXKZO3.js";
6
6
  import "./chunk-GN2YCKFZ.js";
7
7
  export {
8
8
  DateField,
@@ -5,7 +5,7 @@ import * as React from 'react';
5
5
  import { CalendarProps } from './calendar.js';
6
6
  import { DateFieldProps } from './date-field.js';
7
7
  import 'temporal-spec';
8
- import './field-CQjoX8QG.js';
8
+ import './field-DayikvR6.js';
9
9
 
10
10
  interface DatePickerProps extends DateFieldProps {
11
11
  open?: boolean;
@@ -47,7 +47,7 @@ declare const DatePicker: {
47
47
  Field: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
48
48
  asChild?: boolean;
49
49
  } & React.RefAttributes<HTMLElement>>;
50
- Segment: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "value" | "defaultValue" | "onChange" | "children" | "type"> & {
50
+ Segment: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "children" | "defaultValue" | "onChange" | "value" | "type"> & {
51
51
  type: chrona_core.SegmentType;
52
52
  } & React.RefAttributes<HTMLInputElement>>;
53
53
  HiddenInput: (props: HiddenInputProps) => React.JSX.Element;
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  DatePicker,
3
3
  useDatePicker
4
- } from "./chunk-5426MN2K.js";
5
- import "./chunk-ZN4FZDUQ.js";
6
- import "./chunk-EFN32TNK.js";
7
- import "./chunk-VSD2IX3U.js";
4
+ } from "./chunk-U4LLSRIH.js";
5
+ import "./chunk-2GZMCFFY.js";
6
+ import "./chunk-RCWVBOO6.js";
7
+ import "./chunk-JNQXKZO3.js";
8
8
  import "./chunk-GN2YCKFZ.js";
9
9
  export {
10
10
  DatePicker,
@@ -1,9 +1,9 @@
1
- import { FieldKind, FieldOptions, FieldValue } from 'chrona-core';
1
+ import { FieldKind, FieldOptions, FieldValue, FieldInvalidReason } from 'chrona-core';
2
2
 
3
3
  interface FieldProps<Kind extends FieldKind> extends FieldOptions<Kind> {
4
4
  defaultValue?: FieldValue<Kind> | null;
5
5
  onChange?: (value: FieldValue<Kind> | null) => void;
6
- onInvalid?: (reason: "range" | "unavailable") => void;
6
+ onInvalid?: (reason: FieldInvalidReason) => void;
7
7
  id?: string;
8
8
  describedBy?: string;
9
9
  }
package/dist/index.d.ts CHANGED
@@ -7,4 +7,4 @@ export { RangeCalendar, RangeCalendarProps, useRangeCalendar } from './range-cal
7
7
  import 'temporal-spec';
8
8
  import 'chrona-core';
9
9
  import 'react';
10
- import './field-CQjoX8QG.js';
10
+ import './field-DayikvR6.js';
package/dist/index.js CHANGED
@@ -1,25 +1,25 @@
1
1
  import {
2
2
  DatePicker,
3
3
  useDatePicker
4
- } from "./chunk-5426MN2K.js";
4
+ } from "./chunk-U4LLSRIH.js";
5
5
  import {
6
6
  DateField,
7
7
  useDateField
8
- } from "./chunk-ZN4FZDUQ.js";
8
+ } from "./chunk-2GZMCFFY.js";
9
9
  import {
10
10
  RangeCalendar,
11
11
  useRangeCalendar
12
- } from "./chunk-XNVORQQ5.js";
12
+ } from "./chunk-QQANBK5G.js";
13
13
  import {
14
14
  Calendar,
15
15
  CalendarRoot,
16
16
  useCalendar
17
- } from "./chunk-EFN32TNK.js";
17
+ } from "./chunk-RCWVBOO6.js";
18
18
  import {
19
19
  TimeField,
20
20
  useTimeField
21
- } from "./chunk-6QRNDYNF.js";
22
- import "./chunk-VSD2IX3U.js";
21
+ } from "./chunk-ROJQDSGQ.js";
22
+ import "./chunk-JNQXKZO3.js";
23
23
  import {
24
24
  ChronaProvider
25
25
  } from "./chunk-GN2YCKFZ.js";
@@ -26,25 +26,43 @@ declare function useRangeCalendar(input?: RangeCalendarProps): {
26
26
  api: {
27
27
  getCellProps: (date: PlainDate, month?: PlainDate) => {
28
28
  "data-scope": string;
29
- "aria-selected": boolean;
30
29
  "data-selected": string | undefined;
31
30
  "data-in-range": string | undefined;
32
31
  "data-range-start": string | undefined;
33
32
  "data-range-end": string | undefined;
34
33
  "data-preview": string | undefined;
35
34
  "data-invalid": string | undefined;
36
- id: string;
35
+ "aria-selected": boolean;
36
+ "data-date": string;
37
+ "data-focused": string | undefined;
38
+ "data-disabled": string | undefined;
39
+ "data-unavailable": string | undefined;
40
+ "data-outside-month": string | undefined;
41
+ "data-today": string | undefined;
37
42
  role: "gridcell";
38
- tabIndex: number;
39
- "aria-label": string;
40
43
  "aria-disabled": true | undefined;
41
- "aria-current": "date" | undefined;
44
+ "data-part": string;
45
+ };
46
+ getCellTriggerProps: (date: PlainDate, month?: PlainDate) => {
47
+ "data-scope": string;
48
+ "data-selected": string | undefined;
49
+ "data-in-range": string | undefined;
50
+ "data-range-start": string | undefined;
51
+ "data-range-end": string | undefined;
52
+ "data-preview": string | undefined;
53
+ "data-invalid": string | undefined;
42
54
  "data-date": string;
43
55
  "data-focused": string | undefined;
44
56
  "data-disabled": string | undefined;
45
57
  "data-unavailable": string | undefined;
46
58
  "data-outside-month": string | undefined;
47
59
  "data-today": string | undefined;
60
+ id: string;
61
+ type: "button";
62
+ tabIndex: number;
63
+ "aria-label": string;
64
+ "aria-disabled": true | undefined;
65
+ "aria-current": "date" | undefined;
48
66
  "data-part": string;
49
67
  };
50
68
  getRootProps: () => {
@@ -84,25 +102,43 @@ declare function useRangeCalendar(input?: RangeCalendarProps): {
84
102
  api: {
85
103
  getCellProps: (date: PlainDate, month?: PlainDate) => {
86
104
  "data-scope": string;
87
- "aria-selected": boolean;
88
105
  "data-selected": string | undefined;
89
106
  "data-in-range": string | undefined;
90
107
  "data-range-start": string | undefined;
91
108
  "data-range-end": string | undefined;
92
109
  "data-preview": string | undefined;
93
110
  "data-invalid": string | undefined;
94
- id: string;
111
+ "aria-selected": boolean;
112
+ "data-date": string;
113
+ "data-focused": string | undefined;
114
+ "data-disabled": string | undefined;
115
+ "data-unavailable": string | undefined;
116
+ "data-outside-month": string | undefined;
117
+ "data-today": string | undefined;
95
118
  role: "gridcell";
96
- tabIndex: number;
97
- "aria-label": string;
98
119
  "aria-disabled": true | undefined;
99
- "aria-current": "date" | undefined;
120
+ "data-part": string;
121
+ };
122
+ getCellTriggerProps: (date: PlainDate, month?: PlainDate) => {
123
+ "data-scope": string;
124
+ "data-selected": string | undefined;
125
+ "data-in-range": string | undefined;
126
+ "data-range-start": string | undefined;
127
+ "data-range-end": string | undefined;
128
+ "data-preview": string | undefined;
129
+ "data-invalid": string | undefined;
100
130
  "data-date": string;
101
131
  "data-focused": string | undefined;
102
132
  "data-disabled": string | undefined;
103
133
  "data-unavailable": string | undefined;
104
134
  "data-outside-month": string | undefined;
105
135
  "data-today": string | undefined;
136
+ id: string;
137
+ type: "button";
138
+ tabIndex: number;
139
+ "aria-label": string;
140
+ "aria-disabled": true | undefined;
141
+ "aria-current": "date" | undefined;
106
142
  "data-part": string;
107
143
  };
108
144
  getRootProps: () => {
@@ -149,7 +185,7 @@ declare function HiddenInput({ name, form, id, disabled, ...inputProps }: Hidden
149
185
  }): React.JSX.Element;
150
186
  declare const RangeCalendar: {
151
187
  Root: typeof Root;
152
- Cell: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
188
+ Cell: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLElement> & {
153
189
  asChild?: boolean;
154
190
  } & {
155
191
  date: PlainDate;
@@ -189,6 +225,9 @@ declare const RangeCalendar: {
189
225
  } & {
190
226
  day: Weekday;
191
227
  } & React.RefAttributes<HTMLElement>>;
228
+ CellTrigger: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
229
+ asChild?: boolean;
230
+ } & React.RefAttributes<HTMLElement>>;
192
231
  };
193
232
 
194
233
  export { RangeCalendar, type RangeCalendarProps, useRangeCalendar };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  RangeCalendar,
3
3
  useRangeCalendar
4
- } from "./chunk-XNVORQQ5.js";
5
- import "./chunk-EFN32TNK.js";
4
+ } from "./chunk-QQANBK5G.js";
5
+ import "./chunk-RCWVBOO6.js";
6
6
  import "./chunk-GN2YCKFZ.js";
7
7
  export {
8
8
  RangeCalendar,
@@ -1,7 +1,7 @@
1
1
  import { P as PartProps, H as HiddenInputProps, C as ChronaConfig } from './form-BCAGbNh-.js';
2
2
  import * as chrona_core from 'chrona-core';
3
3
  import * as React from 'react';
4
- import { F as FieldProps } from './field-CQjoX8QG.js';
4
+ import { F as FieldProps } from './field-DayikvR6.js';
5
5
 
6
6
  type TimeFieldProps = FieldProps<"time">;
7
7
  declare const TimeField: {
@@ -12,7 +12,7 @@ declare const TimeField: {
12
12
  Field: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & {
13
13
  asChild?: boolean;
14
14
  } & React.RefAttributes<HTMLElement>>;
15
- Segment: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "value" | "defaultValue" | "onChange" | "children" | "type"> & {
15
+ Segment: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "children" | "defaultValue" | "onChange" | "value" | "type"> & {
16
16
  type: chrona_core.SegmentType;
17
17
  } & React.RefAttributes<HTMLInputElement>>;
18
18
  HiddenInput: (props: HiddenInputProps) => React.JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  TimeField,
3
3
  useTimeField
4
- } from "./chunk-6QRNDYNF.js";
5
- import "./chunk-VSD2IX3U.js";
4
+ } from "./chunk-ROJQDSGQ.js";
5
+ import "./chunk-JNQXKZO3.js";
6
6
  import "./chunk-GN2YCKFZ.js";
7
7
  export {
8
8
  TimeField,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrona-react",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Headless Temporal-native React date and time primitives",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -31,6 +31,7 @@
31
31
  "sideEffects": false,
32
32
  "files": [
33
33
  "dist",
34
+ "AGENTS.md",
34
35
  "LICENSE"
35
36
  ],
36
37
  "exports": {
@@ -60,7 +61,7 @@
60
61
  }
61
62
  },
62
63
  "dependencies": {
63
- "chrona-core": "^0.1.0"
64
+ "chrona-core": "^0.2.1"
64
65
  },
65
66
  "peerDependencies": {
66
67
  "react": ">=18.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/date-picker.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { computeAnchorPosition, containTabFocus, transitionPicker, translations, type PlainDate, type PickerEvent } from \"chrona-core\";\nimport { Calendar, type CalendarProps } from \"./calendar\";\nimport { DateField, type DateFieldProps } from \"./date-field\";\nimport { Part, composeEvent, type PartProps } from \"./part\";\nimport { useChronaConfig } from \"./provider\";\n\nexport interface DatePickerProps extends DateFieldProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n modal?: boolean;\n timeZone?: string;\n firstDayOfWeek?: number;\n fixedWeeks?: boolean;\n numberOfMonths?: number;\n pagedNavigation?: boolean;\n}\n\ninterface PickerContext {\n props: DatePickerProps;\n options: DatePickerProps;\n state: { value: PlainDate | null; open: boolean };\n id: string;\n value: PlainDate | null;\n change: (value: PlainDate | null) => void;\n open: boolean;\n send: (event: PickerEvent) => void;\n trigger: { current: HTMLElement | null };\n labelled: boolean;\n registerLabel: (present: boolean) => void;\n}\n\nconst Context = React.createContext<PickerContext | null>(null);\nfunction usePicker() {\n const value = React.useContext(Context);\n if (!value) throw new Error(\"DatePicker parts must be inside DatePicker.Root.\");\n return value;\n}\n\nfunction Root({ children, asChild, className, style, ...input }: DatePickerProps & Pick<PartProps, \"children\" | \"asChild\" | \"className\" | \"style\">) {\n const picker = useDatePicker(input);\n return <Context.Provider value={picker}><Part asChild={asChild} className={className} style={style} dir={picker.props.dir} data-scope=\"date-picker\" data-part=\"root\"><DateField.Root {...picker.props} id={`${picker.id}-field`} value={picker.value} onChange={picker.change}>{children}</DateField.Root></Part></Context.Provider>;\n}\n\nexport function useDatePicker(input: DatePickerProps = {}): PickerContext {\n const props = useChronaConfig(input);\n const generatedId = React.useId();\n const id = props.id ?? generatedId;\n const [uncontrolledValue, setValue] = React.useState(props.defaultValue ?? null);\n const [uncontrolledOpen, setOpen] = React.useState(props.defaultOpen ?? false);\n const value = props.value === undefined ? uncontrolledValue : props.value;\n const open = props.open ?? uncontrolledOpen;\n const trigger = React.useRef<HTMLElement | null>(null);\n const [labelled, registerLabel] = React.useState(false);\n function change(next: PlainDate | null) {\n if (props.value === undefined) setValue(next);\n props.onChange?.(next);\n }\n function send(event: PickerEvent) {\n const result = transitionPicker({ open }, event, props);\n for (const effect of result.effects) if (effect.type === \"openChange\") {\n if (props.open === undefined) setOpen(effect.open);\n props.onOpenChange?.(effect.open);\n }\n }\n return { props, options: props, state: { value, open }, id, value, change, open, send, trigger, labelled, registerLabel };\n}\n\nconst Label = React.forwardRef<HTMLElement, PartProps>(function Label(props, ref) {\n const { registerLabel } = usePicker();\n React.useEffect(() => {\n registerLabel(true);\n return () => registerLabel(false);\n }, [registerLabel]);\n return <DateField.Label {...props} ref={ref} />;\n});\n\nconst Trigger = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<\"button\"> & { asChild?: boolean }>(function Trigger({ onClick, ...props }, ref) {\n const picker = usePicker();\n return <Part as=\"button\" {...props} type=\"button\" ref={(node) => {\n picker.trigger.current = node;\n if (typeof ref === \"function\") ref(node); else if (ref) ref.current = node;\n }} aria-label={props[\"aria-label\"] ?? picker.props.translations?.chooseDate ?? translations.chooseDate} aria-haspopup=\"dialog\" aria-expanded={picker.open} aria-controls={`${picker.id}-dialog`} disabled={picker.props.disabled} data-scope=\"date-picker\" data-part=\"trigger\" onClick={composeEvent(onClick, () => picker.send({ type: \"TOGGLE\" }))} />;\n});\n\nconst Popover = React.forwardRef<HTMLDialogElement, Omit<React.ComponentPropsWithoutRef<\"dialog\">, \"open\"> & { anchored?: boolean }>(function Popover({ children, anchored = true, onCancel, onClose, onKeyDown, ...props }, ref) {\n const picker = usePicker();\n const dialog = React.useRef<HTMLDialogElement | null>(null);\n const latest = React.useRef(picker);\n latest.current = picker;\n\n React.useEffect(() => {\n const element = dialog.current;\n if (!element) return;\n if (picker.open && !element.open) {\n if (picker.props.modal === false) element.show(); else element.showModal();\n element.querySelector<HTMLElement>('[data-part=\"cell\"][tabindex=\"0\"]')?.focus();\n } else if (!picker.open && element.open) {\n element.close();\n picker.trigger.current?.focus();\n }\n }, [picker.open, picker.props.modal, picker.trigger]);\n\n React.useEffect(() => {\n if (!picker.open || !anchored) return;\n const element = dialog.current;\n const anchor = picker.trigger.current;\n const window = element?.ownerDocument.defaultView;\n if (!element || !anchor || !window) return;\n const properties = [\"position\", \"margin\", \"top\", \"left\", \"max-width\", \"max-height\", \"min-width\", \"min-height\", \"box-sizing\", \"overflow\"];\n const original = properties.map((property) => ({ property, value: element.style.getPropertyValue(property), priority: element.style.getPropertyPriority(property) }));\n const originalPlacement = element.getAttribute(\"data-placement\");\n const position = () => {\n const viewport = window.visualViewport;\n const width = viewport?.width ?? element.ownerDocument.documentElement.clientWidth;\n const height = viewport?.height ?? element.ownerDocument.documentElement.clientHeight;\n const offsetTop = viewport?.offsetTop ?? 0;\n const offsetLeft = viewport?.offsetLeft ?? 0;\n Object.assign(element.style, {\n position: \"fixed\", margin: \"0\", boxSizing: \"border-box\", overflow: \"auto\",\n minWidth: \"0\", minHeight: \"0\", maxWidth: `${Math.max(0, width - 8)}px`, maxHeight: `${Math.max(0, height - 8)}px`,\n });\n const rect = anchor.getBoundingClientRect();\n const { top, left, placement } = computeAnchorPosition(\n { top: rect.top - offsetTop, left: rect.left - offsetLeft, width: rect.width, height: rect.height },\n { width: element.offsetWidth, height: element.offsetHeight }, { width, height },\n );\n Object.assign(element.style, { top: `${top + offsetTop}px`, left: `${left + offsetLeft}px` });\n element.setAttribute(\"data-placement\", placement);\n };\n position();\n let frame: number | undefined;\n const schedulePosition = () => {\n if (frame !== undefined) return;\n frame = window.requestAnimationFrame(() => {\n frame = undefined;\n position();\n });\n };\n const observer = window.ResizeObserver ? new window.ResizeObserver(schedulePosition) : undefined;\n observer?.observe(element);\n observer?.observe(anchor);\n window.addEventListener(\"resize\", schedulePosition);\n window.addEventListener(\"scroll\", schedulePosition, true);\n window.visualViewport?.addEventListener(\"resize\", schedulePosition);\n window.visualViewport?.addEventListener(\"scroll\", schedulePosition);\n return () => {\n if (frame !== undefined) window.cancelAnimationFrame(frame);\n observer?.disconnect();\n window.removeEventListener(\"resize\", schedulePosition);\n window.removeEventListener(\"scroll\", schedulePosition, true);\n window.visualViewport?.removeEventListener(\"resize\", schedulePosition);\n window.visualViewport?.removeEventListener(\"scroll\", schedulePosition);\n for (const { property, value, priority } of original) {\n if (value) element.style.setProperty(property, value, priority);\n else element.style.removeProperty(property);\n }\n if (originalPlacement === null) element.removeAttribute(\"data-placement\");\n else element.setAttribute(\"data-placement\", originalPlacement);\n };\n }, [picker.open, anchored, picker.trigger]);\n\n React.useEffect(() => {\n const element = dialog.current;\n if (!picker.open || !element) return;\n const dismiss = (event: PointerEvent) => {\n if (!(event.target instanceof Node) || latest.current.trigger.current?.contains(event.target)) return;\n const rect = element.getBoundingClientRect();\n const onBackdrop = event.target === element && (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom);\n if (!element.contains(event.target) || onBackdrop) latest.current.send({ type: \"CLOSE\" });\n };\n element.ownerDocument.addEventListener(\"pointerdown\", dismiss);\n return () => element.ownerDocument.removeEventListener(\"pointerdown\", dismiss);\n }, [picker.open]);\n\n return <dialog {...props} ref={(node) => {\n dialog.current = node;\n if (typeof ref === \"function\") ref(node); else if (ref) ref.current = node;\n }} id={`${picker.id}-dialog`} aria-label={props[\"aria-label\"] ?? picker.props.translations?.chooseDate ?? translations.chooseDate} aria-labelledby={props[\"aria-labelledby\"] ?? (props[\"aria-label\"] || !picker.labelled ? undefined : `${picker.id}-field-label`)} aria-modal={picker.props.modal !== false || undefined} data-scope=\"date-picker\" data-part=\"popover\"\n onKeyDown={composeEvent(onKeyDown, (event) => { if (picker.props.modal !== false) containTabFocus(event.currentTarget, event); })}\n onCancel={(event) => { onCancel?.(event); const canceled = event.defaultPrevented; event.preventDefault(); if (!canceled) picker.send({ type: \"CLOSE\" }); }}\n onClose={composeEvent(onClose, () => { if (picker.open) picker.send({ type: \"CLOSE\" }); })}>{picker.open ? children : null}</dialog>;\n});\n\nfunction PickerCalendar({ children, ...props }: Omit<CalendarProps, \"value\" | \"defaultValue\" | \"onChange\"> & Pick<PartProps, \"children\" | \"className\" | \"style\">) {\n const picker = usePicker();\n return <Calendar.Root {...picker.props} {...props} value={picker.value} onChange={picker.change} onSelect={() => picker.send({ type: \"SELECT\" })}>{children ?? <><Calendar.Header><Calendar.PrevButton /><Calendar.Heading /><Calendar.NextButton /></Calendar.Header><Calendar.Grid><Calendar.GridHeader /><Calendar.GridBody /></Calendar.Grid></>}</Calendar.Root>;\n}\n\nexport const DatePicker = { Root, Label, Field: DateField.Field, Segment: DateField.Segment, HiddenInput: DateField.HiddenInput, ClearButton: DateField.ClearButton, LiveRegion: DateField.LiveRegion, Trigger, Popover, Calendar: PickerCalendar };"],"mappings":"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","names":["Label","Trigger","Popover"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/calendar.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { calendarKeys, connectCalendar, createCalendar, createStore, formatDate, getNumberFormatter, resolveWeekStart, sameDate, syncCalendar, temporal, transitionCalendar, translations, weeksInMonthView, type CalendarEvent, type CalendarOptions, type PlainDate } from \"chrona-core\";\nimport { Part, composeEvent, type PartProps } from \"./part\";\nimport { useChronaConfig } from \"./provider\";\nimport { useFormReset, type HiddenInputProps } from \"./form\";\n\nexport interface CalendarProps extends CalendarOptions {\n defaultValue?: PlainDate | null;\n defaultFocusedValue?: PlainDate;\n onChange?: (value: PlainDate | null) => void;\n onSelect?: (value: PlainDate) => void;\n onFocusedValueChange?: (value: PlainDate) => void;\n id?: string;\n}\n\nexport function useCalendar(props: CalendarProps = {}) {\n const options = useChronaConfig(props);\n const generatedId = React.useId();\n const id = props.id ?? generatedId;\n const [store] = React.useState(() => createStore(createCalendar({ ...options, value: props.value !== undefined ? props.value : props.defaultValue, focusedValue: props.focusedValue ?? props.defaultFocusedValue })));\n const snapshot = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n // The store is the single source of truth; controlled props are reconciled into it by syncCalendar.\n const state = syncCalendar(snapshot, { ...options, value: props.value, focusedValue: props.focusedValue });\n React.useEffect(() => { store.setState(state); });\n const rootRef = React.useRef<HTMLElement | null>(null);\n const pendingFocus = React.useRef(false);\n const [announcement, setAnnouncement] = React.useState(\"\");\n\n React.useEffect(() => {\n if (pendingFocus.current) {\n pendingFocus.current = false;\n rootRef.current?.querySelector<HTMLElement>('[data-part=\"cell\"][tabindex=\"0\"]')?.focus();\n }\n });\n\n function send(event: CalendarEvent) {\n const dir = options.dir ?? (rootRef.current?.closest(\"[dir]\")?.getAttribute(\"dir\") === \"rtl\" ? \"rtl\" : \"ltr\");\n const result = transitionCalendar(state, event, { ...options, dir });\n store.setState(result.state);\n for (const effect of result.effects) {\n if (effect.type === \"focus\") {\n pendingFocus.current = true;\n if (!sameDate(effect.value, state.focusedValue)) props.onFocusedValueChange?.(effect.value);\n } else if (effect.type === \"change\") {\n props.onChange?.(effect.value);\n setAnnouncement(effect.value ? (options.translations?.selected ?? translations.selected)(formatDate(effect.value, options.locale, { dateStyle: \"full\" })) : \"\");\n } else {\n props.onSelect?.(effect.value);\n }\n }\n }\n\n return {\n state, options, send, rootRef, announcement,\n api: connectCalendar(state, { ...options, id, today: temporal().Now.plainDateISO(options.timeZone) }),\n months: Array.from({ length: options.numberOfMonths ?? 1 }, (_, index) => state.visibleMonth.add({ months: index })),\n };\n}\n\ntype CalendarContextValue = ReturnType<typeof useCalendar>;\nconst Context = React.createContext<CalendarContextValue | null>(null);\nconst MonthContext = React.createContext<PlainDate | null>(null);\n\nfunction useContext() {\n const value = React.useContext(Context);\n if (!value) throw new Error(\"Calendar parts must be inside Calendar.Root.\");\n return value;\n}\n\nexport function CalendarRoot({ children, asChild, className, style, ...props }: CalendarProps & Pick<PartProps, \"children\" | \"asChild\" | \"className\" | \"style\">) {\n const calendar = useCalendar(props);\n return <CalendarSurface calendar={calendar} id={props.id} asChild={asChild} className={className} style={style}>{children}</CalendarSurface>;\n}\n\nexport function CalendarSurface({ calendar, ...props }: PartProps & { calendar: CalendarContextValue }) {\n return <Context.Provider value={calendar}><Part {...calendar.api.getRootProps()} {...props} ref={calendar.rootRef} /></Context.Provider>;\n}\n\nconst Header = React.forwardRef<HTMLElement, PartProps>(function Header(props, ref) {\n return <Part {...props} ref={ref} data-scope=\"calendar\" data-part=\"header\" />;\n});\n\nconst Heading = React.forwardRef<HTMLElement, PartProps>(function Heading({ children, ...props }, ref) {\n const { months, options } = useContext();\n const month = React.useContext(MonthContext);\n return <Part as=\"h2\" {...props} ref={ref} data-scope=\"calendar\" data-part=\"heading\" aria-live=\"polite\" aria-atomic=\"true\">{children ?? (month ? [month] : months).map((date) => formatDate(date, options.locale, { month: \"long\", year: \"numeric\" })).join(options.translations?.rangeSeparator ?? translations.rangeSeparator)}</Part>;\n});\n\ntype ButtonProps = React.ComponentPropsWithoutRef<\"button\"> & { asChild?: boolean };\n\nconst PrevButton = React.forwardRef<HTMLElement, ButtonProps>(function PrevButton({ onClick, ...props }, ref) {\n const { api, send } = useContext();\n return <Part as=\"button\" {...props} {...api.getPrevButtonProps()} ref={ref} onClick={composeEvent(onClick, () => send({ type: \"PAGE\", direction: -1 }))} />;\n});\n\nconst NextButton = React.forwardRef<HTMLElement, ButtonProps>(function NextButton({ onClick, ...props }, ref) {\n const { api, send } = useContext();\n return <Part as=\"button\" {...props} {...api.getNextButtonProps()} ref={ref} onClick={composeEvent(onClick, () => send({ type: \"PAGE\", direction: 1 }))} />;\n});\n\nconst Grid = React.forwardRef<HTMLElement, PartProps & { monthIndex?: number }>(function Grid({ monthIndex = 0, children, ...props }, ref) {\n const { api, months } = useContext();\n const month = months[monthIndex];\n if (!month) throw new Error(\"Calendar.Grid monthIndex is outside numberOfMonths.\");\n return <MonthContext.Provider value={month}><Part {...props} {...api.getGridProps(month)} ref={ref}>{children}</Part></MonthContext.Provider>;\n});\n\nfunction useMonth() {\n const context = useContext();\n const month = React.useContext(MonthContext) ?? context.state.visibleMonth;\n return { ...context, month, weeks: weeksInMonthView(month.toPlainYearMonth(), resolveWeekStart(context.options.locale, context.options.firstDayOfWeek), context.options.fixedWeeks) };\n}\n\nexport interface Weekday { date: PlainDate; label: string }\n\nconst GridHeader = React.forwardRef<HTMLElement, Omit<PartProps, \"children\"> & { children?: (day: Weekday) => React.ReactNode }>(function GridHeader({ children, ...props }, ref) {\n const { weeks, options } = useMonth();\n return <Part {...props} ref={ref} role=\"row\" data-scope=\"calendar\" data-part=\"grid-header\">{weeks[0]!.map((date) => {\n const day = { date, label: formatDate(date, options.locale, { weekday: \"short\" }) };\n return <React.Fragment key={date.toString()}>{children ? children(day) : <HeaderCell day={day} />}</React.Fragment>;\n })}</Part>;\n});\n\nconst HeaderCell = React.forwardRef<HTMLElement, PartProps & { day: Weekday }>(function HeaderCell({ day, children, ...props }, ref) {\n const { options } = useContext();\n return <Part {...props} ref={ref} role=\"columnheader\" aria-label={formatDate(day.date, options.locale, { weekday: \"long\" })} data-scope=\"calendar\" data-part=\"header-cell\">{children ?? day.label}</Part>;\n});\n\nconst GridBody = React.forwardRef<HTMLElement, Omit<PartProps, \"children\"> & { children?: (date: PlainDate) => React.ReactNode }>(function GridBody({ children, ...props }, ref) {\n const { weeks } = useMonth();\n return <Part {...props} ref={ref} role=\"rowgroup\" data-scope=\"calendar\" data-part=\"grid-body\">{weeks.map((week) => <div key={week[0]!.toString()} role=\"row\" data-scope=\"calendar\" data-part=\"row\">{week.map((date) => <React.Fragment key={date.toString()}>{children ? children(date) : <Cell date={date} />}</React.Fragment>)}</div>)}</Part>;\n});\n\nconst Cell = React.forwardRef<HTMLElement, ButtonProps & { date: PlainDate }>(function Cell({ date, children, onClick, onKeyDown, onFocus, ...props }, ref) {\n const { api, send, month, options } = useMonth();\n const cellProps = api.getCellProps(date, month);\n // aria-disabled instead of native disabled keeps out-of-range cells discoverable by screen readers.\n return <Part as=\"button\" {...props} {...cellProps} type=\"button\" ref={ref}\n onFocus={composeEvent(onFocus, () => { if (!options.disabled) send({ type: \"FOCUS\", date }); })}\n onClick={composeEvent(onClick, () => send({ type: \"SELECT\", date }))}\n onKeyDown={composeEvent(onKeyDown, (event) => {\n if (!calendarKeys.has(event.key) || event.altKey || event.ctrlKey || event.metaKey) return;\n event.preventDefault();\n send({ type: \"KEY_DOWN\", key: event.key, shiftKey: event.shiftKey });\n })}>{children ?? getNumberFormatter(options.locale, { useGrouping: false }).format(date.day)}</Part>;\n});\n\nconst LiveRegion = React.forwardRef<HTMLElement, PartProps>(function LiveRegion(props, ref) {\n const { announcement } = useContext();\n return <Part {...props} ref={ref} role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" data-scope=\"calendar\" data-part=\"live-region\">{announcement}</Part>;\n});\n\nconst ClearButton = React.forwardRef<HTMLElement, ButtonProps>(function ClearButton({ onClick, ...props }, ref) {\n const { options, send, state } = useContext();\n return <Part as=\"button\" {...props} ref={ref} type=\"button\" data-scope=\"calendar\" data-part=\"clear-button\" aria-label={options.translations?.clear ?? translations.clear} disabled={options.disabled || options.readOnly || state.value === null} onClick={composeEvent(onClick, () => send({ type: \"CLEAR\" }))} />;\n});\n\nfunction HiddenInput(props: HiddenInputProps) {\n const { state, options, send } = useContext();\n const input = React.useRef<HTMLInputElement>(null);\n useFormReset(input, props.form, () => send({ type: \"RESET\", value: options.defaultValue ?? null }));\n return <input {...props} ref={input} type=\"hidden\" disabled={options.disabled || props.disabled} value={state.value?.toString() ?? \"\"} data-scope=\"calendar\" data-part=\"hidden-input\" />;\n}\n\nexport const Calendar = { Root: CalendarRoot, Header, Heading, PrevButton, NextButton, Grid, GridHeader, HeaderCell, GridBody, Cell, LiveRegion, ClearButton, HiddenInput };"],"mappings":"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","names":["useContext","Header","Heading","PrevButton","NextButton","Grid","GridHeader","HeaderCell","GridBody","Cell","LiveRegion","ClearButton"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/field.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { connectField, createField, createStore, digitValue, fieldHourCycle, transitionField, translations, type FieldEvent, type FieldKind, type FieldOptions, type FieldValue, type SegmentType } from \"chrona-core\";\nimport { Part, composeEvent, type PartProps } from \"./part\";\nimport { useChronaConfig } from \"./provider\";\nimport { useFormReset, type HiddenInputProps } from \"./form\";\n\nexport interface FieldProps<Kind extends FieldKind> extends FieldOptions<Kind> {\n defaultValue?: FieldValue<Kind> | null;\n onChange?: (value: FieldValue<Kind> | null) => void;\n onInvalid?: (reason: \"range\" | \"unavailable\") => void;\n id?: string;\n describedBy?: string;\n}\n\nfunction equalValues(first: { equals: (other: never) => boolean } | null, second: { equals: (other: never) => boolean } | null) {\n return first === null || second === null ? first === second : first.equals(second as never);\n}\n\nexport function useField<Kind extends FieldKind>(kind: Kind, props: FieldProps<Kind>) {\n const options = useChronaConfig(props);\n const generatedId = React.useId();\n const id = props.id ?? generatedId;\n const [store] = React.useState(() => createStore(createField(kind, { ...options, value: props.value !== undefined ? props.value : props.defaultValue })));\n const snapshot = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n const value = props.value !== undefined ? props.value : snapshot.value;\n const placeholderValue = options.placeholderValue ?? snapshot.reference;\n const { minValue, maxValue, locale, hourCycle, granularity } = options;\n const configured = React.useMemo(() => createField(kind, { value, placeholderValue, minValue, maxValue, locale, hourCycle, granularity }), [kind, value, placeholderValue, minValue, maxValue, locale, hourCycle, granularity]);\n const cycle = fieldHourCycle(options);\n const configuration = `${cycle}:${props.granularity ?? \"minute\"}`;\n const previousConfiguration = React.useRef(configuration);\n const state = props.value !== undefined && !equalValues(snapshot.value, props.value)\n ? configured\n : kind === \"time\" && configuration !== previousConfiguration.current\n ? configured\n : snapshot;\n React.useEffect(() => {\n if (previousConfiguration.current !== configuration) {\n previousConfiguration.current = configuration;\n store.setState(state);\n }\n }, [configuration, state, store]);\n const groupRef = React.useRef<HTMLElement | null>(null);\n const [invalidReason, setInvalidReason] = React.useState<\"range\" | \"unavailable\" | null>(null);\n const announcement = invalidReason === null ? \"\" : invalidReason === \"range\"\n ? options.translations?.invalidRange ?? translations.invalidRange\n : options.translations?.unavailable ?? translations.unavailable;\n\n function moveFocus(segment: SegmentType, offset: number) {\n const elements = Array.from(groupRef.current?.querySelectorAll<HTMLInputElement>(\"input[data-segment]\") ?? []);\n const index = elements.findIndex((element) => element.dataset.segment === segment);\n elements[index + offset]?.focus();\n }\n\n function send(event: FieldEvent) {\n const result = transitionField(state, event, options);\n store.setState(result.state);\n if (!result.state.invalid) setInvalidReason(null);\n for (const effect of result.effects) {\n if (effect.type === \"change\") props.onChange?.(effect.value);\n if (effect.type === \"invalid\") { setInvalidReason(effect.reason); props.onInvalid?.(effect.reason); }\n if (effect.type === \"advance\") queueMicrotask(() => moveFocus(effect.segment, 1));\n }\n }\n\n function reset() {\n setInvalidReason(null);\n const value = props.defaultValue ?? null;\n store.setState(createField(kind, { ...options, value }));\n if (!equalValues(state.value, value)) props.onChange?.(value);\n }\n\n const [labelled, setLabelled] = React.useState(false);\n return { id, state, options, send, reset, moveFocus, groupRef, announcement, registerLabel: setLabelled, api: connectField(state, { ...options, id, labelId: labelled ? `${id}-label` : undefined }) };\n}\n\nexport function createFieldComponents<Kind extends FieldKind>(kind: Kind) {\n const Context = React.createContext<ReturnType<typeof useField<Kind>> | null>(null);\n function useContext() {\n const context = React.useContext(Context);\n if (!context) throw new Error(`${kind === \"date\" ? \"DateField\" : \"TimeField\"} parts must be inside their Root.`);\n return context;\n }\n\n function Root({ children, asChild, className, style, ...props }: FieldProps<Kind> & Pick<PartProps, \"children\" | \"asChild\" | \"className\" | \"style\">) {\n const context = useField(kind, props);\n return <Context.Provider value={context}><Part asChild={asChild} className={className} style={style} id={props.id} dir={context.options.dir} data-scope={`${kind}-field`} data-part=\"root\">{children}</Part></Context.Provider>;\n }\n\n const Label = React.forwardRef<HTMLElement, PartProps>(function Label(props, ref) {\n const { id, registerLabel } = useContext();\n React.useEffect(() => {\n registerLabel(true);\n return () => registerLabel(false);\n }, [registerLabel]);\n return <Part as=\"span\" {...props} ref={ref} id={`${id}-label`} data-scope={`${kind}-field`} data-part=\"label\" />;\n });\n\n const Segment = React.forwardRef<HTMLInputElement, Omit<React.ComponentPropsWithoutRef<\"input\">, \"type\" | \"value\" | \"defaultValue\" | \"onChange\" | \"children\"> & { type: SegmentType }>(function Segment({ type, onKeyDown, onFocus, onBlur, onPaste, onDrop, ...props }, ref) {\n const { state, api, options, send, moveFocus, groupRef } = useContext();\n if (!(type in state.parts)) throw new Error(`The ${type} segment is not enabled in this field.`);\n const { display, ...segmentProps } = api.getSegmentProps(type);\n return <input {...props} {...segmentProps} ref={ref} type=\"text\" inputMode={type === \"dayPeriod\" ? \"text\" : \"numeric\"} autoComplete=\"off\" spellCheck={false} value={display} disabled={options.disabled} readOnly={options.readOnly}\n onFocus={composeEvent(onFocus, (event) => { event.currentTarget.select(); })}\n onBlur={composeEvent(onBlur, () => send({ type: \"BLUR\" }))}\n onPaste={composeEvent(onPaste, (event) => event.preventDefault())}\n onDrop={composeEvent(onDrop, (event) => event.preventDefault())}\n onChange={(event) => {\n const native = event.nativeEvent as InputEvent;\n const digit = digitValue(native.data ?? \"\", options.locale);\n event.currentTarget.value = display;\n if (native.inputType === \"insertText\" && digit !== null) send({ type: \"DIGIT\", segment: type, digit });\n else if (native.inputType === \"deleteContentBackward\" || native.inputType === \"deleteContentForward\") send({ type: \"CLEAR\", segment: type });\n }}\n onKeyDown={composeEvent(onKeyDown, (event) => {\n if (event.altKey || event.ctrlKey || event.metaKey || event.nativeEvent.isComposing) return;\n const digit = digitValue(event.key, options.locale);\n const dir = options.dir ?? (groupRef.current?.closest(\"[dir]\")?.getAttribute(\"dir\") === \"rtl\" ? \"rtl\" : \"ltr\");\n if (digit !== null) { event.preventDefault(); send({ type: \"DIGIT\", segment: type, digit }); return; }\n switch (event.key) {\n case \"ArrowUp\": case \"ArrowDown\": event.preventDefault(); send({ type: \"STEP\", segment: type, direction: event.key === \"ArrowUp\" ? 1 : -1 }); break;\n case \"Home\": case \"End\": event.preventDefault(); send({ type: \"EDGE\", segment: type, edge: event.key === \"Home\" ? \"min\" : \"max\" }); break;\n case \"Backspace\": case \"Delete\": event.preventDefault(); send({ type: \"CLEAR\", segment: type }); break;\n case \"ArrowLeft\": case \"ArrowRight\": event.preventDefault(); moveFocus(type, (event.key === \"ArrowRight\" ? 1 : -1) * (dir === \"rtl\" ? -1 : 1)); break;\n default:\n if (type === \"dayPeriod\" && [\"a\", \"p\"].includes(event.key.toLowerCase())) {\n event.preventDefault(); send({ type: \"PERIOD\", value: event.key.toLowerCase() === \"a\" ? 0 : 1 });\n }\n }\n })} />;\n });\n\n const Field = React.forwardRef<HTMLElement, PartProps>(function Field({ children, ...props }, ref) {\n const { api, groupRef } = useContext();\n return <Part {...props} {...api.getGroupProps()} ref={(node) => {\n groupRef.current = node;\n if (typeof ref === \"function\") ref(node); else if (ref) ref.current = node;\n }}>{children ?? api.segments.map((segment, index) => segment.type === \"literal\" ? <span key={index} aria-hidden=\"true\" data-scope={`${kind}-field`} data-part=\"literal\">{segment.value}</span> : <Segment key={segment.type} type={segment.type} />)}</Part>;\n });\n\n function HiddenInput(props: HiddenInputProps) {\n const { state, options, reset } = useContext();\n const input = React.useRef<HTMLInputElement>(null);\n useFormReset(input, props.form, reset);\n return <input {...props} ref={input} type=\"hidden\" value={state.value?.toString() ?? \"\"} disabled={options.disabled || props.disabled} data-scope={`${kind}-field`} data-part=\"hidden-input\" />;\n }\n\n const ClearButton = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<\"button\"> & { asChild?: boolean }>(function ClearButton({ onClick, ...props }, ref) {\n const { options, send } = useContext();\n return <Part as=\"button\" {...props} ref={ref} type=\"button\" aria-label={options.translations?.clear ?? translations.clear} disabled={options.disabled || options.readOnly} data-scope={`${kind}-field`} data-part=\"clear-button\" onClick={composeEvent(onClick, () => send({ type: \"CLEAR\" }))} />;\n });\n\n const LiveRegion = React.forwardRef<HTMLElement, PartProps>(function LiveRegion(props, ref) {\n const { announcement } = useContext();\n return <Part {...props} ref={ref} role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" data-scope={`${kind}-field`} data-part=\"live-region\">{announcement}</Part>;\n });\n\n return { Root, Label, Field, Segment, HiddenInput, ClearButton, LiveRegion };\n}"],"mappings":"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","names":["value","useContext","Label","Segment","Field","ClearButton","LiveRegion"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/range-calendar.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { createRange, createStore, formatDate, getRangeCellProps, transitionRange, translations, validateRange, type DateRange, type PlainDate, type RangeEvent } from \"chrona-core\";\nimport { Calendar, CalendarSurface, useCalendar, type CalendarProps } from \"./calendar\";\nimport { Part, composeEvent, type PartProps } from \"./part\";\nimport { useFormReset, type HiddenInputProps } from \"./form\";\nimport { useChronaConfig } from \"./provider\";\n\nexport interface RangeCalendarProps extends Omit<CalendarProps, \"value\" | \"defaultValue\" | \"onChange\"> {\n value?: DateRange | null;\n defaultValue?: DateRange | null;\n onChange?: (value: DateRange | null) => void;\n onRangeStartChange?: (value: PlainDate | null) => void;\n onInvalid?: () => void;\n}\n\nexport function useRangeCalendar(input: RangeCalendarProps = {}) {\n const props = useChronaConfig(input);\n const [store] = React.useState(() => createStore(createRange(props.value !== undefined ? props.value : props.defaultValue)));\n const snapshot = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n if (props.value) validateRange(props.value);\n const state = { ...snapshot, value: props.value === undefined ? snapshot.value : props.value };\n const [announcement, setAnnouncement] = React.useState(\"\");\n function send(event: RangeEvent) {\n const result = transitionRange(state, event, props);\n store.setState(result.state);\n for (const effect of result.effects) {\n if (effect.type === \"change\") {\n props.onChange?.(effect.value);\n setAnnouncement(effect.value ? [effect.value.start, effect.value.end].map((date) => formatDate(date, props.locale, { dateStyle: \"long\" })).join(props.translations?.rangeSeparator ?? translations.rangeSeparator) : \"\");\n }\n if (effect.type === \"rangeStart\") {\n props.onRangeStartChange?.(effect.value);\n if (effect.value) setAnnouncement(formatDate(effect.value, props.locale, { dateStyle: \"long\" }));\n }\n if (effect.type === \"invalid\") { props.onInvalid?.(); setAnnouncement(props.translations?.unavailable ?? translations.unavailable); }\n }\n }\n const calendar = useCalendar({ ...props, value: null, defaultValue: null, placeholderValue: props.placeholderValue ?? state.value?.start, onChange: (date) => { if (date) send({ type: \"SELECT\", date }); }, onFocusedValueChange: (date) => { props.onFocusedValueChange?.(date); if (state.anchor) send({ type: \"PREVIEW\", date }); } });\n const baseApi = calendar.api;\n const api = { ...baseApi, getCellProps: (date: PlainDate, month?: PlainDate) => ({ ...baseApi.getCellProps(date, month), ...getRangeCellProps(state, date) }) };\n return {\n state, send, announcement, props, options: props, api, rootRef: calendar.rootRef, months: calendar.months,\n reset() { const value = props.defaultValue ?? null; store.setState(createRange(value)); props.onChange?.(value); },\n calendar: { ...calendar, api },\n };\n}\n\nconst Context = React.createContext<ReturnType<typeof useRangeCalendar> | null>(null);\nfunction useContext() {\n const value = React.useContext(Context);\n if (!value) throw new Error(\"RangeCalendar parts must be inside RangeCalendar.Root.\");\n return value;\n}\n\nfunction Root({ children, asChild, className, style, ...props }: RangeCalendarProps & Pick<PartProps, \"children\" | \"asChild\" | \"className\" | \"style\">) {\n const context = useRangeCalendar(props);\n return <Context.Provider value={context}><CalendarSurface calendar={context.calendar} asChild={asChild} className={className} style={style} data-scope=\"range-calendar\" onKeyDown={(event) => { if (event.key === \"Escape\" && context.state.anchor) { event.preventDefault(); context.send({ type: \"CANCEL\" }); } }}>{children}</CalendarSurface></Context.Provider>;\n}\n\nconst Cell = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<typeof Calendar.Cell>>(function Cell({ date, onPointerEnter, ...props }, ref) {\n const { send } = useContext();\n return <Calendar.Cell {...props} ref={ref} date={date} onPointerEnter={composeEvent(onPointerEnter, () => send({ type: \"PREVIEW\", date }))} />;\n});\n\nconst GridBody = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<typeof Calendar.GridBody>>(function GridBody({ children, ...props }, ref) {\n return <Calendar.GridBody {...props} ref={ref}>{children ?? ((date) => <Cell date={date} />)}</Calendar.GridBody>;\n});\n\nconst LiveRegion = React.forwardRef<HTMLElement, PartProps>(function LiveRegion(props, ref) {\n const { announcement } = useContext();\n return <Part {...props} ref={ref} role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" data-scope=\"range-calendar\" data-part=\"live-region\">{announcement}</Part>;\n});\n\nconst ClearButton = React.forwardRef<HTMLElement, React.ComponentPropsWithoutRef<typeof Calendar.ClearButton>>(function ClearButton({ onClick, ...props }, ref) {\n const { send, props: options } = useContext();\n return <Part as=\"button\" {...props} ref={ref} type=\"button\" disabled={options.disabled || options.readOnly} aria-label={options.translations?.clear ?? translations.clear} data-scope=\"range-calendar\" data-part=\"clear-button\" onClick={composeEvent(onClick, () => send({ type: \"CLEAR\" }))} />;\n});\n\nfunction HiddenInput({ name, form, id, disabled, ...inputProps }: HiddenInputProps & { name: string }) {\n const { state, props, reset } = useContext();\n const input = React.useRef<HTMLInputElement>(null);\n useFormReset(input, form, reset);\n return <><input {...inputProps} id={id ? `${id}-start` : undefined} ref={input} type=\"hidden\" name={`${name}.start`} form={form} value={state.value?.start.toString() ?? \"\"} disabled={props.disabled || disabled} data-scope=\"range-calendar\" data-part=\"hidden-input\" /><input {...inputProps} id={id ? `${id}-end` : undefined} type=\"hidden\" name={`${name}.end`} form={form} value={state.value?.end.toString() ?? \"\"} disabled={props.disabled || disabled} data-scope=\"range-calendar\" data-part=\"hidden-input\" /></>;\n}\n\nexport const RangeCalendar = { ...Calendar, Root, Cell, GridBody, LiveRegion, ClearButton, HiddenInput };"],"mappings":"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","names":["useContext","Cell","GridBody","LiveRegion","ClearButton"]}