@destyler/radio 0.2.10 → 0.2.12

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 CHANGED
@@ -1,10 +1,7 @@
1
- import * as _destyler_anatomy0 from "@destyler/anatomy";
2
- import * as _destyler_xstate0 from "@destyler/xstate";
3
1
  import { AnyEventObject, Machine, XSend, XState } from "@destyler/xstate";
4
2
  import { CommonProperties, DirectionProperty, NormalizeProps, PropTypes, RequiredBy } from "@destyler/types";
5
-
6
3
  //#region src/anatomy.d.ts
7
- declare const anatomy: _destyler_anatomy0.AnatomyInstance<"root" | "label" | "item" | "itemText" | "itemControl" | "indicator">;
4
+ export declare const anatomy: import("@destyler/anatomy").AnatomyInstance<"root" | "label" | "indicator" | "item" | "itemControl" | "itemText">;
8
5
  //#endregion
9
6
  //#region src/types.d.ts
10
7
  interface ValueChangeDetails {
@@ -52,7 +49,7 @@ interface PublicContext extends DirectionProperty, CommonProperties {
52
49
  readOnly?: boolean | undefined;
53
50
  /**
54
51
  * Function called once a radio is checked
55
- * @param value the value of the checked radio
52
+ * @param details the value of the checked radio
56
53
  */
57
54
  onValueChange?: (details: ValueChangeDetails) => void;
58
55
  /**
@@ -189,15 +186,15 @@ interface MachineApi<T extends PropTypes = PropTypes> {
189
186
  }
190
187
  //#endregion
191
188
  //#region src/connect.d.ts
192
- declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T>;
189
+ export declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T>;
193
190
  //#endregion
194
191
  //#region src/machine.d.ts
195
- declare function machine(userContext: UserDefinedContext): _destyler_xstate0.Machine<MachineContext, MachineState, _destyler_xstate0.AnyEventObject>;
192
+ export declare function machine(userContext: UserDefinedContext): import("@destyler/xstate").Machine<MachineContext, MachineState, import("@destyler/xstate").AnyEventObject>;
196
193
  //#endregion
197
194
  //#region src/props.d.ts
198
- declare const props: ("value" | "ids" | "defaultValue" | "name" | "form" | "disabled" | "readOnly" | "onValueChange" | "orientation" | "dir" | "id" | "getRootNode")[];
199
- declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "value" | "ids" | "defaultValue" | "name" | "form" | "disabled" | "readOnly" | "onValueChange" | "orientation" | "dir" | "id" | "getRootNode">];
200
- declare const itemProps: (keyof ItemProps)[];
201
- declare const splitItemProps: <Props extends ItemProps>(props: Props) => [ItemProps, Omit<Props, keyof ItemProps>];
195
+ export declare const props: ("value" | "ids" | "defaultValue" | "name" | "form" | "disabled" | "readOnly" | "onValueChange" | "orientation" | "dir" | "id" | "getRootNode")[];
196
+ export declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "value" | "ids" | "defaultValue" | "name" | "form" | "disabled" | "readOnly" | "onValueChange" | "orientation" | "dir" | "id" | "getRootNode">];
197
+ export declare const itemProps: (keyof ItemProps)[];
198
+ export declare const splitItemProps: <Props extends ItemProps>(props: Props) => [ItemProps, Omit<Props, keyof ItemProps>];
202
199
  //#endregion
203
- 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 };
200
+ export type { MachineApi as Api, UserDefinedContext as Context, ElementIds, ItemProps, ItemState, Service, ValueChangeDetails };
package/dist/index.mjs CHANGED
@@ -1,15 +1,13 @@
1
1
  import { createAnatomy } from "@destyler/anatomy";
2
- import { createScope, dataAttr, dispatchInputCheckedEvent, nextTick, queryAll, trackFormControl, visuallyHiddenStyle } from "@destyler/dom";
2
+ import { createScope, dataAttr, dispatchInputCheckedEvent, nextTick, queryAll, trackCanceledInputClick, trackFormControl, visuallyHiddenStyle } from "@destyler/dom";
3
3
  import { isFocusVisible, trackFocusVisible } from "@destyler/focus-visible";
4
4
  import { trackElementRect } from "@destyler/element-rect";
5
5
  import { compact, createSplitProps, isControlled, isEqual, isPropUserProvided, isString, resolveControllableProp, withControllableProvided } from "@destyler/utils";
6
6
  import { createMachine, guards } from "@destyler/xstate";
7
7
  import { createProps } from "@destyler/types";
8
-
9
8
  //#region src/anatomy.ts
10
9
  const anatomy = createAnatomy("radio-group").parts("root", "label", "item", "itemText", "itemControl", "indicator");
11
10
  const parts = anatomy.build();
12
-
13
11
  //#endregion
14
12
  //#region src/dom.ts
15
13
  const dom = createScope({
@@ -25,8 +23,8 @@ const dom = createScope({
25
23
  getIndicatorEl: (ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),
26
24
  getFirstEnabledInputEl: (ctx) => dom.getRootEl(ctx)?.querySelector("input:not(:disabled)"),
27
25
  getFirstEnabledAndCheckedInputEl: (ctx) => dom.getRootEl(ctx)?.querySelector("input:not(:disabled):checked"),
28
- getInputEls: (ctx) => {
29
- const selector = `input[type=radio][data-ownedby='${CSS.escape(dom.getRootId(ctx))}']:not([disabled])`;
26
+ getInputEls: (ctx, includeDisabled = false) => {
27
+ const selector = `input[type=radio][data-ownedby='${CSS.escape(dom.getRootId(ctx))}']${includeDisabled ? "" : ":not([disabled])"}`;
30
28
  return queryAll(dom.getRootEl(ctx), selector);
31
29
  },
32
30
  getActiveRadioEl: (ctx) => {
@@ -51,24 +49,23 @@ const dom = createScope({
51
49
  top: `${rect.top}px`
52
50
  })
53
51
  });
54
-
55
52
  //#endregion
56
53
  //#region src/connect.ts
57
54
  function connect(state, send, normalize) {
58
55
  const groupDisabled = state.context.isDisabled;
59
56
  const readOnly = state.context.readOnly;
60
- function getItemState(props$1) {
57
+ function getItemState(props) {
61
58
  return {
62
- invalid: !!props$1.invalid,
63
- disabled: !!props$1.disabled || groupDisabled,
64
- checked: state.context.value === props$1.value,
65
- focused: state.context.focusedValue === props$1.value,
66
- hovered: state.context.hoveredValue === props$1.value,
67
- active: state.context.activeValue === props$1.value
59
+ invalid: !!props.invalid,
60
+ disabled: !!props.disabled || groupDisabled,
61
+ checked: state.context.value === props.value,
62
+ focused: state.context.focusedValue === props.value,
63
+ hovered: state.context.hoveredValue === props.value,
64
+ active: state.context.activeValue === props.value
68
65
  };
69
66
  }
70
- function getItemDataAttrs(props$1) {
71
- const radioState = getItemState(props$1);
67
+ function getItemDataAttrs(props) {
68
+ const radioState = getItemState(props);
72
69
  return {
73
70
  "data-focus": dataAttr(radioState.focused),
74
71
  "data-focus-visible": dataAttr(radioState.focused && state.context.focusVisible),
@@ -130,20 +127,20 @@ function connect(state, send, normalize) {
130
127
  });
131
128
  },
132
129
  getItemState,
133
- getItemProps(props$1) {
134
- const itemState = getItemState(props$1);
130
+ getItemProps(props) {
131
+ const itemState = getItemState(props);
135
132
  return normalize.label({
136
133
  ...parts.item.attrs,
137
134
  dir: state.context.dir,
138
- id: dom.getItemId(state.context, props$1.value),
139
- htmlFor: dom.getItemHiddenInputId(state.context, props$1.value),
140
- ...getItemDataAttrs(props$1),
135
+ id: dom.getItemId(state.context, props.value),
136
+ htmlFor: dom.getItemHiddenInputId(state.context, props.value),
137
+ ...getItemDataAttrs(props),
141
138
  onPointerMove() {
142
139
  if (itemState.disabled) return;
143
140
  if (itemState.hovered) return;
144
141
  send({
145
142
  type: "SET_HOVERED",
146
- value: props$1.value,
143
+ value: props.value,
147
144
  hovered: true
148
145
  });
149
146
  },
@@ -159,7 +156,7 @@ function connect(state, send, normalize) {
159
156
  if (itemState.focused && event.pointerType === "mouse") event.preventDefault();
160
157
  send({
161
158
  type: "SET_ACTIVE",
162
- value: props$1.value,
159
+ value: props.value,
163
160
  active: true
164
161
  });
165
162
  },
@@ -172,34 +169,34 @@ function connect(state, send, normalize) {
172
169
  }
173
170
  });
174
171
  },
175
- getItemTextProps(props$1) {
172
+ getItemTextProps(props) {
176
173
  return normalize.element({
177
174
  ...parts.itemText.attrs,
178
175
  dir: state.context.dir,
179
- id: dom.getItemLabelId(state.context, props$1.value),
180
- ...getItemDataAttrs(props$1)
176
+ id: dom.getItemLabelId(state.context, props.value),
177
+ ...getItemDataAttrs(props)
181
178
  });
182
179
  },
183
- getItemControlProps(props$1) {
184
- const controlState = getItemState(props$1);
180
+ getItemControlProps(props) {
181
+ const controlState = getItemState(props);
185
182
  return normalize.element({
186
183
  ...parts.itemControl.attrs,
187
184
  "dir": state.context.dir,
188
- "id": dom.getItemControlId(state.context, props$1.value),
185
+ "id": dom.getItemControlId(state.context, props.value),
189
186
  "data-active": dataAttr(controlState.active),
190
187
  "aria-hidden": true,
191
- ...getItemDataAttrs(props$1)
188
+ ...getItemDataAttrs(props)
192
189
  });
193
190
  },
194
- getItemHiddenInputProps(props$1) {
195
- const inputState = getItemState(props$1);
191
+ getItemHiddenInputProps(props) {
192
+ const inputState = getItemState(props);
196
193
  return normalize.input({
197
194
  "data-ownedby": dom.getRootId(state.context),
198
- "id": dom.getItemHiddenInputId(state.context, props$1.value),
195
+ "id": dom.getItemHiddenInputId(state.context, props.value),
199
196
  "type": "radio",
200
197
  "name": state.context.name || state.context.id,
201
198
  "form": state.context.form,
202
- "value": props$1.value,
199
+ "value": props.value,
203
200
  onClick(event) {
204
201
  if (readOnly) {
205
202
  event.preventDefault();
@@ -207,7 +204,7 @@ function connect(state, send, normalize) {
207
204
  }
208
205
  if (event.currentTarget.checked) send({
209
206
  type: "SET_VALUE",
210
- value: props$1.value,
207
+ value: props.value,
211
208
  isTrusted: true
212
209
  });
213
210
  },
@@ -223,7 +220,7 @@ function connect(state, send, normalize) {
223
220
  const focusVisible = isFocusVisible();
224
221
  send({
225
222
  type: "SET_FOCUSED",
226
- value: props$1.value,
223
+ value: props.value,
227
224
  focused: true,
228
225
  focusVisible
229
226
  });
@@ -232,7 +229,7 @@ function connect(state, send, normalize) {
232
229
  if (event.defaultPrevented) return;
233
230
  if (event.key === " ") send({
234
231
  type: "SET_ACTIVE",
235
- value: props$1.value,
232
+ value: props.value,
236
233
  active: true
237
234
  });
238
235
  },
@@ -273,7 +270,6 @@ function connect(state, send, normalize) {
273
270
  }
274
271
  };
275
272
  }
276
-
277
273
  //#endregion
278
274
  //#region src/machine.ts
279
275
  const { not } = guards;
@@ -315,10 +311,14 @@ function machine(userContext) {
315
311
  focusVisible: false,
316
312
  ssr: true
317
313
  },
318
- computed: { isDisabled: (ctx$1) => !!ctx$1.disabled || ctx$1.fieldsetDisabled },
314
+ computed: { isDisabled: (ctx) => !!ctx.disabled || ctx.fieldsetDisabled },
319
315
  entry: ["syncIndicatorRect", "syncSsr"],
320
316
  exit: ["cleanupObserver"],
321
- activities: ["trackFormControlState", "trackFocusVisible"],
317
+ activities: [
318
+ "trackCanceledInputClick",
319
+ "trackFormControlState",
320
+ "trackFocusVisible"
321
+ ],
322
322
  watch: { value: [
323
323
  "setIndicatorTransition",
324
324
  "syncIndicatorRect",
@@ -328,7 +328,7 @@ function machine(userContext) {
328
328
  SET_VALUE: [{
329
329
  guard: not("isTrusted"),
330
330
  actions: ["setValue", "dispatchChangeEvent"]
331
- }, { actions: ["setValue"] }],
331
+ }, { actions: ["setValue", "syncInputElements"] }],
332
332
  SET_HOVERED: { actions: "setHovered" },
333
333
  SET_ACTIVE: { actions: "setActive" },
334
334
  SET_FOCUSED: { actions: "setFocused" }
@@ -337,10 +337,19 @@ function machine(userContext) {
337
337
  }, {
338
338
  guards: { isTrusted: (_ctx, evt) => !!evt.isTrusted },
339
339
  activities: {
340
- trackFormControlState(ctx$1, _evt, { send, initialContext }) {
341
- return trackFormControl(dom.getRootEl(ctx$1), {
340
+ trackCanceledInputClick(ctx) {
341
+ const root = dom.getRootEl(ctx);
342
+ return trackCanceledInputClick(root, (target) => {
343
+ if (target.getAttribute("data-ownedby") !== dom.getRootId(ctx)) return;
344
+ (root?.querySelectorAll("input[type=\"radio\"]"))?.forEach((input) => {
345
+ if (input.getAttribute("data-ownedby") === dom.getRootId(ctx)) input.checked = input.value === ctx.value;
346
+ });
347
+ });
348
+ },
349
+ trackFormControlState(ctx, _evt, { send, initialContext }) {
350
+ return trackFormControl(dom.getRootEl(ctx), {
342
351
  onFieldsetDisabledChange(disabled) {
343
- ctx$1.fieldsetDisabled = disabled;
352
+ ctx.fieldsetDisabled = disabled;
344
353
  },
345
354
  onFormReset() {
346
355
  send({
@@ -350,62 +359,62 @@ function machine(userContext) {
350
359
  }
351
360
  });
352
361
  },
353
- trackFocusVisible(ctx$1) {
354
- return trackFocusVisible({ root: dom.getRootNode(ctx$1) });
362
+ trackFocusVisible(ctx) {
363
+ return trackFocusVisible({ root: dom.getRootNode(ctx) });
355
364
  }
356
365
  },
357
366
  actions: {
358
- setValue(ctx$1, evt) {
359
- set.value(ctx$1, evt.value);
367
+ setValue(ctx, evt) {
368
+ set.value(ctx, evt.value);
360
369
  },
361
- setHovered(ctx$1, evt) {
362
- ctx$1.hoveredValue = evt.value;
370
+ setHovered(ctx, evt) {
371
+ ctx.hoveredValue = evt.value;
363
372
  },
364
- setActive(ctx$1, evt) {
365
- ctx$1.activeValue = evt.value;
373
+ setActive(ctx, evt) {
374
+ ctx.activeValue = evt.value;
366
375
  },
367
- setFocused(ctx$1, evt) {
368
- ctx$1.focusedValue = evt.value;
369
- ctx$1.focusVisible = evt.focusVisible;
376
+ setFocused(ctx, evt) {
377
+ ctx.focusedValue = evt.value;
378
+ ctx.focusVisible = evt.focusVisible;
370
379
  },
371
- syncInputElements(ctx$1) {
372
- dom.getInputEls(ctx$1).forEach((input) => {
373
- input.checked = input.value === ctx$1.value;
380
+ syncInputElements(ctx) {
381
+ dom.getInputEls(ctx, true).forEach((input) => {
382
+ input.checked = input.value === ctx.value;
374
383
  });
375
384
  },
376
- setIndicatorTransition(ctx$1) {
377
- ctx$1.canIndicatorTransition = isString(ctx$1.value);
385
+ setIndicatorTransition(ctx) {
386
+ ctx.canIndicatorTransition = isString(ctx.value);
378
387
  },
379
- cleanupObserver(ctx$1) {
380
- ctx$1.indicatorCleanup?.();
388
+ cleanupObserver(ctx) {
389
+ ctx.indicatorCleanup?.();
381
390
  },
382
- syncSsr(ctx$1) {
383
- ctx$1.ssr = false;
391
+ syncSsr(ctx) {
392
+ ctx.ssr = false;
384
393
  },
385
- syncIndicatorRect(ctx$1) {
386
- ctx$1.indicatorCleanup?.();
387
- if (!dom.getIndicatorEl(ctx$1)) return;
388
- const value = ctx$1.value;
389
- const radioEl = dom.getActiveRadioEl(ctx$1);
394
+ syncIndicatorRect(ctx) {
395
+ ctx.indicatorCleanup?.();
396
+ if (!dom.getIndicatorEl(ctx)) return;
397
+ const value = ctx.value;
398
+ const radioEl = dom.getActiveRadioEl(ctx);
390
399
  if (value == null || !radioEl) {
391
- ctx$1.indicatorRect = {};
400
+ ctx.indicatorRect = {};
392
401
  return;
393
402
  }
394
- ctx$1.indicatorCleanup = trackElementRect(radioEl, {
403
+ ctx.indicatorCleanup = trackElementRect(radioEl, {
395
404
  getRect(el) {
396
405
  return dom.getOffsetRect(el);
397
406
  },
398
407
  onChange(rect) {
399
- ctx$1.indicatorRect = dom.resolveRect(rect);
408
+ ctx.indicatorRect = dom.resolveRect(rect);
400
409
  nextTick(() => {
401
- ctx$1.canIndicatorTransition = false;
410
+ ctx.canIndicatorTransition = false;
402
411
  });
403
412
  }
404
413
  });
405
414
  },
406
- dispatchChangeEvent(ctx$1) {
407
- dom.getInputEls(ctx$1).forEach((inputEl) => {
408
- const checked = inputEl.value === ctx$1.value;
415
+ dispatchChangeEvent(ctx) {
416
+ dom.getInputEls(ctx).forEach((inputEl) => {
417
+ const checked = inputEl.value === ctx.value;
409
418
  if (checked === inputEl.checked) return;
410
419
  dispatchInputCheckedEvent(inputEl, { checked });
411
420
  });
@@ -413,7 +422,6 @@ function machine(userContext) {
413
422
  }
414
423
  });
415
424
  }
416
-
417
425
  //#endregion
418
426
  //#region src/props.ts
419
427
  const props = createProps()([
@@ -437,6 +445,5 @@ const itemProps = createProps()([
437
445
  "invalid"
438
446
  ]);
439
447
  const splitItemProps = createSplitProps(itemProps);
440
-
441
448
  //#endregion
442
- export { anatomy, connect, itemProps, machine, props, splitItemProps, splitProps };
449
+ export { anatomy, connect, itemProps, machine, props, splitItemProps, splitProps };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@destyler/radio",
3
3
  "type": "module",
4
- "version": "0.2.10",
4
+ "version": "0.2.12",
5
5
  "description": "A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.",
6
6
  "author": "Elone Hoo <elonehoo@gmail.com>",
7
7
  "license": "MIT",
@@ -22,13 +22,13 @@
22
22
  "dist"
23
23
  ],
24
24
  "dependencies": {
25
- "@destyler/anatomy": "0.2.10",
26
- "@destyler/dom": "0.2.10",
27
- "@destyler/element-rect": "0.2.10",
28
- "@destyler/focus-visible": "0.2.10",
29
- "@destyler/utils": "0.2.10",
30
- "@destyler/types": "0.2.10",
31
- "@destyler/xstate": "0.2.10"
25
+ "@destyler/anatomy": "0.2.12",
26
+ "@destyler/dom": "0.2.12",
27
+ "@destyler/element-rect": "0.2.12",
28
+ "@destyler/focus-visible": "0.2.12",
29
+ "@destyler/types": "0.2.12",
30
+ "@destyler/utils": "0.2.12",
31
+ "@destyler/xstate": "0.2.12"
32
32
  },
33
33
  "publishConfig": {
34
34
  "access": "public"