@proyecto-viviana/solidaria-components 0.3.1 → 0.4.0
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.js +184 -0
- package/dist/ActionBar.js.map +1 -0
- package/dist/ActionBar.jsx +128 -0
- package/dist/ActionBar.jsx.map +1 -0
- 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.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 +334 -0
- package/dist/Breadcrumbs.js.map +1 -0
- package/dist/Breadcrumbs.jsx +266 -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 +538 -0
- package/dist/Calendar.js.map +1 -0
- package/dist/Calendar.jsx +333 -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 +1720 -0
- package/dist/Color.js.map +1 -0
- package/dist/Color.jsx +1344 -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 -5
- package/dist/ComboBox.d.ts.map +1 -1
- package/dist/ComboBox.js +992 -0
- package/dist/ComboBox.js.map +1 -0
- package/dist/ComboBox.jsx +714 -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 +3 -3
- package/dist/DateField.d.ts.map +1 -1
- package/dist/DateField.js +4 -0
- package/dist/DateField.jsx +4 -0
- package/dist/DateField2.js +499 -0
- package/dist/DateField2.js.map +1 -0
- package/dist/DateField2.jsx +317 -0
- package/dist/DateField2.jsx.map +1 -0
- package/dist/DatePicker.d.ts +4 -4
- package/dist/DatePicker.d.ts.map +1 -1
- package/dist/DatePicker.js +991 -0
- package/dist/DatePicker.js.map +1 -0
- package/dist/DatePicker.jsx +682 -0
- package/dist/DatePicker.jsx.map +1 -0
- 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 +328 -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/HiddenTimeInput.js +104 -0
- package/dist/HiddenTimeInput.js.map +1 -0
- package/dist/HiddenTimeInput.jsx +69 -0
- package/dist/HiddenTimeInput.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.map +1 -1
- package/dist/ListBox.js +670 -0
- package/dist/ListBox.js.map +1 -0
- package/dist/ListBox.jsx +508 -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 +380 -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 +464 -0
- package/dist/Popover.js.map +1 -0
- package/dist/Popover.jsx +333 -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 +410 -0
- package/dist/RangeCalendar.js.map +1 -0
- package/dist/RangeCalendar.jsx +253 -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 +643 -0
- package/dist/SearchField.js.map +1 -0
- package/dist/SearchField.jsx +526 -0
- package/dist/SearchField.jsx.map +1 -0
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js +1031 -0
- package/dist/Select.js.map +1 -0
- package/dist/Select.jsx +744 -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 +165 -0
- package/dist/SharedElementTransition.js.map +1 -0
- package/dist/SharedElementTransition.jsx +138 -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.js +198 -0
- package/dist/StepList.js.map +1 -0
- package/dist/StepList.jsx +141 -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 +48 -0
- package/dist/Table.d.ts.map +1 -1
- package/dist/Table.js +1759 -0
- package/dist/Table.js.map +1 -0
- package/dist/Table.jsx +1348 -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 +595 -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.map +1 -1
- package/dist/TagGroup.js +378 -0
- package/dist/TagGroup.js.map +1 -0
- package/dist/TagGroup.jsx +270 -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 +7 -6
- package/dist/TextField.d.ts.map +1 -1
- package/dist/TextField.js +436 -0
- package/dist/TextField.js.map +1 -0
- package/dist/TextField.jsx +403 -0
- package/dist/TextField.jsx.map +1 -0
- package/dist/TimeField.d.ts +3 -3
- package/dist/TimeField.d.ts.map +1 -1
- package/dist/TimeField.js +372 -0
- package/dist/TimeField.js.map +1 -0
- package/dist/TimeField.jsx +224 -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 +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -23711
- package/dist/index.jsx +70 -18116
- package/dist/useDragAndDrop.js +2 -0
- package/dist/useDragAndDrop.jsx +2 -0
- package/dist/useDragAndDrop2.js +395 -0
- package/dist/useDragAndDrop2.js.map +1 -0
- package/dist/useDragAndDrop2.jsx +395 -0
- package/dist/useDragAndDrop2.jsx.map +1 -0
- package/dist/utils.d.ts +83 -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 +401 -4
- package/src/Breadcrumbs.tsx +3 -1
- package/src/Button.tsx +90 -23
- package/src/Calendar.tsx +27 -10
- package/src/CalendarPicker.tsx +73 -0
- package/src/Checkbox.tsx +539 -3
- package/src/Collection.tsx +9 -3
- package/src/Color.tsx +42 -14
- package/src/ComboBox.tsx +126 -14
- package/src/DateField.tsx +20 -2
- package/src/DatePicker.tsx +117 -10
- package/src/Dialog.tsx +13 -5
- package/src/Disclosure.tsx +3 -1
- package/src/DragAndDrop.tsx +3 -1
- package/src/DropZone.tsx +3 -1
- package/src/GridList.tsx +125 -24
- package/src/Icon.tsx +3 -1
- package/src/Link.tsx +3 -1
- package/src/ListBox.tsx +31 -4
- package/src/Menu.tsx +298 -131
- package/src/Meter.tsx +3 -1
- package/src/Modal.tsx +100 -52
- package/src/NumberField.tsx +73 -10
- package/src/Popover.tsx +49 -11
- package/src/ProgressBar.tsx +3 -1
- package/src/RadioGroup.tsx +468 -4
- package/src/RangeCalendar.tsx +3 -1
- package/src/SearchField.tsx +27 -3
- package/src/Select.tsx +22 -7
- package/src/SelectionIndicator.tsx +3 -1
- package/src/SharedElementTransition.tsx +3 -1
- package/src/Slider.tsx +159 -13
- package/src/Switch.tsx +395 -2
- package/src/Table.tsx +409 -95
- package/src/Tabs.tsx +16 -45
- package/src/TagGroup.tsx +4 -1
- package/src/Text.tsx +31 -10
- package/src/TextField.tsx +73 -10
- package/src/TimeField.tsx +20 -2
- package/src/Toast.tsx +79 -14
- package/src/ToggleButton.tsx +3 -1
- package/src/ToggleButtonGroup.tsx +3 -1
- package/src/Tooltip.tsx +55 -8
- package/src/Tree.tsx +77 -9
- package/src/Virtualizer.tsx +180 -31
- package/src/VirtualizerLayouts.ts +45 -10
- package/src/index.ts +50 -0
- package/src/utils.tsx +243 -27
- package/dist/index.js.map +0 -1
- package/dist/index.jsx.map +0 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { filterDOMProps, useRenderProps } from "./utils.jsx";
|
|
2
|
+
import { For, createContext, createMemo, splitProps, useContext } from "solid-js";
|
|
3
|
+
import { createActionGroup, createActionGroupItem } from "@proyecto-viviana/solidaria";
|
|
4
|
+
import { createListState } from "@proyecto-viviana/solid-stately";
|
|
5
|
+
//#region src/ActionGroup.tsx
|
|
6
|
+
/**
|
|
7
|
+
* ActionGroup component for solidaria-components
|
|
8
|
+
*
|
|
9
|
+
* Pre-wired headless action group component that combines
|
|
10
|
+
* createListState + createActionGroup/createActionGroupItem.
|
|
11
|
+
* Provides proper dynamic roles (toolbar/radiogroup), keyboard
|
|
12
|
+
* navigation, and ARIA attributes.
|
|
13
|
+
*
|
|
14
|
+
* No RAC equivalent exists — this bridges solidaria ARIA hooks
|
|
15
|
+
* directly to a headless component.
|
|
16
|
+
*/
|
|
17
|
+
const ActionGroupContext = createContext(null);
|
|
18
|
+
const ActionGroupStateContext = createContext(null);
|
|
19
|
+
function ActionGroup(props) {
|
|
20
|
+
const [local, ariaGroupProps, domProps] = splitProps(props, [
|
|
21
|
+
"items",
|
|
22
|
+
"selectionMode",
|
|
23
|
+
"orientation",
|
|
24
|
+
"isDisabled",
|
|
25
|
+
"selectedKeys",
|
|
26
|
+
"defaultSelectedKeys",
|
|
27
|
+
"onSelectionChange",
|
|
28
|
+
"onAction",
|
|
29
|
+
"disabledKeys",
|
|
30
|
+
"children",
|
|
31
|
+
"class",
|
|
32
|
+
"style",
|
|
33
|
+
"slot"
|
|
34
|
+
], ["aria-label", "aria-labelledby"]);
|
|
35
|
+
const state = createListState({
|
|
36
|
+
get items() {
|
|
37
|
+
return local.items;
|
|
38
|
+
},
|
|
39
|
+
get selectionMode() {
|
|
40
|
+
return local.selectionMode ?? "none";
|
|
41
|
+
},
|
|
42
|
+
get selectedKeys() {
|
|
43
|
+
return local.selectedKeys;
|
|
44
|
+
},
|
|
45
|
+
get defaultSelectedKeys() {
|
|
46
|
+
return local.defaultSelectedKeys;
|
|
47
|
+
},
|
|
48
|
+
get onSelectionChange() {
|
|
49
|
+
return local.onSelectionChange;
|
|
50
|
+
},
|
|
51
|
+
get disabledKeys() {
|
|
52
|
+
return local.disabledKeys;
|
|
53
|
+
},
|
|
54
|
+
getKey: (item) => item.id,
|
|
55
|
+
getTextValue: (item) => item.label,
|
|
56
|
+
getDisabled: (item) => !!item.isDisabled
|
|
57
|
+
});
|
|
58
|
+
const { actionGroupProps } = createActionGroup({
|
|
59
|
+
get items() {
|
|
60
|
+
return local.items;
|
|
61
|
+
},
|
|
62
|
+
get isDisabled() {
|
|
63
|
+
return local.isDisabled;
|
|
64
|
+
},
|
|
65
|
+
get orientation() {
|
|
66
|
+
return local.orientation;
|
|
67
|
+
},
|
|
68
|
+
get "aria-label"() {
|
|
69
|
+
return ariaGroupProps["aria-label"];
|
|
70
|
+
},
|
|
71
|
+
get "aria-labelledby"() {
|
|
72
|
+
return ariaGroupProps["aria-labelledby"];
|
|
73
|
+
},
|
|
74
|
+
get onAction() {
|
|
75
|
+
return local.onAction;
|
|
76
|
+
}
|
|
77
|
+
}, state);
|
|
78
|
+
const orientation = () => local.orientation ?? "horizontal";
|
|
79
|
+
const renderProps = useRenderProps({
|
|
80
|
+
children: void 0,
|
|
81
|
+
class: local.class,
|
|
82
|
+
style: local.style,
|
|
83
|
+
defaultClassName: "solidaria-ActionGroup"
|
|
84
|
+
}, () => ({
|
|
85
|
+
orientation: orientation(),
|
|
86
|
+
isDisabled: !!local.isDisabled,
|
|
87
|
+
selectionMode: local.selectionMode ?? "none"
|
|
88
|
+
}));
|
|
89
|
+
const filteredDOMProps = createMemo(() => filterDOMProps(domProps, { global: true }));
|
|
90
|
+
return <ActionGroupContext.Provider value={{ state }}>
|
|
91
|
+
<ActionGroupStateContext.Provider value={state}>
|
|
92
|
+
<div {...filteredDOMProps()} {...actionGroupProps} ref={(el) => {
|
|
93
|
+
const refFn = actionGroupProps.ref;
|
|
94
|
+
refFn?.(el);
|
|
95
|
+
}} class={renderProps.class()} style={renderProps.style()} slot={local.slot} data-orientation={orientation()} data-disabled={local.isDisabled || void 0}>
|
|
96
|
+
<For each={local.items}>
|
|
97
|
+
{(item) => <ActionGroupItemWrapper item={item} state={state} renderChild={local.children} />}
|
|
98
|
+
</For>
|
|
99
|
+
</div>
|
|
100
|
+
</ActionGroupStateContext.Provider>
|
|
101
|
+
</ActionGroupContext.Provider>;
|
|
102
|
+
}
|
|
103
|
+
function ActionGroupItemWrapper(props) {
|
|
104
|
+
const { buttonProps } = createActionGroupItem({ get key() {
|
|
105
|
+
return props.item.id;
|
|
106
|
+
} }, props.state);
|
|
107
|
+
const isFocused = () => props.state.focusedKey() === props.item.id;
|
|
108
|
+
const isSelected = () => {
|
|
109
|
+
const keys = props.state.selectedKeys();
|
|
110
|
+
return keys === "all" || keys instanceof Set && keys.has(props.item.id);
|
|
111
|
+
};
|
|
112
|
+
const isDisabled = () => props.state.isDisabled(props.item.id);
|
|
113
|
+
const renderProps = createMemo(() => ({
|
|
114
|
+
isSelected: isSelected(),
|
|
115
|
+
isDisabled: isDisabled(),
|
|
116
|
+
isFocused: isFocused()
|
|
117
|
+
}));
|
|
118
|
+
const { ref: _ref, ...restButtonProps } = buttonProps;
|
|
119
|
+
return <button {...restButtonProps} data-selected={isSelected() || void 0} data-disabled={isDisabled() || void 0} data-focused={isFocused() || void 0}>
|
|
120
|
+
{props.renderChild(props.item, renderProps())}
|
|
121
|
+
</button>;
|
|
122
|
+
}
|
|
123
|
+
function useActionGroupContext() {
|
|
124
|
+
return useContext(ActionGroupContext);
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
export { ActionGroup, ActionGroupContext, ActionGroupStateContext, useActionGroupContext };
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=ActionGroup.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionGroup.jsx","names":[],"sources":["../src/ActionGroup.tsx"],"sourcesContent":["/**\n * ActionGroup component for solidaria-components\n *\n * Pre-wired headless action group component that combines\n * createListState + createActionGroup/createActionGroupItem.\n * Provides proper dynamic roles (toolbar/radiogroup), keyboard\n * navigation, and ARIA attributes.\n *\n * No RAC equivalent exists — this bridges solidaria ARIA hooks\n * directly to a headless component.\n */\n\nimport {\n type JSX,\n type ParentProps,\n createContext,\n createMemo,\n splitProps,\n useContext,\n For,\n} from \"solid-js\";\nimport {\n createActionGroup,\n createActionGroupItem,\n type AriaActionGroupProps,\n} from \"@proyecto-viviana/solidaria\";\nimport {\n createListState,\n type ListState,\n type Key,\n type SelectionMode,\n} from \"@proyecto-viviana/solid-stately\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\n\nexport interface ActionGroupRenderProps {\n /** The orientation of the action group. */\n orientation: \"horizontal\" | \"vertical\";\n /** Whether the entire group is disabled. */\n isDisabled: boolean;\n /** The selection mode. */\n selectionMode: SelectionMode;\n}\n\nexport interface ActionGroupItemRenderProps {\n /** Whether the item is selected. */\n isSelected: boolean;\n /** Whether the item is disabled. */\n isDisabled: boolean;\n /** Whether the item is focused. */\n isFocused: boolean;\n}\n\nexport interface ActionGroupItem {\n id: string;\n label: string;\n isDisabled?: boolean;\n [key: string]: unknown;\n}\n\nexport interface ActionGroupProps<T extends ActionGroupItem = ActionGroupItem> extends SlotProps {\n /** The items in the action group. */\n items: T[];\n /** The selection mode. @default 'none' */\n selectionMode?: SelectionMode;\n /** Orientation of the group. @default 'horizontal' */\n orientation?: \"horizontal\" | \"vertical\";\n /** Whether the entire group is disabled. */\n isDisabled?: boolean;\n /** Accessible label. */\n \"aria-label\"?: string;\n /** Labelled-by id. */\n \"aria-labelledby\"?: string;\n /** Currently selected keys (controlled). */\n selectedKeys?: Iterable<Key>;\n /** Default selected keys (uncontrolled). */\n defaultSelectedKeys?: Iterable<Key>;\n /** Handler called when selection changes. */\n onSelectionChange?: (keys: \"all\" | Set<Key>) => void;\n /** Handler called when an item action is triggered. */\n onAction?: (key: Key) => void;\n /** Keys of disabled items. */\n disabledKeys?: Iterable<Key>;\n /** Render function for each item. */\n children: (item: T, renderProps: ActionGroupItemRenderProps) => JSX.Element;\n /** CSS class for the container. */\n class?: ClassNameOrFunction<ActionGroupRenderProps>;\n /** Inline style for the container. */\n style?: StyleOrFunction<ActionGroupRenderProps>;\n}\n\nexport interface ActionGroupContextValue<T extends ActionGroupItem = ActionGroupItem> {\n state: ListState<T>;\n}\n\nexport const ActionGroupContext = createContext<ActionGroupContextValue | null>(null);\nexport const ActionGroupStateContext = createContext<ListState<ActionGroupItem> | null>(null);\n\nexport function ActionGroup<T extends ActionGroupItem = ActionGroupItem>(\n props: ActionGroupProps<T>,\n): JSX.Element {\n const [local, ariaGroupProps, domProps] = splitProps(\n props,\n [\n \"items\",\n \"selectionMode\",\n \"orientation\",\n \"isDisabled\",\n \"selectedKeys\",\n \"defaultSelectedKeys\",\n \"onSelectionChange\",\n \"onAction\",\n \"disabledKeys\",\n \"children\",\n \"class\",\n \"style\",\n \"slot\",\n ],\n [\"aria-label\", \"aria-labelledby\"],\n );\n\n const state = createListState<T>({\n get items() {\n return local.items;\n },\n get selectionMode() {\n return local.selectionMode ?? \"none\";\n },\n get selectedKeys() {\n return local.selectedKeys;\n },\n get defaultSelectedKeys() {\n return local.defaultSelectedKeys;\n },\n get onSelectionChange() {\n return local.onSelectionChange;\n },\n get disabledKeys() {\n return local.disabledKeys;\n },\n getKey: (item) => item.id,\n getTextValue: (item) => item.label,\n getDisabled: (item) => !!item.isDisabled,\n });\n\n const groupAriaProps: AriaActionGroupProps<T> = {\n get items() {\n return local.items;\n },\n get isDisabled() {\n return local.isDisabled;\n },\n get orientation() {\n return local.orientation;\n },\n get \"aria-label\"() {\n return ariaGroupProps[\"aria-label\"];\n },\n get \"aria-labelledby\"() {\n return ariaGroupProps[\"aria-labelledby\"];\n },\n get onAction() {\n return local.onAction;\n },\n };\n\n const { actionGroupProps } = createActionGroup(groupAriaProps, state as ListState<T>);\n\n const orientation = () => local.orientation ?? \"horizontal\";\n\n const renderProps = useRenderProps(\n {\n children: undefined,\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-ActionGroup\",\n },\n () => ({\n orientation: orientation(),\n isDisabled: !!local.isDisabled,\n selectionMode: (local.selectionMode ?? \"none\") as SelectionMode,\n }),\n );\n\n const filteredDOMProps = createMemo(() =>\n filterDOMProps(domProps as Record<string, unknown>, { global: true }),\n );\n\n return (\n <ActionGroupContext.Provider value={{ state: state as ListState<ActionGroupItem> }}>\n <ActionGroupStateContext.Provider value={state as ListState<ActionGroupItem>}>\n <div\n {...filteredDOMProps()}\n {...actionGroupProps}\n ref={(el: HTMLDivElement) => {\n const refFn = (actionGroupProps as { ref?: (el: HTMLElement) => void }).ref;\n refFn?.(el);\n }}\n class={renderProps.class()}\n style={renderProps.style()}\n slot={local.slot}\n data-orientation={orientation()}\n data-disabled={local.isDisabled || undefined}\n >\n <For each={local.items}>\n {(item) => (\n <ActionGroupItemWrapper\n item={item}\n state={state as ListState<ActionGroupItem>}\n renderChild={\n local.children as (\n item: ActionGroupItem,\n rp: ActionGroupItemRenderProps,\n ) => JSX.Element\n }\n />\n )}\n </For>\n </div>\n </ActionGroupStateContext.Provider>\n </ActionGroupContext.Provider>\n );\n}\n\ninterface ActionGroupItemWrapperProps {\n item: ActionGroupItem;\n state: ListState<ActionGroupItem>;\n renderChild: (item: ActionGroupItem, renderProps: ActionGroupItemRenderProps) => JSX.Element;\n}\n\nfunction ActionGroupItemWrapper(props: ActionGroupItemWrapperProps): JSX.Element {\n const { buttonProps } = createActionGroupItem(\n {\n get key() {\n return props.item.id;\n },\n },\n props.state,\n );\n\n const isFocused = () => props.state.focusedKey() === props.item.id;\n const isSelected = () => {\n const keys = props.state.selectedKeys();\n return keys === \"all\" || (keys instanceof Set && keys.has(props.item.id));\n };\n const isDisabled = () => props.state.isDisabled(props.item.id);\n\n const renderProps = createMemo<ActionGroupItemRenderProps>(() => ({\n isSelected: isSelected(),\n isDisabled: isDisabled(),\n isFocused: isFocused(),\n }));\n\n const { ref: _ref, ...restButtonProps } = buttonProps as Record<string, unknown> & {\n ref?: unknown;\n };\n\n return (\n <button\n {...restButtonProps}\n data-selected={isSelected() || undefined}\n data-disabled={isDisabled() || undefined}\n data-focused={isFocused() || undefined}\n >\n {props.renderChild(props.item, renderProps())}\n </button>\n );\n}\n\nexport function useActionGroupContext(): ActionGroupContextValue | null {\n return useContext(ActionGroupContext);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAoGA,MAAa,qBAAqB,cAA8C,IAAI;AACpF,MAAa,0BAA0B,cAAiD,IAAI;AAE5F,SAAgB,YACd,OACa;CACb,MAAM,CAAC,OAAO,gBAAgB,YAAY,WACxC,OACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACA,CAAC,cAAc,iBAAiB,CAClC;CAEA,MAAM,QAAQ,gBAAmB;EAC/B,IAAI,QAAQ;GACV,OAAO,MAAM;EACf;EACA,IAAI,gBAAgB;GAClB,OAAO,MAAM,iBAAiB;EAChC;EACA,IAAI,eAAe;GACjB,OAAO,MAAM;EACf;EACA,IAAI,sBAAsB;GACxB,OAAO,MAAM;EACf;EACA,IAAI,oBAAoB;GACtB,OAAO,MAAM;EACf;EACA,IAAI,eAAe;GACjB,OAAO,MAAM;EACf;EACA,SAAS,SAAS,KAAK;EACvB,eAAe,SAAS,KAAK;EAC7B,cAAc,SAAS,CAAC,CAAC,KAAK;CAChC,CAAC;CAuBD,MAAM,EAAE,qBAAqB,kBAAkB;EApB7C,IAAI,QAAQ;GACV,OAAO,MAAM;EACf;EACA,IAAI,aAAa;GACf,OAAO,MAAM;EACf;EACA,IAAI,cAAc;GAChB,OAAO,MAAM;EACf;EACA,IAAI,eAAe;GACjB,OAAO,eAAe;EACxB;EACA,IAAI,oBAAoB;GACtB,OAAO,eAAe;EACxB;EACA,IAAI,WAAW;GACb,OAAO,MAAM;EACf;CAG0D,GAAG,KAAqB;CAEpF,MAAM,oBAAoB,MAAM,eAAe;CAE/C,MAAM,cAAc,eAClB;EACE,UAAU,KAAA;EACV,OAAO,MAAM;EACb,OAAO,MAAM;EACb,kBAAkB;CACpB,UACO;EACL,aAAa,YAAY;EACzB,YAAY,CAAC,CAAC,MAAM;EACpB,eAAgB,MAAM,iBAAiB;CACzC,EACF;CAEA,MAAM,mBAAmB,iBACvB,eAAe,UAAqC,EAAE,QAAQ,KAAK,CAAC,CACtE;CAEA,OACE,CAAC,mBAAmB,SAAS,OAAO,EAAS,MAAoC,GAAG;MAClF,CAAC,wBAAwB,SAAS,OAAO,OAAqC;QAC5E,CAAC,QACK,iBAAiB,OACjB,kBACJ,MAAM,OAAuB;EAC3B,MAAM,QAAS,iBAAyD;EACxE,QAAQ,EAAE;CACZ,GACA,OAAO,YAAY,MAAM,GACzB,OAAO,YAAY,MAAM,GACzB,MAAM,MAAM,MACZ,kBAAkB,YAAY,GAC9B,eAAe,MAAM,cAAc,KAAA,GACpC;UACC,CAAC,IAAI,MAAM,MAAM,OAAO;cACpB,SACA,CAAC,uBACC,MAAM,MACN,OAAO,OACP,aACE,MAAM,aAMV;UACJ,EAAE,IAAI;QACR,EAAE,IAAI;MACR,EAAE,wBAAwB,SAAS;IACrC,EAAE,mBAAmB;AAEzB;AAQA,SAAS,uBAAuB,OAAiD;CAC/E,MAAM,EAAE,gBAAgB,sBACtB,EACE,IAAI,MAAM;EACR,OAAO,MAAM,KAAK;CACpB,EACF,GACA,MAAM,KACR;CAEA,MAAM,kBAAkB,MAAM,MAAM,WAAW,MAAM,MAAM,KAAK;CAChE,MAAM,mBAAmB;EACvB,MAAM,OAAO,MAAM,MAAM,aAAa;EACtC,OAAO,SAAS,SAAU,gBAAgB,OAAO,KAAK,IAAI,MAAM,KAAK,EAAE;CACzE;CACA,MAAM,mBAAmB,MAAM,MAAM,WAAW,MAAM,KAAK,EAAE;CAE7D,MAAM,cAAc,kBAA8C;EAChE,YAAY,WAAW;EACvB,YAAY,WAAW;EACvB,WAAW,UAAU;CACvB,EAAE;CAEF,MAAM,EAAE,KAAK,MAAM,GAAG,oBAAoB;CAI1C,OACE,CAAC,WACK,iBACJ,eAAe,WAAW,KAAK,KAAA,GAC/B,eAAe,WAAW,KAAK,KAAA,GAC/B,cAAc,UAAU,KAAK,KAAA,GAC9B;OACE,MAAM,YAAY,MAAM,MAAM,YAAY,CAAC,EAAE;IAChD,EAAE;AAEN;AAEA,SAAgB,wBAAwD;CACtE,OAAO,WAAW,kBAAkB;AACtC"}
|
package/dist/Alert.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { filterDOMProps } from "./utils.js";
|
|
2
|
+
import { Button } from "./Button.js";
|
|
3
|
+
import { createComponent, getNextElement, insert, memo, mergeProps, runHydrationEvents, spread, template } from "solid-js/web";
|
|
4
|
+
import { createContext, createMemo, splitProps, useContext } from "solid-js";
|
|
5
|
+
//#region src/Alert.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Alert component for solidaria-components
|
|
8
|
+
*
|
|
9
|
+
* Minimal headless Alert that owns ARIA semantics (role="alert")
|
|
10
|
+
* and provides render props for styling. The UI layer consumes this
|
|
11
|
+
* for styling/composition only.
|
|
12
|
+
*/
|
|
13
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div>`);
|
|
14
|
+
const AlertContext = createContext(null);
|
|
15
|
+
/**
|
|
16
|
+
* An alert displays a brief, important message in a way that
|
|
17
|
+
* attracts the user's attention without interrupting their task.
|
|
18
|
+
*
|
|
19
|
+
* This is a headless component that provides the ARIA `role="alert"`
|
|
20
|
+
* semantics and render props for styling.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <Alert variant="error" isDismissible onDismiss={() => setVisible(false)}>
|
|
25
|
+
* {({ variant }) => <span>Something went wrong ({variant})</span>}
|
|
26
|
+
* </Alert>
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function Alert(props) {
|
|
30
|
+
const [local, rest] = splitProps(props, [
|
|
31
|
+
"children",
|
|
32
|
+
"class",
|
|
33
|
+
"style",
|
|
34
|
+
"slot",
|
|
35
|
+
"variant",
|
|
36
|
+
"isDismissible",
|
|
37
|
+
"onDismiss"
|
|
38
|
+
]);
|
|
39
|
+
const variant = () => local.variant ?? "info";
|
|
40
|
+
const isDismissible = () => !!local.isDismissible;
|
|
41
|
+
const renderValues = createMemo(() => ({
|
|
42
|
+
variant: variant(),
|
|
43
|
+
isDismissible: isDismissible()
|
|
44
|
+
}));
|
|
45
|
+
const computedClass = createMemo(() => {
|
|
46
|
+
const cls = local.class;
|
|
47
|
+
return typeof cls === "function" ? cls(renderValues()) : cls ?? "solidaria-Alert";
|
|
48
|
+
});
|
|
49
|
+
const computedStyle = createMemo(() => {
|
|
50
|
+
const s = local.style;
|
|
51
|
+
return typeof s === "function" ? s(renderValues()) : s;
|
|
52
|
+
});
|
|
53
|
+
const domProps = createMemo(() => filterDOMProps(rest, { global: true }));
|
|
54
|
+
const contextValue = {
|
|
55
|
+
variant,
|
|
56
|
+
isDismissible,
|
|
57
|
+
onDismiss: local.onDismiss
|
|
58
|
+
};
|
|
59
|
+
return createComponent(AlertContext.Provider, {
|
|
60
|
+
value: contextValue,
|
|
61
|
+
get children() {
|
|
62
|
+
var _el$ = getNextElement(_tmpl$);
|
|
63
|
+
spread(_el$, mergeProps(domProps, {
|
|
64
|
+
"role": "alert",
|
|
65
|
+
get ["class"]() {
|
|
66
|
+
return computedClass();
|
|
67
|
+
},
|
|
68
|
+
get style() {
|
|
69
|
+
return computedStyle();
|
|
70
|
+
},
|
|
71
|
+
get ["data-variant"]() {
|
|
72
|
+
return variant();
|
|
73
|
+
},
|
|
74
|
+
get ["data-dismissible"]() {
|
|
75
|
+
return isDismissible() || void 0;
|
|
76
|
+
}
|
|
77
|
+
}), false, true);
|
|
78
|
+
insert(_el$, (() => {
|
|
79
|
+
var _c$ = memo(() => typeof local.children === "function");
|
|
80
|
+
return () => _c$() ? local.children(renderValues()) : local.children;
|
|
81
|
+
})());
|
|
82
|
+
runHydrationEvents();
|
|
83
|
+
return _el$;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* A dismiss button for use inside an Alert.
|
|
89
|
+
* Uses the headless Button for full keyboard/a11y support.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```tsx
|
|
93
|
+
* <Alert isDismissible onDismiss={handleDismiss}>
|
|
94
|
+
* <span>Alert content</span>
|
|
95
|
+
* <AlertDismissButton aria-label="Dismiss">X</AlertDismissButton>
|
|
96
|
+
* </Alert>
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
function AlertDismissButton(props) {
|
|
100
|
+
const context = useContext(AlertContext);
|
|
101
|
+
return createComponent(Button, mergeProps(props, {
|
|
102
|
+
get ["aria-label"]() {
|
|
103
|
+
return props["aria-label"] ?? "Dismiss";
|
|
104
|
+
},
|
|
105
|
+
onPress: () => context?.onDismiss?.()
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { Alert, AlertContext, AlertDismissButton };
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=Alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Alert.js","names":["JSX","createContext","createMemo","splitProps","useContext","RenderChildren","ClassNameOrFunction","StyleOrFunction","SlotProps","filterDOMProps","Button","ButtonProps","AlertVariant","AlertRenderProps","variant","isDismissible","AlertProps","onDismiss","children","class","style","id","AlertContextValue","AlertContext","Alert","props","Element","local","rest","renderValues","computedClass","cls","computedStyle","s","domProps","global","contextValue","_$createComponent","Provider","value","_el$","_$getNextElement","_tmpl$","_$spread","_$mergeProps","data-variant","data-dismissible","undefined","_$insert","_c$","_$memo","_$runHydrationEvents","AlertDismissButtonProps","Omit","AlertDismissButton","context","aria-label","onPress"],"sources":["../src/Alert.tsx"],"sourcesContent":["/**\n * Alert component for solidaria-components\n *\n * Minimal headless Alert that owns ARIA semantics (role=\"alert\")\n * and provides render props for styling. The UI layer consumes this\n * for styling/composition only.\n */\n\nimport { type JSX, createContext, createMemo, splitProps, useContext } from \"solid-js\";\nimport {\n type RenderChildren,\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n filterDOMProps,\n} from \"./utils\";\nimport { Button, type ButtonProps } from \"./Button\";\n\nexport type AlertVariant = \"info\" | \"success\" | \"warning\" | \"error\";\n\nexport interface AlertRenderProps {\n /** The variant of the alert. */\n variant: AlertVariant;\n /** Whether the alert can be dismissed. */\n isDismissible: boolean;\n}\n\nexport interface AlertProps extends SlotProps {\n /** The variant of the alert. */\n variant?: AlertVariant;\n /** Whether the alert can be dismissed. */\n isDismissible?: boolean;\n /** Handler called when the alert is dismissed. */\n onDismiss?: () => void;\n /** The children of the component. A function may be provided to receive render props. */\n children?: RenderChildren<AlertRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<AlertRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<AlertRenderProps>;\n /** The id of the element. */\n id?: string;\n}\n\nexport interface AlertContextValue {\n variant: () => AlertVariant;\n isDismissible: () => boolean;\n onDismiss?: () => void;\n}\n\nexport const AlertContext = createContext<AlertContextValue | null>(null);\n\n/**\n * An alert displays a brief, important message in a way that\n * attracts the user's attention without interrupting their task.\n *\n * This is a headless component that provides the ARIA `role=\"alert\"`\n * semantics and render props for styling.\n *\n * @example\n * ```tsx\n * <Alert variant=\"error\" isDismissible onDismiss={() => setVisible(false)}>\n * {({ variant }) => <span>Something went wrong ({variant})</span>}\n * </Alert>\n * ```\n */\nexport function Alert(props: AlertProps): JSX.Element {\n const [local, rest] = splitProps(props, [\n \"children\",\n \"class\",\n \"style\",\n \"slot\",\n \"variant\",\n \"isDismissible\",\n \"onDismiss\",\n ]);\n\n const variant = () => local.variant ?? \"info\";\n const isDismissible = () => !!local.isDismissible;\n\n const renderValues = createMemo<AlertRenderProps>(() => ({\n variant: variant(),\n isDismissible: isDismissible(),\n }));\n\n // Resolve class and style manually. We intentionally avoid useRenderProps()\n // because it destructures children eagerly, which would create child\n // components (e.g. AlertDismissButton) BEFORE the AlertContext.Provider\n // is in scope, breaking context for sub-components.\n const computedClass = createMemo(() => {\n const cls = local.class;\n return typeof cls === \"function\" ? cls(renderValues()) : (cls ?? \"solidaria-Alert\");\n });\n\n const computedStyle = createMemo(() => {\n const s = local.style;\n return typeof s === \"function\" ? s(renderValues()) : s;\n });\n\n const domProps = createMemo(() => filterDOMProps(rest, { global: true }));\n\n const contextValue: AlertContextValue = {\n variant,\n isDismissible,\n onDismiss: local.onDismiss,\n };\n\n // Children are accessed lazily inside the Provider scope (via local.children\n // in JSX) so sub-components like AlertDismissButton can read AlertContext.\n return (\n <AlertContext.Provider value={contextValue}>\n <div\n {...domProps()}\n role=\"alert\"\n class={computedClass()}\n style={computedStyle()}\n data-variant={variant()}\n data-dismissible={isDismissible() || undefined}\n >\n {typeof local.children === \"function\"\n ? (local.children as (props: AlertRenderProps) => JSX.Element)(renderValues())\n : local.children}\n </div>\n </AlertContext.Provider>\n );\n}\n\nexport interface AlertDismissButtonProps extends Omit<ButtonProps, \"onPress\"> {}\n\n/**\n * A dismiss button for use inside an Alert.\n * Uses the headless Button for full keyboard/a11y support.\n *\n * @example\n * ```tsx\n * <Alert isDismissible onDismiss={handleDismiss}>\n * <span>Alert content</span>\n * <AlertDismissButton aria-label=\"Dismiss\">X</AlertDismissButton>\n * </Alert>\n * ```\n */\nexport function AlertDismissButton(props: AlertDismissButtonProps): JSX.Element {\n const context = useContext(AlertContext);\n\n return (\n <Button\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Dismiss\"}\n onPress={() => context?.onDismiss?.()}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAkDA,MAAauB,eAAetB,cAAwC,IAAI;;;;;;;;;;;;;;;AAgBxE,SAAgBuB,MAAMC,OAAgC;CACpD,MAAM,CAACE,OAAOC,QAAQzB,WAAWsB,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;CAAW,CACZ;CAED,MAAMX,gBAAgBa,MAAMb,WAAW;CACvC,MAAMC,sBAAsB,CAAC,CAACY,MAAMZ;CAEpC,MAAMc,eAAe3B,kBAAoC;EACvDY,SAASA,QAAQ;EACjBC,eAAeA,cAAc;CAC/B,EAAE;CAMF,MAAMe,gBAAgB5B,iBAAiB;EACrC,MAAM6B,MAAMJ,MAAMR;EAClB,OAAO,OAAOY,QAAQ,aAAaA,IAAIF,aAAa,CAAC,IAAKE,OAAO;CACnE,CAAC;CAED,MAAMC,gBAAgB9B,iBAAiB;EACrC,MAAM+B,IAAIN,MAAMP;EAChB,OAAO,OAAOa,MAAM,aAAaA,EAAEJ,aAAa,CAAC,IAAII;CACvD,CAAC;CAED,MAAMC,WAAWhC,iBAAiBO,eAAemB,MAAM,EAAEO,QAAQ,KAAK,CAAC,CAAC;CAExE,MAAMC,eAAkC;EACtCtB;EACAC;EACAE,WAAWU,MAAMV;CACnB;CAIA,OAAAoB,gBACGd,aAAae,UAAQ;EAACC,OAAOH;EAAY,IAAAlB,WAAA;GAAA,IAAAsB,OAAAC,eAAAC,MAAA;GAAAC,OAAAH,MAAAI,WAElCV,UAAQ;IAAA,QACP;IAAO,KAAA,WAAA;KAAA,OACLJ,cAAc;IAAC;IAAA,IACtBV,QAAK;KAAA,OAAEY,cAAc;IAAC;IAAA,KAAA,kBAAA;KAAA,OACRlB,QAAQ;IAAC;IAAA,KAAA,sBAAA;KAAA,OACLC,cAAc,KAAKgC,KAAAA;IAAS;GAAA,CAAA,GAAA,OAAA,IAAA;GAAAC,OAAAR,aAAA;IAAA,IAAAS,MAAAC,WAE7C,OAAOvB,MAAMT,aAAa,UAAU;IAAA,aAApC+B,IAAA,IACItB,MAAMT,SAAsDW,aAAa,CAAC,IAC3EF,MAAMT;GAAQ,EAAA,CAAA,CAAA;GAAAiC,mBAAA;GAAA,OAAAX;EAAA;CAAA,CAAA;AAI1B;;;;;;;;;;;;;AAgBA,SAAgBc,mBAAmB7B,OAA6C;CAC9E,MAAM8B,UAAUnD,WAAWmB,YAAY;CAEvC,OAAAc,gBACG3B,QAAMkC,WACDnB,OAAK;EAAA,KAAA,gBAAA;GAAA,OACGA,MAAM,iBAAiB;EAAS;EAC5CgC,eAAeF,SAAStC,YAAY;CAAC,CAAA,CAAA;AAG3C"}
|
package/dist/Alert.jsx
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { filterDOMProps } from "./utils.jsx";
|
|
2
|
+
import { Button } from "./Button.jsx";
|
|
3
|
+
import { createContext, createMemo, splitProps, useContext } from "solid-js";
|
|
4
|
+
//#region src/Alert.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Alert component for solidaria-components
|
|
7
|
+
*
|
|
8
|
+
* Minimal headless Alert that owns ARIA semantics (role="alert")
|
|
9
|
+
* and provides render props for styling. The UI layer consumes this
|
|
10
|
+
* for styling/composition only.
|
|
11
|
+
*/
|
|
12
|
+
const AlertContext = createContext(null);
|
|
13
|
+
/**
|
|
14
|
+
* An alert displays a brief, important message in a way that
|
|
15
|
+
* attracts the user's attention without interrupting their task.
|
|
16
|
+
*
|
|
17
|
+
* This is a headless component that provides the ARIA `role="alert"`
|
|
18
|
+
* semantics and render props for styling.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <Alert variant="error" isDismissible onDismiss={() => setVisible(false)}>
|
|
23
|
+
* {({ variant }) => <span>Something went wrong ({variant})</span>}
|
|
24
|
+
* </Alert>
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function Alert(props) {
|
|
28
|
+
const [local, rest] = splitProps(props, [
|
|
29
|
+
"children",
|
|
30
|
+
"class",
|
|
31
|
+
"style",
|
|
32
|
+
"slot",
|
|
33
|
+
"variant",
|
|
34
|
+
"isDismissible",
|
|
35
|
+
"onDismiss"
|
|
36
|
+
]);
|
|
37
|
+
const variant = () => local.variant ?? "info";
|
|
38
|
+
const isDismissible = () => !!local.isDismissible;
|
|
39
|
+
const renderValues = createMemo(() => ({
|
|
40
|
+
variant: variant(),
|
|
41
|
+
isDismissible: isDismissible()
|
|
42
|
+
}));
|
|
43
|
+
const computedClass = createMemo(() => {
|
|
44
|
+
const cls = local.class;
|
|
45
|
+
return typeof cls === "function" ? cls(renderValues()) : cls ?? "solidaria-Alert";
|
|
46
|
+
});
|
|
47
|
+
const computedStyle = createMemo(() => {
|
|
48
|
+
const s = local.style;
|
|
49
|
+
return typeof s === "function" ? s(renderValues()) : s;
|
|
50
|
+
});
|
|
51
|
+
const domProps = createMemo(() => filterDOMProps(rest, { global: true }));
|
|
52
|
+
const contextValue = {
|
|
53
|
+
variant,
|
|
54
|
+
isDismissible,
|
|
55
|
+
onDismiss: local.onDismiss
|
|
56
|
+
};
|
|
57
|
+
return <AlertContext.Provider value={contextValue}>
|
|
58
|
+
<div {...domProps()} role="alert" class={computedClass()} style={computedStyle()} data-variant={variant()} data-dismissible={isDismissible() || void 0}>
|
|
59
|
+
{typeof local.children === "function" ? local.children(renderValues()) : local.children}
|
|
60
|
+
</div>
|
|
61
|
+
</AlertContext.Provider>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A dismiss button for use inside an Alert.
|
|
65
|
+
* Uses the headless Button for full keyboard/a11y support.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* <Alert isDismissible onDismiss={handleDismiss}>
|
|
70
|
+
* <span>Alert content</span>
|
|
71
|
+
* <AlertDismissButton aria-label="Dismiss">X</AlertDismissButton>
|
|
72
|
+
* </Alert>
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
function AlertDismissButton(props) {
|
|
76
|
+
const context = useContext(AlertContext);
|
|
77
|
+
return <Button {...props} aria-label={props["aria-label"] ?? "Dismiss"} onPress={() => context?.onDismiss?.()} />;
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
export { Alert, AlertContext, AlertDismissButton };
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=Alert.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Alert.jsx","names":[],"sources":["../src/Alert.tsx"],"sourcesContent":["/**\n * Alert component for solidaria-components\n *\n * Minimal headless Alert that owns ARIA semantics (role=\"alert\")\n * and provides render props for styling. The UI layer consumes this\n * for styling/composition only.\n */\n\nimport { type JSX, createContext, createMemo, splitProps, useContext } from \"solid-js\";\nimport {\n type RenderChildren,\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n filterDOMProps,\n} from \"./utils\";\nimport { Button, type ButtonProps } from \"./Button\";\n\nexport type AlertVariant = \"info\" | \"success\" | \"warning\" | \"error\";\n\nexport interface AlertRenderProps {\n /** The variant of the alert. */\n variant: AlertVariant;\n /** Whether the alert can be dismissed. */\n isDismissible: boolean;\n}\n\nexport interface AlertProps extends SlotProps {\n /** The variant of the alert. */\n variant?: AlertVariant;\n /** Whether the alert can be dismissed. */\n isDismissible?: boolean;\n /** Handler called when the alert is dismissed. */\n onDismiss?: () => void;\n /** The children of the component. A function may be provided to receive render props. */\n children?: RenderChildren<AlertRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<AlertRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<AlertRenderProps>;\n /** The id of the element. */\n id?: string;\n}\n\nexport interface AlertContextValue {\n variant: () => AlertVariant;\n isDismissible: () => boolean;\n onDismiss?: () => void;\n}\n\nexport const AlertContext = createContext<AlertContextValue | null>(null);\n\n/**\n * An alert displays a brief, important message in a way that\n * attracts the user's attention without interrupting their task.\n *\n * This is a headless component that provides the ARIA `role=\"alert\"`\n * semantics and render props for styling.\n *\n * @example\n * ```tsx\n * <Alert variant=\"error\" isDismissible onDismiss={() => setVisible(false)}>\n * {({ variant }) => <span>Something went wrong ({variant})</span>}\n * </Alert>\n * ```\n */\nexport function Alert(props: AlertProps): JSX.Element {\n const [local, rest] = splitProps(props, [\n \"children\",\n \"class\",\n \"style\",\n \"slot\",\n \"variant\",\n \"isDismissible\",\n \"onDismiss\",\n ]);\n\n const variant = () => local.variant ?? \"info\";\n const isDismissible = () => !!local.isDismissible;\n\n const renderValues = createMemo<AlertRenderProps>(() => ({\n variant: variant(),\n isDismissible: isDismissible(),\n }));\n\n // Resolve class and style manually. We intentionally avoid useRenderProps()\n // because it destructures children eagerly, which would create child\n // components (e.g. AlertDismissButton) BEFORE the AlertContext.Provider\n // is in scope, breaking context for sub-components.\n const computedClass = createMemo(() => {\n const cls = local.class;\n return typeof cls === \"function\" ? cls(renderValues()) : (cls ?? \"solidaria-Alert\");\n });\n\n const computedStyle = createMemo(() => {\n const s = local.style;\n return typeof s === \"function\" ? s(renderValues()) : s;\n });\n\n const domProps = createMemo(() => filterDOMProps(rest, { global: true }));\n\n const contextValue: AlertContextValue = {\n variant,\n isDismissible,\n onDismiss: local.onDismiss,\n };\n\n // Children are accessed lazily inside the Provider scope (via local.children\n // in JSX) so sub-components like AlertDismissButton can read AlertContext.\n return (\n <AlertContext.Provider value={contextValue}>\n <div\n {...domProps()}\n role=\"alert\"\n class={computedClass()}\n style={computedStyle()}\n data-variant={variant()}\n data-dismissible={isDismissible() || undefined}\n >\n {typeof local.children === \"function\"\n ? (local.children as (props: AlertRenderProps) => JSX.Element)(renderValues())\n : local.children}\n </div>\n </AlertContext.Provider>\n );\n}\n\nexport interface AlertDismissButtonProps extends Omit<ButtonProps, \"onPress\"> {}\n\n/**\n * A dismiss button for use inside an Alert.\n * Uses the headless Button for full keyboard/a11y support.\n *\n * @example\n * ```tsx\n * <Alert isDismissible onDismiss={handleDismiss}>\n * <span>Alert content</span>\n * <AlertDismissButton aria-label=\"Dismiss\">X</AlertDismissButton>\n * </Alert>\n * ```\n */\nexport function AlertDismissButton(props: AlertDismissButtonProps): JSX.Element {\n const context = useContext(AlertContext);\n\n return (\n <Button\n {...props}\n aria-label={props[\"aria-label\"] ?? \"Dismiss\"}\n onPress={() => context?.onDismiss?.()}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;AAkDA,MAAa,eAAe,cAAwC,IAAI;;;;;;;;;;;;;;;AAgBxE,SAAgB,MAAM,OAAgC;CACpD,MAAM,CAAC,OAAO,QAAQ,WAAW,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,gBAAgB,MAAM,WAAW;CACvC,MAAM,sBAAsB,CAAC,CAAC,MAAM;CAEpC,MAAM,eAAe,kBAAoC;EACvD,SAAS,QAAQ;EACjB,eAAe,cAAc;CAC/B,EAAE;CAMF,MAAM,gBAAgB,iBAAiB;EACrC,MAAM,MAAM,MAAM;EAClB,OAAO,OAAO,QAAQ,aAAa,IAAI,aAAa,CAAC,IAAK,OAAO;CACnE,CAAC;CAED,MAAM,gBAAgB,iBAAiB;EACrC,MAAM,IAAI,MAAM;EAChB,OAAO,OAAO,MAAM,aAAa,EAAE,aAAa,CAAC,IAAI;CACvD,CAAC;CAED,MAAM,WAAW,iBAAiB,eAAe,MAAM,EAAE,QAAQ,KAAK,CAAC,CAAC;CAExE,MAAM,eAAkC;EACtC;EACA;EACA,WAAW,MAAM;CACnB;CAIA,OACE,CAAC,aAAa,SAAS,OAAO,cAAc;MAC1C,CAAC,QACK,SAAS,GACb,aACA,OAAO,cAAc,GACrB,OAAO,cAAc,GACrB,cAAc,QAAQ,GACtB,kBAAkB,cAAc,KAAK,KAAA,GACtC;SACE,OAAO,MAAM,aAAa,aACtB,MAAM,SAAsD,aAAa,CAAC,IAC3E,MAAM,SAAS;MACrB,EAAE,IAAI;IACR,EAAE,aAAa;AAEnB;;;;;;;;;;;;;AAgBA,SAAgB,mBAAmB,OAA6C;CAC9E,MAAM,UAAU,WAAW,YAAY;CAEvC,OACE,CAAC,WACK,OACJ,YAAY,MAAM,iBAAiB,WACnC,eAAe,SAAS,YAAY;AAG1C"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createComponent } from "solid-js/web";
|
|
2
|
+
import { createContext, createMemo, splitProps, useContext } from "solid-js";
|
|
3
|
+
import { createAutocomplete } from "@proyecto-viviana/solidaria";
|
|
4
|
+
import { createAutocompleteState } from "@proyecto-viviana/solid-stately";
|
|
5
|
+
//#region src/Autocomplete.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Autocomplete component for solidaria-components
|
|
8
|
+
*
|
|
9
|
+
* Provides autocomplete functionality by wrapping a text input
|
|
10
|
+
* with a filterable collection (ListBox/Menu).
|
|
11
|
+
*
|
|
12
|
+
* Port of react-aria-components/src/Autocomplete.tsx
|
|
13
|
+
*/
|
|
14
|
+
const AutocompleteContext = createContext(null);
|
|
15
|
+
const AutocompleteStateContext = createContext(null);
|
|
16
|
+
const AutocompleteCollectionContext = createContext(null);
|
|
17
|
+
/**
|
|
18
|
+
* Hook to consume autocomplete input context.
|
|
19
|
+
* Use this in your input component (TextField/SearchField) to get the autocomplete props.
|
|
20
|
+
*/
|
|
21
|
+
function useAutocompleteInput() {
|
|
22
|
+
return useContext(AutocompleteContext);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Hook to consume autocomplete state context.
|
|
26
|
+
*/
|
|
27
|
+
function useAutocompleteState() {
|
|
28
|
+
return useContext(AutocompleteStateContext);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Hook to consume autocomplete collection context.
|
|
32
|
+
* Use this in your collection component (ListBox/Menu) to get the autocomplete props.
|
|
33
|
+
*/
|
|
34
|
+
function useAutocompleteCollection() {
|
|
35
|
+
return useContext(AutocompleteCollectionContext);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* An autocomplete allows users to search or filter a list of suggestions.
|
|
39
|
+
* It wraps a text input and a collection component (ListBox or Menu),
|
|
40
|
+
* providing keyboard navigation and filtering capabilities.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* // Basic usage with SearchField and ListBox
|
|
45
|
+
* <Autocomplete
|
|
46
|
+
* filter={(textValue, inputValue) =>
|
|
47
|
+
* textValue.toLowerCase().includes(inputValue.toLowerCase())
|
|
48
|
+
* }
|
|
49
|
+
* >
|
|
50
|
+
* <SearchField aria-label="Search">
|
|
51
|
+
* <Input />
|
|
52
|
+
* </SearchField>
|
|
53
|
+
* <ListBox aria-label="Suggestions">
|
|
54
|
+
* <ListBoxItem>Option 1</ListBoxItem>
|
|
55
|
+
* <ListBoxItem>Option 2</ListBoxItem>
|
|
56
|
+
* <ListBoxItem>Option 3</ListBoxItem>
|
|
57
|
+
* </ListBox>
|
|
58
|
+
* </Autocomplete>
|
|
59
|
+
*
|
|
60
|
+
* // Controlled input value
|
|
61
|
+
* const [value, setValue] = createSignal('');
|
|
62
|
+
* <Autocomplete
|
|
63
|
+
* inputValue={value()}
|
|
64
|
+
* onInputChange={setValue}
|
|
65
|
+
* filter={(textValue, inputValue) =>
|
|
66
|
+
* textValue.toLowerCase().includes(inputValue.toLowerCase())
|
|
67
|
+
* }
|
|
68
|
+
* >
|
|
69
|
+
* {/* ... *\/}
|
|
70
|
+
* </Autocomplete>
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
function Autocomplete(props) {
|
|
74
|
+
const [stateProps, ariaProps, local] = splitProps(props, [
|
|
75
|
+
"inputValue",
|
|
76
|
+
"defaultInputValue",
|
|
77
|
+
"onInputChange"
|
|
78
|
+
], [
|
|
79
|
+
"filter",
|
|
80
|
+
"disableAutoFocusFirst",
|
|
81
|
+
"disableVirtualFocus",
|
|
82
|
+
"collectionId",
|
|
83
|
+
"collectionAriaLabel"
|
|
84
|
+
]);
|
|
85
|
+
const state = createAutocompleteState(stateProps);
|
|
86
|
+
let inputRef;
|
|
87
|
+
let collectionRef;
|
|
88
|
+
const autocomplete = createAutocomplete({
|
|
89
|
+
...ariaProps,
|
|
90
|
+
inputRef: () => inputRef,
|
|
91
|
+
collectionRef: () => collectionRef
|
|
92
|
+
}, state);
|
|
93
|
+
const inputContextValue = createMemo(() => ({
|
|
94
|
+
inputProps: autocomplete.inputProps,
|
|
95
|
+
inputRef: (el) => {
|
|
96
|
+
inputRef = el;
|
|
97
|
+
}
|
|
98
|
+
}));
|
|
99
|
+
const collectionContextValue = createMemo(() => ({
|
|
100
|
+
collectionProps: autocomplete.collectionProps,
|
|
101
|
+
collectionRef: (el) => {
|
|
102
|
+
collectionRef = el;
|
|
103
|
+
},
|
|
104
|
+
filter: autocomplete.filter
|
|
105
|
+
}));
|
|
106
|
+
return createComponent(AutocompleteStateContext.Provider, {
|
|
107
|
+
value: state,
|
|
108
|
+
get children() {
|
|
109
|
+
return createComponent(AutocompleteContext.Provider, {
|
|
110
|
+
get value() {
|
|
111
|
+
return inputContextValue();
|
|
112
|
+
},
|
|
113
|
+
get children() {
|
|
114
|
+
return createComponent(AutocompleteCollectionContext.Provider, {
|
|
115
|
+
get value() {
|
|
116
|
+
return collectionContextValue();
|
|
117
|
+
},
|
|
118
|
+
get children() {
|
|
119
|
+
return props.children;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
export { Autocomplete, AutocompleteCollectionContext, AutocompleteContext, AutocompleteStateContext, useAutocompleteCollection, useAutocompleteInput, useAutocompleteState };
|
|
129
|
+
|
|
130
|
+
//# sourceMappingURL=Autocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Autocomplete.js","names":["JSX","ParentProps","createContext","useContext","createMemo","splitProps","createSignal","createAutocomplete","AriaAutocompleteOptions","AutocompleteInputProps","CollectionOptions","createAutocompleteState","AutocompleteState","AutocompleteStateOptions","SlotProps","AutocompleteProps","Omit","T","AutocompleteContextValue","inputProps","inputRef","el","HTMLInputElement","AutocompleteCollectionContextValue","collectionProps","collectionRef","HTMLElement","filter","textValue","AutocompleteContext","AutocompleteStateContext","AutocompleteCollectionContext","useAutocompleteInput","useAutocompleteState","useAutocompleteCollection","Autocomplete","props","Element","stateProps","ariaProps","local","state","autocomplete","inputContextValue","collectionContextValue","_$createComponent","Provider","value","children"],"sources":["../src/Autocomplete.tsx"],"sourcesContent":["/**\n * Autocomplete component for solidaria-components\n *\n * Provides autocomplete functionality by wrapping a text input\n * with a filterable collection (ListBox/Menu).\n *\n * Port of react-aria-components/src/Autocomplete.tsx\n */\n\nimport {\n type JSX,\n type ParentProps,\n createContext,\n useContext,\n createMemo,\n splitProps,\n createSignal,\n} from \"solid-js\";\nimport {\n createAutocomplete,\n type AriaAutocompleteOptions,\n type AutocompleteInputProps,\n type CollectionOptions,\n} from \"@proyecto-viviana/solidaria\";\nimport {\n createAutocompleteState,\n type AutocompleteState,\n type AutocompleteStateOptions,\n} from \"@proyecto-viviana/solid-stately\";\nimport { type SlotProps } from \"./utils\";\n\nexport interface AutocompleteProps<T = unknown>\n extends\n Omit<AutocompleteStateOptions, \"children\">,\n Omit<AriaAutocompleteOptions<T>, \"inputRef\" | \"collectionRef\">,\n ParentProps,\n SlotProps {}\n\nexport interface AutocompleteContextValue {\n inputProps: AutocompleteInputProps;\n inputRef: (el: HTMLInputElement) => void;\n}\n\nexport interface AutocompleteCollectionContextValue {\n collectionProps: CollectionOptions;\n collectionRef: (el: HTMLElement) => void;\n filter?: (textValue: string) => boolean;\n}\n\nexport const AutocompleteContext = createContext<AutocompleteContextValue | null>(null);\nexport const AutocompleteStateContext = createContext<AutocompleteState | null>(null);\nexport const AutocompleteCollectionContext =\n createContext<AutocompleteCollectionContextValue | null>(null);\n\n/**\n * Hook to consume autocomplete input context.\n * Use this in your input component (TextField/SearchField) to get the autocomplete props.\n */\nexport function useAutocompleteInput() {\n return useContext(AutocompleteContext);\n}\n\n/**\n * Hook to consume autocomplete state context.\n */\nexport function useAutocompleteState() {\n return useContext(AutocompleteStateContext);\n}\n\n/**\n * Hook to consume autocomplete collection context.\n * Use this in your collection component (ListBox/Menu) to get the autocomplete props.\n */\nexport function useAutocompleteCollection() {\n return useContext(AutocompleteCollectionContext);\n}\n\n/**\n * An autocomplete allows users to search or filter a list of suggestions.\n * It wraps a text input and a collection component (ListBox or Menu),\n * providing keyboard navigation and filtering capabilities.\n *\n * @example\n * ```tsx\n * // Basic usage with SearchField and ListBox\n * <Autocomplete\n * filter={(textValue, inputValue) =>\n * textValue.toLowerCase().includes(inputValue.toLowerCase())\n * }\n * >\n * <SearchField aria-label=\"Search\">\n * <Input />\n * </SearchField>\n * <ListBox aria-label=\"Suggestions\">\n * <ListBoxItem>Option 1</ListBoxItem>\n * <ListBoxItem>Option 2</ListBoxItem>\n * <ListBoxItem>Option 3</ListBoxItem>\n * </ListBox>\n * </Autocomplete>\n *\n * // Controlled input value\n * const [value, setValue] = createSignal('');\n * <Autocomplete\n * inputValue={value()}\n * onInputChange={setValue}\n * filter={(textValue, inputValue) =>\n * textValue.toLowerCase().includes(inputValue.toLowerCase())\n * }\n * >\n * {/* ... *\\/}\n * </Autocomplete>\n * ```\n */\nexport function Autocomplete<T = unknown>(props: AutocompleteProps<T>): JSX.Element {\n const [stateProps, ariaProps, local] = splitProps(\n props,\n [\"inputValue\", \"defaultInputValue\", \"onInputChange\"],\n [\n \"filter\",\n \"disableAutoFocusFirst\",\n \"disableVirtualFocus\",\n \"collectionId\",\n \"collectionAriaLabel\",\n ],\n );\n\n const state = createAutocompleteState(stateProps);\n\n // Create refs\n let inputRef: HTMLInputElement | undefined;\n let collectionRef: HTMLElement | undefined;\n\n // Create autocomplete aria\n const autocomplete = createAutocomplete<T>(\n {\n ...ariaProps,\n inputRef: () => inputRef,\n collectionRef: () => collectionRef,\n },\n state,\n );\n\n // Input context value\n const inputContextValue = createMemo<AutocompleteContextValue>(() => ({\n inputProps: autocomplete.inputProps,\n inputRef: (el: HTMLInputElement) => {\n inputRef = el;\n },\n }));\n\n // Collection context value\n const collectionContextValue = createMemo<AutocompleteCollectionContextValue>(() => ({\n collectionProps: autocomplete.collectionProps,\n collectionRef: (el: HTMLElement) => {\n collectionRef = el;\n },\n filter: autocomplete.filter,\n }));\n\n return (\n <AutocompleteStateContext.Provider value={state}>\n <AutocompleteContext.Provider value={inputContextValue()}>\n <AutocompleteCollectionContext.Provider value={collectionContextValue()}>\n {props.children}\n </AutocompleteCollectionContext.Provider>\n </AutocompleteContext.Provider>\n </AutocompleteStateContext.Provider>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAiDA,MAAa6B,sBAAsB3B,cAA+C,IAAI;AACtF,MAAa4B,2BAA2B5B,cAAwC,IAAI;AACpF,MAAa6B,gCACX7B,cAAyD,IAAI;;;;;AAM/D,SAAgB8B,uBAAuB;CACrC,OAAO7B,WAAW0B,mBAAmB;AACvC;;;;AAKA,SAAgBI,uBAAuB;CACrC,OAAO9B,WAAW2B,wBAAwB;AAC5C;;;;;AAMA,SAAgBI,4BAA4B;CAC1C,OAAO/B,WAAW4B,6BAA6B;AACjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,SAAgBI,aAA0BC,OAA0C;CAClF,MAAM,CAACE,YAAYC,WAAWC,SAASnC,WACrC+B,OACA;EAAC;EAAc;EAAqB;CAAe,GACnD;EACE;EACA;EACA;EACA;EACA;CAAqB,CAEzB;CAEA,MAAMK,QAAQ9B,wBAAwB2B,UAAU;CAGhD,IAAIlB;CACJ,IAAIK;CAGJ,MAAMiB,eAAenC,mBACnB;EACE,GAAGgC;EACHnB,gBAAgBA;EAChBK,qBAAqBA;CACvB,GACAgB,KACF;CAGA,MAAME,oBAAoBvC,kBAA4C;EACpEe,YAAYuB,aAAavB;EACzBC,WAAWC,OAAyB;GAClCD,WAAWC;EACb;CACF,EAAE;CAGF,MAAMuB,yBAAyBxC,kBAAsD;EACnFoB,iBAAiBkB,aAAalB;EAC9BC,gBAAgBJ,OAAoB;GAClCI,gBAAgBJ;EAClB;EACAM,QAAQe,aAAaf;CACvB,EAAE;CAEF,OAAAkB,gBACGf,yBAAyBgB,UAAQ;EAACC,OAAON;EAAK,IAAAO,WAAA;GAAA,OAAAH,gBAC5ChB,oBAAoBiB,UAAQ;IAAA,IAACC,QAAK;KAAA,OAAEJ,kBAAkB;IAAC;IAAA,IAAAK,WAAA;KAAA,OAAAH,gBACrDd,8BAA8Be,UAAQ;MAAA,IAACC,QAAK;OAAA,OAAEH,uBAAuB;MAAC;MAAA,IAAAI,WAAA;OAAA,OACpEZ,MAAMY;MAAQ;KAAA,CAAA;IAAA;GAAA,CAAA;EAAA;CAAA,CAAA;AAKzB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { createContext, createMemo, splitProps, useContext } from "solid-js";
|
|
2
|
+
import { createAutocomplete } from "@proyecto-viviana/solidaria";
|
|
3
|
+
import { createAutocompleteState } from "@proyecto-viviana/solid-stately";
|
|
4
|
+
//#region src/Autocomplete.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Autocomplete component for solidaria-components
|
|
7
|
+
*
|
|
8
|
+
* Provides autocomplete functionality by wrapping a text input
|
|
9
|
+
* with a filterable collection (ListBox/Menu).
|
|
10
|
+
*
|
|
11
|
+
* Port of react-aria-components/src/Autocomplete.tsx
|
|
12
|
+
*/
|
|
13
|
+
const AutocompleteContext = createContext(null);
|
|
14
|
+
const AutocompleteStateContext = createContext(null);
|
|
15
|
+
const AutocompleteCollectionContext = createContext(null);
|
|
16
|
+
/**
|
|
17
|
+
* Hook to consume autocomplete input context.
|
|
18
|
+
* Use this in your input component (TextField/SearchField) to get the autocomplete props.
|
|
19
|
+
*/
|
|
20
|
+
function useAutocompleteInput() {
|
|
21
|
+
return useContext(AutocompleteContext);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Hook to consume autocomplete state context.
|
|
25
|
+
*/
|
|
26
|
+
function useAutocompleteState() {
|
|
27
|
+
return useContext(AutocompleteStateContext);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Hook to consume autocomplete collection context.
|
|
31
|
+
* Use this in your collection component (ListBox/Menu) to get the autocomplete props.
|
|
32
|
+
*/
|
|
33
|
+
function useAutocompleteCollection() {
|
|
34
|
+
return useContext(AutocompleteCollectionContext);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* An autocomplete allows users to search or filter a list of suggestions.
|
|
38
|
+
* It wraps a text input and a collection component (ListBox or Menu),
|
|
39
|
+
* providing keyboard navigation and filtering capabilities.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* // Basic usage with SearchField and ListBox
|
|
44
|
+
* <Autocomplete
|
|
45
|
+
* filter={(textValue, inputValue) =>
|
|
46
|
+
* textValue.toLowerCase().includes(inputValue.toLowerCase())
|
|
47
|
+
* }
|
|
48
|
+
* >
|
|
49
|
+
* <SearchField aria-label="Search">
|
|
50
|
+
* <Input />
|
|
51
|
+
* </SearchField>
|
|
52
|
+
* <ListBox aria-label="Suggestions">
|
|
53
|
+
* <ListBoxItem>Option 1</ListBoxItem>
|
|
54
|
+
* <ListBoxItem>Option 2</ListBoxItem>
|
|
55
|
+
* <ListBoxItem>Option 3</ListBoxItem>
|
|
56
|
+
* </ListBox>
|
|
57
|
+
* </Autocomplete>
|
|
58
|
+
*
|
|
59
|
+
* // Controlled input value
|
|
60
|
+
* const [value, setValue] = createSignal('');
|
|
61
|
+
* <Autocomplete
|
|
62
|
+
* inputValue={value()}
|
|
63
|
+
* onInputChange={setValue}
|
|
64
|
+
* filter={(textValue, inputValue) =>
|
|
65
|
+
* textValue.toLowerCase().includes(inputValue.toLowerCase())
|
|
66
|
+
* }
|
|
67
|
+
* >
|
|
68
|
+
* {/* ... *\/}
|
|
69
|
+
* </Autocomplete>
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
function Autocomplete(props) {
|
|
73
|
+
const [stateProps, ariaProps, local] = splitProps(props, [
|
|
74
|
+
"inputValue",
|
|
75
|
+
"defaultInputValue",
|
|
76
|
+
"onInputChange"
|
|
77
|
+
], [
|
|
78
|
+
"filter",
|
|
79
|
+
"disableAutoFocusFirst",
|
|
80
|
+
"disableVirtualFocus",
|
|
81
|
+
"collectionId",
|
|
82
|
+
"collectionAriaLabel"
|
|
83
|
+
]);
|
|
84
|
+
const state = createAutocompleteState(stateProps);
|
|
85
|
+
let inputRef;
|
|
86
|
+
let collectionRef;
|
|
87
|
+
const autocomplete = createAutocomplete({
|
|
88
|
+
...ariaProps,
|
|
89
|
+
inputRef: () => inputRef,
|
|
90
|
+
collectionRef: () => collectionRef
|
|
91
|
+
}, state);
|
|
92
|
+
const inputContextValue = createMemo(() => ({
|
|
93
|
+
inputProps: autocomplete.inputProps,
|
|
94
|
+
inputRef: (el) => {
|
|
95
|
+
inputRef = el;
|
|
96
|
+
}
|
|
97
|
+
}));
|
|
98
|
+
const collectionContextValue = createMemo(() => ({
|
|
99
|
+
collectionProps: autocomplete.collectionProps,
|
|
100
|
+
collectionRef: (el) => {
|
|
101
|
+
collectionRef = el;
|
|
102
|
+
},
|
|
103
|
+
filter: autocomplete.filter
|
|
104
|
+
}));
|
|
105
|
+
return <AutocompleteStateContext.Provider value={state}>
|
|
106
|
+
<AutocompleteContext.Provider value={inputContextValue()}>
|
|
107
|
+
<AutocompleteCollectionContext.Provider value={collectionContextValue()}>
|
|
108
|
+
{props.children}
|
|
109
|
+
</AutocompleteCollectionContext.Provider>
|
|
110
|
+
</AutocompleteContext.Provider>
|
|
111
|
+
</AutocompleteStateContext.Provider>;
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
export { Autocomplete, AutocompleteCollectionContext, AutocompleteContext, AutocompleteStateContext, useAutocompleteCollection, useAutocompleteInput, useAutocompleteState };
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=Autocomplete.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Autocomplete.jsx","names":[],"sources":["../src/Autocomplete.tsx"],"sourcesContent":["/**\n * Autocomplete component for solidaria-components\n *\n * Provides autocomplete functionality by wrapping a text input\n * with a filterable collection (ListBox/Menu).\n *\n * Port of react-aria-components/src/Autocomplete.tsx\n */\n\nimport {\n type JSX,\n type ParentProps,\n createContext,\n useContext,\n createMemo,\n splitProps,\n createSignal,\n} from \"solid-js\";\nimport {\n createAutocomplete,\n type AriaAutocompleteOptions,\n type AutocompleteInputProps,\n type CollectionOptions,\n} from \"@proyecto-viviana/solidaria\";\nimport {\n createAutocompleteState,\n type AutocompleteState,\n type AutocompleteStateOptions,\n} from \"@proyecto-viviana/solid-stately\";\nimport { type SlotProps } from \"./utils\";\n\nexport interface AutocompleteProps<T = unknown>\n extends\n Omit<AutocompleteStateOptions, \"children\">,\n Omit<AriaAutocompleteOptions<T>, \"inputRef\" | \"collectionRef\">,\n ParentProps,\n SlotProps {}\n\nexport interface AutocompleteContextValue {\n inputProps: AutocompleteInputProps;\n inputRef: (el: HTMLInputElement) => void;\n}\n\nexport interface AutocompleteCollectionContextValue {\n collectionProps: CollectionOptions;\n collectionRef: (el: HTMLElement) => void;\n filter?: (textValue: string) => boolean;\n}\n\nexport const AutocompleteContext = createContext<AutocompleteContextValue | null>(null);\nexport const AutocompleteStateContext = createContext<AutocompleteState | null>(null);\nexport const AutocompleteCollectionContext =\n createContext<AutocompleteCollectionContextValue | null>(null);\n\n/**\n * Hook to consume autocomplete input context.\n * Use this in your input component (TextField/SearchField) to get the autocomplete props.\n */\nexport function useAutocompleteInput() {\n return useContext(AutocompleteContext);\n}\n\n/**\n * Hook to consume autocomplete state context.\n */\nexport function useAutocompleteState() {\n return useContext(AutocompleteStateContext);\n}\n\n/**\n * Hook to consume autocomplete collection context.\n * Use this in your collection component (ListBox/Menu) to get the autocomplete props.\n */\nexport function useAutocompleteCollection() {\n return useContext(AutocompleteCollectionContext);\n}\n\n/**\n * An autocomplete allows users to search or filter a list of suggestions.\n * It wraps a text input and a collection component (ListBox or Menu),\n * providing keyboard navigation and filtering capabilities.\n *\n * @example\n * ```tsx\n * // Basic usage with SearchField and ListBox\n * <Autocomplete\n * filter={(textValue, inputValue) =>\n * textValue.toLowerCase().includes(inputValue.toLowerCase())\n * }\n * >\n * <SearchField aria-label=\"Search\">\n * <Input />\n * </SearchField>\n * <ListBox aria-label=\"Suggestions\">\n * <ListBoxItem>Option 1</ListBoxItem>\n * <ListBoxItem>Option 2</ListBoxItem>\n * <ListBoxItem>Option 3</ListBoxItem>\n * </ListBox>\n * </Autocomplete>\n *\n * // Controlled input value\n * const [value, setValue] = createSignal('');\n * <Autocomplete\n * inputValue={value()}\n * onInputChange={setValue}\n * filter={(textValue, inputValue) =>\n * textValue.toLowerCase().includes(inputValue.toLowerCase())\n * }\n * >\n * {/* ... *\\/}\n * </Autocomplete>\n * ```\n */\nexport function Autocomplete<T = unknown>(props: AutocompleteProps<T>): JSX.Element {\n const [stateProps, ariaProps, local] = splitProps(\n props,\n [\"inputValue\", \"defaultInputValue\", \"onInputChange\"],\n [\n \"filter\",\n \"disableAutoFocusFirst\",\n \"disableVirtualFocus\",\n \"collectionId\",\n \"collectionAriaLabel\",\n ],\n );\n\n const state = createAutocompleteState(stateProps);\n\n // Create refs\n let inputRef: HTMLInputElement | undefined;\n let collectionRef: HTMLElement | undefined;\n\n // Create autocomplete aria\n const autocomplete = createAutocomplete<T>(\n {\n ...ariaProps,\n inputRef: () => inputRef,\n collectionRef: () => collectionRef,\n },\n state,\n );\n\n // Input context value\n const inputContextValue = createMemo<AutocompleteContextValue>(() => ({\n inputProps: autocomplete.inputProps,\n inputRef: (el: HTMLInputElement) => {\n inputRef = el;\n },\n }));\n\n // Collection context value\n const collectionContextValue = createMemo<AutocompleteCollectionContextValue>(() => ({\n collectionProps: autocomplete.collectionProps,\n collectionRef: (el: HTMLElement) => {\n collectionRef = el;\n },\n filter: autocomplete.filter,\n }));\n\n return (\n <AutocompleteStateContext.Provider value={state}>\n <AutocompleteContext.Provider value={inputContextValue()}>\n <AutocompleteCollectionContext.Provider value={collectionContextValue()}>\n {props.children}\n </AutocompleteCollectionContext.Provider>\n </AutocompleteContext.Provider>\n </AutocompleteStateContext.Provider>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAiDA,MAAa,sBAAsB,cAA+C,IAAI;AACtF,MAAa,2BAA2B,cAAwC,IAAI;AACpF,MAAa,gCACX,cAAyD,IAAI;;;;;AAM/D,SAAgB,uBAAuB;CACrC,OAAO,WAAW,mBAAmB;AACvC;;;;AAKA,SAAgB,uBAAuB;CACrC,OAAO,WAAW,wBAAwB;AAC5C;;;;;AAMA,SAAgB,4BAA4B;CAC1C,OAAO,WAAW,6BAA6B;AACjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,SAAgB,aAA0B,OAA0C;CAClF,MAAM,CAAC,YAAY,WAAW,SAAS,WACrC,OACA;EAAC;EAAc;EAAqB;CAAe,GACnD;EACE;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,MAAM,QAAQ,wBAAwB,UAAU;CAGhD,IAAI;CACJ,IAAI;CAGJ,MAAM,eAAe,mBACnB;EACE,GAAG;EACH,gBAAgB;EAChB,qBAAqB;CACvB,GACA,KACF;CAGA,MAAM,oBAAoB,kBAA4C;EACpE,YAAY,aAAa;EACzB,WAAW,OAAyB;GAClC,WAAW;EACb;CACF,EAAE;CAGF,MAAM,yBAAyB,kBAAsD;EACnF,iBAAiB,aAAa;EAC9B,gBAAgB,OAAoB;GAClC,gBAAgB;EAClB;EACA,QAAQ,aAAa;CACvB,EAAE;CAEF,OACE,CAAC,yBAAyB,SAAS,OAAO,OAAO;MAC/C,CAAC,oBAAoB,SAAS,OAAO,kBAAkB,GAAG;QACxD,CAAC,8BAA8B,SAAS,OAAO,uBAAuB,GAAG;WACtE,MAAM,SAAS;QAClB,EAAE,8BAA8B,SAAS;MAC3C,EAAE,oBAAoB,SAAS;IACjC,EAAE,yBAAyB;AAE/B"}
|