@diceui/tags-input 0.0.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.js ADDED
@@ -0,0 +1,651 @@
1
+ 'use client';
2
+
3
+ import { Primitive } from '@radix-ui/react-primitive';
4
+ import * as React from 'react';
5
+ import { createContext, useControllableState, useId, useDirection, useCollection, useFormControl, useComposedRefs, DATA_ITEM_ATTR, composeEventHandlers, BubbleInput, composeRefs, Presence } from '@diceui/shared';
6
+
7
+ var ROOT_NAME = "TagsInputRoot";
8
+ var [TagsInputProvider, useTagsInput] = createContext(ROOT_NAME);
9
+ var TagsInputRoot = React.forwardRef((props, ref) => {
10
+ const {
11
+ value: valueProp,
12
+ defaultValue,
13
+ onValueChange,
14
+ onValidate,
15
+ onInvalid,
16
+ displayValue = (value2) => value2.toString(),
17
+ addOnPaste = false,
18
+ addOnTab = false,
19
+ disabled = false,
20
+ editable = false,
21
+ loop = false,
22
+ blurBehavior,
23
+ delimiter = ",",
24
+ max = Number.POSITIVE_INFINITY,
25
+ required = false,
26
+ name,
27
+ children,
28
+ dir: dirProp,
29
+ id: idProp,
30
+ ...rootProps
31
+ } = props;
32
+ const [value = [], setValue] = useControllableState({
33
+ prop: valueProp,
34
+ defaultProp: defaultValue,
35
+ onChange: onValueChange
36
+ });
37
+ const [highlightedValue, setHighlightedValue] = React.useState(null);
38
+ const [editingValue, setEditingValue] = React.useState(
39
+ null
40
+ );
41
+ const [isInvalidInput, setIsInvalidInput] = React.useState(false);
42
+ const collectionRef = React.useRef(null);
43
+ const inputRef = React.useRef(null);
44
+ const id = useId();
45
+ const inputId = useId();
46
+ const labelId = useId();
47
+ const dir = useDirection(dirProp);
48
+ const { getEnabledItems } = useCollection({
49
+ ref: collectionRef
50
+ });
51
+ const { isFormControl, onTriggerChange } = useFormControl();
52
+ const composedRef = useComposedRefs(
53
+ ref,
54
+ collectionRef,
55
+ (node) => onTriggerChange(node)
56
+ );
57
+ const onItemAdd = React.useCallback(
58
+ (textValue, options) => {
59
+ if (addOnPaste && options?.viaPaste) {
60
+ const splitValues = textValue.split(delimiter).map((v) => v.trim()).filter(Boolean);
61
+ if (value.length + splitValues.length > max && max > 0) {
62
+ onInvalid?.(textValue);
63
+ return false;
64
+ }
65
+ let newValues2 = [];
66
+ for (const v of splitValues) {
67
+ if (value.includes(v)) {
68
+ onInvalid?.(v);
69
+ }
70
+ }
71
+ newValues2 = [...new Set(splitValues.filter((v) => !value.includes(v)))];
72
+ const validValues = newValues2.filter(
73
+ (v) => !onValidate || onValidate(v)
74
+ );
75
+ if (validValues.length === 0) return false;
76
+ setValue([...value, ...validValues]);
77
+ return true;
78
+ }
79
+ if (value.length >= max && max > 0) {
80
+ onInvalid?.(textValue);
81
+ return false;
82
+ }
83
+ const trimmedValue = textValue.trim();
84
+ if (onValidate && !onValidate(trimmedValue)) {
85
+ setIsInvalidInput(true);
86
+ onInvalid?.(trimmedValue);
87
+ return false;
88
+ }
89
+ const exists = value.some((v) => {
90
+ const valueToCompare = v;
91
+ return valueToCompare === trimmedValue;
92
+ });
93
+ if (exists) {
94
+ setIsInvalidInput(true);
95
+ onInvalid?.(trimmedValue);
96
+ return true;
97
+ }
98
+ const newValue = trimmedValue;
99
+ const newValues = [...value, newValue];
100
+ setValue(newValues);
101
+ setHighlightedValue(null);
102
+ setEditingValue(null);
103
+ setIsInvalidInput(false);
104
+ return true;
105
+ },
106
+ [value, max, addOnPaste, delimiter, setValue, onInvalid, onValidate]
107
+ );
108
+ const onItemUpdate = React.useCallback(
109
+ (index, newTextValue) => {
110
+ if (index !== -1) {
111
+ const trimmedValue = newTextValue.trim();
112
+ const exists = value.some((v, i) => {
113
+ if (i === index) return false;
114
+ const valueToCompare = v;
115
+ return valueToCompare === trimmedValue;
116
+ });
117
+ if (exists) {
118
+ setIsInvalidInput(true);
119
+ onInvalid?.(trimmedValue);
120
+ return;
121
+ }
122
+ if (onValidate && !onValidate(trimmedValue)) {
123
+ setIsInvalidInput(true);
124
+ onInvalid?.(trimmedValue);
125
+ return;
126
+ }
127
+ const updatedValue = displayValue(trimmedValue);
128
+ const newValues = [...value];
129
+ newValues[index] = updatedValue;
130
+ setValue(newValues);
131
+ setHighlightedValue(updatedValue);
132
+ setEditingValue(null);
133
+ setIsInvalidInput(false);
134
+ requestAnimationFrame(() => inputRef.current?.focus());
135
+ }
136
+ },
137
+ [value, setValue, displayValue, onInvalid, onValidate]
138
+ );
139
+ const onItemRemove = React.useCallback(
140
+ (index) => {
141
+ if (index !== -1) {
142
+ const newValues = [...value];
143
+ newValues.splice(index, 1);
144
+ setValue(newValues);
145
+ setHighlightedValue(null);
146
+ setEditingValue(null);
147
+ inputRef.current?.focus();
148
+ }
149
+ },
150
+ [value, setValue]
151
+ );
152
+ const onItemLeave = React.useCallback(() => {
153
+ setHighlightedValue(null);
154
+ setEditingValue(null);
155
+ inputRef.current?.focus();
156
+ }, []);
157
+ const onInputKeydown = React.useCallback(
158
+ (event) => {
159
+ const target = event.target;
160
+ if (!(target instanceof HTMLInputElement)) return;
161
+ const isArrowLeft = event.key === "ArrowLeft" && dir === "ltr" || event.key === "ArrowRight" && dir === "rtl";
162
+ const isArrowRight = event.key === "ArrowRight" && dir === "ltr" || event.key === "ArrowLeft" && dir === "rtl";
163
+ if (target.value && target.selectionStart !== 0) {
164
+ setHighlightedValue(null);
165
+ setEditingValue(null);
166
+ return;
167
+ }
168
+ const findNextEnabledValue = (currentValue, direction) => {
169
+ const collectionElement = collectionRef.current;
170
+ if (!collectionElement) return null;
171
+ const enabledItems = getEnabledItems();
172
+ const enabledValues = enabledItems.map((_, index) => value[index]);
173
+ if (enabledValues.length === 0) return null;
174
+ if (currentValue === null) {
175
+ return direction === "prev" ? enabledValues[enabledValues.length - 1] ?? null : enabledValues[0] ?? null;
176
+ }
177
+ const currentIndex = enabledValues.indexOf(currentValue);
178
+ if (direction === "next") {
179
+ return currentIndex >= enabledValues.length - 1 ? loop ? enabledValues[0] ?? null : null : enabledValues[currentIndex + 1] ?? null;
180
+ }
181
+ return currentIndex <= 0 ? loop ? enabledValues[enabledValues.length - 1] ?? null : null : enabledValues[currentIndex - 1] ?? null;
182
+ };
183
+ switch (event.key) {
184
+ case "Delete":
185
+ case "Backspace": {
186
+ if (target.selectionStart !== 0 || target.selectionEnd !== 0) break;
187
+ if (highlightedValue !== null) {
188
+ const index = value.indexOf(highlightedValue);
189
+ const newValue = findNextEnabledValue(highlightedValue, "prev");
190
+ onItemRemove(index);
191
+ setHighlightedValue(newValue);
192
+ event.preventDefault();
193
+ } else if (event.key === "Backspace" && value.length > 0) {
194
+ const lastValue = findNextEnabledValue(null, "prev");
195
+ setHighlightedValue(lastValue);
196
+ event.preventDefault();
197
+ }
198
+ break;
199
+ }
200
+ case "Enter": {
201
+ if (highlightedValue !== null && editable && !disabled) {
202
+ setEditingValue(highlightedValue);
203
+ event.preventDefault();
204
+ return;
205
+ }
206
+ break;
207
+ }
208
+ case "ArrowLeft":
209
+ case "ArrowRight": {
210
+ if (target.selectionStart === 0 && isArrowLeft && highlightedValue === null && value.length > 0) {
211
+ const lastValue = findNextEnabledValue(null, "prev");
212
+ setHighlightedValue(lastValue);
213
+ event.preventDefault();
214
+ } else if (highlightedValue !== null) {
215
+ const nextValue = findNextEnabledValue(
216
+ highlightedValue,
217
+ isArrowLeft ? "prev" : "next"
218
+ );
219
+ if (nextValue !== null) {
220
+ setHighlightedValue(nextValue);
221
+ event.preventDefault();
222
+ } else if (isArrowRight) {
223
+ setHighlightedValue(null);
224
+ requestAnimationFrame(() => target.setSelectionRange(0, 0));
225
+ }
226
+ }
227
+ break;
228
+ }
229
+ case "Home": {
230
+ if (highlightedValue !== null) {
231
+ const firstValue = findNextEnabledValue(null, "next");
232
+ setHighlightedValue(firstValue);
233
+ event.preventDefault();
234
+ }
235
+ break;
236
+ }
237
+ case "End": {
238
+ if (highlightedValue !== null) {
239
+ const lastValue = findNextEnabledValue(null, "prev");
240
+ setHighlightedValue(lastValue);
241
+ event.preventDefault();
242
+ }
243
+ break;
244
+ }
245
+ case "Escape": {
246
+ setHighlightedValue(null);
247
+ setEditingValue(null);
248
+ requestAnimationFrame(() => target.setSelectionRange(0, 0));
249
+ break;
250
+ }
251
+ }
252
+ },
253
+ [
254
+ highlightedValue,
255
+ value,
256
+ onItemRemove,
257
+ dir,
258
+ editable,
259
+ disabled,
260
+ loop,
261
+ getEnabledItems
262
+ ]
263
+ );
264
+ const getIsClickedInEmptyRoot = React.useCallback((target) => {
265
+ return collectionRef.current?.contains(target) && !target.hasAttribute(DATA_ITEM_ATTR) && target.tagName !== "INPUT";
266
+ }, []);
267
+ return /* @__PURE__ */ React.createElement(
268
+ TagsInputProvider,
269
+ {
270
+ value,
271
+ onValueChange: setValue,
272
+ onItemAdd,
273
+ onItemRemove,
274
+ onItemUpdate,
275
+ onInputKeydown,
276
+ highlightedValue,
277
+ setHighlightedValue,
278
+ editingValue,
279
+ setEditingValue,
280
+ displayValue,
281
+ onItemLeave,
282
+ inputRef,
283
+ isInvalidInput,
284
+ addOnPaste,
285
+ addOnTab,
286
+ disabled,
287
+ editable,
288
+ loop,
289
+ blurBehavior,
290
+ delimiter,
291
+ max,
292
+ dir,
293
+ id,
294
+ inputId,
295
+ labelId
296
+ },
297
+ /* @__PURE__ */ React.createElement(
298
+ Primitive.div,
299
+ {
300
+ id,
301
+ "data-invalid": isInvalidInput ? "" : void 0,
302
+ "data-disabled": disabled ? "" : void 0,
303
+ dir,
304
+ ...rootProps,
305
+ ref: composedRef,
306
+ onClick: composeEventHandlers(rootProps.onClick, (event) => {
307
+ const target = event.target;
308
+ if (!(target instanceof HTMLElement)) return;
309
+ if (getIsClickedInEmptyRoot(target) && document.activeElement !== inputRef.current) {
310
+ event.currentTarget.focus();
311
+ inputRef.current?.focus();
312
+ }
313
+ }),
314
+ onMouseDown: composeEventHandlers(rootProps.onMouseDown, (event) => {
315
+ const target = event.target;
316
+ if (!(target instanceof HTMLElement)) return;
317
+ if (getIsClickedInEmptyRoot(target)) {
318
+ event.preventDefault();
319
+ }
320
+ }),
321
+ onBlur: composeEventHandlers(rootProps.onBlur, (event) => {
322
+ if (event.relatedTarget !== inputRef.current && !collectionRef.current?.contains(event.relatedTarget)) {
323
+ requestAnimationFrame(() => setHighlightedValue(null));
324
+ }
325
+ })
326
+ },
327
+ typeof children === "function" ? /* @__PURE__ */ React.createElement(React.Fragment, null, children({ value })) : children,
328
+ isFormControl && name && /* @__PURE__ */ React.createElement(
329
+ BubbleInput,
330
+ {
331
+ type: "hidden",
332
+ control: collectionRef.current,
333
+ name,
334
+ value,
335
+ required,
336
+ disabled
337
+ }
338
+ )
339
+ )
340
+ );
341
+ });
342
+ TagsInputRoot.displayName = ROOT_NAME;
343
+ var Root = TagsInputRoot;
344
+ var LABEL_NAME = "TagsInputLabel";
345
+ var TagsInputLabel = React.forwardRef(
346
+ (props, ref) => {
347
+ const context = useTagsInput(LABEL_NAME);
348
+ return /* @__PURE__ */ React.createElement(
349
+ Primitive.label,
350
+ {
351
+ id: context.labelId,
352
+ htmlFor: context.inputId,
353
+ ...props,
354
+ ref
355
+ }
356
+ );
357
+ }
358
+ );
359
+ TagsInputLabel.displayName = LABEL_NAME;
360
+ var Label = TagsInputLabel;
361
+ var ITEM_NAME = "TagsInputItem";
362
+ var [TagsInputItemProvider, useTagsInputItem] = createContext(ITEM_NAME);
363
+ var TagsInputItem = React.forwardRef(
364
+ (props, ref) => {
365
+ const { value, disabled, ...itemProps } = props;
366
+ const pointerTypeRef = React.useRef("touch");
367
+ const context = useTagsInput(ITEM_NAME);
368
+ const id = useId();
369
+ const textId = `${id}text`;
370
+ const isHighlighted = value === context.highlightedValue;
371
+ const isEditing = value === context.editingValue;
372
+ const itemDisabled = disabled || context.disabled;
373
+ const displayValue = context.displayValue(value);
374
+ function onSelect() {
375
+ context.setHighlightedValue(value);
376
+ context.inputRef.current?.focus();
377
+ }
378
+ return /* @__PURE__ */ React.createElement(
379
+ TagsInputItemProvider,
380
+ {
381
+ id,
382
+ value,
383
+ isHighlighted,
384
+ isEditing,
385
+ disabled: itemDisabled,
386
+ textId,
387
+ displayValue
388
+ },
389
+ /* @__PURE__ */ React.createElement(
390
+ Primitive.div,
391
+ {
392
+ ...{ [DATA_ITEM_ATTR]: "" },
393
+ "aria-labelledby": textId,
394
+ "aria-current": isHighlighted,
395
+ "aria-disabled": itemDisabled,
396
+ "data-state": isHighlighted ? "active" : "inactive",
397
+ "data-highlighted": isHighlighted ? "" : void 0,
398
+ "data-editing": isEditing ? "" : void 0,
399
+ "data-editable": context.editable ? "" : void 0,
400
+ "data-disabled": itemDisabled ? "" : void 0,
401
+ id,
402
+ ...itemProps,
403
+ ref,
404
+ onClick: composeEventHandlers(itemProps.onClick, (event) => {
405
+ event.stopPropagation();
406
+ if (!isEditing && pointerTypeRef.current !== "mouse") {
407
+ onSelect();
408
+ }
409
+ }),
410
+ onDoubleClick: composeEventHandlers(itemProps.onDoubleClick, () => {
411
+ if (context.editable && !itemDisabled) {
412
+ requestAnimationFrame(() => context.setEditingValue(value));
413
+ }
414
+ }),
415
+ onPointerUp: composeEventHandlers(itemProps.onPointerUp, () => {
416
+ if (pointerTypeRef.current === "mouse") onSelect();
417
+ }),
418
+ onPointerDown: composeEventHandlers(
419
+ itemProps.onPointerDown,
420
+ (event) => pointerTypeRef.current = event.pointerType
421
+ ),
422
+ onPointerMove: composeEventHandlers(
423
+ itemProps.onPointerMove,
424
+ (event) => {
425
+ pointerTypeRef.current = event.pointerType;
426
+ if (disabled) {
427
+ context.onItemLeave();
428
+ } else if (pointerTypeRef.current === "mouse") {
429
+ event.currentTarget.focus({ preventScroll: true });
430
+ }
431
+ }
432
+ ),
433
+ onPointerLeave: composeEventHandlers(
434
+ itemProps.onPointerLeave,
435
+ (event) => {
436
+ if (event.currentTarget === document.activeElement) {
437
+ context.onItemLeave();
438
+ }
439
+ }
440
+ )
441
+ }
442
+ )
443
+ );
444
+ }
445
+ );
446
+ TagsInputItem.displayName = ITEM_NAME;
447
+ var Item = TagsInputItem;
448
+ var INPUT_NAME = "TagsInputInput";
449
+ var TagsInputInput = React.forwardRef(
450
+ (props, ref) => {
451
+ const { autoFocus, ...inputProps } = props;
452
+ const context = useTagsInput(INPUT_NAME);
453
+ function onTab(event) {
454
+ if (!context.addOnTab) return;
455
+ onCustomKeydown(event);
456
+ }
457
+ function onCustomKeydown(event) {
458
+ if (event.defaultPrevented) return;
459
+ const value = event.currentTarget.value;
460
+ if (!value) return;
461
+ const isAdded = context.onItemAdd(value);
462
+ if (isAdded) {
463
+ event.currentTarget.value = "";
464
+ context.setHighlightedValue(null);
465
+ }
466
+ event.preventDefault();
467
+ }
468
+ React.useEffect(() => {
469
+ if (!autoFocus) return;
470
+ const animationFrameId = requestAnimationFrame(
471
+ () => context.inputRef.current?.focus()
472
+ );
473
+ return () => cancelAnimationFrame(animationFrameId);
474
+ }, [autoFocus, context.inputRef]);
475
+ return /* @__PURE__ */ React.createElement(
476
+ Primitive.input,
477
+ {
478
+ type: "text",
479
+ id: context.inputId,
480
+ autoCapitalize: "off",
481
+ autoComplete: "off",
482
+ autoCorrect: "off",
483
+ spellCheck: "false",
484
+ autoFocus,
485
+ "aria-labelledby": context.labelId,
486
+ "data-invalid": context.isInvalidInput ? "" : void 0,
487
+ disabled: context.disabled,
488
+ ...inputProps,
489
+ ref: composeRefs(context.inputRef, ref),
490
+ onBlur: composeEventHandlers(inputProps.onBlur, (event) => {
491
+ if (context.blurBehavior === "add") {
492
+ const value = event.target.value;
493
+ if (value) {
494
+ const isAdded = context.onItemAdd(value);
495
+ if (isAdded) event.target.value = "";
496
+ }
497
+ }
498
+ if (context.blurBehavior === "clear") {
499
+ event.target.value = "";
500
+ }
501
+ }),
502
+ onChange: composeEventHandlers(inputProps.onChange, (event) => {
503
+ const target = event.target;
504
+ if (!(target instanceof HTMLInputElement)) return;
505
+ const delimiter = context.delimiter;
506
+ if (delimiter === target.value.slice(-1)) {
507
+ const value = target.value.slice(0, -1);
508
+ target.value = "";
509
+ if (value) {
510
+ context.onItemAdd(value);
511
+ context.setHighlightedValue(null);
512
+ }
513
+ }
514
+ }),
515
+ onKeyDown: composeEventHandlers(inputProps.onKeyDown, (event) => {
516
+ if (event.key === "Enter") onCustomKeydown(event);
517
+ if (event.key === "Tab") onTab(event);
518
+ context.onInputKeydown(event);
519
+ if (event.key.length === 1) context.setHighlightedValue(null);
520
+ }),
521
+ onPaste: composeEventHandlers(inputProps.onPaste, (event) => {
522
+ if (context.addOnPaste) {
523
+ event.preventDefault();
524
+ const value = event.clipboardData.getData("text");
525
+ context.onItemAdd(value, { viaPaste: true });
526
+ context.setHighlightedValue(null);
527
+ }
528
+ })
529
+ }
530
+ );
531
+ }
532
+ );
533
+ TagsInputInput.displayName = INPUT_NAME;
534
+ var Input = TagsInputInput;
535
+ var ITEM_DELETE_NAME = "TagsInputItemDelete";
536
+ var TagsInputItemDelete = React.forwardRef((props, ref) => {
537
+ const context = useTagsInput(ITEM_DELETE_NAME);
538
+ const itemContext = useTagsInputItem(ITEM_DELETE_NAME);
539
+ const disabled = itemContext.disabled || context.disabled;
540
+ if (itemContext.isEditing) return null;
541
+ return /* @__PURE__ */ React.createElement(
542
+ Primitive.button,
543
+ {
544
+ type: "button",
545
+ tabIndex: -1,
546
+ "aria-labelledby": itemContext.textId,
547
+ "aria-controls": itemContext.id,
548
+ "aria-current": itemContext.isHighlighted,
549
+ "data-state": itemContext.isHighlighted ? "active" : "inactive",
550
+ "data-disabled": disabled ? "" : void 0,
551
+ ...props,
552
+ ref,
553
+ onClick: composeEventHandlers(props.onClick, () => {
554
+ if (disabled) return;
555
+ const index = context.value.findIndex((i) => i === itemContext.value);
556
+ context.onItemRemove(index);
557
+ })
558
+ }
559
+ );
560
+ });
561
+ TagsInputItemDelete.displayName = ITEM_DELETE_NAME;
562
+ var Delete = TagsInputItemDelete;
563
+ var ITEM_TEXT_NAME = "TagsInputItemText";
564
+ var TagsInputItemText = React.forwardRef((props, ref) => {
565
+ const { children, ...itemTextProps } = props;
566
+ const context = useTagsInput(ITEM_TEXT_NAME);
567
+ const itemContext = useTagsInputItem(ITEM_TEXT_NAME);
568
+ const [editValue, setEditValue] = React.useState(itemContext.displayValue);
569
+ if (itemContext.isEditing && context.editable && !itemContext.disabled) {
570
+ return /* @__PURE__ */ React.createElement(
571
+ Primitive.input,
572
+ {
573
+ type: "text",
574
+ autoCapitalize: "off",
575
+ autoComplete: "off",
576
+ autoCorrect: "off",
577
+ spellCheck: "false",
578
+ autoFocus: true,
579
+ "aria-describedby": itemContext.textId,
580
+ value: editValue,
581
+ onInput: (event) => {
582
+ const target = event.target;
583
+ if (!(target instanceof HTMLInputElement)) return;
584
+ target.style.width = "0";
585
+ target.style.width = `${target.scrollWidth + 4}px`;
586
+ },
587
+ onChange: (event) => setEditValue(event.target.value),
588
+ onKeyDown: (event) => {
589
+ if (event.key === "Enter") {
590
+ const index = context.value.findIndex(
591
+ (v) => v === itemContext.value
592
+ );
593
+ context.onItemUpdate(index, editValue);
594
+ } else if (event.key === "Escape") {
595
+ setEditValue(itemContext.displayValue);
596
+ context.setEditingValue(null);
597
+ context.inputRef.current?.focus();
598
+ }
599
+ event.stopPropagation();
600
+ },
601
+ onFocus: (event) => {
602
+ event.target.select();
603
+ event.target.style.width = "0";
604
+ event.target.style.width = `${event.target.scrollWidth + 4}px`;
605
+ },
606
+ onBlur: () => {
607
+ setEditValue(itemContext.displayValue);
608
+ context.setEditingValue(null);
609
+ },
610
+ style: {
611
+ outline: "none",
612
+ background: "inherit",
613
+ border: "none",
614
+ font: "inherit",
615
+ color: "inherit",
616
+ padding: 0,
617
+ minWidth: "1ch"
618
+ }
619
+ }
620
+ );
621
+ }
622
+ return /* @__PURE__ */ React.createElement(Primitive.span, { id: itemContext.textId, ...itemTextProps, ref }, children ?? itemContext.displayValue);
623
+ });
624
+ var Text = TagsInputItemText;
625
+ var CLEAR_NAME = "TagsInputClear";
626
+ var TagsInputClear = React.forwardRef(
627
+ (props, ref) => {
628
+ const { forceMount, ...clearProps } = props;
629
+ const context = useTagsInput(CLEAR_NAME);
630
+ return /* @__PURE__ */ React.createElement(Presence, { present: forceMount || context.value.length > 0 }, /* @__PURE__ */ React.createElement(
631
+ Primitive.button,
632
+ {
633
+ type: "button",
634
+ "aria-disabled": context.disabled,
635
+ "data-state": context.value.length > 0 ? "visible" : "invisible",
636
+ "data-disabled": context.disabled ? "" : void 0,
637
+ ...clearProps,
638
+ ref,
639
+ onClick: composeEventHandlers(props.onClick, () => {
640
+ if (context.disabled) return;
641
+ context.onValueChange([]);
642
+ context.inputRef.current?.focus();
643
+ })
644
+ }
645
+ ));
646
+ }
647
+ );
648
+ TagsInputClear.displayName = CLEAR_NAME;
649
+ var Clear = TagsInputClear;
650
+
651
+ export { Clear, Delete, Input, Item, Label, Root, TagsInputClear, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputLabel, TagsInputRoot, Text };
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@diceui/tags-input",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "keywords": [
6
+ "tags-input",
7
+ "tag-input",
8
+ "ui",
9
+ "react"
10
+ ],
11
+ "author": "Sadman Sakib",
12
+ "license": "MIT",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/sadmann7/diceui",
16
+ "directory": "packages/tags-input"
17
+ },
18
+ "main": "./dist/index.cjs",
19
+ "module": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js",
25
+ "require": "./dist/index.cjs"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "package.json",
31
+ "README.md"
32
+ ],
33
+ "peerDependencies": {
34
+ "@types/react": "*",
35
+ "@types/react-dom": "*",
36
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
37
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
38
+ },
39
+ "peerDependenciesMeta": {
40
+ "@types/react": {
41
+ "optional": true
42
+ },
43
+ "@types/react-dom": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.10.2",
49
+ "tsup": "^8.3.5",
50
+ "typescript": "^5.7.2"
51
+ },
52
+ "dependencies": {
53
+ "@radix-ui/react-primitive": "^2.0.1",
54
+ "lucide-react": "^0.468.0",
55
+ "@diceui/shared": "0.0.1"
56
+ },
57
+ "scripts": {
58
+ "dev": "tsup --format esm --watch --external=react",
59
+ "build": "tsup --clean --external=react",
60
+ "typecheck": "tsc --noEmit"
61
+ }
62
+ }