@seed-design/lynx-react 0.1.1-alpha.0 → 0.2.0-alpha.2

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 (180) hide show
  1. package/lib/components/ActionButton/ActionButton.d.ts +40 -9
  2. package/lib/components/ActionButton/ActionButton.d.ts.map +1 -1
  3. package/lib/components/ActionButton/ActionButton.jsx +132 -14
  4. package/lib/components/BottomSheet/BottomSheet.d.ts +92 -0
  5. package/lib/components/BottomSheet/BottomSheet.d.ts.map +1 -0
  6. package/lib/components/BottomSheet/BottomSheet.jsx +178 -0
  7. package/lib/components/BottomSheet/BottomSheet.namespace.d.ts +2 -0
  8. package/lib/components/BottomSheet/BottomSheet.namespace.d.ts.map +1 -0
  9. package/lib/components/BottomSheet/BottomSheet.namespace.js +1 -0
  10. package/lib/components/BottomSheet/index.d.ts +3 -0
  11. package/lib/components/BottomSheet/index.d.ts.map +1 -0
  12. package/lib/components/BottomSheet/index.js +2 -0
  13. package/lib/components/Checkbox/Checkbox.d.ts +51 -0
  14. package/lib/components/Checkbox/Checkbox.d.ts.map +1 -0
  15. package/lib/components/Checkbox/Checkbox.jsx +121 -0
  16. package/lib/components/Checkbox/Checkbox.namespace.d.ts +2 -0
  17. package/lib/components/Checkbox/Checkbox.namespace.d.ts.map +1 -0
  18. package/lib/components/Checkbox/Checkbox.namespace.js +1 -0
  19. package/lib/components/Checkbox/index.d.ts +3 -0
  20. package/lib/components/Checkbox/index.d.ts.map +1 -0
  21. package/lib/components/Checkbox/index.js +2 -0
  22. package/lib/components/ProgressCircle/ProgressCircle.d.ts +10 -9
  23. package/lib/components/ProgressCircle/ProgressCircle.d.ts.map +1 -1
  24. package/lib/components/ProgressCircle/ProgressCircle.jsx +8 -14
  25. package/lib/components/ProgressCircle/ProgressCircle.namespace.d.ts +2 -0
  26. package/lib/components/ProgressCircle/ProgressCircle.namespace.d.ts.map +1 -0
  27. package/lib/components/ProgressCircle/ProgressCircle.namespace.js +1 -0
  28. package/lib/components/ProgressCircle/index.d.ts +2 -1
  29. package/lib/components/ProgressCircle/index.d.ts.map +1 -1
  30. package/lib/components/ProgressCircle/index.js +2 -1
  31. package/lib/components/RadioGroup/RadioGroup.d.ts +50 -0
  32. package/lib/components/RadioGroup/RadioGroup.d.ts.map +1 -0
  33. package/lib/components/RadioGroup/RadioGroup.jsx +144 -0
  34. package/lib/components/RadioGroup/RadioGroup.namespace.d.ts +2 -0
  35. package/lib/components/RadioGroup/RadioGroup.namespace.d.ts.map +1 -0
  36. package/lib/components/RadioGroup/RadioGroup.namespace.js +1 -0
  37. package/lib/components/RadioGroup/index.d.ts +3 -0
  38. package/lib/components/RadioGroup/index.d.ts.map +1 -0
  39. package/lib/components/RadioGroup/index.js +2 -0
  40. package/lib/components/Switch/Switch.d.ts +27 -0
  41. package/lib/components/Switch/Switch.d.ts.map +1 -0
  42. package/lib/components/Switch/Switch.jsx +75 -0
  43. package/lib/components/Switch/Switch.namespace.d.ts +2 -0
  44. package/lib/components/Switch/Switch.namespace.d.ts.map +1 -0
  45. package/lib/components/Switch/Switch.namespace.js +1 -0
  46. package/lib/components/Switch/index.d.ts +3 -0
  47. package/lib/components/Switch/index.d.ts.map +1 -0
  48. package/lib/components/Switch/index.js +2 -0
  49. package/lib/components/TagGroup/TagGroup.d.ts +40 -0
  50. package/lib/components/TagGroup/TagGroup.d.ts.map +1 -0
  51. package/lib/components/TagGroup/TagGroup.jsx +54 -0
  52. package/lib/components/TagGroup/TagGroup.namespace.d.ts +2 -0
  53. package/lib/components/TagGroup/TagGroup.namespace.d.ts.map +1 -0
  54. package/lib/components/TagGroup/TagGroup.namespace.js +1 -0
  55. package/lib/components/TagGroup/index.d.ts +3 -0
  56. package/lib/components/TagGroup/index.d.ts.map +1 -0
  57. package/lib/components/TagGroup/index.js +2 -0
  58. package/lib/components/index.d.ts +8 -0
  59. package/lib/components/index.d.ts.map +1 -0
  60. package/lib/components/index.js +7 -0
  61. package/lib/hooks/index.d.ts +4 -0
  62. package/lib/hooks/index.d.ts.map +1 -0
  63. package/lib/hooks/index.js +3 -0
  64. package/lib/hooks/use-controllable-state.d.ts +15 -0
  65. package/lib/hooks/use-controllable-state.d.ts.map +1 -0
  66. package/lib/hooks/use-controllable-state.js +27 -0
  67. package/lib/hooks/use-icon-color.d.ts +15 -0
  68. package/lib/hooks/use-icon-color.d.ts.map +1 -0
  69. package/lib/hooks/use-icon-color.js +37 -0
  70. package/lib/hooks/use-press-tap.d.ts +24 -0
  71. package/lib/hooks/use-press-tap.d.ts.map +1 -0
  72. package/lib/hooks/use-press-tap.js +35 -0
  73. package/lib/index.d.ts +3 -4
  74. package/lib/index.d.ts.map +1 -1
  75. package/lib/index.js +3 -4
  76. package/lib/utils/create-slot-recipe-context.d.ts +26 -0
  77. package/lib/utils/create-slot-recipe-context.d.ts.map +1 -0
  78. package/lib/utils/create-slot-recipe-context.jsx +76 -0
  79. package/lib/utils/get-seed-class-name.d.ts.map +1 -0
  80. package/lib/utils/index.d.ts +5 -0
  81. package/lib/utils/index.d.ts.map +1 -0
  82. package/lib/utils/index.js +4 -0
  83. package/lib/utils/resolve-recipe-token.d.ts +38 -0
  84. package/lib/utils/resolve-recipe-token.d.ts.map +1 -0
  85. package/lib/utils/resolve-recipe-token.js +47 -0
  86. package/lib/utils/split-multiple-variants-props.d.ts +29 -0
  87. package/lib/utils/split-multiple-variants-props.d.ts.map +1 -0
  88. package/lib/utils/split-multiple-variants-props.js +34 -0
  89. package/package.json +12 -9
  90. package/src/components/ActionButton/ActionButton.tsx +290 -31
  91. package/src/components/ActionButton/__tests__/ActionButton.test.tsx +35 -0
  92. package/src/components/BottomSheet/BottomSheet.namespace.ts +24 -0
  93. package/src/components/BottomSheet/BottomSheet.tsx +386 -0
  94. package/src/components/BottomSheet/__tests__/BottomSheet.test.tsx +119 -0
  95. package/src/components/BottomSheet/index.ts +27 -0
  96. package/src/components/Checkbox/Checkbox.namespace.ts +12 -0
  97. package/src/components/Checkbox/Checkbox.tsx +291 -0
  98. package/src/components/Checkbox/index.ts +14 -0
  99. package/src/components/ProgressCircle/ProgressCircle.namespace.ts +5 -0
  100. package/src/components/ProgressCircle/ProgressCircle.tsx +14 -13
  101. package/src/components/ProgressCircle/index.ts +9 -1
  102. package/src/components/RadioGroup/RadioGroup.namespace.ts +12 -0
  103. package/src/components/RadioGroup/RadioGroup.tsx +338 -0
  104. package/src/components/RadioGroup/index.ts +14 -0
  105. package/src/components/Switch/Switch.namespace.ts +10 -0
  106. package/src/components/Switch/Switch.tsx +191 -0
  107. package/src/components/Switch/index.ts +12 -0
  108. package/src/components/TagGroup/TagGroup.namespace.ts +8 -0
  109. package/src/components/TagGroup/TagGroup.tsx +125 -0
  110. package/src/components/TagGroup/index.ts +10 -0
  111. package/src/components/__tests__/ProgressCircle.test.ts +33 -0
  112. package/src/components/__tests__/exports.test.ts +38 -0
  113. package/src/components/__tests__/switch.test.ts +34 -0
  114. package/src/components/index.ts +7 -0
  115. package/src/hooks/__tests__/use-controllable-state.test.ts +120 -0
  116. package/src/hooks/__tests__/use-press-tap.test.ts +129 -0
  117. package/src/hooks/index.ts +3 -0
  118. package/src/hooks/use-controllable-state.ts +38 -0
  119. package/src/hooks/use-icon-color.ts +51 -0
  120. package/src/hooks/use-press-tap.ts +54 -0
  121. package/src/index.ts +3 -4
  122. package/src/utils/__tests__/create-slot-recipe-context.test.tsx +228 -0
  123. package/src/utils/__tests__/split-multiple-variants-props.test.ts +61 -0
  124. package/src/utils/create-slot-recipe-context.tsx +147 -0
  125. package/src/utils/index.ts +4 -0
  126. package/src/utils/resolve-recipe-token.ts +47 -0
  127. package/src/utils/split-multiple-variants-props.ts +59 -0
  128. package/lib/components/Box/Box.d.ts +0 -10
  129. package/lib/components/Box/Box.d.ts.map +0 -1
  130. package/lib/components/Box/Box.jsx +0 -19
  131. package/lib/components/Box/index.d.ts +0 -2
  132. package/lib/components/Box/index.d.ts.map +0 -1
  133. package/lib/components/Box/index.js +0 -1
  134. package/lib/components/Flex/Flex.d.ts +0 -33
  135. package/lib/components/Flex/Flex.d.ts.map +0 -1
  136. package/lib/components/Flex/Flex.jsx +0 -7
  137. package/lib/components/Flex/index.d.ts +0 -2
  138. package/lib/components/Flex/index.d.ts.map +0 -1
  139. package/lib/components/Flex/index.js +0 -1
  140. package/lib/components/List/List.d.ts +0 -9
  141. package/lib/components/List/List.d.ts.map +0 -1
  142. package/lib/components/List/List.jsx +0 -17
  143. package/lib/components/List/index.d.ts +0 -2
  144. package/lib/components/List/index.d.ts.map +0 -1
  145. package/lib/components/List/index.js +0 -1
  146. package/lib/components/ListItem/ListItem.d.ts +0 -8
  147. package/lib/components/ListItem/ListItem.d.ts.map +0 -1
  148. package/lib/components/ListItem/ListItem.jsx +0 -11
  149. package/lib/components/ListItem/index.d.ts +0 -2
  150. package/lib/components/ListItem/index.d.ts.map +0 -1
  151. package/lib/components/ListItem/index.js +0 -1
  152. package/lib/components/ScrollView/ScrollView.d.ts +0 -9
  153. package/lib/components/ScrollView/ScrollView.d.ts.map +0 -1
  154. package/lib/components/ScrollView/ScrollView.jsx +0 -17
  155. package/lib/components/ScrollView/index.d.ts +0 -2
  156. package/lib/components/ScrollView/index.d.ts.map +0 -1
  157. package/lib/components/ScrollView/index.js +0 -1
  158. package/lib/components/Stack/Stack.d.ts +0 -6
  159. package/lib/components/Stack/Stack.d.ts.map +0 -1
  160. package/lib/components/Stack/Stack.jsx +0 -10
  161. package/lib/components/Stack/index.d.ts +0 -2
  162. package/lib/components/Stack/index.d.ts.map +0 -1
  163. package/lib/components/Stack/index.js +0 -1
  164. package/lib/components/Text/Text.d.ts +0 -30
  165. package/lib/components/Text/Text.d.ts.map +0 -1
  166. package/lib/components/Text/Text.jsx +0 -49
  167. package/lib/components/Text/index.d.ts +0 -2
  168. package/lib/components/Text/index.d.ts.map +0 -1
  169. package/lib/components/Text/index.js +0 -1
  170. package/lib/get-seed-class-name.d.ts.map +0 -1
  171. package/lib/utils/dynamic-style.d.ts +0 -13
  172. package/lib/utils/dynamic-style.d.ts.map +0 -1
  173. package/lib/utils/dynamic-style.js +0 -26
  174. package/lib/utils/styled.d.ts +0 -120
  175. package/lib/utils/styled.d.ts.map +0 -1
  176. package/lib/utils/styled.jsx +0 -131
  177. package/src/utils/dynamic-style.ts +0 -26
  178. /package/lib/{get-seed-class-name.d.ts → utils/get-seed-class-name.d.ts} +0 -0
  179. /package/lib/{get-seed-class-name.js → utils/get-seed-class-name.js} +0 -0
  180. /package/src/{get-seed-class-name.ts → utils/get-seed-class-name.ts} +0 -0
@@ -0,0 +1,2 @@
1
+ export { SwitchRoot, SwitchControl, SwitchThumb, SwitchLabel, } from "./Switch";
2
+ export * as Switch from "./Switch.namespace";
@@ -0,0 +1,40 @@
1
+ import * as React from "react";
2
+ import { type TagGroupVariantProps } from "@seed-design/lynx-css/recipes/tag-group";
3
+ import { type TagGroupItemVariantProps } from "@seed-design/lynx-css/recipes/tag-group-item";
4
+ /**
5
+ * @platform Lynx
6
+ *
7
+ * 웹 대비 미지원 기능:
8
+ * - `truncate` prop: Lynx flex 모델에서는 item 단위 wrap만 가능해 웹 수준의
9
+ * "한 줄 유지 + label ellipsis" 조합을 재현할 수 없음
10
+ * - `asChild` prop: Lynx Slot 미지원
11
+ * - `flexShrink` prop: CSS variable 동적 주입 제한
12
+ * - 아이콘 slot: Lynx 3.7 SVG 지원 후 검토 (Tier B)
13
+ */
14
+ export interface TagGroupRootProps extends TagGroupVariantProps, TagGroupItemVariantProps {
15
+ children?: React.ReactNode;
16
+ className?: string;
17
+ /**
18
+ * children 사이에 삽입되는 구분자. 기본값 `" · "`.
19
+ */
20
+ separator?: React.ReactNode;
21
+ }
22
+ export declare const TagGroupRoot: React.ForwardRefExoticComponent<TagGroupRootProps & React.RefAttributes<unknown>>;
23
+ /**
24
+ * @platform Lynx
25
+ *
26
+ * 웹 대비 미지원 기능:
27
+ * - `asChild` prop: Lynx Slot 미지원
28
+ * - `flexShrink` prop: CSS variable 동적 주입 제한
29
+ */
30
+ export interface TagGroupItemProps extends TagGroupItemVariantProps {
31
+ children?: React.ReactNode;
32
+ className?: string;
33
+ }
34
+ export declare const TagGroupItem: React.ForwardRefExoticComponent<TagGroupItemProps & React.RefAttributes<unknown>>;
35
+ export interface TagGroupItemLabelProps {
36
+ children?: React.ReactNode;
37
+ className?: string;
38
+ }
39
+ export declare const TagGroupItemLabel: React.ForwardRefExoticComponent<TagGroupItemLabelProps & React.RefAttributes<unknown>>;
40
+ //# sourceMappingURL=TagGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagGroup.d.ts","sourceRoot":"","sources":["../../../src/components/TagGroup/TagGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC9F,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,8CAA8C,CAAC;AAQtD;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAkB,SAAQ,oBAAoB,EAAE,wBAAwB;IACvF,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,eAAO,MAAM,YAAY,mFAsCvB,CAAC;AAGH;;;;;;GAMG;AACH,MAAM,WAAW,iBAAkB,SAAQ,wBAAwB;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,mFAiBvB,CAAC;AAGH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,iBAAiB,wFAY5B,CAAC"}
@@ -0,0 +1,54 @@
1
+ import * as React from "react";
2
+ import clsx from "clsx";
3
+ import { tagGroup } from "@seed-design/lynx-css/recipes/tag-group";
4
+ import { tagGroupItem, } from "@seed-design/lynx-css/recipes/tag-group-item";
5
+ import { createSlotRecipeContext } from "../../utils/create-slot-recipe-context";
6
+ import { splitMultipleVariantsProps } from "../../utils/split-multiple-variants-props";
7
+ const { PropsProvider, useProps, ClassNamesProvider, useClassNames } = createSlotRecipeContext(tagGroupItem);
8
+ export const TagGroupRoot = React.forwardRef((props, ref) => {
9
+ const [{ tagGroup: tagGroupVariantProps, tagGroupItem: tagGroupItemVariantProps }, otherProps] = splitMultipleVariantsProps(props, { tagGroup, tagGroupItem });
10
+ const { children, className, separator = " · ", ...nativeProps } = otherProps;
11
+ const classes = tagGroup(tagGroupVariantProps);
12
+ const visibleChildren = React.Children.toArray(children);
13
+ return (<PropsProvider value={tagGroupItemVariantProps}>
14
+ <view {...(ref ? { ref: ref } : {})} className={clsx(classes.root, className)} {...nativeProps}>
15
+ {visibleChildren.map((child, index) => {
16
+ if (index === 0)
17
+ return child;
18
+ // Lynx <text> separator는 개별 flex item이라 wrap이 발동하면 separator가
19
+ // 이전 row 끝에 남는다. separator와 뒤따르는 item을 하나의 flex-row wrapper로
20
+ // 묶어 같은 wrap 단위로 함께 이동시킨다.
21
+ return (<view key={child.key ?? index} style={{
22
+ display: "flex",
23
+ flexDirection: "row",
24
+ alignItems: "center",
25
+ flexShrink: 0,
26
+ }}>
27
+ <text className={classes.separator}>{separator}</text>
28
+ {child}
29
+ </view>);
30
+ })}
31
+ </view>
32
+ </PropsProvider>);
33
+ });
34
+ TagGroupRoot.displayName = "TagGroupRoot";
35
+ export const TagGroupItem = React.forwardRef((props, ref) => {
36
+ const parentVariantProps = useProps();
37
+ const [localVariantProps, otherProps] = tagGroupItem.splitVariantProps(props);
38
+ const classes = tagGroupItem({ ...parentVariantProps, ...localVariantProps });
39
+ const { children, className, ...nativeProps } = otherProps;
40
+ return (<ClassNamesProvider value={classes}>
41
+ <view {...(ref ? { ref: ref } : {})} className={clsx(classes.root, className)} {...nativeProps}>
42
+ {children}
43
+ </view>
44
+ </ClassNamesProvider>);
45
+ });
46
+ TagGroupItem.displayName = "TagGroupItem";
47
+ export const TagGroupItemLabel = React.forwardRef((props, ref) => {
48
+ const classes = useClassNames();
49
+ const { children, className, ...nativeProps } = props;
50
+ return (<text {...(ref ? { ref: ref } : {})} className={clsx(classes.label, className)} {...nativeProps}>
51
+ {children}
52
+ </text>);
53
+ });
54
+ TagGroupItemLabel.displayName = "TagGroupItemLabel";
@@ -0,0 +1,2 @@
1
+ export { TagGroupItem as Item, TagGroupItemLabel as ItemLabel, TagGroupRoot as Root, type TagGroupItemLabelProps as ItemLabelProps, type TagGroupItemProps as ItemProps, type TagGroupRootProps as RootProps, } from "./TagGroup";
2
+ //# sourceMappingURL=TagGroup.namespace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagGroup.namespace.d.ts","sourceRoot":"","sources":["../../../src/components/TagGroup/TagGroup.namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,IAAI,IAAI,EACpB,iBAAiB,IAAI,SAAS,EAC9B,YAAY,IAAI,IAAI,EACpB,KAAK,sBAAsB,IAAI,cAAc,EAC7C,KAAK,iBAAiB,IAAI,SAAS,EACnC,KAAK,iBAAiB,IAAI,SAAS,GACpC,MAAM,YAAY,CAAC"}
@@ -0,0 +1 @@
1
+ export { TagGroupItem as Item, TagGroupItemLabel as ItemLabel, TagGroupRoot as Root, } from "./TagGroup";
@@ -0,0 +1,3 @@
1
+ export { TagGroupRoot, TagGroupItem, TagGroupItemLabel, type TagGroupRootProps, type TagGroupItemProps, type TagGroupItemLabelProps, } from "./TagGroup";
2
+ export * as TagGroup from "./TagGroup.namespace";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TagGroup/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,GAC5B,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { TagGroupRoot, TagGroupItem, TagGroupItemLabel, } from "./TagGroup";
2
+ export * as TagGroup from "./TagGroup.namespace";
@@ -0,0 +1,8 @@
1
+ export * from "./ActionButton";
2
+ export * from "./BottomSheet";
3
+ export * from "./Checkbox";
4
+ export * from "./ProgressCircle";
5
+ export * from "./RadioGroup";
6
+ export * from "./Switch";
7
+ export * from "./TagGroup";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from "./ActionButton";
2
+ export * from "./BottomSheet";
3
+ export * from "./Checkbox";
4
+ export * from "./ProgressCircle";
5
+ export * from "./RadioGroup";
6
+ export * from "./Switch";
7
+ export * from "./TagGroup";
@@ -0,0 +1,4 @@
1
+ export * from "./use-controllable-state";
2
+ export * from "./use-icon-color";
3
+ export * from "./use-press-tap";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./use-controllable-state";
2
+ export * from "./use-icon-color";
3
+ export * from "./use-press-tap";
@@ -0,0 +1,15 @@
1
+ export interface UseControllableStateProps<T> {
2
+ value?: T;
3
+ defaultValue: T;
4
+ onChange?: (value: T) => void;
5
+ }
6
+ /**
7
+ * Controlled/uncontrolled state pattern for Lynx components.
8
+ *
9
+ * - When `value` is provided, the component is controlled.
10
+ * - When `value` is `undefined`, the component manages its own state
11
+ * starting from `defaultValue`.
12
+ * - `onChange` fires in both modes.
13
+ */
14
+ export declare function useControllableState<T>(props: UseControllableStateProps<T>): [T, (value: T) => void];
15
+ //# sourceMappingURL=use-controllable-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-controllable-state.d.ts","sourceRoot":"","sources":["../../src/hooks/use-controllable-state.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,YAAY,EAAE,CAAC,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,KAAK,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAClC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,CAkBzB"}
@@ -0,0 +1,27 @@
1
+ import { useRef, useState } from "@lynx-js/react";
2
+ import { useMemoizedFn } from "@lynx-js/lynx-ui-common";
3
+ /**
4
+ * Controlled/uncontrolled state pattern for Lynx components.
5
+ *
6
+ * - When `value` is provided, the component is controlled.
7
+ * - When `value` is `undefined`, the component manages its own state
8
+ * starting from `defaultValue`.
9
+ * - `onChange` fires in both modes.
10
+ */
11
+ export function useControllableState(props) {
12
+ const { value, defaultValue, onChange } = props;
13
+ const isControlled = value !== undefined;
14
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
15
+ const currentValue = isControlled ? value : uncontrolledValue;
16
+ const prevValueRef = useRef(currentValue);
17
+ const setValue = useMemoizedFn((nextValue) => {
18
+ if (!isControlled) {
19
+ setUncontrolledValue(nextValue);
20
+ }
21
+ if (nextValue !== prevValueRef.current) {
22
+ onChange?.(nextValue);
23
+ prevValueRef.current = nextValue;
24
+ }
25
+ });
26
+ return [currentValue, setValue];
27
+ }
@@ -0,0 +1,15 @@
1
+ import type { MainThread } from "@lynx-js/types";
2
+ import type { DependencyList, RefObject } from "react";
3
+ /**
4
+ * Lynx `<image>` 의 tint color 를 recipe 의 CSS `color` 로부터 main-thread 에서 읽어
5
+ * `tint-color` attribute 로 mirror. `deps` 가 바뀌면 재동기화.
6
+ *
7
+ * ```tsx
8
+ * const { ref } = useIconColor([variant, disabled, loading]);
9
+ * return cloneElement(iconChild, { ref });
10
+ * ```
11
+ */
12
+ export declare function useIconColor(deps: DependencyList): {
13
+ ref: RefObject<MainThread.Element>;
14
+ };
15
+ //# sourceMappingURL=use-icon-color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-icon-color.d.ts","sourceRoot":"","sources":["../../src/hooks/use-icon-color.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA4BvD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG;IAClD,GAAG,EAAE,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;CACpC,CASA"}
@@ -0,0 +1,37 @@
1
+ import { runOnMainThread, useEffect, useMainThreadRef } from "@lynx-js/react";
2
+ // Lynx `<image>` 의 `tint-color` attribute 는 concrete color(hex/rgb) 만 받는다. CSS
3
+ // `color: var(--seed-color-...)` 를 slot 에 걸면 `getComputedStyleProperty("color")` 가
4
+ // resolved hex 를 돌려주므로 main-thread 에서 한번 읽어 `tint-color` 로 mirror 한다.
5
+ function syncTintColor(ref) {
6
+ "main thread";
7
+ const el = ref.current;
8
+ if (!el)
9
+ return;
10
+ let color;
11
+ if (typeof el.getComputedStyleProperty === "function") {
12
+ color = el.getComputedStyleProperty("color");
13
+ }
14
+ else if (typeof el.getComputedCssProperty === "function") {
15
+ color = el.getComputedCssProperty("color");
16
+ }
17
+ if (color) {
18
+ el.setAttribute("tint-color", color);
19
+ }
20
+ }
21
+ /**
22
+ * Lynx `<image>` 의 tint color 를 recipe 의 CSS `color` 로부터 main-thread 에서 읽어
23
+ * `tint-color` attribute 로 mirror. `deps` 가 바뀌면 재동기화.
24
+ *
25
+ * ```tsx
26
+ * const { ref } = useIconColor([variant, disabled, loading]);
27
+ * return cloneElement(iconChild, { ref });
28
+ * ```
29
+ */
30
+ export function useIconColor(deps) {
31
+ const ref = useMainThreadRef(null);
32
+ // deps 는 caller 가 책임.
33
+ useEffect(() => {
34
+ runOnMainThread(syncTintColor)(ref);
35
+ }, deps);
36
+ return { ref };
37
+ }
@@ -0,0 +1,24 @@
1
+ import type { TouchEvent } from "@lynx-js/types";
2
+ export interface UsePressTapOptions {
3
+ disabled?: boolean;
4
+ onTap?: () => void;
5
+ mainThreadOnTap?: () => void;
6
+ }
7
+ export interface UsePressTapReturn {
8
+ pressed: boolean;
9
+ bindtap: (e: TouchEvent) => void;
10
+ bindtouchstart: (e: TouchEvent) => void;
11
+ bindtouchend: (e: TouchEvent) => void;
12
+ bindtouchcancel: (e: TouchEvent) => void;
13
+ "main-thread:bindtap"?: () => void;
14
+ }
15
+ /**
16
+ * Hook that provides press/tap interaction state for Lynx elements.
17
+ *
18
+ * - Tracks `pressed` state via touch events.
19
+ * - When `disabled` is true, the element cannot become active and no tap fires.
20
+ * - If the element becomes disabled during a press, the active state is cleared.
21
+ * - `main-thread:bindtap` is conditionally included (only when enabled and provided).
22
+ */
23
+ export declare function usePressTap(options?: UsePressTapOptions): UsePressTapReturn;
24
+ //# sourceMappingURL=use-press-tap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-press-tap.d.ts","sourceRoot":"","sources":["../../src/hooks/use-press-tap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACjC,cAAc,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,iBAAiB,CA0B/E"}
@@ -0,0 +1,35 @@
1
+ import { useState } from "@lynx-js/react";
2
+ import { useMemoizedFn } from "@lynx-js/lynx-ui-common";
3
+ /**
4
+ * Hook that provides press/tap interaction state for Lynx elements.
5
+ *
6
+ * - Tracks `pressed` state via touch events.
7
+ * - When `disabled` is true, the element cannot become active and no tap fires.
8
+ * - If the element becomes disabled during a press, the active state is cleared.
9
+ * - `main-thread:bindtap` is conditionally included (only when enabled and provided).
10
+ */
11
+ export function usePressTap(options = {}) {
12
+ const { disabled = false, onTap, mainThreadOnTap } = options;
13
+ const [pressed, setPressed] = useState(false);
14
+ const press = useMemoizedFn(() => {
15
+ if (disabled)
16
+ return;
17
+ setPressed(true);
18
+ });
19
+ const reset = useMemoizedFn(() => {
20
+ setPressed(false);
21
+ });
22
+ const handleTap = useMemoizedFn(() => {
23
+ if (disabled)
24
+ return;
25
+ onTap?.();
26
+ });
27
+ return {
28
+ pressed,
29
+ bindtap: handleTap,
30
+ bindtouchstart: press,
31
+ bindtouchend: reset,
32
+ bindtouchcancel: reset,
33
+ ...(!disabled && mainThreadOnTap ? { "main-thread:bindtap": mainThreadOnTap } : {}),
34
+ };
35
+ }
package/lib/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- export { ActionButton, type ActionButtonProps } from "./components/ActionButton";
2
- export { ProgressCircle, type ProgressCircleProps } from "./components/ProgressCircle";
3
- export { dynamicStyle } from "./utils/dynamic-style";
4
- export { getSeedClassName } from "./get-seed-class-name";
1
+ export * from "./components";
2
+ export * from "./hooks";
3
+ export * from "./utils";
5
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
package/lib/index.js CHANGED
@@ -1,4 +1,3 @@
1
- export { ActionButton } from "./components/ActionButton";
2
- export { ProgressCircle } from "./components/ProgressCircle";
3
- export { dynamicStyle } from "./utils/dynamic-style";
4
- export { getSeedClassName } from "./get-seed-class-name";
1
+ export * from "./components";
2
+ export * from "./hooks";
3
+ export * from "./utils";
@@ -0,0 +1,26 @@
1
+ type SlotRecipe<Props extends Record<string, string | boolean | undefined>, Classnames extends Record<string, string>> = ((props?: Props) => Classnames) & {
2
+ splitVariantProps: <T extends Props>(props: T) => [Props, Omit<T, keyof Props>];
3
+ };
4
+ export declare function createSlotRecipeContext<Props extends Record<string, string | boolean | undefined>, Classnames extends Record<string, string>>(recipe: SlotRecipe<Props, Classnames>): {
5
+ ClassNamesProvider: ({ children, value, }: {
6
+ children: React.ReactNode;
7
+ value: Classnames;
8
+ }) => import("react").JSX.Element;
9
+ PropsProvider: ({ children, value }: {
10
+ children: React.ReactNode;
11
+ value: Props;
12
+ }) => import("react").JSX.Element;
13
+ useClassNames: () => Classnames;
14
+ useProps: () => Props | null;
15
+ withRootProvider: <P>(Component: React.ElementType<any>, options?: {
16
+ defaultProps?: Partial<P>;
17
+ }) => React.ForwardRefExoticComponent<React.PropsWithoutRef<P>>;
18
+ withProvider: <T, P>(Component: React.ElementType<any>, slot: keyof Classnames, options?: {
19
+ defaultProps?: Partial<P>;
20
+ }) => React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<T>>;
21
+ withContext: <T, P>(Component: React.ElementType<any>, slot?: keyof Classnames, options?: {
22
+ defaultProps?: Partial<P>;
23
+ }) => React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<T>>;
24
+ };
25
+ export {};
26
+ //# sourceMappingURL=create-slot-recipe-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-slot-recipe-context.d.ts","sourceRoot":"","sources":["../../src/utils/create-slot-recipe-context.tsx"],"names":[],"mappings":"AAGA,KAAK,UAAU,CACb,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,EAC1D,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IACvC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,UAAU,CAAC,GAAG;IACpC,iBAAiB,EAAE,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC;CACjF,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,EAC1D,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC;+CAOlC;QACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;QAC1B,KAAK,EAAE,UAAU,CAAC;KACnB;yCAI2C;QAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE;;;uBAmB7D,CAAC,aACd,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,YACvB;QACR,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;KAC3B,KACA,KAAK,CAAC,yBAAyB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;mBAwBtC,CAAC,EAAE,CAAC,aACb,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,QAC3B,MAAM,UAAU,YACZ;QACR,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;KAC3B,KACA,KAAK,CAAC,yBAAyB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;kBA4BhE,CAAC,EAAE,CAAC,aACZ,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,SAC1B,MAAM,UAAU,YACb;QACR,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;KAC3B,KACA,KAAK,CAAC,yBAAyB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EA+BtF"}
@@ -0,0 +1,76 @@
1
+ import { createContext, forwardRef, useContext } from "@lynx-js/react";
2
+ import clsx from "clsx";
3
+ export function createSlotRecipeContext(recipe) {
4
+ const ClassNamesContext = createContext(null);
5
+ const PropsContext = createContext(null);
6
+ const ClassNamesProvider = ({ children, value, }) => {
7
+ return <ClassNamesContext.Provider value={value}>{children}</ClassNamesContext.Provider>;
8
+ };
9
+ const PropsProvider = ({ children, value }) => {
10
+ return <PropsContext.Provider value={value}>{children}</PropsContext.Provider>;
11
+ };
12
+ function useClassNames() {
13
+ const context = useContext(ClassNamesContext);
14
+ if (context === null) {
15
+ throw new Error("useClassNames must be used within a ClassNamesProvider. Did you forget to wrap your component in a ClassNamesProvider?");
16
+ }
17
+ return context;
18
+ }
19
+ function useProps() {
20
+ return useContext(PropsContext);
21
+ }
22
+ const withRootProvider = (Component, options) => {
23
+ const { defaultProps } = options ?? {};
24
+ const StyledComponent = (innerProps) => {
25
+ const props = { ...(defaultProps ?? {}), ...useProps(), ...innerProps };
26
+ const [variantProps, otherProps] = recipe.splitVariantProps(props);
27
+ const classNames = recipe(variantProps);
28
+ return (<ClassNamesProvider value={classNames}>
29
+ <PropsProvider value={variantProps}>
30
+ <Component {...otherProps}/>
31
+ </PropsProvider>
32
+ </ClassNamesProvider>);
33
+ };
34
+ // @ts-expect-error — assigning displayName to a plain function component
35
+ StyledComponent.displayName = Component.displayName || Component.name;
36
+ return StyledComponent;
37
+ };
38
+ const withProvider = (Component, slot, options) => {
39
+ const { defaultProps } = options ?? {};
40
+ const StyledComponent = forwardRef((innerProps, ref) => {
41
+ const props = { ...(defaultProps ?? {}), ...useProps(), ...innerProps };
42
+ const [variantProps, otherProps] = recipe.splitVariantProps(props);
43
+ const classNames = recipe(variantProps);
44
+ const slotClassName = classNames[slot];
45
+ const userClassName = props["className"];
46
+ return (<ClassNamesProvider value={classNames}>
47
+ <PropsProvider value={variantProps}>
48
+ <Component {...(ref ? { ref } : {})} {...otherProps} className={clsx(slotClassName, userClassName)}/>
49
+ </PropsProvider>
50
+ </ClassNamesProvider>);
51
+ });
52
+ StyledComponent.displayName = Component.displayName || Component.name;
53
+ return StyledComponent;
54
+ };
55
+ const withContext = (Component, slot, options) => {
56
+ const { defaultProps } = options ?? {};
57
+ const StyledComponent = forwardRef((innerProps, ref) => {
58
+ const props = { ...(defaultProps ?? {}), ...innerProps };
59
+ const classNames = useClassNames();
60
+ const slotClassName = slot ? classNames[slot] : undefined;
61
+ const userClassName = props["className"];
62
+ return (<Component {...(ref ? { ref } : {})} {...props} className={clsx(slotClassName, userClassName)}/>);
63
+ });
64
+ StyledComponent.displayName = Component.displayName || Component.name;
65
+ return StyledComponent;
66
+ };
67
+ return {
68
+ ClassNamesProvider,
69
+ PropsProvider,
70
+ useClassNames,
71
+ useProps,
72
+ withRootProvider,
73
+ withProvider,
74
+ withContext,
75
+ };
76
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-seed-class-name.d.ts","sourceRoot":"","sources":["../../src/utils/get-seed-class-name.ts"],"names":[],"mappings":"AAUA,KAAK,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,CAAC;AAEvD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,MAAM,CAsB5E"}
@@ -0,0 +1,5 @@
1
+ export * from "./create-slot-recipe-context";
2
+ export * from "./get-seed-class-name";
3
+ export * from "./resolve-recipe-token";
4
+ export * from "./split-multiple-variants-props";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./create-slot-recipe-context";
2
+ export * from "./get-seed-class-name";
3
+ export * from "./resolve-recipe-token";
4
+ export * from "./split-multiple-variants-props";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Rootage vars 객체에서 `path` 를 따라 token 값(주로 `"var(--seed-...)"` 스트링)을 꺼낸다.
3
+ *
4
+ * 쓰임새: Lynx `<image>` 의 `tint-color` / `width` / `height` 처럼 CSS 만으로는
5
+ * override 할 수 없거나(아이콘 패키지가 inline style 을 박는 경우 등) React 가
6
+ * recipe 와 같은 소스에서 꺼내 inline attribute 로 주입해야 하는 속성을 다룰 때.
7
+ *
8
+ * ```ts
9
+ * import { actionButton as actionButtonVars } from "@seed-design/lynx-css/vars/component";
10
+ * import { capitalize, resolveRecipeToken } from "@seed-design/lynx-react/utils/resolve-recipe-token";
11
+ *
12
+ * // variant × state × slot → color
13
+ * const color = resolveRecipeToken(actionButtonVars, [
14
+ * `variant${capitalize(variant)}`,
15
+ * state, // "enabled" | "disabled" | "loading" | "pressed"
16
+ * "prefixIcon",
17
+ * "color",
18
+ * ]);
19
+ *
20
+ * // size × layout → icon size
21
+ * const size = resolveRecipeToken(actionButtonVars, [
22
+ * `size${capitalize(size)}Layout${capitalize(layout)}`,
23
+ * "enabled",
24
+ * "prefixIcon",
25
+ * "size",
26
+ * ]);
27
+ * ```
28
+ *
29
+ * recipe token 경로가 컴포넌트마다 조금씩 다르므로(variant/size/layout 조합 여부 등)
30
+ * 이 유틸은 "vars + path" 조합만 제공하고, 각 컴포넌트가 자기 path 를 만들어 호출한다.
31
+ */
32
+ export declare function resolveRecipeToken(vars: unknown, path: readonly string[]): string | undefined;
33
+ /**
34
+ * 첫 글자 대문자. recipe variant key 조립용
35
+ * (e.g. `variant` + `brandSolid` → `variantBrandSolid`).
36
+ */
37
+ export declare function capitalize<T extends string>(value: T): Capitalize<T>;
38
+ //# sourceMappingURL=resolve-recipe-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-recipe-token.d.ts","sourceRoot":"","sources":["../../src/utils/resolve-recipe-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAO7F;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAEpE"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Rootage vars 객체에서 `path` 를 따라 token 값(주로 `"var(--seed-...)"` 스트링)을 꺼낸다.
3
+ *
4
+ * 쓰임새: Lynx `<image>` 의 `tint-color` / `width` / `height` 처럼 CSS 만으로는
5
+ * override 할 수 없거나(아이콘 패키지가 inline style 을 박는 경우 등) React 가
6
+ * recipe 와 같은 소스에서 꺼내 inline attribute 로 주입해야 하는 속성을 다룰 때.
7
+ *
8
+ * ```ts
9
+ * import { actionButton as actionButtonVars } from "@seed-design/lynx-css/vars/component";
10
+ * import { capitalize, resolveRecipeToken } from "@seed-design/lynx-react/utils/resolve-recipe-token";
11
+ *
12
+ * // variant × state × slot → color
13
+ * const color = resolveRecipeToken(actionButtonVars, [
14
+ * `variant${capitalize(variant)}`,
15
+ * state, // "enabled" | "disabled" | "loading" | "pressed"
16
+ * "prefixIcon",
17
+ * "color",
18
+ * ]);
19
+ *
20
+ * // size × layout → icon size
21
+ * const size = resolveRecipeToken(actionButtonVars, [
22
+ * `size${capitalize(size)}Layout${capitalize(layout)}`,
23
+ * "enabled",
24
+ * "prefixIcon",
25
+ * "size",
26
+ * ]);
27
+ * ```
28
+ *
29
+ * recipe token 경로가 컴포넌트마다 조금씩 다르므로(variant/size/layout 조합 여부 등)
30
+ * 이 유틸은 "vars + path" 조합만 제공하고, 각 컴포넌트가 자기 path 를 만들어 호출한다.
31
+ */
32
+ export function resolveRecipeToken(vars, path) {
33
+ let cursor = vars;
34
+ for (const key of path) {
35
+ if (cursor == null || typeof cursor !== "object")
36
+ return undefined;
37
+ cursor = cursor[key];
38
+ }
39
+ return typeof cursor === "string" ? cursor : undefined;
40
+ }
41
+ /**
42
+ * 첫 글자 대문자. recipe variant key 조립용
43
+ * (e.g. `variant` + `brandSolid` → `variantBrandSolid`).
44
+ */
45
+ export function capitalize(value) {
46
+ return (value.charAt(0).toUpperCase() + value.slice(1));
47
+ }
@@ -0,0 +1,29 @@
1
+ type RecipeLike = {
2
+ splitVariantProps: (props: Record<string, unknown>) => [Record<string, unknown>, unknown];
3
+ };
4
+ type ExtractVariantProps<T> = T extends {
5
+ splitVariantProps: (...args: never[]) => [infer V, unknown];
6
+ } ? V : never;
7
+ type ExtractAllVariantKeys<R> = {
8
+ [K in keyof R]: ExtractVariantProps<R[K]> extends infer V ? V extends Record<string, unknown> ? keyof V : never : never;
9
+ }[keyof R];
10
+ /**
11
+ * Split `props` across multiple recipes' variant extractors in one pass.
12
+ *
13
+ * Given `recipesMap` of `{ [recipeKey]: recipe }`, returns:
14
+ * - A bucket per recipe key with that recipe's variant-only props.
15
+ * - `remainingProps` with every recipe variant key stripped out.
16
+ *
17
+ * Keys that appear in more than one recipe (e.g. shared `size`) are copied
18
+ * into each corresponding bucket. `remainingProps` never includes any key
19
+ * that any recipe claimed as a variant.
20
+ *
21
+ * Mirror of `packages/react/src/utils/splitMultipleVariantsProps` adapted
22
+ * to TypeScript for Lynx. Use when a single compound component composes two
23
+ * or more recipes (e.g. Switch's `switch` + `switchmark`).
24
+ */
25
+ export declare function splitMultipleVariantsProps<R extends Record<string, RecipeLike>, P>(props: P, recipesMap: R): [{
26
+ [K in keyof R]: ExtractVariantProps<R[K]>;
27
+ }, Omit<P, ExtractAllVariantKeys<R>>];
28
+ export {};
29
+ //# sourceMappingURL=split-multiple-variants-props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split-multiple-variants-props.d.ts","sourceRoot":"","sources":["../../src/utils/split-multiple-variants-props.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG;IAChB,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;CAC3F,CAAC;AAEF,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,SAAS;IACtC,iBAAiB,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;CAC7D,GACG,CAAC,GACD,KAAK,CAAC;AAEV,KAAK,qBAAqB,CAAC,CAAC,IAAI;KAC7B,CAAC,IAAI,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,GACrD,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAAC,GACP,KAAK,GACP,KAAK;CACV,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,EAChF,KAAK,EAAE,CAAC,EACR,UAAU,EAAE,CAAC,GACZ,CAAC;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,EAAE,IAAI,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAsBpF"}