MicroClub Sidebar
mcoli-ui-registry/mc-sidebarFreeComponent
A sidebar component for MicroClub UI
Live preview
live · rendered by the registry
Rendered by mcoli-ui-registry on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://mcoli-ui.microclub.info/r/mc-sidebar.jsonSource
1'use client';23import * as React from 'react';4import { mergeProps } from '@base-ui/react/merge-props';5import { useRender } from '@base-ui/react/use-render';6import { cva, type VariantProps } from 'class-variance-authority';7import { ChevronDownIcon, PanelLeftIcon } from 'lucide-react';89import { cn } from '@/lib/utils';10import { McButton } from '@/registry/ui/mc-button';1112const SIDEBAR_COOKIE_NAME = 'sidebar_state';13const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;14const SIDEBAR_WIDTH = '255px';15const SIDEBAR_WIDTH_ICON = '51px';16const SIDEBAR_KEYBOARD_SHORTCUT = 'b';1718type SidebarContextProps = {19 state: 'expanded' | 'collapsed';20 open: boolean;21 setOpen: (open: boolean) => void;22 toggleSidebar: () => void;23};2425const SidebarContext = React.createContext<SidebarContextProps | null>(null);2627function useSidebar() {28 const context = React.useContext(SidebarContext);29 if (!context) {30 throw new Error('useSidebar must be used within a SidebarProvider.');31 }32 return context;33}3435function SidebarProvider({36 defaultOpen = true,37 open: openProp,38 onOpenChange: setOpenProp,39 className,40 style,41 children,42 ...props43}: React.ComponentProps<'div'> & {44 defaultOpen?: boolean;45 open?: boolean;46 onOpenChange?: (open: boolean) => void;47}) {48 const [_open, _setOpen] = React.useState(() => {49 if (typeof document === 'undefined') {50 return defaultOpen;51 }5253 const cookie = document.cookie54 .split('; ')55 .find((entry) => entry.startsWith(`${SIDEBAR_COOKIE_NAME}=`));5657 if (!cookie) {58 return defaultOpen;59 }6061 return cookie.split('=')[1] === 'true';62 });63 const open = openProp ?? _open;64 const setOpen = React.useCallback(65 (value: boolean | ((value: boolean) => boolean)) => {66 const openState = typeof value === 'function' ? value(open) : value;67 if (setOpenProp) {68 setOpenProp(openState);69 } else {70 _setOpen(openState);71 }72 },73 [setOpenProp, open]74 );7576 React.useEffect(() => {77 document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;78 }, [open]);7980 const toggleSidebar = React.useCallback(() => {81 return setOpen((open) => !open);82 }, [setOpen]);8384 React.useEffect(() => {85 const handleKeyDown = (event: KeyboardEvent) => {86 if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {87 event.preventDefault();88 toggleSidebar();89 }90 };9192// … truncated
What it pulls in
npm packages
Files it writes
More from mcoli-ui-registry
All 42 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| MicroClub Accordionmc-accordion | mcoli-ui-registry | Components | Free | 2 deps | |
| MicroClub Alertmc-alert | mcoli-ui-registry | Components | Free | 1 dep | |
| MicroClub Alert Dialogmc-alert-dialog | mcoli-ui-registry | Components | Free | 1 dep | |
| MicroClub Avatarmc-avatar | mcoli-ui-registry | Components | Free | 1 dep | |
| MicroClub Badgemc-badge | mcoli-ui-registry | Components | Free | 1 dep | |
| MicroClub Breadcrumbmc-breadcrumb | mcoli-ui-registry | Components | Free | 2 deps | |
| MicroClub Buttonmc-button | mcoli-ui-registry | Components | Free | 2 deps | |
| MicroClub Calendarmc-calendar | mcoli-ui-registry | Components | Free | 3 deps |
