@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.
Files changed (78) hide show
  1. package/lib/components/Field/Field.d.ts +47 -0
  2. package/lib/components/Field/Field.d.ts.map +1 -0
  3. package/lib/components/Field/Field.jsx +121 -0
  4. package/lib/components/Field/Field.namespace.d.ts +2 -0
  5. package/lib/components/Field/Field.namespace.d.ts.map +1 -0
  6. package/lib/components/Field/Field.namespace.js +16 -0
  7. package/lib/components/Field/context.d.ts +19 -0
  8. package/lib/components/Field/context.d.ts.map +1 -0
  9. package/lib/components/Field/context.js +10 -0
  10. package/lib/components/Field/index.d.ts +3 -0
  11. package/lib/components/Field/index.d.ts.map +1 -0
  12. package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.d.ts +42 -0
  13. package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.d.ts.map +1 -0
  14. package/lib/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.jsx +140 -0
  15. package/lib/components/KeyboardAvoidingScrollView/context.d.ts +17 -0
  16. package/lib/components/KeyboardAvoidingScrollView/context.d.ts.map +1 -0
  17. package/lib/components/KeyboardAvoidingScrollView/context.js +12 -0
  18. package/lib/components/KeyboardAvoidingScrollView/engine.d.ts +50 -0
  19. package/lib/components/KeyboardAvoidingScrollView/engine.d.ts.map +1 -0
  20. package/lib/components/KeyboardAvoidingScrollView/engine.js +259 -0
  21. package/lib/components/KeyboardAvoidingScrollView/geometry.d.ts +50 -0
  22. package/lib/components/KeyboardAvoidingScrollView/geometry.d.ts.map +1 -0
  23. package/lib/components/KeyboardAvoidingScrollView/geometry.js +90 -0
  24. package/lib/components/KeyboardAvoidingScrollView/index.d.ts +2 -0
  25. package/lib/components/KeyboardAvoidingScrollView/index.d.ts.map +1 -0
  26. package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.d.ts +11 -0
  27. package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.d.ts.map +1 -0
  28. package/lib/components/KeyboardAvoidingScrollView/keyboard-event-source.js +43 -0
  29. package/lib/components/KeyboardAvoidingScrollView/native-driver.d.ts +34 -0
  30. package/lib/components/KeyboardAvoidingScrollView/native-driver.d.ts.map +1 -0
  31. package/lib/components/KeyboardAvoidingScrollView/native-driver.js +133 -0
  32. package/lib/components/TextField/TextField.d.ts +113 -0
  33. package/lib/components/TextField/TextField.d.ts.map +1 -0
  34. package/lib/components/TextField/TextField.jsx +418 -0
  35. package/lib/components/TextField/TextField.namespace.d.ts +2 -0
  36. package/lib/components/TextField/TextField.namespace.d.ts.map +1 -0
  37. package/lib/components/TextField/TextField.namespace.js +14 -0
  38. package/lib/components/TextField/context.d.ts +22 -0
  39. package/lib/components/TextField/context.d.ts.map +1 -0
  40. package/lib/components/TextField/context.js +7 -0
  41. package/lib/components/TextField/index.d.ts +4 -0
  42. package/lib/components/TextField/index.d.ts.map +1 -0
  43. package/lib/components/TextField/useTextFieldWithGraphemes.d.ts +24 -0
  44. package/lib/components/TextField/useTextFieldWithGraphemes.d.ts.map +1 -0
  45. package/lib/components/TextField/useTextFieldWithGraphemes.js +47 -0
  46. package/lib/components/index.d.ts +3 -0
  47. package/lib/components/index.d.ts.map +1 -1
  48. package/lib/index.js +7 -1
  49. package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_grapheme_data.js +8 -0
  50. package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/_incb_data.js +14 -0
  51. package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/core.js +68 -0
  52. package/lib/node_modules/.bun/unicode-segmenter@0.14.5/node_modules/unicode-segmenter/grapheme.js +175 -0
  53. package/package.json +6 -4
  54. package/src/components/Field/Field.namespace.ts +19 -0
  55. package/src/components/Field/Field.test.tsx +81 -0
  56. package/src/components/Field/Field.tsx +252 -0
  57. package/src/components/Field/context.ts +26 -0
  58. package/src/components/Field/index.ts +21 -0
  59. package/src/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.test.tsx +267 -0
  60. package/src/components/KeyboardAvoidingScrollView/KeyboardAvoidingScrollView.tsx +299 -0
  61. package/src/components/KeyboardAvoidingScrollView/context.ts +24 -0
  62. package/src/components/KeyboardAvoidingScrollView/engine.test.ts +451 -0
  63. package/src/components/KeyboardAvoidingScrollView/engine.ts +417 -0
  64. package/src/components/KeyboardAvoidingScrollView/geometry.test.ts +315 -0
  65. package/src/components/KeyboardAvoidingScrollView/geometry.ts +194 -0
  66. package/src/components/KeyboardAvoidingScrollView/index.ts +5 -0
  67. package/src/components/KeyboardAvoidingScrollView/keyboard-event-source.test.ts +122 -0
  68. package/src/components/KeyboardAvoidingScrollView/keyboard-event-source.ts +75 -0
  69. package/src/components/KeyboardAvoidingScrollView/native-driver.test.ts +223 -0
  70. package/src/components/KeyboardAvoidingScrollView/native-driver.ts +248 -0
  71. package/src/components/TextField/TextField.namespace.ts +16 -0
  72. package/src/components/TextField/TextField.test.tsx +924 -0
  73. package/src/components/TextField/TextField.tsx +912 -0
  74. package/src/components/TextField/context.ts +33 -0
  75. package/src/components/TextField/index.ts +23 -0
  76. package/src/components/TextField/useTextFieldWithGraphemes.test.tsx +80 -0
  77. package/src/components/TextField/useTextFieldWithGraphemes.ts +78 -0
  78. 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 };
@@ -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 };
@@ -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.1",
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.5.1",
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
- "clsx": "^2.1.1"
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
+ });