Skip to content
← Drawer
Edit Drawer
Name
Also known as (comma separated)
Brief definition
Side panel that slides into view.
Notes
Tier
Core
Useful
Reference
Deleted
Controls schema (JSON array)
[ { "id": "title", "type": "text", "label": "Title", "default": "Filters" }, { "id": "side", "type": "select", "label": "Side", "default": "right", "options": [ "left", "right", "top", "bottom" ] }, { "id": "width", "type": "number", "label": "Panel size", "default": 320, "min": 240, "max": 480, "step": 20 }, { "id": "accent", "type": "color", "label": "Accent colour", "default": "#BFD9F2", "presets": [ "#F5C2E0", "#A8E6C1", "#BFD9F2", "#D9C8F0", "#E8A020", "#241430" ] }, { "id": "backdrop", "type": "toggle", "label": "Show backdrop", "default": true }, { "id": "open", "type": "toggle", "label": "Open by default", "default": true } ]
Templates (JSON object keyed by format)
{ "html": "<div class=\"drawer-demo{{#if backdrop}} drawer-demo--backdrop{{/if}}\">\n <div class=\"drawer drawer--{{side}}{{#if open}} drawer--open{{/if}}\" style=\"--size:{{width}}px;--accent:{{accent}};\" role=\"dialog\" aria-modal=\"{{#if backdrop}}true{{/if}}{{#unless backdrop}}false{{/unless}}\" aria-labelledby=\"drawer-title\">\n <div class=\"drawer__header\">\n <h3 class=\"drawer__title\" id=\"drawer-title\">{{title}}</h3>\n <button class=\"drawer__close\" type=\"button\" aria-label=\"Close\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\"><path d=\"M1 1l12 12M13 1L1 13\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linecap=\"round\"/></svg>\n </button>\n </div>\n <div class=\"drawer__body\">\n <p>Panel content lives here, for filters, forms, or navigation that do not need a full page.</p>\n </div>\n </div>\n</div>\n<style>\n.drawer-demo { position: relative; min-height: 360px; border-radius: 12px; overflow: hidden; background: #FAF7F2; }\n.drawer-demo--backdrop { background: rgba(36,20,48,.45); }\n.drawer { position: absolute; box-sizing: border-box; background: #FAF7F2; color: #241430; padding: 20px; box-shadow: 0 20px 44px rgba(36,20,48,.28); font: 16px/1.5 system-ui, sans-serif; }\n@media (prefers-reduced-motion: no-preference) {\n.drawer { transition: transform .2s ease; }\n}\n.drawer--left { left: 0; top: 0; bottom: 0; width: var(--size); border-right: 4px solid var(--accent); transform: translateX(-100%); }\n.drawer--left.drawer--open { transform: translateX(0); }\n.drawer--right { right: 0; top: 0; bottom: 0; width: var(--size); border-left: 4px solid var(--accent); transform: translateX(100%); }\n.drawer--right.drawer--open { transform: translateX(0); }\n.drawer--top { top: 0; left: 0; right: 0; height: var(--size); border-bottom: 4px solid var(--accent); transform: translateY(-100%); }\n.drawer--top.drawer--open { transform: translateY(0); }\n.drawer--bottom { bottom: 0; left: 0; right: 0; height: var(--size); border-top: 4px solid var(--accent); transform: translateY(100%); }\n.drawer--bottom.drawer--open { transform: translateY(0); }\n.drawer__header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }\n.drawer__title { margin: 0; font-size: 17px; font-weight: 600; }\n.drawer__close { background: none; border: none; cursor: pointer; color: #241430; padding: 4px; border-radius: 6px; }\n.drawer__close:hover, .drawer__close:focus-visible { background: var(--accent); outline: none; }\n.drawer__body p { margin: 0; font-size: 14px; color: #241430cc; }\n</style>", "tailwind": "<div class=\"relative min-h-[360px] rounded-xl overflow-hidden bg-[#FAF7F2]{{#if backdrop}} drawer-tw-demo--backdrop{{/if}}\">\n <div role=\"dialog\" aria-modal=\"{{#if backdrop}}true{{/if}}{{#unless backdrop}}false{{/unless}}\" aria-labelledby=\"drawer-tw-title\" class=\"drawer-tw drawer-tw--{{side}}{{#if open}} drawer-tw--open{{/if}} absolute box-border bg-[#FAF7F2] text-[#241430] p-5 shadow-2xl font-sans\" style=\"--size:{{width}}px;--accent:{{accent}};\">\n <div class=\"flex items-center justify-between mb-2.5\">\n <h3 id=\"drawer-tw-title\" class=\"m-0 text-[17px] font-semibold\">{{title}}</h3>\n <button type=\"button\" aria-label=\"Close\" class=\"bg-transparent border-none cursor-pointer text-[#241430] p-1 rounded-md hover:bg-[var(--accent)] focus-visible:bg-[var(--accent)] focus-visible:outline-none\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\"><path d=\"M1 1l12 12M13 1L1 13\" stroke=\"currentColor\" stroke-width=\"1.6\" fill=\"none\" stroke-linecap=\"round\"/></svg>\n </button>\n </div>\n <div class=\"text-sm text-[#241430]/80\">\n <p class=\"m-0\">Panel content lives here, for filters, forms, or navigation that do not need a full page.</p>\n </div>\n </div>\n</div>\n<style>\n.drawer-tw-demo--backdrop { background: rgba(36,20,48,.45); }\n.drawer-tw--left { left: 0; top: 0; bottom: 0; width: var(--size); border-right: 4px solid var(--accent); transform: translateX(-100%); }\n@media (prefers-reduced-motion: no-preference) {\n.drawer-tw--left { transition: transform .2s ease; }\n}\n.drawer-tw--left.drawer-tw--open { transform: translateX(0); }\n.drawer-tw--right { right: 0; top: 0; bottom: 0; width: var(--size); border-left: 4px solid var(--accent); transform: translateX(100%); }\n@media (prefers-reduced-motion: no-preference) {\n.drawer-tw--right { transition: transform .2s ease; }\n}\n.drawer-tw--right.drawer-tw--open { transform: translateX(0); }\n.drawer-tw--top { top: 0; left: 0; right: 0; height: var(--size); border-bottom: 4px solid var(--accent); transform: translateY(-100%); }\n@media (prefers-reduced-motion: no-preference) {\n.drawer-tw--top { transition: transform .2s ease; }\n}\n.drawer-tw--top.drawer-tw--open { transform: translateY(0); }\n.drawer-tw--bottom { bottom: 0; left: 0; right: 0; height: var(--size); border-top: 4px solid var(--accent); transform: translateY(100%); }\n@media (prefers-reduced-motion: no-preference) {\n.drawer-tw--bottom { transition: transform .2s ease; }\n}\n.drawer-tw--bottom.drawer-tw--open { transform: translateY(0); }\n</style>", "react": "import { useState } from \"react\";\n\nexport function Drawer({\n title = \"{{title}}\",\n side = \"{{side}}\",\n width = {{width}},\n accent = \"{{accent}}\",\n backdrop = {{backdrop}},\n open: initialOpen = {{open}},\n}) {\n const [open, setOpen] = useState(initialOpen);\n const positions = {\n left: { left: 0, top: 0, bottom: 0, width, borderRight: `4px solid ${accent}`, transform: open ? \"translateX(0)\" : \"translateX(-100%)\" },\n right: { right: 0, top: 0, bottom: 0, width, borderLeft: `4px solid ${accent}`, transform: open ? \"translateX(0)\" : \"translateX(100%)\" },\n top: { top: 0, left: 0, right: 0, height: width, borderBottom: `4px solid ${accent}`, transform: open ? \"translateY(0)\" : \"translateY(-100%)\" },\n bottom: { bottom: 0, left: 0, right: 0, height: width, borderTop: `4px solid ${accent}`, transform: open ? \"translateY(0)\" : \"translateY(100%)\" },\n };\n return (\n <div style={{ position: \"relative\", minHeight: 360, borderRadius: 12, overflow: \"hidden\",\n background: backdrop ? \"rgba(36,20,48,.45)\" : \"#FAF7F2\" }}>\n {!open && (\n <button type=\"button\" onClick={() => setOpen(true)} style={{ position: \"absolute\", top: 16, left: 16,\n padding: \"8px 14px\", borderRadius: 8, border: \"1.5px solid #24143033\", background: \"#FAF7F2\", cursor: \"pointer\" }}>\n Open drawer\n </button>\n )}\n <div role=\"dialog\" aria-modal={backdrop ? \"true\" : \"false\"} aria-labelledby=\"drawer-title\" className=\"drawer-panel\" style={{\n position: \"absolute\", boxSizing: \"border-box\", background: \"#FAF7F2\", color: \"#241430\", padding: 20,\n boxShadow: \"0 20px 44px rgba(36,20,48,.28)\", fontFamily: \"system-ui, sans-serif\",\n ...positions[side] }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", marginBottom: 10 }}>\n <h3 id=\"drawer-title\" style={{ margin: 0, fontSize: 17, fontWeight: 600 }}>{title}</h3>\n <button type=\"button\" onClick={() => setOpen(false)} aria-label=\"Close\" style={{\n background: \"none\", border: \"none\", cursor: \"pointer\", color: \"#241430\", padding: 4, borderRadius: 6 }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\"><path d=\"M1 1l12 12M13 1L1 13\" stroke=\"currentColor\" strokeWidth=\"1.6\" fill=\"none\" strokeLinecap=\"round\"/></svg>\n </button>\n </div>\n <p style={{ margin: 0, fontSize: 14, color: \"#241430cc\" }}>Panel content lives here, for filters, forms, or navigation that do not need a full page.</p>\n </div>\n <style>{`\n @media (prefers-reduced-motion: no-preference) {\n .drawer-panel { transition: transform .2s ease; }\n }\n `}</style>\n </div>\n );\n}" }
Save
History