@diceui/tags-input 0.7.3 → 1.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diceui/tags-input",
3
- "version": "0.7.3",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -18,19 +18,12 @@
18
18
  "url": "https://github.com/sadmann7/diceui",
19
19
  "directory": "packages/tags-input"
20
20
  },
21
- "main": "./dist/index.cjs",
22
- "module": "./dist/index.mjs",
21
+ "main": "./dist/index.mjs",
23
22
  "types": "./dist/index.d.mts",
24
23
  "exports": {
25
24
  ".": {
26
- "import": {
27
- "types": "./dist/index.d.mts",
28
- "default": "./dist/index.mjs"
29
- },
30
- "require": {
31
- "types": "./dist/index.d.cts",
32
- "default": "./dist/index.cjs"
33
- }
25
+ "types": "./dist/index.d.mts",
26
+ "default": "./dist/index.mjs"
34
27
  }
35
28
  },
36
29
  "files": [
@@ -57,7 +50,7 @@
57
50
  "typescript": "^7.0.2"
58
51
  },
59
52
  "dependencies": {
60
- "@diceui/shared": "0.12.1"
53
+ "@diceui/shared": "1.0.0"
61
54
  },
62
55
  "scripts": {
63
56
  "dev": "tsdown --watch",
package/dist/index.cjs DELETED
@@ -1,629 +0,0 @@
1
- 'use client';
2
- "use client";
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
- //#region \0rolldown/runtime.js
5
- var __create = Object.create;
6
- var __defProp = Object.defineProperty;
7
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
- var __getOwnPropNames = Object.getOwnPropertyNames;
9
- var __getProtoOf = Object.getPrototypeOf;
10
- var __hasOwnProp = Object.prototype.hasOwnProperty;
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
13
- key = keys[i];
14
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
- get: ((k) => from[k]).bind(null, key),
16
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
- });
18
- }
19
- return to;
20
- };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
22
- value: mod,
23
- enumerable: true
24
- }) : target, mod));
25
- //#endregion
26
- let _diceui_shared = require("@diceui/shared");
27
- let react = require("react");
28
- react = __toESM(react, 1);
29
- let react_jsx_runtime = require("react/jsx-runtime");
30
- //#region src/tags-input-root.tsx
31
- const ROOT_NAME = "TagsInputRoot";
32
- const [TagsInputProvider, useTagsInput] = (0, _diceui_shared.createContext)(ROOT_NAME);
33
- const TagsInputRoot = react.forwardRef((props, ref) => {
34
- const { value: valueProp, defaultValue, onValueChange, onValidate, onInvalid, displayValue = (value) => value, addOnPaste = false, addOnTab = false, disabled = false, editable = false, loop = false, blurBehavior, delimiter = ",", max = Number.POSITIVE_INFINITY, readOnly = false, required = false, name, children, dir: dirProp, id: idProp, ...rootProps } = props;
35
- const [value = [], setValue] = (0, _diceui_shared.useControllableState)({
36
- prop: valueProp,
37
- defaultProp: defaultValue,
38
- onChange: onValueChange
39
- });
40
- const [highlightedIndex, setHighlightedIndex] = react.useState(null);
41
- const [editingIndex, setEditingIndex] = react.useState(null);
42
- const [isInvalidInput, setIsInvalidInput] = react.useState(false);
43
- const collectionRef = react.useRef(null);
44
- const inputRef = react.useRef(null);
45
- const id = (0, _diceui_shared.useId)(idProp);
46
- const inputId = (0, _diceui_shared.useId)();
47
- const labelId = (0, _diceui_shared.useId)();
48
- const dir = (0, _diceui_shared.useDirection)(dirProp);
49
- const { getEnabledItems } = (0, _diceui_shared.useItemCollection)({ ref: collectionRef });
50
- const { isFormControl, onTriggerChange } = (0, _diceui_shared.useFormControl)();
51
- const composedRef = (0, _diceui_shared.useComposedRefs)(ref, collectionRef, (node) => onTriggerChange(node));
52
- const onItemAdd = react.useCallback((textValue, options) => {
53
- if (disabled || readOnly) return false;
54
- if (addOnPaste && options?.viaPaste) {
55
- const splitValues = textValue.split(delimiter).map((v) => v.trim()).filter(Boolean);
56
- if (value.length + splitValues.length > max && max > 0) {
57
- onInvalid?.(textValue);
58
- return false;
59
- }
60
- let newValues = [];
61
- for (const v of splitValues) if (value.includes(v)) onInvalid?.(v);
62
- newValues = [...new Set(splitValues.filter((v) => !value.includes(v)))];
63
- const validValues = newValues.filter((v) => !onValidate || onValidate(v));
64
- if (validValues.length === 0) return false;
65
- setValue([...value, ...validValues]);
66
- return true;
67
- }
68
- if (value.length >= max && max > 0) {
69
- onInvalid?.(textValue);
70
- return false;
71
- }
72
- const trimmedValue = textValue.trim();
73
- if (onValidate && !onValidate(trimmedValue)) {
74
- setIsInvalidInput(true);
75
- onInvalid?.(trimmedValue);
76
- return false;
77
- }
78
- if (value.some((v) => {
79
- return v === trimmedValue;
80
- })) {
81
- setIsInvalidInput(true);
82
- onInvalid?.(trimmedValue);
83
- return true;
84
- }
85
- const newValue = trimmedValue;
86
- const newValues = [...value, newValue];
87
- setValue(newValues);
88
- setHighlightedIndex(null);
89
- setEditingIndex(null);
90
- setIsInvalidInput(false);
91
- return true;
92
- }, [
93
- value,
94
- max,
95
- addOnPaste,
96
- delimiter,
97
- setValue,
98
- onInvalid,
99
- onValidate,
100
- disabled,
101
- readOnly
102
- ]);
103
- const onItemUpdate = react.useCallback((index, newTextValue) => {
104
- if (disabled || readOnly) return;
105
- if (index !== -1) {
106
- const trimmedValue = newTextValue.trim();
107
- if (value.some((v, i) => {
108
- if (i === index) return false;
109
- return v === trimmedValue;
110
- })) {
111
- setIsInvalidInput(true);
112
- onInvalid?.(trimmedValue);
113
- return;
114
- }
115
- if (onValidate && !onValidate(trimmedValue)) {
116
- setIsInvalidInput(true);
117
- onInvalid?.(trimmedValue);
118
- return;
119
- }
120
- const updatedValue = displayValue(trimmedValue);
121
- const newValues = [...value];
122
- newValues[index] = updatedValue;
123
- setValue(newValues);
124
- setHighlightedIndex(index);
125
- setEditingIndex(null);
126
- setIsInvalidInput(false);
127
- requestAnimationFrame(() => inputRef.current?.focus());
128
- }
129
- }, [
130
- value,
131
- setValue,
132
- displayValue,
133
- onInvalid,
134
- onValidate,
135
- disabled,
136
- readOnly
137
- ]);
138
- const onItemRemove = react.useCallback((index) => {
139
- if (disabled || readOnly) return;
140
- if (index !== -1) {
141
- const newValues = [...value];
142
- newValues.splice(index, 1);
143
- setValue(newValues);
144
- setHighlightedIndex(null);
145
- setEditingIndex(null);
146
- inputRef.current?.focus();
147
- }
148
- }, [
149
- value,
150
- setValue,
151
- disabled,
152
- readOnly
153
- ]);
154
- const onItemLeave = react.useCallback(() => {
155
- setHighlightedIndex(null);
156
- setEditingIndex(null);
157
- inputRef.current?.focus();
158
- }, []);
159
- const onInputKeydown = react.useCallback((event) => {
160
- const target = event.target;
161
- if (!(target instanceof HTMLInputElement)) return;
162
- const isArrowLeft = event.key === "ArrowLeft" && dir === "ltr" || event.key === "ArrowRight" && dir === "rtl";
163
- const isArrowRight = event.key === "ArrowRight" && dir === "ltr" || event.key === "ArrowLeft" && dir === "rtl";
164
- if (target.value && target.selectionStart !== 0) {
165
- setHighlightedIndex(null);
166
- setEditingIndex(null);
167
- return;
168
- }
169
- function findNextEnabledIndex(currentIndex, direction) {
170
- if (!collectionRef.current) return null;
171
- const enabledIndices = getEnabledItems().map((_, index) => index);
172
- if (enabledIndices.length === 0) return null;
173
- if (currentIndex === null) return direction === "prev" ? enabledIndices[enabledIndices.length - 1] ?? null : enabledIndices[0] ?? null;
174
- const currentEnabledIndex = enabledIndices.indexOf(currentIndex);
175
- if (direction === "next") return currentEnabledIndex >= enabledIndices.length - 1 ? loop ? enabledIndices[0] ?? null : null : enabledIndices[currentEnabledIndex + 1] ?? null;
176
- return currentEnabledIndex <= 0 ? loop ? enabledIndices[enabledIndices.length - 1] ?? null : null : enabledIndices[currentEnabledIndex - 1] ?? null;
177
- }
178
- switch (event.key) {
179
- case "Delete":
180
- case "Backspace":
181
- if (target.selectionStart !== 0 || target.selectionEnd !== 0) break;
182
- if (highlightedIndex !== null) {
183
- const newIndex = findNextEnabledIndex(highlightedIndex, "prev");
184
- onItemRemove(highlightedIndex);
185
- setHighlightedIndex(newIndex);
186
- event.preventDefault();
187
- } else if (event.key === "Backspace" && value.length > 0) {
188
- const lastIndex = findNextEnabledIndex(null, "prev");
189
- setHighlightedIndex(lastIndex);
190
- event.preventDefault();
191
- }
192
- break;
193
- case "Enter":
194
- if (highlightedIndex !== null && editable && !disabled) {
195
- setEditingIndex(highlightedIndex);
196
- event.preventDefault();
197
- return;
198
- }
199
- break;
200
- case "ArrowLeft":
201
- case "ArrowRight":
202
- if (target.selectionStart === 0 && isArrowLeft && highlightedIndex === null && value.length > 0) {
203
- const lastIndex = findNextEnabledIndex(null, "prev");
204
- setHighlightedIndex(lastIndex);
205
- event.preventDefault();
206
- } else if (highlightedIndex !== null) {
207
- const nextIndex = findNextEnabledIndex(highlightedIndex, isArrowLeft ? "prev" : "next");
208
- if (nextIndex !== null) {
209
- setHighlightedIndex(nextIndex);
210
- event.preventDefault();
211
- } else if (isArrowRight) {
212
- setHighlightedIndex(null);
213
- requestAnimationFrame(() => target.setSelectionRange(0, 0));
214
- }
215
- }
216
- break;
217
- case "Home":
218
- if (highlightedIndex !== null) {
219
- const firstIndex = findNextEnabledIndex(null, "next");
220
- setHighlightedIndex(firstIndex);
221
- event.preventDefault();
222
- }
223
- break;
224
- case "End":
225
- if (highlightedIndex !== null) {
226
- const lastIndex = findNextEnabledIndex(null, "prev");
227
- setHighlightedIndex(lastIndex);
228
- event.preventDefault();
229
- }
230
- break;
231
- case "Escape":
232
- if (highlightedIndex !== null) setHighlightedIndex(null);
233
- if (editingIndex !== null) setEditingIndex(null);
234
- requestAnimationFrame(() => target.setSelectionRange(0, 0));
235
- }
236
- }, [
237
- dir,
238
- editingIndex,
239
- highlightedIndex,
240
- value,
241
- onItemRemove,
242
- getEnabledItems,
243
- editable,
244
- disabled,
245
- loop
246
- ]);
247
- const getIsClickedInEmptyRoot = react.useCallback((target) => {
248
- return collectionRef.current?.contains(target) && !target.hasAttribute(_diceui_shared.DATA_ITEM_ATTR) && target.tagName !== "INPUT";
249
- }, []);
250
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TagsInputProvider, {
251
- value,
252
- onValueChange: setValue,
253
- onItemAdd,
254
- onItemRemove,
255
- onItemUpdate,
256
- onInputKeydown,
257
- highlightedIndex,
258
- setHighlightedIndex,
259
- editingIndex,
260
- setEditingIndex,
261
- displayValue,
262
- onItemLeave,
263
- inputRef,
264
- isInvalidInput,
265
- addOnPaste,
266
- addOnTab,
267
- disabled,
268
- editable,
269
- loop,
270
- readOnly,
271
- blurBehavior,
272
- delimiter,
273
- max,
274
- dir,
275
- id,
276
- inputId,
277
- labelId,
278
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_diceui_shared.Primitive.div, {
279
- id,
280
- "data-disabled": disabled ? "" : void 0,
281
- "data-invalid": isInvalidInput ? "" : void 0,
282
- "data-readonly": readOnly ? "" : void 0,
283
- dir,
284
- ...rootProps,
285
- ref: composedRef,
286
- onClick: (0, _diceui_shared.composeEventHandlers)(rootProps.onClick, (event) => {
287
- const target = event.target;
288
- if (!(target instanceof HTMLElement)) return;
289
- if (getIsClickedInEmptyRoot(target) && document.activeElement !== inputRef.current) {
290
- event.currentTarget.focus();
291
- inputRef.current?.focus();
292
- }
293
- }),
294
- onMouseDown: (0, _diceui_shared.composeEventHandlers)(rootProps.onMouseDown, (event) => {
295
- const target = event.target;
296
- if (!(target instanceof HTMLElement)) return;
297
- if (getIsClickedInEmptyRoot(target)) event.preventDefault();
298
- }),
299
- onBlur: (0, _diceui_shared.composeEventHandlers)(rootProps.onBlur, (event) => {
300
- if (event.relatedTarget !== inputRef.current && !collectionRef.current?.contains(event.relatedTarget)) requestAnimationFrame(() => setHighlightedIndex(null));
301
- }),
302
- children: [typeof children === "function" ? children({ value }) : children, isFormControl && name && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.VisuallyHiddenInput, {
303
- type: "hidden",
304
- control: collectionRef.current,
305
- name,
306
- value,
307
- disabled,
308
- required
309
- })]
310
- })
311
- });
312
- });
313
- TagsInputRoot.displayName = ROOT_NAME;
314
- const Root = TagsInputRoot;
315
- //#endregion
316
- //#region src/tags-input-clear.tsx
317
- const CLEAR_NAME = "TagsInputClear";
318
- const TagsInputClear = react.forwardRef((props, ref) => {
319
- const { forceMount, ...clearProps } = props;
320
- const context = useTagsInput(CLEAR_NAME);
321
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.Presence, {
322
- present: forceMount || context.value.length > 0,
323
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.Primitive.button, {
324
- type: "button",
325
- "aria-disabled": context.disabled,
326
- "data-state": context.value.length > 0 ? "visible" : "invisible",
327
- "data-disabled": context.disabled ? "" : void 0,
328
- ...clearProps,
329
- ref,
330
- onClick: (0, _diceui_shared.composeEventHandlers)(props.onClick, () => {
331
- if (context.disabled) return;
332
- context.onValueChange([]);
333
- context.inputRef.current?.focus();
334
- })
335
- })
336
- });
337
- });
338
- TagsInputClear.displayName = CLEAR_NAME;
339
- const Clear = TagsInputClear;
340
- //#endregion
341
- //#region src/tags-input-input.tsx
342
- const INPUT_NAME = "TagsInputInput";
343
- const TagsInputInput = react.forwardRef((props, ref) => {
344
- const { autoFocus, ...inputProps } = props;
345
- const context = useTagsInput(INPUT_NAME);
346
- const onCustomKeydown = react.useCallback((event) => {
347
- if (event.defaultPrevented) return;
348
- const value = event.currentTarget.value;
349
- if (!value) return;
350
- if (context.onItemAdd(value)) {
351
- event.currentTarget.value = "";
352
- context.setHighlightedIndex(null);
353
- }
354
- event.preventDefault();
355
- }, [context.onItemAdd, context.setHighlightedIndex]);
356
- const onTab = react.useCallback((event) => {
357
- if (!context.addOnTab) return;
358
- onCustomKeydown(event);
359
- }, [context.addOnTab, onCustomKeydown]);
360
- react.useEffect(() => {
361
- if (!autoFocus) return;
362
- const animationFrameId = requestAnimationFrame(() => context.inputRef.current?.focus());
363
- return () => cancelAnimationFrame(animationFrameId);
364
- }, [autoFocus, context.inputRef]);
365
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.Primitive.input, {
366
- type: "text",
367
- id: context.inputId,
368
- autoCapitalize: "off",
369
- autoComplete: "off",
370
- autoCorrect: "off",
371
- spellCheck: "false",
372
- autoFocus,
373
- "aria-labelledby": context.labelId,
374
- "aria-readonly": context.readOnly,
375
- "data-invalid": context.isInvalidInput ? "" : void 0,
376
- dir: context.dir,
377
- disabled: context.disabled,
378
- readOnly: context.readOnly,
379
- ...inputProps,
380
- ref: (0, _diceui_shared.composeRefs)(context.inputRef, ref),
381
- onBlur: (0, _diceui_shared.composeEventHandlers)(inputProps.onBlur, (event) => {
382
- if (context.readOnly) return;
383
- if (context.blurBehavior === "add") {
384
- const value = event.target.value;
385
- if (value) {
386
- if (context.onItemAdd(value)) event.target.value = "";
387
- }
388
- }
389
- if (context.blurBehavior === "clear") event.target.value = "";
390
- }),
391
- onChange: (0, _diceui_shared.composeEventHandlers)(inputProps.onChange, (event) => {
392
- if (context.readOnly) return;
393
- const target = event.target;
394
- if (!(target instanceof HTMLInputElement)) return;
395
- if (context.delimiter === target.value.slice(-1)) {
396
- const value = target.value.slice(0, -1);
397
- target.value = "";
398
- if (value) {
399
- context.onItemAdd(value);
400
- context.setHighlightedIndex(null);
401
- }
402
- }
403
- }),
404
- onKeyDown: (0, _diceui_shared.composeEventHandlers)(inputProps.onKeyDown, (event) => {
405
- if (context.readOnly) return;
406
- if (event.key === "Enter") onCustomKeydown(event);
407
- if (event.key === "Tab") onTab(event);
408
- context.onInputKeydown(event);
409
- if (event.key.length === 1) context.setHighlightedIndex(null);
410
- }),
411
- onPaste: (0, _diceui_shared.composeEventHandlers)(inputProps.onPaste, (event) => {
412
- if (context.readOnly) return;
413
- if (context.addOnPaste) {
414
- event.preventDefault();
415
- const value = event.clipboardData.getData("text");
416
- context.onItemAdd(value, { viaPaste: true });
417
- context.setHighlightedIndex(null);
418
- }
419
- })
420
- });
421
- });
422
- TagsInputInput.displayName = INPUT_NAME;
423
- const Input = TagsInputInput;
424
- //#endregion
425
- //#region src/tags-input-item.tsx
426
- const ITEM_NAME = "TagsInputItem";
427
- const [TagsInputItemProvider, useTagsInputItem] = (0, _diceui_shared.createContext)(ITEM_NAME);
428
- const TagsInputItem = react.forwardRef((props, ref) => {
429
- const { value, disabled, ...itemProps } = props;
430
- const pointerTypeRef = react.useRef("touch");
431
- const context = useTagsInput(ITEM_NAME);
432
- const id = (0, _diceui_shared.useId)();
433
- const textId = `${id}text`;
434
- const index = context.value.indexOf(value);
435
- const isHighlighted = index === context.highlightedIndex;
436
- const isEditing = index === context.editingIndex;
437
- const itemDisabled = disabled || context.disabled;
438
- const displayValue = context.displayValue(value);
439
- const onItemSelect = react.useCallback(() => {
440
- context.setHighlightedIndex(index);
441
- context.inputRef.current?.focus();
442
- }, [
443
- context.setHighlightedIndex,
444
- context.inputRef,
445
- index
446
- ]);
447
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TagsInputItemProvider, {
448
- id,
449
- value,
450
- index,
451
- isHighlighted,
452
- isEditing,
453
- disabled: itemDisabled,
454
- textId,
455
- displayValue,
456
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.Primitive.div, {
457
- id,
458
- "aria-labelledby": textId,
459
- "aria-current": isHighlighted,
460
- "aria-disabled": itemDisabled,
461
- [_diceui_shared.DATA_ITEM_ATTR]: "",
462
- "data-state": isHighlighted ? "active" : "inactive",
463
- "data-highlighted": isHighlighted ? "" : void 0,
464
- "data-editing": isEditing ? "" : void 0,
465
- "data-editable": context.editable ? "" : void 0,
466
- "data-disabled": itemDisabled ? "" : void 0,
467
- ...itemProps,
468
- ref,
469
- onClick: (0, _diceui_shared.composeEventHandlers)(itemProps.onClick, (event) => {
470
- event.stopPropagation();
471
- if (!isEditing && pointerTypeRef.current !== "mouse") onItemSelect();
472
- }),
473
- onDoubleClick: (0, _diceui_shared.composeEventHandlers)(itemProps.onDoubleClick, () => {
474
- if (context.editable && !itemDisabled) requestAnimationFrame(() => context.setEditingIndex(index));
475
- }),
476
- onPointerUp: (0, _diceui_shared.composeEventHandlers)(itemProps.onPointerUp, () => {
477
- if (pointerTypeRef.current === "mouse") onItemSelect();
478
- }),
479
- onPointerDown: (0, _diceui_shared.composeEventHandlers)(itemProps.onPointerDown, (event) => pointerTypeRef.current = event.pointerType),
480
- onPointerMove: (0, _diceui_shared.composeEventHandlers)(itemProps.onPointerMove, (event) => {
481
- pointerTypeRef.current = event.pointerType;
482
- if (disabled) context.onItemLeave();
483
- else if (pointerTypeRef.current === "mouse") event.currentTarget.focus({ preventScroll: true });
484
- }),
485
- onPointerLeave: (0, _diceui_shared.composeEventHandlers)(itemProps.onPointerLeave, (event) => {
486
- if (event.currentTarget === document.activeElement) context.onItemLeave();
487
- })
488
- })
489
- });
490
- });
491
- TagsInputItem.displayName = ITEM_NAME;
492
- const Item = TagsInputItem;
493
- //#endregion
494
- //#region src/tags-input-item-delete.tsx
495
- const ITEM_DELETE_NAME = "TagsInputItemDelete";
496
- const TagsInputItemDelete = react.forwardRef((props, ref) => {
497
- const context = useTagsInput(ITEM_DELETE_NAME);
498
- const itemContext = useTagsInputItem(ITEM_DELETE_NAME);
499
- const disabled = itemContext.disabled || context.disabled;
500
- if (itemContext.isEditing) return null;
501
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.Primitive.button, {
502
- type: "button",
503
- tabIndex: disabled ? void 0 : -1,
504
- "aria-labelledby": itemContext.textId,
505
- "aria-controls": itemContext.id,
506
- "aria-current": itemContext.isHighlighted,
507
- "data-state": itemContext.isHighlighted ? "active" : "inactive",
508
- "data-disabled": disabled ? "" : void 0,
509
- ...props,
510
- ref,
511
- onClick: (0, _diceui_shared.composeEventHandlers)(props.onClick, () => {
512
- if (disabled) return;
513
- const index = context.value.indexOf(itemContext.value);
514
- context.onItemRemove(index);
515
- })
516
- });
517
- });
518
- TagsInputItemDelete.displayName = ITEM_DELETE_NAME;
519
- const ItemDelete = TagsInputItemDelete;
520
- //#endregion
521
- //#region src/tags-input-item-text.tsx
522
- const ITEM_TEXT_NAME = "TagsInputItemText";
523
- const TagsInputItemText = react.forwardRef((props, ref) => {
524
- const { children, ...itemTextProps } = props;
525
- const context = useTagsInput(ITEM_TEXT_NAME);
526
- const itemContext = useTagsInputItem(ITEM_TEXT_NAME);
527
- if (itemContext.isEditing && context.editable && !itemContext.disabled) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TagsInputEditableItemText, {});
528
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.Primitive.span, {
529
- id: itemContext.textId,
530
- ...itemTextProps,
531
- ref,
532
- children: children ?? itemContext.displayValue
533
- });
534
- });
535
- const ItemText = TagsInputItemText;
536
- function TagsInputEditableItemText() {
537
- const context = useTagsInput(ITEM_TEXT_NAME);
538
- const itemContext = useTagsInputItem(ITEM_TEXT_NAME);
539
- const [editValue, setEditValue] = react.useState(itemContext.displayValue);
540
- const onBlur = react.useCallback(() => {
541
- setEditValue(itemContext.displayValue);
542
- context.setEditingIndex(null);
543
- }, [context.setEditingIndex, itemContext.displayValue]);
544
- const onChange = react.useCallback((event) => {
545
- const target = event.target;
546
- target.style.width = "0";
547
- target.style.width = `${target.scrollWidth + 4}px`;
548
- setEditValue(event.target.value);
549
- }, []);
550
- const onFocus = react.useCallback((event) => {
551
- event.target.select();
552
- event.target.style.width = "0";
553
- event.target.style.width = `${event.target.scrollWidth + 4}px`;
554
- }, []);
555
- const onKeyDown = react.useCallback((event) => {
556
- if (event.key === "Enter") {
557
- const index = context.value.indexOf(itemContext.value);
558
- context.onItemUpdate(index, editValue);
559
- } else if (event.key === "Escape") {
560
- setEditValue(itemContext.displayValue);
561
- context.setEditingIndex(null);
562
- context.setHighlightedIndex(itemContext.index);
563
- context.inputRef.current?.focus();
564
- }
565
- event.stopPropagation();
566
- }, [
567
- context.value,
568
- context.onItemUpdate,
569
- context.setEditingIndex,
570
- itemContext.displayValue,
571
- context.inputRef.current?.focus,
572
- editValue,
573
- itemContext.value,
574
- context.setHighlightedIndex,
575
- itemContext.index
576
- ]);
577
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.Primitive.input, {
578
- type: "text",
579
- autoCapitalize: "off",
580
- autoComplete: "off",
581
- autoCorrect: "off",
582
- spellCheck: "false",
583
- autoFocus: true,
584
- "aria-describedby": itemContext.textId,
585
- value: editValue,
586
- onChange,
587
- onKeyDown,
588
- onFocus,
589
- onBlur,
590
- style: {
591
- outline: "none",
592
- background: "inherit",
593
- border: "none",
594
- font: "inherit",
595
- color: "inherit",
596
- padding: 0,
597
- minWidth: "1ch"
598
- }
599
- });
600
- }
601
- //#endregion
602
- //#region src/tags-input-label.tsx
603
- const LABEL_NAME = "TagsInputLabel";
604
- const TagsInputLabel = react.forwardRef((props, ref) => {
605
- const context = useTagsInput(LABEL_NAME);
606
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_diceui_shared.Primitive.label, {
607
- id: context.labelId,
608
- htmlFor: context.inputId,
609
- ...props,
610
- ref
611
- });
612
- });
613
- TagsInputLabel.displayName = LABEL_NAME;
614
- const Label = TagsInputLabel;
615
- //#endregion
616
- exports.Clear = Clear;
617
- exports.Input = Input;
618
- exports.Item = Item;
619
- exports.ItemDelete = ItemDelete;
620
- exports.ItemText = ItemText;
621
- exports.Label = Label;
622
- exports.Root = Root;
623
- exports.TagsInputClear = TagsInputClear;
624
- exports.TagsInputInput = TagsInputInput;
625
- exports.TagsInputItem = TagsInputItem;
626
- exports.TagsInputItemDelete = TagsInputItemDelete;
627
- exports.TagsInputItemText = TagsInputItemText;
628
- exports.TagsInputLabel = TagsInputLabel;
629
- exports.TagsInputRoot = TagsInputRoot;
package/dist/index.d.cts DELETED
@@ -1,137 +0,0 @@
1
-
2
- import { Direction, Primitive } from "@diceui/shared";
3
- import * as React from "react";
4
- //#region src/tags-input-clear.d.ts
5
- interface TagsInputClearProps extends React.ComponentPropsWithoutRef<typeof Primitive.button> {
6
- /**
7
- * Whether the clear button should always be rendered.
8
- *
9
- * Can be used to animate the enter and exit of the clear button.
10
- * @default false
11
- */
12
- forceMount?: boolean;
13
- }
14
- declare const TagsInputClear: React.ForwardRefExoticComponent<TagsInputClearProps & React.RefAttributes<HTMLButtonElement>>;
15
- declare const Clear: React.ForwardRefExoticComponent<TagsInputClearProps & React.RefAttributes<HTMLButtonElement>>;
16
- //#endregion
17
- //#region src/tags-input-input.d.ts
18
- interface TagsInputInputProps extends React.ComponentPropsWithoutRef<typeof Primitive.input> {}
19
- declare const TagsInputInput: React.ForwardRefExoticComponent<TagsInputInputProps & React.RefAttributes<HTMLInputElement>>;
20
- declare const Input: React.ForwardRefExoticComponent<TagsInputInputProps & React.RefAttributes<HTMLInputElement>>;
21
- //#endregion
22
- //#region src/tags-input-root.d.ts
23
- type InputValue = string;
24
- interface TagsInputRootProps<T = InputValue> extends Omit<React.ComponentPropsWithoutRef<typeof Primitive.div>, "value" | "defaultValue" | "onValueChange" | "onInvalid" | "children"> {
25
- /** Controlled array of tag values. */
26
- value?: T[];
27
- /** Initial array of tag values when uncontrolled. */
28
- defaultValue?: T[];
29
- /** Callback function to handle changes in the tag values. */
30
- onValueChange?: (value: T[]) => void;
31
- /** Callback function to validate tags before they're added. */
32
- onValidate?: (value: T) => boolean;
33
- /** Callback function to handle invalid input. */
34
- onInvalid?: (value: T) => void;
35
- /** Function to convert a tag value to its display string representation. */
36
- displayValue?: (value: T) => string;
37
- /**
38
- * Enable adding tags by pasting text, which will be split by the delimiter.
39
- * @default false
40
- */
41
- addOnPaste?: boolean;
42
- /**
43
- * Enable adding tags when Tab key is pressed.
44
- * @default false
45
- */
46
- addOnTab?: boolean;
47
- /**
48
- * Disables the entire tags input.
49
- * @default false
50
- */
51
- disabled?: boolean;
52
- /**
53
- * Allow editing of existing tags
54
- * @default false
55
- */
56
- editable?: boolean;
57
- /**
58
- * Enable wrapping focus from last to first tag and vice versa.
59
- * @default false
60
- */
61
- loop?: boolean;
62
- /**
63
- * Behavior when the input loses focus.
64
- * - "add": Add the current input value as a new tag.
65
- * - "clear": Reset the input field, removing its value.
66
- * By default, the input value will stay in the input field.
67
- * Can be overridden by the preventDefault() call in the input's onBlur handler.
68
- */
69
- blurBehavior?: "add" | "clear";
70
- /**
71
- * Character used to split pasted text into multiple tags.
72
- * @default ","
73
- */
74
- delimiter?: string;
75
- /**
76
- * Maximum number of tags allowed.
77
- * @default Number.POSITIVE_INFINITY
78
- */
79
- max?: number;
80
- /**
81
- * Whether the field is required in a form context.
82
- * @default false
83
- */
84
- required?: boolean;
85
- /**
86
- * Whether the tags input is read-only.
87
- * @default false
88
- */
89
- readOnly?: boolean;
90
- /**
91
- * The content of the tags input.
92
- *
93
- * Can be a React node or a function that receives the current value as an argument.
94
- * @default undefined
95
- */
96
- children?: React.ReactNode | ((context: {
97
- value: InputValue[];
98
- }) => React.ReactNode);
99
- /**
100
- * The reading direction of the tags input.
101
- * @default "ltr"
102
- */
103
- dir?: Direction;
104
- /** Name of the form field when used in a form. */
105
- name?: string;
106
- /** Unique identifier for the tags input. */
107
- id?: string;
108
- }
109
- declare const TagsInputRoot: React.ForwardRefExoticComponent<TagsInputRootProps<string> & React.RefAttributes<HTMLDivElement>>;
110
- declare const Root: React.ForwardRefExoticComponent<TagsInputRootProps<string> & React.RefAttributes<HTMLDivElement>>;
111
- //#endregion
112
- //#region src/tags-input-item.d.ts
113
- interface TagsInputItemProps extends React.ComponentPropsWithoutRef<typeof Primitive.div> {
114
- /** The value of the item. */
115
- value: InputValue;
116
- /** Whether the item is disabled. */
117
- disabled?: boolean;
118
- }
119
- declare const TagsInputItem: React.ForwardRefExoticComponent<TagsInputItemProps & React.RefAttributes<HTMLDivElement>>;
120
- declare const Item: React.ForwardRefExoticComponent<TagsInputItemProps & React.RefAttributes<HTMLDivElement>>;
121
- //#endregion
122
- //#region src/tags-input-item-delete.d.ts
123
- interface TagsInputItemDeleteProps extends React.ComponentPropsWithoutRef<typeof Primitive.button> {}
124
- declare const TagsInputItemDelete: React.ForwardRefExoticComponent<TagsInputItemDeleteProps & React.RefAttributes<HTMLButtonElement>>;
125
- declare const ItemDelete: React.ForwardRefExoticComponent<TagsInputItemDeleteProps & React.RefAttributes<HTMLButtonElement>>;
126
- //#endregion
127
- //#region src/tags-input-item-text.d.ts
128
- interface TagsInputItemTextProps extends React.ComponentPropsWithoutRef<typeof Primitive.span> {}
129
- declare const TagsInputItemText: React.ForwardRefExoticComponent<TagsInputItemTextProps & React.RefAttributes<HTMLSpanElement>>;
130
- declare const ItemText: React.ForwardRefExoticComponent<TagsInputItemTextProps & React.RefAttributes<HTMLSpanElement>>;
131
- //#endregion
132
- //#region src/tags-input-label.d.ts
133
- interface TagsInputLabelProps extends React.ComponentPropsWithoutRef<typeof Primitive.label> {}
134
- declare const TagsInputLabel: React.ForwardRefExoticComponent<TagsInputLabelProps & React.RefAttributes<HTMLLabelElement>>;
135
- declare const Label: React.ForwardRefExoticComponent<TagsInputLabelProps & React.RefAttributes<HTMLLabelElement>>;
136
- //#endregion
137
- export { Clear, Input, Item, ItemDelete, ItemText, Label, Root, TagsInputClear, type TagsInputClearProps, TagsInputInput, type TagsInputInputProps, TagsInputItem, TagsInputItemDelete, type TagsInputItemDeleteProps, type TagsInputItemProps, TagsInputItemText, type TagsInputItemTextProps, TagsInputLabel, type TagsInputLabelProps, TagsInputRoot, type TagsInputRootProps };