@proyecto-viviana/solidaria-components 0.2.5 → 0.3.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/LICENSE +21 -0
- package/README.md +39 -272
- package/dist/ActionBar.d.ts +79 -0
- package/dist/ActionBar.d.ts.map +1 -0
- package/dist/ActionGroup.d.ts +74 -0
- package/dist/ActionGroup.d.ts.map +1 -0
- package/dist/Alert.d.ts +70 -0
- package/dist/Alert.d.ts.map +1 -0
- package/dist/Autocomplete.d.ts +5 -5
- package/dist/Autocomplete.d.ts.map +1 -1
- package/dist/Breadcrumbs.d.ts +27 -8
- package/dist/Breadcrumbs.d.ts.map +1 -1
- package/dist/Button.d.ts +28 -5
- package/dist/Button.d.ts.map +1 -1
- package/dist/Calendar.d.ts +51 -7
- package/dist/Calendar.d.ts.map +1 -1
- package/dist/Checkbox.d.ts +33 -8
- package/dist/Checkbox.d.ts.map +1 -1
- package/dist/Collection.d.ts +130 -0
- package/dist/Collection.d.ts.map +1 -0
- package/dist/Color.d.ts +210 -9
- package/dist/Color.d.ts.map +1 -1
- package/dist/ColorEditor.d.ts +42 -0
- package/dist/ColorEditor.d.ts.map +1 -0
- package/dist/ComboBox.d.ts +146 -16
- package/dist/ComboBox.d.ts.map +1 -1
- package/dist/ContextualHelpTrigger.d.ts +40 -0
- package/dist/ContextualHelpTrigger.d.ts.map +1 -0
- package/dist/DateField.d.ts +35 -8
- package/dist/DateField.d.ts.map +1 -1
- package/dist/DatePicker.d.ts +101 -5
- package/dist/DatePicker.d.ts.map +1 -1
- package/dist/DateRangePickerContext.d.ts +30 -0
- package/dist/DateRangePickerContext.d.ts.map +1 -0
- package/dist/Dialog.d.ts +5 -5
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Disclosure.d.ts +25 -5
- package/dist/Disclosure.d.ts.map +1 -1
- package/dist/DragAndDrop.d.ts +80 -0
- package/dist/DragAndDrop.d.ts.map +1 -0
- package/dist/DragPreview.d.ts +14 -0
- package/dist/DragPreview.d.ts.map +1 -0
- package/dist/DropZone.d.ts +27 -0
- package/dist/DropZone.d.ts.map +1 -0
- package/dist/FieldError.d.ts +27 -0
- package/dist/FieldError.d.ts.map +1 -0
- package/dist/FileTrigger.d.ts +26 -0
- package/dist/FileTrigger.d.ts.map +1 -0
- package/dist/Focusable.d.ts +27 -0
- package/dist/Focusable.d.ts.map +1 -0
- package/dist/Form.d.ts +41 -0
- package/dist/Form.d.ts.map +1 -0
- package/dist/GridList.d.ts +69 -10
- package/dist/GridList.d.ts.map +1 -1
- package/dist/HiddenDateInput.d.ts +26 -0
- package/dist/HiddenDateInput.d.ts.map +1 -0
- package/dist/HiddenTimeInput.d.ts +25 -0
- package/dist/HiddenTimeInput.d.ts.map +1 -0
- package/dist/Icon.d.ts +57 -0
- package/dist/Icon.d.ts.map +1 -0
- package/dist/Keyboard.d.ts +13 -0
- package/dist/Keyboard.d.ts.map +1 -0
- package/dist/Landmark.d.ts +3 -3
- package/dist/Landmark.d.ts.map +1 -1
- package/dist/Link.d.ts +10 -4
- package/dist/Link.d.ts.map +1 -1
- package/dist/ListBox.d.ts +73 -11
- package/dist/ListBox.d.ts.map +1 -1
- package/dist/ListDropTargetDelegate.d.ts +38 -0
- package/dist/ListDropTargetDelegate.d.ts.map +1 -0
- package/dist/Menu.d.ts +79 -10
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Meter.d.ts +4 -4
- package/dist/Meter.d.ts.map +1 -1
- package/dist/Modal.d.ts +6 -4
- package/dist/Modal.d.ts.map +1 -1
- package/dist/NumberField.d.ts +10 -12
- package/dist/NumberField.d.ts.map +1 -1
- package/dist/Popover.d.ts +32 -7
- package/dist/Popover.d.ts.map +1 -1
- package/dist/Pressable.d.ts +27 -0
- package/dist/Pressable.d.ts.map +1 -0
- package/dist/ProgressBar.d.ts +6 -4
- package/dist/ProgressBar.d.ts.map +1 -1
- package/dist/RadioGroup.d.ts +43 -9
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RangeCalendar.d.ts +39 -7
- package/dist/RangeCalendar.d.ts.map +1 -1
- package/dist/RouterProvider.d.ts +75 -0
- package/dist/RouterProvider.d.ts.map +1 -0
- package/dist/SearchField.d.ts +23 -21
- package/dist/SearchField.d.ts.map +1 -1
- package/dist/Select.d.ts +48 -7
- package/dist/Select.d.ts.map +1 -1
- package/dist/SelectionIndicator.d.ts +30 -0
- package/dist/SelectionIndicator.d.ts.map +1 -0
- package/dist/Separator.d.ts +9 -3
- package/dist/Separator.d.ts.map +1 -1
- package/dist/SharedElementTransition.d.ts +41 -0
- package/dist/SharedElementTransition.d.ts.map +1 -0
- package/dist/Slider.d.ts +15 -8
- package/dist/Slider.d.ts.map +1 -1
- package/dist/StepList.d.ts +90 -0
- package/dist/StepList.d.ts.map +1 -0
- package/dist/Switch.d.ts +11 -5
- package/dist/Switch.d.ts.map +1 -1
- package/dist/Table.d.ts +222 -19
- package/dist/Table.d.ts.map +1 -1
- package/dist/Tabs.d.ts +47 -10
- package/dist/Tabs.d.ts.map +1 -1
- package/dist/TagGroup.d.ts +22 -10
- package/dist/TagGroup.d.ts.map +1 -1
- package/dist/Text.d.ts +10 -0
- package/dist/Text.d.ts.map +1 -0
- package/dist/TextField.d.ts +19 -11
- package/dist/TextField.d.ts.map +1 -1
- package/dist/TimeField.d.ts +32 -7
- package/dist/TimeField.d.ts.map +1 -1
- package/dist/Toast.d.ts +29 -14
- package/dist/Toast.d.ts.map +1 -1
- package/dist/ToggleButton.d.ts +36 -0
- package/dist/ToggleButton.d.ts.map +1 -0
- package/dist/ToggleButtonGroup.d.ts +33 -0
- package/dist/ToggleButtonGroup.d.ts.map +1 -0
- package/dist/Toolbar.d.ts +7 -3
- package/dist/Toolbar.d.ts.map +1 -1
- package/dist/Tooltip.d.ts +58 -7
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/Tree.d.ts +102 -11
- package/dist/Tree.d.ts.map +1 -1
- package/dist/Virtualizer.d.ts +61 -0
- package/dist/Virtualizer.d.ts.map +1 -0
- package/dist/VirtualizerLayouts.d.ts +82 -0
- package/dist/VirtualizerLayouts.d.ts.map +1 -0
- package/dist/VisuallyHidden.d.ts +4 -2
- package/dist/VisuallyHidden.d.ts.map +1 -1
- package/dist/contexts.d.ts +6 -1
- package/dist/contexts.d.ts.map +1 -1
- package/dist/index.d.ts +73 -39
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23342 -10644
- package/dist/index.js.map +1 -7
- package/dist/index.jsx +18110 -0
- package/dist/index.jsx.map +1 -0
- package/dist/useDragAndDrop.d.ts +93 -0
- package/dist/useDragAndDrop.d.ts.map +1 -0
- package/dist/utils.d.ts +8 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/virtualizer/Layout.d.ts +79 -0
- package/dist/virtualizer/Layout.d.ts.map +1 -0
- package/package.json +33 -32
- package/src/ActionBar.tsx +251 -0
- package/src/ActionGroup.tsx +277 -0
- package/src/Alert.tsx +152 -0
- package/src/Autocomplete.tsx +39 -44
- package/src/Breadcrumbs.tsx +227 -72
- package/src/Button.tsx +315 -74
- package/src/Calendar.tsx +347 -141
- package/src/Checkbox.tsx +414 -123
- package/src/Collection.tsx +350 -0
- package/src/Color.tsx +1325 -284
- package/src/ColorEditor.tsx +213 -0
- package/src/ComboBox.tsx +644 -245
- package/src/ContextualHelpTrigger.tsx +195 -0
- package/src/DateField.tsx +274 -106
- package/src/DatePicker.tsx +892 -111
- package/src/DateRangePickerContext.tsx +44 -0
- package/src/Dialog.tsx +173 -104
- package/src/Disclosure.tsx +158 -105
- package/src/DragAndDrop.tsx +340 -0
- package/src/DragPreview.tsx +47 -0
- package/src/DropZone.tsx +233 -0
- package/src/FieldError.tsx +89 -0
- package/src/FileTrigger.tsx +83 -0
- package/src/Focusable.tsx +103 -0
- package/src/Form.tsx +140 -0
- package/src/GridList.tsx +542 -128
- package/src/HiddenDateInput.tsx +153 -0
- package/src/HiddenTimeInput.tsx +133 -0
- package/src/Icon.tsx +133 -0
- package/src/Keyboard.tsx +26 -0
- package/src/Landmark.tsx +37 -63
- package/src/Link.tsx +132 -69
- package/src/ListBox.tsx +656 -106
- package/src/ListDropTargetDelegate.ts +283 -0
- package/src/Menu.tsx +1234 -132
- package/src/Meter.tsx +44 -58
- package/src/Modal.tsx +262 -166
- package/src/NumberField.tsx +267 -151
- package/src/Popover.tsx +452 -343
- package/src/Pressable.tsx +108 -0
- package/src/ProgressBar.tsx +54 -59
- package/src/RadioGroup.tsx +533 -121
- package/src/RangeCalendar.tsx +249 -150
- package/src/RouterProvider.tsx +223 -0
- package/src/SearchField.tsx +460 -133
- package/src/Select.tsx +804 -233
- package/src/SelectionIndicator.tsx +108 -0
- package/src/Separator.tsx +47 -49
- package/src/SharedElementTransition.tsx +264 -0
- package/src/Slider.tsx +148 -98
- package/src/StepList.tsx +272 -0
- package/src/Switch.tsx +93 -46
- package/src/Table.tsx +1551 -225
- package/src/Tabs.tsx +377 -123
- package/src/TagGroup.tsx +233 -135
- package/src/Text.tsx +18 -0
- package/src/TextField.tsx +413 -86
- package/src/TimeField.tsx +232 -222
- package/src/Toast.tsx +306 -160
- package/src/ToggleButton.tsx +169 -0
- package/src/ToggleButtonGroup.tsx +141 -0
- package/src/Toolbar.tsx +61 -70
- package/src/Tooltip.tsx +473 -116
- package/src/Tree.tsx +1514 -175
- package/src/Virtualizer.tsx +730 -0
- package/src/VirtualizerLayouts.ts +280 -0
- package/src/VisuallyHidden.tsx +32 -38
- package/src/contexts.ts +29 -36
- package/src/index.ts +972 -620
- package/src/useDragAndDrop.ts +367 -0
- package/src/utils.tsx +69 -50
- package/src/virtualizer/Layout.ts +192 -0
- package/dist/index.ssr.js +0 -9785
- package/dist/index.ssr.js.map +0 -7
package/src/TagGroup.tsx
CHANGED
|
@@ -17,19 +17,15 @@ import {
|
|
|
17
17
|
useContext,
|
|
18
18
|
For,
|
|
19
19
|
Show,
|
|
20
|
-
} from
|
|
21
|
-
import {
|
|
22
|
-
createTagGroup,
|
|
23
|
-
createTag,
|
|
24
|
-
type AriaTagGroupProps,
|
|
25
|
-
} from '@proyecto-viviana/solidaria';
|
|
20
|
+
} from "solid-js";
|
|
21
|
+
import { createTagGroup, createTag, type AriaTagGroupProps } from "@proyecto-viviana/solidaria";
|
|
26
22
|
import {
|
|
27
23
|
createListState,
|
|
28
24
|
type ListState,
|
|
29
25
|
type Key,
|
|
30
26
|
type SelectionMode,
|
|
31
27
|
type SelectionBehavior,
|
|
32
|
-
} from
|
|
28
|
+
} from "@proyecto-viviana/solid-stately";
|
|
33
29
|
import {
|
|
34
30
|
type RenderChildren,
|
|
35
31
|
type ClassNameOrFunction,
|
|
@@ -38,11 +34,12 @@ import {
|
|
|
38
34
|
useRenderProps,
|
|
39
35
|
filterDOMProps,
|
|
40
36
|
dataAttr,
|
|
41
|
-
} from
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
} from "./utils";
|
|
38
|
+
import { SharedElementTransition } from "./SharedElementTransition";
|
|
39
|
+
import {
|
|
40
|
+
SelectionIndicatorContext,
|
|
41
|
+
type SelectionIndicatorContextValue,
|
|
42
|
+
} from "./SelectionIndicator";
|
|
46
43
|
|
|
47
44
|
export interface TagGroupRenderProps {
|
|
48
45
|
/** Whether the tag group is disabled. */
|
|
@@ -52,8 +49,10 @@ export interface TagGroupRenderProps {
|
|
|
52
49
|
}
|
|
53
50
|
|
|
54
51
|
export interface TagGroupProps
|
|
55
|
-
extends
|
|
56
|
-
|
|
52
|
+
extends
|
|
53
|
+
Omit<AriaTagGroupProps, "id">,
|
|
54
|
+
SlotProps,
|
|
55
|
+
Omit<JSX.HTMLAttributes<HTMLDivElement>, "class" | "style" | "children"> {
|
|
57
56
|
/** The children of the component. */
|
|
58
57
|
children?: JSX.Element;
|
|
59
58
|
/** The CSS className for the element. */
|
|
@@ -69,7 +68,10 @@ export interface TagListRenderProps {
|
|
|
69
68
|
isFocused: boolean;
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
export interface TagListProps<T>
|
|
71
|
+
export interface TagListProps<T>
|
|
72
|
+
extends
|
|
73
|
+
SlotProps,
|
|
74
|
+
Omit<JSX.HTMLAttributes<HTMLDivElement>, "class" | "style" | "children" | "onSelectionChange"> {
|
|
73
75
|
/** The items to display in the tag list. */
|
|
74
76
|
items: T[];
|
|
75
77
|
/** Function to render each item. */
|
|
@@ -89,7 +91,7 @@ export interface TagListProps<T> extends SlotProps {
|
|
|
89
91
|
/** The default selected keys (uncontrolled). */
|
|
90
92
|
defaultSelectedKeys?: Iterable<Key>;
|
|
91
93
|
/** Handler called when selection changes. */
|
|
92
|
-
onSelectionChange?: (keys:
|
|
94
|
+
onSelectionChange?: (keys: "all" | Set<Key>) => void;
|
|
93
95
|
/** Keys that are disabled. */
|
|
94
96
|
disabledKeys?: Iterable<Key>;
|
|
95
97
|
/** Function to get a unique key from an item. */
|
|
@@ -97,11 +99,11 @@ export interface TagListProps<T> extends SlotProps {
|
|
|
97
99
|
/** Accessibility label. */
|
|
98
100
|
label?: string;
|
|
99
101
|
/** Custom aria-label. */
|
|
100
|
-
|
|
102
|
+
"aria-label"?: string;
|
|
101
103
|
/** Reference to external label element. */
|
|
102
|
-
|
|
104
|
+
"aria-labelledby"?: string;
|
|
103
105
|
/** Reference to description element. */
|
|
104
|
-
|
|
106
|
+
"aria-describedby"?: string;
|
|
105
107
|
/** Whether the tag list is disabled. */
|
|
106
108
|
isDisabled?: boolean;
|
|
107
109
|
/** Handler called when tags are removed. */
|
|
@@ -121,6 +123,8 @@ export interface TagRenderProps {
|
|
|
121
123
|
allowsRemoving: boolean;
|
|
122
124
|
/** The selection mode. */
|
|
123
125
|
selectionMode: SelectionMode;
|
|
126
|
+
/** Props for the remove button when removal is allowed. */
|
|
127
|
+
removeButtonProps: Record<string, unknown>;
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
export interface TagProps extends SlotProps {
|
|
@@ -136,28 +140,29 @@ export interface TagProps extends SlotProps {
|
|
|
136
140
|
class?: ClassNameOrFunction<TagRenderProps>;
|
|
137
141
|
/** The inline style for the element. */
|
|
138
142
|
style?: StyleOrFunction<TagRenderProps>;
|
|
143
|
+
/** Handler called when the tag is activated. */
|
|
144
|
+
onAction?: (key: Key) => void;
|
|
139
145
|
}
|
|
140
146
|
|
|
141
|
-
// ============================================
|
|
142
|
-
// CONTEXT
|
|
143
|
-
// ============================================
|
|
144
|
-
|
|
145
147
|
interface TagGroupContextValue {
|
|
146
148
|
state: ListState;
|
|
147
149
|
onRemove?: (keys: Set<Key>) => void;
|
|
150
|
+
isDisabled?: boolean;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
interface TagContextValue {
|
|
154
|
+
removeButtonProps: Record<string, unknown>;
|
|
155
|
+
allowsRemoving: boolean;
|
|
148
156
|
}
|
|
149
157
|
|
|
150
158
|
export const TagGroupContext = createContext<TagGroupContextValue | null>(null);
|
|
151
159
|
export const TagListStateContext = createContext<ListState | null>(null);
|
|
160
|
+
export const TagContext = createContext<TagContextValue | null>(null);
|
|
152
161
|
|
|
153
162
|
export function useTagGroupContext(): TagGroupContextValue | null {
|
|
154
163
|
return useContext(TagGroupContext);
|
|
155
164
|
}
|
|
156
165
|
|
|
157
|
-
// ============================================
|
|
158
|
-
// TAG GROUP COMPONENT
|
|
159
|
-
// ============================================
|
|
160
|
-
|
|
161
166
|
/**
|
|
162
167
|
* A tag group is a focusable list of labels, categories, keywords, filters, or other items,
|
|
163
168
|
* with support for keyboard navigation, selection, and removal.
|
|
@@ -172,17 +177,14 @@ export function useTagGroupContext(): TagGroupContextValue | null {
|
|
|
172
177
|
* ```
|
|
173
178
|
*/
|
|
174
179
|
export function TagGroup(props: TagGroupProps): JSX.Element {
|
|
175
|
-
const [local] = splitProps(props, [
|
|
176
|
-
'class',
|
|
177
|
-
'style',
|
|
178
|
-
'slot',
|
|
179
|
-
]);
|
|
180
|
+
const [local, domProps] = splitProps(props, ["class", "style", "slot", "children"]);
|
|
180
181
|
|
|
181
182
|
// We need TagList to provide the state, so TagGroup just provides context
|
|
182
183
|
return (
|
|
183
184
|
<div
|
|
184
|
-
|
|
185
|
-
|
|
185
|
+
{...domProps}
|
|
186
|
+
class={typeof local.class === "string" ? local.class : "solidaria-TagGroup"}
|
|
187
|
+
style={typeof local.style === "object" ? local.style : undefined}
|
|
186
188
|
slot={local.slot}
|
|
187
189
|
>
|
|
188
190
|
{props.children}
|
|
@@ -190,33 +192,30 @@ export function TagGroup(props: TagGroupProps): JSX.Element {
|
|
|
190
192
|
);
|
|
191
193
|
}
|
|
192
194
|
|
|
193
|
-
// ============================================
|
|
194
|
-
// TAG LIST COMPONENT
|
|
195
|
-
// ============================================
|
|
196
|
-
|
|
197
195
|
/**
|
|
198
196
|
* TagList contains the list of tags within a TagGroup.
|
|
199
197
|
*/
|
|
200
198
|
export function TagList<T extends { id?: Key; key?: Key }>(props: TagListProps<T>): JSX.Element {
|
|
201
|
-
const [local] = splitProps(props, [
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
199
|
+
const [local, domProps] = splitProps(props, [
|
|
200
|
+
"items",
|
|
201
|
+
"class",
|
|
202
|
+
"style",
|
|
203
|
+
"slot",
|
|
204
|
+
"renderEmptyState",
|
|
205
|
+
"children",
|
|
206
|
+
"selectionMode",
|
|
207
|
+
"selectionBehavior",
|
|
208
|
+
"selectedKeys",
|
|
209
|
+
"defaultSelectedKeys",
|
|
210
|
+
"onSelectionChange",
|
|
211
|
+
"disabledKeys",
|
|
212
|
+
"getKey",
|
|
213
|
+
"label",
|
|
214
|
+
"aria-label",
|
|
215
|
+
"aria-labelledby",
|
|
216
|
+
"aria-describedby",
|
|
217
|
+
"isDisabled",
|
|
218
|
+
"onRemove",
|
|
220
219
|
]);
|
|
221
220
|
|
|
222
221
|
// Create a ref for the grid
|
|
@@ -230,55 +229,78 @@ export function TagList<T extends { id?: Key; key?: Key }>(props: TagListProps<T
|
|
|
230
229
|
return String(item);
|
|
231
230
|
};
|
|
232
231
|
|
|
233
|
-
// Create list state
|
|
234
232
|
const state = createListState({
|
|
235
|
-
get items() {
|
|
233
|
+
get items() {
|
|
234
|
+
return local.items;
|
|
235
|
+
},
|
|
236
236
|
getKey,
|
|
237
|
-
get selectionMode() {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
get
|
|
241
|
-
|
|
242
|
-
|
|
237
|
+
get selectionMode() {
|
|
238
|
+
return local.selectionMode ?? "none";
|
|
239
|
+
},
|
|
240
|
+
get selectionBehavior() {
|
|
241
|
+
return local.selectionBehavior ?? "toggle";
|
|
242
|
+
},
|
|
243
|
+
get selectedKeys() {
|
|
244
|
+
return local.selectedKeys;
|
|
245
|
+
},
|
|
246
|
+
get defaultSelectedKeys() {
|
|
247
|
+
return local.defaultSelectedKeys;
|
|
248
|
+
},
|
|
249
|
+
get onSelectionChange() {
|
|
250
|
+
return local.onSelectionChange;
|
|
251
|
+
},
|
|
252
|
+
get disabledKeys() {
|
|
253
|
+
return local.disabledKeys;
|
|
254
|
+
},
|
|
243
255
|
});
|
|
244
256
|
|
|
245
257
|
// Create tag group accessibility props
|
|
246
258
|
const tagGroupAria = createTagGroup(
|
|
247
259
|
{
|
|
248
|
-
get label() {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
get
|
|
252
|
-
|
|
253
|
-
|
|
260
|
+
get "aria-label"() {
|
|
261
|
+
return local["aria-label"] ?? (!local["aria-labelledby"] ? local.label : undefined);
|
|
262
|
+
},
|
|
263
|
+
get "aria-labelledby"() {
|
|
264
|
+
return local["aria-labelledby"];
|
|
265
|
+
},
|
|
266
|
+
get "aria-describedby"() {
|
|
267
|
+
return local["aria-describedby"];
|
|
268
|
+
},
|
|
269
|
+
get isDisabled() {
|
|
270
|
+
return local.isDisabled;
|
|
271
|
+
},
|
|
272
|
+
get onRemove() {
|
|
273
|
+
return local.onRemove;
|
|
274
|
+
},
|
|
254
275
|
},
|
|
255
276
|
state,
|
|
256
|
-
gridRef
|
|
277
|
+
gridRef,
|
|
257
278
|
);
|
|
258
279
|
|
|
259
|
-
// Track focus
|
|
260
280
|
const [isFocused, setIsFocused] = createSignal(false);
|
|
261
281
|
|
|
262
|
-
// Render props values
|
|
263
282
|
const renderValues = createMemo<TagListRenderProps>(() => ({
|
|
264
283
|
isEmpty: local.items.length === 0,
|
|
265
284
|
isFocused: isFocused(),
|
|
266
285
|
}));
|
|
267
286
|
|
|
268
|
-
// Resolve render props
|
|
269
287
|
const renderProps = useRenderProps(
|
|
270
288
|
{
|
|
271
289
|
class: local.class,
|
|
272
290
|
style: local.style,
|
|
273
|
-
defaultClassName:
|
|
291
|
+
defaultClassName: "solidaria-TagList",
|
|
274
292
|
},
|
|
275
|
-
renderValues
|
|
293
|
+
renderValues,
|
|
276
294
|
);
|
|
277
295
|
|
|
278
|
-
// Context value
|
|
279
296
|
const contextValue: TagGroupContextValue = {
|
|
280
297
|
state,
|
|
281
|
-
get onRemove() {
|
|
298
|
+
get onRemove() {
|
|
299
|
+
return local.onRemove;
|
|
300
|
+
},
|
|
301
|
+
get isDisabled() {
|
|
302
|
+
return local.isDisabled;
|
|
303
|
+
},
|
|
282
304
|
};
|
|
283
305
|
|
|
284
306
|
return (
|
|
@@ -286,46 +308,53 @@ export function TagList<T extends { id?: Key; key?: Key }>(props: TagListProps<T
|
|
|
286
308
|
<TagListStateContext.Provider value={state}>
|
|
287
309
|
<div
|
|
288
310
|
ref={setGridRef}
|
|
311
|
+
{...domProps}
|
|
289
312
|
{...tagGroupAria.gridProps}
|
|
290
313
|
class={renderProps.class()}
|
|
291
314
|
style={renderProps.style()}
|
|
292
|
-
onFocus={() =>
|
|
293
|
-
|
|
315
|
+
onFocus={() => {
|
|
316
|
+
setIsFocused(true);
|
|
317
|
+
state.setFocused(true);
|
|
318
|
+
}}
|
|
319
|
+
onBlur={(e) => {
|
|
320
|
+
const nextTarget = e.relatedTarget as Node | null;
|
|
321
|
+
if (nextTarget && e.currentTarget.contains(nextTarget)) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
setIsFocused(false);
|
|
326
|
+
state.setFocused(false);
|
|
327
|
+
}}
|
|
294
328
|
data-empty={dataAttr(local.items.length === 0)}
|
|
295
329
|
data-focused={dataAttr(isFocused())}
|
|
296
330
|
>
|
|
297
|
-
<
|
|
298
|
-
when={local.items.length > 0}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
{(item) => props.children(item)}
|
|
303
|
-
</For>
|
|
304
|
-
</Show>
|
|
331
|
+
<SharedElementTransition>
|
|
332
|
+
<Show when={local.items.length > 0} fallback={local.renderEmptyState?.()}>
|
|
333
|
+
<For each={local.items}>{(item) => props.children(item)}</For>
|
|
334
|
+
</Show>
|
|
335
|
+
</SharedElementTransition>
|
|
305
336
|
</div>
|
|
306
337
|
</TagListStateContext.Provider>
|
|
307
338
|
</TagGroupContext.Provider>
|
|
308
339
|
);
|
|
309
340
|
}
|
|
310
341
|
|
|
311
|
-
// ============================================
|
|
312
|
-
// TAG COMPONENT
|
|
313
|
-
// ============================================
|
|
314
|
-
|
|
315
342
|
/**
|
|
316
343
|
* A Tag is an individual item within a TagList.
|
|
317
344
|
*/
|
|
318
345
|
export function Tag(props: TagProps): JSX.Element {
|
|
319
346
|
const [local, rest] = splitProps(props, [
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
347
|
+
"id",
|
|
348
|
+
"class",
|
|
349
|
+
"style",
|
|
350
|
+
"slot",
|
|
351
|
+
"isDisabled",
|
|
352
|
+
"textValue",
|
|
353
|
+
"onAction",
|
|
326
354
|
]);
|
|
327
355
|
|
|
328
356
|
const state = useContext(TagListStateContext);
|
|
357
|
+
const groupContext = useContext(TagGroupContext);
|
|
329
358
|
|
|
330
359
|
// Create a ref for the tag
|
|
331
360
|
const [tagRef, setTagRef] = createSignal<HTMLDivElement | null>(null);
|
|
@@ -333,62 +362,104 @@ export function Tag(props: TagProps): JSX.Element {
|
|
|
333
362
|
// Create tag accessibility props
|
|
334
363
|
const tagAria = createTag(
|
|
335
364
|
{
|
|
336
|
-
get key() {
|
|
337
|
-
|
|
338
|
-
|
|
365
|
+
get key() {
|
|
366
|
+
return local.id;
|
|
367
|
+
},
|
|
368
|
+
get isDisabled() {
|
|
369
|
+
return local.isDisabled || groupContext?.isDisabled;
|
|
370
|
+
},
|
|
371
|
+
get textValue() {
|
|
372
|
+
return local.textValue;
|
|
373
|
+
},
|
|
339
374
|
},
|
|
340
375
|
state!,
|
|
341
|
-
tagRef
|
|
376
|
+
tagRef,
|
|
342
377
|
);
|
|
343
378
|
|
|
344
|
-
|
|
379
|
+
const normalizedRemoveButtonProps = createMemo<Record<string, unknown>>(() => {
|
|
380
|
+
const raw = tagAria.removeButtonProps;
|
|
381
|
+
const rawHandler = typeof raw.onPress === "function" ? (raw.onPress as () => void) : undefined;
|
|
382
|
+
return {
|
|
383
|
+
...raw,
|
|
384
|
+
onPress: () => {
|
|
385
|
+
if (!tagAria.isDisabled && groupContext?.onRemove) {
|
|
386
|
+
groupContext.onRemove(new Set([local.id]));
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
rawHandler?.();
|
|
390
|
+
},
|
|
391
|
+
};
|
|
392
|
+
});
|
|
393
|
+
|
|
345
394
|
const renderValues = createMemo<TagRenderProps>(() => ({
|
|
346
395
|
isSelected: tagAria.isSelected,
|
|
347
396
|
isDisabled: tagAria.isDisabled,
|
|
348
397
|
isFocused: tagAria.isFocused,
|
|
349
398
|
isPressed: tagAria.isPressed,
|
|
350
399
|
allowsRemoving: tagAria.allowsRemoving,
|
|
351
|
-
selectionMode: state?.selectionMode() ??
|
|
400
|
+
selectionMode: state?.selectionMode() ?? "none",
|
|
401
|
+
removeButtonProps: normalizedRemoveButtonProps(),
|
|
352
402
|
}));
|
|
353
403
|
|
|
354
|
-
// Resolve render props
|
|
355
404
|
const renderProps = useRenderProps(
|
|
356
405
|
{
|
|
357
406
|
children: props.children,
|
|
358
407
|
class: local.class,
|
|
359
408
|
style: local.style,
|
|
360
|
-
defaultClassName:
|
|
409
|
+
defaultClassName: "solidaria-Tag",
|
|
361
410
|
},
|
|
362
|
-
renderValues
|
|
411
|
+
renderValues,
|
|
363
412
|
);
|
|
364
413
|
|
|
365
|
-
|
|
414
|
+
const selectionIndicatorContext = createMemo<SelectionIndicatorContextValue>(() => ({
|
|
415
|
+
isSelected: () => tagAria.isSelected,
|
|
416
|
+
}));
|
|
417
|
+
|
|
366
418
|
const domProps = createMemo(() => filterDOMProps(rest, { global: true }));
|
|
367
419
|
|
|
368
420
|
return (
|
|
369
|
-
<
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
421
|
+
<SelectionIndicatorContext.Provider value={selectionIndicatorContext()}>
|
|
422
|
+
<TagContext.Provider
|
|
423
|
+
value={{
|
|
424
|
+
get removeButtonProps() {
|
|
425
|
+
return normalizedRemoveButtonProps();
|
|
426
|
+
},
|
|
427
|
+
get allowsRemoving() {
|
|
428
|
+
return tagAria.allowsRemoving;
|
|
429
|
+
},
|
|
430
|
+
}}
|
|
431
|
+
>
|
|
432
|
+
<div
|
|
433
|
+
ref={setTagRef}
|
|
434
|
+
{...domProps()}
|
|
435
|
+
{...tagAria.rowProps}
|
|
436
|
+
class={renderProps.class()}
|
|
437
|
+
style={renderProps.style()}
|
|
438
|
+
onClick={(event) => {
|
|
439
|
+
const rowClick = tagAria.rowProps.onClick;
|
|
440
|
+
if (typeof rowClick === "function") {
|
|
441
|
+
(rowClick as JSX.EventHandler<HTMLDivElement, MouseEvent>)(event);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (!tagAria.isDisabled && !(event.target as Element | null)?.closest("button")) {
|
|
445
|
+
local.onAction?.(local.id);
|
|
446
|
+
}
|
|
447
|
+
}}
|
|
448
|
+
data-selected={dataAttr(tagAria.isSelected)}
|
|
449
|
+
data-disabled={dataAttr(tagAria.isDisabled)}
|
|
450
|
+
data-focused={dataAttr(tagAria.isFocused)}
|
|
451
|
+
data-pressed={dataAttr(tagAria.isPressed)}
|
|
452
|
+
data-allows-removing={dataAttr(tagAria.allowsRemoving)}
|
|
453
|
+
>
|
|
454
|
+
<div {...tagAria.gridCellProps} style={{ display: "contents" }}>
|
|
455
|
+
{renderProps.renderChildren()}
|
|
456
|
+
</div>
|
|
457
|
+
</div>
|
|
458
|
+
</TagContext.Provider>
|
|
459
|
+
</SelectionIndicatorContext.Provider>
|
|
385
460
|
);
|
|
386
461
|
}
|
|
387
462
|
|
|
388
|
-
// ============================================
|
|
389
|
-
// TAG REMOVE BUTTON COMPONENT
|
|
390
|
-
// ============================================
|
|
391
|
-
|
|
392
463
|
export interface TagRemoveButtonProps {
|
|
393
464
|
/** The children of the button (usually an X icon). */
|
|
394
465
|
children?: JSX.Element;
|
|
@@ -396,6 +467,8 @@ export interface TagRemoveButtonProps {
|
|
|
396
467
|
class?: string;
|
|
397
468
|
/** The inline style for the element. */
|
|
398
469
|
style?: JSX.CSSProperties;
|
|
470
|
+
/** Explicit button props from Tag render props. */
|
|
471
|
+
buttonProps?: Record<string, unknown>;
|
|
399
472
|
}
|
|
400
473
|
|
|
401
474
|
/**
|
|
@@ -403,19 +476,44 @@ export interface TagRemoveButtonProps {
|
|
|
403
476
|
* It should be placed inside a Tag component.
|
|
404
477
|
*/
|
|
405
478
|
export function TagRemoveButton(props: TagRemoveButtonProps): JSX.Element {
|
|
406
|
-
|
|
407
|
-
|
|
479
|
+
const tagContext = useContext(TagContext);
|
|
480
|
+
const getRemoveButtonProps = () => props.buttonProps ?? tagContext?.removeButtonProps ?? {};
|
|
481
|
+
const getIsDisabled = () => Boolean(getRemoveButtonProps().isDisabled);
|
|
482
|
+
const rawId = getRemoveButtonProps().id;
|
|
483
|
+
const rawAriaLabel = getRemoveButtonProps()["aria-label"];
|
|
484
|
+
const rawAriaLabelledBy = getRemoveButtonProps()["aria-labelledby"];
|
|
485
|
+
const buttonId: string | undefined = typeof rawId === "string" ? rawId : undefined;
|
|
486
|
+
const ariaLabel: string = typeof rawAriaLabel === "string" ? rawAriaLabel : "Remove";
|
|
487
|
+
const ariaLabelledBy: string | undefined =
|
|
488
|
+
typeof rawAriaLabelledBy === "string" ? rawAriaLabelledBy : undefined;
|
|
489
|
+
|
|
490
|
+
const handleClick: JSX.EventHandler<HTMLButtonElement, MouseEvent> = (event) => {
|
|
491
|
+
event.stopPropagation();
|
|
492
|
+
const handler = getRemoveButtonProps().onPress;
|
|
493
|
+
if (typeof handler === "function" && !getIsDisabled()) {
|
|
494
|
+
(handler as () => void)();
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
const stopRowPress: JSX.EventHandler<HTMLButtonElement, PointerEvent> = (event) => {
|
|
498
|
+
event.stopPropagation();
|
|
499
|
+
};
|
|
500
|
+
|
|
408
501
|
return (
|
|
409
502
|
<button
|
|
410
503
|
type="button"
|
|
411
|
-
class={props.class ??
|
|
504
|
+
class={props.class ?? "solidaria-TagRemoveButton"}
|
|
412
505
|
style={props.style}
|
|
413
|
-
|
|
506
|
+
id={buttonId}
|
|
507
|
+
aria-label={ariaLabel}
|
|
508
|
+
aria-labelledby={ariaLabelledBy}
|
|
509
|
+
disabled={getIsDisabled()}
|
|
510
|
+
data-allows-removing={dataAttr(tagContext?.allowsRemoving ?? false)}
|
|
511
|
+
onPointerDown={stopRowPress}
|
|
512
|
+
onClick={handleClick}
|
|
414
513
|
>
|
|
415
|
-
{props.children ??
|
|
514
|
+
{props.children ?? "×"}
|
|
416
515
|
</button>
|
|
417
516
|
);
|
|
418
517
|
}
|
|
419
518
|
|
|
420
|
-
// Re-export types
|
|
421
519
|
export type { Key, SelectionMode, SelectionBehavior };
|
package/src/Text.tsx
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type JSX, createContext } from "solid-js";
|
|
2
|
+
import type { SlotProps } from "./utils";
|
|
3
|
+
|
|
4
|
+
export interface TextProps extends SlotProps {
|
|
5
|
+
children?: JSX.Element;
|
|
6
|
+
class?: string;
|
|
7
|
+
style?: JSX.CSSProperties;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const TextContext = createContext<null>(null);
|
|
11
|
+
|
|
12
|
+
export function Text(props: TextProps): JSX.Element {
|
|
13
|
+
return (
|
|
14
|
+
<span class={props.class ?? "solidaria-Text"} style={props.style}>
|
|
15
|
+
{props.children}
|
|
16
|
+
</span>
|
|
17
|
+
);
|
|
18
|
+
}
|