@astryxdesign/core 0.5.0-canary.4e1b670 → 0.5.0-canary.51aa5eb
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/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +7 -7
- package/dist/Tokenizer/Tokenizer.d.ts +12 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +31 -21
- package/dist/Typeahead/BaseTypeahead.d.ts +33 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +51 -8
- package/dist/Typeahead/Typeahead.d.ts +8 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +2 -0
- package/package.json +2 -2
- package/src/Table/Table.doc.mjs +2 -2
- package/src/Table/TableFooter.doc.mjs +1 -1
- package/src/Table/useTableSelection.doc.mjs +1 -1
- package/src/TextArea/TextArea.doc.mjs +4 -0
- package/src/TextArea/TextArea.tsx +22 -16
- package/src/Tokenizer/Tokenizer.doc.mjs +16 -3
- package/src/Tokenizer/Tokenizer.test.tsx +161 -0
- package/src/Tokenizer/Tokenizer.tsx +49 -24
- package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
- package/src/Typeahead/BaseTypeahead.tsx +96 -6
- package/src/Typeahead/Typeahead.doc.mjs +6 -0
- package/src/Typeahead/Typeahead.test.tsx +154 -0
- package/src/Typeahead/Typeahead.tsx +9 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../src/TextArea/TextArea.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../src/TextArea/TextArea.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAOL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAQf,OAAO,EAML,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAuB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAI5D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AA8H9C,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjE,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,IAAI,EAAE,kBAAkB,CAAC;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CACzC,SAAS,EACT,UAAU,GAAG,cAAc,CAC5B;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACrC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC;IACxE,qEAAqE;IACrE,YAAY,CAAC,EAAE,CACb,KAAK,EAAE,MAAM,EACb,CAAC,EAAE,WAAW,CAAC,mBAAmB,CAAC,KAChC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,cAAc,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC;IAC3D;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC;IACvD;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC;CACvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,KAAK,EACL,WAAW,EACX,IAAQ,EACR,UAAkB,EAClB,UAAkB,EAClB,eAAe,EACf,MAAM,EACN,aAA0B,EAC1B,YAAY,EACZ,SAAS,EACT,aAAoB,EACpB,OAAO,EACP,SAAS,EACT,YAAoB,EACpB,IAAI,EAAE,QAAQ,EACd,QAAQ,EACR,OAAO,EACP,MAAM,EACN,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,aAAa,+BA8Qf;yBA/Se,QAAQ"}
|
|
@@ -317,13 +317,13 @@ export function TextArea({
|
|
|
317
317
|
"aria-required": isEffectivelyRequired ? 'true' : undefined,
|
|
318
318
|
"aria-invalid": status?.type === 'error' || maxLength != null && valueLength > maxLength ? 'true' : undefined,
|
|
319
319
|
"aria-busy": isBusy || undefined,
|
|
320
|
-
...stylex.props(styles.textarea, textareaSizeStyles[size], isDisabled && styles.textareaDisabled, Boolean(startIcon) && styles.textareaWithStartIcon,
|
|
320
|
+
...mergeProps(themeProps('text-area-control'), stylex.props(styles.textarea, textareaSizeStyles[size], isDisabled && styles.textareaDisabled, Boolean(startIcon) && styles.textareaWithStartIcon,
|
|
321
321
|
// Reserve trailing space only when the end slot actually renders
|
|
322
322
|
// something (spinner or on-field status icon). The `detached`
|
|
323
|
-
// status variant suppresses the on-field icon — its glyph lives
|
|
324
|
-
// the message box below — so reserving here would inset the
|
|
325
|
-
// for an icon that never appears.
|
|
326
|
-
(isBusy || statusIcon != null) && styles.textareaWithStatus, isBusy && statusIcon != null && styles.textareaWithBusyStatus, maxLength != null && styles.textareaWithCounter)
|
|
323
|
+
// status variant suppresses the on-field icon — its glyph lives
|
|
324
|
+
// in the message box below — so reserving here would inset the
|
|
325
|
+
// text for an icon that never appears.
|
|
326
|
+
(isBusy || statusIcon != null) && styles.textareaWithStatus, isBusy && statusIcon != null && styles.textareaWithBusyStatus, maxLength != null && styles.textareaWithCounter))
|
|
327
327
|
}), (isBusy || statusIcon) && /*#__PURE__*/_jsxs("span", {
|
|
328
328
|
...{
|
|
329
329
|
className: "x10l6tqk xctzyg x13oyzgk x47corl x78zum5 x6s0dn4 x1txdalj"
|
|
@@ -333,14 +333,14 @@ export function TextArea({
|
|
|
333
333
|
}), statusIcon]
|
|
334
334
|
}), maxLength != null && /*#__PURE__*/_jsxs("div", {
|
|
335
335
|
id: counterID,
|
|
336
|
-
...{
|
|
336
|
+
...mergeProps(themeProps('text-area-counter'), {
|
|
337
337
|
0: {
|
|
338
338
|
className: "x10l6tqk x112dmjn x13oyzgk x47corl x78zum5 x6s0dn4 xzye2dw x9ynric x141an7d x1ltkj2j xv1l7n4"
|
|
339
339
|
},
|
|
340
340
|
1: {
|
|
341
341
|
className: "x10l6tqk x112dmjn x13oyzgk x47corl x78zum5 x6s0dn4 xzye2dw x9ynric x141an7d x1ltkj2j xjt36v0"
|
|
342
342
|
}
|
|
343
|
-
}[!!(valueLength > maxLength) << 0],
|
|
343
|
+
}[!!(valueLength > maxLength) << 0]),
|
|
344
344
|
children: [valueLength > maxLength &&
|
|
345
345
|
/*#__PURE__*/
|
|
346
346
|
// Non-color cue so the over-limit state isn't conveyed by the red
|
|
@@ -107,6 +107,17 @@ export interface TokenizerProps<T extends SearchableItem> extends Omit<BaseProps
|
|
|
107
107
|
maxMenuItems?: number;
|
|
108
108
|
/** Fixed dropdown width in pixels. Never shrinks below the input width. */
|
|
109
109
|
menuWidth?: number;
|
|
110
|
+
/**
|
|
111
|
+
* Minimum query length before the search source is queried. Below it no
|
|
112
|
+
* search runs and the menu stays closed — useful for remote sources where
|
|
113
|
+
* one or two characters match too much to be worth fetching.
|
|
114
|
+
*
|
|
115
|
+
* With `hasCreate`, the "Create" entry rides on the search results, so it
|
|
116
|
+
* also waits for the threshold.
|
|
117
|
+
*
|
|
118
|
+
* @default 1
|
|
119
|
+
*/
|
|
120
|
+
minQueryLength?: number;
|
|
110
121
|
/** Text shown when no results found. @default 'No results found' */
|
|
111
122
|
emptySearchResultsText?: string;
|
|
112
123
|
/** Whether the input is disabled. @default false */
|
|
@@ -203,7 +214,7 @@ export interface TokenizerProps<T extends SearchableItem> extends Omit<BaseProps
|
|
|
203
214
|
* />
|
|
204
215
|
* ```
|
|
205
216
|
*/
|
|
206
|
-
export declare function Tokenizer<T extends SearchableItem>({ label, isLabelHidden, description, isRequired, isOptional, status, statusVariant, startIcon, labelTooltip, searchSource, value, onChange, renderItem, renderToken, maxEntries, placeholder, hasEntriesOnFocus, maxMenuItems, menuWidth, emptySearchResultsText, isDisabled, htmlName, disabledMessage, hasClear, endContent, hasAutoFocus, size: sizeProp, tokenOverflowBehavior, debounceMs, hasCreate, onChangeQuery, onFocus, onBlur, width, xstyle, className, style, 'data-testid': testId, ref, handleRef, }: TokenizerProps<T>): React.JSX.Element;
|
|
217
|
+
export declare function Tokenizer<T extends SearchableItem>({ label, isLabelHidden, description, isRequired, isOptional, status, statusVariant, startIcon, labelTooltip, searchSource, value, onChange, renderItem, renderToken, maxEntries, placeholder, hasEntriesOnFocus, maxMenuItems, menuWidth, minQueryLength, emptySearchResultsText, isDisabled, htmlName, disabledMessage, hasClear, endContent, hasAutoFocus, size: sizeProp, tokenOverflowBehavior, debounceMs, hasCreate, onChangeQuery, onFocus, onBlur, width, xstyle, className, style, 'data-testid': testId, ref, handleRef, }: TokenizerProps<T>): React.JSX.Element;
|
|
207
218
|
export declare namespace Tokenizer {
|
|
208
219
|
var displayName: string;
|
|
209
220
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tokenizer.d.ts","sourceRoot":"","sources":["../../src/Tokenizer/Tokenizer.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Tokenizer.d.ts","sourceRoot":"","sources":["../../src/Tokenizer/Tokenizer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -237,6 +237,7 @@ export function Tokenizer({
|
|
|
237
237
|
hasEntriesOnFocus,
|
|
238
238
|
maxMenuItems,
|
|
239
239
|
menuWidth,
|
|
240
|
+
minQueryLength,
|
|
240
241
|
emptySearchResultsText,
|
|
241
242
|
isDisabled = false,
|
|
242
243
|
htmlName,
|
|
@@ -357,32 +358,39 @@ export function Tokenizer({
|
|
|
357
358
|
const filteredSource = useMemo(() => ({
|
|
358
359
|
search: async query => {
|
|
359
360
|
const results = await searchSource.search(query);
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
// Append a "Create: X" synthetic item when hasCreate is true,
|
|
363
|
-
// the user has typed something, and it doesn't exactly match an
|
|
364
|
-
// existing result.
|
|
365
|
-
if (hasCreate && query.trim()) {
|
|
366
|
-
const trimmed = query.trim();
|
|
367
|
-
const alreadyExists = selectedIds.has(trimmed) || filtered.some(item => item.label.toLowerCase() === trimmed.toLowerCase());
|
|
368
|
-
if (!alreadyExists) {
|
|
369
|
-
const creatableItem = {
|
|
370
|
-
id: `${CREATABLE_ID_PREFIX}${trimmed}`,
|
|
371
|
-
label: `Create "${trimmed}"`,
|
|
372
|
-
auxiliaryData: {
|
|
373
|
-
__createdValue: trimmed
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
filtered.push(creatableItem);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
return filtered;
|
|
361
|
+
return results.filter(item => !selectedIds.has(item.id));
|
|
380
362
|
},
|
|
381
363
|
bootstrap: async () => {
|
|
382
364
|
const results = await searchSource.bootstrap();
|
|
383
365
|
return results.filter(item => !selectedIds.has(item.id));
|
|
384
366
|
}
|
|
385
|
-
}), [searchSource, selectedIds
|
|
367
|
+
}), [searchSource, selectedIds]);
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* The "Create X" entry. It is derived from the typed text, not fetched for
|
|
371
|
+
* it, so it is offered through `__queryEntries` rather than appended to the
|
|
372
|
+
* search results — which is what keeps it available when the query is too
|
|
373
|
+
* short to search. `minQueryLength` is there to avoid a fetch too broad to
|
|
374
|
+
* be worth making; creating `QA` costs no fetch, and a field that can
|
|
375
|
+
* create it should not stop being able to.
|
|
376
|
+
*/
|
|
377
|
+
const createEntries = useCallback((query, results) => {
|
|
378
|
+
const trimmed = query.trim();
|
|
379
|
+
if (!hasCreate || trimmed === '') {
|
|
380
|
+
return [];
|
|
381
|
+
}
|
|
382
|
+
const alreadyExists = selectedIds.has(trimmed) || results.some(item => item.label.toLowerCase() === trimmed.toLowerCase());
|
|
383
|
+
if (alreadyExists) {
|
|
384
|
+
return [];
|
|
385
|
+
}
|
|
386
|
+
return [{
|
|
387
|
+
id: `${CREATABLE_ID_PREFIX}${trimmed}`,
|
|
388
|
+
label: `Create "${trimmed}"`,
|
|
389
|
+
auxiliaryData: {
|
|
390
|
+
__createdValue: trimmed
|
|
391
|
+
}
|
|
392
|
+
}];
|
|
393
|
+
}, [hasCreate, selectedIds]);
|
|
386
394
|
const emptySource = useMemo(() => ({
|
|
387
395
|
search: async () => [],
|
|
388
396
|
bootstrap: async () => []
|
|
@@ -571,6 +579,7 @@ export function Tokenizer({
|
|
|
571
579
|
hasEntriesOnFocus: isAtMax ? false : hasEntriesOnFocus,
|
|
572
580
|
maxMenuItems: maxMenuItems,
|
|
573
581
|
menuWidth: menuWidth,
|
|
582
|
+
minQueryLength: minQueryLength,
|
|
574
583
|
emptySearchResultsText: emptySearchResultsText,
|
|
575
584
|
isDisabled: isDisabled,
|
|
576
585
|
isFocusableDisabled: showsDisabledMessage,
|
|
@@ -578,6 +587,7 @@ export function Tokenizer({
|
|
|
578
587
|
inputId: inputId,
|
|
579
588
|
ariaDescribedBy: ariaDescribedBy,
|
|
580
589
|
onChangeQuery: onChangeQuery,
|
|
590
|
+
__queryEntries: createEntries,
|
|
581
591
|
debounceMs: debounceMs,
|
|
582
592
|
onKeyDown: handleKeyDown,
|
|
583
593
|
anchorRef: wrapperRef,
|
|
@@ -50,6 +50,18 @@ export interface BaseTypeaheadProps<T extends SearchableItem> extends Omit<BaseP
|
|
|
50
50
|
maxMenuItems?: number;
|
|
51
51
|
/** Fixed dropdown width in pixels. Never shrinks below the anchor width. */
|
|
52
52
|
menuWidth?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Minimum query length before the search source is queried. Below it no
|
|
55
|
+
* search runs and the menu stays closed, so a remote source is not asked
|
|
56
|
+
* for a result set that cannot be meaningful yet — and the user does not
|
|
57
|
+
* see "no results" for a query that was never searched.
|
|
58
|
+
*
|
|
59
|
+
* Measured with `String.length` (UTF-16 code units), like every other
|
|
60
|
+
* length check in the library.
|
|
61
|
+
*
|
|
62
|
+
* @default 1 — every non-empty query is searched.
|
|
63
|
+
*/
|
|
64
|
+
minQueryLength?: number;
|
|
53
65
|
/**
|
|
54
66
|
* Text shown when no results found.
|
|
55
67
|
* @default 'No results found'
|
|
@@ -82,6 +94,27 @@ export interface BaseTypeaheadProps<T extends SearchableItem> extends Omit<BaseP
|
|
|
82
94
|
* Callback when dropdown opens/closes.
|
|
83
95
|
*/
|
|
84
96
|
onOpenChange?: (isOpen: boolean) => void;
|
|
97
|
+
/**
|
|
98
|
+
* Entries derived from the query text rather than fetched for it — today,
|
|
99
|
+
* Tokenizer's "Create ...".
|
|
100
|
+
*
|
|
101
|
+
* They are appended to whatever the search returned, and they are offered
|
|
102
|
+
* whatever `minQueryLength` says: that threshold exists to avoid a fetch
|
|
103
|
+
* that is too broad to be worth making, and these cost no fetch. A field
|
|
104
|
+
* that can create `QA` should not stop being able to just because a search
|
|
105
|
+
* for `QA` would match too much.
|
|
106
|
+
*
|
|
107
|
+
* Receives the results they will be appended to, so a caller can decline to
|
|
108
|
+
* offer an entry that duplicates one.
|
|
109
|
+
*
|
|
110
|
+
* Underscored and `@internal`: `BaseTypeaheadProps` is re-exported from the
|
|
111
|
+
* package entry point, so anything named on it ships as public API at the
|
|
112
|
+
* next cut. This is a wiring detail between Tokenizer and the base — the
|
|
113
|
+
* same reason `DefinedTheme.__inputTokens` carries its prefix.
|
|
114
|
+
*
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
__queryEntries?: (query: string, results: T[]) => T[];
|
|
85
118
|
/**
|
|
86
119
|
* Debounce delay in ms before triggering search after typing.
|
|
87
120
|
* Set to 0 for synchronous/local search sources that don't need debouncing.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseTypeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/BaseTypeahead.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAenD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAS1D,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,cAAc,CAAE,SAAQ,IAAI,CACxE,SAAS,CAAC,WAAW,CAAC,EACtB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAEpC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAE3B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAE/D;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B;
|
|
1
|
+
{"version":3,"file":"BaseTypeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/BaseTypeahead.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAenD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAS1D,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,cAAc,CAAE,SAAQ,IAAI,CACxE,SAAS,CAAC,WAAW,CAAC,EACtB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAEpC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;IAEtD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAE3B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAE/D;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B;AA+HD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,aAAa,EAuoBrB,CAAC,CAAC,SAAS,cAAc,EAC5B,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,KACzB,KAAK,CAAC,YAAY,CAAC"}
|
|
@@ -113,6 +113,19 @@ const itemSizeStyles = {
|
|
|
113
113
|
}
|
|
114
114
|
};
|
|
115
115
|
|
|
116
|
+
// =============================================================================
|
|
117
|
+
// Helpers
|
|
118
|
+
// =============================================================================
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* A query that has been typed but is still shorter than the caller's
|
|
122
|
+
* threshold. An empty query is not "below the minimum" — it is the
|
|
123
|
+
* untouched state, and `hasEntriesOnFocus` owns what happens there.
|
|
124
|
+
*/
|
|
125
|
+
function isBelowMinQueryLength(query, minQueryLength) {
|
|
126
|
+
return query.length > 0 && query.length < minQueryLength;
|
|
127
|
+
}
|
|
128
|
+
|
|
116
129
|
// =============================================================================
|
|
117
130
|
// Component
|
|
118
131
|
// =============================================================================
|
|
@@ -145,12 +158,14 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
145
158
|
hasEntriesOnFocus = false,
|
|
146
159
|
maxMenuItems = 10,
|
|
147
160
|
menuWidth,
|
|
161
|
+
minQueryLength = 1,
|
|
148
162
|
emptySearchResultsText: emptySearchResultsTextFromProps,
|
|
149
163
|
isDisabled = false,
|
|
150
164
|
isFocusableDisabled = false,
|
|
151
165
|
hasAutoFocus = false,
|
|
152
166
|
onChangeQuery,
|
|
153
167
|
onOpenChange,
|
|
168
|
+
__queryEntries,
|
|
154
169
|
inputId: externalInputId,
|
|
155
170
|
ariaDescribedBy,
|
|
156
171
|
ariaLabelledBy,
|
|
@@ -259,7 +274,8 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
259
274
|
return;
|
|
260
275
|
}
|
|
261
276
|
resultsGenRef.current = gen;
|
|
262
|
-
const
|
|
277
|
+
const fetched = searchResults.slice(0, maxMenuItems);
|
|
278
|
+
const shown = [...fetched, ...(__queryEntries?.(searchQuery, fetched) ?? [])];
|
|
263
279
|
setResults(shown);
|
|
264
280
|
setHighlightedIndex(shown.length > 0 ? 0 : -1);
|
|
265
281
|
if (searchResults.length > 0 || searchQuery.length > 0) {
|
|
@@ -283,7 +299,7 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
283
299
|
setIsLoading(false);
|
|
284
300
|
}
|
|
285
301
|
}
|
|
286
|
-
}, [searchSource, maxMenuItems, showLayer, announce, emptySearchResultsText, t]);
|
|
302
|
+
}, [searchSource, maxMenuItems, showLayer, announce, emptySearchResultsText, __queryEntries, t]);
|
|
287
303
|
|
|
288
304
|
// Perform bootstrap
|
|
289
305
|
const performBootstrap = useCallback(async () => {
|
|
@@ -320,14 +336,33 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
320
336
|
if (searchTimeoutRef.current) {
|
|
321
337
|
clearTimeout(searchTimeoutRef.current);
|
|
322
338
|
}
|
|
323
|
-
|
|
339
|
+
|
|
340
|
+
// Nothing to search: either the field was emptied, or the query is
|
|
341
|
+
// still shorter than `minQueryLength`. Both drop stale results and
|
|
342
|
+
// close the menu — showing the empty state for a query that was never
|
|
343
|
+
// searched would report "no results" that nobody looked for.
|
|
344
|
+
if (newQuery.length === 0 && !hasEntriesOnFocus || isBelowMinQueryLength(newQuery, minQueryLength)) {
|
|
324
345
|
searchGenRef.current++;
|
|
325
346
|
searchSource.cancel?.();
|
|
326
|
-
|
|
347
|
+
// A query too short to search can still carry entries derived from
|
|
348
|
+
// the text itself. `hasSearched` stays false either way, so the menu
|
|
349
|
+
// never reports "no results" for a query nobody looked for.
|
|
350
|
+
const derived = __queryEntries?.(newQuery, []) ?? [];
|
|
351
|
+
setResults(derived);
|
|
352
|
+
setHighlightedIndex(derived.length > 0 ? 0 : -1);
|
|
327
353
|
setHasSearched(false);
|
|
354
|
+
// Bumping the generation abandons any in-flight search, which means
|
|
355
|
+
// its own `finally` will decline to clear this — so clear it here or
|
|
356
|
+
// the field spins forever. Backspacing below the threshold on a remote
|
|
357
|
+
// source is the everyday way to hit that.
|
|
358
|
+
setIsLoading(false);
|
|
328
359
|
// Clear any lingering result-count / no-results announcement.
|
|
329
360
|
announce('');
|
|
330
|
-
|
|
361
|
+
if (derived.length > 0) {
|
|
362
|
+
showLayer();
|
|
363
|
+
} else {
|
|
364
|
+
popover.hide();
|
|
365
|
+
}
|
|
331
366
|
return;
|
|
332
367
|
}
|
|
333
368
|
const triggerSearch = () => {
|
|
@@ -342,7 +377,7 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
342
377
|
} else {
|
|
343
378
|
searchTimeoutRef.current = setTimeout(triggerSearch, debounceMs);
|
|
344
379
|
}
|
|
345
|
-
}, [onChangeQuery, hasEntriesOnFocus, performSearch, performBootstrap, popover, debounceMs, searchSource, announce]);
|
|
380
|
+
}, [onChangeQuery, hasEntriesOnFocus, minQueryLength, __queryEntries, showLayer, performSearch, performBootstrap, popover, debounceMs, searchSource, announce]);
|
|
346
381
|
|
|
347
382
|
// Handle input change
|
|
348
383
|
const handleInputChange = useCallback(e => {
|
|
@@ -362,6 +397,10 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
362
397
|
setQuery('');
|
|
363
398
|
setResults([]);
|
|
364
399
|
setHasSearched(false);
|
|
400
|
+
// Same reason as in handleQueryChange: the invalidated search will not
|
|
401
|
+
// clear this itself. Selecting a stale result while the next search is
|
|
402
|
+
// still in flight would otherwise leave the field spinning.
|
|
403
|
+
setIsLoading(false);
|
|
365
404
|
popover.hide();
|
|
366
405
|
inputRef.current?.focus();
|
|
367
406
|
}, [onChange, popover, searchSource]);
|
|
@@ -428,7 +467,11 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
428
467
|
if (results.length > 0) {
|
|
429
468
|
popover.show();
|
|
430
469
|
setHighlightedIndex(0);
|
|
431
|
-
} else if (hasEntriesOnFocus
|
|
470
|
+
} else if (hasEntriesOnFocus &&
|
|
471
|
+
// A below-threshold query was never searched; falling back to the
|
|
472
|
+
// bootstrap entries here would open a menu of suggestions that
|
|
473
|
+
// ignore what the user has already typed.
|
|
474
|
+
!isBelowMinQueryLength(query, minQueryLength)) {
|
|
432
475
|
void performBootstrap();
|
|
433
476
|
}
|
|
434
477
|
}
|
|
@@ -482,7 +525,7 @@ export const BaseTypeahead = function BaseTypeahead({
|
|
|
482
525
|
}
|
|
483
526
|
break;
|
|
484
527
|
}
|
|
485
|
-
}, [popover, results, highlightedIndex, handleSelect, hasEntriesOnFocus, query
|
|
528
|
+
}, [popover, results, highlightedIndex, handleSelect, hasEntriesOnFocus, query, minQueryLength, performBootstrap, externalOnKeyDown]);
|
|
486
529
|
|
|
487
530
|
// Generate item ID for accessibility
|
|
488
531
|
const getItemId = useCallback(index => `${listboxId}-option-${index}`, [listboxId]);
|
|
@@ -69,6 +69,13 @@ export interface TypeaheadProps<T extends SearchableItem> extends Omit<BaseProps
|
|
|
69
69
|
hasEntriesOnFocus?: boolean;
|
|
70
70
|
/** Max dropdown items. @default 10 */
|
|
71
71
|
maxMenuItems?: number;
|
|
72
|
+
/**
|
|
73
|
+
* Minimum query length before the search source is queried. Below it no
|
|
74
|
+
* search runs and the menu stays closed — useful for remote sources where
|
|
75
|
+
* one or two characters match too much to be worth fetching.
|
|
76
|
+
* @default 1
|
|
77
|
+
*/
|
|
78
|
+
minQueryLength?: number;
|
|
72
79
|
/** Text shown when no results found. @default 'No results found' */
|
|
73
80
|
emptySearchResultsText?: string;
|
|
74
81
|
/** Whether the input is disabled. @default false */
|
|
@@ -134,7 +141,7 @@ export interface TypeaheadProps<T extends SearchableItem> extends Omit<BaseProps
|
|
|
134
141
|
* />
|
|
135
142
|
* ```
|
|
136
143
|
*/
|
|
137
|
-
export declare function Typeahead<T extends SearchableItem>({ ref, label, isLabelHidden, description, isRequired, isOptional, status, statusVariant, startIcon, labelTooltip, searchSource, value, onChange, renderItem, placeholder, hasEntriesOnFocus, maxMenuItems, emptySearchResultsText, isDisabled, disabledMessage, hasClear, hasAutoFocus, size: sizeProp, debounceMs, onChangeQuery, onOpenChange, width, xstyle, className, style, 'data-testid': testId, }: TypeaheadProps<T>): React.JSX.Element;
|
|
144
|
+
export declare function Typeahead<T extends SearchableItem>({ ref, label, isLabelHidden, description, isRequired, isOptional, status, statusVariant, startIcon, labelTooltip, searchSource, value, onChange, renderItem, placeholder, hasEntriesOnFocus, maxMenuItems, minQueryLength, emptySearchResultsText, isDisabled, disabledMessage, hasClear, hasAutoFocus, size: sizeProp, debounceMs, onChangeQuery, onOpenChange, width, xstyle, className, style, 'data-testid': testId, }: TypeaheadProps<T>): React.JSX.Element;
|
|
138
145
|
export declare namespace Typeahead {
|
|
139
146
|
var displayName: string;
|
|
140
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Typeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/Typeahead.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Typeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/Typeahead.tsx"],"names":[],"mappings":"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"}
|
|
@@ -132,6 +132,7 @@ export function Typeahead({
|
|
|
132
132
|
placeholder,
|
|
133
133
|
hasEntriesOnFocus,
|
|
134
134
|
maxMenuItems,
|
|
135
|
+
minQueryLength,
|
|
135
136
|
emptySearchResultsText,
|
|
136
137
|
isDisabled = false,
|
|
137
138
|
disabledMessage,
|
|
@@ -312,6 +313,7 @@ export function Typeahead({
|
|
|
312
313
|
placeholder: showToken ? undefined : placeholder,
|
|
313
314
|
hasEntriesOnFocus: hasEntriesOnFocus,
|
|
314
315
|
maxMenuItems: maxMenuItems,
|
|
316
|
+
minQueryLength: minQueryLength,
|
|
315
317
|
emptySearchResultsText: emptySearchResultsText,
|
|
316
318
|
isDisabled: isDisabled,
|
|
317
319
|
hasAutoFocus: hasAutoFocus,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/core",
|
|
3
|
-
"version": "0.5.0-canary.
|
|
3
|
+
"version": "0.5.0-canary.51aa5eb",
|
|
4
4
|
"displayName": "Astryx Core",
|
|
5
5
|
"description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -661,7 +661,7 @@
|
|
|
661
661
|
"react-dom": ">=19.0.0"
|
|
662
662
|
},
|
|
663
663
|
"devDependencies": {
|
|
664
|
-
"@astryxdesign/cli": "0.5.0-canary.
|
|
664
|
+
"@astryxdesign/cli": "0.5.0-canary.51aa5eb",
|
|
665
665
|
"@babel/cli": "^8.0.4",
|
|
666
666
|
"@babel/core": "^7.29.7",
|
|
667
667
|
"@babel/preset-react": "^8.0.1",
|
package/src/Table/Table.doc.mjs
CHANGED
|
@@ -109,7 +109,7 @@ export const docs = {
|
|
|
109
109
|
{
|
|
110
110
|
name: 'children',
|
|
111
111
|
type: 'ReactNode',
|
|
112
|
-
description: 'Children mode: compose the table yourself from TableHeader / TableBody / TableFooter, each holding TableRow and TableCell, instead of using data-driven rendering. The children are passed straight to the <table>, so the section is yours to supply
|
|
112
|
+
description: 'Children mode: compose the table yourself from TableHeader / TableBody / TableFooter, each holding TableRow and TableCell, instead of using data-driven rendering. The children are passed straight to the <table>, so the section is yours to supply. A TableRow placed directly in Table emits <table><tr>, which is invalid HTML and mismatches on hydration (the parser inserts an implied <tbody> for server-rendered markup; React does not on the client). Data-driven mode renders the sections for you.',
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
name: 'xstyle',
|
|
@@ -189,7 +189,7 @@ export const docsDense = {
|
|
|
189
189
|
bestPractices: [
|
|
190
190
|
{ guidance: true, description: 'Use density and divider variants to match the information density and scanning needs of your data.' },
|
|
191
191
|
{ guidance: true, description: 'Compose rich cell content with Astryx components like Badge, StatusDot, and Avatar via renderCell.' },
|
|
192
|
-
{ guidance: true, description: 'Children mode: wrap rows in TableHeader/TableBody/TableFooter. <table> cannot hold a <tr> directly
|
|
192
|
+
{ guidance: true, description: 'Children mode: wrap rows in TableHeader/TableBody/TableFooter. <table> cannot hold a <tr> directly; the parser adds an implied <tbody> for SSR markup, React does not on the client, so unwrapped rows mismatch on hydration.' },
|
|
193
193
|
{ guidance: true, description: 'Set explicit width on every column via proportional() or pixel(). proportional(1) = equal flex w/ 120px min preventing collapse on narrow viewports. Omitting width skips the minimum.' },
|
|
194
194
|
{ guidance: true, description: 'Data-driven API is RSC-safe: proportional(), pixel(), column defs w/o function props work in Server Components. renderCell (any function prop) requires a "use client" wrapper.' },
|
|
195
195
|
{ guidance: false, description: 'Use a table for data without consistent columns. Use a list or card layout for heterogeneous content.' },
|
|
@@ -8,7 +8,7 @@ export const docs = {
|
|
|
8
8
|
displayName: 'Table Footer',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
10
|
description:
|
|
11
|
-
'<tfoot> wrapper for children mode. Holds summary or total rows beneath the body. A row must sit inside a section
|
|
11
|
+
'<tfoot> wrapper for children mode. Holds summary or total rows beneath the body. A row must sit inside a section: <table> cannot contain a <tr> directly, because the HTML parser inserts an implied <tbody> when it parses server-rendered markup and React does not when it renders on the client, so the two trees mismatch on hydration. Children mode only: the data-driven data={...} path renders a header and a body, never a footer.',
|
|
12
12
|
props: [
|
|
13
13
|
{
|
|
14
14
|
name: 'children',
|
|
@@ -65,7 +65,7 @@ export const docs = {
|
|
|
65
65
|
name: 'hasRowHighlight',
|
|
66
66
|
type: 'boolean',
|
|
67
67
|
description:
|
|
68
|
-
'Paints checked rows with the accent wash. Set false when the surrounding UI already uses row background to mean something else (a row open in a detail panel, say)
|
|
68
|
+
'Paints checked rows with the accent wash. Set false when the surrounding UI already uses row background to mean something else (a row open in a detail panel, say). The wash is an inline style, so it cannot be overridden from userland. Only the background is dropped: aria-selected is still set on checked rows either way.',
|
|
69
69
|
default: 'true',
|
|
70
70
|
},
|
|
71
71
|
],
|
|
@@ -187,6 +187,8 @@ export const docs = {
|
|
|
187
187
|
theming: {
|
|
188
188
|
targets: [
|
|
189
189
|
{className: 'astryx-text-area', visualProps: ['size', 'status'], states: ['disabled', 'readonly']},
|
|
190
|
+
{className: 'astryx-text-area-control'},
|
|
191
|
+
{className: 'astryx-text-area-counter'},
|
|
190
192
|
// Still emitted beside the names above, so themes written against
|
|
191
193
|
// them keep working. Drop in the next major.
|
|
192
194
|
{className: 'astryx-textarea', visualProps: ['size', 'status'], states: ['disabled', 'readonly'], deprecatedFor: 'text-area'},
|
|
@@ -385,6 +387,8 @@ export const docsZh = {
|
|
|
385
387
|
theming: {
|
|
386
388
|
targets: [
|
|
387
389
|
{className: 'astryx-text-area', visualProps: ['size', 'status'], states: ['disabled', 'readonly']},
|
|
390
|
+
{className: 'astryx-text-area-control'},
|
|
391
|
+
{className: 'astryx-text-area-counter'},
|
|
388
392
|
// Still emitted beside the names above, so themes written against
|
|
389
393
|
// them keep working. Drop in the next major.
|
|
390
394
|
{className: 'astryx-textarea', visualProps: ['size', 'status'], states: ['disabled', 'readonly'], deprecatedFor: 'text-area'},
|
|
@@ -615,19 +615,22 @@ export function TextArea({
|
|
|
615
615
|
: undefined
|
|
616
616
|
}
|
|
617
617
|
aria-busy={isBusy || undefined}
|
|
618
|
-
{...
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
618
|
+
{...mergeProps(
|
|
619
|
+
themeProps('text-area-control'),
|
|
620
|
+
stylex.props(
|
|
621
|
+
styles.textarea,
|
|
622
|
+
textareaSizeStyles[size],
|
|
623
|
+
isDisabled && styles.textareaDisabled,
|
|
624
|
+
Boolean(startIcon) && styles.textareaWithStartIcon,
|
|
625
|
+
// Reserve trailing space only when the end slot actually renders
|
|
626
|
+
// something (spinner or on-field status icon). The `detached`
|
|
627
|
+
// status variant suppresses the on-field icon — its glyph lives
|
|
628
|
+
// in the message box below — so reserving here would inset the
|
|
629
|
+
// text for an icon that never appears.
|
|
630
|
+
(isBusy || statusIcon != null) && styles.textareaWithStatus,
|
|
631
|
+
isBusy && statusIcon != null && styles.textareaWithBusyStatus,
|
|
632
|
+
maxLength != null && styles.textareaWithCounter,
|
|
633
|
+
),
|
|
631
634
|
)}
|
|
632
635
|
/>
|
|
633
636
|
{(isBusy || statusIcon) && (
|
|
@@ -639,9 +642,12 @@ export function TextArea({
|
|
|
639
642
|
{maxLength != null && (
|
|
640
643
|
<div
|
|
641
644
|
id={counterID}
|
|
642
|
-
{...
|
|
643
|
-
|
|
644
|
-
|
|
645
|
+
{...mergeProps(
|
|
646
|
+
themeProps('text-area-counter'),
|
|
647
|
+
stylex.props(
|
|
648
|
+
styles.counter,
|
|
649
|
+
valueLength > maxLength && styles.counterError,
|
|
650
|
+
),
|
|
645
651
|
)}>
|
|
646
652
|
{valueLength > maxLength && (
|
|
647
653
|
// Non-color cue so the over-limit state isn't conveyed by the red
|
|
@@ -132,7 +132,7 @@ export const docs = {
|
|
|
132
132
|
{
|
|
133
133
|
name: 'maxMenuItems',
|
|
134
134
|
type: 'number',
|
|
135
|
-
description: 'Maximum number of
|
|
135
|
+
description: 'Maximum number of search results to display. The hasCreate entry is offered on top of them, so a menu can show one more than this.',
|
|
136
136
|
default: '10',
|
|
137
137
|
},
|
|
138
138
|
{
|
|
@@ -140,6 +140,12 @@ export const docs = {
|
|
|
140
140
|
type: 'number',
|
|
141
141
|
description: 'Fixed dropdown width in pixels. The menu never shrinks below its anchor width.',
|
|
142
142
|
},
|
|
143
|
+
{
|
|
144
|
+
name: 'minQueryLength',
|
|
145
|
+
type: 'number',
|
|
146
|
+
description: 'Minimum query length before the search source is queried. Below it no search runs, and the menu stays closed — unless hasCreate is set, in which case the "Create ..." entry is still offered, being derived from the typed text rather than fetched for it.',
|
|
147
|
+
default: '1',
|
|
148
|
+
},
|
|
143
149
|
{
|
|
144
150
|
name: 'emptySearchResultsText',
|
|
145
151
|
type: 'string',
|
|
@@ -386,7 +392,7 @@ export const docsZh = {
|
|
|
386
392
|
{
|
|
387
393
|
name: 'maxMenuItems',
|
|
388
394
|
type: 'number',
|
|
389
|
-
description: '
|
|
395
|
+
description: '下拉列表显示的最大搜索结果数。“创建 ...”条目会在此之外额外提供,因此菜单可能比该数量多显示一项。',
|
|
390
396
|
default: '10',
|
|
391
397
|
},
|
|
392
398
|
{
|
|
@@ -394,6 +400,12 @@ export const docsZh = {
|
|
|
394
400
|
type: 'number',
|
|
395
401
|
description: '下拉菜单的固定像素宽度。菜单不会小于其锚点宽度。',
|
|
396
402
|
},
|
|
403
|
+
{
|
|
404
|
+
name: 'minQueryLength',
|
|
405
|
+
type: 'number',
|
|
406
|
+
description: '查询搜索源前的最小查询长度。低于该长度不会发起搜索,菜单保持关闭;但设置 hasCreate 时仍会提供“创建 ...”条目——该条目由输入的文本推导而来,并非通过搜索获取。',
|
|
407
|
+
default: '1',
|
|
408
|
+
},
|
|
397
409
|
{
|
|
398
410
|
name: 'emptySearchResultsText',
|
|
399
411
|
type: 'string',
|
|
@@ -515,8 +527,9 @@ export const docsDense = {
|
|
|
515
527
|
isOptional: 'Shows optional indicator on label.',
|
|
516
528
|
labelTooltip: 'Tooltip on label.',
|
|
517
529
|
hasEntriesOnFocus: 'Show bootstrap results on focus before typing.',
|
|
518
|
-
maxMenuItems: 'Max
|
|
530
|
+
maxMenuItems: 'Max search results shown; the hasCreate entry sits on top of them.',
|
|
519
531
|
menuWidth: 'Fixed dropdown width in pixels.',
|
|
532
|
+
minQueryLength: 'Min query length before searching. Menu stays closed below it, except the hasCreate entry.',
|
|
520
533
|
emptySearchResultsText: 'Text when search returns no results.',
|
|
521
534
|
hasAutoFocus: 'Auto-focus input on mount.',
|
|
522
535
|
size: 'Input+token size.',
|