@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,104 @@
|
|
|
1
|
+
import { addEventListener, effect, getNextElement, setAttribute, setProperty, style, template, use } from "solid-js/web";
|
|
2
|
+
import { createEffect, createSignal } from "solid-js";
|
|
3
|
+
import { createFormValidation } from "@proyecto-viviana/solidaria";
|
|
4
|
+
//#region src/HiddenTimeInput.tsx
|
|
5
|
+
/**
|
|
6
|
+
* HiddenTimeInput component for solidaria-components
|
|
7
|
+
*
|
|
8
|
+
* A hidden native time input for form submission.
|
|
9
|
+
*/
|
|
10
|
+
var _tmpl$ = /*#__PURE__*/ template(`<input tabindex=-1 aria-hidden=true>`);
|
|
11
|
+
function accessValue(value) {
|
|
12
|
+
return typeof value === "function" ? value() : value;
|
|
13
|
+
}
|
|
14
|
+
function formatTimeValue(value, granularity) {
|
|
15
|
+
if (!value) return "";
|
|
16
|
+
const hour = String(value.hour).padStart(2, "0");
|
|
17
|
+
const minute = String(granularity === "hour" ? 0 : value.minute).padStart(2, "0");
|
|
18
|
+
if (granularity === "second") return `${hour}:${minute}:${String(value.second).padStart(2, "0")}`;
|
|
19
|
+
return `${hour}:${minute}`;
|
|
20
|
+
}
|
|
21
|
+
function stepForGranularity(granularity) {
|
|
22
|
+
switch (granularity) {
|
|
23
|
+
case "hour": return 3600;
|
|
24
|
+
case "second": return 1;
|
|
25
|
+
default: return 60;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function HiddenTimeInput(props) {
|
|
29
|
+
const granularity = () => props.granularity ?? "minute";
|
|
30
|
+
const hasValidationBehavior = () => props.validationBehavior != null;
|
|
31
|
+
const validationBehavior = () => props.validationBehavior;
|
|
32
|
+
const usesNativeValidation = () => validationBehavior() === "native";
|
|
33
|
+
const value = () => accessValue(props.value);
|
|
34
|
+
const minValue = () => accessValue(props.minValue);
|
|
35
|
+
const maxValue = () => accessValue(props.maxValue);
|
|
36
|
+
const inputType = () => usesNativeValidation() ? "text" : hasValidationBehavior() ? "hidden" : "time";
|
|
37
|
+
const formattedValue = () => formatTimeValue(value(), granularity());
|
|
38
|
+
const formattedMin = () => formatTimeValue(minValue(), granularity());
|
|
39
|
+
const formattedMax = () => formatTimeValue(maxValue(), granularity());
|
|
40
|
+
const [inputRef, setInputRef] = createSignal();
|
|
41
|
+
if (props.validationState) createFormValidation({
|
|
42
|
+
get validationBehavior() {
|
|
43
|
+
return validationBehavior();
|
|
44
|
+
},
|
|
45
|
+
get focus() {
|
|
46
|
+
return props.focus;
|
|
47
|
+
}
|
|
48
|
+
}, props.validationState, inputRef);
|
|
49
|
+
createEffect(() => {
|
|
50
|
+
const val = formattedValue();
|
|
51
|
+
const input = inputRef();
|
|
52
|
+
if (input && input.value !== val) input.value = val;
|
|
53
|
+
});
|
|
54
|
+
return (() => {
|
|
55
|
+
var _el$ = getNextElement(_tmpl$);
|
|
56
|
+
addEventListener(_el$, "change", usesNativeValidation() ? () => {} : void 0);
|
|
57
|
+
use((el) => {
|
|
58
|
+
setInputRef(el);
|
|
59
|
+
}, _el$);
|
|
60
|
+
effect((_p$) => {
|
|
61
|
+
var _v$ = inputType(), _v$2 = props.name, _v$3 = props.form, _v$4 = props.autoComplete, _v$5 = props.isDisabled, _v$6 = usesNativeValidation() && props.isRequired ? true : void 0, _v$7 = usesNativeValidation() || void 0, _v$8 = hasValidationBehavior() ? void 0 : formattedMin() || void 0, _v$9 = hasValidationBehavior() ? void 0 : formattedMax() || void 0, _v$0 = hasValidationBehavior() ? void 0 : stepForGranularity(granularity()), _v$1 = {
|
|
62
|
+
position: "absolute",
|
|
63
|
+
width: "1px",
|
|
64
|
+
height: "1px",
|
|
65
|
+
padding: "0",
|
|
66
|
+
margin: "-1px",
|
|
67
|
+
overflow: "hidden",
|
|
68
|
+
clip: "rect(0, 0, 0, 0)",
|
|
69
|
+
"white-space": "nowrap",
|
|
70
|
+
"border-width": "0"
|
|
71
|
+
};
|
|
72
|
+
_v$ !== _p$.e && setAttribute(_el$, "type", _p$.e = _v$);
|
|
73
|
+
_v$2 !== _p$.t && setAttribute(_el$, "name", _p$.t = _v$2);
|
|
74
|
+
_v$3 !== _p$.a && setAttribute(_el$, "form", _p$.a = _v$3);
|
|
75
|
+
_v$4 !== _p$.o && setAttribute(_el$, "autocomplete", _p$.o = _v$4);
|
|
76
|
+
_v$5 !== _p$.i && setProperty(_el$, "disabled", _p$.i = _v$5);
|
|
77
|
+
_v$6 !== _p$.n && setProperty(_el$, "required", _p$.n = _v$6);
|
|
78
|
+
_v$7 !== _p$.s && setProperty(_el$, "hidden", _p$.s = _v$7);
|
|
79
|
+
_v$8 !== _p$.h && setAttribute(_el$, "min", _p$.h = _v$8);
|
|
80
|
+
_v$9 !== _p$.r && setAttribute(_el$, "max", _p$.r = _v$9);
|
|
81
|
+
_v$0 !== _p$.d && setAttribute(_el$, "step", _p$.d = _v$0);
|
|
82
|
+
_p$.l = style(_el$, _v$1, _p$.l);
|
|
83
|
+
return _p$;
|
|
84
|
+
}, {
|
|
85
|
+
e: void 0,
|
|
86
|
+
t: void 0,
|
|
87
|
+
a: void 0,
|
|
88
|
+
o: void 0,
|
|
89
|
+
i: void 0,
|
|
90
|
+
n: void 0,
|
|
91
|
+
s: void 0,
|
|
92
|
+
h: void 0,
|
|
93
|
+
r: void 0,
|
|
94
|
+
d: void 0,
|
|
95
|
+
l: void 0
|
|
96
|
+
});
|
|
97
|
+
effect(() => setProperty(_el$, "value", formattedValue()));
|
|
98
|
+
return _el$;
|
|
99
|
+
})();
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
export { HiddenTimeInput };
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=HiddenTimeInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HiddenTimeInput.js","names":["JSX","createEffect","createSignal","FormValidationState","TimeValue","createFormValidation","MaybeAccessor","T","HiddenTimeInputProps","name","form","value","autoComplete","isDisabled","isRequired","validationBehavior","validationState","focus","minValue","maxValue","granularity","accessValue","formatTimeValue","hour","String","padStart","minute","second","stepForGranularity","HiddenTimeInput","props","Element","hasValidationBehavior","usesNativeValidation","inputType","formattedValue","formattedMin","formattedMax","inputRef","setInputRef","HTMLInputElement","val","input","_el$","_$getNextElement","_tmpl$","_$addEventListener","undefined","_$use","el","_$effect","_p$","_v$","_v$2","_v$3","_v$4","_v$5","_v$6","_v$7","_v$8","_v$9","_v$0","_v$1","position","width","height","padding","margin","overflow","clip","CSSProperties","e","_$setAttribute","t","a","o","i","_$setProperty","n","s","h","r","d","l","_$style"],"sources":["../src/HiddenTimeInput.tsx"],"sourcesContent":["/**\n * HiddenTimeInput component for solidaria-components\n *\n * A hidden native time input for form submission.\n */\nimport { type JSX, createEffect, createSignal } from \"solid-js\";\nimport { type FormValidationState, type TimeValue } from \"@proyecto-viviana/solid-stately\";\nimport { createFormValidation } from \"@proyecto-viviana/solidaria\";\n\ntype MaybeAccessor<T> = T | (() => T);\n\nexport interface HiddenTimeInputProps {\n name?: string;\n form?: string;\n value?: MaybeAccessor<TimeValue | null | undefined>;\n autoComplete?: string;\n isDisabled?: boolean;\n isRequired?: boolean;\n validationBehavior?: \"aria\" | \"native\";\n validationState?: FormValidationState;\n focus?: () => void;\n minValue?: MaybeAccessor<TimeValue | undefined>;\n maxValue?: MaybeAccessor<TimeValue | undefined>;\n granularity?: \"hour\" | \"minute\" | \"second\";\n}\n\nfunction accessValue<T>(value: MaybeAccessor<T> | undefined): T | undefined {\n return typeof value === \"function\" ? (value as () => T)() : value;\n}\n\nfunction formatTimeValue(\n value: TimeValue | undefined | null,\n granularity: \"hour\" | \"minute\" | \"second\",\n): string {\n if (!value) return \"\";\n\n const hour = String(value.hour).padStart(2, \"0\");\n const minute = String(granularity === \"hour\" ? 0 : value.minute).padStart(2, \"0\");\n\n if (granularity === \"second\") {\n const second = String(value.second).padStart(2, \"0\");\n return `${hour}:${minute}:${second}`;\n }\n\n return `${hour}:${minute}`;\n}\n\nfunction stepForGranularity(granularity: \"hour\" | \"minute\" | \"second\"): number {\n switch (granularity) {\n case \"hour\":\n return 3600;\n case \"second\":\n return 1;\n case \"minute\":\n default:\n return 60;\n }\n}\n\nexport function HiddenTimeInput(props: HiddenTimeInputProps): JSX.Element {\n const granularity = () => props.granularity ?? \"minute\";\n const hasValidationBehavior = () => props.validationBehavior != null;\n const validationBehavior = () => props.validationBehavior;\n const usesNativeValidation = () => validationBehavior() === \"native\";\n const value = () => accessValue(props.value);\n const minValue = () => accessValue(props.minValue);\n const maxValue = () => accessValue(props.maxValue);\n const inputType = () =>\n usesNativeValidation() ? \"text\" : hasValidationBehavior() ? \"hidden\" : \"time\";\n const formattedValue = () => formatTimeValue(value(), granularity());\n const formattedMin = () => formatTimeValue(minValue(), granularity());\n const formattedMax = () => formatTimeValue(maxValue(), granularity());\n\n const [inputRef, setInputRef] = createSignal<HTMLInputElement>();\n\n if (props.validationState) {\n createFormValidation(\n {\n get validationBehavior() {\n return validationBehavior();\n },\n get focus() {\n return props.focus;\n },\n },\n props.validationState,\n inputRef,\n );\n }\n\n createEffect(() => {\n const val = formattedValue();\n const input = inputRef();\n if (input && input.value !== val) {\n input.value = val;\n }\n });\n\n return (\n <input\n ref={(el) => {\n setInputRef(el);\n }}\n type={inputType()}\n name={props.name}\n form={props.form}\n value={formattedValue()}\n autocomplete={props.autoComplete}\n disabled={props.isDisabled}\n required={usesNativeValidation() && props.isRequired ? true : undefined}\n hidden={usesNativeValidation() || undefined}\n min={hasValidationBehavior() ? undefined : formattedMin() || undefined}\n max={hasValidationBehavior() ? undefined : formattedMax() || undefined}\n step={hasValidationBehavior() ? undefined : stepForGranularity(granularity())}\n onChange={usesNativeValidation() ? () => {} : undefined}\n tabIndex={-1}\n aria-hidden=\"true\"\n style={\n {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n padding: \"0\",\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n \"white-space\": \"nowrap\",\n \"border-width\": \"0\",\n } as JSX.CSSProperties\n }\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createEffect, createSignal } from "solid-js";
|
|
2
|
+
import { createFormValidation } from "@proyecto-viviana/solidaria";
|
|
3
|
+
//#region src/HiddenTimeInput.tsx
|
|
4
|
+
/**
|
|
5
|
+
* HiddenTimeInput component for solidaria-components
|
|
6
|
+
*
|
|
7
|
+
* A hidden native time input for form submission.
|
|
8
|
+
*/
|
|
9
|
+
function accessValue(value) {
|
|
10
|
+
return typeof value === "function" ? value() : value;
|
|
11
|
+
}
|
|
12
|
+
function formatTimeValue(value, granularity) {
|
|
13
|
+
if (!value) return "";
|
|
14
|
+
const hour = String(value.hour).padStart(2, "0");
|
|
15
|
+
const minute = String(granularity === "hour" ? 0 : value.minute).padStart(2, "0");
|
|
16
|
+
if (granularity === "second") return `${hour}:${minute}:${String(value.second).padStart(2, "0")}`;
|
|
17
|
+
return `${hour}:${minute}`;
|
|
18
|
+
}
|
|
19
|
+
function stepForGranularity(granularity) {
|
|
20
|
+
switch (granularity) {
|
|
21
|
+
case "hour": return 3600;
|
|
22
|
+
case "second": return 1;
|
|
23
|
+
default: return 60;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function HiddenTimeInput(props) {
|
|
27
|
+
const granularity = () => props.granularity ?? "minute";
|
|
28
|
+
const hasValidationBehavior = () => props.validationBehavior != null;
|
|
29
|
+
const validationBehavior = () => props.validationBehavior;
|
|
30
|
+
const usesNativeValidation = () => validationBehavior() === "native";
|
|
31
|
+
const value = () => accessValue(props.value);
|
|
32
|
+
const minValue = () => accessValue(props.minValue);
|
|
33
|
+
const maxValue = () => accessValue(props.maxValue);
|
|
34
|
+
const inputType = () => usesNativeValidation() ? "text" : hasValidationBehavior() ? "hidden" : "time";
|
|
35
|
+
const formattedValue = () => formatTimeValue(value(), granularity());
|
|
36
|
+
const formattedMin = () => formatTimeValue(minValue(), granularity());
|
|
37
|
+
const formattedMax = () => formatTimeValue(maxValue(), granularity());
|
|
38
|
+
const [inputRef, setInputRef] = createSignal();
|
|
39
|
+
if (props.validationState) createFormValidation({
|
|
40
|
+
get validationBehavior() {
|
|
41
|
+
return validationBehavior();
|
|
42
|
+
},
|
|
43
|
+
get focus() {
|
|
44
|
+
return props.focus;
|
|
45
|
+
}
|
|
46
|
+
}, props.validationState, inputRef);
|
|
47
|
+
createEffect(() => {
|
|
48
|
+
const val = formattedValue();
|
|
49
|
+
const input = inputRef();
|
|
50
|
+
if (input && input.value !== val) input.value = val;
|
|
51
|
+
});
|
|
52
|
+
return <input ref={(el) => {
|
|
53
|
+
setInputRef(el);
|
|
54
|
+
}} type={inputType()} name={props.name} form={props.form} value={formattedValue()} autocomplete={props.autoComplete} disabled={props.isDisabled} required={usesNativeValidation() && props.isRequired ? true : void 0} hidden={usesNativeValidation() || void 0} min={hasValidationBehavior() ? void 0 : formattedMin() || void 0} max={hasValidationBehavior() ? void 0 : formattedMax() || void 0} step={hasValidationBehavior() ? void 0 : stepForGranularity(granularity())} onChange={usesNativeValidation() ? () => {} : void 0} tabIndex={-1} aria-hidden="true" style={{
|
|
55
|
+
position: "absolute",
|
|
56
|
+
width: "1px",
|
|
57
|
+
height: "1px",
|
|
58
|
+
padding: "0",
|
|
59
|
+
margin: "-1px",
|
|
60
|
+
overflow: "hidden",
|
|
61
|
+
clip: "rect(0, 0, 0, 0)",
|
|
62
|
+
"white-space": "nowrap",
|
|
63
|
+
"border-width": "0"
|
|
64
|
+
}} />;
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { HiddenTimeInput };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=HiddenTimeInput.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HiddenTimeInput.jsx","names":[],"sources":["../src/HiddenTimeInput.tsx"],"sourcesContent":["/**\n * HiddenTimeInput component for solidaria-components\n *\n * A hidden native time input for form submission.\n */\nimport { type JSX, createEffect, createSignal } from \"solid-js\";\nimport { type FormValidationState, type TimeValue } from \"@proyecto-viviana/solid-stately\";\nimport { createFormValidation } from \"@proyecto-viviana/solidaria\";\n\ntype MaybeAccessor<T> = T | (() => T);\n\nexport interface HiddenTimeInputProps {\n name?: string;\n form?: string;\n value?: MaybeAccessor<TimeValue | null | undefined>;\n autoComplete?: string;\n isDisabled?: boolean;\n isRequired?: boolean;\n validationBehavior?: \"aria\" | \"native\";\n validationState?: FormValidationState;\n focus?: () => void;\n minValue?: MaybeAccessor<TimeValue | undefined>;\n maxValue?: MaybeAccessor<TimeValue | undefined>;\n granularity?: \"hour\" | \"minute\" | \"second\";\n}\n\nfunction accessValue<T>(value: MaybeAccessor<T> | undefined): T | undefined {\n return typeof value === \"function\" ? (value as () => T)() : value;\n}\n\nfunction formatTimeValue(\n value: TimeValue | undefined | null,\n granularity: \"hour\" | \"minute\" | \"second\",\n): string {\n if (!value) return \"\";\n\n const hour = String(value.hour).padStart(2, \"0\");\n const minute = String(granularity === \"hour\" ? 0 : value.minute).padStart(2, \"0\");\n\n if (granularity === \"second\") {\n const second = String(value.second).padStart(2, \"0\");\n return `${hour}:${minute}:${second}`;\n }\n\n return `${hour}:${minute}`;\n}\n\nfunction stepForGranularity(granularity: \"hour\" | \"minute\" | \"second\"): number {\n switch (granularity) {\n case \"hour\":\n return 3600;\n case \"second\":\n return 1;\n case \"minute\":\n default:\n return 60;\n }\n}\n\nexport function HiddenTimeInput(props: HiddenTimeInputProps): JSX.Element {\n const granularity = () => props.granularity ?? \"minute\";\n const hasValidationBehavior = () => props.validationBehavior != null;\n const validationBehavior = () => props.validationBehavior;\n const usesNativeValidation = () => validationBehavior() === \"native\";\n const value = () => accessValue(props.value);\n const minValue = () => accessValue(props.minValue);\n const maxValue = () => accessValue(props.maxValue);\n const inputType = () =>\n usesNativeValidation() ? \"text\" : hasValidationBehavior() ? \"hidden\" : \"time\";\n const formattedValue = () => formatTimeValue(value(), granularity());\n const formattedMin = () => formatTimeValue(minValue(), granularity());\n const formattedMax = () => formatTimeValue(maxValue(), granularity());\n\n const [inputRef, setInputRef] = createSignal<HTMLInputElement>();\n\n if (props.validationState) {\n createFormValidation(\n {\n get validationBehavior() {\n return validationBehavior();\n },\n get focus() {\n return props.focus;\n },\n },\n props.validationState,\n inputRef,\n );\n }\n\n createEffect(() => {\n const val = formattedValue();\n const input = inputRef();\n if (input && input.value !== val) {\n input.value = val;\n }\n });\n\n return (\n <input\n ref={(el) => {\n setInputRef(el);\n }}\n type={inputType()}\n name={props.name}\n form={props.form}\n value={formattedValue()}\n autocomplete={props.autoComplete}\n disabled={props.isDisabled}\n required={usesNativeValidation() && props.isRequired ? true : undefined}\n hidden={usesNativeValidation() || undefined}\n min={hasValidationBehavior() ? undefined : formattedMin() || undefined}\n max={hasValidationBehavior() ? undefined : formattedMax() || undefined}\n step={hasValidationBehavior() ? undefined : stepForGranularity(granularity())}\n onChange={usesNativeValidation() ? () => {} : undefined}\n tabIndex={-1}\n aria-hidden=\"true\"\n style={\n {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n padding: \"0\",\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n \"white-space\": \"nowrap\",\n \"border-width\": \"0\",\n } as JSX.CSSProperties\n }\n />\n );\n}\n"],"mappings":";;;;;;;;AA0BA,SAAS,YAAe,OAAoD;CAC1E,OAAO,OAAO,UAAU,aAAc,MAAkB,IAAI;AAC9D;AAEA,SAAS,gBACP,OACA,aACQ;CACR,IAAI,CAAC,OAAO,OAAO;CAEnB,MAAM,OAAO,OAAO,MAAM,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;CAC/C,MAAM,SAAS,OAAO,gBAAgB,SAAS,IAAI,MAAM,MAAM,CAAC,CAAC,SAAS,GAAG,GAAG;CAEhF,IAAI,gBAAgB,UAElB,OAAO,GAAG,KAAK,GAAG,OAAO,GADV,OAAO,MAAM,MAAM,CAAC,CAAC,SAAS,GAAG,GACf;CAGnC,OAAO,GAAG,KAAK,GAAG;AACpB;AAEA,SAAS,mBAAmB,aAAmD;CAC7E,QAAQ,aAAR;EACE,KAAK,QACH,OAAO;EACT,KAAK,UACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAgB,gBAAgB,OAA0C;CACxE,MAAM,oBAAoB,MAAM,eAAe;CAC/C,MAAM,8BAA8B,MAAM,sBAAsB;CAChE,MAAM,2BAA2B,MAAM;CACvC,MAAM,6BAA6B,mBAAmB,MAAM;CAC5D,MAAM,cAAc,YAAY,MAAM,KAAK;CAC3C,MAAM,iBAAiB,YAAY,MAAM,QAAQ;CACjD,MAAM,iBAAiB,YAAY,MAAM,QAAQ;CACjD,MAAM,kBACJ,qBAAqB,IAAI,SAAS,sBAAsB,IAAI,WAAW;CACzE,MAAM,uBAAuB,gBAAgB,MAAM,GAAG,YAAY,CAAC;CACnE,MAAM,qBAAqB,gBAAgB,SAAS,GAAG,YAAY,CAAC;CACpE,MAAM,qBAAqB,gBAAgB,SAAS,GAAG,YAAY,CAAC;CAEpE,MAAM,CAAC,UAAU,eAAe,aAA+B;CAE/D,IAAI,MAAM,iBACR,qBACE;EACE,IAAI,qBAAqB;GACvB,OAAO,mBAAmB;EAC5B;EACA,IAAI,QAAQ;GACV,OAAO,MAAM;EACf;CACF,GACA,MAAM,iBACN,QACF;CAGF,mBAAmB;EACjB,MAAM,MAAM,eAAe;EAC3B,MAAM,QAAQ,SAAS;EACvB,IAAI,SAAS,MAAM,UAAU,KAC3B,MAAM,QAAQ;CAElB,CAAC;CAED,OACE,CAAC,MACC,MAAM,OAAO;EACX,YAAY,EAAE;CAChB,GACA,MAAM,UAAU,GAChB,MAAM,MAAM,MACZ,MAAM,MAAM,MACZ,OAAO,eAAe,GACtB,cAAc,MAAM,cACpB,UAAU,MAAM,YAChB,UAAU,qBAAqB,KAAK,MAAM,aAAa,OAAO,KAAA,GAC9D,QAAQ,qBAAqB,KAAK,KAAA,GAClC,KAAK,sBAAsB,IAAI,KAAA,IAAY,aAAa,KAAK,KAAA,GAC7D,KAAK,sBAAsB,IAAI,KAAA,IAAY,aAAa,KAAK,KAAA,GAC7D,MAAM,sBAAsB,IAAI,KAAA,IAAY,mBAAmB,YAAY,CAAC,GAC5E,UAAU,qBAAqB,UAAU,CAAC,IAAI,KAAA,GAC9C,UAAU,IACV,mBACA,OACE;EACE,UAAU;EACV,OAAO;EACP,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,UAAU;EACV,MAAM;EACN,eAAe;EACf,gBAAgB;CAClB;AAIR"}
|
package/dist/Icon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../src/Icon.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,GAAG,EAA+C,MAAM,UAAU,CAAC;AACjF,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,SAAS,EAGf,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,YAAY,EAAE,OAAO,CAAC;IACtB,qDAAqD;IACrD,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yFAAyF;IACzF,QAAQ,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAC3C,yCAAyC;IACzC,KAAK,CAAC,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IAC7C,wCAAwC;IACxC,KAAK,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IACzC,6BAA6B;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,WAAW,8CAAwC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../src/Icon.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,GAAG,EAA+C,MAAM,UAAU,CAAC;AACjF,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,SAAS,EAGf,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,YAAY,EAAE,OAAO,CAAC;IACtB,qDAAqD;IACrD,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yFAAyF;IACzF,QAAQ,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAC3C,yCAAyC;IACzC,KAAK,CAAC,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IAC7C,wCAAwC;IACxC,KAAK,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IACzC,6BAA6B;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,WAAW,8CAAwC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,OAAO,CAkElD"}
|
package/dist/Icon.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { filterDOMProps, useRenderProps } from "./utils.js";
|
|
2
|
+
import { Button } from "./Button.js";
|
|
3
|
+
import { createComponent, getNextElement, insert, mergeProps, runHydrationEvents, spread, template } from "solid-js/web";
|
|
4
|
+
import { Show, createContext, createMemo, splitProps } from "solid-js";
|
|
5
|
+
//#region src/Icon.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Icon component for solidaria-components
|
|
8
|
+
*
|
|
9
|
+
* Minimal headless Icon that owns ARIA semantics:
|
|
10
|
+
* - Decorative (no label): aria-hidden="true"
|
|
11
|
+
* - Informative (aria-label): role="img" + aria-label
|
|
12
|
+
* - Interactive (onPress): wraps content in headless Button
|
|
13
|
+
*
|
|
14
|
+
* The UI layer consumes this for styling/composition only.
|
|
15
|
+
*/
|
|
16
|
+
var _tmpl$ = /*#__PURE__*/ template(`<span>`);
|
|
17
|
+
const IconContext = createContext(null);
|
|
18
|
+
/**
|
|
19
|
+
* An icon wrapper that provides correct ARIA semantics.
|
|
20
|
+
*
|
|
21
|
+
* - **Decorative** (no `aria-label`): renders `<span aria-hidden="true">`
|
|
22
|
+
* - **Informative** (`aria-label` provided): renders `<span role="img" aria-label="...">`
|
|
23
|
+
* - **Interactive** (`onPress` provided): wraps in headless `Button`
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* // Decorative
|
|
28
|
+
* <Icon><SearchSvg /></Icon>
|
|
29
|
+
*
|
|
30
|
+
* // Informative
|
|
31
|
+
* <Icon aria-label="Search"><SearchSvg /></Icon>
|
|
32
|
+
*
|
|
33
|
+
* // Interactive
|
|
34
|
+
* <Icon onPress={handleSearch} aria-label="Search"><SearchSvg /></Icon>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
function Icon(props) {
|
|
38
|
+
const [local, rest] = splitProps(props, [
|
|
39
|
+
"children",
|
|
40
|
+
"class",
|
|
41
|
+
"style",
|
|
42
|
+
"slot",
|
|
43
|
+
"onPress",
|
|
44
|
+
"aria-label",
|
|
45
|
+
"aria-labelledby"
|
|
46
|
+
]);
|
|
47
|
+
const hasLabel = () => !!(local["aria-label"] || local["aria-labelledby"]);
|
|
48
|
+
const isInteractive = () => !!local.onPress;
|
|
49
|
+
const isDecorative = () => !hasLabel();
|
|
50
|
+
const renderValues = createMemo(() => ({
|
|
51
|
+
isDecorative: isDecorative(),
|
|
52
|
+
isInteractive: isInteractive()
|
|
53
|
+
}));
|
|
54
|
+
const renderProps = useRenderProps({
|
|
55
|
+
get children() {
|
|
56
|
+
return local.children;
|
|
57
|
+
},
|
|
58
|
+
class: local.class,
|
|
59
|
+
style: local.style,
|
|
60
|
+
defaultClassName: "solidaria-Icon"
|
|
61
|
+
}, renderValues);
|
|
62
|
+
const domProps = createMemo(() => filterDOMProps(rest, { global: true }));
|
|
63
|
+
return createComponent(Show, {
|
|
64
|
+
get when() {
|
|
65
|
+
return isInteractive();
|
|
66
|
+
},
|
|
67
|
+
get fallback() {
|
|
68
|
+
return (() => {
|
|
69
|
+
var _el$ = getNextElement(_tmpl$);
|
|
70
|
+
spread(_el$, mergeProps(domProps, {
|
|
71
|
+
get role() {
|
|
72
|
+
return hasLabel() ? "img" : void 0;
|
|
73
|
+
},
|
|
74
|
+
get ["aria-hidden"]() {
|
|
75
|
+
return isDecorative() ? "true" : void 0;
|
|
76
|
+
},
|
|
77
|
+
get ["aria-label"]() {
|
|
78
|
+
return local["aria-label"];
|
|
79
|
+
},
|
|
80
|
+
get ["aria-labelledby"]() {
|
|
81
|
+
return local["aria-labelledby"];
|
|
82
|
+
},
|
|
83
|
+
get ["class"]() {
|
|
84
|
+
return renderProps.class();
|
|
85
|
+
},
|
|
86
|
+
get style() {
|
|
87
|
+
return renderProps.style();
|
|
88
|
+
},
|
|
89
|
+
"data-interactive": void 0,
|
|
90
|
+
get ["data-decorative"]() {
|
|
91
|
+
return isDecorative() || void 0;
|
|
92
|
+
}
|
|
93
|
+
}), false, true);
|
|
94
|
+
insert(_el$, () => renderProps.renderChildren());
|
|
95
|
+
runHydrationEvents();
|
|
96
|
+
return _el$;
|
|
97
|
+
})();
|
|
98
|
+
},
|
|
99
|
+
get children() {
|
|
100
|
+
return createComponent(Button, mergeProps(domProps, {
|
|
101
|
+
get onPress() {
|
|
102
|
+
return local.onPress;
|
|
103
|
+
},
|
|
104
|
+
get ["aria-label"]() {
|
|
105
|
+
return local["aria-label"];
|
|
106
|
+
},
|
|
107
|
+
get ["aria-labelledby"]() {
|
|
108
|
+
return local["aria-labelledby"];
|
|
109
|
+
},
|
|
110
|
+
get ["class"]() {
|
|
111
|
+
return renderProps.class();
|
|
112
|
+
},
|
|
113
|
+
get style() {
|
|
114
|
+
return renderProps.style();
|
|
115
|
+
},
|
|
116
|
+
"data-interactive": "",
|
|
117
|
+
get children() {
|
|
118
|
+
return renderProps.renderChildren();
|
|
119
|
+
}
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
export { Icon, IconContext };
|
|
126
|
+
|
|
127
|
+
//# sourceMappingURL=Icon.js.map
|
package/dist/Icon.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Icon.js","names":["JSX","createContext","createMemo","Show","splitProps","RenderChildren","ClassNameOrFunction","StyleOrFunction","SlotProps","useRenderProps","filterDOMProps","Button","PressEvent","IconRenderProps","isDecorative","isInteractive","IconProps","onPress","e","children","class","style","id","IconContext","Icon","props","Element","local","rest","hasLabel","renderValues","renderProps","defaultClassName","domProps","global","_$createComponent","when","fallback","_el$","_$getNextElement","_tmpl$","_$spread","_$mergeProps","role","undefined","aria-hidden","aria-label","aria-labelledby","data-decorative","_$insert","renderChildren","_$runHydrationEvents"],"sources":["../src/Icon.tsx"],"sourcesContent":["/**\n * Icon component for solidaria-components\n *\n * Minimal headless Icon that owns ARIA semantics:\n * - Decorative (no label): aria-hidden=\"true\"\n * - Informative (aria-label): role=\"img\" + aria-label\n * - Interactive (onPress): wraps content in headless Button\n *\n * The UI layer consumes this for styling/composition only.\n */\n\nimport { type JSX, createContext, createMemo, Show, splitProps } from \"solid-js\";\nimport {\n type RenderChildren,\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\nimport { Button } from \"./Button\";\nimport type { PressEvent } from \"@proyecto-viviana/solidaria\";\n\nexport interface IconRenderProps {\n /** Whether the icon is purely decorative (no label). */\n isDecorative: boolean;\n /** Whether the icon is interactive (has onPress). */\n isInteractive: boolean;\n}\n\nexport interface IconProps extends SlotProps {\n /** Handler called when the icon is pressed (makes it interactive). */\n onPress?: (e: PressEvent) => void;\n /** Accessible label for the icon. When provided, the icon is informative (role=\"img\"). */\n \"aria-label\"?: string;\n /** ID of an element that labels this icon. */\n \"aria-labelledby\"?: string;\n /** The children of the component. A function may be provided to receive render props. */\n children?: RenderChildren<IconRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<IconRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<IconRenderProps>;\n /** The id of the element. */\n id?: string;\n}\n\nexport const IconContext = createContext<IconProps | null>(null);\n\n/**\n * An icon wrapper that provides correct ARIA semantics.\n *\n * - **Decorative** (no `aria-label`): renders `<span aria-hidden=\"true\">`\n * - **Informative** (`aria-label` provided): renders `<span role=\"img\" aria-label=\"...\">`\n * - **Interactive** (`onPress` provided): wraps in headless `Button`\n *\n * @example\n * ```tsx\n * // Decorative\n * <Icon><SearchSvg /></Icon>\n *\n * // Informative\n * <Icon aria-label=\"Search\"><SearchSvg /></Icon>\n *\n * // Interactive\n * <Icon onPress={handleSearch} aria-label=\"Search\"><SearchSvg /></Icon>\n * ```\n */\nexport function Icon(props: IconProps): JSX.Element {\n const [local, rest] = splitProps(props, [\n \"children\",\n \"class\",\n \"style\",\n \"slot\",\n \"onPress\",\n \"aria-label\",\n \"aria-labelledby\",\n ]);\n\n const hasLabel = () => !!(local[\"aria-label\"] || local[\"aria-labelledby\"]);\n const isInteractive = () => !!local.onPress;\n const isDecorative = () => !hasLabel();\n\n const renderValues = createMemo<IconRenderProps>(() => ({\n isDecorative: isDecorative(),\n isInteractive: isInteractive(),\n }));\n\n const renderProps = useRenderProps(\n {\n get children() {\n return local.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Icon\",\n },\n renderValues,\n );\n\n const domProps = createMemo(() => filterDOMProps(rest, { global: true }));\n\n return (\n <Show\n when={isInteractive()}\n fallback={\n <span\n {...domProps()}\n role={hasLabel() ? \"img\" : undefined}\n aria-hidden={isDecorative() ? \"true\" : undefined}\n aria-label={local[\"aria-label\"]}\n aria-labelledby={local[\"aria-labelledby\"]}\n class={renderProps.class()}\n style={renderProps.style()}\n data-interactive={undefined}\n data-decorative={isDecorative() || undefined}\n >\n {renderProps.renderChildren()}\n </span>\n }\n >\n <Button\n {...domProps()}\n onPress={local.onPress}\n aria-label={local[\"aria-label\"]}\n aria-labelledby={local[\"aria-labelledby\"]}\n class={renderProps.class()}\n style={renderProps.style()}\n data-interactive=\"\"\n >\n {renderProps.renderChildren()}\n </Button>\n </Show>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA+CA,MAAauB,cAActB,cAAgC,IAAI;;;;;;;;;;;;;;;;;;;;AAqB/D,SAAgBuB,KAAKC,OAA+B;CAClD,MAAM,CAACE,OAAOC,QAAQxB,WAAWqB,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;CAAiB,CAClB;CAED,MAAMI,iBAAiB,CAAC,EAAEF,MAAM,iBAAiBA,MAAM;CACvD,MAAMZ,sBAAsB,CAAC,CAACY,MAAMV;CACpC,MAAMH,qBAAqB,CAACe,SAAS;CAErC,MAAMC,eAAe5B,kBAAmC;EACtDY,cAAcA,aAAa;EAC3BC,eAAeA,cAAc;CAC/B,EAAE;CAEF,MAAMgB,cAActB,eAClB;EACE,IAAIU,WAAW;GACb,OAAOQ,MAAMR;EACf;EACAC,OAAOO,MAAMP;EACbC,OAAOM,MAAMN;EACbW,kBAAkB;CACpB,GACAF,YACF;CAEA,MAAMG,WAAW/B,iBAAiBQ,eAAekB,MAAM,EAAEM,QAAQ,KAAK,CAAC,CAAC;CAExE,OAAAC,gBACGhC,MAAI;EAAA,IACHiC,OAAI;GAAA,OAAErB,cAAc;EAAC;EAAA,IACrBsB,WAAQ;GAAA,cAAA;IAAA,IAAAC,OAAAC,eAAAC,MAAA;IAAAC,OAAAH,MAAAI,WAEAT,UAAQ;KAAA,IACZU,OAAI;MAAA,OAAEd,SAAS,IAAI,QAAQe,KAAAA;KAAS;KAAA,KAAA,iBAAA;MAAA,OACvB9B,aAAa,IAAI,SAAS8B,KAAAA;KAAS;KAAA,KAAA,gBAAA;MAAA,OACpCjB,MAAM;KAAa;KAAA,KAAA,qBAAA;MAAA,OACdA,MAAM;KAAkB;KAAA,KAAA,WAAA;MAAA,OAClCI,YAAYX,MAAM;KAAC;KAAA,IAC1BC,QAAK;MAAA,OAAEU,YAAYV,MAAM;KAAC;KAAA,oBACRuB,KAAAA;KAAS,KAAA,qBAAA;MAAA,OACV9B,aAAa,KAAK8B,KAAAA;KAAS;IAAA,CAAA,GAAA,OAAA,IAAA;IAAAK,OAAAX,YAE3CP,YAAYmB,eAAe,CAAC;IAAAC,mBAAA;IAAA,OAAAb;GAAA,EAAA,CAAA;EAAA;EAAA,IAAAnB,WAAA;GAAA,OAAAgB,gBAIhCxB,QAAM+B,WACDT,UAAQ;IAAA,IACZhB,UAAO;KAAA,OAAEU,MAAMV;IAAO;IAAA,KAAA,gBAAA;KAAA,OACVU,MAAM;IAAa;IAAA,KAAA,qBAAA;KAAA,OACdA,MAAM;IAAkB;IAAA,KAAA,WAAA;KAAA,OAClCI,YAAYX,MAAM;IAAC;IAAA,IAC1BC,QAAK;KAAA,OAAEU,YAAYV,MAAM;IAAC;IAAA,oBAAA;IAAA,IAAAF,WAAA;KAAA,OAGzBY,YAAYmB,eAAe;IAAC;GAAA,CAAA,CAAA;EAAA;CAAA,CAAA;AAIrC"}
|
package/dist/Icon.jsx
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { filterDOMProps, useRenderProps } from "./utils.jsx";
|
|
2
|
+
import { Button } from "./Button.jsx";
|
|
3
|
+
import { Show, createContext, createMemo, splitProps } from "solid-js";
|
|
4
|
+
//#region src/Icon.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Icon component for solidaria-components
|
|
7
|
+
*
|
|
8
|
+
* Minimal headless Icon that owns ARIA semantics:
|
|
9
|
+
* - Decorative (no label): aria-hidden="true"
|
|
10
|
+
* - Informative (aria-label): role="img" + aria-label
|
|
11
|
+
* - Interactive (onPress): wraps content in headless Button
|
|
12
|
+
*
|
|
13
|
+
* The UI layer consumes this for styling/composition only.
|
|
14
|
+
*/
|
|
15
|
+
const IconContext = createContext(null);
|
|
16
|
+
/**
|
|
17
|
+
* An icon wrapper that provides correct ARIA semantics.
|
|
18
|
+
*
|
|
19
|
+
* - **Decorative** (no `aria-label`): renders `<span aria-hidden="true">`
|
|
20
|
+
* - **Informative** (`aria-label` provided): renders `<span role="img" aria-label="...">`
|
|
21
|
+
* - **Interactive** (`onPress` provided): wraps in headless `Button`
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* // Decorative
|
|
26
|
+
* <Icon><SearchSvg /></Icon>
|
|
27
|
+
*
|
|
28
|
+
* // Informative
|
|
29
|
+
* <Icon aria-label="Search"><SearchSvg /></Icon>
|
|
30
|
+
*
|
|
31
|
+
* // Interactive
|
|
32
|
+
* <Icon onPress={handleSearch} aria-label="Search"><SearchSvg /></Icon>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function Icon(props) {
|
|
36
|
+
const [local, rest] = splitProps(props, [
|
|
37
|
+
"children",
|
|
38
|
+
"class",
|
|
39
|
+
"style",
|
|
40
|
+
"slot",
|
|
41
|
+
"onPress",
|
|
42
|
+
"aria-label",
|
|
43
|
+
"aria-labelledby"
|
|
44
|
+
]);
|
|
45
|
+
const hasLabel = () => !!(local["aria-label"] || local["aria-labelledby"]);
|
|
46
|
+
const isInteractive = () => !!local.onPress;
|
|
47
|
+
const isDecorative = () => !hasLabel();
|
|
48
|
+
const renderValues = createMemo(() => ({
|
|
49
|
+
isDecorative: isDecorative(),
|
|
50
|
+
isInteractive: isInteractive()
|
|
51
|
+
}));
|
|
52
|
+
const renderProps = useRenderProps({
|
|
53
|
+
get children() {
|
|
54
|
+
return local.children;
|
|
55
|
+
},
|
|
56
|
+
class: local.class,
|
|
57
|
+
style: local.style,
|
|
58
|
+
defaultClassName: "solidaria-Icon"
|
|
59
|
+
}, renderValues);
|
|
60
|
+
const domProps = createMemo(() => filterDOMProps(rest, { global: true }));
|
|
61
|
+
return <Show when={isInteractive()} fallback={<span {...domProps()} role={hasLabel() ? "img" : void 0} aria-hidden={isDecorative() ? "true" : void 0} aria-label={local["aria-label"]} aria-labelledby={local["aria-labelledby"]} class={renderProps.class()} style={renderProps.style()} data-interactive={void 0} data-decorative={isDecorative() || void 0}>
|
|
62
|
+
{renderProps.renderChildren()}
|
|
63
|
+
</span>}>
|
|
64
|
+
<Button {...domProps()} onPress={local.onPress} aria-label={local["aria-label"]} aria-labelledby={local["aria-labelledby"]} class={renderProps.class()} style={renderProps.style()} data-interactive="">
|
|
65
|
+
{renderProps.renderChildren()}
|
|
66
|
+
</Button>
|
|
67
|
+
</Show>;
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
export { Icon, IconContext };
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=Icon.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Icon.jsx","names":[],"sources":["../src/Icon.tsx"],"sourcesContent":["/**\n * Icon component for solidaria-components\n *\n * Minimal headless Icon that owns ARIA semantics:\n * - Decorative (no label): aria-hidden=\"true\"\n * - Informative (aria-label): role=\"img\" + aria-label\n * - Interactive (onPress): wraps content in headless Button\n *\n * The UI layer consumes this for styling/composition only.\n */\n\nimport { type JSX, createContext, createMemo, Show, splitProps } from \"solid-js\";\nimport {\n type RenderChildren,\n type ClassNameOrFunction,\n type StyleOrFunction,\n type SlotProps,\n useRenderProps,\n filterDOMProps,\n} from \"./utils\";\nimport { Button } from \"./Button\";\nimport type { PressEvent } from \"@proyecto-viviana/solidaria\";\n\nexport interface IconRenderProps {\n /** Whether the icon is purely decorative (no label). */\n isDecorative: boolean;\n /** Whether the icon is interactive (has onPress). */\n isInteractive: boolean;\n}\n\nexport interface IconProps extends SlotProps {\n /** Handler called when the icon is pressed (makes it interactive). */\n onPress?: (e: PressEvent) => void;\n /** Accessible label for the icon. When provided, the icon is informative (role=\"img\"). */\n \"aria-label\"?: string;\n /** ID of an element that labels this icon. */\n \"aria-labelledby\"?: string;\n /** The children of the component. A function may be provided to receive render props. */\n children?: RenderChildren<IconRenderProps>;\n /** The CSS className for the element. */\n class?: ClassNameOrFunction<IconRenderProps>;\n /** The inline style for the element. */\n style?: StyleOrFunction<IconRenderProps>;\n /** The id of the element. */\n id?: string;\n}\n\nexport const IconContext = createContext<IconProps | null>(null);\n\n/**\n * An icon wrapper that provides correct ARIA semantics.\n *\n * - **Decorative** (no `aria-label`): renders `<span aria-hidden=\"true\">`\n * - **Informative** (`aria-label` provided): renders `<span role=\"img\" aria-label=\"...\">`\n * - **Interactive** (`onPress` provided): wraps in headless `Button`\n *\n * @example\n * ```tsx\n * // Decorative\n * <Icon><SearchSvg /></Icon>\n *\n * // Informative\n * <Icon aria-label=\"Search\"><SearchSvg /></Icon>\n *\n * // Interactive\n * <Icon onPress={handleSearch} aria-label=\"Search\"><SearchSvg /></Icon>\n * ```\n */\nexport function Icon(props: IconProps): JSX.Element {\n const [local, rest] = splitProps(props, [\n \"children\",\n \"class\",\n \"style\",\n \"slot\",\n \"onPress\",\n \"aria-label\",\n \"aria-labelledby\",\n ]);\n\n const hasLabel = () => !!(local[\"aria-label\"] || local[\"aria-labelledby\"]);\n const isInteractive = () => !!local.onPress;\n const isDecorative = () => !hasLabel();\n\n const renderValues = createMemo<IconRenderProps>(() => ({\n isDecorative: isDecorative(),\n isInteractive: isInteractive(),\n }));\n\n const renderProps = useRenderProps(\n {\n get children() {\n return local.children;\n },\n class: local.class,\n style: local.style,\n defaultClassName: \"solidaria-Icon\",\n },\n renderValues,\n );\n\n const domProps = createMemo(() => filterDOMProps(rest, { global: true }));\n\n return (\n <Show\n when={isInteractive()}\n fallback={\n <span\n {...domProps()}\n role={hasLabel() ? \"img\" : undefined}\n aria-hidden={isDecorative() ? \"true\" : undefined}\n aria-label={local[\"aria-label\"]}\n aria-labelledby={local[\"aria-labelledby\"]}\n class={renderProps.class()}\n style={renderProps.style()}\n data-interactive={undefined}\n data-decorative={isDecorative() || undefined}\n >\n {renderProps.renderChildren()}\n </span>\n }\n >\n <Button\n {...domProps()}\n onPress={local.onPress}\n aria-label={local[\"aria-label\"]}\n aria-labelledby={local[\"aria-labelledby\"]}\n class={renderProps.class()}\n style={renderProps.style()}\n data-interactive=\"\"\n >\n {renderProps.renderChildren()}\n </Button>\n </Show>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AA+CA,MAAa,cAAc,cAAgC,IAAI;;;;;;;;;;;;;;;;;;;;AAqB/D,SAAgB,KAAK,OAA+B;CAClD,MAAM,CAAC,OAAO,QAAQ,WAAW,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,iBAAiB,CAAC,EAAE,MAAM,iBAAiB,MAAM;CACvD,MAAM,sBAAsB,CAAC,CAAC,MAAM;CACpC,MAAM,qBAAqB,CAAC,SAAS;CAErC,MAAM,eAAe,kBAAmC;EACtD,cAAc,aAAa;EAC3B,eAAe,cAAc;CAC/B,EAAE;CAEF,MAAM,cAAc,eAClB;EACE,IAAI,WAAW;GACb,OAAO,MAAM;EACf;EACA,OAAO,MAAM;EACb,OAAO,MAAM;EACb,kBAAkB;CACpB,GACA,YACF;CAEA,MAAM,WAAW,iBAAiB,eAAe,MAAM,EAAE,QAAQ,KAAK,CAAC,CAAC;CAExE,OACE,CAAC,KACC,MAAM,cAAc,GACpB,UACE,CAAC,SACK,SAAS,GACb,MAAM,SAAS,IAAI,QAAQ,KAAA,GAC3B,aAAa,aAAa,IAAI,SAAS,KAAA,GACvC,YAAY,MAAM,eAClB,iBAAiB,MAAM,oBACvB,OAAO,YAAY,MAAM,GACzB,OAAO,YAAY,MAAM,GACzB,kBAAkB,KAAA,GAClB,iBAAiB,aAAa,KAAK,KAAA,GACpC;WACE,YAAY,eAAe,EAAE;QAChC,EAAE,OAEL;MACC,CAAC,WACK,SAAS,GACb,SAAS,MAAM,SACf,YAAY,MAAM,eAClB,iBAAiB,MAAM,oBACvB,OAAO,YAAY,MAAM,GACzB,OAAO,YAAY,MAAM,GACzB,oBACD;SACE,YAAY,eAAe,EAAE;MAChC,EAAE,OAAO;IACX,EAAE;AAEN"}
|
package/dist/Keyboard.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getNextElement, insert, runHydrationEvents, spread, template } from "solid-js/web";
|
|
2
|
+
import { createContext, splitProps, useContext } from "solid-js";
|
|
3
|
+
//#region src/Keyboard.tsx
|
|
4
|
+
/**
|
|
5
|
+
* Keyboard primitive for solidaria-components.
|
|
6
|
+
*
|
|
7
|
+
* Displays keyboard key hints with semantic <kbd> markup.
|
|
8
|
+
* Port direction: react-aria-components/src/Keyboard.tsx
|
|
9
|
+
*/
|
|
10
|
+
var _tmpl$ = /*#__PURE__*/ template(`<kbd dir=ltr>`);
|
|
11
|
+
const KeyboardContext = createContext(null);
|
|
12
|
+
function Keyboard(props) {
|
|
13
|
+
const context = useContext(KeyboardContext);
|
|
14
|
+
const merged = () => ({
|
|
15
|
+
...context,
|
|
16
|
+
...props
|
|
17
|
+
});
|
|
18
|
+
const [local, domProps] = splitProps(merged(), ["children"]);
|
|
19
|
+
return (() => {
|
|
20
|
+
var _el$ = getNextElement(_tmpl$);
|
|
21
|
+
spread(_el$, domProps, false, true);
|
|
22
|
+
insert(_el$, () => local.children);
|
|
23
|
+
runHydrationEvents();
|
|
24
|
+
return _el$;
|
|
25
|
+
})();
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { Keyboard, KeyboardContext };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=Keyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Keyboard.js","names":["JSX","createContext","splitProps","useContext","KeyboardProps","HTMLAttributes","HTMLElement","children","Element","KeyboardContext","Keyboard","props","context","merged","local","domProps","_el$","_$getNextElement","_tmpl$","_$spread","_$insert","_$runHydrationEvents"],"sources":["../src/Keyboard.tsx"],"sourcesContent":["/**\n * Keyboard primitive for solidaria-components.\n *\n * Displays keyboard key hints with semantic <kbd> markup.\n * Port direction: react-aria-components/src/Keyboard.tsx\n */\n\nimport { type JSX, createContext, splitProps, useContext } from \"solid-js\";\n\nexport interface KeyboardProps extends JSX.HTMLAttributes<HTMLElement> {\n children?: JSX.Element;\n}\n\nexport const KeyboardContext = createContext<KeyboardProps | null>(null);\n\nexport function Keyboard(props: KeyboardProps): JSX.Element {\n const context = useContext(KeyboardContext);\n const merged = () => ({ ...context, ...props });\n const [local, domProps] = splitProps(merged(), [\"children\"]);\n\n return (\n <kbd dir=\"ltr\" {...domProps}>\n {local.children}\n </kbd>\n );\n}\n"],"mappings":";;;;;;;;;;AAaA,MAAaS,kBAAkBR,cAAoC,IAAI;AAEvE,SAAgBS,SAASC,OAAmC;CAC1D,MAAMC,UAAUT,WAAWM,eAAe;CAC1C,MAAMI,gBAAgB;EAAE,GAAGD;EAAS,GAAGD;CAAM;CAC7C,MAAM,CAACG,OAAOC,YAAYb,WAAWW,OAAO,GAAG,CAAC,UAAU,CAAC;CAE3D,cAAA;EAAA,IAAAG,OAAAC,eAAAC,MAAA;EAAAC,OAAAH,MACqBD,UAAQ,OAAA,IAAA;EAAAK,OAAAJ,YACxBF,MAAMP,QAAQ;EAAAc,mBAAA;EAAA,OAAAL;CAAA,EAAA,CAAA;AAGrB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createContext, splitProps, useContext } from "solid-js";
|
|
2
|
+
//#region src/Keyboard.tsx
|
|
3
|
+
/**
|
|
4
|
+
* Keyboard primitive for solidaria-components.
|
|
5
|
+
*
|
|
6
|
+
* Displays keyboard key hints with semantic <kbd> markup.
|
|
7
|
+
* Port direction: react-aria-components/src/Keyboard.tsx
|
|
8
|
+
*/
|
|
9
|
+
const KeyboardContext = createContext(null);
|
|
10
|
+
function Keyboard(props) {
|
|
11
|
+
const context = useContext(KeyboardContext);
|
|
12
|
+
const merged = () => ({
|
|
13
|
+
...context,
|
|
14
|
+
...props
|
|
15
|
+
});
|
|
16
|
+
const [local, domProps] = splitProps(merged(), ["children"]);
|
|
17
|
+
return <kbd dir="ltr" {...domProps}>
|
|
18
|
+
{local.children}
|
|
19
|
+
</kbd>;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { Keyboard, KeyboardContext };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=Keyboard.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Keyboard.jsx","names":[],"sources":["../src/Keyboard.tsx"],"sourcesContent":["/**\n * Keyboard primitive for solidaria-components.\n *\n * Displays keyboard key hints with semantic <kbd> markup.\n * Port direction: react-aria-components/src/Keyboard.tsx\n */\n\nimport { type JSX, createContext, splitProps, useContext } from \"solid-js\";\n\nexport interface KeyboardProps extends JSX.HTMLAttributes<HTMLElement> {\n children?: JSX.Element;\n}\n\nexport const KeyboardContext = createContext<KeyboardProps | null>(null);\n\nexport function Keyboard(props: KeyboardProps): JSX.Element {\n const context = useContext(KeyboardContext);\n const merged = () => ({ ...context, ...props });\n const [local, domProps] = splitProps(merged(), [\"children\"]);\n\n return (\n <kbd dir=\"ltr\" {...domProps}>\n {local.children}\n </kbd>\n );\n}\n"],"mappings":";;;;;;;;AAaA,MAAa,kBAAkB,cAAoC,IAAI;AAEvE,SAAgB,SAAS,OAAmC;CAC1D,MAAM,UAAU,WAAW,eAAe;CAC1C,MAAM,gBAAgB;EAAE,GAAG;EAAS,GAAG;CAAM;CAC7C,MAAM,CAAC,OAAO,YAAY,WAAW,OAAO,GAAG,CAAC,UAAU,CAAC;CAE3D,OACE,CAAC,IAAI,cAAc,UAAU;OAC1B,MAAM,SAAS;IAClB,EAAE;AAEN"}
|
package/dist/Landmark.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { filterDOMProps } from "./utils.js";
|
|
2
|
+
import { Dynamic, createComponent, mergeProps } from "solid-js/web";
|
|
3
|
+
import { createContext, createMemo, createSignal, splitProps } from "solid-js";
|
|
4
|
+
import { createLandmark, getLandmarkController } from "@proyecto-viviana/solidaria";
|
|
5
|
+
//#region src/Landmark.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Landmark component for solidaria-components
|
|
8
|
+
*
|
|
9
|
+
* Pre-wired headless landmark component that combines aria hooks.
|
|
10
|
+
* Enables F6 keyboard navigation between major page sections.
|
|
11
|
+
*/
|
|
12
|
+
const LandmarkContext = createContext(null);
|
|
13
|
+
/**
|
|
14
|
+
* Maps ARIA landmark roles to their semantic HTML elements.
|
|
15
|
+
* Using semantic elements is preferred when possible.
|
|
16
|
+
*/
|
|
17
|
+
const roleToSemanticElement = {
|
|
18
|
+
main: "main",
|
|
19
|
+
navigation: "nav",
|
|
20
|
+
search: "search",
|
|
21
|
+
banner: "header",
|
|
22
|
+
contentinfo: "footer",
|
|
23
|
+
complementary: "aside",
|
|
24
|
+
form: "form",
|
|
25
|
+
region: "section"
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* A landmark is a region of the page that helps screen reader users navigate.
|
|
29
|
+
* Press F6 to cycle through landmarks, or Shift+F6 to go backwards.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* // Main content area
|
|
34
|
+
* <Landmark role="main" aria-label="Main content">
|
|
35
|
+
* <h1>Welcome</h1>
|
|
36
|
+
* <p>Page content here...</p>
|
|
37
|
+
* </Landmark>
|
|
38
|
+
*
|
|
39
|
+
* // Navigation
|
|
40
|
+
* <Landmark role="navigation" aria-label="Primary navigation">
|
|
41
|
+
* <nav>...</nav>
|
|
42
|
+
* </Landmark>
|
|
43
|
+
*
|
|
44
|
+
* // Search
|
|
45
|
+
* <Landmark role="search" aria-label="Site search">
|
|
46
|
+
* <form>...</form>
|
|
47
|
+
* </Landmark>
|
|
48
|
+
*
|
|
49
|
+
* // Custom element type
|
|
50
|
+
* <Landmark role="region" aria-label="Featured content" elementType="div">
|
|
51
|
+
* ...
|
|
52
|
+
* </Landmark>
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
function Landmark(props) {
|
|
56
|
+
const [local, ariaProps] = splitProps(props, [
|
|
57
|
+
"class",
|
|
58
|
+
"style",
|
|
59
|
+
"slot",
|
|
60
|
+
"children",
|
|
61
|
+
"elementType"
|
|
62
|
+
]);
|
|
63
|
+
const [ref, setRef] = createSignal();
|
|
64
|
+
const elementType = createMemo(() => {
|
|
65
|
+
if (local.elementType) return local.elementType;
|
|
66
|
+
return roleToSemanticElement[ariaProps.role] ?? "div";
|
|
67
|
+
});
|
|
68
|
+
const landmarkAria = createLandmark({
|
|
69
|
+
get role() {
|
|
70
|
+
return ariaProps.role;
|
|
71
|
+
},
|
|
72
|
+
get "aria-label"() {
|
|
73
|
+
return ariaProps["aria-label"];
|
|
74
|
+
},
|
|
75
|
+
get "aria-labelledby"() {
|
|
76
|
+
return ariaProps["aria-labelledby"];
|
|
77
|
+
},
|
|
78
|
+
get id() {
|
|
79
|
+
return ariaProps.id;
|
|
80
|
+
},
|
|
81
|
+
get focus() {
|
|
82
|
+
return ariaProps.focus;
|
|
83
|
+
}
|
|
84
|
+
}, ref);
|
|
85
|
+
const renderValues = createMemo(() => ({ role: ariaProps.role }));
|
|
86
|
+
const resolvedClass = createMemo(() => {
|
|
87
|
+
const cls = local.class;
|
|
88
|
+
if (typeof cls === "function") return cls(renderValues());
|
|
89
|
+
return cls ?? `solidaria-Landmark solidaria-Landmark--${ariaProps.role}`;
|
|
90
|
+
});
|
|
91
|
+
const resolvedStyle = createMemo(() => {
|
|
92
|
+
const style = local.style;
|
|
93
|
+
if (typeof style === "function") return style(renderValues());
|
|
94
|
+
return style;
|
|
95
|
+
});
|
|
96
|
+
const domProps = createMemo(() => filterDOMProps(ariaProps, { global: true }));
|
|
97
|
+
return createComponent(Dynamic, mergeProps({
|
|
98
|
+
get component() {
|
|
99
|
+
return elementType();
|
|
100
|
+
},
|
|
101
|
+
ref: setRef
|
|
102
|
+
}, domProps, () => landmarkAria.landmarkProps, {
|
|
103
|
+
get ["class"]() {
|
|
104
|
+
return resolvedClass();
|
|
105
|
+
},
|
|
106
|
+
get style() {
|
|
107
|
+
return resolvedStyle();
|
|
108
|
+
},
|
|
109
|
+
get slot() {
|
|
110
|
+
return local.slot;
|
|
111
|
+
},
|
|
112
|
+
get children() {
|
|
113
|
+
return props.children;
|
|
114
|
+
}
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns a controller for programmatic landmark navigation.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```tsx
|
|
122
|
+
* const controller = useLandmarkController();
|
|
123
|
+
*
|
|
124
|
+
* <button onClick={() => controller.focusMain()}>Skip to main content</button>
|
|
125
|
+
* <button onClick={() => controller.focusNext()}>Next landmark</button>
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
function useLandmarkController() {
|
|
129
|
+
return getLandmarkController();
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
132
|
+
export { Landmark, LandmarkContext, useLandmarkController };
|
|
133
|
+
|
|
134
|
+
//# sourceMappingURL=Landmark.js.map
|