@kenos-ui/react-datepicker 0.3.1 → 0.3.3
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/CHANGELOG.md +18 -0
- package/README.md +117 -90
- package/dist/index.cjs +26 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +25 -84
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @kenos-ui/react-datepicker
|
|
2
2
|
|
|
3
|
+
## 0.3.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- docs: major refresh of README.md and root documentation
|
|
8
|
+
|
|
9
|
+
- Update package README to accurately reflect current API (unified `DatePicker.Root` with `mode`, first-class `<DatePicker.Input>`, full composition)
|
|
10
|
+
- Add strong examples for segmented input, range with dual inputs + hover preview, multiple selection, and custom rendering
|
|
11
|
+
- Align with brand voice and recent announcement content
|
|
12
|
+
- Update root README with correct features and examples
|
|
13
|
+
|
|
14
|
+
## 0.3.2
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [aaa8a57]
|
|
19
|
+
- @kenos-ui/utils@0.0.1
|
|
20
|
+
|
|
3
21
|
## 0.3.1
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# @kenos-ui/react-datepicker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Headless date & scheduling primitives for React.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Built on native `Intl`, [timescape](https://github.com/dan-lee/timescape) (segmented inputs), and Floating UI. Full keyboard navigation, WAI-ARIA patterns, and a focus on real-world composition.
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- Unstyled — bring your own CSS
|
|
13
|
-
- React 19+, TypeScript-first
|
|
7
|
+
- Single, range, and multiple selection with one API (`mode`)
|
|
8
|
+
- Outstanding segmented date input (`<DatePicker.Input />`)
|
|
9
|
+
- Fully unstyled — bring your own CSS or Tailwind
|
|
10
|
+
- Excellent keyboard + screen reader support
|
|
11
|
+
- React 19+ and TypeScript-first
|
|
14
12
|
|
|
15
13
|
## Installation
|
|
16
14
|
|
|
@@ -18,15 +16,21 @@ Kenos UI — headless date & scheduling primitives for React. Built on top of th
|
|
|
18
16
|
npm install @kenos-ui/react-datepicker
|
|
19
17
|
```
|
|
20
18
|
|
|
21
|
-
## Quick
|
|
19
|
+
## Quick start (with segmented input)
|
|
22
20
|
|
|
23
21
|
```tsx
|
|
24
22
|
import { DatePicker } from "@kenos-ui/react-datepicker";
|
|
25
23
|
|
|
26
24
|
function App() {
|
|
25
|
+
const [date, setDate] = useState<Date | null>(null);
|
|
26
|
+
|
|
27
27
|
return (
|
|
28
|
-
<DatePicker.Root>
|
|
29
|
-
<DatePicker.
|
|
28
|
+
<DatePicker.Root value={date} onValueChange={setDate}>
|
|
29
|
+
<DatePicker.Label>Pick a date</DatePicker.Label>
|
|
30
|
+
<div>
|
|
31
|
+
<DatePicker.Input />
|
|
32
|
+
<DatePicker.Trigger>📅</DatePicker.Trigger>
|
|
33
|
+
</div>
|
|
30
34
|
<DatePicker.Content>
|
|
31
35
|
<DatePicker.Calendar />
|
|
32
36
|
</DatePicker.Content>
|
|
@@ -35,125 +39,148 @@ function App() {
|
|
|
35
39
|
}
|
|
36
40
|
```
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
The `<DatePicker.Input />` gives users a native-feeling segmented editor (month / day / year) that respects the locale's order and separators.
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
## Date range
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
One of the strongest use cases:
|
|
43
47
|
|
|
44
48
|
```tsx
|
|
45
|
-
import { DatePicker } from "@kenos-ui/react-datepicker";
|
|
49
|
+
import { DatePicker, type DateRange } from "@kenos-ui/react-datepicker";
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
<DatePicker.PrevTrigger />
|
|
50
|
-
<DatePicker.ViewTrigger />
|
|
51
|
-
<DatePicker.NextTrigger />
|
|
52
|
-
</DatePicker.ViewControl>
|
|
53
|
-
<DatePicker.View view="day">
|
|
54
|
-
<DatePicker.Grid header={<DatePicker.WeekDays />}>
|
|
55
|
-
{({ weeks }) => weeks.map((week, i) => (
|
|
56
|
-
<tr key={i}>
|
|
57
|
-
{week.map((d, j) => <DatePicker.Day key={j} date={d} />)}
|
|
58
|
-
</tr>
|
|
59
|
-
))}
|
|
60
|
-
</DatePicker.Grid>
|
|
61
|
-
</DatePicker.View>
|
|
62
|
-
</DatePicker.Root>
|
|
51
|
+
function TripDates() {
|
|
52
|
+
const [range, setRange] = useState<DateRange>({ start: null, end: null });
|
|
63
53
|
|
|
64
|
-
|
|
65
|
-
<DatePicker.Root>
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
return (
|
|
55
|
+
<DatePicker.Root mode="range" value={range} onValueChange={setRange}>
|
|
56
|
+
<DatePicker.Label>Trip dates</DatePicker.Label>
|
|
57
|
+
<div>
|
|
58
|
+
<DatePicker.Input index={0} />
|
|
59
|
+
<span>to</span>
|
|
60
|
+
<DatePicker.Input index={1} />
|
|
61
|
+
<DatePicker.Trigger>📅</DatePicker.Trigger>
|
|
62
|
+
</div>
|
|
63
|
+
<DatePicker.Content>
|
|
64
|
+
<DatePicker.Calendar />
|
|
65
|
+
</DatePicker.Content>
|
|
66
|
+
</DatePicker.Root>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
68
69
|
```
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
**Data attributes (on Day):** `[data-selected]`, `[data-today]`, `[data-outside-month]`, `[data-disabled]`, `[data-in-range]`, `[data-range-start]`, `[data-range-end]`
|
|
71
|
+
Range mode includes live hover preview between start and end.
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
### Date Picker
|
|
79
|
-
|
|
80
|
-
Text input paired with a calendar popover.
|
|
73
|
+
## Multiple dates
|
|
81
74
|
|
|
82
75
|
```tsx
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<DatePicker.Root locale="en-US" onValueChange={(date) => console.log(date)}>
|
|
76
|
+
<DatePicker.Root mode="multiple" onValueChange={setDates}>
|
|
77
|
+
<DatePicker.Input />
|
|
86
78
|
<DatePicker.Trigger />
|
|
87
79
|
<DatePicker.Content>
|
|
88
80
|
<DatePicker.Calendar />
|
|
89
81
|
</DatePicker.Content>
|
|
90
|
-
</DatePicker.Root
|
|
82
|
+
</DatePicker.Root>
|
|
91
83
|
```
|
|
92
84
|
|
|
93
|
-
|
|
85
|
+
## Calendar composition
|
|
94
86
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
---
|
|
87
|
+
Use the convenient shorthand:
|
|
98
88
|
|
|
99
|
-
|
|
89
|
+
```tsx
|
|
90
|
+
<DatePicker.Root>
|
|
91
|
+
<DatePicker.Calendar />
|
|
92
|
+
</DatePicker.Root>
|
|
93
|
+
```
|
|
100
94
|
|
|
101
|
-
|
|
95
|
+
Or take full control:
|
|
102
96
|
|
|
103
97
|
```tsx
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
98
|
+
<DatePicker.Root>
|
|
99
|
+
<DatePicker.ViewControl>
|
|
100
|
+
<DatePicker.PrevTrigger />
|
|
101
|
+
<DatePicker.ViewTrigger />
|
|
102
|
+
<DatePicker.NextTrigger />
|
|
103
|
+
</DatePicker.ViewControl>
|
|
104
|
+
|
|
105
|
+
<DatePicker.View view="day">
|
|
106
|
+
<DatePicker.Grid header={<DatePicker.WeekDays />}>
|
|
107
|
+
{({ weeks }) =>
|
|
108
|
+
weeks.map((week, i) => (
|
|
109
|
+
<tr key={i}>
|
|
110
|
+
{week.map((d, j) => (
|
|
111
|
+
<DatePicker.Day key={j} date={d}>
|
|
112
|
+
{({ isSelected, isToday }) => (
|
|
113
|
+
// custom rendering
|
|
114
|
+
<span className={isSelected ? "selected" : ""}>
|
|
115
|
+
{d.getDate()}
|
|
116
|
+
</span>
|
|
117
|
+
)}
|
|
118
|
+
</DatePicker.Day>
|
|
119
|
+
))}
|
|
120
|
+
</tr>
|
|
121
|
+
))
|
|
122
|
+
}
|
|
123
|
+
</DatePicker.Grid>
|
|
124
|
+
</DatePicker.View>
|
|
125
|
+
</DatePicker.Root>
|
|
112
126
|
```
|
|
113
127
|
|
|
114
|
-
|
|
128
|
+
You can also render month/year grids with `MonthGrid` / `YearGrid`.
|
|
115
129
|
|
|
116
|
-
|
|
130
|
+
## Positioning & advanced Content
|
|
117
131
|
|
|
118
|
-
|
|
132
|
+
`<DatePicker.Content>` is powered by Floating UI and supports:
|
|
119
133
|
|
|
120
|
-
|
|
134
|
+
- `side`, `align`, `sideOffset`, `alignOffset`
|
|
135
|
+
- `portal`
|
|
136
|
+
- `forceMount` (for enter/exit animations via `[data-state="open"]`)
|
|
137
|
+
- `avoidCollisions`
|
|
121
138
|
|
|
122
139
|
```tsx
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
<DateField.Segment segment="month" />
|
|
127
|
-
<DateField.Literal>/</DateField.Literal>
|
|
128
|
-
<DateField.Segment segment="day" />
|
|
129
|
-
<DateField.Literal>/</DateField.Literal>
|
|
130
|
-
<DateField.Segment segment="year" />
|
|
131
|
-
</DateField.Root>;
|
|
140
|
+
<DatePicker.Content portal side="top" align="end" forceMount>
|
|
141
|
+
<DatePicker.Calendar />
|
|
142
|
+
</DatePicker.Content>
|
|
132
143
|
```
|
|
133
144
|
|
|
134
|
-
|
|
145
|
+
## Key props on Root
|
|
146
|
+
|
|
147
|
+
- `mode`: `"single" | "range" | "multiple"`
|
|
148
|
+
- `locale`, `weekStartsOn`
|
|
149
|
+
- `minDate`, `maxDate`, `disabled`
|
|
150
|
+
- `readOnly`
|
|
151
|
+
- `modal` — opt-in focus trap + `aria-modal` (default `false` — follows popup policy)
|
|
152
|
+
- `defaultOpen`, `closeOnSelect`
|
|
135
153
|
|
|
136
|
-
|
|
154
|
+
See the full prop tables and more examples in the [project README](https://github.com/allysontsoares/kenos-ui/blob/main/README.md).
|
|
137
155
|
|
|
138
156
|
## Localization
|
|
139
157
|
|
|
140
|
-
|
|
158
|
+
Everything is driven by `Intl.Locale`:
|
|
141
159
|
|
|
142
160
|
```tsx
|
|
143
|
-
|
|
144
|
-
<DatePicker.Root locale="ar" />
|
|
145
|
-
|
|
146
|
-
// Brazilian Portuguese
|
|
147
|
-
<DatePicker.Root locale="pt-BR" />
|
|
148
|
-
|
|
149
|
-
// Japanese
|
|
161
|
+
<DatePicker.Root locale="pt-BR" /> {/* dd/mm/yyyy, week starts Monday */}
|
|
162
|
+
<DatePicker.Root locale="ar" /> {/* RTL + Saturday start */}
|
|
150
163
|
<DatePicker.Root locale="ja-JP" />
|
|
151
164
|
```
|
|
152
165
|
|
|
153
166
|
## Requirements
|
|
154
167
|
|
|
155
|
-
- React
|
|
156
|
-
- Node
|
|
168
|
+
- React ≥ 19
|
|
169
|
+
- Node ≥ 22
|
|
170
|
+
|
|
171
|
+
## Exports
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import {
|
|
175
|
+
DatePicker,
|
|
176
|
+
useDatePickerContext,
|
|
177
|
+
// types
|
|
178
|
+
type DatePickerRootProps,
|
|
179
|
+
type DateRange,
|
|
180
|
+
type DayCellMeta,
|
|
181
|
+
// ...
|
|
182
|
+
} from "@kenos-ui/react-datepicker";
|
|
183
|
+
```
|
|
157
184
|
|
|
158
185
|
## License
|
|
159
186
|
|
|
@@ -161,4 +188,4 @@ MIT
|
|
|
161
188
|
|
|
162
189
|
---
|
|
163
190
|
|
|
164
|
-
*Kenos UI*
|
|
191
|
+
*Kenos UI* — https://github.com/allysontsoares/kenos-ui/tree/main/packages/datepicker
|
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,7 @@ var React = require('react');
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var react = require('timescape/react');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
|
+
var utils = require('@kenos-ui/utils');
|
|
7
8
|
var reactDom$1 = require('@floating-ui/react-dom');
|
|
8
9
|
|
|
9
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -418,6 +419,7 @@ function resolveConfig(props) {
|
|
|
418
419
|
mode: props.mode ?? "single",
|
|
419
420
|
locale: props.locale ?? (typeof navigator !== "undefined" ? navigator.language : "en-US"),
|
|
420
421
|
readOnly: props.readOnly ?? false,
|
|
422
|
+
modal: props.modal ?? false,
|
|
421
423
|
closeOnSelect: props.closeOnSelect ?? (props.mode !== "range" && props.mode !== "multiple"),
|
|
422
424
|
...props.weekStartsOn !== void 0 && { weekStartsOn: props.weekStartsOn },
|
|
423
425
|
...props.minDate !== void 0 && { minDate: props.minDate },
|
|
@@ -443,7 +445,7 @@ function resolveInitialValue(props) {
|
|
|
443
445
|
}
|
|
444
446
|
function useDatePicker(props) {
|
|
445
447
|
const uid = React.useId();
|
|
446
|
-
const { mode, locale, weekStartsOn, minDate, maxDate, disabled, readOnly, closeOnSelect } = props;
|
|
448
|
+
const { mode, locale, weekStartsOn, minDate, maxDate, disabled, readOnly, closeOnSelect, modal } = props;
|
|
447
449
|
const config = React.useMemo(
|
|
448
450
|
() => resolveConfig({
|
|
449
451
|
mode,
|
|
@@ -453,9 +455,10 @@ function useDatePicker(props) {
|
|
|
453
455
|
maxDate,
|
|
454
456
|
disabled,
|
|
455
457
|
readOnly,
|
|
456
|
-
closeOnSelect
|
|
458
|
+
closeOnSelect,
|
|
459
|
+
modal
|
|
457
460
|
}),
|
|
458
|
-
[mode, locale, weekStartsOn, minDate, maxDate, disabled, readOnly, closeOnSelect]
|
|
461
|
+
[mode, locale, weekStartsOn, minDate, maxDate, disabled, readOnly, closeOnSelect, modal]
|
|
459
462
|
);
|
|
460
463
|
const initialValue = resolveInitialValue(props);
|
|
461
464
|
const [state, dispatch] = React.useReducer(
|
|
@@ -657,6 +660,7 @@ function Segments({
|
|
|
657
660
|
}
|
|
658
661
|
if (e.key === "Escape") {
|
|
659
662
|
e.preventDefault();
|
|
663
|
+
e.stopPropagation();
|
|
660
664
|
if (state.open) dispatch({ type: "CLOSE" });
|
|
661
665
|
}
|
|
662
666
|
}
|
|
@@ -807,76 +811,6 @@ function Trigger({ children, onClick, disabled, ...props }) {
|
|
|
807
811
|
}
|
|
808
812
|
);
|
|
809
813
|
}
|
|
810
|
-
function useClickOutside(refs, handler, enabled = true) {
|
|
811
|
-
const refsRef = React.useRef(refs);
|
|
812
|
-
refsRef.current = refs;
|
|
813
|
-
React.useEffect(() => {
|
|
814
|
-
if (!enabled) return;
|
|
815
|
-
function onPointerDown(e) {
|
|
816
|
-
const target = e.target;
|
|
817
|
-
if (refsRef.current.every((r) => !r.current?.contains(target))) {
|
|
818
|
-
handler();
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
document.addEventListener("pointerdown", onPointerDown, true);
|
|
822
|
-
return () => document.removeEventListener("pointerdown", onPointerDown, true);
|
|
823
|
-
}, [enabled, handler]);
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
// src/utils/aria.ts
|
|
827
|
-
function getFocusableElements(container) {
|
|
828
|
-
const selector = [
|
|
829
|
-
"a[href]",
|
|
830
|
-
"button:not([disabled])",
|
|
831
|
-
"input:not([disabled])",
|
|
832
|
-
"select:not([disabled])",
|
|
833
|
-
"textarea:not([disabled])",
|
|
834
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
835
|
-
].join(", ");
|
|
836
|
-
return Array.from(container.querySelectorAll(selector)).filter(
|
|
837
|
-
(el) => !el.closest("[hidden]") && el.offsetParent !== null
|
|
838
|
-
);
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
// src/date-picker/use-focus-trap.ts
|
|
842
|
-
function useFocusTrap(containerRef, enabled = true) {
|
|
843
|
-
React.useEffect(() => {
|
|
844
|
-
if (!enabled || !containerRef.current) return;
|
|
845
|
-
const container = containerRef.current;
|
|
846
|
-
function onKeyDown(e) {
|
|
847
|
-
if (e.key !== "Tab") return;
|
|
848
|
-
const focusable = getFocusableElements(container);
|
|
849
|
-
if (!focusable.length) return;
|
|
850
|
-
const first = focusable[0];
|
|
851
|
-
const last = focusable[focusable.length - 1];
|
|
852
|
-
if (e.shiftKey) {
|
|
853
|
-
if (document.activeElement === first) {
|
|
854
|
-
e.preventDefault();
|
|
855
|
-
last.focus();
|
|
856
|
-
}
|
|
857
|
-
} else {
|
|
858
|
-
if (document.activeElement === last) {
|
|
859
|
-
e.preventDefault();
|
|
860
|
-
first.focus();
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
const observer = new MutationObserver(() => {
|
|
865
|
-
const active = document.activeElement;
|
|
866
|
-
if (active?.getAttribute("role") === "spinbutton") return;
|
|
867
|
-
if (!container.contains(active)) {
|
|
868
|
-
const firstFocusable = getFocusableElements(container)[0];
|
|
869
|
-
firstFocusable?.focus();
|
|
870
|
-
}
|
|
871
|
-
});
|
|
872
|
-
observer.observe(container, { childList: true, subtree: true });
|
|
873
|
-
container.addEventListener("keydown", onKeyDown);
|
|
874
|
-
return () => {
|
|
875
|
-
container.removeEventListener("keydown", onKeyDown);
|
|
876
|
-
observer.disconnect();
|
|
877
|
-
};
|
|
878
|
-
}, [enabled, containerRef]);
|
|
879
|
-
}
|
|
880
814
|
function toPlacement(side, align) {
|
|
881
815
|
return align === "center" ? side : `${side}-${align}`;
|
|
882
816
|
}
|
|
@@ -975,12 +909,26 @@ function Content({
|
|
|
975
909
|
},
|
|
976
910
|
[setFloating]
|
|
977
911
|
);
|
|
978
|
-
|
|
912
|
+
const close = React.useCallback(() => {
|
|
913
|
+
const source = state.openSource;
|
|
914
|
+
dispatch({ type: "CLOSE" });
|
|
915
|
+
utils.restoreFocus({
|
|
916
|
+
openSource: source === "input" ? "input" : source === "trigger" ? "trigger" : "unknown",
|
|
917
|
+
trigger: document.getElementById(ids.trigger),
|
|
918
|
+
input: document.getElementById(ids.input) ?? document.getElementById(`${ids.input}-0`)
|
|
919
|
+
});
|
|
920
|
+
}, [dispatch, ids.input, ids.trigger, state.openSource]);
|
|
921
|
+
utils.useClickOutside(
|
|
979
922
|
[contentRef, triggerRef, inputRef, input0Ref, input1Ref],
|
|
980
|
-
|
|
923
|
+
close,
|
|
981
924
|
isOpen
|
|
982
925
|
);
|
|
983
|
-
|
|
926
|
+
utils.useEscapeKey({
|
|
927
|
+
enabled: isOpen,
|
|
928
|
+
stopPropagation: true,
|
|
929
|
+
onEscape: close
|
|
930
|
+
});
|
|
931
|
+
utils.useFocusTrap(contentRef, isOpen && config.modal);
|
|
984
932
|
const [transitionsReady, setTransitionsReady] = React.useState(false);
|
|
985
933
|
React.useEffect(() => {
|
|
986
934
|
if (!isOpen || !isPositioned) {
|
|
@@ -1009,7 +957,7 @@ function Content({
|
|
|
1009
957
|
ref: mergedRef,
|
|
1010
958
|
id: ids.content,
|
|
1011
959
|
role: "dialog",
|
|
1012
|
-
"aria-modal": "true",
|
|
960
|
+
"aria-modal": config.modal ? "true" : void 0,
|
|
1013
961
|
"aria-labelledby": ids.label,
|
|
1014
962
|
"data-state": isOpen ? "open" : "closed",
|
|
1015
963
|
style: {
|
|
@@ -1023,14 +971,7 @@ function Content({
|
|
|
1023
971
|
...isOpen && !transitionsReady ? { transition: "none" } : void 0,
|
|
1024
972
|
...style
|
|
1025
973
|
},
|
|
1026
|
-
onKeyDown
|
|
1027
|
-
if (e.key === "Escape") {
|
|
1028
|
-
e.preventDefault();
|
|
1029
|
-
dispatch({ type: "CLOSE" });
|
|
1030
|
-
document.getElementById(ids.trigger)?.focus();
|
|
1031
|
-
}
|
|
1032
|
-
onKeyDown?.(e);
|
|
1033
|
-
},
|
|
974
|
+
onKeyDown,
|
|
1034
975
|
...props,
|
|
1035
976
|
children: [
|
|
1036
977
|
/* @__PURE__ */ jsxRuntime.jsx(
|