fluid-primitives 0.19.1 → 1.0.0-beta.1
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/README.md +9 -0
- package/dist/Client-HrMIqv7d.js +1934 -0
- package/dist/accordion.d.ts +2 -2
- package/dist/accordion.js +25 -29
- package/dist/button.d.ts +52 -0
- package/dist/button.js +135 -0
- package/dist/checkbox-group.d.ts +6 -5
- package/dist/checkbox-group.js +36 -20
- package/dist/{checkbox-group.registry-CGwuF7SF.js → checkbox-group.registry-D8P8A4LY.js} +13 -8
- package/dist/checkbox.d.ts +18 -4
- package/dist/checkbox.js +30 -27
- package/dist/client.d.ts +2 -2
- package/dist/client.js +2 -2
- package/dist/clipboard.d.ts +12 -5
- package/dist/clipboard.js +14 -16
- package/dist/collapsible.d.ts +3 -3
- package/dist/collapsible.js +13 -17
- package/dist/combobox.d.ts +37 -0
- package/dist/combobox.js +151 -0
- package/dist/date-picker.d.ts +67 -0
- package/dist/date-picker.js +289 -0
- package/dist/dialog.d.ts +3 -3
- package/dist/dialog.js +11 -12
- package/dist/field-array.d.ts +97 -0
- package/dist/field-array.js +223 -0
- package/dist/field.d.ts +30 -54
- package/dist/field.js +589 -175
- package/dist/fieldset.d.ts +15 -0
- package/dist/fieldset.js +27 -0
- package/dist/file-upload.d.ts +85 -0
- package/dist/file-upload.js +255 -0
- package/dist/form.d.ts +2 -83
- package/dist/form.fields-B58TZukv.js +329 -0
- package/dist/form.js +263 -276
- package/dist/index-B06gIN_k.d.ts +1358 -0
- package/dist/input.d.ts +96 -0
- package/dist/input.js +233 -0
- package/dist/menu.d.ts +55 -0
- package/dist/menu.js +144 -0
- package/dist/navigation-menu.d.ts +3 -3
- package/dist/navigation-menu.js +29 -43
- package/dist/number-input.d.ts +13 -4
- package/dist/number-input.js +30 -31
- package/dist/popover.d.ts +11 -3
- package/dist/popover.js +17 -18
- package/dist/radio-group.d.ts +4 -4
- package/dist/radio-group.js +35 -42
- package/dist/scroll-area.d.ts +3 -3
- package/dist/scroll-area.js +10 -9
- package/dist/select.d.ts +13 -51
- package/dist/select.js +62 -55
- package/dist/slider.d.ts +27 -0
- package/dist/slider.js +71 -0
- package/dist/switch.d.ts +4 -4
- package/dist/switch.js +24 -33
- package/dist/tabs.d.ts +3 -3
- package/dist/tabs.js +12 -15
- package/dist/textarea.d.ts +101 -0
- package/dist/textarea.js +231 -0
- package/dist/tooltip.d.ts +11 -3
- package/dist/tooltip.js +11 -10
- package/package.json +79 -24
- package/dist/Client-C51NSHxg.js +0 -248
- package/dist/field.dom-CJQXpQbZ.js +0 -11
- package/dist/form.registry-Cb8Pvoe8.d.ts +0 -7
- package/dist/form.registry-CmpTny_s.js +0 -51
- package/dist/index-B8JCdyld.d.ts +0 -118
package/dist/input.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { b as FieldClientApi, c as Machine$1, y as FieldAwareComponent } from "./index-B06gIN_k.js";
|
|
2
|
+
import { EventObject } from "@zag-js/core";
|
|
3
|
+
import { JSX, PropTypes } from "@zag-js/types";
|
|
4
|
+
|
|
5
|
+
//#region Resources/Private/Primitives/Input/src/input.types.d.ts
|
|
6
|
+
interface InputTranslations {
|
|
7
|
+
/**
|
|
8
|
+
* The text of the word count part. `%count%` is replaced with the number of characters, `%max%`
|
|
9
|
+
* with `maxLength`, e.g. `%count% / %max% characters`.
|
|
10
|
+
*/
|
|
11
|
+
wordCount?: string;
|
|
12
|
+
}
|
|
13
|
+
interface InputProps$1 {
|
|
14
|
+
/** The unique identifier of the input. */
|
|
15
|
+
id: string;
|
|
16
|
+
/** The ids of the parts other elements reference: `input` (the `for` of its label) and `wordCount`. */
|
|
17
|
+
ids?: Record<string, string>;
|
|
18
|
+
/** The name of the input, as it is submitted with the form. Taken from the closest field. */
|
|
19
|
+
name?: string;
|
|
20
|
+
/** Whether the input is disabled. Taken from the closest field. */
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/** Whether the input is read-only. Taken from the closest field. */
|
|
23
|
+
readOnly?: boolean;
|
|
24
|
+
/** Whether the input is required. Taken from the closest field. */
|
|
25
|
+
required?: boolean;
|
|
26
|
+
/** Whether the input is invalid. Taken from the closest field. */
|
|
27
|
+
invalid?: boolean;
|
|
28
|
+
/** The initial value of the input. */
|
|
29
|
+
defaultValue?: string;
|
|
30
|
+
/** The most characters allowed. It also drives the word count, e.g. `42 / 250 characters`. */
|
|
31
|
+
maxLength?: number;
|
|
32
|
+
/** A regular expression the value has to match. */
|
|
33
|
+
pattern?: string;
|
|
34
|
+
/** The kind of virtual keyboard to show on devices that have one. */
|
|
35
|
+
inputMode?: JSX.HTMLAttributes<HTMLInputElement>['inputMode'];
|
|
36
|
+
/** The localized texts of the input. */
|
|
37
|
+
translations?: InputTranslations;
|
|
38
|
+
/**
|
|
39
|
+
* Whether the word count is announced to assistive tech. Set to `false` to stay silent.
|
|
40
|
+
* @default true
|
|
41
|
+
*/
|
|
42
|
+
announce?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Milliseconds to debounce word count announcements by, so rapid typing doesn't
|
|
45
|
+
* spam assistive tech on every keystroke. Set to 0 to announce every change immediately.
|
|
46
|
+
* @default 600
|
|
47
|
+
*/
|
|
48
|
+
announceDebounce?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Runs on every native `input` event, before the value is committed. Return the value to write
|
|
51
|
+
* back to the input, e.g. uppercased or digits only. The cursor position is kept. It cannot be
|
|
52
|
+
* set from a Fluid template, only by constructing `Input` in your own entry file.
|
|
53
|
+
*/
|
|
54
|
+
transform?: (value: string, event: Event) => string;
|
|
55
|
+
/** Called when the value changes. */
|
|
56
|
+
onValueChange?: (details: {
|
|
57
|
+
value: string;
|
|
58
|
+
}) => void;
|
|
59
|
+
}
|
|
60
|
+
interface InputHandle {
|
|
61
|
+
/** The current value of the input. */
|
|
62
|
+
value: string;
|
|
63
|
+
/** The number of characters in the value. */
|
|
64
|
+
count: number;
|
|
65
|
+
/** The word count text, e.g. `42 / 250 characters`. `null` without `maxLength` or when the text is turned off. */
|
|
66
|
+
countText: string | null;
|
|
67
|
+
/** Whether the input is disabled. */
|
|
68
|
+
disabled: boolean;
|
|
69
|
+
/** Whether the input is read-only. */
|
|
70
|
+
readOnly: boolean;
|
|
71
|
+
/** Whether the input is required. */
|
|
72
|
+
required: boolean;
|
|
73
|
+
/** Whether the input is invalid. */
|
|
74
|
+
invalid: boolean;
|
|
75
|
+
/** The name of the input. */
|
|
76
|
+
name: string | undefined;
|
|
77
|
+
/** The most characters allowed. */
|
|
78
|
+
maxLength: number | undefined;
|
|
79
|
+
}
|
|
80
|
+
interface InputApi extends InputHandle {
|
|
81
|
+
getRootProps(): PropTypes['element'];
|
|
82
|
+
getInputProps(): PropTypes['input'];
|
|
83
|
+
getLabelProps(): PropTypes['label'];
|
|
84
|
+
getWordCountProps(): PropTypes['element'];
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region Resources/Private/Primitives/Input/Input.d.ts
|
|
88
|
+
declare class Input extends FieldAwareComponent<InputProps$1, InputApi> {
|
|
89
|
+
static componentName: string;
|
|
90
|
+
propsWithField(props: InputProps$1, field: FieldClientApi): InputProps$1;
|
|
91
|
+
initMachine(props: InputProps$1): Machine$1<any>;
|
|
92
|
+
initApi(): InputApi;
|
|
93
|
+
render(): void;
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
export { Input };
|
package/dist/input.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { a as normalizeProps, at as Machine$1, o as mergeProps, s as FieldAwareComponent } from "./Client-HrMIqv7d.js";
|
|
2
|
+
import { createSplitProps, debounce } from "@zag-js/utils";
|
|
3
|
+
import { createAnatomy } from "@zag-js/anatomy";
|
|
4
|
+
import { createMachine } from "@zag-js/core";
|
|
5
|
+
import { createProps } from "@zag-js/types";
|
|
6
|
+
import { createLiveRegion } from "@zag-js/live-region";
|
|
7
|
+
|
|
8
|
+
//#region Resources/Private/Primitives/Input/src/input.anatomy.ts
|
|
9
|
+
const anatomy = createAnatomy("input").parts("root", "label", "input", "wordCount");
|
|
10
|
+
const parts = anatomy.build();
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region Resources/Private/Primitives/Input/src/input.dom.ts
|
|
14
|
+
const getInputId = (scope) => scope.ids?.input ?? `input:${scope.id}:input`;
|
|
15
|
+
const getWordCountId = (scope) => scope.ids?.wordCount ?? `input:${scope.id}:wordCount`;
|
|
16
|
+
const getInputEl = (scope) => scope.query(scope.selector(parts.input));
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region Resources/Private/Primitives/Input/src/input.connect.ts
|
|
20
|
+
const SELECTABLE_INPUT_TYPES = new Set([
|
|
21
|
+
"text",
|
|
22
|
+
"search",
|
|
23
|
+
"tel",
|
|
24
|
+
"url",
|
|
25
|
+
"password"
|
|
26
|
+
]);
|
|
27
|
+
function createInputHandle(service) {
|
|
28
|
+
const { prop, context, computed } = service;
|
|
29
|
+
return {
|
|
30
|
+
value: context.get("value"),
|
|
31
|
+
count: computed("count"),
|
|
32
|
+
countText: computed("countText"),
|
|
33
|
+
disabled: !!prop("disabled"),
|
|
34
|
+
readOnly: !!prop("readOnly"),
|
|
35
|
+
required: !!prop("required"),
|
|
36
|
+
invalid: !!prop("invalid"),
|
|
37
|
+
name: prop("name"),
|
|
38
|
+
maxLength: prop("maxLength")
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function connect(service, normalize) {
|
|
42
|
+
const { scope, prop, send } = service;
|
|
43
|
+
const handle = createInputHandle(service);
|
|
44
|
+
return {
|
|
45
|
+
...handle,
|
|
46
|
+
getRootProps() {
|
|
47
|
+
return normalize.element({
|
|
48
|
+
...parts.root.attrs(scope.id),
|
|
49
|
+
"data-invalid": handle.invalid ? "" : void 0,
|
|
50
|
+
"data-disabled": handle.disabled ? "" : void 0,
|
|
51
|
+
"data-readonly": handle.readOnly ? "" : void 0
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
getInputProps() {
|
|
55
|
+
return normalize.input({
|
|
56
|
+
...parts.input.attrs(scope.id),
|
|
57
|
+
id: getInputId(scope),
|
|
58
|
+
name: handle.name,
|
|
59
|
+
disabled: handle.disabled || void 0,
|
|
60
|
+
readOnly: handle.readOnly || void 0,
|
|
61
|
+
required: handle.required || void 0,
|
|
62
|
+
maxLength: handle.maxLength,
|
|
63
|
+
pattern: prop("pattern"),
|
|
64
|
+
inputMode: prop("inputMode"),
|
|
65
|
+
value: handle.value,
|
|
66
|
+
"aria-invalid": handle.invalid ? "true" : void 0,
|
|
67
|
+
"data-invalid": handle.invalid ? "" : void 0,
|
|
68
|
+
"data-disabled": handle.disabled ? "" : void 0,
|
|
69
|
+
"data-readonly": handle.readOnly ? "" : void 0,
|
|
70
|
+
onInput(event) {
|
|
71
|
+
const target = event.currentTarget;
|
|
72
|
+
const transform = prop("transform");
|
|
73
|
+
let value = target.value;
|
|
74
|
+
if (transform) {
|
|
75
|
+
const transformed = transform(value, event);
|
|
76
|
+
if (transformed !== value) {
|
|
77
|
+
value = transformed;
|
|
78
|
+
if (SELECTABLE_INPUT_TYPES.has(target.type)) {
|
|
79
|
+
const { selectionStart, selectionEnd } = target;
|
|
80
|
+
target.value = value;
|
|
81
|
+
if (selectionStart != null) target.selectionStart = selectionStart;
|
|
82
|
+
if (selectionEnd != null) target.selectionEnd = selectionEnd;
|
|
83
|
+
} else target.value = value;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
send({
|
|
87
|
+
type: "VALUE_CHANGE",
|
|
88
|
+
value
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
getLabelProps() {
|
|
94
|
+
return normalize.label({
|
|
95
|
+
...parts.label.attrs(scope.id),
|
|
96
|
+
htmlFor: getInputId(scope),
|
|
97
|
+
"data-invalid": handle.invalid ? "" : void 0,
|
|
98
|
+
"data-disabled": handle.disabled ? "" : void 0,
|
|
99
|
+
"data-required": handle.required ? "" : void 0
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
getWordCountProps() {
|
|
103
|
+
return normalize.element({
|
|
104
|
+
...parts.wordCount.attrs(scope.id),
|
|
105
|
+
id: getWordCountId(scope),
|
|
106
|
+
"aria-hidden": "true"
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region Resources/Private/Primitives/Input/src/input.machine.ts
|
|
114
|
+
const machine = createMachine({
|
|
115
|
+
initialState() {
|
|
116
|
+
return "idle";
|
|
117
|
+
},
|
|
118
|
+
context({ bindable, prop }) {
|
|
119
|
+
return { value: bindable(() => ({ defaultValue: prop("defaultValue") ?? "" })) };
|
|
120
|
+
},
|
|
121
|
+
refs() {
|
|
122
|
+
return { announce: null };
|
|
123
|
+
},
|
|
124
|
+
computed: {
|
|
125
|
+
count({ context }) {
|
|
126
|
+
return context.get("value").length;
|
|
127
|
+
},
|
|
128
|
+
countText({ prop, computed }) {
|
|
129
|
+
const wordCountTemplate = prop("translations")?.wordCount;
|
|
130
|
+
const maxLength = prop("maxLength");
|
|
131
|
+
if (!wordCountTemplate || maxLength == null) return null;
|
|
132
|
+
const count = computed("count");
|
|
133
|
+
return wordCountTemplate.replaceAll("%count%", String(count)).replaceAll("%max%", String(maxLength));
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
entry: ["syncValueFromDom"],
|
|
137
|
+
effects: ["manageLiveRegion"],
|
|
138
|
+
states: { idle: {} },
|
|
139
|
+
on: { VALUE_CHANGE: { actions: ["setValue"] } },
|
|
140
|
+
implementations: {
|
|
141
|
+
actions: {
|
|
142
|
+
setValue({ context, event, prop, refs, computed }) {
|
|
143
|
+
const value = event.value;
|
|
144
|
+
context.set("value", value);
|
|
145
|
+
prop("onValueChange")?.({ value });
|
|
146
|
+
const countText = computed("countText");
|
|
147
|
+
if (countText) refs.get("announce")?.(countText);
|
|
148
|
+
},
|
|
149
|
+
syncValueFromDom({ context, scope }) {
|
|
150
|
+
const inputEl = getInputEl(scope);
|
|
151
|
+
if (inputEl) context.set("value", inputEl.value);
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
effects: { manageLiveRegion({ refs, prop, computed }) {
|
|
155
|
+
if (prop("announce") === false || computed("countText") === null) return void 0;
|
|
156
|
+
const liveRegion = createLiveRegion({ level: "polite" });
|
|
157
|
+
const debounceMs = prop("announceDebounce") ?? 600;
|
|
158
|
+
const announce = debounceMs > 0 ? debounce((text) => liveRegion.announce(text), debounceMs) : (text) => liveRegion.announce(text);
|
|
159
|
+
refs.set("announce", announce);
|
|
160
|
+
return () => {
|
|
161
|
+
liveRegion.destroy();
|
|
162
|
+
};
|
|
163
|
+
} }
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
//#endregion
|
|
168
|
+
//#region Resources/Private/Primitives/Input/src/input.props.ts
|
|
169
|
+
const props = createProps()([
|
|
170
|
+
"id",
|
|
171
|
+
"ids",
|
|
172
|
+
"name",
|
|
173
|
+
"disabled",
|
|
174
|
+
"readOnly",
|
|
175
|
+
"required",
|
|
176
|
+
"invalid",
|
|
177
|
+
"defaultValue",
|
|
178
|
+
"maxLength",
|
|
179
|
+
"pattern",
|
|
180
|
+
"inputMode",
|
|
181
|
+
"translations",
|
|
182
|
+
"announce",
|
|
183
|
+
"announceDebounce",
|
|
184
|
+
"transform",
|
|
185
|
+
"onValueChange"
|
|
186
|
+
]);
|
|
187
|
+
const splitProps = createSplitProps(props);
|
|
188
|
+
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region Resources/Private/Primitives/Input/Input.ts
|
|
191
|
+
var Input = class extends FieldAwareComponent {
|
|
192
|
+
static componentName = "input";
|
|
193
|
+
propsWithField(props, field) {
|
|
194
|
+
return {
|
|
195
|
+
...props,
|
|
196
|
+
disabled: props.disabled ?? field.disabled,
|
|
197
|
+
readOnly: props.readOnly ?? field.readOnly,
|
|
198
|
+
required: props.required ?? field.required,
|
|
199
|
+
invalid: props.invalid ?? field.invalid,
|
|
200
|
+
name: props.name ?? field.name
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
initMachine(props) {
|
|
204
|
+
props = this.withFieldProps(props);
|
|
205
|
+
const [machineProps] = splitProps(props);
|
|
206
|
+
return new Machine$1(machine, machineProps);
|
|
207
|
+
}
|
|
208
|
+
initApi() {
|
|
209
|
+
return connect(this.machine.service, normalizeProps);
|
|
210
|
+
}
|
|
211
|
+
render() {
|
|
212
|
+
this.subscribeToFieldService();
|
|
213
|
+
const rootEl = this.hydrator.query("root");
|
|
214
|
+
if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
|
|
215
|
+
const wordCountEl = this.hydrator.query("wordCount");
|
|
216
|
+
const wordCountId = wordCountEl ? getWordCountId(this.machine.scope) : void 0;
|
|
217
|
+
const inputEl = this.hydrator.query("input");
|
|
218
|
+
if (inputEl) {
|
|
219
|
+
const describeIds = [this.field?.ariaDescribedby, wordCountId].filter(Boolean).join(" ");
|
|
220
|
+
const mergedProps = mergeProps(this.api.getInputProps(), { "aria-describedby": describeIds || void 0 });
|
|
221
|
+
this.spreadTextControlProps(inputEl, mergedProps);
|
|
222
|
+
}
|
|
223
|
+
const labelEl = this.hydrator.query("label");
|
|
224
|
+
if (labelEl) this.spreadProps(labelEl, this.api.getLabelProps());
|
|
225
|
+
if (wordCountEl) {
|
|
226
|
+
this.spreadProps(wordCountEl, this.api.getWordCountProps());
|
|
227
|
+
wordCountEl.textContent = this.api.countText ?? "";
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
//#endregion
|
|
233
|
+
export { Input };
|
package/dist/menu.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { X as ConverterMachineProps, c as Machine, z as Component } from "./index-B06gIN_k.js";
|
|
2
|
+
import * as _$_zag_js_types0 from "@zag-js/types";
|
|
3
|
+
import * as menu from "@zag-js/menu";
|
|
4
|
+
|
|
5
|
+
//#region Resources/Private/Primitives/Menu/Menu.d.ts
|
|
6
|
+
declare const menuPropConverters: {
|
|
7
|
+
positioning: (positioning: menu.Props["positioning"]) => menu.PositioningOptions | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare module 'fluid-primitives' {
|
|
10
|
+
interface HydrationPropsOverrides {
|
|
11
|
+
menu: ConverterMachineProps<typeof menuPropConverters>;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
declare class Menu extends Component<menu.Props, menu.Api> {
|
|
15
|
+
static componentName: string;
|
|
16
|
+
/**
|
|
17
|
+
* Submenus that linked themselves to this menu (see {@see linkToParent}). Zag composes a
|
|
18
|
+
* `menu.triggerItem` from this menu's item props and the *child's* trigger props, and marks it
|
|
19
|
+
* with the child's own scope id - so each one is found through its child, not through this menu.
|
|
20
|
+
*/
|
|
21
|
+
private submenus;
|
|
22
|
+
initMachine(props: menu.Props): Machine<any>;
|
|
23
|
+
initApi(): menu.Api<_$_zag_js_types0.PropTypes<{
|
|
24
|
+
[x: string]: any;
|
|
25
|
+
}>>;
|
|
26
|
+
init(): void;
|
|
27
|
+
private get parentId();
|
|
28
|
+
private getParentInstance;
|
|
29
|
+
/**
|
|
30
|
+
* Composes two independent `Menu` instances into a submenu relationship - see `menu.root`'s
|
|
31
|
+
* `parentId` prop and `menu.triggerItem`'s `childId` prop. Zag's own `setParent`/`setChild` API
|
|
32
|
+
* expects live `MenuService` instances, which only exist once both components have mounted, so
|
|
33
|
+
* this runs after `init()` (deferred via `setTimeout`, so it doesn't depend on mount order
|
|
34
|
+
* between the two) rather than as a machine prop.
|
|
35
|
+
*/
|
|
36
|
+
private linkToParent;
|
|
37
|
+
destroy(): void;
|
|
38
|
+
render(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Spreads `getTriggerItemProps(childApi)` onto the `menu.triggerItem` element of each linked
|
|
41
|
+
* submenu - it carries that submenu's own root id, so the child finds it with its own
|
|
42
|
+
* `query('triggerItem')`.
|
|
43
|
+
*/
|
|
44
|
+
private renderTriggerItems;
|
|
45
|
+
/**
|
|
46
|
+
* Zag's menu machine doesn't own checked state for checkbox/radio items itself (unlike
|
|
47
|
+
* RadioGroup/CheckboxGroup) - it only calls back `onCheckedChange` with the next value on
|
|
48
|
+
* click. `data-state` is therefore the source of truth across renders: each render reads it,
|
|
49
|
+
* `onCheckedChange` updates it (also unchecking radio siblings sharing the same `name`), then
|
|
50
|
+
* re-renders so the new state is spread onto the DOM again.
|
|
51
|
+
*/
|
|
52
|
+
private renderOptionItem;
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { Menu };
|
package/dist/menu.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { K as registerClientPropConverters, a as normalizeProps, at as Machine, rt as Component } from "./Client-HrMIqv7d.js";
|
|
2
|
+
import * as menu from "@zag-js/menu";
|
|
3
|
+
|
|
4
|
+
//#region Resources/Private/Primitives/Menu/Menu.ts
|
|
5
|
+
registerClientPropConverters("menu", { positioning: (positioning) => positioning });
|
|
6
|
+
var Menu = class extends Component {
|
|
7
|
+
static componentName = "menu";
|
|
8
|
+
/**
|
|
9
|
+
* Submenus that linked themselves to this menu (see {@see linkToParent}). Zag composes a
|
|
10
|
+
* `menu.triggerItem` from this menu's item props and the *child's* trigger props, and marks it
|
|
11
|
+
* with the child's own scope id - so each one is found through its child, not through this menu.
|
|
12
|
+
*/
|
|
13
|
+
submenus = /* @__PURE__ */ new Set();
|
|
14
|
+
initMachine(props) {
|
|
15
|
+
const [menuProps] = menu.splitProps(props);
|
|
16
|
+
return new Machine(menu.machine, menuProps);
|
|
17
|
+
}
|
|
18
|
+
initApi() {
|
|
19
|
+
return menu.connect(this.machine.service, normalizeProps);
|
|
20
|
+
}
|
|
21
|
+
init() {
|
|
22
|
+
super.init();
|
|
23
|
+
this.linkToParent();
|
|
24
|
+
}
|
|
25
|
+
get parentId() {
|
|
26
|
+
return this.userProps.parentId;
|
|
27
|
+
}
|
|
28
|
+
getParentInstance() {
|
|
29
|
+
return this.parentId ? this.getPeerInstance(this.parentId) ?? null : null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Composes two independent `Menu` instances into a submenu relationship - see `menu.root`'s
|
|
33
|
+
* `parentId` prop and `menu.triggerItem`'s `childId` prop. Zag's own `setParent`/`setChild` API
|
|
34
|
+
* expects live `MenuService` instances, which only exist once both components have mounted, so
|
|
35
|
+
* this runs after `init()` (deferred via `setTimeout`, so it doesn't depend on mount order
|
|
36
|
+
* between the two) rather than as a machine prop.
|
|
37
|
+
*/
|
|
38
|
+
linkToParent() {
|
|
39
|
+
if (!this.parentId) return;
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
const parent = this.getParentInstance();
|
|
42
|
+
if (!parent) return;
|
|
43
|
+
parent.submenus.add(this);
|
|
44
|
+
parent.api.setChild(this.machine.service);
|
|
45
|
+
this.api.setParent(parent.machine.service);
|
|
46
|
+
parent.refresh();
|
|
47
|
+
this.machine.subscribe(() => parent.refresh());
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
destroy() {
|
|
51
|
+
this.getParentInstance()?.submenus.delete(this);
|
|
52
|
+
super.destroy();
|
|
53
|
+
}
|
|
54
|
+
render() {
|
|
55
|
+
this.spreadPropsByOptionalValue("trigger", ({ value }) => this.api.getTriggerProps({ value }));
|
|
56
|
+
this.spreadPropsByOptionalValue("contextTrigger", ({ value }) => this.api.getContextTriggerProps({ value }));
|
|
57
|
+
const indicatorEl = this.hydrator.query("indicator");
|
|
58
|
+
if (indicatorEl) this.spreadProps(indicatorEl, this.api.getIndicatorProps());
|
|
59
|
+
const positionerEl = this.hydrator.query("positioner");
|
|
60
|
+
if (positionerEl) this.spreadProps(positionerEl, this.api.getPositionerProps());
|
|
61
|
+
const arrowEl = this.hydrator.query("arrow");
|
|
62
|
+
if (arrowEl) this.spreadProps(arrowEl, this.api.getArrowProps());
|
|
63
|
+
const arrowTipEl = this.hydrator.query("arrowTip");
|
|
64
|
+
if (arrowTipEl) this.spreadProps(arrowTipEl, this.api.getArrowTipProps());
|
|
65
|
+
const contentEl = this.hydrator.query("content");
|
|
66
|
+
if (contentEl) this.spreadProps(contentEl, this.api.getContentProps());
|
|
67
|
+
this.spreadPropsByValue("itemGroup", ({ value }) => this.api.getItemGroupProps({ id: value }));
|
|
68
|
+
this.spreadPropsByValue("itemGroupLabel", ({ value }) => this.api.getItemGroupLabelProps({ htmlFor: value }));
|
|
69
|
+
this.spreadPropsByOptionalValue("separator", () => this.api.getSeparatorProps());
|
|
70
|
+
this.spreadPropsByValue("item", ({ value, el }) => {
|
|
71
|
+
if (el.hasAttribute("data-menu-trigger-item")) return;
|
|
72
|
+
if (el.dataset.type) {
|
|
73
|
+
this.renderOptionItem(el);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
return this.api.getItemProps({
|
|
77
|
+
value,
|
|
78
|
+
disabled: el.hasAttribute("data-disabled"),
|
|
79
|
+
valueText: el.dataset.valuetext
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
this.renderTriggerItems();
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Spreads `getTriggerItemProps(childApi)` onto the `menu.triggerItem` element of each linked
|
|
86
|
+
* submenu - it carries that submenu's own root id, so the child finds it with its own
|
|
87
|
+
* `query('triggerItem')`.
|
|
88
|
+
*/
|
|
89
|
+
renderTriggerItems() {
|
|
90
|
+
this.submenus.forEach((child) => {
|
|
91
|
+
if (!child.machine.context.get("isSubmenu")) return;
|
|
92
|
+
const el = child.hydrator.query("triggerItem");
|
|
93
|
+
if (el) this.spreadProps(el, this.api.getTriggerItemProps(child.api));
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Zag's menu machine doesn't own checked state for checkbox/radio items itself (unlike
|
|
98
|
+
* RadioGroup/CheckboxGroup) - it only calls back `onCheckedChange` with the next value on
|
|
99
|
+
* click. `data-state` is therefore the source of truth across renders: each render reads it,
|
|
100
|
+
* `onCheckedChange` updates it (also unchecking radio siblings sharing the same `name`), then
|
|
101
|
+
* re-renders so the new state is spread onto the DOM again.
|
|
102
|
+
*/
|
|
103
|
+
renderOptionItem(el) {
|
|
104
|
+
const value = el.dataset.value;
|
|
105
|
+
if (value === void 0) return;
|
|
106
|
+
const type = el.dataset.type === "radio" ? "radio" : "checkbox";
|
|
107
|
+
const disabled = el.hasAttribute("data-disabled");
|
|
108
|
+
const valueText = el.dataset.valuetext;
|
|
109
|
+
const name = el.dataset.name;
|
|
110
|
+
const checked = el.dataset.state === "checked";
|
|
111
|
+
const optionProps = this.api.getOptionItemProps({
|
|
112
|
+
type,
|
|
113
|
+
value,
|
|
114
|
+
checked,
|
|
115
|
+
disabled,
|
|
116
|
+
valueText,
|
|
117
|
+
onCheckedChange: (nextChecked) => {
|
|
118
|
+
if (type === "radio" && name) this.hydrator.queryAll("item").forEach((sibling) => {
|
|
119
|
+
if (sibling.dataset.name === name) sibling.dataset.state = sibling === el ? "checked" : "unchecked";
|
|
120
|
+
});
|
|
121
|
+
else el.dataset.state = nextChecked ? "checked" : "unchecked";
|
|
122
|
+
this.render();
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
this.spreadProps(el, optionProps);
|
|
126
|
+
const indicatorEl = this.hydrator.query("itemIndicator", el);
|
|
127
|
+
if (indicatorEl) this.spreadProps(indicatorEl, this.api.getItemIndicatorProps({
|
|
128
|
+
value,
|
|
129
|
+
checked,
|
|
130
|
+
disabled,
|
|
131
|
+
valueText
|
|
132
|
+
}));
|
|
133
|
+
const textEl = this.hydrator.query("itemText", el);
|
|
134
|
+
if (textEl) this.spreadProps(textEl, this.api.getItemTextProps({
|
|
135
|
+
value,
|
|
136
|
+
checked,
|
|
137
|
+
disabled,
|
|
138
|
+
valueText
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
//#endregion
|
|
144
|
+
export { Menu };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as navigationMenu from "@zag-js/navigation-menu";
|
|
1
|
+
import { c as Machine, z as Component } from "./index-B06gIN_k.js";
|
|
3
2
|
import * as _$_zag_js_types0 from "@zag-js/types";
|
|
3
|
+
import * as navigationMenu from "@zag-js/navigation-menu";
|
|
4
4
|
|
|
5
5
|
//#region Resources/Private/Primitives/NavigationMenu/NavigationMenu.d.ts
|
|
6
6
|
declare class NavigationMenu extends Component<navigationMenu.Props, navigationMenu.Api> {
|
|
7
|
-
static
|
|
7
|
+
static componentName: string;
|
|
8
8
|
initMachine(props: navigationMenu.Props): Machine<any>;
|
|
9
9
|
initApi(): navigationMenu.Api<_$_zag_js_types0.PropTypes<{
|
|
10
10
|
[x: string]: any;
|
package/dist/navigation-menu.js
CHANGED
|
@@ -1,68 +1,54 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as normalizeProps, at as Machine, rt as Component } from "./Client-HrMIqv7d.js";
|
|
2
2
|
import * as navigationMenu from "@zag-js/navigation-menu";
|
|
3
3
|
|
|
4
4
|
//#region Resources/Private/Primitives/NavigationMenu/NavigationMenu.ts
|
|
5
5
|
var NavigationMenu = class extends Component {
|
|
6
|
-
static
|
|
6
|
+
static componentName = "navigationMenu";
|
|
7
7
|
initMachine(props) {
|
|
8
|
-
|
|
8
|
+
const [machineProps] = navigationMenu.splitProps(props);
|
|
9
|
+
return new Machine(navigationMenu.machine, machineProps);
|
|
9
10
|
}
|
|
10
11
|
initApi() {
|
|
11
12
|
return navigationMenu.connect(this.machine.service, normalizeProps);
|
|
12
13
|
}
|
|
13
14
|
render() {
|
|
14
|
-
const rootEl = this.
|
|
15
|
+
const rootEl = this.hydrator.query("root");
|
|
15
16
|
if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
|
|
16
|
-
const listEl = this.
|
|
17
|
+
const listEl = this.hydrator.query("list");
|
|
17
18
|
if (listEl) this.spreadProps(listEl, this.api.getListProps());
|
|
18
|
-
this.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.getElements("viewport-proxy").forEach((viewportProxyEl) => {
|
|
35
|
-
this.spreadProps(viewportProxyEl, this.api.getViewportProxyProps({ value: viewportProxyEl.dataset.value }));
|
|
36
|
-
});
|
|
37
|
-
this.getElements("content").forEach((contentEl) => {
|
|
38
|
-
this.spreadProps(contentEl, this.api.getContentProps({ value: contentEl.dataset.value }));
|
|
39
|
-
});
|
|
40
|
-
this.getElements("link").forEach((linkEl) => {
|
|
41
|
-
this.spreadProps(linkEl, this.api.getLinkProps({
|
|
42
|
-
value: linkEl.dataset.value,
|
|
43
|
-
current: linkEl.hasAttribute("data-current")
|
|
44
|
-
}));
|
|
45
|
-
});
|
|
46
|
-
const indicatorEl = this.getElement("indicator");
|
|
19
|
+
this.spreadPropsByValue("item", ({ el, value }) => this.api.getItemProps({
|
|
20
|
+
value,
|
|
21
|
+
disabled: el.hasAttribute("data-disabled")
|
|
22
|
+
}));
|
|
23
|
+
this.spreadPropsByValue("trigger", ({ el, value }) => this.api.getTriggerProps({
|
|
24
|
+
value,
|
|
25
|
+
disabled: el.hasAttribute("data-disabled")
|
|
26
|
+
}));
|
|
27
|
+
this.spreadPropsByValue("triggerProxy", ({ value }) => this.api.getTriggerProxyProps({ value }));
|
|
28
|
+
this.spreadPropsByValue("viewportProxy", ({ value }) => this.api.getViewportProxyProps({ value }));
|
|
29
|
+
this.spreadPropsByValue("content", ({ value }) => this.api.getContentProps({ value }));
|
|
30
|
+
this.spreadPropsByValue("link", ({ el, value }) => this.api.getLinkProps({
|
|
31
|
+
value,
|
|
32
|
+
current: el.hasAttribute("data-current")
|
|
33
|
+
}));
|
|
34
|
+
const indicatorEl = this.hydrator.query("indicator");
|
|
47
35
|
if (indicatorEl) this.spreadProps(indicatorEl, this.api.getIndicatorProps());
|
|
48
|
-
const arrowEl = this.
|
|
36
|
+
const arrowEl = this.hydrator.query("arrow");
|
|
49
37
|
if (arrowEl) this.spreadProps(arrowEl, this.api.getArrowProps());
|
|
50
|
-
const viewportPositionerEl = this.
|
|
38
|
+
const viewportPositionerEl = this.hydrator.query("viewportPositioner");
|
|
51
39
|
if (viewportPositionerEl) {
|
|
52
40
|
const align = viewportPositionerEl.dataset.align || void 0;
|
|
53
41
|
this.spreadProps(viewportPositionerEl, this.api.getViewportPositionerProps({ align }));
|
|
54
42
|
}
|
|
55
|
-
const viewportEl = this.
|
|
43
|
+
const viewportEl = this.hydrator.query("viewport");
|
|
56
44
|
if (viewportEl) {
|
|
57
45
|
const align = viewportEl.dataset.align || void 0;
|
|
58
46
|
this.spreadProps(viewportEl, this.api.getViewportProps({ align }));
|
|
59
47
|
}
|
|
60
|
-
this.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}));
|
|
65
|
-
});
|
|
48
|
+
this.spreadPropsByValue("itemIndicator", ({ el, value }) => this.api.getItemIndicatorProps({
|
|
49
|
+
value,
|
|
50
|
+
disabled: el.hasAttribute("data-disabled")
|
|
51
|
+
}));
|
|
66
52
|
}
|
|
67
53
|
};
|
|
68
54
|
|
package/dist/number-input.d.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as numberInput from "@zag-js/number-input";
|
|
1
|
+
import { X as ConverterMachineProps, b as FieldClientApi, c as Machine, y as FieldAwareComponent } from "./index-B06gIN_k.js";
|
|
3
2
|
import * as _$_zag_js_types0 from "@zag-js/types";
|
|
3
|
+
import * as numberInput from "@zag-js/number-input";
|
|
4
4
|
|
|
5
5
|
//#region Resources/Private/Primitives/NumberInput/NumberInput.d.ts
|
|
6
|
+
declare const numberInputPropConverters: {
|
|
7
|
+
formatOptions: (formatOptions: numberInput.Props["formatOptions"]) => Intl.NumberFormatOptions | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare module 'fluid-primitives' {
|
|
10
|
+
interface HydrationPropsOverrides {
|
|
11
|
+
numberInput: ConverterMachineProps<typeof numberInputPropConverters>;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
6
14
|
declare class NumberInput extends FieldAwareComponent<numberInput.Props, numberInput.Api> {
|
|
7
|
-
static
|
|
8
|
-
propsWithField(props: numberInput.Props,
|
|
15
|
+
static componentName: string;
|
|
16
|
+
propsWithField(props: numberInput.Props, field: FieldClientApi): numberInput.Props;
|
|
17
|
+
transformProps(props: numberInput.Props): numberInput.Props;
|
|
9
18
|
initMachine(props: numberInput.Props): Machine<any>;
|
|
10
19
|
initApi(): numberInput.Api<_$_zag_js_types0.PropTypes<{
|
|
11
20
|
[x: string]: any;
|