@destyler/switch 0.0.6 → 0.0.7-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/dist/index.cjs CHANGED
@@ -1,189 +1,286 @@
1
1
  'use strict';
2
2
 
3
- const vue = require('vue');
4
- const primitive = require('@destyler/primitive');
5
- const composition = require('@destyler/composition');
6
- const shared = require('@destyler/shared');
7
- const directives = require('@destyler/directives');
3
+ const anatomy$1 = require('@zag-js/anatomy');
4
+ const domQuery = require('@zag-js/dom-query');
5
+ const focusVisible = require('@zag-js/focus-visible');
6
+ const core = require('@zag-js/core');
7
+ const domEvent = require('@zag-js/dom-event');
8
+ const formUtils = require('@zag-js/form-utils');
9
+ const utils = require('@zag-js/utils');
10
+ const types = require('@zag-js/types');
8
11
 
9
- const switchRootProps = {
10
- ...primitive.primitiveProps,
11
- /**
12
- * @default button
13
- */
14
- as: {
15
- ...primitive.primitiveProps.as,
16
- default: "button"
17
- },
18
- /**
19
- * The state of the switch when it is initially rendered.
20
- * Use when you do not need to control its state.
21
- */
22
- defaultChecked: {
23
- type: Boolean,
24
- required: false
25
- },
26
- /**
27
- * The controlled state of the switch.
28
- * Can be bind as `v-model:checked`.
29
- */
30
- checked: {
31
- type: Boolean,
32
- required: false,
33
- default: void 0
34
- },
35
- /**
36
- * When `true`, prevents the user from interacting with the switch.
37
- */
38
- disabled: {
39
- type: Boolean,
40
- required: false
41
- },
42
- /**
43
- * When `true`, indicates that the user must check the switch before the owning form can be submitted.
44
- */
45
- required: {
46
- type: Boolean,
47
- required: false
48
- },
49
- /**
50
- * The name of the switch. Submitted with its owning form as part of a name/value pair.
51
- */
52
- name: {
53
- type: String,
54
- required: false
55
- },
56
- /**
57
- * Id of the element
58
- */
59
- id: {
60
- type: String,
61
- required: false
62
- },
63
- /**
64
- * The value given as data when submitted with a `name`.
65
- */
66
- value: {
67
- type: String,
68
- required: false,
69
- default: "on"
70
- }
71
- };
72
- const switchRootEmits = {
73
- "update:checked": (_checked) => true
74
- };
75
- const [injectSwitchRootContext, provideSwitchRootContext] = shared.createContext("DestylerSwitchRoot");
76
- const SwitchRoot = vue.defineComponent({
77
- name: "DestylerSwitchRoot",
78
- props: switchRootProps,
79
- emits: switchRootEmits,
80
- setup(props, { emit }) {
81
- const { disabled } = vue.toRefs(props);
82
- const checked = composition.useVModel(props, "checked", emit, {
83
- defaultValue: props.defaultChecked,
84
- passive: props.checked === void 0
85
- });
86
- function toggleCheck() {
87
- if (disabled.value)
88
- return;
89
- checked.value = !checked.value;
90
- }
91
- const { forwardRef, currentElement } = composition.useForwardExpose();
92
- const isFormControl = composition.useFormControl(currentElement);
93
- const ariaLabel = vue.computed(() => props.id && currentElement.value ? document.querySelector(`[for="${props.id}"]`)?.textContent : void 0);
94
- provideSwitchRootContext({
95
- checked,
96
- toggleCheck,
97
- disabled
98
- });
99
- return {
100
- forwardRef,
101
- toggleCheck,
102
- isFormControl,
103
- ariaLabel,
104
- checked,
105
- disabled
106
- };
107
- },
108
- render() {
109
- return [
110
- vue.withDirectives(vue.h(primitive.Primitive, vue.mergeProps(this.$attrs, {
111
- "ref": (el) => this.forwardRef(el),
112
- "role": "switch",
113
- "type": this.$props.as === "button" ? "button" : void 0,
114
- "value": this.value,
115
- "aria-label": this.$attrs["aria-label"] || this.ariaLabel,
116
- "aria-checked": this.checked,
117
- "aria-required": this.$props.required,
118
- "data-state": this.checked ? "checked" : "unchecked",
119
- "data-disabled": this.disabled ? "" : void 0,
120
- "as": this.$props.as,
121
- "asChild": this.$props.asChild,
122
- "disabled": this.disabled,
123
- "onClick": () => {
124
- this.toggleCheck();
12
+ const anatomy = anatomy$1.createAnatomy("switch").parts("root", "label", "control", "thumb");
13
+ const parts = anatomy.build();
14
+
15
+ const dom = domQuery.createScope({
16
+ getRootId: (ctx) => ctx.ids?.root ?? `switch:${ctx.id}`,
17
+ getLabelId: (ctx) => ctx.ids?.label ?? `switch:${ctx.id}:label`,
18
+ getThumbId: (ctx) => ctx.ids?.thumb ?? `switch:${ctx.id}:thumb`,
19
+ getControlId: (ctx) => ctx.ids?.control ?? `switch:${ctx.id}:control`,
20
+ getHiddenInputId: (ctx) => ctx.ids?.hiddenInput ?? `switch:${ctx.id}:input`,
21
+ getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
22
+ getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx))
23
+ });
24
+
25
+ function connect(state, send, normalize) {
26
+ const disabled = state.context.isDisabled;
27
+ const readOnly = state.context.readOnly;
28
+ const checked = state.context.checked;
29
+ const focused = !disabled && state.context.focused;
30
+ const focusVisible$1 = !disabled && state.context.focusVisible;
31
+ const dataAttrs = {
32
+ "data-active": domQuery.dataAttr(state.context.active),
33
+ "data-focus": domQuery.dataAttr(focused),
34
+ "data-focus-visible": domQuery.dataAttr(focusVisible$1),
35
+ "data-readonly": domQuery.dataAttr(readOnly),
36
+ "data-hover": domQuery.dataAttr(state.context.hovered),
37
+ "data-disabled": domQuery.dataAttr(disabled),
38
+ "data-state": state.context.checked ? "checked" : "unchecked",
39
+ "data-invalid": domQuery.dataAttr(state.context.invalid)
40
+ };
41
+ return {
42
+ checked,
43
+ disabled,
44
+ focused,
45
+ setChecked(checked2) {
46
+ send({ type: "CHECKED.SET", checked: checked2, isTrusted: false });
47
+ },
48
+ toggleChecked() {
49
+ send({ type: "CHECKED.TOGGLE", checked, isTrusted: false });
50
+ },
51
+ getRootProps() {
52
+ return normalize.label({
53
+ ...parts.root.attrs,
54
+ ...dataAttrs,
55
+ dir: state.context.dir,
56
+ id: dom.getRootId(state.context),
57
+ htmlFor: dom.getHiddenInputId(state.context),
58
+ onPointerMove() {
59
+ if (disabled)
60
+ return;
61
+ send({ type: "CONTEXT.SET", context: { hovered: true } });
125
62
  },
126
- "onKeydown": vue.withModifiers(() => {
127
- this.toggleCheck();
128
- }, ["enter", "prevent"])
129
- }), () => this.$slots.default?.()), [
130
- [directives.BindOnceDirective, { id: this.$props.id }]
131
- ]),
132
- this.isFormControl ? vue.h("input", {
63
+ onPointerLeave() {
64
+ if (disabled)
65
+ return;
66
+ send({ type: "CONTEXT.SET", context: { hovered: false } });
67
+ },
68
+ onClick(event) {
69
+ if (disabled)
70
+ return;
71
+ const target = domQuery.getEventTarget(event);
72
+ if (target === dom.getHiddenInputEl(state.context)) {
73
+ event.stopPropagation();
74
+ }
75
+ }
76
+ });
77
+ },
78
+ getLabelProps() {
79
+ return normalize.element({
80
+ ...parts.label.attrs,
81
+ ...dataAttrs,
82
+ dir: state.context.dir,
83
+ id: dom.getLabelId(state.context)
84
+ });
85
+ },
86
+ getThumbProps() {
87
+ return normalize.element({
88
+ ...parts.thumb.attrs,
89
+ ...dataAttrs,
90
+ "dir": state.context.dir,
91
+ "id": dom.getThumbId(state.context),
92
+ "aria-hidden": true
93
+ });
94
+ },
95
+ getControlProps() {
96
+ return normalize.element({
97
+ ...parts.control.attrs,
98
+ ...dataAttrs,
99
+ "dir": state.context.dir,
100
+ "id": dom.getControlId(state.context),
101
+ "aria-hidden": true
102
+ });
103
+ },
104
+ getHiddenInputProps() {
105
+ return normalize.input({
106
+ "id": dom.getHiddenInputId(state.context),
133
107
  "type": "checkbox",
134
- "name": this.$props.name,
135
- "tabindex": -1,
136
- "aria-hidden": "",
137
- "disabled": this.disabled,
138
- "required": this.$props.required,
139
- "value": this.value,
140
- "checked": !!this.checked,
141
- "data-state": this.checked ? "checked" : "unchecked",
142
- "data-disabled": this.disabled ? "" : void 0,
143
- "style": {
144
- transform: "translateX(-100%)",
145
- position: "absolute",
146
- pointerEvents: "none",
147
- opacity: 0,
148
- margin: 0
108
+ "required": state.context.required,
109
+ "defaultChecked": checked,
110
+ "disabled": disabled,
111
+ "aria-labelledby": dom.getLabelId(state.context),
112
+ "aria-invalid": state.context.invalid,
113
+ "name": state.context.name,
114
+ "form": state.context.form,
115
+ "value": state.context.value,
116
+ "style": domQuery.visuallyHiddenStyle,
117
+ onFocus() {
118
+ const focusVisible2 = focusVisible.isFocusVisible();
119
+ send({ type: "CONTEXT.SET", context: { focused: true, focusVisible: focusVisible2 } });
120
+ },
121
+ onBlur() {
122
+ send({ type: "CONTEXT.SET", context: { focused: false, focusVisible: false } });
123
+ },
124
+ onClick(event) {
125
+ if (readOnly) {
126
+ event.preventDefault();
127
+ return;
128
+ }
129
+ const checked2 = event.currentTarget.checked;
130
+ send({ type: "CHECKED.SET", checked: checked2, isTrusted: true });
149
131
  }
150
- }) : null
151
- ];
152
- }
153
- });
132
+ });
133
+ }
134
+ };
135
+ }
154
136
 
155
- const switchThumbProps = {
156
- ...primitive.primitiveProps,
157
- /**
158
- * @default span
159
- */
160
- as: {
161
- ...primitive.primitiveProps.as,
162
- default: "span"
137
+ const { not } = core.guards;
138
+ const invoke = {
139
+ change: (ctx) => {
140
+ ctx.onCheckedChange?.({ checked: ctx.checked });
163
141
  }
164
142
  };
165
- const SwitchThumb = vue.defineComponent({
166
- name: "DestylerSwitchThump",
167
- props: switchThumbProps,
168
- setup(_) {
169
- const rootContext = injectSwitchRootContext();
170
- composition.useForwardExpose();
171
- return {
172
- rootContext
173
- };
174
- },
175
- render() {
176
- return vue.h(primitive.Primitive, {
177
- "data-state": this.rootContext.checked?.value ? "checked" : "unchecked",
178
- "data-disabled": this.rootContext.disabled.value ? "" : void 0,
179
- "asChild": this.$props.asChild,
180
- "as": this.$props.as
181
- }, () => this.$slots.default?.());
143
+ const set = {
144
+ checked: (ctx, checked) => {
145
+ if (utils.isEqual(ctx.checked, checked))
146
+ return;
147
+ ctx.checked = checked;
148
+ invoke.change(ctx);
182
149
  }
183
- });
150
+ };
151
+ function machine(userContext) {
152
+ const ctx = utils.compact(userContext);
153
+ return core.createMachine(
154
+ {
155
+ id: "switch",
156
+ initial: "ready",
157
+ context: {
158
+ checked: false,
159
+ label: "switch",
160
+ value: "on",
161
+ disabled: false,
162
+ ...ctx,
163
+ fieldsetDisabled: false,
164
+ focusVisible: false
165
+ },
166
+ computed: {
167
+ isDisabled: (ctx2) => ctx2.disabled || ctx2.fieldsetDisabled
168
+ },
169
+ watch: {
170
+ disabled: "removeFocusIfNeeded",
171
+ checked: "syncInputElement"
172
+ },
173
+ activities: ["trackFormControlState", "trackPressEvent", "trackFocusVisible"],
174
+ on: {
175
+ "CHECKED.TOGGLE": [
176
+ {
177
+ guard: not("isTrusted"),
178
+ actions: ["toggleChecked", "dispatchChangeEvent"]
179
+ },
180
+ {
181
+ actions: ["toggleChecked"]
182
+ }
183
+ ],
184
+ "CHECKED.SET": [
185
+ {
186
+ guard: not("isTrusted"),
187
+ actions: ["setChecked", "dispatchChangeEvent"]
188
+ },
189
+ {
190
+ actions: ["setChecked"]
191
+ }
192
+ ],
193
+ "CONTEXT.SET": {
194
+ actions: ["setContext"]
195
+ }
196
+ },
197
+ states: {
198
+ ready: {}
199
+ }
200
+ },
201
+ {
202
+ guards: {
203
+ isTrusted: (_ctx, evt) => !!evt.isTrusted
204
+ },
205
+ activities: {
206
+ trackPressEvent(ctx2) {
207
+ if (ctx2.isDisabled)
208
+ return;
209
+ return domEvent.trackPress({
210
+ pointerNode: dom.getRootEl(ctx2),
211
+ keyboardNode: dom.getHiddenInputEl(ctx2),
212
+ isValidKey: (event) => event.key === " ",
213
+ onPress: () => ctx2.active = false,
214
+ onPressStart: () => ctx2.active = true,
215
+ onPressEnd: () => ctx2.active = false
216
+ });
217
+ },
218
+ trackFocusVisible(ctx2) {
219
+ if (ctx2.isDisabled)
220
+ return;
221
+ return focusVisible.trackFocusVisible({ root: dom.getRootNode(ctx2) });
222
+ },
223
+ trackFormControlState(ctx2, _evt, { send, initialContext }) {
224
+ return formUtils.trackFormControl(dom.getHiddenInputEl(ctx2), {
225
+ onFieldsetDisabledChange(disabled) {
226
+ ctx2.fieldsetDisabled = disabled;
227
+ },
228
+ onFormReset() {
229
+ send({ type: "CHECKED.SET", checked: !!initialContext.checked, src: "form-reset" });
230
+ }
231
+ });
232
+ }
233
+ },
234
+ actions: {
235
+ setContext(ctx2, evt) {
236
+ Object.assign(ctx2, evt.context);
237
+ },
238
+ syncInputElement(ctx2) {
239
+ const inputEl = dom.getHiddenInputEl(ctx2);
240
+ if (!inputEl)
241
+ return;
242
+ inputEl.checked = !!ctx2.checked;
243
+ },
244
+ removeFocusIfNeeded(ctx2) {
245
+ if (ctx2.disabled && ctx2.focused) {
246
+ ctx2.focused = false;
247
+ }
248
+ },
249
+ setChecked(ctx2, evt) {
250
+ set.checked(ctx2, evt.checked);
251
+ },
252
+ toggleChecked(ctx2, _evt) {
253
+ set.checked(ctx2, !ctx2.checked);
254
+ },
255
+ dispatchChangeEvent(ctx2) {
256
+ const inputEl = dom.getHiddenInputEl(ctx2);
257
+ formUtils.dispatchInputCheckedEvent(inputEl, { checked: ctx2.checked });
258
+ }
259
+ }
260
+ }
261
+ );
262
+ }
263
+
264
+ const props = types.createProps()([
265
+ "checked",
266
+ "dir",
267
+ "disabled",
268
+ "form",
269
+ "getRootNode",
270
+ "id",
271
+ "ids",
272
+ "invalid",
273
+ "label",
274
+ "name",
275
+ "onCheckedChange",
276
+ "readOnly",
277
+ "required",
278
+ "value"
279
+ ]);
280
+ const splitProps = utils.createSplitProps(props);
184
281
 
185
- exports.SwitchRoot = SwitchRoot;
186
- exports.SwitchThumb = SwitchThumb;
187
- exports.switchRootEmits = switchRootEmits;
188
- exports.switchRootProps = switchRootProps;
189
- exports.switchThumbProps = switchThumbProps;
282
+ exports.anatomy = anatomy;
283
+ exports.connect = connect;
284
+ exports.machine = machine;
285
+ exports.props = props;
286
+ exports.splitProps = splitProps;