Skip to content

Commit

Permalink
feat: add checkbox component
Browse files Browse the repository at this point in the history
  • Loading branch information
axzilla committed Oct 12, 2024
1 parent 6663361 commit bc54e1c
Show file tree
Hide file tree
Showing 7 changed files with 522 additions and 0 deletions.
35 changes: 35 additions & 0 deletions assets/css/output.css
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,10 @@ body {
margin-left: 0.25rem;
}

.ml-2 {
margin-left: 0.5rem;
}

.ml-auto {
margin-left: auto;
}
Expand Down Expand Up @@ -839,6 +843,10 @@ body {
height: 6rem;
}

.h-4 {
height: 1rem;
}

.h-5 {
height: 1.25rem;
}
Expand Down Expand Up @@ -899,6 +907,10 @@ body {
width: 75%;
}

.w-4 {
width: 1rem;
}

.w-56 {
width: 14rem;
}
Expand Down Expand Up @@ -963,6 +975,10 @@ body {
flex-shrink: 1;
}

.shrink-0 {
flex-shrink: 0;
}

.-translate-x-1\/4 {
--tw-translate-x: -25%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
Expand Down Expand Up @@ -1183,6 +1199,10 @@ body {
border-radius: calc(var(--radius) - 2px);
}

.rounded-sm {
border-radius: calc(var(--radius) - 4px);
}

.border {
border-width: 1px;
}
Expand Down Expand Up @@ -1232,6 +1252,11 @@ body {
border-color: hsl(var(--input) / var(--tw-border-opacity));
}

.border-primary {
--tw-border-opacity: 1;
border-color: hsl(var(--primary) / var(--tw-border-opacity));
}

.border-transparent {
border-color: transparent;
}
Expand Down Expand Up @@ -1933,6 +1958,16 @@ body {
opacity: 0.7;
}

.data-\[state\=checked\]\:bg-primary[data-state="checked"] {
--tw-bg-opacity: 1;
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
}

.data-\[state\=checked\]\:text-primary-foreground[data-state="checked"] {
--tw-text-opacity: 1;
color: hsl(var(--primary-foreground) / var(--tw-text-opacity));
}

.dark\:from-gray-900:is(.dark *) {
--tw-gradient-from: #111827 var(--tw-gradient-from-position);
--tw-gradient-to: rgb(17 24 39 / 0) var(--tw-gradient-to-position);
Expand Down
1 change: 1 addition & 0 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func main() {
mux.Handle("GET /docs/components/avatar", templ.Handler(pages.Avatar()))
mux.Handle("GET /docs/components/button", templ.Handler(pages.Button()))
mux.Handle("GET /docs/components/card", templ.Handler(pages.Card()))
mux.Handle("GET /docs/components/checkbox", templ.Handler(pages.Checkbox()))
mux.Handle("GET /docs/components/datepicker", templ.Handler(pages.Datepicker()))
mux.Handle("GET /docs/components/dropdown-menu", templ.Handler(pages.DropdownMenu()))
mux.Handle("GET /docs/components/icon", templ.Handler(pages.Icon()))
Expand Down
4 changes: 4 additions & 0 deletions internals/shared/menudata.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ var Sections = []Section{
Text: "Card",
Href: "/docs/components/card",
},
{
Text: "Checkbox",
Href: "/docs/components/checkbox",
},
{
Text: "Datepicker",
Href: "/docs/components/datepicker",
Expand Down
39 changes: 39 additions & 0 deletions internals/ui/pages/checkbox.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package pages

import (
"github.com/axzilla/goilerplate/internals/ui/layouts"
"github.com/axzilla/goilerplate/internals/ui/showcase"
"github.com/axzilla/goilerplate/pkg/components"
)

templ Checkbox() {
@layouts.DocsLayout() {
<div>
<div class="mb-16">
<h1 class="text-3xl font-bold mb-2">Checkbox</h1>
<p class="mb-4 text-muted-foreground">A control that allows the user to toggle between checked and not checked.</p>
</div>
@components.Tabs(components.TabsProps{
Tabs: []components.Tab{
{
ID: "preview",
Title: "Preview",
Content: showcase.CheckboxShowcase(),
},
{
ID: "code",
Title: "Code",
Content: CodeSnippetFromEmbedded("checkbox.templ", "go", showcase.TemplFiles),
},
{
ID: "component",
Title: "Component",
Content: CodeSnippetFromEmbedded("checkbox.templ", "go", components.TemplFiles),
},
},
TabsContainerClass: "md:w-1/2",
ContentContainerClass: "w-full",
})
</div>
}
}
68 changes: 68 additions & 0 deletions internals/ui/showcase/checkbox.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package showcase

import "github.com/axzilla/goilerplate/pkg/components"

templ CheckboxShowcase() {
<div class="flex justify-center items-center border rounded-md py-16 px-4">
<div>
<div class="mb-8">
<h2 class="font-semibold mb-2">Default Checkbox</h2>
@components.Checkbox(components.CheckboxProps{
ID: "default-checkbox",
Name: "default",
Value: "default",
Label: "Accept terms and conditions",
})
</div>
<div class="mb-8">
<h2 class="font-semibold mb-2">Checked Checkbox</h2>
@components.Checkbox(components.CheckboxProps{
ID: "checked-checkbox",
Name: "newsletter",
Value: "subscribe",
Label: "Receive newsletter",
Checked: true,
})
</div>
<div class="mb-8">
<h2 class="font-semibold mb-2">Disabled Checkbox</h2>
@components.Checkbox(components.CheckboxProps{
ID: "disabled-checkbox",
Name: "disabled",
Value: "disabled",
Label: "Disabled option",
Disabled: true,
})
</div>
<div class="mb-8">
<h2 class="font-semibold mb-2">Disabled Checked Checkbox</h2>
@components.Checkbox(components.CheckboxProps{
ID: "disabled-checked-checkbox",
Name: "disabled-checked",
Value: "disabled-checked",
Label: "Disabled checked option",
Checked: true,
Disabled: true,
})
</div>
<div class="mb-8">
<h2 class="font-semibold mb-2">Checkbox with Dynamic Checked State</h2>
@components.Checkbox(components.CheckboxProps{
ID: "dynamic-checkbox",
Name: "dynamic",
Value: "dynamic",
Label: "Dynamic checkbox",
Checked: "dynamicState",
})
</div>
<div class="mb-8">
<h2 class="font-semibold mb-2">Checkbox without Label</h2>
@components.Checkbox(components.CheckboxProps{
ID: "no-label-checkbox",
Name: "no-label",
Value: "no-label",
})
</div>
</div>
</div>
}
94 changes: 94 additions & 0 deletions pkg/components/checkbox.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package components

// CheckboxProps defines the properties for the Checkbox component.
type CheckboxProps struct {
// ID is the unique identifier for the checkbox input.
ID string

// Name is the name attribute for the checkbox input.
Name string

// Value is the value attribute for the checkbox input.
Value string

// Label is the text label associated with the checkbox.
// If empty, no label will be rendered.
Label string

// Checked can be either a bool or a string.
// If bool, it directly controls the checked state.
// If string, it's treated as a JavaScript expression for dynamic checking.
Checked any

// Disabled can be either a bool or a string.
// If bool, it directly controls the disabled state.
// If string, it's treated as a JavaScript expression for dynamic disabling.
Disabled any

// Class specifies additional CSS classes to apply to the checkbox input.
Class string

// Attributes allows passing additional HTML attributes to the checkbox input element.
Attributes templ.Attributes
}

// Checkbox renders a checkbox input element with an optional label.
//
// Usage:
//
// @components.Checkbox(components.CheckboxProps{
// ID: "terms",
// Name: "terms",
// Value: "accepted",
// Label: "I accept the terms and conditions",
// Checked: true,
// })
//
// Props:
// - ID: The unique identifier for the checkbox. Required.
// - Name: The name attribute for the checkbox. Default: "" (empty string)
// - Value: The value attribute for the checkbox. Default: "" (empty string)
// - Label: The text label for the checkbox. If empty, no label is rendered.
// - Checked: Controls the checked state. Can be bool or string. Default: nil
// - Disabled: Controls the disabled state. Can be bool or string. Default: nil
// - Class: Additional CSS classes for the checkbox input. Default: "" (empty string)
// - Attributes: Additional HTML attributes for the checkbox input. Default: nil
templ Checkbox(props CheckboxProps) {
<div class="flex items-center">
<input
type="checkbox"
id={ props.ID }
name={ props.Name }
value={ props.Value }
if props.Disabled != nil {
if disabledBool, ok := props.Disabled.(bool); ok {
disabled?={ disabledBool }
}
if disabledStr, ok := props.Disabled.(string); ok {
:disabled={ disabledStr }
}
}
if props.Checked != nil {
if checkedBool, ok := props.Checked.(bool); ok {
checked?={ checkedBool }
}
if checkedStr, ok := props.Checked.(string); ok {
:checked={ checkedStr }
}
}
class={ "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
props.Class }
{ props.Attributes... }
/>
if props.Label != "" {
<label
for={ props.ID }
class={ "ml-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
templ.KV("text-muted-foreground", props.Disabled) }
>
{ props.Label }
</label>
}
</div>
}
Loading

0 comments on commit bc54e1c

Please sign in to comment.