banhaten 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -1
- package/CONTRIBUTING.md +6 -4
- package/README.md +4 -2
- package/docs/design-spacing.md +13 -0
- package/docs/design-system/README.md +2 -0
- package/docs/design-system/appearances/default.md +1 -1
- package/docs/design-system/appearances/rounded.md +1 -1
- package/docs/design-system/appearances/sharp.md +1 -1
- package/docs/design-system/component-showcase-consistency-report.md +5 -5
- package/docs/design-system/components/README.md +15 -0
- package/docs/design-system/components/accordion.md +1 -1
- package/docs/design-system/components/activity-feed.md +1 -1
- package/docs/design-system/components/activity-heatmap.md +1 -1
- package/docs/design-system/components/agent-input.md +85 -0
- package/docs/design-system/components/alert-dialog.md +1 -1
- package/docs/design-system/components/alert.md +10 -4
- package/docs/design-system/components/app-header.md +97 -0
- package/docs/design-system/components/approval-card.md +134 -0
- package/docs/design-system/components/attribute.md +14 -2
- package/docs/design-system/components/avatar.md +1 -1
- package/docs/design-system/components/badge.md +1 -1
- package/docs/design-system/components/banner.md +1 -1
- package/docs/design-system/components/breadcrumbs.md +8 -3
- package/docs/design-system/components/button-group.md +1 -1
- package/docs/design-system/components/button.md +8 -5
- package/docs/design-system/components/card.md +15 -1
- package/docs/design-system/components/catalog-components.md +1 -1
- package/docs/design-system/components/chart.md +95 -24
- package/docs/design-system/components/checkbox.md +1 -1
- package/docs/design-system/components/collapsible.md +20 -6
- package/docs/design-system/components/command.md +1 -1
- package/docs/design-system/components/context-menu.md +1 -1
- package/docs/design-system/components/date-picker.md +1 -1
- package/docs/design-system/components/file-upload.md +1 -1
- package/docs/design-system/components/hover-card.md +1 -1
- package/docs/design-system/components/inline-citations.md +93 -0
- package/docs/design-system/components/input-group.md +1 -1
- package/docs/design-system/components/input.md +59 -3
- package/docs/design-system/components/item.md +1 -1
- package/docs/design-system/components/kbd.md +6 -4
- package/docs/design-system/components/menu.md +35 -4
- package/docs/design-system/components/menubar.md +1 -1
- package/docs/design-system/components/modal.md +2 -2
- package/docs/design-system/components/native-select.md +1 -1
- package/docs/design-system/components/navigation-menu.md +1 -1
- package/docs/design-system/components/onboarding-step-list-item.md +1 -1
- package/docs/design-system/components/page-header.md +58 -17
- package/docs/design-system/components/pagination.md +2 -2
- package/docs/design-system/components/popover.md +1 -1
- package/docs/design-system/components/progress-slider.md +1 -1
- package/docs/design-system/components/radio-card.md +1 -1
- package/docs/design-system/components/radio-group.md +1 -1
- package/docs/design-system/components/resizable.md +1 -1
- package/docs/design-system/components/rolling-count.md +61 -0
- package/docs/design-system/components/scroll-area.md +1 -1
- package/docs/design-system/components/select.md +12 -2
- package/docs/design-system/components/sheet.md +1 -1
- package/docs/design-system/components/shimmer-text.md +67 -0
- package/docs/design-system/components/sidebar.md +75 -8
- package/docs/design-system/components/skeleton.md +2 -2
- package/docs/design-system/components/slideout.md +1 -1
- package/docs/design-system/components/slider.md +2 -2
- package/docs/design-system/components/social-button.md +2 -2
- package/docs/design-system/components/streaming-text.md +82 -0
- package/docs/design-system/components/table.md +103 -21
- package/docs/design-system/components/tabs.md +25 -6
- package/docs/design-system/components/tag.md +1 -1
- package/docs/design-system/components/task-list.md +95 -0
- package/docs/design-system/components/textarea.md +1 -1
- package/docs/design-system/components/thinking-reasoning.md +72 -0
- package/docs/design-system/components/thinking-state.md +67 -0
- package/docs/design-system/components/timeline.md +1 -1
- package/docs/design-system/components/toast.md +1 -1
- package/docs/design-system/components/toggle.md +2 -2
- package/docs/design-system/components/toolbar.md +11 -6
- package/docs/design-system/components/tooltip.md +6 -4
- package/docs/design-system/density-and-elevation.md +16 -16
- package/docs/design-system/design-system-test-missing-items.md +8 -8
- package/docs/design-system/installation.md +2 -0
- package/docs/design-system/tabs.md +2 -1
- package/docs/design-system/template-gap-audit.md +32 -0
- package/docs/design-system/templates.md +59 -0
- package/docs/design-system/token-governance.md +15 -2
- package/package.json +2 -2
- package/registry/components/accordion.tsx +2 -2
- package/registry/components/agent-input-parts.tsx +552 -0
- package/registry/components/agent-input-state.ts +156 -0
- package/registry/components/agent-input.css +307 -0
- package/registry/components/agent-input.tsx +382 -0
- package/registry/components/alert-dialog.tsx +2 -2
- package/registry/components/alert.tsx +23 -7
- package/registry/components/app-header.tsx +151 -0
- package/registry/components/approval-card.css +409 -0
- package/registry/components/approval-card.tsx +401 -0
- package/registry/components/approval-frame.tsx +108 -0
- package/registry/components/approval-questions.tsx +559 -0
- package/registry/components/attribute.tsx +48 -13
- package/registry/components/autocomplete.tsx +15 -68
- package/registry/components/avatar.tsx +2 -2
- package/registry/components/badge.tsx +8 -7
- package/registry/components/button-group.tsx +2 -2
- package/registry/components/button.tsx +19 -14
- package/registry/components/card.tsx +18 -5
- package/registry/components/chart-block-data.ts +177 -0
- package/registry/components/chart-block.css +171 -0
- package/registry/components/chart-block.tsx +260 -0
- package/registry/components/chart-interactions.ts +123 -0
- package/registry/components/chart-options.cartesian.ts +162 -0
- package/registry/components/chart-options.paint.ts +99 -0
- package/registry/components/chart-options.parts.ts +72 -0
- package/registry/components/chart-options.radial.ts +109 -0
- package/registry/components/chart-options.ts +44 -0
- package/registry/components/chart-options.types.ts +67 -0
- package/registry/components/chart.tsx +1 -1
- package/registry/components/checkbox.tsx +6 -6
- package/registry/components/collapsible.tsx +43 -3
- package/registry/components/command.tsx +1 -1
- package/registry/components/context-menu.tsx +1 -1
- package/registry/components/data-chart.tsx +40 -0
- package/registry/components/date-picker.tsx +9 -9
- package/registry/components/echart-theme.ts +246 -0
- package/registry/components/echart.css +49 -0
- package/registry/components/echart.tsx +178 -0
- package/registry/components/expanded/Breadcrumbs.tsx +5 -1
- package/registry/components/expanded/PageHeader.tsx +67 -24
- package/registry/components/expanded/Table.tsx +60 -22
- package/registry/components/expanded/activityFeed.css +2 -2
- package/registry/components/expanded/activityHeatmap.css +1 -1
- package/registry/components/expanded/banner.css +2 -2
- package/registry/components/expanded/breadcrumbs.css +19 -2
- package/registry/components/expanded/catalogComponentsShowcase.css +1 -1
- package/registry/components/expanded/fileUpload.css +7 -7
- package/registry/components/expanded/onboardingStepListItem.css +2 -2
- package/registry/components/expanded/pageHeader.css +38 -44
- package/registry/components/expanded/slideout.css +4 -4
- package/registry/components/expanded/table.css +58 -9
- package/registry/components/expanded/timeline.css +1 -1
- package/registry/components/hover-card.tsx +1 -1
- package/registry/components/inline-citations.css +126 -0
- package/registry/components/inline-citations.tsx +292 -0
- package/registry/components/input-group.tsx +4 -4
- package/registry/components/input.tsx +150 -137
- package/registry/components/item.tsx +1 -1
- package/registry/components/kbd.tsx +3 -2
- package/registry/components/menu.tsx +117 -12
- package/registry/components/menubar.tsx +2 -2
- package/registry/components/modal.tsx +3 -3
- package/registry/components/native-select.tsx +4 -4
- package/registry/components/navigation-menu.tsx +2 -2
- package/registry/components/pagination.tsx +4 -4
- package/registry/components/popover.tsx +3 -3
- package/registry/components/progress-slider.tsx +1 -1
- package/registry/components/radio-card.tsx +7 -7
- package/registry/components/radio-group.tsx +2 -2
- package/registry/components/resizable.tsx +2 -2
- package/registry/components/rolling-count.css +37 -0
- package/registry/components/rolling-count.tsx +110 -0
- package/registry/components/scroll-area.tsx +1 -1
- package/registry/components/select.tsx +15 -10
- package/registry/components/sheet.tsx +2 -2
- package/registry/components/shimmer-text.css +69 -0
- package/registry/components/shimmer-text.tsx +43 -0
- package/registry/components/sidebar.tsx +528 -223
- package/registry/components/skeleton.tsx +1 -1
- package/registry/components/slider.tsx +2 -2
- package/registry/components/social-button.tsx +1 -1
- package/registry/components/streaming-text.css +45 -0
- package/registry/components/streaming-text.tsx +165 -0
- package/registry/components/table-elements.tsx +164 -5
- package/registry/components/tabs.css +32 -4
- package/registry/components/tabs.tsx +5 -1
- package/registry/components/tag.tsx +1 -1
- package/registry/components/task-list.css +328 -0
- package/registry/components/task-list.tsx +429 -0
- package/registry/components/textarea.tsx +4 -4
- package/registry/components/thinking-reasoning.css +178 -0
- package/registry/components/thinking-reasoning.tsx +253 -0
- package/registry/components/thinking-state.css +8 -0
- package/registry/components/thinking-state.tsx +46 -0
- package/registry/components/toast.tsx +1 -1
- package/registry/components/toggle.tsx +2 -2
- package/registry/components/toolbar.tsx +6 -6
- package/registry/components/tooltip.tsx +6 -4
- package/registry/examples/agent-input-demo.tsx +90 -0
- package/registry/examples/app-header-demo.tsx +40 -0
- package/registry/examples/approval-card-demo.tsx +83 -0
- package/registry/examples/button-demo.tsx +3 -0
- package/registry/examples/chart-block-demo.tsx +5 -0
- package/registry/examples/chart-demo.tsx +6 -21
- package/registry/examples/collection-filter-bar-demo.tsx +1 -1
- package/registry/examples/control-density-contract-demo.tsx +5 -1
- package/registry/examples/inline-citations-demo.tsx +31 -0
- package/registry/examples/input-actions-demo.tsx +36 -0
- package/registry/examples/menu-demo.tsx +1 -1
- package/registry/examples/popover-demo.tsx +1 -0
- package/registry/examples/rolling-count-demo.tsx +39 -0
- package/registry/examples/shimmer-text-demo.tsx +20 -0
- package/registry/examples/streaming-text-demo.tsx +28 -0
- package/registry/examples/task-list-demo.tsx +74 -0
- package/registry/examples/thinking-reasoning-demo.tsx +74 -0
- package/registry/examples/thinking-state-demo.tsx +13 -0
- package/registry/guidance/charts.LICENSE.txt +24 -0
- package/registry/hooks/use-controllable-state.ts +33 -0
- package/registry/hooks/use-listbox-navigation.ts +73 -0
- package/registry/hooks/use-motion-end.ts +55 -0
- package/registry/hooks/use-reduced-motion.ts +28 -0
- package/registry/index.json +1808 -190
- package/registry/styles/globals.css +992 -1088
- package/registry.json +385 -10
- package/schema/registry.schema.json +5 -1
- package/schema/tokens.schema.json +8 -4
- package/src/cli/file-transaction.js +15 -8
- package/src/cli/index.js +22 -29
- package/tokens/banhaten.tokens.json +490 -192
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ChevronRightIcon,
|
|
9
9
|
ChevronsUpDownIcon,
|
|
10
10
|
FolderIcon,
|
|
11
|
+
MoreHorizontalIcon,
|
|
11
12
|
PanelLeftIcon,
|
|
12
13
|
SearchIcon,
|
|
13
14
|
SparklesIcon,
|
|
@@ -22,10 +23,13 @@ import {
|
|
|
22
23
|
} from "@/components/ui/tooltip"
|
|
23
24
|
import { cn } from "@/lib/utils"
|
|
24
25
|
|
|
26
|
+
type SidebarSize = "default" | "comfortable"
|
|
27
|
+
|
|
25
28
|
type SidebarContextValue = {
|
|
26
29
|
collapsed: boolean
|
|
27
30
|
dir?: "ltr" | "rtl"
|
|
28
31
|
setCollapsed: (collapsed: boolean) => void
|
|
32
|
+
size: SidebarSize
|
|
29
33
|
toggle: () => void
|
|
30
34
|
}
|
|
31
35
|
|
|
@@ -34,6 +38,7 @@ type SidebarProviderProps = React.ComponentProps<"div"> & {
|
|
|
34
38
|
defaultCollapsed?: boolean
|
|
35
39
|
dir?: "ltr" | "rtl"
|
|
36
40
|
onCollapsedChange?: (collapsed: boolean) => void
|
|
41
|
+
size?: SidebarSize
|
|
37
42
|
}
|
|
38
43
|
type SidebarProps = React.ComponentProps<"aside"> & {
|
|
39
44
|
side?: "start" | "end"
|
|
@@ -45,10 +50,11 @@ type SidebarHeaderActionProps = React.ComponentProps<"button"> & {
|
|
|
45
50
|
type SidebarHeaderBrandProps = React.ComponentProps<"div"> & {
|
|
46
51
|
brand?: React.ReactNode
|
|
47
52
|
collapseAction?: React.ReactNode | false
|
|
48
|
-
logo?: React.ReactNode
|
|
53
|
+
logo?: React.ReactNode | false
|
|
49
54
|
onSearchClick?: React.MouseEventHandler<HTMLButtonElement>
|
|
50
55
|
searchAction?: React.ReactNode | false
|
|
51
56
|
searchLabel?: string
|
|
57
|
+
subtitle?: React.ReactNode
|
|
52
58
|
}
|
|
53
59
|
type SidebarWorkspaceVariant = "actions" | "card"
|
|
54
60
|
type SidebarHeaderWorkspaceSwitchProps = React.ComponentProps<"div"> & {
|
|
@@ -63,12 +69,16 @@ type SidebarHeaderWorkspaceSwitchProps = React.ComponentProps<"div"> & {
|
|
|
63
69
|
variant?: SidebarWorkspaceVariant
|
|
64
70
|
workspaceLabel?: string
|
|
65
71
|
}
|
|
72
|
+
type SidebarFooterProps = SidebarSectionProps & {
|
|
73
|
+
divider?: boolean
|
|
74
|
+
}
|
|
66
75
|
type SidebarFooterUserProps = React.ComponentProps<"button"> & {
|
|
67
|
-
avatar?: React.ReactNode
|
|
76
|
+
avatar?: React.ReactNode | false
|
|
68
77
|
name?: React.ReactNode
|
|
78
|
+
showIdentityPreview?: boolean
|
|
69
79
|
supportText?: React.ReactNode
|
|
70
|
-
trailingIcon?: React.ReactNode
|
|
71
|
-
variant?: "default" | "supporting-text"
|
|
80
|
+
trailingIcon?: React.ReactNode | false
|
|
81
|
+
variant?: "default" | "supporting-text" | "card"
|
|
72
82
|
}
|
|
73
83
|
type SidebarGroupLabelProps = React.ComponentProps<"div"> & {
|
|
74
84
|
actions?: React.ReactNode
|
|
@@ -134,6 +144,7 @@ function SidebarProvider({
|
|
|
134
144
|
defaultCollapsed = false,
|
|
135
145
|
dir,
|
|
136
146
|
onCollapsedChange,
|
|
147
|
+
size = "default",
|
|
137
148
|
...props
|
|
138
149
|
}: SidebarProviderProps) {
|
|
139
150
|
const [uncontrolledCollapsed, setUncontrolledCollapsed] =
|
|
@@ -156,9 +167,10 @@ function SidebarProvider({
|
|
|
156
167
|
collapsed: resolvedCollapsed,
|
|
157
168
|
dir,
|
|
158
169
|
setCollapsed,
|
|
170
|
+
size,
|
|
159
171
|
toggle: () => setCollapsed(!resolvedCollapsed),
|
|
160
172
|
}),
|
|
161
|
-
[dir, resolvedCollapsed, setCollapsed]
|
|
173
|
+
[dir, resolvedCollapsed, setCollapsed, size]
|
|
162
174
|
)
|
|
163
175
|
|
|
164
176
|
return (
|
|
@@ -166,6 +178,7 @@ function SidebarProvider({
|
|
|
166
178
|
<TooltipProvider delayDuration={0}>
|
|
167
179
|
<div
|
|
168
180
|
data-collapsed={resolvedCollapsed ? "true" : "false"}
|
|
181
|
+
data-size={size}
|
|
169
182
|
data-slot="sidebar-provider"
|
|
170
183
|
dir={dir}
|
|
171
184
|
className={cn("relative min-w-0", className)}
|
|
@@ -178,29 +191,66 @@ function SidebarProvider({
|
|
|
178
191
|
)
|
|
179
192
|
}
|
|
180
193
|
|
|
181
|
-
/** The 280px navigation surface that contracts to the Figma 48px icon rail. */
|
|
194
|
+
/** The 280px navigation surface with a 900px minimum height that contracts to the Figma 48px icon rail. */
|
|
182
195
|
const Sidebar = React.forwardRef<HTMLElement, SidebarProps>(function Sidebar(
|
|
183
|
-
{ className, side = "start", ...props },
|
|
196
|
+
{ className, onTransitionEnd, side = "start", ...props },
|
|
184
197
|
ref
|
|
185
198
|
) {
|
|
186
199
|
const context = React.useContext(SidebarContext)
|
|
187
200
|
const collapsed = context?.collapsed ?? false
|
|
188
201
|
const dir = context?.dir
|
|
202
|
+
const size = context?.size ?? "default"
|
|
203
|
+
const [overflowVisible, setOverflowVisible] = React.useState(collapsed)
|
|
204
|
+
const previousCollapsed = React.useRef(collapsed)
|
|
205
|
+
|
|
206
|
+
React.useEffect(() => {
|
|
207
|
+
if (previousCollapsed.current === collapsed) return
|
|
208
|
+
previousCollapsed.current = collapsed
|
|
209
|
+
|
|
210
|
+
if (!collapsed) {
|
|
211
|
+
setOverflowVisible(false)
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const prefersReducedMotion =
|
|
216
|
+
typeof window !== "undefined" &&
|
|
217
|
+
typeof window.matchMedia === "function" &&
|
|
218
|
+
window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
|
219
|
+
|
|
220
|
+
setOverflowVisible(prefersReducedMotion)
|
|
221
|
+
}, [collapsed])
|
|
189
222
|
|
|
190
223
|
return (
|
|
191
224
|
<aside
|
|
192
225
|
data-collapsed={collapsed ? "true" : "false"}
|
|
226
|
+
data-overflow-visible={overflowVisible ? "true" : "false"}
|
|
193
227
|
data-side={side}
|
|
228
|
+
data-size={size}
|
|
194
229
|
data-slot="sidebar"
|
|
195
230
|
dir={dir}
|
|
196
231
|
ref={ref}
|
|
197
232
|
className={cn(
|
|
198
|
-
"group/sidebar flex h-full min-h-[var(--bh-
|
|
233
|
+
"group/sidebar flex h-full min-h-[var(--bh-sidebar-min-height)] w-[var(--bh-sidebar-width)] max-w-full shrink-0 flex-col overflow-hidden bg-[var(--bh-sidebar-bg)] text-[var(--bh-content-default)] transition-[width,background-color] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] will-change-[width] motion-reduce:transition-none",
|
|
199
234
|
"border-e border-[var(--bh-sidebar-border)]",
|
|
200
235
|
"data-[collapsed=true]:w-[var(--bh-sidebar-width-collapsed)] data-[collapsed=true]:bg-[var(--bh-sidebar-bg-collapsed)]",
|
|
236
|
+
collapsed && overflowVisible && "overflow-visible",
|
|
201
237
|
side === "end" && "ms-auto border-e-0 border-s",
|
|
238
|
+
// Comfortable, expanded: the ATS360 shell rail's 1px inside stroke on all four sides, an outline inset by its own
|
|
239
|
+
// width so it takes no width and draws above the header and footer fills.
|
|
240
|
+
size === "comfortable" &&
|
|
241
|
+
"data-[collapsed=false]:border-0 data-[collapsed=false]:[outline:var(--bh-border-width-default)_solid_var(--bh-sidebar-border)] data-[collapsed=false]:[outline-offset:calc(var(--bh-border-width-default)*-1)]",
|
|
202
242
|
className
|
|
203
243
|
)}
|
|
244
|
+
onTransitionEnd={(event) => {
|
|
245
|
+
onTransitionEnd?.(event)
|
|
246
|
+
if (
|
|
247
|
+
!event.defaultPrevented &&
|
|
248
|
+
event.currentTarget === event.target &&
|
|
249
|
+
event.propertyName === "width"
|
|
250
|
+
) {
|
|
251
|
+
setOverflowVisible(collapsed)
|
|
252
|
+
}
|
|
253
|
+
}}
|
|
204
254
|
{...props}
|
|
205
255
|
/>
|
|
206
256
|
)
|
|
@@ -212,8 +262,9 @@ function SidebarHeader({ className, ...props }: SidebarSectionProps) {
|
|
|
212
262
|
<div
|
|
213
263
|
data-slot="sidebar-header"
|
|
214
264
|
className={cn(
|
|
215
|
-
"flex shrink-0 flex-col items-
|
|
216
|
-
"group-data-[collapsed=true]/sidebar:
|
|
265
|
+
"flex shrink-0 flex-col items-center gap-[var(--bh-space-lg-10)] overflow-hidden bg-[var(--bh-sidebar-bg)] p-[var(--bh-sidebar-padding)] transition-[padding] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
266
|
+
"group-data-[collapsed=true]/sidebar:px-[var(--bh-space-xs-4)] group-data-[collapsed=true]/sidebar:py-[var(--bh-space-md-8)]",
|
|
267
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:px-[var(--bh-sidebar-comfortable-padding)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:pb-[var(--bh-space-none)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:pt-[var(--bh-sidebar-comfortable-padding)]",
|
|
217
268
|
className
|
|
218
269
|
)}
|
|
219
270
|
{...props}
|
|
@@ -237,7 +288,7 @@ const SidebarHeaderAction = React.forwardRef<
|
|
|
237
288
|
type={type}
|
|
238
289
|
className={cn(
|
|
239
290
|
"inline-flex size-[var(--bh-sidebar-header-action-size)] shrink-0 items-center justify-center rounded-[var(--bh-radius-full)] border border-transparent bg-[var(--bh-interactive-ghost-default)] text-[var(--bh-content-default)] outline-none transition-[background-color,border-color,box-shadow,color]",
|
|
240
|
-
"hover:bg-[var(--bh-interactive-ghost-hover)] focus-visible:border-[var(--bh-border-focus)] focus-visible:shadow-[var(--
|
|
291
|
+
"hover:bg-[var(--bh-interactive-ghost-hover)] focus-visible:border-[var(--bh-border-focus)] focus-visible:shadow-[var(--elevation-button-focus)]",
|
|
241
292
|
className
|
|
242
293
|
)}
|
|
243
294
|
{...props}
|
|
@@ -253,7 +304,10 @@ const SidebarHeaderAction = React.forwardRef<
|
|
|
253
304
|
)
|
|
254
305
|
})
|
|
255
306
|
|
|
256
|
-
/**
|
|
307
|
+
/**
|
|
308
|
+
* Brand header with optional search and collapse actions; actions disappear on the icon rail.
|
|
309
|
+
* Pass logo={false} for a text-only brand and subtitle for a stacked product or module line.
|
|
310
|
+
*/
|
|
257
311
|
function SidebarHeaderBrand({
|
|
258
312
|
brand = "Banhaten",
|
|
259
313
|
className,
|
|
@@ -262,63 +316,123 @@ function SidebarHeaderBrand({
|
|
|
262
316
|
onSearchClick,
|
|
263
317
|
searchAction,
|
|
264
318
|
searchLabel = "Search",
|
|
319
|
+
subtitle,
|
|
265
320
|
...props
|
|
266
321
|
}: SidebarHeaderBrandProps) {
|
|
267
322
|
const { collapsed } = useSidebarContext()
|
|
323
|
+
const hasCollapseAction = collapseAction !== false
|
|
324
|
+
const showLogo = logo !== false
|
|
325
|
+
const stacked = subtitle !== undefined && subtitle !== null && subtitle !== false
|
|
326
|
+
|
|
327
|
+
const name = (
|
|
328
|
+
<span
|
|
329
|
+
aria-hidden={collapsed || undefined}
|
|
330
|
+
data-slot="sidebar-brand-name"
|
|
331
|
+
dir="auto"
|
|
332
|
+
className={cn(
|
|
333
|
+
"max-w-[calc(var(--bh-sidebar-width)-var(--bh-space-10xl-80))] truncate opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
334
|
+
"text-[length:var(--bh-text-body-xl-semibold-font-size)] font-[var(--bh-text-body-xl-semibold-font-weight)] leading-[var(--bh-text-body-xl-semibold-line-height)] tracking-[var(--bh-text-body-xl-semibold-letter-spacing)]",
|
|
335
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:text-[length:var(--bh-text-heading-md-semibold-font-size)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:font-[var(--bh-text-heading-md-semibold-font-weight)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:leading-[var(--bh-text-heading-md-semibold-line-height)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:tracking-[var(--bh-text-heading-md-semibold-letter-spacing)]",
|
|
336
|
+
collapsed &&
|
|
337
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
338
|
+
)}
|
|
339
|
+
>
|
|
340
|
+
{brand}
|
|
341
|
+
</span>
|
|
342
|
+
)
|
|
268
343
|
|
|
269
344
|
return (
|
|
270
345
|
<div
|
|
271
346
|
data-collapsed={collapsed ? "true" : "false"}
|
|
272
347
|
data-slot="sidebar-header-brand"
|
|
348
|
+
data-stacked={stacked ? "true" : "false"}
|
|
273
349
|
className={cn(
|
|
274
|
-
"
|
|
275
|
-
collapsed &&
|
|
276
|
-
|
|
350
|
+
"relative h-[var(--bh-sidebar-brand-height)] w-full transition-[width,height] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
351
|
+
stacked && !collapsed && "h-auto",
|
|
352
|
+
collapsed && hasCollapseAction &&
|
|
353
|
+
"h-[calc(var(--bh-sidebar-header-action-size)+var(--bh-space-sm-6)+var(--bh-sidebar-header-action-size))] w-[var(--bh-sidebar-compact-control-size)]",
|
|
354
|
+
collapsed && !hasCollapseAction &&
|
|
355
|
+
"h-[var(--bh-sidebar-header-action-size)] w-[var(--bh-sidebar-compact-control-size)]",
|
|
277
356
|
className
|
|
278
357
|
)}
|
|
279
358
|
{...props}
|
|
280
359
|
>
|
|
281
360
|
<span
|
|
282
361
|
data-slot="sidebar-brand-content"
|
|
283
|
-
className=
|
|
362
|
+
className={cn(
|
|
363
|
+
"absolute start-[var(--bh-space-sm-6)] top-[var(--bh-space-xs-4)] flex min-w-0 items-center gap-[var(--bh-space-md-8)] transition-[inset-inline-start,top,gap] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
364
|
+
stacked && !collapsed &&
|
|
365
|
+
"static items-start px-[var(--bh-space-sm-6)] py-[var(--bh-space-xs-4)] group-data-[size=comfortable]/sidebar:p-[var(--bh-sidebar-comfortable-brand-padding)]",
|
|
366
|
+
collapsed && "start-[var(--bh-space-xs-4)] top-0 gap-0"
|
|
367
|
+
)}
|
|
284
368
|
>
|
|
285
|
-
|
|
286
|
-
data-slot="sidebar-brand-logo"
|
|
287
|
-
className="inline-flex size-[var(--bh-sidebar-header-action-size)] shrink-0 items-center justify-center overflow-hidden rounded-[var(--bh-radius-full)] [&>*]:size-full"
|
|
288
|
-
>
|
|
289
|
-
{logo ?? (
|
|
290
|
-
<span className="inline-flex size-full items-center justify-center bg-[var(--bh-bg-brand-default)] text-[var(--bh-content-on-brand)]">
|
|
291
|
-
<SparklesIcon
|
|
292
|
-
aria-hidden="true"
|
|
293
|
-
className="size-[var(--bh-sidebar-icon-size)]"
|
|
294
|
-
/>
|
|
295
|
-
</span>
|
|
296
|
-
)}
|
|
297
|
-
</span>
|
|
298
|
-
{!collapsed ? (
|
|
369
|
+
{showLogo ? (
|
|
299
370
|
<span
|
|
300
|
-
data-slot="sidebar-brand-
|
|
301
|
-
|
|
302
|
-
className="truncate text-[length:var(--bh-text-body-xl-semibold-font-size)] font-[var(--bh-text-body-xl-semibold-font-weight)] leading-[var(--bh-text-body-xl-semibold-line-height)] tracking-[var(--bh-text-body-xl-semibold-letter-spacing)]"
|
|
371
|
+
data-slot="sidebar-brand-logo"
|
|
372
|
+
className="inline-flex size-[var(--bh-sidebar-header-action-size)] shrink-0 items-center justify-center overflow-hidden rounded-[var(--bh-radius-full)] [&>*]:size-full"
|
|
303
373
|
>
|
|
304
|
-
{
|
|
374
|
+
{logo ?? (
|
|
375
|
+
<span className="inline-flex size-full items-center justify-center bg-[var(--bh-bg-brand-default)] text-[var(--bh-content-on-brand)]">
|
|
376
|
+
<SparklesIcon
|
|
377
|
+
aria-hidden="true"
|
|
378
|
+
className="size-[var(--bh-sidebar-icon-size)]"
|
|
379
|
+
/>
|
|
380
|
+
</span>
|
|
381
|
+
)}
|
|
305
382
|
</span>
|
|
306
383
|
) : null}
|
|
384
|
+
{stacked ? (
|
|
385
|
+
<span
|
|
386
|
+
aria-hidden={collapsed || undefined}
|
|
387
|
+
data-slot="sidebar-brand-text"
|
|
388
|
+
className={cn(
|
|
389
|
+
"flex min-w-0 flex-col gap-[var(--bh-space-xs-4)] opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
390
|
+
collapsed &&
|
|
391
|
+
"pointer-events-none max-w-0 overflow-hidden opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
392
|
+
)}
|
|
393
|
+
>
|
|
394
|
+
{name}
|
|
395
|
+
<span
|
|
396
|
+
data-slot="sidebar-brand-subtitle"
|
|
397
|
+
dir="auto"
|
|
398
|
+
className="max-w-[calc(var(--bh-sidebar-width)-var(--bh-space-10xl-80))] truncate text-[length:var(--bh-text-body-sm-regular-font-size)] font-[var(--bh-text-body-sm-regular-font-weight)] leading-[var(--bh-text-body-sm-regular-line-height)] tracking-[var(--bh-text-body-sm-regular-letter-spacing)] text-[var(--bh-content-subtle)]"
|
|
399
|
+
>
|
|
400
|
+
{subtitle}
|
|
401
|
+
</span>
|
|
402
|
+
</span>
|
|
403
|
+
) : (
|
|
404
|
+
name
|
|
405
|
+
)}
|
|
307
406
|
</span>
|
|
308
407
|
|
|
309
|
-
{
|
|
408
|
+
{searchAction !== false || hasCollapseAction ? (
|
|
310
409
|
<span
|
|
311
410
|
data-slot="sidebar-brand-actions"
|
|
312
|
-
className=
|
|
411
|
+
className={cn(
|
|
412
|
+
"absolute end-[var(--bh-space-xs-4)] top-[calc((var(--bh-sidebar-brand-height)-var(--bh-sidebar-header-action-size))/2)] flex shrink-0 items-center gap-[var(--bh-space-sm-6)] transition-[top,inset-inline-end,gap] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
413
|
+
collapsed && hasCollapseAction &&
|
|
414
|
+
"end-[var(--bh-space-xs-4)] top-[calc(var(--bh-sidebar-header-action-size)+var(--bh-space-sm-6))] gap-0"
|
|
415
|
+
)}
|
|
313
416
|
>
|
|
314
|
-
{searchAction === false
|
|
315
|
-
|
|
316
|
-
|
|
417
|
+
{searchAction === false ? null : (
|
|
418
|
+
<span
|
|
419
|
+
aria-hidden={collapsed || undefined}
|
|
420
|
+
data-slot="sidebar-brand-search-action"
|
|
421
|
+
inert={collapsed ? true : undefined}
|
|
422
|
+
className={cn(
|
|
423
|
+
"inline-flex max-w-[var(--bh-sidebar-header-action-size)] overflow-hidden opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] duration-[var(--bh-sidebar-motion-duration-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
424
|
+
collapsed &&
|
|
425
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)]"
|
|
426
|
+
)}
|
|
427
|
+
>
|
|
428
|
+
{searchAction ?? (
|
|
317
429
|
<SidebarHeaderAction label={searchLabel} onClick={onSearchClick}>
|
|
318
430
|
<SearchIcon aria-hidden="true" />
|
|
319
431
|
</SidebarHeaderAction>
|
|
320
432
|
)}
|
|
321
|
-
|
|
433
|
+
</span>
|
|
434
|
+
)}
|
|
435
|
+
{hasCollapseAction ? collapseAction ?? <SidebarTrigger /> : null}
|
|
322
436
|
</span>
|
|
323
437
|
) : null}
|
|
324
438
|
</div>
|
|
@@ -342,6 +456,7 @@ function SidebarHeaderWorkspaceSwitch({
|
|
|
342
456
|
}: SidebarHeaderWorkspaceSwitchProps) {
|
|
343
457
|
const { collapsed } = useSidebarContext()
|
|
344
458
|
const card = variant === "card"
|
|
459
|
+
const hasCollapseAction = collapseAction !== false
|
|
345
460
|
|
|
346
461
|
const workspaceButton = (
|
|
347
462
|
<button
|
|
@@ -350,20 +465,20 @@ function SidebarHeaderWorkspaceSwitch({
|
|
|
350
465
|
onClick={onWorkspaceClick}
|
|
351
466
|
type="button"
|
|
352
467
|
className={cn(
|
|
353
|
-
"group/workspace
|
|
468
|
+
"group/workspace absolute start-0 top-0 flex min-w-0 items-center overflow-hidden text-start outline-none transition-[width,height,gap,padding,border-radius,background-color,border-color,box-shadow] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
354
469
|
card
|
|
355
470
|
? "h-[var(--bh-sidebar-workspace-card-height)] w-full gap-[var(--bh-space-md-8)] overflow-hidden rounded-[var(--bh-radius-lg-8)] border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-default)] p-[var(--bh-space-sm-6)] hover:bg-[var(--bh-bg-default-hover)] focus-visible:border-[length:var(--bh-border-width-strong)] focus-visible:border-[var(--bh-border-focus)]"
|
|
356
471
|
: "h-[var(--bh-sidebar-compact-control-size)] w-[var(--bh-sidebar-workspace-trigger-width)] max-w-[var(--bh-sidebar-workspace-trigger-max-width)] gap-[var(--bh-space-md-8)] rounded-[var(--bh-radius-md-6)] p-[var(--bh-space-sm-6)] hover:bg-[var(--bh-interactive-ghost-hover)] focus-visible:border-[length:var(--bh-border-width-strong)] focus-visible:border-[var(--bh-border-focus)]",
|
|
357
472
|
collapsed && card &&
|
|
358
|
-
"size-[var(--bh-sidebar-compact-control-size)]
|
|
473
|
+
"size-[var(--bh-sidebar-compact-control-size)] gap-0 px-[var(--bh-space-xxs-2)] py-0",
|
|
359
474
|
collapsed && !card &&
|
|
360
|
-
"size-[var(--bh-sidebar-item-height-collapsed)] max-w-[var(--bh-sidebar-item-height-collapsed)]
|
|
475
|
+
"size-[var(--bh-sidebar-item-height-collapsed)] max-w-[var(--bh-sidebar-item-height-collapsed)] gap-0 px-[var(--bh-space-sm-6)] py-0"
|
|
361
476
|
)}
|
|
362
477
|
>
|
|
363
478
|
<span
|
|
364
479
|
data-slot="sidebar-workspace-image"
|
|
365
480
|
className={cn(
|
|
366
|
-
"inline-flex shrink-0 items-center justify-center overflow-hidden [&>*]:size-full",
|
|
481
|
+
"inline-flex shrink-0 items-center justify-center overflow-hidden transition-[width,height,border-radius] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none [&>*]:size-full",
|
|
367
482
|
card
|
|
368
483
|
? "size-[var(--bh-space-6xl-32)] rounded-[var(--bh-radius-md-6)]"
|
|
369
484
|
: "size-[var(--bh-space-5xl-24)] rounded-[var(--bh-radius-lg-8)]",
|
|
@@ -379,54 +494,75 @@ function SidebarHeaderWorkspaceSwitch({
|
|
|
379
494
|
)}
|
|
380
495
|
</span>
|
|
381
496
|
|
|
382
|
-
{
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
{supportText}
|
|
398
|
-
</span>
|
|
497
|
+
{card ? (
|
|
498
|
+
<span
|
|
499
|
+
aria-hidden={collapsed || undefined}
|
|
500
|
+
className={cn(
|
|
501
|
+
"flex min-w-0 max-w-[var(--bh-sidebar-width)] flex-1 flex-col items-start justify-center overflow-hidden opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
502
|
+
collapsed &&
|
|
503
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
504
|
+
)}
|
|
505
|
+
>
|
|
506
|
+
<span
|
|
507
|
+
data-slot="sidebar-workspace-label"
|
|
508
|
+
dir="auto"
|
|
509
|
+
className="w-full truncate text-[length:var(--bh-text-body-sm-medium-font-size)] font-[var(--bh-text-body-sm-medium-font-weight)] leading-[var(--bh-text-body-sm-medium-line-height)] tracking-[var(--bh-text-body-sm-medium-letter-spacing)]"
|
|
510
|
+
>
|
|
511
|
+
{label}
|
|
399
512
|
</span>
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
>
|
|
407
|
-
{label}
|
|
408
|
-
</span>
|
|
409
|
-
<ChevronDownIcon
|
|
410
|
-
aria-hidden="true"
|
|
411
|
-
className="size-[var(--bh-space-3xl-16)] shrink-0"
|
|
412
|
-
data-rtl-flip="true"
|
|
413
|
-
/>
|
|
513
|
+
<span
|
|
514
|
+
data-slot="sidebar-workspace-support"
|
|
515
|
+
dir="auto"
|
|
516
|
+
className="w-full truncate text-[length:var(--bh-text-body-2xs-regular-font-size)] font-[var(--bh-text-body-2xs-regular-font-weight)] leading-[var(--bh-text-body-2xs-regular-line-height)] tracking-[var(--bh-text-body-2xs-regular-letter-spacing)] text-[var(--bh-content-subtle)]"
|
|
517
|
+
>
|
|
518
|
+
{supportText}
|
|
414
519
|
</span>
|
|
415
|
-
|
|
416
|
-
) :
|
|
520
|
+
</span>
|
|
521
|
+
) : (
|
|
522
|
+
<span
|
|
523
|
+
aria-hidden={collapsed || undefined}
|
|
524
|
+
className={cn(
|
|
525
|
+
"flex min-w-0 max-w-[var(--bh-sidebar-width)] items-center gap-[var(--bh-space-xxs-2)] overflow-hidden opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
526
|
+
collapsed &&
|
|
527
|
+
"pointer-events-none max-w-0 gap-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
528
|
+
)}
|
|
529
|
+
>
|
|
530
|
+
<span
|
|
531
|
+
data-slot="sidebar-workspace-label"
|
|
532
|
+
dir="auto"
|
|
533
|
+
className="truncate text-[length:var(--bh-text-body-sm-medium-font-size)] font-[var(--bh-text-body-sm-medium-font-weight)] leading-[var(--bh-text-body-sm-medium-line-height)] tracking-[var(--bh-text-body-sm-medium-letter-spacing)]"
|
|
534
|
+
>
|
|
535
|
+
{label}
|
|
536
|
+
</span>
|
|
537
|
+
<ChevronDownIcon
|
|
538
|
+
aria-hidden="true"
|
|
539
|
+
className="size-[var(--bh-space-3xl-16)] shrink-0"
|
|
540
|
+
data-rtl-flip="true"
|
|
541
|
+
/>
|
|
542
|
+
</span>
|
|
543
|
+
)}
|
|
544
|
+
|
|
545
|
+
{!card ? (
|
|
417
546
|
<span
|
|
418
547
|
aria-hidden="true"
|
|
419
548
|
data-slot="sidebar-workspace-caret"
|
|
420
|
-
className=
|
|
549
|
+
className={cn(
|
|
550
|
+
"pointer-events-none absolute end-0 top-1/2 inline-flex size-[var(--bh-space-3xl-16)] -translate-y-1/2 items-center justify-center rounded-[var(--bh-radius-full)] border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-default)] opacity-[var(--bh-opacity-0)] transition-opacity duration-[var(--bh-sidebar-motion-duration-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
551
|
+
collapsed &&
|
|
552
|
+
"opacity-[var(--bh-opacity-100)] delay-[var(--bh-sidebar-motion-delay-content)]"
|
|
553
|
+
)}
|
|
421
554
|
>
|
|
422
555
|
<ChevronDownIcon className="size-[var(--bh-space-xl-12)]" />
|
|
423
556
|
</span>
|
|
424
557
|
) : null}
|
|
425
558
|
|
|
426
|
-
{card
|
|
559
|
+
{card ? (
|
|
427
560
|
<ChevronsUpDownIcon
|
|
428
561
|
aria-hidden="true"
|
|
429
|
-
className=
|
|
562
|
+
className={cn(
|
|
563
|
+
"size-[var(--bh-space-3xl-16)] shrink-0 text-[var(--bh-content-muted)] opacity-[var(--bh-opacity-100)] transition-opacity duration-[var(--bh-sidebar-motion-duration-content)] delay-[var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
564
|
+
collapsed && "opacity-[var(--bh-opacity-0)] delay-0"
|
|
565
|
+
)}
|
|
430
566
|
/>
|
|
431
567
|
) : null}
|
|
432
568
|
</button>
|
|
@@ -438,31 +574,58 @@ function SidebarHeaderWorkspaceSwitch({
|
|
|
438
574
|
data-slot="sidebar-header-workspace-switch"
|
|
439
575
|
data-variant={variant}
|
|
440
576
|
className={cn(
|
|
441
|
-
"
|
|
577
|
+
"relative w-full transition-[width,height] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
442
578
|
card
|
|
443
579
|
? "h-[var(--bh-sidebar-workspace-card-height)]"
|
|
444
|
-
: "h-[var(--bh-sidebar-compact-control-size)]
|
|
445
|
-
collapsed && card &&
|
|
446
|
-
|
|
447
|
-
|
|
580
|
+
: "h-[var(--bh-sidebar-compact-control-size)]",
|
|
581
|
+
collapsed && card && hasCollapseAction &&
|
|
582
|
+
"h-[calc(var(--bh-sidebar-compact-control-size)+var(--bh-space-sm-6)+var(--bh-sidebar-header-action-size))] w-[var(--bh-sidebar-compact-control-size)]",
|
|
583
|
+
collapsed && card && !hasCollapseAction &&
|
|
584
|
+
"h-[var(--bh-sidebar-compact-control-size)] w-[var(--bh-sidebar-compact-control-size)]",
|
|
585
|
+
collapsed && !card && hasCollapseAction &&
|
|
586
|
+
"h-[calc(var(--bh-sidebar-item-height-collapsed)+var(--bh-space-sm-6)+var(--bh-sidebar-header-action-size))] w-[var(--bh-sidebar-item-height-collapsed)]",
|
|
587
|
+
collapsed && !card && !hasCollapseAction &&
|
|
588
|
+
"h-[var(--bh-sidebar-item-height-collapsed)] w-[var(--bh-sidebar-item-height-collapsed)]",
|
|
448
589
|
className
|
|
449
590
|
)}
|
|
450
591
|
{...props}
|
|
451
592
|
>
|
|
452
593
|
{workspaceButton}
|
|
453
|
-
{!card &&
|
|
594
|
+
{(!card && searchAction !== false) || hasCollapseAction ? (
|
|
454
595
|
<span
|
|
596
|
+
aria-hidden={(card && !collapsed) || undefined}
|
|
455
597
|
data-slot="sidebar-workspace-actions"
|
|
456
|
-
|
|
598
|
+
inert={card && !collapsed ? true : undefined}
|
|
599
|
+
className={cn(
|
|
600
|
+
"absolute flex shrink-0 items-center gap-[var(--bh-space-sm-6)] transition-[top,inset-inline-end,gap,opacity] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
601
|
+
card
|
|
602
|
+
? "pointer-events-none end-[var(--bh-space-xs-4)] top-[calc((var(--bh-sidebar-workspace-card-height)-var(--bh-sidebar-header-action-size))/2)] opacity-[var(--bh-opacity-0)]"
|
|
603
|
+
: "end-[var(--bh-space-md-8)] top-[calc((var(--bh-sidebar-compact-control-size)-var(--bh-sidebar-header-action-size))/2)] opacity-[var(--bh-opacity-100)]",
|
|
604
|
+
collapsed && card &&
|
|
605
|
+
"pointer-events-auto end-[var(--bh-space-xs-4)] top-[calc(var(--bh-sidebar-compact-control-size)+var(--bh-space-sm-6))] gap-0 opacity-[var(--bh-opacity-100)]",
|
|
606
|
+
collapsed && !card &&
|
|
607
|
+
"end-[var(--bh-space-sm-6)] top-[calc(var(--bh-sidebar-item-height-collapsed)+var(--bh-space-sm-6))] gap-0"
|
|
608
|
+
)}
|
|
457
609
|
>
|
|
458
|
-
{searchAction
|
|
459
|
-
|
|
460
|
-
|
|
610
|
+
{!card && searchAction !== false ? (
|
|
611
|
+
<span
|
|
612
|
+
aria-hidden={collapsed || undefined}
|
|
613
|
+
data-slot="sidebar-workspace-search-action"
|
|
614
|
+
inert={collapsed ? true : undefined}
|
|
615
|
+
className={cn(
|
|
616
|
+
"inline-flex max-w-[var(--bh-sidebar-header-action-size)] overflow-hidden opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] duration-[var(--bh-sidebar-motion-duration-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
617
|
+
collapsed &&
|
|
618
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)]"
|
|
619
|
+
)}
|
|
620
|
+
>
|
|
621
|
+
{searchAction ?? (
|
|
461
622
|
<SidebarHeaderAction label={searchLabel} onClick={onSearchClick}>
|
|
462
623
|
<SearchIcon aria-hidden="true" />
|
|
463
624
|
</SidebarHeaderAction>
|
|
464
625
|
)}
|
|
465
|
-
|
|
626
|
+
</span>
|
|
627
|
+
) : null}
|
|
628
|
+
{hasCollapseAction ? collapseAction ?? <SidebarTrigger /> : null}
|
|
466
629
|
</span>
|
|
467
630
|
) : null}
|
|
468
631
|
</div>
|
|
@@ -475,8 +638,9 @@ function SidebarBody({ className, ...props }: SidebarSectionProps) {
|
|
|
475
638
|
<div
|
|
476
639
|
data-slot="sidebar-body"
|
|
477
640
|
className={cn(
|
|
478
|
-
"min-h-0 flex-1 overflow-auto px-[var(--bh-space-xl-12)] py-0",
|
|
641
|
+
"min-h-0 flex-1 overflow-auto px-[var(--bh-space-xl-12)] py-0 transition-[padding] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
479
642
|
"group-data-[collapsed=true]/sidebar:px-0",
|
|
643
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:flex group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:flex-col group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:gap-[var(--bh-sidebar-comfortable-section-gap)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:px-[var(--bh-sidebar-comfortable-padding)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:pt-[var(--bh-sidebar-comfortable-section-gap)]",
|
|
480
644
|
className
|
|
481
645
|
)}
|
|
482
646
|
{...props}
|
|
@@ -484,14 +648,17 @@ function SidebarBody({ className, ...props }: SidebarSectionProps) {
|
|
|
484
648
|
)
|
|
485
649
|
}
|
|
486
650
|
|
|
487
|
-
/** Bottom-pinned footer with the matching expanded and collapsed padding. */
|
|
488
|
-
function SidebarFooter({ className, ...props }:
|
|
651
|
+
/** Bottom-pinned footer with the matching expanded and collapsed padding; divider={false} drops the top rule. */
|
|
652
|
+
function SidebarFooter({ className, divider = true, ...props }: SidebarFooterProps) {
|
|
489
653
|
return (
|
|
490
654
|
<div
|
|
655
|
+
data-divider={divider ? "true" : "false"}
|
|
491
656
|
data-slot="sidebar-footer"
|
|
492
657
|
className={cn(
|
|
493
|
-
"mt-auto shrink-0
|
|
658
|
+
"mt-auto shrink-0 bg-[var(--bh-sidebar-bg)] px-[var(--bh-sidebar-padding)] py-[var(--bh-space-md-8)] transition-[padding] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
659
|
+
divider && "border-t border-[var(--bh-sidebar-border)]",
|
|
494
660
|
"group-data-[collapsed=true]/sidebar:p-[var(--bh-space-xs-4)]",
|
|
661
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:p-[var(--bh-sidebar-comfortable-padding)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:pt-[var(--bh-sidebar-comfortable-section-gap)]",
|
|
495
662
|
className
|
|
496
663
|
)}
|
|
497
664
|
{...props}
|
|
@@ -509,6 +676,7 @@ const SidebarFooterUser = React.forwardRef<
|
|
|
509
676
|
avatar,
|
|
510
677
|
className,
|
|
511
678
|
name = "Username",
|
|
679
|
+
showIdentityPreview = true,
|
|
512
680
|
supportText = "user@example.com",
|
|
513
681
|
trailingIcon,
|
|
514
682
|
type = "button",
|
|
@@ -518,7 +686,16 @@ const SidebarFooterUser = React.forwardRef<
|
|
|
518
686
|
ref
|
|
519
687
|
) {
|
|
520
688
|
const { collapsed } = useSidebarContext()
|
|
689
|
+
const card = variant === "card"
|
|
521
690
|
const supporting = variant === "supporting-text"
|
|
691
|
+
const showSupport = supporting || card
|
|
692
|
+
// The card treatment is text-only unless an avatar or trailing icon is passed;
|
|
693
|
+
// the collapsed rail always keeps a glyph so the control stays visible.
|
|
694
|
+
const showAvatar =
|
|
695
|
+
collapsed || (avatar !== false && (!card || (avatar !== undefined && avatar !== null)))
|
|
696
|
+
const showTrailing =
|
|
697
|
+
trailingIcon !== false &&
|
|
698
|
+
(!card || (trailingIcon !== undefined && trailingIcon !== null))
|
|
522
699
|
const resolvedLabel =
|
|
523
700
|
ariaLabel ?? (typeof name === "string" ? name : "Open user menu")
|
|
524
701
|
|
|
@@ -531,13 +708,15 @@ const SidebarFooterUser = React.forwardRef<
|
|
|
531
708
|
ref={ref}
|
|
532
709
|
type={type}
|
|
533
710
|
className={cn(
|
|
534
|
-
"flex w-full items-center rounded-[var(--bh-radius-lg-8)] text-start outline-none transition-[background-color,border-color,box-shadow]",
|
|
535
|
-
|
|
536
|
-
? "
|
|
537
|
-
:
|
|
538
|
-
|
|
711
|
+
"group/footer-user relative flex w-full items-center rounded-[var(--bh-radius-lg-8)] text-start outline-none transition-[width,height,gap,padding,border-radius,background-color,border-color,box-shadow] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
712
|
+
card
|
|
713
|
+
? "gap-[var(--bh-space-xs-4)] bg-[var(--bh-sidebar-user-card-bg)] p-[var(--bh-space-md-8)] hover:bg-[var(--bh-sidebar-user-card-bg-hover)]"
|
|
714
|
+
: supporting
|
|
715
|
+
? "h-[var(--bh-space-8xl-48)] gap-[var(--bh-space-xs-4)] p-[var(--bh-space-sm-6)] hover:bg-[var(--bh-interactive-ghost-hover)]"
|
|
716
|
+
: "h-[var(--bh-sidebar-item-height-collapsed)] gap-[var(--bh-space-xs-4)] border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-default)] px-[var(--bh-space-sm-6)] py-[var(--bh-space-md-8)] hover:bg-[var(--bh-bg-default-hover)]",
|
|
717
|
+
"focus-visible:border-[length:var(--bh-border-width-strong)] focus-visible:border-[var(--bh-border-focus)] focus-visible:shadow-[var(--elevation-button-focus)]",
|
|
539
718
|
collapsed &&
|
|
540
|
-
"mx-auto size-[var(--bh-sidebar-compact-control-size)] justify-center gap-0 rounded-[var(--bh-radius-full)] border-0 p-0 hover:bg-[var(--bh-interactive-ghost-hover)]",
|
|
719
|
+
"mx-auto size-[var(--bh-sidebar-compact-control-size)] justify-center gap-0 rounded-[var(--bh-radius-full)] border-0 bg-[var(--bh-interactive-ghost-default)] p-0 hover:bg-[var(--bh-interactive-ghost-hover)]",
|
|
541
720
|
className
|
|
542
721
|
)}
|
|
543
722
|
{...props}
|
|
@@ -545,70 +724,125 @@ const SidebarFooterUser = React.forwardRef<
|
|
|
545
724
|
<span
|
|
546
725
|
data-slot="sidebar-footer-user-content"
|
|
547
726
|
className={cn(
|
|
548
|
-
"flex min-w-0 flex-1 items-center gap-[var(--bh-space-md-8)] px-[var(--bh-space-xxs-2)]",
|
|
549
|
-
|
|
550
|
-
|
|
727
|
+
"flex min-w-0 flex-1 items-center gap-[var(--bh-space-md-8)] overflow-hidden px-[var(--bh-space-xxs-2)] transition-[width,height,gap,padding] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
728
|
+
card && "px-[var(--bh-space-none)]",
|
|
729
|
+
collapsed && "gap-0 p-0"
|
|
551
730
|
)}
|
|
552
731
|
>
|
|
732
|
+
{showAvatar ? (
|
|
733
|
+
<span
|
|
734
|
+
data-slot="sidebar-footer-user-avatar"
|
|
735
|
+
className={cn(
|
|
736
|
+
"inline-flex shrink-0 items-center justify-center overflow-hidden rounded-[var(--bh-radius-full)] transition-[width,height,border-radius] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none [&>*]:size-full",
|
|
737
|
+
supporting || card ? "size-[var(--bh-space-6xl-32)]" : "size-[var(--bh-space-5xl-24)]",
|
|
738
|
+
collapsed && "size-[var(--bh-sidebar-compact-control-size)]"
|
|
739
|
+
)}
|
|
740
|
+
>
|
|
741
|
+
{avatar === false || avatar === undefined || avatar === null ? (
|
|
742
|
+
<UserIcon
|
|
743
|
+
aria-hidden="true"
|
|
744
|
+
className="size-[var(--bh-sidebar-icon-size)]"
|
|
745
|
+
/>
|
|
746
|
+
) : (
|
|
747
|
+
avatar
|
|
748
|
+
)}
|
|
749
|
+
</span>
|
|
750
|
+
) : null}
|
|
553
751
|
<span
|
|
554
|
-
|
|
752
|
+
aria-hidden={collapsed || undefined}
|
|
753
|
+
data-slot="sidebar-footer-user-text"
|
|
555
754
|
className={cn(
|
|
556
|
-
"
|
|
557
|
-
|
|
558
|
-
collapsed &&
|
|
755
|
+
"flex min-w-0 max-w-[var(--bh-sidebar-width)] flex-1 flex-col items-start justify-center overflow-hidden opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none rtl:items-end rtl:text-right",
|
|
756
|
+
card && "gap-[var(--bh-space-xs-4)]",
|
|
757
|
+
collapsed &&
|
|
758
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
559
759
|
)}
|
|
560
760
|
>
|
|
561
|
-
{avatar ?? (
|
|
562
|
-
<UserIcon
|
|
563
|
-
aria-hidden="true"
|
|
564
|
-
className="size-[var(--bh-sidebar-icon-size)]"
|
|
565
|
-
/>
|
|
566
|
-
)}
|
|
567
|
-
</span>
|
|
568
|
-
{!collapsed ? (
|
|
569
761
|
<span
|
|
570
|
-
data-slot="sidebar-footer-user-
|
|
571
|
-
|
|
762
|
+
data-slot="sidebar-footer-user-name"
|
|
763
|
+
dir="auto"
|
|
764
|
+
className={cn(
|
|
765
|
+
"w-full truncate",
|
|
766
|
+
card
|
|
767
|
+
? "text-[length:var(--bh-text-body-md-medium-font-size)] font-[var(--bh-text-body-md-medium-font-weight)] leading-[var(--bh-text-body-md-medium-line-height)] tracking-[var(--bh-text-body-md-medium-letter-spacing)] text-[var(--bh-content-default)]"
|
|
768
|
+
: "text-[length:var(--bh-text-body-sm-medium-font-size)] font-[var(--bh-text-body-sm-medium-font-weight)] leading-[var(--bh-text-body-sm-medium-line-height)] tracking-[var(--bh-text-body-sm-medium-letter-spacing)]"
|
|
769
|
+
)}
|
|
572
770
|
>
|
|
771
|
+
{name}
|
|
772
|
+
</span>
|
|
773
|
+
{showSupport ? (
|
|
573
774
|
<span
|
|
574
|
-
data-slot="sidebar-footer-user-
|
|
775
|
+
data-slot="sidebar-footer-user-support"
|
|
575
776
|
dir="auto"
|
|
576
|
-
className=
|
|
777
|
+
className={cn(
|
|
778
|
+
"w-full truncate text-[var(--bh-content-subtle)]",
|
|
779
|
+
card
|
|
780
|
+
? "text-[length:var(--bh-text-body-sm-regular-font-size)] font-[var(--bh-text-body-sm-regular-font-weight)] leading-[var(--bh-text-body-sm-regular-line-height)] tracking-[var(--bh-text-body-sm-regular-letter-spacing)]"
|
|
781
|
+
: "text-[length:var(--bh-text-body-2xs-regular-font-size)] font-[var(--bh-text-body-2xs-regular-font-weight)] leading-[var(--bh-text-body-2xs-regular-line-height)] tracking-[var(--bh-text-body-2xs-regular-letter-spacing)]"
|
|
782
|
+
)}
|
|
577
783
|
>
|
|
578
|
-
{
|
|
784
|
+
{supportText}
|
|
579
785
|
</span>
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
data-slot="sidebar-footer-user-support"
|
|
583
|
-
dir="auto"
|
|
584
|
-
className="w-full truncate text-[length:var(--bh-text-body-2xs-regular-font-size)] font-[var(--bh-text-body-2xs-regular-font-weight)] leading-[var(--bh-text-body-2xs-regular-line-height)] tracking-[var(--bh-text-body-2xs-regular-letter-spacing)] text-[var(--bh-content-subtle)]"
|
|
585
|
-
>
|
|
586
|
-
{supportText}
|
|
587
|
-
</span>
|
|
588
|
-
) : null}
|
|
589
|
-
</span>
|
|
590
|
-
) : null}
|
|
786
|
+
) : null}
|
|
787
|
+
</span>
|
|
591
788
|
</span>
|
|
592
|
-
{
|
|
789
|
+
{showTrailing ? (
|
|
593
790
|
<span
|
|
594
791
|
aria-hidden="true"
|
|
595
792
|
data-slot="sidebar-footer-user-trailing"
|
|
596
|
-
className=
|
|
793
|
+
className={cn(
|
|
794
|
+
"inline-flex size-[var(--bh-space-4xl-20)] max-w-[var(--bh-space-4xl-20)] shrink-0 items-center justify-center overflow-hidden text-[var(--bh-content-muted)] opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none [&_svg]:size-[var(--bh-space-3xl-16)]",
|
|
795
|
+
collapsed &&
|
|
796
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
797
|
+
)}
|
|
597
798
|
>
|
|
598
799
|
{trailingIcon ?? <ChevronsUpDownIcon />}
|
|
599
800
|
</span>
|
|
600
801
|
) : null}
|
|
802
|
+
{collapsed && showIdentityPreview ? (
|
|
803
|
+
<span
|
|
804
|
+
aria-hidden="true"
|
|
805
|
+
data-slot="sidebar-footer-user-preview"
|
|
806
|
+
className={cn(
|
|
807
|
+
"pointer-events-none invisible absolute bottom-0 start-[calc(100%+var(--bh-sidebar-user-preview-gap))] z-[var(--bh-z-overlay)] flex h-[var(--bh-sidebar-user-preview-height)] w-[var(--bh-sidebar-user-preview-width)] items-center gap-[var(--bh-space-md-8)] rounded-[var(--bh-radius-xl-10)] border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-raised)] px-[var(--bh-space-xl-12)] py-[var(--bh-space-md-8)] opacity-[var(--bh-opacity-0)] shadow-[var(--elevation-component-default)] transition-[opacity,visibility]",
|
|
808
|
+
"group-hover/footer-user:visible group-hover/footer-user:opacity-[var(--bh-opacity-100)] group-focus-visible/footer-user:visible group-focus-visible/footer-user:opacity-[var(--bh-opacity-100)] group-data-[state=open]/footer-user:hidden",
|
|
809
|
+
"group-data-[side=end]/sidebar:start-auto group-data-[side=end]/sidebar:end-[calc(100%+var(--bh-sidebar-user-preview-gap))]"
|
|
810
|
+
)}
|
|
811
|
+
>
|
|
812
|
+
<span className="flex min-w-0 flex-1 flex-col items-start justify-center">
|
|
813
|
+
<span
|
|
814
|
+
dir="auto"
|
|
815
|
+
className="w-full truncate text-[length:var(--bh-text-body-sm-medium-font-size)] font-[var(--bh-text-body-sm-medium-font-weight)] leading-[var(--bh-text-body-sm-medium-line-height)] tracking-[var(--bh-text-body-sm-medium-letter-spacing)] text-[var(--bh-content-default)]"
|
|
816
|
+
>
|
|
817
|
+
{name}
|
|
818
|
+
</span>
|
|
819
|
+
<span
|
|
820
|
+
dir="auto"
|
|
821
|
+
className="w-full truncate text-[length:var(--bh-text-body-xs-regular-font-size)] font-[var(--bh-text-body-xs-regular-font-weight)] leading-[var(--bh-text-body-xs-regular-line-height)] tracking-[var(--bh-text-body-xs-regular-letter-spacing)] text-[var(--bh-content-subtle)]"
|
|
822
|
+
>
|
|
823
|
+
{supportText}
|
|
824
|
+
</span>
|
|
825
|
+
</span>
|
|
826
|
+
<span className="inline-flex size-[var(--bh-space-4xl-20)] shrink-0 items-center justify-center text-[var(--bh-content-muted)] [&_svg]:size-[var(--bh-space-3xl-16)]">
|
|
827
|
+
{trailingIcon ?? <MoreHorizontalIcon />}
|
|
828
|
+
</span>
|
|
829
|
+
</span>
|
|
830
|
+
) : null}
|
|
601
831
|
</button>
|
|
602
832
|
)
|
|
603
833
|
})
|
|
604
834
|
|
|
605
|
-
/**
|
|
835
|
+
/**
|
|
836
|
+
* A Figma sidebar group: 12px top padding, 6px bottom padding, and no menu gap.
|
|
837
|
+
* The comfortable size drops the padding (the body's section gap separates groups) and spaces label and rows by 8px.
|
|
838
|
+
*/
|
|
606
839
|
function SidebarGroup({ className, ...props }: SidebarSectionProps) {
|
|
607
840
|
return (
|
|
608
841
|
<div
|
|
609
842
|
data-slot="sidebar-group"
|
|
610
843
|
className={cn(
|
|
611
844
|
"flex w-full flex-col items-start pb-[var(--bh-space-sm-6)] pt-[var(--bh-space-xl-12)]",
|
|
845
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:gap-[var(--bh-sidebar-comfortable-item-gap)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:py-[var(--bh-space-none)]",
|
|
612
846
|
className
|
|
613
847
|
)}
|
|
614
848
|
{...props}
|
|
@@ -627,46 +861,56 @@ function SidebarGroupLabel({
|
|
|
627
861
|
}: SidebarGroupLabelProps) {
|
|
628
862
|
const { collapsed } = useSidebarContext()
|
|
629
863
|
|
|
630
|
-
if (collapsed) return null
|
|
631
|
-
|
|
632
864
|
return (
|
|
633
865
|
<div
|
|
634
|
-
|
|
866
|
+
aria-hidden={collapsed || undefined}
|
|
867
|
+
data-slot="sidebar-group-label-motion"
|
|
868
|
+
inert={collapsed ? true : undefined}
|
|
635
869
|
className={cn(
|
|
636
|
-
"
|
|
637
|
-
|
|
870
|
+
"grid w-full grid-rows-[1fr] opacity-[var(--bh-opacity-100)] transition-[grid-template-rows,opacity] duration-[var(--bh-sidebar-motion-duration-content)] delay-[var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
871
|
+
collapsed &&
|
|
872
|
+
"pointer-events-none grid-rows-[0fr] opacity-[var(--bh-opacity-0)] delay-0"
|
|
638
873
|
)}
|
|
639
|
-
{...props}
|
|
640
874
|
>
|
|
641
|
-
<
|
|
642
|
-
data-slot="sidebar-group-label
|
|
643
|
-
className=
|
|
875
|
+
<div
|
|
876
|
+
data-slot="sidebar-group-label"
|
|
877
|
+
className={cn(
|
|
878
|
+
"group/label flex min-h-0 h-[var(--bh-space-5xl-24)] w-full items-center gap-[var(--bh-space-xs-4)] overflow-hidden rounded-[var(--bh-radius-lg-8)] px-[var(--bh-space-sm-6)] pb-[var(--bh-space-xs-4)]",
|
|
879
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:h-[var(--bh-sidebar-comfortable-group-label-height)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:px-[var(--bh-space-none)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:pb-[var(--bh-space-none)]",
|
|
880
|
+
className
|
|
881
|
+
)}
|
|
882
|
+
{...props}
|
|
644
883
|
>
|
|
645
884
|
<span
|
|
646
|
-
data-slot="sidebar-group-label-
|
|
647
|
-
|
|
648
|
-
className="truncate text-[length:var(--bh-text-body-sm-medium-font-size)] font-[var(--bh-text-body-sm-medium-font-weight)] leading-[var(--bh-text-body-sm-medium-line-height)] tracking-[var(--bh-text-body-sm-medium-letter-spacing)] text-[var(--bh-content-muted)]"
|
|
885
|
+
data-slot="sidebar-group-label-content"
|
|
886
|
+
className="flex min-w-0 flex-1 items-center gap-[var(--bh-space-xxxs-1)]"
|
|
649
887
|
>
|
|
650
|
-
|
|
888
|
+
<span
|
|
889
|
+
data-slot="sidebar-group-label-text"
|
|
890
|
+
dir="auto"
|
|
891
|
+
className="truncate text-[length:var(--bh-text-body-sm-medium-font-size)] font-[var(--bh-text-body-sm-medium-font-weight)] leading-[var(--bh-text-body-sm-medium-line-height)] tracking-[var(--bh-text-body-sm-medium-letter-spacing)] text-[var(--bh-sidebar-group-label-content)]"
|
|
892
|
+
>
|
|
893
|
+
{children}
|
|
894
|
+
</span>
|
|
895
|
+
{expandable ? (
|
|
896
|
+
<span
|
|
897
|
+
aria-hidden="true"
|
|
898
|
+
data-slot="sidebar-group-label-expand"
|
|
899
|
+
className="inline-flex size-[var(--bh-space-3xl-16)] shrink-0 items-center justify-center opacity-[var(--bh-opacity-0)] transition-opacity group-hover/label:opacity-[var(--bh-opacity-100)] group-focus-within/label:opacity-[var(--bh-opacity-100)] [&_svg]:size-full"
|
|
900
|
+
>
|
|
901
|
+
{expandIcon ?? <ChevronRightIcon data-rtl-flip="true" />}
|
|
902
|
+
</span>
|
|
903
|
+
) : null}
|
|
651
904
|
</span>
|
|
652
|
-
{
|
|
905
|
+
{actions ? (
|
|
653
906
|
<span
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
className="inline-flex size-[var(--bh-space-3xl-16)] shrink-0 items-center justify-center opacity-[var(--bh-opacity-0)] transition-opacity group-hover/label:opacity-[var(--bh-opacity-100)] group-focus-within/label:opacity-[var(--bh-opacity-100)] [&_svg]:size-full"
|
|
907
|
+
data-slot="sidebar-group-label-actions"
|
|
908
|
+
className="flex shrink-0 items-center gap-[var(--bh-space-xs-4)] opacity-[var(--bh-opacity-0)] transition-opacity group-hover/label:opacity-[var(--bh-opacity-100)] group-focus-within/label:opacity-[var(--bh-opacity-100)]"
|
|
657
909
|
>
|
|
658
|
-
{
|
|
910
|
+
{actions}
|
|
659
911
|
</span>
|
|
660
912
|
) : null}
|
|
661
|
-
</
|
|
662
|
-
{actions ? (
|
|
663
|
-
<span
|
|
664
|
-
data-slot="sidebar-group-label-actions"
|
|
665
|
-
className="flex shrink-0 items-center gap-[var(--bh-space-xs-4)] opacity-[var(--bh-opacity-0)] transition-opacity group-hover/label:opacity-[var(--bh-opacity-100)] group-focus-within/label:opacity-[var(--bh-opacity-100)]"
|
|
666
|
-
>
|
|
667
|
-
{actions}
|
|
668
|
-
</span>
|
|
669
|
-
) : null}
|
|
913
|
+
</div>
|
|
670
914
|
</div>
|
|
671
915
|
)
|
|
672
916
|
}
|
|
@@ -698,12 +942,16 @@ const SidebarGroupAction = React.forwardRef<
|
|
|
698
942
|
)
|
|
699
943
|
})
|
|
700
944
|
|
|
701
|
-
/** List wrapper for contiguous 32px sidebar menu rows. */
|
|
945
|
+
/** List wrapper for contiguous 32px sidebar menu rows, or 40px rows 8px apart at the comfortable size. */
|
|
702
946
|
function SidebarMenu({ className, ...props }: SidebarMenuProps) {
|
|
703
947
|
return (
|
|
704
948
|
<ul
|
|
705
949
|
data-slot="sidebar-menu"
|
|
706
|
-
className={cn(
|
|
950
|
+
className={cn(
|
|
951
|
+
"m-0 flex w-full list-none flex-col p-0",
|
|
952
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:gap-[var(--bh-sidebar-comfortable-item-gap)]",
|
|
953
|
+
className
|
|
954
|
+
)}
|
|
707
955
|
{...props}
|
|
708
956
|
/>
|
|
709
957
|
)
|
|
@@ -765,8 +1013,6 @@ const SidebarMenuButton = React.forwardRef<
|
|
|
765
1013
|
const resolvedLabel =
|
|
766
1014
|
ariaLabel ?? (typeof label === "string" ? label : undefined)
|
|
767
1015
|
|
|
768
|
-
if (collapsed && isLevel2) return null
|
|
769
|
-
|
|
770
1016
|
const content = (
|
|
771
1017
|
<>
|
|
772
1018
|
{isLevel2 ? (
|
|
@@ -808,37 +1054,58 @@ const SidebarMenuButton = React.forwardRef<
|
|
|
808
1054
|
</span>
|
|
809
1055
|
) : null}
|
|
810
1056
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
1057
|
+
<span
|
|
1058
|
+
aria-hidden={collapsed || undefined}
|
|
1059
|
+
data-slot="sidebar-menu-label"
|
|
1060
|
+
dir="auto"
|
|
1061
|
+
className={cn(
|
|
1062
|
+
"min-w-0 max-w-[var(--bh-sidebar-width)] flex-1 truncate ps-[var(--bh-space-xs-4)] opacity-[var(--bh-opacity-100)] transition-[max-width,opacity,padding] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content),0ms] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content),0ms] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
1063
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:ps-[var(--bh-sidebar-comfortable-label-padding)]",
|
|
1064
|
+
collapsed &&
|
|
1065
|
+
"pointer-events-none max-w-0 p-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms,var(--bh-sidebar-motion-duration-content)]"
|
|
1066
|
+
)}
|
|
1067
|
+
>
|
|
1068
|
+
{label}
|
|
1069
|
+
</span>
|
|
820
1070
|
|
|
821
|
-
{
|
|
1071
|
+
{supportText ? (
|
|
822
1072
|
<span
|
|
1073
|
+
aria-hidden={collapsed || undefined}
|
|
823
1074
|
data-slot="sidebar-menu-support"
|
|
824
1075
|
dir="auto"
|
|
825
|
-
className=
|
|
1076
|
+
className={cn(
|
|
1077
|
+
"max-w-[var(--bh-sidebar-width)] shrink-0 overflow-hidden whitespace-nowrap text-[length:var(--bh-text-body-xs-regular-font-size)] font-[var(--bh-text-body-xs-regular-font-weight)] leading-[var(--bh-text-body-xs-regular-line-height)] tracking-[var(--bh-text-body-xs-regular-letter-spacing)] text-[var(--bh-content-muted)] opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
1078
|
+
collapsed &&
|
|
1079
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
1080
|
+
)}
|
|
826
1081
|
>
|
|
827
1082
|
{supportText}
|
|
828
1083
|
</span>
|
|
829
1084
|
) : null}
|
|
830
1085
|
|
|
831
|
-
{
|
|
832
|
-
<span
|
|
1086
|
+
{badge ? (
|
|
1087
|
+
<span
|
|
1088
|
+
aria-hidden={collapsed || undefined}
|
|
1089
|
+
data-slot="sidebar-menu-badge-slot"
|
|
1090
|
+
className={cn(
|
|
1091
|
+
"inline-flex max-w-[var(--bh-sidebar-width)] shrink-0 overflow-hidden opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
1092
|
+
collapsed &&
|
|
1093
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
1094
|
+
)}
|
|
1095
|
+
>
|
|
833
1096
|
{badge}
|
|
834
1097
|
</span>
|
|
835
1098
|
) : null}
|
|
836
1099
|
|
|
837
|
-
{
|
|
1100
|
+
{trailingIcon ? (
|
|
838
1101
|
<span
|
|
839
1102
|
aria-hidden="true"
|
|
840
1103
|
data-slot="sidebar-menu-trailing"
|
|
841
|
-
className=
|
|
1104
|
+
className={cn(
|
|
1105
|
+
"inline-flex size-[var(--bh-sidebar-icon-slot-size)] max-w-[var(--bh-sidebar-icon-slot-size)] shrink-0 items-center justify-center overflow-hidden text-[var(--bh-content-muted)] opacity-[var(--bh-opacity-100)] transition-[max-width,opacity] [transition-duration:0ms,var(--bh-sidebar-motion-duration-content)] [transition-delay:0ms,var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none [&_svg]:size-[var(--bh-sidebar-icon-size)] [&_svg]:shrink-0",
|
|
1106
|
+
collapsed &&
|
|
1107
|
+
"pointer-events-none max-w-0 opacity-[var(--bh-opacity-0)] [transition-delay:var(--bh-sidebar-motion-duration-content),0ms]"
|
|
1108
|
+
)}
|
|
842
1109
|
>
|
|
843
1110
|
{trailingIcon}
|
|
844
1111
|
</span>
|
|
@@ -847,7 +1114,7 @@ const SidebarMenuButton = React.forwardRef<
|
|
|
847
1114
|
)
|
|
848
1115
|
|
|
849
1116
|
const buttonClassName = cn(
|
|
850
|
-
"group/menu-button relative flex w-full min-w-0 items-center gap-[var(--bh-space-sm-6)] rounded-[var(--bh-radius-lg-8)] border-[length:var(--bh-border-width-strong)] border-transparent px-[var(--bh-sidebar-item-padding-x)] text-start text-[length:var(--bh-text-body-sm-regular-font-size)] font-[var(--bh-text-body-sm-regular-font-weight)] leading-[var(--bh-text-body-sm-regular-line-height)] tracking-[var(--bh-text-body-sm-regular-letter-spacing)] text-[var(--bh-sidebar-item-content)] outline-none transition-[background-color,border-color,color]",
|
|
1117
|
+
"group/menu-button relative flex w-full min-w-0 items-center gap-[var(--bh-space-sm-6)] overflow-hidden rounded-[var(--bh-radius-lg-8)] border-[length:var(--bh-border-width-strong)] border-transparent px-[var(--bh-sidebar-item-padding-x)] text-start text-[length:var(--bh-text-body-sm-regular-font-size)] font-[var(--bh-text-body-sm-regular-font-weight)] leading-[var(--bh-text-body-sm-regular-line-height)] tracking-[var(--bh-text-body-sm-regular-letter-spacing)] text-[var(--bh-sidebar-item-content)] opacity-[var(--bh-opacity-100)] outline-none transition-[width,height,gap,padding,margin,opacity,background-color,border-color,color] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
851
1118
|
"hover:rounded-[var(--bh-radius-md-6)] hover:bg-[var(--bh-sidebar-item-bg-hover)]",
|
|
852
1119
|
"focus-visible:rounded-[var(--bh-radius-md-6)] focus-visible:border-[var(--bh-border-focus)]",
|
|
853
1120
|
"data-[state=hover]:rounded-[var(--bh-radius-md-6)] data-[state=hover]:bg-[var(--bh-sidebar-item-bg-hover)]",
|
|
@@ -855,22 +1122,29 @@ const SidebarMenuButton = React.forwardRef<
|
|
|
855
1122
|
"disabled:pointer-events-none disabled:text-[var(--bh-content-disabled)]",
|
|
856
1123
|
variant === "avatar"
|
|
857
1124
|
? "h-[var(--bh-sidebar-compact-control-size)]"
|
|
858
|
-
: "h-[var(--bh-sidebar-item-height)]",
|
|
1125
|
+
: "h-[var(--bh-sidebar-item-height)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:h-[var(--bh-sidebar-comfortable-item-height)]",
|
|
1126
|
+
"group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:text-[length:var(--bh-text-body-md-regular-font-size)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:leading-[var(--bh-text-body-md-regular-line-height)] group-data-[size=comfortable]/sidebar:group-data-[collapsed=false]/sidebar:tracking-[var(--bh-text-body-md-regular-letter-spacing)]",
|
|
859
1127
|
(active || state === "active") &&
|
|
860
1128
|
"rounded-[var(--bh-radius-md-6)] bg-[var(--bh-sidebar-item-bg-active)] font-[var(--bh-text-body-sm-medium-font-weight)] text-[var(--bh-sidebar-item-content-active)]",
|
|
861
|
-
collapsed &&
|
|
862
|
-
"
|
|
1129
|
+
collapsed && !isLevel2 &&
|
|
1130
|
+
"ms-[var(--bh-space-xs-4)] size-[var(--bh-sidebar-item-height-collapsed)] gap-0 rounded-[var(--bh-radius-lg-8)] px-[var(--bh-space-md-8)] py-0",
|
|
1131
|
+
collapsed && !isLevel2 && variant === "avatar" &&
|
|
1132
|
+
"px-[var(--bh-space-sm-6)]",
|
|
1133
|
+
collapsed && isLevel2 &&
|
|
1134
|
+
"pointer-events-none h-0 w-full gap-0 border-0 p-0 opacity-[var(--bh-opacity-0)]",
|
|
863
1135
|
className
|
|
864
1136
|
)
|
|
865
1137
|
|
|
866
1138
|
const commonProps = {
|
|
867
1139
|
"aria-current": active ? ("page" as const) : undefined,
|
|
1140
|
+
"aria-hidden": collapsed && isLevel2 ? true : undefined,
|
|
868
1141
|
"aria-label": resolvedLabel,
|
|
869
1142
|
"data-active": active ? "true" : "false",
|
|
870
1143
|
"data-collapsed": collapsed ? "true" : "false",
|
|
871
1144
|
"data-slot": "sidebar-menu-button",
|
|
872
1145
|
"data-state": state,
|
|
873
1146
|
"data-variant": variant,
|
|
1147
|
+
inert: collapsed && isLevel2 ? true : undefined,
|
|
874
1148
|
className: buttonClassName,
|
|
875
1149
|
}
|
|
876
1150
|
|
|
@@ -885,33 +1159,48 @@ const SidebarMenuButton = React.forwardRef<
|
|
|
885
1159
|
)
|
|
886
1160
|
|
|
887
1161
|
const resolvedTooltip = tooltip ?? resolvedLabel
|
|
888
|
-
if (!
|
|
1162
|
+
if (!resolvedTooltip || isLevel2) return button
|
|
889
1163
|
|
|
890
1164
|
return (
|
|
891
1165
|
<Tooltip>
|
|
892
1166
|
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1167
|
+
{collapsed ? (
|
|
1168
|
+
<TooltipContent
|
|
1169
|
+
pointerPosition={dir === "rtl" ? "center-right" : "center-left"}
|
|
1170
|
+
showShortcut={false}
|
|
1171
|
+
side={dir === "rtl" ? "left" : "right"}
|
|
1172
|
+
>
|
|
1173
|
+
{resolvedTooltip}
|
|
1174
|
+
</TooltipContent>
|
|
1175
|
+
) : null}
|
|
900
1176
|
</Tooltip>
|
|
901
1177
|
)
|
|
902
1178
|
})
|
|
903
1179
|
|
|
904
|
-
/** Nested menu list that
|
|
1180
|
+
/** Nested menu list that contracts before the icon rail settles. */
|
|
905
1181
|
function SidebarMenuSub({ className, ...props }: SidebarMenuSubProps) {
|
|
906
1182
|
const { collapsed } = useSidebarContext()
|
|
907
|
-
if (collapsed) return null
|
|
908
1183
|
|
|
909
1184
|
return (
|
|
910
|
-
<
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
{
|
|
914
|
-
|
|
1185
|
+
<div
|
|
1186
|
+
aria-hidden={collapsed || undefined}
|
|
1187
|
+
data-slot="sidebar-menu-sub-motion"
|
|
1188
|
+
inert={collapsed ? true : undefined}
|
|
1189
|
+
className={cn(
|
|
1190
|
+
"grid w-full grid-rows-[1fr] opacity-[var(--bh-opacity-100)] transition-[grid-template-rows,opacity] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
1191
|
+
collapsed &&
|
|
1192
|
+
"pointer-events-none grid-rows-[0fr] opacity-[var(--bh-opacity-0)]"
|
|
1193
|
+
)}
|
|
1194
|
+
>
|
|
1195
|
+
<ul
|
|
1196
|
+
data-slot="sidebar-menu-sub"
|
|
1197
|
+
className={cn(
|
|
1198
|
+
"m-0 flex min-h-0 w-full list-none flex-col overflow-hidden p-0",
|
|
1199
|
+
className
|
|
1200
|
+
)}
|
|
1201
|
+
{...props}
|
|
1202
|
+
/>
|
|
1203
|
+
</div>
|
|
915
1204
|
)
|
|
916
1205
|
}
|
|
917
1206
|
|
|
@@ -958,7 +1247,6 @@ const SidebarMenuTreeItem = React.forwardRef<
|
|
|
958
1247
|
ref
|
|
959
1248
|
) {
|
|
960
1249
|
const { collapsed } = useSidebarContext()
|
|
961
|
-
if (collapsed) return null
|
|
962
1250
|
|
|
963
1251
|
const label = getSlottableLabel(children, asChild)
|
|
964
1252
|
const resolvedLabel =
|
|
@@ -998,18 +1286,23 @@ const SidebarMenuTreeItem = React.forwardRef<
|
|
|
998
1286
|
const commonProps = {
|
|
999
1287
|
"aria-current": active ? ("page" as const) : undefined,
|
|
1000
1288
|
"aria-expanded": showChevron ? expanded : undefined,
|
|
1289
|
+
"aria-hidden": collapsed || undefined,
|
|
1001
1290
|
"aria-label": resolvedLabel,
|
|
1002
1291
|
"data-active": active ? "true" : "false",
|
|
1292
|
+
"data-collapsed": collapsed ? "true" : "false",
|
|
1003
1293
|
"data-level": String(level),
|
|
1004
1294
|
"data-slot": "sidebar-menu-tree-item",
|
|
1005
1295
|
"data-state": state,
|
|
1296
|
+
inert: collapsed ? true : undefined,
|
|
1006
1297
|
className: cn(
|
|
1007
|
-
"flex h-[var(--bh-sidebar-tree-item-height)] w-full min-w-0 items-center gap-[var(--bh-space-sm-6)] rounded-[var(--bh-radius-lg-8)] border-[length:var(--bh-border-width-strong)] border-transparent pe-[var(--bh-space-sm-6)] text-start text-[length:var(--bh-text-body-xs-regular-font-size)] font-[var(--bh-text-body-xs-regular-font-weight)] leading-[var(--bh-text-body-xs-regular-line-height)] tracking-[var(--bh-text-body-xs-regular-letter-spacing)] text-[var(--bh-content-subtle)] outline-none transition-[background-color,border-color,color]",
|
|
1298
|
+
"flex h-[var(--bh-sidebar-tree-item-height)] w-full min-w-0 items-center gap-[var(--bh-space-sm-6)] overflow-hidden rounded-[var(--bh-radius-lg-8)] border-[length:var(--bh-border-width-strong)] border-transparent pe-[var(--bh-space-sm-6)] text-start text-[length:var(--bh-text-body-xs-regular-font-size)] font-[var(--bh-text-body-xs-regular-font-weight)] leading-[var(--bh-text-body-xs-regular-line-height)] tracking-[var(--bh-text-body-xs-regular-letter-spacing)] text-[var(--bh-content-subtle)] opacity-[var(--bh-opacity-100)] outline-none transition-[height,gap,padding,opacity,background-color,border-color,color] duration-[var(--bh-sidebar-motion-duration-content)] delay-[var(--bh-sidebar-motion-delay-content)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
1008
1299
|
"hover:rounded-[var(--bh-radius-md-6)] hover:bg-[var(--bh-interactive-ghost-hover)] focus-visible:rounded-[var(--bh-radius-md-6)] focus-visible:border-[var(--bh-border-focus)]",
|
|
1009
1300
|
"data-[state=hover]:rounded-[var(--bh-radius-md-6)] data-[state=hover]:bg-[var(--bh-interactive-ghost-hover)] data-[state=focus]:rounded-[var(--bh-radius-md-6)] data-[state=focus]:border-[var(--bh-border-focus)]",
|
|
1010
1301
|
(active || state === "active") &&
|
|
1011
1302
|
"rounded-[var(--bh-radius-md-6)] bg-[var(--bh-interactive-ghost-active)] font-[var(--bh-text-body-xs-semibold-font-weight)] text-[var(--bh-content-default)]",
|
|
1012
1303
|
treeLevelClasses[level],
|
|
1304
|
+
collapsed &&
|
|
1305
|
+
"pointer-events-none h-0 gap-0 border-0 p-0 opacity-[var(--bh-opacity-0)] delay-0",
|
|
1013
1306
|
className
|
|
1014
1307
|
),
|
|
1015
1308
|
}
|
|
@@ -1036,32 +1329,42 @@ function SidebarTreeGroup({
|
|
|
1036
1329
|
...props
|
|
1037
1330
|
}: SidebarTreeGroupProps) {
|
|
1038
1331
|
const { collapsed } = useSidebarContext()
|
|
1039
|
-
if (collapsed) return null
|
|
1040
1332
|
|
|
1041
1333
|
return (
|
|
1042
1334
|
<div
|
|
1043
|
-
|
|
1335
|
+
aria-hidden={collapsed || undefined}
|
|
1336
|
+
data-slot="sidebar-tree-group-motion"
|
|
1337
|
+
inert={collapsed ? true : undefined}
|
|
1044
1338
|
className={cn(
|
|
1045
|
-
"
|
|
1046
|
-
|
|
1339
|
+
"grid w-full grid-rows-[1fr] opacity-[var(--bh-opacity-100)] transition-[grid-template-rows,opacity] duration-[var(--bh-sidebar-motion-duration)] ease-[var(--bh-sidebar-motion-easing)] motion-reduce:transition-none",
|
|
1340
|
+
collapsed &&
|
|
1341
|
+
"pointer-events-none grid-rows-[0fr] opacity-[var(--bh-opacity-0)]"
|
|
1047
1342
|
)}
|
|
1048
|
-
{...props}
|
|
1049
1343
|
>
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1344
|
+
<div
|
|
1345
|
+
data-slot="sidebar-tree-group"
|
|
1346
|
+
className={cn(
|
|
1347
|
+
"flex min-h-0 w-full flex-col items-start gap-[var(--bh-space-sm-6)] overflow-hidden pb-[var(--bh-space-sm-6)] pt-[var(--bh-space-xl-12)]",
|
|
1348
|
+
className
|
|
1349
|
+
)}
|
|
1350
|
+
{...props}
|
|
1351
|
+
>
|
|
1352
|
+
{label ? (
|
|
1353
|
+
<SidebarGroupLabel
|
|
1354
|
+
actions={actions}
|
|
1355
|
+
className={cn(
|
|
1356
|
+
expandable &&
|
|
1357
|
+
"[&_[data-slot=sidebar-group-label-expand]]:opacity-[var(--bh-opacity-100)]"
|
|
1358
|
+
)}
|
|
1359
|
+
expandable={expandable}
|
|
1360
|
+
expandIcon={expandIcon ?? (expandable ? <ChevronDownIcon /> : undefined)}
|
|
1361
|
+
>
|
|
1362
|
+
{label}
|
|
1363
|
+
</SidebarGroupLabel>
|
|
1364
|
+
) : null}
|
|
1365
|
+
<div data-slot="sidebar-tree-menu" className="flex w-full flex-col">
|
|
1366
|
+
{children}
|
|
1367
|
+
</div>
|
|
1065
1368
|
</div>
|
|
1066
1369
|
</div>
|
|
1067
1370
|
)
|
|
@@ -1084,7 +1387,7 @@ const SidebarToggle = React.forwardRef<HTMLButtonElement, SidebarToggleProps>(
|
|
|
1084
1387
|
type={type}
|
|
1085
1388
|
className={cn(
|
|
1086
1389
|
"inline-flex size-[var(--bh-sidebar-header-action-size)] shrink-0 items-center justify-center rounded-[var(--bh-radius-full)] border border-transparent bg-[var(--bh-interactive-ghost-default)] text-[var(--bh-content-default)] outline-none transition-[background-color,border-color,box-shadow,color]",
|
|
1087
|
-
"hover:bg-[var(--bh-interactive-ghost-hover)] focus-visible:border-[var(--bh-border-focus)] focus-visible:shadow-[var(--
|
|
1390
|
+
"hover:bg-[var(--bh-interactive-ghost-hover)] focus-visible:border-[var(--bh-border-focus)] focus-visible:shadow-[var(--elevation-button-focus)]",
|
|
1088
1391
|
className
|
|
1089
1392
|
)}
|
|
1090
1393
|
onClick={(event) => {
|
|
@@ -1203,6 +1506,7 @@ export {
|
|
|
1203
1506
|
SidebarTrigger,
|
|
1204
1507
|
}
|
|
1205
1508
|
export type {
|
|
1509
|
+
SidebarFooterProps,
|
|
1206
1510
|
SidebarFooterUserProps,
|
|
1207
1511
|
SidebarGroupActionProps,
|
|
1208
1512
|
SidebarGroupLabelProps,
|
|
@@ -1223,6 +1527,7 @@ export type {
|
|
|
1223
1527
|
SidebarProviderProps,
|
|
1224
1528
|
SidebarRailProps,
|
|
1225
1529
|
SidebarSectionProps,
|
|
1530
|
+
SidebarSize,
|
|
1226
1531
|
SidebarToggleProps,
|
|
1227
1532
|
SidebarTreeGroupProps,
|
|
1228
1533
|
SidebarTriggerProps,
|