@funstack/ui 0.1.0-alpha.1 → 0.1.0-alpha.3
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/accordion/accordion-context.mjs.map +1 -1
- package/dist/accordion/accordion-item.mjs +18 -4
- package/dist/accordion/accordion-item.mjs.map +1 -1
- package/dist/accordion/accordion-panel.mjs +2 -3
- package/dist/accordion/accordion-panel.mjs.map +1 -1
- package/dist/accordion/accordion-root.d.mts.map +1 -1
- package/dist/accordion/accordion-root.mjs +32 -14
- package/dist/accordion/accordion-root.mjs.map +1 -1
- package/dist/accordion/accordion-trigger.mjs +4 -5
- package/dist/accordion/accordion-trigger.mjs.map +1 -1
- package/dist/checkbox/checkbox.d.mts +5 -3
- package/dist/checkbox/checkbox.d.mts.map +1 -1
- package/dist/checkbox/checkbox.mjs +25 -9
- package/dist/checkbox/checkbox.mjs.map +1 -1
- package/dist/checkbox-group/checkbox-group-context.mjs.map +1 -1
- package/dist/checkbox-group/checkbox-group-item.d.mts +2 -1
- package/dist/checkbox-group/checkbox-group-item.d.mts.map +1 -1
- package/dist/checkbox-group/checkbox-group-item.mjs +3 -1
- package/dist/checkbox-group/checkbox-group-item.mjs.map +1 -1
- package/dist/checkbox-group/checkbox-group-root.d.mts +5 -2
- package/dist/checkbox-group/checkbox-group-root.d.mts.map +1 -1
- package/dist/checkbox-group/checkbox-group-root.mjs +24 -5
- package/dist/checkbox-group/checkbox-group-root.mjs.map +1 -1
- package/dist/combobox/combobox-clear.d.mts +34 -0
- package/dist/combobox/combobox-clear.d.mts.map +1 -0
- package/dist/combobox/combobox-clear.mjs +58 -0
- package/dist/combobox/combobox-clear.mjs.map +1 -0
- package/dist/combobox/combobox-context.mjs +23 -0
- package/dist/combobox/combobox-context.mjs.map +1 -0
- package/dist/combobox/combobox-group.d.mts +72 -0
- package/dist/combobox/combobox-group.d.mts.map +1 -0
- package/dist/combobox/combobox-group.mjs +104 -0
- package/dist/combobox/combobox-group.mjs.map +1 -0
- package/dist/combobox/combobox-input.d.mts +42 -0
- package/dist/combobox/combobox-input.d.mts.map +1 -0
- package/dist/combobox/combobox-input.mjs +102 -0
- package/dist/combobox/combobox-input.mjs.map +1 -0
- package/dist/combobox/combobox-label.d.mts +22 -0
- package/dist/combobox/combobox-label.d.mts.map +1 -0
- package/dist/combobox/combobox-label.mjs +32 -0
- package/dist/combobox/combobox-label.mjs.map +1 -0
- package/dist/combobox/combobox-list.d.mts +37 -0
- package/dist/combobox/combobox-list.d.mts.map +1 -0
- package/dist/combobox/combobox-list.mjs +70 -0
- package/dist/combobox/combobox-list.mjs.map +1 -0
- package/dist/combobox/combobox-option.d.mts +45 -0
- package/dist/combobox/combobox-option.d.mts.map +1 -0
- package/dist/combobox/combobox-option.mjs +88 -0
- package/dist/combobox/combobox-option.mjs.map +1 -0
- package/dist/combobox/combobox-popup.d.mts +49 -0
- package/dist/combobox/combobox-popup.d.mts.map +1 -0
- package/dist/combobox/combobox-popup.mjs +86 -0
- package/dist/combobox/combobox-popup.mjs.map +1 -0
- package/dist/combobox/combobox-root.d.mts +135 -0
- package/dist/combobox/combobox-root.d.mts.map +1 -0
- package/dist/combobox/combobox-root.mjs +523 -0
- package/dist/combobox/combobox-root.mjs.map +1 -0
- package/dist/combobox/combobox-trigger.d.mts +36 -0
- package/dist/combobox/combobox-trigger.d.mts.map +1 -0
- package/dist/combobox/combobox-trigger.mjs +92 -0
- package/dist/combobox/combobox-trigger.mjs.map +1 -0
- package/dist/combobox/index.d.mts +36 -0
- package/dist/combobox/index.d.mts.map +1 -0
- package/dist/combobox/index.mjs +36 -0
- package/dist/combobox/index.mjs.map +1 -0
- package/dist/dialog/dialog-close.d.mts +17 -10
- package/dist/dialog/dialog-close.d.mts.map +1 -1
- package/dist/dialog/dialog-close.mjs +31 -20
- package/dist/dialog/dialog-close.mjs.map +1 -1
- package/dist/dialog/dialog-context.mjs.map +1 -1
- package/dist/dialog/dialog-form.d.mts +12 -5
- package/dist/dialog/dialog-form.d.mts.map +1 -1
- package/dist/dialog/dialog-form.mjs +16 -28
- package/dist/dialog/dialog-form.mjs.map +1 -1
- package/dist/dialog/dialog-popup.d.mts +10 -4
- package/dist/dialog/dialog-popup.d.mts.map +1 -1
- package/dist/dialog/dialog-popup.mjs +106 -41
- package/dist/dialog/dialog-popup.mjs.map +1 -1
- package/dist/dialog/dialog-root.d.mts +14 -8
- package/dist/dialog/dialog-root.d.mts.map +1 -1
- package/dist/dialog/dialog-root.mjs +66 -11
- package/dist/dialog/dialog-root.mjs.map +1 -1
- package/dist/dialog/dialog-trigger.d.mts +3 -2
- package/dist/dialog/dialog-trigger.d.mts.map +1 -1
- package/dist/dialog/dialog-trigger.mjs.map +1 -1
- package/dist/dialog/index.d.mts +4 -2
- package/dist/dialog/index.d.mts.map +1 -1
- package/dist/dialog/index.mjs +4 -2
- package/dist/dialog/index.mjs.map +1 -1
- package/dist/field/field-control.d.mts +33 -0
- package/dist/field/field-control.d.mts.map +1 -0
- package/dist/field/field-control.mjs +68 -0
- package/dist/field/field-control.mjs.map +1 -0
- package/dist/field/field-description.d.mts +24 -0
- package/dist/field/field-description.d.mts.map +1 -0
- package/dist/field/field-description.mjs +34 -0
- package/dist/field/field-description.mjs.map +1 -0
- package/dist/field/field-error.d.mts +30 -0
- package/dist/field/field-error.d.mts.map +1 -0
- package/dist/field/field-error.mjs +42 -0
- package/dist/field/field-error.mjs.map +1 -0
- package/dist/field/field-label.d.mts +25 -0
- package/dist/field/field-label.d.mts.map +1 -0
- package/dist/field/field-label.mjs +46 -0
- package/dist/field/field-label.mjs.map +1 -0
- package/dist/field/field-root.d.mts +53 -0
- package/dist/field/field-root.d.mts.map +1 -0
- package/dist/field/field-root.mjs +317 -0
- package/dist/field/field-root.mjs.map +1 -0
- package/dist/field/index.d.mts +18 -0
- package/dist/field/index.d.mts.map +1 -0
- package/dist/field/index.mjs +17 -0
- package/dist/field/index.mjs.map +1 -0
- package/dist/form/form-root.d.mts +58 -0
- package/dist/form/form-root.d.mts.map +1 -0
- package/dist/form/form-root.mjs +146 -0
- package/dist/form/form-root.mjs.map +1 -0
- package/dist/form/form-submit.d.mts +31 -0
- package/dist/form/form-submit.d.mts.map +1 -0
- package/dist/form/form-submit.mjs +52 -0
- package/dist/form/form-submit.mjs.map +1 -0
- package/dist/form/index.d.mts +11 -0
- package/dist/form/index.d.mts.map +1 -0
- package/dist/form/index.mjs +11 -0
- package/dist/form/index.mjs.map +1 -0
- package/dist/index.d.mts +46 -2
- package/dist/index.mjs +8 -1
- package/dist/internal/content-focus-probe.mjs +42 -0
- package/dist/internal/content-focus-probe.mjs.map +1 -0
- package/dist/internal/field-context.d.mts +19 -0
- package/dist/internal/field-context.d.mts.map +1 -0
- package/dist/internal/field-context.mjs +14 -0
- package/dist/internal/field-context.mjs.map +1 -0
- package/dist/internal/focus-first-invalid.mjs +67 -0
- package/dist/internal/focus-first-invalid.mjs.map +1 -0
- package/dist/internal/form-status-watcher.mjs +31 -0
- package/dist/internal/form-status-watcher.mjs.map +1 -0
- package/dist/internal/modal-registry.mjs +39 -0
- package/dist/internal/modal-registry.mjs.map +1 -0
- package/dist/internal/platform-attributes.d.mts +12 -1
- package/dist/internal/platform-attributes.d.mts.map +1 -1
- package/dist/internal/types.d.mts +11 -1
- package/dist/internal/types.d.mts.map +1 -1
- package/dist/internal/use-controllable-action.mjs +35 -13
- package/dist/internal/use-controllable-action.mjs.map +1 -1
- package/dist/internal/use-field-control.mjs +107 -0
- package/dist/internal/use-field-control.mjs.map +1 -0
- package/dist/internal/use-form-owner-event.mjs +44 -0
- package/dist/internal/use-form-owner-event.mjs.map +1 -0
- package/dist/internal/use-form-reset.mjs +12 -31
- package/dist/internal/use-form-reset.mjs.map +1 -1
- package/dist/internal/use-hydrated-mount.mjs +21 -0
- package/dist/internal/use-hydrated-mount.mjs.map +1 -0
- package/dist/internal/use-latest.mjs +32 -0
- package/dist/internal/use-latest.mjs.map +1 -0
- package/dist/internal/use-modal-registration.mjs +47 -0
- package/dist/internal/use-modal-registration.mjs.map +1 -0
- package/dist/internal/use-native-group-reconciliation.mjs +6 -5
- package/dist/internal/use-native-group-reconciliation.mjs.map +1 -1
- package/dist/internal/use-native-select-value.mjs +184 -0
- package/dist/internal/use-native-select-value.mjs.map +1 -0
- package/dist/internal/use-popover-popup.mjs +8 -22
- package/dist/internal/use-popover-popup.mjs.map +1 -1
- package/dist/internal/use-popover-root.mjs +58 -23
- package/dist/internal/use-popover-root.mjs.map +1 -1
- package/dist/internal/validity.d.mts +24 -0
- package/dist/internal/validity.d.mts.map +1 -0
- package/dist/internal/validity.mjs +108 -0
- package/dist/internal/validity.mjs.map +1 -0
- package/dist/menu/menu-group.d.mts.map +1 -1
- package/dist/menu/menu-group.mjs +3 -2
- package/dist/menu/menu-group.mjs.map +1 -1
- package/dist/menu/menu-radio-group.mjs +9 -4
- package/dist/menu/menu-radio-group.mjs.map +1 -1
- package/dist/menu/menu-root.mjs.map +1 -1
- package/dist/radio-group/radio-group-root.d.mts +4 -2
- package/dist/radio-group/radio-group-root.d.mts.map +1 -1
- package/dist/radio-group/radio-group-root.mjs +34 -8
- package/dist/radio-group/radio-group-root.mjs.map +1 -1
- package/dist/select/index.d.mts +30 -0
- package/dist/select/index.d.mts.map +1 -0
- package/dist/select/index.mjs +30 -0
- package/dist/select/index.mjs.map +1 -0
- package/dist/select/select-context.mjs +13 -0
- package/dist/select/select-context.mjs.map +1 -0
- package/dist/select/select-dom.mjs +44 -0
- package/dist/select/select-dom.mjs.map +1 -0
- package/dist/select/select-group-label.d.mts +22 -0
- package/dist/select/select-group-label.d.mts.map +1 -0
- package/dist/select/select-group-label.mjs +39 -0
- package/dist/select/select-group-label.mjs.map +1 -0
- package/dist/select/select-group.d.mts +28 -0
- package/dist/select/select-group.d.mts.map +1 -0
- package/dist/select/select-group.mjs +47 -0
- package/dist/select/select-group.mjs.map +1 -0
- package/dist/select/select-option.d.mts +42 -0
- package/dist/select/select-option.d.mts.map +1 -0
- package/dist/select/select-option.mjs +65 -0
- package/dist/select/select-option.mjs.map +1 -0
- package/dist/select/select-root.d.mts +68 -0
- package/dist/select/select-root.d.mts.map +1 -0
- package/dist/select/select-root.mjs +114 -0
- package/dist/select/select-root.mjs.map +1 -0
- package/dist/select/select-separator.d.mts +20 -0
- package/dist/select/select-separator.d.mts.map +1 -0
- package/dist/select/select-separator.mjs +30 -0
- package/dist/select/select-separator.mjs.map +1 -0
- package/dist/select/select-trigger.d.mts +29 -0
- package/dist/select/select-trigger.d.mts.map +1 -0
- package/dist/select/select-trigger.mjs +48 -0
- package/dist/select/select-trigger.mjs.map +1 -0
- package/dist/select/select-value.d.mts +31 -0
- package/dist/select/select-value.d.mts.map +1 -0
- package/dist/select/select-value.mjs +101 -0
- package/dist/select/select-value.mjs.map +1 -0
- package/dist/slider/index.d.mts +32 -0
- package/dist/slider/index.d.mts.map +1 -0
- package/dist/slider/index.mjs +27 -0
- package/dist/slider/index.mjs.map +1 -0
- package/dist/slider/slider-arithmetic.mjs +120 -0
- package/dist/slider/slider-arithmetic.mjs.map +1 -0
- package/dist/slider/slider-context.mjs +13 -0
- package/dist/slider/slider-context.mjs.map +1 -0
- package/dist/slider/slider-indicator.d.mts +22 -0
- package/dist/slider/slider-indicator.d.mts.map +1 -0
- package/dist/slider/slider-indicator.mjs +36 -0
- package/dist/slider/slider-indicator.mjs.map +1 -0
- package/dist/slider/slider-label.d.mts +23 -0
- package/dist/slider/slider-label.d.mts.map +1 -0
- package/dist/slider/slider-label.mjs +44 -0
- package/dist/slider/slider-label.mjs.map +1 -0
- package/dist/slider/slider-root.d.mts +111 -0
- package/dist/slider/slider-root.d.mts.map +1 -0
- package/dist/slider/slider-root.mjs +582 -0
- package/dist/slider/slider-root.mjs.map +1 -0
- package/dist/slider/slider-thumb.d.mts +58 -0
- package/dist/slider/slider-thumb.d.mts.map +1 -0
- package/dist/slider/slider-thumb.mjs +145 -0
- package/dist/slider/slider-thumb.mjs.map +1 -0
- package/dist/slider/slider-track.d.mts +29 -0
- package/dist/slider/slider-track.d.mts.map +1 -0
- package/dist/slider/slider-track.mjs +54 -0
- package/dist/slider/slider-track.mjs.map +1 -0
- package/dist/slider/slider-value.d.mts +34 -0
- package/dist/slider/slider-value.d.mts.map +1 -0
- package/dist/slider/slider-value.mjs +38 -0
- package/dist/slider/slider-value.mjs.map +1 -0
- package/dist/switch/switch.d.mts +5 -3
- package/dist/switch/switch.d.mts.map +1 -1
- package/dist/switch/switch.mjs +24 -8
- package/dist/switch/switch.mjs.map +1 -1
- package/dist/tabs/tabs-root.mjs +13 -3
- package/dist/tabs/tabs-root.mjs.map +1 -1
- package/dist/toast/index.d.mts +25 -0
- package/dist/toast/index.d.mts.map +1 -0
- package/dist/toast/index.mjs +26 -0
- package/dist/toast/index.mjs.map +1 -0
- package/dist/toast/toast-action.d.mts +39 -0
- package/dist/toast/toast-action.d.mts.map +1 -0
- package/dist/toast/toast-action.mjs +64 -0
- package/dist/toast/toast-action.mjs.map +1 -0
- package/dist/toast/toast-close.d.mts +25 -0
- package/dist/toast/toast-close.d.mts.map +1 -0
- package/dist/toast/toast-close.mjs +46 -0
- package/dist/toast/toast-close.mjs.map +1 -0
- package/dist/toast/toast-context.mjs +19 -0
- package/dist/toast/toast-context.mjs.map +1 -0
- package/dist/toast/toast-description.d.mts +24 -0
- package/dist/toast/toast-description.d.mts.map +1 -0
- package/dist/toast/toast-description.mjs +35 -0
- package/dist/toast/toast-description.mjs.map +1 -0
- package/dist/toast/toast-root.d.mts +43 -0
- package/dist/toast/toast-root.d.mts.map +1 -0
- package/dist/toast/toast-root.mjs +204 -0
- package/dist/toast/toast-root.mjs.map +1 -0
- package/dist/toast/toast-title.d.mts +24 -0
- package/dist/toast/toast-title.d.mts.map +1 -0
- package/dist/toast/toast-title.mjs +33 -0
- package/dist/toast/toast-title.mjs.map +1 -0
- package/dist/toast/toast-viewport.d.mts +52 -0
- package/dist/toast/toast-viewport.d.mts.map +1 -0
- package/dist/toast/toast-viewport.mjs +621 -0
- package/dist/toast/toast-viewport.mjs.map +1 -0
- package/dist/toast/toast.d.mts +119 -0
- package/dist/toast/toast.d.mts.map +1 -0
- package/dist/toast/toast.mjs +153 -0
- package/dist/toast/toast.mjs.map +1 -0
- package/package.json +7 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-context.mjs","names":[],"sources":["../../src/select/select-context.ts"],"sourcesContent":["\"use client\";\nimport { createContext, use } from \"react\";\n\nexport interface SelectContextValue {\n /** Optimistic value: Options render `data-selected` from it. */\n readonly optimistic: string;\n readonly pending: boolean;\n /** `Root disabled` (natively disables the whole `<select>`). */\n readonly disabled: boolean;\n /** Inside a `Select.Group disabled` (`false` outside groups): Options match `:disabled`. */\n readonly groupDisabled: boolean;\n /**\n * Called by each Option from its mount layout effect with its element and whether that render\n * hydrated server HTML. Late options are re-applied, and hydrated late options reconciled\n * (design/components/select.md 6.2).\n */\n readonly optionMounted: (el: HTMLOptionElement | null, hydrated: boolean) => void;\n}\n\nexport const SelectContext = createContext<SelectContextValue | null>(null);\n\nexport function useSelectContext(part: string): SelectContextValue {\n const context = use(SelectContext);\n if (context === null) {\n throw new Error(`${part} must be rendered inside a Select.Root.`);\n }\n return context;\n}\n"],"mappings":";;;AAmBA,MAAa,gBAAgB,cAAyC,IAAI;AAE1E,SAAgB,iBAAiB,MAAkC;CACjE,MAAM,UAAU,IAAI,aAAa;CACjC,IAAI,YAAY,MACd,MAAM,IAAI,MAAM,GAAG,KAAK,wCAAwC;CAElE,OAAO;AACT"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useRef } from "react";
|
|
3
|
+
//#region src/select/select-dom.ts
|
|
4
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
5
|
+
/**
|
|
6
|
+
* The library ref of a Select part: stores the node in `node` and, in development,
|
|
7
|
+
* warns once per instance when the mounted element is not `<tag>` (conventions 1.2: Select's parts
|
|
8
|
+
* keep their native elements) or when `position` reports a misplaced element (a message, or
|
|
9
|
+
* `null` when the element is where HTML wants it). Ref callbacks run in the layout phase, when
|
|
10
|
+
* the element's siblings are in place.
|
|
11
|
+
*/
|
|
12
|
+
function useSelectPartRef(component, tag, position) {
|
|
13
|
+
const node = useRef(null);
|
|
14
|
+
const warnedTag = useRef(false);
|
|
15
|
+
const warnedPosition = useRef(false);
|
|
16
|
+
return {
|
|
17
|
+
ref: useCallback((el) => {
|
|
18
|
+
node.current = el;
|
|
19
|
+
if (isDev && !warnedTag.current && el.tagName !== tag.toUpperCase()) {
|
|
20
|
+
warnedTag.current = true;
|
|
21
|
+
console.error(`${component}: expected to render a <${tag}> element but got <${el.tagName.toLowerCase()}>. The parser, the picker and <selectedcontent> cloning key on the native element; a \`render\` element must keep it.`);
|
|
22
|
+
}
|
|
23
|
+
if (isDev && position && !warnedPosition.current) {
|
|
24
|
+
const message = position(el);
|
|
25
|
+
if (message !== null) {
|
|
26
|
+
warnedPosition.current = true;
|
|
27
|
+
console.error(`${component}: ${message}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return () => {
|
|
31
|
+
node.current = null;
|
|
32
|
+
};
|
|
33
|
+
}, [
|
|
34
|
+
component,
|
|
35
|
+
tag,
|
|
36
|
+
position
|
|
37
|
+
]),
|
|
38
|
+
node
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { useSelectPartRef };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=select-dom.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-dom.mjs","names":[],"sources":["../../src/select/select-dom.ts"],"sourcesContent":["\"use client\";\nimport { useCallback, useRef } from \"react\";\nimport type { RefCallback, RefObject } from \"react\";\n\nconst isDev = process.env.NODE_ENV !== \"production\";\n\nexport interface SelectPartRef<E extends Element> {\n /** The library ref to pass to `useRender`. */\n readonly ref: RefCallback<E>;\n /** The mounted element. Read it from effects and handlers only. */\n readonly node: RefObject<E | null>;\n}\n\n/**\n * The library ref of a Select part: stores the node in `node` and, in development,\n * warns once per instance when the mounted element is not `<tag>` (conventions 1.2: Select's parts\n * keep their native elements) or when `position` reports a misplaced element (a message, or\n * `null` when the element is where HTML wants it). Ref callbacks run in the layout phase, when\n * the element's siblings are in place.\n */\nexport function useSelectPartRef<E extends Element>(\n component: string,\n tag: string,\n position?: (el: E) => string | null,\n): SelectPartRef<E> {\n const node = useRef<E | null>(null);\n const warnedTag = useRef(false);\n const warnedPosition = useRef(false);\n const ref = useCallback(\n (el: E) => {\n node.current = el;\n if (isDev && !warnedTag.current && el.tagName !== tag.toUpperCase()) {\n warnedTag.current = true;\n console.error(\n `${component}: expected to render a <${tag}> element but got ` +\n `<${el.tagName.toLowerCase()}>. The parser, the picker and <selectedcontent> cloning ` +\n `key on the native element; a \\`render\\` element must keep it.`,\n );\n }\n if (isDev && position && !warnedPosition.current) {\n const message = position(el);\n if (message !== null) {\n warnedPosition.current = true;\n console.error(`${component}: ${message}`);\n }\n }\n return () => {\n node.current = null;\n };\n },\n // `position` is a module-level function at every call site, so the callback is stable.\n [component, tag, position],\n );\n return { ref, node };\n}\n"],"mappings":";;;AAIA,MAAM,QAAQ,QAAQ,IAAI,aAAa;;;;;;;;AAgBvC,SAAgB,iBACd,WACA,KACA,UACkB;CAClB,MAAM,OAAO,OAAiB,IAAI;CAClC,MAAM,YAAY,OAAO,KAAK;CAC9B,MAAM,iBAAiB,OAAO,KAAK;CA0BnC,OAAO;EAAE,KAzBG,aACT,OAAU;GACT,KAAK,UAAU;GACf,IAAI,SAAS,CAAC,UAAU,WAAW,GAAG,YAAY,IAAI,YAAY,GAAG;IACnE,UAAU,UAAU;IACpB,QAAQ,MACN,GAAG,UAAU,0BAA0B,IAAI,qBACrC,GAAG,QAAQ,YAAY,EAAE,sHAEjC;GACF;GACA,IAAI,SAAS,YAAY,CAAC,eAAe,SAAS;IAChD,MAAM,UAAU,SAAS,EAAE;IAC3B,IAAI,YAAY,MAAM;KACpB,eAAe,UAAU;KACzB,QAAQ,MAAM,GAAG,UAAU,IAAI,SAAS;IAC1C;GACF;GACA,aAAa;IACX,KAAK,UAAU;GACjB;EACF,GAEA;GAAC;GAAW;GAAK;EAAQ,CAEhB;EAAG;CAAK;AACrB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RenderProp, StateValue } from "../internal/types.mjs";
|
|
2
|
+
import { SelectRootState } from "./select-root.mjs";
|
|
3
|
+
import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
|
|
4
|
+
//#region src/select/select-group-label.d.ts
|
|
5
|
+
export interface SelectGroupLabelProps extends Omit<ComponentPropsWithRef<"legend">, "className" | "style" | "children"> {
|
|
6
|
+
className?: StateValue<string | undefined, SelectRootState>;
|
|
7
|
+
style?: StateValue<CSSProperties | undefined, SelectRootState>;
|
|
8
|
+
children?: StateValue<ReactNode, SelectRootState>;
|
|
9
|
+
/** Replace the rendered element. Must keep a `<legend>`. */
|
|
10
|
+
render?: RenderProp<ComponentPropsWithRef<"legend">, SelectRootState>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The rich label of a `Select.Group`: a `<legend>`, rendered by engines with customizable select.
|
|
14
|
+
* Optional; must be the **first child** of its Group. Keep its text equal to the Group's `label`,
|
|
15
|
+
* which native pickers and assistive technology use. Owns no keys.
|
|
16
|
+
*/
|
|
17
|
+
export declare function SelectGroupLabel({ className, style, children, render, ...rest }: SelectGroupLabelProps): ReactNode;
|
|
18
|
+
export declare namespace SelectGroupLabel {
|
|
19
|
+
var displayName: string;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//# sourceMappingURL=select-group-label.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-group-label.d.mts","names":[],"sources":["../../src/select/select-group-label.tsx"],"mappings":";;;;iBAQiB,8BAA8B,KAC7C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,iCAAiC;;;;;;;wBAcvC,mBACd,WACA,OACA,UACA,WACG,QACF,wBAAqB;yBANR"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRender } from "../internal/use-render.mjs";
|
|
3
|
+
import { useSelectContext } from "./select-context.mjs";
|
|
4
|
+
import { useSelectPartRef } from "./select-dom.mjs";
|
|
5
|
+
//#region src/select/select-group-label.tsx
|
|
6
|
+
function firstChildOfGroup(el) {
|
|
7
|
+
const parent = el.parentElement;
|
|
8
|
+
if (parent?.tagName === "OPTGROUP" && parent.firstElementChild === el) return null;
|
|
9
|
+
return "must be the first child of a Select.Group's <optgroup> (HTML content model).";
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The rich label of a `Select.Group`: a `<legend>`, rendered by engines with customizable select.
|
|
13
|
+
* Optional; must be the **first child** of its Group. Keep its text equal to the Group's `label`,
|
|
14
|
+
* which native pickers and assistive technology use. Owns no keys.
|
|
15
|
+
*/
|
|
16
|
+
function SelectGroupLabel({ className, style, children, render, ...rest }) {
|
|
17
|
+
const ctx = useSelectContext("Select.GroupLabel");
|
|
18
|
+
const state = {
|
|
19
|
+
value: ctx.optimistic,
|
|
20
|
+
pending: ctx.pending,
|
|
21
|
+
disabled: ctx.disabled
|
|
22
|
+
};
|
|
23
|
+
const { ref } = useSelectPartRef("Select.GroupLabel", "legend", firstChildOfGroup);
|
|
24
|
+
return useRender({
|
|
25
|
+
defaultElement: "legend",
|
|
26
|
+
render,
|
|
27
|
+
state,
|
|
28
|
+
className,
|
|
29
|
+
style,
|
|
30
|
+
children,
|
|
31
|
+
props: rest,
|
|
32
|
+
ref
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
SelectGroupLabel.displayName = "SelectGroupLabel";
|
|
36
|
+
//#endregion
|
|
37
|
+
export { SelectGroupLabel };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=select-group-label.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-group-label.mjs","names":[],"sources":["../../src/select/select-group-label.tsx"],"sourcesContent":["\"use client\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { useSelectContext } from \"./select-context.js\";\nimport { useSelectPartRef } from \"./select-dom.js\";\nimport type { SelectRootState } from \"./select-root.js\";\n\nexport interface SelectGroupLabelProps extends Omit<\n ComponentPropsWithRef<\"legend\">,\n \"className\" | \"style\" | \"children\"\n> {\n className?: StateValue<string | undefined, SelectRootState>;\n style?: StateValue<CSSProperties | undefined, SelectRootState>;\n children?: StateValue<ReactNode, SelectRootState>;\n /** Replace the rendered element. Must keep a `<legend>`. */\n render?: RenderProp<ComponentPropsWithRef<\"legend\">, SelectRootState>;\n}\n\nfunction firstChildOfGroup(el: HTMLLegendElement): string | null {\n const parent = el.parentElement;\n if (parent?.tagName === \"OPTGROUP\" && parent.firstElementChild === el) return null;\n return \"must be the first child of a Select.Group's <optgroup> (HTML content model).\";\n}\n\n/**\n * The rich label of a `Select.Group`: a `<legend>`, rendered by engines with customizable select.\n * Optional; must be the **first child** of its Group. Keep its text equal to the Group's `label`,\n * which native pickers and assistive technology use. Owns no keys.\n */\nexport function SelectGroupLabel({\n className,\n style,\n children,\n render,\n ...rest\n}: SelectGroupLabelProps) {\n const ctx = useSelectContext(\"Select.GroupLabel\");\n const state: SelectRootState = {\n value: ctx.optimistic,\n pending: ctx.pending,\n disabled: ctx.disabled,\n };\n const { ref } = useSelectPartRef<HTMLLegendElement>(\n \"Select.GroupLabel\",\n \"legend\",\n firstChildOfGroup,\n );\n return useRender<ComponentPropsWithRef<\"legend\">, SelectRootState>({\n defaultElement: \"legend\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n ref,\n });\n}\n\nSelectGroupLabel.displayName = \"SelectGroupLabel\";\n"],"mappings":";;;;;AAmBA,SAAS,kBAAkB,IAAsC;CAC/D,MAAM,SAAS,GAAG;CAClB,IAAI,QAAQ,YAAY,cAAc,OAAO,sBAAsB,IAAI,OAAO;CAC9E,OAAO;AACT;;;;;;AAOA,SAAgB,iBAAiB,EAC/B,WACA,OACA,UACA,QACA,GAAG,QACqB;CACxB,MAAM,MAAM,iBAAiB,mBAAmB;CAChD,MAAM,QAAyB;EAC7B,OAAO,IAAI;EACX,SAAS,IAAI;EACb,UAAU,IAAI;CAChB;CACA,MAAM,EAAE,QAAQ,iBACd,qBACA,UACA,iBACF;CACA,OAAO,UAA4D;EACjE,gBAAgB;EAChB;EACA;EACA;EACA;EACA;EACA,OAAO;EACP;CACF,CAAC;AACH;AAEA,iBAAiB,cAAc"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { RenderProp, StateValue } from "../internal/types.mjs";
|
|
2
|
+
import { SelectRootState } from "./select-root.mjs";
|
|
3
|
+
import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
|
|
4
|
+
//#region src/select/select-group.d.ts
|
|
5
|
+
export interface SelectGroupProps extends Omit<ComponentPropsWithRef<"optgroup">, "label" | "className" | "style" | "children"> {
|
|
6
|
+
/**
|
|
7
|
+
* The `<optgroup label>`: shown by native pickers (Firefox today) and read by assistive
|
|
8
|
+
* technology. Required. Keep it equal to the text of a `Select.GroupLabel`, if any.
|
|
9
|
+
*/
|
|
10
|
+
label: string;
|
|
11
|
+
/** Native `disabled`: every option in the group is disabled. */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
className?: StateValue<string | undefined, SelectRootState>;
|
|
14
|
+
style?: StateValue<CSSProperties | undefined, SelectRootState>;
|
|
15
|
+
children?: StateValue<ReactNode, SelectRootState>;
|
|
16
|
+
/** Replace the rendered element. Must keep an `<optgroup>`. */
|
|
17
|
+
render?: RenderProp<ComponentPropsWithRef<"optgroup">, SelectRootState>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* An `<optgroup>` of options. Its state is the Root's state. Owned key: `label`. Its `disabled`
|
|
21
|
+
* reaches the Options' `state.disabled` / `data-disabled` through context, as `:disabled` does.
|
|
22
|
+
*/
|
|
23
|
+
export declare function SelectGroup({ label, disabled, className, style, children, render, ...rest }: SelectGroupProps): import("react").JSX.Element;
|
|
24
|
+
export declare namespace SelectGroup {
|
|
25
|
+
var displayName: string;
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//# sourceMappingURL=select-group.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-group.d.mts","names":[],"sources":["../../src/select/select-group.tsx"],"mappings":";;;;iBASiB,yBAAyB,KACxC;;;;;EAOA;;EAEA;EACA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,mCAAmC;;;;;;wBAOzC,cACd,OACA,UACA,WACA,OACA,UACA,WACG,QACF,mCAAgB,IAAA;yBARH"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRender } from "../internal/use-render.mjs";
|
|
3
|
+
import { SelectContext, useSelectContext } from "./select-context.mjs";
|
|
4
|
+
import { useSelectPartRef } from "./select-dom.mjs";
|
|
5
|
+
import { useMemo } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/select/select-group.tsx
|
|
8
|
+
/**
|
|
9
|
+
* An `<optgroup>` of options. Its state is the Root's state. Owned key: `label`. Its `disabled`
|
|
10
|
+
* reaches the Options' `state.disabled` / `data-disabled` through context, as `:disabled` does.
|
|
11
|
+
*/
|
|
12
|
+
function SelectGroup({ label, disabled = false, className, style, children, render, ...rest }) {
|
|
13
|
+
const ctx = useSelectContext("Select.Group");
|
|
14
|
+
const state = {
|
|
15
|
+
value: ctx.optimistic,
|
|
16
|
+
pending: ctx.pending,
|
|
17
|
+
disabled: ctx.disabled
|
|
18
|
+
};
|
|
19
|
+
const { ref } = useSelectPartRef("Select.Group", "optgroup");
|
|
20
|
+
const element = useRender({
|
|
21
|
+
defaultElement: "optgroup",
|
|
22
|
+
render,
|
|
23
|
+
state,
|
|
24
|
+
className,
|
|
25
|
+
style,
|
|
26
|
+
children,
|
|
27
|
+
props: {
|
|
28
|
+
...rest,
|
|
29
|
+
disabled
|
|
30
|
+
},
|
|
31
|
+
libraryProps: { label },
|
|
32
|
+
ref
|
|
33
|
+
});
|
|
34
|
+
const context = useMemo(() => ({
|
|
35
|
+
...ctx,
|
|
36
|
+
groupDisabled: disabled
|
|
37
|
+
}), [ctx, disabled]);
|
|
38
|
+
return /* @__PURE__ */ jsx(SelectContext, {
|
|
39
|
+
value: context,
|
|
40
|
+
children: element
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
SelectGroup.displayName = "SelectGroup";
|
|
44
|
+
//#endregion
|
|
45
|
+
export { SelectGroup };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=select-group.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-group.mjs","names":[],"sources":["../../src/select/select-group.tsx"],"sourcesContent":["\"use client\";\nimport { useMemo } from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { SelectContext, useSelectContext } from \"./select-context.js\";\nimport { useSelectPartRef } from \"./select-dom.js\";\nimport type { SelectRootState } from \"./select-root.js\";\n\nexport interface SelectGroupProps extends Omit<\n ComponentPropsWithRef<\"optgroup\">,\n \"label\" | \"className\" | \"style\" | \"children\"\n> {\n /**\n * The `<optgroup label>`: shown by native pickers (Firefox today) and read by assistive\n * technology. Required. Keep it equal to the text of a `Select.GroupLabel`, if any.\n */\n label: string;\n /** Native `disabled`: every option in the group is disabled. */\n disabled?: boolean;\n className?: StateValue<string | undefined, SelectRootState>;\n style?: StateValue<CSSProperties | undefined, SelectRootState>;\n children?: StateValue<ReactNode, SelectRootState>;\n /** Replace the rendered element. Must keep an `<optgroup>`. */\n render?: RenderProp<ComponentPropsWithRef<\"optgroup\">, SelectRootState>;\n}\n\n/**\n * An `<optgroup>` of options. Its state is the Root's state. Owned key: `label`. Its `disabled`\n * reaches the Options' `state.disabled` / `data-disabled` through context, as `:disabled` does.\n */\nexport function SelectGroup({\n label,\n disabled = false,\n className,\n style,\n children,\n render,\n ...rest\n}: SelectGroupProps) {\n const ctx = useSelectContext(\"Select.Group\");\n const state: SelectRootState = {\n value: ctx.optimistic,\n pending: ctx.pending,\n disabled: ctx.disabled,\n };\n const { ref } = useSelectPartRef<HTMLOptGroupElement>(\"Select.Group\", \"optgroup\");\n const element = useRender<ComponentPropsWithRef<\"optgroup\">, SelectRootState>({\n defaultElement: \"optgroup\",\n render,\n state,\n className,\n style,\n children,\n props: { ...rest, disabled },\n libraryProps: { label },\n ref,\n });\n // Nested groups are not valid HTML, so this only ever turns `false` into the group's value.\n const context = useMemo(() => ({ ...ctx, groupDisabled: disabled }), [ctx, disabled]);\n return <SelectContext value={context}>{element}</SelectContext>;\n}\n\nSelectGroup.displayName = \"SelectGroup\";\n"],"mappings":";;;;;;;;;;;AA+BA,SAAgB,YAAY,EAC1B,OACA,WAAW,OACX,WACA,OACA,UACA,QACA,GAAG,QACgB;CACnB,MAAM,MAAM,iBAAiB,cAAc;CAC3C,MAAM,QAAyB;EAC7B,OAAO,IAAI;EACX,SAAS,IAAI;EACb,UAAU,IAAI;CAChB;CACA,MAAM,EAAE,QAAQ,iBAAsC,gBAAgB,UAAU;CAChF,MAAM,UAAU,UAA8D;EAC5E,gBAAgB;EAChB;EACA;EACA;EACA;EACA;EACA,OAAO;GAAE,GAAG;GAAM;EAAS;EAC3B,cAAc,EAAE,MAAM;EACtB;CACF,CAAC;CAED,MAAM,UAAU,eAAe;EAAE,GAAG;EAAK,eAAe;CAAS,IAAI,CAAC,KAAK,QAAQ,CAAC;CACpF,OAAO,oBAAC,eAAD;EAAe,OAAO;EAAU,UAAA;CAAuB,CAAA;AAChE;AAEA,YAAY,cAAc"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { RenderProp, StateValue } from "../internal/types.mjs";
|
|
2
|
+
import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
|
|
3
|
+
//#region src/select/select-option.d.ts
|
|
4
|
+
export interface SelectOptionState {
|
|
5
|
+
readonly value: string;
|
|
6
|
+
/** Optimistic: true as soon as the user picks this option, before the action settles. */
|
|
7
|
+
readonly selected: boolean;
|
|
8
|
+
/** The Root is pending and this option is the optimistic target. */
|
|
9
|
+
readonly pending: boolean;
|
|
10
|
+
/** Disabled by its own prop, a disabled `Select.Group`, or `Root disabled` (as `:disabled`). */
|
|
11
|
+
readonly disabled: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface SelectOptionProps extends Omit<ComponentPropsWithRef<"option">, "value" | "selected" | "className" | "style" | "children"> {
|
|
14
|
+
/** The option's value. Required: React cannot infer a value from rich children. */
|
|
15
|
+
value: string;
|
|
16
|
+
/** Native `disabled`: not pickable, skipped by keyboard navigation. */
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
className?: StateValue<string | undefined, SelectOptionState>;
|
|
19
|
+
style?: StateValue<CSSProperties | undefined, SelectOptionState>;
|
|
20
|
+
/**
|
|
21
|
+
* The option's content. Keep it readable as plain text: engines without customizable select
|
|
22
|
+
* (Firefox today) show only the text. Give icons `aria-hidden` and no text. Avoid the `label`
|
|
23
|
+
* attribute (Chromium names the option from it but shows the content).
|
|
24
|
+
*/
|
|
25
|
+
children?: StateValue<ReactNode, SelectOptionState>;
|
|
26
|
+
/** Replace the rendered element. Must keep an `<option>`. */
|
|
27
|
+
render?: RenderProp<ComponentPropsWithRef<"option">, SelectOptionState>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* One `<option>`. It never renders `selected`: the selection is the Root's `value={optimistic}`
|
|
31
|
+
* plus the Root's re-apply for options that mount after the select's own commit (a Suspense
|
|
32
|
+
* boundary or `use()` inside the select), which the Option reports from its mount layout effect.
|
|
33
|
+
*
|
|
34
|
+
* Owned keys: `value`, `selected` (never rendered), `disabled`, `data-selected`, `data-pending`,
|
|
35
|
+
* `data-disabled`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function SelectOption({ value, disabled: disabledProp, className, style, children, render, ...rest }: SelectOptionProps): ReactNode;
|
|
38
|
+
export declare namespace SelectOption {
|
|
39
|
+
var displayName: string;
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//# sourceMappingURL=select-option.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-option.d.mts","names":[],"sources":["../../src/select/select-option.tsx"],"mappings":";;;iBAWiB;WACN;;WAEA;;WAEA;;WAEA;;iBAGM,0BAA0B,KACzC;;EAIA;;EAEA;EACA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;;;;;EAM9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,iCAAiC;;;;;;;;;;wBAWvC,eACd,OACA,UAAU,cACV,WACA,OACA,UACA,WACG,QACF,oBAAiB;yBARJ"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { dataAttr } from "../internal/data-attr.mjs";
|
|
3
|
+
import { useRender } from "../internal/use-render.mjs";
|
|
4
|
+
import { syncPresence } from "../internal/sync-presence.mjs";
|
|
5
|
+
import { useSelectContext } from "./select-context.mjs";
|
|
6
|
+
import { useSelectPartRef } from "./select-dom.mjs";
|
|
7
|
+
import { useHydratedMount } from "../internal/use-hydrated-mount.mjs";
|
|
8
|
+
import { useEffectEvent, useLayoutEffect } from "react";
|
|
9
|
+
//#region src/select/select-option.tsx
|
|
10
|
+
/**
|
|
11
|
+
* One `<option>`. It never renders `selected`: the selection is the Root's `value={optimistic}`
|
|
12
|
+
* plus the Root's re-apply for options that mount after the select's own commit (a Suspense
|
|
13
|
+
* boundary or `use()` inside the select), which the Option reports from its mount layout effect.
|
|
14
|
+
*
|
|
15
|
+
* Owned keys: `value`, `selected` (never rendered), `disabled`, `data-selected`, `data-pending`,
|
|
16
|
+
* `data-disabled`.
|
|
17
|
+
*/
|
|
18
|
+
function SelectOption({ value, disabled: disabledProp = false, className, style, children, render, ...rest }) {
|
|
19
|
+
const ctx = useSelectContext("Select.Option");
|
|
20
|
+
const selected = ctx.optimistic === value;
|
|
21
|
+
const pending = ctx.pending && selected;
|
|
22
|
+
const disabled = ctx.disabled || ctx.groupDisabled || disabledProp;
|
|
23
|
+
const hydrated = useHydratedMount();
|
|
24
|
+
const { ref, node } = useSelectPartRef("Select.Option", "option");
|
|
25
|
+
const reportMount = useEffectEvent(() => {
|
|
26
|
+
const el = node.current;
|
|
27
|
+
if (el !== null) {
|
|
28
|
+
syncPresence(el, "data-selected", selected);
|
|
29
|
+
syncPresence(el, "data-pending", pending);
|
|
30
|
+
syncPresence(el, "data-disabled", disabled);
|
|
31
|
+
}
|
|
32
|
+
ctx.optionMounted(el, hydrated);
|
|
33
|
+
});
|
|
34
|
+
useLayoutEffect(() => {
|
|
35
|
+
reportMount();
|
|
36
|
+
}, []);
|
|
37
|
+
return useRender({
|
|
38
|
+
defaultElement: "option",
|
|
39
|
+
render,
|
|
40
|
+
state: {
|
|
41
|
+
value,
|
|
42
|
+
selected,
|
|
43
|
+
pending,
|
|
44
|
+
disabled
|
|
45
|
+
},
|
|
46
|
+
className,
|
|
47
|
+
style,
|
|
48
|
+
children,
|
|
49
|
+
props: rest,
|
|
50
|
+
libraryProps: {
|
|
51
|
+
value,
|
|
52
|
+
selected: void 0,
|
|
53
|
+
disabled: disabledProp,
|
|
54
|
+
"data-selected": dataAttr(selected),
|
|
55
|
+
"data-pending": dataAttr(pending),
|
|
56
|
+
"data-disabled": dataAttr(disabled)
|
|
57
|
+
},
|
|
58
|
+
ref
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
SelectOption.displayName = "SelectOption";
|
|
62
|
+
//#endregion
|
|
63
|
+
export { SelectOption };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=select-option.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-option.mjs","names":[],"sources":["../../src/select/select-option.tsx"],"sourcesContent":["\"use client\";\nimport { useEffectEvent, useLayoutEffect } from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport { syncPresence } from \"../internal/sync-presence.js\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { useHydratedMount } from \"../internal/use-hydrated-mount.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { useSelectContext } from \"./select-context.js\";\nimport { useSelectPartRef } from \"./select-dom.js\";\n\nexport interface SelectOptionState {\n readonly value: string;\n /** Optimistic: true as soon as the user picks this option, before the action settles. */\n readonly selected: boolean;\n /** The Root is pending and this option is the optimistic target. */\n readonly pending: boolean;\n /** Disabled by its own prop, a disabled `Select.Group`, or `Root disabled` (as `:disabled`). */\n readonly disabled: boolean;\n}\n\nexport interface SelectOptionProps extends Omit<\n ComponentPropsWithRef<\"option\">,\n \"value\" | \"selected\" | \"className\" | \"style\" | \"children\"\n> {\n /** The option's value. Required: React cannot infer a value from rich children. */\n value: string;\n /** Native `disabled`: not pickable, skipped by keyboard navigation. */\n disabled?: boolean;\n className?: StateValue<string | undefined, SelectOptionState>;\n style?: StateValue<CSSProperties | undefined, SelectOptionState>;\n /**\n * The option's content. Keep it readable as plain text: engines without customizable select\n * (Firefox today) show only the text. Give icons `aria-hidden` and no text. Avoid the `label`\n * attribute (Chromium names the option from it but shows the content).\n */\n children?: StateValue<ReactNode, SelectOptionState>;\n /** Replace the rendered element. Must keep an `<option>`. */\n render?: RenderProp<ComponentPropsWithRef<\"option\">, SelectOptionState>;\n}\n\n/**\n * One `<option>`. It never renders `selected`: the selection is the Root's `value={optimistic}`\n * plus the Root's re-apply for options that mount after the select's own commit (a Suspense\n * boundary or `use()` inside the select), which the Option reports from its mount layout effect.\n *\n * Owned keys: `value`, `selected` (never rendered), `disabled`, `data-selected`, `data-pending`,\n * `data-disabled`.\n */\nexport function SelectOption({\n value,\n disabled: disabledProp = false,\n className,\n style,\n children,\n render,\n ...rest\n}: SelectOptionProps) {\n const ctx = useSelectContext(\"Select.Option\");\n const selected = ctx.optimistic === value;\n const pending = ctx.pending && selected;\n const disabled = ctx.disabled || ctx.groupDisabled || disabledProp;\n const hydrated = useHydratedMount();\n const { ref, node } = useSelectPartRef<HTMLOptionElement>(\"Select.Option\", \"option\");\n\n // Reads the mount render's values: for a hydrated option that is the hydration render, which\n // used the server snapshot (`hydrated === true`).\n const reportMount = useEffectEvent(() => {\n const el = node.current;\n if (el !== null) {\n // Hydration keeps server attributes that differ from the client render (React only warns);\n // an option hydrating after its Root can render a different state than the server did.\n syncPresence(el, \"data-selected\", selected);\n syncPresence(el, \"data-pending\", pending);\n syncPresence(el, \"data-disabled\", disabled);\n }\n ctx.optionMounted(el, hydrated);\n });\n useLayoutEffect(() => {\n reportMount();\n }, []);\n\n const state: SelectOptionState = { value, selected, pending, disabled };\n\n return useRender<ComponentPropsWithRef<\"option\">, SelectOptionState>({\n defaultElement: \"option\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n libraryProps: {\n value,\n selected: undefined,\n // Only the Option's own prop: `Root disabled` and the Group disable natively themselves.\n disabled: disabledProp,\n \"data-selected\": dataAttr(selected),\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n },\n ref,\n });\n}\n\nSelectOption.displayName = \"SelectOption\";\n"],"mappings":";;;;;;;;;;;;;;;;;AAiDA,SAAgB,aAAa,EAC3B,OACA,UAAU,eAAe,OACzB,WACA,OACA,UACA,QACA,GAAG,QACiB;CACpB,MAAM,MAAM,iBAAiB,eAAe;CAC5C,MAAM,WAAW,IAAI,eAAe;CACpC,MAAM,UAAU,IAAI,WAAW;CAC/B,MAAM,WAAW,IAAI,YAAY,IAAI,iBAAiB;CACtD,MAAM,WAAW,iBAAiB;CAClC,MAAM,EAAE,KAAK,SAAS,iBAAoC,iBAAiB,QAAQ;CAInF,MAAM,cAAc,qBAAqB;EACvC,MAAM,KAAK,KAAK;EAChB,IAAI,OAAO,MAAM;GAGf,aAAa,IAAI,iBAAiB,QAAQ;GAC1C,aAAa,IAAI,gBAAgB,OAAO;GACxC,aAAa,IAAI,iBAAiB,QAAQ;EAC5C;EACA,IAAI,cAAc,IAAI,QAAQ;CAChC,CAAC;CACD,sBAAsB;EACpB,YAAY;CACd,GAAG,CAAC,CAAC;CAIL,OAAO,UAA8D;EACnE,gBAAgB;EAChB;EACA,OAAA;GALiC;GAAO;GAAU;GAAS;EAKvD;EACJ;EACA;EACA;EACA,OAAO;EACP,cAAc;GACZ;GACA,UAAU,KAAA;GAEV,UAAU;GACV,iBAAiB,SAAS,QAAQ;GAClC,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;EACpC;EACA;CACF,CAAC;AACH;AAEA,aAAa,cAAc"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ActionDetails, ChangeAction, ChangeReason, RenderProp, StateValue } from "../internal/types.mjs";
|
|
2
|
+
import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
|
|
3
|
+
//#region src/select/select-root.d.ts
|
|
4
|
+
/** Details passed as the second argument of `valueChangeAction`. */
|
|
5
|
+
export interface SelectValueChangeDetails extends ActionDetails {
|
|
6
|
+
/**
|
|
7
|
+
* `"activate"`: the user picked an option (pointer, keyboard, typeahead, or browser autofill,
|
|
8
|
+
* which the library cannot tell from a pick); `details.event` is the native `change` event.
|
|
9
|
+
* `"platform"`: the browser changed the value without a pick the library saw: a form reset
|
|
10
|
+
* (`details.event` is the `reset` event), or a pick before hydration / Firefox form-state
|
|
11
|
+
* restoration reconciled at mount (`details.event` is `undefined`).
|
|
12
|
+
*/
|
|
13
|
+
readonly reason: ChangeReason;
|
|
14
|
+
}
|
|
15
|
+
export interface SelectRootState {
|
|
16
|
+
/** Optimistic value. Content rendered from it must not suspend. */
|
|
17
|
+
readonly value: string;
|
|
18
|
+
/** An action dispatched through this Select is in flight. */
|
|
19
|
+
readonly pending: boolean;
|
|
20
|
+
/** The `disabled` prop. */
|
|
21
|
+
readonly disabled: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface SelectRootProps extends Omit<ComponentPropsWithRef<"select">, "value" | "defaultValue" | "onChange" | "multiple" | "size" | "disabled" | "className" | "style" | "children"> {
|
|
24
|
+
/** Controlled value. `undefined` means uncontrolled. Use `""` for the placeholder option. */
|
|
25
|
+
value?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Initial value in uncontrolled mode, and the value a form reset returns to (the latest prop is
|
|
28
|
+
* mirrored into the options' `defaultSelected`). When omitted, the browser's choice (an option
|
|
29
|
+
* whose value is `""`, else the first enabled option) is adopted at mount, without a dispatch,
|
|
30
|
+
* and is what a form reset returns to. Until a pick (or a platform change) sets the value,
|
|
31
|
+
* options that mount later without the adopted one (a Suspense fallback) adopt again.
|
|
32
|
+
*/
|
|
33
|
+
defaultValue?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Runs inside the Root's transition whenever the selected option changes. May be sync or async
|
|
36
|
+
* (also a Server Function); rejections reach the nearest Error Boundary and roll the selection
|
|
37
|
+
* back.
|
|
38
|
+
*
|
|
39
|
+
* In engines whose closed select changes the value on every arrow press (Firefox, Safari with
|
|
40
|
+
* native appearance), every press dispatches; the latest dispatch wins. A `setState` placed
|
|
41
|
+
* after your own `await` is not a Transition update; wrap it in `startTransition` (React
|
|
42
|
+
* limitation). Controlled mode is the way to veto a change.
|
|
43
|
+
*/
|
|
44
|
+
valueChangeAction?: ChangeAction<string, SelectValueChangeDetails>;
|
|
45
|
+
/** Native `disabled`. Never set by the library while pending. */
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
className?: StateValue<string | undefined, SelectRootState>;
|
|
48
|
+
style?: StateValue<CSSProperties | undefined, SelectRootState>;
|
|
49
|
+
children?: StateValue<ReactNode, SelectRootState>;
|
|
50
|
+
/** Replace the rendered element. Must keep a `<select>`. */
|
|
51
|
+
render?: RenderProp<ComponentPropsWithRef<"select">, SelectRootState>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The `<select>` itself: owns the value, the transition, the form-reset listener, the mount
|
|
55
|
+
* reconciliation and the re-apply of late options (design/components/select.md 15.2). Renders
|
|
56
|
+
* `value={optimistic}`: react-dom restores a controlled select to its props after every event,
|
|
57
|
+
* and only the sync-lane optimistic value survives that restore.
|
|
58
|
+
*
|
|
59
|
+
* Owned keys (conventions 1.2): `value`, `disabled`, `data-pending`, `data-disabled`, `onChange`;
|
|
60
|
+
* inside a `Field.Root` also `id`, `name`, `required`, `aria-invalid`, `aria-describedby`
|
|
61
|
+
* (token-merged) and `data-invalid`, and `disabled` / `name` / `required` default from the Field.
|
|
62
|
+
*/
|
|
63
|
+
export declare function SelectRoot({ value, defaultValue, valueChangeAction, disabled: disabledProp, className, style, children, render, ...rest }: SelectRootProps): import("react").JSX.Element;
|
|
64
|
+
export declare namespace SelectRoot {
|
|
65
|
+
var displayName: string;
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
//# sourceMappingURL=select-root.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-root.d.mts","names":[],"sources":["../../src/select/select-root.tsx"],"mappings":";;;;iBA2BiB,iCAAiC;;;;;;;;WAQvC,QAAQ;;iBAGF;;WAEN;;WAEA;;WAEA;;iBAGM,wBAAwB,KACvC;;EAYA;;;;;;;;EAQA;;;;;;;;;;;EAWA,oBAAoB,qBAAqB;;EAEzC;EACA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,iCAAiC;;;;;;;;;;;;wBAavC,aACd,OACA,cACA,mBACA,UAAU,cACV,WACA,OACA,UACA,WACG,QACF,kCAAe,IAAA;yBAVF"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createActionDetails } from "../internal/action-details.mjs";
|
|
3
|
+
import { dataAttr } from "../internal/data-attr.mjs";
|
|
4
|
+
import { transitionTypes } from "../internal/transition-types.mjs";
|
|
5
|
+
import { useControllableAction } from "../internal/use-controllable-action.mjs";
|
|
6
|
+
import { useRender } from "../internal/use-render.mjs";
|
|
7
|
+
import { fieldInputProps, useFieldControl, useFieldValueChange, useMergedRef } from "../internal/use-field-control.mjs";
|
|
8
|
+
import { SelectContext } from "./select-context.mjs";
|
|
9
|
+
import { useSelectPartRef } from "./select-dom.mjs";
|
|
10
|
+
import { useNativeSelectValue } from "../internal/use-native-select-value.mjs";
|
|
11
|
+
import { useMemo, useRef, useState } from "react";
|
|
12
|
+
import { jsx } from "react/jsx-runtime";
|
|
13
|
+
//#region src/select/select-root.tsx
|
|
14
|
+
/**
|
|
15
|
+
* The `<select>` itself: owns the value, the transition, the form-reset listener, the mount
|
|
16
|
+
* reconciliation and the re-apply of late options (design/components/select.md 15.2). Renders
|
|
17
|
+
* `value={optimistic}`: react-dom restores a controlled select to its props after every event,
|
|
18
|
+
* and only the sync-lane optimistic value survives that restore.
|
|
19
|
+
*
|
|
20
|
+
* Owned keys (conventions 1.2): `value`, `disabled`, `data-pending`, `data-disabled`, `onChange`;
|
|
21
|
+
* inside a `Field.Root` also `id`, `name`, `required`, `aria-invalid`, `aria-describedby`
|
|
22
|
+
* (token-merged) and `data-invalid`, and `disabled` / `name` / `required` default from the Field.
|
|
23
|
+
*/
|
|
24
|
+
function SelectRoot({ value, defaultValue, valueChangeAction, disabled: disabledProp, className, style, children, render, ...rest }) {
|
|
25
|
+
const { ref: libraryRef, node: selectRef } = useSelectPartRef("Select.Root", "select");
|
|
26
|
+
const field = useFieldControl({
|
|
27
|
+
labelable: true,
|
|
28
|
+
name: rest.name,
|
|
29
|
+
disabled: disabledProp,
|
|
30
|
+
required: rest.required,
|
|
31
|
+
id: rest.id,
|
|
32
|
+
component: "Select.Root"
|
|
33
|
+
});
|
|
34
|
+
const disabled = field.disabled;
|
|
35
|
+
const rootRef = useMergedRef(libraryRef, field.ref);
|
|
36
|
+
const { optimistic, pending, dispatch, latestInFlight, adopt } = useControllableAction({
|
|
37
|
+
controlled: value,
|
|
38
|
+
defaultValue,
|
|
39
|
+
initialValue: "",
|
|
40
|
+
action: valueChangeAction,
|
|
41
|
+
transitionTypes: () => transitionTypes("select"),
|
|
42
|
+
warn: {
|
|
43
|
+
component: "Select.Root",
|
|
44
|
+
prop: "value"
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
useFieldValueChange(optimistic);
|
|
48
|
+
const [mountValue] = useState(value);
|
|
49
|
+
const resetTarget = value === void 0 ? defaultValue : mountValue ?? value;
|
|
50
|
+
const established = useRef(false);
|
|
51
|
+
const dispatchChange = (next, details) => {
|
|
52
|
+
established.current = true;
|
|
53
|
+
dispatch(next, details);
|
|
54
|
+
};
|
|
55
|
+
const { optionMounted } = useNativeSelectValue({
|
|
56
|
+
ref: selectRef,
|
|
57
|
+
optimistic,
|
|
58
|
+
latestInFlight,
|
|
59
|
+
resetTarget,
|
|
60
|
+
adoptDefault: value === void 0 && defaultValue === void 0 ? {
|
|
61
|
+
adopt,
|
|
62
|
+
established: () => established.current
|
|
63
|
+
} : void 0,
|
|
64
|
+
onPlatformChange: (next, event) => dispatchChange(next, createActionDetails(event, { reason: "platform" }))
|
|
65
|
+
});
|
|
66
|
+
const context = useMemo(() => ({
|
|
67
|
+
optimistic,
|
|
68
|
+
pending,
|
|
69
|
+
disabled,
|
|
70
|
+
groupDisabled: false,
|
|
71
|
+
optionMounted
|
|
72
|
+
}), [
|
|
73
|
+
optimistic,
|
|
74
|
+
pending,
|
|
75
|
+
disabled,
|
|
76
|
+
optionMounted
|
|
77
|
+
]);
|
|
78
|
+
const element = useRender({
|
|
79
|
+
defaultElement: "select",
|
|
80
|
+
render,
|
|
81
|
+
state: {
|
|
82
|
+
value: optimistic,
|
|
83
|
+
pending,
|
|
84
|
+
disabled
|
|
85
|
+
},
|
|
86
|
+
className,
|
|
87
|
+
style,
|
|
88
|
+
children,
|
|
89
|
+
props: rest,
|
|
90
|
+
libraryProps: {
|
|
91
|
+
...fieldInputProps(field),
|
|
92
|
+
value: optimistic,
|
|
93
|
+
disabled,
|
|
94
|
+
"data-pending": dataAttr(pending),
|
|
95
|
+
"data-disabled": dataAttr(disabled),
|
|
96
|
+
onChange: (event) => {
|
|
97
|
+
if (disabled) return;
|
|
98
|
+
const next = event.currentTarget.value;
|
|
99
|
+
if (next === optimistic) return;
|
|
100
|
+
dispatchChange(next, createActionDetails(event.nativeEvent, { reason: "activate" }));
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
ref: rootRef
|
|
104
|
+
});
|
|
105
|
+
return /* @__PURE__ */ jsx(SelectContext, {
|
|
106
|
+
value: context,
|
|
107
|
+
children: element
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
SelectRoot.displayName = "SelectRoot";
|
|
111
|
+
//#endregion
|
|
112
|
+
export { SelectRoot };
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=select-root.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-root.mjs","names":[],"sources":["../../src/select/select-root.tsx"],"sourcesContent":["\"use client\";\nimport { useMemo, useRef, useState } from \"react\";\nimport type { ChangeEvent, ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport { createActionDetails } from \"../internal/action-details.js\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport { transitionTypes } from \"../internal/transition-types.js\";\nimport type {\n ActionDetails,\n ChangeAction,\n ChangeReason,\n RenderProp,\n StateValue,\n} from \"../internal/types.js\";\nimport { useControllableAction } from \"../internal/use-controllable-action.js\";\nimport { useNativeSelectValue } from \"../internal/use-native-select-value.js\";\nimport {\n fieldInputProps,\n useFieldControl,\n useFieldValueChange,\n useMergedRef,\n} from \"../internal/use-field-control.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { SelectContext } from \"./select-context.js\";\nimport type { SelectContextValue } from \"./select-context.js\";\nimport { useSelectPartRef } from \"./select-dom.js\";\n\n/** Details passed as the second argument of `valueChangeAction`. */\nexport interface SelectValueChangeDetails extends ActionDetails {\n /**\n * `\"activate\"`: the user picked an option (pointer, keyboard, typeahead, or browser autofill,\n * which the library cannot tell from a pick); `details.event` is the native `change` event.\n * `\"platform\"`: the browser changed the value without a pick the library saw: a form reset\n * (`details.event` is the `reset` event), or a pick before hydration / Firefox form-state\n * restoration reconciled at mount (`details.event` is `undefined`).\n */\n readonly reason: ChangeReason;\n}\n\nexport interface SelectRootState {\n /** Optimistic value. Content rendered from it must not suspend. */\n readonly value: string;\n /** An action dispatched through this Select is in flight. */\n readonly pending: boolean;\n /** The `disabled` prop. */\n readonly disabled: boolean;\n}\n\nexport interface SelectRootProps extends Omit<\n ComponentPropsWithRef<\"select\">,\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"multiple\"\n | \"size\"\n | \"disabled\"\n | \"className\"\n | \"style\"\n | \"children\"\n> {\n /** Controlled value. `undefined` means uncontrolled. Use `\"\"` for the placeholder option. */\n value?: string;\n /**\n * Initial value in uncontrolled mode, and the value a form reset returns to (the latest prop is\n * mirrored into the options' `defaultSelected`). When omitted, the browser's choice (an option\n * whose value is `\"\"`, else the first enabled option) is adopted at mount, without a dispatch,\n * and is what a form reset returns to. Until a pick (or a platform change) sets the value,\n * options that mount later without the adopted one (a Suspense fallback) adopt again.\n */\n defaultValue?: string;\n /**\n * Runs inside the Root's transition whenever the selected option changes. May be sync or async\n * (also a Server Function); rejections reach the nearest Error Boundary and roll the selection\n * back.\n *\n * In engines whose closed select changes the value on every arrow press (Firefox, Safari with\n * native appearance), every press dispatches; the latest dispatch wins. A `setState` placed\n * after your own `await` is not a Transition update; wrap it in `startTransition` (React\n * limitation). Controlled mode is the way to veto a change.\n */\n valueChangeAction?: ChangeAction<string, SelectValueChangeDetails>;\n /** Native `disabled`. Never set by the library while pending. */\n disabled?: boolean;\n className?: StateValue<string | undefined, SelectRootState>;\n style?: StateValue<CSSProperties | undefined, SelectRootState>;\n children?: StateValue<ReactNode, SelectRootState>;\n /** Replace the rendered element. Must keep a `<select>`. */\n render?: RenderProp<ComponentPropsWithRef<\"select\">, SelectRootState>;\n}\n\n/**\n * The `<select>` itself: owns the value, the transition, the form-reset listener, the mount\n * reconciliation and the re-apply of late options (design/components/select.md 15.2). Renders\n * `value={optimistic}`: react-dom restores a controlled select to its props after every event,\n * and only the sync-lane optimistic value survives that restore.\n *\n * Owned keys (conventions 1.2): `value`, `disabled`, `data-pending`, `data-disabled`, `onChange`;\n * inside a `Field.Root` also `id`, `name`, `required`, `aria-invalid`, `aria-describedby`\n * (token-merged) and `data-invalid`, and `disabled` / `name` / `required` default from the Field.\n */\nexport function SelectRoot({\n value,\n defaultValue,\n valueChangeAction,\n disabled: disabledProp,\n className,\n style,\n children,\n render,\n ...rest\n}: SelectRootProps) {\n const { ref: libraryRef, node: selectRef } = useSelectPartRef<HTMLSelectElement>(\n \"Select.Root\",\n \"select\",\n );\n // Inside a Field.Root (design/components/field-form.md 7.2) the Field owns the id and the ARIA\n // wiring, and `name` / `required` / `disabled` default from it.\n const field = useFieldControl({\n labelable: true,\n name: rest.name,\n disabled: disabledProp,\n required: rest.required,\n id: rest.id,\n component: \"Select.Root\",\n });\n const disabled = field.disabled;\n const rootRef = useMergedRef<HTMLSelectElement>(libraryRef, field.ref);\n\n const { optimistic, pending, dispatch, latestInFlight, adopt } = useControllableAction<\n string,\n SelectValueChangeDetails\n >({\n controlled: value,\n defaultValue,\n initialValue: \"\",\n action: valueChangeAction,\n transitionTypes: () => transitionTypes(\"select\"),\n warn: { component: \"Select.Root\", prop: \"value\" },\n });\n // Inside a Field: a value React writes with no event (a rejected action rolling back, a\n // controlled change) re-reads validity and `validate` after the commit.\n useFieldValueChange(optimistic);\n // Deliberately no warning when neither `value` nor `defaultValue` is given: the browser's\n // first-option default is adopted (design decision 3, product-owner decision 4).\n\n // Controlled: the mount-time value is the reset target (conventions 3.8 rule 6). Neither\n // `value` nor `defaultValue`: the value adopted at mount, chosen inside the hook.\n const [mountValue] = useState(value);\n const resetTarget = value === undefined ? defaultValue : (mountValue ?? value);\n\n // Any dispatch, a pick or a platform change, ends the adoption of the browser's default.\n const established = useRef(false);\n const dispatchChange = (next: string, details: SelectValueChangeDetails) => {\n established.current = true;\n dispatch(next, details);\n };\n\n const { optionMounted } = useNativeSelectValue({\n ref: selectRef,\n optimistic,\n latestInFlight,\n resetTarget,\n adoptDefault:\n value === undefined && defaultValue === undefined\n ? { adopt, established: () => established.current }\n : undefined,\n onPlatformChange: (next, event) =>\n dispatchChange(next, createActionDetails(event, { reason: \"platform\" })),\n });\n\n // Memoised (#48): every member is a state value, a prop or a stable callback.\n const context = useMemo<SelectContextValue>(\n () => ({ optimistic, pending, disabled, groupDisabled: false, optionMounted }),\n [optimistic, pending, disabled, optionMounted],\n );\n const state: SelectRootState = { value: optimistic, pending, disabled };\n\n const element = useRender<ComponentPropsWithRef<\"select\">, SelectRootState>({\n defaultElement: \"select\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n libraryProps: {\n ...fieldInputProps(field),\n value: optimistic,\n disabled,\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n onChange: (event: ChangeEvent<HTMLSelectElement>) => {\n // A natively disabled select fires no change; this covers `render` elements.\n if (disabled) return;\n const next = event.currentTarget.value;\n // No-op rule against the optimistic value (conventions 2.3, design 4.2).\n if (next === optimistic) return;\n dispatchChange(next, createActionDetails(event.nativeEvent, { reason: \"activate\" }));\n },\n },\n ref: rootRef,\n });\n\n return <SelectContext value={context}>{element}</SelectContext>;\n}\n\nSelectRoot.displayName = \"SelectRoot\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAmGA,SAAgB,WAAW,EACzB,OACA,cACA,mBACA,UAAU,cACV,WACA,OACA,UACA,QACA,GAAG,QACe;CAClB,MAAM,EAAE,KAAK,YAAY,MAAM,cAAc,iBAC3C,eACA,QACF;CAGA,MAAM,QAAQ,gBAAgB;EAC5B,WAAW;EACX,MAAM,KAAK;EACX,UAAU;EACV,UAAU,KAAK;EACf,IAAI,KAAK;EACT,WAAW;CACb,CAAC;CACD,MAAM,WAAW,MAAM;CACvB,MAAM,UAAU,aAAgC,YAAY,MAAM,GAAG;CAErE,MAAM,EAAE,YAAY,SAAS,UAAU,gBAAgB,UAAU,sBAG/D;EACA,YAAY;EACZ;EACA,cAAc;EACd,QAAQ;EACR,uBAAuB,gBAAgB,QAAQ;EAC/C,MAAM;GAAE,WAAW;GAAe,MAAM;EAAQ;CAClD,CAAC;CAGD,oBAAoB,UAAU;CAM9B,MAAM,CAAC,cAAc,SAAS,KAAK;CACnC,MAAM,cAAc,UAAU,KAAA,IAAY,eAAgB,cAAc;CAGxE,MAAM,cAAc,OAAO,KAAK;CAChC,MAAM,kBAAkB,MAAc,YAAsC;EAC1E,YAAY,UAAU;EACtB,SAAS,MAAM,OAAO;CACxB;CAEA,MAAM,EAAE,kBAAkB,qBAAqB;EAC7C,KAAK;EACL;EACA;EACA;EACA,cACE,UAAU,KAAA,KAAa,iBAAiB,KAAA,IACpC;GAAE;GAAO,mBAAmB,YAAY;EAAQ,IAChD,KAAA;EACN,mBAAmB,MAAM,UACvB,eAAe,MAAM,oBAAoB,OAAO,EAAE,QAAQ,WAAW,CAAC,CAAC;CAC3E,CAAC;CAGD,MAAM,UAAU,eACP;EAAE;EAAY;EAAS;EAAU,eAAe;EAAO;CAAc,IAC5E;EAAC;EAAY;EAAS;EAAU;CAAa,CAC/C;CAGA,MAAM,UAAU,UAA4D;EAC1E,gBAAgB;EAChB;EACA,OAAA;GAL+B,OAAO;GAAY;GAAS;EAKvD;EACJ;EACA;EACA;EACA,OAAO;EACP,cAAc;GACZ,GAAG,gBAAgB,KAAK;GACxB,OAAO;GACP;GACA,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;GAClC,WAAW,UAA0C;IAEnD,IAAI,UAAU;IACd,MAAM,OAAO,MAAM,cAAc;IAEjC,IAAI,SAAS,YAAY;IACzB,eAAe,MAAM,oBAAoB,MAAM,aAAa,EAAE,QAAQ,WAAW,CAAC,CAAC;GACrF;EACF;EACA,KAAK;CACP,CAAC;CAED,OAAO,oBAAC,eAAD;EAAe,OAAO;EAAU,UAAA;CAAuB,CAAA;AAChE;AAEA,WAAW,cAAc"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RenderProp, StateValue } from "../internal/types.mjs";
|
|
2
|
+
import { SelectRootState } from "./select-root.mjs";
|
|
3
|
+
import { CSSProperties, ComponentPropsWithRef } from "react";
|
|
4
|
+
//#region src/select/select-separator.d.ts
|
|
5
|
+
export interface SelectSeparatorProps extends Omit<ComponentPropsWithRef<"hr">, "className" | "style" | "children"> {
|
|
6
|
+
className?: StateValue<string | undefined, SelectRootState>;
|
|
7
|
+
style?: StateValue<CSSProperties | undefined, SelectRootState>;
|
|
8
|
+
/** Replace the rendered element. */
|
|
9
|
+
render?: RenderProp<ComponentPropsWithRef<"hr">, SelectRootState>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A decorative `<hr>` between options or groups (exposed as `separator` by Chromium's
|
|
13
|
+
* customizable select; a line in native pickers). Owns no keys.
|
|
14
|
+
*/
|
|
15
|
+
export declare function SelectSeparator({ className, style, render, ...rest }: SelectSeparatorProps): import("react").ReactNode;
|
|
16
|
+
export declare namespace SelectSeparator {
|
|
17
|
+
var displayName: string;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
//# sourceMappingURL=select-separator.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-separator.d.mts","names":[],"sources":["../../src/select/select-separator.tsx"],"mappings":";;;;iBAOiB,6BAA6B,KAC5C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;EAE9C,SAAS,WAAW,6BAA6B;;;;;;wBAOnC,kBAAkB,WAAW,OAAO,WAAW,QAAQ,uCAAoB;yBAA3E"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRender } from "../internal/use-render.mjs";
|
|
3
|
+
import { useSelectContext } from "./select-context.mjs";
|
|
4
|
+
//#region src/select/select-separator.tsx
|
|
5
|
+
/**
|
|
6
|
+
* A decorative `<hr>` between options or groups (exposed as `separator` by Chromium's
|
|
7
|
+
* customizable select; a line in native pickers). Owns no keys.
|
|
8
|
+
*/
|
|
9
|
+
function SelectSeparator({ className, style, render, ...rest }) {
|
|
10
|
+
const ctx = useSelectContext("Select.Separator");
|
|
11
|
+
const state = {
|
|
12
|
+
value: ctx.optimistic,
|
|
13
|
+
pending: ctx.pending,
|
|
14
|
+
disabled: ctx.disabled
|
|
15
|
+
};
|
|
16
|
+
return useRender({
|
|
17
|
+
defaultElement: "hr",
|
|
18
|
+
render,
|
|
19
|
+
state,
|
|
20
|
+
className,
|
|
21
|
+
style,
|
|
22
|
+
children: void 0,
|
|
23
|
+
props: rest
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
SelectSeparator.displayName = "SelectSeparator";
|
|
27
|
+
//#endregion
|
|
28
|
+
export { SelectSeparator };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=select-separator.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-separator.mjs","names":[],"sources":["../../src/select/select-separator.tsx"],"sourcesContent":["\"use client\";\nimport type { ComponentPropsWithRef, CSSProperties } from \"react\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { useSelectContext } from \"./select-context.js\";\nimport type { SelectRootState } from \"./select-root.js\";\n\nexport interface SelectSeparatorProps extends Omit<\n ComponentPropsWithRef<\"hr\">,\n \"className\" | \"style\" | \"children\"\n> {\n className?: StateValue<string | undefined, SelectRootState>;\n style?: StateValue<CSSProperties | undefined, SelectRootState>;\n /** Replace the rendered element. */\n render?: RenderProp<ComponentPropsWithRef<\"hr\">, SelectRootState>;\n}\n\n/**\n * A decorative `<hr>` between options or groups (exposed as `separator` by Chromium's\n * customizable select; a line in native pickers). Owns no keys.\n */\nexport function SelectSeparator({ className, style, render, ...rest }: SelectSeparatorProps) {\n const ctx = useSelectContext(\"Select.Separator\");\n const state: SelectRootState = {\n value: ctx.optimistic,\n pending: ctx.pending,\n disabled: ctx.disabled,\n };\n return useRender<ComponentPropsWithRef<\"hr\">, SelectRootState>({\n defaultElement: \"hr\",\n render,\n state,\n className,\n style,\n children: undefined,\n props: rest,\n });\n}\n\nSelectSeparator.displayName = \"SelectSeparator\";\n"],"mappings":";;;;;;;;AAqBA,SAAgB,gBAAgB,EAAE,WAAW,OAAO,QAAQ,GAAG,QAA8B;CAC3F,MAAM,MAAM,iBAAiB,kBAAkB;CAC/C,MAAM,QAAyB;EAC7B,OAAO,IAAI;EACX,SAAS,IAAI;EACb,UAAU,IAAI;CAChB;CACA,OAAO,UAAwD;EAC7D,gBAAgB;EAChB;EACA;EACA;EACA;EACA,UAAU,KAAA;EACV,OAAO;CACT,CAAC;AACH;AAEA,gBAAgB,cAAc"}
|