@xonic0506/sonic-ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-RULES.md +1 -1
- package/DESIGN.md +355 -16
- package/README.md +2 -0
- package/dist/components/alert-dialog.d.ts +16 -0
- package/dist/components/alert-dialog.js +46 -0
- package/dist/components/badge.d.ts +8 -0
- package/dist/components/badge.js +77 -0
- package/dist/components/button.d.ts +11 -2
- package/dist/components/button.js +24 -14
- package/dist/components/checkbox.d.ts +30 -0
- package/dist/components/checkbox.js +48 -0
- package/dist/components/dialog.d.ts +11 -0
- package/dist/components/dialog.js +17 -14
- package/dist/components/empty-state.d.ts +11 -0
- package/dist/components/empty-state.js +17 -0
- package/dist/components/error-state.d.ts +12 -0
- package/dist/components/error-state.js +24 -0
- package/dist/components/field.d.ts +13 -0
- package/dist/components/field.js +33 -0
- package/dist/components/input.d.ts +1 -0
- package/dist/components/input.js +5 -5
- package/dist/components/menu.d.ts +33 -0
- package/dist/components/menu.js +44 -0
- package/dist/components/popover.d.ts +26 -0
- package/dist/components/popover.js +50 -0
- package/dist/components/popup-styles.d.ts +3 -0
- package/dist/components/popup-styles.js +5 -0
- package/dist/components/progress.d.ts +16 -0
- package/dist/components/progress.js +27 -0
- package/dist/components/radio-group.d.ts +20 -0
- package/dist/components/radio-group.js +40 -0
- package/dist/components/select.d.ts +30 -0
- package/dist/components/select.js +66 -0
- package/dist/components/separator.d.ts +7 -0
- package/dist/components/separator.js +14 -0
- package/dist/components/skeleton.d.ts +8 -0
- package/dist/components/skeleton.js +22 -0
- package/dist/components/state-layout.d.ts +11 -0
- package/dist/components/state-layout.js +31 -0
- package/dist/components/switch.d.ts +12 -0
- package/dist/components/switch.js +24 -0
- package/dist/components/tabs.d.ts +31 -0
- package/dist/components/tabs.js +41 -0
- package/dist/components/textarea.d.ts +6 -0
- package/dist/components/textarea.js +20 -0
- package/dist/components/toast.d.ts +24 -0
- package/dist/components/toast.js +62 -0
- package/dist/components/tooltip.d.ts +11 -0
- package/dist/components/tooltip.js +19 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +23 -5
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +15 -0
- package/package.json +4 -2
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
|
|
2
|
+
interface ButtonBaseProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {
|
|
3
3
|
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
|
|
4
|
-
size?: 'sm' | 'md' | 'lg';
|
|
5
4
|
className?: string;
|
|
6
5
|
/** 다른 요소로 렌더링할 때 (예: render={<a href="/" />}) */
|
|
7
6
|
render?: React.ReactElement;
|
|
7
|
+
/** 진행 중: 스피너 표시, 클릭 막기, 포커스 유지, aria-busy */
|
|
8
|
+
loading?: boolean;
|
|
8
9
|
}
|
|
10
|
+
/** 아이콘만 있는 버튼은 읽을 글자가 없어서 aria-label이 필수예요 */
|
|
11
|
+
export type ButtonProps = ButtonBaseProps & ({
|
|
12
|
+
size?: 'sm' | 'md' | 'lg';
|
|
13
|
+
} | {
|
|
14
|
+
size: 'icon-sm' | 'icon-md' | 'icon-lg';
|
|
15
|
+
'aria-label': string;
|
|
16
|
+
});
|
|
9
17
|
export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
18
|
+
export {};
|
|
@@ -3,9 +3,10 @@ import { cn as e } from "../lib/cn.js";
|
|
|
3
3
|
import * as t from "react";
|
|
4
4
|
import { Button as n } from "@base-ui/react/button";
|
|
5
5
|
import { cva as r } from "class-variance-authority";
|
|
6
|
-
import {
|
|
6
|
+
import { LoaderCircle as i } from "lucide-react";
|
|
7
|
+
import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
7
8
|
//#region src/components/button.tsx
|
|
8
|
-
var
|
|
9
|
+
var c = r("sn:box-border sn:inline-flex sn:items-center sn:justify-center sn:gap-2 sn:whitespace-nowrap sn:rounded-md sn:border sn:border-transparent sn:font-sans sn:cursor-pointer sn:select-none sn:transition-colors sn:duration-(--sn-duration-fast) sn:ease-standard sn:focus-visible:outline-2 sn:focus-visible:outline-offset-2 sn:focus-visible:outline-focus sn:data-disabled:not-data-loading:cursor-not-allowed sn:data-disabled:not-data-loading:opacity-(--sn-opacity-disabled) sn:data-loading:cursor-progress sn:[&_svg]:pointer-events-none sn:[&_svg]:shrink-0", {
|
|
9
10
|
variants: {
|
|
10
11
|
variant: {
|
|
11
12
|
primary: "sn:bg-primary sn:text-on-primary sn:hover:not-data-disabled:bg-primary-hover",
|
|
@@ -14,26 +15,35 @@ var a = r("sn:box-border sn:inline-flex sn:items-center sn:justify-center sn:gap
|
|
|
14
15
|
danger: "sn:bg-danger sn:text-on-danger"
|
|
15
16
|
},
|
|
16
17
|
size: {
|
|
17
|
-
sm: "sn:h-7 sn:px-2 sn:text-label",
|
|
18
|
-
md: "sn:h-8 sn:px-3 sn:text-body-strong",
|
|
19
|
-
lg: "sn:h-10 sn:px-4 sn:text-body-strong"
|
|
18
|
+
sm: "sn:h-7 sn:px-2 sn:text-label sn:[&_svg]:size-4",
|
|
19
|
+
md: "sn:h-8 sn:px-3 sn:text-body-strong sn:[&_svg]:size-4",
|
|
20
|
+
lg: "sn:h-10 sn:px-4 sn:text-body-strong sn:[&_svg]:size-5",
|
|
21
|
+
"icon-sm": "sn:size-7 sn:p-0 sn:[&_svg]:size-4",
|
|
22
|
+
"icon-md": "sn:size-8 sn:p-0 sn:[&_svg]:size-4",
|
|
23
|
+
"icon-lg": "sn:size-10 sn:p-0 sn:[&_svg]:size-5"
|
|
20
24
|
}
|
|
21
25
|
},
|
|
22
26
|
defaultVariants: {
|
|
23
27
|
variant: "primary",
|
|
24
28
|
size: "md"
|
|
25
29
|
}
|
|
26
|
-
}),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
}), l = t.forwardRef(function({ variant: t, size: r, className: l, render: u, loading: d, disabled: f, children: p, ...m }, h) {
|
|
31
|
+
let g = /* @__PURE__ */ o(i, { className: "sn:animate-[sn-spin_var(--sn-duration-loop)_linear_infinite] sn:motion-reduce:animate-none" });
|
|
32
|
+
return /* @__PURE__ */ o(n, {
|
|
33
|
+
ref: h,
|
|
34
|
+
render: u,
|
|
35
|
+
nativeButton: !u || u.type === "button",
|
|
36
|
+
disabled: f || d,
|
|
37
|
+
focusableWhenDisabled: d,
|
|
38
|
+
"aria-busy": d || void 0,
|
|
39
|
+
"data-loading": d ? "" : void 0,
|
|
40
|
+
className: e(c({
|
|
32
41
|
variant: t,
|
|
33
42
|
size: r
|
|
34
|
-
}),
|
|
35
|
-
...
|
|
43
|
+
}), l),
|
|
44
|
+
...m,
|
|
45
|
+
children: d && r?.startsWith("icon-") ? g : d ? /* @__PURE__ */ s(a, { children: [g, p] }) : p
|
|
36
46
|
});
|
|
37
47
|
});
|
|
38
48
|
//#endregion
|
|
39
|
-
export {
|
|
49
|
+
export { l as Button };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
declare const labelClass = "sn:inline-flex sn:items-center sn:gap-2 sn:font-sans sn:text-body sn:text-default sn:cursor-pointer";
|
|
3
|
+
declare const disabledClass = "sn:cursor-not-allowed sn:opacity-(--sn-opacity-disabled)";
|
|
4
|
+
declare const focusClass = "sn:focus-visible:outline-2 sn:focus-visible:outline-offset-2 sn:focus-visible:outline-focus";
|
|
5
|
+
export interface CheckboxProps {
|
|
6
|
+
checked?: boolean;
|
|
7
|
+
defaultChecked?: boolean;
|
|
8
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
9
|
+
/** 일부만 선택된 상태 (그룹의 상위 항목) */
|
|
10
|
+
indeterminate?: boolean;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
/** CheckboxGroup 안에서 쓰는 값 */
|
|
13
|
+
value?: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
className?: string;
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLElement>>;
|
|
19
|
+
export interface CheckboxGroupProps {
|
|
20
|
+
/** 그룹 이름 (fieldset legend) */
|
|
21
|
+
label: React.ReactNode;
|
|
22
|
+
value?: string[];
|
|
23
|
+
defaultValue?: string[];
|
|
24
|
+
onValueChange?: (value: string[]) => void;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
className?: string;
|
|
27
|
+
children: React.ReactNode;
|
|
28
|
+
}
|
|
29
|
+
export declare function CheckboxGroup({ label, value, defaultValue, onValueChange, disabled, className, children }: CheckboxGroupProps): React.JSX.Element;
|
|
30
|
+
export { labelClass as choiceLabelClass, disabledClass as choiceDisabledClass, focusClass as choiceFocusClass };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../lib/cn.js";
|
|
3
|
+
import { boxClass as t } from "./popup-styles.js";
|
|
4
|
+
import * as n from "react";
|
|
5
|
+
import { Check as r, Minus as i } from "lucide-react";
|
|
6
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
|
+
import { Checkbox as s } from "@base-ui/react/checkbox";
|
|
8
|
+
import { CheckboxGroup as c } from "@base-ui/react/checkbox-group";
|
|
9
|
+
import { Fieldset as l } from "@base-ui/react/fieldset";
|
|
10
|
+
//#region src/components/checkbox.tsx
|
|
11
|
+
var u = "sn:inline-flex sn:items-center sn:gap-2 sn:font-sans sn:text-body sn:text-default sn:cursor-pointer", d = "sn:cursor-not-allowed sn:opacity-(--sn-opacity-disabled)", f = "sn:focus-visible:outline-2 sn:focus-visible:outline-offset-2 sn:focus-visible:outline-focus", p = n.forwardRef(function({ checked: n, defaultChecked: c, onCheckedChange: l, indeterminate: d, disabled: p, value: m, name: h, className: g, children: _ }, v) {
|
|
12
|
+
return /* @__PURE__ */ o("label", {
|
|
13
|
+
className: e(u, p && "sn:cursor-not-allowed sn:opacity-(--sn-opacity-disabled)", g),
|
|
14
|
+
children: [/* @__PURE__ */ a(s.Root, {
|
|
15
|
+
ref: v,
|
|
16
|
+
checked: n,
|
|
17
|
+
defaultChecked: c,
|
|
18
|
+
onCheckedChange: l && ((e) => l(e)),
|
|
19
|
+
indeterminate: d,
|
|
20
|
+
disabled: p,
|
|
21
|
+
value: m,
|
|
22
|
+
name: h,
|
|
23
|
+
className: e(t, f, "sn:data-checked:border-transparent sn:data-checked:bg-primary sn:data-indeterminate:border-transparent sn:data-indeterminate:bg-primary"),
|
|
24
|
+
children: /* @__PURE__ */ a(s.Indicator, {
|
|
25
|
+
className: "sn:flex",
|
|
26
|
+
children: a(d ? i : r, {})
|
|
27
|
+
})
|
|
28
|
+
}), _]
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
function m({ label: t, value: n, defaultValue: r, onValueChange: i, disabled: s, className: u, children: d }) {
|
|
32
|
+
return /* @__PURE__ */ o(l.Root, {
|
|
33
|
+
className: e("sn:m-0 sn:flex sn:min-w-0 sn:flex-col sn:gap-3 sn:border-0 sn:p-0 sn:font-sans", u),
|
|
34
|
+
children: [/* @__PURE__ */ a(l.Legend, {
|
|
35
|
+
className: "sn:p-0 sn:text-label sn:text-default",
|
|
36
|
+
children: t
|
|
37
|
+
}), /* @__PURE__ */ a(c, {
|
|
38
|
+
value: n,
|
|
39
|
+
defaultValue: r,
|
|
40
|
+
onValueChange: i && ((e) => i(e)),
|
|
41
|
+
disabled: s,
|
|
42
|
+
className: "sn:flex sn:flex-col sn:gap-2",
|
|
43
|
+
children: d
|
|
44
|
+
})]
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { p as Checkbox, m as CheckboxGroup, d as choiceDisabledClass, f as choiceFocusClass, u as choiceLabelClass };
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
export declare const backdropClass = "sn:fixed sn:inset-0 sn:z-50 sn:bg-overlay sn:transition-opacity sn:duration-(--sn-duration-normal) sn:ease-standard sn:data-starting-style:opacity-0 sn:data-ending-style:opacity-0 sn:motion-reduce:transition-none";
|
|
3
|
+
export declare const dialogPopupClass = "sn:fixed sn:top-1/2 sn:left-1/2 sn:z-50 sn:box-border sn:flex sn:w-110 sn:max-w-[calc(100vw-2*var(--sn-space-4))] sn:-translate-x-1/2 sn:-translate-y-1/2 sn:flex-col sn:gap-4 sn:rounded-lg sn:border sn:border-default sn:bg-surface sn:p-6 sn:font-sans sn:text-body sn:text-default sn:outline-none sn:transition-[opacity,scale] sn:duration-(--sn-duration-normal) sn:ease-standard sn:data-starting-style:scale-98 sn:data-starting-style:opacity-0 sn:data-ending-style:scale-98 sn:data-ending-style:opacity-0 sn:motion-reduce:transition-none";
|
|
4
|
+
export declare const dialogTitleClass = "sn:m-0 sn:text-title sn:text-default";
|
|
5
|
+
export declare const dialogDescriptionClass = "sn:-mt-3 sn:mb-0 sn:text-caption sn:text-muted";
|
|
2
6
|
export interface DialogProps {
|
|
3
7
|
open?: boolean;
|
|
4
8
|
defaultOpen?: boolean;
|
|
@@ -15,8 +19,15 @@ export declare const DialogTrigger: React.ForwardRefExoticComponent<DialogButton
|
|
|
15
19
|
export declare const DialogClose: React.ForwardRefExoticComponent<DialogButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
16
20
|
export interface DialogPopupProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'className'> {
|
|
17
21
|
className?: string;
|
|
22
|
+
/** 열릴 때 포커스할 요소 (기본: 팝업 안 첫 포커스 가능 요소) */
|
|
23
|
+
initialFocus?: React.RefObject<HTMLElement | null>;
|
|
24
|
+
/** 닫힌 뒤 포커스할 요소 (기본: 트리거나 열기 전 포커스 요소). 코드로 열었을 때 지정해요 */
|
|
25
|
+
finalFocus?: React.RefObject<HTMLElement | null>;
|
|
18
26
|
}
|
|
19
27
|
export declare const DialogPopup: React.ForwardRefExoticComponent<DialogPopupProps & React.RefAttributes<HTMLDivElement>>;
|
|
28
|
+
export type TextProps<E extends HTMLElement> = Omit<React.HTMLAttributes<E>, 'className'> & {
|
|
29
|
+
className?: string;
|
|
30
|
+
};
|
|
20
31
|
export declare const DialogTitle: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLHeadingElement>, "className"> & {
|
|
21
32
|
className?: string;
|
|
22
33
|
} & React.RefAttributes<HTMLHeadingElement>>;
|
|
@@ -4,41 +4,44 @@ import * as t from "react";
|
|
|
4
4
|
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
5
|
import { Dialog as i } from "@base-ui/react/dialog";
|
|
6
6
|
//#region src/components/dialog.tsx
|
|
7
|
-
|
|
7
|
+
var a = "sn:fixed sn:inset-0 sn:z-50 sn:bg-overlay sn:transition-opacity sn:duration-(--sn-duration-normal) sn:ease-standard sn:data-starting-style:opacity-0 sn:data-ending-style:opacity-0 sn:motion-reduce:transition-none", o = "sn:fixed sn:top-1/2 sn:left-1/2 sn:z-50 sn:box-border sn:flex sn:w-110 sn:max-w-[calc(100vw-2*var(--sn-space-4))] sn:-translate-x-1/2 sn:-translate-y-1/2 sn:flex-col sn:gap-4 sn:rounded-lg sn:border sn:border-default sn:bg-surface sn:p-6 sn:font-sans sn:text-body sn:text-default sn:outline-none sn:transition-[opacity,scale] sn:duration-(--sn-duration-normal) sn:ease-standard sn:data-starting-style:scale-98 sn:data-starting-style:opacity-0 sn:data-ending-style:scale-98 sn:data-ending-style:opacity-0 sn:motion-reduce:transition-none", s = "sn:m-0 sn:text-title sn:text-default", c = "sn:-mt-3 sn:mb-0 sn:text-caption sn:text-muted";
|
|
8
|
+
function l({ onOpenChange: e, ...t }) {
|
|
8
9
|
return /* @__PURE__ */ n(i.Root, {
|
|
9
10
|
...t,
|
|
10
11
|
onOpenChange: e && ((t) => e(t))
|
|
11
12
|
});
|
|
12
13
|
}
|
|
13
|
-
var
|
|
14
|
+
var u = t.forwardRef(function(e, t) {
|
|
14
15
|
return /* @__PURE__ */ n(i.Trigger, {
|
|
15
16
|
ref: t,
|
|
16
17
|
...e
|
|
17
18
|
});
|
|
18
|
-
}),
|
|
19
|
+
}), d = t.forwardRef(function(e, t) {
|
|
19
20
|
return /* @__PURE__ */ n(i.Close, {
|
|
20
21
|
ref: t,
|
|
21
22
|
...e
|
|
22
23
|
});
|
|
23
|
-
}),
|
|
24
|
-
return /* @__PURE__ */ r(i.Portal, { children: [/* @__PURE__ */ n(i.Backdrop, { className:
|
|
25
|
-
ref:
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
}), f = t.forwardRef(function({ className: t, initialFocus: s, finalFocus: c, ...l }, u) {
|
|
25
|
+
return /* @__PURE__ */ r(i.Portal, { children: [/* @__PURE__ */ n(i.Backdrop, { className: a }), /* @__PURE__ */ n(i.Popup, {
|
|
26
|
+
ref: u,
|
|
27
|
+
initialFocus: s,
|
|
28
|
+
finalFocus: c,
|
|
29
|
+
className: e(o, t),
|
|
30
|
+
...l
|
|
28
31
|
})] });
|
|
29
|
-
}),
|
|
32
|
+
}), p = t.forwardRef(function({ className: t, ...r }, a) {
|
|
30
33
|
return /* @__PURE__ */ n(i.Title, {
|
|
31
34
|
ref: a,
|
|
32
|
-
className: e(
|
|
35
|
+
className: e(s, t),
|
|
33
36
|
...r
|
|
34
37
|
});
|
|
35
|
-
}),
|
|
38
|
+
}), m = t.forwardRef(function({ className: t, ...r }, a) {
|
|
36
39
|
return /* @__PURE__ */ n(i.Description, {
|
|
37
40
|
ref: a,
|
|
38
|
-
className: e(
|
|
41
|
+
className: e(c, t),
|
|
39
42
|
...r
|
|
40
43
|
});
|
|
41
|
-
}),
|
|
44
|
+
}), h = t.forwardRef(function({ className: t, ...r }, i) {
|
|
42
45
|
return /* @__PURE__ */ n("div", {
|
|
43
46
|
ref: i,
|
|
44
47
|
className: e("sn:mt-2 sn:flex sn:justify-end sn:gap-2", t),
|
|
@@ -46,4 +49,4 @@ var o = t.forwardRef(function(e, t) {
|
|
|
46
49
|
});
|
|
47
50
|
});
|
|
48
51
|
//#endregion
|
|
49
|
-
export {
|
|
52
|
+
export { l as Dialog, d as DialogClose, m as DialogDescription, h as DialogFooter, f as DialogPopup, p as DialogTitle, u as DialogTrigger, a as backdropClass, c as dialogDescriptionClass, o as dialogPopupClass, s as dialogTitleClass };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface EmptyStateProps {
|
|
3
|
+
/** lucide 아이콘 (24px로 맞춰져요) */
|
|
4
|
+
icon?: React.ReactNode;
|
|
5
|
+
title: React.ReactNode;
|
|
6
|
+
description?: React.ReactNode;
|
|
7
|
+
/** 다음에 할 행동 하나. 보통 <Button> */
|
|
8
|
+
action?: React.ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function EmptyState({ icon, title, description, action, className }: EmptyStateProps): React.JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { StateLayout as e } from "./state-layout.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/empty-state.tsx
|
|
6
|
+
function n({ icon: n, title: r, description: i, action: a, className: o }) {
|
|
7
|
+
return /* @__PURE__ */ t(e, {
|
|
8
|
+
icon: n,
|
|
9
|
+
iconClassName: "sn:text-muted",
|
|
10
|
+
title: r,
|
|
11
|
+
description: i,
|
|
12
|
+
className: o,
|
|
13
|
+
children: a
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { n as EmptyState };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface ErrorStateProps {
|
|
3
|
+
/** 기본값: triangle-alert */
|
|
4
|
+
icon?: React.ReactNode;
|
|
5
|
+
title: React.ReactNode;
|
|
6
|
+
description?: React.ReactNode;
|
|
7
|
+
/** 있으면 "다시 시도" 버튼을 보여 줘요 */
|
|
8
|
+
onRetry?: () => void;
|
|
9
|
+
retryLabel?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function ErrorState({ icon, title, description, onRetry, retryLabel, className }: ErrorStateProps): React.JSX.Element;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button as e } from "./button.js";
|
|
3
|
+
import { StateLayout as t } from "./state-layout.js";
|
|
4
|
+
import "react";
|
|
5
|
+
import { RefreshCw as n, TriangleAlert as r } from "lucide-react";
|
|
6
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
7
|
+
//#region src/components/error-state.tsx
|
|
8
|
+
function o({ icon: o = /* @__PURE__ */ i(r, {}), title: s, description: c, onRetry: l, retryLabel: u = "다시 시도", className: d }) {
|
|
9
|
+
return /* @__PURE__ */ i(t, {
|
|
10
|
+
role: "alert",
|
|
11
|
+
icon: o,
|
|
12
|
+
iconClassName: "sn:text-danger",
|
|
13
|
+
title: s,
|
|
14
|
+
description: c,
|
|
15
|
+
className: d,
|
|
16
|
+
children: l && /* @__PURE__ */ a(e, {
|
|
17
|
+
variant: "secondary",
|
|
18
|
+
onClick: l,
|
|
19
|
+
children: [/* @__PURE__ */ i(n, {}), u]
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { o as ErrorState };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface FieldProps {
|
|
3
|
+
label: React.ReactNode;
|
|
4
|
+
description?: React.ReactNode;
|
|
5
|
+
/** invalid일 때만 보이고, 그때는 description 자리를 대신해요 */
|
|
6
|
+
error?: React.ReactNode;
|
|
7
|
+
/** 안의 Input에 자동으로 전달돼요. Input에는 invalid를 따로 주지 않아요 */
|
|
8
|
+
invalid?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
className?: string;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export declare const Field: React.ForwardRefExoticComponent<FieldProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../lib/cn.js";
|
|
3
|
+
import * as t from "react";
|
|
4
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
|
+
import { Field as i } from "@base-ui/react/field";
|
|
6
|
+
//#region src/components/field.tsx
|
|
7
|
+
var a = t.forwardRef(function({ label: t, description: a, error: o, invalid: s, disabled: c, className: l, children: u }, d) {
|
|
8
|
+
let f = s && !!o;
|
|
9
|
+
return /* @__PURE__ */ r(i.Root, {
|
|
10
|
+
ref: d,
|
|
11
|
+
invalid: s,
|
|
12
|
+
disabled: c,
|
|
13
|
+
className: e("sn:flex sn:flex-col sn:gap-2 sn:font-sans", l),
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ n(i.Label, {
|
|
16
|
+
className: "sn:text-label sn:text-default",
|
|
17
|
+
children: t
|
|
18
|
+
}),
|
|
19
|
+
u,
|
|
20
|
+
a && !f && /* @__PURE__ */ n(i.Description, {
|
|
21
|
+
className: "sn:m-0 sn:text-caption sn:text-muted",
|
|
22
|
+
children: a
|
|
23
|
+
}),
|
|
24
|
+
f && /* @__PURE__ */ n(i.Error, {
|
|
25
|
+
match: !0,
|
|
26
|
+
className: "sn:m-0 sn:text-caption sn:text-danger",
|
|
27
|
+
children: o
|
|
28
|
+
})
|
|
29
|
+
]
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//#endregion
|
|
33
|
+
export { a as Field };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
export declare const inputClass = "sn:box-border sn:m-0 sn:w-full sn:min-w-0 sn:rounded-md sn:border sn:border-default sn:bg-surface sn:px-3 sn:font-sans sn:text-body sn:text-default sn:placeholder:text-muted sn:transition-colors sn:duration-(--sn-duration-fast) sn:ease-standard sn:hover:not-data-disabled:border-strong sn:focus-visible:outline-2 sn:focus-visible:outline-offset-2 sn:focus-visible:outline-focus sn:aria-invalid:focus-visible:outline-danger sn:data-invalid:focus-visible:outline-danger sn:aria-invalid:border-danger sn:hover:aria-invalid:border-danger sn:data-invalid:border-danger sn:data-disabled:cursor-not-allowed sn:data-disabled:opacity-(--sn-opacity-disabled)";
|
|
2
3
|
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'className' | 'size'> {
|
|
3
4
|
/** 에러 상태. aria-invalid로 전달돼요 */
|
|
4
5
|
invalid?: boolean;
|
package/dist/components/input.js
CHANGED
|
@@ -4,13 +4,13 @@ import * as t from "react";
|
|
|
4
4
|
import { jsx as n } from "react/jsx-runtime";
|
|
5
5
|
import { Input as r } from "@base-ui/react/input";
|
|
6
6
|
//#region src/components/input.tsx
|
|
7
|
-
var i = t.forwardRef(function({ invalid: t, className:
|
|
7
|
+
var i = "sn:box-border sn:m-0 sn:w-full sn:min-w-0 sn:rounded-md sn:border sn:border-default sn:bg-surface sn:px-3 sn:font-sans sn:text-body sn:text-default sn:placeholder:text-muted sn:transition-colors sn:duration-(--sn-duration-fast) sn:ease-standard sn:hover:not-data-disabled:border-strong sn:focus-visible:outline-2 sn:focus-visible:outline-offset-2 sn:focus-visible:outline-focus sn:aria-invalid:focus-visible:outline-danger sn:data-invalid:focus-visible:outline-danger sn:aria-invalid:border-danger sn:hover:aria-invalid:border-danger sn:data-invalid:border-danger sn:data-disabled:cursor-not-allowed sn:data-disabled:opacity-(--sn-opacity-disabled)", a = t.forwardRef(function({ invalid: t, className: a, ...o }, s) {
|
|
8
8
|
return /* @__PURE__ */ n(r, {
|
|
9
|
-
ref:
|
|
9
|
+
ref: s,
|
|
10
10
|
"aria-invalid": t || void 0,
|
|
11
|
-
className: e("sn:
|
|
12
|
-
...
|
|
11
|
+
className: e("sn:h-8", i, a),
|
|
12
|
+
...o
|
|
13
13
|
});
|
|
14
14
|
});
|
|
15
15
|
//#endregion
|
|
16
|
-
export {
|
|
16
|
+
export { a as Input, i as inputClass };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface MenuProps {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
defaultOpen?: boolean;
|
|
5
|
+
onOpenChange?: (open: boolean) => void;
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare function Menu({ onOpenChange, ...props }: MenuProps): React.JSX.Element;
|
|
9
|
+
export interface MenuTriggerProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {
|
|
10
|
+
className?: string;
|
|
11
|
+
/** 보통 sonic-ui Button: render={<Button size="icon-md" variant="ghost" aria-label="더 보기" />} */
|
|
12
|
+
render?: React.ReactElement;
|
|
13
|
+
}
|
|
14
|
+
export declare const MenuTrigger: React.ForwardRefExoticComponent<MenuTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
15
|
+
export interface MenuPopupProps {
|
|
16
|
+
className?: string;
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare const MenuPopup: React.ForwardRefExoticComponent<MenuPopupProps & React.RefAttributes<HTMLDivElement>>;
|
|
20
|
+
export interface MenuItemProps {
|
|
21
|
+
/** danger: 삭제처럼 위험한 동작. 맨 아래, 구분선 뒤에 둬요 */
|
|
22
|
+
tone?: 'default' | 'danger';
|
|
23
|
+
onClick?: () => void;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
/** 고른 뒤 메뉴를 닫을지 (기본 true) */
|
|
26
|
+
closeOnClick?: boolean;
|
|
27
|
+
className?: string;
|
|
28
|
+
children?: React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
export declare const MenuItem: React.ForwardRefExoticComponent<MenuItemProps & React.RefAttributes<HTMLDivElement>>;
|
|
31
|
+
export declare function MenuSeparator({ className }: {
|
|
32
|
+
className?: string;
|
|
33
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../lib/cn.js";
|
|
3
|
+
import { itemClass as t, popupClass as n } from "./popup-styles.js";
|
|
4
|
+
import * as r from "react";
|
|
5
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
6
|
+
import { Menu as a } from "@base-ui/react/menu";
|
|
7
|
+
//#region src/components/menu.tsx
|
|
8
|
+
function o({ onOpenChange: e, ...t }) {
|
|
9
|
+
return /* @__PURE__ */ i(a.Root, {
|
|
10
|
+
...t,
|
|
11
|
+
onOpenChange: e && ((t) => e(t))
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
var s = r.forwardRef(function(e, t) {
|
|
15
|
+
return /* @__PURE__ */ i(a.Trigger, {
|
|
16
|
+
ref: t,
|
|
17
|
+
...e
|
|
18
|
+
});
|
|
19
|
+
}), c = r.forwardRef(function({ className: t, children: r }, o) {
|
|
20
|
+
return /* @__PURE__ */ i(a.Portal, { children: /* @__PURE__ */ i(a.Positioner, {
|
|
21
|
+
sideOffset: 4,
|
|
22
|
+
align: "start",
|
|
23
|
+
className: "sn:z-50 sn:outline-none",
|
|
24
|
+
children: /* @__PURE__ */ i(a.Popup, {
|
|
25
|
+
ref: o,
|
|
26
|
+
className: e(n, "sn:min-w-48", t),
|
|
27
|
+
children: r
|
|
28
|
+
})
|
|
29
|
+
}) });
|
|
30
|
+
}), l = r.forwardRef(function({ tone: n = "default", onClick: r, disabled: o, closeOnClick: s, className: c, children: l }, u) {
|
|
31
|
+
return /* @__PURE__ */ i(a.Item, {
|
|
32
|
+
ref: u,
|
|
33
|
+
onClick: r && (() => r()),
|
|
34
|
+
disabled: o,
|
|
35
|
+
closeOnClick: s,
|
|
36
|
+
className: e(t, n === "danger" ? "sn:text-danger" : "sn:text-default", c),
|
|
37
|
+
children: l
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
function u({ className: t }) {
|
|
41
|
+
return /* @__PURE__ */ i(a.Separator, { className: e("sn:my-1 sn:h-px sn:border-0 sn:bg-(--sn-color-border-default)", t) });
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { o as Menu, l as MenuItem, c as MenuPopup, u as MenuSeparator, s as MenuTrigger };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface PopoverProps {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
defaultOpen?: boolean;
|
|
5
|
+
onOpenChange?: (open: boolean) => void;
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare function Popover({ onOpenChange, ...props }: PopoverProps): React.JSX.Element;
|
|
9
|
+
export interface PopoverButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {
|
|
10
|
+
className?: string;
|
|
11
|
+
render?: React.ReactElement;
|
|
12
|
+
}
|
|
13
|
+
export declare const PopoverTrigger: React.ForwardRefExoticComponent<PopoverButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
14
|
+
export declare const PopoverClose: React.ForwardRefExoticComponent<PopoverButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
15
|
+
export interface PopoverPopupProps {
|
|
16
|
+
side?: 'top' | 'bottom' | 'left' | 'right';
|
|
17
|
+
className?: string;
|
|
18
|
+
children?: React.ReactNode;
|
|
19
|
+
}
|
|
20
|
+
export declare const PopoverPopup: React.ForwardRefExoticComponent<PopoverPopupProps & React.RefAttributes<HTMLDivElement>>;
|
|
21
|
+
export declare const PopoverTitle: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLHeadingElement>, "className"> & {
|
|
22
|
+
className?: string;
|
|
23
|
+
} & React.RefAttributes<HTMLHeadingElement>>;
|
|
24
|
+
export declare const PopoverDescription: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLParagraphElement>, "className"> & {
|
|
25
|
+
className?: string;
|
|
26
|
+
} & React.RefAttributes<HTMLParagraphElement>>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../lib/cn.js";
|
|
3
|
+
import { popupClass as t } from "./popup-styles.js";
|
|
4
|
+
import * as n from "react";
|
|
5
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
6
|
+
import { Popover as i } from "@base-ui/react/popover";
|
|
7
|
+
//#region src/components/popover.tsx
|
|
8
|
+
function a({ onOpenChange: e, ...t }) {
|
|
9
|
+
return /* @__PURE__ */ r(i.Root, {
|
|
10
|
+
...t,
|
|
11
|
+
onOpenChange: e && ((t) => e(t))
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
var o = n.forwardRef(function(e, t) {
|
|
15
|
+
return /* @__PURE__ */ r(i.Trigger, {
|
|
16
|
+
ref: t,
|
|
17
|
+
...e
|
|
18
|
+
});
|
|
19
|
+
}), s = n.forwardRef(function(e, t) {
|
|
20
|
+
return /* @__PURE__ */ r(i.Close, {
|
|
21
|
+
ref: t,
|
|
22
|
+
...e
|
|
23
|
+
});
|
|
24
|
+
}), c = n.forwardRef(function({ side: n = "bottom", className: a, children: o }, s) {
|
|
25
|
+
return /* @__PURE__ */ r(i.Portal, { children: /* @__PURE__ */ r(i.Positioner, {
|
|
26
|
+
side: n,
|
|
27
|
+
sideOffset: 8,
|
|
28
|
+
align: "start",
|
|
29
|
+
className: "sn:z-50 sn:outline-none",
|
|
30
|
+
children: /* @__PURE__ */ r(i.Popup, {
|
|
31
|
+
ref: s,
|
|
32
|
+
className: e(t, "sn:flex sn:w-80 sn:max-w-[calc(100vw-2*var(--sn-space-4))] sn:min-w-0 sn:flex-col sn:gap-3 sn:p-4", a),
|
|
33
|
+
children: o
|
|
34
|
+
})
|
|
35
|
+
}) });
|
|
36
|
+
}), l = n.forwardRef(function({ className: t, ...n }, a) {
|
|
37
|
+
return /* @__PURE__ */ r(i.Title, {
|
|
38
|
+
ref: a,
|
|
39
|
+
className: e("sn:m-0 sn:text-body-strong sn:text-default", t),
|
|
40
|
+
...n
|
|
41
|
+
});
|
|
42
|
+
}), u = n.forwardRef(function({ className: t, ...n }, a) {
|
|
43
|
+
return /* @__PURE__ */ r(i.Description, {
|
|
44
|
+
ref: a,
|
|
45
|
+
className: e("sn:-mt-2 sn:mb-0 sn:text-caption sn:text-muted", t),
|
|
46
|
+
...n
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//#endregion
|
|
50
|
+
export { a as Popover, s as PopoverClose, u as PopoverDescription, c as PopoverPopup, l as PopoverTitle, o as PopoverTrigger };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const popupClass = "sn:box-border sn:min-w-(--anchor-width) sn:max-h-(--available-height) sn:overflow-y-auto sn:origin-(--transform-origin) sn:rounded-lg sn:border sn:border-default sn:bg-surface sn:p-1 sn:font-sans sn:text-body sn:text-default sn:outline-none sn:transition-[opacity,scale] sn:duration-(--sn-duration-normal) sn:ease-standard sn:data-starting-style:scale-98 sn:data-starting-style:opacity-0 sn:data-ending-style:scale-98 sn:data-ending-style:opacity-0 sn:motion-reduce:transition-none";
|
|
2
|
+
export declare const itemClass = "sn:group sn:flex sn:h-8 sn:cursor-default sn:items-center sn:gap-2 sn:rounded-md sn:px-2 sn:outline-none sn:select-none sn:data-highlighted:bg-subtle sn:data-disabled:opacity-(--sn-opacity-disabled) sn:[&_svg]:size-4 sn:[&_svg]:shrink-0";
|
|
3
|
+
export declare const boxClass = "sn:box-border sn:inline-flex sn:size-4 sn:shrink-0 sn:items-center sn:justify-center sn:rounded-sm sn:border sn:border-strong sn:bg-surface sn:text-on-primary sn:[&_svg]:size-3";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/components/popup-styles.ts
|
|
3
|
+
var e = "sn:box-border sn:min-w-(--anchor-width) sn:max-h-(--available-height) sn:overflow-y-auto sn:origin-(--transform-origin) sn:rounded-lg sn:border sn:border-default sn:bg-surface sn:p-1 sn:font-sans sn:text-body sn:text-default sn:outline-none sn:transition-[opacity,scale] sn:duration-(--sn-duration-normal) sn:ease-standard sn:data-starting-style:scale-98 sn:data-starting-style:opacity-0 sn:data-ending-style:scale-98 sn:data-ending-style:opacity-0 sn:motion-reduce:transition-none", t = "sn:group sn:flex sn:h-8 sn:cursor-default sn:items-center sn:gap-2 sn:rounded-md sn:px-2 sn:outline-none sn:select-none sn:data-highlighted:bg-subtle sn:data-disabled:opacity-(--sn-opacity-disabled) sn:[&_svg]:size-4 sn:[&_svg]:shrink-0", n = "sn:box-border sn:inline-flex sn:size-4 sn:shrink-0 sn:items-center sn:justify-center sn:rounded-sm sn:border sn:border-strong sn:bg-surface sn:text-on-primary sn:[&_svg]:size-3";
|
|
4
|
+
//#endregion
|
|
5
|
+
export { n as boxClass, t as itemClass, e as popupClass };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
interface ProgressBaseProps {
|
|
3
|
+
value: number;
|
|
4
|
+
/** 기본 100 */
|
|
5
|
+
max?: number;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
/** 라벨이 없으면 읽을 이름이 없어서 aria-label이 필수예요 */
|
|
9
|
+
export type ProgressProps = ProgressBaseProps & ({
|
|
10
|
+
label: React.ReactNode;
|
|
11
|
+
} | {
|
|
12
|
+
label?: undefined;
|
|
13
|
+
'aria-label': string;
|
|
14
|
+
});
|
|
15
|
+
export declare function Progress({ value, max, className, ...props }: ProgressProps): React.JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../lib/cn.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
5
|
+
import { Progress as r } from "@base-ui/react/progress";
|
|
6
|
+
//#region src/components/progress.tsx
|
|
7
|
+
function i({ value: i, max: a = 100, className: o, ...s }) {
|
|
8
|
+
let c = s.label;
|
|
9
|
+
return /* @__PURE__ */ n(r.Root, {
|
|
10
|
+
value: i,
|
|
11
|
+
max: a,
|
|
12
|
+
"aria-label": "aria-label" in s ? s["aria-label"] : void 0,
|
|
13
|
+
className: e("sn:flex sn:flex-col sn:gap-2 sn:font-sans", o),
|
|
14
|
+
children: [c != null && /* @__PURE__ */ n("div", {
|
|
15
|
+
className: "sn:flex sn:items-center sn:gap-2",
|
|
16
|
+
children: [/* @__PURE__ */ t(r.Label, {
|
|
17
|
+
className: "sn:min-w-0 sn:flex-1 sn:text-label sn:text-default",
|
|
18
|
+
children: c
|
|
19
|
+
}), /* @__PURE__ */ t(r.Value, { className: "sn:font-mono sn:text-caption sn:text-muted" })]
|
|
20
|
+
}), /* @__PURE__ */ t(r.Track, {
|
|
21
|
+
className: "sn:h-1 sn:overflow-hidden sn:rounded-full sn:bg-subtle",
|
|
22
|
+
children: /* @__PURE__ */ t(r.Indicator, { className: "sn:h-full sn:rounded-full sn:bg-primary sn:transition-[width] sn:duration-(--sn-duration-normal) sn:ease-standard sn:motion-reduce:transition-none" })
|
|
23
|
+
})]
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { i as Progress };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface RadioGroupProps {
|
|
3
|
+
/** 그룹 이름 (fieldset legend) */
|
|
4
|
+
label: React.ReactNode;
|
|
5
|
+
value?: string;
|
|
6
|
+
defaultValue?: string;
|
|
7
|
+
onValueChange?: (value: string) => void;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
name?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export declare function RadioGroup({ label, value, defaultValue, onValueChange, disabled, name, className, children }: RadioGroupProps): React.JSX.Element;
|
|
14
|
+
export interface RadioProps {
|
|
15
|
+
value: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
className?: string;
|
|
18
|
+
children?: React.ReactNode;
|
|
19
|
+
}
|
|
20
|
+
export declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLElement>>;
|