templui

module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2024 License: MIT

README

Templ UI - A library of templ UI components

Go Reference Go Report Card

A library of components to be used in a Go/templ/HTMX/Alpine.js project, based on Flowbite components and the Lucide icon library.

Note: all Flowbite JS code has been rewritten using Alpine.

This is a work in progress, breaking changes might happen.

Go support: 1.23+

Setup

Start a new project

Install this package :

go get -u github.com/jfbus/templui

Create a new assets_src directory & install Flowbite:

npm install flowbite

No need to configure Tailwind & Flowbite, it is handled by templui.

Install Alpine.js.

In the same assets_src directory, create a tailwind.config.go file :

//go:generate tailwindconfig
package tailwind_config

Generate the tailwind config file:

go generate
Add to an existing Tailwind project

Add the tailwind.config.go file beside your tailwind.config.js file.

Update the tailwind config file:

go generate

go generate can run with an existing config; it renames the previous config file to tailwind.config.js.saved.

Roadmap

  • Rating
  • Tooltip
  • Only add used components in tailwind config
  • Storybook-like viewer

Sizes

Sizes vary from size.XS to size.NineXL. Not all components support all sizes. Each component definition lists the allowed sizes.

Overriding CSS classes

Default CSS classes are defined by a Defaults package variable. They can be changed if you need to globally change the style.

You can override two components: Class (borders, spacing, text size, ...) and Color (foreground/background/text color, ...). There are usually Class attributes in each component to add your style overrides.

  • style.Class() replaces all Class values by new CSS classes,
  • style.Color() replaces all Color values by new CSS classes,
  • style.Add() adds new CSS classes to the default ones,
  • style.ReplaceClass()/style.ReplaceColor()/style.Replace() replace some CSS classes by new ones.

Remove removes the specified class family, including all variants (modifiers, values, ...)

style.Replace("ring", "foo") // removes ring-2, ring-[2px], hover:ring-2, ...

Components

Icon

Basic usage:

import "github.com/jfbus/templui/components/icon"

@icon.C(icon.Flower)

A size can be set:

import "github.com/jfbus/templui/components/size"

@icon.C(icon.D{Icon:icon.Flower, Size:size:S})

Icon sizes are mapped to text sizes:

xs s normal l xl 2xl 3xl 4xl 5xl 6xl 7xl 8xl 9xl full
3 3.5 4 18px 5 6 30px 9 12 60px 72px 24 32 full

size.S translates into a w-3.5 h-3.5 class. size.L translates into a w-[18px] h-[18px] class.

Input Field
@input.C(input.D{
    Name:  "foo",
    Label: "Foo",
    Value: [your value],
    Size:  size.S,
    Icon:  icon.Flower,
})

With HTMX attributes and a spinning loader:

@input.C(input.D{
    Name:       "foo",
    Label:      "Foo",
    Value:      [your value],
    Loader:     true,
    Attributes: templ.Attributes{
        "hx-post":   "/add",
        "hx-target": "#list",
})

You can define a custom loader by changing loader.DefaultLoader.

Textarea
import "github.com/jfbus/templui/components/textarea"

@textarea.C(textarea.D{
    Name:  "foo",
    Label: "Foo",
    Value: [your value],
    Icon:  icon.Flower,
})
Select
import (
	"github.com/jfbus/templui/components/selectfield"
	"github.com/jfbus/templui/components/selectfield/option"
)

@selectfield.C(selectfield.D{
    Name:  "country",
    Label: "Country",
    Options: []option.D{{
        Label: "Select a country",
    }, {
        Value: "FR",
        Label: "France",
    }, {
        Value: "DE",
        Label: "Germany",
    }, {
        Value: "GB",
        Label: "United Kingdom",
    }},
    Selected: "DE",
})
Radio/Radiogroup
import (
  "github.com/jfbus/templui/components/radio"
  "github.com/jfbus/templui/components/radiogroup"
)

@radiogroup.C(radiogroup.D{
  Name: "choice",
  Style: radiogroup.StyleBordered,
  Inputs: []radio.D{{
    Value: "choice1",
    Label: "Choice 1",
  }, {
    Value: "choice2",
    Label: "Choice 2",
  }},
})
Inline editing
import "github.com/jfbus/templui/components/inline"

@inline.C(inline.D{
    Value:    [your value],
    IconSize: size.S,
    Edit:     input.C(input.D{
        Name:         "title",
        Value:        [your value],
        Icon:         icon.CornerDownLeft,
        IconPosition: position.End,
        Size:         size.S,
        Attributes:   templ.Attributes{
            "hx-trigger": "keyup[key=='Enter']",
            "hx-post":    "/add",
            "hx-target":  "#item",
            "hx-swap":    "outerHTML",
      },
    }),
})
Button
import "github.com/jfbus/templui/components/button"

@button.C(button.D{
    Name:  "foo",
    Label: "Foo",
    Value: [your value],
    Icon:  icon.Pencil,
})
Button group
import "github.com/jfbus/templui/components/buttongroup"

@buttongroup.C(buttongroup.D{
    Size:    size.S,
    Buttons: []button.D{
        {
            Icon:  icon.ArrowDownNarrowWide,
            Label: label.D{
                  Label: "Sort",
                  Hide: true,
            },
        },
        {
            Icon:      icon.Heart,
            Label: label.D{
                  Label: "Rating",
                  Hide: true,
            },
        },
        {
            Icon:      icon.Banknote,
            Label: label.D{
                  Label: "Price",
                  Hide: true,
            },
        },
    },
})
Table
import (
    "github.com/jfbus/templui/components/table"
    "github.com/jfbus/templui/components/table/row"
    "github.com/jfbus/templui/components/table/cell"
)

@table.C(table.D{
    Style:  table.StyleStripedRows,
    Header: &row.D{
        Cells: []string{"Email","Name","Status", ""},
    },
    Rows: []row.D{{
        Cells: []any{
            "John Doe",
            "john.doe@example.com",
            "active",
            cell.D{
                Class:   style.D{Class:"text-center"},
                Content: button.C(button.D{
                    Label: "disable",
                }),
            },
        },
    }},
})

Row contents can either be a slice of strings, a slice of cell.D definitions, a slice of templ.Component components or a []any slice containing any number of these.

Accordion
import (
    "github.com/jfbus/templui/components/accordion"
    "github.com/jfbus/templui/components/accordion/element"
)

@accordion.C(accordion.D{
    ID: "accordion",
    Children: []element.D{{
        Open:    true,
        Title:   "First",
        Content: your.component(),
    }, {
        Title:   "Second",
        Content: your.component(),
    }},
})
Toast

Toasts either close manually or automatically.

import "github.com/jfbus/templui/components/toast"

@toast.C(toast.D{
    Style:   toast.StyleError,
    Content: "An error occurred !",
})

Helpers

import "github.com/jfbus/templui/components/helper"
S

helper.S renders anything (numbers, booleans, ...). {helper.S(1)} is the equivalent of {strconv.Itoa(1)}

IfEmpty

Renders the first non empty string from a list of string parameters.

helper.IfEmpty(item.Value, "???")
L

L returns a templ.Component based on a list of templ.Component values.

FAQ

I use a new component and it looks broken !

Run go generate again, and update your Tailwind class (npx tailwindcss -i [...] -o [...]).

Check that your tailwind.config.js content section contains :

  • your templates (something like "../views/**/*.{templ,go}")
  • templui (something like "[your local path]/github.com/jfbus/templui/**/*.{templ,go}")

Directories

Path Synopsis
cmd
templ: version: v0.2.793
templ: version: v0.2.793
a
templ: version: v0.2.793
templ: version: v0.2.793
accordion
templ: version: v0.2.793
templ: version: v0.2.793
accordion/element
templ: version: v0.2.793
templ: version: v0.2.793
button
Package button implements buttons.
Package button implements buttons.
buttongroup
Package buttongroup implements button groups.
Package buttongroup implements button groups.
checkbox
Package checkbox implements checkbox fields.
Package checkbox implements checkbox fields.
checkboxgroup
templ: version: v0.2.793
templ: version: v0.2.793
div
templ: version: v0.2.793
templ: version: v0.2.793
dropdown
Package dropdown implements dropdowns.
Package dropdown implements dropdowns.
dropzone
Package dropzone implements drap & drop upload drop zones.
Package dropzone implements drap & drop upload drop zones.
footer
templ: version: v0.2.793
templ: version: v0.2.793
footer/section
templ: version: v0.2.793
templ: version: v0.2.793
form
Package form defines the form tag.
Package form defines the form tag.
form/validation
Package validation enables your handler to return validation errors.
Package validation enables your handler to return validation errors.
form/validation/message
templ: version: v0.2.793
templ: version: v0.2.793
icon
Package icon adds Lucide icons.
Package icon adds Lucide icons.
inline
Package inline implements inline edits.
Package inline implements inline edits.
input
Package input implements text input fields.
Package input implements text input fields.
label
Package label implements labels.
Package label implements labels.
layout
templ: version: v0.2.793
templ: version: v0.2.793
loader
Package loader implements the default loader.
Package loader implements the default loader.
modal
Package modal adds modals.
Package modal adds modals.
navbar
templ: version: v0.2.793
templ: version: v0.2.793
radio
Package radio implements radio fields.
Package radio implements radio fields.
radiogroup
templ: version: v0.2.793
templ: version: v0.2.793
selectfield
Package selectfield implements select fields.
Package selectfield implements select fields.
sidebar
templ: version: v0.2.793
templ: version: v0.2.793
sidebar/control
templ: version: v0.2.793
templ: version: v0.2.793
social
templ: version: v0.2.793
templ: version: v0.2.793
table
Package table implements tables.
Package table implements tables.
table/cell
templ: version: v0.2.793
templ: version: v0.2.793
table/row
templ: version: v0.2.793
templ: version: v0.2.793
text
Package text renders anything (numbers, errors, ...) as text.
Package text renders anything (numbers, errors, ...) as text.
textarea
Package textarea implements textarea fields.
Package textarea implements textarea fields.
toast
templ: version: v0.2.793
templ: version: v0.2.793
toast/container
templ: version: v0.2.793
templ: version: v0.2.793
templ: version: v0.2.793
templ: version: v0.2.793

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL