Drawer
Basic
// Package drawer holds the site's example gsx components for ui/drawer.
package drawer
import (
"github.com/gsxhq/gsxui/ui"
"github.com/gsxhq/gsxui/ui/icon"
)
// Basic adapts shadcn's own drawer-demo.tsx (a bottom-anchored goal-counter
// drawer): the recharts BarChart sparkline has no gsxui equivalent (the
// roadmap defers charting entirely — "chart — defer until demanded"), so
// it is replaced with a static decorative bar row of plain divs standing
// in for the chart's shape, not a literal port. The +/- stepper buttons
// are likewise static markup — shadcn's demo wires them to useState, which
// has no server-rendered gsx equivalent; they render with the demo's own
// styling (ui.Button variant="outline" size="icon" rounded-full) as a
// visual stand-in around the fixed goal number.
//
// The trigger is one real Button carrying the drawer trigger style slot plus
// Dialog's behavior/ARIA contract. The footer's Cancel button is a real Button
// carrying data-gsxui-dialog-close directly rather than wrapped in
// DrawerClose, the same button-in-button reasoning as
// site/examples/sheet/basic.gsx's own Save-changes button.
component Basic() {
<ui.Drawer>
<ui.Button
variant="outline"
data-gsxui-slot-drawer-trigger
aria-haspopup="dialog"
aria-expanded="false"
>
Open Drawer
</ui.Button>
<ui.DrawerContent direction="">
<div class="mx-auto w-full max-w-sm">
<ui.DrawerHeader>
<ui.DrawerTitle>Move Goal</ui.DrawerTitle>
<ui.DrawerDescription>Set your daily activity goal.</ui.DrawerDescription>
</ui.DrawerHeader>
<ui.DrawerClose>Close drawer</ui.DrawerClose>
<div class="p-4 pb-0">
<div class="flex items-center justify-center gap-2">
<ui.Button variant="outline" size="icon" class="size-8 shrink-0 rounded-full" aria-label="Decrease goal">
<icon.Minus/>
</ui.Button>
<div class="flex-1 text-center">
<div class="text-7xl font-bold tracking-tighter">350</div>
<div class="text-[0.70rem] text-muted-foreground uppercase">Calories/day</div>
</div>
<ui.Button variant="outline" size="icon" class="size-8 shrink-0 rounded-full" aria-label="Increase goal">
<icon.Plus/>
</ui.Button>
</div>
<div class="mt-3 flex h-[120px] items-end gap-1">
<div class="h-[40%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[65%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[45%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[80%] flex-1 rounded-sm bg-foreground"></div>
<div class="h-[55%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[70%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[35%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[60%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[50%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[75%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[42%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[58%] flex-1 rounded-sm bg-foreground/20"></div>
<div class="h-[38%] flex-1 rounded-sm bg-foreground/20"></div>
</div>
</div>
<ui.DrawerFooter>
<ui.Button>Submit</ui.Button>
<ui.Button variant="outline" data-gsxui-dialog-close>Cancel</ui.Button>
</ui.DrawerFooter>
</div>
</ui.DrawerContent>
</ui.Drawer>
}
Directions
package drawer
import "github.com/gsxhq/gsxui/ui"
// Directions renders one drawer per anchoring direction, mirroring the
// direction demo on shadcn's own drawer docs. Each drawer is its own
// ui.Drawer root so the trigger-to-dialog proximity wiring stays
// unambiguous. Content is kept minimal — this example exists to exercise
// the four per-direction class strings (positioning, free-edge rounding,
// slide axis, handle-bar visibility, header alignment), not to restate the
// goal-counter demo.
component Directions() {
<div class="flex flex-wrap gap-2">
{ for _, dir := range []string{"bottom", "top", "left", "right"} {
<ui.Drawer>
<ui.Button
variant="outline"
data-gsxui-slot-drawer-trigger
aria-haspopup="dialog"
aria-expanded="false"
class="capitalize"
>
{ dir }
</ui.Button>
<ui.DrawerContent direction={dir}>
<ui.DrawerHeader>
<ui.DrawerTitle class="capitalize">{ dir } drawer</ui.DrawerTitle>
<ui.DrawerDescription>Anchored to the { dir } edge.</ui.DrawerDescription>
</ui.DrawerHeader>
<div class="p-4 pt-0 text-sm text-muted-foreground">
The free edge is rounded and the panel slides in from the { dir }.
</div>
<ui.DrawerFooter>
<ui.Button variant="outline" data-gsxui-dialog-close>Close</ui.Button>
</ui.DrawerFooter>
</ui.DrawerContent>
</ui.Drawer>
} }
</div>
}