@destyler/radio 0.0.7-beta.7 → 0.0.7-beta.9

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/index.d.mts DELETED
@@ -1,194 +0,0 @@
1
- import * as _zag_js_anatomy from '@zag-js/anatomy';
2
- import { DirectionProperty, CommonProperties, PropTypes, RequiredBy, NormalizeProps } from '@zag-js/types';
3
- import * as _zag_js_core from '@zag-js/core';
4
- import { StateMachine, Machine } from '@zag-js/core';
5
-
6
- declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "item" | "itemText" | "itemControl" | "indicator">;
7
-
8
- interface ValueChangeDetails {
9
- value: string;
10
- }
11
- type ElementIds = Partial<{
12
- root: string;
13
- label: string;
14
- indicator: string;
15
- item: (value: string) => string;
16
- itemLabel: (value: string) => string;
17
- itemControl: (value: string) => string;
18
- itemHiddenInput: (value: string) => string;
19
- }>;
20
- interface PublicContext extends DirectionProperty, CommonProperties {
21
- /**
22
- * The ids of the elements in the radio. Useful for composition.
23
- */
24
- ids?: ElementIds | undefined;
25
- /**
26
- * The value of the checked radio
27
- */
28
- value: string | null;
29
- /**
30
- * The name of the input fields in the radio
31
- * (Useful for form submission).
32
- */
33
- name?: string | undefined;
34
- /**
35
- * The associate form of the underlying input.
36
- */
37
- form?: string | undefined;
38
- /**
39
- * If `true`, the radio group will be disabled
40
- */
41
- disabled?: boolean | undefined;
42
- /**
43
- * Whether the checkbox is read-only
44
- */
45
- readOnly?: boolean | undefined;
46
- /**
47
- * Function called once a radio is checked
48
- * @param value the value of the checked radio
49
- */
50
- onValueChange?: (details: ValueChangeDetails) => void;
51
- /**
52
- * Orientation of the radio group
53
- */
54
- orientation?: 'horizontal' | 'vertical' | undefined;
55
- }
56
- interface PrivateContext {
57
- /**
58
- * @internal
59
- * The id of the active radio
60
- */
61
- activeValue: string | null;
62
- /**
63
- * @internal
64
- * The id of the focused radio
65
- */
66
- focusedValue: string | null;
67
- /**
68
- * @internal
69
- * The id of the hovered radio
70
- */
71
- hoveredValue: string | null;
72
- /**
73
- * @internal
74
- * The active tab indicator's dom rect
75
- */
76
- indicatorRect: Partial<{
77
- left: string;
78
- top: string;
79
- width: string;
80
- height: string;
81
- }>;
82
- /**
83
- * @internal
84
- * Whether the active tab indicator's rect can transition
85
- */
86
- canIndicatorTransition?: boolean | undefined;
87
- /**
88
- * @internal
89
- * Function to clean up the observer for the active tab's rect
90
- */
91
- indicatorCleanup?: VoidFunction | null | undefined;
92
- /**
93
- * @internal
94
- * Whether the radio group's fieldset is disabled
95
- */
96
- fieldsetDisabled: boolean;
97
- /**
98
- * @internal
99
- * Whether the radio group is in focus
100
- */
101
- focusVisible: boolean;
102
- /**
103
- * @internal
104
- * Whether the radio group is in server-side rendering
105
- */
106
- ssr: boolean;
107
- }
108
- type UserDefinedContext = RequiredBy<PublicContext, 'id'>;
109
- type ComputedContext = Readonly<{
110
- /**
111
- * @computed
112
- * Whether the radio group is disabled
113
- */
114
- isDisabled: boolean;
115
- }>;
116
- interface MachineContext extends PublicContext, PrivateContext, ComputedContext {
117
- }
118
- interface MachineState {
119
- value: 'idle';
120
- }
121
- type State = StateMachine.State<MachineContext, MachineState>;
122
- type Send = StateMachine.Send<StateMachine.AnyEventObject>;
123
- type Service = Machine<MachineContext, MachineState, StateMachine.AnyEventObject>;
124
- interface ItemProps {
125
- value: string;
126
- disabled?: boolean | undefined;
127
- invalid?: boolean | undefined;
128
- }
129
- interface ItemState {
130
- /**
131
- * Whether the radio is invalid
132
- */
133
- invalid: boolean;
134
- /**
135
- * Whether the radio is disabled
136
- */
137
- disabled: boolean;
138
- /**
139
- * Whether the radio is checked
140
- */
141
- checked: boolean;
142
- /**
143
- * Whether the radio is focused
144
- */
145
- focused: boolean;
146
- /**
147
- * Whether the radio is hovered
148
- */
149
- hovered: boolean;
150
- /**
151
- * Whether the radio is active or pressed
152
- */
153
- active: boolean;
154
- }
155
- interface MachineApi<T extends PropTypes = PropTypes> {
156
- /**
157
- * The current value of the radio group
158
- */
159
- value: string | null;
160
- /**
161
- * Function to set the value of the radio group
162
- */
163
- setValue: (value: string) => void;
164
- /**
165
- * Function to clear the value of the radio group
166
- */
167
- clearValue: () => void;
168
- /**
169
- * Function to focus the radio group
170
- */
171
- focus: () => void;
172
- /**
173
- * Returns the state details of a radio input
174
- */
175
- getItemState: (props: ItemProps) => ItemState;
176
- getRootProps: () => T['element'];
177
- getLabelProps: () => T['element'];
178
- getItemProps: (props: ItemProps) => T['label'];
179
- getItemTextProps: (props: ItemProps) => T['element'];
180
- getItemControlProps: (props: ItemProps) => T['element'];
181
- getItemHiddenInputProps: (props: ItemProps) => T['input'];
182
- getIndicatorProps: () => T['element'];
183
- }
184
-
185
- declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T>;
186
-
187
- declare function machine(userContext: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
188
-
189
- declare const props: ("ids" | "value" | "name" | "form" | "disabled" | "readOnly" | "onValueChange" | "orientation" | "id" | "dir" | "getRootNode")[];
190
- declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "ids" | "value" | "name" | "form" | "disabled" | "readOnly" | "onValueChange" | "orientation" | "id" | "dir" | "getRootNode">];
191
- declare const itemProps: (keyof ItemProps)[];
192
- declare const splitItemProps: <Props extends ItemProps>(props: Props) => [ItemProps, Omit<Props, keyof ItemProps>];
193
-
194
- export { type MachineApi as Api, type UserDefinedContext as Context, type ElementIds, type ItemProps, type ItemState, type Service, type ValueChangeDetails, anatomy, connect, itemProps, machine, props, splitItemProps, splitProps };
package/dist/index.mjs DELETED
@@ -1,428 +0,0 @@
1
- import { createAnatomy } from '@zag-js/anatomy';
2
- import { createScope, queryAll, dataAttr, visuallyHiddenStyle, nextTick } from '@zag-js/dom-query';
3
- import { isFocusVisible, trackFocusVisible } from '@zag-js/focus-visible';
4
- import { guards, createMachine } from '@zag-js/core';
5
- import { trackElementRect } from '@zag-js/element-rect';
6
- import { dispatchInputCheckedEvent, trackFormControl } from '@zag-js/form-utils';
7
- import { compact, isString, isEqual, createSplitProps } from '@zag-js/utils';
8
- import { createProps } from '@zag-js/types';
9
-
10
- const anatomy = createAnatomy("radio-group").parts(
11
- "root",
12
- "label",
13
- "item",
14
- "itemText",
15
- "itemControl",
16
- "indicator"
17
- );
18
- const parts = anatomy.build();
19
-
20
- const dom = createScope({
21
- getRootId: (ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
22
- getLabelId: (ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
23
- getItemId: (ctx, value) => ctx.ids?.item?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
24
- getItemHiddenInputId: (ctx, value) => ctx.ids?.itemHiddenInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
25
- getItemControlId: (ctx, value) => ctx.ids?.itemControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,
26
- getItemLabelId: (ctx, value) => ctx.ids?.itemLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,
27
- getIndicatorId: (ctx) => ctx.ids?.indicator ?? `radio-group:${ctx.id}:indicator`,
28
- getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
29
- getItemHiddenInputEl: (ctx, value) => dom.getById(ctx, dom.getItemHiddenInputId(ctx, value)),
30
- getIndicatorEl: (ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),
31
- getFirstEnabledInputEl: (ctx) => dom.getRootEl(ctx)?.querySelector("input:not(:disabled)"),
32
- getFirstEnabledAndCheckedInputEl: (ctx) => dom.getRootEl(ctx)?.querySelector("input:not(:disabled):checked"),
33
- getInputEls: (ctx) => {
34
- const ownerId = CSS.escape(dom.getRootId(ctx));
35
- const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`;
36
- return queryAll(dom.getRootEl(ctx), selector);
37
- },
38
- getActiveRadioEl: (ctx) => {
39
- if (!ctx.value)
40
- return;
41
- return dom.getById(ctx, dom.getItemId(ctx, ctx.value));
42
- },
43
- getOffsetRect: (el) => ({
44
- left: el?.offsetLeft ?? 0,
45
- top: el?.offsetTop ?? 0,
46
- width: el?.offsetWidth ?? 0,
47
- height: el?.offsetHeight ?? 0
48
- }),
49
- getRectById: (ctx, id) => {
50
- const radioEl = dom.getById(ctx, dom.getItemId(ctx, id));
51
- if (!radioEl)
52
- return;
53
- return dom.resolveRect(dom.getOffsetRect(radioEl));
54
- },
55
- resolveRect: (rect) => ({
56
- width: `${rect.width}px`,
57
- height: `${rect.height}px`,
58
- left: `${rect.left}px`,
59
- top: `${rect.top}px`
60
- })
61
- });
62
-
63
- function connect(state, send, normalize) {
64
- const groupDisabled = state.context.isDisabled;
65
- const readOnly = state.context.readOnly;
66
- function getItemState(props) {
67
- return {
68
- invalid: !!props.invalid,
69
- disabled: !!props.disabled || groupDisabled,
70
- checked: state.context.value === props.value,
71
- focused: state.context.focusedValue === props.value,
72
- hovered: state.context.hoveredValue === props.value,
73
- active: state.context.activeValue === props.value
74
- };
75
- }
76
- function getItemDataAttrs(props) {
77
- const radioState = getItemState(props);
78
- return {
79
- "data-focus": dataAttr(radioState.focused),
80
- "data-focus-visible": dataAttr(radioState.focused && state.context.focusVisible),
81
- "data-disabled": dataAttr(radioState.disabled),
82
- "data-readonly": dataAttr(readOnly),
83
- "data-state": radioState.checked ? "checked" : "unchecked",
84
- "data-hover": dataAttr(radioState.hovered),
85
- "data-invalid": dataAttr(radioState.invalid),
86
- "data-orientation": state.context.orientation,
87
- "data-ssr": dataAttr(state.context.ssr)
88
- };
89
- }
90
- const focus = () => {
91
- const firstEnabledAndCheckedInput = dom.getFirstEnabledAndCheckedInputEl(state.context);
92
- if (firstEnabledAndCheckedInput) {
93
- firstEnabledAndCheckedInput.focus();
94
- return;
95
- }
96
- const firstEnabledInput = dom.getFirstEnabledInputEl(state.context);
97
- firstEnabledInput?.focus();
98
- };
99
- return {
100
- focus,
101
- value: state.context.value,
102
- setValue(value) {
103
- send({ type: "SET_VALUE", value, isTrusted: false });
104
- },
105
- clearValue() {
106
- send({ type: "SET_VALUE", value: null, isTrusted: false });
107
- },
108
- getRootProps() {
109
- return normalize.element({
110
- ...parts.root.attrs,
111
- "role": "radiogroup",
112
- "id": dom.getRootId(state.context),
113
- "aria-labelledby": dom.getLabelId(state.context),
114
- "data-orientation": state.context.orientation,
115
- "data-disabled": dataAttr(groupDisabled),
116
- "aria-orientation": state.context.orientation,
117
- "dir": state.context.dir,
118
- "style": {
119
- position: "relative"
120
- }
121
- });
122
- },
123
- getLabelProps() {
124
- return normalize.element({
125
- ...parts.label.attrs,
126
- "dir": state.context.dir,
127
- "data-orientation": state.context.orientation,
128
- "data-disabled": dataAttr(groupDisabled),
129
- "id": dom.getLabelId(state.context),
130
- "onClick": focus
131
- });
132
- },
133
- getItemState,
134
- getItemProps(props) {
135
- const itemState = getItemState(props);
136
- return normalize.label({
137
- ...parts.item.attrs,
138
- dir: state.context.dir,
139
- id: dom.getItemId(state.context, props.value),
140
- htmlFor: dom.getItemHiddenInputId(state.context, props.value),
141
- ...getItemDataAttrs(props),
142
- onPointerMove() {
143
- if (itemState.disabled)
144
- return;
145
- if (itemState.hovered)
146
- return;
147
- send({ type: "SET_HOVERED", value: props.value, hovered: true });
148
- },
149
- onPointerLeave() {
150
- if (itemState.disabled)
151
- return;
152
- send({ type: "SET_HOVERED", value: null });
153
- },
154
- onPointerDown(event) {
155
- if (itemState.disabled)
156
- return;
157
- if (itemState.focused && event.pointerType === "mouse") {
158
- event.preventDefault();
159
- }
160
- send({ type: "SET_ACTIVE", value: props.value, active: true });
161
- },
162
- onPointerUp() {
163
- if (itemState.disabled)
164
- return;
165
- send({ type: "SET_ACTIVE", value: null });
166
- }
167
- });
168
- },
169
- getItemTextProps(props) {
170
- return normalize.element({
171
- ...parts.itemText.attrs,
172
- dir: state.context.dir,
173
- id: dom.getItemLabelId(state.context, props.value),
174
- ...getItemDataAttrs(props)
175
- });
176
- },
177
- getItemControlProps(props) {
178
- const controlState = getItemState(props);
179
- return normalize.element({
180
- ...parts.itemControl.attrs,
181
- "dir": state.context.dir,
182
- "id": dom.getItemControlId(state.context, props.value),
183
- "data-active": dataAttr(controlState.active),
184
- "aria-hidden": true,
185
- ...getItemDataAttrs(props)
186
- });
187
- },
188
- getItemHiddenInputProps(props) {
189
- const inputState = getItemState(props);
190
- return normalize.input({
191
- "data-ownedby": dom.getRootId(state.context),
192
- "id": dom.getItemHiddenInputId(state.context, props.value),
193
- "type": "radio",
194
- "name": state.context.name || state.context.id,
195
- "form": state.context.form,
196
- "value": props.value,
197
- onClick(event) {
198
- if (readOnly) {
199
- event.preventDefault();
200
- return;
201
- }
202
- if (event.currentTarget.checked) {
203
- send({ type: "SET_VALUE", value: props.value, isTrusted: true });
204
- }
205
- },
206
- onBlur() {
207
- send({ type: "SET_FOCUSED", value: null, focused: false, focusVisible: false });
208
- },
209
- onFocus() {
210
- const focusVisible = isFocusVisible();
211
- send({ type: "SET_FOCUSED", value: props.value, focused: true, focusVisible });
212
- },
213
- onKeyDown(event) {
214
- if (event.defaultPrevented)
215
- return;
216
- if (event.key === " ") {
217
- send({ type: "SET_ACTIVE", value: props.value, active: true });
218
- }
219
- },
220
- onKeyUp(event) {
221
- if (event.defaultPrevented)
222
- return;
223
- if (event.key === " ") {
224
- send({ type: "SET_ACTIVE", value: null });
225
- }
226
- },
227
- "disabled": inputState.disabled,
228
- "defaultChecked": inputState.checked,
229
- "style": visuallyHiddenStyle
230
- });
231
- },
232
- getIndicatorProps() {
233
- return normalize.element({
234
- "id": dom.getIndicatorId(state.context),
235
- ...parts.indicator.attrs,
236
- "dir": state.context.dir,
237
- "hidden": state.context.value == null,
238
- "data-disabled": dataAttr(groupDisabled),
239
- "data-orientation": state.context.orientation,
240
- "style": {
241
- "--transition-property": "left, top, width, height",
242
- "--left": state.context.indicatorRect?.left,
243
- "--top": state.context.indicatorRect?.top,
244
- "--width": state.context.indicatorRect?.width,
245
- "--height": state.context.indicatorRect?.height,
246
- "position": "absolute",
247
- "willChange": "var(--transition-property)",
248
- "transitionProperty": "var(--transition-property)",
249
- "transitionDuration": state.context.canIndicatorTransition ? "var(--transition-duration, 150ms)" : "0ms",
250
- "transitionTimingFunction": "var(--transition-timing-function)",
251
- [state.context.orientation === "horizontal" ? "left" : "top"]: state.context.orientation === "horizontal" ? "var(--left)" : "var(--top)"
252
- }
253
- });
254
- }
255
- };
256
- }
257
-
258
- const { not } = guards;
259
- const invoke = {
260
- change: (ctx) => {
261
- if (ctx.value == null)
262
- return;
263
- ctx.onValueChange?.({ value: ctx.value });
264
- }
265
- };
266
- const set = {
267
- value: (ctx, value) => {
268
- if (isEqual(ctx.value, value))
269
- return;
270
- ctx.value = value;
271
- invoke.change(ctx);
272
- }
273
- };
274
- function machine(userContext) {
275
- const ctx = compact(userContext);
276
- return createMachine(
277
- {
278
- id: "radio",
279
- initial: "idle",
280
- context: {
281
- value: null,
282
- activeValue: null,
283
- focusedValue: null,
284
- hoveredValue: null,
285
- disabled: false,
286
- orientation: "vertical",
287
- ...ctx,
288
- indicatorRect: {},
289
- canIndicatorTransition: false,
290
- fieldsetDisabled: false,
291
- focusVisible: false,
292
- ssr: true
293
- },
294
- computed: {
295
- isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled
296
- },
297
- entry: ["syncIndicatorRect", "syncSsr"],
298
- exit: ["cleanupObserver"],
299
- activities: ["trackFormControlState", "trackFocusVisible"],
300
- watch: {
301
- value: ["setIndicatorTransition", "syncIndicatorRect", "syncInputElements"]
302
- },
303
- on: {
304
- SET_VALUE: [
305
- {
306
- guard: not("isTrusted"),
307
- actions: ["setValue", "dispatchChangeEvent"]
308
- },
309
- {
310
- actions: ["setValue"]
311
- }
312
- ],
313
- SET_HOVERED: {
314
- actions: "setHovered"
315
- },
316
- SET_ACTIVE: {
317
- actions: "setActive"
318
- },
319
- SET_FOCUSED: {
320
- actions: "setFocused"
321
- }
322
- },
323
- states: {
324
- idle: {}
325
- }
326
- },
327
- {
328
- guards: {
329
- isTrusted: (_ctx, evt) => !!evt.isTrusted
330
- },
331
- activities: {
332
- trackFormControlState(ctx2, _evt, { send, initialContext }) {
333
- return trackFormControl(dom.getRootEl(ctx2), {
334
- onFieldsetDisabledChange(disabled) {
335
- ctx2.fieldsetDisabled = disabled;
336
- },
337
- onFormReset() {
338
- send({ type: "SET_VALUE", value: initialContext.value });
339
- }
340
- });
341
- },
342
- trackFocusVisible(ctx2) {
343
- return trackFocusVisible({ root: dom.getRootNode(ctx2) });
344
- }
345
- },
346
- actions: {
347
- setValue(ctx2, evt) {
348
- set.value(ctx2, evt.value);
349
- },
350
- setHovered(ctx2, evt) {
351
- ctx2.hoveredValue = evt.value;
352
- },
353
- setActive(ctx2, evt) {
354
- ctx2.activeValue = evt.value;
355
- },
356
- setFocused(ctx2, evt) {
357
- ctx2.focusedValue = evt.value;
358
- ctx2.focusVisible = evt.focusVisible;
359
- },
360
- syncInputElements(ctx2) {
361
- const inputs = dom.getInputEls(ctx2);
362
- inputs.forEach((input) => {
363
- input.checked = input.value === ctx2.value;
364
- });
365
- },
366
- setIndicatorTransition(ctx2) {
367
- ctx2.canIndicatorTransition = isString(ctx2.value);
368
- },
369
- cleanupObserver(ctx2) {
370
- ctx2.indicatorCleanup?.();
371
- },
372
- syncSsr(ctx2) {
373
- ctx2.ssr = false;
374
- },
375
- syncIndicatorRect(ctx2) {
376
- ctx2.indicatorCleanup?.();
377
- if (!dom.getIndicatorEl(ctx2))
378
- return;
379
- const value = ctx2.value;
380
- const radioEl = dom.getActiveRadioEl(ctx2);
381
- if (value == null || !radioEl) {
382
- ctx2.indicatorRect = {};
383
- return;
384
- }
385
- ctx2.indicatorCleanup = trackElementRect(radioEl, {
386
- getRect(el) {
387
- return dom.getOffsetRect(el);
388
- },
389
- onChange(rect) {
390
- ctx2.indicatorRect = dom.resolveRect(rect);
391
- nextTick(() => {
392
- ctx2.canIndicatorTransition = false;
393
- });
394
- }
395
- });
396
- },
397
- dispatchChangeEvent(ctx2) {
398
- const inputEls = dom.getInputEls(ctx2);
399
- inputEls.forEach((inputEl) => {
400
- const checked = inputEl.value === ctx2.value;
401
- if (checked === inputEl.checked)
402
- return;
403
- dispatchInputCheckedEvent(inputEl, { checked });
404
- });
405
- }
406
- }
407
- }
408
- );
409
- }
410
-
411
- const props = createProps()([
412
- "dir",
413
- "disabled",
414
- "form",
415
- "getRootNode",
416
- "id",
417
- "ids",
418
- "name",
419
- "onValueChange",
420
- "orientation",
421
- "readOnly",
422
- "value"
423
- ]);
424
- const splitProps = createSplitProps(props);
425
- const itemProps = createProps()(["value", "disabled", "invalid"]);
426
- const splitItemProps = createSplitProps(itemProps);
427
-
428
- export { anatomy, connect, itemProps, machine, props, splitItemProps, splitProps };