Skip to content

Usage

Default

The drawer component uses :is-open prop with :on-close callback to control visibility. By default, it slides in from the left side of the screen.

vue
<script setup lang="ts">
import { ref } from 'vue';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLDrawer from '@codeandfunction/callaloo/CLDrawer';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import { CLColors, CLTextTypes } from '@codeandfunction/callaloo';

const showDrawer = ref(false);
</script>

<template>
  <CLButton :color="CLColors.Primary" @click="showDrawer = true">Open Drawer</CLButton>
  <CLDrawer
    :is-open="showDrawer"
    :on-close="() => showDrawer = false">
    <div style="padding: 24px;">
      <CLHeading type="section">Drawer Title</CLHeading>
      <CLText :type="CLTextTypes.Body" style="margin-top: 16px;">
        This is the default drawer that slides in from the left. You can add any content here.
      </CLText>
      <div style="margin-top: 24px;">
        <CLButton @click="showDrawer = false">Close Drawer</CLButton>
      </div>
    </div>
  </CLDrawer>
</template>

Left Position

Use the position prop set to CLDrawerPosition.Left to slide the drawer in from the left side.

vue
<script setup lang="ts">
import { ref } from 'vue';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLDrawer from '@codeandfunction/callaloo/CLDrawer';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import { CLColors, CLDrawerPosition, CLTextTypes } from '@codeandfunction/callaloo';

const showDrawer = ref(false);
</script>

<template>
  <CLButton :color="CLColors.Primary" @click="showDrawer = true">Open Left Drawer</CLButton>
  <CLDrawer
    :is-open="showDrawer"
    :on-close="() => showDrawer = false"
    :position="CLDrawerPosition.Left">
    <div style="padding: 24px;">
      <CLHeading type="section">Left Drawer</CLHeading>
      <CLText :type="CLTextTypes.Body" style="margin-top: 16px;">
        This drawer slides in from the left side of the screen. It takes the full height of the viewport.
      </CLText>
      <div style="margin-top: 24px;">
        <CLButton @click="showDrawer = false">Close</CLButton>
      </div>
    </div>
  </CLDrawer>
</template>

Right Position

Use the position prop set to CLDrawerPosition.Right to slide the drawer in from the right side.

vue
<script setup lang="ts">
import { ref } from 'vue';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLDrawer from '@codeandfunction/callaloo/CLDrawer';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import { CLColors, CLDrawerPosition, CLTextTypes } from '@codeandfunction/callaloo';

const showDrawer = ref(false);
</script>

<template>
  <CLButton :color="CLColors.Primary" @click="showDrawer = true">Open Right Drawer</CLButton>
  <CLDrawer
    :is-open="showDrawer"
    :on-close="() => showDrawer = false"
    :position="CLDrawerPosition.Right">
    <div style="padding: 24px;">
      <CLHeading type="section">Right Drawer</CLHeading>
      <CLText :type="CLTextTypes.Body" style="margin-top: 16px;">
        This drawer slides in from the right side of the screen. It takes the full height of the viewport.
      </CLText>
      <div style="margin-top: 24px;">
        <CLButton @click="showDrawer = false">Close</CLButton>
      </div>
    </div>
  </CLDrawer>
</template>

Top Position

Use the position prop set to CLDrawerPosition.Top to slide the drawer in from the top.

vue
<script setup lang="ts">
import { ref } from 'vue';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLDrawer from '@codeandfunction/callaloo/CLDrawer';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import { CLColors, CLDrawerPosition, CLTextTypes } from '@codeandfunction/callaloo';

const showDrawer = ref(false);
</script>

<template>
  <CLButton :color="CLColors.Primary" @click="showDrawer = true">Open Top Drawer</CLButton>
  <CLDrawer
    :is-open="showDrawer"
    :on-close="() => showDrawer = false"
    :position="CLDrawerPosition.Top">
    <div style="padding: 24px;">
      <CLHeading type="section">Top Drawer</CLHeading>
      <CLText :type="CLTextTypes.Body" style="margin-top: 16px;">
        This drawer slides in from the top of the screen. It takes the full width of the viewport.
      </CLText>
      <div style="margin-top: 24px;">
        <CLButton @click="showDrawer = false">Close</CLButton>
      </div>
    </div>
  </CLDrawer>
</template>

Bottom Position

Use the position prop set to CLDrawerPosition.Bottom to slide the drawer in from the bottom.

vue
<script setup lang="ts">
import { ref } from 'vue';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLDrawer from '@codeandfunction/callaloo/CLDrawer';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import { CLColors, CLDrawerPosition, CLTextTypes } from '@codeandfunction/callaloo';

const showDrawer = ref(false);
</script>

<template>
  <CLButton :color="CLColors.Primary" @click="showDrawer = true">Open Bottom Drawer</CLButton>
  <CLDrawer
    :is-open="showDrawer"
    :on-close="() => showDrawer = false"
    :position="CLDrawerPosition.Bottom">
    <div style="padding: 24px;">
      <CLHeading type="section">Bottom Drawer</CLHeading>
      <CLText :type="CLTextTypes.Body" style="margin-top: 16px;">
        This drawer slides in from the bottom of the screen. It takes the full width of the viewport.
      </CLText>
      <div style="margin-top: 24px;">
        <CLButton @click="showDrawer = false">Close</CLButton>
      </div>
    </div>
  </CLDrawer>
</template>

With Snap Point

Use the snap-point prop to control how much of the screen the drawer should open to. The value is a decimal from 0 to 1 (e.g., 0.3 means 30% of the screen). This only works when auto-size is false.

vue
<script setup lang="ts">
import { ref } from 'vue';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLDrawer from '@codeandfunction/callaloo/CLDrawer';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import { CLColors, CLDrawerPosition, CLTextTypes } from '@codeandfunction/callaloo';

const showDrawer = ref(false);
const snapPoint = ref(0.6);
</script>

<template>
  <CLButton :color="CLColors.Primary" @click="showDrawer = true">Open Drawer with Snap Point</CLButton>
  <CLDrawer
    :is-open="showDrawer"
    :on-close="() => showDrawer = false"
    :snap-point="snapPoint"
    :auto-size="false"
    :position="CLDrawerPosition.Bottom">
    <div style="padding: 24px;">
      <CLHeading type="section">Drawer with Snap Point</CLHeading>
      <CLText :type="CLTextTypes.Body" style="margin-top: 16px;">
        This drawer opens to {{ (snapPoint * 100).toFixed(0) }}% of the screen height.
      </CLText>
      <div style="margin-top: 24px;">
        <CLButton @click="showDrawer = false">Close</CLButton>
      </div>
    </div>
  </CLDrawer>
</template>

Auto Size

Set auto-size to true to make the drawer automatically size based on its content. The drawer will respect the content size rather than using a percentage of the screen.

vue
<script setup lang="ts">
import { ref } from 'vue';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLDrawer from '@codeandfunction/callaloo/CLDrawer';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import { CLColors, CLDrawerPosition, CLTextTypes } from '@codeandfunction/callaloo';

const showDrawer = ref(false);
</script>

<template>
  <CLButton :color="CLColors.Primary" @click="showDrawer = true">Open Auto-Size Drawer</CLButton>
  <CLDrawer
    :is-open="showDrawer"
    :on-close="() => showDrawer = false"
    :auto-size="true"
    :position="CLDrawerPosition.Left">
    <div style="padding: 24px; width: 300px;">
      <CLHeading type="section">Auto-Size Drawer</CLHeading>
      <CLText :type="CLTextTypes.Body" style="margin-top: 16px;">
        This drawer automatically sizes based on its content width (300px in this case).
        The drawer will respect the content size rather than using a percentage of the screen.
      </CLText>
      <div style="margin-top: 24px;">
        <CLButton @click="showDrawer = false">Close</CLButton>
      </div>
    </div>
  </CLDrawer>
</template>

Non-Dismissible

Set dismissible to false to prevent the drawer from closing when clicking outside or pressing ESC.

vue
<script setup lang="ts">
import { ref } from 'vue';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLDrawer from '@codeandfunction/callaloo/CLDrawer';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import { CLColors, CLTextTypes } from '@codeandfunction/callaloo';

const showDrawer = ref(false);
</script>

<template>
  <CLButton :color="CLColors.Primary" @click="showDrawer = true">Open Non-Dismissible Drawer</CLButton>
  <CLDrawer
    :is-open="showDrawer"
    :on-close="() => showDrawer = false"
    :dismissible="false">
    <div style="padding: 24px;">
      <CLHeading type="section">Non-Dismissible Drawer</CLHeading>
      <CLText :type="CLTextTypes.Body" style="margin-top: 16px;">
        This drawer can only be closed using the close button or a programmatic action.
        Clicking outside or pressing ESC will not close it.
      </CLText>
      <div style="margin-top: 24px;">
        <CLButton @click="showDrawer = false">Close</CLButton>
      </div>
    </div>
  </CLDrawer>
</template>

Props

Slots

Released under the MIT License.