@seed-design/lynx-react 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/Field/Field.d.ts +47 -0
- package/lib/components/Field/Field.d.ts.map +1 -0
- package/lib/components/Field/Field.jsx +121 -0
- package/lib/components/Field/Field.namespace.d.ts +2 -0
- package/lib/components/Field/Field.namespace.d.ts.map +1 -0
- package/lib/components/Field/Field.namespace.js +16 -0
- package/lib/components/Field/context.d.ts +19 -0
- package/lib/components/Field/context.d.ts.map +1 -0
- package/lib/components/Field/context.js +10 -0
- package/lib/components/Field/index.d.ts +3 -0
- package/lib/components/Field/index.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.d.ts +42 -0
- package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.jsx +140 -0
- package/lib/components/KeyboardAvoidingScrollView/context.d.ts +17 -0
- package/lib/components/KeyboardAvoidingScrollView/context.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/context.js +12 -0
- package/lib/components/KeyboardAvoidingScrollView/engine.d.ts +50 -0
- package/lib/components/KeyboardAvoidingScrollView/engine.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/engine.js +259 -0
- package/lib/components/KeyboardAvoidingScrollView/geometry.d.ts +50 -0
- package/lib/components/KeyboardAvoidingScrollView/geometry.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/geometry.js +90 -0
- package/lib/components/KeyboardAvoidingScrollView/index.d.ts +2 -0
- package/lib/components/KeyboardAvoidingScrollView/index.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.d.ts +11 -0
- package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.js +43 -0
- package/lib/components/KeyboardAvoidingScrollView/native-driver.d.ts +34 -0
- package/lib/components/KeyboardAvoidingScrollView/native-driver.d.ts.map +1 -0
- package/lib/components/KeyboardAvoidingScrollView/native-driver.js +133 -0
- package/lib/components/TextField/TextField.d.ts +113 -0
- package/lib/components/TextField/TextField.d.ts.map +1 -0
- package/lib/components/TextField/TextField.jsx +418 -0
- package/lib/components/TextField/TextField.namespace.d.ts +2 -0
- package/lib/components/TextField/TextField.namespace.d.ts.map +1 -0
- package/lib/components/TextField/TextField.namespace.js +14 -0
- package/lib/components/TextField/context.d.ts +22 -0
- package/lib/components/TextField/context.d.ts.map +1 -0
- package/lib/components/TextField/context.js +7 -0
- package/lib/components/TextField/index.d.ts +4 -0
- package/lib/components/TextField/index.d.ts.map +1 -0
- package/lib/components/TextField/useTextFieldWithGraphemes.d.ts +24 -0
- package/lib/components/TextField/useTextFieldWithGraphemes.d.ts.map +1 -0
- package/lib/components/TextField/useTextFieldWithGraphemes.js +47 -0
- package/lib/components/index.d.ts +3 -0
- package/lib/components/index.d.ts.map +1 -1
- package/lib/index.js +7 -1
- package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_grapheme_data.js +8 -0
- package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_incb_data.js +14 -0
- package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/core.js +68 -0
- package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/grapheme.js +175 -0
- package/package.json +6 -4
- package/src/components/Field/Field.namespace.ts +19 -0
- package/src/components/Field/Field.test.tsx +81 -0
- package/src/components/Field/Field.tsx +252 -0
- package/src/components/Field/context.ts +26 -0
- package/src/components/Field/index.ts +21 -0
- package/src/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.test.tsx +267 -0
- package/src/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.tsx +299 -0
- package/src/components/KeyboardAvoidingScrollView/context.ts +24 -0
- package/src/components/KeyboardAvoidingScrollView/engine.test.ts +451 -0
- package/src/components/KeyboardAvoidingScrollView/engine.ts +417 -0
- package/src/components/KeyboardAvoidingScrollView/geometry.test.ts +315 -0
- package/src/components/KeyboardAvoidingScrollView/geometry.ts +194 -0
- package/src/components/KeyboardAvoidingScrollView/index.ts +5 -0
- package/src/components/KeyboardAvoidingScrollView/keyboard-event-source.test.ts +122 -0
- package/src/components/KeyboardAvoidingScrollView/keyboard-event-source.ts +75 -0
- package/src/components/KeyboardAvoidingScrollView/native-driver.test.ts +223 -0
- package/src/components/KeyboardAvoidingScrollView/native-driver.ts +248 -0
- package/src/components/TextField/TextField.namespace.ts +16 -0
- package/src/components/TextField/TextField.test.tsx +924 -0
- package/src/components/TextField/TextField.tsx +912 -0
- package/src/components/TextField/context.ts +33 -0
- package/src/components/TextField/index.ts +23 -0
- package/src/components/TextField/useTextFieldWithGraphemes.test.tsx +80 -0
- package/src/components/TextField/useTextFieldWithGraphemes.ts +78 -0
- package/src/components/index.ts +3 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { NATIVE_TEXT_MAX_LENGTH_UNLIMITED } from "./context.js";
|
|
2
|
+
import { splitGraphemes } from "../../node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/grapheme.js";
|
|
3
|
+
import * as React from "@lynx-js/react";
|
|
4
|
+
//#region src/components/TextField/useTextFieldWithGraphemes.ts
|
|
5
|
+
var cachedValue = "";
|
|
6
|
+
var cachedGraphemes = [];
|
|
7
|
+
function getGraphemes(value) {
|
|
8
|
+
if (value === cachedValue) return cachedGraphemes;
|
|
9
|
+
cachedValue = value;
|
|
10
|
+
cachedGraphemes = Array.from(splitGraphemes(value));
|
|
11
|
+
return cachedGraphemes;
|
|
12
|
+
}
|
|
13
|
+
function useTextFieldWithGraphemes({ maxGraphemeCount, value: controlledValue, defaultValue = "", onValueChange }) {
|
|
14
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
|
|
15
|
+
const isControlled = controlledValue !== void 0;
|
|
16
|
+
const value = isControlled ? controlledValue : uncontrolledValue;
|
|
17
|
+
const graphemes = React.useMemo(() => getGraphemes(value), [value]);
|
|
18
|
+
return {
|
|
19
|
+
textFieldRootProps: {
|
|
20
|
+
value,
|
|
21
|
+
onValueChange: React.useCallback((nextValue) => {
|
|
22
|
+
"background only";
|
|
23
|
+
const nextGraphemes = getGraphemes(nextValue);
|
|
24
|
+
const slicedGraphemes = maxGraphemeCount === void 0 ? nextGraphemes : nextGraphemes.slice(0, maxGraphemeCount);
|
|
25
|
+
if (!isControlled) setUncontrolledValue(nextValue);
|
|
26
|
+
onValueChange?.({
|
|
27
|
+
value: nextValue,
|
|
28
|
+
graphemes: nextGraphemes,
|
|
29
|
+
slicedValue: slicedGraphemes.join(""),
|
|
30
|
+
slicedGraphemes
|
|
31
|
+
});
|
|
32
|
+
}, [
|
|
33
|
+
isControlled,
|
|
34
|
+
maxGraphemeCount,
|
|
35
|
+
onValueChange
|
|
36
|
+
]),
|
|
37
|
+
nativeInsertionMaxLength: maxGraphemeCount === void 0 ? void 0 : graphemes.length >= maxGraphemeCount ? value.length : NATIVE_TEXT_MAX_LENGTH_UNLIMITED
|
|
38
|
+
},
|
|
39
|
+
counterProps: {
|
|
40
|
+
current: graphemes.length,
|
|
41
|
+
max: maxGraphemeCount ?? 0
|
|
42
|
+
},
|
|
43
|
+
graphemes
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { useTextFieldWithGraphemes };
|
|
@@ -4,11 +4,14 @@ export * from './Badge';
|
|
|
4
4
|
export * from './Box';
|
|
5
5
|
export * from './BottomSheet';
|
|
6
6
|
export * from './Checkbox';
|
|
7
|
+
export * from './Field';
|
|
7
8
|
export * from './Icon';
|
|
9
|
+
export * from './KeyboardAvoidingScrollView';
|
|
8
10
|
export * from './ProgressCircle';
|
|
9
11
|
export * from './RadioGroup';
|
|
10
12
|
export * from './Stack';
|
|
11
13
|
export * from './Switch';
|
|
12
14
|
export * from './TagGroup';
|
|
13
15
|
export * from './Text';
|
|
16
|
+
export * from './TextField';
|
|
14
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -17,6 +17,9 @@ import { useControllableState } from "./hooks/useControllableState.js";
|
|
|
17
17
|
import { splitMultipleVariantsProps } from "./utils/split-multiple-variants-props.js";
|
|
18
18
|
import { CheckboxControl, CheckboxGroup, CheckboxIndicator, CheckboxLabel, CheckboxRoot } from "./components/Checkbox/Checkbox.jsx";
|
|
19
19
|
import { Checkbox_namespace_exports } from "./components/Checkbox/Checkbox.namespace.js";
|
|
20
|
+
import { FieldCharacterCount, FieldDescription, FieldErrorMessage, FieldFooter, FieldHeader, FieldIndicatorText, FieldLabel, FieldRequiredIndicator, FieldRoot } from "./components/Field/Field.jsx";
|
|
21
|
+
import { Field_namespace_exports } from "./components/Field/Field.namespace.js";
|
|
22
|
+
import { KeyboardAvoidingScrollView } from "./components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.jsx";
|
|
20
23
|
import { RadioGroupItem, RadioGroupItemControl, RadioGroupItemIndicator, RadioGroupItemLabel, RadioGroupRoot } from "./components/RadioGroup/RadioGroup.jsx";
|
|
21
24
|
import { RadioGroup_namespace_exports } from "./components/RadioGroup/RadioGroup.namespace.js";
|
|
22
25
|
import { HStack, VStack } from "./components/Stack/Stack.jsx";
|
|
@@ -25,6 +28,9 @@ import { Switch_namespace_exports } from "./components/Switch/Switch.namespace.j
|
|
|
25
28
|
import { TagGroupItem, TagGroupItemLabel, TagGroupRoot } from "./components/TagGroup/TagGroup.jsx";
|
|
26
29
|
import { TagGroup_namespace_exports } from "./components/TagGroup/TagGroup.namespace.js";
|
|
27
30
|
import { Text } from "./components/Text/Text.jsx";
|
|
31
|
+
import { TextFieldInput, TextFieldPrefixIcon, TextFieldPrefixText, TextFieldRoot, TextFieldSuffixIcon, TextFieldSuffixText, TextFieldTextarea } from "./components/TextField/TextField.jsx";
|
|
32
|
+
import { useTextFieldWithGraphemes } from "./components/TextField/useTextFieldWithGraphemes.js";
|
|
33
|
+
import { TextField_namespace_exports } from "./components/TextField/TextField.namespace.js";
|
|
28
34
|
import { getSeedClassName } from "./utils/get-seed-class-name.js";
|
|
29
35
|
import { useSeedClassName } from "./hooks/useSeedClassName.js";
|
|
30
|
-
export { ActionButton, AppBar_namespace_exports as AppBar, AppBarIconButton, AppBarLeft, AppBarMain, AppBarRight, AppBarRoot, AppBarSlot, AppBarSubtitle, AppBarTitle, Badge, BottomSheet_namespace_exports as BottomSheet, BottomSheetBackdrop, BottomSheetBody, BottomSheetContent, BottomSheetDescription, BottomSheetFooter, BottomSheetHandle, BottomSheetHeader, BottomSheetPositioner, BottomSheetRoot, BottomSheetTitle, BottomSheetTrigger, Box, Checkbox_namespace_exports as Checkbox, CheckboxControl, CheckboxGroup, CheckboxIndicator, CheckboxLabel, CheckboxRoot, HStack, Icon, PrefixIcon, ProgressCircle_namespace_exports as ProgressCircle, ProgressCircleRange, ProgressCircleRoot, RadioGroup_namespace_exports as RadioGroup, RadioGroupItem, RadioGroupItemControl, RadioGroupItemIndicator, RadioGroupItemLabel, RadioGroupRoot, SuffixIcon, Switch_namespace_exports as Switch, SwitchControl, SwitchLabel, SwitchRoot, SwitchThumb, TagGroup_namespace_exports as TagGroup, TagGroupItem, TagGroupItemLabel, TagGroupRoot, Text, VStack, capitalize, createSlotRecipeContext, getSeedClassName, resolveRecipeToken, splitMultipleVariantsProps, useControllableState, useIconColor, usePressTap, useSafeArea, useSeedClassName };
|
|
36
|
+
export { ActionButton, AppBar_namespace_exports as AppBar, AppBarIconButton, AppBarLeft, AppBarMain, AppBarRight, AppBarRoot, AppBarSlot, AppBarSubtitle, AppBarTitle, Badge, BottomSheet_namespace_exports as BottomSheet, BottomSheetBackdrop, BottomSheetBody, BottomSheetContent, BottomSheetDescription, BottomSheetFooter, BottomSheetHandle, BottomSheetHeader, BottomSheetPositioner, BottomSheetRoot, BottomSheetTitle, BottomSheetTrigger, Box, Checkbox_namespace_exports as Checkbox, CheckboxControl, CheckboxGroup, CheckboxIndicator, CheckboxLabel, CheckboxRoot, Field_namespace_exports as Field, FieldCharacterCount, FieldDescription, FieldErrorMessage, FieldFooter, FieldHeader, FieldIndicatorText, FieldLabel, FieldRequiredIndicator, FieldRoot, HStack, Icon, KeyboardAvoidingScrollView, PrefixIcon, ProgressCircle_namespace_exports as ProgressCircle, ProgressCircleRange, ProgressCircleRoot, RadioGroup_namespace_exports as RadioGroup, RadioGroupItem, RadioGroupItemControl, RadioGroupItemIndicator, RadioGroupItemLabel, RadioGroupRoot, SuffixIcon, Switch_namespace_exports as Switch, SwitchControl, SwitchLabel, SwitchRoot, SwitchThumb, TagGroup_namespace_exports as TagGroup, TagGroupItem, TagGroupItemLabel, TagGroupRoot, Text, TextField_namespace_exports as TextField, TextFieldInput, TextFieldPrefixIcon, TextFieldPrefixText, TextFieldRoot, TextFieldSuffixIcon, TextFieldSuffixText, TextFieldTextarea, VStack, capitalize, createSlotRecipeContext, getSeedClassName, resolveRecipeToken, splitMultipleVariantsProps, useControllableState, useIconColor, usePressTap, useSafeArea, useSeedClassName, useTextFieldWithGraphemes };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { decodeUnicodeData } from "./core.js";
|
|
2
|
+
//#region ../../node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_grapheme_data.js
|
|
3
|
+
/**
|
|
4
|
+
* @type {GraphemeCategoryRange[]}
|
|
5
|
+
*/
|
|
6
|
+
var grapheme_ranges = decodeUnicodeData(",9,a,,b,1,d,,e,h,3j,w,4p,,4t,,4u,,lc,33,w3,6,13l,18,14v,,14x,1,150,1,153,,16o,5,174,a,17g,,18r,k,19s,,1cm,6,1ct,,1cv,5,1d3,1,1d6,3,1e7,,1e9,,1f4,q,1ie,a,1kb,8,1kt,,1li,3,1ln,8,1lx,2,1m1,4,1nd,2,1ow,1,1p3,8,1qi,n,1r6,,1r7,v,1s3,,1tm,,1tn,,1to,,1tq,2,1tt,7,1u1,3,1u5,,1u6,1,1u9,6,1uq,1,1vl,,1vm,1,1x8,,1xa,,1xb,1,1xd,3,1xj,1,1xn,1,1xp,,1xz,,1ya,1,1z2,,1z5,1,1z7,,20s,,20u,2,20x,1,213,1,217,2,21d,,228,1,22d,,22p,1,22r,,24c,,24e,2,24h,4,24n,1,24p,,24r,1,24t,,25e,1,262,5,269,,26a,1,27w,,27y,1,280,,281,3,287,1,28b,1,28d,,28l,2,28y,1,29u,,2bi,,2bj,,2bk,,2bl,1,2bq,2,2bu,2,2bx,,2c7,,2dc,,2dd,2,2dg,,2f0,,2f2,2,2f5,3,2fa,2,2fe,3,2fp,1,2g2,1,2gx,,2gy,1,2ik,,2im,,2in,1,2ip,,2iq,,2ir,1,2iu,2,2iy,3,2j9,1,2jm,1,2k3,,2kg,1,2ki,1,2m3,1,2m6,,2m7,1,2m9,3,2me,2,2mi,2,2ml,,2mm,,2mv,,2n6,1,2o1,,2o2,1,2q2,,2q7,,2q8,1,2qa,2,2qe,,2qg,6,2qn,,2r6,1,2sx,,2sz,,2t0,6,2tj,7,2wh,,2wj,,2wk,8,2x4,6,2zc,1,305,,307,,309,,30e,1,31t,d,327,,328,4,32e,1,32l,a,32x,z,346,,371,3,375,,376,5,37d,1,37f,1,37h,1,386,1,388,1,38e,2,38x,3,39e,,39g,,39h,1,39p,,3a5,,3cw,2n,3fk,1z,3hk,2f,3tp,2,4k2,3,4ky,2,4lu,1,4mq,1,4ok,1,4om,,4on,6,4ou,7,4p2,,4p3,1,4p5,a,4pp,,4qz,2,4r2,,4r3,,4ud,1,4vd,,4yo,2,4yr,3,4yv,1,4yx,2,4z4,1,4z6,,4z7,5,4zd,2,55j,1,55l,1,55n,,579,,57a,,57b,,57c,6,57k,,57m,,57p,7,57x,5,583,9,58f,,59s,u,5c0,3,5c4,,5dg,9,5dq,3,5du,2,5ez,8,5fk,1,5fm,,5gh,,5gi,3,5gm,1,5go,5,5ie,,5if,,5ig,1,5ii,2,5il,,5im,,5in,4,5k4,7,5kc,7,5kk,1,5km,1,5ow,2,5p0,c,5pd,,5pe,6,5pp,,5pw,,5pz,,5q0,1,5vk,1r,6bv,,6bw,,6bx,,6by,1,6co,6,6d8,,6dl,,6e8,f,6hc,w,6jm,,6k9,,6ms,5,6nd,1,6xm,1,6y0,,70o,,72n,,73d,a,73s,2,79e,,7fu,1,7g6,,7gg,,7i3,3,7i8,5,7if,b,7is,35,7m8,39,7pk,a,7pw,,7py,,7q5,,7q9,,7qg,,7qr,1,7r8,,7rb,,7rg,,7ri,,7rn,2,7rr,,7s3,4,7th,2,7tt,,7u8,,7un,,850,1,8hx,2,8ij,1,8k0,,8k5,,8vj,2,8zj,,928,v,wvj,3,wvo,9,wwu,1,wz4,1,x6q,,x6u,,x6z,,x7n,1,x7p,1,x7r,,x7w,,xa8,1,xbo,f,xc4,1,xcw,h,xdr,,xeu,7,xfr,a,xg2,,xg3,,xgg,s,xhc,2,xhf,,xir,,xis,1,xiu,3,xiy,1,xj0,1,xj2,1,xj4,,xk5,,xm1,5,xm7,1,xm9,1,xmb,1,xmd,1,xmr,,xn0,,xn1,,xoc,,xps,,xpu,2,xpz,1,xq6,1,xq9,,xrf,,xrg,1,xri,1,xrp,,xrq,,xyb,1,xyd,,xye,1,xyg,,xyh,1,xyk,,xyl,,1e68,f,1e74,f,1edb,,1ehq,1,1ek0,b,1eyl,,1f4w,,1f92,4,1gjl,2,1gjp,1,1gjw,3,1gl4,2,1glb,,1gpx,1,1h5w,3,1h7t,4,1hgr,1,1hj0,3,1hl2,a,1hmq,3,1hq8,,1hq9,,1hqa,,1hrs,e,1htc,,1htf,1,1htr,2,1htu,,1hv4,2,1hv7,3,1hvb,1,1hvd,1,1hvh,,1hvm,,1hvx,,1hxc,2,1hyf,4,1hyk,,1hyl,7,1hz9,1,1i0j,,1i0w,1,1i0y,,1i2b,2,1i2e,8,1i2n,,1i2o,,1i2q,1,1i2x,3,1i32,,1i33,,1i5o,2,1i5r,2,1i5u,1,1i5w,3,1i66,,1i69,,1ian,,1iao,2,1iar,7,1ibk,1,1ibm,1,1id7,1,1ida,,1idb,,1idc,,1idd,3,1idj,1,1idn,1,1idp,,1idz,,1iea,1,1iee,6,1ieo,4,1igo,,1igp,1,1igr,5,1igy,,1ih1,,1ih3,2,1ih6,,1ih8,1,1iha,2,1ihd,,1ihe,,1iht,1,1ik5,2,1ik8,7,1ikg,1,1iki,2,1ikl,,1ikm,,1ila,,1ink,,1inl,1,1inn,5,1int,,1inu,,1inv,1,1inx,,1iny,,1inz,1,1io1,,1io2,1,1iun,,1iuo,1,1iuq,3,1iuw,3,1iv0,1,1iv2,,1iv3,1,1ivw,1,1iy8,2,1iyb,7,1iyj,1,1iyl,,1iym,,1iyn,1,1j1n,,1j1o,,1j1p,,1j1q,1,1j1s,7,1j4t,,1j4u,,1j4v,,1j4y,3,1j52,,1j53,4,1jcc,2,1jcf,8,1jco,,1jcp,1,1jjk,,1jjl,4,1jjr,1,1jjv,3,1jjz,,1jk0,,1jk1,,1jk2,,1jk3,,1jo1,2,1jo4,3,1joa,1,1joc,3,1jog,,1jok,,1jpd,9,1jqr,5,1jqx,,1jqy,,1jqz,3,1jrb,,1jrl,5,1jrr,1,1jrt,2,1jt0,5,1jt6,c,1jtj,,1jtk,1,1k4v,,1k4w,6,1k54,5,1k5a,,1k5b,,1k7m,l,1k89,,1k8a,6,1k8h,,1k8i,1,1k8k,,1k8l,1,1kc1,5,1kca,,1kcc,1,1kcf,6,1kcm,,1kcn,,1kei,4,1keo,1,1ker,1,1ket,,1keu,,1kev,,1koj,1,1kol,1,1kow,1,1koy,,1koz,,1kqc,1,1kqe,4,1kqm,1,1kqo,2,1kre,,1ovk,f,1ow0,,1ow7,e,1xr2,b,1xre,2,1xrh,2,1zow,4,1zqo,6,206b,,206f,3,20jz,,20k1,1i,20lr,3,20o4,,20og,1,2ftp,1,2fts,3,2jgg,19,2jhs,m,2jxh,4,2jxp,5,2jxv,7,2jy3,7,2jyd,6,2jze,3,2k3m,2,2lmo,1i,2lob,1d,2lpx,,2lqc,,2lqz,4,2lr5,e,2mtc,6,2mtk,g,2mu3,6,2mub,1,2mue,4,2mxb,,2n1s,6,2nce,,2ne4,3,2nsc,3,2nzi,1,2ok0,6,2on8,6,2pz4,73,2q6l,2,2q7j,,2q98,5,2q9q,1,2qa6,,2qa9,9,2qb1,1k,2qcm,p,2qdd,e,2qe2,,2qen,,2qeq,8,2qf0,3,2qfd,c1,2qrf,4,2qrk,8t,2r0m,7d,2r9c,3j,2rg4,b,2rit,16,2rkc,3,2rm0,7,2rmi,5,2rns,7,2rou,29,2rrg,1a,2rss,9,2rt3,c8,2scg,sd,jny8,v,jnz4,2n,jo1s,3j,jo5c,6n,joc0,2rz", "262122424333333393233393339333333333393393b3b3b3b3b333b33b3bb33333b3b3333333b3b33bb3333b33b3bb33333b3bbb333b333b33333b3b3b3b3333b3b33b3bb39333b33b33b3b3b333b333333b3b333333b33b3b3333b3335dc333333b3b3b33323333b3bb3b33b3b3b3333b3333b3b333bb3b33b3b3b3b3b333b333b3323e2244234444444444444444444444444444444444444444443333333333b3b3bb33333b353b3b3b3b333b3b333b333333b3bb3b3b3bb333232333333333333333b3b3333bb3b393933b3b33bb3b393b3b3b3333b33b33b3bbb33b333b3333bb3933b3b3b333b3b3b3b3b33b3b3b33b3b3b33b3b33b33b3b3b33bb39b9b3b33b3b33b9333b393b3b33b33b3b3b3333393b3b3b33b39bb3b332333b333dd3b33332333323333333333333333333333344444444a44444434444444444444423232");
|
|
7
|
+
//#endregion
|
|
8
|
+
export { grapheme_ranges };
|
package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_incb_data.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { decodeUnicodeData } from "./core.js";
|
|
2
|
+
//#region ../../node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_incb_data.js
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('./core.js').UnicodeRange} UnicodeRange
|
|
5
|
+
* @typedef {import('./core.js').UnicodeDataEncoding} UnicodeDataEncoding
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The Unicode `Indic_Conjunct_Break=Consonant` derived property table
|
|
9
|
+
*
|
|
10
|
+
* @type {UnicodeRange[]}
|
|
11
|
+
*/
|
|
12
|
+
var consonant_ranges = decodeUnicodeData("1sl,10,1ug,7,1vc,7,1w5,j,1wq,6,1wy,,1x2,3,1y4,1,1y7,,1yo,1,239,j,23u,6,242,1,245,4,261,,26t,j,27e,6,27m,1,27p,4,28s,1,28v,,29d,,2dx,j,2ei,f,2fs,2,2l1,11");
|
|
13
|
+
//#endregion
|
|
14
|
+
export { consonant_ranges };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
//#region ../../node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/core.js
|
|
2
|
+
/**
|
|
3
|
+
* @template {number} [T=number]
|
|
4
|
+
* @typedef {[from: number, to: number, category: T]} CategorizedUnicodeRange
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {CategorizedUnicodeRange<0>} UnicodeRange
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {string & { __tag: 'UnicodeDataEncoding' }} UnicodeDataEncoding
|
|
11
|
+
*
|
|
12
|
+
* Encoding for array of {@link UnicodeRange}, items separated by comma.
|
|
13
|
+
*
|
|
14
|
+
* Each {@link UnicodeDataRow} packed as a base36 integer:
|
|
15
|
+
*
|
|
16
|
+
* padding = to - from
|
|
17
|
+
* encoding = base36(from) + ',' + base36(padding)
|
|
18
|
+
*
|
|
19
|
+
* Notes:
|
|
20
|
+
* - base36 can hold surprisingly large numbers in a few characters.
|
|
21
|
+
* - The biggest codepoint is 0xE01F0 (918,000) at this point
|
|
22
|
+
* - The max value of a category is 23; https://www.unicode.org/reports/tr29/tr29-45.html#Table_Word_Break_Property_Values
|
|
23
|
+
* - The longest range is 42,720; CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* @template {number} [T=number]
|
|
27
|
+
* @param {UnicodeDataEncoding} data
|
|
28
|
+
* @param {string} [cats='']
|
|
29
|
+
* @returns {Array<CategorizedUnicodeRange<T>>}
|
|
30
|
+
*/
|
|
31
|
+
function decodeUnicodeData(data, cats = "") {
|
|
32
|
+
let buf = [], nums = data.split(",").map((s) => s ? parseInt(s, 36) : 0), n = 0;
|
|
33
|
+
for (let i = 0; i < nums.length; i++) i % 2 ? buf.push([
|
|
34
|
+
n,
|
|
35
|
+
n + nums[i],
|
|
36
|
+
cats ? parseInt(cats[i >> 1], 36) : 0
|
|
37
|
+
]) : n = nums[i];
|
|
38
|
+
return buf;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* @template {object} Ext
|
|
42
|
+
* @typedef {{
|
|
43
|
+
* segment: string,
|
|
44
|
+
* index: number,
|
|
45
|
+
* input: string,
|
|
46
|
+
* } & Ext} SegmentOutput
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* @template {object} T
|
|
50
|
+
* @typedef {IterableIterator<SegmentOutput<T>>} Segmenter
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* @template {number} [T=number]
|
|
54
|
+
* @param {number} cp
|
|
55
|
+
* @param {CategorizedUnicodeRange<T>[]} ranges
|
|
56
|
+
* @return {number} index of matched unicode range, or -1 if no match
|
|
57
|
+
*/
|
|
58
|
+
function findUnicodeRangeIndex(cp, ranges, lo = 0, hi = ranges.length - 1) {
|
|
59
|
+
while (lo <= hi) {
|
|
60
|
+
let mid = lo + hi >>> 1, range = ranges[mid];
|
|
61
|
+
if (cp < range[0]) hi = mid - 1;
|
|
62
|
+
else if (cp > range[1]) lo = mid + 1;
|
|
63
|
+
else return mid;
|
|
64
|
+
}
|
|
65
|
+
return -1;
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { decodeUnicodeData, findUnicodeRangeIndex };
|
package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/grapheme.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { findUnicodeRangeIndex } from "./core.js";
|
|
2
|
+
import { grapheme_ranges } from "./_grapheme_data.js";
|
|
3
|
+
import { consonant_ranges } from "./_incb_data.js";
|
|
4
|
+
//#region ../../node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/grapheme.js
|
|
5
|
+
var BMP_MAX = 65535;
|
|
6
|
+
/**
|
|
7
|
+
* Unicode segmentation by extended grapheme rules.
|
|
8
|
+
*
|
|
9
|
+
* This is fully compatible with the {@link Intl.Segmenter.segment} API
|
|
10
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter/segment
|
|
11
|
+
*
|
|
12
|
+
* @param {string} input
|
|
13
|
+
* @return {GraphemeSegmenter} iterator for grapheme cluster segments
|
|
14
|
+
*/
|
|
15
|
+
function* graphemeSegments(input) {
|
|
16
|
+
let cp = input.codePointAt(0);
|
|
17
|
+
if (cp == null) return;
|
|
18
|
+
/** Current cursor position. */
|
|
19
|
+
let cursor = cp <= BMP_MAX ? 1 : 2;
|
|
20
|
+
/** Total length of the input string. */
|
|
21
|
+
let len = input.length;
|
|
22
|
+
/** Category of codepoint immediately preceding cursor */
|
|
23
|
+
let catBefore = cat(cp);
|
|
24
|
+
/** @type {GraphemeCategoryNum} Category of codepoint immediately preceding cursor. */
|
|
25
|
+
let catAfter = 0;
|
|
26
|
+
/** The number of RIS codepoints preceding `cursor`. */
|
|
27
|
+
let risCount = 0;
|
|
28
|
+
/**
|
|
29
|
+
* Emoji state for GB11: tracks if we've seen Extended_Pictographic followed by Extend* ZWJ
|
|
30
|
+
* Only relevant when catBefore === ZWJ && catAfter === Extended_Pictographic
|
|
31
|
+
*/
|
|
32
|
+
let emoji = false;
|
|
33
|
+
/** InCB=Consonant - segment started with Indic consonant */
|
|
34
|
+
let consonant = false;
|
|
35
|
+
/** InCB=Linker - seen a linker after consonant */
|
|
36
|
+
let linker = false;
|
|
37
|
+
let index = 0;
|
|
38
|
+
/** Beginning category of a segment */
|
|
39
|
+
let _catBegin = catBefore;
|
|
40
|
+
/** Memoize the beginning code point of the segment. */
|
|
41
|
+
let _hd = cp;
|
|
42
|
+
while (cursor < len) {
|
|
43
|
+
cp = input.codePointAt(cursor);
|
|
44
|
+
catAfter = cat(cp);
|
|
45
|
+
let boundary = true;
|
|
46
|
+
if (catBefore === 1) boundary = catAfter !== 6;
|
|
47
|
+
else if (catBefore === 2 || catBefore === 6) boundary = true;
|
|
48
|
+
else if (catAfter === 1 || catAfter === 2 || catAfter === 6) boundary = true;
|
|
49
|
+
else if (catAfter === 3 || catAfter === 14 || catAfter === 11) boundary = false;
|
|
50
|
+
else if (catBefore === 9) boundary = false;
|
|
51
|
+
else if (catBefore === 14 && catAfter === 4) boundary = !emoji;
|
|
52
|
+
else if (catBefore === 10 && catAfter === 10) boundary = risCount++ % 2 === 1;
|
|
53
|
+
else if (catBefore === 5) boundary = !(catAfter === 5 || catAfter === 13 || catAfter === 7 || catAfter === 8);
|
|
54
|
+
else if ((catBefore === 7 || catBefore === 13) && (catAfter === 13 || catAfter === 12)) boundary = false;
|
|
55
|
+
else if ((catBefore === 8 || catBefore === 12) && catAfter === 12) boundary = false;
|
|
56
|
+
else if (catAfter === 0 && consonant && linker && isIndicConjunctConsonant(cp)) boundary = false;
|
|
57
|
+
if (boundary) {
|
|
58
|
+
yield {
|
|
59
|
+
segment: input.slice(index, cursor),
|
|
60
|
+
index,
|
|
61
|
+
input,
|
|
62
|
+
_hd,
|
|
63
|
+
_catBegin,
|
|
64
|
+
_catEnd: catBefore
|
|
65
|
+
};
|
|
66
|
+
emoji = false;
|
|
67
|
+
risCount = 0;
|
|
68
|
+
index = cursor;
|
|
69
|
+
_catBegin = catAfter;
|
|
70
|
+
_hd = cp;
|
|
71
|
+
} else if (catAfter === 14 && (catBefore === 3 || catBefore === 4)) emoji = true;
|
|
72
|
+
else if (cp >= 2325) {
|
|
73
|
+
if (!consonant && catBefore === 0) consonant = isIndicConjunctConsonant(_hd);
|
|
74
|
+
if (consonant && catAfter === 3) linker = linker || cp === 2381 || cp === 2509 || cp === 2637 || cp === 2765 || cp === 2893 || cp === 3149 || cp === 3405;
|
|
75
|
+
else linker = false;
|
|
76
|
+
}
|
|
77
|
+
cursor += cp <= BMP_MAX ? 1 : 2;
|
|
78
|
+
catBefore = catAfter;
|
|
79
|
+
}
|
|
80
|
+
if (index < len) yield {
|
|
81
|
+
segment: input.slice(index),
|
|
82
|
+
index,
|
|
83
|
+
input,
|
|
84
|
+
_hd,
|
|
85
|
+
_catBegin,
|
|
86
|
+
_catEnd: catBefore
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Split given text into extended grapheme clusters.
|
|
91
|
+
*
|
|
92
|
+
* @param {string} text
|
|
93
|
+
* @return {IterableIterator<string>} iterator for grapheme clusters
|
|
94
|
+
*
|
|
95
|
+
* @see {@link graphemeSegments} if you need extra information.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* [...splitGraphemes('abc')] // => ['a', 'b', 'c']
|
|
99
|
+
*/
|
|
100
|
+
function* splitGraphemes(text) {
|
|
101
|
+
for (let s of graphemeSegments(text)) yield s.segment;
|
|
102
|
+
}
|
|
103
|
+
var SEG0 = new Uint8Array(6080), SEG0_MIN = 128, SEG0_MAX = 12287;
|
|
104
|
+
var SEG1 = new Uint8Array(1536), SEG1_MIN = 40960, SEG1_MAX = 44031;
|
|
105
|
+
var SEG_CURSOR = (() => {
|
|
106
|
+
let cursor = 0;
|
|
107
|
+
while (true) {
|
|
108
|
+
let [start, end, cat] = grapheme_ranges[cursor];
|
|
109
|
+
if (start > SEG1_MAX) break;
|
|
110
|
+
cursor++;
|
|
111
|
+
if (end < SEG0_MIN || start > SEG0_MAX && end < SEG1_MIN) continue;
|
|
112
|
+
for (let cp = start; cp <= end; cp++) {
|
|
113
|
+
let seg, idx = 0;
|
|
114
|
+
if (cp <= SEG0_MAX) {
|
|
115
|
+
seg = SEG0;
|
|
116
|
+
idx = cp - SEG0_MIN >> 1;
|
|
117
|
+
} else {
|
|
118
|
+
seg = SEG1;
|
|
119
|
+
idx = cp - SEG1_MIN >> 1;
|
|
120
|
+
}
|
|
121
|
+
seg[idx] = cp & 1 ? seg[idx] & 15 | cat << 4 : seg[idx] & 240 | cat;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return cursor;
|
|
125
|
+
})();
|
|
126
|
+
/**
|
|
127
|
+
* `Grapheme_Cluster_Break` property value of a given codepoint
|
|
128
|
+
*
|
|
129
|
+
* @see https://www.unicode.org/reports/tr29/tr29-43.html#Default_Grapheme_Cluster_Table
|
|
130
|
+
*
|
|
131
|
+
* @param {number} cp
|
|
132
|
+
* @return {GraphemeCategoryNum}
|
|
133
|
+
*/
|
|
134
|
+
function cat(cp) {
|
|
135
|
+
if (cp < SEG0_MIN) {
|
|
136
|
+
if (cp >= 32) return 0;
|
|
137
|
+
if (cp === 10) return 6;
|
|
138
|
+
if (cp === 13) return 1;
|
|
139
|
+
return 2;
|
|
140
|
+
}
|
|
141
|
+
if (cp <= SEG0_MAX) {
|
|
142
|
+
let byte = SEG0[cp - SEG0_MIN >> 1];
|
|
143
|
+
return cp & 1 ? byte >> 4 : byte & 15;
|
|
144
|
+
}
|
|
145
|
+
if (cp < SEG1_MIN) {
|
|
146
|
+
if (cp < 12336) return cp >= 12330 ? 3 : 0;
|
|
147
|
+
if (cp < 12443) {
|
|
148
|
+
if (cp === 12336 || cp === 12349) return 4;
|
|
149
|
+
return cp >= 12441 ? 3 : 0;
|
|
150
|
+
}
|
|
151
|
+
if (cp === 12951 || cp === 12953) return 4;
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
if (cp <= SEG1_MAX) {
|
|
155
|
+
let byte = SEG1[cp - SEG1_MIN >> 1];
|
|
156
|
+
return cp & 1 ? byte >> 4 : byte & 15;
|
|
157
|
+
}
|
|
158
|
+
if (cp <= 55203) return (cp - 44032) % 28 === 0 ? 7 : 8;
|
|
159
|
+
if (cp <= 55295) {
|
|
160
|
+
if (cp <= 55238) return cp >= 55216 ? 13 : 0;
|
|
161
|
+
return cp >= 55243 ? 12 : 0;
|
|
162
|
+
}
|
|
163
|
+
if (cp < 65024) return cp === 64286 ? 3 : 0;
|
|
164
|
+
let idx = findUnicodeRangeIndex(cp, grapheme_ranges, SEG_CURSOR);
|
|
165
|
+
return idx < 0 ? 0 : grapheme_ranges[idx][2];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* @param {number} cp
|
|
169
|
+
* @return {boolean}
|
|
170
|
+
*/
|
|
171
|
+
function isIndicConjunctConsonant(cp) {
|
|
172
|
+
return findUnicodeRangeIndex(cp, consonant_ranges) >= 0;
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
export { splitGraphemes };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seed-design/lynx-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/daangn/seed-design.git",
|
|
@@ -39,9 +39,10 @@
|
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@lynx-js/react": "^0.117.0",
|
|
41
41
|
"@lynx-js/types": "^3.7.0",
|
|
42
|
-
"@seed-design/lynx-css": "0.
|
|
42
|
+
"@seed-design/lynx-css": "0.8.0",
|
|
43
43
|
"@testing-library/jest-dom": "^6.9.1",
|
|
44
44
|
"jsdom": "^29.0.2",
|
|
45
|
+
"preact": "npm:@lynx-js/internal-preact@10.28.4-ee7bb26",
|
|
45
46
|
"vite": "^8.0.0",
|
|
46
47
|
"vite-plugin-dts": "^4.5.4",
|
|
47
48
|
"vitest": "^3.2.4"
|
|
@@ -50,8 +51,9 @@
|
|
|
50
51
|
"access": "public"
|
|
51
52
|
},
|
|
52
53
|
"dependencies": {
|
|
53
|
-
"@lynx-js/lynx-ui-sheet": "^3.130.1",
|
|
54
54
|
"@lynx-js/lynx-ui-common": "^3.130.0",
|
|
55
|
-
"
|
|
55
|
+
"@lynx-js/lynx-ui-sheet": "^3.130.1",
|
|
56
|
+
"clsx": "^2.1.1",
|
|
57
|
+
"unicode-segmenter": "^0.14.4"
|
|
56
58
|
}
|
|
57
59
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export {
|
|
2
|
+
FieldCharacterCount as CharacterCount,
|
|
3
|
+
FieldDescription as Description,
|
|
4
|
+
FieldErrorMessage as ErrorMessage,
|
|
5
|
+
FieldFooter as Footer,
|
|
6
|
+
FieldHeader as Header,
|
|
7
|
+
FieldIndicatorText as IndicatorText,
|
|
8
|
+
FieldLabel as Label,
|
|
9
|
+
FieldRequiredIndicator as RequiredIndicator,
|
|
10
|
+
FieldRoot as Root,
|
|
11
|
+
type FieldCharacterCountProps as CharacterCountProps,
|
|
12
|
+
type FieldDescriptionProps as DescriptionProps,
|
|
13
|
+
type FieldErrorMessageProps as ErrorMessageProps,
|
|
14
|
+
type FieldFooterProps as FooterProps,
|
|
15
|
+
type FieldHeaderProps as HeaderProps,
|
|
16
|
+
type FieldIndicatorTextProps as IndicatorTextProps,
|
|
17
|
+
type FieldLabelProps as LabelProps,
|
|
18
|
+
type FieldRootProps as RootProps,
|
|
19
|
+
} from "./Field";
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import { getQueriesForElement, render } from "@lynx-js/react/testing-library";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
import { Field } from "./index";
|
|
6
|
+
|
|
7
|
+
function getRenderedRoot() {
|
|
8
|
+
const root = elementTree.root;
|
|
9
|
+
|
|
10
|
+
if (!root) {
|
|
11
|
+
throw new Error("Expected Lynx render root to exist.");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return root;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getRenderedQueries() {
|
|
18
|
+
return getQueriesForElement(getRenderedRoot());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("Field", () => {
|
|
22
|
+
it("renders the complete field composition with recipe slot classes", () => {
|
|
23
|
+
render(
|
|
24
|
+
<Field.Root className="custom-field" required>
|
|
25
|
+
<Field.Header>
|
|
26
|
+
<Field.Label weight="bold">
|
|
27
|
+
제목
|
|
28
|
+
<Field.RequiredIndicator />
|
|
29
|
+
<Field.IndicatorText>필수</Field.IndicatorText>
|
|
30
|
+
</Field.Label>
|
|
31
|
+
</Field.Header>
|
|
32
|
+
<Field.Footer>
|
|
33
|
+
<Field.Description>설명</Field.Description>
|
|
34
|
+
<Field.CharacterCount current={3} max={10} />
|
|
35
|
+
</Field.Footer>
|
|
36
|
+
</Field.Root>,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const root = getRenderedRoot();
|
|
40
|
+
const { getByText } = getRenderedQueries();
|
|
41
|
+
const fieldRoot = root.querySelector(".seed-field__root");
|
|
42
|
+
|
|
43
|
+
expect(fieldRoot).toHaveClass("custom-field");
|
|
44
|
+
expect(root.querySelector(".seed-field__header")).toBeInTheDocument();
|
|
45
|
+
expect(root.querySelector(".seed-field__footer")).toBeInTheDocument();
|
|
46
|
+
expect(getByText("제목")).toHaveClass("seed-field-label__root--weight_bold");
|
|
47
|
+
expect(getByText("필수")).toHaveClass("seed-field-label__indicatorText");
|
|
48
|
+
expect(getByText("필수").textContent).toBe("\u00a0필수");
|
|
49
|
+
expect(getByText("*")).toHaveAttribute("accessibility-elements-hidden", "true");
|
|
50
|
+
expect(getByText("*").textContent).toBe("\u200a*");
|
|
51
|
+
expect(getByText("설명")).toHaveClass("seed-field__description");
|
|
52
|
+
expect(root.querySelector(".seed-field__characterCount")).toHaveTextContent("3");
|
|
53
|
+
expect(root.querySelector(".seed-field__maxCharacterCount")).toHaveTextContent("/10");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("applies invalid and empty character count variants", () => {
|
|
57
|
+
render(
|
|
58
|
+
<Field.Root invalid>
|
|
59
|
+
<Field.Footer>
|
|
60
|
+
<Field.ErrorMessage>오류</Field.ErrorMessage>
|
|
61
|
+
<Field.CharacterCount current={0} max={10} />
|
|
62
|
+
</Field.Footer>
|
|
63
|
+
</Field.Root>,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const { getByText } = getRenderedQueries();
|
|
67
|
+
|
|
68
|
+
expect(getByText("오류")).toHaveClass("seed-field__errorMessage");
|
|
69
|
+
const root = getRenderedRoot();
|
|
70
|
+
const current = root.querySelector(".seed-field__characterCount");
|
|
71
|
+
const max = root.querySelector(".seed-field__maxCharacterCount");
|
|
72
|
+
|
|
73
|
+
expect(current).toHaveClass("seed-field__characterCount--invalid_true");
|
|
74
|
+
expect(current).toHaveClass("seed-field__characterCount--empty_true");
|
|
75
|
+
expect(max).toHaveClass("seed-field__maxCharacterCount--invalid_true");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("throws when a compound slot is rendered outside Field.Root", () => {
|
|
79
|
+
expect(() => render(<Field.Footer />)).toThrow(/ClassNamesProvider/);
|
|
80
|
+
});
|
|
81
|
+
});
|