@proyecto-viviana/solidaria-components 0.3.2 → 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 +4 -4
- 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 +6 -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 -23932
- package/dist/index.jsx +70 -18337
- 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 +22 -2
- 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 +50 -6
- package/src/DateField.tsx +20 -2
- package/src/DatePicker.tsx +57 -5
- 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 +252 -128
- package/src/Meter.tsx +3 -1
- package/src/Modal.tsx +100 -52
- package/src/NumberField.tsx +51 -8
- package/src/Popover.tsx +40 -10
- 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 +3 -1
- package/src/Text.tsx +31 -10
- package/src/TextField.tsx +43 -5
- 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 +3 -1
- 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,184 @@
|
|
|
1
|
+
import { filterDOMProps, useRenderProps } from "./utils.js";
|
|
2
|
+
import { className, createComponent, delegateEvents, effect, getNextElement, insert, mergeProps, runHydrationEvents, setAttribute, spread, style, template, use } from "solid-js/web";
|
|
3
|
+
import { Show, createContext, createEffect, createMemo, splitProps, useContext } from "solid-js";
|
|
4
|
+
import { announce, createToolbar } from "@proyecto-viviana/solidaria";
|
|
5
|
+
//#region src/ActionBar.tsx
|
|
6
|
+
/**
|
|
7
|
+
* ActionBar component for solidaria-components
|
|
8
|
+
*
|
|
9
|
+
* Headless action bar that appears when items are selected in a collection.
|
|
10
|
+
* Shows a selection count, clear button, and action buttons.
|
|
11
|
+
*
|
|
12
|
+
* No RAC headless equivalent — this is a thin component layer that ties
|
|
13
|
+
* selection state to visibility and keyboard behavior.
|
|
14
|
+
*/
|
|
15
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div>`), _tmpl$2 = /*#__PURE__*/ template(`<div style=position:relative>`), _tmpl$3 = /*#__PURE__*/ template(`<span>`), _tmpl$4 = /*#__PURE__*/ template(`<button type=button>`);
|
|
16
|
+
function assignRef(ref, el) {
|
|
17
|
+
if (!ref) return;
|
|
18
|
+
if (typeof ref === "function") ref(el);
|
|
19
|
+
else ref.current = el;
|
|
20
|
+
}
|
|
21
|
+
const ActionBarContext = createContext(null);
|
|
22
|
+
function useActionBarContext() {
|
|
23
|
+
return useContext(ActionBarContext);
|
|
24
|
+
}
|
|
25
|
+
function ActionBar(props) {
|
|
26
|
+
const [local, domProps] = splitProps(props, [
|
|
27
|
+
"selectedItemCount",
|
|
28
|
+
"onClearSelection",
|
|
29
|
+
"onAction",
|
|
30
|
+
"children",
|
|
31
|
+
"class",
|
|
32
|
+
"style",
|
|
33
|
+
"slot",
|
|
34
|
+
"aria-label",
|
|
35
|
+
"aria-labelledby",
|
|
36
|
+
"onKeyDown",
|
|
37
|
+
"actionsAvailableMessage",
|
|
38
|
+
"ref"
|
|
39
|
+
]);
|
|
40
|
+
const selectedItemCount = () => local.selectedItemCount ?? 0;
|
|
41
|
+
const isOpen = () => selectedItemCount() !== 0;
|
|
42
|
+
const { toolbarProps } = createToolbar({
|
|
43
|
+
orientation: "horizontal",
|
|
44
|
+
get "aria-label"() {
|
|
45
|
+
return local["aria-label"] ?? (local["aria-labelledby"] ? void 0 : "Actions");
|
|
46
|
+
},
|
|
47
|
+
get "aria-labelledby"() {
|
|
48
|
+
return local["aria-labelledby"];
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
let wasOpen = false;
|
|
52
|
+
createEffect(() => {
|
|
53
|
+
const open = isOpen();
|
|
54
|
+
if (open && !wasOpen) {
|
|
55
|
+
const message = local.actionsAvailableMessage ?? "Actions available.";
|
|
56
|
+
if (message) announce(message);
|
|
57
|
+
}
|
|
58
|
+
wasOpen = open;
|
|
59
|
+
});
|
|
60
|
+
const handleKeyDown = (e) => {
|
|
61
|
+
const onKeyDown = local.onKeyDown;
|
|
62
|
+
onKeyDown?.(e);
|
|
63
|
+
if (e.defaultPrevented) return;
|
|
64
|
+
if (e.key === "Escape" && isOpen()) {
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
e.stopPropagation();
|
|
67
|
+
local.onClearSelection?.();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const renderProps = useRenderProps({
|
|
71
|
+
children: void 0,
|
|
72
|
+
class: local.class,
|
|
73
|
+
style: local.style,
|
|
74
|
+
defaultClassName: "solidaria-ActionBar"
|
|
75
|
+
}, () => ({
|
|
76
|
+
isOpen: isOpen(),
|
|
77
|
+
selectedItemCount: selectedItemCount()
|
|
78
|
+
}));
|
|
79
|
+
const filteredDOMProps = createMemo(() => filterDOMProps(domProps, { global: true }));
|
|
80
|
+
const contextValue = createMemo(() => ({
|
|
81
|
+
selectedItemCount,
|
|
82
|
+
onClearSelection: local.onClearSelection,
|
|
83
|
+
onAction: local.onAction
|
|
84
|
+
}));
|
|
85
|
+
return createComponent(Show, {
|
|
86
|
+
get when() {
|
|
87
|
+
return isOpen();
|
|
88
|
+
},
|
|
89
|
+
get children() {
|
|
90
|
+
return createComponent(ActionBarContext.Provider, {
|
|
91
|
+
get value() {
|
|
92
|
+
return contextValue();
|
|
93
|
+
},
|
|
94
|
+
get children() {
|
|
95
|
+
var _el$ = getNextElement(_tmpl$);
|
|
96
|
+
use((el) => assignRef(local.ref, el), _el$);
|
|
97
|
+
spread(_el$, mergeProps(filteredDOMProps, toolbarProps, {
|
|
98
|
+
get ["class"]() {
|
|
99
|
+
return renderProps.class();
|
|
100
|
+
},
|
|
101
|
+
get style() {
|
|
102
|
+
return renderProps.style();
|
|
103
|
+
},
|
|
104
|
+
get slot() {
|
|
105
|
+
return local.slot;
|
|
106
|
+
},
|
|
107
|
+
get ["data-open"]() {
|
|
108
|
+
return isOpen() || void 0;
|
|
109
|
+
},
|
|
110
|
+
"onKeyDown": handleKeyDown
|
|
111
|
+
}), false, true);
|
|
112
|
+
insert(_el$, () => local.children);
|
|
113
|
+
runHydrationEvents();
|
|
114
|
+
return _el$;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Container that positions a collection and its ActionBar.
|
|
122
|
+
*/
|
|
123
|
+
function ActionBarContainer(props) {
|
|
124
|
+
return (() => {
|
|
125
|
+
var _el$2 = getNextElement(_tmpl$2);
|
|
126
|
+
insert(_el$2, () => props.children);
|
|
127
|
+
effect((_p$) => {
|
|
128
|
+
var _v$ = props.class ?? "solidaria-ActionBarContainer", _v$2 = { ...props.style };
|
|
129
|
+
_v$ !== _p$.e && className(_el$2, _p$.e = _v$);
|
|
130
|
+
_p$.t = style(_el$2, _v$2, _p$.t);
|
|
131
|
+
return _p$;
|
|
132
|
+
}, {
|
|
133
|
+
e: void 0,
|
|
134
|
+
t: void 0
|
|
135
|
+
});
|
|
136
|
+
return _el$2;
|
|
137
|
+
})();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Displays the count of selected items.
|
|
141
|
+
*/
|
|
142
|
+
function ActionBarSelectionCount(props) {
|
|
143
|
+
const ctx = useActionBarContext();
|
|
144
|
+
const text = () => {
|
|
145
|
+
if (!ctx) return "";
|
|
146
|
+
const count = ctx.selectedItemCount();
|
|
147
|
+
if (count === "all") return "All selected";
|
|
148
|
+
if (count === 0) return "None selected";
|
|
149
|
+
return `${count} selected`;
|
|
150
|
+
};
|
|
151
|
+
return (() => {
|
|
152
|
+
var _el$3 = getNextElement(_tmpl$3);
|
|
153
|
+
insert(_el$3, text);
|
|
154
|
+
effect(() => className(_el$3, props.class));
|
|
155
|
+
return _el$3;
|
|
156
|
+
})();
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Button to clear the current selection.
|
|
160
|
+
*/
|
|
161
|
+
function ActionBarClearButton(props) {
|
|
162
|
+
const ctx = useActionBarContext();
|
|
163
|
+
return (() => {
|
|
164
|
+
var _el$4 = getNextElement(_tmpl$4);
|
|
165
|
+
_el$4.$$click = () => ctx?.onClearSelection?.();
|
|
166
|
+
insert(_el$4, () => props.children ?? "✕");
|
|
167
|
+
effect((_p$) => {
|
|
168
|
+
var _v$3 = props["aria-label"] ?? "Clear selection", _v$4 = props.class;
|
|
169
|
+
_v$3 !== _p$.e && setAttribute(_el$4, "aria-label", _p$.e = _v$3);
|
|
170
|
+
_v$4 !== _p$.t && className(_el$4, _p$.t = _v$4);
|
|
171
|
+
return _p$;
|
|
172
|
+
}, {
|
|
173
|
+
e: void 0,
|
|
174
|
+
t: void 0
|
|
175
|
+
});
|
|
176
|
+
runHydrationEvents();
|
|
177
|
+
return _el$4;
|
|
178
|
+
})();
|
|
179
|
+
}
|
|
180
|
+
delegateEvents(["click"]);
|
|
181
|
+
//#endregion
|
|
182
|
+
export { ActionBar, ActionBarClearButton, ActionBarContainer, ActionBarContext, ActionBarSelectionCount, useActionBarContext };
|
|
183
|
+
|
|
184
|
+
//# sourceMappingURL=ActionBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionBar.js","names":["JSX","ParentProps","Show","createContext","createMemo","createEffect","splitProps","useContext","announce","createToolbar","Key","ClassNameOrFunction","StyleOrFunction","SlotProps","useRenderProps","filterDOMProps","RefLike","el","T","current","assignRef","ref","ActionBarRenderProps","isOpen","selectedItemCount","ActionBarProps","Omit","HTMLAttributes","HTMLDivElement","onClearSelection","onAction","key","children","Element","class","style","onKeyDown","EventHandlerUnion","KeyboardEvent","actionsAvailableMessage","ActionBarContextValue","ActionBarContext","useActionBarContext","ActionBar","props","local","domProps","toolbarProps","orientation","aria-label","undefined","aria-labelledby","wasOpen","open","message","handleKeyDown","e","EventHandler","defaultPrevented","preventDefault","stopPropagation","renderProps","defaultClassName","filteredDOMProps","Record","global","contextValue","_$createComponent","when","Provider","value","_el$","_$getNextElement","_tmpl$","_$use","_$spread","_$mergeProps","slot","data-open","_$insert","_$runHydrationEvents","ActionBarContainerProps","CSSProperties","ActionBarContainer","_el$2","_tmpl$2","_$effect","_p$","_v$","_v$2","_$className","t","_$style","ActionBarSelectionCountProps","ActionBarSelectionCount","ctx","text","count","_el$3","_tmpl$3","ActionBarClearButtonProps","ActionBarClearButton","_el$4","_tmpl$4","$$click","_v$3","_v$4","_$setAttribute","_$delegateEvents"],"sources":["../src/ActionBar.tsx"],"sourcesContent":["/**\n * ActionBar component for solidaria-components\n *\n * Headless action bar that appears when items are selected in a collection.\n * Shows a selection count, clear button, and action buttons.\n *\n * No RAC headless equivalent — this is a thin component layer that ties\n * selection state to visibility and keyboard behavior.\n */\n\nimport {\n type JSX,\n type ParentProps,\n Show,\n createContext,\n createMemo,\n createEffect,\n splitProps,\n useContext,\n} from \"solid-js\";\nimport { announce, createToolbar } from \"@proyecto-viviana/solidaria\";\nimport type { Key } from \"@proyecto-viviana/solid-stately\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\n\ntype RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;\n\nfunction assignRef<T>(ref: RefLike<T>, el: T): void {\n if (!ref) return;\n if (typeof ref === \"function\") {\n ref(el);\n } else {\n ref.current = el;\n }\n}\n\nexport interface ActionBarRenderProps {\n /** Whether the action bar is visible. */\n isOpen: boolean;\n /** The number of selected items. */\n selectedItemCount: number | \"all\";\n}\n\nexport interface ActionBarProps\n extends\n Omit<JSX.HTMLAttributes<HTMLDivElement>, \"class\" | \"style\" | \"children\" | \"ref\" | \"slot\">,\n SlotProps {\n /** The number of selected items. ActionBar is hidden when 0. @default 0 */\n selectedItemCount?: number | \"all\";\n /** Callback when the clear button is pressed. */\n onClearSelection?: () => void;\n /** Callback when an action is triggered. */\n onAction?: (key: Key) => void;\n /** The action buttons to display. */\n children?: JSX.Element;\n /** CSS class for the container. */\n class?: ClassNameOrFunction<ActionBarRenderProps>;\n /** Inline style for the container. */\n style?: StyleOrFunction<ActionBarRenderProps>;\n /** Accessible label for the action bar. @default 'Actions' */\n \"aria-label\"?: string;\n /** Identifies the element (or elements) that labels the action bar. */\n \"aria-labelledby\"?: string;\n /** Optional keydown handler on the action bar element. */\n onKeyDown?: JSX.EventHandlerUnion<HTMLDivElement, KeyboardEvent>;\n /** Screen reader announcement when the action bar becomes available. */\n actionsAvailableMessage?: string;\n /** Ref for the underlying action bar element. */\n ref?: RefLike<HTMLDivElement>;\n}\n\nexport interface ActionBarContextValue {\n selectedItemCount: () => number | \"all\";\n onClearSelection?: () => void;\n onAction?: (key: Key) => void;\n}\n\nexport const ActionBarContext = createContext<ActionBarContextValue | null>(null);\n\nexport function useActionBarContext(): ActionBarContextValue | null {\n return useContext(ActionBarContext);\n}\n\nexport function ActionBar(props: ActionBarProps): JSX.Element {\n const [local, domProps] = splitProps(props, [\n \"selectedItemCount\",\n \"onClearSelection\",\n \"onAction\",\n \"children\",\n \"class\",\n \"style\",\n \"slot\",\n \"aria-label\",\n \"aria-labelledby\",\n \"onKeyDown\",\n \"actionsAvailableMessage\",\n \"ref\",\n ]);\n\n const selectedItemCount = () => local.selectedItemCount ?? 0;\n const isOpen = () => selectedItemCount() !== 0;\n\n const { toolbarProps } = createToolbar({\n orientation: \"horizontal\",\n get \"aria-label\"() {\n return local[\"aria-label\"] ?? (local[\"aria-labelledby\"] ? undefined : \"Actions\");\n },\n get \"aria-labelledby\"() {\n return local[\"aria-labelledby\"];\n },\n });\n\n let wasOpen = false;\n createEffect(() => {\n const open = isOpen();\n if (open && !wasOpen) {\n const message = local.actionsAvailableMessage ?? \"Actions available.\";\n if (message) {\n announce(message);\n }\n }\n wasOpen = open;\n });\n\n const handleKeyDown: JSX.EventHandlerUnion<HTMLDivElement, KeyboardEvent> = (e) => {\n const onKeyDown = local.onKeyDown as\n | JSX.EventHandler<HTMLDivElement, KeyboardEvent>\n | undefined;\n onKeyDown?.(e);\n if (e.defaultPrevented) {\n return;\n }\n\n if (e.key === \"Escape\" && isOpen()) {\n e.preventDefault();\n e.stopPropagation();\n local.onClearSelection?.();\n }\n };\n\n const renderProps = useRenderProps(\n {\n children: undefined,\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-ActionBar\",\n },\n () => ({\n isOpen: isOpen(),\n selectedItemCount: selectedItemCount(),\n }),\n );\n\n const filteredDOMProps = createMemo(() =>\n filterDOMProps(domProps as Record<string, unknown>, { global: true }),\n );\n\n const contextValue = createMemo<ActionBarContextValue>(() => ({\n selectedItemCount,\n onClearSelection: local.onClearSelection,\n onAction: local.onAction,\n }));\n\n return (\n <Show when={isOpen()}>\n <ActionBarContext.Provider value={contextValue()}>\n <div\n {...filteredDOMProps()}\n {...toolbarProps}\n class={renderProps.class()}\n style={renderProps.style()}\n slot={local.slot}\n data-open={isOpen() || undefined}\n onKeyDown={handleKeyDown}\n ref={(el) => assignRef(local.ref, el)}\n >\n {local.children}\n </div>\n </ActionBarContext.Provider>\n </Show>\n );\n}\n\nexport interface ActionBarContainerProps extends ParentProps {\n class?: string;\n style?: JSX.CSSProperties;\n}\n\n/**\n * Container that positions a collection and its ActionBar.\n */\nexport function ActionBarContainer(props: ActionBarContainerProps): JSX.Element {\n return (\n <div\n class={props.class ?? \"solidaria-ActionBarContainer\"}\n style={{ position: \"relative\", ...props.style }}\n >\n {props.children}\n </div>\n );\n}\n\nexport interface ActionBarSelectionCountProps {\n class?: string;\n}\n\n/**\n * Displays the count of selected items.\n */\nexport function ActionBarSelectionCount(props: ActionBarSelectionCountProps): JSX.Element {\n const ctx = useActionBarContext();\n\n const text = () => {\n if (!ctx) return \"\";\n const count = ctx.selectedItemCount();\n if (count === \"all\") return \"All selected\";\n if (count === 0) return \"None selected\";\n return `${count} selected`;\n };\n\n return <span class={props.class}>{text()}</span>;\n}\n\nexport interface ActionBarClearButtonProps {\n class?: string;\n children?: JSX.Element;\n \"aria-label\"?: string;\n}\n\n/**\n * Button to clear the current selection.\n */\nexport function ActionBarClearButton(props: ActionBarClearButtonProps): JSX.Element {\n const ctx = useActionBarContext();\n\n return (\n <button\n type=\"button\"\n aria-label={props[\"aria-label\"] ?? \"Clear selection\"}\n class={props.class}\n onClick={() => ctx?.onClearSelection?.()}\n >\n {props.children ?? \"\\u2715\"}\n </button>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { filterDOMProps, useRenderProps } from "./utils.jsx";
|
|
2
|
+
import { Show, createContext, createEffect, createMemo, splitProps, useContext } from "solid-js";
|
|
3
|
+
import { announce, createToolbar } from "@proyecto-viviana/solidaria";
|
|
4
|
+
//#region src/ActionBar.tsx
|
|
5
|
+
/**
|
|
6
|
+
* ActionBar component for solidaria-components
|
|
7
|
+
*
|
|
8
|
+
* Headless action bar that appears when items are selected in a collection.
|
|
9
|
+
* Shows a selection count, clear button, and action buttons.
|
|
10
|
+
*
|
|
11
|
+
* No RAC headless equivalent — this is a thin component layer that ties
|
|
12
|
+
* selection state to visibility and keyboard behavior.
|
|
13
|
+
*/
|
|
14
|
+
function assignRef(ref, el) {
|
|
15
|
+
if (!ref) return;
|
|
16
|
+
if (typeof ref === "function") ref(el);
|
|
17
|
+
else ref.current = el;
|
|
18
|
+
}
|
|
19
|
+
const ActionBarContext = createContext(null);
|
|
20
|
+
function useActionBarContext() {
|
|
21
|
+
return useContext(ActionBarContext);
|
|
22
|
+
}
|
|
23
|
+
function ActionBar(props) {
|
|
24
|
+
const [local, domProps] = splitProps(props, [
|
|
25
|
+
"selectedItemCount",
|
|
26
|
+
"onClearSelection",
|
|
27
|
+
"onAction",
|
|
28
|
+
"children",
|
|
29
|
+
"class",
|
|
30
|
+
"style",
|
|
31
|
+
"slot",
|
|
32
|
+
"aria-label",
|
|
33
|
+
"aria-labelledby",
|
|
34
|
+
"onKeyDown",
|
|
35
|
+
"actionsAvailableMessage",
|
|
36
|
+
"ref"
|
|
37
|
+
]);
|
|
38
|
+
const selectedItemCount = () => local.selectedItemCount ?? 0;
|
|
39
|
+
const isOpen = () => selectedItemCount() !== 0;
|
|
40
|
+
const { toolbarProps } = createToolbar({
|
|
41
|
+
orientation: "horizontal",
|
|
42
|
+
get "aria-label"() {
|
|
43
|
+
return local["aria-label"] ?? (local["aria-labelledby"] ? void 0 : "Actions");
|
|
44
|
+
},
|
|
45
|
+
get "aria-labelledby"() {
|
|
46
|
+
return local["aria-labelledby"];
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
let wasOpen = false;
|
|
50
|
+
createEffect(() => {
|
|
51
|
+
const open = isOpen();
|
|
52
|
+
if (open && !wasOpen) {
|
|
53
|
+
const message = local.actionsAvailableMessage ?? "Actions available.";
|
|
54
|
+
if (message) announce(message);
|
|
55
|
+
}
|
|
56
|
+
wasOpen = open;
|
|
57
|
+
});
|
|
58
|
+
const handleKeyDown = (e) => {
|
|
59
|
+
const onKeyDown = local.onKeyDown;
|
|
60
|
+
onKeyDown?.(e);
|
|
61
|
+
if (e.defaultPrevented) return;
|
|
62
|
+
if (e.key === "Escape" && isOpen()) {
|
|
63
|
+
e.preventDefault();
|
|
64
|
+
e.stopPropagation();
|
|
65
|
+
local.onClearSelection?.();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const renderProps = useRenderProps({
|
|
69
|
+
children: void 0,
|
|
70
|
+
class: local.class,
|
|
71
|
+
style: local.style,
|
|
72
|
+
defaultClassName: "solidaria-ActionBar"
|
|
73
|
+
}, () => ({
|
|
74
|
+
isOpen: isOpen(),
|
|
75
|
+
selectedItemCount: selectedItemCount()
|
|
76
|
+
}));
|
|
77
|
+
const filteredDOMProps = createMemo(() => filterDOMProps(domProps, { global: true }));
|
|
78
|
+
const contextValue = createMemo(() => ({
|
|
79
|
+
selectedItemCount,
|
|
80
|
+
onClearSelection: local.onClearSelection,
|
|
81
|
+
onAction: local.onAction
|
|
82
|
+
}));
|
|
83
|
+
return <Show when={isOpen()}>
|
|
84
|
+
<ActionBarContext.Provider value={contextValue()}>
|
|
85
|
+
<div {...filteredDOMProps()} {...toolbarProps} class={renderProps.class()} style={renderProps.style()} slot={local.slot} data-open={isOpen() || void 0} onKeyDown={handleKeyDown} ref={(el) => assignRef(local.ref, el)}>
|
|
86
|
+
{local.children}
|
|
87
|
+
</div>
|
|
88
|
+
</ActionBarContext.Provider>
|
|
89
|
+
</Show>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Container that positions a collection and its ActionBar.
|
|
93
|
+
*/
|
|
94
|
+
function ActionBarContainer(props) {
|
|
95
|
+
return <div class={props.class ?? "solidaria-ActionBarContainer"} style={{
|
|
96
|
+
position: "relative",
|
|
97
|
+
...props.style
|
|
98
|
+
}}>
|
|
99
|
+
{props.children}
|
|
100
|
+
</div>;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Displays the count of selected items.
|
|
104
|
+
*/
|
|
105
|
+
function ActionBarSelectionCount(props) {
|
|
106
|
+
const ctx = useActionBarContext();
|
|
107
|
+
const text = () => {
|
|
108
|
+
if (!ctx) return "";
|
|
109
|
+
const count = ctx.selectedItemCount();
|
|
110
|
+
if (count === "all") return "All selected";
|
|
111
|
+
if (count === 0) return "None selected";
|
|
112
|
+
return `${count} selected`;
|
|
113
|
+
};
|
|
114
|
+
return <span class={props.class}>{text()}</span>;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Button to clear the current selection.
|
|
118
|
+
*/
|
|
119
|
+
function ActionBarClearButton(props) {
|
|
120
|
+
const ctx = useActionBarContext();
|
|
121
|
+
return <button type="button" aria-label={props["aria-label"] ?? "Clear selection"} class={props.class} onClick={() => ctx?.onClearSelection?.()}>
|
|
122
|
+
{props.children ?? "✕"}
|
|
123
|
+
</button>;
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
export { ActionBar, ActionBarClearButton, ActionBarContainer, ActionBarContext, ActionBarSelectionCount, useActionBarContext };
|
|
127
|
+
|
|
128
|
+
//# sourceMappingURL=ActionBar.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionBar.jsx","names":[],"sources":["../src/ActionBar.tsx"],"sourcesContent":["/**\n * ActionBar component for solidaria-components\n *\n * Headless action bar that appears when items are selected in a collection.\n * Shows a selection count, clear button, and action buttons.\n *\n * No RAC headless equivalent — this is a thin component layer that ties\n * selection state to visibility and keyboard behavior.\n */\n\nimport {\n type JSX,\n type ParentProps,\n Show,\n createContext,\n createMemo,\n createEffect,\n splitProps,\n useContext,\n} from \"solid-js\";\nimport { announce, createToolbar } from \"@proyecto-viviana/solidaria\";\nimport type { Key } from \"@proyecto-viviana/solid-stately\";\nimport {\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\n\ntype RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;\n\nfunction assignRef<T>(ref: RefLike<T>, el: T): void {\n if (!ref) return;\n if (typeof ref === \"function\") {\n ref(el);\n } else {\n ref.current = el;\n }\n}\n\nexport interface ActionBarRenderProps {\n /** Whether the action bar is visible. */\n isOpen: boolean;\n /** The number of selected items. */\n selectedItemCount: number | \"all\";\n}\n\nexport interface ActionBarProps\n extends\n Omit<JSX.HTMLAttributes<HTMLDivElement>, \"class\" | \"style\" | \"children\" | \"ref\" | \"slot\">,\n SlotProps {\n /** The number of selected items. ActionBar is hidden when 0. @default 0 */\n selectedItemCount?: number | \"all\";\n /** Callback when the clear button is pressed. */\n onClearSelection?: () => void;\n /** Callback when an action is triggered. */\n onAction?: (key: Key) => void;\n /** The action buttons to display. */\n children?: JSX.Element;\n /** CSS class for the container. */\n class?: ClassNameOrFunction<ActionBarRenderProps>;\n /** Inline style for the container. */\n style?: StyleOrFunction<ActionBarRenderProps>;\n /** Accessible label for the action bar. @default 'Actions' */\n \"aria-label\"?: string;\n /** Identifies the element (or elements) that labels the action bar. */\n \"aria-labelledby\"?: string;\n /** Optional keydown handler on the action bar element. */\n onKeyDown?: JSX.EventHandlerUnion<HTMLDivElement, KeyboardEvent>;\n /** Screen reader announcement when the action bar becomes available. */\n actionsAvailableMessage?: string;\n /** Ref for the underlying action bar element. */\n ref?: RefLike<HTMLDivElement>;\n}\n\nexport interface ActionBarContextValue {\n selectedItemCount: () => number | \"all\";\n onClearSelection?: () => void;\n onAction?: (key: Key) => void;\n}\n\nexport const ActionBarContext = createContext<ActionBarContextValue | null>(null);\n\nexport function useActionBarContext(): ActionBarContextValue | null {\n return useContext(ActionBarContext);\n}\n\nexport function ActionBar(props: ActionBarProps): JSX.Element {\n const [local, domProps] = splitProps(props, [\n \"selectedItemCount\",\n \"onClearSelection\",\n \"onAction\",\n \"children\",\n \"class\",\n \"style\",\n \"slot\",\n \"aria-label\",\n \"aria-labelledby\",\n \"onKeyDown\",\n \"actionsAvailableMessage\",\n \"ref\",\n ]);\n\n const selectedItemCount = () => local.selectedItemCount ?? 0;\n const isOpen = () => selectedItemCount() !== 0;\n\n const { toolbarProps } = createToolbar({\n orientation: \"horizontal\",\n get \"aria-label\"() {\n return local[\"aria-label\"] ?? (local[\"aria-labelledby\"] ? undefined : \"Actions\");\n },\n get \"aria-labelledby\"() {\n return local[\"aria-labelledby\"];\n },\n });\n\n let wasOpen = false;\n createEffect(() => {\n const open = isOpen();\n if (open && !wasOpen) {\n const message = local.actionsAvailableMessage ?? \"Actions available.\";\n if (message) {\n announce(message);\n }\n }\n wasOpen = open;\n });\n\n const handleKeyDown: JSX.EventHandlerUnion<HTMLDivElement, KeyboardEvent> = (e) => {\n const onKeyDown = local.onKeyDown as\n | JSX.EventHandler<HTMLDivElement, KeyboardEvent>\n | undefined;\n onKeyDown?.(e);\n if (e.defaultPrevented) {\n return;\n }\n\n if (e.key === \"Escape\" && isOpen()) {\n e.preventDefault();\n e.stopPropagation();\n local.onClearSelection?.();\n }\n };\n\n const renderProps = useRenderProps(\n {\n children: undefined,\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-ActionBar\",\n },\n () => ({\n isOpen: isOpen(),\n selectedItemCount: selectedItemCount(),\n }),\n );\n\n const filteredDOMProps = createMemo(() =>\n filterDOMProps(domProps as Record<string, unknown>, { global: true }),\n );\n\n const contextValue = createMemo<ActionBarContextValue>(() => ({\n selectedItemCount,\n onClearSelection: local.onClearSelection,\n onAction: local.onAction,\n }));\n\n return (\n <Show when={isOpen()}>\n <ActionBarContext.Provider value={contextValue()}>\n <div\n {...filteredDOMProps()}\n {...toolbarProps}\n class={renderProps.class()}\n style={renderProps.style()}\n slot={local.slot}\n data-open={isOpen() || undefined}\n onKeyDown={handleKeyDown}\n ref={(el) => assignRef(local.ref, el)}\n >\n {local.children}\n </div>\n </ActionBarContext.Provider>\n </Show>\n );\n}\n\nexport interface ActionBarContainerProps extends ParentProps {\n class?: string;\n style?: JSX.CSSProperties;\n}\n\n/**\n * Container that positions a collection and its ActionBar.\n */\nexport function ActionBarContainer(props: ActionBarContainerProps): JSX.Element {\n return (\n <div\n class={props.class ?? \"solidaria-ActionBarContainer\"}\n style={{ position: \"relative\", ...props.style }}\n >\n {props.children}\n </div>\n );\n}\n\nexport interface ActionBarSelectionCountProps {\n class?: string;\n}\n\n/**\n * Displays the count of selected items.\n */\nexport function ActionBarSelectionCount(props: ActionBarSelectionCountProps): JSX.Element {\n const ctx = useActionBarContext();\n\n const text = () => {\n if (!ctx) return \"\";\n const count = ctx.selectedItemCount();\n if (count === \"all\") return \"All selected\";\n if (count === 0) return \"None selected\";\n return `${count} selected`;\n };\n\n return <span class={props.class}>{text()}</span>;\n}\n\nexport interface ActionBarClearButtonProps {\n class?: string;\n children?: JSX.Element;\n \"aria-label\"?: string;\n}\n\n/**\n * Button to clear the current selection.\n */\nexport function ActionBarClearButton(props: ActionBarClearButtonProps): JSX.Element {\n const ctx = useActionBarContext();\n\n return (\n <button\n type=\"button\"\n aria-label={props[\"aria-label\"] ?? \"Clear selection\"}\n class={props.class}\n onClick={() => ctx?.onClearSelection?.()}\n >\n {props.children ?? \"\\u2715\"}\n </button>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { filterDOMProps, useRenderProps } from "./utils.js";
|
|
2
|
+
import { createComponent, getNextElement, insert, mergeProps, runHydrationEvents, spread, template, use } from "solid-js/web";
|
|
3
|
+
import { For, createContext, createMemo, splitProps, useContext } from "solid-js";
|
|
4
|
+
import { createActionGroup, createActionGroupItem } from "@proyecto-viviana/solidaria";
|
|
5
|
+
import { createListState } from "@proyecto-viviana/solid-stately";
|
|
6
|
+
//#region src/ActionGroup.tsx
|
|
7
|
+
/**
|
|
8
|
+
* ActionGroup component for solidaria-components
|
|
9
|
+
*
|
|
10
|
+
* Pre-wired headless action group component that combines
|
|
11
|
+
* createListState + createActionGroup/createActionGroupItem.
|
|
12
|
+
* Provides proper dynamic roles (toolbar/radiogroup), keyboard
|
|
13
|
+
* navigation, and ARIA attributes.
|
|
14
|
+
*
|
|
15
|
+
* No RAC equivalent exists — this bridges solidaria ARIA hooks
|
|
16
|
+
* directly to a headless component.
|
|
17
|
+
*/
|
|
18
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div>`), _tmpl$2 = /*#__PURE__*/ template(`<button>`);
|
|
19
|
+
const ActionGroupContext = createContext(null);
|
|
20
|
+
const ActionGroupStateContext = createContext(null);
|
|
21
|
+
function ActionGroup(props) {
|
|
22
|
+
const [local, ariaGroupProps, domProps] = splitProps(props, [
|
|
23
|
+
"items",
|
|
24
|
+
"selectionMode",
|
|
25
|
+
"orientation",
|
|
26
|
+
"isDisabled",
|
|
27
|
+
"selectedKeys",
|
|
28
|
+
"defaultSelectedKeys",
|
|
29
|
+
"onSelectionChange",
|
|
30
|
+
"onAction",
|
|
31
|
+
"disabledKeys",
|
|
32
|
+
"children",
|
|
33
|
+
"class",
|
|
34
|
+
"style",
|
|
35
|
+
"slot"
|
|
36
|
+
], ["aria-label", "aria-labelledby"]);
|
|
37
|
+
const state = createListState({
|
|
38
|
+
get items() {
|
|
39
|
+
return local.items;
|
|
40
|
+
},
|
|
41
|
+
get selectionMode() {
|
|
42
|
+
return local.selectionMode ?? "none";
|
|
43
|
+
},
|
|
44
|
+
get selectedKeys() {
|
|
45
|
+
return local.selectedKeys;
|
|
46
|
+
},
|
|
47
|
+
get defaultSelectedKeys() {
|
|
48
|
+
return local.defaultSelectedKeys;
|
|
49
|
+
},
|
|
50
|
+
get onSelectionChange() {
|
|
51
|
+
return local.onSelectionChange;
|
|
52
|
+
},
|
|
53
|
+
get disabledKeys() {
|
|
54
|
+
return local.disabledKeys;
|
|
55
|
+
},
|
|
56
|
+
getKey: (item) => item.id,
|
|
57
|
+
getTextValue: (item) => item.label,
|
|
58
|
+
getDisabled: (item) => !!item.isDisabled
|
|
59
|
+
});
|
|
60
|
+
const { actionGroupProps } = createActionGroup({
|
|
61
|
+
get items() {
|
|
62
|
+
return local.items;
|
|
63
|
+
},
|
|
64
|
+
get isDisabled() {
|
|
65
|
+
return local.isDisabled;
|
|
66
|
+
},
|
|
67
|
+
get orientation() {
|
|
68
|
+
return local.orientation;
|
|
69
|
+
},
|
|
70
|
+
get "aria-label"() {
|
|
71
|
+
return ariaGroupProps["aria-label"];
|
|
72
|
+
},
|
|
73
|
+
get "aria-labelledby"() {
|
|
74
|
+
return ariaGroupProps["aria-labelledby"];
|
|
75
|
+
},
|
|
76
|
+
get onAction() {
|
|
77
|
+
return local.onAction;
|
|
78
|
+
}
|
|
79
|
+
}, state);
|
|
80
|
+
const orientation = () => local.orientation ?? "horizontal";
|
|
81
|
+
const renderProps = useRenderProps({
|
|
82
|
+
children: void 0,
|
|
83
|
+
class: local.class,
|
|
84
|
+
style: local.style,
|
|
85
|
+
defaultClassName: "solidaria-ActionGroup"
|
|
86
|
+
}, () => ({
|
|
87
|
+
orientation: orientation(),
|
|
88
|
+
isDisabled: !!local.isDisabled,
|
|
89
|
+
selectionMode: local.selectionMode ?? "none"
|
|
90
|
+
}));
|
|
91
|
+
const filteredDOMProps = createMemo(() => filterDOMProps(domProps, { global: true }));
|
|
92
|
+
return createComponent(ActionGroupContext.Provider, {
|
|
93
|
+
value: { state },
|
|
94
|
+
get children() {
|
|
95
|
+
return createComponent(ActionGroupStateContext.Provider, {
|
|
96
|
+
value: state,
|
|
97
|
+
get children() {
|
|
98
|
+
var _el$ = getNextElement(_tmpl$);
|
|
99
|
+
use((el) => {
|
|
100
|
+
const refFn = actionGroupProps.ref;
|
|
101
|
+
refFn?.(el);
|
|
102
|
+
}, _el$);
|
|
103
|
+
spread(_el$, mergeProps(filteredDOMProps, actionGroupProps, {
|
|
104
|
+
get ["class"]() {
|
|
105
|
+
return renderProps.class();
|
|
106
|
+
},
|
|
107
|
+
get style() {
|
|
108
|
+
return renderProps.style();
|
|
109
|
+
},
|
|
110
|
+
get slot() {
|
|
111
|
+
return local.slot;
|
|
112
|
+
},
|
|
113
|
+
get ["data-orientation"]() {
|
|
114
|
+
return orientation();
|
|
115
|
+
},
|
|
116
|
+
get ["data-disabled"]() {
|
|
117
|
+
return local.isDisabled || void 0;
|
|
118
|
+
}
|
|
119
|
+
}), false, true);
|
|
120
|
+
insert(_el$, createComponent(For, {
|
|
121
|
+
get each() {
|
|
122
|
+
return local.items;
|
|
123
|
+
},
|
|
124
|
+
children: (item) => createComponent(ActionGroupItemWrapper, {
|
|
125
|
+
item,
|
|
126
|
+
state,
|
|
127
|
+
get renderChild() {
|
|
128
|
+
return local.children;
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
}));
|
|
132
|
+
runHydrationEvents();
|
|
133
|
+
return _el$;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function ActionGroupItemWrapper(props) {
|
|
140
|
+
const { buttonProps } = createActionGroupItem({ get key() {
|
|
141
|
+
return props.item.id;
|
|
142
|
+
} }, props.state);
|
|
143
|
+
const isFocused = () => props.state.focusedKey() === props.item.id;
|
|
144
|
+
const isSelected = () => {
|
|
145
|
+
const keys = props.state.selectedKeys();
|
|
146
|
+
return keys === "all" || keys instanceof Set && keys.has(props.item.id);
|
|
147
|
+
};
|
|
148
|
+
const isDisabled = () => props.state.isDisabled(props.item.id);
|
|
149
|
+
const renderProps = createMemo(() => ({
|
|
150
|
+
isSelected: isSelected(),
|
|
151
|
+
isDisabled: isDisabled(),
|
|
152
|
+
isFocused: isFocused()
|
|
153
|
+
}));
|
|
154
|
+
const { ref: _ref, ...restButtonProps } = buttonProps;
|
|
155
|
+
return (() => {
|
|
156
|
+
var _el$2 = getNextElement(_tmpl$2);
|
|
157
|
+
spread(_el$2, mergeProps(restButtonProps, {
|
|
158
|
+
get ["data-selected"]() {
|
|
159
|
+
return isSelected() || void 0;
|
|
160
|
+
},
|
|
161
|
+
get ["data-disabled"]() {
|
|
162
|
+
return isDisabled() || void 0;
|
|
163
|
+
},
|
|
164
|
+
get ["data-focused"]() {
|
|
165
|
+
return isFocused() || void 0;
|
|
166
|
+
}
|
|
167
|
+
}), false, true);
|
|
168
|
+
insert(_el$2, () => props.renderChild(props.item, renderProps()));
|
|
169
|
+
runHydrationEvents();
|
|
170
|
+
return _el$2;
|
|
171
|
+
})();
|
|
172
|
+
}
|
|
173
|
+
function useActionGroupContext() {
|
|
174
|
+
return useContext(ActionGroupContext);
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
export { ActionGroup, ActionGroupContext, ActionGroupStateContext, useActionGroupContext };
|
|
178
|
+
|
|
179
|
+
//# sourceMappingURL=ActionGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionGroup.js","names":["JSX","ParentProps","createContext","createMemo","splitProps","useContext","For","createActionGroup","createActionGroupItem","AriaActionGroupProps","createListState","ListState","Key","SelectionMode","ClassNameOrFunction","StyleOrFunction","SlotProps","useRenderProps","filterDOMProps","ActionGroupRenderProps","orientation","isDisabled","selectionMode","ActionGroupItemRenderProps","isSelected","isFocused","ActionGroupItem","id","label","key","ActionGroupProps","items","T","selectedKeys","Iterable","defaultSelectedKeys","onSelectionChange","keys","Set","onAction","disabledKeys","children","item","renderProps","Element","class","style","ActionGroupContextValue","state","ActionGroupContext","ActionGroupStateContext","ActionGroup","props","local","ariaGroupProps","domProps","getKey","getTextValue","getDisabled","groupAriaProps","aria-label","aria-labelledby","actionGroupProps","undefined","defaultClassName","filteredDOMProps","Record","global","_$createComponent","Provider","value","_el$","_$getNextElement","_tmpl$","_$use","el","HTMLDivElement","refFn","ref","HTMLElement","_$spread","_$mergeProps","slot","data-orientation","data-disabled","_$insert","each","ActionGroupItemWrapper","renderChild","rp","_$runHydrationEvents","ActionGroupItemWrapperProps","buttonProps","focusedKey","has","_ref","restButtonProps","_el$2","_tmpl$2","data-selected","data-focused","useActionGroupContext"],"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":"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"}
|