Skip to content

A fully accessible, configurable and themeable dropdown component for Go web applications.

License

Notifications You must be signed in to change notification settings

indaco/gropdown

Repository files navigation

gropdown

license   go report card   go reference Built with Devbox

FeaturesInstallationUsageAPI ReferenceAccessibility (A11Y)ThemingExamples

A fully accessible, configurable and themeable server-rendered dropdown component for Go web applications. Built with templ library for seamless integration with Go-based web frontends.

Features

  • Accessible: Fully compliant with the WAI-ARIA Menu Button Design Pattern, to ensure accessibility for all users.
  • No External Dependencies: Built with native Go and the templ library, requiring no external dependencies.
  • Configurable: The component offers various configuration options to customize its behavior (e.g. positioning, open by default...)
  • Multiple dropdown: multiple gropdown components on the same page, each with its own style.
  • Themeable: Supports theming via CSS variables, allowing easy customization of appearance. Comes with built-in support for light and dark modes, as well as the ability to define custom themes using the data-theme attribute.
  • Versatile: Items can be buttons or links (<a>). When a link item is marked as external, a visual icon will be added to indicate it.
Image

Installation

To install the Dropdown module, use the go get command:

go get github.com/indaco/gropdown

Ensure your project is using Go Modules (it will have a go.mod file in its root if it already does).

Usage

Tip

refer to the Examples section.

Import the Dropdown module into your project:

import "github.com/indaco/gropdown"

Configuration & Context

// Default options
dropdownConfig := gropdown.NewConfigBuilder().Build()

Available Options

Users can access each configuration option using the corresponding With method, such as gropdown.WithOpen(true) or gropdown.WithPosition(gropdown.Left).

Option Type Default Description
Open bool false indicates whether the dropdown menu is currently open.
Placement Placement Bottom indicates the position of the dropdown content relative to the button. Options: Top, Bottom, Left, and Right.
Animation bool true indicates whether the dropdown button should use animations on open and close.
CloseOnOutsideClick bool true indicates whether the dropdown should be closed when a click occurs outside of it.

To allow configurations to be accessible at any level in the dropdown hierarchy and make each component on the same page function independently, gropdown makes use of the templ component context and the implicit ctx variable. You can read more about templ component context here.

In your function handler, create a configuration for gropdown and attach it to the request context passed into the handler function.

func HandleHome(w http.ResponseWriter, r *http.Request) {
  dropdownConfig := gropdown.NewConfigBuilder().WithPlacement(gropdown.Top).Build()

  configMap := gropdown.NewConfigMap()
  configMap.Add("demo", dropdownConfig)
  ctx := context.WithValue(r.Context(), gropdown.ConfigContextKey, configMap)
  err := Page().Render(ctx, w)
  if err != nil {
    return
  }
}

Dropdown Component Structure - Markup

In your templ file, defines the structure for the dropdown component.

Important

It is crucial to ensure that the value passed to gropdown.Root matches the one used when adding the gropdownConfig to the configMap as per step above. This ensures that multiple dropdowns on the same page function independently.

// Set the button label.
@gropdown.Root("demo") {
  @gropdown.Button("Menu")
  @gropdown.Content() {
    @gropdown.Item("Profile",
      gropdown.ItemOptions{
        Href: "/profile",
        Icon: profileIcon,
      },
    )
    @gropdown.Item("Settings",
      gropdown.ItemOptions{
        Href: "/settings",
        Icon: settingsIcon,
      },
    )
    @gropdown.Divider()
    @gropdown.Item("GitHub",
      gropdown.ItemOptions{
        Href:     "https://github.com",
        External: true,
        Icon:     globeIcon,
      },
    )
    @gropdown.Divider()
    @gropdown.Item("Button",
      gropdown.ItemOptions{
        Icon:  clickIcon,
        Attrs: templ.Attributes{"onclick": "alert('Hello gropdown');"},
      },
    )
  }
}

CSS and Javascript

gropdown leverages the templ library's features, including CSS Components and JavaScript Templates, to encapsulate all necessary styling and functionality without relying on external dependencies.

  • GropdownCSS: it supplies the required CSS, encapsulating the visual design and layout specifics of the component.
  • GropdownJS: it provides the JavaScript logic essential for dynamic behaviors such as displaying, keyboard navigation and interaction with the component.

To facilitate integration with Go's template/html standard library, gropdown includes a dedicated HTMLGenerator type to seamlessly integrate the component into web applications built with Go's html/template standard library.

There are methods acting as wrappers to the templ's templ.ToGoHTML, generate the necessary HTML to be embedded them into server-rendered pages:

  • GropdownCSSToGoHTML: render the GropdownCSS component into a template.HTML value.
  • GropdownJSToGoHTML: render the GropdownJS component into a template.HTML value.

API Reference

gropdown.Root

Property Type Description
id string The unique identifier for the dropdown menu component.

gropdown.Button

Property Type Description
label string The text displayed for the dropdown menu button.
icon ButtonIcon The icon displayed next to the dropdown menu button.

gropdown.Content

None

gropdown.Item

Property Type Description
label string The text displayed for the dropdown menu item.
opts ItemOptions The options for configuring the behavior and appearance of the item.

gropdown.Divider

None

Accessibility (A11Y)

The dropdown component is designed to be accessible to screen readers and supports keyboard navigation according to the WAI-ARIA pattern for menu buttons.

Screen Reader Support

Ensure that proper ARIA attributes are used to convey the state and role of the dropdown elements.

Keyboard Interaction

  • Focusing the Dropdown:
    • Use the Tab key to navigate to the dropdown button. Pressing Enter or Space will open the dropdown menu.
  • Navigating within the Dropdown Menu:
    • Use the Arrow keys to move focus between items within the dropdown menu.
    • Pressing Home or End keys will move focus to the first or last item respectively.
    • Use A-Z or a-z keys to move focus to the next menu item with a label that starts with the typed character if such a menu item exists. Otherwise, focus does not move.
  • Selecting an Item:
    • Press Enter to select the currently focused item in the dropdown menu.
  • Closing the Dropdown:
    • Press Escape to close the dropdown and sets focus to the menu button.

Theming

Dropdown is themeable using CSS variables (prefix gdd) to customize the appearance according to your design.

By default, it supports both light and dark modes. In addition to the built-in modes, you can define your own custom themes using the data-theme attribute. Simply add a data-theme attribute to the root element of your application and define the corresponding CSS variables for your custom theme.

For a comprehensive list of CSS custom properties, along with their default values and descriptions, please consult the gropdown CSS custom Props document.

Examples

Contributing

Contributions are welcome! Feel free to open an issue or submit a pull request.

Development Environment Setup

To set up a development environment for this repository, you can use devbox along with the provided devbox.json configuration file.

  1. Install devbox by following the instructions in the devbox documentation.
  2. Clone this repository to your local machine.
  3. Navigate to the root directory of the cloned repository.
  4. Run devbox install to install all packages mentioned in the devbox.json file.
  5. Run devbox shell to start a new shell with access to the environment.
  6. Once the devbox environment is set up, you can start developing, testing, and contributing to the repository.

Using the Makefile

Additionally, you can make use of the provided Makefile to run various tasks:

make build       # The main build target
make examples    # Process templ files in the _examples folder
make templ       # Process TEMPL files
make test        # Run go tests
make help        # Print this help message

License

This project is licensed under the MIT License - see the LICENSE file for details.