@destyler/dynamic 0.0.5 → 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.
@@ -1,608 +0,0 @@
1
- import { defineComponent, toRefs, ref, h, mergeProps, onMounted, withDirectives, withKeys, nextTick, computed } from 'vue';
2
- import { primitiveProps, Primitive } from '@destyler/primitive';
3
- import { useDirection, useVModel, useForwardExpose, useFormControl, useArrowNavigation, useId } from '@destyler/composition';
4
- import { createContext } from '@destyler/shared';
5
- import { useFocusWithin } from '@vueuse/core';
6
- import { CollectionSlot, CollectionItem } from '@destyler/collection';
7
- import { createCollection } from '@destyler/collection/composition';
8
- import { VisuallyHiddenInput } from '@destyler/visually-hidden/component';
9
- import { BindOnceDirective } from '@destyler/directives';
10
-
11
- const dynamicRootProps = {
12
- ...primitiveProps,
13
- /**
14
- * The controlled value of the tags input. Can be bind as `v-model`.
15
- *
16
- * @default () => []
17
- */
18
- modelValue: {
19
- type: Array,
20
- required: false,
21
- default: () => []
22
- },
23
- /**
24
- * The value of the tags that should be added.
25
- * Use when you do not need to control the state of the tags input
26
- */
27
- defaultValue: {
28
- type: Array,
29
- required: false
30
- },
31
- /**
32
- * When `true`, allow adding tags on paste.
33
- * Work in conjunction with delimiter prop.
34
- *
35
- * @default false
36
- */
37
- addOnPaste: {
38
- type: Boolean,
39
- required: false,
40
- default: false
41
- },
42
- /**
43
- * When `true` allow adding tags on tab keydown
44
- *
45
- * @default false
46
- */
47
- addOnTab: {
48
- type: Boolean,
49
- required: false,
50
- default: false
51
- },
52
- /**
53
- * When `true` allow adding tags blur input
54
- *
55
- * @default false
56
- */
57
- addOnBlur: {
58
- type: Boolean,
59
- required: false,
60
- default: false
61
- },
62
- /**
63
- * When `true`, allow duplicated tags.
64
- *
65
- * @default false
66
- */
67
- duplicate: {
68
- type: Boolean,
69
- required: false,
70
- default: false
71
- },
72
- /**
73
- * When `true`, prevents the user from interacting with the tags input.
74
- *
75
- * @default false
76
- */
77
- disabled: {
78
- type: Boolean,
79
- required: false,
80
- default: false
81
- },
82
- /**
83
- * The character to trigger the addition of a new tag.
84
- * Also used to split tags for `@paste` event
85
- *
86
- * @default ,
87
- */
88
- delimiter: {
89
- type: String,
90
- required: false,
91
- default: ","
92
- },
93
- /**
94
- s* The reading direction of the combobox when applicable.
95
- */
96
- dir: {
97
- type: String,
98
- required: false
99
- },
100
- /**
101
- * Maximum number of tags.
102
- *
103
- * @default 0
104
- */
105
- max: {
106
- type: Number,
107
- required: false,
108
- default: 0
109
- },
110
- /**
111
- * When `true`, indicates that the user must add the
112
- * tags input before the owning form can be submitted.
113
- *
114
- * @default false
115
- */
116
- required: {
117
- type: Boolean,
118
- required: false,
119
- default: false
120
- },
121
- /**
122
- * The name of the tags input submitted with its
123
- * owning form as part of a name/value pair.
124
- */
125
- name: {
126
- type: String,
127
- required: false
128
- },
129
- /**
130
- * The unique identifier of the machine.
131
- */
132
- id: {
133
- type: String,
134
- required: false
135
- }
136
- };
137
- const dynamicRootEmits = {
138
- /**
139
- * Event handler called when the value is invalid
140
- */
141
- "invalid": (_payload) => true,
142
- /**
143
- * Event handler called when the value changes
144
- */
145
- "update:modelValue": (_value) => true
146
- };
147
- const [injectDynamicRootContext, provideDynamicRootContext] = createContext("DestylerDynamicRoot");
148
- const DynamicRoot = defineComponent({
149
- name: "DestylerDynamicRoot",
150
- props: dynamicRootProps,
151
- emits: dynamicRootEmits,
152
- slots: Object,
153
- setup(props, { emit }) {
154
- const { addOnPaste, disabled, delimiter, max, id, dir: propDir, addOnBlur, addOnTab } = toRefs(props);
155
- const dir = useDirection(propDir);
156
- const modelValue = useVModel(props, "modelValue", emit, {
157
- defaultValue: props.defaultValue,
158
- passive: true,
159
- deep: true
160
- });
161
- const { forwardRef, currentElement } = useForwardExpose();
162
- const { focused } = useFocusWithin(currentElement);
163
- const isFormControl = useFormControl(currentElement);
164
- const { getItems } = createCollection();
165
- const selectedElement = ref();
166
- const isInvalidInput = ref(false);
167
- provideDynamicRootContext({
168
- modelValue,
169
- onAddValue: (payload) => {
170
- if (modelValue.value.length >= max.value && !!max.value) {
171
- emit("invalid", payload);
172
- return false;
173
- }
174
- if (props.duplicate) {
175
- modelValue.value.push(payload);
176
- return true;
177
- } else {
178
- const exist = modelValue.value.includes(payload);
179
- if (!exist) {
180
- modelValue.value.push(payload);
181
- return true;
182
- } else {
183
- isInvalidInput.value = true;
184
- }
185
- }
186
- emit("invalid", payload);
187
- return false;
188
- },
189
- onRemoveValue: (index) => {
190
- if (index !== -1)
191
- modelValue.value.splice(index, 1);
192
- },
193
- onInputKeydown: (event) => {
194
- const target = event.target;
195
- const collection = getItems().map((i) => i.ref).filter((i) => i.dataset.disabled !== "");
196
- if (!collection.length)
197
- return;
198
- const lastTag = collection.at(-1);
199
- switch (event.key) {
200
- case "Delete":
201
- case "Backspace": {
202
- if (target.selectionStart !== 0 || target.selectionEnd !== 0)
203
- break;
204
- if (selectedElement.value) {
205
- const index = collection.findIndex((i) => i === selectedElement.value);
206
- modelValue.value.splice(index, 1);
207
- selectedElement.value = selectedElement.value === lastTag ? collection.at(index - 1) : collection.at(index + 1);
208
- event.preventDefault();
209
- } else if (event.key === "Backspace") {
210
- selectedElement.value = lastTag;
211
- event.preventDefault();
212
- }
213
- break;
214
- }
215
- case "Home":
216
- case "End":
217
- case "ArrowRight":
218
- case "ArrowLeft": {
219
- const isArrowRight = event.key === "ArrowRight" && dir.value === "ltr" || event.key === "ArrowLeft" && dir.value === "rtl";
220
- const isArrowLeft = !isArrowRight;
221
- if (target.selectionStart !== 0 || target.selectionEnd !== 0)
222
- break;
223
- if (isArrowLeft && !selectedElement.value) {
224
- selectedElement.value = lastTag;
225
- event.preventDefault();
226
- } else if (isArrowRight && lastTag && selectedElement.value === lastTag) {
227
- selectedElement.value = void 0;
228
- event.preventDefault();
229
- } else if (selectedElement.value) {
230
- const el = useArrowNavigation(event, selectedElement.value, void 0, {
231
- itemsArray: collection,
232
- loop: false,
233
- dir: dir.value
234
- });
235
- if (el)
236
- selectedElement.value = el;
237
- event.preventDefault();
238
- }
239
- break;
240
- }
241
- case "ArrowUp":
242
- case "ArrowDown": {
243
- if (selectedElement.value)
244
- event.preventDefault();
245
- break;
246
- }
247
- default: {
248
- selectedElement.value = void 0;
249
- }
250
- }
251
- },
252
- selectedElement,
253
- isInvalidInput,
254
- addOnPaste,
255
- addOnBlur,
256
- addOnTab,
257
- dir,
258
- disabled,
259
- delimiter,
260
- max,
261
- id
262
- });
263
- return {
264
- forwardRef,
265
- dir,
266
- isInvalidInput,
267
- disabled,
268
- focused,
269
- modelValue,
270
- isFormControl
271
- };
272
- },
273
- render() {
274
- return h(CollectionSlot, {}, () => h(Primitive, {
275
- "ref": (el) => this.forwardRef(el),
276
- "dir": this.dir,
277
- "as": this.$props.as,
278
- "asChild": this.$props.asChild,
279
- "data-invalid": this.isInvalidInput ? "" : void 0,
280
- "data-disabled": this.disabled ? "" : void 0,
281
- "data-focused": this.focused ? "" : void 0
282
- }, () => [
283
- this.$slots.default?.({ modelValue: this.modelValue }),
284
- this.isFormControl && this.$props.name ? h(VisuallyHiddenInput, {
285
- name: this.$props.name,
286
- value: this.modelValue,
287
- required: this.required,
288
- disabled: this.disabled
289
- }) : null
290
- ]));
291
- }
292
- });
293
-
294
- const dynamicClearProps = {
295
- ...primitiveProps,
296
- /**
297
- * @default button
298
- */
299
- as: {
300
- ...primitiveProps.as,
301
- default: "button"
302
- }
303
- };
304
- const DynamicClear = defineComponent({
305
- name: "DestylerDynamicClear",
306
- props: dynamicClearProps,
307
- setup() {
308
- useForwardExpose();
309
- const context = injectDynamicRootContext();
310
- function handleCancel() {
311
- if (context.disabled.value)
312
- return;
313
- context.modelValue.value = [];
314
- }
315
- return {
316
- context,
317
- handleCancel
318
- };
319
- },
320
- render() {
321
- return h(Primitive, mergeProps(this.$props, {
322
- "type": this.$props.as === "button" ? "button" : void 0,
323
- "data-disabled": this.context.disabled.value ? "" : void 0,
324
- "onClick": () => {
325
- this.handleCancel();
326
- }
327
- }), () => this.$slots.default?.());
328
- }
329
- });
330
-
331
- const dynamicInputProps = {
332
- ...primitiveProps,
333
- /**
334
- * @default input
335
- */
336
- as: {
337
- ...primitiveProps.as,
338
- default: "input"
339
- },
340
- /**
341
- * The placeholder character to use for empty tags input.
342
- */
343
- placeholder: {
344
- type: String,
345
- required: false
346
- },
347
- /**
348
- * Focus on element when mounted.
349
- */
350
- autoFocus: {
351
- type: Boolean,
352
- required: false
353
- },
354
- /**
355
- * Maximum number of character allowed.
356
- */
357
- maxLength: {
358
- type: Number,
359
- required: false
360
- }
361
- };
362
- const DynamicInput = defineComponent({
363
- name: "DestylerDynamicInput",
364
- props: dynamicInputProps,
365
- setup(props) {
366
- const context = injectDynamicRootContext();
367
- const { forwardRef, currentElement } = useForwardExpose();
368
- function handleBlur(event) {
369
- if (!context.addOnBlur.value)
370
- return;
371
- const target = event.target;
372
- if (!target.value)
373
- return;
374
- const isAdded = context.onAddValue(target.value);
375
- if (isAdded)
376
- target.value = "";
377
- }
378
- function handleTab(event) {
379
- if (!context.addOnTab.value)
380
- return;
381
- handleCustomKeydown(event);
382
- }
383
- async function handleCustomKeydown(event) {
384
- await nextTick();
385
- if (event.defaultPrevented)
386
- return;
387
- const target = event.target;
388
- if (!target.value)
389
- return;
390
- const isAdded = context.onAddValue(target.value);
391
- if (isAdded)
392
- target.value = "";
393
- event.preventDefault();
394
- }
395
- function handleInput(event) {
396
- context.isInvalidInput.value = false;
397
- const delimiter = context.delimiter.value;
398
- if (delimiter === event.data) {
399
- const target = event.target;
400
- target.value = target.value.replaceAll(delimiter, "");
401
- const isAdded = context.onAddValue(target.value);
402
- if (isAdded)
403
- target.value = "";
404
- }
405
- }
406
- function handlePaste(event) {
407
- if (context.addOnPaste.value) {
408
- event.preventDefault();
409
- const clipboardData = event.clipboardData;
410
- if (!clipboardData)
411
- return;
412
- const value = clipboardData.getData("text");
413
- if (context.delimiter.value) {
414
- const splittedValue = value.split(context.delimiter.value);
415
- splittedValue.forEach((v) => {
416
- context.onAddValue(v);
417
- });
418
- } else {
419
- context.onAddValue(value);
420
- }
421
- }
422
- }
423
- onMounted(() => {
424
- const inputEl = currentElement.value.nodeName === "INPUT" ? currentElement.value : currentElement.value.querySelector("input");
425
- if (!inputEl)
426
- return;
427
- setTimeout(() => {
428
- if (props.autoFocus)
429
- inputEl?.focus();
430
- }, 1);
431
- });
432
- return {
433
- forwardRef,
434
- context,
435
- handleInput,
436
- handlePaste,
437
- handleCustomKeydown,
438
- handleBlur,
439
- handleTab
440
- };
441
- },
442
- render() {
443
- return withDirectives(h(Primitive, {
444
- "ref": (el) => this.forwardRef(el),
445
- "type": "text",
446
- "autocomplete": "off",
447
- "autocorrect": "off",
448
- "autocapitalize": "off",
449
- "as": this.$props.as,
450
- "asChild": this.$props.asChild,
451
- "maxlength": this.$props.maxLength,
452
- "placeholder": this.$props.placeholder,
453
- "disabled": this.context.disabled.value,
454
- "data-invalid": this.context.isInvalidInput.value ? "" : void 0,
455
- "onInput": (event) => {
456
- this.handleInput(event);
457
- },
458
- "onKeydown": [
459
- withKeys(this.handleCustomKeydown, ["enter"]),
460
- withKeys(this.handleTab, ["tab"]),
461
- this.context.onInputKeydown
462
- ],
463
- "onBlur": (event) => {
464
- this.handleBlur(event);
465
- },
466
- "onPaste": (event) => {
467
- this.handlePaste(event);
468
- }
469
- }, () => this.$slots.default?.()), [
470
- [BindOnceDirective, { id: this.context.id?.value }]
471
- ]);
472
- }
473
- });
474
-
475
- const dynamicItemProps = {
476
- ...primitiveProps,
477
- /**
478
- * Value associated with the tags
479
- */
480
- value: {
481
- type: String,
482
- required: true
483
- },
484
- /**
485
- * When `true`, prevents the user from interacting with the tags input.
486
- */
487
- disabled: {
488
- type: Boolean,
489
- required: false
490
- }
491
- };
492
- const [injectDynamicItemContext, provideDynamicItemContext] = createContext("DestylerDynamicItem");
493
- const DynamicItem = defineComponent({
494
- name: "DestylerDynamicItem",
495
- props: dynamicItemProps,
496
- setup(props) {
497
- const { value } = toRefs(props);
498
- const context = injectDynamicRootContext();
499
- const { forwardRef, currentElement } = useForwardExpose();
500
- const isSelected = computed(() => context.selectedElement.value === currentElement.value);
501
- const textId = useId();
502
- const disabled = computed(() => props.disabled || context.disabled.value);
503
- provideDynamicItemContext({
504
- value,
505
- isSelected,
506
- disabled,
507
- textId
508
- });
509
- return {
510
- forwardRef,
511
- textId,
512
- isSelected,
513
- disabled
514
- };
515
- },
516
- render() {
517
- return h(CollectionItem, {}, () => h(Primitive, {
518
- "ref": this.forwardRef,
519
- "as": this.$props.as,
520
- "asChild": this.$props.asChild,
521
- "aria-labelledby": this.textId,
522
- "aria-current": this.isSelected,
523
- "data-disabled": this.disabled ? "" : void 0,
524
- "data-state": this.isSelected ? "active" : "inactive"
525
- }, () => this.$slots.default?.()));
526
- }
527
- });
528
-
529
- const dynamicItemDeleteProps = {
530
- ...primitiveProps,
531
- /**
532
- * @default button
533
- */
534
- as: {
535
- ...primitiveProps.as,
536
- default: "button"
537
- }
538
- };
539
- const DynamicItemDelete = defineComponent({
540
- name: "DestylerDynamicItemDelete",
541
- props: dynamicItemDeleteProps,
542
- setup() {
543
- useForwardExpose();
544
- const context = injectDynamicRootContext();
545
- const itemContext = injectDynamicItemContext();
546
- const disabled = computed(() => itemContext.disabled?.value || context.disabled.value);
547
- function handleDelete() {
548
- if (disabled.value)
549
- return;
550
- const index = context.modelValue.value.findIndex((i) => i === itemContext.value.value);
551
- context.onRemoveValue(index);
552
- }
553
- return {
554
- context,
555
- itemContext,
556
- disabled,
557
- handleDelete
558
- };
559
- },
560
- render() {
561
- return h(Primitive, mergeProps(this.$props, {
562
- "tabindex": "-1",
563
- "aria-labelledby": this.itemContext.textId,
564
- "aria-current": this.itemContext.isSelected.value,
565
- "data-state": this.itemContext.isSelected.value ? "active" : "inactive",
566
- "data-disabled": this.disabled ? "" : void 0,
567
- "type": this.$props.as === "button" ? "button" : void 0,
568
- "onClick": () => {
569
- this.handleDelete();
570
- }
571
- }), () => this.$slots.default?.());
572
- }
573
- });
574
-
575
- const dynamicItemTextProps = {
576
- ...primitiveProps,
577
- /**
578
- * @default span
579
- */
580
- as: {
581
- ...primitiveProps.as,
582
- default: "span"
583
- }
584
- };
585
- const DynamicItemText = defineComponent({
586
- name: "DestylerDynamicItemText",
587
- props: dynamicItemTextProps,
588
- slots: Object,
589
- setup() {
590
- const itemContext = injectDynamicItemContext();
591
- useForwardExpose();
592
- itemContext.textId || (itemContext.textId = useId(void 0, "destyler-tags-input-item-text"));
593
- return {
594
- itemContext
595
- };
596
- },
597
- render() {
598
- return withDirectives(h(
599
- Primitive,
600
- this.$props,
601
- () => this.$slots.default ? this.$slots.default?.({ text: this.itemContext.value.value }) : this.itemContext.value.value
602
- ), [
603
- [BindOnceDirective, { id: this.itemContext.textId }]
604
- ]);
605
- }
606
- });
607
-
608
- export { DynamicClear, DynamicInput, DynamicItem, DynamicItemDelete, DynamicItemText, DynamicRoot, dynamicClearProps, dynamicInputProps, dynamicItemDeleteProps, dynamicItemProps, dynamicItemTextProps, dynamicRootEmits, dynamicRootProps };
package/dist/resolver.cjs DELETED
@@ -1,25 +0,0 @@
1
- 'use strict';
2
-
3
- const name = "@destyler/dynamic";
4
-
5
- const packageName = name;
6
- const dynamicComponentName = [
7
- "DynamicClear",
8
- "DynamicInput",
9
- "DynamicItem",
10
- "DynamicItemDelete",
11
- "DynamicItemText",
12
- "DynamicRoot"
13
- ];
14
- function DynamicResolver() {
15
- return {
16
- type: "component",
17
- resolve: (name2) => {
18
- if (dynamicComponentName.includes(name2))
19
- return { name: name2, from: packageName };
20
- }
21
- };
22
- }
23
-
24
- exports.DynamicResolver = DynamicResolver;
25
- exports.dynamicComponentName = dynamicComponentName;
@@ -1,6 +0,0 @@
1
- import { ComponentResolver } from 'unplugin-vue-components';
2
-
3
- declare const dynamicComponentName: string[];
4
- declare function DynamicResolver(): ComponentResolver;
5
-
6
- export { DynamicResolver, dynamicComponentName };
@@ -1,6 +0,0 @@
1
- import { ComponentResolver } from 'unplugin-vue-components';
2
-
3
- declare const dynamicComponentName: string[];
4
- declare function DynamicResolver(): ComponentResolver;
5
-
6
- export { DynamicResolver, dynamicComponentName };
@@ -1,6 +0,0 @@
1
- import { ComponentResolver } from 'unplugin-vue-components';
2
-
3
- declare const dynamicComponentName: string[];
4
- declare function DynamicResolver(): ComponentResolver;
5
-
6
- export { DynamicResolver, dynamicComponentName };
package/dist/resolver.mjs DELETED
@@ -1,22 +0,0 @@
1
- const name = "@destyler/dynamic";
2
-
3
- const packageName = name;
4
- const dynamicComponentName = [
5
- "DynamicClear",
6
- "DynamicInput",
7
- "DynamicItem",
8
- "DynamicItemDelete",
9
- "DynamicItemText",
10
- "DynamicRoot"
11
- ];
12
- function DynamicResolver() {
13
- return {
14
- type: "component",
15
- resolve: (name2) => {
16
- if (dynamicComponentName.includes(name2))
17
- return { name: name2, from: packageName };
18
- }
19
- };
20
- }
21
-
22
- export { DynamicResolver, dynamicComponentName };