Docs Components Overlays

Drawer

React example follows below.
ts
import * as React from "react";
const drawerFixture = {
id: "drawer",
trigger: "Open drawer",
side: "bottom",
eyebrow: "Deploy",
title: "Ship v2.4.2",
body: "Rolling restart across 6 replicas.",
dismissable: true,
} satisfies {
id: string;
trigger: string;
side: "bottom" | "top" | "left" | "right";
eyebrow: string;
title: string;
body: string;
dismissable: boolean;
};
import { Button, Drawer } from "@grassroot/ui-react";
export default function DrawerDemo() {
const [open, setOpen] = React.useState(false);
return (
<div>
<Button variant="secondary" onClick={() => setOpen(true)}>
{drawerFixture.trigger}
</Button>
<Drawer
open={open}
onOpenChange={setOpen}
side={drawerFixture.side}
eyebrow={drawerFixture.eyebrow}
title={drawerFixture.title}
dismissable={drawerFixture.dismissable}
>
{drawerFixture.body}
</Drawer>
</div>
);
}
ts
<script setup lang="ts">
import { ref } from "vue";
import { Button, Drawer } from "@grassroot/ui-vue";
const drawerFixture = {
id: "drawer",
trigger: "Open drawer",
side: "bottom",
eyebrow: "Deploy",
title: "Ship v2.4.2",
body: "Rolling restart across 6 replicas.",
dismissable: true,
} satisfies {
id: string;
trigger: string;
side: "bottom" | "top" | "left" | "right";
eyebrow: string;
title: string;
body: string;
dismissable: boolean;
};
const open = ref(false);
</script>
<template>
<div>
<Button variant="secondary" @click="open = true">{{ drawerFixture.trigger }}</Button>
<Drawer
v-model:open="open"
:side="drawerFixture.side"
:eyebrow="drawerFixture.eyebrow"
:dismissable="drawerFixture.dismissable"
><template #title>{{ drawerFixture.title }}</template
>{{ drawerFixture.body }}</Drawer
>
</div>
</template>
ts
import { Component, signal } from "@angular/core";
import { GrassrootButton, GrassrootDrawer, GrassrootDrawerTitle } from "@grassroot/ui-angular";
const drawerFixture = {
id: "drawer",
trigger: "Open drawer",
side: "bottom",
eyebrow: "Deploy",
title: "Ship v2.4.2",
body: "Rolling restart across 6 replicas.",
dismissable: true,
} satisfies {
id: string;
trigger: string;
side: "bottom" | "top" | "left" | "right";
eyebrow: string;
title: string;
body: string;
dismissable: boolean;
};
@Component({
selector: "app-drawer-demo",
standalone: true,
imports: [GrassrootButton, GrassrootDrawer, GrassrootDrawerTitle],
template: `
<div>
<grassroot-button variant="secondary" (click)="open.set(true)">{{
fixture.trigger
}}</grassroot-button>
<grassroot-drawer
[open]="open()"
(openChange)="open.set($event)"
[side]="fixture.side"
[eyebrow]="fixture.eyebrow"
[dismissable]="fixture.dismissable"
><h2 grassrootDrawerTitle>{{ fixture.title }}</h2>
{{ fixture.body }}</grassroot-drawer
>
</div>
`,
})
export class DrawerDemoComponent {
readonly open = signal(false);
protected readonly fixture = drawerFixture;
}
export default DrawerDemoComponent;
ts
<script lang="ts">
import { Button, Drawer } from "@grassroot/ui-svelte";
const drawerFixture = {
id: "drawer",
trigger: "Open drawer",
side: "bottom",
eyebrow: "Deploy",
title: "Ship v2.4.2",
body: "Rolling restart across 6 replicas.",
dismissable: true,
} satisfies {
id: string;
trigger: string;
side: "bottom" | "top" | "left" | "right";
eyebrow: string;
title: string;
body: string;
dismissable: boolean;
};
let open = $state(false);
</script>
{#snippet title()}{drawerFixture.title}{/snippet}
{#snippet children()}{drawerFixture.body}{/snippet}
<div>
<Button variant="secondary" onClick={() => (open = true)}>{drawerFixture.trigger}</Button>
<Drawer
{open}
onOpenChange={(next) => (open = next)}
side={drawerFixture.side}
eyebrow={drawerFixture.eyebrow}
dismissable={drawerFixture.dismissable}
{title}
{children}
/>
</div>
ts
/** @jsxImportSource solid-js */
import { createSignal } from "solid-js";
import { Button, Drawer } from "@grassroot/ui-solid";
const drawerFixture = {
id: "drawer",
trigger: "Open drawer",
side: "bottom",
eyebrow: "Deploy",
title: "Ship v2.4.2",
body: "Rolling restart across 6 replicas.",
dismissable: true,
} satisfies {
id: string;
trigger: string;
side: "bottom" | "top" | "left" | "right";
eyebrow: string;
title: string;
body: string;
dismissable: boolean;
};
export default function DrawerDemo() {
const [open, setOpen] = createSignal(false);
return (
<div>
<Button variant="secondary" onClick={() => setOpen(true)}>
{drawerFixture.trigger}
</Button>
<Drawer
open={open()}
onOpenChange={setOpen}
side={drawerFixture.side}
eyebrow={drawerFixture.eyebrow}
title={drawerFixture.title}
dismissable={drawerFixture.dismissable}
>
{drawerFixture.body}
</Drawer>
</div>
);
}

Installation

API Reference

Import

import * as React from "react";
import { Button, Drawer } from "@grassroot/ui-react";

Props

Prop
Type
Default
Requirement
open
boolean
required
onOpenChange
(open: boolean) => void
required
side
"top" | "bottom" | "right" | "left" | undefined
optional
eyebrow
string | undefined
optional
dismissable
boolean | undefined
optional
className
string | undefined
optional
Prop
open
Type
boolean
Default
Requirement
required
Prop
onOpenChange
Type
(open: boolean) => void
Default
Requirement
required
Prop
side
Type
"top" | "bottom" | "right" | "left" | undefined
Default
Requirement
optional
Prop
eyebrow
Type
string | undefined
Default
Requirement
optional
Prop
dismissable
Type
boolean | undefined
Default
Requirement
optional
Prop
className
Type
string | undefined
Default
Requirement
optional

Events

EventPayload
onOpenChange(open: boolean) => void

Content regions

  • children
  • title

Import

import { ref } from "vue";
import { Button, Drawer } from "@grassroot/ui-vue";

Props

Prop
Type
Default
Requirement
open
boolean
required
side
"bottom" | "top" | "left" | "right"
"bottom"
optional
eyebrow
string
optional
dismissable
boolean
true
optional
Prop
open
Type
boolean
Default
Requirement
required
Prop
side
Type
"bottom" | "top" | "left" | "right"
Default
"bottom"
Requirement
optional
Prop
eyebrow
Type
string
Default
Requirement
optional
Prop
dismissable
Type
boolean
Default
true
Requirement
optional

Events

EventPayload
update:open(_open: boolean) => true

Content regions

  • default
  • title

Import

import { Component, signal } from "@angular/core";
import { GrassrootButton, GrassrootDrawer, GrassrootDrawerTitle } from "@grassroot/ui-angular";

Props

Prop
Type
Default
Requirement
open
boolean
required
side
"bottom" | "top" | "left" | "right"
"bottom"
optional
eyebrow
string | undefined
undefined
optional
dismissable
boolean
true
optional
className
string
optional
Prop
open
Type
boolean
Default
Requirement
required
Prop
side
Type
"bottom" | "top" | "left" | "right"
Default
"bottom"
Requirement
optional
Prop
eyebrow
Type
string | undefined
Default
undefined
Requirement
optional
Prop
dismissable
Type
boolean
Default
true
Requirement
optional
Prop
className
Type
string
Default
Requirement
optional

Events

EventPayload
openChangeboolean

Content regions

  • default
  • title

Import

import { Button, Drawer } from "@grassroot/ui-svelte";

Props

Prop
Type
Default
Requirement
open
boolean
required
side
"bottom" | "top" | "left" | "right"
"bottom"
optional
eyebrow
string
optional
dismissable
boolean
true
optional
onOpenChange
(open: boolean) => void
required
className
string
optional
Prop
open
Type
boolean
Default
Requirement
required
Prop
side
Type
"bottom" | "top" | "left" | "right"
Default
"bottom"
Requirement
optional
Prop
eyebrow
Type
string
Default
Requirement
optional
Prop
dismissable
Type
boolean
Default
true
Requirement
optional
Prop
onOpenChange
Type
(open: boolean) => void
Default
Requirement
required
Prop
className
Type
string
Default
Requirement
optional

Events

EventPayload
onOpenChange(open: boolean) => void

Content regions

  • children
  • title

Import

import { createSignal } from "solid-js";
import { Button, Drawer } from "@grassroot/ui-solid";

Props

Prop
Type
Default
Requirement
open
boolean
required
onOpenChange
(open: boolean) => void
required
side
"bottom" | "top" | "left" | "right"
"bottom"
optional
eyebrow
string
optional
dismissable
boolean
true
optional
className
string
optional
Prop
open
Type
boolean
Default
Requirement
required
Prop
onOpenChange
Type
(open: boolean) => void
Default
Requirement
required
Prop
side
Type
"bottom" | "top" | "left" | "right"
Default
"bottom"
Requirement
optional
Prop
eyebrow
Type
string
Default
Requirement
optional
Prop
dismissable
Type
boolean
Default
true
Requirement
optional
Prop
className
Type
string
Default
Requirement
optional

Events

EventPayload
onOpenChange(open: boolean) => void

Content regions

  • children
  • title