Skip to content

@vibe-labs/design-vue-responsive

Vue 3 responsive layout components for the Vibe Design System. Container-query-driven grid, stack, and container wrapper with a composable for imperative breakpoint access.

Usage

ts
import { VibeResponsiveContainer, VibeResponsiveGrid, VibeResponsiveStack, useContainerBreakpoint } from "@vibe-labs/design-vue-responsive";

Requires CSS from @vibe-labs/design-components-responsive (loaded via @vibe-labs/design-components).

Components

VibeResponsiveContainer

Establishes a container query context. Wrap any area that needs responsive children.

vue
<VibeResponsiveContainer>
  <!-- children can use container queries -->
</VibeResponsiveContainer>

<VibeResponsiveContainer name="sidebar" type="size">
  <!-- named container with both-axis sizing -->
</VibeResponsiveContainer>

Props

PropTypeDefaultDescription
tagstring"div"HTML element to render
typeContainerType"inline"inline · size · normal
nameContainerNamemain · sidebar · card · panel

Slots

SlotDescription
defaultContent

VibeResponsiveGrid

12-column grid with per-breakpoint column counts. Must be inside a VibeResponsiveContainer.

vue
<VibeResponsiveContainer>
  <VibeResponsiveGrid :cols="1" :cols-sm="2" :cols-lg="3" :cols-xl="4">
    <div>Card</div>
    <div>Card</div>
    <div>Card</div>
    <div>Card</div>
  </VibeResponsiveGrid>
</VibeResponsiveContainer>

Props

PropTypeDefaultDescription
tagstring"div"HTML element to render
colsGridColumn1Default column count
colsXsGridColumnColumns at xs (480px)
colsSmGridColumnColumns at sm (640px)
colsMdGridColumnColumns at md (768px)
colsLgGridColumnColumns at lg (1024px)
colsXlGridColumnColumns at xl (1280px)
cols2xlGridColumnColumns at 2xl (1536px)

Gap defaults to var(--responsive-grid-gap). Override with spacing utility classes or inline style.

Slots

SlotDescription
defaultGrid items

VibeResponsiveStack

Flex column that switches to row at a breakpoint. Must be inside a VibeResponsiveContainer.

vue
<VibeResponsiveContainer>
  <VibeResponsiveStack breakpoint="md">
    <aside>Sidebar</aside>
    <main>Content</main>
  </VibeResponsiveStack>
</VibeResponsiveContainer>

Props

PropTypeDefaultDescription
tagstring"div"HTML element to render
breakpointBreakpoint"md"Breakpoint to switch to row

Gap defaults to var(--responsive-stack-gap). Override with spacing utility classes or inline style.

Slots

SlotDescription
defaultStack children

Composables

useContainerBreakpoint

Observes a container element's inline size via ResizeObserver and exposes reactive breakpoint state. Use for logic that CSS container queries can't handle (swapping components, changing props, conditional rendering).

vue
<script setup>
import { ref } from "vue";
import { VibeResponsiveContainer, useContainerBreakpoint } from "@vibe-labs/design-vue-responsive";

const containerRef = ref<HTMLElement>();
const { current, above, below, width } = useContainerBreakpoint(containerRef);
</script>

<template>
  <VibeResponsiveContainer ref="containerRef">
    <p>Width: {{ width }}px — Breakpoint: {{ current ?? "below xs" }}</p>
    <DetailedTable v-if="above('lg')" />
    <CompactList v-else />
  </VibeResponsiveContainer>
</template>

Parameters

ParamTypeDescription
targetMaybeRefOrGetter<HTMLElement | null>Container element to observe

Returns

PropertyTypeDescription
currentRef<Breakpoint | null>Largest matching breakpoint, or null if below xs
above(bp: Breakpoint) => booleanTrue when container width >= breakpoint
below(bp: Breakpoint) => booleanTrue when container width < breakpoint
widthRef<number>Current container width in pixels

Cleans up automatically via onScopeDispose.

Dependencies

PackagePurpose
@vibe-labs/design-components-responsiveCSS + TypeScript types
@vibe-labs/coreShared utilities
vue (peer)Vue 3.5+

Build

bash
npm run build