jaci-ui 0.2.0 → 0.4.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/CHANGELOG.md +12 -0
- package/README.md +95 -0
- package/dist/components/button-group/button-group.cjs +22 -0
- package/dist/components/button-group/button-group.cjs.map +1 -0
- package/dist/components/button-group/button-group.d.cts +12 -0
- package/dist/components/button-group/button-group.d.ts +12 -0
- package/dist/components/button-group/button-group.js +21 -0
- package/dist/components/button-group/button-group.js.map +1 -0
- package/dist/components/button-group/index.d.cts +2 -0
- package/dist/components/button-group/index.d.ts +2 -0
- package/dist/components/calendar/calendar.cjs +377 -0
- package/dist/components/calendar/calendar.cjs.map +1 -0
- package/dist/components/calendar/calendar.d.cts +56 -0
- package/dist/components/calendar/calendar.d.ts +56 -0
- package/dist/components/calendar/calendar.js +368 -0
- package/dist/components/calendar/calendar.js.map +1 -0
- package/dist/components/calendar/index.d.cts +2 -0
- package/dist/components/calendar/index.d.ts +2 -0
- package/dist/components/combobox/combobox.cjs +13 -1
- package/dist/components/combobox/combobox.cjs.map +1 -1
- package/dist/components/combobox/combobox.d.cts +7 -2
- package/dist/components/combobox/combobox.d.ts +7 -2
- package/dist/components/combobox/combobox.js +13 -2
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/combobox/index.d.cts +2 -2
- package/dist/components/combobox/index.d.ts +2 -2
- package/dist/components/controls/input.cjs +26 -5
- package/dist/components/controls/input.cjs.map +1 -1
- package/dist/components/controls/input.d.cts +5 -2
- package/dist/components/controls/input.d.ts +5 -2
- package/dist/components/controls/input.js +28 -7
- package/dist/components/controls/input.js.map +1 -1
- package/dist/components/controls/textarea.cjs +26 -5
- package/dist/components/controls/textarea.cjs.map +1 -1
- package/dist/components/controls/textarea.d.cts +5 -2
- package/dist/components/controls/textarea.d.ts +5 -2
- package/dist/components/controls/textarea.js +28 -7
- package/dist/components/controls/textarea.js.map +1 -1
- package/dist/components/date-picker/date-picker.cjs +9 -9
- package/dist/components/date-picker/date-picker.cjs.map +1 -1
- package/dist/components/date-picker/date-picker.d.cts +3 -1
- package/dist/components/date-picker/date-picker.d.ts +3 -1
- package/dist/components/date-picker/date-picker.js +9 -9
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.cjs +589 -0
- package/dist/components/date-range-picker/date-range-picker.cjs.map +1 -0
- package/dist/components/date-range-picker/date-range-picker.d.cts +134 -0
- package/dist/components/date-range-picker/date-range-picker.d.ts +134 -0
- package/dist/components/date-range-picker/date-range-picker.js +568 -0
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -0
- package/dist/components/date-range-picker/index.d.cts +2 -0
- package/dist/components/date-range-picker/index.d.ts +2 -0
- package/dist/components/empty-state/empty-state.cjs +62 -0
- package/dist/components/empty-state/empty-state.cjs.map +1 -0
- package/dist/components/empty-state/empty-state.d.cts +18 -0
- package/dist/components/empty-state/empty-state.d.ts +18 -0
- package/dist/components/empty-state/empty-state.js +57 -0
- package/dist/components/empty-state/empty-state.js.map +1 -0
- package/dist/components/empty-state/index.d.cts +2 -0
- package/dist/components/empty-state/index.d.ts +2 -0
- package/dist/components/field/field.cjs +106 -11
- package/dist/components/field/field.cjs.map +1 -1
- package/dist/components/field/field.d.cts +22 -4
- package/dist/components/field/field.d.ts +22 -4
- package/dist/components/field/field.js +107 -13
- package/dist/components/field/field.js.map +1 -1
- package/dist/components/field/index.d.cts +2 -2
- package/dist/components/field/index.d.ts +2 -2
- package/dist/components/icon-button/icon-button.cjs +40 -0
- package/dist/components/icon-button/icon-button.cjs.map +1 -0
- package/dist/components/icon-button/icon-button.d.cts +12 -0
- package/dist/components/icon-button/icon-button.d.ts +12 -0
- package/dist/components/icon-button/icon-button.js +40 -0
- package/dist/components/icon-button/icon-button.js.map +1 -0
- package/dist/components/icon-button/index.d.cts +2 -0
- package/dist/components/icon-button/index.d.ts +2 -0
- package/dist/components/input-group/index.d.cts +2 -0
- package/dist/components/input-group/index.d.ts +2 -0
- package/dist/components/input-group/input-group.cjs +32 -0
- package/dist/components/input-group/input-group.cjs.map +1 -0
- package/dist/components/input-group/input-group.d.cts +15 -0
- package/dist/components/input-group/input-group.d.ts +15 -0
- package/dist/components/input-group/input-group.js +30 -0
- package/dist/components/input-group/input-group.js.map +1 -0
- package/dist/components/pin-input/index.d.cts +2 -0
- package/dist/components/pin-input/index.d.ts +2 -0
- package/dist/components/pin-input/pin-input.cjs +266 -0
- package/dist/components/pin-input/pin-input.cjs.map +1 -0
- package/dist/components/pin-input/pin-input.d.cts +46 -0
- package/dist/components/pin-input/pin-input.d.ts +46 -0
- package/dist/components/pin-input/pin-input.js +258 -0
- package/dist/components/pin-input/pin-input.js.map +1 -0
- package/dist/components/select/index.d.cts +2 -2
- package/dist/components/select/index.d.ts +2 -2
- package/dist/components/select/select.cjs +80 -3
- package/dist/components/select/select.cjs.map +1 -1
- package/dist/components/select/select.d.cts +18 -3
- package/dist/components/select/select.d.ts +18 -3
- package/dist/components/select/select.js +78 -5
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/tags-input/tags-input.cjs +83 -5
- package/dist/components/tags-input/tags-input.cjs.map +1 -1
- package/dist/components/tags-input/tags-input.d.cts +3 -0
- package/dist/components/tags-input/tags-input.d.ts +3 -0
- package/dist/components/tags-input/tags-input.js +83 -5
- package/dist/components/tags-input/tags-input.js.map +1 -1
- package/dist/components/upload/index.d.cts +2 -2
- package/dist/components/upload/index.d.ts +2 -2
- package/dist/components/upload/upload.cjs +90 -10
- package/dist/components/upload/upload.cjs.map +1 -1
- package/dist/components/upload/upload.d.cts +25 -2
- package/dist/components/upload/upload.d.ts +25 -2
- package/dist/components/upload/upload.js +89 -11
- package/dist/components/upload/upload.js.map +1 -1
- package/dist/index.cjs +70 -0
- package/dist/index.d.cts +21 -5
- package/dist/index.d.ts +21 -5
- package/dist/index.js +13 -5
- package/dist/styled-system/recipes/button-group.cjs +30 -0
- package/dist/styled-system/recipes/button-group.cjs.map +1 -0
- package/dist/styled-system/recipes/button-group.js +30 -0
- package/dist/styled-system/recipes/button-group.js.map +1 -0
- package/dist/styled-system/recipes/calendar.cjs +43 -0
- package/dist/styled-system/recipes/calendar.cjs.map +1 -0
- package/dist/styled-system/recipes/calendar.js +43 -0
- package/dist/styled-system/recipes/calendar.js.map +1 -0
- package/dist/styled-system/recipes/combobox.cjs +1 -0
- package/dist/styled-system/recipes/combobox.cjs.map +1 -1
- package/dist/styled-system/recipes/combobox.js +1 -0
- package/dist/styled-system/recipes/combobox.js.map +1 -1
- package/dist/styled-system/recipes/date-range-picker.cjs +52 -0
- package/dist/styled-system/recipes/date-range-picker.cjs.map +1 -0
- package/dist/styled-system/recipes/date-range-picker.js +52 -0
- package/dist/styled-system/recipes/date-range-picker.js.map +1 -0
- package/dist/styled-system/recipes/empty-state.cjs +36 -0
- package/dist/styled-system/recipes/empty-state.cjs.map +1 -0
- package/dist/styled-system/recipes/empty-state.js +36 -0
- package/dist/styled-system/recipes/empty-state.js.map +1 -0
- package/dist/styled-system/recipes/icon-button.cjs +40 -0
- package/dist/styled-system/recipes/icon-button.cjs.map +1 -0
- package/dist/styled-system/recipes/icon-button.js +40 -0
- package/dist/styled-system/recipes/icon-button.js.map +1 -0
- package/dist/styled-system/recipes/input-group.cjs +30 -0
- package/dist/styled-system/recipes/input-group.cjs.map +1 -0
- package/dist/styled-system/recipes/input-group.js +30 -0
- package/dist/styled-system/recipes/input-group.js.map +1 -0
- package/dist/styled-system/recipes/pin-input.cjs +39 -0
- package/dist/styled-system/recipes/pin-input.cjs.map +1 -0
- package/dist/styled-system/recipes/pin-input.js +39 -0
- package/dist/styled-system/recipes/pin-input.js.map +1 -0
- package/dist/styled-system/recipes/select.cjs +5 -1
- package/dist/styled-system/recipes/select.cjs.map +1 -1
- package/dist/styled-system/recipes/select.js +5 -1
- package/dist/styled-system/recipes/select.js.map +1 -1
- package/dist/styled-system/recipes/upload.cjs +2 -0
- package/dist/styled-system/recipes/upload.cjs.map +1 -1
- package/dist/styled-system/recipes/upload.js +2 -0
- package/dist/styled-system/recipes/upload.js.map +1 -1
- package/dist/styles/theme.cjs +15 -0
- package/dist/styles/theme.cjs.map +1 -1
- package/dist/styles/theme.js +15 -0
- package/dist/styles/theme.js.map +1 -1
- package/dist/styles.css +901 -46
- package/dist/theme/index.d.cts +2 -0
- package/dist/theme/index.d.ts +2 -0
- package/dist/theme/theme-provider.cjs +86 -0
- package/dist/theme/theme-provider.cjs.map +1 -0
- package/dist/theme/theme-provider.d.cts +66 -0
- package/dist/theme/theme-provider.d.ts +66 -0
- package/dist/theme/theme-provider.js +85 -0
- package/dist/theme/theme-provider.js.map +1 -0
- package/package.json +3 -2
|
@@ -18,12 +18,24 @@ function changedEvent(event, value) {
|
|
|
18
18
|
target: nextTarget
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
function tagKey(tag, index) {
|
|
22
|
+
return `${tag}-${index}`;
|
|
23
|
+
}
|
|
24
|
+
function hasDelimiter(value, delimiter) {
|
|
25
|
+
if (typeof delimiter === "string") return delimiter.length > 0 && value.includes(delimiter);
|
|
26
|
+
delimiter.lastIndex = 0;
|
|
27
|
+
const result = delimiter.test(value);
|
|
28
|
+
delimiter.lastIndex = 0;
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
const TagsInput = (0, react.forwardRef)(function TagsInput({ "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, allowDuplicates = false, className, data = [], defaultTags = [], defaultValue = "", disabled = false, delimiter = /[,\n]/u, editable = false, id: providedId, label, onBlur, onChange, onFocus, onInputValueChange, onTagsChange, placeholder, tags: controlledTags, value: controlledInputValue, ...props }, ref) {
|
|
22
32
|
const generatedId = (0, react.useId)();
|
|
23
33
|
const id = providedId ?? generatedId;
|
|
24
34
|
const [uncontrolledTags, setUncontrolledTags] = (0, react.useState)(() => [...defaultTags]);
|
|
25
35
|
const [uncontrolledInputValue, setUncontrolledInputValue] = (0, react.useState)(defaultValue);
|
|
26
36
|
const [focused, setFocused] = (0, react.useState)(false);
|
|
37
|
+
const [composing, setComposing] = (0, react.useState)(false);
|
|
38
|
+
const [editingTag, setEditingTag] = (0, react.useState)(null);
|
|
27
39
|
const rootRef = (0, react.useRef)(null);
|
|
28
40
|
const styles = require_tags_input.tagsInput();
|
|
29
41
|
const selectedTags = controlledTags === void 0 ? uncontrolledTags : [...controlledTags];
|
|
@@ -43,11 +55,38 @@ const TagsInput = (0, react.forwardRef)(function TagsInput({ "aria-describedby":
|
|
|
43
55
|
]);
|
|
44
56
|
const addTag = (0, react.useCallback)((rawTag, event) => {
|
|
45
57
|
const tag = rawTag.trim();
|
|
46
|
-
|
|
58
|
+
const isAllowed = data.length === 0 || data.includes(tag);
|
|
59
|
+
const duplicate = selectedTags.includes(tag);
|
|
60
|
+
if (tag && isAllowed && (allowDuplicates || !duplicate)) if (editingTag) {
|
|
61
|
+
updateTags([
|
|
62
|
+
...selectedTags.slice(0, editingTag.index),
|
|
63
|
+
tag,
|
|
64
|
+
...selectedTags.slice(editingTag.index)
|
|
65
|
+
]);
|
|
66
|
+
setEditingTag(null);
|
|
67
|
+
} else updateTags([...selectedTags, tag]);
|
|
68
|
+
else if (editingTag) return;
|
|
69
|
+
clearInput(event);
|
|
70
|
+
}, [
|
|
71
|
+
allowDuplicates,
|
|
72
|
+
clearInput,
|
|
73
|
+
data,
|
|
74
|
+
editingTag,
|
|
75
|
+
selectedTags,
|
|
76
|
+
updateTags
|
|
77
|
+
]);
|
|
78
|
+
const addDelimited = (0, react.useCallback)((rawValue, event) => {
|
|
79
|
+
const separator = typeof delimiter === "string" && delimiter.length === 0 ? /\r?\n/u : delimiter;
|
|
80
|
+
const values = rawValue.split(separator).map((value) => value.trim()).filter(Boolean);
|
|
81
|
+
const nextTags = [...selectedTags];
|
|
82
|
+
for (const value of values) if ((data.length === 0 || data.includes(value)) && (allowDuplicates || !nextTags.includes(value))) nextTags.push(value);
|
|
83
|
+
if (nextTags.length !== selectedTags.length) updateTags(nextTags);
|
|
47
84
|
clearInput(event);
|
|
48
85
|
}, [
|
|
86
|
+
allowDuplicates,
|
|
49
87
|
clearInput,
|
|
50
88
|
data,
|
|
89
|
+
delimiter,
|
|
51
90
|
selectedTags,
|
|
52
91
|
updateTags
|
|
53
92
|
]);
|
|
@@ -66,8 +105,8 @@ const TagsInput = (0, react.forwardRef)(function TagsInput({ "aria-describedby":
|
|
|
66
105
|
onChange?.(event);
|
|
67
106
|
return;
|
|
68
107
|
}
|
|
69
|
-
if (nextValue
|
|
70
|
-
|
|
108
|
+
if (!composing && hasDelimiter(nextValue, delimiter)) {
|
|
109
|
+
addDelimited(nextValue, event);
|
|
71
110
|
return;
|
|
72
111
|
}
|
|
73
112
|
if (controlledInputValue === void 0) setUncontrolledInputValue(nextValue);
|
|
@@ -78,6 +117,41 @@ const TagsInput = (0, react.forwardRef)(function TagsInput({ "aria-describedby":
|
|
|
78
117
|
setFocused(false);
|
|
79
118
|
onBlur?.(event);
|
|
80
119
|
}
|
|
120
|
+
function handlePaste(event) {
|
|
121
|
+
const pasted = event.clipboardData.getData("text");
|
|
122
|
+
if (!pasted || !hasDelimiter(pasted, delimiter) && !pasted.includes("\n")) return;
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
addDelimited(pasted);
|
|
125
|
+
}
|
|
126
|
+
function handleKeyDown(event) {
|
|
127
|
+
if (event.nativeEvent.isComposing || composing) return;
|
|
128
|
+
if (event.key === "Enter") {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
if (inputValue.trim()) addTag(inputValue);
|
|
131
|
+
else if (editingTag) setEditingTag(null);
|
|
132
|
+
} else if (event.key === "Escape" && editingTag) {
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
updateTags([
|
|
135
|
+
...selectedTags.slice(0, editingTag.index),
|
|
136
|
+
editingTag.value,
|
|
137
|
+
...selectedTags.slice(editingTag.index)
|
|
138
|
+
]);
|
|
139
|
+
clearInput();
|
|
140
|
+
setEditingTag(null);
|
|
141
|
+
} else if (event.key === "Backspace" && !inputValue && editable && selectedTags.length > 0) {
|
|
142
|
+
const index = selectedTags.length - 1;
|
|
143
|
+
const tag = selectedTags[index];
|
|
144
|
+
if (tag === void 0) return;
|
|
145
|
+
setEditingTag({
|
|
146
|
+
index,
|
|
147
|
+
value: tag
|
|
148
|
+
});
|
|
149
|
+
updateTags(selectedTags.slice(0, -1));
|
|
150
|
+
if (controlledInputValue === void 0) setUncontrolledInputValue(tag);
|
|
151
|
+
onInputValueChange?.(tag);
|
|
152
|
+
}
|
|
153
|
+
props.onKeyDown?.(event);
|
|
154
|
+
}
|
|
81
155
|
function removeTag(index) {
|
|
82
156
|
updateTags(selectedTags.filter((_, currentIndex) => currentIndex !== index));
|
|
83
157
|
}
|
|
@@ -117,7 +191,7 @@ const TagsInput = (0, react.forwardRef)(function TagsInput({ "aria-describedby":
|
|
|
117
191
|
type: "button",
|
|
118
192
|
children: "×"
|
|
119
193
|
})]
|
|
120
|
-
}, tag))
|
|
194
|
+
}, tagKey(tag, index)))
|
|
121
195
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
122
196
|
...props,
|
|
123
197
|
...ariaDescribedBy ? { "aria-describedby": ariaDescribedBy } : {},
|
|
@@ -129,10 +203,14 @@ const TagsInput = (0, react.forwardRef)(function TagsInput({ "aria-describedby":
|
|
|
129
203
|
id,
|
|
130
204
|
onBlur: handleBlur,
|
|
131
205
|
onChange: handleChange,
|
|
206
|
+
onCompositionEnd: () => setComposing(false),
|
|
207
|
+
onCompositionStart: () => setComposing(true),
|
|
132
208
|
onFocus: (event) => {
|
|
133
209
|
setFocused(true);
|
|
134
210
|
onFocus?.(event);
|
|
135
211
|
},
|
|
212
|
+
onKeyDown: handleKeyDown,
|
|
213
|
+
onPaste: handlePaste,
|
|
136
214
|
placeholder,
|
|
137
215
|
ref,
|
|
138
216
|
type: "text",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags-input.cjs","names":["tagsInput","cx"],"sources":["../../../src/components/tags-input/tags-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback, useId, useMemo, useRef, useState } from \"react\";\nimport type {\n ChangeEvent,\n ChangeEventHandler,\n ComponentPropsWithoutRef,\n FocusEvent,\n MouseEvent,\n ReactNode,\n} from \"react\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { tagsInput } from \"../../styled-system/recipes\";\n\nexport interface TagsInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"children\" | \"defaultValue\" | \"onChange\" | \"type\" | \"value\"\n > {\n /** Current tags. Omit this prop to use the uncontrolled API. */\n tags?: readonly string[];\n /** Initial tags for the uncontrolled API. */\n defaultTags?: readonly string[];\n /** Called whenever a tag is added or removed. */\n onTagsChange?: (tags: string[]) => void;\n /** Optional suggestions. A tag is accepted after a comma only when it is in this list. */\n data?: readonly string[];\n /** Visible label for the input. */\n label?: ReactNode;\n /** Current text query. This is the native input value, not the selected tags. */\n value?: string;\n /** Initial text query for an uncontrolled input. */\n defaultValue?: string;\n /** Native input change callback. */\n onChange?: ChangeEventHandler<HTMLInputElement>;\n /** Optional callback useful when a controlled query is cleared by selecting a tag. */\n onInputValueChange?: (value: string) => void;\n}\n\nfunction changedEvent(event: ChangeEvent<HTMLInputElement>, value: string) {\n const target = event.target;\n const nextTarget = {\n checked: target.checked,\n id: target.id,\n name: target.name,\n value,\n } as HTMLInputElement;\n\n return {\n ...event,\n currentTarget: nextTarget,\n target: nextTarget,\n } as ChangeEvent<HTMLInputElement>;\n}\n\nexport const TagsInput = forwardRef<HTMLInputElement, TagsInputProps>(function TagsInput(\n {\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n \"aria-label\": ariaLabel,\n className,\n data = [],\n defaultTags = [],\n defaultValue = \"\",\n disabled = false,\n id: providedId,\n label,\n onBlur,\n onChange,\n onFocus,\n onInputValueChange,\n onTagsChange,\n placeholder,\n tags: controlledTags,\n value: controlledInputValue,\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const id = providedId ?? generatedId;\n const [uncontrolledTags, setUncontrolledTags] = useState<string[]>(() => [...defaultTags]);\n const [uncontrolledInputValue, setUncontrolledInputValue] = useState(defaultValue);\n const [focused, setFocused] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n const styles = tagsInput();\n const selectedTags = controlledTags === undefined ? uncontrolledTags : [...controlledTags];\n const inputValue =\n controlledInputValue === undefined ? uncontrolledInputValue : controlledInputValue;\n\n const updateTags = useCallback(\n (nextTags: string[]) => {\n if (controlledTags === undefined) setUncontrolledTags(nextTags);\n onTagsChange?.(nextTags);\n },\n [controlledTags, onTagsChange],\n );\n\n const clearInput = useCallback(\n (event?: ChangeEvent<HTMLInputElement>) => {\n if (controlledInputValue === undefined) setUncontrolledInputValue(\"\");\n onInputValueChange?.(\"\");\n if (event) onChange?.(changedEvent(event, \"\"));\n },\n [controlledInputValue, onChange, onInputValueChange],\n );\n\n const addTag = useCallback(\n (rawTag: string, event?: ChangeEvent<HTMLInputElement>) => {\n const tag = rawTag.trim();\n if (tag && !selectedTags.includes(tag) && data.includes(tag)) {\n updateTags([...selectedTags, tag]);\n }\n clearInput(event);\n },\n [clearInput, data, selectedTags, updateTags],\n );\n\n const suggestions = useMemo(() => {\n const query = inputValue.trim().toLocaleLowerCase();\n return data.filter(\n (item) =>\n !selectedTags.includes(item) &&\n (query.length === 0 || item.toLocaleLowerCase().includes(query)),\n );\n }, [data, inputValue, selectedTags]);\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n const nextValue = event.currentTarget.value;\n if (nextValue.trim() === \"\") {\n clearInput(event);\n onChange?.(event);\n return;\n }\n\n if (nextValue.endsWith(\",\")) {\n addTag(nextValue.slice(0, -1), event);\n return;\n }\n\n if (controlledInputValue === undefined) setUncontrolledInputValue(nextValue);\n onInputValueChange?.(nextValue);\n onChange?.(event);\n }\n\n function handleBlur(event: FocusEvent<HTMLInputElement>) {\n setFocused(false);\n onBlur?.(event);\n }\n\n function removeTag(index: number) {\n updateTags(selectedTags.filter((_, currentIndex) => currentIndex !== index));\n }\n\n return (\n <div\n className={styles.root}\n data-jaci-component=\"tags-input\"\n data-slot=\"tags-input\"\n ref={rootRef}\n >\n {label ? (\n <label className={styles.label} data-slot=\"tags-input-label\" htmlFor={id}>\n {label}\n </label>\n ) : null}\n <div\n className={cx(styles.control, className)}\n data-disabled={disabled || undefined}\n data-focus={focused || undefined}\n data-slot=\"tags-input-control\"\n >\n <div className={styles.tagList} data-slot=\"tags-input-tag-list\">\n {selectedTags.map((tag, index) => (\n <span className={styles.tag} data-slot=\"tags-input-tag\" key={tag}>\n <span className={styles.tagLabel} data-slot=\"tags-input-tag-label\">\n {tag}\n </span>\n <button\n aria-label={`Remove ${tag}`}\n className={styles.tagRemove}\n data-slot=\"tags-input-tag-remove\"\n disabled={disabled}\n onClick={() => removeTag(index)}\n type=\"button\"\n >\n ×\n </button>\n </span>\n ))}\n </div>\n <input\n {...props}\n {...(ariaDescribedBy ? { \"aria-describedby\": ariaDescribedBy } : {})}\n {...(ariaInvalid !== undefined ? { \"aria-invalid\": ariaInvalid } : {})}\n {...(ariaLabel ? { \"aria-label\": ariaLabel } : {})}\n autoComplete=\"off\"\n className={styles.input}\n disabled={disabled}\n id={id}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={(event) => {\n setFocused(true);\n onFocus?.(event);\n }}\n placeholder={placeholder}\n ref={ref}\n type=\"text\"\n value={inputValue}\n />\n </div>\n {focused && data.length > 0 ? (\n <div className={styles.positioner} data-slot=\"tags-input-positioner\">\n <div\n aria-label=\"Suggestions\"\n className={styles.list}\n data-slot=\"tags-input-list\"\n role=\"listbox\"\n >\n {suggestions.length > 0 ? (\n suggestions.map((item) => (\n <button\n aria-selected={false}\n className={styles.item}\n data-slot=\"tags-input-item\"\n key={item}\n onClick={() => addTag(item)}\n onMouseDown={(event: MouseEvent<HTMLButtonElement>) => event.preventDefault()}\n role=\"option\"\n type=\"button\"\n >\n {item}\n </button>\n ))\n ) : (\n <div className={styles.empty} data-slot=\"tags-input-empty\">\n No options\n </div>\n )}\n </div>\n </div>\n ) : null}\n </div>\n );\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tags-input.cjs","names":["tagsInput","cx"],"sources":["../../../src/components/tags-input/tags-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback, useId, useMemo, useRef, useState } from \"react\";\nimport type {\n ChangeEvent,\n ChangeEventHandler,\n ComponentPropsWithoutRef,\n FocusEvent,\n KeyboardEvent,\n MouseEvent,\n ClipboardEvent,\n ReactNode,\n} from \"react\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { tagsInput } from \"../../styled-system/recipes\";\n\nexport interface TagsInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"children\" | \"defaultValue\" | \"onChange\" | \"type\" | \"value\"\n > {\n /** Current tags. Omit this prop to use the uncontrolled API. */\n tags?: readonly string[];\n /** Initial tags for the uncontrolled API. */\n defaultTags?: readonly string[];\n /** Called whenever a tag is added or removed. */\n onTagsChange?: (tags: string[]) => void;\n /** Optional suggestions. A tag is accepted after a comma only when it is in this list. */\n data?: readonly string[];\n /** Visible label for the input. */\n label?: ReactNode;\n /** Current text query. This is the native input value, not the selected tags. */\n value?: string;\n /** Initial text query for an uncontrolled input. */\n defaultValue?: string;\n /** Native input change callback. */\n onChange?: ChangeEventHandler<HTMLInputElement>;\n /** Optional callback useful when a controlled query is cleared by selecting a tag. */\n onInputValueChange?: (value: string) => void;\n allowDuplicates?: boolean;\n delimiter?: string | RegExp;\n editable?: boolean;\n}\n\nfunction changedEvent(event: ChangeEvent<HTMLInputElement>, value: string) {\n const target = event.target;\n const nextTarget = {\n checked: target.checked,\n id: target.id,\n name: target.name,\n value,\n } as HTMLInputElement;\n\n return {\n ...event,\n currentTarget: nextTarget,\n target: nextTarget,\n } as ChangeEvent<HTMLInputElement>;\n}\n\nfunction tagKey(tag: string, index: number) {\n return `${tag}-${index}`;\n}\n\nfunction hasDelimiter(value: string, delimiter: string | RegExp) {\n if (typeof delimiter === \"string\") return delimiter.length > 0 && value.includes(delimiter);\n delimiter.lastIndex = 0;\n const result = delimiter.test(value);\n delimiter.lastIndex = 0;\n return result;\n}\n\nexport const TagsInput = forwardRef<HTMLInputElement, TagsInputProps>(function TagsInput(\n {\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n \"aria-label\": ariaLabel,\n allowDuplicates = false,\n className,\n data = [],\n defaultTags = [],\n defaultValue = \"\",\n disabled = false,\n delimiter = /[,\\n]/u,\n editable = false,\n id: providedId,\n label,\n onBlur,\n onChange,\n onFocus,\n onInputValueChange,\n onTagsChange,\n placeholder,\n tags: controlledTags,\n value: controlledInputValue,\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const id = providedId ?? generatedId;\n const [uncontrolledTags, setUncontrolledTags] = useState<string[]>(() => [...defaultTags]);\n const [uncontrolledInputValue, setUncontrolledInputValue] = useState(defaultValue);\n const [focused, setFocused] = useState(false);\n const [composing, setComposing] = useState(false);\n const [editingTag, setEditingTag] = useState<{ index: number; value: string } | null>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const styles = tagsInput();\n const selectedTags = controlledTags === undefined ? uncontrolledTags : [...controlledTags];\n const inputValue =\n controlledInputValue === undefined ? uncontrolledInputValue : controlledInputValue;\n\n const updateTags = useCallback(\n (nextTags: string[]) => {\n if (controlledTags === undefined) setUncontrolledTags(nextTags);\n onTagsChange?.(nextTags);\n },\n [controlledTags, onTagsChange],\n );\n\n const clearInput = useCallback(\n (event?: ChangeEvent<HTMLInputElement>) => {\n if (controlledInputValue === undefined) setUncontrolledInputValue(\"\");\n onInputValueChange?.(\"\");\n if (event) onChange?.(changedEvent(event, \"\"));\n },\n [controlledInputValue, onChange, onInputValueChange],\n );\n\n const addTag = useCallback(\n (rawTag: string, event?: ChangeEvent<HTMLInputElement>) => {\n const tag = rawTag.trim();\n const isAllowed = data.length === 0 || data.includes(tag);\n const duplicate = selectedTags.includes(tag);\n if (tag && isAllowed && (allowDuplicates || !duplicate)) {\n if (editingTag) {\n updateTags([\n ...selectedTags.slice(0, editingTag.index),\n tag,\n ...selectedTags.slice(editingTag.index),\n ]);\n setEditingTag(null);\n } else {\n updateTags([...selectedTags, tag]);\n }\n } else if (editingTag) {\n return;\n }\n clearInput(event);\n },\n [allowDuplicates, clearInput, data, editingTag, selectedTags, updateTags],\n );\n\n const addDelimited = useCallback(\n (rawValue: string, event?: ChangeEvent<HTMLInputElement>) => {\n const separator =\n typeof delimiter === \"string\" && delimiter.length === 0 ? /\\r?\\n/u : delimiter;\n const values = rawValue\n .split(separator)\n .map((value) => value.trim())\n .filter(Boolean);\n const nextTags = [...selectedTags];\n for (const value of values) {\n const isAllowed = data.length === 0 || data.includes(value);\n if (isAllowed && (allowDuplicates || !nextTags.includes(value))) nextTags.push(value);\n }\n if (nextTags.length !== selectedTags.length) updateTags(nextTags);\n clearInput(event);\n },\n [allowDuplicates, clearInput, data, delimiter, selectedTags, updateTags],\n );\n\n const suggestions = useMemo(() => {\n const query = inputValue.trim().toLocaleLowerCase();\n return data.filter(\n (item) =>\n !selectedTags.includes(item) &&\n (query.length === 0 || item.toLocaleLowerCase().includes(query)),\n );\n }, [data, inputValue, selectedTags]);\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n const nextValue = event.currentTarget.value;\n if (nextValue.trim() === \"\") {\n clearInput(event);\n onChange?.(event);\n return;\n }\n\n if (!composing && hasDelimiter(nextValue, delimiter)) {\n addDelimited(nextValue, event);\n return;\n }\n\n if (controlledInputValue === undefined) setUncontrolledInputValue(nextValue);\n onInputValueChange?.(nextValue);\n onChange?.(event);\n }\n\n function handleBlur(event: FocusEvent<HTMLInputElement>) {\n setFocused(false);\n onBlur?.(event);\n }\n\n function handlePaste(event: ClipboardEvent<HTMLInputElement>) {\n const pasted = event.clipboardData.getData(\"text\");\n if (!pasted || (!hasDelimiter(pasted, delimiter) && !pasted.includes(\"\\n\"))) return;\n event.preventDefault();\n addDelimited(pasted);\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n if (event.nativeEvent.isComposing || composing) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n if (inputValue.trim()) addTag(inputValue);\n else if (editingTag) setEditingTag(null);\n } else if (event.key === \"Escape\" && editingTag) {\n event.preventDefault();\n updateTags([\n ...selectedTags.slice(0, editingTag.index),\n editingTag.value,\n ...selectedTags.slice(editingTag.index),\n ]);\n clearInput();\n setEditingTag(null);\n } else if (event.key === \"Backspace\" && !inputValue && editable && selectedTags.length > 0) {\n const index = selectedTags.length - 1;\n const tag = selectedTags[index];\n if (tag === undefined) return;\n setEditingTag({ index, value: tag });\n updateTags(selectedTags.slice(0, -1));\n if (controlledInputValue === undefined) setUncontrolledInputValue(tag);\n onInputValueChange?.(tag);\n }\n props.onKeyDown?.(event);\n }\n\n function removeTag(index: number) {\n updateTags(selectedTags.filter((_, currentIndex) => currentIndex !== index));\n }\n\n return (\n <div\n className={styles.root}\n data-jaci-component=\"tags-input\"\n data-slot=\"tags-input\"\n ref={rootRef}\n >\n {label ? (\n <label className={styles.label} data-slot=\"tags-input-label\" htmlFor={id}>\n {label}\n </label>\n ) : null}\n <div\n className={cx(styles.control, className)}\n data-disabled={disabled || undefined}\n data-focus={focused || undefined}\n data-slot=\"tags-input-control\"\n >\n <div className={styles.tagList} data-slot=\"tags-input-tag-list\">\n {selectedTags.map((tag, index) => (\n <span className={styles.tag} data-slot=\"tags-input-tag\" key={tagKey(tag, index)}>\n <span className={styles.tagLabel} data-slot=\"tags-input-tag-label\">\n {tag}\n </span>\n <button\n aria-label={`Remove ${tag}`}\n className={styles.tagRemove}\n data-slot=\"tags-input-tag-remove\"\n disabled={disabled}\n onClick={() => removeTag(index)}\n type=\"button\"\n >\n ×\n </button>\n </span>\n ))}\n </div>\n <input\n {...props}\n {...(ariaDescribedBy ? { \"aria-describedby\": ariaDescribedBy } : {})}\n {...(ariaInvalid !== undefined ? { \"aria-invalid\": ariaInvalid } : {})}\n {...(ariaLabel ? { \"aria-label\": ariaLabel } : {})}\n autoComplete=\"off\"\n className={styles.input}\n disabled={disabled}\n id={id}\n onBlur={handleBlur}\n onChange={handleChange}\n onCompositionEnd={() => setComposing(false)}\n onCompositionStart={() => setComposing(true)}\n onFocus={(event) => {\n setFocused(true);\n onFocus?.(event);\n }}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n ref={ref}\n type=\"text\"\n value={inputValue}\n />\n </div>\n {focused && data.length > 0 ? (\n <div className={styles.positioner} data-slot=\"tags-input-positioner\">\n <div\n aria-label=\"Suggestions\"\n className={styles.list}\n data-slot=\"tags-input-list\"\n role=\"listbox\"\n >\n {suggestions.length > 0 ? (\n suggestions.map((item) => (\n <button\n aria-selected={false}\n className={styles.item}\n data-slot=\"tags-input-item\"\n key={item}\n onClick={() => addTag(item)}\n onMouseDown={(event: MouseEvent<HTMLButtonElement>) => event.preventDefault()}\n role=\"option\"\n type=\"button\"\n >\n {item}\n </button>\n ))\n ) : (\n <div className={styles.empty} data-slot=\"tags-input-empty\">\n No options\n </div>\n )}\n </div>\n </div>\n ) : null}\n </div>\n );\n});\n"],"mappings":"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"}
|
|
@@ -19,6 +19,9 @@ interface TagsInputProps extends Omit<ComponentPropsWithoutRef<"input">, "childr
|
|
|
19
19
|
onChange?: ChangeEventHandler<HTMLInputElement>;
|
|
20
20
|
/** Optional callback useful when a controlled query is cleared by selecting a tag. */
|
|
21
21
|
onInputValueChange?: (value: string) => void;
|
|
22
|
+
allowDuplicates?: boolean;
|
|
23
|
+
delimiter?: string | RegExp;
|
|
24
|
+
editable?: boolean;
|
|
22
25
|
}
|
|
23
26
|
declare const TagsInput: import("react").ForwardRefExoticComponent<TagsInputProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
24
27
|
//#endregion
|
|
@@ -19,6 +19,9 @@ interface TagsInputProps extends Omit<ComponentPropsWithoutRef<"input">, "childr
|
|
|
19
19
|
onChange?: ChangeEventHandler<HTMLInputElement>;
|
|
20
20
|
/** Optional callback useful when a controlled query is cleared by selecting a tag. */
|
|
21
21
|
onInputValueChange?: (value: string) => void;
|
|
22
|
+
allowDuplicates?: boolean;
|
|
23
|
+
delimiter?: string | RegExp;
|
|
24
|
+
editable?: boolean;
|
|
22
25
|
}
|
|
23
26
|
declare const TagsInput: import("react").ForwardRefExoticComponent<TagsInputProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
24
27
|
//#endregion
|
|
@@ -18,12 +18,24 @@ function changedEvent(event, value) {
|
|
|
18
18
|
target: nextTarget
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
function tagKey(tag, index) {
|
|
22
|
+
return `${tag}-${index}`;
|
|
23
|
+
}
|
|
24
|
+
function hasDelimiter(value, delimiter) {
|
|
25
|
+
if (typeof delimiter === "string") return delimiter.length > 0 && value.includes(delimiter);
|
|
26
|
+
delimiter.lastIndex = 0;
|
|
27
|
+
const result = delimiter.test(value);
|
|
28
|
+
delimiter.lastIndex = 0;
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
const TagsInput = forwardRef(function TagsInput({ "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, allowDuplicates = false, className, data = [], defaultTags = [], defaultValue = "", disabled = false, delimiter = /[,\n]/u, editable = false, id: providedId, label, onBlur, onChange, onFocus, onInputValueChange, onTagsChange, placeholder, tags: controlledTags, value: controlledInputValue, ...props }, ref) {
|
|
22
32
|
const generatedId = useId();
|
|
23
33
|
const id = providedId ?? generatedId;
|
|
24
34
|
const [uncontrolledTags, setUncontrolledTags] = useState(() => [...defaultTags]);
|
|
25
35
|
const [uncontrolledInputValue, setUncontrolledInputValue] = useState(defaultValue);
|
|
26
36
|
const [focused, setFocused] = useState(false);
|
|
37
|
+
const [composing, setComposing] = useState(false);
|
|
38
|
+
const [editingTag, setEditingTag] = useState(null);
|
|
27
39
|
const rootRef = useRef(null);
|
|
28
40
|
const styles = tagsInput();
|
|
29
41
|
const selectedTags = controlledTags === void 0 ? uncontrolledTags : [...controlledTags];
|
|
@@ -43,11 +55,38 @@ const TagsInput = forwardRef(function TagsInput({ "aria-describedby": ariaDescri
|
|
|
43
55
|
]);
|
|
44
56
|
const addTag = useCallback((rawTag, event) => {
|
|
45
57
|
const tag = rawTag.trim();
|
|
46
|
-
|
|
58
|
+
const isAllowed = data.length === 0 || data.includes(tag);
|
|
59
|
+
const duplicate = selectedTags.includes(tag);
|
|
60
|
+
if (tag && isAllowed && (allowDuplicates || !duplicate)) if (editingTag) {
|
|
61
|
+
updateTags([
|
|
62
|
+
...selectedTags.slice(0, editingTag.index),
|
|
63
|
+
tag,
|
|
64
|
+
...selectedTags.slice(editingTag.index)
|
|
65
|
+
]);
|
|
66
|
+
setEditingTag(null);
|
|
67
|
+
} else updateTags([...selectedTags, tag]);
|
|
68
|
+
else if (editingTag) return;
|
|
69
|
+
clearInput(event);
|
|
70
|
+
}, [
|
|
71
|
+
allowDuplicates,
|
|
72
|
+
clearInput,
|
|
73
|
+
data,
|
|
74
|
+
editingTag,
|
|
75
|
+
selectedTags,
|
|
76
|
+
updateTags
|
|
77
|
+
]);
|
|
78
|
+
const addDelimited = useCallback((rawValue, event) => {
|
|
79
|
+
const separator = typeof delimiter === "string" && delimiter.length === 0 ? /\r?\n/u : delimiter;
|
|
80
|
+
const values = rawValue.split(separator).map((value) => value.trim()).filter(Boolean);
|
|
81
|
+
const nextTags = [...selectedTags];
|
|
82
|
+
for (const value of values) if ((data.length === 0 || data.includes(value)) && (allowDuplicates || !nextTags.includes(value))) nextTags.push(value);
|
|
83
|
+
if (nextTags.length !== selectedTags.length) updateTags(nextTags);
|
|
47
84
|
clearInput(event);
|
|
48
85
|
}, [
|
|
86
|
+
allowDuplicates,
|
|
49
87
|
clearInput,
|
|
50
88
|
data,
|
|
89
|
+
delimiter,
|
|
51
90
|
selectedTags,
|
|
52
91
|
updateTags
|
|
53
92
|
]);
|
|
@@ -66,8 +105,8 @@ const TagsInput = forwardRef(function TagsInput({ "aria-describedby": ariaDescri
|
|
|
66
105
|
onChange?.(event);
|
|
67
106
|
return;
|
|
68
107
|
}
|
|
69
|
-
if (nextValue
|
|
70
|
-
|
|
108
|
+
if (!composing && hasDelimiter(nextValue, delimiter)) {
|
|
109
|
+
addDelimited(nextValue, event);
|
|
71
110
|
return;
|
|
72
111
|
}
|
|
73
112
|
if (controlledInputValue === void 0) setUncontrolledInputValue(nextValue);
|
|
@@ -78,6 +117,41 @@ const TagsInput = forwardRef(function TagsInput({ "aria-describedby": ariaDescri
|
|
|
78
117
|
setFocused(false);
|
|
79
118
|
onBlur?.(event);
|
|
80
119
|
}
|
|
120
|
+
function handlePaste(event) {
|
|
121
|
+
const pasted = event.clipboardData.getData("text");
|
|
122
|
+
if (!pasted || !hasDelimiter(pasted, delimiter) && !pasted.includes("\n")) return;
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
addDelimited(pasted);
|
|
125
|
+
}
|
|
126
|
+
function handleKeyDown(event) {
|
|
127
|
+
if (event.nativeEvent.isComposing || composing) return;
|
|
128
|
+
if (event.key === "Enter") {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
if (inputValue.trim()) addTag(inputValue);
|
|
131
|
+
else if (editingTag) setEditingTag(null);
|
|
132
|
+
} else if (event.key === "Escape" && editingTag) {
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
updateTags([
|
|
135
|
+
...selectedTags.slice(0, editingTag.index),
|
|
136
|
+
editingTag.value,
|
|
137
|
+
...selectedTags.slice(editingTag.index)
|
|
138
|
+
]);
|
|
139
|
+
clearInput();
|
|
140
|
+
setEditingTag(null);
|
|
141
|
+
} else if (event.key === "Backspace" && !inputValue && editable && selectedTags.length > 0) {
|
|
142
|
+
const index = selectedTags.length - 1;
|
|
143
|
+
const tag = selectedTags[index];
|
|
144
|
+
if (tag === void 0) return;
|
|
145
|
+
setEditingTag({
|
|
146
|
+
index,
|
|
147
|
+
value: tag
|
|
148
|
+
});
|
|
149
|
+
updateTags(selectedTags.slice(0, -1));
|
|
150
|
+
if (controlledInputValue === void 0) setUncontrolledInputValue(tag);
|
|
151
|
+
onInputValueChange?.(tag);
|
|
152
|
+
}
|
|
153
|
+
props.onKeyDown?.(event);
|
|
154
|
+
}
|
|
81
155
|
function removeTag(index) {
|
|
82
156
|
updateTags(selectedTags.filter((_, currentIndex) => currentIndex !== index));
|
|
83
157
|
}
|
|
@@ -117,7 +191,7 @@ const TagsInput = forwardRef(function TagsInput({ "aria-describedby": ariaDescri
|
|
|
117
191
|
type: "button",
|
|
118
192
|
children: "×"
|
|
119
193
|
})]
|
|
120
|
-
}, tag))
|
|
194
|
+
}, tagKey(tag, index)))
|
|
121
195
|
}), /* @__PURE__ */ jsx("input", {
|
|
122
196
|
...props,
|
|
123
197
|
...ariaDescribedBy ? { "aria-describedby": ariaDescribedBy } : {},
|
|
@@ -129,10 +203,14 @@ const TagsInput = forwardRef(function TagsInput({ "aria-describedby": ariaDescri
|
|
|
129
203
|
id,
|
|
130
204
|
onBlur: handleBlur,
|
|
131
205
|
onChange: handleChange,
|
|
206
|
+
onCompositionEnd: () => setComposing(false),
|
|
207
|
+
onCompositionStart: () => setComposing(true),
|
|
132
208
|
onFocus: (event) => {
|
|
133
209
|
setFocused(true);
|
|
134
210
|
onFocus?.(event);
|
|
135
211
|
},
|
|
212
|
+
onKeyDown: handleKeyDown,
|
|
213
|
+
onPaste: handlePaste,
|
|
136
214
|
placeholder,
|
|
137
215
|
ref,
|
|
138
216
|
type: "text",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags-input.js","names":[],"sources":["../../../src/components/tags-input/tags-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback, useId, useMemo, useRef, useState } from \"react\";\nimport type {\n ChangeEvent,\n ChangeEventHandler,\n ComponentPropsWithoutRef,\n FocusEvent,\n MouseEvent,\n ReactNode,\n} from \"react\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { tagsInput } from \"../../styled-system/recipes\";\n\nexport interface TagsInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"children\" | \"defaultValue\" | \"onChange\" | \"type\" | \"value\"\n > {\n /** Current tags. Omit this prop to use the uncontrolled API. */\n tags?: readonly string[];\n /** Initial tags for the uncontrolled API. */\n defaultTags?: readonly string[];\n /** Called whenever a tag is added or removed. */\n onTagsChange?: (tags: string[]) => void;\n /** Optional suggestions. A tag is accepted after a comma only when it is in this list. */\n data?: readonly string[];\n /** Visible label for the input. */\n label?: ReactNode;\n /** Current text query. This is the native input value, not the selected tags. */\n value?: string;\n /** Initial text query for an uncontrolled input. */\n defaultValue?: string;\n /** Native input change callback. */\n onChange?: ChangeEventHandler<HTMLInputElement>;\n /** Optional callback useful when a controlled query is cleared by selecting a tag. */\n onInputValueChange?: (value: string) => void;\n}\n\nfunction changedEvent(event: ChangeEvent<HTMLInputElement>, value: string) {\n const target = event.target;\n const nextTarget = {\n checked: target.checked,\n id: target.id,\n name: target.name,\n value,\n } as HTMLInputElement;\n\n return {\n ...event,\n currentTarget: nextTarget,\n target: nextTarget,\n } as ChangeEvent<HTMLInputElement>;\n}\n\nexport const TagsInput = forwardRef<HTMLInputElement, TagsInputProps>(function TagsInput(\n {\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n \"aria-label\": ariaLabel,\n className,\n data = [],\n defaultTags = [],\n defaultValue = \"\",\n disabled = false,\n id: providedId,\n label,\n onBlur,\n onChange,\n onFocus,\n onInputValueChange,\n onTagsChange,\n placeholder,\n tags: controlledTags,\n value: controlledInputValue,\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const id = providedId ?? generatedId;\n const [uncontrolledTags, setUncontrolledTags] = useState<string[]>(() => [...defaultTags]);\n const [uncontrolledInputValue, setUncontrolledInputValue] = useState(defaultValue);\n const [focused, setFocused] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n const styles = tagsInput();\n const selectedTags = controlledTags === undefined ? uncontrolledTags : [...controlledTags];\n const inputValue =\n controlledInputValue === undefined ? uncontrolledInputValue : controlledInputValue;\n\n const updateTags = useCallback(\n (nextTags: string[]) => {\n if (controlledTags === undefined) setUncontrolledTags(nextTags);\n onTagsChange?.(nextTags);\n },\n [controlledTags, onTagsChange],\n );\n\n const clearInput = useCallback(\n (event?: ChangeEvent<HTMLInputElement>) => {\n if (controlledInputValue === undefined) setUncontrolledInputValue(\"\");\n onInputValueChange?.(\"\");\n if (event) onChange?.(changedEvent(event, \"\"));\n },\n [controlledInputValue, onChange, onInputValueChange],\n );\n\n const addTag = useCallback(\n (rawTag: string, event?: ChangeEvent<HTMLInputElement>) => {\n const tag = rawTag.trim();\n if (tag && !selectedTags.includes(tag) && data.includes(tag)) {\n updateTags([...selectedTags, tag]);\n }\n clearInput(event);\n },\n [clearInput, data, selectedTags, updateTags],\n );\n\n const suggestions = useMemo(() => {\n const query = inputValue.trim().toLocaleLowerCase();\n return data.filter(\n (item) =>\n !selectedTags.includes(item) &&\n (query.length === 0 || item.toLocaleLowerCase().includes(query)),\n );\n }, [data, inputValue, selectedTags]);\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n const nextValue = event.currentTarget.value;\n if (nextValue.trim() === \"\") {\n clearInput(event);\n onChange?.(event);\n return;\n }\n\n if (nextValue.endsWith(\",\")) {\n addTag(nextValue.slice(0, -1), event);\n return;\n }\n\n if (controlledInputValue === undefined) setUncontrolledInputValue(nextValue);\n onInputValueChange?.(nextValue);\n onChange?.(event);\n }\n\n function handleBlur(event: FocusEvent<HTMLInputElement>) {\n setFocused(false);\n onBlur?.(event);\n }\n\n function removeTag(index: number) {\n updateTags(selectedTags.filter((_, currentIndex) => currentIndex !== index));\n }\n\n return (\n <div\n className={styles.root}\n data-jaci-component=\"tags-input\"\n data-slot=\"tags-input\"\n ref={rootRef}\n >\n {label ? (\n <label className={styles.label} data-slot=\"tags-input-label\" htmlFor={id}>\n {label}\n </label>\n ) : null}\n <div\n className={cx(styles.control, className)}\n data-disabled={disabled || undefined}\n data-focus={focused || undefined}\n data-slot=\"tags-input-control\"\n >\n <div className={styles.tagList} data-slot=\"tags-input-tag-list\">\n {selectedTags.map((tag, index) => (\n <span className={styles.tag} data-slot=\"tags-input-tag\" key={tag}>\n <span className={styles.tagLabel} data-slot=\"tags-input-tag-label\">\n {tag}\n </span>\n <button\n aria-label={`Remove ${tag}`}\n className={styles.tagRemove}\n data-slot=\"tags-input-tag-remove\"\n disabled={disabled}\n onClick={() => removeTag(index)}\n type=\"button\"\n >\n ×\n </button>\n </span>\n ))}\n </div>\n <input\n {...props}\n {...(ariaDescribedBy ? { \"aria-describedby\": ariaDescribedBy } : {})}\n {...(ariaInvalid !== undefined ? { \"aria-invalid\": ariaInvalid } : {})}\n {...(ariaLabel ? { \"aria-label\": ariaLabel } : {})}\n autoComplete=\"off\"\n className={styles.input}\n disabled={disabled}\n id={id}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={(event) => {\n setFocused(true);\n onFocus?.(event);\n }}\n placeholder={placeholder}\n ref={ref}\n type=\"text\"\n value={inputValue}\n />\n </div>\n {focused && data.length > 0 ? (\n <div className={styles.positioner} data-slot=\"tags-input-positioner\">\n <div\n aria-label=\"Suggestions\"\n className={styles.list}\n data-slot=\"tags-input-list\"\n role=\"listbox\"\n >\n {suggestions.length > 0 ? (\n suggestions.map((item) => (\n <button\n aria-selected={false}\n className={styles.item}\n data-slot=\"tags-input-item\"\n key={item}\n onClick={() => addTag(item)}\n onMouseDown={(event: MouseEvent<HTMLButtonElement>) => event.preventDefault()}\n role=\"option\"\n type=\"button\"\n >\n {item}\n </button>\n ))\n ) : (\n <div className={styles.empty} data-slot=\"tags-input-empty\">\n No options\n </div>\n )}\n </div>\n </div>\n ) : null}\n </div>\n );\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tags-input.js","names":[],"sources":["../../../src/components/tags-input/tags-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback, useId, useMemo, useRef, useState } from \"react\";\nimport type {\n ChangeEvent,\n ChangeEventHandler,\n ComponentPropsWithoutRef,\n FocusEvent,\n KeyboardEvent,\n MouseEvent,\n ClipboardEvent,\n ReactNode,\n} from \"react\";\n\nimport { cx } from \"../../styled-system/css\";\nimport { tagsInput } from \"../../styled-system/recipes\";\n\nexport interface TagsInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"children\" | \"defaultValue\" | \"onChange\" | \"type\" | \"value\"\n > {\n /** Current tags. Omit this prop to use the uncontrolled API. */\n tags?: readonly string[];\n /** Initial tags for the uncontrolled API. */\n defaultTags?: readonly string[];\n /** Called whenever a tag is added or removed. */\n onTagsChange?: (tags: string[]) => void;\n /** Optional suggestions. A tag is accepted after a comma only when it is in this list. */\n data?: readonly string[];\n /** Visible label for the input. */\n label?: ReactNode;\n /** Current text query. This is the native input value, not the selected tags. */\n value?: string;\n /** Initial text query for an uncontrolled input. */\n defaultValue?: string;\n /** Native input change callback. */\n onChange?: ChangeEventHandler<HTMLInputElement>;\n /** Optional callback useful when a controlled query is cleared by selecting a tag. */\n onInputValueChange?: (value: string) => void;\n allowDuplicates?: boolean;\n delimiter?: string | RegExp;\n editable?: boolean;\n}\n\nfunction changedEvent(event: ChangeEvent<HTMLInputElement>, value: string) {\n const target = event.target;\n const nextTarget = {\n checked: target.checked,\n id: target.id,\n name: target.name,\n value,\n } as HTMLInputElement;\n\n return {\n ...event,\n currentTarget: nextTarget,\n target: nextTarget,\n } as ChangeEvent<HTMLInputElement>;\n}\n\nfunction tagKey(tag: string, index: number) {\n return `${tag}-${index}`;\n}\n\nfunction hasDelimiter(value: string, delimiter: string | RegExp) {\n if (typeof delimiter === \"string\") return delimiter.length > 0 && value.includes(delimiter);\n delimiter.lastIndex = 0;\n const result = delimiter.test(value);\n delimiter.lastIndex = 0;\n return result;\n}\n\nexport const TagsInput = forwardRef<HTMLInputElement, TagsInputProps>(function TagsInput(\n {\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": ariaInvalid,\n \"aria-label\": ariaLabel,\n allowDuplicates = false,\n className,\n data = [],\n defaultTags = [],\n defaultValue = \"\",\n disabled = false,\n delimiter = /[,\\n]/u,\n editable = false,\n id: providedId,\n label,\n onBlur,\n onChange,\n onFocus,\n onInputValueChange,\n onTagsChange,\n placeholder,\n tags: controlledTags,\n value: controlledInputValue,\n ...props\n },\n ref,\n) {\n const generatedId = useId();\n const id = providedId ?? generatedId;\n const [uncontrolledTags, setUncontrolledTags] = useState<string[]>(() => [...defaultTags]);\n const [uncontrolledInputValue, setUncontrolledInputValue] = useState(defaultValue);\n const [focused, setFocused] = useState(false);\n const [composing, setComposing] = useState(false);\n const [editingTag, setEditingTag] = useState<{ index: number; value: string } | null>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const styles = tagsInput();\n const selectedTags = controlledTags === undefined ? uncontrolledTags : [...controlledTags];\n const inputValue =\n controlledInputValue === undefined ? uncontrolledInputValue : controlledInputValue;\n\n const updateTags = useCallback(\n (nextTags: string[]) => {\n if (controlledTags === undefined) setUncontrolledTags(nextTags);\n onTagsChange?.(nextTags);\n },\n [controlledTags, onTagsChange],\n );\n\n const clearInput = useCallback(\n (event?: ChangeEvent<HTMLInputElement>) => {\n if (controlledInputValue === undefined) setUncontrolledInputValue(\"\");\n onInputValueChange?.(\"\");\n if (event) onChange?.(changedEvent(event, \"\"));\n },\n [controlledInputValue, onChange, onInputValueChange],\n );\n\n const addTag = useCallback(\n (rawTag: string, event?: ChangeEvent<HTMLInputElement>) => {\n const tag = rawTag.trim();\n const isAllowed = data.length === 0 || data.includes(tag);\n const duplicate = selectedTags.includes(tag);\n if (tag && isAllowed && (allowDuplicates || !duplicate)) {\n if (editingTag) {\n updateTags([\n ...selectedTags.slice(0, editingTag.index),\n tag,\n ...selectedTags.slice(editingTag.index),\n ]);\n setEditingTag(null);\n } else {\n updateTags([...selectedTags, tag]);\n }\n } else if (editingTag) {\n return;\n }\n clearInput(event);\n },\n [allowDuplicates, clearInput, data, editingTag, selectedTags, updateTags],\n );\n\n const addDelimited = useCallback(\n (rawValue: string, event?: ChangeEvent<HTMLInputElement>) => {\n const separator =\n typeof delimiter === \"string\" && delimiter.length === 0 ? /\\r?\\n/u : delimiter;\n const values = rawValue\n .split(separator)\n .map((value) => value.trim())\n .filter(Boolean);\n const nextTags = [...selectedTags];\n for (const value of values) {\n const isAllowed = data.length === 0 || data.includes(value);\n if (isAllowed && (allowDuplicates || !nextTags.includes(value))) nextTags.push(value);\n }\n if (nextTags.length !== selectedTags.length) updateTags(nextTags);\n clearInput(event);\n },\n [allowDuplicates, clearInput, data, delimiter, selectedTags, updateTags],\n );\n\n const suggestions = useMemo(() => {\n const query = inputValue.trim().toLocaleLowerCase();\n return data.filter(\n (item) =>\n !selectedTags.includes(item) &&\n (query.length === 0 || item.toLocaleLowerCase().includes(query)),\n );\n }, [data, inputValue, selectedTags]);\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n const nextValue = event.currentTarget.value;\n if (nextValue.trim() === \"\") {\n clearInput(event);\n onChange?.(event);\n return;\n }\n\n if (!composing && hasDelimiter(nextValue, delimiter)) {\n addDelimited(nextValue, event);\n return;\n }\n\n if (controlledInputValue === undefined) setUncontrolledInputValue(nextValue);\n onInputValueChange?.(nextValue);\n onChange?.(event);\n }\n\n function handleBlur(event: FocusEvent<HTMLInputElement>) {\n setFocused(false);\n onBlur?.(event);\n }\n\n function handlePaste(event: ClipboardEvent<HTMLInputElement>) {\n const pasted = event.clipboardData.getData(\"text\");\n if (!pasted || (!hasDelimiter(pasted, delimiter) && !pasted.includes(\"\\n\"))) return;\n event.preventDefault();\n addDelimited(pasted);\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n if (event.nativeEvent.isComposing || composing) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n if (inputValue.trim()) addTag(inputValue);\n else if (editingTag) setEditingTag(null);\n } else if (event.key === \"Escape\" && editingTag) {\n event.preventDefault();\n updateTags([\n ...selectedTags.slice(0, editingTag.index),\n editingTag.value,\n ...selectedTags.slice(editingTag.index),\n ]);\n clearInput();\n setEditingTag(null);\n } else if (event.key === \"Backspace\" && !inputValue && editable && selectedTags.length > 0) {\n const index = selectedTags.length - 1;\n const tag = selectedTags[index];\n if (tag === undefined) return;\n setEditingTag({ index, value: tag });\n updateTags(selectedTags.slice(0, -1));\n if (controlledInputValue === undefined) setUncontrolledInputValue(tag);\n onInputValueChange?.(tag);\n }\n props.onKeyDown?.(event);\n }\n\n function removeTag(index: number) {\n updateTags(selectedTags.filter((_, currentIndex) => currentIndex !== index));\n }\n\n return (\n <div\n className={styles.root}\n data-jaci-component=\"tags-input\"\n data-slot=\"tags-input\"\n ref={rootRef}\n >\n {label ? (\n <label className={styles.label} data-slot=\"tags-input-label\" htmlFor={id}>\n {label}\n </label>\n ) : null}\n <div\n className={cx(styles.control, className)}\n data-disabled={disabled || undefined}\n data-focus={focused || undefined}\n data-slot=\"tags-input-control\"\n >\n <div className={styles.tagList} data-slot=\"tags-input-tag-list\">\n {selectedTags.map((tag, index) => (\n <span className={styles.tag} data-slot=\"tags-input-tag\" key={tagKey(tag, index)}>\n <span className={styles.tagLabel} data-slot=\"tags-input-tag-label\">\n {tag}\n </span>\n <button\n aria-label={`Remove ${tag}`}\n className={styles.tagRemove}\n data-slot=\"tags-input-tag-remove\"\n disabled={disabled}\n onClick={() => removeTag(index)}\n type=\"button\"\n >\n ×\n </button>\n </span>\n ))}\n </div>\n <input\n {...props}\n {...(ariaDescribedBy ? { \"aria-describedby\": ariaDescribedBy } : {})}\n {...(ariaInvalid !== undefined ? { \"aria-invalid\": ariaInvalid } : {})}\n {...(ariaLabel ? { \"aria-label\": ariaLabel } : {})}\n autoComplete=\"off\"\n className={styles.input}\n disabled={disabled}\n id={id}\n onBlur={handleBlur}\n onChange={handleChange}\n onCompositionEnd={() => setComposing(false)}\n onCompositionStart={() => setComposing(true)}\n onFocus={(event) => {\n setFocused(true);\n onFocus?.(event);\n }}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n ref={ref}\n type=\"text\"\n value={inputValue}\n />\n </div>\n {focused && data.length > 0 ? (\n <div className={styles.positioner} data-slot=\"tags-input-positioner\">\n <div\n aria-label=\"Suggestions\"\n className={styles.list}\n data-slot=\"tags-input-list\"\n role=\"listbox\"\n >\n {suggestions.length > 0 ? (\n suggestions.map((item) => (\n <button\n aria-selected={false}\n className={styles.item}\n data-slot=\"tags-input-item\"\n key={item}\n onClick={() => addTag(item)}\n onMouseDown={(event: MouseEvent<HTMLButtonElement>) => event.preventDefault()}\n role=\"option\"\n type=\"button\"\n >\n {item}\n </button>\n ))\n ) : (\n <div className={styles.empty} data-slot=\"tags-input-empty\">\n No options\n </div>\n )}\n </div>\n </div>\n ) : null}\n </div>\n );\n});\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Upload, UploadDropzone, UploadDropzoneProps, UploadError, UploadErrorProps, UploadHint, UploadHintProps, UploadIcon, UploadIconProps, UploadInput, UploadInputProps, UploadItem, UploadItemProps, UploadList, UploadListProps, UploadPreview, UploadPreviewProps, UploadProgress, UploadProgressProps, UploadRejection, UploadRejectionReason, UploadRemove, UploadRemoveProps, UploadRoot, UploadRootProps, UploadText, UploadTextProps, UploadTrigger, UploadTriggerProps } from "./upload.cjs";
|
|
2
|
-
export { Upload, UploadDropzone, type UploadDropzoneProps, UploadError, type UploadErrorProps, UploadHint, type UploadHintProps, UploadIcon, type UploadIconProps, UploadInput, type UploadInputProps, UploadItem, type UploadItemProps, UploadList, type UploadListProps, UploadPreview, type UploadPreviewProps, UploadProgress, type UploadProgressProps, type UploadRejection, type UploadRejectionReason, UploadRemove, type UploadRemoveProps, UploadRoot, type UploadRootProps, UploadText, type UploadTextProps, UploadTrigger, type UploadTriggerProps };
|
|
1
|
+
import { Upload, UploadCancel, UploadCancelProps, UploadDropzone, UploadDropzoneProps, UploadError, UploadErrorProps, UploadFileState, UploadFileStatus, UploadHint, UploadHintProps, UploadIcon, UploadIconProps, UploadInput, UploadInputProps, UploadItem, UploadItemProps, UploadList, UploadListProps, UploadPreview, UploadPreviewProps, UploadProgress, UploadProgressProps, UploadRejection, UploadRejectionReason, UploadRemove, UploadRemoveProps, UploadRoot, UploadRootProps, UploadStatus, UploadStatusProps, UploadText, UploadTextProps, UploadTrigger, UploadTriggerProps } from "./upload.cjs";
|
|
2
|
+
export { Upload, UploadCancel, type UploadCancelProps, UploadDropzone, type UploadDropzoneProps, UploadError, type UploadErrorProps, type UploadFileState, type UploadFileStatus, UploadHint, type UploadHintProps, UploadIcon, type UploadIconProps, UploadInput, type UploadInputProps, UploadItem, type UploadItemProps, UploadList, type UploadListProps, UploadPreview, type UploadPreviewProps, UploadProgress, type UploadProgressProps, type UploadRejection, type UploadRejectionReason, UploadRemove, type UploadRemoveProps, UploadRoot, type UploadRootProps, UploadStatus, type UploadStatusProps, UploadText, type UploadTextProps, UploadTrigger, type UploadTriggerProps };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Upload, UploadDropzone, UploadDropzoneProps, UploadError, UploadErrorProps, UploadHint, UploadHintProps, UploadIcon, UploadIconProps, UploadInput, UploadInputProps, UploadItem, UploadItemProps, UploadList, UploadListProps, UploadPreview, UploadPreviewProps, UploadProgress, UploadProgressProps, UploadRejection, UploadRejectionReason, UploadRemove, UploadRemoveProps, UploadRoot, UploadRootProps, UploadText, UploadTextProps, UploadTrigger, UploadTriggerProps } from "./upload.js";
|
|
2
|
-
export { Upload, UploadDropzone, type UploadDropzoneProps, UploadError, type UploadErrorProps, UploadHint, type UploadHintProps, UploadIcon, type UploadIconProps, UploadInput, type UploadInputProps, UploadItem, type UploadItemProps, UploadList, type UploadListProps, UploadPreview, type UploadPreviewProps, UploadProgress, type UploadProgressProps, type UploadRejection, type UploadRejectionReason, UploadRemove, type UploadRemoveProps, UploadRoot, type UploadRootProps, UploadText, type UploadTextProps, UploadTrigger, type UploadTriggerProps };
|
|
1
|
+
import { Upload, UploadCancel, UploadCancelProps, UploadDropzone, UploadDropzoneProps, UploadError, UploadErrorProps, UploadFileState, UploadFileStatus, UploadHint, UploadHintProps, UploadIcon, UploadIconProps, UploadInput, UploadInputProps, UploadItem, UploadItemProps, UploadList, UploadListProps, UploadPreview, UploadPreviewProps, UploadProgress, UploadProgressProps, UploadRejection, UploadRejectionReason, UploadRemove, UploadRemoveProps, UploadRoot, UploadRootProps, UploadStatus, UploadStatusProps, UploadText, UploadTextProps, UploadTrigger, UploadTriggerProps } from "./upload.js";
|
|
2
|
+
export { Upload, UploadCancel, type UploadCancelProps, UploadDropzone, type UploadDropzoneProps, UploadError, type UploadErrorProps, type UploadFileState, type UploadFileStatus, UploadHint, type UploadHintProps, UploadIcon, type UploadIconProps, UploadInput, type UploadInputProps, UploadItem, type UploadItemProps, UploadList, type UploadListProps, UploadPreview, type UploadPreviewProps, UploadProgress, type UploadProgressProps, type UploadRejection, type UploadRejectionReason, UploadRemove, type UploadRemoveProps, UploadRoot, type UploadRootProps, UploadStatus, type UploadStatusProps, UploadText, type UploadTextProps, UploadTrigger, type UploadTriggerProps };
|