Features • Installation • Usage • API Reference • Accessibility (A11Y) • Theming • Examples • Contributing
A fully accessible, configurable and themeable server-rendered Tab component for Go web applications. Built with templ library for seamless integration with Go-based web frontends.
- No External Dependencies: Built with native Go and the
templ
library,tabber
requires no external CSS or JavaScript dependencies. - Accessibility: Compliant with the WAI-ARIA Tabs Design Pattern,
tabber
ensures accessibility for all users, with proper use of ARIA attributes and keyboard navigation support. - Headless Component:
tabber
comes as a headless component, providing flexible styling options that can be easily customized to suit your design needs. - Pre-defined variants: Choose from predefined variants or define your own custom themes to match your application's style. Users can create their own tabber style variant as a re-usable templ component and use it.
- Responsive Design: Built with responsiveness in mind,
tabber
adjusts seamlessly to different screen sizes and devices, ensuring a consistent user experience across platforms. - Multiple Variants:
tabber
allows for enabling multiple variants on the same page, providing versatility and adaptability to diverse design requirements. - Multiple tabs: multiple
tabber
components on the same page, each with its own style. - Customizable Configuration:
tabber
offers various configuration options, including positioning, alignment, and more, allowing you to tailor its behavior to fit your specific use case. - Auto-generated or User-defined Dark Mode: Dark mode can be automatically generated based on the primary color defined or set by the user.
- Themeable with CSS Variables: Easily customize the appearance of
tabber
using CSS variables, with built-in support for theming.
Disclaimer: Please note that the demo video may not include the latest features and updates of the project. However, it still accurately represents the overall concepts and functionality.
To install the tabber
module, use the go get
command:
go get github.com/indaco/tabber@latest
Ensure your project is using Go Modules (it will have a go.mod
file in its root if it already does).
Tip
refer to the Examples section.
Import the tabber
module into your project:
import "github.com/indaco/tabber"
// Default options
tabberConfig := tabber.NewConfigBuilder().Build()
Users can access each configuration option using the corresponding With
method, such as tabber.WithActiveTab(2)
or tabber.WithPlacement(tabber.Left)
.
Option | Type | Description |
---|---|---|
ActiveTab |
number | Specifies the index of the initially active tab. The indexing starts from 1 for the first tab. |
Placement |
Placement | Determines the position of the tab list relative to the tab panels. Options: Top , Bottom , Left , and Right . |
Variants |
Enables specific visual variants for the tab component. | |
Alignment |
Alignment | Defines the alignment of the tab items within the tab list. Options: Start , Center , and End . |
To allow configurations to be accessible at any level in the tabs hierarchy, tabber
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 tabber
and attach it to the request context passed into the handler function.
func HandleHome(w http.ResponseWriter, r *http.Request) {
tabberConfig := tabber.NewConfigBuilder().WithVariant(tabber.Underlined).Build()
configMap := tabber.NewConfigMap()
configMap.Add("my-tab", tabberConfig)
ctx := context.WithValue(r.Context(), tabber.ConfigContextKey, configMap)
err := Page().Render(ctx, w)
if err != nil {
return
}
}
By default tabber
is headless, you have to enable single or multiple predefined variants.
tabberConfig := tabber.NewConfigBuilder().WithVariant(tabber.Underlined).Build()
// or enabling multiple variants. The first value is the default one.
tabberConfig := tabber.NewConfigBuilder().WithVariants(tabber.Underlined, tabber.Rounded).Build()
Available Predefined Variants:
Accent
Bordered
Grouped
Rounded
Pills
Underlined
You can also define and use your own variant. Please, refer to Create Your Own Tabber Variant.
In your templ
file, defines the structure for the tab component.
Important
It is crucial to ensure that the value passed to tabber.Root
matches the one used when adding the tabberConfig
to the configMap
as per step above. This ensures that multiple tabs on the same page function independently.
const (
profileIcon = `<svg ...></svg>`
settingsIcon = `<svg ...></svg>`
)
templ Page() {
@tabber.Root("my-tab") {
@tabber.TabList() {
@tabber.Tab(1, "First", tabber.Icon(profileIcon))
@tabber.Tab(2, "Second", tabber.Icon(settingsIcon))
@tabber.Tab(3, "Third")
}
@tabber.TabPanel(1) {
<h3>1 - Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.</p>
}
@tabber.TabPanel(2) {
<h3>2 - Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.</p>
}
@tabber.TabPanel(3) {
<h3>3 - Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.</p>
}
}
}
tabber
leverages the templ library's features, including CSS Components and JavaScript Templates, to encapsulate all necessary styling and functionality without relying on external dependencies.
TabberCSS
: Supplies the required CSS, encapsulating the visual design and layout specifics of the component. Moreover,TabberCSS
selectively includes styles specific to the enabled style variant, ensuring that only essential styles are loaded to optimize page performance and minimize unnecessary overhead.TabberJS
: 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, tabber
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:
TabberCSSToGoHTML
: Renders theTabberCSS
component into atemplate.HTML
value.TabberJSToGoHTML
: Renders theTabberJS
component into atemplate.HTML
value.
Property | Type | Description |
---|---|---|
id |
string | The unique identifier for the tab component. |
None
Property | Type | Description |
---|---|---|
value |
int | The unique identifier for the tab. |
label |
string | The text displayed for the tab button. |
icon |
TabIcon | The icon displayed close to the tab button. |
Property | Type | Description |
---|---|---|
value |
int | The unique identifier for the tab panel referenced by the tab button. |
The tab component is designed to be accessible to screen readers and supports keyboard navigation according to the WAI-ARIA Tabs Design Pattern.
Ensure that proper ARIA attributes are used to convey the state and role of the tab elements.
- Focusing the Tab Item:
- Use the
Tab
key to navigate to the tab button. PressingEnter
orSpace
will switch the tab.
- Use the
- Navigating within the Tab component:
- Use the
Arrow
keys to move focus between items within the tabs list. - Pressing
Home
orEnd
keys will move focus to the first or last item respectively. - Use
A-Z
ora-z
keys to move focus to the next tab item with a label that starts with the typed character if such a tab item exists. Otherwise, focus does not move.
- Use the
- Selecting an Item:
- Press
Enter
to select the currently focused item in the tabs list.
- Press
Customizing the appearance of tabber
to align with your design preferences is both straightforward and flexible, largely due to its extensive use of CSS custom properties (CSS variables) prefixed with gtb
. For a comprehensive list of CSS custom properties, along with their default values and descriptions, please consult the tabber CSS custom Props document.
There are three primary methods you can employ to easily adjust tabber
styles and variants. Depending on your specific requirements, choose the most suitable approach to achieve your desired styling.
In addition, you would create your own tabber
variant as reusable templ
component, register and use it. Refer to Create your own tabber variant.
By default, tabber
utilizes a single hsl
color and dynamically generates shades of it using the color-mix
function in the oklab
color space. To change the primary color, simply override the --gtb-base
property with your desired value. Refer to the colors section in the CSS custom props documentation for more details.
If you prefer a different color space other than oklab
, you can customize it by overriding the --gtb-color-space
property with your preferred value. For a comprehensive list of available color spaces, refer to the documentation.
To view the default base color shades and their derivations, consult the tabber-css.templ file here.
If one of the predefined style variants suits your needs but you desire more flexibility in certain aspects, such as using different colors instead of shades of the base color, you can define values for the Simplified set of css custom props.
The majority of tabber components utilize CSS custom properties to facilitate the creation of style variants and enable extensive customization of styles.
Here, we are defining and creating a new variant called sketched
in the sketched-variant.templ
file:
/*
* sketched-variant.templ
*/
import "github.com/indaco/tabber"
const Sketched tabber.Variant = "sketched"
// SketchedVariant is a new variant for tabber.
type SketchedVariant struct{}
// Implement TabberVariant interface
func (nv SketchedVariant) GetClassName() templ.Component {
return SketchedVariantCss()
}
templ SketchedVariantCss() {
<style>
:root {
[data-variant="sketched"] {
--gtb-root-py: 1.5em;
--gtb-root-px: 2em;
--gtb-root-border-width: 4px;
--gtb-root-border-style: solid;
/* refer to the source code... */
}
}
</style>
}
Use your newly create sketched
variant:
// register the Sketched variant and use it.
tabber.RegisterVariant(Sketched, SketchedVariant{})
tabberConfig := tabber.NewConfigBuilder().WithVariant(Sketched).Build()
configMap := tabber.NewConfigMap()
configMap.Add("sketched-tabber", tabberConfig)
To run the examples, make sure to compile them first by running make examples
. Then, move to the example folder and run
cd _examples/demo/
go run .
- demo
- use with
template/html
- multiple-tabs
- customise color
- customise theme
- customise variant
- variant creation
Contributions are welcome! Feel free to open an issue or submit a pull request.
To set up a development environment for this repository, you can use devbox along with the provided devbox.json
configuration file.
- Install devbox by following the instructions in the devbox documentation.
- Clone this repository to your local machine.
- Navigate to the root directory of the cloned repository.
- Run
devbox install
to install all packages mentioned in thedevbox.json
file. - Run
devbox shell
to start a new shell with access to the environment. - Once the devbox environment is set up, you can start developing, testing, and contributing to the repository.
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
This project is licensed under the MIT License - see the LICENSE file for details.