Drawer

A teleported panel for secondary flows and mobile-friendly details.

Installation

npx alixan-ui-nuxt add drawer

Usage

app.vue
<template>
  <NuxtPage />
  <DrawerHost /> <!-- Add DrawerHost once near the root. It renders only on the client. -->
</template>
Example.vue

Project name: Alixan UI

<script setup lang="ts">
import WorkspaceDrawer from '~/components/WorkspaceDrawer.vue'

const drawer = useDrawer()
const projectName = ref('Alixan UI')

const openDrawer = () => {
  drawer.open(WorkspaceDrawer, {
    width: '420px',
    height: '360px',
    position: 'bottom',
    title: 'drawerPreview.title',
    data: {
      projectName: projectName.value,
      onSave: (value: string) => {
        projectName.value = value
      },
    },
  })
}
</script>

<template>
  <div class="flex flex-wrap items-center gap-3">
    <Button @click="openDrawer">
      {{ $t('drawerPreview.openDrawer') }}
    </Button>
    <p class="text-sm text-muted-foreground">
      {{ $t('drawerPreview.projectName') }}:
      <span class="font-medium text-foreground">{{ projectName }}</span>
    </p>
  </div>
</template>
WorkspaceDrawer.vue
<script setup lang="ts">
interface WorkspaceDrawerData {
  projectName: string
  onSave: (value: string) => void
}

const props = defineProps<{
  data: WorkspaceDrawerData
  close: () => void
}>()

const projectName = ref('')

onMounted(() => {
  projectName.value = props.data.projectName
})

const save = () => {
  props.data.onSave(projectName.value)
  props.close()
}
</script>

<template>
  <div class="size-full flex flex-col divide-y">
    <div class="flex-1 space-y-3 p-4">
      <Input v-model="projectName" label="drawerPreview.projectName" />
    </div>

    <div class="grid grid-cols-2 gap-2 p-4">
      <Button variant="outlined" label="drawerPreview.cancel" @click="close" />
      <Button label="drawerPreview.save" @click="save" />
    </div>
  </div>
</template>

API Reference

PropTypeDefaultDescription
componentComponent-Vue component rendered inside DrawerHost.
titlestring-Passed to DrawerHeader.
widthstring'420px'Drawer max-width.
heightstring'420px'Drawer max-height for top and bottom positions.
position'top' | 'right' | 'bottom' | 'left''bottom'Drawer placement.
dataRecord<string, unknown>{}Data passed to the dynamic component.