sh-ui-cli 0.98.0 → 0.109.1
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 +169 -0
- package/data/registry/react/components/scroll-area/index.module.tsx +71 -0
- package/data/registry/react/components/scroll-area/index.tailwind.tsx +54 -0
- package/data/registry/react/components/scroll-area/index.tsx +67 -0
- package/data/registry/react/components/scroll-area/styles.css +64 -0
- package/data/registry/react/components/scroll-area/styles.module.css +64 -0
- package/data/registry/react/components/sheet/index.module.tsx +93 -0
- package/data/registry/react/components/sheet/index.tailwind.tsx +120 -0
- package/data/registry/react/components/sheet/index.tsx +121 -0
- package/data/registry/react/components/sheet/styles.css +183 -0
- package/data/registry/react/components/sheet/styles.module.css +171 -0
- package/data/registry/react/registry.json +94 -0
- package/data/registry/react/tokens-used.json +86 -1
- package/data/summaries/react.json +3 -1
- package/data/tokens/src/primitives.json +8 -0
- package/data/tokens/src/semantic.json +36 -10
- package/package.json +1 -1
- package/src/add.mjs +39 -14
- package/src/create/cli-args.js +18 -5
- package/src/create/generator.js +116 -4
- package/src/create/index.mjs +3 -0
- package/src/create/plugins/nextIntl.js +3 -0
- package/src/create/theme/decode.js +3 -0
- package/src/create/theme/presets.js +45 -8
- package/src/css-bundle.mjs +60 -0
- package/src/mcp.mjs +47 -3
- package/src/remove.mjs +10 -1
- package/src/theme-extract.mjs +1 -0
- package/templates/nextjs-standalone/_arch/flat/app/globals.css +16 -4
- package/templates/nextjs-standalone/_arch/flat/lib/styles/tokens.css +35 -4
- package/templates/nextjs-standalone/_arch/fsd/src/shared/styles/tokens.css +35 -4
- package/templates/nextjs-standalone/_arch/mes/app/globals.css +16 -4
- package/templates/nextjs-standalone/_arch/mes/src/lib/styles/tokens.css +33 -2
- package/templates/nextjs-standalone/app/globals.css +16 -4
- package/templates/ui-app-template/src/styles/globals.css +16 -4
- package/templates/ui-app-template/src/styles/tokens.css +35 -4
- package/templates/vite-standalone/_arch/flat/src/lib/styles/globals.css +16 -0
- package/templates/vite-standalone/_arch/flat/src/lib/styles/tokens.css +35 -4
- package/templates/vite-standalone/_arch/fsd/src/shared/styles/globals.css +16 -0
- package/templates/vite-standalone/_arch/fsd/src/shared/styles/tokens.css +35 -4
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Drawer as BaseDrawer } from "@base-ui/react/drawer";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
5
|
+
type WithStringClassName<T> = Omit<T, "className"> & { className?: string };
|
|
6
|
+
|
|
7
|
+
export const Sheet = BaseDrawer.Root;
|
|
8
|
+
export const SheetTrigger = BaseDrawer.Trigger;
|
|
9
|
+
export const SheetClose = BaseDrawer.Close;
|
|
10
|
+
|
|
11
|
+
export function SheetCloseX({
|
|
12
|
+
className,
|
|
13
|
+
children,
|
|
14
|
+
...props
|
|
15
|
+
}: React.ButtonHTMLAttributes<HTMLButtonElement>) {
|
|
16
|
+
return (
|
|
17
|
+
<BaseDrawer.Close
|
|
18
|
+
className={cn(
|
|
19
|
+
"absolute top-3 right-3 inline-flex items-center justify-center w-[var(--control-sm)] h-[var(--control-sm)] bg-transparent text-foreground-muted border-none rounded-[var(--radius)] cursor-pointer text-xl leading-none transition-colors duration-[var(--duration-fast)] hover:bg-background-subtle hover:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2",
|
|
20
|
+
className,
|
|
21
|
+
)}
|
|
22
|
+
aria-label="닫기"
|
|
23
|
+
{...props}
|
|
24
|
+
>
|
|
25
|
+
{children ?? "×"}
|
|
26
|
+
</BaseDrawer.Close>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function SheetHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
31
|
+
return (
|
|
32
|
+
<div
|
|
33
|
+
className={cn("flex flex-col gap-[var(--space-1)] mb-[var(--space-4)]", className)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function SheetFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
40
|
+
return (
|
|
41
|
+
<div
|
|
42
|
+
className={cn(
|
|
43
|
+
"flex justify-end gap-[var(--space-2)] mt-[var(--space-6)]",
|
|
44
|
+
className,
|
|
45
|
+
)}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface SheetContentProps
|
|
52
|
+
extends WithStringClassName<React.ComponentPropsWithoutRef<typeof BaseDrawer.Popup>> {
|
|
53
|
+
side?: "right" | "left" | "top" | "bottom";
|
|
54
|
+
container?: React.ComponentPropsWithoutRef<typeof BaseDrawer.Portal>["container"];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const SIDE_CLASSES: Record<NonNullable<SheetContentProps["side"]>, string> = {
|
|
58
|
+
right:
|
|
59
|
+
"top-0 right-0 h-[100dvh] w-[calc(100%-2rem)] max-w-md border-l border-border data-[starting-style]:translate-x-full data-[ending-style]:translate-x-full",
|
|
60
|
+
left:
|
|
61
|
+
"top-0 left-0 h-[100dvh] w-[calc(100%-2rem)] max-w-md border-r border-border data-[starting-style]:-translate-x-full data-[ending-style]:-translate-x-full",
|
|
62
|
+
top:
|
|
63
|
+
"top-0 left-0 right-0 w-screen max-h-[calc(100dvh-4rem)] border-b border-border data-[starting-style]:-translate-y-full data-[ending-style]:-translate-y-full",
|
|
64
|
+
bottom:
|
|
65
|
+
"bottom-0 left-0 right-0 w-screen max-h-[calc(100dvh-4rem)] border-t border-border data-[starting-style]:translate-y-full data-[ending-style]:translate-y-full",
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const SheetContent = React.forwardRef<HTMLDivElement, SheetContentProps>(
|
|
69
|
+
function SheetContent({ className, children, side = "right", container, ...props }, ref) {
|
|
70
|
+
return (
|
|
71
|
+
<BaseDrawer.Portal container={container}>
|
|
72
|
+
<BaseDrawer.Backdrop className="fixed inset-0 z-[var(--z-overlay)] bg-black/25 backdrop-blur-md transition-opacity duration-[var(--duration-slow)] data-[starting-style]:opacity-0 data-[ending-style]:opacity-0" />
|
|
73
|
+
<BaseDrawer.Popup
|
|
74
|
+
ref={ref}
|
|
75
|
+
data-side={side}
|
|
76
|
+
className={cn(
|
|
77
|
+
"fixed z-[var(--z-modal)] flex flex-col p-[var(--space-6)] bg-background text-foreground shadow-[var(--shadow-xl)] outline-none overflow-y-auto transition-[opacity,transform] duration-[var(--duration-slow)] focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:[outline-offset:-2px] motion-reduce:transition-none motion-reduce:data-[starting-style]:transform-none motion-reduce:data-[ending-style]:transform-none",
|
|
78
|
+
SIDE_CLASSES[side],
|
|
79
|
+
className,
|
|
80
|
+
)}
|
|
81
|
+
{...props}
|
|
82
|
+
>
|
|
83
|
+
{children}
|
|
84
|
+
</BaseDrawer.Popup>
|
|
85
|
+
</BaseDrawer.Portal>
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
export const SheetTitle = React.forwardRef<
|
|
91
|
+
HTMLHeadingElement,
|
|
92
|
+
WithStringClassName<React.ComponentPropsWithoutRef<typeof BaseDrawer.Title>>
|
|
93
|
+
>(function SheetTitle({ className, ...props }, ref) {
|
|
94
|
+
return (
|
|
95
|
+
<BaseDrawer.Title
|
|
96
|
+
ref={ref}
|
|
97
|
+
className={cn(
|
|
98
|
+
"m-0 text-[length:var(--text-lg)] font-semibold text-balance",
|
|
99
|
+
className,
|
|
100
|
+
)}
|
|
101
|
+
{...props}
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
export const SheetDescription = React.forwardRef<
|
|
107
|
+
HTMLParagraphElement,
|
|
108
|
+
WithStringClassName<React.ComponentPropsWithoutRef<typeof BaseDrawer.Description>>
|
|
109
|
+
>(function SheetDescription({ className, ...props }, ref) {
|
|
110
|
+
return (
|
|
111
|
+
<BaseDrawer.Description
|
|
112
|
+
ref={ref}
|
|
113
|
+
className={cn(
|
|
114
|
+
"m-0 text-foreground-muted text-[length:var(--text-sm)] leading-normal",
|
|
115
|
+
className,
|
|
116
|
+
)}
|
|
117
|
+
{...props}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Drawer as BaseDrawer } from "@base-ui/react/drawer";
|
|
3
|
+
import "./styles.css";
|
|
4
|
+
|
|
5
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
6
|
+
type WithStringClassName<T> = Omit<T, "className"> & { className?: string };
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 화면 가장자리에서 슬라이드 인 하는 side drawer 컨테이너. 글로벌 알림함 / 작업 큐 / 보조 패널
|
|
10
|
+
* 처럼 사이드바와 무관한 위치에서 떠올리는 모달 시트에 사용. 사이드바 인근 detail 패널은 Sidebar 의
|
|
11
|
+
* SidebarPanel 을, 강제 응답이 필요한 중앙 모달은 Dialog 를 권장.
|
|
12
|
+
*
|
|
13
|
+
* 위치는 `<SheetContent side>` 로 지정 — right(기본) / left / top / bottom.
|
|
14
|
+
*/
|
|
15
|
+
export const Sheet = BaseDrawer.Root;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Sheet 를 여는 트리거. 자체로 `<button>` 을 렌더 — 자식 button 중첩 금지. 커스텀 Button 등으로
|
|
19
|
+
* 슬롯하려면 `render` prop:
|
|
20
|
+
*
|
|
21
|
+
* <SheetTrigger render={<Button>열기</Button>} />
|
|
22
|
+
*/
|
|
23
|
+
export const SheetTrigger = BaseDrawer.Trigger;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 클릭 시 Sheet 를 닫는 요소 (예: footer 취소 버튼). 자체로 `<button>` 을 렌더하므로 자식 button
|
|
27
|
+
* 중첩 금지. 커스텀 Button 슬롯은 `render` prop 사용.
|
|
28
|
+
*/
|
|
29
|
+
export const SheetClose = BaseDrawer.Close;
|
|
30
|
+
|
|
31
|
+
/** 우상단에 배치되는 X 닫기 버튼. `aria-label="닫기"` 가 자동 부여된다. */
|
|
32
|
+
export function SheetCloseX({
|
|
33
|
+
className,
|
|
34
|
+
children,
|
|
35
|
+
...props
|
|
36
|
+
}: React.ButtonHTMLAttributes<HTMLButtonElement>) {
|
|
37
|
+
return (
|
|
38
|
+
<BaseDrawer.Close
|
|
39
|
+
className={cn("sh-ui-sheet__close", className)}
|
|
40
|
+
aria-label="닫기"
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
{children ?? "×"}
|
|
44
|
+
</BaseDrawer.Close>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Sheet 콘텐츠 상단의 제목 영역. */
|
|
49
|
+
export function SheetHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
50
|
+
return <div className={cn("sh-ui-sheet__header", className)} {...props} />;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Sheet 콘텐츠 하단의 액션 버튼 영역. 보통 [취소, 확인] 순서. */
|
|
54
|
+
export function SheetFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
55
|
+
return <div className={cn("sh-ui-sheet__footer", className)} {...props} />;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface SheetContentProps
|
|
59
|
+
extends WithStringClassName<React.ComponentPropsWithoutRef<typeof BaseDrawer.Popup>> {
|
|
60
|
+
/**
|
|
61
|
+
* Sheet 가 슬라이드 인 하는 방향.
|
|
62
|
+
* @default "right"
|
|
63
|
+
*/
|
|
64
|
+
side?: "right" | "left" | "top" | "bottom";
|
|
65
|
+
/**
|
|
66
|
+
* Portal 마운트 노드. 다른 stacking context 안에 갇혀야 할 때 지정.
|
|
67
|
+
* @default document.body
|
|
68
|
+
*/
|
|
69
|
+
container?: React.ComponentPropsWithoutRef<typeof BaseDrawer.Portal>["container"];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Sheet 의 실제 콘텐츠. Portal 로 body 끝에 마운트되며 backdrop · focus trap · ESC 닫힘 등이
|
|
74
|
+
* 자동 처리된다. `side` 로 진입 방향을 지정 — right/left 는 사이드 패널, top/bottom 은 시트 형태.
|
|
75
|
+
* 접근성: 안에 반드시 `SheetTitle` 을 두고, 추가 설명은 `SheetDescription` 으로 연결할 것.
|
|
76
|
+
*/
|
|
77
|
+
export const SheetContent = React.forwardRef<HTMLDivElement, SheetContentProps>(
|
|
78
|
+
function SheetContent({ className, children, side = "right", container, ...props }, ref) {
|
|
79
|
+
return (
|
|
80
|
+
<BaseDrawer.Portal container={container}>
|
|
81
|
+
<BaseDrawer.Backdrop className="sh-ui-sheet__backdrop" />
|
|
82
|
+
<BaseDrawer.Popup
|
|
83
|
+
ref={ref}
|
|
84
|
+
data-side={side}
|
|
85
|
+
className={cn("sh-ui-sheet__content", className)}
|
|
86
|
+
{...props}
|
|
87
|
+
>
|
|
88
|
+
{children}
|
|
89
|
+
</BaseDrawer.Popup>
|
|
90
|
+
</BaseDrawer.Portal>
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
/** Sheet 의 제목. 접근성을 위해 SheetContent 안에 항상 포함시킬 것. */
|
|
96
|
+
export const SheetTitle = React.forwardRef<
|
|
97
|
+
HTMLHeadingElement,
|
|
98
|
+
WithStringClassName<React.ComponentPropsWithoutRef<typeof BaseDrawer.Title>>
|
|
99
|
+
>(function SheetTitle({ className, ...props }, ref) {
|
|
100
|
+
return (
|
|
101
|
+
<BaseDrawer.Title
|
|
102
|
+
ref={ref}
|
|
103
|
+
className={cn("sh-ui-sheet__title", className)}
|
|
104
|
+
{...props}
|
|
105
|
+
/>
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
/** Sheet 의 보조 설명. 제목만으로 맥락이 부족할 때 사용. */
|
|
110
|
+
export const SheetDescription = React.forwardRef<
|
|
111
|
+
HTMLParagraphElement,
|
|
112
|
+
WithStringClassName<React.ComponentPropsWithoutRef<typeof BaseDrawer.Description>>
|
|
113
|
+
>(function SheetDescription({ className, ...props }, ref) {
|
|
114
|
+
return (
|
|
115
|
+
<BaseDrawer.Description
|
|
116
|
+
ref={ref}
|
|
117
|
+
className={cn("sh-ui-sheet__description", className)}
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
});
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/* ── Backdrop ── */
|
|
2
|
+
|
|
3
|
+
.sh-ui-sheet__backdrop {
|
|
4
|
+
position: fixed;
|
|
5
|
+
inset: 0;
|
|
6
|
+
z-index: var(--z-overlay);
|
|
7
|
+
background: rgba(0, 0, 0, 0.25);
|
|
8
|
+
backdrop-filter: blur(8px);
|
|
9
|
+
transition: opacity var(--duration-slow) ease;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.sh-ui-sheet__backdrop[data-starting-style],
|
|
13
|
+
.sh-ui-sheet__backdrop[data-ending-style] {
|
|
14
|
+
opacity: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* ── Content (Popup) ── */
|
|
18
|
+
|
|
19
|
+
.sh-ui-sheet__content {
|
|
20
|
+
position: fixed;
|
|
21
|
+
z-index: var(--z-modal);
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
padding: var(--space-6);
|
|
25
|
+
background: var(--background);
|
|
26
|
+
color: var(--foreground);
|
|
27
|
+
border: 1px solid var(--border);
|
|
28
|
+
box-shadow: var(--shadow-xl);
|
|
29
|
+
outline: none;
|
|
30
|
+
overflow-y: auto;
|
|
31
|
+
transition:
|
|
32
|
+
opacity var(--duration-slow) ease,
|
|
33
|
+
transform var(--duration-slow) ease;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.sh-ui-sheet__content[data-side="right"] {
|
|
37
|
+
top: 0;
|
|
38
|
+
right: 0;
|
|
39
|
+
height: 100dvh;
|
|
40
|
+
width: calc(100% - 2rem);
|
|
41
|
+
max-width: 28rem;
|
|
42
|
+
border-left: 1px solid var(--border);
|
|
43
|
+
border-top: none;
|
|
44
|
+
border-right: none;
|
|
45
|
+
border-bottom: none;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.sh-ui-sheet__content[data-side="left"] {
|
|
49
|
+
top: 0;
|
|
50
|
+
left: 0;
|
|
51
|
+
height: 100dvh;
|
|
52
|
+
width: calc(100% - 2rem);
|
|
53
|
+
max-width: 28rem;
|
|
54
|
+
border-right: 1px solid var(--border);
|
|
55
|
+
border-top: none;
|
|
56
|
+
border-left: none;
|
|
57
|
+
border-bottom: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.sh-ui-sheet__content[data-side="top"] {
|
|
61
|
+
top: 0;
|
|
62
|
+
left: 0;
|
|
63
|
+
right: 0;
|
|
64
|
+
width: 100vw;
|
|
65
|
+
max-height: calc(100dvh - 4rem);
|
|
66
|
+
border-bottom: 1px solid var(--border);
|
|
67
|
+
border-top: none;
|
|
68
|
+
border-left: none;
|
|
69
|
+
border-right: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.sh-ui-sheet__content[data-side="bottom"] {
|
|
73
|
+
bottom: 0;
|
|
74
|
+
left: 0;
|
|
75
|
+
right: 0;
|
|
76
|
+
width: 100vw;
|
|
77
|
+
max-height: calc(100dvh - 4rem);
|
|
78
|
+
border-top: 1px solid var(--border);
|
|
79
|
+
border-bottom: none;
|
|
80
|
+
border-left: none;
|
|
81
|
+
border-right: none;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Enter/exit transforms — slide from the edge */
|
|
85
|
+
|
|
86
|
+
.sh-ui-sheet__content[data-side="right"][data-starting-style],
|
|
87
|
+
.sh-ui-sheet__content[data-side="right"][data-ending-style] {
|
|
88
|
+
transform: translateX(100%);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.sh-ui-sheet__content[data-side="left"][data-starting-style],
|
|
92
|
+
.sh-ui-sheet__content[data-side="left"][data-ending-style] {
|
|
93
|
+
transform: translateX(-100%);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.sh-ui-sheet__content[data-side="top"][data-starting-style],
|
|
97
|
+
.sh-ui-sheet__content[data-side="top"][data-ending-style] {
|
|
98
|
+
transform: translateY(-100%);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.sh-ui-sheet__content[data-side="bottom"][data-starting-style],
|
|
102
|
+
.sh-ui-sheet__content[data-side="bottom"][data-ending-style] {
|
|
103
|
+
transform: translateY(100%);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.sh-ui-sheet__content:focus-visible {
|
|
107
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
108
|
+
outline-offset: -2px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* ── Close X ── */
|
|
112
|
+
|
|
113
|
+
.sh-ui-sheet__close {
|
|
114
|
+
position: absolute;
|
|
115
|
+
top: var(--space-3);
|
|
116
|
+
right: var(--space-3);
|
|
117
|
+
width: var(--control-sm);
|
|
118
|
+
height: var(--control-sm);
|
|
119
|
+
display: inline-flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
background: transparent;
|
|
123
|
+
color: var(--foreground-muted);
|
|
124
|
+
border: none;
|
|
125
|
+
border-radius: var(--radius);
|
|
126
|
+
cursor: pointer;
|
|
127
|
+
font-size: 1.25rem;
|
|
128
|
+
line-height: 1;
|
|
129
|
+
transition: background var(--duration-fast) ease, color var(--duration-fast) ease;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.sh-ui-sheet__close:hover {
|
|
133
|
+
background: var(--background-subtle);
|
|
134
|
+
color: var(--foreground);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.sh-ui-sheet__close:focus-visible {
|
|
138
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
139
|
+
outline-offset: 2px;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* ── Header / Footer ── */
|
|
143
|
+
|
|
144
|
+
.sh-ui-sheet__header {
|
|
145
|
+
display: flex;
|
|
146
|
+
flex-direction: column;
|
|
147
|
+
gap: var(--space-1);
|
|
148
|
+
margin-bottom: var(--space-4);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.sh-ui-sheet__footer {
|
|
152
|
+
display: flex;
|
|
153
|
+
justify-content: flex-end;
|
|
154
|
+
gap: var(--space-2);
|
|
155
|
+
margin-top: var(--space-6);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* ── Title / Description ── */
|
|
159
|
+
|
|
160
|
+
.sh-ui-sheet__title {
|
|
161
|
+
margin: 0;
|
|
162
|
+
font-size: var(--text-lg);
|
|
163
|
+
font-weight: var(--weight-semibold);
|
|
164
|
+
text-wrap: balance;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.sh-ui-sheet__description {
|
|
168
|
+
margin: 0;
|
|
169
|
+
color: var(--foreground-muted);
|
|
170
|
+
font-size: var(--text-sm);
|
|
171
|
+
line-height: 1.5;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@media (prefers-reduced-motion: reduce) {
|
|
175
|
+
.sh-ui-sheet__backdrop,
|
|
176
|
+
.sh-ui-sheet__content {
|
|
177
|
+
transition: opacity 0.01ms;
|
|
178
|
+
}
|
|
179
|
+
.sh-ui-sheet__content[data-starting-style],
|
|
180
|
+
.sh-ui-sheet__content[data-ending-style] {
|
|
181
|
+
transform: none;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
.sheet__backdrop {
|
|
2
|
+
position: fixed;
|
|
3
|
+
inset: 0;
|
|
4
|
+
z-index: var(--z-overlay);
|
|
5
|
+
background: rgba(0, 0, 0, 0.25);
|
|
6
|
+
backdrop-filter: blur(8px);
|
|
7
|
+
transition: opacity var(--duration-slow) ease;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.sheet__backdrop[data-starting-style],
|
|
11
|
+
.sheet__backdrop[data-ending-style] {
|
|
12
|
+
opacity: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.sheet__content {
|
|
16
|
+
position: fixed;
|
|
17
|
+
z-index: var(--z-modal);
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
padding: var(--space-6);
|
|
21
|
+
background: var(--background);
|
|
22
|
+
color: var(--foreground);
|
|
23
|
+
border: 1px solid var(--border);
|
|
24
|
+
box-shadow: var(--shadow-xl);
|
|
25
|
+
outline: none;
|
|
26
|
+
overflow-y: auto;
|
|
27
|
+
transition:
|
|
28
|
+
opacity var(--duration-slow) ease,
|
|
29
|
+
transform var(--duration-slow) ease;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.sheet__content[data-side="right"] {
|
|
33
|
+
top: 0;
|
|
34
|
+
right: 0;
|
|
35
|
+
height: 100dvh;
|
|
36
|
+
width: calc(100% - 2rem);
|
|
37
|
+
max-width: 28rem;
|
|
38
|
+
border-left: 1px solid var(--border);
|
|
39
|
+
border-top: none;
|
|
40
|
+
border-right: none;
|
|
41
|
+
border-bottom: none;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.sheet__content[data-side="left"] {
|
|
45
|
+
top: 0;
|
|
46
|
+
left: 0;
|
|
47
|
+
height: 100dvh;
|
|
48
|
+
width: calc(100% - 2rem);
|
|
49
|
+
max-width: 28rem;
|
|
50
|
+
border-right: 1px solid var(--border);
|
|
51
|
+
border-top: none;
|
|
52
|
+
border-left: none;
|
|
53
|
+
border-bottom: none;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.sheet__content[data-side="top"] {
|
|
57
|
+
top: 0;
|
|
58
|
+
left: 0;
|
|
59
|
+
right: 0;
|
|
60
|
+
width: 100vw;
|
|
61
|
+
max-height: calc(100dvh - 4rem);
|
|
62
|
+
border-bottom: 1px solid var(--border);
|
|
63
|
+
border-top: none;
|
|
64
|
+
border-left: none;
|
|
65
|
+
border-right: none;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.sheet__content[data-side="bottom"] {
|
|
69
|
+
bottom: 0;
|
|
70
|
+
left: 0;
|
|
71
|
+
right: 0;
|
|
72
|
+
width: 100vw;
|
|
73
|
+
max-height: calc(100dvh - 4rem);
|
|
74
|
+
border-top: 1px solid var(--border);
|
|
75
|
+
border-bottom: none;
|
|
76
|
+
border-left: none;
|
|
77
|
+
border-right: none;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.sheet__content[data-side="right"][data-starting-style],
|
|
81
|
+
.sheet__content[data-side="right"][data-ending-style] {
|
|
82
|
+
transform: translateX(100%);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.sheet__content[data-side="left"][data-starting-style],
|
|
86
|
+
.sheet__content[data-side="left"][data-ending-style] {
|
|
87
|
+
transform: translateX(-100%);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.sheet__content[data-side="top"][data-starting-style],
|
|
91
|
+
.sheet__content[data-side="top"][data-ending-style] {
|
|
92
|
+
transform: translateY(-100%);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.sheet__content[data-side="bottom"][data-starting-style],
|
|
96
|
+
.sheet__content[data-side="bottom"][data-ending-style] {
|
|
97
|
+
transform: translateY(100%);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.sheet__content:focus-visible {
|
|
101
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
102
|
+
outline-offset: -2px;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.sheet__close {
|
|
106
|
+
position: absolute;
|
|
107
|
+
top: var(--space-3);
|
|
108
|
+
right: var(--space-3);
|
|
109
|
+
width: var(--control-sm);
|
|
110
|
+
height: var(--control-sm);
|
|
111
|
+
display: inline-flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
justify-content: center;
|
|
114
|
+
background: transparent;
|
|
115
|
+
color: var(--foreground-muted);
|
|
116
|
+
border: none;
|
|
117
|
+
border-radius: var(--radius);
|
|
118
|
+
cursor: pointer;
|
|
119
|
+
font-size: 1.25rem;
|
|
120
|
+
line-height: 1;
|
|
121
|
+
transition: background var(--duration-fast) ease, color var(--duration-fast) ease;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.sheet__close:hover {
|
|
125
|
+
background: var(--background-subtle);
|
|
126
|
+
color: var(--foreground);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.sheet__close:focus-visible {
|
|
130
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
131
|
+
outline-offset: 2px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.sheet__header {
|
|
135
|
+
display: flex;
|
|
136
|
+
flex-direction: column;
|
|
137
|
+
gap: var(--space-1);
|
|
138
|
+
margin-bottom: var(--space-4);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.sheet__footer {
|
|
142
|
+
display: flex;
|
|
143
|
+
justify-content: flex-end;
|
|
144
|
+
gap: var(--space-2);
|
|
145
|
+
margin-top: var(--space-6);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.sheet__title {
|
|
149
|
+
margin: 0;
|
|
150
|
+
font-size: var(--text-lg);
|
|
151
|
+
font-weight: var(--weight-semibold);
|
|
152
|
+
text-wrap: balance;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.sheet__description {
|
|
156
|
+
margin: 0;
|
|
157
|
+
color: var(--foreground-muted);
|
|
158
|
+
font-size: var(--text-sm);
|
|
159
|
+
line-height: 1.5;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@media (prefers-reduced-motion: reduce) {
|
|
163
|
+
.sheet__backdrop,
|
|
164
|
+
.sheet__content {
|
|
165
|
+
transition: opacity 0.01ms;
|
|
166
|
+
}
|
|
167
|
+
.sheet__content[data-starting-style],
|
|
168
|
+
.sheet__content[data-ending-style] {
|
|
169
|
+
transform: none;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -2322,6 +2322,100 @@
|
|
|
2322
2322
|
"form"
|
|
2323
2323
|
]
|
|
2324
2324
|
},
|
|
2325
|
+
"scroll-area": {
|
|
2326
|
+
"name": "scroll-area",
|
|
2327
|
+
"type": "component",
|
|
2328
|
+
"files": [
|
|
2329
|
+
{
|
|
2330
|
+
"src": "components/scroll-area/index.tsx",
|
|
2331
|
+
"dest": "{components}/scroll-area/index.tsx",
|
|
2332
|
+
"frameworks": [
|
|
2333
|
+
"plain"
|
|
2334
|
+
]
|
|
2335
|
+
},
|
|
2336
|
+
{
|
|
2337
|
+
"src": "components/scroll-area/styles.css",
|
|
2338
|
+
"dest": "{components}/scroll-area/styles.css",
|
|
2339
|
+
"frameworks": [
|
|
2340
|
+
"plain"
|
|
2341
|
+
]
|
|
2342
|
+
},
|
|
2343
|
+
{
|
|
2344
|
+
"src": "components/scroll-area/index.tailwind.tsx",
|
|
2345
|
+
"dest": "{components}/scroll-area/index.tsx",
|
|
2346
|
+
"frameworks": [
|
|
2347
|
+
"tailwind"
|
|
2348
|
+
]
|
|
2349
|
+
},
|
|
2350
|
+
{
|
|
2351
|
+
"src": "components/scroll-area/index.module.tsx",
|
|
2352
|
+
"dest": "{components}/scroll-area/index.tsx",
|
|
2353
|
+
"frameworks": [
|
|
2354
|
+
"css-modules"
|
|
2355
|
+
]
|
|
2356
|
+
},
|
|
2357
|
+
{
|
|
2358
|
+
"src": "components/scroll-area/styles.module.css",
|
|
2359
|
+
"dest": "{components}/scroll-area/styles.module.css",
|
|
2360
|
+
"frameworks": [
|
|
2361
|
+
"css-modules"
|
|
2362
|
+
]
|
|
2363
|
+
}
|
|
2364
|
+
],
|
|
2365
|
+
"dependencies": [
|
|
2366
|
+
"@base-ui/react"
|
|
2367
|
+
],
|
|
2368
|
+
"registryDependencies": [
|
|
2369
|
+
"utils"
|
|
2370
|
+
]
|
|
2371
|
+
},
|
|
2372
|
+
"sheet": {
|
|
2373
|
+
"name": "sheet",
|
|
2374
|
+
"type": "component",
|
|
2375
|
+
"files": [
|
|
2376
|
+
{
|
|
2377
|
+
"src": "components/sheet/index.tsx",
|
|
2378
|
+
"dest": "{components}/sheet/index.tsx",
|
|
2379
|
+
"frameworks": [
|
|
2380
|
+
"plain"
|
|
2381
|
+
]
|
|
2382
|
+
},
|
|
2383
|
+
{
|
|
2384
|
+
"src": "components/sheet/styles.css",
|
|
2385
|
+
"dest": "{components}/sheet/styles.css",
|
|
2386
|
+
"frameworks": [
|
|
2387
|
+
"plain"
|
|
2388
|
+
]
|
|
2389
|
+
},
|
|
2390
|
+
{
|
|
2391
|
+
"src": "components/sheet/index.tailwind.tsx",
|
|
2392
|
+
"dest": "{components}/sheet/index.tsx",
|
|
2393
|
+
"frameworks": [
|
|
2394
|
+
"tailwind"
|
|
2395
|
+
]
|
|
2396
|
+
},
|
|
2397
|
+
{
|
|
2398
|
+
"src": "components/sheet/index.module.tsx",
|
|
2399
|
+
"dest": "{components}/sheet/index.tsx",
|
|
2400
|
+
"frameworks": [
|
|
2401
|
+
"css-modules"
|
|
2402
|
+
]
|
|
2403
|
+
},
|
|
2404
|
+
{
|
|
2405
|
+
"src": "components/sheet/styles.module.css",
|
|
2406
|
+
"dest": "{components}/sheet/styles.module.css",
|
|
2407
|
+
"frameworks": [
|
|
2408
|
+
"css-modules"
|
|
2409
|
+
]
|
|
2410
|
+
}
|
|
2411
|
+
],
|
|
2412
|
+
"dependencies": [
|
|
2413
|
+
"@base-ui/react"
|
|
2414
|
+
],
|
|
2415
|
+
"registryDependencies": [
|
|
2416
|
+
"utils"
|
|
2417
|
+
]
|
|
2418
|
+
},
|
|
2325
2419
|
"utils": {
|
|
2326
2420
|
"name": "utils",
|
|
2327
2421
|
"type": "lib",
|