sh-ui-cli 0.45.1 → 0.45.3
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/data/changelog/versions.json +25 -0
- package/data/registry/react/components/accordion/index.tailwind.tsx +5 -7
- package/data/registry/react/components/accordion/index.tsx +5 -7
- package/data/registry/react/components/avatar/index.tailwind.tsx +4 -6
- package/data/registry/react/components/avatar/index.tsx +4 -6
- package/data/registry/react/components/badge/index.tailwind.tsx +2 -4
- package/data/registry/react/components/badge/index.tsx +2 -4
- package/data/registry/react/components/breadcrumb/index.tailwind.tsx +8 -10
- package/data/registry/react/components/breadcrumb/index.tsx +8 -10
- package/data/registry/react/components/button/index.tailwind.tsx +2 -1
- package/data/registry/react/components/button/index.tsx +3 -4
- package/data/registry/react/components/calendar/index.tailwind.tsx +10 -12
- package/data/registry/react/components/calendar/index.tsx +9 -11
- package/data/registry/react/components/card/index.tailwind.tsx +8 -10
- package/data/registry/react/components/card/index.tsx +8 -10
- package/data/registry/react/components/carousel/index.tailwind.tsx +7 -9
- package/data/registry/react/components/carousel/index.tsx +7 -9
- package/data/registry/react/components/checkbox/index.tailwind.tsx +3 -5
- package/data/registry/react/components/checkbox/index.tsx +3 -5
- package/data/registry/react/components/code-editor/index.tailwind.tsx +2 -4
- package/data/registry/react/components/code-editor/index.tsx +2 -4
- package/data/registry/react/components/code-panel/index.tailwind.tsx +5 -7
- package/data/registry/react/components/code-panel/index.tsx +5 -7
- package/data/registry/react/components/color-picker/index.tailwind.tsx +7 -6
- package/data/registry/react/components/color-picker/index.tsx +7 -6
- package/data/registry/react/components/combobox/index.tailwind.tsx +8 -10
- package/data/registry/react/components/combobox/index.tsx +8 -10
- package/data/registry/react/components/context-menu/index.tailwind.tsx +10 -12
- package/data/registry/react/components/context-menu/index.tsx +10 -12
- package/data/registry/react/components/date-picker/index.tailwind.tsx +7 -9
- package/data/registry/react/components/date-picker/index.tsx +7 -9
- package/data/registry/react/components/dialog/index.tailwind.tsx +6 -8
- package/data/registry/react/components/dialog/index.tsx +6 -8
- package/data/registry/react/components/dropdown-menu/index.tailwind.tsx +10 -12
- package/data/registry/react/components/dropdown-menu/index.tsx +10 -12
- package/data/registry/react/components/file-upload/index.tailwind.tsx +6 -8
- package/data/registry/react/components/file-upload/index.tsx +6 -8
- package/data/registry/react/components/form/field.tailwind.tsx +2 -1
- package/data/registry/react/components/form/field.tsx +2 -3
- package/data/registry/react/components/header/index.tailwind.tsx +17 -19
- package/data/registry/react/components/header/index.tsx +17 -19
- package/data/registry/react/components/input/index.tailwind.tsx +4 -6
- package/data/registry/react/components/input/index.tsx +4 -6
- package/data/registry/react/components/label/index.tailwind.tsx +6 -8
- package/data/registry/react/components/label/index.tsx +6 -8
- package/data/registry/react/components/markdown-editor/index.tailwind.tsx +2 -4
- package/data/registry/react/components/markdown-editor/index.tsx +2 -4
- package/data/registry/react/components/menubar/index.tailwind.tsx +2 -4
- package/data/registry/react/components/menubar/index.tsx +2 -4
- package/data/registry/react/components/numeric-input/index.tailwind.tsx +2 -4
- package/data/registry/react/components/numeric-input/index.tsx +2 -4
- package/data/registry/react/components/page-toc/index.tailwind.tsx +3 -2
- package/data/registry/react/components/page-toc/index.tsx +2 -3
- package/data/registry/react/components/pagination/index.tailwind.tsx +8 -10
- package/data/registry/react/components/pagination/index.tsx +8 -10
- package/data/registry/react/components/popover/index.tailwind.tsx +4 -6
- package/data/registry/react/components/popover/index.tsx +4 -6
- package/data/registry/react/components/progress/index.tailwind.tsx +3 -5
- package/data/registry/react/components/progress/index.tsx +2 -4
- package/data/registry/react/components/radio/index.tailwind.tsx +3 -5
- package/data/registry/react/components/radio/index.tsx +3 -5
- package/data/registry/react/components/rich-text-editor/index.tailwind.tsx +3 -5
- package/data/registry/react/components/rich-text-editor/index.tsx +3 -5
- package/data/registry/react/components/select/index.tailwind.tsx +8 -10
- package/data/registry/react/components/select/index.tsx +8 -10
- package/data/registry/react/components/separator/index.tailwind.tsx +2 -4
- package/data/registry/react/components/separator/index.tsx +2 -4
- package/data/registry/react/components/sidebar/index.tailwind.tsx +32 -43
- package/data/registry/react/components/sidebar/index.tsx +29 -46
- package/data/registry/react/components/skeleton/index.tailwind.tsx +2 -4
- package/data/registry/react/components/skeleton/index.tsx +2 -4
- package/data/registry/react/components/slider/index.tailwind.tsx +5 -7
- package/data/registry/react/components/slider/index.tsx +5 -7
- package/data/registry/react/components/spinner/index.tailwind.tsx +3 -5
- package/data/registry/react/components/spinner/index.tsx +2 -4
- package/data/registry/react/components/switch/index.tailwind.tsx +3 -5
- package/data/registry/react/components/switch/index.tsx +2 -4
- package/data/registry/react/components/tabs/index.tailwind.tsx +6 -8
- package/data/registry/react/components/tabs/index.tsx +6 -8
- package/data/registry/react/components/textarea/index.tailwind.tsx +2 -4
- package/data/registry/react/components/textarea/index.tsx +2 -4
- package/data/registry/react/components/toggle/index.tailwind.tsx +4 -6
- package/data/registry/react/components/toggle/index.tsx +4 -6
- package/data/registry/react/components/tooltip/index.tailwind.tsx +2 -4
- package/data/registry/react/components/tooltip/index.tsx +2 -4
- package/data/registry/react/lib/cn.tailwind.ts +17 -0
- package/data/registry/react/peer-versions.json +3 -1
- package/data/registry/react/registry.json +159 -43
- package/package.json +1 -1
- package/src/add.mjs +25 -1
- package/src/mcp-init.mjs +13 -5
- package/src/mcp.mjs +20 -15
- package/templates/ui-app-template/sh-ui.config.json +5 -0
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
3
4
|
type DivProps = React.HTMLAttributes<HTMLDivElement>;
|
|
4
5
|
|
|
5
|
-
function mergeClass(base: string, extra?: string) {
|
|
6
|
-
return extra ? `${base} ${extra}` : base;
|
|
7
|
-
}
|
|
8
6
|
|
|
9
7
|
export const Card = React.forwardRef<HTMLDivElement, DivProps>(
|
|
10
8
|
({ className, ...props }, ref) => (
|
|
11
9
|
<div
|
|
12
10
|
ref={ref}
|
|
13
|
-
className={
|
|
11
|
+
className={cn(
|
|
14
12
|
"flex flex-col gap-[var(--space-6)] py-[var(--space-6)] bg-background text-foreground border border-border rounded-[var(--radius)] max-sm:gap-[var(--space-4)] max-sm:py-[var(--space-4)]",
|
|
15
13
|
className,
|
|
16
14
|
)}
|
|
@@ -25,7 +23,7 @@ export const CardHeader = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
25
23
|
<div
|
|
26
24
|
ref={ref}
|
|
27
25
|
data-slot="card-header"
|
|
28
|
-
className={
|
|
26
|
+
className={cn(
|
|
29
27
|
"grid grid-cols-1 auto-rows-auto gap-y-1.5 px-[var(--space-6)] has-[[data-slot=card-action]]:grid-cols-[1fr_auto] max-sm:px-[var(--space-4)]",
|
|
30
28
|
className,
|
|
31
29
|
)}
|
|
@@ -39,7 +37,7 @@ export const CardTitle = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
39
37
|
({ className, ...props }, ref) => (
|
|
40
38
|
<div
|
|
41
39
|
ref={ref}
|
|
42
|
-
className={
|
|
40
|
+
className={cn(
|
|
43
41
|
"text-[length:var(--text-base)] font-semibold leading-tight tracking-tight",
|
|
44
42
|
className,
|
|
45
43
|
)}
|
|
@@ -53,7 +51,7 @@ export const CardDescription = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
53
51
|
({ className, ...props }, ref) => (
|
|
54
52
|
<div
|
|
55
53
|
ref={ref}
|
|
56
|
-
className={
|
|
54
|
+
className={cn(
|
|
57
55
|
"text-[length:var(--text-sm)] leading-normal text-foreground-muted",
|
|
58
56
|
className,
|
|
59
57
|
)}
|
|
@@ -72,7 +70,7 @@ export const CardAction = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
72
70
|
<div
|
|
73
71
|
ref={ref}
|
|
74
72
|
data-slot="card-action"
|
|
75
|
-
className={
|
|
73
|
+
className={cn(
|
|
76
74
|
"col-start-2 row-span-2 self-start justify-self-end",
|
|
77
75
|
className,
|
|
78
76
|
)}
|
|
@@ -86,7 +84,7 @@ export const CardContent = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
86
84
|
({ className, ...props }, ref) => (
|
|
87
85
|
<div
|
|
88
86
|
ref={ref}
|
|
89
|
-
className={
|
|
87
|
+
className={cn(
|
|
90
88
|
"px-[var(--space-6)] text-[length:var(--text-sm)] leading-relaxed max-sm:px-[var(--space-4)]",
|
|
91
89
|
className,
|
|
92
90
|
)}
|
|
@@ -100,7 +98,7 @@ export const CardFooter = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
100
98
|
({ className, ...props }, ref) => (
|
|
101
99
|
<div
|
|
102
100
|
ref={ref}
|
|
103
|
-
className={
|
|
101
|
+
className={cn(
|
|
104
102
|
"px-[var(--space-6)] flex items-center gap-[var(--space-2)] max-sm:px-[var(--space-4)] max-sm:flex-wrap",
|
|
105
103
|
className,
|
|
106
104
|
)}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
2
3
|
import "./styles.css";
|
|
3
4
|
|
|
4
5
|
type DivProps = React.HTMLAttributes<HTMLDivElement>;
|
|
5
6
|
|
|
6
|
-
function mergeClass(base: string, extra?: string) {
|
|
7
|
-
return extra ? `${base} ${extra}` : base;
|
|
8
|
-
}
|
|
9
7
|
|
|
10
8
|
export const Card = React.forwardRef<HTMLDivElement, DivProps>(
|
|
11
9
|
({ className, ...props }, ref) => (
|
|
12
|
-
<div ref={ref} className={
|
|
10
|
+
<div ref={ref} className={cn("sh-ui-card", className)} {...props} />
|
|
13
11
|
),
|
|
14
12
|
);
|
|
15
13
|
Card.displayName = "Card";
|
|
@@ -19,7 +17,7 @@ export const CardHeader = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
19
17
|
<div
|
|
20
18
|
ref={ref}
|
|
21
19
|
data-slot="card-header"
|
|
22
|
-
className={
|
|
20
|
+
className={cn("sh-ui-card__header", className)}
|
|
23
21
|
{...props}
|
|
24
22
|
/>
|
|
25
23
|
),
|
|
@@ -30,7 +28,7 @@ export const CardTitle = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
30
28
|
({ className, ...props }, ref) => (
|
|
31
29
|
<div
|
|
32
30
|
ref={ref}
|
|
33
|
-
className={
|
|
31
|
+
className={cn("sh-ui-card__title", className)}
|
|
34
32
|
{...props}
|
|
35
33
|
/>
|
|
36
34
|
),
|
|
@@ -41,7 +39,7 @@ export const CardDescription = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
41
39
|
({ className, ...props }, ref) => (
|
|
42
40
|
<div
|
|
43
41
|
ref={ref}
|
|
44
|
-
className={
|
|
42
|
+
className={cn("sh-ui-card__description", className)}
|
|
45
43
|
{...props}
|
|
46
44
|
/>
|
|
47
45
|
),
|
|
@@ -56,7 +54,7 @@ export const CardAction = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
56
54
|
({ className, ...props }, ref) => (
|
|
57
55
|
<div
|
|
58
56
|
ref={ref}
|
|
59
|
-
className={
|
|
57
|
+
className={cn("sh-ui-card__action", className)}
|
|
60
58
|
{...props}
|
|
61
59
|
/>
|
|
62
60
|
),
|
|
@@ -67,7 +65,7 @@ export const CardContent = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
67
65
|
({ className, ...props }, ref) => (
|
|
68
66
|
<div
|
|
69
67
|
ref={ref}
|
|
70
|
-
className={
|
|
68
|
+
className={cn("sh-ui-card__content", className)}
|
|
71
69
|
{...props}
|
|
72
70
|
/>
|
|
73
71
|
),
|
|
@@ -78,7 +76,7 @@ export const CardFooter = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
78
76
|
({ className, ...props }, ref) => (
|
|
79
77
|
<div
|
|
80
78
|
ref={ref}
|
|
81
|
-
className={
|
|
79
|
+
className={cn("sh-ui-card__footer", className)}
|
|
82
80
|
{...props}
|
|
83
81
|
/>
|
|
84
82
|
),
|
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
6
|
-
return args.filter(Boolean).join(" ");
|
|
7
|
-
}
|
|
8
5
|
|
|
6
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
9
7
|
type Orientation = "horizontal" | "vertical";
|
|
10
8
|
|
|
11
9
|
interface CarouselContextValue {
|
|
@@ -144,7 +142,7 @@ export const Carousel = React.forwardRef<HTMLDivElement, CarouselProps>(
|
|
|
144
142
|
<CarouselContext.Provider value={value}>
|
|
145
143
|
<div
|
|
146
144
|
ref={ref}
|
|
147
|
-
className={
|
|
145
|
+
className={cn("relative w-full", className)}
|
|
148
146
|
data-orientation={orientation}
|
|
149
147
|
role="region"
|
|
150
148
|
aria-roledescription="carousel"
|
|
@@ -171,7 +169,7 @@ export const CarouselContent = React.forwardRef<HTMLDivElement, React.HTMLAttrib
|
|
|
171
169
|
return (
|
|
172
170
|
<div
|
|
173
171
|
ref={mergedRef}
|
|
174
|
-
className={
|
|
172
|
+
className={cn(
|
|
175
173
|
"flex gap-[var(--space-4)] overflow-x-auto overflow-y-hidden snap-x snap-mandatory scroll-smooth [scrollbar-width:none] [-ms-overflow-style:none] [-webkit-overflow-scrolling:touch] overscroll-x-contain [&::-webkit-scrollbar]:hidden motion-reduce:scroll-auto",
|
|
176
174
|
orientation === "vertical" && "flex-col overflow-x-hidden overflow-y-auto snap-y snap-mandatory h-80",
|
|
177
175
|
className,
|
|
@@ -193,7 +191,7 @@ export const CarouselItem = React.forwardRef<HTMLDivElement, React.HTMLAttribute
|
|
|
193
191
|
ref={ref}
|
|
194
192
|
role="group"
|
|
195
193
|
aria-roledescription="slide"
|
|
196
|
-
className={
|
|
194
|
+
className={cn(
|
|
197
195
|
"flex-[0_0_100%] min-w-0 snap-start snap-always",
|
|
198
196
|
orientation === "vertical" && "basis-auto",
|
|
199
197
|
className,
|
|
@@ -218,7 +216,7 @@ export const CarouselPrevious = React.forwardRef<HTMLButtonElement, React.Button
|
|
|
218
216
|
ref={ref}
|
|
219
217
|
type="button"
|
|
220
218
|
aria-label="이전"
|
|
221
|
-
className={
|
|
219
|
+
className={cn(
|
|
222
220
|
navClasses,
|
|
223
221
|
orientation === "horizontal" ? "-left-4" : "-top-4 left-1/2",
|
|
224
222
|
className,
|
|
@@ -248,7 +246,7 @@ export const CarouselNext = React.forwardRef<HTMLButtonElement, React.ButtonHTML
|
|
|
248
246
|
ref={ref}
|
|
249
247
|
type="button"
|
|
250
248
|
aria-label="다음"
|
|
251
|
-
className={
|
|
249
|
+
className={cn(
|
|
252
250
|
navClasses,
|
|
253
251
|
orientation === "horizontal" ? "-right-4" : "-bottom-4 left-1/2 [top:auto]",
|
|
254
252
|
className,
|
|
@@ -282,7 +280,7 @@ export const CarouselIndicators = React.forwardRef<HTMLDivElement, CarouselIndic
|
|
|
282
280
|
ref={ref}
|
|
283
281
|
role="tablist"
|
|
284
282
|
aria-label="슬라이드 선택"
|
|
285
|
-
className={
|
|
283
|
+
className={cn(
|
|
286
284
|
"flex justify-center items-center gap-[var(--space-2)] mt-[var(--space-3)]",
|
|
287
285
|
orientation === "vertical" && "absolute top-1/2 right-2 mt-0 flex-col -translate-y-1/2",
|
|
288
286
|
className,
|
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import "./styles.css";
|
|
5
5
|
|
|
6
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
7
|
-
return args.filter(Boolean).join(" ");
|
|
8
|
-
}
|
|
9
6
|
|
|
7
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
10
8
|
type Orientation = "horizontal" | "vertical";
|
|
11
9
|
|
|
12
10
|
interface CarouselContextValue {
|
|
@@ -259,7 +257,7 @@ export const Carousel = React.forwardRef<HTMLDivElement, CarouselProps>(
|
|
|
259
257
|
<CarouselContext.Provider value={value}>
|
|
260
258
|
<div
|
|
261
259
|
ref={ref}
|
|
262
|
-
className={
|
|
260
|
+
className={cn("sh-ui-carousel", className)}
|
|
263
261
|
data-orientation={orientation}
|
|
264
262
|
role="region"
|
|
265
263
|
aria-roledescription="carousel"
|
|
@@ -292,7 +290,7 @@ export const CarouselContent = React.forwardRef<
|
|
|
292
290
|
return (
|
|
293
291
|
<div
|
|
294
292
|
ref={mergedRef}
|
|
295
|
-
className={
|
|
293
|
+
className={cn("sh-ui-carousel__content", className)}
|
|
296
294
|
data-orientation={orientation}
|
|
297
295
|
{...props}
|
|
298
296
|
/>
|
|
@@ -313,7 +311,7 @@ export const CarouselItem = React.forwardRef<
|
|
|
313
311
|
ref={ref}
|
|
314
312
|
role="group"
|
|
315
313
|
aria-roledescription="slide"
|
|
316
|
-
className={
|
|
314
|
+
className={cn("sh-ui-carousel__item", className)}
|
|
317
315
|
data-orientation={orientation}
|
|
318
316
|
{...props}
|
|
319
317
|
/>
|
|
@@ -332,7 +330,7 @@ export const CarouselPrevious = React.forwardRef<
|
|
|
332
330
|
ref={ref}
|
|
333
331
|
type="button"
|
|
334
332
|
aria-label="이전"
|
|
335
|
-
className={
|
|
333
|
+
className={cn("sh-ui-carousel__nav", "sh-ui-carousel__nav--prev", className)}
|
|
336
334
|
data-orientation={orientation}
|
|
337
335
|
disabled={disabled || atStart || count === 0}
|
|
338
336
|
onClick={(e) => {
|
|
@@ -368,7 +366,7 @@ export const CarouselNext = React.forwardRef<
|
|
|
368
366
|
ref={ref}
|
|
369
367
|
type="button"
|
|
370
368
|
aria-label="다음"
|
|
371
|
-
className={
|
|
369
|
+
className={cn("sh-ui-carousel__nav", "sh-ui-carousel__nav--next", className)}
|
|
372
370
|
data-orientation={orientation}
|
|
373
371
|
disabled={disabled || atEnd || count === 0}
|
|
374
372
|
onClick={(e) => {
|
|
@@ -410,7 +408,7 @@ export const CarouselIndicators = React.forwardRef<
|
|
|
410
408
|
ref={ref}
|
|
411
409
|
role="tablist"
|
|
412
410
|
aria-label="슬라이드 선택"
|
|
413
|
-
className={
|
|
411
|
+
className={cn("sh-ui-carousel__indicators", className)}
|
|
414
412
|
data-orientation={orientation}
|
|
415
413
|
{...props}
|
|
416
414
|
>
|
|
@@ -2,10 +2,8 @@ import * as React from "react";
|
|
|
2
2
|
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
|
|
3
3
|
import { CheckboxGroup as BaseCheckboxGroup } from "@base-ui/react/checkbox-group";
|
|
4
4
|
|
|
5
|
-
function cx(...args: (string | undefined | false)[]) {
|
|
6
|
-
return args.filter(Boolean).join(" ");
|
|
7
|
-
}
|
|
8
5
|
|
|
6
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
9
7
|
export type CheckboxProps = Omit<
|
|
10
8
|
React.ComponentPropsWithoutRef<typeof BaseCheckbox.Root>,
|
|
11
9
|
"className"
|
|
@@ -17,7 +15,7 @@ export const Checkbox = React.forwardRef<HTMLElement, CheckboxProps>(
|
|
|
17
15
|
({ className, ...props }, ref) => (
|
|
18
16
|
<BaseCheckbox.Root
|
|
19
17
|
ref={ref}
|
|
20
|
-
className={
|
|
18
|
+
className={cn(
|
|
21
19
|
"inline-flex items-center justify-center w-[1.125rem] h-[1.125rem] border border-border-strong rounded-[calc(var(--radius)-2px)] bg-background text-primary-foreground cursor-pointer shrink-0 transition-[background-color,border-color] duration-[var(--duration-fast)] hover:not-data-[disabled]:border-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-foreground focus-visible:outline-offset-2 data-[checked]:bg-primary data-[checked]:border-primary data-[indeterminate]:bg-primary data-[indeterminate]:border-primary data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:cursor-not-allowed motion-reduce:transition-none [@media(hover:none)_and_(pointer:coarse)]:w-5 [@media(hover:none)_and_(pointer:coarse)]:h-5",
|
|
22
20
|
className,
|
|
23
21
|
)}
|
|
@@ -43,7 +41,7 @@ export const CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps
|
|
|
43
41
|
({ className, orientation = "vertical", ...props }, ref) => (
|
|
44
42
|
<BaseCheckboxGroup
|
|
45
43
|
ref={ref}
|
|
46
|
-
className={
|
|
44
|
+
className={cn(
|
|
47
45
|
"flex gap-2.5",
|
|
48
46
|
orientation === "vertical" ? "flex-col" : "flex-row flex-wrap",
|
|
49
47
|
className,
|
|
@@ -3,10 +3,8 @@ import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
|
|
|
3
3
|
import { CheckboxGroup as BaseCheckboxGroup } from "@base-ui/react/checkbox-group";
|
|
4
4
|
import "./styles.css";
|
|
5
5
|
|
|
6
|
-
function cx(...args: (string | undefined | false)[]) {
|
|
7
|
-
return args.filter(Boolean).join(" ");
|
|
8
|
-
}
|
|
9
6
|
|
|
7
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
10
8
|
/* ───────────── Checkbox ───────────── */
|
|
11
9
|
|
|
12
10
|
export type CheckboxProps = Omit<
|
|
@@ -24,7 +22,7 @@ export const Checkbox = React.forwardRef<HTMLElement, CheckboxProps>(
|
|
|
24
22
|
({ className, ...props }, ref) => (
|
|
25
23
|
<BaseCheckbox.Root
|
|
26
24
|
ref={ref}
|
|
27
|
-
className={
|
|
25
|
+
className={cn("sh-ui-checkbox", className)}
|
|
28
26
|
{...props}
|
|
29
27
|
>
|
|
30
28
|
<BaseCheckbox.Indicator className="sh-ui-checkbox__indicator">
|
|
@@ -60,7 +58,7 @@ export const CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps
|
|
|
60
58
|
({ className, orientation = "vertical", ...props }, ref) => (
|
|
61
59
|
<BaseCheckboxGroup
|
|
62
60
|
ref={ref}
|
|
63
|
-
className={
|
|
61
|
+
className={cn("sh-ui-checkbox-group", className)}
|
|
64
62
|
data-orientation={orientation}
|
|
65
63
|
{...props}
|
|
66
64
|
/>
|
|
@@ -10,6 +10,7 @@ import { css as cssLang } from "@codemirror/lang-css";
|
|
|
10
10
|
import { html } from "@codemirror/lang-html";
|
|
11
11
|
import { markdown } from "@codemirror/lang-markdown";
|
|
12
12
|
|
|
13
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
13
14
|
export type CodeEditorLanguage =
|
|
14
15
|
| "text" | "javascript" | "typescript" | "jsx" | "tsx"
|
|
15
16
|
| "json" | "css" | "html" | "markdown";
|
|
@@ -30,9 +31,6 @@ export interface CodeEditorProps {
|
|
|
30
31
|
"aria-labelledby"?: string;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
34
|
-
return args.filter(Boolean).join(" ");
|
|
35
|
-
}
|
|
36
34
|
|
|
37
35
|
function languageExtension(language: CodeEditorLanguage): Extension {
|
|
38
36
|
switch (language) {
|
|
@@ -136,7 +134,7 @@ export function CodeEditor({
|
|
|
136
134
|
return (
|
|
137
135
|
<div
|
|
138
136
|
ref={hostRef}
|
|
139
|
-
className={
|
|
137
|
+
className={cn(
|
|
140
138
|
"sh-ui-code-editor relative border border-border rounded-[var(--radius)] bg-background text-[0.8125rem] leading-relaxed overflow-hidden transition-[border-color] duration-[var(--duration-fast)] focus-within:border-foreground focus-within:outline-[length:var(--border-width-strong)] focus-within:outline-foreground focus-within:outline-offset-2 data-[readonly]:bg-background-subtle motion-reduce:transition-none",
|
|
141
139
|
className,
|
|
142
140
|
)}
|
|
@@ -11,6 +11,7 @@ import { html } from "@codemirror/lang-html";
|
|
|
11
11
|
import { markdown } from "@codemirror/lang-markdown";
|
|
12
12
|
import "./styles.css";
|
|
13
13
|
|
|
14
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
14
15
|
export type CodeEditorLanguage =
|
|
15
16
|
| "text"
|
|
16
17
|
| "javascript"
|
|
@@ -59,9 +60,6 @@ export interface CodeEditorProps {
|
|
|
59
60
|
"aria-labelledby"?: string;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
63
|
-
return args.filter(Boolean).join(" ");
|
|
64
|
-
}
|
|
65
63
|
|
|
66
64
|
function languageExtension(language: CodeEditorLanguage): Extension {
|
|
67
65
|
switch (language) {
|
|
@@ -219,7 +217,7 @@ export function CodeEditor({
|
|
|
219
217
|
return (
|
|
220
218
|
<div
|
|
221
219
|
ref={hostRef}
|
|
222
|
-
className={
|
|
220
|
+
className={cn("sh-ui-code-editor", className)}
|
|
223
221
|
data-readonly={readOnly || undefined}
|
|
224
222
|
style={
|
|
225
223
|
{
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { codeToHtml } from "shiki";
|
|
2
2
|
import { CodePanelCopyButton } from "./copy";
|
|
3
3
|
|
|
4
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
5
|
-
return args.filter(Boolean).join(" ");
|
|
6
|
-
}
|
|
7
4
|
|
|
5
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
8
6
|
export interface CodePanelProps
|
|
9
7
|
extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
|
|
10
8
|
code?: string;
|
|
@@ -21,7 +19,7 @@ const rootClasses =
|
|
|
21
19
|
export async function CodePanel({
|
|
22
20
|
code, language = "text", filename, showLineNumbers = true, hideCopy, className, children, ...rest
|
|
23
21
|
}: CodePanelProps) {
|
|
24
|
-
const classes =
|
|
22
|
+
const classes = cn(rootClasses, className);
|
|
25
23
|
|
|
26
24
|
if (children !== undefined) {
|
|
27
25
|
return <div className={classes} {...rest}>{children}</div>;
|
|
@@ -52,7 +50,7 @@ export async function CodePanel({
|
|
|
52
50
|
export function CodePanelHeader({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
53
51
|
return (
|
|
54
52
|
<div
|
|
55
|
-
className={
|
|
53
|
+
className={cn(
|
|
56
54
|
"flex items-center justify-between gap-[var(--space-2)] py-[var(--space-2)] pl-[var(--space-4)] pr-[var(--space-3)] border-b border-border bg-background-muted text-[length:var(--text-xs)] text-foreground-muted",
|
|
57
55
|
className,
|
|
58
56
|
)}
|
|
@@ -65,7 +63,7 @@ export function CodePanelHeader({ className, children, ...props }: React.HTMLAtt
|
|
|
65
63
|
|
|
66
64
|
export function CodePanelFilename({ className, children, ...props }: React.HTMLAttributes<HTMLSpanElement>) {
|
|
67
65
|
return (
|
|
68
|
-
<span className={
|
|
66
|
+
<span className={cn("font-mono text-foreground", className)} {...props}>{children}</span>
|
|
69
67
|
);
|
|
70
68
|
}
|
|
71
69
|
|
|
@@ -93,7 +91,7 @@ export async function CodePanelBody({
|
|
|
93
91
|
|
|
94
92
|
return (
|
|
95
93
|
<div
|
|
96
|
-
className={
|
|
94
|
+
className={cn(
|
|
97
95
|
"overflow-x-auto [&_pre]:m-0 [&_pre]:py-[var(--space-3)] [&_pre]:px-[var(--space-4)] [&_pre]:!bg-transparent [&_pre]:font-mono [&_pre]:text-[length:inherit] [&_pre]:leading-[inherit] [&_pre]:border-none [&_pre]:rounded-none [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-[length:inherit] [&_code]:block [&_.shiki]:!text-[var(--shiki-light)] [&_.shiki_span]:!text-[var(--shiki-light)] [&_.shiki]:!bg-transparent [&_.shiki_span]:!bg-transparent [.dark_&_.shiki]:!text-[var(--shiki-dark)] [.dark_&_.shiki_span]:!text-[var(--shiki-dark)] data-[line-numbers]:[&_pre_code]:[counter-reset:step] data-[line-numbers]:[&_pre_code_.line]:before:[content:counter(step)] data-[line-numbers]:[&_pre_code_.line]:before:[counter-increment:step] data-[line-numbers]:[&_pre_code_.line]:before:inline-block data-[line-numbers]:[&_pre_code_.line]:before:w-7 data-[line-numbers]:[&_pre_code_.line]:before:mr-[var(--space-4)] data-[line-numbers]:[&_pre_code_.line]:before:text-right data-[line-numbers]:[&_pre_code_.line]:before:text-foreground-muted data-[line-numbers]:[&_pre_code_.line]:before:opacity-70 data-[line-numbers]:[&_pre_code_.line]:before:select-none",
|
|
98
96
|
className,
|
|
99
97
|
)}
|
|
@@ -2,10 +2,8 @@ import { codeToHtml } from "shiki";
|
|
|
2
2
|
import { CodePanelCopyButton } from "./copy";
|
|
3
3
|
import "./styles.css";
|
|
4
4
|
|
|
5
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
6
|
-
return args.filter(Boolean).join(" ");
|
|
7
|
-
}
|
|
8
5
|
|
|
6
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
9
7
|
export interface CodePanelProps
|
|
10
8
|
extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
|
|
11
9
|
/** 하이라이팅할 코드 문자열. children을 제공하지 않을 때 필수. */
|
|
@@ -56,7 +54,7 @@ export async function CodePanel({
|
|
|
56
54
|
children,
|
|
57
55
|
...rest
|
|
58
56
|
}: CodePanelProps) {
|
|
59
|
-
const classes =
|
|
57
|
+
const classes = cn("sh-ui-code", className);
|
|
60
58
|
|
|
61
59
|
if (children !== undefined) {
|
|
62
60
|
return (
|
|
@@ -104,7 +102,7 @@ export function CodePanelHeader({
|
|
|
104
102
|
...props
|
|
105
103
|
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
106
104
|
return (
|
|
107
|
-
<div className={
|
|
105
|
+
<div className={cn("sh-ui-code__header", className)} {...props}>
|
|
108
106
|
{children}
|
|
109
107
|
</div>
|
|
110
108
|
);
|
|
@@ -119,7 +117,7 @@ export function CodePanelFilename({
|
|
|
119
117
|
...props
|
|
120
118
|
}: React.HTMLAttributes<HTMLSpanElement>) {
|
|
121
119
|
return (
|
|
122
|
-
<span className={
|
|
120
|
+
<span className={cn("sh-ui-code__filename", className)} {...props}>
|
|
123
121
|
{children}
|
|
124
122
|
</span>
|
|
125
123
|
);
|
|
@@ -182,7 +180,7 @@ export async function CodePanelBody({
|
|
|
182
180
|
|
|
183
181
|
return (
|
|
184
182
|
<div
|
|
185
|
-
className={
|
|
183
|
+
className={cn("sh-ui-code__body", className)}
|
|
186
184
|
data-line-numbers={showLineNumbers || undefined}
|
|
187
185
|
dangerouslySetInnerHTML={{ __html: html }}
|
|
188
186
|
{...rest}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
5
6
|
interface HSV { h: number; s: number; v: number; }
|
|
6
7
|
interface HSVA extends HSV { a: number; }
|
|
7
8
|
|
|
@@ -136,7 +137,7 @@ export function ColorPicker({
|
|
|
136
137
|
|
|
137
138
|
return (
|
|
138
139
|
<ColorPickerContext.Provider value={ctx}>
|
|
139
|
-
<div className={
|
|
140
|
+
<div className={cn("flex flex-col gap-2.5 w-full select-none", className)} {...rest}>
|
|
140
141
|
{children ?? (<><ColorPickerSaturation /><ColorPickerHue /><ColorPickerHex /></>)}
|
|
141
142
|
</div>
|
|
142
143
|
</ColorPickerContext.Provider>
|
|
@@ -157,7 +158,7 @@ export function ColorPickerSaturation({ className, style, ...rest }: ColorPicker
|
|
|
157
158
|
<div
|
|
158
159
|
ref={drag.ref}
|
|
159
160
|
onPointerDown={drag.onPointerDown}
|
|
160
|
-
className={
|
|
161
|
+
className={cn("relative w-full aspect-[4/3] rounded-[var(--radius)] cursor-crosshair overflow-hidden touch-none", className)}
|
|
161
162
|
style={{ background: pureHueHex, ...style }}
|
|
162
163
|
role="slider"
|
|
163
164
|
aria-label="채도/명도"
|
|
@@ -187,7 +188,7 @@ export function ColorPickerHue({ className, ...rest }: ColorPickerHueProps) {
|
|
|
187
188
|
<div
|
|
188
189
|
ref={drag.ref}
|
|
189
190
|
onPointerDown={drag.onPointerDown}
|
|
190
|
-
className={
|
|
191
|
+
className={cn("relative w-full h-3.5 rounded-full cursor-pointer touch-none bg-[linear-gradient(to_right,#f00_0%,#ff0_16.66%,#0f0_33.33%,#0ff_50%,#00f_66.66%,#f0f_83.33%,#f00_100%)]", className)}
|
|
191
192
|
role="slider"
|
|
192
193
|
aria-label="색조"
|
|
193
194
|
aria-valuemin={0} aria-valuemax={360} aria-valuenow={Math.round(hsva.h)}
|
|
@@ -215,7 +216,7 @@ export function ColorPickerAlpha({ className, style, ...rest }: ColorPickerAlpha
|
|
|
215
216
|
<div
|
|
216
217
|
ref={drag.ref}
|
|
217
218
|
onPointerDown={drag.onPointerDown}
|
|
218
|
-
className={
|
|
219
|
+
className={cn("relative w-full h-3.5 rounded-full cursor-pointer touch-none overflow-hidden bg-white bg-[length:8px_8px] bg-[position:0_0,0_4px,4px_-4px,-4px_0] [background-image:linear-gradient(45deg,#ccc_25%,transparent_25%),linear-gradient(-45deg,#ccc_25%,transparent_25%),linear-gradient(45deg,transparent_75%,#ccc_75%),linear-gradient(-45deg,transparent_75%,#ccc_75%)]", className)}
|
|
219
220
|
role="slider"
|
|
220
221
|
aria-label="투명도"
|
|
221
222
|
aria-valuemin={0} aria-valuemax={100} aria-valuenow={Math.round(hsva.a * 100)}
|
|
@@ -248,7 +249,7 @@ export function ColorPickerHex({ className, showSwatch = true, ...rest }: ColorP
|
|
|
248
249
|
|
|
249
250
|
return (
|
|
250
251
|
<div
|
|
251
|
-
className={
|
|
252
|
+
className={cn("flex items-center gap-[var(--space-2)]", className)}
|
|
252
253
|
{...rest}
|
|
253
254
|
>
|
|
254
255
|
{showSwatch && (
|
|
@@ -285,7 +286,7 @@ export function ColorPickerSwatches({ className, colors, ...rest }: ColorPickerS
|
|
|
285
286
|
<div
|
|
286
287
|
role="group"
|
|
287
288
|
aria-label="미리 준비된 색상"
|
|
288
|
-
className={
|
|
289
|
+
className={cn("flex flex-wrap gap-1.5", className)}
|
|
289
290
|
{...rest}
|
|
290
291
|
>
|
|
291
292
|
{colors.map((c) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
4
5
|
import "./styles.css";
|
|
5
6
|
|
|
6
7
|
/* ───────────── types ───────────── */
|
|
@@ -234,7 +235,7 @@ export function ColorPicker({
|
|
|
234
235
|
return (
|
|
235
236
|
<ColorPickerContext.Provider value={ctx}>
|
|
236
237
|
<div
|
|
237
|
-
className={
|
|
238
|
+
className={cn("sh-ui-color-picker", className)}
|
|
238
239
|
{...rest}
|
|
239
240
|
>
|
|
240
241
|
{children ?? (
|
|
@@ -271,7 +272,7 @@ export function ColorPickerSaturation({
|
|
|
271
272
|
<div
|
|
272
273
|
ref={drag.ref}
|
|
273
274
|
onPointerDown={drag.onPointerDown}
|
|
274
|
-
className={
|
|
275
|
+
className={cn("sh-ui-color-picker__sv", className)}
|
|
275
276
|
style={{ background: pureHueHex, ...style }}
|
|
276
277
|
role="slider"
|
|
277
278
|
aria-label="채도/명도"
|
|
@@ -309,7 +310,7 @@ export function ColorPickerHue({ className, ...rest }: ColorPickerHueProps) {
|
|
|
309
310
|
<div
|
|
310
311
|
ref={drag.ref}
|
|
311
312
|
onPointerDown={drag.onPointerDown}
|
|
312
|
-
className={
|
|
313
|
+
className={cn("sh-ui-color-picker__hue", className)}
|
|
313
314
|
role="slider"
|
|
314
315
|
aria-label="색조"
|
|
315
316
|
aria-valuemin={0}
|
|
@@ -341,7 +342,7 @@ export function ColorPickerAlpha({ className, style, ...rest }: ColorPickerAlpha
|
|
|
341
342
|
<div
|
|
342
343
|
ref={drag.ref}
|
|
343
344
|
onPointerDown={drag.onPointerDown}
|
|
344
|
-
className={
|
|
345
|
+
className={cn("sh-ui-color-picker__alpha", className)}
|
|
345
346
|
role="slider"
|
|
346
347
|
aria-label="투명도"
|
|
347
348
|
aria-valuemin={0}
|
|
@@ -392,7 +393,7 @@ export function ColorPickerHex({
|
|
|
392
393
|
|
|
393
394
|
return (
|
|
394
395
|
<div
|
|
395
|
-
className={
|
|
396
|
+
className={cn("sh-ui-color-picker__row", className)}
|
|
396
397
|
{...rest}
|
|
397
398
|
>
|
|
398
399
|
{showSwatch && (
|
|
@@ -442,7 +443,7 @@ export function ColorPickerSwatches({
|
|
|
442
443
|
<div
|
|
443
444
|
role="group"
|
|
444
445
|
aria-label="미리 준비된 색상"
|
|
445
|
-
className={
|
|
446
|
+
className={cn("sh-ui-color-picker__swatches", className)}
|
|
446
447
|
{...rest}
|
|
447
448
|
>
|
|
448
449
|
{colors.map((c) => {
|