@proyecto-viviana/solidaria-components 0.3.2 → 0.4.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/dist/ActionBar.d.ts.map +1 -1
- package/dist/ActionBar.js +175 -0
- package/dist/ActionBar.js.map +1 -0
- package/dist/ActionBar.jsx +119 -0
- package/dist/ActionBar.jsx.map +1 -0
- package/dist/ActionGroup.d.ts.map +1 -1
- package/dist/ActionGroup.js +179 -0
- package/dist/ActionGroup.js.map +1 -0
- package/dist/ActionGroup.jsx +129 -0
- package/dist/ActionGroup.jsx.map +1 -0
- package/dist/Alert.js +111 -0
- package/dist/Alert.js.map +1 -0
- package/dist/Alert.jsx +82 -0
- package/dist/Alert.jsx.map +1 -0
- package/dist/Autocomplete.d.ts +2 -2
- package/dist/Autocomplete.d.ts.map +1 -1
- package/dist/Autocomplete.js +130 -0
- package/dist/Autocomplete.js.map +1 -0
- package/dist/Autocomplete.jsx +116 -0
- package/dist/Autocomplete.jsx.map +1 -0
- package/dist/Breadcrumbs.d.ts.map +1 -1
- package/dist/Breadcrumbs.js +333 -0
- package/dist/Breadcrumbs.js.map +1 -0
- package/dist/Breadcrumbs.jsx +261 -0
- package/dist/Breadcrumbs.jsx.map +1 -0
- package/dist/Button.d.ts.map +1 -1
- package/dist/Button.js +348 -0
- package/dist/Button.js.map +1 -0
- package/dist/Button.jsx +314 -0
- package/dist/Button.jsx.map +1 -0
- package/dist/Calendar.d.ts +4 -4
- package/dist/Calendar.d.ts.map +1 -1
- package/dist/Calendar.js +573 -0
- package/dist/Calendar.js.map +1 -0
- package/dist/Calendar.jsx +342 -0
- package/dist/Calendar.jsx.map +1 -0
- package/dist/CalendarPicker.d.ts +33 -0
- package/dist/CalendarPicker.d.ts.map +1 -0
- package/dist/CalendarPicker.js +44 -0
- package/dist/CalendarPicker.js.map +1 -0
- package/dist/CalendarPicker.jsx +44 -0
- package/dist/CalendarPicker.jsx.map +1 -0
- package/dist/Checkbox.d.ts +83 -4
- package/dist/Checkbox.d.ts.map +1 -1
- package/dist/Checkbox.js +923 -0
- package/dist/Checkbox.js.map +1 -0
- package/dist/Checkbox.jsx +707 -0
- package/dist/Checkbox.jsx.map +1 -0
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +202 -0
- package/dist/Collection.js.map +1 -0
- package/dist/Collection.jsx +152 -0
- package/dist/Collection.jsx.map +1 -0
- package/dist/Color.d.ts.map +1 -1
- package/dist/Color.js +1717 -0
- package/dist/Color.js.map +1 -0
- package/dist/Color.jsx +1340 -0
- package/dist/Color.jsx.map +1 -0
- package/dist/ColorEditor.js +208 -0
- package/dist/ColorEditor.js.map +1 -0
- package/dist/ColorEditor.jsx +120 -0
- package/dist/ColorEditor.jsx.map +1 -0
- package/dist/ComboBox.d.ts +8 -4
- package/dist/ComboBox.d.ts.map +1 -1
- package/dist/ComboBox.js +1000 -0
- package/dist/ComboBox.js.map +1 -0
- package/dist/ComboBox.jsx +724 -0
- package/dist/ComboBox.jsx.map +1 -0
- package/dist/ContextualHelpTrigger.js +146 -0
- package/dist/ContextualHelpTrigger.js.map +1 -0
- package/dist/ContextualHelpTrigger.jsx +109 -0
- package/dist/ContextualHelpTrigger.jsx.map +1 -0
- package/dist/DateField.d.ts +14 -5
- package/dist/DateField.d.ts.map +1 -1
- package/dist/DateField.js +4 -0
- package/dist/DateField.jsx +4 -0
- package/dist/DateField2.js +502 -0
- package/dist/DateField2.js.map +1 -0
- package/dist/DateField2.jsx +354 -0
- package/dist/DateField2.jsx.map +1 -0
- package/dist/DatePicker.d.ts +46 -7
- package/dist/DatePicker.d.ts.map +1 -1
- package/dist/DatePicker.js +7 -0
- package/dist/DatePicker.jsx +7 -0
- package/dist/DatePicker2.js +1171 -0
- package/dist/DatePicker2.js.map +1 -0
- package/dist/DatePicker2.jsx +820 -0
- package/dist/DatePicker2.jsx.map +1 -0
- package/dist/DateRangePickerContext.d.ts +2 -0
- package/dist/DateRangePickerContext.d.ts.map +1 -1
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Dialog.js +337 -0
- package/dist/Dialog.js.map +1 -0
- package/dist/Dialog.jsx +192 -0
- package/dist/Dialog.jsx.map +1 -0
- package/dist/Disclosure.d.ts.map +1 -1
- package/dist/Disclosure.js +331 -0
- package/dist/Disclosure.js.map +1 -0
- package/dist/Disclosure.jsx +230 -0
- package/dist/Disclosure.jsx.map +1 -0
- package/dist/DragAndDrop.d.ts.map +1 -1
- package/dist/DragAndDrop.js +176 -0
- package/dist/DragAndDrop.js.map +1 -0
- package/dist/DragAndDrop.jsx +160 -0
- package/dist/DragAndDrop.jsx.map +1 -0
- package/dist/DropZone.d.ts.map +1 -1
- package/dist/DropZone.js +189 -0
- package/dist/DropZone.js.map +1 -0
- package/dist/DropZone.jsx +144 -0
- package/dist/DropZone.jsx.map +1 -0
- package/dist/FieldError.js +66 -0
- package/dist/FieldError.js.map +1 -0
- package/dist/FieldError.jsx +47 -0
- package/dist/FieldError.jsx.map +1 -0
- package/dist/FileTrigger.js +79 -0
- package/dist/FileTrigger.js.map +1 -0
- package/dist/FileTrigger.jsx +49 -0
- package/dist/FileTrigger.jsx.map +1 -0
- package/dist/Focusable.js +70 -0
- package/dist/Focusable.js.map +1 -0
- package/dist/Focusable.jsx +69 -0
- package/dist/Focusable.jsx.map +1 -0
- package/dist/Form.js +99 -0
- package/dist/Form.js.map +1 -0
- package/dist/Form.jsx +73 -0
- package/dist/Form.jsx.map +1 -0
- package/dist/GridList.d.ts +34 -2
- package/dist/GridList.d.ts.map +1 -1
- package/dist/GridList.js +723 -0
- package/dist/GridList.js.map +1 -0
- package/dist/GridList.jsx +552 -0
- package/dist/GridList.jsx.map +1 -0
- package/dist/Icon.d.ts.map +1 -1
- package/dist/Icon.js +127 -0
- package/dist/Icon.js.map +1 -0
- package/dist/Icon.jsx +72 -0
- package/dist/Icon.jsx.map +1 -0
- package/dist/Keyboard.js +30 -0
- package/dist/Keyboard.js.map +1 -0
- package/dist/Keyboard.jsx +24 -0
- package/dist/Keyboard.jsx.map +1 -0
- package/dist/Landmark.js +134 -0
- package/dist/Landmark.js.map +1 -0
- package/dist/Landmark.jsx +118 -0
- package/dist/Landmark.jsx.map +1 -0
- package/dist/Link.d.ts.map +1 -1
- package/dist/Link.js +219 -0
- package/dist/Link.js.map +1 -0
- package/dist/Link.jsx +189 -0
- package/dist/Link.jsx.map +1 -0
- package/dist/ListBox.d.ts +2 -2
- package/dist/ListBox.d.ts.map +1 -1
- package/dist/ListBox.js +831 -0
- package/dist/ListBox.js.map +1 -0
- package/dist/ListBox.jsx +644 -0
- package/dist/ListBox.jsx.map +1 -0
- package/dist/Menu.d.ts +27 -9
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Menu.js +1254 -0
- package/dist/Menu.js.map +1 -0
- package/dist/Menu.jsx +1042 -0
- package/dist/Menu.jsx.map +1 -0
- package/dist/Meter.d.ts.map +1 -1
- package/dist/Meter.js +123 -0
- package/dist/Meter.js.map +1 -0
- package/dist/Meter.jsx +107 -0
- package/dist/Meter.jsx.map +1 -0
- package/dist/Modal.d.ts.map +1 -1
- package/dist/Modal.js +382 -0
- package/dist/Modal.js.map +1 -0
- package/dist/Modal.jsx +314 -0
- package/dist/Modal.jsx.map +1 -0
- package/dist/NumberField.d.ts +3 -3
- package/dist/NumberField.d.ts.map +1 -1
- package/dist/NumberField.js +573 -0
- package/dist/NumberField.js.map +1 -0
- package/dist/NumberField.jsx +443 -0
- package/dist/NumberField.jsx.map +1 -0
- package/dist/Popover.d.ts +10 -2
- package/dist/Popover.d.ts.map +1 -1
- package/dist/Popover.js +471 -0
- package/dist/Popover.js.map +1 -0
- package/dist/Popover.jsx +354 -0
- package/dist/Popover.jsx.map +1 -0
- package/dist/Pressable.js +69 -0
- package/dist/Pressable.js.map +1 -0
- package/dist/Pressable.jsx +68 -0
- package/dist/Pressable.jsx.map +1 -0
- package/dist/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar.js +130 -0
- package/dist/ProgressBar.js.map +1 -0
- package/dist/ProgressBar.jsx +114 -0
- package/dist/ProgressBar.jsx.map +1 -0
- package/dist/RadioGroup.d.ts +82 -4
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RadioGroup.js +931 -0
- package/dist/RadioGroup.js.map +1 -0
- package/dist/RadioGroup.jsx +681 -0
- package/dist/RadioGroup.jsx.map +1 -0
- package/dist/RangeCalendar.d.ts.map +1 -1
- package/dist/RangeCalendar.js +546 -0
- package/dist/RangeCalendar.js.map +1 -0
- package/dist/RangeCalendar.jsx +323 -0
- package/dist/RangeCalendar.jsx.map +1 -0
- package/dist/RouterProvider.js +118 -0
- package/dist/RouterProvider.js.map +1 -0
- package/dist/RouterProvider.jsx +112 -0
- package/dist/RouterProvider.jsx.map +1 -0
- package/dist/SearchField.d.ts +2 -2
- package/dist/SearchField.d.ts.map +1 -1
- package/dist/SearchField.js +667 -0
- package/dist/SearchField.js.map +1 -0
- package/dist/SearchField.jsx +550 -0
- package/dist/SearchField.jsx.map +1 -0
- package/dist/Select.d.ts +7 -0
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js +1044 -0
- package/dist/Select.js.map +1 -0
- package/dist/Select.jsx +759 -0
- package/dist/Select.jsx.map +1 -0
- package/dist/SelectionIndicator.d.ts.map +1 -1
- package/dist/SelectionIndicator.js +86 -0
- package/dist/SelectionIndicator.js.map +1 -0
- package/dist/SelectionIndicator.jsx +50 -0
- package/dist/SelectionIndicator.jsx.map +1 -0
- package/dist/Separator.js +97 -0
- package/dist/Separator.js.map +1 -0
- package/dist/Separator.jsx +85 -0
- package/dist/Separator.jsx.map +1 -0
- package/dist/SharedElementTransition.d.ts.map +1 -1
- package/dist/SharedElementTransition.js +167 -0
- package/dist/SharedElementTransition.js.map +1 -0
- package/dist/SharedElementTransition.jsx +140 -0
- package/dist/SharedElementTransition.jsx.map +1 -0
- package/dist/Slider.d.ts +33 -1
- package/dist/Slider.d.ts.map +1 -1
- package/dist/Slider.js +515 -0
- package/dist/Slider.js.map +1 -0
- package/dist/Slider.jsx +403 -0
- package/dist/Slider.jsx.map +1 -0
- package/dist/StepList.d.ts.map +1 -1
- package/dist/StepList.js +191 -0
- package/dist/StepList.js.map +1 -0
- package/dist/StepList.jsx +136 -0
- package/dist/StepList.jsx.map +1 -0
- package/dist/Switch.d.ts +65 -2
- package/dist/Switch.d.ts.map +1 -1
- package/dist/Switch.js +534 -0
- package/dist/Switch.js.map +1 -0
- package/dist/Switch.jsx +393 -0
- package/dist/Switch.jsx.map +1 -0
- package/dist/Table.d.ts +50 -0
- package/dist/Table.d.ts.map +1 -1
- package/dist/Table.js +1766 -0
- package/dist/Table.js.map +1 -0
- package/dist/Table.jsx +1355 -0
- package/dist/Table.jsx.map +1 -0
- package/dist/Tabs.d.ts +0 -4
- package/dist/Tabs.d.ts.map +1 -1
- package/dist/Tabs.js +598 -0
- package/dist/Tabs.js.map +1 -0
- package/dist/Tabs.jsx +367 -0
- package/dist/Tabs.jsx.map +1 -0
- package/dist/TagGroup.d.ts +3 -1
- package/dist/TagGroup.d.ts.map +1 -1
- package/dist/TagGroup.js +382 -0
- package/dist/TagGroup.js.map +1 -0
- package/dist/TagGroup.jsx +273 -0
- package/dist/TagGroup.jsx.map +1 -0
- package/dist/Text.d.ts +18 -6
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +42 -0
- package/dist/Text.js.map +1 -0
- package/dist/Text.jsx +35 -0
- package/dist/Text.jsx.map +1 -0
- package/dist/TextField.d.ts +6 -6
- package/dist/TextField.d.ts.map +1 -1
- package/dist/TextField.js +439 -0
- package/dist/TextField.js.map +1 -0
- package/dist/TextField.jsx +406 -0
- package/dist/TextField.jsx.map +1 -0
- package/dist/TimeField.d.ts +17 -53
- package/dist/TimeField.d.ts.map +1 -1
- package/dist/TimeField.js +278 -0
- package/dist/TimeField.js.map +1 -0
- package/dist/TimeField.jsx +218 -0
- package/dist/TimeField.jsx.map +1 -0
- package/dist/Toast.d.ts +14 -0
- package/dist/Toast.d.ts.map +1 -1
- package/dist/Toast.js +551 -0
- package/dist/Toast.js.map +1 -0
- package/dist/Toast.jsx +361 -0
- package/dist/Toast.jsx.map +1 -0
- package/dist/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton.js +123 -0
- package/dist/ToggleButton.js.map +1 -0
- package/dist/ToggleButton.jsx +88 -0
- package/dist/ToggleButton.jsx.map +1 -0
- package/dist/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/ToggleButtonGroup.js +114 -0
- package/dist/ToggleButtonGroup.js.map +1 -0
- package/dist/ToggleButtonGroup.jsx +85 -0
- package/dist/ToggleButtonGroup.jsx.map +1 -0
- package/dist/Toolbar.js +112 -0
- package/dist/Toolbar.js.map +1 -0
- package/dist/Toolbar.jsx +92 -0
- package/dist/Toolbar.jsx.map +1 -0
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip.js +539 -0
- package/dist/Tooltip.js.map +1 -0
- package/dist/Tooltip.jsx +465 -0
- package/dist/Tooltip.jsx.map +1 -0
- package/dist/Tree.d.ts +14 -2
- package/dist/Tree.d.ts.map +1 -1
- package/dist/Tree.js +1424 -0
- package/dist/Tree.js.map +1 -0
- package/dist/Tree.jsx +1172 -0
- package/dist/Tree.jsx.map +1 -0
- package/dist/Virtualizer.d.ts +16 -2
- package/dist/Virtualizer.d.ts.map +1 -1
- package/dist/Virtualizer.js +2 -0
- package/dist/Virtualizer.jsx +2 -0
- package/dist/Virtualizer2.js +751 -0
- package/dist/Virtualizer2.js.map +1 -0
- package/dist/Virtualizer2.jsx +730 -0
- package/dist/Virtualizer2.jsx.map +1 -0
- package/dist/VirtualizerLayouts.d.ts +18 -0
- package/dist/VirtualizerLayouts.d.ts.map +1 -1
- package/dist/VisuallyHidden.js +42 -0
- package/dist/VisuallyHidden.js.map +1 -0
- package/dist/VisuallyHidden.jsx +35 -0
- package/dist/VisuallyHidden.jsx.map +1 -0
- package/dist/contexts.js +33 -0
- package/dist/contexts.js.map +1 -0
- package/dist/contexts.jsx +33 -0
- package/dist/contexts.jsx.map +1 -0
- package/dist/index.d.ts +9 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +69 -23932
- package/dist/index.jsx +69 -18337
- package/dist/useDragAndDrop.d.ts +0 -8
- package/dist/useDragAndDrop.d.ts.map +1 -1
- package/dist/useDragAndDrop.js +2 -0
- package/dist/useDragAndDrop.jsx +2 -0
- package/dist/useDragAndDrop2.js +399 -0
- package/dist/useDragAndDrop2.js.map +1 -0
- package/dist/useDragAndDrop2.jsx +399 -0
- package/dist/useDragAndDrop2.jsx.map +1 -0
- package/dist/utils.d.ts +84 -11
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +285 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.jsx +277 -0
- package/dist/utils.jsx.map +1 -0
- package/dist/virtualizer/Layout.js +144 -0
- package/dist/virtualizer/Layout.js.map +1 -0
- package/dist/virtualizer/Layout.jsx +144 -0
- package/dist/virtualizer/Layout.jsx.map +1 -0
- package/package.json +395 -4
- package/src/ActionBar.tsx +10 -12
- package/src/ActionGroup.tsx +5 -3
- package/src/Autocomplete.tsx +14 -9
- package/src/Breadcrumbs.tsx +58 -39
- package/src/Button.tsx +22 -2
- package/src/Calendar.tsx +57 -11
- package/src/CalendarPicker.tsx +73 -0
- package/src/Checkbox.tsx +539 -3
- package/src/Collection.tsx +9 -3
- package/src/Color.tsx +84 -41
- package/src/ComboBox.tsx +97 -21
- package/src/DateField.tsx +304 -53
- package/src/DatePicker.tsx +402 -62
- package/src/DateRangePickerContext.tsx +2 -0
- package/src/Dialog.tsx +13 -5
- package/src/Disclosure.tsx +7 -1
- package/src/DragAndDrop.tsx +3 -1
- package/src/DropZone.tsx +3 -1
- package/src/GridList.tsx +133 -26
- package/src/Icon.tsx +3 -1
- package/src/Link.tsx +3 -1
- package/src/ListBox.tsx +354 -25
- package/src/Menu.tsx +252 -128
- package/src/Meter.tsx +3 -1
- package/src/Modal.tsx +120 -56
- package/src/NumberField.tsx +51 -8
- package/src/Popover.tsx +68 -17
- package/src/ProgressBar.tsx +3 -1
- package/src/RadioGroup.tsx +468 -4
- package/src/RangeCalendar.tsx +123 -2
- package/src/SearchField.tsx +80 -4
- package/src/Select.tsx +122 -26
- package/src/SelectionIndicator.tsx +3 -1
- package/src/SharedElementTransition.tsx +95 -37
- package/src/Slider.tsx +159 -13
- package/src/StepList.tsx +0 -7
- package/src/Switch.tsx +395 -2
- package/src/Table.tsx +428 -99
- package/src/Tabs.tsx +17 -45
- package/src/TagGroup.tsx +29 -7
- package/src/Text.tsx +31 -10
- package/src/TextField.tsx +44 -6
- package/src/TimeField.tsx +127 -192
- package/src/Toast.tsx +79 -14
- package/src/ToggleButton.tsx +3 -1
- package/src/ToggleButtonGroup.tsx +3 -1
- package/src/Tooltip.tsx +3 -1
- package/src/Tree.tsx +91 -13
- package/src/Virtualizer.tsx +180 -31
- package/src/VirtualizerLayouts.ts +45 -10
- package/src/index.ts +51 -8
- package/src/useDragAndDrop.ts +8 -10
- package/src/utils.tsx +246 -30
- package/dist/HiddenTimeInput.d.ts +0 -25
- package/dist/HiddenTimeInput.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.jsx.map +0 -1
- package/src/HiddenTimeInput.tsx +0 -133
package/src/DatePicker.tsx
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
type JSX,
|
|
10
|
+
type Context,
|
|
10
11
|
createContext,
|
|
11
12
|
createEffect,
|
|
12
13
|
createMemo,
|
|
@@ -19,13 +20,19 @@ import {
|
|
|
19
20
|
import { Portal } from "solid-js/web";
|
|
20
21
|
import {
|
|
21
22
|
createDatePicker,
|
|
23
|
+
createDateField,
|
|
22
24
|
createDateRangePicker,
|
|
25
|
+
createEnterAnimation,
|
|
26
|
+
createFocusRing,
|
|
27
|
+
createHover,
|
|
23
28
|
createPopover,
|
|
29
|
+
mergeProps,
|
|
24
30
|
FocusScope,
|
|
25
31
|
useUNSAFE_PortalContext,
|
|
26
32
|
type AriaDatePickerProps,
|
|
27
33
|
type AriaDateRangePickerProps,
|
|
28
34
|
type DatePickerState as AriaDatePickerState,
|
|
35
|
+
type PlacementAxis,
|
|
29
36
|
} from "@proyecto-viviana/solidaria";
|
|
30
37
|
import {
|
|
31
38
|
createDateFieldState,
|
|
@@ -53,7 +60,9 @@ import {
|
|
|
53
60
|
useRenderProps,
|
|
54
61
|
dataAttr,
|
|
55
62
|
useIsHydrated,
|
|
63
|
+
Provider,
|
|
56
64
|
} from "./utils";
|
|
65
|
+
import { TextContext } from "./Text";
|
|
57
66
|
import { DateFieldContext } from "./DateField";
|
|
58
67
|
import { CalendarContext } from "./Calendar";
|
|
59
68
|
import { RangeCalendarContext } from "./RangeCalendar";
|
|
@@ -173,6 +182,25 @@ export interface DatePickerButtonRenderProps {
|
|
|
173
182
|
isDisabled: boolean;
|
|
174
183
|
/** Whether the calendar is open. */
|
|
175
184
|
isOpen: boolean;
|
|
185
|
+
/**
|
|
186
|
+
* Whether the button is currently pressed. Provided by the single
|
|
187
|
+
* DatePicker (fed from `createDatePicker().isButtonPressed()`); the range
|
|
188
|
+
* variant does not yet publish press state, so this is optional.
|
|
189
|
+
*/
|
|
190
|
+
isPressed?: boolean;
|
|
191
|
+
/**
|
|
192
|
+
* Whether the button is hovered. Fed from the trigger's own `createHover`;
|
|
193
|
+
* mirrors RAC `Button`'s `isHovered` renderProp so the styled S2
|
|
194
|
+
* `baseColor("gray-100")` hover-step background compiles into the className.
|
|
195
|
+
*/
|
|
196
|
+
isHovered?: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Whether the button is keyboard-focused (focus-visible). Fed from
|
|
199
|
+
* `createFocusRing`; mirrors RAC `Button`'s `isFocusVisible` so the styled
|
|
200
|
+
* S2 `focusRing()` outline (a renderProps-gated class, not a CSS
|
|
201
|
+
* `[data-focus-visible]` selector) compiles into the className.
|
|
202
|
+
*/
|
|
203
|
+
isFocusVisible?: boolean;
|
|
176
204
|
}
|
|
177
205
|
|
|
178
206
|
export interface DatePickerButtonProps extends SlotProps {
|
|
@@ -184,6 +212,12 @@ export interface DatePickerButtonProps extends SlotProps {
|
|
|
184
212
|
style?: StyleOrFunction<DatePickerButtonRenderProps>;
|
|
185
213
|
/** Whether the button is disabled. */
|
|
186
214
|
isDisabled?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Ref callback for the underlying button element. Mirrors S2's CalendarButton,
|
|
217
|
+
* whose `buttonRef` feeds `pressScale(buttonRef)`; the styled layer forwards a
|
|
218
|
+
* setter here so it can size the press transform against the real element.
|
|
219
|
+
*/
|
|
220
|
+
ref?: (element: HTMLButtonElement) => void;
|
|
187
221
|
}
|
|
188
222
|
|
|
189
223
|
export interface DateRangePickerButtonProps extends DatePickerButtonProps {}
|
|
@@ -451,6 +485,23 @@ function DatePickerInner<T extends DateValue = CalendarDate>(
|
|
|
451
485
|
isDateDisabled: stateProps.isDateDisabled,
|
|
452
486
|
});
|
|
453
487
|
|
|
488
|
+
// RAC's useDatePicker re-mounts a FRESH useCalendarState every popover open
|
|
489
|
+
// and passes autoFocus:true, so useCalendarState seeds isFocused=true and the
|
|
490
|
+
// focused cell auto-focuses (useCalendarState.mjs line 80:
|
|
491
|
+
// `useState(props.autoFocus || false)`). The port SHARES one persistent
|
|
492
|
+
// calendarState across opens, so isFocused would stay whatever it last was
|
|
493
|
+
// (false after the first close). Mirror the fresh-mount behavior by flagging
|
|
494
|
+
// the shared state focused on each false->true open transition; the
|
|
495
|
+
// CalendarCell focus effect then pulls DOM focus to the value/today cell.
|
|
496
|
+
let wasOpen = false;
|
|
497
|
+
createEffect(() => {
|
|
498
|
+
const open = datePickerState.isOpen();
|
|
499
|
+
if (open && !wasOpen) {
|
|
500
|
+
calendarState.setFocused(true);
|
|
501
|
+
}
|
|
502
|
+
wasOpen = open;
|
|
503
|
+
});
|
|
504
|
+
|
|
454
505
|
// Create date picker ARIA props
|
|
455
506
|
const pickerAria = createDatePicker(
|
|
456
507
|
() => ({
|
|
@@ -461,6 +512,18 @@ function DatePickerInner<T extends DateValue = CalendarDate>(
|
|
|
461
512
|
fieldState as unknown as DateFieldState<DateValue>,
|
|
462
513
|
overlayState as AriaDatePickerState,
|
|
463
514
|
calendarState as unknown as CalendarState<DateValue>,
|
|
515
|
+
() => fieldRef(),
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
// The composed picker's fieldProps (stamped role="presentation") are fed
|
|
519
|
+
// through createDateField — mirroring RAC's DateField consuming
|
|
520
|
+
// useDatePicker().fieldProps. This is what actually names the segments and
|
|
521
|
+
// publishes the value description through the shared hookData WeakMap; without
|
|
522
|
+
// it the segments would be unnamed and carry no selected-date announcement.
|
|
523
|
+
const fieldAria = createDateField(
|
|
524
|
+
() => pickerAria.fieldProps,
|
|
525
|
+
fieldState as unknown as DateFieldState<DateValue>,
|
|
526
|
+
() => fieldRef(),
|
|
464
527
|
);
|
|
465
528
|
|
|
466
529
|
const contextValue: DatePickerContextValue = {
|
|
@@ -515,18 +578,35 @@ function DatePickerInner<T extends DateValue = CalendarDate>(
|
|
|
515
578
|
<DateFieldContext.Provider
|
|
516
579
|
value={{
|
|
517
580
|
state: fieldState as unknown as DateFieldState<DateValue>,
|
|
581
|
+
// Read through getters so the DateInput/DateSegment consumers see the
|
|
582
|
+
// LIVE memo values (createDescription appends the value-description id
|
|
583
|
+
// via a deferred effect; froze snapshots would miss it). inputProps are
|
|
584
|
+
// the createDateField group props (role="presentation" here), which name
|
|
585
|
+
// the segments — NOT the raw pickerAria.fieldProps.
|
|
518
586
|
aria: {
|
|
519
|
-
labelProps
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
587
|
+
get labelProps() {
|
|
588
|
+
return pickerAria.labelProps;
|
|
589
|
+
},
|
|
590
|
+
get inputProps() {
|
|
591
|
+
return fieldAria.fieldProps;
|
|
592
|
+
},
|
|
593
|
+
get descriptionProps() {
|
|
594
|
+
return pickerAria.descriptionProps;
|
|
595
|
+
},
|
|
596
|
+
get errorMessageProps() {
|
|
597
|
+
return pickerAria.errorMessageProps;
|
|
598
|
+
},
|
|
523
599
|
},
|
|
524
600
|
}}
|
|
525
601
|
>
|
|
526
602
|
<CalendarContext.Provider value={calendarState as unknown as CalendarState<DateValue>}>
|
|
603
|
+
{/* BARE ROLELESS root — mirrors RAC `DatePicker`'s outer `<div>`. The
|
|
604
|
+
* presentation FieldGroup shell (rendered as a child via
|
|
605
|
+
* `DatePickerFieldGroup`) is what carries `pickerAria.groupProps`
|
|
606
|
+
* (role="presentation" + label/describedby + arrow-nav/press). A
|
|
607
|
+
* described node here would be a spurious AX entry the S2 oracle lacks. */}
|
|
527
608
|
<div
|
|
528
609
|
ref={setFieldRef}
|
|
529
|
-
{...pickerAria.groupProps}
|
|
530
610
|
class={renderProps.class()}
|
|
531
611
|
style={renderProps.style()}
|
|
532
612
|
data-disabled={dataAttr(fieldState.isDisabled())}
|
|
@@ -535,7 +615,27 @@ function DatePickerInner<T extends DateValue = CalendarDate>(
|
|
|
535
615
|
data-invalid={dataAttr(isInvalid())}
|
|
536
616
|
data-open={dataAttr(overlayState.isOpen)}
|
|
537
617
|
>
|
|
538
|
-
|
|
618
|
+
<Provider
|
|
619
|
+
values={
|
|
620
|
+
[
|
|
621
|
+
[
|
|
622
|
+
TextContext,
|
|
623
|
+
{
|
|
624
|
+
slots: {
|
|
625
|
+
get description() {
|
|
626
|
+
return pickerAria.descriptionProps;
|
|
627
|
+
},
|
|
628
|
+
get errorMessage() {
|
|
629
|
+
return pickerAria.errorMessageProps;
|
|
630
|
+
},
|
|
631
|
+
},
|
|
632
|
+
},
|
|
633
|
+
],
|
|
634
|
+
] as Array<[Context<unknown>, unknown]>
|
|
635
|
+
}
|
|
636
|
+
>
|
|
637
|
+
{props.children}
|
|
638
|
+
</Provider>
|
|
539
639
|
</div>
|
|
540
640
|
<Show when={(rest as Record<string, unknown>).name}>
|
|
541
641
|
<HiddenDateInput
|
|
@@ -626,6 +726,10 @@ function DateRangePickerInner<T extends DateValue = CalendarDate>(
|
|
|
626
726
|
};
|
|
627
727
|
|
|
628
728
|
let triggerRef: HTMLElement | null = null;
|
|
729
|
+
// The roleless root element — scopes the shared segment focus manager and the
|
|
730
|
+
// outer arrow-navigation across BOTH fields, mirroring the single DatePicker's
|
|
731
|
+
// `fieldRef`.
|
|
732
|
+
const [fieldRef, setFieldRef] = createSignal<HTMLDivElement | null>(null);
|
|
629
733
|
const overlayState = {
|
|
630
734
|
get isOpen() {
|
|
631
735
|
return isOpen();
|
|
@@ -660,6 +764,21 @@ function DateRangePickerInner<T extends DateValue = CalendarDate>(
|
|
|
660
764
|
},
|
|
661
765
|
});
|
|
662
766
|
|
|
767
|
+
// Mirror the single DatePicker: RAC re-mounts a FRESH useRangeCalendarState
|
|
768
|
+
// per popover open with autoFocus:true, so isFocused seeds true and the focused
|
|
769
|
+
// cell auto-focuses AND publishes its range-selection prompt describedby
|
|
770
|
+
// ("Click to start selecting date range"). The port shares one persistent
|
|
771
|
+
// range state across opens, so flag it focused on each false->true open
|
|
772
|
+
// transition to reproduce that behavior.
|
|
773
|
+
let wasRangeOpen = false;
|
|
774
|
+
createEffect(() => {
|
|
775
|
+
const open = overlayState.isOpen;
|
|
776
|
+
if (open && !wasRangeOpen) {
|
|
777
|
+
calendarState.setFocused(true);
|
|
778
|
+
}
|
|
779
|
+
wasRangeOpen = open;
|
|
780
|
+
});
|
|
781
|
+
|
|
663
782
|
const isInvalid = createMemo(
|
|
664
783
|
() =>
|
|
665
784
|
Boolean((rest as { isInvalid?: boolean }).isInvalid) ||
|
|
@@ -716,7 +835,12 @@ function DateRangePickerInner<T extends DateValue = CalendarDate>(
|
|
|
716
835
|
hideTimeZone: stateProps.hideTimeZone,
|
|
717
836
|
placeholderValue: stateProps.placeholderValue,
|
|
718
837
|
validationState: () => (isInvalid() ? "invalid" : access(stateProps.validationState)),
|
|
719
|
-
isDateUnavailable
|
|
838
|
+
// The range picker's isDateUnavailable is anchor-aware (date, anchorDate),
|
|
839
|
+
// but a text field has no range anchor, so adapt it to the field's 1-arg form
|
|
840
|
+
// by always passing a null anchor (checks raw per-date availability).
|
|
841
|
+
isDateUnavailable: stateProps.isDateUnavailable
|
|
842
|
+
? (date: DateValue) => stateProps.isDateUnavailable!(date, null)
|
|
843
|
+
: undefined,
|
|
720
844
|
} satisfies Partial<DateFieldStateProps<T>>;
|
|
721
845
|
|
|
722
846
|
const startFieldState = createDateFieldState<T>({
|
|
@@ -739,14 +863,36 @@ function DateRangePickerInner<T extends DateValue = CalendarDate>(
|
|
|
739
863
|
}),
|
|
740
864
|
calendarState as unknown as RangeCalendarState<DateValue>,
|
|
741
865
|
overlayState as AriaDatePickerState,
|
|
866
|
+
() => fieldRef(),
|
|
867
|
+
);
|
|
868
|
+
|
|
869
|
+
// Each range field's presentation field props (stamped role="presentation" +
|
|
870
|
+
// the SHARED focus manager) are fed through createDateField — mirroring RAC's
|
|
871
|
+
// two `<DateInput>`s consuming useDateRangePicker().start/endFieldProps. This
|
|
872
|
+
// names the segments ("month, Start Date" / "month, End Date") and publishes
|
|
873
|
+
// them through the shared hookData WeakMap; the shared focus manager makes arrow
|
|
874
|
+
// keys and auto-advance walk across the start/end boundary.
|
|
875
|
+
const startFieldAria = createDateField(
|
|
876
|
+
() => pickerAria.startFieldProps,
|
|
877
|
+
startFieldState as unknown as DateFieldState<DateValue>,
|
|
878
|
+
() => fieldRef(),
|
|
879
|
+
);
|
|
880
|
+
const endFieldAria = createDateField(
|
|
881
|
+
() => pickerAria.endFieldProps,
|
|
882
|
+
endFieldState as unknown as DateFieldState<DateValue>,
|
|
883
|
+
() => fieldRef(),
|
|
742
884
|
);
|
|
743
885
|
|
|
744
886
|
const startFieldContext: DateRangePickerFieldContextValue = {
|
|
745
887
|
state: startFieldState as unknown as DateFieldState<DateValue>,
|
|
746
888
|
aria: {
|
|
747
889
|
labelProps: {},
|
|
890
|
+
// The DateInput group carries createDateField's fieldProps (role="presentation"
|
|
891
|
+
// + arrow-nav bubbling + unicode-bidi isolate), mirroring the standalone
|
|
892
|
+
// DateField's `inputProps ← fieldProps` mapping. NO hiddenInputProps — the
|
|
893
|
+
// range owner renders its HiddenDateInput siblings below.
|
|
748
894
|
get inputProps() {
|
|
749
|
-
return
|
|
895
|
+
return startFieldAria.fieldProps;
|
|
750
896
|
},
|
|
751
897
|
get descriptionProps() {
|
|
752
898
|
return pickerAria.descriptionProps;
|
|
@@ -762,7 +908,7 @@ function DateRangePickerInner<T extends DateValue = CalendarDate>(
|
|
|
762
908
|
aria: {
|
|
763
909
|
labelProps: {},
|
|
764
910
|
get inputProps() {
|
|
765
|
-
return
|
|
911
|
+
return endFieldAria.fieldProps;
|
|
766
912
|
},
|
|
767
913
|
get descriptionProps() {
|
|
768
914
|
return pickerAria.descriptionProps;
|
|
@@ -813,8 +959,15 @@ function DateRangePickerInner<T extends DateValue = CalendarDate>(
|
|
|
813
959
|
<RangeCalendarContext.Provider
|
|
814
960
|
value={calendarState as unknown as RangeCalendarState<DateValue>}
|
|
815
961
|
>
|
|
962
|
+
{/* BARE ROLELESS root — mirrors RAC `DateRangePicker`'s outer `<div>`.
|
|
963
|
+
* The presentation FieldGroup shell (rendered as a child via the styled
|
|
964
|
+
* DateRangeDisplay) is what carries `pickerAria.groupProps` (role=
|
|
965
|
+
* "presentation" + label/describedby + outer arrow-nav/press). A described
|
|
966
|
+
* or role="group" node here would be a spurious AX entry the S2 oracle
|
|
967
|
+
* lacks. The ref scopes the shared segment focus manager across both
|
|
968
|
+
* fields (see createDateRangePicker). */}
|
|
816
969
|
<div
|
|
817
|
-
{
|
|
970
|
+
ref={setFieldRef}
|
|
818
971
|
class={renderProps.class()}
|
|
819
972
|
style={renderProps.style()}
|
|
820
973
|
data-disabled={dataAttr(calendarState.isDisabled())}
|
|
@@ -823,7 +976,27 @@ function DateRangePickerInner<T extends DateValue = CalendarDate>(
|
|
|
823
976
|
data-invalid={dataAttr(isInvalid())}
|
|
824
977
|
data-open={dataAttr(overlayState.isOpen)}
|
|
825
978
|
>
|
|
826
|
-
|
|
979
|
+
<Provider
|
|
980
|
+
values={
|
|
981
|
+
[
|
|
982
|
+
[
|
|
983
|
+
TextContext,
|
|
984
|
+
{
|
|
985
|
+
slots: {
|
|
986
|
+
get description() {
|
|
987
|
+
return pickerAria.descriptionProps;
|
|
988
|
+
},
|
|
989
|
+
get errorMessage() {
|
|
990
|
+
return pickerAria.errorMessageProps;
|
|
991
|
+
},
|
|
992
|
+
},
|
|
993
|
+
},
|
|
994
|
+
],
|
|
995
|
+
] as Array<[Context<unknown>, unknown]>
|
|
996
|
+
}
|
|
997
|
+
>
|
|
998
|
+
{props.children}
|
|
999
|
+
</Provider>
|
|
827
1000
|
</div>
|
|
828
1001
|
<Show when={(rest as Record<string, unknown>).startName}>
|
|
829
1002
|
<HiddenDateInput
|
|
@@ -859,14 +1032,38 @@ function DateRangePickerInner<T extends DateValue = CalendarDate>(
|
|
|
859
1032
|
export function DatePickerButton(props: DatePickerButtonProps): JSX.Element {
|
|
860
1033
|
const context = useDatePickerContext();
|
|
861
1034
|
|
|
1035
|
+
// Mirror RAC's `buttonProps.isDisabled = props.isDisabled || props.isReadOnly`
|
|
1036
|
+
// (a read-only picker can't open its calendar) — `createDatePicker` computes
|
|
1037
|
+
// this as `isButtonDisabled()`. Reading `fieldState.isDisabled()` alone would
|
|
1038
|
+
// miss the read-only case (read-only ≠ disabled on the field), so the trigger
|
|
1039
|
+
// would paint enabled while the S2 oracle dims it.
|
|
1040
|
+
const isDisabled = () => context.pickerAria.isButtonDisabled() || (props.isDisabled ?? false);
|
|
1041
|
+
|
|
1042
|
+
// Mirror RAC: the trigger is a `<Button>` whose own `useFocusRing`/`useHover`/
|
|
1043
|
+
// `usePress` drive its interaction paint state. The press signal is owned by
|
|
1044
|
+
// `createDatePicker` (`isButtonPressed`); focus-visible and hover are wired
|
|
1045
|
+
// here so the S2 `focusRing()`/`baseColor()` selectors (`data-focus-visible`,
|
|
1046
|
+
// `data-hovered`, `data-pressed`) resolve exactly as they do upstream.
|
|
1047
|
+
const { isFocused, isFocusVisible, focusProps } = createFocusRing();
|
|
1048
|
+
const { isHovered, hoverProps } = createHover({
|
|
1049
|
+
get isDisabled() {
|
|
1050
|
+
return isDisabled();
|
|
1051
|
+
},
|
|
1052
|
+
});
|
|
1053
|
+
|
|
862
1054
|
const renderValues = createMemo<DatePickerButtonRenderProps>(() => ({
|
|
863
|
-
isDisabled:
|
|
1055
|
+
isDisabled: isDisabled(),
|
|
864
1056
|
isOpen: context.overlayState.isOpen,
|
|
1057
|
+
isPressed: context.pickerAria.isButtonPressed(),
|
|
1058
|
+
isHovered: isHovered(),
|
|
1059
|
+
isFocusVisible: isFocusVisible(),
|
|
865
1060
|
}));
|
|
866
1061
|
|
|
867
1062
|
const renderProps = useRenderProps(
|
|
868
1063
|
{
|
|
869
|
-
children
|
|
1064
|
+
get children() {
|
|
1065
|
+
return props.children;
|
|
1066
|
+
},
|
|
870
1067
|
class: props.class,
|
|
871
1068
|
style: props.style,
|
|
872
1069
|
defaultClassName: "solidaria-DatePickerButton",
|
|
@@ -882,17 +1079,30 @@ export function DatePickerButton(props: DatePickerButtonProps): JSX.Element {
|
|
|
882
1079
|
return props.children ?? "📅";
|
|
883
1080
|
};
|
|
884
1081
|
|
|
1082
|
+
const buttonProps = createMemo(() =>
|
|
1083
|
+
mergeProps(
|
|
1084
|
+
context.pickerAria.buttonProps as Record<string, unknown>,
|
|
1085
|
+
focusProps as Record<string, unknown>,
|
|
1086
|
+
hoverProps as Record<string, unknown>,
|
|
1087
|
+
),
|
|
1088
|
+
);
|
|
1089
|
+
|
|
885
1090
|
return (
|
|
886
1091
|
<button
|
|
887
1092
|
ref={(el) => {
|
|
888
1093
|
context.setTriggerRef(el);
|
|
1094
|
+
props.ref?.(el);
|
|
889
1095
|
}}
|
|
890
|
-
{...
|
|
1096
|
+
{...buttonProps()}
|
|
891
1097
|
class={renderProps.class()}
|
|
892
1098
|
style={renderProps.style()}
|
|
893
|
-
disabled={
|
|
894
|
-
data-disabled={dataAttr(
|
|
1099
|
+
disabled={isDisabled()}
|
|
1100
|
+
data-disabled={dataAttr(isDisabled())}
|
|
895
1101
|
data-open={dataAttr(context.overlayState.isOpen)}
|
|
1102
|
+
attr:data-hovered={isHovered() ? "true" : undefined}
|
|
1103
|
+
attr:data-focused={isFocused() ? "true" : undefined}
|
|
1104
|
+
attr:data-focus-visible={isFocusVisible() ? "true" : undefined}
|
|
1105
|
+
attr:data-pressed={context.pickerAria.isButtonPressed() ? "true" : undefined}
|
|
896
1106
|
>
|
|
897
1107
|
{getChildren()}
|
|
898
1108
|
</button>
|
|
@@ -902,14 +1112,37 @@ export function DatePickerButton(props: DatePickerButtonProps): JSX.Element {
|
|
|
902
1112
|
export function DateRangePickerButton(props: DateRangePickerButtonProps): JSX.Element {
|
|
903
1113
|
const context = useDateRangePickerContext();
|
|
904
1114
|
|
|
1115
|
+
// Mirror RAC's `buttonProps.isDisabled = props.isDisabled || props.isReadOnly`
|
|
1116
|
+
// (a read-only picker can't open its calendar) — `createDateRangePicker` computes
|
|
1117
|
+
// this as `isButtonDisabled()`. Reading `calendarState.isDisabled()` alone would
|
|
1118
|
+
// miss the read-only case, so the trigger would paint enabled while S2 dims it.
|
|
1119
|
+
const isDisabled = () => context.pickerAria.isButtonDisabled() || (props.isDisabled ?? false);
|
|
1120
|
+
|
|
1121
|
+
// Mirror RAC: the trigger is a `<Button>` whose own `useFocusRing`/`useHover`/
|
|
1122
|
+
// `usePress` drive its interaction paint state. The press signal is owned by
|
|
1123
|
+
// `createDateRangePicker` (`isButtonPressed`); focus-visible and hover are wired
|
|
1124
|
+
// here so the S2 `focusRing()`/`baseColor()` selectors (`data-focus-visible`,
|
|
1125
|
+
// `data-hovered`, `data-pressed`) resolve exactly as they do upstream.
|
|
1126
|
+
const { isFocused, isFocusVisible, focusProps } = createFocusRing();
|
|
1127
|
+
const { isHovered, hoverProps } = createHover({
|
|
1128
|
+
get isDisabled() {
|
|
1129
|
+
return isDisabled();
|
|
1130
|
+
},
|
|
1131
|
+
});
|
|
1132
|
+
|
|
905
1133
|
const renderValues = createMemo<DatePickerButtonRenderProps>(() => ({
|
|
906
|
-
isDisabled:
|
|
1134
|
+
isDisabled: isDisabled(),
|
|
907
1135
|
isOpen: context.overlayState.isOpen,
|
|
1136
|
+
isPressed: context.pickerAria.isButtonPressed(),
|
|
1137
|
+
isHovered: isHovered(),
|
|
1138
|
+
isFocusVisible: isFocusVisible(),
|
|
908
1139
|
}));
|
|
909
1140
|
|
|
910
1141
|
const renderProps = useRenderProps(
|
|
911
1142
|
{
|
|
912
|
-
children
|
|
1143
|
+
get children() {
|
|
1144
|
+
return props.children;
|
|
1145
|
+
},
|
|
913
1146
|
class: props.class,
|
|
914
1147
|
style: props.style,
|
|
915
1148
|
defaultClassName: "solidaria-DateRangePickerButton",
|
|
@@ -924,26 +1157,56 @@ export function DateRangePickerButton(props: DateRangePickerButtonProps): JSX.El
|
|
|
924
1157
|
return props.children ?? "📅";
|
|
925
1158
|
};
|
|
926
1159
|
|
|
1160
|
+
const buttonProps = createMemo(() =>
|
|
1161
|
+
mergeProps(
|
|
1162
|
+
context.pickerAria.buttonProps as Record<string, unknown>,
|
|
1163
|
+
focusProps as Record<string, unknown>,
|
|
1164
|
+
hoverProps as Record<string, unknown>,
|
|
1165
|
+
),
|
|
1166
|
+
);
|
|
1167
|
+
|
|
927
1168
|
return (
|
|
928
1169
|
<button
|
|
929
|
-
ref={(el) =>
|
|
930
|
-
|
|
1170
|
+
ref={(el) => {
|
|
1171
|
+
context.setTriggerRef(el);
|
|
1172
|
+
props.ref?.(el);
|
|
1173
|
+
}}
|
|
1174
|
+
{...buttonProps()}
|
|
931
1175
|
class={renderProps.class()}
|
|
932
1176
|
style={renderProps.style()}
|
|
933
|
-
disabled={
|
|
934
|
-
data-disabled={dataAttr(
|
|
1177
|
+
disabled={isDisabled()}
|
|
1178
|
+
data-disabled={dataAttr(isDisabled())}
|
|
935
1179
|
data-open={dataAttr(context.overlayState.isOpen)}
|
|
1180
|
+
attr:data-hovered={isHovered() ? "true" : undefined}
|
|
1181
|
+
attr:data-focused={isFocused() ? "true" : undefined}
|
|
1182
|
+
attr:data-focus-visible={isFocusVisible() ? "true" : undefined}
|
|
1183
|
+
attr:data-pressed={context.pickerAria.isButtonPressed() ? "true" : undefined}
|
|
936
1184
|
>
|
|
937
1185
|
{getChildren()}
|
|
938
1186
|
</button>
|
|
939
1187
|
);
|
|
940
1188
|
}
|
|
941
1189
|
|
|
1190
|
+
/**
|
|
1191
|
+
* Render props for the popover surface, mirroring RAC `Popover`'s
|
|
1192
|
+
* enter/exit/placement renderProps. The styled layer keys the S2
|
|
1193
|
+
* opacity/translate enter transition on these (a renderProps-gated class, not a
|
|
1194
|
+
* CSS `[data-entering]` selector).
|
|
1195
|
+
*/
|
|
1196
|
+
export interface DatePickerContentRenderProps {
|
|
1197
|
+
/** Whether the popover is playing its enter transition (`data-entering`). */
|
|
1198
|
+
isEntering: boolean;
|
|
1199
|
+
/** Whether the popover is playing its exit transition (`data-exiting`). */
|
|
1200
|
+
isExiting: boolean;
|
|
1201
|
+
/** The resolved placement axis, for the direction-dependent translate. */
|
|
1202
|
+
placement: PlacementAxis | null;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
942
1205
|
export interface DatePickerContentProps extends SlotProps {
|
|
943
1206
|
/** The children of the component. */
|
|
944
1207
|
children?: JSX.Element;
|
|
945
|
-
/** The CSS className for the element. */
|
|
946
|
-
class?: string;
|
|
1208
|
+
/** The CSS className for the element, or a function of the render props. */
|
|
1209
|
+
class?: string | ((renderProps: DatePickerContentRenderProps) => string);
|
|
947
1210
|
/** The inline style for the element. */
|
|
948
1211
|
style?: JSX.CSSProperties;
|
|
949
1212
|
}
|
|
@@ -971,10 +1234,12 @@ export interface DatePickerDescriptionProps {
|
|
|
971
1234
|
|
|
972
1235
|
export function DatePickerDescription(props: DatePickerDescriptionProps): JSX.Element {
|
|
973
1236
|
const context = useDatePickerContext();
|
|
1237
|
+
// Rendered as <span> (→ AX role "text"), mirroring S2's <Text slot="description">
|
|
1238
|
+
// and the standalone DateFieldDescription — NOT a <p> (paragraph).
|
|
974
1239
|
return (
|
|
975
|
-
<
|
|
1240
|
+
<span {...context.pickerAria.descriptionProps} class={props.class}>
|
|
976
1241
|
{props.children}
|
|
977
|
-
</
|
|
1242
|
+
</span>
|
|
978
1243
|
);
|
|
979
1244
|
}
|
|
980
1245
|
|
|
@@ -985,10 +1250,12 @@ export interface DatePickerErrorMessageProps {
|
|
|
985
1250
|
|
|
986
1251
|
export function DatePickerErrorMessage(props: DatePickerErrorMessageProps): JSX.Element {
|
|
987
1252
|
const context = useDatePickerContext();
|
|
1253
|
+
// Rendered as <span> (→ AX role "text"), mirroring S2's <FieldError> and the
|
|
1254
|
+
// standalone DateFieldErrorMessage — NOT a <p> and NOT role="alert".
|
|
988
1255
|
return (
|
|
989
|
-
<
|
|
1256
|
+
<span {...context.pickerAria.errorMessageProps} class={props.class}>
|
|
990
1257
|
{props.children}
|
|
991
|
-
</
|
|
1258
|
+
</span>
|
|
992
1259
|
);
|
|
993
1260
|
}
|
|
994
1261
|
|
|
@@ -1013,10 +1280,12 @@ export interface DateRangePickerDescriptionProps {
|
|
|
1013
1280
|
|
|
1014
1281
|
export function DateRangePickerDescription(props: DateRangePickerDescriptionProps): JSX.Element {
|
|
1015
1282
|
const context = useDateRangePickerContext();
|
|
1283
|
+
// Rendered as <span> (→ AX role "text"), mirroring S2's <Text slot="description">
|
|
1284
|
+
// and the single DatePickerDescription — NOT a <p> (paragraph).
|
|
1016
1285
|
return (
|
|
1017
|
-
<
|
|
1286
|
+
<span {...context.pickerAria.descriptionProps} class={props.class}>
|
|
1018
1287
|
{props.children}
|
|
1019
|
-
</
|
|
1288
|
+
</span>
|
|
1020
1289
|
);
|
|
1021
1290
|
}
|
|
1022
1291
|
|
|
@@ -1027,10 +1296,12 @@ export interface DateRangePickerErrorMessageProps {
|
|
|
1027
1296
|
|
|
1028
1297
|
export function DateRangePickerErrorMessage(props: DateRangePickerErrorMessageProps): JSX.Element {
|
|
1029
1298
|
const context = useDateRangePickerContext();
|
|
1299
|
+
// Rendered as <span> (→ AX role "text"), mirroring S2's <FieldError> and the
|
|
1300
|
+
// single DatePickerErrorMessage — NOT a <p> and NOT role="alert".
|
|
1030
1301
|
return (
|
|
1031
|
-
<
|
|
1302
|
+
<span {...context.pickerAria.errorMessageProps} class={props.class}>
|
|
1032
1303
|
{props.children}
|
|
1033
|
-
</
|
|
1304
|
+
</span>
|
|
1034
1305
|
);
|
|
1035
1306
|
}
|
|
1036
1307
|
|
|
@@ -1054,13 +1325,16 @@ function createEscapeDismissFallback(isOpen: () => boolean, close: () => void):
|
|
|
1054
1325
|
export function DatePickerContent(props: DatePickerContentProps): JSX.Element {
|
|
1055
1326
|
const context = useDatePickerContext();
|
|
1056
1327
|
const portalContext = useUNSAFE_PortalContext();
|
|
1057
|
-
let
|
|
1328
|
+
// A signal (not a plain `let`) so the enter-animation effect re-runs when the
|
|
1329
|
+
// section mounts on open — `createEnterAnimation` reads this to know the
|
|
1330
|
+
// element exists before removing the initial `data-entering` styles.
|
|
1331
|
+
const [contentRef, setContentRef] = createSignal<HTMLElement>();
|
|
1058
1332
|
const portalContainer = () => portalContext.getContainer?.() ?? undefined;
|
|
1059
1333
|
|
|
1060
1334
|
const popoverAria = createPopover(
|
|
1061
1335
|
{
|
|
1062
1336
|
triggerRef: () => context.triggerRef()?.parentElement ?? context.triggerRef(),
|
|
1063
|
-
popoverRef: () => contentRef ?? null,
|
|
1337
|
+
popoverRef: () => contentRef() ?? null,
|
|
1064
1338
|
placement: "bottom start",
|
|
1065
1339
|
offset: 8,
|
|
1066
1340
|
isNonModal: false,
|
|
@@ -1076,6 +1350,35 @@ export function DatePickerContent(props: DatePickerContentProps): JSX.Element {
|
|
|
1076
1350
|
|
|
1077
1351
|
createEscapeDismissFallback(() => context.overlayState.isOpen, context.overlayState.close);
|
|
1078
1352
|
|
|
1353
|
+
// Mirror S2's `<Popover>` enter transition (RAC `useEnterAnimation`): the
|
|
1354
|
+
// surface mounts carrying `data-entering` (opacity 0 + a small placement-ward
|
|
1355
|
+
// translate), which an effect removes on the next frame so the CSS transition
|
|
1356
|
+
// plays. The exit half is out of scope for this unit — the popover unmounts on
|
|
1357
|
+
// close (no `isOpen || isExiting` gate), so `isExiting` stays false; only the
|
|
1358
|
+
// enter motion is certified (D2).
|
|
1359
|
+
const isEntering = createEnterAnimation(contentRef, () => context.overlayState.isOpen);
|
|
1360
|
+
|
|
1361
|
+
const renderProps = (): DatePickerContentRenderProps => ({
|
|
1362
|
+
isEntering: isEntering(),
|
|
1363
|
+
isExiting: false,
|
|
1364
|
+
// Seed the base placement so the ENTER frame already carries the
|
|
1365
|
+
// placement-ward `translate` (S2's popover motion is placement-gated:
|
|
1366
|
+
// `translateY: { placement: { bottom: { isEntering: -4 } } }`). RAC resolves
|
|
1367
|
+
// placement in a `useLayoutEffect` BEFORE the first paint, so no painted
|
|
1368
|
+
// frame is ever null-placement; the port's positioning `createEffect` lands
|
|
1369
|
+
// one frame later, so without this seed the entering frame drops `translateY`
|
|
1370
|
+
// and only `opacity` transitions (D2 caught the missing translate). The
|
|
1371
|
+
// desired placement is `bottom start` (see `createPopover` above), so the
|
|
1372
|
+
// base axis is always `bottom` until the measure refines it.
|
|
1373
|
+
placement: popoverAria.placement() ?? "bottom",
|
|
1374
|
+
});
|
|
1375
|
+
|
|
1376
|
+
const resolvedClass = (): string => {
|
|
1377
|
+
const c = props.class;
|
|
1378
|
+
if (typeof c === "function") return c(renderProps());
|
|
1379
|
+
return c ?? "solidaria-DatePickerContent";
|
|
1380
|
+
};
|
|
1381
|
+
|
|
1079
1382
|
const cleanPopoverProps = () => {
|
|
1080
1383
|
const {
|
|
1081
1384
|
style: _style,
|
|
@@ -1095,28 +1398,39 @@ export function DatePickerContent(props: DatePickerContentProps): JSX.Element {
|
|
|
1095
1398
|
};
|
|
1096
1399
|
};
|
|
1097
1400
|
|
|
1098
|
-
//
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
}
|
|
1104
|
-
});
|
|
1401
|
+
// Close-focus restoration is delegated to the overlay's `FocusScope`
|
|
1402
|
+
// (`restoreFocus`) — exactly as RAC's DatePicker does, and as certified Select
|
|
1403
|
+
// and Menu do. The prior ad-hoc effect (`if (!open) triggerRef().focus()`)
|
|
1404
|
+
// fired once on mount with `open === false`, stealing focus to the trigger and
|
|
1405
|
+
// painting a phantom focus ring at rest.
|
|
1105
1406
|
|
|
1106
1407
|
return (
|
|
1107
1408
|
<Show when={context.overlayState.isOpen}>
|
|
1108
1409
|
<Portal mount={portalContainer()}>
|
|
1109
1410
|
<FocusScope contain restoreFocus>
|
|
1411
|
+
{/* Un-folded to mirror S2's `<Popover>` DOM. The OUTER role-null `<div>`
|
|
1412
|
+
* is the positioned surface that carries the enter motion + chrome —
|
|
1413
|
+
* this is the element RAC/S2 animate (`AriaPopover`'s div: role null, no
|
|
1414
|
+
* tabindex, accessible name computed from the calendar's textContent).
|
|
1415
|
+
* A nested `role="dialog"` element (RAC's `Dialog`, which S2's
|
|
1416
|
+
* CalendarPopover wraps the Calendar in) carries the dialog semantics.
|
|
1417
|
+
* Folding both onto one `<section role="dialog">` made D2 animate the
|
|
1418
|
+
* dialog node instead of the role-null div; the role-null wrapper is
|
|
1419
|
+
* pruned from the AX tree so D5/D6 are unaffected. */}
|
|
1110
1420
|
<div
|
|
1111
|
-
ref={
|
|
1421
|
+
ref={setContentRef}
|
|
1112
1422
|
{...cleanPopoverProps()}
|
|
1113
|
-
{
|
|
1114
|
-
tabIndex={-1}
|
|
1115
|
-
class={props.class ?? "solidaria-DatePickerContent"}
|
|
1423
|
+
class={resolvedClass()}
|
|
1116
1424
|
style={mergedStyle()}
|
|
1117
|
-
data-placement={popoverAria.placement() ??
|
|
1425
|
+
data-placement={popoverAria.placement() ?? "bottom"}
|
|
1426
|
+
data-entering={dataAttr(isEntering())}
|
|
1118
1427
|
>
|
|
1119
|
-
{
|
|
1428
|
+
{/* RAC's `Dialog` renders a `<section role="dialog">` by default — the
|
|
1429
|
+
* D5 roving trail records this element's tag, so it must be `section`
|
|
1430
|
+
* (a `<div>` here regressed the focus-trail tag match). */}
|
|
1431
|
+
<section {...context.pickerAria.dialogProps} tabIndex={-1}>
|
|
1432
|
+
{props.children}
|
|
1433
|
+
</section>
|
|
1120
1434
|
</div>
|
|
1121
1435
|
</FocusScope>
|
|
1122
1436
|
</Portal>
|
|
@@ -1127,13 +1441,16 @@ export function DatePickerContent(props: DatePickerContentProps): JSX.Element {
|
|
|
1127
1441
|
export function DateRangePickerContent(props: DateRangePickerContentProps): JSX.Element {
|
|
1128
1442
|
const context = useDateRangePickerContext();
|
|
1129
1443
|
const portalContext = useUNSAFE_PortalContext();
|
|
1130
|
-
let
|
|
1444
|
+
// A signal (not a plain `let`) so the enter-animation effect re-runs when the
|
|
1445
|
+
// surface mounts on open — `createEnterAnimation` reads this to know the
|
|
1446
|
+
// element exists before removing the initial `data-entering` styles.
|
|
1447
|
+
const [contentRef, setContentRef] = createSignal<HTMLElement>();
|
|
1131
1448
|
const portalContainer = () => portalContext.getContainer?.() ?? undefined;
|
|
1132
1449
|
|
|
1133
1450
|
const popoverAria = createPopover(
|
|
1134
1451
|
{
|
|
1135
1452
|
triggerRef: () => context.triggerRef()?.parentElement ?? context.triggerRef(),
|
|
1136
|
-
popoverRef: () => contentRef ?? null,
|
|
1453
|
+
popoverRef: () => contentRef() ?? null,
|
|
1137
1454
|
placement: "bottom start",
|
|
1138
1455
|
offset: 8,
|
|
1139
1456
|
isNonModal: false,
|
|
@@ -1149,6 +1466,26 @@ export function DateRangePickerContent(props: DateRangePickerContentProps): JSX.
|
|
|
1149
1466
|
|
|
1150
1467
|
createEscapeDismissFallback(() => context.overlayState.isOpen, context.overlayState.close);
|
|
1151
1468
|
|
|
1469
|
+
// Mirror S2's `<Popover>` enter transition (RAC `useEnterAnimation`): the
|
|
1470
|
+
// surface mounts carrying `data-entering` (opacity 0 + a small placement-ward
|
|
1471
|
+
// translate), which an effect removes on the next frame so the CSS transition
|
|
1472
|
+
// plays. Only the enter half is certified (D2) — the popover unmounts on close.
|
|
1473
|
+
const isEntering = createEnterAnimation(contentRef, () => context.overlayState.isOpen);
|
|
1474
|
+
|
|
1475
|
+
const renderProps = (): DatePickerContentRenderProps => ({
|
|
1476
|
+
isEntering: isEntering(),
|
|
1477
|
+
isExiting: false,
|
|
1478
|
+
// Seed the base placement so the ENTER frame already carries the
|
|
1479
|
+
// placement-ward `translate` (see the single DatePickerContent note).
|
|
1480
|
+
placement: popoverAria.placement() ?? "bottom",
|
|
1481
|
+
});
|
|
1482
|
+
|
|
1483
|
+
const resolvedClass = (): string => {
|
|
1484
|
+
const c = props.class;
|
|
1485
|
+
if (typeof c === "function") return c(renderProps());
|
|
1486
|
+
return c ?? "solidaria-DateRangePickerContent";
|
|
1487
|
+
};
|
|
1488
|
+
|
|
1152
1489
|
const cleanPopoverProps = () => {
|
|
1153
1490
|
const {
|
|
1154
1491
|
style: _style,
|
|
@@ -1168,28 +1505,31 @@ export function DateRangePickerContent(props: DateRangePickerContentProps): JSX.
|
|
|
1168
1505
|
};
|
|
1169
1506
|
};
|
|
1170
1507
|
|
|
1171
|
-
//
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
if (!open) {
|
|
1175
|
-
requestAnimationFrame(() => context.triggerRef()?.focus());
|
|
1176
|
-
}
|
|
1177
|
-
});
|
|
1508
|
+
// Close-focus restoration is delegated to the overlay's `FocusScope`
|
|
1509
|
+
// (`restoreFocus`) — see the single-value `DatePickerContent` note. The prior
|
|
1510
|
+
// ad-hoc effect fired on mount and painted a phantom focus ring at rest.
|
|
1178
1511
|
|
|
1179
1512
|
return (
|
|
1180
1513
|
<Show when={context.overlayState.isOpen}>
|
|
1181
1514
|
<Portal mount={portalContainer()}>
|
|
1182
1515
|
<FocusScope contain restoreFocus>
|
|
1516
|
+
{/* Un-folded to mirror S2's `<Popover>` DOM (see DatePickerContent).
|
|
1517
|
+
* OUTER role-null `<div>` = positioned surface carrying the enter
|
|
1518
|
+
* motion + chrome (the element RAC/S2 animate; pruned from the AX
|
|
1519
|
+
* tree). Nested `<section role="dialog">` carries the dialog
|
|
1520
|
+
* semantics — the D5 roving trail records this tag, so it must be
|
|
1521
|
+
* `section`, not a folded `div`. */}
|
|
1183
1522
|
<div
|
|
1184
|
-
ref={
|
|
1523
|
+
ref={setContentRef}
|
|
1185
1524
|
{...cleanPopoverProps()}
|
|
1186
|
-
{
|
|
1187
|
-
tabIndex={-1}
|
|
1188
|
-
class={props.class ?? "solidaria-DateRangePickerContent"}
|
|
1525
|
+
class={resolvedClass()}
|
|
1189
1526
|
style={mergedStyle()}
|
|
1190
|
-
data-placement={popoverAria.placement() ??
|
|
1527
|
+
data-placement={popoverAria.placement() ?? "bottom"}
|
|
1528
|
+
data-entering={dataAttr(isEntering())}
|
|
1191
1529
|
>
|
|
1192
|
-
{
|
|
1530
|
+
<section {...context.pickerAria.dialogProps} tabIndex={-1}>
|
|
1531
|
+
{props.children}
|
|
1532
|
+
</section>
|
|
1193
1533
|
</div>
|
|
1194
1534
|
</FocusScope>
|
|
1195
1535
|
</Portal>
|