diff --git a/apps/studio/components/interfaces/Account/Preferences/ThemeSettings.tsx b/apps/studio/components/interfaces/Account/Preferences/ThemeSettings.tsx index f4b5762c270..73ae2129770 100644 --- a/apps/studio/components/interfaces/Account/Preferences/ThemeSettings.tsx +++ b/apps/studio/components/interfaces/Account/Preferences/ThemeSettings.tsx @@ -9,22 +9,26 @@ import { Label_Shadcn_, RadioGroup_Shadcn_, RadioGroupLargeItem_Shadcn_, + Select_Shadcn_, + SelectContent_Shadcn_, + SelectItem_Shadcn_, + SelectTrigger_Shadcn_, + SelectValue_Shadcn_, Separator, singleThemes, - Switch, Theme, } from 'ui' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' +import { DEFAULT_SIDEBAR_BEHAVIOR } from 'components/interfaces/Sidebar' export const ThemeSettings = () => { const [mounted, setMounted] = useState(false) const { theme, setTheme } = useTheme() - const [allowNavPanelToExpand, setAllowNavPanelToExpand] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.EXPAND_NAVIGATION_PANEL, - true + const [sidebarBehaviour, setSidebarBehaviour] = useLocalStorageQuery( + LOCAL_STORAGE_KEYS.SIDEBAR_BEHAVIOR, + DEFAULT_SIDEBAR_BEHAVIOR ) - /** * Avoid Hydration Mismatch * https://github.com/pacocoursey/next-themes?tab=readme-ov-file#avoid-hydration-mismatch @@ -83,15 +87,24 @@ export const ThemeSettings = () => { - + + + + + + Expanded + Collapsed + Expand on hover + + diff --git a/apps/studio/components/interfaces/Sidebar.tsx b/apps/studio/components/interfaces/Sidebar.tsx new file mode 100644 index 00000000000..9898e873d2d --- /dev/null +++ b/apps/studio/components/interfaces/Sidebar.tsx @@ -0,0 +1,384 @@ +import { AnimatePresence, motion, MotionProps } from 'framer-motion' +import { isUndefined } from 'lodash' +import { Blocks, Boxes, ChartArea, Command, PanelLeftDashed, Settings, Users } from 'lucide-react' +import Link from 'next/link' +import { useRouter } from 'next/router' +import { ComponentProps, ComponentPropsWithoutRef, FC, useEffect } from 'react' + +import { useParams } from 'common' +import { + generateOtherRoutes, + generateProductRoutes, + generateSettingsRoutes, + generateToolRoutes, +} from 'components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils' +import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' +import { ProjectIndexPageLink } from 'data/prefetchers/project.$ref' +import { useHideSidebar } from 'hooks/misc/useHideSidebar' +import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' +import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' +import { Home } from 'icons' +import { IS_PLATFORM, LOCAL_STORAGE_KEYS } from 'lib/constants' +import { + Button, + DropdownMenu, + DropdownMenuContent, + DropdownMenuLabel, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuTrigger, + Separator, + SidebarContent as SidebarContentPrimitive, + SidebarFooter, + SidebarGroup, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + Sidebar as SidebarPrimitive, + useSidebar, +} from 'ui' +import { useSetCommandMenuOpen } from 'ui-patterns' +import { ThemeDropdown } from './ThemeDropdown' +import { UserDropdown } from './UserDropdown' + +export const ICON_SIZE = 32 +export const ICON_STROKE_WIDTH = 1.5 +export type SidebarBehaviourType = 'expandable' | 'open' | 'closed' +export const DEFAULT_SIDEBAR_BEHAVIOR = 'expandable' + +const SidebarMotion = motion(SidebarPrimitive) as FC< + ComponentProps & { + transition?: MotionProps['transition'] + } +> + +export interface SidebarProps extends ComponentPropsWithoutRef {} + +export const Sidebar = ({ className, ...props }: SidebarProps) => { + const { setOpen } = useSidebar() + const hideSideBar = useHideSidebar() + + const [sidebarBehaviour, setSidebarBehaviour] = useLocalStorageQuery( + LOCAL_STORAGE_KEYS.SIDEBAR_BEHAVIOR, + DEFAULT_SIDEBAR_BEHAVIOR + ) + + useEffect(() => { + // logic to toggle sidebar open based on sidebarBehaviour state + if (sidebarBehaviour === 'open') setOpen(true) + if (sidebarBehaviour === 'closed') setOpen(false) + }, [sidebarBehaviour, setOpen]) + + return ( + <> + + {!hideSideBar && ( + { + if (sidebarBehaviour === 'expandable') setOpen(true) + }} + onMouseLeave={() => { + if (sidebarBehaviour === 'expandable') setOpen(false) + }} + > + + + + ) + + return ( + + {sidebarBehaviour === 'closed' ? ( + + + {button} + + + Theme + + + ) : ( + {button} + )} + + + Theme + { + setTheme(value) + }} + > + {singleThemes.map((theme: Theme) => ( + + {theme.name} + + ))} + + + + + ) +} diff --git a/apps/studio/components/interfaces/UserDropdown.tsx b/apps/studio/components/interfaces/UserDropdown.tsx new file mode 100644 index 00000000000..4d4e2b72f1a --- /dev/null +++ b/apps/studio/components/interfaces/UserDropdown.tsx @@ -0,0 +1,146 @@ +import { Command, FlaskConical, Palette, Settings } from 'lucide-react' +import { useTheme } from 'next-themes' +import Link from 'next/link' +import { useRouter } from 'next/navigation' + +import { ProfileImage } from 'components/ui/ProfileImage' +import { useSignOut } from 'lib/auth' +import { IS_PLATFORM } from 'lib/constants' +import { useProfile } from 'lib/profile' +import { useAppStateSnapshot } from 'state/app-state' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuTrigger, + SidebarMenuButton, + Theme, + cn, + singleThemes, +} from 'ui' +import { useSetCommandMenuOpen } from 'ui-patterns/CommandMenu' +import { ICON_SIZE, ICON_STROKE_WIDTH, SideBarNavLink } from './Sidebar' + +export const UserDropdown = () => { + const { profile } = useProfile() + const appStateSnapshot = useAppStateSnapshot() + const { theme, setTheme } = useTheme() + const signOut = useSignOut() + const router = useRouter() + + const setCommandMenuOpen = useSetCommandMenuOpen() + return ( + + + + + + + + {IS_PLATFORM && ( + <> +
+ {profile && ( + <> + + {profile.username} + + {profile.primary_email !== profile.username && ( + + {profile.primary_email} + + )} + + )} +
+ + + + + + Account preferences + + + appStateSnapshot.setShowFeaturePreviewModal(true)} + onSelect={() => appStateSnapshot.setShowFeaturePreviewModal(true)} + > + + Feature previews + + setCommandMenuOpen(true)}> + + Command menu + + + + + )} + + Theme + { + setTheme(value) + }} + > + {singleThemes.map((theme: Theme) => ( + + {theme.name} + + ))} + + + {IS_PLATFORM && ( + <> + + + { + await signOut() + await router.push('/sign-in') + }} + > + Log out + + + + )} +
+
+ ) +} diff --git a/apps/studio/components/layouts/DefaultLayout.tsx b/apps/studio/components/layouts/DefaultLayout.tsx index 8ab85cf71ca..39108bdc686 100644 --- a/apps/studio/components/layouts/DefaultLayout.tsx +++ b/apps/studio/components/layouts/DefaultLayout.tsx @@ -3,9 +3,10 @@ import { PropsWithChildren } from 'react' import { useParams } from 'common' import { AppBannerWrapper } from 'components/interfaces/App' import { AppBannerContextProvider } from 'components/interfaces/App/AppBannerWrapperContext' +import { Sidebar } from 'components/interfaces/Sidebar' +import { SidebarProvider } from 'ui' import { LayoutHeader } from './ProjectLayout/LayoutHeader' import MobileNavigationBar from './ProjectLayout/NavigationBar/MobileNavigationBar' -import NavigationBar from './ProjectLayout/NavigationBar/NavigationBar' import { ProjectContextProvider } from './ProjectLayout/ProjectContext' export interface DefaultLayoutProps { @@ -26,25 +27,28 @@ export interface DefaultLayoutProps { const DefaultLayout = ({ children, showProductMenu }: PropsWithChildren) => { const { ref } = useParams() return ( - - -
- {/* Top Banner */} - -
- - + + + +
+ {/* Top Banner */} + +
+ + +
+ {/* Main Content Area */} +
+ {/* Sidebar */} + + + {/* Main Content */} +
{children}
+
- {/* Main Content Area */} -
- {/* Sidebar */} - - {/* Main Content */} -
{children}
-
-
- - + + + ) } diff --git a/apps/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx b/apps/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx index 1b79f6708ab..4fbe538f5e4 100644 --- a/apps/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx +++ b/apps/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx @@ -109,12 +109,12 @@ const LayoutHeader = ({ {projectRef && ( Supabase )} diff --git a/apps/studio/components/layouts/ProjectLayout/NavigationBar/MobileNavigationBar.tsx b/apps/studio/components/layouts/ProjectLayout/NavigationBar/MobileNavigationBar.tsx index 8464ac57d6b..dc88c081d65 100644 --- a/apps/studio/components/layouts/ProjectLayout/NavigationBar/MobileNavigationBar.tsx +++ b/apps/studio/components/layouts/ProjectLayout/NavigationBar/MobileNavigationBar.tsx @@ -4,25 +4,16 @@ import { useRouter } from 'next/router' import { useState } from 'react' import { useParams } from 'common' +import { SidebarContent } from 'components/interfaces/Sidebar' import { IS_PLATFORM } from 'lib/constants' -import { useAppStateSnapshot } from 'state/app-state' import { buttonVariants, cn } from 'ui' import { CommandMenuTrigger } from 'ui-patterns' import MobileSheetNav from 'ui-patterns/MobileSheetNav/MobileSheetNav' -import { NavContent } from './NavigationBar' const MobileNavigationBar = () => { const router = useRouter() const [isSheetOpen, setIsSheetOpen] = useState(false) const { ref: projectRef } = useParams() - const snap = useAppStateSnapshot() - - const onCloseNavigationIconLink = (event: any) => { - snap.setNavigationPanelOpen( - false, - event.target.id === 'icon-link' || ['svg', 'path'].includes(event.target.localName) - ) - } return (
@@ -37,7 +28,6 @@ const MobileNavigationBar = () => { Supabase {
- - + +
) diff --git a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx deleted file mode 100644 index 40ae286e050..00000000000 --- a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.tsx +++ /dev/null @@ -1,447 +0,0 @@ -import { Home } from 'icons' -import { isUndefined } from 'lodash' -import { Command, FileText, FlaskConical, Search, Settings } from 'lucide-react' -import { useTheme } from 'next-themes' -import Link from 'next/link' -import { useRouter } from 'next/router' -import { useState } from 'react' - -import { useParams } from 'common' -import { useIsAPIDocsSidePanelEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' -import { ProfileImage } from 'components/ui/ProfileImage' -import { useProjectLintsQuery } from 'data/lint/lint-query' -import { ProjectIndexPageLink } from 'data/prefetchers/project.$ref' -import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' -import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' -import { useFlag } from 'hooks/ui/useFlag' -import { useSignOut } from 'lib/auth' -import { IS_PLATFORM, LOCAL_STORAGE_KEYS } from 'lib/constants' -import { useProfile } from 'lib/profile' -import { useAppStateSnapshot } from 'state/app-state' -import { - AiIconAnimation, - Button, - DropdownMenu, - DropdownMenuContent, - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuRadioGroup, - DropdownMenuRadioItem, - DropdownMenuSeparator, - DropdownMenuTrigger, - HoverCardContent_Shadcn_, - HoverCardTrigger_Shadcn_, - HoverCard_Shadcn_, - Separator, - Theme, - Tooltip, - TooltipContent, - TooltipTrigger, - cn, - singleThemes, -} from 'ui' -import { useSetCommandMenuOpen } from 'ui-patterns/CommandMenu' -import { useProjectContext } from '../ProjectContext' -import { CommandOption } from './CommandOption' -import { - generateOtherRoutes, - generateProductRoutes, - generateSettingsRoutes, - generateToolRoutes, -} from './NavigationBar.utils' -import { NavigationIconButton } from './NavigationIconButton' -import NavigationIconLink from './NavigationIconLink' - -export const ICON_SIZE = 20 -export const ICON_STROKE_WIDTH = 1.5 - -const NavigationBar = () => { - const snap = useAppStateSnapshot() - - const [storedAllowNavPanel] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.EXPAND_NAVIGATION_PANEL, - true - ) - // Don't allow the nav panel to expand in playwright tests - const allowNavPanelToExpand = process.env.NEXT_PUBLIC_NODE_ENV !== 'test' && storedAllowNavPanel - - return ( -
- -
- ) -} - -export const NavContent = () => { - const router = useRouter() - const { profile } = useProfile() - const { project } = useProjectContext() - const { theme, setTheme } = useTheme() - const { ref: projectRef } = useParams() - const setCommandMenuOpen = useSetCommandMenuOpen() - const snap = useAppStateSnapshot() - - const signOut = useSignOut() - - const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled() - const [hasInvalidImg, setHasInvalidImg] = useState(false) - const [userDropdownOpen, setUserDropdownOpenState] = useState(false) - - const [storedAllowNavPanel] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.EXPAND_NAVIGATION_PANEL, - true - ) - // Don't allow the nav panel to expand in playwright tests - const allowNavPanelToExpand = process.env.NEXT_PUBLIC_NODE_ENV !== 'test' && storedAllowNavPanel - - const { - projectAuthAll: authEnabled, - projectEdgeFunctionAll: edgeFunctionsEnabled, - projectStorageAll: storageEnabled, - realtimeAll: realtimeEnabled, - } = useIsFeatureEnabled([ - 'project_auth:all', - 'project_edge_function:all', - 'project_storage:all', - 'realtime:all', - ]) - - const { data } = useProjectLintsQuery({ - projectRef: project?.ref, - }) - - const securityLints = (data ?? []).filter((lint) => lint.categories.includes('SECURITY')) - const errorLints = securityLints.filter((lint) => lint.level === 'ERROR') - - const activeRoute = router.pathname.split('/')[3] - const toolRoutes = generateToolRoutes(projectRef, project) - const productRoutes = generateProductRoutes(projectRef, project, { - auth: authEnabled, - edgeFunctions: edgeFunctionsEnabled, - storage: storageEnabled, - realtime: realtimeEnabled, - }) - const showWarehouse = useFlag('warehouse') - - const otherRoutes = generateOtherRoutes(projectRef, project) - const settingsRoutes = generateSettingsRoutes(projectRef, project) - - const onCloseNavigationIconLink = (event: any) => { - snap.setNavigationPanelOpen( - false, - event.target.id === 'icon-link' || ['svg', 'path'].includes(event.target.localName) - ) - } - - const CommandButton = ( - - - } - > - Commands - - - - - - - } - label="Search" - shortcut="K" - onClick={() => { - setCommandMenuOpen(true) - snap.setNavigationPanelOpen(false) - }} - /> - - } - label="Assistant" - shortcut="I" - onClick={() => { - snap.setAiAssistantPanel({ open: !snap.aiAssistantPanel.open }) - }} - /> - - - ) - - const UserAccountButton = ( - - ) - - return ( - <> -
    - , - link: `/project/${projectRef}`, - linkElement: , - }} - onClick={onCloseNavigationIconLink} - /> - - {toolRoutes.map((route) => ( - - ))} - - {productRoutes.map((route) => ( - - ))} - - - {otherRoutes.map((route) => { - if (route.key === 'api' && isNewAPIDocsEnabled) { - return ( - { - snap.setShowProjectApiDocs(true) - snap.setNavigationPanelOpen(false) - }} - icon={} - > - Project API - - ) - } else if (route.key === 'advisors') { - return ( -
    - {securityLints.length > 0 && ( -
    0 ? 'bg-destructive-600' : 'bg-warning-600' - )} - /> - )} - - -
    - ) - } else if (route.key === 'logs') { - // TODO: Undo this when warehouse flag is removed - const label = showWarehouse ? 'Logs & Analytics' : route.label - const newRoute = { ...route, label } - return ( - - ) - } else { - return ( - - ) - } - })} -
- -
    - {settingsRoutes.map((route) => ( - - ))} - - {IS_PLATFORM && ( - <> - {!allowNavPanelToExpand && ( - - {CommandButton} - - Commands - - - )} - {allowNavPanelToExpand && CommandButton} - - )} - - { - setUserDropdownOpenState(open) - if (open === false) snap.setNavigationPanelOpen(false) - }} - > - {allowNavPanelToExpand ? ( - {UserAccountButton} - ) : ( - - - {UserAccountButton} - - - Account settings - - - )} - - - {IS_PLATFORM && ( - <> -
    - {profile && ( - <> - - {profile.username} - - {profile.primary_email !== profile.username && ( - - {profile.primary_email} - - )} - - )} -
    - - - - - - Account preferences - - - snap.setShowFeaturePreviewModal(true)} - onSelect={() => snap.setShowFeaturePreviewModal(true)} - > - - Feature previews - - - - - )} - - Theme - { - setTheme(value) - }} - > - {singleThemes.map((theme: Theme) => ( - - {theme.name} - - ))} - - - {IS_PLATFORM && ( - <> - - - { - await signOut() - await router.push('/sign-in') - }} - > - Log out - - - - )} -
    -
    -
- - ) -} - -export default NavigationBar diff --git a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx index 16eedb4530e..1d0bd06a8f1 100644 --- a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx +++ b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx @@ -14,7 +14,7 @@ import { TableEditor, } from 'icons' import { IS_PLATFORM, PROJECT_STATUS } from 'lib/constants' -import { ICON_SIZE, ICON_STROKE_WIDTH } from './NavigationBar' +import { ICON_SIZE, ICON_STROKE_WIDTH } from 'components/interfaces/Sidebar' export const generateToolRoutes = (ref?: string, project?: Project): Route[] => { const isProjectBuilding = project?.status === PROJECT_STATUS.COMING_UP diff --git a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationIconLink.tsx b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationIconLink.tsx index 86e8e9bebf8..bf356f5b22b 100644 --- a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationIconLink.tsx +++ b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationIconLink.tsx @@ -12,7 +12,6 @@ import { cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui' import type { Route } from 'components/ui/ui.types' import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { LOCAL_STORAGE_KEYS } from 'lib/constants' -import { useAppStateSnapshot } from 'state/app-state' interface NavigationIconButtonProps extends AnchorHTMLAttributes { route: Route @@ -21,8 +20,6 @@ interface NavigationIconButtonProps extends AnchorHTMLAttributes( ({ route, isActive = false, onClick = noop, ...props }, ref) => { - const snap = useAppStateSnapshot() - const [storedAllowNavPanel] = useLocalStorageQuery( LOCAL_STORAGE_KEYS.EXPAND_NAVIGATION_PANEL, true @@ -78,7 +75,6 @@ const NavigationIconLink = forwardRef { selectedFeaturePreview: '', showAiSettingsModal: false, showGenerateSqlModal: false, - navigationPanelOpen: false, - navigationPanelJustClosed: false, ongoingQueriesPanelOpen: false, mobileMenuOpen: false, } @@ -149,8 +147,6 @@ const getInitialState = () => { selectedFeaturePreview: '', showAiSettingsModal: false, showGenerateSqlModal: false, - navigationPanelOpen: false, - navigationPanelJustClosed: false, ongoingQueriesPanelOpen: false, mobileMenuOpen: false, } @@ -215,27 +211,6 @@ export const appState = proxy({ appState.showGenerateSqlModal = value }, - navigationPanelOpen: false, - navigationPanelJustClosed: false, - setNavigationPanelOpen: (value: boolean, trackJustClosed: boolean = false) => { - if (value === false) { - if (trackJustClosed) { - appState.navigationPanelOpen = false - appState.navigationPanelJustClosed = true - } else { - appState.navigationPanelOpen = false - appState.navigationPanelJustClosed = false - } - } else { - if (appState.navigationPanelJustClosed === false) { - appState.navigationPanelOpen = true - } - } - }, - setNavigationPanelJustClosed: (value: boolean) => { - appState.navigationPanelJustClosed = value - }, - resetAiAssistantPanel: () => { appState.aiAssistantPanel = { ...INITIAL_AI_ASSISTANT, diff --git a/apps/studio/styles/main.scss b/apps/studio/styles/main.scss index 1a97ce799d5..42081c2bdc9 100644 --- a/apps/studio/styles/main.scss +++ b/apps/studio/styles/main.scss @@ -15,6 +15,14 @@ --chart-5: 27 87% 67%; --chart-warning: hsl(var(--warning-default)); --chart-destructive: hsl(var(--destructive-default)); + --sidebar-background: var(--background-dash-sidebar); + --sidebar-foreground: var(--foreground-default); + --sidebar-primary: var(--foreground-default); + --sidebar-primary-foreground: var(--warning-default); + --sidebar-accent: var(--background-selection); + --sidebar-accent-foreground: var(--foreground-default); + --sidebar-border: var(--border-default); + --sidebar-ring: 217.2 91.2% 59.8%; } .dark { @@ -25,6 +33,14 @@ --chart-5: 340 75% 55%; --chart-warning: hsl(var(--warning-default)); --chart-destructive: hsl(var(--destructive-default)); + --sidebar-background: var(--background-dash-sidebar); + --sidebar-foreground: var(--foreground-default); + --sidebar-primary: var(--foreground-default); + --sidebar-primary-foreground: var(--warning-default); + --sidebar-accent: var(--background-selection); + --sidebar-accent-foreground: var(--foreground-default); + --sidebar-border: var(--border-default); + --sidebar-ring: 217.2 91.2% 59.8%; } @layer utilities { diff --git a/packages/config/tailwind.config.js b/packages/config/tailwind.config.js index 88c13876744..70cda2e9a53 100644 --- a/packages/config/tailwind.config.js +++ b/packages/config/tailwind.config.js @@ -112,6 +112,16 @@ const uiConfig = ui({ extend: { colors: { ...kebabToNested(colorExtend), + sidebar: { + DEFAULT: 'hsl(var(--sidebar-background))', + foreground: 'hsl(var(--sidebar-foreground))', + primary: 'hsl(var(--sidebar-primary))', + 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))', + accent: 'hsl(var(--sidebar-accent))', + 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))', + border: 'hsl(var(--sidebar-border))', + ring: 'hsl(var(--sidebar-ring))', + }, }, typography: ({ theme }) => ({ diff --git a/packages/ui/src/components/shadcn/ui/sidebar.tsx b/packages/ui/src/components/shadcn/ui/sidebar.tsx index 77aea8b0612..e2e57e05f41 100644 --- a/packages/ui/src/components/shadcn/ui/sidebar.tsx +++ b/packages/ui/src/components/shadcn/ui/sidebar.tsx @@ -149,6 +149,7 @@ SidebarProvider.displayName = 'SidebarProvider' const Sidebar = React.forwardRef< HTMLDivElement, React.ComponentProps<'div'> & { + overflowing?: boolean side?: 'left' | 'right' variant?: 'sidebar' | 'floating' | 'inset' collapsible?: 'offcanvas' | 'icon' | 'none' @@ -156,6 +157,7 @@ const Sidebar = React.forwardRef< >( ( { + overflowing = false, side = 'left', variant = 'sidebar', collapsible = 'offcanvas', @@ -205,7 +207,10 @@ const Sidebar = React.forwardRef< return (