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>
}