Dropdown-menu
Basic
// Package dropdown holds the site's example gsx components for ui/dropdown.
package dropdown
import (
"github.com/gsxhq/gsxui/ui"
)
// Basic renders a menu with a label, separator, and plain items. Its one
// trigger Button carries both Button styling and DropdownMenu's trigger
// behavior/state contract.
component Basic() {
<ui.DropdownMenu>
<ui.Button
variant="outline"
data-gsxui-slot-dropdown-menu-trigger
aria-haspopup="menu"
aria-expanded="false"
>
Options
</ui.Button>
<ui.DropdownMenuContent>
<ui.DropdownMenuGroup>
<ui.DropdownMenuLabel>My Account</ui.DropdownMenuLabel>
<ui.DropdownMenuSeparator/>
<ui.DropdownMenuItem>Profile</ui.DropdownMenuItem>
<ui.DropdownMenuItem>Billing</ui.DropdownMenuItem>
<ui.DropdownMenuItem>
Settings <ui.DropdownMenuShortcut>⌘,</ui.DropdownMenuShortcut>
</ui.DropdownMenuItem>
</ui.DropdownMenuGroup>
</ui.DropdownMenuContent>
</ui.DropdownMenu>
}
Destructive and disabled items
package dropdown
import (
"github.com/gsxhq/gsxui/ui"
)
// Destructive shows a destructive item alongside a disabled one — variant
// styles the row red; aria-disabled/data-disabled skip it in roving focus
// and the click handler (see ui/dropdown/dropdown.js).
component Destructive() {
<ui.DropdownMenu>
<ui.Button
variant="outline"
data-gsxui-slot-dropdown-menu-trigger
aria-haspopup="menu"
aria-expanded="false"
>
Manage
</ui.Button>
<ui.DropdownMenuContent>
<ui.DropdownMenuItem>Rename</ui.DropdownMenuItem>
<ui.DropdownMenuItem aria-disabled="true" data-disabled="true">Archive (unavailable)</ui.DropdownMenuItem>
<ui.DropdownMenuSeparator/>
<ui.DropdownMenuItem variant="destructive">Delete</ui.DropdownMenuItem>
</ui.DropdownMenuContent>
</ui.DropdownMenu>
}
Checkbox items
package dropdown
import (
"github.com/gsxhq/gsxui/ui"
)
// Checkboxes shows DropdownMenuCheckboxItem: one server-rendered checked,
// one unchecked. Selecting an item flips it in place (dropdown.js) and does
// not close the menu — a caller who needs the value elsewhere listens for
// gsxui:change on the item.
component Checkboxes() {
<ui.DropdownMenu>
<ui.Button
variant="outline"
data-gsxui-slot-dropdown-menu-trigger
aria-haspopup="menu"
aria-expanded="false"
>
View
</ui.Button>
<ui.DropdownMenuContent>
<ui.DropdownMenuLabel>Appearance</ui.DropdownMenuLabel>
<ui.DropdownMenuSeparator/>
<ui.DropdownMenuCheckboxItem checked={true} value="toolbar">Show Toolbar</ui.DropdownMenuCheckboxItem>
<ui.DropdownMenuCheckboxItem checked={false} value="statusbar">Show Status Bar</ui.DropdownMenuCheckboxItem>
<ui.DropdownMenuCheckboxItem checked={false} value="sidebar" aria-disabled="true" data-disabled="true">
Show Sidebar
</ui.DropdownMenuCheckboxItem>
</ui.DropdownMenuContent>
</ui.DropdownMenu>
}
Radio items
package dropdown
import (
"github.com/gsxhq/gsxui/ui"
)
// Radios shows DropdownMenuRadioGroup/DropdownMenuRadioItem: "top" is the
// server-rendered current value. Selecting a different item closes the
// menu (unlike a checkbox item) and emits gsxui:change on the group with
// the newly picked value.
component Radios() {
<ui.DropdownMenu>
<ui.Button
variant="outline"
data-gsxui-slot-dropdown-menu-trigger
aria-haspopup="menu"
aria-expanded="false"
>
Panel Position
</ui.Button>
<ui.DropdownMenuContent>
<ui.DropdownMenuLabel>Panel Position</ui.DropdownMenuLabel>
<ui.DropdownMenuSeparator/>
<ui.DropdownMenuRadioGroup value="top">
<ui.DropdownMenuRadioItem checked={true} value="top">Top</ui.DropdownMenuRadioItem>
<ui.DropdownMenuRadioItem checked={false} value="bottom">Bottom</ui.DropdownMenuRadioItem>
<ui.DropdownMenuRadioItem checked={false} value="right">Right</ui.DropdownMenuRadioItem>
</ui.DropdownMenuRadioGroup>
</ui.DropdownMenuContent>
</ui.DropdownMenu>
}
Submenu
package dropdown
import (
"github.com/gsxhq/gsxui/ui"
)
// Submenu shows DropdownMenuSub/SubTrigger/SubContent nested inside a
// regular DropdownMenuContent — opened by hover, ArrowRight, or click; see
// ui/dropdown.gsx's file header for why SubContent must render DOM-nested
// rather than portalled.
component Submenu() {
<ui.DropdownMenu>
<ui.Button
variant="outline"
data-gsxui-slot-dropdown-menu-trigger
aria-haspopup="menu"
aria-expanded="false"
>
Actions
</ui.Button>
<ui.DropdownMenuContent>
<ui.DropdownMenuItem>New File</ui.DropdownMenuItem>
<ui.DropdownMenuSub>
<ui.DropdownMenuSubTrigger>More Tools</ui.DropdownMenuSubTrigger>
<ui.DropdownMenuSubContent>
<ui.DropdownMenuItem>Save Page As...</ui.DropdownMenuItem>
<ui.DropdownMenuItem>Create Shortcut...</ui.DropdownMenuItem>
<ui.DropdownMenuItem>Name Window...</ui.DropdownMenuItem>
</ui.DropdownMenuSubContent>
</ui.DropdownMenuSub>
<ui.DropdownMenuSeparator/>
<ui.DropdownMenuItem>Exit</ui.DropdownMenuItem>
</ui.DropdownMenuContent>
</ui.DropdownMenu>
}
RTL
package dropdown
import (
"github.com/gsxhq/gsxui/ui"
)
// Rtl keeps Basic's flat menu shape (label, separator, plain items —
// shadcn's own dropdown-menu-rtl demo adds Sub/checkbox/radio groups this
// directory's Basic doesn't compose; DEVIATED from rather than invented)
// and translates its strings to Arabic, using dropdown-menu-rtl's own
// account/profile/billing/settings vocabulary.
component Rtl() {
<div dir="rtl" lang="ar">
<ui.DropdownMenu>
<ui.Button
variant="outline"
data-gsxui-slot-dropdown-menu-trigger
aria-haspopup="menu"
aria-expanded="false"
>
فتح القائمة
</ui.Button>
<ui.DropdownMenuContent>
<ui.DropdownMenuGroup>
<ui.DropdownMenuLabel>الحساب</ui.DropdownMenuLabel>
<ui.DropdownMenuSeparator/>
<ui.DropdownMenuItem>الملف الشخصي</ui.DropdownMenuItem>
<ui.DropdownMenuItem>الفوترة</ui.DropdownMenuItem>
<ui.DropdownMenuItem>
الإعدادات <ui.DropdownMenuShortcut>⌘,</ui.DropdownMenuShortcut>
</ui.DropdownMenuItem>
</ui.DropdownMenuGroup>
</ui.DropdownMenuContent>
</ui.DropdownMenu>
</div>
}