diff --git a/packages/lsd-docs/app/components/Header.tsx b/packages/lsd-docs/app/components/Header.tsx index 0f43107c..2286f2de 100644 --- a/packages/lsd-docs/app/components/Header.tsx +++ b/packages/lsd-docs/app/components/Header.tsx @@ -1,6 +1,6 @@ 'use client'; -import { Button, SidebarTrigger } from '@nipsys/lsd'; +import { Button, SidebarTrigger, useSidebar } from '@nipsys/lsd'; import { GithubLogoIcon, MagnifyingGlassIcon } from '@phosphor-icons/react'; import Link from 'next/link'; import { FontToggle } from './docs/FontToggle'; @@ -12,12 +12,14 @@ interface HeaderProps { } export default function Header({ className }: HeaderProps) { + const { isMobile } = useSidebar(); + return (
-
-
- -
+
+ {isMobile && }
@@ -468,6 +536,79 @@ export default function MyComponent() {
+ +
+ + SidebarTrigger + +
+ + + icon + + Icon element to display in the trigger button. Defaults to SidebarSimpleIcon + with duotone weight. + + + + + Type: React.ReactNode + + + Optional + + + + + + text + + Accessible label text for the trigger button. Defaults to "Toggle Sidebar". + + + + + Type: string + + + Optional + + + + + + iconClassName + + Class name applied to the icon element. Defaults to "lsd:size-4/5". + + + + + Type: string + + + Optional + + + + + + textClassName + + Class name applied to the text span element. Defaults to "lsd:sr-only". + + + + + Type: string + + + Optional + + + +
+
diff --git a/packages/lsd-docs/e2e/sidebar-behavior.spec.ts b/packages/lsd-docs/e2e/sidebar-behavior.spec.ts index 6f673362..448b30e1 100644 --- a/packages/lsd-docs/e2e/sidebar-behavior.spec.ts +++ b/packages/lsd-docs/e2e/sidebar-behavior.spec.ts @@ -34,7 +34,7 @@ test.describe('Sidebar Behavior', () => { await page.goto('/examples/sidebar/basic'); const _sidebar = page.locator('[data-slot="sidebar"]'); - const trigger = page.locator('[data-sidebar="trigger"]'); + const trigger = page.locator('[data-sidebar="trigger"]').first(); const rail = page.locator('[data-sidebar="rail"]'); await expect(rail).toBeVisible(); diff --git a/packages/lsd/src/components/ui/sidebar/Sidebar.tsx b/packages/lsd/src/components/ui/sidebar/Sidebar.tsx index 381a2b67..be3cab1e 100644 --- a/packages/lsd/src/components/ui/sidebar/Sidebar.tsx +++ b/packages/lsd/src/components/ui/sidebar/Sidebar.tsx @@ -1,3 +1,4 @@ +import { CaretLeftIcon, CaretRightIcon } from '@phosphor-icons/react'; import type * as React from 'react'; import { Sheet, @@ -7,6 +8,7 @@ import { SheetTitle, } from '@/components/ui/sheet'; import { cn } from '@/lib/utils'; +import { SidebarTrigger } from './SidebarContent'; import { useSidebar } from './SidebarContext'; import { SIDEBAR_WIDTH_MOBILE, type SidebarProps } from './types'; @@ -67,12 +69,24 @@ export function Sidebar({ side = 'left', variant = 'sidebar', collapsible = 'offcanvas', + showTrigger = true, + triggerIconExpanded, + triggerIconCollapsed, + triggerClassName, className, children, ...props }: SidebarProps) { const { isMobile, state, openMobile, setOpenMobile } = useSidebar(); + const defaultTriggerIconExpanded = ; + const defaultTriggerIconCollapsed = ; + + const triggerIcon = + state === 'expanded' + ? (triggerIconExpanded ?? defaultTriggerIconExpanded) + : (triggerIconCollapsed ?? defaultTriggerIconCollapsed); + if (collapsible === 'none') { return (
+ {showTrigger && ( + + )}
; + return ( ); } diff --git a/packages/lsd/src/components/ui/sidebar/types.ts b/packages/lsd/src/components/ui/sidebar/types.ts index 1951a3f3..cc0e1305 100644 --- a/packages/lsd/src/components/ui/sidebar/types.ts +++ b/packages/lsd/src/components/ui/sidebar/types.ts @@ -41,6 +41,30 @@ export interface SidebarProps extends React.ComponentProps<'div'> { * Controls how sidebar collapses: offcanvas (slides out), icon (shows only icons), or none (no collapse). */ collapsible?: 'offcanvas' | 'icon' | 'none'; + /** + * Whether to show the sidebar trigger button. + * + * When true, displays the trigger button to toggle sidebar visibility. + */ + showTrigger?: boolean; + /** + * Icon element for the sidebar trigger when expanded. + * + * Passed to SidebarTrigger's icon prop when sidebar is expanded. + */ + triggerIconExpanded?: React.ReactNode; + /** + * Icon element for the sidebar trigger when collapsed. + * + * Passed to SidebarTrigger's icon prop when sidebar is collapsed. + */ + triggerIconCollapsed?: React.ReactNode; + /** + * Class name for the sidebar trigger button. + * + * Applied to the SidebarTrigger component. + */ + triggerClassName?: string; } export interface SidebarProviderProps extends React.ComponentProps<'div'> { @@ -148,7 +172,32 @@ export interface SidebarMenuSkeletonProps extends React.ComponentProps<'div'> { showIcon?: boolean; } -export interface SidebarTriggerProps extends React.ComponentProps {} +export interface SidebarTriggerProps extends React.ComponentProps { + /** + * Icon element to display in the trigger button. + * + * Defaults to SidebarSimpleIcon with duotone weight. + */ + icon?: React.ReactNode; + /** + * Accessible label text for the trigger button. + * + * Defaults to "Toggle Sidebar". + */ + text?: string; + /** + * Class name applied to the icon element. + * + * Defaults to "lsd:size-4/5". + */ + iconClassName?: string; + /** + * Class name applied to the text span element. + * + * Defaults to "lsd:sr-only". + */ + textClassName?: string; +} export interface SidebarRailProps extends React.ComponentProps<'button'> {}