@proyecto-viviana/solidaria-components 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ActionBar.js +184 -0
- package/dist/ActionBar.js.map +1 -0
- package/dist/ActionBar.jsx +128 -0
- package/dist/ActionBar.jsx.map +1 -0
- package/dist/ActionGroup.js +179 -0
- package/dist/ActionGroup.js.map +1 -0
- package/dist/ActionGroup.jsx +129 -0
- package/dist/ActionGroup.jsx.map +1 -0
- package/dist/Alert.js +111 -0
- package/dist/Alert.js.map +1 -0
- package/dist/Alert.jsx +82 -0
- package/dist/Alert.jsx.map +1 -0
- package/dist/Autocomplete.js +130 -0
- package/dist/Autocomplete.js.map +1 -0
- package/dist/Autocomplete.jsx +116 -0
- package/dist/Autocomplete.jsx.map +1 -0
- package/dist/Breadcrumbs.d.ts.map +1 -1
- package/dist/Breadcrumbs.js +334 -0
- package/dist/Breadcrumbs.js.map +1 -0
- package/dist/Breadcrumbs.jsx +266 -0
- package/dist/Breadcrumbs.jsx.map +1 -0
- package/dist/Button.d.ts.map +1 -1
- package/dist/Button.js +348 -0
- package/dist/Button.js.map +1 -0
- package/dist/Button.jsx +314 -0
- package/dist/Button.jsx.map +1 -0
- package/dist/Calendar.d.ts +4 -4
- package/dist/Calendar.d.ts.map +1 -1
- package/dist/Calendar.js +538 -0
- package/dist/Calendar.js.map +1 -0
- package/dist/Calendar.jsx +333 -0
- package/dist/Calendar.jsx.map +1 -0
- package/dist/CalendarPicker.d.ts +33 -0
- package/dist/CalendarPicker.d.ts.map +1 -0
- package/dist/CalendarPicker.js +44 -0
- package/dist/CalendarPicker.js.map +1 -0
- package/dist/CalendarPicker.jsx +44 -0
- package/dist/CalendarPicker.jsx.map +1 -0
- package/dist/Checkbox.d.ts +83 -4
- package/dist/Checkbox.d.ts.map +1 -1
- package/dist/Checkbox.js +923 -0
- package/dist/Checkbox.js.map +1 -0
- package/dist/Checkbox.jsx +707 -0
- package/dist/Checkbox.jsx.map +1 -0
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +202 -0
- package/dist/Collection.js.map +1 -0
- package/dist/Collection.jsx +152 -0
- package/dist/Collection.jsx.map +1 -0
- package/dist/Color.d.ts.map +1 -1
- package/dist/Color.js +1720 -0
- package/dist/Color.js.map +1 -0
- package/dist/Color.jsx +1344 -0
- package/dist/Color.jsx.map +1 -0
- package/dist/ColorEditor.js +208 -0
- package/dist/ColorEditor.js.map +1 -0
- package/dist/ColorEditor.jsx +120 -0
- package/dist/ColorEditor.jsx.map +1 -0
- package/dist/ComboBox.d.ts +4 -4
- package/dist/ComboBox.d.ts.map +1 -1
- package/dist/ComboBox.js +992 -0
- package/dist/ComboBox.js.map +1 -0
- package/dist/ComboBox.jsx +714 -0
- package/dist/ComboBox.jsx.map +1 -0
- package/dist/ContextualHelpTrigger.js +146 -0
- package/dist/ContextualHelpTrigger.js.map +1 -0
- package/dist/ContextualHelpTrigger.jsx +109 -0
- package/dist/ContextualHelpTrigger.jsx.map +1 -0
- package/dist/DateField.d.ts +3 -3
- package/dist/DateField.d.ts.map +1 -1
- package/dist/DateField.js +4 -0
- package/dist/DateField.jsx +4 -0
- package/dist/DateField2.js +499 -0
- package/dist/DateField2.js.map +1 -0
- package/dist/DateField2.jsx +317 -0
- package/dist/DateField2.jsx.map +1 -0
- package/dist/DatePicker.d.ts +4 -4
- package/dist/DatePicker.d.ts.map +1 -1
- package/dist/DatePicker.js +991 -0
- package/dist/DatePicker.js.map +1 -0
- package/dist/DatePicker.jsx +682 -0
- package/dist/DatePicker.jsx.map +1 -0
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Dialog.js +337 -0
- package/dist/Dialog.js.map +1 -0
- package/dist/Dialog.jsx +192 -0
- package/dist/Dialog.jsx.map +1 -0
- package/dist/Disclosure.d.ts.map +1 -1
- package/dist/Disclosure.js +328 -0
- package/dist/Disclosure.js.map +1 -0
- package/dist/Disclosure.jsx +230 -0
- package/dist/Disclosure.jsx.map +1 -0
- package/dist/DragAndDrop.d.ts.map +1 -1
- package/dist/DragAndDrop.js +176 -0
- package/dist/DragAndDrop.js.map +1 -0
- package/dist/DragAndDrop.jsx +160 -0
- package/dist/DragAndDrop.jsx.map +1 -0
- package/dist/DropZone.d.ts.map +1 -1
- package/dist/DropZone.js +189 -0
- package/dist/DropZone.js.map +1 -0
- package/dist/DropZone.jsx +144 -0
- package/dist/DropZone.jsx.map +1 -0
- package/dist/FieldError.js +66 -0
- package/dist/FieldError.js.map +1 -0
- package/dist/FieldError.jsx +47 -0
- package/dist/FieldError.jsx.map +1 -0
- package/dist/FileTrigger.js +79 -0
- package/dist/FileTrigger.js.map +1 -0
- package/dist/FileTrigger.jsx +49 -0
- package/dist/FileTrigger.jsx.map +1 -0
- package/dist/Focusable.js +70 -0
- package/dist/Focusable.js.map +1 -0
- package/dist/Focusable.jsx +69 -0
- package/dist/Focusable.jsx.map +1 -0
- package/dist/Form.js +99 -0
- package/dist/Form.js.map +1 -0
- package/dist/Form.jsx +73 -0
- package/dist/Form.jsx.map +1 -0
- package/dist/GridList.d.ts +34 -2
- package/dist/GridList.d.ts.map +1 -1
- package/dist/GridList.js +723 -0
- package/dist/GridList.js.map +1 -0
- package/dist/GridList.jsx +552 -0
- package/dist/GridList.jsx.map +1 -0
- package/dist/HiddenTimeInput.js +104 -0
- package/dist/HiddenTimeInput.js.map +1 -0
- package/dist/HiddenTimeInput.jsx +69 -0
- package/dist/HiddenTimeInput.jsx.map +1 -0
- package/dist/Icon.d.ts.map +1 -1
- package/dist/Icon.js +127 -0
- package/dist/Icon.js.map +1 -0
- package/dist/Icon.jsx +72 -0
- package/dist/Icon.jsx.map +1 -0
- package/dist/Keyboard.js +30 -0
- package/dist/Keyboard.js.map +1 -0
- package/dist/Keyboard.jsx +24 -0
- package/dist/Keyboard.jsx.map +1 -0
- package/dist/Landmark.js +134 -0
- package/dist/Landmark.js.map +1 -0
- package/dist/Landmark.jsx +118 -0
- package/dist/Landmark.jsx.map +1 -0
- package/dist/Link.d.ts.map +1 -1
- package/dist/Link.js +219 -0
- package/dist/Link.js.map +1 -0
- package/dist/Link.jsx +189 -0
- package/dist/Link.jsx.map +1 -0
- package/dist/ListBox.d.ts.map +1 -1
- package/dist/ListBox.js +670 -0
- package/dist/ListBox.js.map +1 -0
- package/dist/ListBox.jsx +508 -0
- package/dist/ListBox.jsx.map +1 -0
- package/dist/Menu.d.ts +27 -9
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Menu.js +1254 -0
- package/dist/Menu.js.map +1 -0
- package/dist/Menu.jsx +1042 -0
- package/dist/Menu.jsx.map +1 -0
- package/dist/Meter.d.ts.map +1 -1
- package/dist/Meter.js +123 -0
- package/dist/Meter.js.map +1 -0
- package/dist/Meter.jsx +107 -0
- package/dist/Meter.jsx.map +1 -0
- package/dist/Modal.d.ts.map +1 -1
- package/dist/Modal.js +380 -0
- package/dist/Modal.js.map +1 -0
- package/dist/Modal.jsx +314 -0
- package/dist/Modal.jsx.map +1 -0
- package/dist/NumberField.d.ts +3 -3
- package/dist/NumberField.d.ts.map +1 -1
- package/dist/NumberField.js +573 -0
- package/dist/NumberField.js.map +1 -0
- package/dist/NumberField.jsx +443 -0
- package/dist/NumberField.jsx.map +1 -0
- package/dist/Popover.d.ts +10 -2
- package/dist/Popover.d.ts.map +1 -1
- package/dist/Popover.js +464 -0
- package/dist/Popover.js.map +1 -0
- package/dist/Popover.jsx +333 -0
- package/dist/Popover.jsx.map +1 -0
- package/dist/Pressable.js +69 -0
- package/dist/Pressable.js.map +1 -0
- package/dist/Pressable.jsx +68 -0
- package/dist/Pressable.jsx.map +1 -0
- package/dist/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar.js +130 -0
- package/dist/ProgressBar.js.map +1 -0
- package/dist/ProgressBar.jsx +114 -0
- package/dist/ProgressBar.jsx.map +1 -0
- package/dist/RadioGroup.d.ts +82 -4
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RadioGroup.js +931 -0
- package/dist/RadioGroup.js.map +1 -0
- package/dist/RadioGroup.jsx +681 -0
- package/dist/RadioGroup.jsx.map +1 -0
- package/dist/RangeCalendar.d.ts.map +1 -1
- package/dist/RangeCalendar.js +410 -0
- package/dist/RangeCalendar.js.map +1 -0
- package/dist/RangeCalendar.jsx +253 -0
- package/dist/RangeCalendar.jsx.map +1 -0
- package/dist/RouterProvider.js +118 -0
- package/dist/RouterProvider.js.map +1 -0
- package/dist/RouterProvider.jsx +112 -0
- package/dist/RouterProvider.jsx.map +1 -0
- package/dist/SearchField.d.ts +2 -2
- package/dist/SearchField.d.ts.map +1 -1
- package/dist/SearchField.js +643 -0
- package/dist/SearchField.js.map +1 -0
- package/dist/SearchField.jsx +526 -0
- package/dist/SearchField.jsx.map +1 -0
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js +1031 -0
- package/dist/Select.js.map +1 -0
- package/dist/Select.jsx +744 -0
- package/dist/Select.jsx.map +1 -0
- package/dist/SelectionIndicator.d.ts.map +1 -1
- package/dist/SelectionIndicator.js +86 -0
- package/dist/SelectionIndicator.js.map +1 -0
- package/dist/SelectionIndicator.jsx +50 -0
- package/dist/SelectionIndicator.jsx.map +1 -0
- package/dist/Separator.js +97 -0
- package/dist/Separator.js.map +1 -0
- package/dist/Separator.jsx +85 -0
- package/dist/Separator.jsx.map +1 -0
- package/dist/SharedElementTransition.d.ts.map +1 -1
- package/dist/SharedElementTransition.js +165 -0
- package/dist/SharedElementTransition.js.map +1 -0
- package/dist/SharedElementTransition.jsx +138 -0
- package/dist/SharedElementTransition.jsx.map +1 -0
- package/dist/Slider.d.ts +33 -1
- package/dist/Slider.d.ts.map +1 -1
- package/dist/Slider.js +515 -0
- package/dist/Slider.js.map +1 -0
- package/dist/Slider.jsx +403 -0
- package/dist/Slider.jsx.map +1 -0
- package/dist/StepList.js +198 -0
- package/dist/StepList.js.map +1 -0
- package/dist/StepList.jsx +141 -0
- package/dist/StepList.jsx.map +1 -0
- package/dist/Switch.d.ts +65 -2
- package/dist/Switch.d.ts.map +1 -1
- package/dist/Switch.js +534 -0
- package/dist/Switch.js.map +1 -0
- package/dist/Switch.jsx +393 -0
- package/dist/Switch.jsx.map +1 -0
- package/dist/Table.d.ts +48 -0
- package/dist/Table.d.ts.map +1 -1
- package/dist/Table.js +1759 -0
- package/dist/Table.js.map +1 -0
- package/dist/Table.jsx +1348 -0
- package/dist/Table.jsx.map +1 -0
- package/dist/Tabs.d.ts +0 -4
- package/dist/Tabs.d.ts.map +1 -1
- package/dist/Tabs.js +595 -0
- package/dist/Tabs.js.map +1 -0
- package/dist/Tabs.jsx +367 -0
- package/dist/Tabs.jsx.map +1 -0
- package/dist/TagGroup.d.ts.map +1 -1
- package/dist/TagGroup.js +378 -0
- package/dist/TagGroup.js.map +1 -0
- package/dist/TagGroup.jsx +270 -0
- package/dist/TagGroup.jsx.map +1 -0
- package/dist/Text.d.ts +18 -6
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +42 -0
- package/dist/Text.js.map +1 -0
- package/dist/Text.jsx +35 -0
- package/dist/Text.jsx.map +1 -0
- package/dist/TextField.d.ts +6 -6
- package/dist/TextField.d.ts.map +1 -1
- package/dist/TextField.js +436 -0
- package/dist/TextField.js.map +1 -0
- package/dist/TextField.jsx +403 -0
- package/dist/TextField.jsx.map +1 -0
- package/dist/TimeField.d.ts +3 -3
- package/dist/TimeField.d.ts.map +1 -1
- package/dist/TimeField.js +372 -0
- package/dist/TimeField.js.map +1 -0
- package/dist/TimeField.jsx +224 -0
- package/dist/TimeField.jsx.map +1 -0
- package/dist/Toast.d.ts +14 -0
- package/dist/Toast.d.ts.map +1 -1
- package/dist/Toast.js +551 -0
- package/dist/Toast.js.map +1 -0
- package/dist/Toast.jsx +361 -0
- package/dist/Toast.jsx.map +1 -0
- package/dist/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton.js +123 -0
- package/dist/ToggleButton.js.map +1 -0
- package/dist/ToggleButton.jsx +88 -0
- package/dist/ToggleButton.jsx.map +1 -0
- package/dist/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/ToggleButtonGroup.js +114 -0
- package/dist/ToggleButtonGroup.js.map +1 -0
- package/dist/ToggleButtonGroup.jsx +85 -0
- package/dist/ToggleButtonGroup.jsx.map +1 -0
- package/dist/Toolbar.js +112 -0
- package/dist/Toolbar.js.map +1 -0
- package/dist/Toolbar.jsx +92 -0
- package/dist/Toolbar.jsx.map +1 -0
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip.js +539 -0
- package/dist/Tooltip.js.map +1 -0
- package/dist/Tooltip.jsx +465 -0
- package/dist/Tooltip.jsx.map +1 -0
- package/dist/Tree.d.ts +14 -2
- package/dist/Tree.d.ts.map +1 -1
- package/dist/Tree.js +1424 -0
- package/dist/Tree.js.map +1 -0
- package/dist/Tree.jsx +1172 -0
- package/dist/Tree.jsx.map +1 -0
- package/dist/Virtualizer.d.ts +16 -2
- package/dist/Virtualizer.d.ts.map +1 -1
- package/dist/Virtualizer.js +2 -0
- package/dist/Virtualizer.jsx +2 -0
- package/dist/Virtualizer2.js +751 -0
- package/dist/Virtualizer2.js.map +1 -0
- package/dist/Virtualizer2.jsx +730 -0
- package/dist/Virtualizer2.jsx.map +1 -0
- package/dist/VirtualizerLayouts.d.ts +18 -0
- package/dist/VirtualizerLayouts.d.ts.map +1 -1
- package/dist/VisuallyHidden.js +42 -0
- package/dist/VisuallyHidden.js.map +1 -0
- package/dist/VisuallyHidden.jsx +35 -0
- package/dist/VisuallyHidden.jsx.map +1 -0
- package/dist/contexts.js +33 -0
- package/dist/contexts.js.map +1 -0
- package/dist/contexts.jsx +33 -0
- package/dist/contexts.jsx.map +1 -0
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -23932
- package/dist/index.jsx +70 -18337
- package/dist/useDragAndDrop.js +2 -0
- package/dist/useDragAndDrop.jsx +2 -0
- package/dist/useDragAndDrop2.js +395 -0
- package/dist/useDragAndDrop2.js.map +1 -0
- package/dist/useDragAndDrop2.jsx +395 -0
- package/dist/useDragAndDrop2.jsx.map +1 -0
- package/dist/utils.d.ts +83 -11
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +285 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.jsx +277 -0
- package/dist/utils.jsx.map +1 -0
- package/dist/virtualizer/Layout.js +144 -0
- package/dist/virtualizer/Layout.js.map +1 -0
- package/dist/virtualizer/Layout.jsx +144 -0
- package/dist/virtualizer/Layout.jsx.map +1 -0
- package/package.json +401 -4
- package/src/Breadcrumbs.tsx +3 -1
- package/src/Button.tsx +22 -2
- package/src/Calendar.tsx +27 -10
- package/src/CalendarPicker.tsx +73 -0
- package/src/Checkbox.tsx +539 -3
- package/src/Collection.tsx +9 -3
- package/src/Color.tsx +42 -14
- package/src/ComboBox.tsx +50 -6
- package/src/DateField.tsx +20 -2
- package/src/DatePicker.tsx +57 -5
- package/src/Dialog.tsx +13 -5
- package/src/Disclosure.tsx +3 -1
- package/src/DragAndDrop.tsx +3 -1
- package/src/DropZone.tsx +3 -1
- package/src/GridList.tsx +125 -24
- package/src/Icon.tsx +3 -1
- package/src/Link.tsx +3 -1
- package/src/ListBox.tsx +31 -4
- package/src/Menu.tsx +252 -128
- package/src/Meter.tsx +3 -1
- package/src/Modal.tsx +100 -52
- package/src/NumberField.tsx +51 -8
- package/src/Popover.tsx +40 -10
- package/src/ProgressBar.tsx +3 -1
- package/src/RadioGroup.tsx +468 -4
- package/src/RangeCalendar.tsx +3 -1
- package/src/SearchField.tsx +27 -3
- package/src/Select.tsx +22 -7
- package/src/SelectionIndicator.tsx +3 -1
- package/src/SharedElementTransition.tsx +3 -1
- package/src/Slider.tsx +159 -13
- package/src/Switch.tsx +395 -2
- package/src/Table.tsx +409 -95
- package/src/Tabs.tsx +16 -45
- package/src/TagGroup.tsx +3 -1
- package/src/Text.tsx +31 -10
- package/src/TextField.tsx +43 -5
- package/src/TimeField.tsx +20 -2
- package/src/Toast.tsx +79 -14
- package/src/ToggleButton.tsx +3 -1
- package/src/ToggleButtonGroup.tsx +3 -1
- package/src/Tooltip.tsx +3 -1
- package/src/Tree.tsx +77 -9
- package/src/Virtualizer.tsx +180 -31
- package/src/VirtualizerLayouts.ts +45 -10
- package/src/index.ts +50 -0
- package/src/utils.tsx +243 -27
- package/dist/index.js.map +0 -1
- package/dist/index.jsx.map +0 -1
package/src/utils.tsx
CHANGED
|
@@ -6,16 +6,20 @@
|
|
|
6
6
|
import {
|
|
7
7
|
type JSX,
|
|
8
8
|
type Accessor,
|
|
9
|
+
type Context,
|
|
9
10
|
type FlowComponent,
|
|
10
|
-
|
|
11
|
+
createComponent,
|
|
11
12
|
createContext,
|
|
12
13
|
useContext,
|
|
13
14
|
createMemo,
|
|
14
15
|
createSignal,
|
|
15
16
|
onMount,
|
|
17
|
+
sharedConfig,
|
|
18
|
+
untrack,
|
|
16
19
|
Show,
|
|
17
20
|
} from "solid-js";
|
|
18
21
|
import { isServer } from "solid-js/web";
|
|
22
|
+
import { mergeProps } from "@proyecto-viviana/solidaria";
|
|
19
23
|
|
|
20
24
|
/**
|
|
21
25
|
* Render props pattern - children can be a function that receives state
|
|
@@ -73,6 +77,19 @@ export interface RenderPropsResult<T> {
|
|
|
73
77
|
* {renderProps.renderChildren()}
|
|
74
78
|
*/
|
|
75
79
|
renderChildren: () => JSX.Element;
|
|
80
|
+
/**
|
|
81
|
+
* Render a render-prop child ONCE over a reactive view of the values,
|
|
82
|
+
* mirroring how React reconciles a render prop's returned tree in place.
|
|
83
|
+
*
|
|
84
|
+
* Prefer this over `renderChildren()` for interactive leaf components (a
|
|
85
|
+
* Tab, a toggle segment) whose child wraps the pressable element: re-invoking
|
|
86
|
+
* the render function on every values() change recreates that DOM subtree,
|
|
87
|
+
* which detaches the pointer/press target mid-gesture and makes the browser
|
|
88
|
+
* suppress the native `click` (createPress then has to synthesize an
|
|
89
|
+
* untrusted fallback click — a visible parity break vs React). Static (non
|
|
90
|
+
* function) children are returned untouched, exactly like `renderChildren`.
|
|
91
|
+
*/
|
|
92
|
+
renderChildrenStable: () => JSX.Element;
|
|
76
93
|
/** The raw children prop (function or JSX) - use renderChildren() in most cases */
|
|
77
94
|
children: RenderChildren<T> | undefined;
|
|
78
95
|
/** The render props values accessor */
|
|
@@ -115,9 +132,55 @@ export function useRenderProps<T extends object>(
|
|
|
115
132
|
class: computedClass,
|
|
116
133
|
style: computedStyle,
|
|
117
134
|
renderChildren: () => {
|
|
118
|
-
const currentValues = values();
|
|
119
135
|
const children = props.children;
|
|
120
|
-
|
|
136
|
+
// Only read values() for render-prop children. Static JSX children must
|
|
137
|
+
// not track the render-state memo: re-running the insertion effect
|
|
138
|
+
// recreates real DOM nodes on every hover/press/focus flip (React keeps
|
|
139
|
+
// them stable via vdom diffing), which detaches the pressed node
|
|
140
|
+
// mid-press and suppresses the browser's native click.
|
|
141
|
+
//
|
|
142
|
+
// A render prop takes the values argument, so classify by arity — the
|
|
143
|
+
// same convention `solid-js/h` uses for dynamic props. A zero-arg
|
|
144
|
+
// function child is an accessor (a compiled `{expression}` child, a
|
|
145
|
+
// solid-refresh dev wrapper, a one-shot `solid-js/h` element thunk):
|
|
146
|
+
// return it untouched so the insert machinery unwraps it in its own
|
|
147
|
+
// nested effect. Calling it here would track its reads in the shared
|
|
148
|
+
// insertion effect, and every re-run disposes the child computations
|
|
149
|
+
// that effect owns — a one-shot h thunk then hands back the same
|
|
150
|
+
// disposed node, leaving connected DOM whose reactivity is dead.
|
|
151
|
+
return typeof children === "function" && children.length > 0
|
|
152
|
+
? children(values())
|
|
153
|
+
: (children as JSX.Element);
|
|
154
|
+
},
|
|
155
|
+
renderChildrenStable: () => {
|
|
156
|
+
const children = props.children;
|
|
157
|
+
if (typeof children !== "function" || children.length === 0) {
|
|
158
|
+
return children as JSX.Element;
|
|
159
|
+
}
|
|
160
|
+
// Invoke the render function exactly once, over a getter view of the
|
|
161
|
+
// values, so the returned DOM is created a single time and only the
|
|
162
|
+
// reactive reads inside it (JSX bindings, component props) re-run on a
|
|
163
|
+
// values() change — React's reconciliation, not Solid's recreation.
|
|
164
|
+
//
|
|
165
|
+
// `untrack` keeps the enclosing insert from tracking values() (so it
|
|
166
|
+
// never re-runs and never recreates), but does NOT change the owner:
|
|
167
|
+
// this still executes inside the caller's insert scope, so any slotted
|
|
168
|
+
// context the render prop reads binds against the surrounding provider.
|
|
169
|
+
//
|
|
170
|
+
// The value keys are read once here (untracked). Render-state memos in
|
|
171
|
+
// this codebase return a fixed-shape object, so the key set is stable.
|
|
172
|
+
return untrack(() => {
|
|
173
|
+
const snapshot = values();
|
|
174
|
+
const view = {} as T;
|
|
175
|
+
for (const key of Object.keys(snapshot) as Array<keyof T & string>) {
|
|
176
|
+
Object.defineProperty(view, key, {
|
|
177
|
+
enumerable: true,
|
|
178
|
+
configurable: true,
|
|
179
|
+
get: () => values()[key],
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return (children as (renderProps: T) => JSX.Element)(view);
|
|
183
|
+
});
|
|
121
184
|
},
|
|
122
185
|
get children() {
|
|
123
186
|
return props.children;
|
|
@@ -139,41 +202,177 @@ export function composeRenderProps<T extends object>(
|
|
|
139
202
|
};
|
|
140
203
|
}
|
|
141
204
|
|
|
205
|
+
/** A Solid ref target: a callback, a mutable `{ current }` object, or undefined. */
|
|
206
|
+
export type RefLike<T> = T | ((el: T) => void) | { current?: T | null } | undefined;
|
|
207
|
+
|
|
208
|
+
/** A value paired with an optional ref to merge onto the consuming element. */
|
|
209
|
+
export type WithRef<T, E> = T & { ref?: RefLike<E> };
|
|
210
|
+
|
|
142
211
|
/**
|
|
143
|
-
*
|
|
212
|
+
* A context value carrying named slots (mirrors react-aria-components'
|
|
213
|
+
* `SlottedValue`). Each entry under `slots` is the props object delivered to the
|
|
214
|
+
* component rendered with the matching `slot` name.
|
|
144
215
|
*/
|
|
145
|
-
export
|
|
216
|
+
export interface SlottedValue<T> {
|
|
217
|
+
slots?: Record<string, T>;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** A slotted context value: a slots record, a bare value, or null/undefined. */
|
|
221
|
+
export type SlottedContextValue<T> = SlottedValue<T> | T | null | undefined;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* The value type for a context consumed via {@link useContextProps}. Mirrors
|
|
225
|
+
* upstream `ContextValue<T, E>`: it may carry `slots` and an optional `ref` to
|
|
226
|
+
* merge onto the consuming element.
|
|
227
|
+
*/
|
|
228
|
+
export type ContextValue<T, E = HTMLElement> = SlottedContextValue<WithRef<T, E>>;
|
|
146
229
|
|
|
147
230
|
/**
|
|
148
|
-
* Creates a context
|
|
231
|
+
* Creates a context that can carry either a bare value or a `slots` record.
|
|
149
232
|
*/
|
|
150
233
|
export function createSlottedContext<T>() {
|
|
151
|
-
return createContext<T
|
|
234
|
+
return createContext<SlottedContextValue<T>>(null);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Assigns an element to a Solid ref (callback or mutable `{ current }` object). */
|
|
238
|
+
export function assignRef<T>(ref: RefLike<T>, el: T): void {
|
|
239
|
+
if (!ref) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (typeof ref === "function") {
|
|
244
|
+
(ref as (el: T) => void)(el);
|
|
245
|
+
} else if (typeof ref === "object" && "current" in ref) {
|
|
246
|
+
(ref as { current?: T | null }).current = el;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Merges multiple Solid refs into one callback that forwards to each, once. */
|
|
251
|
+
export function mergeRefs<T>(...refs: Array<RefLike<T>>): (el: T) => void {
|
|
252
|
+
return (el: T) => {
|
|
253
|
+
const seen = new Set<RefLike<T>>();
|
|
254
|
+
for (const ref of refs) {
|
|
255
|
+
if (!ref || seen.has(ref)) {
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
seen.add(ref);
|
|
260
|
+
assignRef(ref, el);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
152
263
|
}
|
|
153
264
|
|
|
154
265
|
/**
|
|
155
|
-
*
|
|
266
|
+
* Resolves a (possibly slotted) context value for the given slot name. Port of
|
|
267
|
+
* react-aria-components' `useSlottedContext`:
|
|
268
|
+
* - `slot === null` opts out of the context entirely (returns `null`);
|
|
269
|
+
* - if the context carries a `slots` record, the entry for `slot` (or
|
|
270
|
+
* {@link DEFAULT_SLOT}) is returned, throwing on an unknown slot name;
|
|
271
|
+
* - otherwise the bare context value is returned.
|
|
156
272
|
*/
|
|
157
273
|
export function useSlottedContext<T>(
|
|
158
|
-
context:
|
|
159
|
-
|
|
160
|
-
|
|
274
|
+
context: Context<SlottedContextValue<T>>,
|
|
275
|
+
slot?: string | null,
|
|
276
|
+
): T | null | undefined {
|
|
277
|
+
const ctx = useContext(context);
|
|
278
|
+
if (slot === null) {
|
|
279
|
+
// An explicit `null` slot means: ignore this context.
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (ctx && typeof ctx === "object" && "slots" in ctx && ctx.slots) {
|
|
284
|
+
const slots = ctx.slots as Record<string, T>;
|
|
285
|
+
const slotName = slot || DEFAULT_SLOT;
|
|
286
|
+
const slotValue = slots[slotName];
|
|
287
|
+
if (!slotValue) {
|
|
288
|
+
const validSlots = Object.keys(slots)
|
|
289
|
+
.map((name) => `"${name}"`)
|
|
290
|
+
.join(", ");
|
|
291
|
+
throw new Error(
|
|
292
|
+
slot
|
|
293
|
+
? `Invalid slot "${slot}". Valid slot names are ${validSlots}.`
|
|
294
|
+
: `A slot prop is required. Valid slot names are ${validSlots}.`,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
return slotValue;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return ctx as T | null | undefined;
|
|
161
301
|
}
|
|
162
302
|
|
|
163
|
-
|
|
303
|
+
/**
|
|
304
|
+
* Merges context-provided props and a context ref into a component's own props
|
|
305
|
+
* and ref. Port of react-aria-components' `useContextProps`:
|
|
306
|
+
* - the context is resolved for `props.slot` via {@link useSlottedContext};
|
|
307
|
+
* - props win over context props (handler props are chained by `mergeProps`);
|
|
308
|
+
* - the component's own ref and the context's ref merge into one callback.
|
|
309
|
+
*
|
|
310
|
+
* The prop merge stays reactive (Solid `mergeProps` preserves getters), so prop
|
|
311
|
+
* changes keep flowing; the context value is read once at setup, matching a single
|
|
312
|
+
* upstream render.
|
|
313
|
+
*/
|
|
314
|
+
export function useContextProps<TProps extends SlotProps, TRef>(
|
|
164
315
|
props: TProps,
|
|
165
|
-
ref: TRef
|
|
166
|
-
context
|
|
167
|
-
): [TProps, TRef] {
|
|
168
|
-
|
|
169
|
-
|
|
316
|
+
ref: RefLike<TRef>,
|
|
317
|
+
context: Context<ContextValue<TProps, TRef>>,
|
|
318
|
+
): [TProps, (el: TRef) => void] {
|
|
319
|
+
const ctx = (useSlottedContext(context, props.slot) ?? {}) as WithRef<Partial<TProps>, TRef>;
|
|
320
|
+
const { ref: contextRef, ...contextProps } = ctx;
|
|
321
|
+
const mergedRef = mergeRefs(ref, contextRef);
|
|
322
|
+
const mergedProps = mergeProps(contextProps as object, props as object) as unknown as TProps;
|
|
323
|
+
return [mergedProps, mergedRef];
|
|
170
324
|
}
|
|
171
325
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
326
|
+
/**
|
|
327
|
+
* Detects whether slotted content was rendered into a placeholder, for the
|
|
328
|
+
* aria-label fallback pattern. Port of react-aria-components' `useSlot`: returns a
|
|
329
|
+
* ref callback to attach to the placeholder and an accessor that is `true` while
|
|
330
|
+
* an element is mounted there. The accessor flips to `false` after mount if the
|
|
331
|
+
* ref never ran (no slotted content was provided).
|
|
332
|
+
*/
|
|
333
|
+
export function useSlot(initialState = true): [(el: Element | null) => void, Accessor<boolean>] {
|
|
334
|
+
const [hasSlot, setHasSlot] = createSignal(initialState);
|
|
335
|
+
let hasRun = false;
|
|
336
|
+
const ref = (el: Element | null) => {
|
|
337
|
+
hasRun = true;
|
|
338
|
+
setHasSlot(!!el);
|
|
339
|
+
};
|
|
340
|
+
onMount(() => {
|
|
341
|
+
if (!hasRun) {
|
|
342
|
+
setHasSlot(false);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
return [ref, hasSlot];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Nests a set of context providers around `children`. Port of
|
|
350
|
+
* react-aria-components' `Provider`: each `[Context, value]` pair wraps the
|
|
351
|
+
* previous result, so the LAST pair is the outermost provider — matching upstream's
|
|
352
|
+
* wrap-in-iteration-order.
|
|
353
|
+
*
|
|
354
|
+
* `children` is read through a lazy getter inside the innermost provider so child
|
|
355
|
+
* components are *created* within every provider's owner; Solid binds `useContext`
|
|
356
|
+
* at component-execution time, so eager children would miss these providers.
|
|
357
|
+
*/
|
|
358
|
+
export function Provider(props: {
|
|
359
|
+
values: Array<[Context<unknown>, unknown]>;
|
|
360
|
+
children: JSX.Element;
|
|
361
|
+
}): JSX.Element {
|
|
362
|
+
const build = (index: number): JSX.Element => {
|
|
363
|
+
if (index < 0) {
|
|
364
|
+
return props.children;
|
|
365
|
+
}
|
|
366
|
+
const [context, value] = props.values[index];
|
|
367
|
+
return createComponent(context.Provider, {
|
|
368
|
+
value,
|
|
369
|
+
get children() {
|
|
370
|
+
return build(index - 1);
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
};
|
|
374
|
+
return build(props.values.length - 1);
|
|
375
|
+
}
|
|
177
376
|
|
|
178
377
|
/**
|
|
179
378
|
* Converts boolean state values to data attributes
|
|
@@ -299,7 +498,12 @@ export const ClientOnly: FlowComponent<ClientOnlyProps> = (props) => {
|
|
|
299
498
|
return <>{props.fallback}</>;
|
|
300
499
|
}
|
|
301
500
|
|
|
302
|
-
//
|
|
501
|
+
// Outside a hydration walk there is nothing to defer (see useIsHydrated).
|
|
502
|
+
if (!sharedConfig.context) {
|
|
503
|
+
return <>{props.children}</>;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Hydrating: render the fallback until the walk completes.
|
|
303
507
|
const [isHydrated, setIsHydrated] = createSignal(false);
|
|
304
508
|
|
|
305
509
|
// onMount runs after hydration is complete
|
|
@@ -334,16 +538,28 @@ export function useIsHydrated(): Accessor<boolean> {
|
|
|
334
538
|
return () => false;
|
|
335
539
|
}
|
|
336
540
|
|
|
337
|
-
//
|
|
541
|
+
// Outside a hydration walk (pure CSR, or a remount created after hydration
|
|
542
|
+
// finished) the caller is already "hydrated" — report true immediately.
|
|
543
|
+
// Solid sets `sharedConfig.context` only while synchronously walking
|
|
544
|
+
// server-rendered DOM, so this is exactly the window the false→true flip
|
|
545
|
+
// exists for. A fresh per-instance false→true flip on every remount is not
|
|
546
|
+
// just wasted work: ancestor `children()`/`Context.Provider` resolution
|
|
547
|
+
// unwraps and tracks the <Show> accessor this hook gates, so the post-mount
|
|
548
|
+
// flip re-resolves those children, recreates the subtree (with another fresh
|
|
549
|
+
// signal), and loops forever — a stack overflow with no overlay rendered.
|
|
550
|
+
if (!sharedConfig.context) {
|
|
551
|
+
return () => true;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// Hydrating: start false (so the first render matches the server, which
|
|
338
555
|
// emitted nothing for hydrated-gated content) and flip to true after mount.
|
|
339
556
|
const [isHydrated, setIsHydrated] = createSignal(false);
|
|
340
557
|
|
|
341
558
|
// onMount runs in the effect phase — *after* the synchronous hydration pass
|
|
342
559
|
// has finished walking the server DOM — so flipping here renders the gated
|
|
343
560
|
// content as a fresh client-side update (Portal: no getNextElement walk, no
|
|
344
|
-
// mismatch)
|
|
345
|
-
//
|
|
346
|
-
// gate above and is strictly earlier than a rAF tick.
|
|
561
|
+
// mismatch). This mirrors the component gate above and is strictly earlier
|
|
562
|
+
// than a rAF tick.
|
|
347
563
|
onMount(() => {
|
|
348
564
|
setIsHydrated(true);
|
|
349
565
|
});
|