sh-ui-cli 0.52.0 → 0.52.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/data/changelog/versions.json +25 -0
  2. package/data/registry/react/components/_smoke/vanilla-extract.test.ts +33 -0
  3. package/data/registry/react/components/input/styles.css.ts +6 -6
  4. package/data/registry/react/registry.json +35 -852
  5. package/package.json +2 -2
  6. package/src/api.d.ts +3 -4
  7. package/src/constants.js +9 -5
  8. package/src/create/plugins/pluginSchema.js +5 -3
  9. package/src/mcp.mjs +4 -3
  10. package/data/registry/react/components/accordion/index.vanilla-extract.tsx +0 -97
  11. package/data/registry/react/components/accordion/styles.css.ts +0 -131
  12. package/data/registry/react/components/avatar/index.vanilla-extract.tsx +0 -73
  13. package/data/registry/react/components/avatar/styles.css.ts +0 -68
  14. package/data/registry/react/components/badge/index.vanilla-extract.tsx +0 -40
  15. package/data/registry/react/components/badge/styles.css.ts +0 -71
  16. package/data/registry/react/components/breadcrumb/index.vanilla-extract.tsx +0 -152
  17. package/data/registry/react/components/breadcrumb/styles.css.ts +0 -95
  18. package/data/registry/react/components/calendar/index.vanilla-extract.tsx +0 -806
  19. package/data/registry/react/components/calendar/styles.css.ts +0 -250
  20. package/data/registry/react/components/carousel/index.vanilla-extract.tsx +0 -430
  21. package/data/registry/react/components/carousel/styles.css.ts +0 -169
  22. package/data/registry/react/components/checkbox/index.vanilla-extract.tsx +0 -96
  23. package/data/registry/react/components/checkbox/styles.css.ts +0 -74
  24. package/data/registry/react/components/code-editor/index.vanilla-extract.tsx +0 -230
  25. package/data/registry/react/components/code-editor/styles.css.ts +0 -97
  26. package/data/registry/react/components/code-panel/index.vanilla-extract.tsx +0 -191
  27. package/data/registry/react/components/code-panel/styles.css.ts +0 -151
  28. package/data/registry/react/components/color-picker/index.vanilla-extract.tsx +0 -467
  29. package/data/registry/react/components/color-picker/styles.css.ts +0 -169
  30. package/data/registry/react/components/combobox/index.vanilla-extract.tsx +0 -165
  31. package/data/registry/react/components/combobox/styles.css.ts +0 -174
  32. package/data/registry/react/components/context-menu/index.vanilla-extract.tsx +0 -251
  33. package/data/registry/react/components/context-menu/styles.css.ts +0 -167
  34. package/data/registry/react/components/date-picker/index.vanilla-extract.tsx +0 -520
  35. package/data/registry/react/components/date-picker/styles.css.ts +0 -111
  36. package/data/registry/react/components/dialog/index.vanilla-extract.tsx +0 -95
  37. package/data/registry/react/components/dialog/styles.css.ts +0 -140
  38. package/data/registry/react/components/dropdown-menu/index.vanilla-extract.tsx +0 -255
  39. package/data/registry/react/components/dropdown-menu/styles.css.ts +0 -175
  40. package/data/registry/react/components/file-upload/index.vanilla-extract.tsx +0 -487
  41. package/data/registry/react/components/file-upload/styles.css.ts +0 -193
  42. package/data/registry/react/components/form/index.vanilla-extract.tsx +0 -61
  43. package/data/registry/react/components/form/styles.css.ts +0 -56
  44. package/data/registry/react/components/header/index.vanilla-extract.tsx +0 -805
  45. package/data/registry/react/components/header/styles.css.ts +0 -413
  46. package/data/registry/react/components/label/index.vanilla-extract.tsx +0 -52
  47. package/data/registry/react/components/label/styles.css.ts +0 -141
  48. package/data/registry/react/components/markdown-editor/index.vanilla-extract.tsx +0 -119
  49. package/data/registry/react/components/markdown-editor/styles.css.ts +0 -231
  50. package/data/registry/react/components/menubar/index.vanilla-extract.tsx +0 -32
  51. package/data/registry/react/components/menubar/styles.css.ts +0 -53
  52. package/data/registry/react/components/numeric-input/index.vanilla-extract.tsx +0 -148
  53. package/data/registry/react/components/numeric-input/styles.css.ts +0 -65
  54. package/data/registry/react/components/page-toc/index.vanilla-extract.tsx +0 -174
  55. package/data/registry/react/components/page-toc/styles.css.ts +0 -97
  56. package/data/registry/react/components/pagination/index.vanilla-extract.tsx +0 -269
  57. package/data/registry/react/components/pagination/styles.css.ts +0 -113
  58. package/data/registry/react/components/popover/index.vanilla-extract.tsx +0 -113
  59. package/data/registry/react/components/popover/styles.css.ts +0 -78
  60. package/data/registry/react/components/progress/index.vanilla-extract.tsx +0 -54
  61. package/data/registry/react/components/progress/styles.css.ts +0 -53
  62. package/data/registry/react/components/radio/index.vanilla-extract.tsx +0 -65
  63. package/data/registry/react/components/radio/styles.css.ts +0 -79
  64. package/data/registry/react/components/rich-text-editor/index.vanilla-extract.tsx +0 -348
  65. package/data/registry/react/components/rich-text-editor/styles.css.ts +0 -243
  66. package/data/registry/react/components/select/index.vanilla-extract.tsx +0 -234
  67. package/data/registry/react/components/select/styles.css.ts +0 -225
  68. package/data/registry/react/components/separator/index.vanilla-extract.tsx +0 -46
  69. package/data/registry/react/components/separator/styles.css.ts +0 -24
  70. package/data/registry/react/components/sidebar/index.vanilla-extract.tsx +0 -1067
  71. package/data/registry/react/components/sidebar/styles.css.ts +0 -578
  72. package/data/registry/react/components/skeleton/index.vanilla-extract.tsx +0 -22
  73. package/data/registry/react/components/skeleton/styles.css.ts +0 -30
  74. package/data/registry/react/components/slider/index.vanilla-extract.tsx +0 -298
  75. package/data/registry/react/components/slider/styles.css.ts +0 -75
  76. package/data/registry/react/components/spinner/index.vanilla-extract.tsx +0 -38
  77. package/data/registry/react/components/spinner/styles.css.ts +0 -60
  78. package/data/registry/react/components/switch/index.vanilla-extract.tsx +0 -39
  79. package/data/registry/react/components/switch/styles.css.ts +0 -87
  80. package/data/registry/react/components/tabs/index.vanilla-extract.tsx +0 -91
  81. package/data/registry/react/components/tabs/styles.css.ts +0 -145
  82. package/data/registry/react/components/textarea/index.vanilla-extract.tsx +0 -23
  83. package/data/registry/react/components/textarea/styles.css.ts +0 -55
  84. package/data/registry/react/components/toast/index.vanilla-extract.tsx +0 -258
  85. package/data/registry/react/components/toast/styles.css.ts +0 -307
  86. package/data/registry/react/components/toggle/index.vanilla-extract.tsx +0 -131
  87. package/data/registry/react/components/toggle/styles.css.ts +0 -109
  88. package/data/registry/react/components/tooltip/index.vanilla-extract.tsx +0 -83
  89. package/data/registry/react/components/tooltip/styles.css.ts +0 -59
@@ -1,234 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { Select as BaseSelect } from "@base-ui/react/select";
5
- import { byKey, select__trigger, select__value, select__placeholder, select__icon, select__positioner, select__content, select__label, select__item, selectItemText, select__indicator, select__separator, select__chips, select__chip, selectChipRemove } from "./styles.css";
6
-
7
-
8
- import { cn } from "@SH_UI_UTILS@";
9
- export const Select = BaseSelect.Root;
10
-
11
- /** shadcn 호환: <SelectValue placeholder="..." /> */
12
- export function SelectValue({
13
- placeholder,
14
- className,
15
- ...props
16
- }: { placeholder?: string; className?: string } & Omit<
17
- React.ComponentPropsWithoutRef<typeof BaseSelect.Value>,
18
- "children"
19
- >) {
20
- return (
21
- <BaseSelect.Value className={cn(select__value, className)} {...props}>
22
- {(value) =>
23
- value !== null && value !== undefined && value !== "" ? (
24
- (value as React.ReactNode)
25
- ) : (
26
- <span className={select__placeholder}>{placeholder}</span>
27
- )
28
- }
29
- </BaseSelect.Value>
30
- );
31
- }
32
-
33
- export const SelectTrigger = React.forwardRef<
34
- HTMLButtonElement,
35
- Omit<React.ComponentPropsWithoutRef<typeof BaseSelect.Trigger>, "className"> & { className?: string }
36
- >(({ className, children, ...props }, ref) => (
37
- <BaseSelect.Trigger
38
- ref={ref}
39
- className={cn(select__trigger, className)}
40
- {...props}
41
- >
42
- {children}
43
- <BaseSelect.Icon className={select__icon} aria-hidden>
44
- <svg viewBox="0 0 16 16" width="14" height="14" fill="none">
45
- <path
46
- d="M4 6l4 4 4-4"
47
- stroke="currentColor"
48
- strokeWidth="1.5"
49
- strokeLinecap="round"
50
- strokeLinejoin="round"
51
- />
52
- </svg>
53
- </BaseSelect.Icon>
54
- </BaseSelect.Trigger>
55
- ));
56
- SelectTrigger.displayName = "SelectTrigger";
57
-
58
- /** Portal + Positioner + Popup을 한 번에.
59
- * container: portal이 마운트될 DOM 노드. 기본 body. 토큰 스코프 안에 띄우려면 해당 컨테이너 ref 전달. */
60
- export const SelectContent = React.forwardRef<
61
- HTMLDivElement,
62
- Omit<React.ComponentPropsWithoutRef<typeof BaseSelect.Popup>, "className"> & {
63
- className?: string;
64
- container?: React.ComponentPropsWithoutRef<typeof BaseSelect.Portal>["container"];
65
- }
66
- >(({ className, children, container, ...props }, ref) => (
67
- <BaseSelect.Portal container={container}>
68
- <BaseSelect.Positioner
69
- className={select__positioner}
70
- sideOffset={4}
71
- align="start"
72
- >
73
- <BaseSelect.Popup
74
- ref={ref}
75
- className={cn(select__content, className)}
76
- {...props}
77
- >
78
- {children}
79
- </BaseSelect.Popup>
80
- </BaseSelect.Positioner>
81
- </BaseSelect.Portal>
82
- ));
83
- SelectContent.displayName = "SelectContent";
84
-
85
- export const SelectGroup = BaseSelect.Group;
86
-
87
- export const SelectLabel = React.forwardRef<
88
- HTMLDivElement,
89
- Omit<React.ComponentPropsWithoutRef<typeof BaseSelect.GroupLabel>, "className"> & { className?: string }
90
- >(({ className, ...props }, ref) => (
91
- <BaseSelect.GroupLabel
92
- ref={ref}
93
- className={cn(select__label, className)}
94
- {...props}
95
- />
96
- ));
97
- SelectLabel.displayName = "SelectLabel";
98
-
99
- export const SelectItem = React.forwardRef<
100
- HTMLDivElement,
101
- Omit<React.ComponentPropsWithoutRef<typeof BaseSelect.Item>, "className"> & { className?: string }
102
- >(({ className, children, ...props }, ref) => (
103
- <BaseSelect.Item
104
- ref={ref}
105
- className={cn(select__item, className)}
106
- {...props}
107
- >
108
- <BaseSelect.ItemIndicator className={select__indicator} aria-hidden>
109
- <svg viewBox="0 0 16 16" width="14" height="14" fill="none">
110
- <path
111
- d="M3.5 8.5l3 3 6-7"
112
- stroke="currentColor"
113
- strokeWidth="1.75"
114
- strokeLinecap="round"
115
- strokeLinejoin="round"
116
- />
117
- </svg>
118
- </BaseSelect.ItemIndicator>
119
- <BaseSelect.ItemText className={selectItemText}>
120
- {children}
121
- </BaseSelect.ItemText>
122
- </BaseSelect.Item>
123
- ));
124
- SelectItem.displayName = "SelectItem";
125
-
126
- export const SelectSeparator = React.forwardRef<
127
- HTMLDivElement,
128
- Omit<React.ComponentPropsWithoutRef<typeof BaseSelect.Separator>, "className"> & { className?: string }
129
- >(({ className, ...props }, ref) => (
130
- <BaseSelect.Separator
131
- ref={ref}
132
- className={cn(select__separator, className)}
133
- {...props}
134
- />
135
- ));
136
- SelectSeparator.displayName = "SelectSeparator";
137
-
138
- /* ───────── Multi-select ─────────
139
- *
140
- * Base UI Select의 `multiple` 모드를 얇게 래핑한 것.
141
- * Trigger/Content/Item/Group/Label/Separator는 그대로 재사용한다.
142
- */
143
-
144
- type BaseRootProps = React.ComponentPropsWithoutRef<typeof BaseSelect.Root>;
145
-
146
- /** 칩 X 버튼 등에서 개별 항목을 제거할 수 있도록 MultiSelect 내부 상태를 expose한다. */
147
- type MultiSelectCtx = {
148
- values: string[];
149
- remove: (value: string) => void;
150
- clear: () => void;
151
- };
152
- const MultiSelectContext = React.createContext<MultiSelectCtx | null>(null);
153
- export const useMultiSelect = () => {
154
- const ctx = React.useContext(MultiSelectContext);
155
- if (!ctx) throw new Error("useMultiSelect는 MultiSelect 하위에서만 사용할 수 있습니다.");
156
- return ctx;
157
- };
158
-
159
- export const MultiSelect = React.forwardRef<
160
- HTMLDivElement,
161
- Omit<BaseRootProps, "multiple" | "value" | "defaultValue" | "onValueChange"> & {
162
- value?: string[];
163
- defaultValue?: string[];
164
- onValueChange?: (value: string[]) => void;
165
- }
166
- >(({ value: valueProp, defaultValue, onValueChange, children, ...props }, _ref) => {
167
- const isControlled = valueProp !== undefined;
168
- const [internal, setInternal] = React.useState<string[]>(defaultValue ?? []);
169
- const values = isControlled ? valueProp! : internal;
170
-
171
- const commit = React.useCallback(
172
- (next: string[]) => {
173
- if (!isControlled) setInternal(next);
174
- onValueChange?.(next);
175
- },
176
- [isControlled, onValueChange],
177
- );
178
-
179
- const ctx = React.useMemo<MultiSelectCtx>(
180
- () => ({
181
- values,
182
- remove: (v) => commit(values.filter((x) => x !== v)),
183
- clear: () => commit([]),
184
- }),
185
- [values, commit],
186
- );
187
-
188
- return (
189
- <MultiSelectContext.Provider value={ctx}>
190
- <BaseSelect.Root multiple value={values} onValueChange={commit} {...props}>
191
- {children}
192
- </BaseSelect.Root>
193
- </MultiSelectContext.Provider>
194
- );
195
- });
196
- MultiSelect.displayName = "MultiSelect";
197
-
198
- /**
199
- * 다중 선택 값 표시. 배열이 비면 placeholder, 있으면 join 또는 사용자 정의 renderer.
200
- *
201
- * <MultiSelectValue placeholder="과일" /> // "Apple, Banana"
202
- * <MultiSelectValue placeholder="과일" render={(arr) => ...} /> // 커스텀 (칩 등)
203
- */
204
- export function MultiSelectValue({
205
- placeholder,
206
- render,
207
- separator = ", ",
208
- className,
209
- ...props
210
- }: {
211
- placeholder?: string;
212
- render?: (
213
- values: string[],
214
- handlers: { remove: (value: string) => void; clear: () => void },
215
- ) => React.ReactNode;
216
- separator?: string;
217
- className?: string;
218
- } & Omit<
219
- React.ComponentPropsWithoutRef<typeof BaseSelect.Value>,
220
- "children" | "render"
221
- >) {
222
- const { remove, clear } = useMultiSelect();
223
- return (
224
- <BaseSelect.Value className={cn(select__value, className)} {...props}>
225
- {(value) => {
226
- const arr = Array.isArray(value) ? (value as string[]) : [];
227
- if (arr.length === 0) {
228
- return <span className={select__placeholder}>{placeholder}</span>;
229
- }
230
- return render ? render(arr, { remove, clear }) : arr.join(separator);
231
- }}
232
- </BaseSelect.Value>
233
- );
234
- }
@@ -1,225 +0,0 @@
1
- import { style, keyframes } from "@vanilla-extract/css";
2
-
3
- export const shUiSelectIn = keyframes({
4
- "from": {
5
- opacity: 0,
6
- transform: "scale(0.96)",
7
- },
8
- "to": {
9
- opacity: 1,
10
- transform: "scale(1)",
11
- },
12
- });
13
-
14
- export const shUiSelectOut = keyframes({
15
- "from": {
16
- opacity: 1,
17
- transform: "scale(1)",
18
- },
19
- "to": {
20
- opacity: 0,
21
- transform: "scale(0.96)",
22
- },
23
- });
24
-
25
- export const select__trigger = style({
26
- display: "inline-flex",
27
- alignItems: "center",
28
- justifyContent: "space-between",
29
- gap: "var(--space-2)",
30
- minWidth: "10rem",
31
- height: "var(--control-md)",
32
- padding: "0 var(--space-3)",
33
- background: "var(--background)",
34
- color: "var(--foreground)",
35
- border: "1px solid var(--border)",
36
- borderRadius: "var(--radius)",
37
- fontSize: "var(--text-sm)",
38
- lineHeight: 1,
39
- cursor: "pointer",
40
- transition: "border-color var(--duration-fast), background-color var(--duration-fast)",
41
- userSelect: "none",
42
- WebkitTapHighlightColor: "transparent",
43
- selectors: {
44
- "&:hover:not(:disabled)": {
45
- borderColor: "var(--border-strong)",
46
- },
47
- "&:focus-visible": {
48
- outline: "var(--border-width-strong) solid var(--foreground)",
49
- outlineOffset: "2px",
50
- },
51
- "&[data-popup-open]": {
52
- borderColor: "var(--border-strong)",
53
- },
54
- "&:disabled": {
55
- opacity: "var(--opacity-disabled)",
56
- pointerEvents: "none",
57
- },
58
- [`&[data-popup-open] ${select__icon}`]: {
59
- transform: "rotate(180deg)",
60
- },
61
- },
62
- });
63
-
64
- export const select__value = style({
65
- flex: "1 1 auto",
66
- textAlign: "left",
67
- overflow: "hidden",
68
- textOverflow: "ellipsis",
69
- whiteSpace: "nowrap",
70
- });
71
-
72
- export const select__placeholder = style({
73
- color: "var(--foreground-subtle)",
74
- });
75
-
76
- export const select__icon = style({
77
- display: "inline-flex",
78
- alignItems: "center",
79
- justifyContent: "center",
80
- color: "var(--foreground-muted)",
81
- flexShrink: 0,
82
- transition: "transform var(--duration-fast)",
83
- });
84
-
85
- export const select__positioner = style({
86
- outline: "none",
87
- zIndex: "var(--z-dropdown)",
88
- });
89
-
90
- export const select__content = style({
91
- minWidth: "var(--anchor-width, 10rem)",
92
- maxHeight: "min(24rem, var(--available-height, 24rem))",
93
- overflowY: "auto",
94
- padding: "var(--space-1)",
95
- background: "var(--background)",
96
- color: "var(--foreground)",
97
- border: "1px solid var(--border)",
98
- borderRadius: "var(--radius)",
99
- boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.08),\n 0 2px 4px -2px rgba(0, 0, 0, 0.05)",
100
- fontSize: "var(--text-sm)",
101
- transformOrigin: "var(--transform-origin)",
102
- animation: "sh-ui-select-in 140ms ease-out",
103
- selectors: {
104
- "&[data-ending-style]": {
105
- animation: "sh-ui-select-out 100ms ease-in forwards",
106
- },
107
- },
108
- });
109
-
110
- export const select__label = style({
111
- padding: "var(--space-2) var(--space-2) var(--space-1)",
112
- fontSize: "var(--text-xs)",
113
- fontWeight: "var(--weight-semibold)",
114
- color: "var(--foreground-muted)",
115
- textTransform: "uppercase",
116
- letterSpacing: "0.04em",
117
- });
118
-
119
- export const select__item = style({
120
- display: "flex",
121
- alignItems: "center",
122
- gap: "var(--space-2)",
123
- padding: "0.5rem 0.75rem",
124
- borderRadius: "calc(var(--radius) - 2px)",
125
- cursor: "pointer",
126
- outline: "none",
127
- userSelect: "none",
128
- transition: "background-color 80ms",
129
- selectors: {
130
- "&[data-highlighted]": {
131
- background: "var(--background-muted)",
132
- },
133
- "&:hover": {
134
- background: "var(--background-muted)",
135
- },
136
- "&[data-disabled]": {
137
- opacity: "var(--opacity-disabled)",
138
- pointerEvents: "none",
139
- },
140
- },
141
- });
142
-
143
- export const selectItemText = style({
144
- flex: 1,
145
- });
146
-
147
- export const select__indicator = style({
148
- order: 1,
149
- marginLeft: "auto",
150
- display: "inline-flex",
151
- alignItems: "center",
152
- justifyContent: "center",
153
- color: "var(--foreground)",
154
- });
155
-
156
- export const select__separator = style({
157
- height: "1px",
158
- background: "var(--border)",
159
- margin: "var(--space-1) 0",
160
- });
161
-
162
- export const select__chips = style({
163
- display: "inline-flex",
164
- alignItems: "center",
165
- gap: "var(--space-1)",
166
- flexWrap: "nowrap",
167
- overflow: "hidden",
168
- });
169
-
170
- export const select__chip = style({
171
- display: "inline-flex",
172
- alignItems: "center",
173
- gap: "var(--space-1)",
174
- padding: "0.125rem 0.375rem 0.125rem var(--space-2)",
175
- fontSize: "var(--text-xs)",
176
- lineHeight: "1.25rem",
177
- background: "var(--background-muted)",
178
- borderRadius: "calc(var(--radius) - 2px)",
179
- whiteSpace: "nowrap",
180
- });
181
-
182
- export const selectChipRemove = style({
183
- display: "inline-flex",
184
- alignItems: "center",
185
- justifyContent: "center",
186
- width: "1rem",
187
- height: "1rem",
188
- padding: 0,
189
- border: 0,
190
- borderRadius: "999px",
191
- background: "transparent",
192
- color: "var(--foreground-muted)",
193
- fontSize: "var(--text-sm)",
194
- lineHeight: 1,
195
- cursor: "pointer",
196
- transition: "background-color var(--duration-fast), color var(--duration-fast)",
197
- selectors: {
198
- "&:hover": {
199
- background: "var(--background)",
200
- color: "var(--foreground)",
201
- },
202
- "&:focus-visible": {
203
- outline: "var(--border-width-strong) solid var(--foreground)",
204
- outlineOffset: "1px",
205
- },
206
- },
207
- });
208
-
209
- /** 동적 키로 클래스 참조용 — `byKey[\`badge--${variant}\`]` 같은 패턴 지원. */
210
- export const byKey: Record<string, string> = {
211
- "select__trigger": select__trigger,
212
- "select__value": select__value,
213
- "select__placeholder": select__placeholder,
214
- "select__icon": select__icon,
215
- "select__positioner": select__positioner,
216
- "select__content": select__content,
217
- "select__label": select__label,
218
- "select__item": select__item,
219
- "select__item-text": selectItemText,
220
- "select__indicator": select__indicator,
221
- "select__separator": select__separator,
222
- "select__chips": select__chips,
223
- "select__chip": select__chip,
224
- "select__chip-remove": selectChipRemove,
225
- };
@@ -1,46 +0,0 @@
1
- import * as React from "react";
2
- import { byKey, separator, separatorHorizontal, separatorVertical } from "./styles.css";
3
-
4
-
5
- import { cn } from "@SH_UI_UTILS@";
6
- export type SeparatorOrientation = "horizontal" | "vertical";
7
-
8
- export interface SeparatorProps
9
- extends Omit<React.HTMLAttributes<HTMLDivElement>, "role"> {
10
- orientation?: SeparatorOrientation;
11
- /**
12
- * 의미 없는 시각적 구분선인지 여부. 기본 true(aria-hidden).
13
- * 스크린리더에도 섹션 구분을 알려야 하면 false.
14
- */
15
- decorative?: boolean;
16
- }
17
-
18
- /**
19
- * 시각적 구분선. 가로(height=1px) / 세로(width=1px).
20
- *
21
- * 의미 있는 구분에는 `decorative={false}`로 role=separator가 붙고, 그렇지 않으면
22
- * aria-hidden 처리되어 보조 기술에 노출되지 않는다.
23
- */
24
- export const Separator = React.forwardRef<HTMLDivElement, SeparatorProps>(
25
- function Separator(
26
- { className, orientation = "horizontal", decorative = true, ...props },
27
- ref,
28
- ) {
29
- return (
30
- <div
31
- ref={ref}
32
- role={decorative ? undefined : "separator"}
33
- aria-orientation={decorative ? undefined : orientation}
34
- aria-hidden={decorative || undefined}
35
- data-orientation={orientation}
36
- className={cn(
37
- separator,
38
- byKey[`separator--${orientation}`],
39
- className,
40
- )}
41
- {...props}
42
- />
43
- );
44
- },
45
- );
46
- Separator.displayName = "Separator";
@@ -1,24 +0,0 @@
1
- import { style } from "@vanilla-extract/css";
2
-
3
- export const separator = style({
4
- background: "var(--border)",
5
- flexShrink: 0,
6
- });
7
-
8
- export const separatorHorizontal = style({
9
- width: "100%",
10
- height: "1px",
11
- });
12
-
13
- export const separatorVertical = style({
14
- width: "1px",
15
- height: "100%",
16
- alignSelf: "stretch",
17
- });
18
-
19
- /** 동적 키로 클래스 참조용 — `byKey[\`badge--${variant}\`]` 같은 패턴 지원. */
20
- export const byKey: Record<string, string> = {
21
- "separator": separator,
22
- "separator--horizontal": separatorHorizontal,
23
- "separator--vertical": separatorVertical,
24
- };