cursedbelt 5.91.0 → 5.92.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react/activity-bar/activityBar.css +5 -0
- package/dist/react/components/Autocomplete.d.ts +11 -2
- package/dist/react/components/Autocomplete.d.ts.map +1 -1
- package/dist/react/components/Autocomplete.js +7 -6
- package/dist/react/components/Autocomplete.js.map +1 -1
- package/dist/react/components/FileDropZone.d.ts.map +1 -1
- package/dist/react/components/FileDropZone.js +12 -76
- package/dist/react/components/FileDropZone.js.map +1 -1
- package/dist/react/components/TagsInput.d.ts +46 -4
- package/dist/react/components/TagsInput.d.ts.map +1 -1
- package/dist/react/components/TagsInput.js +92 -39
- package/dist/react/components/TagsInput.js.map +1 -1
- package/dist/react/components/TagsInputSuggesting.d.ts +8 -0
- package/dist/react/components/TagsInputSuggesting.d.ts.map +1 -0
- package/dist/react/components/TagsInputSuggesting.js +48 -0
- package/dist/react/components/TagsInputSuggesting.js.map +1 -0
- package/dist/react/components/dropTransfer.d.ts +53 -0
- package/dist/react/components/dropTransfer.d.ts.map +1 -0
- package/dist/react/components/dropTransfer.js +116 -0
- package/dist/react/components/dropTransfer.js.map +1 -0
- package/dist/react/components/suggestionList.d.ts +13 -0
- package/dist/react/components/suggestionList.d.ts.map +1 -0
- package/dist/react/components/suggestionList.js +19 -0
- package/dist/react/components/suggestionList.js.map +1 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/media-gallery/MediaMetaEditor.d.ts +4 -4
- package/dist/react/optimistic/optimistic.d.ts +11 -2
- package/dist/react/optimistic/optimistic.d.ts.map +1 -1
- package/dist/react/optimistic/optimistic.js +4 -2
- package/dist/react/optimistic/optimistic.js.map +1 -1
- package/dist/scripts/guardrailsEnforce.d.ts.map +1 -1
- package/dist/styles-areas/analytics.css +14 -19
- package/dist/styles-areas/auth.css +3 -4
- package/dist/styles-areas/canvas-hud.css +3 -3
- package/dist/styles-areas/chat.css +10 -11
- package/dist/styles-areas/code-editor.css +2 -2
- package/dist/styles-areas/core.css +60 -54
- package/dist/styles-areas/data-table.css +13 -17
- package/dist/styles-areas/disk-usage.css +6 -7
- package/dist/styles-areas/emoji.css +2 -3
- package/dist/styles-areas/fields.css +15 -20
- package/dist/styles-areas/master-detail.css +3 -4
- package/dist/styles-areas/master-lock.css +1 -2
- package/dist/styles-areas/media-gallery.css +8 -10
- package/dist/styles-areas/rich-text.css +3 -3
- package/dist/styles-areas/stats.css +13 -17
- package/dist/styles-areas/wizard.css +6 -11
- package/package.json +7 -1
- package/scripts/guardrails-baseline.json +1 -1
- package/scripts/guardrailsEnforce.spec.ts +13 -0
- package/scripts/guardrailsEnforce.ts +5 -3
- package/scripts/styleAreas.ts +3 -0
- package/src/react/activity-bar/activityBar.css +5 -0
- package/src/react/components/Autocomplete.spec.tsx +55 -1
- package/src/react/components/Autocomplete.tsx +18 -43
- package/src/react/components/FileDropZone.tsx +12 -83
- package/src/react/components/TagsInput.spec.tsx +129 -14
- package/src/react/components/TagsInput.tsx +153 -85
- package/src/react/components/TagsInputSuggesting.tsx +94 -0
- package/src/react/components/dropTransfer.spec.ts +76 -0
- package/src/react/components/dropTransfer.ts +133 -0
- package/src/react/components/suggestionList.tsx +66 -0
- package/src/react/disk-usage/DiskUsage.spec.tsx +3 -0
- package/src/react/index.ts +1 -0
- package/src/react/lib/floatingStyles.spec.ts +2 -1
- package/src/react/media-gallery/MediaMetaEditor.tsx +4 -4
- package/src/react/optimistic/optimistic.spec.tsx +41 -0
- package/src/react/optimistic/optimistic.ts +13 -4
- package/src/styles-areas/analytics.css +14 -19
- package/src/styles-areas/auth.css +3 -4
- package/src/styles-areas/canvas-hud.css +3 -3
- package/src/styles-areas/chat.css +10 -11
- package/src/styles-areas/code-editor.css +2 -2
- package/src/styles-areas/core.css +60 -54
- package/src/styles-areas/data-table.css +13 -17
- package/src/styles-areas/disk-usage.css +6 -7
- package/src/styles-areas/emoji.css +2 -3
- package/src/styles-areas/fields.css +15 -20
- package/src/styles-areas/master-detail.css +3 -4
- package/src/styles-areas/master-lock.css +1 -2
- package/src/styles-areas/media-gallery.css +8 -10
- package/src/styles-areas/rich-text.css +3 -3
- package/src/styles-areas/stats.css +13 -17
- package/src/styles-areas/wizard.css +6 -11
|
@@ -264,6 +264,11 @@
|
|
|
264
264
|
.cbab-slot {
|
|
265
265
|
inline-size: 44px;
|
|
266
266
|
block-size: 44px;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* 12px centers the rail's OWN 20px glyph. A slot holds the consumer's control, which
|
|
270
|
+
`max-inline-size: 100%` would squeeze to that 20px — it gets the whole 44 instead. */
|
|
271
|
+
.cbab-btn {
|
|
267
272
|
padding-inline: 12px;
|
|
268
273
|
}
|
|
269
274
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type InputHTMLAttributes, type ReactNode } from 'react';
|
|
1
|
+
import { type InputHTMLAttributes, type ReactNode, type Ref } from 'react';
|
|
2
2
|
import { type ControlSize } from '../lib/field.js';
|
|
3
3
|
export interface AutocompleteProps<S = string> extends Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'onBlur' | 'placeholder' | 'disabled' | 'id' | 'name' | 'aria-invalid' | 'aria-describedby' | 'className' | 'size'> {
|
|
4
4
|
/** The current text value (controlled). */
|
|
@@ -7,6 +7,13 @@ export interface AutocompleteProps<S = string> extends Omit<InputHTMLAttributes<
|
|
|
7
7
|
onBlur?: () => void;
|
|
8
8
|
/** Static suggestion items shown in the dropdown. */
|
|
9
9
|
suggestions?: S[];
|
|
10
|
+
/**
|
|
11
|
+
* Whether a static suggestion matches what is typed. Default: its text CONTAINS the typed text,
|
|
12
|
+
* any case (Base UI's own match). A field whose value is more than the query — a comma list
|
|
13
|
+
* where each suggestion completes the LAST entry — passes its own. `null` shows them as given.
|
|
14
|
+
* Never applied to {@link loadSuggestions}: the loader's answer already is the search.
|
|
15
|
+
*/
|
|
16
|
+
filter?: ((item: S, query: string) => boolean) | null;
|
|
10
17
|
/** Async fetch — called on every keystroke (debounced 250 ms).
|
|
11
18
|
* When provided, replaces the static `suggestions`. */
|
|
12
19
|
loadSuggestions?: (query: string) => Promise<S[]>;
|
|
@@ -31,6 +38,8 @@ export interface AutocompleteProps<S = string> extends Omit<InputHTMLAttributes<
|
|
|
31
38
|
/** Height on the shared control-height scale (`--control-h-*`, task cbux-41).
|
|
32
39
|
* Default `md`. */
|
|
33
40
|
size?: ControlSize;
|
|
41
|
+
/** The input element — to focus it from a form that names what is missing. */
|
|
42
|
+
inputRef?: Ref<HTMLInputElement>;
|
|
34
43
|
}
|
|
35
44
|
/**
|
|
36
45
|
* Free-text input with a suggestions dropdown, built on Base UI Autocomplete.
|
|
@@ -43,5 +52,5 @@ export interface AutocompleteProps<S = string> extends Omit<InputHTMLAttributes<
|
|
|
43
52
|
* - Object suggestions via `itemToString`, rich rows via `renderSuggestion`
|
|
44
53
|
* - Full keyboard navigation (arrows, Enter to fill, Escape to close)
|
|
45
54
|
*/
|
|
46
|
-
export declare function AutocompleteField<S = string>({ value, onChange, onBlur, suggestions, loadSuggestions, itemToString, renderSuggestion, placeholder, disabled, id, name, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, className, size, ...rest }: AutocompleteProps<S>): import("react").JSX.Element;
|
|
55
|
+
export declare function AutocompleteField<S = string>({ value, onChange, onBlur, suggestions, filter, loadSuggestions, itemToString, renderSuggestion, placeholder, disabled, id, name, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, className, size, inputRef, ...rest }: AutocompleteProps<S>): import("react").JSX.Element;
|
|
47
56
|
//# sourceMappingURL=Autocomplete.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Autocomplete.d.ts","sourceRoot":"","sources":["../../../src/react/components/Autocomplete.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAoC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Autocomplete.d.ts","sourceRoot":"","sources":["../../../src/react/components/Autocomplete.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,EAAoC,MAAM,OAAO,CAAC;AAG7G,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,iBAAiB,CAAC;AAGtE,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAC3C,SAAQ,IAAI,CACV,mBAAmB,CAAC,gBAAgB,CAAC,EACnC,OAAO,GACP,UAAU,GACV,QAAQ,GACR,aAAa,GACb,UAAU,GACV,IAAI,GACJ,MAAM,GACN,cAAc,GACd,kBAAkB,GAClB,WAAW,GACX,MAAM,CACT;IACD,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,qDAAqD;IACrD,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;IAClB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,CAAC;IACtD;4DACwD;IACxD,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAClD;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACnC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;wBACoB;IACpB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAClC;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,MAAM,EAAE,EAC5C,KAAU,EACV,QAAQ,EACR,MAAM,EACN,WAAgB,EAChB,MAAM,EACN,eAAe,EACf,YAAqC,EACrC,gBAAgB,EAChB,WAA+B,EAC/B,QAAQ,EACR,EAAE,EACF,IAAI,EACJ,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,SAAS,EACT,IAAW,EACX,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,iBAAiB,CAAC,CAAC,CAAC,+BA0EtB"}
|
|
@@ -6,7 +6,7 @@ import { useCallback, useEffect, useState } from 'react';
|
|
|
6
6
|
import { useDebouncedCallback } from '../hooks/useDebouncedCallback.js';
|
|
7
7
|
import { cn } from '../lib/cn.js';
|
|
8
8
|
import { fieldControlClass } from '../lib/field.js';
|
|
9
|
-
import {
|
|
9
|
+
import { SuggestionList } from './suggestionList.js';
|
|
10
10
|
const DEBOUNCE_MS = 250;
|
|
11
11
|
/**
|
|
12
12
|
* Free-text input with a suggestions dropdown, built on Base UI Autocomplete.
|
|
@@ -19,7 +19,7 @@ const DEBOUNCE_MS = 250;
|
|
|
19
19
|
* - Object suggestions via `itemToString`, rich rows via `renderSuggestion`
|
|
20
20
|
* - Full keyboard navigation (arrows, Enter to fill, Escape to close)
|
|
21
21
|
*/
|
|
22
|
-
export function AutocompleteField({ value = '', onChange, onBlur, suggestions = [], loadSuggestions, itemToString = (item) => String(item), renderSuggestion, placeholder = 'Type to search…', disabled, id, name, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, className, size = 'md', ...rest }) {
|
|
22
|
+
export function AutocompleteField({ value = '', onChange, onBlur, suggestions = [], filter, loadSuggestions, itemToString = (item) => String(item), renderSuggestion, placeholder = 'Type to search…', disabled, id, name, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, className, size = 'md', inputRef, ...rest }) {
|
|
23
23
|
const isAsync = Boolean(loadSuggestions);
|
|
24
24
|
const [asyncSuggestions, setAsyncSuggestions] = useState([]);
|
|
25
25
|
const [loading, setLoading] = useState(false);
|
|
@@ -47,9 +47,10 @@ export function AutocompleteField({ value = '', onChange, onBlur, suggestions =
|
|
|
47
47
|
const handleValueChange = useCallback((v) => {
|
|
48
48
|
onChange?.(v);
|
|
49
49
|
}, [onChange]);
|
|
50
|
-
return (_jsxs(Autocomplete.Root, { value: value, onValueChange: handleValueChange, items: activeSuggestions, itemToStringValue: itemToString, disabled: disabled, mode: 'list',
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
return (_jsxs(Autocomplete.Root, { value: value, onValueChange: handleValueChange, items: activeSuggestions, itemToStringValue: itemToString, disabled: disabled, mode: 'list',
|
|
51
|
+
// Static suggestions narrow to what is typed (by default Base UI's own match: contains, any
|
|
52
|
+
// case, accents folded). A loader's answer is already the search — drawn as it came.
|
|
53
|
+
filter: isAsync ? null : filter, autoHighlight: false, children: [_jsxs(Autocomplete.InputGroup, { className: 'relative flex items-center', children: [_jsx(Autocomplete.Input, { ...rest, ref: inputRef, id: id, name: name, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, placeholder: placeholder, onBlur: onBlur, className: cn(fieldControlClass(size), 'pr-8', // space for the chevron/spinner
|
|
54
|
+
className) }), _jsx("span", { className: 'pointer-events-none absolute right-2 flex size-5 items-center justify-center text-muted-foreground', children: loading ? (_jsx(Loader2, { className: 'size-4 animate-spin', "aria-label": 'Loading suggestions' })) : (_jsx(ChevronDown, { className: 'size-4 opacity-50', "aria-hidden": true })) })] }), _jsx(SuggestionList, { itemToString: itemToString, renderSuggestion: renderSuggestion })] }));
|
|
54
55
|
}
|
|
55
56
|
//# sourceMappingURL=Autocomplete.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Autocomplete.js","sourceRoot":"","sources":["../../../src/react/components/Autocomplete.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,
|
|
1
|
+
{"version":3,"file":"Autocomplete.js","sourceRoot":"","sources":["../../../src/react/components/Autocomplete.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileDropZone.d.ts","sourceRoot":"","sources":["../../../src/react/components/FileDropZone.tsx"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"FileDropZone.d.ts","sourceRoot":"","sources":["../../../src/react/components/FileDropZone.tsx"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAC;AAMhF,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACjC;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACrC;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAAC,QAAQ,EAAE,IAAI,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAClE,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,UAAU,EACV,MAAM,EAAE,YAAY,EACpB,MAAM,EACN,QAAe,EACf,QAAgB,EAChB,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,MAAgB,EAChB,GAAG,IAAI,EACR,EAAE,iBAAiB,+BAqKnB"}
|
|
@@ -3,96 +3,32 @@ import { Upload, X } from 'lucide-react';
|
|
|
3
3
|
import { useId, useRef, useState } from 'react';
|
|
4
4
|
import { cn } from '../lib/cn.js';
|
|
5
5
|
import { Button } from './Button.js';
|
|
6
|
+
import { isHiddenName, matchesAccept, walkDrop } from './dropTransfer.js';
|
|
6
7
|
import { Input } from './Input.js';
|
|
7
|
-
/** What a folder can hold before walking it stops — a drop, not a disk scan. */
|
|
8
|
-
const MAX_FOLDER_FILES = 5000;
|
|
9
|
-
const isHidden = (name) => name.startsWith('.');
|
|
10
|
-
/**
|
|
11
|
-
* Every file under `entry`, depth-first. A directory's reader answers in batches until empty.
|
|
12
|
-
*
|
|
13
|
-
* Each file carries its path from the dropped folder in `webkitRelativePath` (`Album/CD1/01.mp3`),
|
|
14
|
-
* exactly as a folder PICKER's files do natively — so an app reading provenance (music defaults
|
|
15
|
-
* its "where these came from" field to the top folder) gets the same answer from both gestures.
|
|
16
|
-
* A drop leaves it `''` otherwise, and that difference is what kept music on its own walk.
|
|
17
|
-
*/
|
|
18
|
-
async function filesUnder(entry, out, prefix = '') {
|
|
19
|
-
if (out.length >= MAX_FOLDER_FILES || isHidden(entry.name))
|
|
20
|
-
return;
|
|
21
|
-
if (entry.isFile && entry.file) {
|
|
22
|
-
const read = entry.file.bind(entry);
|
|
23
|
-
const file = await new Promise((ok, fail) => read(ok, fail));
|
|
24
|
-
Object.defineProperty(file, 'webkitRelativePath', { value: `${prefix}${file.name}`, configurable: true });
|
|
25
|
-
out.push(file);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if (!entry.isDirectory || !entry.createReader)
|
|
29
|
-
return;
|
|
30
|
-
const reader = entry.createReader();
|
|
31
|
-
while (out.length < MAX_FOLDER_FILES) {
|
|
32
|
-
const batch = await new Promise((ok, fail) => reader.readEntries(ok, fail));
|
|
33
|
-
if (batch.length === 0)
|
|
34
|
-
return;
|
|
35
|
-
for (const child of batch)
|
|
36
|
-
await filesUnder(child, out, `${prefix}${entry.name}/`);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
8
|
/**
|
|
40
9
|
* A drop's files, with every dropped FOLDER replaced by the accepted files inside it — see the
|
|
41
10
|
* FOLDER section above. `null` when nothing in the drop is a folder, so the ordinary path stays
|
|
42
|
-
* exactly `dataTransfer.files`.
|
|
43
|
-
*
|
|
44
|
-
* 🔴 The entries are taken SYNCHRONOUSLY, before the first `await`: a browser empties the
|
|
45
|
-
* `DataTransfer` once the drop event returns.
|
|
11
|
+
* exactly `dataTransfer.files`. The walk itself is {@link walkDrop}, shared with every app's own
|
|
12
|
+
* drop target through {@link filesFromDataTransfer}.
|
|
46
13
|
*/
|
|
47
14
|
function folderAwareDrop(transfer, accept) {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
? item.webkitGetAsEntry()
|
|
51
|
-
: null);
|
|
52
|
-
if (!entries.some((entry) => entry?.isDirectory))
|
|
15
|
+
const walking = walkDrop(transfer);
|
|
16
|
+
if (!walking)
|
|
53
17
|
return null;
|
|
54
|
-
|
|
55
|
-
return (async () => {
|
|
56
|
-
const loose = [];
|
|
18
|
+
return walking.then(({ loose, folders }) => {
|
|
57
19
|
const fromFolders = [];
|
|
58
20
|
const emptyFolders = [];
|
|
59
|
-
for (const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (file)
|
|
63
|
-
loose.push(file);
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
const inside = [];
|
|
67
|
-
try {
|
|
68
|
-
await filesUnder(entry, inside);
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
// An unreadable folder yields what was read before the error — and, if that is nothing, a refusal below.
|
|
72
|
-
}
|
|
73
|
-
const kept = inside.filter((f) => matchesAccept(f, accept));
|
|
21
|
+
for (const folder of folders) {
|
|
22
|
+
// A folder that yields nothing acceptable is a refusal under its own name, never silence.
|
|
23
|
+
const kept = folder.files.filter((f) => matchesAccept(f, accept));
|
|
74
24
|
if (kept.length > 0)
|
|
75
25
|
fromFolders.push(...kept);
|
|
76
26
|
else
|
|
77
|
-
emptyFolders.push(new File([],
|
|
27
|
+
emptyFolders.push(new File([], folder.name));
|
|
78
28
|
}
|
|
79
29
|
return { loose, fromFolders, emptyFolders };
|
|
80
|
-
})();
|
|
81
|
-
}
|
|
82
|
-
const matchesAccept = (file, accept) => {
|
|
83
|
-
if (!accept)
|
|
84
|
-
return true;
|
|
85
|
-
return accept.split(',').some((raw) => {
|
|
86
|
-
const rule = raw.trim().toLowerCase();
|
|
87
|
-
if (!rule)
|
|
88
|
-
return false;
|
|
89
|
-
if (rule.startsWith('.'))
|
|
90
|
-
return file.name.toLowerCase().endsWith(rule);
|
|
91
|
-
if (rule.endsWith('/*'))
|
|
92
|
-
return file.type.toLowerCase().startsWith(rule.slice(0, -1));
|
|
93
|
-
return file.type.toLowerCase() === rule;
|
|
94
30
|
});
|
|
95
|
-
}
|
|
31
|
+
}
|
|
96
32
|
/**
|
|
97
33
|
* A folder PICKER's files, judged the way a dropped folder's are: what `accept` turns away is
|
|
98
34
|
* skipped, hidden files are never meant, and a folder that yields nothing is refused under its own
|
|
@@ -101,7 +37,7 @@ const matchesAccept = (file, accept) => {
|
|
|
101
37
|
*/
|
|
102
38
|
function folderPick(list, accept) {
|
|
103
39
|
const all = list ? [...list] : [];
|
|
104
|
-
const kept = all.filter((f) => !f.webkitRelativePath.split('/').some(
|
|
40
|
+
const kept = all.filter((f) => !f.webkitRelativePath.split('/').some(isHiddenName) && matchesAccept(f, accept));
|
|
105
41
|
if (kept.length > 0 || all.length === 0)
|
|
106
42
|
return { fromFolders: kept, emptyFolders: [] };
|
|
107
43
|
const name = all[0]?.webkitRelativePath.split('/')[0] || 'That folder';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileDropZone.js","sourceRoot":"","sources":["../../../src/react/components/FileDropZone.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAkC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAChF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"FileDropZone.js","sourceRoot":"","sources":["../../../src/react/components/FileDropZone.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ComponentType, type KeyboardEvent } from 'react';
|
|
1
2
|
import { type ControlSize } from '../lib/field.js';
|
|
2
3
|
export interface TagsInputProps {
|
|
3
4
|
/** The committed tags (controlled). */
|
|
@@ -11,9 +12,14 @@ export interface TagsInputProps {
|
|
|
11
12
|
maxTags?: number;
|
|
12
13
|
/**
|
|
13
14
|
* Tags to offer as you type — the vocabulary already in use, so a re-tag matches
|
|
14
|
-
* the first spelling instead of minting "Bank"/"bank"/"banking" three ways.
|
|
15
|
-
*
|
|
16
|
-
* tags already committed on this value are not re-offered. Omit for none
|
|
15
|
+
* the first spelling instead of minting "Bank"/"bank"/"banking" three ways. Drawn
|
|
16
|
+
* in the page by the kit's own list (Base UI Autocomplete), narrowed to what is
|
|
17
|
+
* typed; tags already committed on this value are not re-offered. Omit for none —
|
|
18
|
+
* and a field that omits it never loads that list's engine (see {@link TagsInput}).
|
|
19
|
+
*
|
|
20
|
+
* 🔴 Never a `<datalist>`: the browser draws its list outside the page, where no
|
|
21
|
+
* stylesheet reaches it — it popped up light in dark mode (owner, 2026-10-23,
|
|
22
|
+
* forge task 3602).
|
|
17
23
|
*/
|
|
18
24
|
suggestions?: readonly string[];
|
|
19
25
|
id?: string;
|
|
@@ -28,12 +34,48 @@ export interface TagsInputProps {
|
|
|
28
34
|
* same `size`; the row grows past it as tags wrap. Default `md`. */
|
|
29
35
|
size?: ControlSize;
|
|
30
36
|
}
|
|
37
|
+
/** What the suggesting field takes beyond the public props: the draft lives in {@link TagsInput},
|
|
38
|
+
* so a word typed before the list's engine arrived is still there after it does. */
|
|
39
|
+
export interface TagsFieldProps extends TagsInputProps {
|
|
40
|
+
draft: string;
|
|
41
|
+
setDraft: (draft: string) => void;
|
|
42
|
+
/** Focus the input on mount — the plain field had it when the engine arrived. */
|
|
43
|
+
initialFocus?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** The editing both fields share: commit, remove, the comma/Enter/Backspace keys, a pasted list. */
|
|
46
|
+
export declare function useTagEditing({ value, onChange, draft, setDraft }: Pick<TagsFieldProps, 'value' | 'onChange' | 'draft' | 'setDraft'>): {
|
|
47
|
+
commit: (raw: string) => void;
|
|
48
|
+
removeAt: (index: number) => void;
|
|
49
|
+
onKeyDown: (e: KeyboardEvent<HTMLInputElement>) => void;
|
|
50
|
+
type: (v: string) => void;
|
|
51
|
+
};
|
|
52
|
+
/** The chip row's frame — an Input-shaped container reading the field tokens. */
|
|
53
|
+
export declare function tagsRowClass(size: ControlSize, disabled: boolean | undefined, className: string | undefined): string;
|
|
54
|
+
export declare const TAGS_INPUT_CLASS = "min-w-24 flex-1 bg-transparent py-0.5 text-base text-field-fg outline-none placeholder:text-field-placeholder sm:pointer-fine:text-sm";
|
|
55
|
+
/** The committed tags as removable chips. */
|
|
56
|
+
export declare function TagChips({ value, disabled, onRemove }: {
|
|
57
|
+
value: string[];
|
|
58
|
+
disabled?: boolean | undefined;
|
|
59
|
+
onRemove: (index: number) => void;
|
|
60
|
+
}): import("react").JSX.Element[];
|
|
61
|
+
type SuggestingField = ComponentType<TagsFieldProps>;
|
|
62
|
+
/** Fetch the suggesting field (Base UI Autocomplete) once per page. */
|
|
63
|
+
export declare function preloadSuggestingTagsInput(): Promise<SuggestingField>;
|
|
31
64
|
/**
|
|
32
65
|
* Comma / Enter-delimited tag input: pill chips inside an Input-shaped container that
|
|
33
66
|
* reads the same field-style tokens (border / ring / invalid). Controlled —
|
|
34
67
|
* `value: string[]`, `onChange(next)`. Type + Enter or comma to add (paste
|
|
35
68
|
* "a,b,c" splits into three); the ✕ on a chip or Backspace on an empty input removes
|
|
36
69
|
* one. Replaces the ad-hoc CommaTagsInput. The registry's `tags` control.
|
|
70
|
+
*
|
|
71
|
+
* ── Why the suggesting field is a dynamic `import()` ─────────────────────────
|
|
72
|
+
* 🔴 Suggestions are drawn by Base UI's Autocomplete, ~38 kB gzip. 5.92.0 rooted EVERY TagsInput
|
|
73
|
+
* in it, so a field that suggests nothing — station's disk-usage rules, every form's `tags`
|
|
74
|
+
* control — carried it: station's FolderSizesView chunk went 7.15 → 44.32 kB gzip (forge task
|
|
75
|
+
* 3614). A field given `suggestions` fetches it on mount (the same move as `InfoHint`); until it
|
|
76
|
+
* arrives — and for good, without `suggestions` — this file's plain input is the field, holding
|
|
77
|
+
* the draft and the focus it hands over.
|
|
37
78
|
*/
|
|
38
|
-
export declare function TagsInput(
|
|
79
|
+
export declare function TagsInput(props: TagsInputProps): import("react").JSX.Element;
|
|
80
|
+
export {};
|
|
39
81
|
//# sourceMappingURL=TagsInput.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagsInput.d.ts","sourceRoot":"","sources":["../../../src/react/components/TagsInput.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TagsInput.d.ts","sourceRoot":"","sources":["../../../src/react/components/TagsInput.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAA+B,MAAM,OAAO,CAAC;AAE5F,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG7E,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACpC,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;yEAEqE;IACrE,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAaD;qFACqF;AACrF,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,iFAAiF;IACjF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,oGAAoG;AACpG,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;kBAC9G,MAAM;sBAKF,MAAM;mBACT,aAAa,CAAC,gBAAgB,CAAC;cASpC,MAAM;EASxB;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,UAU3G;AAED,eAAO,MAAM,gBAAgB,0IAC4G,CAAC;AAE1I,6CAA6C;AAE7C,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,iCAc7I;AAED,KAAK,eAAe,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;AAKrD,uEAAuE;AACvE,wBAAgB,0BAA0B,IAAI,OAAO,CAAC,eAAe,CAAC,CAQrE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,+BA+B9C"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { X } from 'lucide-react';
|
|
3
|
-
import {
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { cn } from '../lib/cn.js';
|
|
5
5
|
import { CONTROL_MIN_HEIGHT_CLASS } from '../lib/field.js';
|
|
6
6
|
import { IconButton } from './IconButton.js';
|
|
@@ -15,22 +15,8 @@ function mergeTags(current, additions) {
|
|
|
15
15
|
}
|
|
16
16
|
return next;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
* reads the same field-style tokens (border / ring / invalid). Controlled —
|
|
21
|
-
* `value: string[]`, `onChange(next)`. Type + Enter or comma to add (paste
|
|
22
|
-
* "a,b,c" splits into three); the ✕ on a chip or Backspace on an empty input removes
|
|
23
|
-
* one. Replaces the ad-hoc CommaTagsInput. The registry's `tags` control.
|
|
24
|
-
*/
|
|
25
|
-
export function TagsInput({ value, onChange, onBlur, placeholder = 'Add a tag…', disabled, maxTags, id, name, suggestions, 'aria-invalid': ariaInvalid, 'aria-label': ariaLabel, 'aria-describedby': ariaDescribedBy, className, size = 'md', ...rest }) {
|
|
26
|
-
const [draft, setDraft] = useState('');
|
|
27
|
-
const listId = useId();
|
|
28
|
-
const atMax = maxTags != null && value.length >= maxTags;
|
|
29
|
-
// Case-insensitive: a committed "Bank" must suppress the suggestion "bank" —
|
|
30
|
-
// offering it back commits nothing (mergeTags dedupes case-sensitively, so it
|
|
31
|
-
// WOULD land as a second chip) and reads as the field suggesting a duplicate.
|
|
32
|
-
const committed = new Set(value.map((tag) => tag.toLowerCase()));
|
|
33
|
-
const offered = (suggestions ?? []).filter((tag) => !committed.has(tag.toLowerCase()));
|
|
18
|
+
/** The editing both fields share: commit, remove, the comma/Enter/Backspace keys, a pasted list. */
|
|
19
|
+
export function useTagEditing({ value, onChange, draft, setDraft }) {
|
|
34
20
|
const commit = (raw) => {
|
|
35
21
|
const next = mergeTags(value, [raw]);
|
|
36
22
|
if (next.length !== value.length)
|
|
@@ -48,30 +34,97 @@ export function TagsInput({ value, onChange, onBlur, placeholder = 'Add a tag…
|
|
|
48
34
|
removeAt(value.length - 1);
|
|
49
35
|
}
|
|
50
36
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
37
|
+
/** A typed or pasted value: every comma commits what is before it, the rest stays the draft. */
|
|
38
|
+
const type = (v) => {
|
|
39
|
+
if (!v.includes(','))
|
|
40
|
+
return setDraft(v);
|
|
41
|
+
const parts = v.split(',');
|
|
42
|
+
const last = parts.pop() ?? '';
|
|
43
|
+
const merged = mergeTags(value, parts);
|
|
44
|
+
if (merged.length !== value.length)
|
|
45
|
+
onChange(merged);
|
|
46
|
+
setDraft(last);
|
|
47
|
+
};
|
|
48
|
+
return { commit, removeAt, onKeyDown, type };
|
|
49
|
+
}
|
|
50
|
+
/** The chip row's frame — an Input-shaped container reading the field tokens. */
|
|
51
|
+
export function tagsRowClass(size, disabled, className) {
|
|
52
|
+
return cn(
|
|
53
|
+
// `py-1`, not `py-1.5`: the empty row is a 20px line + 8px + 2px border, under the min-height, so it
|
|
54
|
+
// sits at exactly the control height beside an Input; `py-1.5` made it 38px next to a 36px one (FND-4).
|
|
55
|
+
// guardrails-ignore control-height-tokens: min-height chip-wrapping row (not fixed) — py- clears wrapped lines
|
|
56
|
+
'flex w-full flex-wrap items-center gap-1.5 rounded-field border border-field-border bg-field-bg px-2 py-1 transition focus-within:border-field-ring focus-within:ring-2 focus-within:ring-field-ring/30 aria-[invalid=true]:border-field-error', CONTROL_MIN_HEIGHT_CLASS[size], disabled && 'cursor-not-allowed opacity-50', className);
|
|
57
|
+
}
|
|
58
|
+
export const TAGS_INPUT_CLASS = 'min-w-24 flex-1 bg-transparent py-0.5 text-base text-field-fg outline-none placeholder:text-field-placeholder sm:pointer-fine:text-sm';
|
|
59
|
+
/** The committed tags as removable chips. */
|
|
60
|
+
// no-attribute-forward: a list of chips with no element of its own — the row it sits in takes the caller's attributes
|
|
61
|
+
export function TagChips({ value, disabled, onRemove }) {
|
|
62
|
+
return value.map((tag, i) => (_jsxs("span", { className: 'inline-flex items-center gap-1 rounded bg-muted py-0.5 pl-2 pr-1 text-sm text-foreground', children: [tag, _jsx(IconButton, { label: `Remove ${tag}`, disabled: disabled, onClick: () => onRemove(i), className: 'h-auto min-h-0 w-auto size-4 rounded-sm p-0 text-muted-foreground hover:bg-border hover:text-foreground [&_svg]:size-3', children: _jsx(X, { "aria-hidden": true }) })] }, tag)));
|
|
63
|
+
}
|
|
64
|
+
let loadedSuggesting = null;
|
|
65
|
+
let pendingSuggesting = null;
|
|
66
|
+
/** Fetch the suggesting field (Base UI Autocomplete) once per page. */
|
|
67
|
+
export function preloadSuggestingTagsInput() {
|
|
68
|
+
if (!pendingSuggesting) {
|
|
69
|
+
pendingSuggesting = import('./TagsInputSuggesting.js').then((m) => {
|
|
70
|
+
loadedSuggesting = m.default;
|
|
71
|
+
return m.default;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return pendingSuggesting;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Comma / Enter-delimited tag input: pill chips inside an Input-shaped container that
|
|
78
|
+
* reads the same field-style tokens (border / ring / invalid). Controlled —
|
|
79
|
+
* `value: string[]`, `onChange(next)`. Type + Enter or comma to add (paste
|
|
80
|
+
* "a,b,c" splits into three); the ✕ on a chip or Backspace on an empty input removes
|
|
81
|
+
* one. Replaces the ad-hoc CommaTagsInput. The registry's `tags` control.
|
|
82
|
+
*
|
|
83
|
+
* ── Why the suggesting field is a dynamic `import()` ─────────────────────────
|
|
84
|
+
* 🔴 Suggestions are drawn by Base UI's Autocomplete, ~38 kB gzip. 5.92.0 rooted EVERY TagsInput
|
|
85
|
+
* in it, so a field that suggests nothing — station's disk-usage rules, every form's `tags`
|
|
86
|
+
* control — carried it: station's FolderSizesView chunk went 7.15 → 44.32 kB gzip (forge task
|
|
87
|
+
* 3614). A field given `suggestions` fetches it on mount (the same move as `InfoHint`); until it
|
|
88
|
+
* arrives — and for good, without `suggestions` — this file's plain input is the field, holding
|
|
89
|
+
* the draft and the focus it hands over.
|
|
90
|
+
*/
|
|
91
|
+
export function TagsInput(props) {
|
|
92
|
+
const wantsList = props.suggestions !== undefined;
|
|
93
|
+
// `() => loadedSuggesting`: a component IS a function, and `useState(fn)` would call it.
|
|
94
|
+
const [Suggesting, setSuggesting] = useState(() => (wantsList ? loadedSuggesting : null));
|
|
95
|
+
const [draft, setDraft] = useState('');
|
|
96
|
+
const focused = useRef(false);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (!wantsList || Suggesting)
|
|
99
|
+
return;
|
|
100
|
+
let alive = true;
|
|
101
|
+
void preloadSuggestingTagsInput().then((c) => {
|
|
102
|
+
if (alive)
|
|
103
|
+
setSuggesting(() => c);
|
|
104
|
+
});
|
|
105
|
+
return () => {
|
|
106
|
+
alive = false;
|
|
107
|
+
};
|
|
108
|
+
}, [wantsList, Suggesting]);
|
|
109
|
+
if (wantsList && Suggesting) {
|
|
110
|
+
return _jsx(Suggesting, { ...props, draft: draft, setDraft: setDraft, initialFocus: focused.current });
|
|
111
|
+
}
|
|
112
|
+
return (_jsx(PlainTagsField, { ...props, draft: draft, setDraft: setDraft, onFocusChange: (on) => {
|
|
113
|
+
focused.current = on;
|
|
114
|
+
} }));
|
|
115
|
+
}
|
|
116
|
+
function PlainTagsField({ value, onChange, onBlur, placeholder = 'Add a tag…', disabled, maxTags, id, name, suggestions: _suggestions, 'aria-invalid': ariaInvalid, 'aria-label': ariaLabel, 'aria-describedby': ariaDescribedBy, className, size = 'md', draft, setDraft, onFocusChange, ...rest }) {
|
|
117
|
+
const { commit, removeAt, onKeyDown, type } = useTagEditing({ value, onChange, draft, setDraft });
|
|
118
|
+
const atMax = maxTags != null && value.length >= maxTags;
|
|
119
|
+
return (_jsxs("div", { ...rest, "aria-invalid": ariaInvalid, className: tagsRowClass(size, disabled, className), children: [_jsx(TagChips, { value: value, disabled: disabled, onRemove: removeAt }), !atMax ? (_jsx("input", {
|
|
120
|
+
// guardrails-ignore no-raw-inputs: perf — the chip row is the field's frame, so its draft
|
|
121
|
+
// input is borderless; the Field-layer Input draws a second frame, and Base UI's (38 kB)
|
|
122
|
+
// is what this path exists to skip (forge task 3614).
|
|
123
|
+
id: id, name: name, value: draft, onChange: (e) => type(e.target.value), disabled: disabled, placeholder: value.length === 0 ? placeholder : undefined, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, autoComplete: 'off', onKeyDown: onKeyDown, onFocus: () => onFocusChange(true), onBlur: () => {
|
|
124
|
+
onFocusChange(false);
|
|
72
125
|
if (draft.trim())
|
|
73
126
|
commit(draft);
|
|
74
127
|
onBlur?.();
|
|
75
|
-
}, className:
|
|
128
|
+
}, className: TAGS_INPUT_CLASS })) : null] }));
|
|
76
129
|
}
|
|
77
130
|
//# sourceMappingURL=TagsInput.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagsInput.js","sourceRoot":"","sources":["../../../src/react/components/TagsInput.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"TagsInput.js","sourceRoot":"","sources":["../../../src/react/components/TagsInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type TagsFieldProps } from './TagsInput.js';
|
|
2
|
+
/**
|
|
3
|
+
* A `TagsInput` that suggests — the chip row as an Autocomplete input group, its list the kit's
|
|
4
|
+
* `SuggestionList`. Loaded by `TagsInput.tsx` with a dynamic `import()` only when a field is given
|
|
5
|
+
* `suggestions`; that file says why.
|
|
6
|
+
*/
|
|
7
|
+
export default function TagsInputSuggesting({ value, onChange, onBlur, placeholder, disabled, maxTags, id, name, suggestions, 'aria-invalid': ariaInvalid, 'aria-label': ariaLabel, 'aria-describedby': ariaDescribedBy, className, size, draft, setDraft, initialFocus, ...rest }: TagsFieldProps): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=TagsInputSuggesting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagsInputSuggesting.d.ts","sourceRoot":"","sources":["../../../src/react/components/TagsInputSuggesting.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,cAAc,EAA+B,MAAM,gBAAgB,CAAC;AAE9G;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAC1C,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAA0B,EAC1B,QAAQ,EACR,OAAO,EACP,EAAE,EACF,IAAI,EACJ,WAAW,EACX,cAAc,EAAE,WAAW,EAC3B,YAAY,EAAE,SAAS,EACvB,kBAAkB,EAAE,eAAe,EACnC,SAAS,EACT,IAAW,EACX,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,GAAG,IAAI,EACR,EAAE,cAAc,+BAgEhB"}
|