@diceui/tags-input 0.1.1 → 0.3.0
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 +30 -7
- package/dist/index.d.cts +13 -3
- package/dist/index.d.ts +13 -3
- package/dist/index.js +31 -8
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
43
43
|
blurBehavior,
|
|
44
44
|
delimiter = ",",
|
|
45
45
|
max = Number.POSITIVE_INFINITY,
|
|
46
|
+
readOnly = false,
|
|
46
47
|
required = false,
|
|
47
48
|
name,
|
|
48
49
|
children,
|
|
@@ -66,7 +67,7 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
66
67
|
const inputId = shared.useId();
|
|
67
68
|
const labelId = shared.useId();
|
|
68
69
|
const dir = shared.useDirection(dirProp);
|
|
69
|
-
const { getEnabledItems } = shared.
|
|
70
|
+
const { getEnabledItems } = shared.useItemCollection({
|
|
70
71
|
ref: collectionRef
|
|
71
72
|
});
|
|
72
73
|
const { isFormControl, onTriggerChange } = shared.useFormControl();
|
|
@@ -77,6 +78,7 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
77
78
|
);
|
|
78
79
|
const onItemAdd = React__namespace.useCallback(
|
|
79
80
|
(textValue, options) => {
|
|
81
|
+
if (disabled || readOnly) return false;
|
|
80
82
|
if (addOnPaste && options?.viaPaste) {
|
|
81
83
|
const splitValues = textValue.split(delimiter).map((v) => v.trim()).filter(Boolean);
|
|
82
84
|
if (value.length + splitValues.length > max && max > 0) {
|
|
@@ -124,10 +126,21 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
124
126
|
setIsInvalidInput(false);
|
|
125
127
|
return true;
|
|
126
128
|
},
|
|
127
|
-
[
|
|
129
|
+
[
|
|
130
|
+
value,
|
|
131
|
+
max,
|
|
132
|
+
addOnPaste,
|
|
133
|
+
delimiter,
|
|
134
|
+
setValue,
|
|
135
|
+
onInvalid,
|
|
136
|
+
onValidate,
|
|
137
|
+
disabled,
|
|
138
|
+
readOnly
|
|
139
|
+
]
|
|
128
140
|
);
|
|
129
141
|
const onItemUpdate = React__namespace.useCallback(
|
|
130
142
|
(index, newTextValue) => {
|
|
143
|
+
if (disabled || readOnly) return;
|
|
131
144
|
if (index !== -1) {
|
|
132
145
|
const trimmedValue = newTextValue.trim();
|
|
133
146
|
const exists = value.some((v, i) => {
|
|
@@ -155,10 +168,11 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
155
168
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
156
169
|
}
|
|
157
170
|
},
|
|
158
|
-
[value, setValue, displayValue, onInvalid, onValidate]
|
|
171
|
+
[value, setValue, displayValue, onInvalid, onValidate, disabled, readOnly]
|
|
159
172
|
);
|
|
160
173
|
const onItemRemove = React__namespace.useCallback(
|
|
161
174
|
(index) => {
|
|
175
|
+
if (disabled || readOnly) return;
|
|
162
176
|
if (index !== -1) {
|
|
163
177
|
const newValues = [...value];
|
|
164
178
|
newValues.splice(index, 1);
|
|
@@ -168,7 +182,7 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
168
182
|
inputRef.current?.focus();
|
|
169
183
|
}
|
|
170
184
|
},
|
|
171
|
-
[value, setValue]
|
|
185
|
+
[value, setValue, disabled, readOnly]
|
|
172
186
|
);
|
|
173
187
|
const onItemLeave = React__namespace.useCallback(() => {
|
|
174
188
|
setHighlightedIndex(null);
|
|
@@ -306,6 +320,7 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
306
320
|
disabled,
|
|
307
321
|
editable,
|
|
308
322
|
loop,
|
|
323
|
+
readOnly,
|
|
309
324
|
blurBehavior,
|
|
310
325
|
delimiter,
|
|
311
326
|
max,
|
|
@@ -318,8 +333,9 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
318
333
|
shared.Primitive.div,
|
|
319
334
|
{
|
|
320
335
|
id,
|
|
321
|
-
"data-invalid": isInvalidInput ? "" : void 0,
|
|
322
336
|
"data-disabled": disabled ? "" : void 0,
|
|
337
|
+
"data-invalid": isInvalidInput ? "" : void 0,
|
|
338
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
323
339
|
dir,
|
|
324
340
|
...rootProps,
|
|
325
341
|
ref: composedRef,
|
|
@@ -352,8 +368,8 @@ var TagsInputRoot = React__namespace.forwardRef((props, ref) => {
|
|
|
352
368
|
control: collectionRef.current,
|
|
353
369
|
name,
|
|
354
370
|
value,
|
|
355
|
-
|
|
356
|
-
|
|
371
|
+
disabled,
|
|
372
|
+
required
|
|
357
373
|
}
|
|
358
374
|
)
|
|
359
375
|
)
|
|
@@ -511,11 +527,15 @@ var TagsInputInput = React__namespace.forwardRef(
|
|
|
511
527
|
spellCheck: "false",
|
|
512
528
|
autoFocus,
|
|
513
529
|
"aria-labelledby": context.labelId,
|
|
530
|
+
"aria-readonly": context.readOnly,
|
|
514
531
|
"data-invalid": context.isInvalidInput ? "" : void 0,
|
|
532
|
+
dir: context.dir,
|
|
515
533
|
disabled: context.disabled,
|
|
534
|
+
readOnly: context.readOnly,
|
|
516
535
|
...inputProps,
|
|
517
536
|
ref: shared.composeRefs(context.inputRef, ref),
|
|
518
537
|
onBlur: shared.composeEventHandlers(inputProps.onBlur, (event) => {
|
|
538
|
+
if (context.readOnly) return;
|
|
519
539
|
if (context.blurBehavior === "add") {
|
|
520
540
|
const value = event.target.value;
|
|
521
541
|
if (value) {
|
|
@@ -528,6 +548,7 @@ var TagsInputInput = React__namespace.forwardRef(
|
|
|
528
548
|
}
|
|
529
549
|
}),
|
|
530
550
|
onChange: shared.composeEventHandlers(inputProps.onChange, (event) => {
|
|
551
|
+
if (context.readOnly) return;
|
|
531
552
|
const target = event.target;
|
|
532
553
|
if (!(target instanceof HTMLInputElement)) return;
|
|
533
554
|
const delimiter = context.delimiter;
|
|
@@ -541,12 +562,14 @@ var TagsInputInput = React__namespace.forwardRef(
|
|
|
541
562
|
}
|
|
542
563
|
}),
|
|
543
564
|
onKeyDown: shared.composeEventHandlers(inputProps.onKeyDown, (event) => {
|
|
565
|
+
if (context.readOnly) return;
|
|
544
566
|
if (event.key === "Enter") onCustomKeydown(event);
|
|
545
567
|
if (event.key === "Tab") onTab(event);
|
|
546
568
|
context.onInputKeydown(event);
|
|
547
569
|
if (event.key.length === 1) context.setHighlightedIndex(null);
|
|
548
570
|
}),
|
|
549
571
|
onPaste: shared.composeEventHandlers(inputProps.onPaste, (event) => {
|
|
572
|
+
if (context.readOnly) return;
|
|
550
573
|
if (context.addOnPaste) {
|
|
551
574
|
event.preventDefault();
|
|
552
575
|
const value = event.clipboardData.getData("text");
|
package/dist/index.d.cts
CHANGED
|
@@ -63,10 +63,16 @@ interface TagsInputRootProps<T = InputValue> extends Omit<React.ComponentPropsWi
|
|
|
63
63
|
* @default Number.POSITIVE_INFINITY
|
|
64
64
|
*/
|
|
65
65
|
max?: number;
|
|
66
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* Whether the field is required in a form context.
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
67
70
|
required?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Whether the tags input is read-only.
|
|
73
|
+
* @default false
|
|
74
|
+
*/
|
|
75
|
+
readOnly?: boolean;
|
|
70
76
|
/**
|
|
71
77
|
* The content of the tags input.
|
|
72
78
|
*
|
|
@@ -82,6 +88,8 @@ interface TagsInputRootProps<T = InputValue> extends Omit<React.ComponentPropsWi
|
|
|
82
88
|
* @default "ltr"
|
|
83
89
|
*/
|
|
84
90
|
dir?: Direction;
|
|
91
|
+
/** Name of the form field when used in a form. */
|
|
92
|
+
name?: string;
|
|
85
93
|
/** Unique identifier for the tags input. */
|
|
86
94
|
id?: string;
|
|
87
95
|
}
|
|
@@ -94,7 +102,9 @@ declare const TagsInputLabel: React.ForwardRefExoticComponent<TagsInputLabelProp
|
|
|
94
102
|
declare const Label: React.ForwardRefExoticComponent<TagsInputLabelProps & React.RefAttributes<HTMLLabelElement>>;
|
|
95
103
|
|
|
96
104
|
interface TagsInputItemProps extends React.ComponentPropsWithoutRef<typeof Primitive.div> {
|
|
105
|
+
/** The value of the item. */
|
|
97
106
|
value: InputValue;
|
|
107
|
+
/** Whether the item is disabled. */
|
|
98
108
|
disabled?: boolean;
|
|
99
109
|
}
|
|
100
110
|
declare const TagsInputItem: React.ForwardRefExoticComponent<TagsInputItemProps & React.RefAttributes<HTMLDivElement>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -63,10 +63,16 @@ interface TagsInputRootProps<T = InputValue> extends Omit<React.ComponentPropsWi
|
|
|
63
63
|
* @default Number.POSITIVE_INFINITY
|
|
64
64
|
*/
|
|
65
65
|
max?: number;
|
|
66
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* Whether the field is required in a form context.
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
67
70
|
required?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Whether the tags input is read-only.
|
|
73
|
+
* @default false
|
|
74
|
+
*/
|
|
75
|
+
readOnly?: boolean;
|
|
70
76
|
/**
|
|
71
77
|
* The content of the tags input.
|
|
72
78
|
*
|
|
@@ -82,6 +88,8 @@ interface TagsInputRootProps<T = InputValue> extends Omit<React.ComponentPropsWi
|
|
|
82
88
|
* @default "ltr"
|
|
83
89
|
*/
|
|
84
90
|
dir?: Direction;
|
|
91
|
+
/** Name of the form field when used in a form. */
|
|
92
|
+
name?: string;
|
|
85
93
|
/** Unique identifier for the tags input. */
|
|
86
94
|
id?: string;
|
|
87
95
|
}
|
|
@@ -94,7 +102,9 @@ declare const TagsInputLabel: React.ForwardRefExoticComponent<TagsInputLabelProp
|
|
|
94
102
|
declare const Label: React.ForwardRefExoticComponent<TagsInputLabelProps & React.RefAttributes<HTMLLabelElement>>;
|
|
95
103
|
|
|
96
104
|
interface TagsInputItemProps extends React.ComponentPropsWithoutRef<typeof Primitive.div> {
|
|
105
|
+
/** The value of the item. */
|
|
97
106
|
value: InputValue;
|
|
107
|
+
/** Whether the item is disabled. */
|
|
98
108
|
disabled?: boolean;
|
|
99
109
|
}
|
|
100
110
|
declare const TagsInputItem: React.ForwardRefExoticComponent<TagsInputItemProps & React.RefAttributes<HTMLDivElement>>;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { createContext, useControllableState, useId, useDirection,
|
|
4
|
+
import { createContext, useControllableState, useId, useDirection, useItemCollection, useFormControl, useComposedRefs, DATA_ITEM_ATTR, Primitive, composeEventHandlers, BubbleInput, composeRefs, Presence } from '@diceui/shared';
|
|
5
5
|
|
|
6
6
|
var ROOT_NAME = "TagsInputRoot";
|
|
7
7
|
var [TagsInputProvider, useTagsInput] = createContext(ROOT_NAME);
|
|
@@ -21,6 +21,7 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
21
21
|
blurBehavior,
|
|
22
22
|
delimiter = ",",
|
|
23
23
|
max = Number.POSITIVE_INFINITY,
|
|
24
|
+
readOnly = false,
|
|
24
25
|
required = false,
|
|
25
26
|
name,
|
|
26
27
|
children,
|
|
@@ -44,7 +45,7 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
44
45
|
const inputId = useId();
|
|
45
46
|
const labelId = useId();
|
|
46
47
|
const dir = useDirection(dirProp);
|
|
47
|
-
const { getEnabledItems } =
|
|
48
|
+
const { getEnabledItems } = useItemCollection({
|
|
48
49
|
ref: collectionRef
|
|
49
50
|
});
|
|
50
51
|
const { isFormControl, onTriggerChange } = useFormControl();
|
|
@@ -55,6 +56,7 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
55
56
|
);
|
|
56
57
|
const onItemAdd = React.useCallback(
|
|
57
58
|
(textValue, options) => {
|
|
59
|
+
if (disabled || readOnly) return false;
|
|
58
60
|
if (addOnPaste && options?.viaPaste) {
|
|
59
61
|
const splitValues = textValue.split(delimiter).map((v) => v.trim()).filter(Boolean);
|
|
60
62
|
if (value.length + splitValues.length > max && max > 0) {
|
|
@@ -102,10 +104,21 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
102
104
|
setIsInvalidInput(false);
|
|
103
105
|
return true;
|
|
104
106
|
},
|
|
105
|
-
[
|
|
107
|
+
[
|
|
108
|
+
value,
|
|
109
|
+
max,
|
|
110
|
+
addOnPaste,
|
|
111
|
+
delimiter,
|
|
112
|
+
setValue,
|
|
113
|
+
onInvalid,
|
|
114
|
+
onValidate,
|
|
115
|
+
disabled,
|
|
116
|
+
readOnly
|
|
117
|
+
]
|
|
106
118
|
);
|
|
107
119
|
const onItemUpdate = React.useCallback(
|
|
108
120
|
(index, newTextValue) => {
|
|
121
|
+
if (disabled || readOnly) return;
|
|
109
122
|
if (index !== -1) {
|
|
110
123
|
const trimmedValue = newTextValue.trim();
|
|
111
124
|
const exists = value.some((v, i) => {
|
|
@@ -133,10 +146,11 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
133
146
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
134
147
|
}
|
|
135
148
|
},
|
|
136
|
-
[value, setValue, displayValue, onInvalid, onValidate]
|
|
149
|
+
[value, setValue, displayValue, onInvalid, onValidate, disabled, readOnly]
|
|
137
150
|
);
|
|
138
151
|
const onItemRemove = React.useCallback(
|
|
139
152
|
(index) => {
|
|
153
|
+
if (disabled || readOnly) return;
|
|
140
154
|
if (index !== -1) {
|
|
141
155
|
const newValues = [...value];
|
|
142
156
|
newValues.splice(index, 1);
|
|
@@ -146,7 +160,7 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
146
160
|
inputRef.current?.focus();
|
|
147
161
|
}
|
|
148
162
|
},
|
|
149
|
-
[value, setValue]
|
|
163
|
+
[value, setValue, disabled, readOnly]
|
|
150
164
|
);
|
|
151
165
|
const onItemLeave = React.useCallback(() => {
|
|
152
166
|
setHighlightedIndex(null);
|
|
@@ -284,6 +298,7 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
284
298
|
disabled,
|
|
285
299
|
editable,
|
|
286
300
|
loop,
|
|
301
|
+
readOnly,
|
|
287
302
|
blurBehavior,
|
|
288
303
|
delimiter,
|
|
289
304
|
max,
|
|
@@ -296,8 +311,9 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
296
311
|
Primitive.div,
|
|
297
312
|
{
|
|
298
313
|
id,
|
|
299
|
-
"data-invalid": isInvalidInput ? "" : void 0,
|
|
300
314
|
"data-disabled": disabled ? "" : void 0,
|
|
315
|
+
"data-invalid": isInvalidInput ? "" : void 0,
|
|
316
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
301
317
|
dir,
|
|
302
318
|
...rootProps,
|
|
303
319
|
ref: composedRef,
|
|
@@ -330,8 +346,8 @@ var TagsInputRoot = React.forwardRef((props, ref) => {
|
|
|
330
346
|
control: collectionRef.current,
|
|
331
347
|
name,
|
|
332
348
|
value,
|
|
333
|
-
|
|
334
|
-
|
|
349
|
+
disabled,
|
|
350
|
+
required
|
|
335
351
|
}
|
|
336
352
|
)
|
|
337
353
|
)
|
|
@@ -489,11 +505,15 @@ var TagsInputInput = React.forwardRef(
|
|
|
489
505
|
spellCheck: "false",
|
|
490
506
|
autoFocus,
|
|
491
507
|
"aria-labelledby": context.labelId,
|
|
508
|
+
"aria-readonly": context.readOnly,
|
|
492
509
|
"data-invalid": context.isInvalidInput ? "" : void 0,
|
|
510
|
+
dir: context.dir,
|
|
493
511
|
disabled: context.disabled,
|
|
512
|
+
readOnly: context.readOnly,
|
|
494
513
|
...inputProps,
|
|
495
514
|
ref: composeRefs(context.inputRef, ref),
|
|
496
515
|
onBlur: composeEventHandlers(inputProps.onBlur, (event) => {
|
|
516
|
+
if (context.readOnly) return;
|
|
497
517
|
if (context.blurBehavior === "add") {
|
|
498
518
|
const value = event.target.value;
|
|
499
519
|
if (value) {
|
|
@@ -506,6 +526,7 @@ var TagsInputInput = React.forwardRef(
|
|
|
506
526
|
}
|
|
507
527
|
}),
|
|
508
528
|
onChange: composeEventHandlers(inputProps.onChange, (event) => {
|
|
529
|
+
if (context.readOnly) return;
|
|
509
530
|
const target = event.target;
|
|
510
531
|
if (!(target instanceof HTMLInputElement)) return;
|
|
511
532
|
const delimiter = context.delimiter;
|
|
@@ -519,12 +540,14 @@ var TagsInputInput = React.forwardRef(
|
|
|
519
540
|
}
|
|
520
541
|
}),
|
|
521
542
|
onKeyDown: composeEventHandlers(inputProps.onKeyDown, (event) => {
|
|
543
|
+
if (context.readOnly) return;
|
|
522
544
|
if (event.key === "Enter") onCustomKeydown(event);
|
|
523
545
|
if (event.key === "Tab") onTab(event);
|
|
524
546
|
context.onInputKeydown(event);
|
|
525
547
|
if (event.key.length === 1) context.setHighlightedIndex(null);
|
|
526
548
|
}),
|
|
527
549
|
onPaste: composeEventHandlers(inputProps.onPaste, (event) => {
|
|
550
|
+
if (context.readOnly) return;
|
|
528
551
|
if (context.addOnPaste) {
|
|
529
552
|
event.preventDefault();
|
|
530
553
|
const value = event.clipboardData.getData("text");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diceui/tags-input",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"typescript": "^5.7.2"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@diceui/shared": "0.
|
|
55
|
+
"@diceui/shared": "0.7.0"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"dev": "tsup --watch",
|