@unikit-bridge/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.
@@ -0,0 +1,148 @@
1
+ // RadioGroup — shadcn/ui new-york-v4 radio-group을 UniKit 브리지로 이식.
2
+ // 포팅 판단:
3
+ // - radix RadioGroup(Root/Item/Indicator) 제거 — 선택 상태는 React context로
4
+ // 직접 관리하고, 원본의 data-state=checked 셀렉터 대신 선택 점 조건부 렌더.
5
+ // - CircleIcon(lucide) 제거 — 원본 Indicator(fill-primary, size-2=8px)를
6
+ // 동일 크기의 점 View(bg-primary)로 대체(문자 글리프보다 치수가 정확하다).
7
+ // - RadioGroup 컨테이너는 role="radiogroup"(RN 0.88 표준 역할 — 스크린리더가
8
+ // 라디오 묶음으로 발표)을 지정한다(사이클 30 G4 반영).
9
+ // - 원본 컨테이너 "grid gap-3"에서 grid는 웹 전용이라 제거 — View 기본 flex-col
10
+ // + gap-3으로 세로 배치를 양쪽에서 동일하게 재현.
11
+ // - aria-invalid:* 클래스는 v0.1 API에 invalid 상태가 없어 제외.
12
+ import {
13
+ createContext,
14
+ forwardRef,
15
+ useContext,
16
+ useState,
17
+ } from "react";
18
+ import {
19
+ Pressable,
20
+ View,
21
+ type BridgePressableRef,
22
+ type BridgeViewRef,
23
+ type PressableProps,
24
+ type ViewProps,
25
+ } from "@unikit-bridge/ui/primitives";
26
+
27
+ import { cn } from "../lib/utils";
28
+
29
+ // 그룹 상태 — RadioGroup이 공급하고 RadioGroupItem이 소비.
30
+ type RadioGroupContextValue = {
31
+ /** 현재 선택값(선택 없음 "") */
32
+ value: string;
33
+ /** 그룹 차단이 항목에 전파된다 */
34
+ disabled: boolean;
35
+ /** 항목 눌림 — 항목이 자기 value를 전달해 그룹이 정리한다 */
36
+ onItemPress: (value: string) => void;
37
+ };
38
+
39
+ const RadioGroupContext = createContext<RadioGroupContextValue>({
40
+ value: "",
41
+ disabled: false,
42
+ onItemPress: () => {},
43
+ });
44
+
45
+ export type RadioGroupProps = ViewProps & {
46
+ /** 제어형 선택값 */
47
+ value?: string;
48
+ /** 비제어형 초기 선택값 */
49
+ defaultValue?: string;
50
+ /** 선택 변경 콜백 */
51
+ onValueChange?: (value: string) => void;
52
+ /** 그룹 전체 차단 — 항목에 일괄 전파 */
53
+ disabled?: boolean;
54
+ };
55
+
56
+ const RadioGroup = forwardRef<BridgeViewRef, RadioGroupProps>(
57
+ (
58
+ {
59
+ className,
60
+ value,
61
+ defaultValue = "",
62
+ onValueChange,
63
+ disabled = false,
64
+ children,
65
+ ...props
66
+ },
67
+ ref,
68
+ ) => {
69
+ // 제어/비제어 통합 — 라디오는 항상 단일 선택이라 문자열 state면 충분하다.
70
+ const [uncontrolled, setUncontrolled] = useState(defaultValue);
71
+ const isControlled = value !== undefined;
72
+ const selectedValue = isControlled ? value : uncontrolled;
73
+
74
+ const handleItemPress = (itemValue: string) => {
75
+ if (!isControlled) setUncontrolled(itemValue);
76
+ onValueChange?.(itemValue);
77
+ };
78
+
79
+ return (
80
+ <View
81
+ ref={ref}
82
+ accessibilityRole="radiogroup"
83
+ className={cn("gap-3", className)}
84
+ {...props}
85
+ >
86
+ <RadioGroupContext.Provider
87
+ value={{
88
+ value: selectedValue,
89
+ disabled,
90
+ onItemPress: handleItemPress,
91
+ }}
92
+ >
93
+ {children}
94
+ </RadioGroupContext.Provider>
95
+ </View>
96
+ );
97
+ },
98
+ );
99
+ RadioGroup.displayName = "RadioGroup";
100
+
101
+ // 터치 타깃 44px 보정: 16px 원 → hitSlop = (44 − 16) / 2 = 14px.
102
+ const HIT_SLOP = 14;
103
+
104
+ export type RadioGroupItemProps = Omit<
105
+ PressableProps,
106
+ "onPress" | "aria-checked"
107
+ > & {
108
+ /** 이 항목의 값 — 그룹 value와의 일치 여부가 선택 상태가 된다 */
109
+ value: string;
110
+ };
111
+
112
+ const RadioGroupItem = forwardRef<BridgePressableRef, RadioGroupItemProps>(
113
+ ({ className, value, disabled, hitSlop, ...props }, ref) => {
114
+ const group = useContext(RadioGroupContext);
115
+ const isChecked = group.value === value;
116
+ const isDisabled = disabled || group.disabled;
117
+
118
+ return (
119
+ <Pressable
120
+ ref={ref}
121
+ accessibilityRole="radio"
122
+ aria-checked={isChecked}
123
+ aria-disabled={isDisabled ? true : undefined}
124
+ disabled={isDisabled}
125
+ hitSlop={hitSlop ?? HIT_SLOP}
126
+ onPress={() => group.onItemPress(value)}
127
+ className={cn(
128
+ // 링은 border-input(라이트 1.27:1)이 배경에 묻혀 컨트롤 경계가 안
129
+ // 보이므로 foreground/50(양 모드 ≥3:1, G4)로 조정.
130
+ "flex size-4 shrink-0 flex-row items-center justify-center rounded-full border border-foreground/50 web:shadow-xs web:transition-all web:outline-none web:focus-visible:border-ring web:focus-visible:ring-2 web:focus-visible:ring-ring/50",
131
+ isDisabled &&
132
+ "web:pointer-events-none web:cursor-not-allowed opacity-50",
133
+ className,
134
+ )}
135
+ {...props}
136
+ >
137
+ {/* 선택 점 — 원본 Indicator(fill-primary size-2 = 8px) 대응.
138
+ 선택 시에만 렌더, 항목 테두리는 선택과 무관하게 유지된다. */}
139
+ {isChecked ? (
140
+ <View aria-hidden className="size-2 rounded-full bg-primary" />
141
+ ) : null}
142
+ </Pressable>
143
+ );
144
+ },
145
+ );
146
+ RadioGroupItem.displayName = "RadioGroupItem";
147
+
148
+ export { RadioGroup, RadioGroupItem };
@@ -0,0 +1,50 @@
1
+ // Separator — shadcn/ui new-york-v4 separator 포팅(/tmp/shadcn-ref/src/separator).
2
+ // 포팅 판단:
3
+ // - radix-ui Separator 엔진 제거 — 상호작용이 없는 장식선이므로 Pressable이 아니라
4
+ // View로 이식하고, 원본의 data-orientation 셀렉터(가로 h-px w-full /
5
+ // 세로 h-full w-px)를 orientation prop 조건부 클래스로 전개한다(토큰 유지).
6
+ // - 접근성: BridgeRole "separator" 계약 사용. radix의 decorative 기본값(true)을
7
+ // 따라 장식용이면 role 없이 aria-hidden으로 은닉하고, decorative={false}일 때만
8
+ // role="separator"를 노출한다(원본과 같은 의미 구분).
9
+ import { forwardRef } from "react";
10
+ import {
11
+ View,
12
+ type BridgeViewRef,
13
+ type ViewProps,
14
+ } from "@unikit-bridge/ui/primitives";
15
+ import { cva, type VariantProps } from "class-variance-authority";
16
+
17
+ import { cn } from "../lib/utils";
18
+
19
+ const separatorVariants = cva("shrink-0 bg-border", {
20
+ variants: {
21
+ orientation: {
22
+ horizontal: "h-px w-full",
23
+ vertical: "h-full w-px",
24
+ },
25
+ },
26
+ defaultVariants: {
27
+ orientation: "horizontal",
28
+ },
29
+ });
30
+
31
+ export type SeparatorProps = ViewProps &
32
+ VariantProps<typeof separatorVariants> & {
33
+ /** 장식 구분선(기본값)이면 스크린리더에서 은닉, false면 role 노출 */
34
+ decorative?: boolean;
35
+ };
36
+
37
+ const Separator = forwardRef<BridgeViewRef, SeparatorProps>(
38
+ ({ className, orientation, decorative = true, ...props }, ref) => (
39
+ <View
40
+ ref={ref}
41
+ accessibilityRole={decorative ? undefined : "separator"}
42
+ aria-hidden={decorative ? true : undefined}
43
+ className={cn(separatorVariants({ orientation }), className)}
44
+ {...props}
45
+ />
46
+ ),
47
+ );
48
+ Separator.displayName = "Separator";
49
+
50
+ export { Separator, separatorVariants };
@@ -0,0 +1,36 @@
1
+ // Skeleton — shadcn/ui new-york-v4 skeleton 포팅(/tmp/shadcn-ref/src/skeleton).
2
+ // 포팅 판단:
3
+ // - 원본은 단일 <div className="animate-pulse rounded-md bg-accent"> — 브리지 View
4
+ // 하나로 대응되며 자식 텍스트가 없어 이중 지정 대상도 없다(className 병합만).
5
+ // - animate-pulse는 web: 접두 — uniwind의 keyframes 애니메이션은 미보증이라
6
+ // 네이티브에서는 정적 회색 블록으로 렌더된다(로드맵: 네이티브 펄스 애니메이션).
7
+ import { forwardRef } from "react";
8
+ import {
9
+ View,
10
+ type BridgeViewRef,
11
+ type ViewProps,
12
+ } from "@unikit-bridge/ui/primitives";
13
+ import { cva } from "class-variance-authority";
14
+
15
+ import { cn } from "../lib/utils";
16
+
17
+ // 다크 bg-accent(zinc-800)는 배경 대비 1.34:1로 블록이 거의 안 보인다(G4) —
18
+ // 다크 한정 muted-foreground/60(≥3:1)으로 올린다. 라이트는 감사 통과값 유지.
19
+ const skeletonVariants = cva(
20
+ "rounded-md bg-accent dark:bg-muted-foreground/60 web:animate-pulse",
21
+ );
22
+
23
+ export type SkeletonProps = ViewProps;
24
+
25
+ const Skeleton = forwardRef<BridgeViewRef, SkeletonProps>(
26
+ ({ className, ...props }, ref) => (
27
+ <View
28
+ ref={ref}
29
+ className={cn(skeletonVariants(), className)}
30
+ {...props}
31
+ />
32
+ ),
33
+ );
34
+ Skeleton.displayName = "Skeleton";
35
+
36
+ export { Skeleton, skeletonVariants };
@@ -0,0 +1,128 @@
1
+ // Switch — shadcn/ui new-york-v4 switch를 UniKit 브리지로 이식.
2
+ // 포팅 판단:
3
+ // - radix Switch(Root/Thumb) 제거 — 토글 상태는 React state(제어/비제어)로 관리.
4
+ // - 원본의 data-state·data-size·group-data 셀렉터 전개 — 크기는 cva size
5
+ // 변형(default/sm)으로, 트랙 배경과 썸 위치는 상태 조건부 클래스로.
6
+ // - 썸 이동은 원본의 translate-x 계산값 대신 트랙 justify-start/end +
7
+ // px-0.5(안쪽 2px 여백) — transform·calc 없이 양 플랫폼에서 동일한 레이아웃.
8
+ // 이에 따라 썸 미끄러짐 애니메이션(transition-transform)은 재현 불가해 제거.
9
+ // - 이중 지정 원칙(§0.5): 트랙 배경은 Pressable, 썸 배경은 내부 View에 명시.
10
+ import { forwardRef, useState } from "react";
11
+ import {
12
+ Pressable,
13
+ View,
14
+ type BridgePressableRef,
15
+ type PressableProps,
16
+ } from "@unikit-bridge/ui/primitives";
17
+ import { cva, type VariantProps } from "class-variance-authority";
18
+
19
+ import { cn } from "../lib/utils";
20
+
21
+ // 트랙(Pressable) — 원본 크기 토큰: default 18.4px(h-4.5 근사)·w-8, sm h-3.5·w-6.
22
+ const switchTrackVariants = cva(
23
+ "flex shrink-0 flex-row items-center rounded-full border border-transparent px-0.5 web:shadow-xs web:transition-all web:outline-none web:focus-visible:border-ring web:focus-visible:ring-2 web:focus-visible:ring-ring/50",
24
+ {
25
+ variants: {
26
+ size: {
27
+ default: "h-4.5 w-8",
28
+ sm: "h-3.5 w-6",
29
+ },
30
+ },
31
+ defaultVariants: {
32
+ size: "default",
33
+ },
34
+ },
35
+ );
36
+
37
+ // 썸(View) — 원본의 size=default→size-4 · sm→size-3 대응.
38
+ const switchThumbVariants = cva("rounded-full", {
39
+ variants: {
40
+ size: {
41
+ default: "size-4",
42
+ sm: "size-3",
43
+ },
44
+ },
45
+ defaultVariants: {
46
+ size: "default",
47
+ },
48
+ });
49
+
50
+ export type SwitchProps = Omit<PressableProps, "onPress" | "aria-checked"> &
51
+ VariantProps<typeof switchTrackVariants> & {
52
+ /** 제어형 토글 상태(지정 시 내부 state를 대체) */
53
+ checked?: boolean;
54
+ /** 비제어형 초기 토글 상태 */
55
+ defaultChecked?: boolean;
56
+ /** 토글 전환 콜백 */
57
+ onCheckedChange?: (checked: boolean) => void;
58
+ };
59
+
60
+ // 터치 타깃 44px 보정: default 트랙 18.4px → 13px, sm 14px → 15px.
61
+ const HIT_SLOP = { default: 13, sm: 15 } as const;
62
+
63
+ const Switch = forwardRef<BridgePressableRef, SwitchProps>(
64
+ (
65
+ {
66
+ className,
67
+ checked,
68
+ defaultChecked = false,
69
+ onCheckedChange,
70
+ disabled,
71
+ size,
72
+ hitSlop,
73
+ ...props
74
+ },
75
+ ref,
76
+ ) => {
77
+ // 제어/비제어 통합 — 자식 없음(원본과 동일하게 트랙+썸만 렌더).
78
+ const [uncontrolled, setUncontrolled] = useState(defaultChecked);
79
+ const isControlled = checked !== undefined;
80
+ const isChecked = isControlled ? checked : uncontrolled;
81
+ const resolvedSize = size ?? "default";
82
+
83
+ const handlePress = () => {
84
+ const next = !isChecked;
85
+ if (!isControlled) setUncontrolled(next);
86
+ onCheckedChange?.(next);
87
+ };
88
+
89
+ return (
90
+ <Pressable
91
+ ref={ref}
92
+ accessibilityRole="switch"
93
+ aria-checked={isChecked}
94
+ aria-disabled={disabled ? true : undefined}
95
+ disabled={disabled}
96
+ hitSlop={hitSlop ?? HIT_SLOP[resolvedSize]}
97
+ onPress={handlePress}
98
+ className={cn(
99
+ switchTrackVariants({ size }),
100
+ // 원본 상태 셀렉터(checked→bg-primary / unchecked→bg-input) 전개 —
101
+ // 썸 이동도 같은 조건의 justify-start/end로 표현.
102
+ // 꺼짐 트랙은 bg-input(라이트 1.27:1·다크 1.2:1)이 배경에 묻혀
103
+ // "꺼짐" 상태를 오독시켜 foreground/50(양 모드 ≥3:1, G4)로 조정.
104
+ isChecked
105
+ ? "justify-end bg-primary"
106
+ : "justify-start bg-foreground/50",
107
+ disabled && "web:pointer-events-none web:cursor-not-allowed opacity-50",
108
+ className,
109
+ )}
110
+ {...props}
111
+ >
112
+ {/* 썸 — 장식 요소(aria-hidden). 다크 모드 썸 색은 상태별로 다르다(원본 준수). */}
113
+ <View
114
+ aria-hidden
115
+ className={cn(
116
+ switchThumbVariants({ size }),
117
+ isChecked
118
+ ? "bg-background dark:bg-primary-foreground"
119
+ : "bg-background dark:bg-foreground",
120
+ )}
121
+ />
122
+ </Pressable>
123
+ );
124
+ },
125
+ );
126
+ Switch.displayName = "Switch";
127
+
128
+ export { Switch, switchTrackVariants, switchThumbVariants };
@@ -0,0 +1,193 @@
1
+ // Table — shadcn/ui new-york-v4 table 포팅(/tmp/shadcn-ref/src/table). 8종 export.
2
+ // 포팅 판단:
3
+ // - 원본은 <table>/<thead>/<tr>/<th> 등 표 요소 + 자손 셀렉터([&_tr]:border-b,
4
+ // [&_tr:last-child]:border-0, has-aria-expanded:...)로 스타일링한다. 브리지에는
5
+ // 표 요소가 없으므로 전부 View(div)로 이식하되 시각 토큰(테두리·배경·여백·높이)은
6
+ // 유지하고, 행/셀 배치는 flex(행=flex-row, 셀=flex-1 균등 폭)로 재구성했다.
7
+ // 셀 폭 균등(flex-1)은 원본 table 자동 배치와 다르다 — 사용처에서 셀 className으로
8
+ // 조절한다.
9
+ // - BridgeRole에 table/row/cell/columnheader가 없어 role 지정은 미지원.
10
+ // 제목셀(TableHead)은 시각(굵기·높이)으로만 구분한다. 스크린리더에 표 의미를
11
+ // 전달하지 못하는 한계는 로드맵 항목으로 기록한다.
12
+ // - 셀(TableHead·TableCell)의 children은 문자열을 권장한다 — 내부 Text가 색·
13
+ // 타이포를 담당한다(이중 지정). 사용자 정의 콘텐츠는 직접 Text를 넣어야 한다.
14
+ // - 자손 셀렉터 미지원으로 소실되는 원본 토큰: TableHeader의 [&_tr]:border-b는
15
+ // TableRow 자체 border-b로 흡수, TableBody의 마지막 행 보더 제거(:last-child)와
16
+ // TableRow의 data-state=selected·has-aria-expanded 배경은 미지원.
17
+ // whitespace-nowrap·overflow-x-auto·transition·hover는 web: 접두.
18
+ // caption-bottom은 flex-col DOM 순서 배치로 대체(캡션을 마지막에 넣으면 하단).
19
+ import { createContext, forwardRef, useContext } from "react";
20
+ import {
21
+ Text,
22
+ View,
23
+ type BridgeViewRef,
24
+ type ViewProps,
25
+ } from "@unikit-bridge/ui/primitives";
26
+ import { cva } from "class-variance-authority";
27
+
28
+ import { cn } from "../lib/utils";
29
+
30
+ // 가로 스크롤 컨테이너(원본 table-container div)
31
+ // 표 구역 context — 푸터 여부를 셀 Text로 전달한다(alert.tsx의 variant context
32
+ // 와 동일 패턴). 컨테이너 font-medium은 웹에서만 텍스트로 상속되고 네이티브에서는
33
+ // 무시되는 비대칭이라 이중 지정 원칙대로 내부 Text에 내린다(사소 4).
34
+ const TableSectionContext = createContext<"body" | "footer">("body");
35
+
36
+ const tableContainerVariants = cva("relative w-full web:overflow-x-auto");
37
+ // 표 본체 — 행이 쌓이는 열(원본 <table>의 w-full)
38
+ const tableVariants = cva("w-full flex-col");
39
+ const tableHeaderVariants = cva("flex-col");
40
+ const tableBodyVariants = cva("flex-col");
41
+ const tableFooterVariants = cva("flex-col border-t bg-muted/50");
42
+ const tableRowVariants = cva(
43
+ "flex-row border-b web:transition-colors web:hover:bg-muted/50",
44
+ );
45
+ const tableHeadVariants = cva("h-10 flex-1 items-center px-2 text-left");
46
+ const tableHeadTextVariants = cva(
47
+ "font-sans text-sm font-medium text-foreground web:whitespace-nowrap",
48
+ );
49
+ const tableCellVariants = cva("flex-1 items-center p-2 text-left");
50
+ const tableCellTextVariants = cva(
51
+ "font-sans text-sm text-foreground web:whitespace-nowrap",
52
+ );
53
+ const tableCaptionVariants = cva("w-full mt-4");
54
+ const tableCaptionTextVariants = cva("font-sans text-sm text-muted-foreground");
55
+
56
+ export type TableProps = ViewProps;
57
+ export type TableHeaderProps = ViewProps;
58
+ export type TableBodyProps = ViewProps;
59
+ export type TableFooterProps = ViewProps;
60
+ export type TableRowProps = ViewProps;
61
+ export type TableHeadProps = ViewProps;
62
+ export type TableCellProps = ViewProps;
63
+ export type TableCaptionProps = ViewProps;
64
+
65
+ // 원본과 같이 ref·className·props는 컨테이너가 아니라 표 본체(원본 <table>)에.
66
+ const Table = forwardRef<BridgeViewRef, TableProps>(
67
+ ({ className, ...props }, ref) => (
68
+ <View className={cn(tableContainerVariants())}>
69
+ <View
70
+ ref={ref}
71
+ className={cn(tableVariants(), className)}
72
+ {...props}
73
+ />
74
+ </View>
75
+ ),
76
+ );
77
+ Table.displayName = "Table";
78
+
79
+ const TableHeader = forwardRef<BridgeViewRef, TableHeaderProps>(
80
+ ({ className, ...props }, ref) => (
81
+ <View
82
+ ref={ref}
83
+ className={cn(tableHeaderVariants(), className)}
84
+ {...props}
85
+ />
86
+ ),
87
+ );
88
+ TableHeader.displayName = "TableHeader";
89
+
90
+ const TableBody = forwardRef<BridgeViewRef, TableBodyProps>(
91
+ ({ className, ...props }, ref) => (
92
+ <View
93
+ ref={ref}
94
+ className={cn(tableBodyVariants(), className)}
95
+ {...props}
96
+ />
97
+ ),
98
+ );
99
+ TableBody.displayName = "TableBody";
100
+
101
+ const TableFooter = forwardRef<BridgeViewRef, TableFooterProps>(
102
+ ({ className, children, ...props }, ref) => (
103
+ <TableSectionContext.Provider value="footer">
104
+ <View
105
+ ref={ref}
106
+ className={cn(tableFooterVariants(), className)}
107
+ {...props}
108
+ >
109
+ {children}
110
+ </View>
111
+ </TableSectionContext.Provider>
112
+ ),
113
+ );
114
+ TableFooter.displayName = "TableFooter";
115
+
116
+ const TableRow = forwardRef<BridgeViewRef, TableRowProps>(
117
+ ({ className, ...props }, ref) => (
118
+ <View
119
+ ref={ref}
120
+ className={cn(tableRowVariants(), className)}
121
+ {...props}
122
+ />
123
+ ),
124
+ );
125
+ TableRow.displayName = "TableRow";
126
+
127
+ const TableHead = forwardRef<BridgeViewRef, TableHeadProps>(
128
+ ({ className, children, ...props }, ref) => (
129
+ <View
130
+ ref={ref}
131
+ className={cn(tableHeadVariants(), className)}
132
+ {...props}
133
+ >
134
+ <Text className={cn(tableHeadTextVariants())}>{children}</Text>
135
+ </View>
136
+ ),
137
+ );
138
+ TableHead.displayName = "TableHead";
139
+
140
+ const TableCell = forwardRef<BridgeViewRef, TableCellProps>(
141
+ ({ className, children, ...props }, ref) => {
142
+ // 푸터 안 셀은 굵게 — 원본 font-medium 상속을 이중 지정으로 재현(사소 4).
143
+ const inFooter = useContext(TableSectionContext) === "footer";
144
+ return (
145
+ <View
146
+ ref={ref}
147
+ className={cn(tableCellVariants(), className)}
148
+ {...props}
149
+ >
150
+ <Text className={cn(tableCellTextVariants(), inFooter && "font-medium")}>
151
+ {children}
152
+ </Text>
153
+ </View>
154
+ );
155
+ },
156
+ );
157
+ TableCell.displayName = "TableCell";
158
+
159
+ const TableCaption = forwardRef<BridgeViewRef, TableCaptionProps>(
160
+ ({ className, children, ...props }, ref) => (
161
+ <View
162
+ ref={ref}
163
+ className={cn(tableCaptionVariants(), className)}
164
+ {...props}
165
+ >
166
+ <Text className={cn(tableCaptionTextVariants())}>{children}</Text>
167
+ </View>
168
+ ),
169
+ );
170
+ TableCaption.displayName = "TableCaption";
171
+
172
+ export {
173
+ Table,
174
+ TableHeader,
175
+ TableBody,
176
+ TableFooter,
177
+ TableRow,
178
+ TableHead,
179
+ TableCell,
180
+ TableCaption,
181
+ tableContainerVariants,
182
+ tableVariants,
183
+ tableHeaderVariants,
184
+ tableBodyVariants,
185
+ tableFooterVariants,
186
+ tableRowVariants,
187
+ tableHeadVariants,
188
+ tableHeadTextVariants,
189
+ tableCellVariants,
190
+ tableCellTextVariants,
191
+ tableCaptionVariants,
192
+ tableCaptionTextVariants,
193
+ };