logo

Aki UI

アキ ウイ

Smooth Drawer

スムースドロワー

A sheet that comes up from the bottom edge and can be thrown back down. Dismissal reads velocity as well as distance, so a quick flick closes it from near the top while a slow drag has to travel; anything short of that springs back. There is no drawer library behind it — the sheet is a dragging Framer Motion element, and the dialog obligations are handled here: Tab is trapped inside the panel, Escape closes it, the body stops scrolling while it is up, and document.activeElement is remembered on open so focus lands back on the trigger on close. The gradient price tag and shimmering call to action from the original are gone; the body is yours to fill. Adapted from Kokonut UI under the MIT licence.

Installation

Copy and paste the following code into a new component file:1

"use client"

/**
* Adapted for Aki UI from Kokonut UI's Smooth Drawer.
* Original author: @dorianbaffier — https://kokonutui.com
* Copyright (c) 2025 kokonutUI, MIT License.
* https://github.com/kokonut-labs/kokonutui
*
* Reworked here onto the local palette. The vaul drawer and the shadcn Button
* are gone: the sheet, its drag-to-dismiss and its focus trap are hand-rolled

How to use it2

"use client"

import { SmoothDrawer } from "@/components/ui/smooth-drawer"

export default function Page() {
return (
<SmoothDrawer
trigger="Upgrade"
title="Aki UI — lifetime"
description="Every component, every update, one payment."

Props

SmoothDrawer

NameDefaultDescription
trigger

string

Label on the button that opens the sheet

title

string

Heading, also the accessible name of the dialog

description

string

Line under the heading, used as the description

children

ReactNode

Body between the description and the buttons

confirmLabel"Confirm"

string

Text on the primary button

cancelLabel"Maybe later"

string

Text on the dismiss button

onConfirm

() => void

Fired by the primary button, which then closes the sheet

darkfalse

boolean

Render the dark palette