@seed-design/lynx-react 0.0.0-alpha-20260622094810
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/_virtual/_rolldown/runtime.js +13 -0
- package/lib/components/ActionButton/ActionButton.d.ts +49 -0
- package/lib/components/ActionButton/ActionButton.d.ts.map +1 -0
- package/lib/components/ActionButton/ActionButton.jsx +158 -0
- package/lib/components/ActionButton/index.d.ts +2 -0
- package/lib/components/ActionButton/index.d.ts.map +1 -0
- package/lib/components/AppBar/AppBar.d.ts +35 -0
- package/lib/components/AppBar/AppBar.d.ts.map +1 -0
- package/lib/components/AppBar/AppBar.jsx +132 -0
- package/lib/components/AppBar/AppBar.namespace.d.ts +2 -0
- package/lib/components/AppBar/AppBar.namespace.d.ts.map +1 -0
- package/lib/components/AppBar/AppBar.namespace.js +15 -0
- package/lib/components/AppBar/context.d.ts +13 -0
- package/lib/components/AppBar/context.d.ts.map +1 -0
- package/lib/components/AppBar/context.js +12 -0
- package/lib/components/AppBar/index.d.ts +3 -0
- package/lib/components/AppBar/index.d.ts.map +1 -0
- package/lib/components/AppBar/useAppBar.d.ts +15 -0
- package/lib/components/AppBar/useAppBar.d.ts.map +1 -0
- package/lib/components/AppBar/useAppBar.js +72 -0
- package/lib/components/Badge/Badge.d.ts +14 -0
- package/lib/components/Badge/Badge.d.ts.map +1 -0
- package/lib/components/Badge/Badge.jsx +15 -0
- package/lib/components/Badge/index.d.ts +2 -0
- package/lib/components/Badge/index.d.ts.map +1 -0
- package/lib/components/BottomSheet/BottomSheet.d.ts +87 -0
- package/lib/components/BottomSheet/BottomSheet.d.ts.map +1 -0
- package/lib/components/BottomSheet/BottomSheet.jsx +163 -0
- package/lib/components/BottomSheet/BottomSheet.namespace.d.ts +2 -0
- package/lib/components/BottomSheet/BottomSheet.namespace.d.ts.map +1 -0
- package/lib/components/BottomSheet/BottomSheet.namespace.js +18 -0
- package/lib/components/BottomSheet/index.d.ts +3 -0
- package/lib/components/BottomSheet/index.d.ts.map +1 -0
- package/lib/components/Box/Box.d.ts +20 -0
- package/lib/components/Box/Box.d.ts.map +1 -0
- package/lib/components/Box/Box.jsx +14 -0
- package/lib/components/Box/index.d.ts +2 -0
- package/lib/components/Box/index.d.ts.map +1 -0
- package/lib/components/Checkbox/Checkbox.d.ts +35 -0
- package/lib/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/lib/components/Checkbox/Checkbox.jsx +130 -0
- package/lib/components/Checkbox/Checkbox.namespace.d.ts +2 -0
- package/lib/components/Checkbox/Checkbox.namespace.d.ts.map +1 -0
- package/lib/components/Checkbox/Checkbox.namespace.js +12 -0
- package/lib/components/Checkbox/index.d.ts +3 -0
- package/lib/components/Checkbox/index.d.ts.map +1 -0
- package/lib/components/Icon/Icon.d.ts +37 -0
- package/lib/components/Icon/Icon.d.ts.map +1 -0
- package/lib/components/Icon/Icon.jsx +143 -0
- package/lib/components/Icon/index.d.ts +2 -0
- package/lib/components/Icon/index.d.ts.map +1 -0
- package/lib/components/ProgressCircle/ProgressCircle.d.ts +25 -0
- package/lib/components/ProgressCircle/ProgressCircle.d.ts.map +1 -0
- package/lib/components/ProgressCircle/ProgressCircle.jsx +281 -0
- package/lib/components/ProgressCircle/ProgressCircle.namespace.d.ts +2 -0
- package/lib/components/ProgressCircle/ProgressCircle.namespace.d.ts.map +1 -0
- package/lib/components/ProgressCircle/ProgressCircle.namespace.js +9 -0
- package/lib/components/ProgressCircle/index.d.ts +3 -0
- package/lib/components/ProgressCircle/index.d.ts.map +1 -0
- package/lib/components/RadioGroup/RadioGroup.d.ts +34 -0
- package/lib/components/RadioGroup/RadioGroup.d.ts.map +1 -0
- package/lib/components/RadioGroup/RadioGroup.jsx +160 -0
- package/lib/components/RadioGroup/RadioGroup.namespace.d.ts +2 -0
- package/lib/components/RadioGroup/RadioGroup.namespace.d.ts.map +1 -0
- package/lib/components/RadioGroup/RadioGroup.namespace.js +12 -0
- package/lib/components/RadioGroup/index.d.ts +3 -0
- package/lib/components/RadioGroup/index.d.ts.map +1 -0
- package/lib/components/Stack/Stack.d.ts +33 -0
- package/lib/components/Stack/Stack.d.ts.map +1 -0
- package/lib/components/Stack/Stack.jsx +39 -0
- package/lib/components/Stack/index.d.ts +2 -0
- package/lib/components/Stack/index.d.ts.map +1 -0
- package/lib/components/Switch/Switch.d.ts +21 -0
- package/lib/components/Switch/Switch.d.ts.map +1 -0
- package/lib/components/Switch/Switch.jsx +101 -0
- package/lib/components/Switch/Switch.namespace.d.ts +2 -0
- package/lib/components/Switch/Switch.namespace.d.ts.map +1 -0
- package/lib/components/Switch/Switch.namespace.js +11 -0
- package/lib/components/Switch/index.d.ts +3 -0
- package/lib/components/Switch/index.d.ts.map +1 -0
- package/lib/components/TagGroup/TagGroup.d.ts +34 -0
- package/lib/components/TagGroup/TagGroup.d.ts.map +1 -0
- package/lib/components/TagGroup/TagGroup.jsx +57 -0
- package/lib/components/TagGroup/TagGroup.namespace.d.ts +2 -0
- package/lib/components/TagGroup/TagGroup.namespace.d.ts.map +1 -0
- package/lib/components/TagGroup/TagGroup.namespace.js +10 -0
- package/lib/components/TagGroup/index.d.ts +3 -0
- package/lib/components/TagGroup/index.d.ts.map +1 -0
- package/lib/components/Text/Text.d.ts +7 -0
- package/lib/components/Text/Text.d.ts.map +1 -0
- package/lib/components/Text/Text.jsx +28 -0
- package/lib/components/Text/index.d.ts +2 -0
- package/lib/components/Text/index.d.ts.map +1 -0
- package/lib/components/index.d.ts +14 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/hooks/index.d.ts +5 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/useControllableState.d.ts +15 -0
- package/lib/hooks/useControllableState.d.ts.map +1 -0
- package/lib/hooks/useControllableState.js +27 -0
- package/lib/hooks/useIconColor.d.ts +19 -0
- package/lib/hooks/useIconColor.d.ts.map +1 -0
- package/lib/hooks/useIconColor.js +38 -0
- package/lib/hooks/usePressTap.d.ts +27 -0
- package/lib/hooks/usePressTap.d.ts.map +1 -0
- package/lib/hooks/usePressTap.js +35 -0
- package/lib/hooks/useSafeArea.d.ts +19 -0
- package/lib/hooks/useSafeArea.d.ts.map +1 -0
- package/lib/hooks/useSafeArea.js +33 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +29 -0
- package/lib/types.d.ts +51 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/utils/children.d.ts +3 -0
- package/lib/utils/children.d.ts.map +1 -0
- package/lib/utils/children.js +8 -0
- package/lib/utils/create-slot-recipe-context.d.ts +27 -0
- package/lib/utils/create-slot-recipe-context.d.ts.map +1 -0
- package/lib/utils/create-slot-recipe-context.jsx +94 -0
- package/lib/utils/get-seed-class-name.d.ts +22 -0
- package/lib/utils/get-seed-class-name.d.ts.map +1 -0
- package/lib/utils/get-seed-class-name.js +28 -0
- package/lib/utils/index.d.ts +5 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/resolve-recipe-token.d.ts +38 -0
- package/lib/utils/resolve-recipe-token.d.ts.map +1 -0
- package/lib/utils/resolve-recipe-token.js +49 -0
- package/lib/utils/split-multiple-variants-props.d.ts +29 -0
- package/lib/utils/split-multiple-variants-props.d.ts.map +1 -0
- package/lib/utils/split-multiple-variants-props.js +34 -0
- package/lib/utils/styled.d.ts +83 -0
- package/lib/utils/styled.d.ts.map +1 -0
- package/lib/utils/styled.js +144 -0
- package/package.json +54 -0
- package/src/components/ActionButton/ActionButton.test.tsx +167 -0
- package/src/components/ActionButton/ActionButton.tsx +363 -0
- package/src/components/ActionButton/index.ts +1 -0
- package/src/components/AppBar/AppBar.namespace.ts +18 -0
- package/src/components/AppBar/AppBar.test.tsx +270 -0
- package/src/components/AppBar/AppBar.tsx +288 -0
- package/src/components/AppBar/context.ts +27 -0
- package/src/components/AppBar/index.ts +21 -0
- package/src/components/AppBar/useAppBar.ts +100 -0
- package/src/components/Badge/Badge.test.tsx +54 -0
- package/src/components/Badge/Badge.tsx +32 -0
- package/src/components/Badge/index.ts +1 -0
- package/src/components/BottomSheet/BottomSheet.namespace.ts +24 -0
- package/src/components/BottomSheet/BottomSheet.test.tsx +219 -0
- package/src/components/BottomSheet/BottomSheet.tsx +423 -0
- package/src/components/BottomSheet/index.ts +27 -0
- package/src/components/Box/Box.test.tsx +85 -0
- package/src/components/Box/Box.tsx +39 -0
- package/src/components/Box/index.ts +1 -0
- package/src/components/Checkbox/Checkbox.namespace.ts +12 -0
- package/src/components/Checkbox/Checkbox.tsx +282 -0
- package/src/components/Checkbox/index.ts +14 -0
- package/src/components/Icon/Icon.tsx +265 -0
- package/src/components/Icon/index.ts +8 -0
- package/src/components/ProgressCircle/ProgressCircle.namespace.ts +5 -0
- package/src/components/ProgressCircle/ProgressCircle.tsx +424 -0
- package/src/components/ProgressCircle/index.ts +9 -0
- package/src/components/RadioGroup/RadioGroup.namespace.ts +12 -0
- package/src/components/RadioGroup/RadioGroup.tsx +320 -0
- package/src/components/RadioGroup/index.ts +14 -0
- package/src/components/Stack/Stack.tsx +97 -0
- package/src/components/Stack/index.ts +1 -0
- package/src/components/Switch/Switch.namespace.ts +10 -0
- package/src/components/Switch/Switch.tsx +200 -0
- package/src/components/Switch/index.ts +12 -0
- package/src/components/TagGroup/TagGroup.namespace.ts +8 -0
- package/src/components/TagGroup/TagGroup.tsx +127 -0
- package/src/components/TagGroup/index.ts +10 -0
- package/src/components/Text/Text.tsx +64 -0
- package/src/components/Text/index.ts +1 -0
- package/src/components/index.ts +13 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useControllableState.test.ts +120 -0
- package/src/hooks/useControllableState.ts +38 -0
- package/src/hooks/useIconColor.test.ts +13 -0
- package/src/hooks/useIconColor.ts +67 -0
- package/src/hooks/usePressTap.test.ts +129 -0
- package/src/hooks/usePressTap.ts +58 -0
- package/src/hooks/useSafeArea.test.ts +83 -0
- package/src/hooks/useSafeArea.ts +56 -0
- package/src/index.ts +4 -0
- package/src/types.ts +76 -0
- package/src/utils/children.ts +13 -0
- package/src/utils/create-slot-recipe-context.test.tsx +96 -0
- package/src/utils/create-slot-recipe-context.tsx +187 -0
- package/src/utils/get-seed-class-name.ts +47 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/resolve-recipe-token.ts +47 -0
- package/src/utils/split-multiple-variants-props.test.ts +61 -0
- package/src/utils/split-multiple-variants-props.ts +59 -0
- package/src/utils/styled.ts +442 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import { render } from "@lynx-js/react/testing-library";
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
|
|
5
|
+
import { Text } from "../Text";
|
|
6
|
+
import { Box } from "./Box";
|
|
7
|
+
|
|
8
|
+
interface TestLynxGlobal {
|
|
9
|
+
lynx?: {
|
|
10
|
+
__globalProps?: {
|
|
11
|
+
safeAreaInsetTop?: number;
|
|
12
|
+
safeAreaInsetBottom?: number;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
lynxTestingEnv?: {
|
|
16
|
+
backgroundThread: {
|
|
17
|
+
globalThis: TestLynxGlobal;
|
|
18
|
+
};
|
|
19
|
+
mainThread: {
|
|
20
|
+
globalThis: TestLynxGlobal;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getRenderedRoot() {
|
|
26
|
+
const root = elementTree.root;
|
|
27
|
+
|
|
28
|
+
if (!root) {
|
|
29
|
+
throw new Error("Expected Lynx render root to exist.");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return root;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function expectStyle(style: CSSStyleDeclaration, expected: Record<string, string>) {
|
|
36
|
+
for (const [key, value] of Object.entries(expected)) {
|
|
37
|
+
expect(style.getPropertyValue(key)).toBe(value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function setGlobalProps(
|
|
42
|
+
globalProps: NonNullable<NonNullable<TestLynxGlobal["lynx"]>["__globalProps"]>,
|
|
43
|
+
) {
|
|
44
|
+
const lynxTestingEnv = (globalThis as TestLynxGlobal).lynxTestingEnv;
|
|
45
|
+
const globals = [
|
|
46
|
+
globalThis as TestLynxGlobal,
|
|
47
|
+
lynxTestingEnv?.backgroundThread.globalThis,
|
|
48
|
+
lynxTestingEnv?.mainThread.globalThis,
|
|
49
|
+
].filter((global): global is TestLynxGlobal => Boolean(global));
|
|
50
|
+
|
|
51
|
+
for (const global of globals) {
|
|
52
|
+
global.lynx = {
|
|
53
|
+
...global.lynx,
|
|
54
|
+
__globalProps: globalProps,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
describe("Box", () => {
|
|
60
|
+
afterEach(() => {
|
|
61
|
+
setGlobalProps({});
|
|
62
|
+
vi.unstubAllGlobals();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("resolves top and bottom safe area padding from global props", () => {
|
|
66
|
+
setGlobalProps({
|
|
67
|
+
safeAreaInsetTop: 47,
|
|
68
|
+
safeAreaInsetBottom: 34,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
render(
|
|
72
|
+
<Box className="box-test" pt="safeArea" pb="safeArea">
|
|
73
|
+
<Text>Box content</Text>
|
|
74
|
+
</Box>,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const box = getRenderedRoot().querySelector(".box-test");
|
|
78
|
+
|
|
79
|
+
expect(box).toBeInTheDocument();
|
|
80
|
+
expectStyle((box as HTMLElement).style, {
|
|
81
|
+
"padding-top": "47px",
|
|
82
|
+
"padding-bottom": "34px",
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import * as React from "@lynx-js/react";
|
|
3
|
+
|
|
4
|
+
import type { LynxPressableProps, LynxStyledElementProps, LynxViewRef } from "../../types";
|
|
5
|
+
import { useStyleProps, type StyleProps } from "../../utils/styled";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @platform Lynx
|
|
9
|
+
*
|
|
10
|
+
* `Box`는 SEED style prop을 native `<view>`의 object style로 변환하는 편의
|
|
11
|
+
* primitive입니다. 많은 항목을 반복 렌더링하는 화면에서는 primitive 컴포넌트
|
|
12
|
+
* 렌더링과 style prop 해석 비용이 누적될 수 있습니다. 앱 코드에서는 native
|
|
13
|
+
* `<view>`/`<text>`와 Tailwind utility className을 우선 고려하세요. 패키지
|
|
14
|
+
* 컴포넌트 내부에서는 native tag와 recipe className을 사용하고, inline style은
|
|
15
|
+
* 런타임 값이 필요한 경우에만 제한적으로 사용합니다.
|
|
16
|
+
*/
|
|
17
|
+
export interface BoxProps extends StyleProps, LynxStyledElementProps, LynxPressableProps {
|
|
18
|
+
bindtouchstart?: () => void;
|
|
19
|
+
bindtouchend?: () => void;
|
|
20
|
+
bindtouchcancel?: () => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const Box = React.forwardRef<unknown, BoxProps>((props, ref) => {
|
|
24
|
+
const { style, restProps } = useStyleProps(props);
|
|
25
|
+
const { children, className, ...nativeProps } = restProps;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<view
|
|
29
|
+
{...(ref ? { ref: ref as LynxViewRef } : {})}
|
|
30
|
+
{...nativeProps}
|
|
31
|
+
className={clsx(className)}
|
|
32
|
+
style={style}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</view>
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
Box.displayName = "Box";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Box, type BoxProps } from "./Box";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export {
|
|
2
|
+
CheckboxControl as Control,
|
|
3
|
+
CheckboxGroup as Group,
|
|
4
|
+
CheckboxIndicator as Indicator,
|
|
5
|
+
CheckboxLabel as Label,
|
|
6
|
+
CheckboxRoot as Root,
|
|
7
|
+
type CheckboxControlProps as ControlProps,
|
|
8
|
+
type CheckboxGroupProps as GroupProps,
|
|
9
|
+
type CheckboxIndicatorProps as IndicatorProps,
|
|
10
|
+
type CheckboxLabelProps as LabelProps,
|
|
11
|
+
type CheckboxRootProps as RootProps,
|
|
12
|
+
} from "./Checkbox";
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import * as React from "@lynx-js/react";
|
|
2
|
+
import { isValidElement, type ReactElement } from "@lynx-js/react";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
|
|
5
|
+
import { checkbox } from "@seed-design/lynx-css/recipes/checkbox";
|
|
6
|
+
import type { CheckboxVariantProps } from "@seed-design/lynx-css/recipes/checkbox";
|
|
7
|
+
import { checkmark } from "@seed-design/lynx-css/recipes/checkmark";
|
|
8
|
+
import type { CheckmarkVariantProps } from "@seed-design/lynx-css/recipes/checkmark";
|
|
9
|
+
import { checkboxGroup } from "@seed-design/lynx-css/recipes/checkbox-group";
|
|
10
|
+
|
|
11
|
+
import { useControllableState } from "../../hooks/useControllableState";
|
|
12
|
+
import { usePressTap } from "../../hooks/usePressTap";
|
|
13
|
+
import type {
|
|
14
|
+
LynxIconElementProps,
|
|
15
|
+
LynxStyledElementProps,
|
|
16
|
+
LynxTextRef,
|
|
17
|
+
LynxViewRef,
|
|
18
|
+
} from "../../types";
|
|
19
|
+
import { splitMultipleVariantsProps } from "../../utils/split-multiple-variants-props";
|
|
20
|
+
import { InternalIcon } from "../Icon/Icon";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @platform Lynx
|
|
24
|
+
*
|
|
25
|
+
* 웹 대비 미지원 기능:
|
|
26
|
+
* - HiddenInput / name / value / required / invalid: Lynx에 native form 제출 모델이 없음
|
|
27
|
+
* - focus / focusVisible: Lynx에 키보드 포커스 개념이 없음
|
|
28
|
+
* - onChange (raw DOM event): 의미 없음. 토글 이벤트는 onCheckedChange로만 노출
|
|
29
|
+
* - weight="default" | "stronger" 호환 매핑: Lynx 신규 컴포넌트이므로 처음부터 "regular" | "bold" 만 노출
|
|
30
|
+
*
|
|
31
|
+
* Indicator 는 `@karrotmarket/lynx-monochrome-icon` 의 monochrome icon 컴포넌트를
|
|
32
|
+
* 받는다. 내부에서 `<image tint-color=...>` 로 렌더되므로 `useIconColor` 훅이
|
|
33
|
+
* recipe 의 `color` 토큰을 `tint-color` 로 동기화한다. raw SVG 주입은 Lynx 범위 밖.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
interface CheckboxContextValue {
|
|
37
|
+
checked: boolean;
|
|
38
|
+
indeterminate: boolean;
|
|
39
|
+
disabled: boolean;
|
|
40
|
+
pressed: boolean;
|
|
41
|
+
checkboxVariantProps: CheckboxVariantProps;
|
|
42
|
+
checkmarkVariantProps: CheckmarkVariantProps;
|
|
43
|
+
toggle: () => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const CheckboxContext = React.createContext<CheckboxContextValue | null>(null);
|
|
47
|
+
|
|
48
|
+
function useCheckboxContext(consumer: string): CheckboxContextValue {
|
|
49
|
+
const ctx = React.useContext(CheckboxContext);
|
|
50
|
+
if (!ctx) {
|
|
51
|
+
throw new Error(`<${consumer}/> must be rendered inside <CheckboxRoot/>.`);
|
|
52
|
+
}
|
|
53
|
+
return ctx;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface CheckmarkControlContextValue {
|
|
57
|
+
iconClassName: string;
|
|
58
|
+
checkmarkVariantProps: CheckmarkVariantProps;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const CheckmarkControlContext = React.createContext<CheckmarkControlContextValue | null>(null);
|
|
62
|
+
|
|
63
|
+
function useCheckmarkControlContext(consumer: string): CheckmarkControlContextValue {
|
|
64
|
+
const ctx = React.useContext(CheckmarkControlContext);
|
|
65
|
+
if (!ctx) {
|
|
66
|
+
throw new Error(`<${consumer}/> must be rendered inside <CheckboxControl/>.`);
|
|
67
|
+
}
|
|
68
|
+
return ctx;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
72
|
+
|
|
73
|
+
export interface CheckboxRootProps
|
|
74
|
+
extends CheckboxVariantProps,
|
|
75
|
+
Omit<CheckmarkVariantProps, "size" | "checked" | "disabled" | "indeterminate">,
|
|
76
|
+
LynxStyledElementProps {
|
|
77
|
+
checked?: boolean;
|
|
78
|
+
defaultChecked?: boolean;
|
|
79
|
+
indeterminate?: boolean;
|
|
80
|
+
disabled?: boolean;
|
|
81
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const CheckboxRoot = React.forwardRef<unknown, CheckboxRootProps>((props, ref) => {
|
|
85
|
+
const {
|
|
86
|
+
children,
|
|
87
|
+
className,
|
|
88
|
+
checked: checkedProp,
|
|
89
|
+
defaultChecked = false,
|
|
90
|
+
indeterminate = false,
|
|
91
|
+
disabled = false,
|
|
92
|
+
onCheckedChange,
|
|
93
|
+
...restProps
|
|
94
|
+
} = props;
|
|
95
|
+
const [{ checkbox: checkboxVariantProps, checkmark: checkmarkVariantProps }, nativeProps] =
|
|
96
|
+
splitMultipleVariantsProps(restProps, { checkbox, checkmark });
|
|
97
|
+
|
|
98
|
+
const [checked, setChecked] = useControllableState({
|
|
99
|
+
value: checkedProp,
|
|
100
|
+
defaultValue: defaultChecked,
|
|
101
|
+
onChange: onCheckedChange,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const toggle = React.useCallback(() => setChecked(!checked), [checked, setChecked]);
|
|
105
|
+
|
|
106
|
+
const { pressed, ...pressHandlers } = usePressTap({
|
|
107
|
+
disabled,
|
|
108
|
+
onTap: toggle,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const rootClassName = checkbox({ ...checkboxVariantProps, disabled }).root;
|
|
112
|
+
|
|
113
|
+
const contextValue = React.useMemo<CheckboxContextValue>(
|
|
114
|
+
() => ({
|
|
115
|
+
checked,
|
|
116
|
+
indeterminate,
|
|
117
|
+
disabled,
|
|
118
|
+
pressed,
|
|
119
|
+
checkboxVariantProps,
|
|
120
|
+
checkmarkVariantProps,
|
|
121
|
+
toggle,
|
|
122
|
+
}),
|
|
123
|
+
[
|
|
124
|
+
checked,
|
|
125
|
+
indeterminate,
|
|
126
|
+
disabled,
|
|
127
|
+
pressed,
|
|
128
|
+
checkboxVariantProps,
|
|
129
|
+
checkmarkVariantProps,
|
|
130
|
+
toggle,
|
|
131
|
+
],
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
<CheckboxContext.Provider value={contextValue}>
|
|
136
|
+
<view
|
|
137
|
+
{...(ref ? { ref: ref as LynxViewRef } : {})}
|
|
138
|
+
className={clsx(rootClassName, className)}
|
|
139
|
+
{...pressHandlers}
|
|
140
|
+
{...nativeProps}
|
|
141
|
+
>
|
|
142
|
+
{children}
|
|
143
|
+
</view>
|
|
144
|
+
</CheckboxContext.Provider>
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
CheckboxRoot.displayName = "CheckboxRoot";
|
|
148
|
+
|
|
149
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
150
|
+
|
|
151
|
+
export interface CheckboxControlProps
|
|
152
|
+
extends Pick<CheckmarkVariantProps, "tone" | "variant" | "size">,
|
|
153
|
+
LynxStyledElementProps {}
|
|
154
|
+
|
|
155
|
+
export const CheckboxControl = React.forwardRef<unknown, CheckboxControlProps>((props, ref) => {
|
|
156
|
+
const [variantProps, restProps] = checkmark.splitVariantProps(props);
|
|
157
|
+
const { children, className, ...nativeProps } = restProps;
|
|
158
|
+
const context = useCheckboxContext("CheckboxControl");
|
|
159
|
+
const checkmarkVariantProps: CheckmarkVariantProps = {
|
|
160
|
+
...context.checkmarkVariantProps,
|
|
161
|
+
...variantProps,
|
|
162
|
+
checked: context.checked,
|
|
163
|
+
disabled: context.disabled,
|
|
164
|
+
indeterminate: context.indeterminate,
|
|
165
|
+
pressed: context.pressed,
|
|
166
|
+
};
|
|
167
|
+
const classes = checkmark(checkmarkVariantProps);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<CheckmarkControlContext.Provider
|
|
171
|
+
value={{ iconClassName: classes.icon, checkmarkVariantProps }}
|
|
172
|
+
>
|
|
173
|
+
<view
|
|
174
|
+
{...(ref ? { ref: ref as LynxViewRef } : {})}
|
|
175
|
+
className={clsx(classes.root, className)}
|
|
176
|
+
{...nativeProps}
|
|
177
|
+
>
|
|
178
|
+
{children}
|
|
179
|
+
</view>
|
|
180
|
+
</CheckmarkControlContext.Provider>
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
CheckboxControl.displayName = "CheckboxControl";
|
|
184
|
+
|
|
185
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
186
|
+
|
|
187
|
+
export interface CheckboxIndicatorProps
|
|
188
|
+
extends Pick<LynxStyledElementProps, "className" | "style"> {
|
|
189
|
+
/** Icon rendered when neither checked nor indeterminate. Optional. */
|
|
190
|
+
unchecked?: ReactElement<LynxIconElementProps>;
|
|
191
|
+
/** Icon rendered when `checked=true` and `indeterminate=false`. */
|
|
192
|
+
checked: ReactElement<LynxIconElementProps>;
|
|
193
|
+
/** Icon rendered when `indeterminate=true`. */
|
|
194
|
+
indeterminate?: ReactElement<LynxIconElementProps>;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function CheckboxIndicator(props: CheckboxIndicatorProps) {
|
|
198
|
+
const {
|
|
199
|
+
unchecked,
|
|
200
|
+
checked: checkedIcon,
|
|
201
|
+
indeterminate: indeterminateIcon,
|
|
202
|
+
className,
|
|
203
|
+
style,
|
|
204
|
+
} = props;
|
|
205
|
+
const context = useCheckboxContext("CheckboxIndicator");
|
|
206
|
+
const { iconClassName, checkmarkVariantProps } = useCheckmarkControlContext("CheckboxIndicator");
|
|
207
|
+
|
|
208
|
+
if (process.env.NODE_ENV !== "production" && context.indeterminate && !indeterminateIcon) {
|
|
209
|
+
console.warn(
|
|
210
|
+
"[seed-design] CheckboxIndicator: `indeterminate` prop must be provided when the checkbox is in an indeterminate state.",
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const icon = context.indeterminate
|
|
215
|
+
? indeterminateIcon
|
|
216
|
+
: context.checked
|
|
217
|
+
? checkedIcon
|
|
218
|
+
: unchecked;
|
|
219
|
+
if (!icon || !isValidElement<LynxIconElementProps>(icon)) return null;
|
|
220
|
+
|
|
221
|
+
return (
|
|
222
|
+
<InternalIcon
|
|
223
|
+
icon={icon}
|
|
224
|
+
className={clsx(iconClassName, className)}
|
|
225
|
+
style={style}
|
|
226
|
+
deps={[
|
|
227
|
+
context.checked,
|
|
228
|
+
context.indeterminate,
|
|
229
|
+
context.disabled,
|
|
230
|
+
context.pressed,
|
|
231
|
+
checkmarkVariantProps.tone,
|
|
232
|
+
checkmarkVariantProps.variant,
|
|
233
|
+
checkmarkVariantProps.size,
|
|
234
|
+
]}
|
|
235
|
+
/>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
CheckboxIndicator.displayName = "CheckboxIndicator";
|
|
239
|
+
|
|
240
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
241
|
+
|
|
242
|
+
export interface CheckboxLabelProps extends LynxStyledElementProps {}
|
|
243
|
+
|
|
244
|
+
export const CheckboxLabel = React.forwardRef<unknown, CheckboxLabelProps>((props, ref) => {
|
|
245
|
+
const { children, className, ...nativeProps } = props;
|
|
246
|
+
const context = useCheckboxContext("CheckboxLabel");
|
|
247
|
+
const labelClassName = checkbox({
|
|
248
|
+
...context.checkboxVariantProps,
|
|
249
|
+
disabled: context.disabled,
|
|
250
|
+
}).label;
|
|
251
|
+
|
|
252
|
+
return (
|
|
253
|
+
<text
|
|
254
|
+
{...(ref ? { ref: ref as LynxTextRef } : {})}
|
|
255
|
+
className={clsx(labelClassName, className)}
|
|
256
|
+
{...nativeProps}
|
|
257
|
+
>
|
|
258
|
+
{children}
|
|
259
|
+
</text>
|
|
260
|
+
);
|
|
261
|
+
});
|
|
262
|
+
CheckboxLabel.displayName = "CheckboxLabel";
|
|
263
|
+
|
|
264
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
265
|
+
|
|
266
|
+
export interface CheckboxGroupProps extends LynxStyledElementProps {}
|
|
267
|
+
|
|
268
|
+
export const CheckboxGroup = React.forwardRef<unknown, CheckboxGroupProps>((props, ref) => {
|
|
269
|
+
const { children, className, ...nativeProps } = props;
|
|
270
|
+
const classes = checkboxGroup();
|
|
271
|
+
|
|
272
|
+
return (
|
|
273
|
+
<view
|
|
274
|
+
{...(ref ? { ref: ref as LynxViewRef } : {})}
|
|
275
|
+
className={clsx(classes.root, className)}
|
|
276
|
+
{...nativeProps}
|
|
277
|
+
>
|
|
278
|
+
{children}
|
|
279
|
+
</view>
|
|
280
|
+
);
|
|
281
|
+
});
|
|
282
|
+
CheckboxGroup.displayName = "CheckboxGroup";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export {
|
|
2
|
+
CheckboxRoot,
|
|
3
|
+
CheckboxControl,
|
|
4
|
+
CheckboxIndicator,
|
|
5
|
+
CheckboxLabel,
|
|
6
|
+
CheckboxGroup,
|
|
7
|
+
type CheckboxRootProps,
|
|
8
|
+
type CheckboxControlProps,
|
|
9
|
+
type CheckboxIndicatorProps,
|
|
10
|
+
type CheckboxLabelProps,
|
|
11
|
+
type CheckboxGroupProps,
|
|
12
|
+
} from "./Checkbox";
|
|
13
|
+
|
|
14
|
+
export * as Checkbox from "./Checkbox.namespace";
|