@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/Tabs.tsx
CHANGED
|
@@ -6,14 +6,18 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
+
type Accessor,
|
|
9
10
|
type JSX,
|
|
10
11
|
createContext,
|
|
12
|
+
createEffect,
|
|
11
13
|
createMemo,
|
|
14
|
+
createSignal,
|
|
12
15
|
splitProps,
|
|
13
16
|
useContext,
|
|
14
17
|
For,
|
|
15
18
|
Show,
|
|
16
|
-
|
|
19
|
+
onCleanup,
|
|
20
|
+
} from "solid-js";
|
|
17
21
|
import {
|
|
18
22
|
createTabList,
|
|
19
23
|
createTab,
|
|
@@ -23,14 +27,14 @@ import {
|
|
|
23
27
|
type AriaTabListProps,
|
|
24
28
|
type AriaTabProps,
|
|
25
29
|
type AriaTabPanelProps,
|
|
26
|
-
} from
|
|
30
|
+
} from "@proyecto-viviana/solidaria";
|
|
27
31
|
import {
|
|
28
32
|
createTabListState,
|
|
29
33
|
type TabListState,
|
|
30
34
|
type Key,
|
|
31
35
|
type TabOrientation,
|
|
32
36
|
type KeyboardActivation,
|
|
33
|
-
} from
|
|
37
|
+
} from "@proyecto-viviana/solid-stately";
|
|
34
38
|
import {
|
|
35
39
|
type RenderChildren,
|
|
36
40
|
type ClassNameOrFunction,
|
|
@@ -38,11 +42,20 @@ import {
|
|
|
38
42
|
type SlotProps,
|
|
39
43
|
useRenderProps,
|
|
40
44
|
filterDOMProps,
|
|
41
|
-
} from
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
} from "./utils";
|
|
46
|
+
import {
|
|
47
|
+
SelectionIndicator,
|
|
48
|
+
SelectionIndicatorContext,
|
|
49
|
+
type SelectionIndicatorContextValue,
|
|
50
|
+
} from "./SelectionIndicator";
|
|
51
|
+
import { SharedElementTransition } from "./SharedElementTransition";
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
SelectionIndicator,
|
|
55
|
+
SelectionIndicatorContext,
|
|
56
|
+
type SelectionIndicatorProps,
|
|
57
|
+
type SelectionIndicatorRenderProps,
|
|
58
|
+
} from "./SelectionIndicator";
|
|
46
59
|
|
|
47
60
|
export interface TabsRenderProps {
|
|
48
61
|
/** The orientation of the tabs. */
|
|
@@ -80,6 +93,8 @@ export interface TabsProps<T> extends SlotProps {
|
|
|
80
93
|
class?: ClassNameOrFunction<TabsRenderProps>;
|
|
81
94
|
/** The inline style for the element. */
|
|
82
95
|
style?: StyleOrFunction<TabsRenderProps>;
|
|
96
|
+
/** Ref for the root tabs element. */
|
|
97
|
+
ref?: RefLike<HTMLDivElement>;
|
|
83
98
|
}
|
|
84
99
|
|
|
85
100
|
export interface TabListRenderProps {
|
|
@@ -93,9 +108,11 @@ export interface TabListRenderProps {
|
|
|
93
108
|
isFocusVisible: boolean;
|
|
94
109
|
}
|
|
95
110
|
|
|
96
|
-
export interface TabListProps<T> extends Omit<AriaTabListProps,
|
|
97
|
-
/**
|
|
98
|
-
|
|
111
|
+
export interface TabListProps<T> extends Omit<AriaTabListProps, "children">, SlotProps {
|
|
112
|
+
/** Items to render in the tab list. */
|
|
113
|
+
items?: T[];
|
|
114
|
+
/** The children of the tab list - static tabs or a render function for each item. */
|
|
115
|
+
children?: JSX.Element | ((item: T) => JSX.Element);
|
|
99
116
|
/** The CSS className for the element. */
|
|
100
117
|
class?: ClassNameOrFunction<TabListRenderProps>;
|
|
101
118
|
/** The inline style for the element. */
|
|
@@ -117,7 +134,7 @@ export interface TabRenderProps {
|
|
|
117
134
|
isDisabled: boolean;
|
|
118
135
|
}
|
|
119
136
|
|
|
120
|
-
export interface TabProps extends Omit<AriaTabProps,
|
|
137
|
+
export interface TabProps extends Omit<AriaTabProps, "key">, SlotProps {
|
|
121
138
|
/** The unique key for the tab. */
|
|
122
139
|
id: Key;
|
|
123
140
|
/** The children of the tab. */
|
|
@@ -135,6 +152,14 @@ export interface TabPanelRenderProps {
|
|
|
135
152
|
isFocused: boolean;
|
|
136
153
|
/** Whether the panel has visible focus ring. */
|
|
137
154
|
isFocusVisible: boolean;
|
|
155
|
+
/** Whether the panel is non-interactive while force mounted. */
|
|
156
|
+
isInert: boolean;
|
|
157
|
+
/** Whether the panel is currently entering. */
|
|
158
|
+
isEntering: boolean;
|
|
159
|
+
/** Whether the panel is currently exiting. */
|
|
160
|
+
isExiting: boolean;
|
|
161
|
+
/** State of the tab list. */
|
|
162
|
+
state: TabListState<unknown> | null;
|
|
138
163
|
}
|
|
139
164
|
|
|
140
165
|
export interface TabPanelProps extends AriaTabPanelProps, SlotProps {
|
|
@@ -148,21 +173,63 @@ export interface TabPanelProps extends AriaTabPanelProps, SlotProps {
|
|
|
148
173
|
shouldForceMount?: boolean;
|
|
149
174
|
}
|
|
150
175
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
176
|
+
export interface TabPanelsProps extends SlotProps {
|
|
177
|
+
/** The grouped tab panels. */
|
|
178
|
+
children?: JSX.Element;
|
|
179
|
+
/** The CSS className for the element. */
|
|
180
|
+
class?: string;
|
|
181
|
+
/** The inline style for the element. */
|
|
182
|
+
style?: JSX.CSSProperties;
|
|
183
|
+
}
|
|
154
184
|
|
|
155
185
|
interface TabsContextValue<T> {
|
|
156
186
|
state: TabListState<T>;
|
|
157
|
-
items: T[]
|
|
187
|
+
items: Accessor<T[]>;
|
|
188
|
+
setTabListItems(items: T[] | undefined): void;
|
|
189
|
+
registerTab(tab: RegisteredTab): void;
|
|
190
|
+
unregisterTab(id: Key): void;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
type RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;
|
|
194
|
+
|
|
195
|
+
function assignRef<T>(ref: RefLike<T>, element: T): void {
|
|
196
|
+
if (!ref) return;
|
|
197
|
+
if (typeof ref === "function") {
|
|
198
|
+
ref(element);
|
|
199
|
+
} else if (typeof ref === "object" && "current" in ref) {
|
|
200
|
+
ref.current = element;
|
|
201
|
+
}
|
|
158
202
|
}
|
|
159
203
|
|
|
160
204
|
export const TabsContext = createContext<TabsContextValue<unknown> | null>(null);
|
|
161
205
|
export const TabsStateContext = createContext<TabListState<unknown> | null>(null);
|
|
162
206
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
207
|
+
interface RegisteredTab {
|
|
208
|
+
id: Key;
|
|
209
|
+
textValue?: string;
|
|
210
|
+
isDisabled?: boolean;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
interface CollectionItemLike {
|
|
214
|
+
id?: Key;
|
|
215
|
+
key?: Key;
|
|
216
|
+
label?: string;
|
|
217
|
+
textValue?: string;
|
|
218
|
+
isDisabled?: boolean;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function collectionItemKey<T>(item: T): Key {
|
|
222
|
+
const tab = item as CollectionItemLike;
|
|
223
|
+
const key = tab.id ?? tab.key;
|
|
224
|
+
if (key == null) {
|
|
225
|
+
throw new Error("Tabs collection items require an id or key.");
|
|
226
|
+
}
|
|
227
|
+
return key;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function staticTabText(tab: RegisteredTab): string {
|
|
231
|
+
return tab.textValue ?? String(tab.id);
|
|
232
|
+
}
|
|
166
233
|
|
|
167
234
|
/**
|
|
168
235
|
* Tabs provide a way to organize content into multiple sections, with only one section visible at a time.
|
|
@@ -170,23 +237,55 @@ export const TabsStateContext = createContext<TabListState<unknown> | null>(null
|
|
|
170
237
|
export function Tabs<T>(props: TabsProps<T>): JSX.Element {
|
|
171
238
|
const [local, stateProps, rest] = splitProps(
|
|
172
239
|
props,
|
|
173
|
-
[
|
|
174
|
-
[
|
|
240
|
+
["class", "style", "slot", "ref"],
|
|
241
|
+
[
|
|
242
|
+
"items",
|
|
243
|
+
"getKey",
|
|
244
|
+
"getTextValue",
|
|
245
|
+
"getDisabled",
|
|
246
|
+
"disabledKeys",
|
|
247
|
+
"selectedKey",
|
|
248
|
+
"defaultSelectedKey",
|
|
249
|
+
"onSelectionChange",
|
|
250
|
+
"isDisabled",
|
|
251
|
+
"keyboardActivation",
|
|
252
|
+
"orientation",
|
|
253
|
+
],
|
|
175
254
|
);
|
|
176
255
|
|
|
256
|
+
const [tabListItems, setTabListItems] = createSignal<T[] | undefined>(undefined);
|
|
257
|
+
const [registeredTabs, setRegisteredTabs] = createSignal<RegisteredTab[]>([]);
|
|
258
|
+
const effectiveItems = createMemo<T[]>(() => {
|
|
259
|
+
if (stateProps.items) return stateProps.items;
|
|
260
|
+
if (tabListItems()) return tabListItems() ?? [];
|
|
261
|
+
return registeredTabs() as T[];
|
|
262
|
+
});
|
|
263
|
+
|
|
177
264
|
// Create tab list state
|
|
178
265
|
const state = createTabListState<T>({
|
|
179
266
|
get items() {
|
|
180
|
-
return
|
|
267
|
+
return effectiveItems();
|
|
181
268
|
},
|
|
182
269
|
get getKey() {
|
|
183
|
-
return stateProps.getKey;
|
|
270
|
+
return stateProps.getKey ?? collectionItemKey;
|
|
184
271
|
},
|
|
185
272
|
get getTextValue() {
|
|
186
|
-
return
|
|
273
|
+
return (
|
|
274
|
+
stateProps.getTextValue ??
|
|
275
|
+
((item: T) => {
|
|
276
|
+
const tab = item as RegisteredTab & CollectionItemLike;
|
|
277
|
+
return tab.textValue ?? tab.label ?? staticTabText(tab);
|
|
278
|
+
})
|
|
279
|
+
);
|
|
187
280
|
},
|
|
188
281
|
get getDisabled() {
|
|
189
|
-
return
|
|
282
|
+
return (
|
|
283
|
+
stateProps.getDisabled ??
|
|
284
|
+
((item: T) => {
|
|
285
|
+
const tab = item as RegisteredTab & CollectionItemLike;
|
|
286
|
+
return tab.isDisabled ?? false;
|
|
287
|
+
})
|
|
288
|
+
);
|
|
190
289
|
},
|
|
191
290
|
get disabledKeys() {
|
|
192
291
|
return stateProps.disabledKeys;
|
|
@@ -211,31 +310,49 @@ export function Tabs<T>(props: TabsProps<T>): JSX.Element {
|
|
|
211
310
|
},
|
|
212
311
|
});
|
|
213
312
|
|
|
214
|
-
// Render props values
|
|
215
313
|
const renderValues = createMemo<TabsRenderProps>(() => ({
|
|
216
314
|
orientation: state.orientation(),
|
|
217
315
|
isDisabled: state.isDisabled(),
|
|
218
316
|
}));
|
|
219
317
|
|
|
220
|
-
// Resolve render props
|
|
221
318
|
const renderProps = useRenderProps(
|
|
222
319
|
{
|
|
223
320
|
class: local.class,
|
|
224
321
|
style: local.style,
|
|
225
322
|
children: props.children,
|
|
226
|
-
defaultClassName:
|
|
323
|
+
defaultClassName: "solidaria-Tabs",
|
|
227
324
|
},
|
|
228
|
-
renderValues
|
|
325
|
+
renderValues,
|
|
229
326
|
);
|
|
230
327
|
|
|
231
|
-
|
|
232
|
-
|
|
328
|
+
const domProps = createMemo(() =>
|
|
329
|
+
filterDOMProps(rest as Record<string, unknown>, { global: true }),
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
const contextValue: TabsContextValue<T> = {
|
|
333
|
+
state,
|
|
334
|
+
items: effectiveItems,
|
|
335
|
+
setTabListItems(items) {
|
|
336
|
+
setTabListItems(() => items);
|
|
337
|
+
},
|
|
338
|
+
registerTab(tab) {
|
|
339
|
+
setRegisteredTabs((current) => {
|
|
340
|
+
const next = current.filter((item) => item.id !== tab.id);
|
|
341
|
+
next.push(tab);
|
|
342
|
+
return next;
|
|
343
|
+
});
|
|
344
|
+
},
|
|
345
|
+
unregisterTab(id) {
|
|
346
|
+
setRegisteredTabs((current) => current.filter((item) => item.id !== id));
|
|
347
|
+
},
|
|
348
|
+
};
|
|
233
349
|
|
|
234
350
|
return (
|
|
235
|
-
<TabsContext.Provider value={
|
|
351
|
+
<TabsContext.Provider value={contextValue as TabsContextValue<unknown>}>
|
|
236
352
|
<TabsStateContext.Provider value={state}>
|
|
237
353
|
<div
|
|
238
354
|
{...domProps()}
|
|
355
|
+
ref={(element) => assignRef(local.ref, element)}
|
|
239
356
|
class={renderProps.class()}
|
|
240
357
|
style={renderProps.style()}
|
|
241
358
|
data-orientation={state.orientation()}
|
|
@@ -252,24 +369,21 @@ export function Tabs<T>(props: TabsProps<T>): JSX.Element {
|
|
|
252
369
|
* A TabList contains Tab elements that represent the available tabs.
|
|
253
370
|
*/
|
|
254
371
|
export function TabList<T>(props: TabListProps<T>): JSX.Element {
|
|
255
|
-
const [local, ariaProps] = splitProps(
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
372
|
+
const [local, collectionProps, ariaProps] = splitProps(
|
|
373
|
+
props,
|
|
374
|
+
["class", "style", "slot"],
|
|
375
|
+
["items"],
|
|
376
|
+
);
|
|
260
377
|
|
|
261
|
-
// Get state from context
|
|
262
378
|
const context = useContext(TabsContext);
|
|
263
379
|
|
|
264
380
|
return (
|
|
265
|
-
<Show
|
|
266
|
-
when={context}
|
|
267
|
-
fallback={<div class="solidaria-TabList" role="tablist" />}
|
|
268
|
-
>
|
|
381
|
+
<Show when={context} fallback={<div class="solidaria-TabList" role="tablist" />}>
|
|
269
382
|
{(ctx) => (
|
|
270
383
|
<TabListInner
|
|
271
384
|
context={ctx()}
|
|
272
385
|
local={local}
|
|
386
|
+
items={collectionProps.items}
|
|
273
387
|
ariaProps={ariaProps}
|
|
274
388
|
children={props.children}
|
|
275
389
|
/>
|
|
@@ -281,20 +395,50 @@ export function TabList<T>(props: TabListProps<T>): JSX.Element {
|
|
|
281
395
|
/** Inner TabList component that has access to context */
|
|
282
396
|
function TabListInner<T>(props: {
|
|
283
397
|
context: TabsContextValue<unknown>;
|
|
284
|
-
local: {
|
|
285
|
-
|
|
286
|
-
|
|
398
|
+
local: {
|
|
399
|
+
class?: ClassNameOrFunction<TabListRenderProps>;
|
|
400
|
+
style?: StyleOrFunction<TabListRenderProps>;
|
|
401
|
+
slot?: string;
|
|
402
|
+
};
|
|
403
|
+
ariaProps: Omit<TabListProps<T>, "children" | "class" | "style" | "slot" | "items">;
|
|
404
|
+
items?: T[];
|
|
405
|
+
children?: JSX.Element | ((item: T) => JSX.Element);
|
|
287
406
|
}): JSX.Element {
|
|
288
407
|
const state = props.context.state as TabListState<T>;
|
|
289
|
-
const items = props.context.items as T[]
|
|
408
|
+
const items = props.context.items as Accessor<T[]>;
|
|
409
|
+
const renderItem = createMemo(() => {
|
|
410
|
+
if (typeof props.children !== "function") {
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const child = props.children as (...args: unknown[]) => JSX.Element;
|
|
415
|
+
if (child.length === 0 && props.items === undefined) {
|
|
416
|
+
return undefined;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return props.children as (item: T) => JSX.Element;
|
|
420
|
+
});
|
|
421
|
+
const renderedChildren = createMemo(() => {
|
|
422
|
+
if (renderItem() || typeof props.children !== "function") {
|
|
423
|
+
return props.children as JSX.Element;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return (props.children as () => JSX.Element)();
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
createEffect(() => {
|
|
430
|
+
props.context.setTabListItems(props.items as unknown[] | undefined);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
onCleanup(() => {
|
|
434
|
+
props.context.setTabListItems(undefined);
|
|
435
|
+
});
|
|
290
436
|
|
|
291
437
|
// Create tab list aria props
|
|
292
438
|
const { tabListProps } = createTabList<T>(props.ariaProps as AriaTabListProps, state);
|
|
293
439
|
|
|
294
|
-
// Create focus ring
|
|
295
440
|
const { isFocused, isFocusVisible, focusProps } = createFocusRing();
|
|
296
441
|
|
|
297
|
-
// Render props values
|
|
298
442
|
const renderValues = createMemo<TabListRenderProps>(() => ({
|
|
299
443
|
orientation: state.orientation(),
|
|
300
444
|
isDisabled: state.isDisabled(),
|
|
@@ -302,26 +446,35 @@ function TabListInner<T>(props: {
|
|
|
302
446
|
isFocusVisible: isFocusVisible(),
|
|
303
447
|
}));
|
|
304
448
|
|
|
305
|
-
// Resolve render props
|
|
306
449
|
const renderProps = useRenderProps(
|
|
307
450
|
{
|
|
308
451
|
class: props.local.class,
|
|
309
452
|
style: props.local.style,
|
|
310
|
-
defaultClassName:
|
|
453
|
+
defaultClassName: "solidaria-TabList",
|
|
311
454
|
},
|
|
312
|
-
renderValues
|
|
455
|
+
renderValues,
|
|
313
456
|
);
|
|
314
457
|
|
|
315
458
|
// Helper to safely call event handlers that may be bound tuples
|
|
316
459
|
const callHandler = <E extends Event>(
|
|
317
|
-
handler:
|
|
318
|
-
event: E
|
|
460
|
+
handler: JSX.EventHandlerUnion<HTMLElement, E> | undefined,
|
|
461
|
+
event: E,
|
|
319
462
|
) => {
|
|
320
463
|
if (!handler) return;
|
|
321
464
|
if (Array.isArray(handler)) {
|
|
322
465
|
handler[1].call(handler[0], event);
|
|
323
|
-
|
|
324
|
-
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
if (typeof handler === "function") {
|
|
469
|
+
(handler as (evt: E) => void)(event);
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
if (
|
|
473
|
+
typeof handler === "object" &&
|
|
474
|
+
"handleEvent" in handler &&
|
|
475
|
+
typeof handler.handleEvent === "function"
|
|
476
|
+
) {
|
|
477
|
+
(handler.handleEvent as (evt: E) => void)(event);
|
|
325
478
|
}
|
|
326
479
|
};
|
|
327
480
|
|
|
@@ -332,21 +485,21 @@ function TabListInner<T>(props: {
|
|
|
332
485
|
|
|
333
486
|
const handleFocus = (e: FocusEvent) => {
|
|
334
487
|
tabListProps.onFocus(e);
|
|
335
|
-
callHandler(focusProps.onFocus
|
|
488
|
+
callHandler(focusProps.onFocus, e);
|
|
336
489
|
};
|
|
337
490
|
|
|
338
491
|
const handleBlur = (e: FocusEvent) => {
|
|
339
492
|
tabListProps.onBlur(e);
|
|
340
|
-
callHandler(focusProps.onBlur
|
|
493
|
+
callHandler(focusProps.onBlur, e);
|
|
341
494
|
};
|
|
342
495
|
|
|
343
496
|
return (
|
|
344
497
|
<div
|
|
345
498
|
role={tabListProps.role}
|
|
346
|
-
aria-orientation={tabListProps[
|
|
347
|
-
aria-label={tabListProps[
|
|
348
|
-
aria-labelledby={tabListProps[
|
|
349
|
-
aria-describedby={tabListProps[
|
|
499
|
+
aria-orientation={tabListProps["aria-orientation"]}
|
|
500
|
+
aria-label={tabListProps["aria-label"]}
|
|
501
|
+
aria-labelledby={tabListProps["aria-labelledby"]}
|
|
502
|
+
aria-describedby={tabListProps["aria-describedby"]}
|
|
350
503
|
class={renderProps.class()}
|
|
351
504
|
style={renderProps.style()}
|
|
352
505
|
onKeyDown={handleKeyDown}
|
|
@@ -357,7 +510,13 @@ function TabListInner<T>(props: {
|
|
|
357
510
|
data-orientation={state.orientation()}
|
|
358
511
|
data-disabled={state.isDisabled() || undefined}
|
|
359
512
|
>
|
|
360
|
-
|
|
513
|
+
{renderItem() ? (
|
|
514
|
+
<SharedElementTransition>
|
|
515
|
+
<For each={(props.items ?? items()) as T[]}>{(item) => renderItem()?.(item)}</For>
|
|
516
|
+
</SharedElementTransition>
|
|
517
|
+
) : (
|
|
518
|
+
renderedChildren()
|
|
519
|
+
)}
|
|
361
520
|
</div>
|
|
362
521
|
);
|
|
363
522
|
}
|
|
@@ -366,24 +525,17 @@ function TabListInner<T>(props: {
|
|
|
366
525
|
* A Tab represents an individual tab in a TabList.
|
|
367
526
|
*/
|
|
368
527
|
export function Tab(props: TabProps): JSX.Element {
|
|
369
|
-
const [local, ariaProps] = splitProps(props, [
|
|
370
|
-
|
|
371
|
-
'style',
|
|
372
|
-
'slot',
|
|
373
|
-
'id',
|
|
374
|
-
]);
|
|
375
|
-
|
|
376
|
-
// Get state from context
|
|
528
|
+
const [local, ariaProps] = splitProps(props, ["class", "style", "slot", "id"]);
|
|
529
|
+
|
|
377
530
|
const context = useContext(TabsStateContext);
|
|
531
|
+
const tabsContext = useContext(TabsContext);
|
|
378
532
|
|
|
379
533
|
return (
|
|
380
|
-
<Show
|
|
381
|
-
when={context}
|
|
382
|
-
fallback={<div class="solidaria-Tab" role="tab" />}
|
|
383
|
-
>
|
|
534
|
+
<Show when={context} fallback={<div class="solidaria-Tab" role="tab" />}>
|
|
384
535
|
{(state) => (
|
|
385
536
|
<TabInner
|
|
386
537
|
state={state()}
|
|
538
|
+
tabsContext={tabsContext}
|
|
387
539
|
local={local}
|
|
388
540
|
ariaProps={ariaProps}
|
|
389
541
|
children={props.children}
|
|
@@ -396,10 +548,34 @@ export function Tab(props: TabProps): JSX.Element {
|
|
|
396
548
|
/** Inner Tab component that has access to context */
|
|
397
549
|
function TabInner(props: {
|
|
398
550
|
state: TabListState<unknown>;
|
|
399
|
-
|
|
400
|
-
|
|
551
|
+
tabsContext: TabsContextValue<unknown> | null;
|
|
552
|
+
local: {
|
|
553
|
+
class?: ClassNameOrFunction<TabRenderProps>;
|
|
554
|
+
style?: StyleOrFunction<TabRenderProps>;
|
|
555
|
+
slot?: string;
|
|
556
|
+
id: Key;
|
|
557
|
+
};
|
|
558
|
+
ariaProps: Omit<TabProps, "children" | "class" | "style" | "slot" | "id">;
|
|
401
559
|
children?: RenderChildren<TabRenderProps>;
|
|
402
560
|
}): JSX.Element {
|
|
561
|
+
let tabRef: HTMLDivElement | undefined;
|
|
562
|
+
const textValue = () => {
|
|
563
|
+
if (props.ariaProps["aria-label"]) return props.ariaProps["aria-label"];
|
|
564
|
+
return typeof props.children === "string" ? props.children : undefined;
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
createEffect(() => {
|
|
568
|
+
props.tabsContext?.registerTab({
|
|
569
|
+
id: props.local.id,
|
|
570
|
+
textValue: textValue(),
|
|
571
|
+
isDisabled: props.ariaProps.isDisabled,
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
onCleanup(() => {
|
|
576
|
+
props.tabsContext?.unregisterTab(props.local.id);
|
|
577
|
+
});
|
|
578
|
+
|
|
403
579
|
// Create tab aria props
|
|
404
580
|
const tabAria = createTab<unknown>(
|
|
405
581
|
{
|
|
@@ -407,21 +583,23 @@ function TabInner(props: {
|
|
|
407
583
|
get isDisabled() {
|
|
408
584
|
return props.ariaProps.isDisabled;
|
|
409
585
|
},
|
|
410
|
-
get
|
|
411
|
-
return props.ariaProps[
|
|
586
|
+
get "aria-label"() {
|
|
587
|
+
return props.ariaProps["aria-label"];
|
|
588
|
+
},
|
|
589
|
+
get "aria-labelledby"() {
|
|
590
|
+
return props.ariaProps["aria-labelledby"];
|
|
412
591
|
},
|
|
413
592
|
},
|
|
414
|
-
props.state
|
|
593
|
+
props.state,
|
|
594
|
+
() => tabRef ?? null,
|
|
415
595
|
);
|
|
416
596
|
|
|
417
|
-
// Create hover
|
|
418
597
|
const { isHovered, hoverProps } = createHover({
|
|
419
598
|
get isDisabled() {
|
|
420
599
|
return tabAria.isDisabled();
|
|
421
600
|
},
|
|
422
601
|
});
|
|
423
602
|
|
|
424
|
-
// Render props values
|
|
425
603
|
const renderValues = createMemo<TabRenderProps>(() => ({
|
|
426
604
|
isSelected: tabAria.isSelected(),
|
|
427
605
|
isFocused: tabAria.isFocused(),
|
|
@@ -431,42 +609,112 @@ function TabInner(props: {
|
|
|
431
609
|
isDisabled: tabAria.isDisabled(),
|
|
432
610
|
}));
|
|
433
611
|
|
|
434
|
-
// Resolve render props
|
|
435
612
|
const renderProps = useRenderProps(
|
|
436
613
|
{
|
|
437
614
|
children: props.children,
|
|
438
615
|
class: props.local.class,
|
|
439
616
|
style: props.local.style,
|
|
440
|
-
defaultClassName:
|
|
617
|
+
defaultClassName: "solidaria-Tab",
|
|
441
618
|
},
|
|
442
|
-
renderValues
|
|
619
|
+
renderValues,
|
|
620
|
+
);
|
|
621
|
+
|
|
622
|
+
const selectionIndicatorContext = createMemo<SelectionIndicatorContextValue>(() => ({
|
|
623
|
+
isSelected: tabAria.isSelected,
|
|
624
|
+
}));
|
|
625
|
+
|
|
626
|
+
return (
|
|
627
|
+
<SelectionIndicatorContext.Provider value={selectionIndicatorContext()}>
|
|
628
|
+
<div
|
|
629
|
+
ref={tabRef}
|
|
630
|
+
id={tabAria.tabProps.id}
|
|
631
|
+
role={tabAria.tabProps.role}
|
|
632
|
+
aria-selected={tabAria.isSelected()}
|
|
633
|
+
aria-disabled={tabAria.isDisabled() || undefined}
|
|
634
|
+
aria-controls={tabAria.isSelected() ? tabAria.tabProps["aria-controls"] : undefined}
|
|
635
|
+
aria-label={tabAria.tabProps["aria-label"]}
|
|
636
|
+
aria-labelledby={tabAria.tabProps["aria-labelledby"]}
|
|
637
|
+
tabIndex={tabAria.isSelected() && !tabAria.isDisabled() ? 0 : -1}
|
|
638
|
+
class={renderProps.class()}
|
|
639
|
+
style={renderProps.style()}
|
|
640
|
+
onKeyDown={tabAria.tabProps.onKeyDown}
|
|
641
|
+
onMouseDown={tabAria.tabProps.onMouseDown}
|
|
642
|
+
onPointerDown={tabAria.tabProps.onPointerDown}
|
|
643
|
+
onClick={tabAria.tabProps.onClick}
|
|
644
|
+
onFocus={tabAria.tabProps.onFocus}
|
|
645
|
+
{...hoverProps}
|
|
646
|
+
data-selected={tabAria.isSelected() || undefined}
|
|
647
|
+
data-focused={tabAria.isFocused() || undefined}
|
|
648
|
+
data-focus-visible={tabAria.isFocusVisible() || undefined}
|
|
649
|
+
data-pressed={tabAria.isPressed() || undefined}
|
|
650
|
+
data-hovered={isHovered() || undefined}
|
|
651
|
+
data-disabled={tabAria.isDisabled() || undefined}
|
|
652
|
+
>
|
|
653
|
+
{renderProps.renderChildren()}
|
|
654
|
+
</div>
|
|
655
|
+
</SelectionIndicatorContext.Provider>
|
|
443
656
|
);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Groups multiple TabPanel elements.
|
|
661
|
+
*/
|
|
662
|
+
export function TabPanels(props: TabPanelsProps): JSX.Element {
|
|
663
|
+
const [local, rest] = splitProps(props, ["class", "style", "slot", "children"]);
|
|
664
|
+
const domProps = createMemo(() =>
|
|
665
|
+
filterDOMProps(rest as Record<string, unknown>, { global: true }),
|
|
666
|
+
);
|
|
667
|
+
const state = useContext(TabsStateContext);
|
|
668
|
+
let ref: HTMLDivElement | undefined;
|
|
669
|
+
let previousSelectedKey: Key | null | undefined = undefined;
|
|
670
|
+
const [panelSize, setPanelSize] = createSignal<{ width?: string; height?: string }>({});
|
|
671
|
+
|
|
672
|
+
createEffect(() => {
|
|
673
|
+
const selectedKey = state?.selectedKey() ?? null;
|
|
674
|
+
if (!ref) {
|
|
675
|
+
previousSelectedKey = selectedKey;
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
if (previousSelectedKey === undefined) {
|
|
680
|
+
previousSelectedKey = selectedKey;
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
if (previousSelectedKey === selectedKey) return;
|
|
685
|
+
previousSelectedKey = selectedKey;
|
|
686
|
+
|
|
687
|
+
const transition = window.getComputedStyle(ref).transition;
|
|
688
|
+
const shouldMeasureWidth = /width|inline-size|all/.test(transition);
|
|
689
|
+
const shouldMeasureHeight = /height|block-size|all/.test(transition);
|
|
690
|
+
if (!shouldMeasureWidth && !shouldMeasureHeight) return;
|
|
691
|
+
|
|
692
|
+
const selectedPanel = ref.querySelector<HTMLElement>('[role="tabpanel"]:not([hidden])');
|
|
693
|
+
if (!selectedPanel) return;
|
|
694
|
+
|
|
695
|
+
setPanelSize({
|
|
696
|
+
width: shouldMeasureWidth ? `${selectedPanel.offsetWidth}px` : undefined,
|
|
697
|
+
height: shouldMeasureHeight ? `${selectedPanel.offsetHeight}px` : undefined,
|
|
698
|
+
});
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
const mergedStyle = (): JSX.CSSProperties =>
|
|
702
|
+
({
|
|
703
|
+
...local.style,
|
|
704
|
+
...(panelSize().width ? { "--tab-panel-width": panelSize().width } : {}),
|
|
705
|
+
...(panelSize().height ? { "--tab-panel-height": panelSize().height } : {}),
|
|
706
|
+
}) as JSX.CSSProperties;
|
|
444
707
|
|
|
445
708
|
return (
|
|
446
709
|
<div
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
tabIndex={tabAria.isSelected() && !tabAria.isDisabled() ? 0 : -1}
|
|
454
|
-
class={renderProps.class()}
|
|
455
|
-
style={renderProps.style()}
|
|
456
|
-
onKeyDown={tabAria.tabProps.onKeyDown}
|
|
457
|
-
onMouseDown={tabAria.tabProps.onMouseDown}
|
|
458
|
-
onPointerDown={tabAria.tabProps.onPointerDown}
|
|
459
|
-
onClick={tabAria.tabProps.onClick}
|
|
460
|
-
onFocus={tabAria.tabProps.onFocus}
|
|
461
|
-
{...hoverProps}
|
|
462
|
-
data-selected={tabAria.isSelected() || undefined}
|
|
463
|
-
data-focused={tabAria.isFocused() || undefined}
|
|
464
|
-
data-focus-visible={tabAria.isFocusVisible() || undefined}
|
|
465
|
-
data-pressed={tabAria.isPressed() || undefined}
|
|
466
|
-
data-hovered={isHovered() || undefined}
|
|
467
|
-
data-disabled={tabAria.isDisabled() || undefined}
|
|
710
|
+
{...domProps()}
|
|
711
|
+
ref={(el) => {
|
|
712
|
+
ref = el;
|
|
713
|
+
}}
|
|
714
|
+
class={local.class ?? "solidaria-TabPanels"}
|
|
715
|
+
style={mergedStyle()}
|
|
468
716
|
>
|
|
469
|
-
{
|
|
717
|
+
{local.children}
|
|
470
718
|
</div>
|
|
471
719
|
);
|
|
472
720
|
}
|
|
@@ -475,12 +723,7 @@ function TabInner(props: {
|
|
|
475
723
|
* A TabPanel displays the content for a selected Tab.
|
|
476
724
|
*/
|
|
477
725
|
export function TabPanel(props: TabPanelProps): JSX.Element {
|
|
478
|
-
const [local, ariaProps] = splitProps(props, [
|
|
479
|
-
'class',
|
|
480
|
-
'style',
|
|
481
|
-
'slot',
|
|
482
|
-
'shouldForceMount',
|
|
483
|
-
]);
|
|
726
|
+
const [local, ariaProps] = splitProps(props, ["class", "style", "slot", "shouldForceMount"]);
|
|
484
727
|
|
|
485
728
|
// Get state from context (may be null for SSR scenarios)
|
|
486
729
|
const state = useContext(TabsStateContext);
|
|
@@ -490,23 +733,29 @@ export function TabPanel(props: TabPanelProps): JSX.Element {
|
|
|
490
733
|
|
|
491
734
|
// Create focus ring for the panel
|
|
492
735
|
const { isFocused, isFocusVisible, focusProps } = createFocusRing();
|
|
736
|
+
const isInert = () =>
|
|
737
|
+
Boolean(local.shouldForceMount && ariaProps.id !== undefined && !isSelected());
|
|
738
|
+
const isEntering = () => false;
|
|
739
|
+
const isExiting = () => false;
|
|
493
740
|
|
|
494
|
-
// Render props values
|
|
495
741
|
const renderValues = createMemo<TabPanelRenderProps>(() => ({
|
|
496
742
|
isSelected: isSelected(),
|
|
497
743
|
isFocused: isFocused(),
|
|
498
744
|
isFocusVisible: isFocusVisible(),
|
|
745
|
+
isInert: isInert(),
|
|
746
|
+
isEntering: isEntering(),
|
|
747
|
+
isExiting: isExiting(),
|
|
748
|
+
state,
|
|
499
749
|
}));
|
|
500
750
|
|
|
501
|
-
// Resolve render props
|
|
502
751
|
const renderProps = useRenderProps(
|
|
503
752
|
{
|
|
504
753
|
children: props.children,
|
|
505
754
|
class: local.class,
|
|
506
755
|
style: local.style,
|
|
507
|
-
defaultClassName:
|
|
756
|
+
defaultClassName: "solidaria-TabPanel",
|
|
508
757
|
},
|
|
509
|
-
renderValues
|
|
758
|
+
renderValues,
|
|
510
759
|
);
|
|
511
760
|
|
|
512
761
|
// Determine if we should render the panel
|
|
@@ -515,7 +764,6 @@ export function TabPanel(props: TabPanelProps): JSX.Element {
|
|
|
515
764
|
const shouldRender = () => {
|
|
516
765
|
if (local.shouldForceMount) return true;
|
|
517
766
|
if (ariaProps.id === undefined) {
|
|
518
|
-
// Shared panel pattern - render when any tab is selected
|
|
519
767
|
return state ? state.selectedKey() !== null : true;
|
|
520
768
|
}
|
|
521
769
|
return isSelected();
|
|
@@ -526,9 +774,9 @@ export function TabPanel(props: TabPanelProps): JSX.Element {
|
|
|
526
774
|
<div
|
|
527
775
|
id={tabPanelProps.id}
|
|
528
776
|
role={tabPanelProps.role}
|
|
529
|
-
aria-labelledby={tabPanelProps[
|
|
530
|
-
aria-label={tabPanelProps[
|
|
531
|
-
aria-describedby={tabPanelProps[
|
|
777
|
+
aria-labelledby={tabPanelProps["aria-labelledby"]}
|
|
778
|
+
aria-label={tabPanelProps["aria-label"]}
|
|
779
|
+
aria-describedby={tabPanelProps["aria-describedby"]}
|
|
532
780
|
tabIndex={tabPanelProps.tabIndex}
|
|
533
781
|
class={renderProps.class()}
|
|
534
782
|
style={renderProps.style()}
|
|
@@ -537,8 +785,13 @@ export function TabPanel(props: TabPanelProps): JSX.Element {
|
|
|
537
785
|
data-selected={isSelected() || undefined}
|
|
538
786
|
data-focused={isFocused() || undefined}
|
|
539
787
|
data-focus-visible={isFocusVisible() || undefined}
|
|
540
|
-
inert={
|
|
541
|
-
|
|
788
|
+
inert={isInert() ? true : undefined}
|
|
789
|
+
data-inert={isInert() || undefined}
|
|
790
|
+
data-entering={isEntering() || undefined}
|
|
791
|
+
data-exiting={isExiting() || undefined}
|
|
792
|
+
hidden={
|
|
793
|
+
ariaProps.id !== undefined && !isSelected() && !local.shouldForceMount ? true : undefined
|
|
794
|
+
}
|
|
542
795
|
>
|
|
543
796
|
{renderProps.renderChildren()}
|
|
544
797
|
</div>
|
|
@@ -546,7 +799,8 @@ export function TabPanel(props: TabPanelProps): JSX.Element {
|
|
|
546
799
|
);
|
|
547
800
|
}
|
|
548
801
|
|
|
549
|
-
// Attach sub-components
|
|
550
802
|
Tabs.List = TabList;
|
|
551
803
|
Tabs.Tab = Tab;
|
|
804
|
+
Tabs.Panels = TabPanels;
|
|
552
805
|
Tabs.Panel = TabPanel;
|
|
806
|
+
Tabs.SelectionIndicator = SelectionIndicator;
|