@astryxdesign/core 0.4.2-canary.01592f7 → 0.4.2-canary.255e810
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/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +3 -19
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +4 -1
- package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatFilterValue.js +2 -4
- package/dist/Table/columnUtils.d.ts.map +1 -1
- package/dist/Table/columnUtils.js +4 -1
- package/dist/TextArea/TextArea.d.ts +6 -3
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +17 -6
- package/dist/TreeList/TreeList.js +2 -1
- package/dist/astryx.umd.js +45 -45
- package/dist/astryx.umd.js.map +4 -4
- package/dist/utils/characters.d.ts +27 -0
- package/dist/utils/characters.d.ts.map +1 -0
- package/dist/utils/characters.js +83 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/package.json +2 -2
- package/src/Avatar/Avatar.test.tsx +6 -1
- package/src/Avatar/Avatar.tsx +3 -21
- package/src/PowerSearch/PowerSearch.test.tsx +48 -3
- package/src/PowerSearch/PowerSearch.tsx +4 -1
- package/src/PowerSearch/formatFilterValue.test.ts +22 -0
- package/src/PowerSearch/formatFilterValue.ts +2 -4
- package/src/Table/Table.test.tsx +6 -0
- package/src/Table/columnUtils.ts +3 -1
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.test.tsx +72 -0
- package/src/TextArea/TextArea.tsx +26 -8
- package/src/TreeList/TreeList.doc.mjs +2 -2
- package/src/TreeList/TreeList.tsx +1 -1
- package/src/theme/extensibleAxes.test.ts +365 -0
- package/src/utils/characters.test.ts +141 -0
- package/src/utils/characters.ts +88 -0
- package/src/utils/index.ts +2 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/Avatar/Avatar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAoC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/Avatar/Avatar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAoC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAiB5C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AA4BrD;;;;;;GAMG;AACH,KAAK,eAAe,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD;;GAEG;AACH,KAAK,iBAAiB,GACpB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgBpD;AA6HD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAChD;AA0DD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,EACrB,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,WAAW,EACX,IAAI,EACJ,IAAW,EACX,GAAG,EACH,MAAM,EACN,OAAc,EACd,IAAI,EACJ,EAAE,EACF,MAAM,EACN,GAAG,EACH,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BA+Pb;yBAlRe,MAAM"}
|
package/dist/Avatar/Avatar.js
CHANGED
|
@@ -25,6 +25,7 @@ import { AvatarSizeContext } from "./AvatarSizeContext.js";
|
|
|
25
25
|
import { useAvatarGroup } from "../AvatarGroup/AvatarGroupContext.js";
|
|
26
26
|
import { mergeProps, mergeRefs } from "../utils/index.js";
|
|
27
27
|
import { themeProps } from "../utils/themeProps.js";
|
|
28
|
+
import { firstCharacter } from "../utils/characters.js";
|
|
28
29
|
import { focusOutlineProps } from "../utils/focusOutline.stylex.js";
|
|
29
30
|
import { useTooltip } from "../Tooltip/useTooltip.js";
|
|
30
31
|
import { useDevWarning } from "../hooks/useDevWarning.js";
|
|
@@ -194,23 +195,6 @@ const groupDynamicStyles = {
|
|
|
194
195
|
"--x---_avatar-group-overlap": `${offset}px` != null ? `${offset}px` : undefined
|
|
195
196
|
}]
|
|
196
197
|
};
|
|
197
|
-
/**
|
|
198
|
-
* Reuse a single segmenter when the runtime supports Intl.Segmenter.
|
|
199
|
-
*/
|
|
200
|
-
const graphemeSegmenter = typeof Intl.Segmenter === 'function' ? new Intl.Segmenter(undefined, {
|
|
201
|
-
granularity: 'grapheme'
|
|
202
|
-
}) : null;
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Return the first user-perceived character, with a code-point fallback.
|
|
206
|
-
*/
|
|
207
|
-
function firstGrapheme(word) {
|
|
208
|
-
if (graphemeSegmenter) {
|
|
209
|
-
return [...graphemeSegmenter.segment(word)][0]?.segment ?? '';
|
|
210
|
-
}
|
|
211
|
-
return [...word][0] ?? '';
|
|
212
|
-
}
|
|
213
|
-
|
|
214
198
|
/**
|
|
215
199
|
* Generates initials from a name string.
|
|
216
200
|
* Takes the first letter of the first two words.
|
|
@@ -226,9 +210,9 @@ function getInitials(name) {
|
|
|
226
210
|
return '';
|
|
227
211
|
}
|
|
228
212
|
if (words.length === 1) {
|
|
229
|
-
return
|
|
213
|
+
return firstCharacter(words[0]).toUpperCase();
|
|
230
214
|
}
|
|
231
|
-
return (
|
|
215
|
+
return (firstCharacter(words[0]) + firstCharacter(words[words.length - 1])).toUpperCase();
|
|
232
216
|
}
|
|
233
217
|
|
|
234
218
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PowerSearch.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/PowerSearch.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,EAGL,KAAK,yBAAyB,EAC/B,MAAM,cAAc,CAAC;AAMtB,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"PowerSearch.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/PowerSearch.tsx"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,7 @@ import { formatFilterValue } from "./formatFilterValue.js";
|
|
|
33
33
|
import { PowerSearchEditPopover } from "./PowerSearchEditPopover.js";
|
|
34
34
|
import { resolveOperatorLabel } from "./resolveOperatorLabel.js";
|
|
35
35
|
import { themeProps } from "../utils/themeProps.js";
|
|
36
|
+
import { truncateCharacters } from "../utils/characters.js";
|
|
36
37
|
import { useTranslator } from "../i18n/index.js";
|
|
37
38
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
38
39
|
// =============================================================================
|
|
@@ -68,7 +69,9 @@ const popoverLayerStyles = {
|
|
|
68
69
|
}
|
|
69
70
|
};
|
|
70
71
|
function truncateString(value, limit) {
|
|
71
|
-
|
|
72
|
+
// Same semantics as before — strings within limit + 3 pass through, longer
|
|
73
|
+
// ones cut to limit + '...' — but counted in characters, not code units.
|
|
74
|
+
return truncateCharacters(value, limit + 3, '...');
|
|
72
75
|
}
|
|
73
76
|
function getEnumLabel(values, value) {
|
|
74
77
|
return values.find(v => v.value === value)?.label ?? value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatFilterValue.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/formatFilterValue.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAE,WAAW,EAAW,MAAM,SAAS,CAAC;AAClE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"formatFilterValue.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/formatFilterValue.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAE,WAAW,EAAW,MAAM,SAAS,CAAC;AAClE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AA4C1C,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,EACjB,CAAC,EAAE,YAAY,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAsHR"}
|
|
@@ -10,11 +10,9 @@
|
|
|
10
10
|
* - /packages/core/src/PowerSearch/index.ts
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import { truncateCharacters } from "../utils/characters.js";
|
|
13
14
|
function truncate(str, maxLength) {
|
|
14
|
-
|
|
15
|
-
return str;
|
|
16
|
-
}
|
|
17
|
-
return str.slice(0, maxLength - 1) + '\u2026';
|
|
15
|
+
return truncateCharacters(str, maxLength);
|
|
18
16
|
}
|
|
19
17
|
function formatEnumLabel(value, enumValues) {
|
|
20
18
|
const item = enumValues.find(v => v.value === value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"columnUtils.d.ts","sourceRoot":"","sources":["../../src/Table/columnUtils.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AACpD,OAAO,KAAK,EAAC,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"columnUtils.d.ts","sourceRoot":"","sources":["../../src/Table/columnUtils.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AACpD,OAAO,KAAK,EAAC,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAC,MAAM,SAAS,CAAC;AAGxE,8DAA8D;AAC9D,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAM5C;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,KAAK,EAAE,aAAa,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,sDAAsD;IACtD,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC1C,oGAAoG;IACpG,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,GACxB,oBAAoB,CAmEtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,KAAK,GAAE,MAAU,EACjB,OAAO,CAAC,EAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAC,GAC5B,iBAAiB,CAMnB;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAE/C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnE,IAAI,EAAE,CAAC,EACP,GAAG,EAAE,MAAM,GACV,SAAS,CAiBX;AA+DD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,IAAI,EAAE,CAAC,EAAE,GACR,WAAW,CAAC,CAAC,CAAC,EAAE,CAmDlB"}
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* - /packages/core/src/Table/index.ts (exports if functions change)
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { firstCharacter } from "../utils/characters.js";
|
|
15
|
+
|
|
14
16
|
/** Default minimum width (in px) for proportional columns. */
|
|
15
17
|
export const DEFAULT_MIN_COLUMN_WIDTH = 120;
|
|
16
18
|
|
|
@@ -153,7 +155,8 @@ export function capitalize(str) {
|
|
|
153
155
|
if (str.length === 0) {
|
|
154
156
|
return str;
|
|
155
157
|
}
|
|
156
|
-
|
|
158
|
+
const first = firstCharacter(str);
|
|
159
|
+
return first.toUpperCase() + str.slice(first.length);
|
|
157
160
|
}
|
|
158
161
|
|
|
159
162
|
/**
|
|
@@ -149,10 +149,13 @@ export interface TextAreaProps extends Omit<BaseProps, 'onChange' | 'defaultValu
|
|
|
149
149
|
*/
|
|
150
150
|
onPaste?: (e: ClipboardEvent<HTMLTextAreaElement>) => void;
|
|
151
151
|
/**
|
|
152
|
-
* Maximum number of characters allowed
|
|
153
|
-
*
|
|
152
|
+
* Maximum number of characters allowed, counted as user-perceived
|
|
153
|
+
* characters — an emoji or flag sequence counts as one. When set,
|
|
154
|
+
* displays a character counter below the textarea.
|
|
154
155
|
* Does not enforce the limit natively — the counter shows error styling
|
|
155
|
-
* when exceeded, and the consumer can validate via onChange.
|
|
156
|
+
* when exceeded, and the consumer can validate via onChange. Validate with
|
|
157
|
+
* `characterCount` (exported from this package) rather than `value.length`
|
|
158
|
+
* so enforcement matches the displayed count.
|
|
156
159
|
*/
|
|
157
160
|
maxLength?: number;
|
|
158
161
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../src/TextArea/TextArea.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../src/TextArea/TextArea.tsx"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - /apps/storybook/stories/TextArea.stories.tsx (storybook stories)
|
|
16
16
|
* - /packages/cli/assets/templates/blocks/components/TextArea/ (showcase blocks)
|
|
17
17
|
*/
|
|
18
|
-
import { useId, useOptimistic, useTransition, useRef, useCallback } from 'react';
|
|
18
|
+
import { useId, useOptimistic, useTransition, useRef, useCallback, useMemo } from 'react';
|
|
19
19
|
import * as stylex from '@stylexjs/stylex';
|
|
20
20
|
import "../theme/tokens.stylex.js";
|
|
21
21
|
import { colorVars, spacingVars, typographyVars, typeScaleVars } from "../theme/tokens.stylex.js";
|
|
@@ -29,6 +29,7 @@ import { useInputStatusIcon } from "../hooks/useInputStatusIcon.js";
|
|
|
29
29
|
import { useAnnounce } from "../hooks/useAnnounce.js";
|
|
30
30
|
import { useSize } from "../SizeContext/SizeContext.js";
|
|
31
31
|
import { themeProps } from "../utils/themeProps.js";
|
|
32
|
+
import { characterCount } from "../utils/characters.js";
|
|
32
33
|
import { useTranslator } from "../i18n/index.js";
|
|
33
34
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
34
35
|
const COUNTER_WARNING_THRESHOLD = 0.8;
|
|
@@ -208,7 +209,11 @@ export function TextArea({
|
|
|
208
209
|
return;
|
|
209
210
|
}
|
|
210
211
|
const newValue = e.target.value;
|
|
211
|
-
announceCounter
|
|
212
|
+
// Guarded here, not just inside announceCounter, so textareas without a
|
|
213
|
+
// maxLength never pay for segmenting the whole value on each keystroke.
|
|
214
|
+
if (maxLength != null) {
|
|
215
|
+
announceCounter(characterCount(newValue));
|
|
216
|
+
}
|
|
212
217
|
onChange?.(newValue, e);
|
|
213
218
|
if (changeAction && !e.defaultPrevented) {
|
|
214
219
|
startTransition(async () => {
|
|
@@ -217,6 +222,12 @@ export function TextArea({
|
|
|
217
222
|
});
|
|
218
223
|
}
|
|
219
224
|
};
|
|
225
|
+
|
|
226
|
+
// Counter semantics count user-perceived characters, so an emoji or flag
|
|
227
|
+
// sequence counts as one character, not its code units.
|
|
228
|
+
// Only measured when a counter exists — segmentation is O(value length),
|
|
229
|
+
// and memoized so re-renders that keep the same value skip it entirely.
|
|
230
|
+
const valueLength = useMemo(() => maxLength != null ? characterCount(optimisticValue) : 0, [maxLength, optimisticValue]);
|
|
220
231
|
const effectivelyDisabled = isDisabled || isBusy;
|
|
221
232
|
|
|
222
233
|
// Focus textarea when clicking anywhere on the wrapper (icons, padding, etc.)
|
|
@@ -293,7 +304,7 @@ export function TextArea({
|
|
|
293
304
|
"data-autofocus": hasAutoFocus || undefined,
|
|
294
305
|
"aria-describedby": ariaDescribedBy,
|
|
295
306
|
"aria-required": isRequired && !isOptional ? 'true' : undefined,
|
|
296
|
-
"aria-invalid": status?.type === 'error' || maxLength != null &&
|
|
307
|
+
"aria-invalid": status?.type === 'error' || maxLength != null && valueLength > maxLength ? 'true' : undefined,
|
|
297
308
|
"aria-busy": isBusy || undefined,
|
|
298
309
|
...stylex.props(styles.textarea, textareaSizeStyles[size], isDisabled && styles.textareaDisabled, Boolean(startIcon) && styles.textareaWithStartIcon,
|
|
299
310
|
// Reserve trailing space only when the end slot actually renders
|
|
@@ -318,8 +329,8 @@ export function TextArea({
|
|
|
318
329
|
1: {
|
|
319
330
|
className: "x10l6tqk x112dmjn x13oyzgk x47corl x78zum5 x6s0dn4 xzye2dw x9ynric x141an7d x1ltkj2j xjt36v0"
|
|
320
331
|
}
|
|
321
|
-
}[!!(
|
|
322
|
-
children: [
|
|
332
|
+
}[!!(valueLength > maxLength) << 0],
|
|
333
|
+
children: [valueLength > maxLength &&
|
|
323
334
|
/*#__PURE__*/
|
|
324
335
|
// Non-color cue so the over-limit state isn't conveyed by the red
|
|
325
336
|
// color alone (WCAG 1.4.1). Decorative — the count text and the
|
|
@@ -327,7 +338,7 @@ export function TextArea({
|
|
|
327
338
|
_jsx(Icon, {
|
|
328
339
|
icon: "warning",
|
|
329
340
|
size: "sm"
|
|
330
|
-
}),
|
|
341
|
+
}), valueLength, "/", maxLength]
|
|
331
342
|
})]
|
|
332
343
|
}), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
|
|
333
344
|
});
|
|
@@ -226,7 +226,8 @@ export function TreeList({
|
|
|
226
226
|
ref: ref,
|
|
227
227
|
"data-testid": testId,
|
|
228
228
|
...mergeProps(themeProps('tree-list', {
|
|
229
|
-
density
|
|
229
|
+
density,
|
|
230
|
+
variant
|
|
230
231
|
}), stylex.props(styles.root, xstyle), className, style),
|
|
231
232
|
children: [header != null && /*#__PURE__*/_jsx("div", {
|
|
232
233
|
id: headerId,
|