Drawer
Bottom sheet on the dialog.sheet primitive — a slide-up panel with drag handle. Other sides live under Sheet.
INSTALL
1pnpm dlx @sayagodev/mo add sheetOr import the files from the package (no copy):
1import "@sayagodev/mo/css/sheet.css";2import "@sayagodev/mo/js/base.js";3import "@sayagodev/mo/js/sheet.js";
EXAMPLES
Invite users
1<button type="button" class="outline" command="show-modal" commandfor="ex-drawer-invite">Open drawer</button>2 3<dialog closedby="any" id="ex-drawer-invite" class="sheet" data-side="bottom">4 <form method="dialog">5 <div class="handle" aria-hidden="true"></div>6 <header>7 <h3>Invite users</h3>8 <p>Invite your colleagues to start using your app.</p>9 </header>10 <div>11 <div data-field>12 <label for="ex-drawer-invite-email">Email</label>13 <input id="ex-drawer-invite-email" type="email" placeholder="[email protected]" />14 </div>15 </div>16 <footer>17 <button type="submit" class="ghost" value="cancel">Cancel</button>18 <button type="submit">Continue</button>19 </footer>20 </form>21</dialog>22
Form in a drawer
1<button type="button" class="outline" command="show-modal" commandfor="ex-drawer-team">Edit team</button>2 3<dialog closedby="any" id="ex-drawer-team" class="sheet" data-side="bottom">4 <form method="dialog">5 <div class="handle" aria-hidden="true"></div>6 <header>7 <h3>Create team</h3>8 <p>Pick a name for your new team.</p>9 </header>10 <div>11 <div data-field>12 <label for="ex-drawer-team-name">Team name</label>13 <input id="ex-drawer-team-name" placeholder="Acme Inc." />14 </div>15 </div>16 <footer>17 <button type="submit" class="ghost" value="cancel">Cancel</button>18 <button type="submit">Save changes</button>19 </footer>20 </form>21</dialog>22
USAGE
1<button type="button" command="show-modal" commandfor="dr1">Open drawer</button>2 3<dialog id="dr1" class="sheet" data-side="bottom">4 <form method="dialog">5 <div class="handle" aria-hidden="true"></div>6 <header><h3>Title</h3><p>Description</p></header>7 <div>…content…</div>8 <footer><button type="submit">Continue</button></footer>9 </form>10</dialog>
API
NAMEKINDDESCRIPTION
.sheet + data-side="bottom"classSlide-up panel on <dialog>; other sides are Sheet
commandfor / commandattributeDeclarative open/close; Esc and backdrop clicks close natively
.handleelementCentered rounded grab bar at the top (decorative, aria-hidden)
--mo-sheet-max-block-sizetokenPanel height cap (default 50vh)
--mo-sheet-handle-*tokenHandle width/height hooks
FILES
src/css/sheet.csssrc/js/base.jssrc/js/sheet.jsInstall:
mo add sheetTHEMING · PLAYGROUND
This is the exact component from the examples above, wearing a completely different theme. Edit the tokens and --mo-* hooks in the editor — autocomplete knows them all — and the preview obeys in real time. Your CSS always wins.
Global tokens
--border--muted--muted-foreground--radiusComponent hooks
--mo-sheet-handle-height--mo-sheet-handle-width--mo-sheet-max-block-size--mo-sheet-max-widthPreview
Your CSS
Try it: type --mo- for the component hooks, or edit any value — the preview obeys in real time.