@0k/vue-side-panel

Shared Vue 3 side-panel chrome and interaction controller for responsive docked panels and drawers.
381
Install
npm install @0k/vue-side-panel
Latest Version:0.1.6
Vue:3
License:MIT
Last Updated:Oct 8, 2026
Links: GitHub  ·  npm
Maintainer: vaab

#+TITLE: @0k/vue-side-panel

  • Purpose

=@0k/vue-side-panel= provides resizable side panels for Vue 3 applications: docked beside the content on wide screens, sliding drawers on narrow ones. It owns panel chrome and interaction (collapse, resize, drawer exclusivity, backdrop and Escape dismissal, accessible controls). The host application keeps its content, navigation, grid reservation, storage keys, persistence adapters, labels, and visual theme.

  • Install

#+begin_src sh npm install @0k/vue-side-panel #+end_src

=vue= =^3.5= is a peer dependency.

  • Usage

#+begin_src typescript // main.ts import '@0k/vue-side-panel/style.css'; #+end_src

#+begin_src vue

<script setup lang="ts"> import { onBeforeUnmount } from 'vue'; import { SidePanel, createPanelController } from '@0k/vue-side-panel'; const sidebar = createPanelController({ id: 'sidebar', side: 'left', defaultWidth: 280, minWidth: 200, maxWidth: 480, collapsedStorageKey: 'app.sidebar.collapsed', widthStorageKey: 'app.sidebar.width', cssWidthVariable: '--app-sidebar-width', }); onBeforeUnmount(() => sidebar.dispose()); </script> #+end_src

The controller writes the current width to =cssWidthVariable= on the document root, so the host layout can reserve the docked width (for instance a padding-left: var(--app-sidebar-width) applied while sidebar.docked.value is true).

  • Behavior contract
  • One module-level =(min-width: 75rem)= media query (DESKTOP_WIDE_QUERY) selects docked or drawer mode.
  • Desktop collapse and width persist through host-supplied keys and storage (default: localStorage). Storage and callback failures never prevent in-memory use.
  • Mobile drawers are transient. Panels sharing a createDrawerGroup() group have one open drawer at most.
  • Left and right panels support pointer and keyboard resizing (arrow keys: 8 px, with Shift: 32 px) with bounded values and cleanup on pointer-up, cancellation, or unmount.
  • =SidePanel= provides backdrop, Escape dismissal, collapse/reopen controls, accessible labels, and header/body/footer slots. The footer stays pinned.
  • Closed drawers stay mounted for their exit transition, then become hidden and non-interactive.
  • Styling is entirely through =--side-panel-*= custom properties and host classes; the package does not impose an application palette or typography.
  • API

** createPanelController(options)

| Option | Type | Meaning | |------------------------+----------------------------+-----------------------------------------------| | id | string | Panel identifier within its drawer group | | side | "left" or "right" | Edge the panel is attached to | | defaultWidth | number | Width in px when nothing is stored | | minWidth, maxWidth | number | Resize bounds in px | | collapsedStorageKey | string | Storage key of the desktop collapsed state | | widthStorageKey | string | Storage key of the width | | cssWidthVariable | string starting with -- | Root CSS variable receiving the width | | storage | PanelStorage, optional | getItem / setItem / removeItem adapter | | drawerGroup | DrawerGroup, optional | Shared group from createDrawerGroup() | | initialDrawerOpen | boolean, optional | Open the drawer initially (own group only) | | onCollapsedCommit | callback, optional | Called after a collapse change is committed | | onWidthCommit | callback, optional | Called after a resize is committed |

The returned controller exposes reactive collapsed, width, drawerOpen, visible, docked, reopenVisible and isDesktopWide; the actions openPanel(), closePanel(), togglePanel(), setCollapsed() and setWidth(); and dispose(), which releases its watcher and timer. For custom chrome built on usePanelResize, it also exposes id, side, minWidth, maxWidth, widthMode ("layout", "drag" or "nudge"), openDrawer(), closeDrawer(), setWidthLive() (width without persisting), setDragging() and markNudge().

=SidePanel= reads its controller once when it is created: to switch controllers, re-key the component.

** SidePanel props

  • Required labels (no built-in strings, for host translation): panelLabel, closeLabel, reopenLabel, resizeLabel.
  • contained (default false): when docked, the panel stays in normal flow and fills its host container instead of being fixed to the viewport edge.
  • showBackdrop, showClose, showReopen (default true).
  • Host class hooks: hostClass, panelClass, backdropClass, closeClass, resizeClass, reopenClass.
  • Test ids: panelTestId, closeTestId, resizeTestId, reopenTestId.

** SidePanel slots

  • default: panel body.
  • header, footer: rendered only when provided; the footer stays pinned.
  • close: replaces the close button; receives { close }.
  • reopen: replaces the content of the reopen handle.

** Other exports

  • createDrawerGroup(initial?): one-open-at-most group shared by panels.
  • usePanelViewport(): returns the shared reactive isDesktopWide flag.
  • usePanelResize(options): the pointer and keyboard resize logic used by =SidePanel=, for custom chrome.

** Theming

Override any =--side-panel-= custom property on the host, for example --side-panel-background, --side-panel-color, --side-panel-border-color, --side-panel-z-index, --side-panel-backdrop-background, --side-panel-transition-duration, --side-panel-drawer-max-width and the ~--side-panel-safe-~ insets. See [[https://github.com/0k/vue-side-panel/blob/master/src/SidePanel.vue][src/SidePanel.vue]] for the full list and the defaults.

  • Development

Run npm run check (tests, type check, build).

Releases are published to npm with the =pkg= release workflow from a tagged commit: the version comes from the tag and README.md is generated from README.org.

  • License

MIT, see LICENSE.

Related Packages

vue3-side-panel

Easy to use and flexible modal sidebar component for Vue3

83,799 62
@greenborn/vue-side-menu

Menú lateral genérico y autocontenido para Vue 3: configurable por props, respon...

691 0
vue-grid-layout

A draggable and resizable grid layout, as a Vue component.

2,102,559 7,398
vue3-grid-layout-next

A draggable and resizable grid layout, as a Vue component.

773,720 129
vue-grid-layout-v3

A draggable and resizable grid layout, as a Vue component.

429,159 113

Version History

Version Released Vue License
0.1.6 ^3.5.0 MIT