sh-ui-cli 0.45.2 → 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 +13 -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/templates/ui-app-template/sh-ui.config.json +5 -0
|
@@ -5,6 +5,7 @@ import { useEditor, EditorContent, type Editor } from "@tiptap/react";
|
|
|
5
5
|
import StarterKit from "@tiptap/starter-kit";
|
|
6
6
|
import Placeholder from "@tiptap/extension-placeholder";
|
|
7
7
|
import Link from "@tiptap/extension-link";
|
|
8
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
8
9
|
import {
|
|
9
10
|
BoldIcon, ItalicIcon, StrikethroughIcon,
|
|
10
11
|
Heading1Icon, Heading2Icon, Heading3Icon,
|
|
@@ -26,9 +27,6 @@ export interface RichTextEditorProps {
|
|
|
26
27
|
"aria-label"?: string;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
30
|
-
return args.filter(Boolean).join(" ");
|
|
31
|
-
}
|
|
32
30
|
|
|
33
31
|
export function RichTextEditor({
|
|
34
32
|
value: valueProp, defaultValue, onChange, placeholder, readOnly = false, hideToolbar = false,
|
|
@@ -68,7 +66,7 @@ export function RichTextEditor({
|
|
|
68
66
|
|
|
69
67
|
return (
|
|
70
68
|
<div
|
|
71
|
-
className={
|
|
69
|
+
className={cn(
|
|
72
70
|
"sh-ui-rte flex flex-col border border-border rounded-[var(--radius)] bg-background 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",
|
|
73
71
|
className,
|
|
74
72
|
)}
|
|
@@ -158,7 +156,7 @@ function ToolbarButton({ editor, label, icon, isActive, canRun, run, disabled }:
|
|
|
158
156
|
return (
|
|
159
157
|
<button
|
|
160
158
|
type="button"
|
|
161
|
-
className={
|
|
159
|
+
className={cn(
|
|
162
160
|
"inline-flex items-center justify-center w-7 h-7 p-0 bg-transparent text-foreground-muted border border-transparent rounded-[calc(var(--radius)-2px)] cursor-pointer transition-[color,background-color,border-color] duration-[var(--duration-fast)] hover:not-disabled:text-foreground hover:not-disabled:bg-background hover:not-disabled:border-border focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-foreground focus-visible:outline-offset-1 disabled:opacity-50 disabled:cursor-not-allowed motion-reduce:transition-none",
|
|
163
161
|
isActive && "text-foreground bg-background border-border-strong",
|
|
164
162
|
)}
|
|
@@ -5,6 +5,7 @@ import { useEditor, EditorContent, type Editor } from "@tiptap/react";
|
|
|
5
5
|
import StarterKit from "@tiptap/starter-kit";
|
|
6
6
|
import Placeholder from "@tiptap/extension-placeholder";
|
|
7
7
|
import Link from "@tiptap/extension-link";
|
|
8
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
8
9
|
import {
|
|
9
10
|
BoldIcon,
|
|
10
11
|
ItalicIcon,
|
|
@@ -51,9 +52,6 @@ export interface RichTextEditorProps {
|
|
|
51
52
|
"aria-label"?: string;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
55
|
-
return args.filter(Boolean).join(" ");
|
|
56
|
-
}
|
|
57
55
|
|
|
58
56
|
/**
|
|
59
57
|
* Tiptap 기반 리치 텍스트 에디터.
|
|
@@ -117,7 +115,7 @@ export function RichTextEditor({
|
|
|
117
115
|
|
|
118
116
|
return (
|
|
119
117
|
<div
|
|
120
|
-
className={
|
|
118
|
+
className={cn("sh-ui-rte", className)}
|
|
121
119
|
data-readonly={readOnly || undefined}
|
|
122
120
|
style={
|
|
123
121
|
{
|
|
@@ -330,7 +328,7 @@ function ToolbarButton({
|
|
|
330
328
|
return (
|
|
331
329
|
<button
|
|
332
330
|
type="button"
|
|
333
|
-
className={
|
|
331
|
+
className={cn("sh-ui-rte__btn", isActive && "is-active")}
|
|
334
332
|
aria-label={label}
|
|
335
333
|
aria-pressed={isActive || undefined}
|
|
336
334
|
title={label}
|
|
@@ -3,17 +3,15 @@
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
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
|
export const Select = BaseSelect.Root;
|
|
11
9
|
|
|
12
10
|
export function SelectValue({ placeholder, className, ...props }: { placeholder?: string; className?: string } & Omit<
|
|
13
11
|
React.ComponentPropsWithoutRef<typeof BaseSelect.Value>, "children"
|
|
14
12
|
>) {
|
|
15
13
|
return (
|
|
16
|
-
<BaseSelect.Value className={
|
|
14
|
+
<BaseSelect.Value className={cn("flex-1 text-left overflow-hidden text-ellipsis whitespace-nowrap", className)} {...props}>
|
|
17
15
|
{(value) =>
|
|
18
16
|
value !== null && value !== undefined && value !== "" ? (
|
|
19
17
|
(value as React.ReactNode)
|
|
@@ -31,7 +29,7 @@ export const SelectTrigger = React.forwardRef<
|
|
|
31
29
|
>(({ className, children, ...props }, ref) => (
|
|
32
30
|
<BaseSelect.Trigger
|
|
33
31
|
ref={ref}
|
|
34
|
-
className={
|
|
32
|
+
className={cn(
|
|
35
33
|
"inline-flex items-center justify-between gap-[var(--space-2)] min-w-40 h-[var(--control-md)] px-[var(--space-3)] bg-background text-foreground border border-border rounded-[var(--radius)] text-[length:var(--text-sm)] leading-none cursor-pointer transition-[border-color,background-color] duration-[var(--duration-fast)] select-none hover:not-disabled:border-border-strong focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-foreground focus-visible:outline-offset-2 data-[popup-open]:border-border-strong disabled:opacity-[var(--opacity-disabled)] disabled:pointer-events-none",
|
|
36
34
|
className,
|
|
37
35
|
)}
|
|
@@ -61,7 +59,7 @@ export const SelectContent = React.forwardRef<
|
|
|
61
59
|
<BaseSelect.Positioner className="outline-none z-[var(--z-dropdown)]" sideOffset={4} align="start">
|
|
62
60
|
<BaseSelect.Popup
|
|
63
61
|
ref={ref}
|
|
64
|
-
className={
|
|
62
|
+
className={cn(
|
|
65
63
|
"min-w-[var(--anchor-width,10rem)] max-h-[min(24rem,var(--available-height,24rem))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[0_4px_6px_-1px_rgba(0,0,0,0.08),0_2px_4px_-2px_rgba(0,0,0,0.05)] text-[length:var(--text-sm)] origin-[var(--transform-origin)] animate-[sh-ui-select-in_140ms_ease-out] data-[ending-style]:animate-[sh-ui-select-out_100ms_ease-in_forwards] motion-reduce:animate-none motion-reduce:data-[ending-style]:animate-none",
|
|
66
64
|
className,
|
|
67
65
|
)}
|
|
@@ -82,7 +80,7 @@ export const SelectLabel = React.forwardRef<
|
|
|
82
80
|
>(({ className, ...props }, ref) => (
|
|
83
81
|
<BaseSelect.GroupLabel
|
|
84
82
|
ref={ref}
|
|
85
|
-
className={
|
|
83
|
+
className={cn(
|
|
86
84
|
"py-[var(--space-2)] px-[var(--space-2)] pb-[var(--space-1)] text-[length:var(--text-xs)] font-semibold text-foreground-muted uppercase tracking-[0.04em]",
|
|
87
85
|
className,
|
|
88
86
|
)}
|
|
@@ -97,7 +95,7 @@ export const SelectItem = React.forwardRef<
|
|
|
97
95
|
>(({ className, children, ...props }, ref) => (
|
|
98
96
|
<BaseSelect.Item
|
|
99
97
|
ref={ref}
|
|
100
|
-
className={
|
|
98
|
+
className={cn(
|
|
101
99
|
"flex items-center gap-[var(--space-2)] py-2 px-3 rounded-[calc(var(--radius)-2px)] cursor-pointer outline-none select-none transition-colors duration-[80ms] data-[highlighted]:bg-background-muted hover:bg-background-muted data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:pointer-events-none",
|
|
102
100
|
className,
|
|
103
101
|
)}
|
|
@@ -122,7 +120,7 @@ export const SelectSeparator = React.forwardRef<
|
|
|
122
120
|
>(({ className, ...props }, ref) => (
|
|
123
121
|
<BaseSelect.Separator
|
|
124
122
|
ref={ref}
|
|
125
|
-
className={
|
|
123
|
+
className={cn("h-px bg-border my-[var(--space-1)]", className)}
|
|
126
124
|
{...props}
|
|
127
125
|
/>
|
|
128
126
|
));
|
|
@@ -178,7 +176,7 @@ export function MultiSelectValue({
|
|
|
178
176
|
} & Omit<React.ComponentPropsWithoutRef<typeof BaseSelect.Value>, "children" | "render">) {
|
|
179
177
|
const { remove, clear } = useMultiSelect();
|
|
180
178
|
return (
|
|
181
|
-
<BaseSelect.Value className={
|
|
179
|
+
<BaseSelect.Value className={cn("flex-1 text-left overflow-hidden text-ellipsis whitespace-nowrap", className)} {...props}>
|
|
182
180
|
{(value) => {
|
|
183
181
|
const arr = Array.isArray(value) ? (value as string[]) : [];
|
|
184
182
|
if (arr.length === 0) return <span className="text-foreground-subtle">{placeholder}</span>;
|
|
@@ -4,10 +4,8 @@ import * as React from "react";
|
|
|
4
4
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
5
5
|
import "./styles.css";
|
|
6
6
|
|
|
7
|
-
function cx(...args: (string | undefined | false)[]) {
|
|
8
|
-
return args.filter(Boolean).join(" ");
|
|
9
|
-
}
|
|
10
7
|
|
|
8
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
11
9
|
export const Select = BaseSelect.Root;
|
|
12
10
|
|
|
13
11
|
/** shadcn 호환: <SelectValue placeholder="..." /> */
|
|
@@ -20,7 +18,7 @@ export function SelectValue({
|
|
|
20
18
|
"children"
|
|
21
19
|
>) {
|
|
22
20
|
return (
|
|
23
|
-
<BaseSelect.Value className={
|
|
21
|
+
<BaseSelect.Value className={cn("sh-ui-select__value", className)} {...props}>
|
|
24
22
|
{(value) =>
|
|
25
23
|
value !== null && value !== undefined && value !== "" ? (
|
|
26
24
|
(value as React.ReactNode)
|
|
@@ -38,7 +36,7 @@ export const SelectTrigger = React.forwardRef<
|
|
|
38
36
|
>(({ className, children, ...props }, ref) => (
|
|
39
37
|
<BaseSelect.Trigger
|
|
40
38
|
ref={ref}
|
|
41
|
-
className={
|
|
39
|
+
className={cn("sh-ui-select__trigger", className)}
|
|
42
40
|
{...props}
|
|
43
41
|
>
|
|
44
42
|
{children}
|
|
@@ -74,7 +72,7 @@ export const SelectContent = React.forwardRef<
|
|
|
74
72
|
>
|
|
75
73
|
<BaseSelect.Popup
|
|
76
74
|
ref={ref}
|
|
77
|
-
className={
|
|
75
|
+
className={cn("sh-ui-select__content", className)}
|
|
78
76
|
{...props}
|
|
79
77
|
>
|
|
80
78
|
{children}
|
|
@@ -92,7 +90,7 @@ export const SelectLabel = React.forwardRef<
|
|
|
92
90
|
>(({ className, ...props }, ref) => (
|
|
93
91
|
<BaseSelect.GroupLabel
|
|
94
92
|
ref={ref}
|
|
95
|
-
className={
|
|
93
|
+
className={cn("sh-ui-select__label", className)}
|
|
96
94
|
{...props}
|
|
97
95
|
/>
|
|
98
96
|
));
|
|
@@ -104,7 +102,7 @@ export const SelectItem = React.forwardRef<
|
|
|
104
102
|
>(({ className, children, ...props }, ref) => (
|
|
105
103
|
<BaseSelect.Item
|
|
106
104
|
ref={ref}
|
|
107
|
-
className={
|
|
105
|
+
className={cn("sh-ui-select__item", className)}
|
|
108
106
|
{...props}
|
|
109
107
|
>
|
|
110
108
|
<BaseSelect.ItemIndicator className="sh-ui-select__indicator" aria-hidden>
|
|
@@ -131,7 +129,7 @@ export const SelectSeparator = React.forwardRef<
|
|
|
131
129
|
>(({ className, ...props }, ref) => (
|
|
132
130
|
<BaseSelect.Separator
|
|
133
131
|
ref={ref}
|
|
134
|
-
className={
|
|
132
|
+
className={cn("sh-ui-select__separator", className)}
|
|
135
133
|
{...props}
|
|
136
134
|
/>
|
|
137
135
|
));
|
|
@@ -223,7 +221,7 @@ export function MultiSelectValue({
|
|
|
223
221
|
>) {
|
|
224
222
|
const { remove, clear } = useMultiSelect();
|
|
225
223
|
return (
|
|
226
|
-
<BaseSelect.Value className={
|
|
224
|
+
<BaseSelect.Value className={cn("sh-ui-select__value", className)} {...props}>
|
|
227
225
|
{(value) => {
|
|
228
226
|
const arr = Array.isArray(value) ? (value as string[]) : [];
|
|
229
227
|
if (arr.length === 0) {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
function cx(...args: (string | undefined | false | null)[]) {
|
|
4
|
-
return args.filter(Boolean).join(" ");
|
|
5
|
-
}
|
|
6
3
|
|
|
4
|
+
import { cn } from "@SH_UI_UTILS@";
|
|
7
5
|
export type SeparatorOrientation = "horizontal" | "vertical";
|
|
8
6
|
|
|
9
7
|
export interface SeparatorProps
|
|
@@ -33,7 +31,7 @@ export const Separator = React.forwardRef<HTMLDivElement, SeparatorProps>(
|
|
|
33
31
|
aria-orientation={decorative ? undefined : orientation}
|
|
34
32
|
aria-hidden={decorative || undefined}
|
|
35
33
|
data-orientation={orientation}
|
|
36
|
-
className={
|
|
34
|
+
className={cn("bg-border shrink-0", sizing, className)}
|
|
37
35
|
{...props}
|
|
38
36
|
/>
|
|
39
37
|
);
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import "./styles.css";
|
|
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 type SeparatorOrientation = "horizontal" | "vertical";
|
|
9
7
|
|
|
10
8
|
export interface SeparatorProps
|
|
@@ -35,7 +33,7 @@ export const Separator = React.forwardRef<HTMLDivElement, SeparatorProps>(
|
|
|
35
33
|
aria-orientation={decorative ? undefined : orientation}
|
|
36
34
|
aria-hidden={decorative || undefined}
|
|
37
35
|
data-orientation={orientation}
|
|
38
|
-
className={
|
|
36
|
+
className={cn(
|
|
39
37
|
"sh-ui-separator",
|
|
40
38
|
`sh-ui-separator--${orientation}`,
|
|
41
39
|
className,
|
|
@@ -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 { ChevronRightIcon, PanelLeftIcon } from "lucide-react";
|
|
5
6
|
import { Popover, PopoverContent, PopoverTrigger } from "../popover";
|
|
6
7
|
|
|
@@ -116,14 +117,12 @@ export function SidebarProvider({
|
|
|
116
117
|
return (
|
|
117
118
|
<SidebarContext.Provider value={value}>
|
|
118
119
|
<div
|
|
119
|
-
className={[
|
|
120
|
-
"[--sidebar-width:16rem] [--sidebar-width-icon:3rem] [--sidebar-width-mobile:18rem]",
|
|
120
|
+
className={cn("[--sidebar-width:16rem] [--sidebar-width-icon:3rem] [--sidebar-width-mobile:18rem]",
|
|
121
121
|
"[--sidebar-bg:var(--background-subtle)] [--sidebar-fg:var(--foreground)] [--sidebar-border:var(--border)]",
|
|
122
122
|
"[--sidebar-accent:var(--background-muted)] [--sidebar-accent-fg:var(--foreground)]",
|
|
123
123
|
"flex w-full",
|
|
124
124
|
embedded ? "min-h-0 h-full" : "min-h-[100svh]",
|
|
125
|
-
className
|
|
126
|
-
].filter(Boolean).join(" ")}
|
|
125
|
+
className)}
|
|
127
126
|
style={style}
|
|
128
127
|
data-embedded={embedded || undefined}
|
|
129
128
|
data-panel-open={activePanel ? "true" : undefined}
|
|
@@ -160,7 +159,7 @@ export function Sidebar({ side = "left", variant = "sidebar", collapsible = "off
|
|
|
160
159
|
if (collapsible === "none") {
|
|
161
160
|
return wrap(
|
|
162
161
|
<aside
|
|
163
|
-
className={
|
|
162
|
+
className={cn(sidebarRoot, "h-[100svh] sticky top-0", className)}
|
|
164
163
|
data-side={side}
|
|
165
164
|
data-variant={variant}
|
|
166
165
|
{...props}
|
|
@@ -180,7 +179,7 @@ export function Sidebar({ side = "left", variant = "sidebar", collapsible = "off
|
|
|
180
179
|
|
|
181
180
|
return wrap(
|
|
182
181
|
<aside
|
|
183
|
-
className={
|
|
182
|
+
className={cn(sidebarRoot, className)}
|
|
184
183
|
data-state={state}
|
|
185
184
|
data-collapsible={state === "collapsed" ? collapsible : ""}
|
|
186
185
|
data-variant={variant}
|
|
@@ -208,13 +207,11 @@ function MobileSidebar({ side, className, openMobile, setOpenMobile, children, .
|
|
|
208
207
|
)}
|
|
209
208
|
<aside
|
|
210
209
|
ref={asideRef}
|
|
211
|
-
className={[
|
|
212
|
-
"fixed top-0 bottom-0 w-[var(--sidebar-width-mobile)] z-[var(--z-overlay)] transition-transform duration-[var(--duration-slow)] flex flex-col bg-[var(--sidebar-bg)] text-[var(--sidebar-fg)] motion-reduce:transition-none",
|
|
210
|
+
className={cn("fixed top-0 bottom-0 w-[var(--sidebar-width-mobile)] z-[var(--z-overlay)] transition-transform duration-[var(--duration-slow)] flex flex-col bg-[var(--sidebar-bg)] text-[var(--sidebar-fg)] motion-reduce:transition-none",
|
|
213
211
|
side === "left"
|
|
214
212
|
? "left-0 border-r border-[var(--sidebar-border)] data-[state=open]:translate-x-0 data-[state=closed]:-translate-x-full"
|
|
215
213
|
: "right-0 border-l border-[var(--sidebar-border)] data-[state=open]:translate-x-0 data-[state=closed]:translate-x-full",
|
|
216
|
-
className
|
|
217
|
-
].filter(Boolean).join(" ")}
|
|
214
|
+
className)}
|
|
218
215
|
data-side={side}
|
|
219
216
|
data-state={openMobile ? "open" : "closed"}
|
|
220
217
|
role="dialog"
|
|
@@ -236,10 +233,8 @@ export function SidebarTrigger({ className, onClick, ...props }: SidebarTriggerP
|
|
|
236
233
|
<button
|
|
237
234
|
type="button"
|
|
238
235
|
aria-label="Toggle Sidebar"
|
|
239
|
-
className={[
|
|
240
|
-
|
|
241
|
-
className,
|
|
242
|
-
].filter(Boolean).join(" ")}
|
|
236
|
+
className={cn("inline-flex items-center justify-center w-8 h-8 border border-transparent bg-transparent text-foreground-muted rounded-[calc(var(--radius)-2px)] cursor-pointer transition-[background-color,color,border-color] duration-[var(--duration-fast)] hover:bg-[var(--sidebar-accent)] hover:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-foreground focus-visible:outline-offset-2 motion-reduce:transition-none",
|
|
237
|
+
className)}
|
|
243
238
|
onClick={(e) => { onClick?.(e); toggleSidebar(); }}
|
|
244
239
|
{...props}
|
|
245
240
|
>
|
|
@@ -267,10 +262,8 @@ export function SidebarPanel({ id, className, children, ...props }: SidebarPanel
|
|
|
267
262
|
return (
|
|
268
263
|
<aside
|
|
269
264
|
ref={ref}
|
|
270
|
-
className={[
|
|
271
|
-
|
|
272
|
-
className,
|
|
273
|
-
].filter(Boolean).join(" ")}
|
|
265
|
+
className={cn("[--sidebar-panel-width:20rem] flex flex-col w-[var(--sidebar-panel-width)] shrink-0 bg-background border-r border-[var(--sidebar-border)] relative z-[4] overflow-hidden animate-[sh-ui-sidebar-panel-in_180ms_ease-out] data-[state=closed]:hidden max-md:fixed max-md:top-0 max-md:bottom-0 max-md:left-0 max-md:w-[min(var(--sidebar-panel-width),90vw)] max-md:z-[var(--z-modal)] max-md:shadow-[0_10px_30px_rgba(0,0,0,0.15)] motion-reduce:animate-none",
|
|
266
|
+
className)}
|
|
274
267
|
data-state={open ? "open" : "closed"}
|
|
275
268
|
role={isMobile ? "dialog" : undefined}
|
|
276
269
|
aria-modal={open && isMobile ? "true" : undefined}
|
|
@@ -293,7 +286,7 @@ export function SidebarPanel({ id, className, children, ...props }: SidebarPanel
|
|
|
293
286
|
export function SidebarPanelHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
294
287
|
return (
|
|
295
288
|
<div
|
|
296
|
-
className={
|
|
289
|
+
className={cn("flex items-center gap-[var(--space-2)] py-3.5 px-[var(--space-4)] border-b border-[var(--sidebar-border)] font-semibold text-[0.9375rem]", className)}
|
|
297
290
|
{...props}
|
|
298
291
|
/>
|
|
299
292
|
);
|
|
@@ -302,58 +295,56 @@ export function SidebarPanelHeader({ className, ...props }: React.HTMLAttributes
|
|
|
302
295
|
export function SidebarPanelContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
303
296
|
return (
|
|
304
297
|
<div
|
|
305
|
-
className={
|
|
298
|
+
className={cn("flex-1 min-h-0 overflow-y-auto py-[var(--space-3)] px-[var(--space-4)] pb-[var(--space-4)]", className)}
|
|
306
299
|
{...props}
|
|
307
300
|
/>
|
|
308
301
|
);
|
|
309
302
|
}
|
|
310
303
|
|
|
311
304
|
export function SidebarInset({ className, ...props }: React.HTMLAttributes<HTMLElement>) {
|
|
312
|
-
return <main className={
|
|
305
|
+
return <main className={cn("flex-1 min-w-0 bg-background flex flex-col", className)} {...props} />;
|
|
313
306
|
}
|
|
314
307
|
|
|
315
308
|
export function SidebarHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
316
|
-
return <div className={
|
|
309
|
+
return <div className={cn("flex flex-col gap-[var(--space-2)] p-[var(--space-2)] overflow-hidden", className)} {...props} />;
|
|
317
310
|
}
|
|
318
311
|
|
|
319
312
|
export function SidebarFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
320
|
-
return <div className={
|
|
313
|
+
return <div className={cn("flex flex-col gap-[var(--space-2)] p-[var(--space-2)] overflow-hidden", className)} {...props} />;
|
|
321
314
|
}
|
|
322
315
|
|
|
323
316
|
export function SidebarContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
324
|
-
return <div className={
|
|
317
|
+
return <div className={cn("flex flex-col flex-1 min-h-0 overflow-y-auto gap-0", className)} {...props} />;
|
|
325
318
|
}
|
|
326
319
|
|
|
327
320
|
export function SidebarSeparator({ className, ...props }: React.HTMLAttributes<HTMLHRElement>) {
|
|
328
|
-
return <hr className={
|
|
321
|
+
return <hr className={cn("my-[var(--space-1)] mx-[var(--space-2)] border-0 border-t border-[var(--sidebar-border)] w-auto", className)} {...props} />;
|
|
329
322
|
}
|
|
330
323
|
|
|
331
324
|
export function SidebarGroup({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
332
|
-
return <div className={
|
|
325
|
+
return <div className={cn("flex flex-col p-[var(--space-2)] min-w-0", className)} {...props} />;
|
|
333
326
|
}
|
|
334
327
|
|
|
335
328
|
export function SidebarGroupLabel({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
336
329
|
return (
|
|
337
330
|
<div
|
|
338
|
-
className={[
|
|
339
|
-
|
|
340
|
-
className,
|
|
341
|
-
].filter(Boolean).join(" ")}
|
|
331
|
+
className={cn("flex items-center h-8 px-[var(--space-2)] text-[length:var(--text-xs)] font-medium text-foreground-muted rounded-[calc(var(--radius)-2px)] [[data-state=collapsed][data-collapsible=icon]_&]:hidden",
|
|
332
|
+
className)}
|
|
342
333
|
{...props}
|
|
343
334
|
/>
|
|
344
335
|
);
|
|
345
336
|
}
|
|
346
337
|
|
|
347
338
|
export function SidebarGroupContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
348
|
-
return <div className={
|
|
339
|
+
return <div className={cn("w-full text-[length:var(--text-sm)]", className)} {...props} />;
|
|
349
340
|
}
|
|
350
341
|
|
|
351
342
|
export function SidebarMenu({ className, ...props }: React.HTMLAttributes<HTMLUListElement>) {
|
|
352
|
-
return <ul className={
|
|
343
|
+
return <ul className={cn("list-none m-0 p-0 flex flex-col min-w-0 gap-0", className)} {...props} />;
|
|
353
344
|
}
|
|
354
345
|
|
|
355
346
|
export function SidebarMenuItem({ className, ...props }: React.HTMLAttributes<HTMLLIElement>) {
|
|
356
|
-
return <li className={
|
|
347
|
+
return <li className={cn("relative m-0", className)} {...props} />;
|
|
357
348
|
}
|
|
358
349
|
|
|
359
350
|
export interface SidebarMenuButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
@@ -385,14 +376,14 @@ export const SidebarMenuButton = React.forwardRef<HTMLButtonElement, SidebarMenu
|
|
|
385
376
|
if (!e.defaultPrevented && panelId != null && ctx) ctx.setActivePanel(panelId);
|
|
386
377
|
}, [onClick, panelId, ctx]);
|
|
387
378
|
|
|
388
|
-
const cls =
|
|
379
|
+
const cls = cn(menuButtonBase, menuButtonSize[size], className);
|
|
389
380
|
|
|
390
381
|
if (asChild && React.isValidElement(children)) {
|
|
391
382
|
const child = children as React.ReactElement<Record<string, unknown>>;
|
|
392
383
|
const merged: Record<string, unknown> = {
|
|
393
384
|
...props,
|
|
394
385
|
onClick: handleClick,
|
|
395
|
-
className:
|
|
386
|
+
className: cn((child.props.className as string) || "", cls),
|
|
396
387
|
"data-active": resolvedIsActive || undefined,
|
|
397
388
|
};
|
|
398
389
|
return React.cloneElement(child, merged);
|
|
@@ -409,17 +400,15 @@ export const SidebarMenuButton = React.forwardRef<HTMLButtonElement, SidebarMenu
|
|
|
409
400
|
export function SidebarMenuSub({ className, ...props }: React.HTMLAttributes<HTMLUListElement>) {
|
|
410
401
|
return (
|
|
411
402
|
<ul
|
|
412
|
-
className={[
|
|
413
|
-
|
|
414
|
-
className,
|
|
415
|
-
].filter(Boolean).join(" ")}
|
|
403
|
+
className={cn("list-none mt-0.5 ml-3.5 pt-0.5 pr-0 pb-0.5 pl-2.5 border-l border-[var(--sidebar-border)] flex flex-col gap-0.5 min-w-0 [[data-state=collapsed][data-collapsible=icon]_&]:hidden",
|
|
404
|
+
className)}
|
|
416
405
|
{...props}
|
|
417
406
|
/>
|
|
418
407
|
);
|
|
419
408
|
}
|
|
420
409
|
|
|
421
410
|
export function SidebarMenuSubItem({ className, ...props }: React.HTMLAttributes<HTMLLIElement>) {
|
|
422
|
-
return <li className={
|
|
411
|
+
return <li className={cn("relative", className)} {...props} />;
|
|
423
412
|
}
|
|
424
413
|
|
|
425
414
|
export interface SidebarMenuSubButtonProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
@@ -436,13 +425,13 @@ export const SidebarMenuSubButton = React.forwardRef<HTMLAnchorElement, SidebarM
|
|
|
436
425
|
function SidebarMenuSubButton({ className, isActive, size = "md", asChild, sectionId, children, ...props }, ref) {
|
|
437
426
|
const tocActive = useTOCActiveId();
|
|
438
427
|
const resolvedIsActive = isActive ?? (sectionId != null ? tocActive === sectionId : undefined);
|
|
439
|
-
const cls =
|
|
428
|
+
const cls = cn(menuSubButtonBase, size === "sm" && "text-[length:var(--text-xs)]", className);
|
|
440
429
|
|
|
441
430
|
if (asChild && React.isValidElement(children)) {
|
|
442
431
|
const child = children as React.ReactElement<Record<string, unknown>>;
|
|
443
432
|
const merged: Record<string, unknown> = {
|
|
444
433
|
...props,
|
|
445
|
-
className:
|
|
434
|
+
className: cn((child.props.className as string) || "", cls),
|
|
446
435
|
"data-active": resolvedIsActive || undefined,
|
|
447
436
|
};
|
|
448
437
|
return React.cloneElement(child, merged);
|
|
@@ -503,7 +492,7 @@ export interface SidebarCollapsibleTriggerProps extends React.ButtonHTMLAttribut
|
|
|
503
492
|
|
|
504
493
|
export function SidebarCollapsibleTrigger({ className, size = "md", children, onClick, ...props }: SidebarCollapsibleTriggerProps) {
|
|
505
494
|
const { open, toggle, flyoutMode, flyoutOpen } = useCollapsible();
|
|
506
|
-
const cls =
|
|
495
|
+
const cls = cn(menuButtonBase, menuButtonSize[size], className);
|
|
507
496
|
const isOpen = flyoutMode ? flyoutOpen : open;
|
|
508
497
|
|
|
509
498
|
const content = (
|