Infinite UI Demo

Infinite UI is a collection of reusable components for building elegant user interfaces in Go.
It is built with a-h/templ, Alpine.js, Tailwind CSS, Phosphor Icons and the occasional additional JavaScript libraries when necessary.

GitHub Repository GitHub Discussions Reddit Subreddit Go Report Card License

@uiForm

uiForm is a collection of components that make it easy to create forms.

.InputField

An input field is a basic form element that allows users to enter text.

Usage

@uiForm.InputField(uiForm.InputFieldSettings{
	InputType: uiForm.InputTypeText,
	InputName: "name",
	Label:     "Name",

	// OptionalFields
	TwoWayStatePath: "name",
})
Alpine.js Parent State (x-data)
<div x-data="{name: ''}"></div>

Live Example

Basic Input

Name

Value & IsReadOnly

Name

InputTypeNumberMin, Max & Step

Name

AffixLeftValue & AffixRightValue

Name
goinfinite.dev/
Name
.jpg

HintValue & HintDisplay

Name
This is a helpful hint displayed as a description below the input.
Name

.TextArea

A textarea is a form element that allows users to enter multiple lines of text.

Usage

@uiForm.TextArea(uiForm.TextAreaSettings{
	InputName: "description",
	Label:     "Description",

	// OptionalFields
	TwoWayStatePath: "description",
	IsRequired:      false,
	IsReadOnly:      false,
})
Alpine.js Parent State (x-data)
<div x-data="{description: ''}"></div>

Live Example

Description

Value & IsReadOnly

Description

.RadioInput

A radio input allows users to select one option from a set of options.

Usage

@uiForm.RadioInput(uiForm.RadioInputSettings{
	Label:           "Option 1",
	StateValue:      "option1",
	TwoWayStatePath: "selectedOption",
})
@uiForm.RadioInput(uiForm.RadioInputSettings{
	Label:           "Option 2",
	StateValue:      "option2",
	TwoWayStatePath: "selectedOption",
})
Alpine.js Parent State (x-data)
<div x-data="{selectedOption: 'option2'}"></div>

Live Example

.InlineRadioGroup

An inline radio group displays a set of radio options in a horizontal layout.

Usage

@uiForm.InlineRadioGroup(uiForm.InlineRadioGroupSettings{
	Label: "Select an option",
	InputSettings: []uiForm.RadioInputSettings{
		{
			Label:           "Option 1",
			StateValue:      "option1",
			TwoWayStatePath: "groupSelection",
		},
		{
			Label:           "Option 2",
			StateValue:      "option2",
			TwoWayStatePath: "groupSelection",
		},
	},

	// OptionalFields
	TwoWayStatePath: "groupSelection",
	InputName:       "group1",
})
Alpine.js Parent State (x-data)
<div x-data="{groupSelection: 'option2'}"></div>

Live Example

Select an option

.SelectInput

A select input allows users to select one option from a dropdown list.

Usage (w/FlatOptions)

@uiForm.SelectInput(uiForm.SelectInputSettings{
	InputName: "country",
	Label:     "Country",

	// OptionalFields
	FlatOptions: []string{"Argentina", "Brazil", "Chile"},
	TwoWayStatePath:          "country",
	ShouldIncludeBlankOption: true,
})
Alpine.js Parent State (x-data)
<div x-data="{country: ''}"></div>

Live Example

Country
  • --
  • Argentina
  • Brazil
  • Chile

Usage (w/LabelValueOptions)

@uiForm.SelectInput(uiForm.SelectInputSettings{
	InputName: "country",
	Label:     "Country",

	// OptionalFields
	LabelValueOptions: []uiForm.SelectLabelValueOption{
		{
			Label: "Argentina",
			Value: "AR",
		},
		{
			Label: "Brazil",
			Value: "BR",
		},
		{
			Label: "Chile",
			Value: "CL",
		},
	},
	TwoWayStatePath:          "country",
	ShouldIncludeBlankOption: true,
})
Alpine.js Parent State (x-data)
<div x-data="{country: ''}"></div>

Live Example

Country
  • --
  • Argentina
  • Brazil
  • Chile

Usage (w/LabelValueOptions and LabelHtml)

@uiForm.SelectInput(uiForm.SelectInputSettings{
	InputName: "country",
	Label:     "Country",

	// OptionalFields
	LabelValueOptions: []uiForm.SelectLabelValueOption{
		{
			Label:     "Argentina",
			LabelHtml: SelectInputDemoOption1(),
			Value:     "AR",
		},
		{
			Label:     "Brazil",
			LabelHtml: SelectInputDemoOption2(),
			Value:     "BR",
		},
		{
			Label:     "Chile",
			LabelHtml: SelectInputDemoOption3(),
			Value:     "CL",
		},
	},
	TwoWayStatePath:          "country",
	ShouldIncludeBlankOption: true,
})
Alpine.js Parent State (x-data)
<div x-data="{country: ''}"></div>

Live Example

Click the dropdown to see the HTML labels.

Country
  • --
  • 🇦🇷 Argentina

    Known for its dance and wine.

  • 🇧🇷 Brazil

    Known for its music and natural beauty.

  • 🇨🇱 Chile

    Known for its deserts and mysterious islands.

@uiDisplay

uiDisplay is a collection of components for displaying content.

.Alert

An alert is a notification component that displays important information to users.

Usage

@uiDisplay.Alert(uiDisplay.AlertSettings{
	// OptionalFields
	Title:       "Alert Title",
	Description: "This is an alert message.",
	Variation:   uiDisplay.AlertVariationInfo,
	Size:        uiDisplay.AlertSizeMd,
	IsCloseable: true,
})

Live Example

Alert Variations

Flashy Customization Examples

Alpine.js Integration

Alpine.js Parent State (x-data)
<div x-data="{alertMessage: 'Dynamic alert content!', isAlertCloseable: true}"></div>

Dynamic Content

Dynamic Close Button

.Accordion

An accordion is a vertically stacked list of items that can be expanded or collapsed to reveal content.

Usage

@uiDisplay.Accordion(uiDisplay.AccordionSettings{
	Items: []uiDisplay.AccordionItemSettings{
		{
			Title: "Section 1",
			Content: AccordionDemoSection1(),
			Icon: "ph-info",
		},
		{
			Title: "Section 2",
			Content: AccordionDemoSection2(),
		},
		{
			Title: "Section 3",
			Content: AccordionDemoSection3(),
		},
	},
})

Live Example

Section 1

This is the content for section 1. You can put any content here.

Section 2

This is the content for section 2. You can put any content here.

Section 3

This is the content for section 3. You can put any content here.

.LoadingOverlay (htmx-ready)

A loading overlay displays a loading indicator over content to show that an operation is in progress.

Usage

@uiDisplay.LoadingOverlay(uiDisplay.LoadingOverlaySettings{
	// OptionalFields
	IsLoadingOneWayStatePath: "isLoading",
	BackgroundColor:          "neutral-900/80",
	Icon:                     "ph-compass-rose",
	IconSize:                 uiDisplay.LoadingOverlayIconSizeMd,
	AnimationName:            uiDisplay.LoadingOverlayAnimationNameSpin,
	AnimationDurationSeconds: "2",
})

Live Example

Alpine.js Parent State (x-data)
<div x-data="{isLoading: false}"></div>

The page content will be covered by the loading overlay when triggered.

.CloakLoading (pre-Alpine/HTMX)

A cloak loading screen that appears only before the JavaScript libraries are loaded to prevent FOUC (Flash of Unstyled Content).

Usage

@uiDisplay.CloakLoading(uiDisplay.CloakLoadingSettings{
	// OptionalFields
	HideDelaySeconds:             "1",
	BackgroundColor:              "rgb(23, 23, 23)", // neutral-800
	TextMessage:                  "Loading...",
	TextColor:                    "rgb(250, 250, 250)", // neutral-50
	TextSize:                     uiDisplay.CloakLoadingTextSizeMd,
	Icon:                         "ph-compass-rose",
	IconSize:                     uiDisplay.CloakLoadingIconSizeLg,
	IconColor:                    "rgb(59, 130, 246)", // primary-400
	IconAnimationName:            uiDisplay.CloakLoadingAnimationNameSpin,
	IconAnimationDurationSeconds: "3",
})
Keep in mind that the colors must be set as rgb(a), hex or hsl(a) values as they are used in the inline style.

Live Example

Since the demo is already loaded with Alpine.js, the CloakLoading component will behave like a regular loading overlay.
In a real application, this would be the first thing that appears when the page starts loading.

The page content will be covered by the cloak loading screen when triggered.

.Tag

A tag is a small label that can be used to categorize or identify content.

Usage

@uiDisplay.Tag(uiDisplay.TagSettings{
	OuterLeftIcon: "ph-info",
	OuterLeftLabel: "Info",
	OuterRadius: uiDisplay.TagRadiusMd,
	InnerIcon: "ph-warning",
	InnerLabel: "Warning",
	Size: uiDisplay.TagSizeXs,
})

Live Example

TagSizeXs to TagSizeXl

Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning

TagRadiusNone to TagRadiusFull
(OuterRadius & InnerRadius)

Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning

OuterRingColor
(w/ OuterBackgroundColor "transparent")

Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning

OuterBackgroundColor
(w/o OuterRingColor)

Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning

InnerBackgroundColor

Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning
Info
Warning

Side Elements OnClickFunc

Add
Remove

.Toast

A toast is a temporary notification displayed to provide feedback to users.

Usage

@uiDisplay.Toast(uiDisplay.ToastSettings{
	// OptionalFields
	BackgroundColor: "neutral-800",
	TextColor:       "neutral-50",
	Size:            uiDisplay.ToastSizeMd,
	RingThickness:   uiDisplay.ToastRingThicknessMd,
	RingColor:       "neutral-500",
	Radius:          uiDisplay.ToastRadiusMd,
})

Live Example

@uiControl

uiControl is a collection of components for controlling content.

.Button

A button is a clickable element that can be used to trigger an action.

Usage

@uiControl.Button(uiControl.ButtonSettings{
	Label:       "Click me",
	IconLeft:    "ph-info",
	OnClickFunc: "alert('Button clicked!')",
})

Live Example

ButtonSizeXs to ButtonSizeXl

Button Shapes

IconLeft & IconRight

Button Colors

Button with Ring

Button with Tooltip

IsDisabledOneWayStatePath

Count:

.RangeSlider

A range slider allows users to select a value from a range by dragging a thumb along a track.

Usage

@uiControl.RangeSlider(uiControl.RangeSliderSettings{
	ThumbValueTwoWayStatePath: "sliderValue",
	TrackStartValue:           "0",
	TrackEndValue:             "100",
	TrackSteps:                "1",
})
Alpine.js Parent State (x-data)
<div x-data="{sliderValue: 50}"></div>

Live Example

Basic Slider

Value:

RangeSliderSizeXs to RangeSliderSizeXl

Thumb Shapes

Thumb Colors & Icons

ThumbValueBubble

Track Labels Positions

Track Colors & Icons

Dual Mode

Price Range: $ - $

Loading...