@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
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createContext, useContext } from "solid-js";
|
|
2
|
+
import { type createDateRangePicker } from "@proyecto-viviana/solidaria";
|
|
3
|
+
import {
|
|
4
|
+
type DateFieldState,
|
|
5
|
+
type DateValue,
|
|
6
|
+
type RangeCalendarState,
|
|
7
|
+
} from "@proyecto-viviana/solid-stately";
|
|
8
|
+
|
|
9
|
+
export interface DateRangePickerFieldContextValue {
|
|
10
|
+
state: DateFieldState<DateValue>;
|
|
11
|
+
aria: {
|
|
12
|
+
labelProps: Record<string, unknown>;
|
|
13
|
+
inputProps: Record<string, unknown>;
|
|
14
|
+
descriptionProps: Record<string, unknown>;
|
|
15
|
+
errorMessageProps: Record<string, unknown>;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface DateRangePickerContextValue {
|
|
20
|
+
calendarState: RangeCalendarState<DateValue>;
|
|
21
|
+
startFieldState: DateFieldState<DateValue>;
|
|
22
|
+
endFieldState: DateFieldState<DateValue>;
|
|
23
|
+
startFieldContext: DateRangePickerFieldContextValue;
|
|
24
|
+
endFieldContext: DateRangePickerFieldContextValue;
|
|
25
|
+
overlayState: {
|
|
26
|
+
isOpen: boolean;
|
|
27
|
+
open: () => void;
|
|
28
|
+
close: () => void;
|
|
29
|
+
toggle: () => void;
|
|
30
|
+
};
|
|
31
|
+
triggerRef: () => HTMLElement | null;
|
|
32
|
+
setTriggerRef: (element: HTMLElement | null) => void;
|
|
33
|
+
pickerAria: ReturnType<typeof createDateRangePicker>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const DateRangePickerContext = createContext<DateRangePickerContextValue | null>(null);
|
|
37
|
+
|
|
38
|
+
export function useDateRangePickerContext(): DateRangePickerContextValue {
|
|
39
|
+
const context = useContext(DateRangePickerContext);
|
|
40
|
+
if (!context) {
|
|
41
|
+
throw new Error("DateRangePicker components must be used within a DateRangePicker");
|
|
42
|
+
}
|
|
43
|
+
return context;
|
|
44
|
+
}
|
package/src/Dialog.tsx
CHANGED
|
@@ -8,20 +8,25 @@
|
|
|
8
8
|
import {
|
|
9
9
|
type JSX,
|
|
10
10
|
createContext,
|
|
11
|
+
createEffect,
|
|
11
12
|
createMemo,
|
|
12
13
|
createUniqueId,
|
|
13
14
|
splitProps,
|
|
14
15
|
useContext,
|
|
15
16
|
Switch,
|
|
16
17
|
Match,
|
|
17
|
-
} from
|
|
18
|
+
} from "solid-js";
|
|
18
19
|
import {
|
|
19
20
|
createDialog,
|
|
20
21
|
createOverlayTrigger,
|
|
22
|
+
focusSafely,
|
|
21
23
|
type AriaDialogProps,
|
|
22
|
-
} from
|
|
23
|
-
import {
|
|
24
|
-
|
|
24
|
+
} from "@proyecto-viviana/solidaria";
|
|
25
|
+
import {
|
|
26
|
+
createOverlayTriggerState,
|
|
27
|
+
type OverlayTriggerState,
|
|
28
|
+
} from "@proyecto-viviana/solid-stately";
|
|
29
|
+
import { DialogTriggerContext, useOverlayTriggerState } from "./contexts";
|
|
25
30
|
import {
|
|
26
31
|
type RenderChildren,
|
|
27
32
|
type ClassNameOrFunction,
|
|
@@ -29,171 +34,206 @@ import {
|
|
|
29
34
|
type SlotProps,
|
|
30
35
|
useRenderProps,
|
|
31
36
|
filterDOMProps,
|
|
32
|
-
} from
|
|
33
|
-
|
|
34
|
-
// ============================================
|
|
35
|
-
// TYPES
|
|
36
|
-
// ============================================
|
|
37
|
+
} from "./utils";
|
|
37
38
|
|
|
38
39
|
export interface DialogRenderProps {
|
|
39
40
|
/** Function to close the dialog */
|
|
40
|
-
close: () => void
|
|
41
|
+
close: () => void;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
export interface DialogProps extends Omit<AriaDialogProps,
|
|
44
|
+
export interface DialogProps extends Omit<AriaDialogProps, "class" | "style">, SlotProps {
|
|
44
45
|
/** The children of the component - can be JSX or render function. */
|
|
45
|
-
children?: RenderChildren<DialogRenderProps
|
|
46
|
+
children?: RenderChildren<DialogRenderProps>;
|
|
46
47
|
/** The CSS className for the element. */
|
|
47
|
-
class?: ClassNameOrFunction<DialogRenderProps
|
|
48
|
+
class?: ClassNameOrFunction<DialogRenderProps>;
|
|
48
49
|
/** The inline style for the element. */
|
|
49
|
-
style?: StyleOrFunction<DialogRenderProps
|
|
50
|
+
style?: StyleOrFunction<DialogRenderProps>;
|
|
50
51
|
/** Callback when dialog should close */
|
|
51
|
-
onClose?: () => void
|
|
52
|
+
onClose?: () => void;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
export interface DialogTriggerProps {
|
|
55
56
|
/** The children - should include a trigger and modal/popover content. */
|
|
56
|
-
children: JSX.Element
|
|
57
|
+
children: JSX.Element;
|
|
57
58
|
/** Whether the dialog is open (controlled). */
|
|
58
|
-
isOpen?: boolean
|
|
59
|
+
isOpen?: boolean;
|
|
59
60
|
/** Whether the dialog is open by default (uncontrolled). */
|
|
60
|
-
defaultOpen?: boolean
|
|
61
|
+
defaultOpen?: boolean;
|
|
61
62
|
/** Callback when open state changes. */
|
|
62
|
-
onOpenChange?: (isOpen: boolean) => void
|
|
63
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
// ============================================
|
|
66
|
-
// CONTEXTS
|
|
67
|
-
// ============================================
|
|
68
|
-
|
|
69
66
|
interface DialogContextValue {
|
|
70
|
-
close: () => void
|
|
71
|
-
titleId?: string
|
|
67
|
+
close: () => void;
|
|
68
|
+
titleId?: string;
|
|
72
69
|
}
|
|
73
70
|
|
|
74
|
-
export const DialogContext = createContext<DialogContextValue | null>(null)
|
|
71
|
+
export const DialogContext = createContext<DialogContextValue | null>(null);
|
|
75
72
|
|
|
76
|
-
|
|
77
|
-
export { DialogTriggerContext, useDialogTrigger } from './contexts'
|
|
78
|
-
|
|
79
|
-
// ============================================
|
|
80
|
-
// DIALOG TRIGGER COMPONENT
|
|
81
|
-
// ============================================
|
|
73
|
+
export { DialogTriggerContext, useDialogTrigger } from "./contexts";
|
|
82
74
|
|
|
83
75
|
/**
|
|
84
76
|
* A DialogTrigger opens a dialog when a trigger element is pressed.
|
|
85
77
|
* Children should include a trigger element (e.g. Button) and the dialog content.
|
|
86
78
|
*/
|
|
87
79
|
export function DialogTrigger(props: DialogTriggerProps): JSX.Element {
|
|
88
|
-
const [local] = splitProps(props, [
|
|
80
|
+
const [local] = splitProps(props, ["isOpen", "defaultOpen", "onOpenChange"]);
|
|
89
81
|
|
|
90
|
-
// Create overlay trigger state
|
|
91
82
|
const state = createOverlayTriggerState({
|
|
92
83
|
get isOpen() {
|
|
93
|
-
return local.isOpen
|
|
84
|
+
return local.isOpen;
|
|
94
85
|
},
|
|
95
86
|
get defaultOpen() {
|
|
96
|
-
return local.defaultOpen
|
|
87
|
+
return local.defaultOpen;
|
|
97
88
|
},
|
|
98
89
|
onOpenChange: local.onOpenChange,
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
let triggerRef: HTMLElement | null = null;
|
|
93
|
+
const triggerId = createUniqueId();
|
|
94
|
+
|
|
95
|
+
// Create overlay trigger props so registered trigger components can expose
|
|
96
|
+
// the same expanded/controls relationship as React Aria DialogTrigger.
|
|
97
|
+
const triggerAria = createOverlayTrigger({ type: "dialog" }, state, () => triggerRef);
|
|
98
|
+
|
|
99
|
+
const restoreFocusToTrigger = () => {
|
|
100
|
+
const trigger = triggerRef;
|
|
101
|
+
if (!trigger?.isConnected) return;
|
|
102
|
+
|
|
103
|
+
const win = trigger.ownerDocument.defaultView ?? window;
|
|
104
|
+
win.requestAnimationFrame(() => {
|
|
105
|
+
win.requestAnimationFrame(() => {
|
|
106
|
+
if (trigger.isConnected && !state.isOpen()) {
|
|
107
|
+
focusSafely(trigger);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const stateWithFocusRestore: OverlayTriggerState = {
|
|
114
|
+
isOpen: state.isOpen,
|
|
115
|
+
setOpen: (isOpen) => {
|
|
116
|
+
state.setOpen(isOpen);
|
|
117
|
+
if (!isOpen) {
|
|
118
|
+
restoreFocusToTrigger();
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
open: state.open,
|
|
122
|
+
close: () => {
|
|
123
|
+
state.close();
|
|
124
|
+
restoreFocusToTrigger();
|
|
125
|
+
},
|
|
126
|
+
toggle: () => {
|
|
127
|
+
const wasOpen = state.isOpen();
|
|
128
|
+
state.toggle();
|
|
129
|
+
if (wasOpen) {
|
|
130
|
+
restoreFocusToTrigger();
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
};
|
|
104
134
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
135
|
+
const setTriggerRef = (el: HTMLElement | null) => {
|
|
136
|
+
if (!el) return;
|
|
137
|
+
if (!triggerRef || !triggerRef.isConnected) {
|
|
138
|
+
triggerRef = el;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
111
141
|
|
|
112
142
|
// Context value - memoized to avoid unnecessary re-renders
|
|
113
143
|
const contextValue = createMemo(() => ({
|
|
114
|
-
state,
|
|
144
|
+
state: stateWithFocusRestore,
|
|
115
145
|
triggerRef: () => triggerRef,
|
|
146
|
+
setTriggerRef,
|
|
116
147
|
triggerId,
|
|
117
|
-
|
|
148
|
+
triggerProps: triggerAria.triggerProps,
|
|
149
|
+
overlayProps: triggerAria.overlayProps,
|
|
150
|
+
}));
|
|
118
151
|
|
|
119
152
|
// In SolidJS, we simply render children directly within the provider
|
|
120
|
-
// The children will have access to the context
|
|
121
153
|
return (
|
|
122
154
|
<DialogTriggerContext.Provider value={contextValue()}>
|
|
123
155
|
{props.children}
|
|
124
156
|
</DialogTriggerContext.Provider>
|
|
125
|
-
)
|
|
157
|
+
);
|
|
126
158
|
}
|
|
127
159
|
|
|
128
|
-
// ============================================
|
|
129
|
-
// DIALOG COMPONENT
|
|
130
|
-
// ============================================
|
|
131
|
-
|
|
132
160
|
/**
|
|
133
161
|
* A dialog is an overlay shown above other content in an application.
|
|
134
162
|
*/
|
|
135
163
|
export function Dialog(props: DialogProps): JSX.Element {
|
|
136
164
|
const [local, ariaProps, rest] = splitProps(
|
|
137
165
|
props,
|
|
138
|
-
[
|
|
139
|
-
[
|
|
140
|
-
)
|
|
166
|
+
["class", "style", "slot", "onClose"],
|
|
167
|
+
["role", "aria-label", "aria-labelledby", "aria-describedby"],
|
|
168
|
+
);
|
|
141
169
|
|
|
142
|
-
let dialogRef!: HTMLDivElement
|
|
170
|
+
let dialogRef!: HTMLDivElement;
|
|
143
171
|
|
|
144
172
|
// Get trigger context for aria-labelledby fallback
|
|
145
|
-
const triggerContext = useContext(DialogTriggerContext)
|
|
173
|
+
const triggerContext = useContext(DialogTriggerContext);
|
|
146
174
|
|
|
147
175
|
// createDialog returns dialogProps AND titleProps (with the id for the Heading)
|
|
148
176
|
const { dialogProps, titleProps } = createDialog(
|
|
149
177
|
{
|
|
150
178
|
get role() {
|
|
151
|
-
return ariaProps.role
|
|
179
|
+
return ariaProps.role;
|
|
152
180
|
},
|
|
153
|
-
get
|
|
154
|
-
return ariaProps[
|
|
181
|
+
get "aria-label"() {
|
|
182
|
+
return ariaProps["aria-label"];
|
|
155
183
|
},
|
|
156
|
-
get
|
|
157
|
-
|
|
158
|
-
return ariaProps['aria-labelledby'] ?? triggerContext?.triggerId
|
|
184
|
+
get "aria-labelledby"() {
|
|
185
|
+
return ariaProps["aria-labelledby"];
|
|
159
186
|
},
|
|
160
|
-
get
|
|
161
|
-
return ariaProps[
|
|
187
|
+
get "aria-describedby"() {
|
|
188
|
+
return ariaProps["aria-describedby"];
|
|
162
189
|
},
|
|
163
190
|
},
|
|
164
|
-
() => dialogRef
|
|
165
|
-
)
|
|
191
|
+
() => dialogRef,
|
|
192
|
+
);
|
|
166
193
|
|
|
167
194
|
// Get titleId from titleProps - this links Dialog's aria-labelledby to Heading's id
|
|
168
|
-
const titleId = () => titleProps()?.id
|
|
195
|
+
const titleId = () => titleProps()?.id as string | undefined;
|
|
169
196
|
|
|
170
197
|
// Get close function from OverlayTriggerState context or onClose prop
|
|
171
|
-
const overlayState = useOverlayTriggerState()
|
|
198
|
+
const overlayState = useOverlayTriggerState();
|
|
172
199
|
|
|
173
200
|
const close = () => {
|
|
174
|
-
local.onClose?.()
|
|
175
|
-
overlayState
|
|
176
|
-
|
|
177
|
-
|
|
201
|
+
local.onClose?.();
|
|
202
|
+
if (overlayState) {
|
|
203
|
+
overlayState.close();
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
triggerContext?.state.close();
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
createEffect(() => {
|
|
210
|
+
if (!dialogRef || ariaProps["aria-label"] || ariaProps["aria-labelledby"]) return;
|
|
211
|
+
const labelledBy = dialogRef.getAttribute("aria-labelledby");
|
|
212
|
+
if (labelledBy && dialogRef.ownerDocument.getElementById(labelledBy)) return;
|
|
213
|
+
|
|
214
|
+
const trigger = triggerContext?.triggerRef();
|
|
215
|
+
if (trigger?.id) {
|
|
216
|
+
dialogRef.setAttribute("aria-labelledby", trigger.id);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
178
219
|
|
|
179
|
-
// Render props values
|
|
180
220
|
const renderValues = createMemo<DialogRenderProps>(() => ({
|
|
181
221
|
close,
|
|
182
|
-
}))
|
|
222
|
+
}));
|
|
183
223
|
|
|
184
|
-
// Resolve render props
|
|
185
224
|
const renderProps = useRenderProps(
|
|
186
225
|
{
|
|
187
226
|
children: props.children,
|
|
188
227
|
class: local.class,
|
|
189
228
|
style: local.style,
|
|
190
|
-
defaultClassName:
|
|
229
|
+
defaultClassName: "solidaria-Dialog",
|
|
191
230
|
},
|
|
192
|
-
renderValues
|
|
193
|
-
)
|
|
231
|
+
renderValues,
|
|
232
|
+
);
|
|
194
233
|
|
|
195
|
-
|
|
196
|
-
|
|
234
|
+
const domProps = createMemo(() =>
|
|
235
|
+
filterDOMProps(rest as Record<string, unknown>, { global: true }),
|
|
236
|
+
);
|
|
197
237
|
|
|
198
238
|
return (
|
|
199
239
|
<DialogContext.Provider value={{ close, titleId: titleId() }}>
|
|
@@ -203,26 +243,23 @@ export function Dialog(props: DialogProps): JSX.Element {
|
|
|
203
243
|
ref={dialogRef}
|
|
204
244
|
class={renderProps.class()}
|
|
205
245
|
style={renderProps.style()}
|
|
246
|
+
slot={local.slot}
|
|
206
247
|
>
|
|
207
248
|
{renderProps.renderChildren()}
|
|
208
249
|
</div>
|
|
209
250
|
</DialogContext.Provider>
|
|
210
|
-
)
|
|
251
|
+
);
|
|
211
252
|
}
|
|
212
253
|
|
|
213
|
-
// ============================================
|
|
214
|
-
// HEADING COMPONENT
|
|
215
|
-
// ============================================
|
|
216
|
-
|
|
217
254
|
export interface HeadingProps {
|
|
218
255
|
/** The children of the heading. */
|
|
219
|
-
children: JSX.Element
|
|
256
|
+
children: JSX.Element;
|
|
220
257
|
/** The CSS className. */
|
|
221
|
-
class?: string
|
|
258
|
+
class?: string;
|
|
222
259
|
/** The heading level (1-6). Defaults to 2. */
|
|
223
|
-
level?: 1 | 2 | 3 | 4 | 5 | 6
|
|
260
|
+
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
224
261
|
/** The slot to render into. */
|
|
225
|
-
slot?: string
|
|
262
|
+
slot?: string;
|
|
226
263
|
}
|
|
227
264
|
|
|
228
265
|
/**
|
|
@@ -230,33 +267,65 @@ export interface HeadingProps {
|
|
|
230
267
|
* When rendered inside a Dialog, automatically gets the titleProps.
|
|
231
268
|
*/
|
|
232
269
|
export function Heading(props: HeadingProps): JSX.Element {
|
|
233
|
-
const dialogContext = useContext(DialogContext)
|
|
234
|
-
const level = () => props.level ?? 2
|
|
235
|
-
const id = () => dialogContext?.titleId
|
|
270
|
+
const dialogContext = useContext(DialogContext);
|
|
271
|
+
const level = () => props.level ?? 2;
|
|
272
|
+
const id = () => dialogContext?.titleId;
|
|
273
|
+
let headingRef: HTMLHeadingElement | undefined;
|
|
274
|
+
|
|
275
|
+
createEffect(() => {
|
|
276
|
+
const el = headingRef;
|
|
277
|
+
if (!el) return;
|
|
278
|
+
|
|
279
|
+
const contextId = id();
|
|
280
|
+
if (contextId) {
|
|
281
|
+
el.id = contextId;
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!el.id) {
|
|
286
|
+
const dialog = el.closest('[role="dialog"],[role="alertdialog"]');
|
|
287
|
+
const labelledBy = dialog?.getAttribute("aria-labelledby");
|
|
288
|
+
if (labelledBy && !el.ownerDocument.getElementById(labelledBy)) {
|
|
289
|
+
el.id = labelledBy;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
});
|
|
236
293
|
|
|
237
294
|
return (
|
|
238
295
|
<Switch>
|
|
239
296
|
<Match when={level() === 1}>
|
|
240
|
-
<h1 id={id()} class={props.class}>
|
|
297
|
+
<h1 ref={headingRef} id={id()} class={props.class}>
|
|
298
|
+
{props.children}
|
|
299
|
+
</h1>
|
|
241
300
|
</Match>
|
|
242
301
|
<Match when={level() === 2}>
|
|
243
|
-
<h2 id={id()} class={props.class}>
|
|
302
|
+
<h2 ref={headingRef} id={id()} class={props.class}>
|
|
303
|
+
{props.children}
|
|
304
|
+
</h2>
|
|
244
305
|
</Match>
|
|
245
306
|
<Match when={level() === 3}>
|
|
246
|
-
<h3 id={id()} class={props.class}>
|
|
307
|
+
<h3 ref={headingRef} id={id()} class={props.class}>
|
|
308
|
+
{props.children}
|
|
309
|
+
</h3>
|
|
247
310
|
</Match>
|
|
248
311
|
<Match when={level() === 4}>
|
|
249
|
-
<h4 id={id()} class={props.class}>
|
|
312
|
+
<h4 ref={headingRef} id={id()} class={props.class}>
|
|
313
|
+
{props.children}
|
|
314
|
+
</h4>
|
|
250
315
|
</Match>
|
|
251
316
|
<Match when={level() === 5}>
|
|
252
|
-
<h5 id={id()} class={props.class}>
|
|
317
|
+
<h5 ref={headingRef} id={id()} class={props.class}>
|
|
318
|
+
{props.children}
|
|
319
|
+
</h5>
|
|
253
320
|
</Match>
|
|
254
321
|
<Match when={level() === 6}>
|
|
255
|
-
<h6 id={id()} class={props.class}>
|
|
322
|
+
<h6 ref={headingRef} id={id()} class={props.class}>
|
|
323
|
+
{props.children}
|
|
324
|
+
</h6>
|
|
256
325
|
</Match>
|
|
257
326
|
</Switch>
|
|
258
|
-
)
|
|
327
|
+
);
|
|
259
328
|
}
|
|
260
329
|
|
|
261
330
|
// Keep backward compatibility
|
|
262
|
-
export { Heading as DialogHeading }
|
|
331
|
+
export { Heading as DialogHeading };
|