@seed-design/lynx-react 0.1.1-alpha.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 (74) hide show
  1. package/lib/components/ActionButton/ActionButton.d.ts +24 -0
  2. package/lib/components/ActionButton/ActionButton.d.ts.map +1 -0
  3. package/lib/components/ActionButton/ActionButton.jsx +21 -0
  4. package/lib/components/ActionButton/index.d.ts +2 -0
  5. package/lib/components/ActionButton/index.d.ts.map +1 -0
  6. package/lib/components/ActionButton/index.js +1 -0
  7. package/lib/components/Box/Box.d.ts +10 -0
  8. package/lib/components/Box/Box.d.ts.map +1 -0
  9. package/lib/components/Box/Box.jsx +19 -0
  10. package/lib/components/Box/index.d.ts +2 -0
  11. package/lib/components/Box/index.d.ts.map +1 -0
  12. package/lib/components/Box/index.js +1 -0
  13. package/lib/components/Flex/Flex.d.ts +33 -0
  14. package/lib/components/Flex/Flex.d.ts.map +1 -0
  15. package/lib/components/Flex/Flex.jsx +7 -0
  16. package/lib/components/Flex/index.d.ts +2 -0
  17. package/lib/components/Flex/index.d.ts.map +1 -0
  18. package/lib/components/Flex/index.js +1 -0
  19. package/lib/components/List/List.d.ts +9 -0
  20. package/lib/components/List/List.d.ts.map +1 -0
  21. package/lib/components/List/List.jsx +17 -0
  22. package/lib/components/List/index.d.ts +2 -0
  23. package/lib/components/List/index.d.ts.map +1 -0
  24. package/lib/components/List/index.js +1 -0
  25. package/lib/components/ListItem/ListItem.d.ts +8 -0
  26. package/lib/components/ListItem/ListItem.d.ts.map +1 -0
  27. package/lib/components/ListItem/ListItem.jsx +11 -0
  28. package/lib/components/ListItem/index.d.ts +2 -0
  29. package/lib/components/ListItem/index.d.ts.map +1 -0
  30. package/lib/components/ListItem/index.js +1 -0
  31. package/lib/components/ProgressCircle/ProgressCircle.d.ts +28 -0
  32. package/lib/components/ProgressCircle/ProgressCircle.d.ts.map +1 -0
  33. package/lib/components/ProgressCircle/ProgressCircle.jsx +292 -0
  34. package/lib/components/ProgressCircle/index.d.ts +2 -0
  35. package/lib/components/ProgressCircle/index.d.ts.map +1 -0
  36. package/lib/components/ProgressCircle/index.js +1 -0
  37. package/lib/components/ScrollView/ScrollView.d.ts +9 -0
  38. package/lib/components/ScrollView/ScrollView.d.ts.map +1 -0
  39. package/lib/components/ScrollView/ScrollView.jsx +17 -0
  40. package/lib/components/ScrollView/index.d.ts +2 -0
  41. package/lib/components/ScrollView/index.d.ts.map +1 -0
  42. package/lib/components/ScrollView/index.js +1 -0
  43. package/lib/components/Stack/Stack.d.ts +6 -0
  44. package/lib/components/Stack/Stack.d.ts.map +1 -0
  45. package/lib/components/Stack/Stack.jsx +10 -0
  46. package/lib/components/Stack/index.d.ts +2 -0
  47. package/lib/components/Stack/index.d.ts.map +1 -0
  48. package/lib/components/Stack/index.js +1 -0
  49. package/lib/components/Text/Text.d.ts +30 -0
  50. package/lib/components/Text/Text.d.ts.map +1 -0
  51. package/lib/components/Text/Text.jsx +49 -0
  52. package/lib/components/Text/index.d.ts +2 -0
  53. package/lib/components/Text/index.d.ts.map +1 -0
  54. package/lib/components/Text/index.js +1 -0
  55. package/lib/get-seed-class-name.d.ts +23 -0
  56. package/lib/get-seed-class-name.d.ts.map +1 -0
  57. package/lib/get-seed-class-name.js +39 -0
  58. package/lib/index.d.ts +5 -0
  59. package/lib/index.d.ts.map +1 -0
  60. package/lib/index.js +4 -0
  61. package/lib/utils/dynamic-style.d.ts +13 -0
  62. package/lib/utils/dynamic-style.d.ts.map +1 -0
  63. package/lib/utils/dynamic-style.js +26 -0
  64. package/lib/utils/styled.d.ts +120 -0
  65. package/lib/utils/styled.d.ts.map +1 -0
  66. package/lib/utils/styled.jsx +131 -0
  67. package/package.json +51 -0
  68. package/src/components/ActionButton/ActionButton.tsx +62 -0
  69. package/src/components/ActionButton/index.ts +1 -0
  70. package/src/components/ProgressCircle/ProgressCircle.tsx +409 -0
  71. package/src/components/ProgressCircle/index.ts +1 -0
  72. package/src/get-seed-class-name.ts +52 -0
  73. package/src/index.ts +4 -0
  74. package/src/utils/dynamic-style.ts +26 -0
@@ -0,0 +1,24 @@
1
+ import type { ActionButtonVariantProps } from "@seed-design/lynx-css/recipes/action-button";
2
+ import * as React from "react";
3
+ /**
4
+ * @platform Lynx
5
+ *
6
+ * 미지원 기능 (Lynx 3.7 SVG 지원 후 추가 예정):
7
+ * - loading: SVG 기반 spinner 필요
8
+ * - layout: "iconOnly": SVG 아이콘 렌더링 필요
9
+ * - PrefixIcon / SuffixIcon: SVG 아이콘 렌더링 필요
10
+ *
11
+ * 웹 대비 미지원 기능:
12
+ * - color / fontWeight props: CSS variable 동적 주입 제한
13
+ * - bleedX / bleedY props: CSS variable 동적 주입 제한
14
+ */
15
+ export interface ActionButtonProps extends Omit<ActionButtonVariantProps, "loading" | "layout"> {
16
+ children?: React.ReactNode;
17
+ disabled?: boolean;
18
+ className?: string;
19
+ flexGrow?: number;
20
+ bindtap?: () => void;
21
+ "main-thread:bindtap"?: () => void;
22
+ }
23
+ export declare const ActionButton: React.ForwardRefExoticComponent<ActionButtonProps & React.RefAttributes<unknown>>;
24
+ //# sourceMappingURL=ActionButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionButton.d.ts","sourceRoot":"","sources":["../../../src/components/ActionButton/ActionButton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAE5F,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,wBAAwB,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7F,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAED,eAAO,MAAM,YAAY,mFAkCvB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { actionButton } from "@seed-design/lynx-css/recipes/action-button";
2
+ import clsx from "clsx";
3
+ import * as React from "react";
4
+ export const ActionButton = React.forwardRef((props, ref) => {
5
+ const [variantProps, restProps] = actionButton.splitVariantProps(props);
6
+ const { children, className, flexGrow, bindtap, "main-thread:bindtap": mainThreadBindtap, ...nativeProps } = restProps;
7
+ const { disabled = false } = variantProps;
8
+ const classes = actionButton({
9
+ ...variantProps,
10
+ layout: "withText",
11
+ disabled: disabled ? true : undefined,
12
+ });
13
+ const isInteractive = !disabled;
14
+ return (<view {...(ref ? { ref: ref } : {})} className={clsx(classes.root, className)} style={flexGrow != null ? { flexGrow } : undefined} {...(isInteractive && bindtap && { bindtap })} {...(isInteractive &&
15
+ mainThreadBindtap && {
16
+ "main-thread:bindtap": mainThreadBindtap,
17
+ })} {...nativeProps}>
18
+ <text className={classes.text}>{children}</text>
19
+ </view>);
20
+ });
21
+ ActionButton.displayName = "ActionButton";
@@ -0,0 +1,2 @@
1
+ export { ActionButton, type ActionButtonProps } from "./ActionButton";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ActionButton/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export { ActionButton } from "./ActionButton";
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from "react";
2
+ import { type StyleProps } from "../../utils/styled";
3
+ export interface BoxProps extends StyleProps {
4
+ asChild?: boolean;
5
+ className?: string;
6
+ style?: React.CSSProperties;
7
+ children?: ReactNode;
8
+ }
9
+ export declare const Box: import("react").ForwardRefExoticComponent<BoxProps & import("react").RefAttributes<any>>;
10
+ //# sourceMappingURL=Box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Box.d.ts","sourceRoot":"","sources":["../../../src/components/Box/Box.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEpE,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,eAAO,MAAM,GAAG,0FAgBd,CAAC"}
@@ -0,0 +1,19 @@
1
+ import clsx from "clsx";
2
+ import { forwardRef } from "react";
3
+ import { Slot } from "@seed-design/lynx-primitive";
4
+ import { useStyleProps } from "../../utils/styled";
5
+ export const Box = forwardRef((props, ref) => {
6
+ const { style, restProps } = useStyleProps(props);
7
+ const { asChild = false, className, children, ...nativeProps } = restProps;
8
+ const mergedProps = {
9
+ ...(ref ? { ref } : {}),
10
+ className: clsx("seed-box", className),
11
+ style: style,
12
+ ...nativeProps,
13
+ };
14
+ if (asChild) {
15
+ return <Slot {...mergedProps}>{children}</Slot>;
16
+ }
17
+ return <view {...mergedProps}>{children}</view>;
18
+ });
19
+ Box.displayName = "Box";
@@ -0,0 +1,2 @@
1
+ export { Box, type BoxProps } from "./Box";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Box/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAC"}
@@ -0,0 +1 @@
1
+ export { Box } from "./Box";
@@ -0,0 +1,33 @@
1
+ import { type BoxProps } from "../Box/Box";
2
+ export interface FlexProps extends Omit<BoxProps, "display"> {
3
+ /**
4
+ * @default "flex"
5
+ */
6
+ display?: "flex" | "none";
7
+ /**
8
+ * Shorthand for `flexDirection`.
9
+ */
10
+ direction?: BoxProps["flexDirection"];
11
+ /**
12
+ * Shorthand for `flexWrap`.
13
+ */
14
+ wrap?: BoxProps["flexWrap"];
15
+ /**
16
+ * Shorthand for `alignItems`.
17
+ */
18
+ align?: BoxProps["alignItems"];
19
+ /**
20
+ * Shorthand for `justifyContent`.
21
+ */
22
+ justify?: BoxProps["justifyContent"];
23
+ /**
24
+ * Shorthand for `flexGrow`.
25
+ */
26
+ grow?: BoxProps["flexGrow"];
27
+ /**
28
+ * Shorthand for `flexShrink`.
29
+ */
30
+ shrink?: BoxProps["flexShrink"];
31
+ }
32
+ export declare const Flex: import("react").ForwardRefExoticComponent<FlexProps & import("react").RefAttributes<any>>;
33
+ //# sourceMappingURL=Flex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Flex.d.ts","sourceRoot":"","sources":["../../../src/components/Flex/Flex.tsx"],"names":[],"mappings":"AACA,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC1D;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1B;;OAEG;IACH,SAAS,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAEtC;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE5B;;OAEG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IAE/B;;OAEG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAErC;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE5B;;OAEG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;CACjC;AAED,eAAO,MAAM,IAAI,2FAgBf,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { forwardRef } from "react";
2
+ import { Box } from "../Box/Box";
3
+ export const Flex = forwardRef((props, ref) => {
4
+ const { direction, wrap, align, justify, grow, shrink, ...rest } = props;
5
+ return (<Box ref={ref} display="flex" flexDirection={direction} flexWrap={wrap} alignItems={align} justifyContent={justify} flexGrow={grow} flexShrink={shrink} {...rest}/>);
6
+ });
7
+ Flex.displayName = "Flex";
@@ -0,0 +1,2 @@
1
+ export { Flex, type FlexProps } from "./Flex";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Flex/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1 @@
1
+ export { Flex } from "./Flex";
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ import { type StyleProps } from "../../utils/styled";
3
+ import type { ListProps as LynxListProps } from "@lynx-js/types";
4
+ export interface ListProps extends StyleProps, Omit<LynxListProps, "style"> {
5
+ asChild?: boolean;
6
+ children?: ReactNode;
7
+ }
8
+ export declare const List: import("react").NamedExoticComponent<Omit<ListProps, "ref"> & import("react").RefAttributes<any>>;
9
+ //# sourceMappingURL=List.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"List.d.ts","sourceRoot":"","sources":["../../../src/components/List/List.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEjE,MAAM,WAAW,SAAU,SAAQ,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAuBD,eAAO,MAAM,IAAI,mGAAiB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { forwardRef, memo } from "react";
2
+ import { Slot } from "@seed-design/lynx-primitive";
3
+ import { useStyleProps } from "../../utils/styled";
4
+ const ListImpl = forwardRef((props, ref) => {
5
+ const { style, restProps } = useStyleProps(props);
6
+ const { asChild = false, className, children, ...nativeProps } = restProps;
7
+ if (asChild) {
8
+ return (<Slot {...(ref ? { ref } : {})} className={className} style={style} {...nativeProps}>
9
+ {children}
10
+ </Slot>);
11
+ }
12
+ return (<list {...(ref ? { ref } : {})} className={className} style={style} {...nativeProps}>
13
+ {children}
14
+ </list>);
15
+ });
16
+ ListImpl.displayName = "List";
17
+ export const List = memo(ListImpl);
@@ -0,0 +1,2 @@
1
+ export { List, type ListProps } from "./List";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/List/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1 @@
1
+ export { List } from "./List";
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from "react";
2
+ import { type StyleProps } from "../../utils/styled";
3
+ import type { ListItemProps as LynxListItemProps } from "@lynx-js/types";
4
+ export interface ListItemProps extends StyleProps, Omit<LynxListItemProps, "style"> {
5
+ children?: ReactNode;
6
+ }
7
+ export declare const ListItem: import("react").NamedExoticComponent<Omit<ListItemProps, "ref"> & import("react").RefAttributes<any>>;
8
+ //# sourceMappingURL=ListItem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListItem.d.ts","sourceRoot":"","sources":["../../../src/components/ListItem/ListItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,MAAM,WAAW,aAAc,SAAQ,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACjF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAoBD,eAAO,MAAM,QAAQ,uGAAqB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { forwardRef, memo } from "react";
2
+ import { useStyleProps } from "../../utils/styled";
3
+ const ListItemImpl = forwardRef((props, ref) => {
4
+ const { style, restProps } = useStyleProps(props);
5
+ const { className, children, ...nativeProps } = restProps;
6
+ return (<list-item {...(ref ? { ref } : {})} className={className} style={style} {...nativeProps}>
7
+ {children}
8
+ </list-item>);
9
+ });
10
+ ListItemImpl.displayName = "ListItem";
11
+ export const ListItem = memo(ListItemImpl);
@@ -0,0 +1,2 @@
1
+ export { ListItem, type ListItemProps } from "./ListItem";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ListItem/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1 @@
1
+ export { ListItem } from "./ListItem";
@@ -0,0 +1,28 @@
1
+ import type { ProgressCircleVariantProps } from "@seed-design/lynx-css/recipes/progress-circle";
2
+ export interface RootProps extends ProgressCircleVariantProps {
3
+ minValue?: number;
4
+ maxValue?: number;
5
+ value?: number;
6
+ children?: React.ReactNode;
7
+ className?: string;
8
+ }
9
+ /**
10
+ * Lynx에서 SVG를 사용할 수 없어 CSS clip-path 기반 pie sector로 구현.
11
+ *
12
+ * **Known Issues:**
13
+ * - clip-path가 Lynx에서 animatable이 아니라 JS RAF로 매 프레임 SVG path 생성
14
+ * - Lynx main thread에서 모듈 레벨 Map 미지원으로 인스턴스 간 RAF 공유 불가
15
+ * - 다수 인스턴스 동시 렌더링 시 성능 저하 가능
16
+ *
17
+ * Lynx SVG + stroke-dasharray 지원 시 CSS-only 애니메이션으로 전환 예정.
18
+ */
19
+ declare function Root(props: RootProps): import("react").JSX.Element;
20
+ declare function Track(): null;
21
+ declare function Range(): import("react").JSX.Element;
22
+ export declare const ProgressCircle: {
23
+ Root: typeof Root;
24
+ Track: typeof Track;
25
+ Range: typeof Range;
26
+ };
27
+ export {};
28
+ //# sourceMappingURL=ProgressCircle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProgressCircle.d.ts","sourceRoot":"","sources":["../../../src/components/ProgressCircle/ProgressCircle.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAqGhG,MAAM,WAAW,SAAU,SAAQ,0BAA0B;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,iBAAS,IAAI,CAAC,KAAK,EAAE,SAAS,+BAgC7B;AAED,iBAAS,KAAK,SAEb;AAED,iBAAS,KAAK,gCAQb;AAyOD,eAAO,MAAM,cAAc;;;;CAI1B,CAAC"}
@@ -0,0 +1,292 @@
1
+ import { createContext, runOnMainThread, useContext, useEffect, useMemo, useMainThreadRef, } from "@lynx-js/react";
2
+ import clsx from "clsx";
3
+ import { progressCircle } from "@seed-design/lynx-css/recipes/progress-circle";
4
+ const ProgressCircleContext = createContext(null);
5
+ function useProgressCircleCtx() {
6
+ const ctx = useContext(ProgressCircleContext);
7
+ if (!ctx) {
8
+ throw new Error("ProgressCircle compound components must be used within ProgressCircle.Root");
9
+ }
10
+ return ctx;
11
+ }
12
+ // --- Background-thread-only utilities (for initial render) ---
13
+ function computeRingGeometry(numSize) {
14
+ const halfSize = numSize / 2;
15
+ const innerR = 0.53 * Math.SQRT2 * halfSize;
16
+ const ringCenterR = (halfSize + innerR) / 2;
17
+ const capSize = halfSize - innerR;
18
+ return { halfSize, innerR, ringCenterR, capSize };
19
+ }
20
+ function bgPieClipPath(size, angleDeg) {
21
+ if (angleDeg >= 360)
22
+ return undefined;
23
+ if (angleDeg <= 0)
24
+ return 'path("M 0 0 Z")';
25
+ const c = size / 2;
26
+ const r = c + 1;
27
+ const rad = (angleDeg * Math.PI) / 180;
28
+ const endX = c + r * Math.sin(rad);
29
+ const endY = c - r * Math.cos(rad);
30
+ const largeArc = angleDeg > 180 ? 1 : 0;
31
+ return `path("M ${c} ${c} L ${c} ${c - r} A ${r} ${r} 0 ${largeArc} 1 ${endX} ${endY} Z")`;
32
+ }
33
+ // --- Main-thread-only utilities (for animations) ---
34
+ // Compiled into the main thread bundle. Must NOT be called from render code.
35
+ function cubicBezier(rawT, x1, y1, x2, y2) {
36
+ "main thread";
37
+ const t = Math.max(0, Math.min(1, rawT));
38
+ const cx = 3 * x1;
39
+ const bx = 3 * (x2 - x1) - cx;
40
+ const ax = 1 - cx - bx;
41
+ let currentT = t;
42
+ for (let i = 0; i < 8; i++) {
43
+ const currentX = ((ax * currentT + bx) * currentT + cx) * currentT - t;
44
+ const currentDx = (3 * ax * currentT + 2 * bx) * currentT + cx;
45
+ if (Math.abs(currentDx) < 1e-6)
46
+ break;
47
+ currentT = currentT - currentX / currentDx;
48
+ }
49
+ const cy = 3 * y1;
50
+ const by = 3 * (y2 - y1) - cy;
51
+ const ay = 1 - cy - by;
52
+ return ((ay * currentT + by) * currentT + cy) * currentT;
53
+ }
54
+ function pieClipPath(size, angleDeg) {
55
+ "main thread";
56
+ if (angleDeg >= 360)
57
+ return undefined;
58
+ if (angleDeg <= 0)
59
+ return 'path("M 0 0 Z")';
60
+ const c = size / 2;
61
+ const r = c + 1;
62
+ const rad = (angleDeg * Math.PI) / 180;
63
+ const endX = c + r * Math.sin(rad);
64
+ const endY = c - r * Math.cos(rad);
65
+ const largeArc = angleDeg > 180 ? 1 : 0;
66
+ return `path("M ${c} ${c} L ${c} ${c - r} A ${r} ${r} 0 ${largeArc} 1 ${endX} ${endY} Z")`;
67
+ }
68
+ function sampleIndeterminate(t) {
69
+ "main thread";
70
+ const containerEased = cubicBezier(t, 0.35, 0.25, 0.65, 0.75);
71
+ const headEased = cubicBezier(t, 0.35, 0, 0.65, 1);
72
+ const tailEased = cubicBezier(t, 0.35, 0, 0.65, 0.6);
73
+ const headLength = headEased <= 0.75 ? (headEased / 0.75) * 360 : 360;
74
+ const tailOffset = tailEased <= 1 / 3 ? 0 : ((tailEased - 1 / 3) / (2 / 3)) * 360;
75
+ const arcLength = Math.max(0, headLength - tailOffset);
76
+ const containerDeg = containerEased * 360 + tailOffset;
77
+ return { containerDeg, arcLength };
78
+ }
79
+ // --- Animation constants ---
80
+ const INDETERMINATE_DURATION = 1200;
81
+ const TRANSITION_DURATION = 300;
82
+ /**
83
+ * Lynx에서 SVG를 사용할 수 없어 CSS clip-path 기반 pie sector로 구현.
84
+ *
85
+ * **Known Issues:**
86
+ * - clip-path가 Lynx에서 animatable이 아니라 JS RAF로 매 프레임 SVG path 생성
87
+ * - Lynx main thread에서 모듈 레벨 Map 미지원으로 인스턴스 간 RAF 공유 불가
88
+ * - 다수 인스턴스 동시 렌더링 시 성능 저하 가능
89
+ *
90
+ * Lynx SVG + stroke-dasharray 지원 시 CSS-only 애니메이션으로 전환 예정.
91
+ */
92
+ function Root(props) {
93
+ const size = props.size ?? "40";
94
+ const tone = props.tone ?? "neutral";
95
+ const numSize = Number(size);
96
+ const isDeterminate = props.minValue !== undefined && props.maxValue !== undefined && props.value !== undefined;
97
+ const range = (props.maxValue ?? 1) - (props.minValue ?? 0);
98
+ const progress = isDeterminate
99
+ ? range === 0
100
+ ? 0
101
+ : ((props.value ?? 0) - (props.minValue ?? 0)) / range
102
+ : 0;
103
+ const classes = progressCircle({ tone, size });
104
+ const ctx = useMemo(() => ({ tone, numSize, isDeterminate, progress, classes }), [tone, numSize, isDeterminate, progress, classes]);
105
+ return (<ProgressCircleContext.Provider value={ctx}>
106
+ <view className={clsx(classes.root, props.className)} style={{ width: `${numSize}px`, height: `${numSize}px` }}>
107
+ {props.children}
108
+ </view>
109
+ </ProgressCircleContext.Provider>);
110
+ }
111
+ function Track() {
112
+ return null;
113
+ }
114
+ function Range() {
115
+ const { numSize, isDeterminate, progress, classes } = useProgressCircleCtx();
116
+ if (!isDeterminate) {
117
+ return <IndeterminateRange numSize={numSize} classes={classes}/>;
118
+ }
119
+ return <DeterminateRange numSize={numSize} progress={progress} classes={classes}/>;
120
+ }
121
+ function DeterminateRange({ numSize, progress, classes, }) {
122
+ const rangeRef = useMainThreadRef(null);
123
+ const startCapRef = useMainThreadRef(null);
124
+ const endCapRef = useMainThreadRef(null);
125
+ const prevProgressRef = useMainThreadRef(progress);
126
+ const cancelRef = useMainThreadRef(0);
127
+ const { halfSize, ringCenterR, capSize } = computeRingGeometry(numSize);
128
+ const initialAngle = progress * 360;
129
+ const initialClipPath = bgPieClipPath(numSize, initialAngle);
130
+ const initialEndRad = (initialAngle * Math.PI) / 180;
131
+ function startAnimation(newProgress) {
132
+ "main thread";
133
+ if (cancelRef.current) {
134
+ cancelAnimationFrame(cancelRef.current);
135
+ cancelRef.current = 0;
136
+ }
137
+ const from = prevProgressRef.current ?? 0;
138
+ prevProgressRef.current = newProgress;
139
+ if (from === newProgress)
140
+ return;
141
+ const rangeEl = rangeRef.current;
142
+ const endCapEl = endCapRef.current;
143
+ let startTs = 0;
144
+ function applyProgress(p) {
145
+ const angleDeg = p * 360;
146
+ const cp = pieClipPath(numSize, angleDeg);
147
+ if (cp) {
148
+ rangeEl?.setStyleProperty("clip-path", cp);
149
+ }
150
+ else {
151
+ rangeEl?.setStyleProperty("clip-path", "none");
152
+ }
153
+ const rad = (angleDeg * Math.PI) / 180;
154
+ endCapEl?.setStyleProperties({
155
+ left: `${halfSize + ringCenterR * Math.sin(rad) - capSize / 2}px`,
156
+ top: `${halfSize - ringCenterR * Math.cos(rad) - capSize / 2}px`,
157
+ });
158
+ }
159
+ function step(ts) {
160
+ if (!startTs)
161
+ startTs = Number(ts);
162
+ const elapsed = ts - startTs;
163
+ if (elapsed >= TRANSITION_DURATION) {
164
+ applyProgress(newProgress);
165
+ cancelRef.current = 0;
166
+ return;
167
+ }
168
+ const t = elapsed / TRANSITION_DURATION;
169
+ const eased = cubicBezier(t, 0, 0, 0.15, 1);
170
+ applyProgress(from + (newProgress - from) * eased);
171
+ cancelRef.current = requestAnimationFrame(step);
172
+ }
173
+ applyProgress(from);
174
+ cancelRef.current = requestAnimationFrame(step);
175
+ }
176
+ function cancelAnimation() {
177
+ "main thread";
178
+ if (cancelRef.current) {
179
+ cancelAnimationFrame(cancelRef.current);
180
+ cancelRef.current = 0;
181
+ }
182
+ }
183
+ useEffect(() => {
184
+ runOnMainThread(startAnimation)(progress);
185
+ return () => {
186
+ runOnMainThread(cancelAnimation)();
187
+ };
188
+ }, [progress]);
189
+ return (<>
190
+ <view main-thread:ref={rangeRef} className={classes.range} style={{
191
+ position: "absolute",
192
+ width: `${numSize}px`,
193
+ height: `${numSize}px`,
194
+ borderRadius: "50%",
195
+ clipPath: initialClipPath,
196
+ }}/>
197
+ <view main-thread:ref={startCapRef} className={classes.cap} style={{
198
+ width: `${capSize}px`,
199
+ height: `${capSize}px`,
200
+ left: `${halfSize - capSize / 2}px`,
201
+ top: `${halfSize - ringCenterR - capSize / 2}px`,
202
+ }}/>
203
+ <view main-thread:ref={endCapRef} className={classes.cap} style={{
204
+ width: `${capSize}px`,
205
+ height: `${capSize}px`,
206
+ left: `${halfSize + ringCenterR * Math.sin(initialEndRad) - capSize / 2}px`,
207
+ top: `${halfSize - ringCenterR * Math.cos(initialEndRad) - capSize / 2}px`,
208
+ }}/>
209
+ </>);
210
+ }
211
+ function IndeterminateRange({ numSize, classes }) {
212
+ const containerRef = useMainThreadRef(null);
213
+ const rangeRef = useMainThreadRef(null);
214
+ const headCapRef = useMainThreadRef(null);
215
+ const tailCapRef = useMainThreadRef(null);
216
+ const rafIdRef = useMainThreadRef(0);
217
+ const { halfSize, ringCenterR, capSize } = computeRingGeometry(numSize);
218
+ function startLoop() {
219
+ "main thread";
220
+ const containerEl = containerRef.current;
221
+ const rangeEl = rangeRef.current;
222
+ const headCapEl = headCapRef.current;
223
+ let startTs = 0;
224
+ function tick(ts) {
225
+ if (!startTs)
226
+ startTs = Number(ts);
227
+ const elapsed = ts - startTs;
228
+ const t = (elapsed % INDETERMINATE_DURATION) / INDETERMINATE_DURATION;
229
+ const state = sampleIndeterminate(t);
230
+ containerEl?.setStyleProperty("transform", `rotate(${state.containerDeg}deg)`);
231
+ const clipPath = pieClipPath(numSize, state.arcLength);
232
+ if (clipPath) {
233
+ rangeEl?.setStyleProperty("clip-path", clipPath);
234
+ }
235
+ else {
236
+ rangeEl?.setStyleProperty("clip-path", "none");
237
+ }
238
+ const headRad = (state.arcLength * Math.PI) / 180;
239
+ headCapEl?.setStyleProperties({
240
+ left: `${halfSize + ringCenterR * Math.sin(headRad) - capSize / 2}px`,
241
+ top: `${halfSize - ringCenterR * Math.cos(headRad) - capSize / 2}px`,
242
+ });
243
+ rafIdRef.current = requestAnimationFrame(tick);
244
+ }
245
+ rafIdRef.current = requestAnimationFrame(tick);
246
+ }
247
+ function stopLoop() {
248
+ "main thread";
249
+ if (rafIdRef.current) {
250
+ cancelAnimationFrame(rafIdRef.current);
251
+ rafIdRef.current = 0;
252
+ }
253
+ }
254
+ useEffect(() => {
255
+ runOnMainThread(startLoop)();
256
+ return () => {
257
+ runOnMainThread(stopLoop)();
258
+ };
259
+ }, []);
260
+ const initialClipPath = 'path("M 0 0 Z")';
261
+ return (<view main-thread:ref={containerRef} style={{
262
+ position: "absolute",
263
+ width: `${numSize}px`,
264
+ height: `${numSize}px`,
265
+ transform: "rotate(0deg)",
266
+ }}>
267
+ <view main-thread:ref={rangeRef} className={classes.range} style={{
268
+ position: "absolute",
269
+ width: `${numSize}px`,
270
+ height: `${numSize}px`,
271
+ borderRadius: "50%",
272
+ clipPath: initialClipPath,
273
+ }}/>
274
+ <view main-thread:ref={tailCapRef} className={classes.cap} style={{
275
+ width: `${capSize}px`,
276
+ height: `${capSize}px`,
277
+ left: `${halfSize - capSize / 2}px`,
278
+ top: `${halfSize - ringCenterR - capSize / 2}px`,
279
+ }}/>
280
+ <view main-thread:ref={headCapRef} className={classes.cap} style={{
281
+ width: `${capSize}px`,
282
+ height: `${capSize}px`,
283
+ left: `${halfSize - capSize / 2}px`,
284
+ top: `${halfSize - ringCenterR - capSize / 2}px`,
285
+ }}/>
286
+ </view>);
287
+ }
288
+ export const ProgressCircle = {
289
+ Root,
290
+ Track,
291
+ Range,
292
+ };
@@ -0,0 +1,2 @@
1
+ export { ProgressCircle, type RootProps as ProgressCircleProps } from "./ProgressCircle";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ProgressCircle/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,SAAS,IAAI,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ export { ProgressCircle } from "./ProgressCircle";
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ import { type StyleProps } from "../../utils/styled";
3
+ import type { ScrollViewProps as LynxScrollViewProps } from "@lynx-js/types";
4
+ export interface ScrollViewProps extends StyleProps, Omit<LynxScrollViewProps, "style"> {
5
+ asChild?: boolean;
6
+ children?: ReactNode;
7
+ }
8
+ export declare const ScrollView: import("react").NamedExoticComponent<Omit<ScrollViewProps, "ref"> & import("react").RefAttributes<any>>;
9
+ //# sourceMappingURL=ScrollView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScrollView.d.ts","sourceRoot":"","sources":["../../../src/components/ScrollView/ScrollView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,IAAI,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,MAAM,WAAW,eAAgB,SAAQ,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA4BD,eAAO,MAAM,UAAU,yGAAuB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { forwardRef, memo } from "react";
2
+ import { Slot } from "@seed-design/lynx-primitive";
3
+ import { useStyleProps } from "../../utils/styled";
4
+ const ScrollViewImpl = forwardRef((props, ref) => {
5
+ const { style, restProps } = useStyleProps(props);
6
+ const { asChild = false, className, children, ...nativeProps } = restProps;
7
+ if (asChild) {
8
+ return (<Slot {...(ref ? { ref } : {})} className={className} style={style} {...nativeProps}>
9
+ {children}
10
+ </Slot>);
11
+ }
12
+ return (<scroll-view {...(ref ? { ref } : {})} className={className} style={style} {...nativeProps}>
13
+ {children}
14
+ </scroll-view>);
15
+ });
16
+ ScrollViewImpl.displayName = "ScrollView";
17
+ export const ScrollView = memo(ScrollViewImpl);
@@ -0,0 +1,2 @@
1
+ export { ScrollView, type ScrollViewProps } from "./ScrollView";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ScrollView/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1 @@
1
+ export { ScrollView } from "./ScrollView";
@@ -0,0 +1,6 @@
1
+ import { type FlexProps } from "../Flex/Flex";
2
+ export type VStackProps = Omit<FlexProps, "flexDirection">;
3
+ export type HStackProps = Omit<FlexProps, "flexDirection">;
4
+ export declare const VStack: import("react").ForwardRefExoticComponent<VStackProps & import("react").RefAttributes<any>>;
5
+ export declare const HStack: import("react").ForwardRefExoticComponent<HStackProps & import("react").RefAttributes<any>>;
6
+ //# sourceMappingURL=Stack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stack.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.tsx"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAC3D,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAE3D,eAAO,MAAM,MAAM,6FAEjB,CAAC;AAIH,eAAO,MAAM,MAAM,6FAEjB,CAAC"}