From 4d3f00550e37ea4312aa9535ec4e931dc1c2a752 Mon Sep 17 00:00:00 2001 From: Xavier Saliniere Date: Wed, 29 Apr 2026 18:47:22 -0400 Subject: [PATCH 1/5] feat(sidebar): add integrated trigger button support --- .../lsd/src/components/ui/sidebar/Sidebar.tsx | 29 +++++++++-- .../lsd/src/components/ui/sidebar/types.ts | 51 ++++++++++++++++++- 2 files changed, 76 insertions(+), 4 deletions(-) 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 && ( + + )}
{ * 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'> {} From 6185cab7ba4af7917518b61ff8df70ebd38d9734 Mon Sep 17 00:00:00 2001 From: Xavier Saliniere Date: Wed, 29 Apr 2026 18:47:33 -0400 Subject: [PATCH 2/5] feat(sidebar): enhance SidebarTrigger with custom props --- .../src/components/ui/sidebar/SidebarContent.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/lsd/src/components/ui/sidebar/SidebarContent.tsx b/packages/lsd/src/components/ui/sidebar/SidebarContent.tsx index 9d400f77..6ec4e395 100644 --- a/packages/lsd/src/components/ui/sidebar/SidebarContent.tsx +++ b/packages/lsd/src/components/ui/sidebar/SidebarContent.tsx @@ -142,9 +142,19 @@ export function SidebarInset({ className, ...props }: SidebarInsetProps) { * * @exportAs sub */ -export function SidebarTrigger({ className, onClick, ...props }: SidebarTriggerProps) { +export function SidebarTrigger({ + className, + onClick, + icon, + text = 'Toggle Sidebar', + iconClassName = 'lsd:size-4/5', + textClassName = 'lsd:sr-only', + ...props +}: SidebarTriggerProps) { const { toggleSidebar } = useSidebar(); + const defaultIcon = ; + return ( ); } From f0e159a9f2fa5cd9b9920e129ab347e860d2cd0a Mon Sep 17 00:00:00 2001 From: Xavier Saliniere Date: Wed, 29 Apr 2026 18:47:33 -0400 Subject: [PATCH 3/5] docs(sidebar): document integrated trigger props --- .../lsd-docs/app/components/sidebar/page.tsx | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/packages/lsd-docs/app/components/sidebar/page.tsx b/packages/lsd-docs/app/components/sidebar/page.tsx index e51ac45c..44d8e91e 100644 --- a/packages/lsd-docs/app/components/sidebar/page.tsx +++ b/packages/lsd-docs/app/components/sidebar/page.tsx @@ -164,6 +164,74 @@ export default function MyComponent() { + + + showTrigger + + Whether to show the sidebar trigger button. When true, displays the trigger + button to toggle sidebar visibility. + + + + + Type: boolean + + + Optional + + + + + + triggerIconExpanded + + Icon element for the sidebar trigger when expanded. Passed to SidebarTrigger's + icon prop when sidebar is expanded. + + + + + Type: React.ReactNode + + + Optional + + + + + + triggerIconCollapsed + + Icon element for the sidebar trigger when collapsed. Passed to SidebarTrigger's + icon prop when sidebar is collapsed. + + + + + Type: React.ReactNode + + + Optional + + + + + + triggerClassName + + Class name for the sidebar trigger button. Applied to the SidebarTrigger + component. + + + + + Type: string + + + Optional + + +
@@ -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 + + + +
+
From e52564cfe1544e31e7ec41def96ad2f00e3f75f6 Mon Sep 17 00:00:00 2001 From: Xavier Saliniere Date: Wed, 29 Apr 2026 18:47:33 -0400 Subject: [PATCH 4/5] docs(sidebar): update Header for mobile trigger placement --- packages/lsd-docs/app/components/Header.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) 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 && }