mirror of
https://github.com/axzilla/templui.git
synced 2025-02-21 00:12:48 +00:00
feat(form WIP): enhance showcase components with new layouts and improved accessibility
This commit is contained in:
parent
6c9dc2c483
commit
14a5400b52
@ -1,5 +1,5 @@
|
||||
# Build-Stage
|
||||
FROM golang:1.22-alpine AS build
|
||||
FROM golang:1.23-alpine AS build
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the source code
|
||||
|
@ -629,18 +629,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.pointer-events-none {
|
||||
pointer-events: none;
|
||||
}
|
||||
@ -649,10 +637,6 @@ body {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed;
|
||||
}
|
||||
@ -751,10 +735,6 @@ body {
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.m-0 {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
@ -986,18 +966,10 @@ body {
|
||||
width: 1.75rem;
|
||||
}
|
||||
|
||||
.w-72 {
|
||||
width: 18rem;
|
||||
}
|
||||
|
||||
.w-8 {
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.w-96 {
|
||||
width: 24rem;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
@ -1014,6 +986,10 @@ body {
|
||||
max-width: 28rem;
|
||||
}
|
||||
|
||||
.max-w-sm {
|
||||
max-width: 24rem;
|
||||
}
|
||||
|
||||
.max-w-xl {
|
||||
max-width: 36rem;
|
||||
}
|
||||
@ -1038,10 +1014,6 @@ body {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.-translate-x-1 {
|
||||
--tw-translate-x: -0.25rem;
|
||||
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));
|
||||
@ -1772,6 +1744,10 @@ body {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.opacity-50 {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.opacity-80 {
|
||||
opacity: 0.8;
|
||||
}
|
||||
@ -1815,6 +1791,11 @@ body {
|
||||
--tw-ring-color: rgb(0 0 0 / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.ring-destructive {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: hsl(var(--destructive) / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.ring-opacity-5 {
|
||||
--tw-ring-opacity: 0.05;
|
||||
}
|
||||
@ -2133,22 +2114,6 @@ body {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline:focus {
|
||||
outline-style: solid;
|
||||
}
|
||||
|
||||
.focus\:outline-2:focus {
|
||||
outline-width: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline-offset-2:focus {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline-ring:focus {
|
||||
outline-color: hsl(var(--ring) / 1);
|
||||
}
|
||||
|
||||
.focus\:ring-2:focus {
|
||||
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
@ -2173,10 +2138,6 @@ body {
|
||||
--tw-ring-offset-width: 2px;
|
||||
}
|
||||
|
||||
.checked\:focus\:outline-primary:focus:checked {
|
||||
outline-color: hsl(var(--primary) / 1);
|
||||
}
|
||||
|
||||
.focus-visible\:outline-none:focus-visible {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
@ -2207,10 +2168,6 @@ body {
|
||||
--tw-ring-offset-color: hsl(var(--background) / 1);
|
||||
}
|
||||
|
||||
.active\:outline-offset-0:active {
|
||||
outline-offset: 0px;
|
||||
}
|
||||
|
||||
.disabled\:pointer-events-none:disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
@ -2241,18 +2198,13 @@ body {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.peer:checked ~ .peer-checked\:visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.peer:checked ~ .peer-checked\:bg-primary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.peer:checked ~ .peer-checked\:text-foreground {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
.peer:checked ~ .peer-checked\:opacity-100 {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.peer:checked ~ .peer-checked\:after\:translate-x-\[16px\]::after {
|
||||
@ -2279,10 +2231,6 @@ body {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.peer:disabled ~ .peer-disabled\:opacity-70 {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.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);
|
||||
@ -2313,11 +2261,6 @@ body {
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:file\:text-foreground:is(.dark *)::file-selector-button {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:hover\:bg-gray-700:hover:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(55 65 81 / var(--tw-bg-opacity));
|
||||
@ -2511,19 +2454,6 @@ body {
|
||||
background-color: hsl(var(--primary) / 0.9);
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:checked\)\]\:text-foreground:has(input:checked) {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:disabled\)\]\:cursor-not-allowed:has(input:disabled) {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:disabled\)\]\:opacity-50:has(input:disabled) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.\[\&\:has\(svg\)\]\:pl-11:has(svg) {
|
||||
padding-left: 2.75rem;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func main() {
|
||||
mux.Handle("GET /docs/components/icon", templ.Handler(pages.Icon()))
|
||||
mux.Handle("GET /docs/components/input", templ.Handler(pages.Input()))
|
||||
mux.Handle("GET /docs/components/modal", templ.Handler(pages.Modal()))
|
||||
mux.Handle("GET /docs/components/radio-group", templ.Handler(pages.RadioGroup()))
|
||||
mux.Handle("GET /docs/components/radio", templ.Handler(pages.Radio()))
|
||||
mux.Handle("GET /docs/components/select", templ.Handler(pages.Select()))
|
||||
mux.Handle("GET /docs/components/sheet", templ.Handler(pages.Sheet()))
|
||||
mux.Handle("GET /docs/components/slider", templ.Handler(pages.Slider()))
|
||||
|
@ -78,8 +78,8 @@ var Sections = []Section{
|
||||
Href: "/docs/components/modal",
|
||||
},
|
||||
{
|
||||
Text: "Radio Group",
|
||||
Href: "/docs/components/radio-group",
|
||||
Text: "Radio",
|
||||
Href: "/docs/components/radio",
|
||||
},
|
||||
{
|
||||
Text: "Select",
|
||||
|
@ -7,18 +7,11 @@ import (
|
||||
|
||||
type showcaseWrapperProps struct {
|
||||
Content templ.Component
|
||||
Class string
|
||||
}
|
||||
|
||||
templ showcaseWrapper(p showcaseWrapperProps) {
|
||||
<div class="flex justify-center items-center border rounded-md py-16 px-4">
|
||||
if p.Class != "" {
|
||||
<div class={ p.Class }>
|
||||
@p.Content
|
||||
</div>
|
||||
} else {
|
||||
@p.Content
|
||||
}
|
||||
@p.Content
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -27,7 +20,6 @@ type ExampleWrapperProps struct {
|
||||
ShowcaseFile templ.Component
|
||||
PreviewCodeFile string
|
||||
ComponentCodeFile string
|
||||
ShowcaseClass string
|
||||
}
|
||||
|
||||
templ ExampleWrapper(p ExampleWrapperProps) {
|
||||
@ -49,7 +41,6 @@ func generateTabs(p ExampleWrapperProps) []components.Tab {
|
||||
Title: "Preview",
|
||||
Content: showcaseWrapper(showcaseWrapperProps{
|
||||
Content: p.ShowcaseFile,
|
||||
Class: p.ShowcaseClass,
|
||||
}),
|
||||
},
|
||||
{
|
||||
|
@ -24,12 +24,30 @@ templ Checkbox() {
|
||||
PreviewCodeFile: "checkbox_checked.templ",
|
||||
ComponentCodeFile: "checkbox.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Label",
|
||||
ShowcaseFile: showcase.CheckboxWithLabel(),
|
||||
PreviewCodeFile: "checkbox_with_label.templ",
|
||||
ComponentCodeFile: "checkbox.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Disabled",
|
||||
ShowcaseFile: showcase.CheckboxDisabled(),
|
||||
PreviewCodeFile: "checkbox_disabled.templ",
|
||||
ComponentCodeFile: "checkbox.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Custom Icon",
|
||||
ShowcaseFile: showcase.CheckboxCustomIcon(),
|
||||
PreviewCodeFile: "checkbox_custom_icon.templ",
|
||||
ComponentCodeFile: "checkbox.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Form",
|
||||
ShowcaseFile: showcase.CheckboxForm(),
|
||||
PreviewCodeFile: "checkbox_form.templ",
|
||||
ComponentCodeFile: "checkbox.templ",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,12 @@ templ Datepicker() {
|
||||
PreviewCodeFile: "datepicker_default.templ",
|
||||
ComponentCodeFile: "datepicker.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Label",
|
||||
ShowcaseFile: showcase.DatepickerWithLabel(),
|
||||
PreviewCodeFile: "datepicker_with_label.templ",
|
||||
ComponentCodeFile: "datepicker.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Custom Placeholder",
|
||||
ShowcaseFile: showcase.DatepickerCustomPlaceholder(),
|
||||
@ -42,6 +48,12 @@ templ Datepicker() {
|
||||
PreviewCodeFile: "datepicker_formats.templ",
|
||||
ComponentCodeFile: "datepicker.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Form",
|
||||
ShowcaseFile: showcase.DatepickerForm(),
|
||||
PreviewCodeFile: "datepicker_form.templ",
|
||||
ComponentCodeFile: "datepicker.templ",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,18 +18,6 @@ templ Input() {
|
||||
PreviewCodeFile: "input_default.templ",
|
||||
ComponentCodeFile: "input.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Placeholder",
|
||||
ShowcaseFile: showcase.InputWithPlaceholder(),
|
||||
PreviewCodeFile: "input_with_placeholder.templ",
|
||||
ComponentCodeFile: "input.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Values",
|
||||
ShowcaseFile: showcase.InputWithValues(),
|
||||
PreviewCodeFile: "input_with_values.templ",
|
||||
ComponentCodeFile: "input.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "File",
|
||||
ShowcaseFile: showcase.InputFile(),
|
||||
@ -49,21 +37,9 @@ templ Input() {
|
||||
ComponentCodeFile: "input.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Description",
|
||||
ShowcaseFile: showcase.InputWithDescription(),
|
||||
PreviewCodeFile: "input_with_description.templ",
|
||||
ComponentCodeFile: "input.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Error",
|
||||
ShowcaseFile: showcase.InputWithError(),
|
||||
PreviewCodeFile: "input_with_error.templ",
|
||||
ComponentCodeFile: "input.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Advanced",
|
||||
ShowcaseFile: showcase.InputAdvanced(),
|
||||
PreviewCodeFile: "input_advanced.templ",
|
||||
SectionName: "Form",
|
||||
ShowcaseFile: showcase.InputForm(),
|
||||
PreviewCodeFile: "input_form.templ",
|
||||
ComponentCodeFile: "input.templ",
|
||||
})
|
||||
}
|
||||
|
47
internals/ui/pages/radio.templ
Normal file
47
internals/ui/pages/radio.templ
Normal file
@ -0,0 +1,47 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/internals/ui/layouts"
|
||||
"github.com/axzilla/goilerplate/internals/ui/modules"
|
||||
"github.com/axzilla/goilerplate/internals/ui/showcase"
|
||||
)
|
||||
|
||||
templ Radio() {
|
||||
@layouts.DocsLayout() {
|
||||
@modules.PageWrapper(modules.PageWrapperProps{
|
||||
Name: "Radio",
|
||||
Description: templ.Raw("Control for selecting a single option from a list of choices."),
|
||||
}) {
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Default",
|
||||
ShowcaseFile: showcase.RadioDefault(),
|
||||
PreviewCodeFile: "radio_default.templ",
|
||||
ComponentCodeFile: "radio.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Checked",
|
||||
ShowcaseFile: showcase.RadioChecked(),
|
||||
PreviewCodeFile: "radio_checked.templ",
|
||||
ComponentCodeFile: "radio.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Label",
|
||||
ShowcaseFile: showcase.RadioWithLabel(),
|
||||
PreviewCodeFile: "radio_with_label.templ",
|
||||
ComponentCodeFile: "radio.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Disabled",
|
||||
ShowcaseFile: showcase.RadioDisabled(),
|
||||
PreviewCodeFile: "radio_disabled.templ",
|
||||
ComponentCodeFile: "radio.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Form",
|
||||
ShowcaseFile: showcase.RadioForm(),
|
||||
PreviewCodeFile: "radio_form.templ",
|
||||
ComponentCodeFile: "radio.templ",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/internals/ui/layouts"
|
||||
"github.com/axzilla/goilerplate/internals/ui/modules"
|
||||
"github.com/axzilla/goilerplate/internals/ui/showcase"
|
||||
)
|
||||
|
||||
templ RadioGroup() {
|
||||
@layouts.DocsLayout() {
|
||||
@modules.PageWrapper(modules.PageWrapperProps{
|
||||
Name: "Radio Group",
|
||||
Description: templ.Raw("Control for selecting a single option from a list of choices."),
|
||||
}) {
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Using Props",
|
||||
ShowcaseFile: showcase.RadioGroupProps(),
|
||||
PreviewCodeFile: "radio_group_props.templ",
|
||||
ComponentCodeFile: "radio_group.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Using Attributes",
|
||||
ShowcaseFile: showcase.RadioGroupAttributes(),
|
||||
PreviewCodeFile: "radio_group_attributes.templ",
|
||||
ComponentCodeFile: "radio_group.templ",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
@ -15,31 +15,39 @@ templ Select() {
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Default",
|
||||
ShowcaseFile: showcase.SelectDefault(),
|
||||
ShowcaseClass: "w-72",
|
||||
PreviewCodeFile: "select_default.templ",
|
||||
ComponentCodeFile: "select.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Placeholder",
|
||||
ShowcaseFile: showcase.SelectWithPlaceholder(),
|
||||
ShowcaseClass: "w-72",
|
||||
PreviewCodeFile: "select_with_placeholder.templ",
|
||||
ComponentCodeFile: "select.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Selected Value",
|
||||
ShowcaseFile: showcase.SelectSelectedValue(),
|
||||
ShowcaseClass: "w-72",
|
||||
PreviewCodeFile: "select_selected_value.templ",
|
||||
ComponentCodeFile: "select.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Label",
|
||||
ShowcaseFile: showcase.SelectWithLabel(),
|
||||
PreviewCodeFile: "select_with_label.templ",
|
||||
ComponentCodeFile: "select.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Disabled",
|
||||
ShowcaseFile: showcase.SelectDisabled(),
|
||||
ShowcaseClass: "w-72",
|
||||
PreviewCodeFile: "select_disabled.templ",
|
||||
ComponentCodeFile: "select.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Form",
|
||||
ShowcaseFile: showcase.SelectForm(),
|
||||
PreviewCodeFile: "select_form.templ",
|
||||
ComponentCodeFile: "select.templ",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,42 +15,36 @@ templ Slider() {
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Default",
|
||||
ShowcaseFile: showcase.SliderDefault(),
|
||||
ShowcaseClass: "w-96",
|
||||
PreviewCodeFile: "slider_default.templ",
|
||||
ComponentCodeFile: "sheet.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Value",
|
||||
ShowcaseFile: showcase.SliderWithValue(),
|
||||
ShowcaseClass: "w-96",
|
||||
PreviewCodeFile: "slider_with_value.templ",
|
||||
ComponentCodeFile: "sheet.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Label",
|
||||
ShowcaseFile: showcase.SliderWithLabel(),
|
||||
ShowcaseClass: "w-96",
|
||||
PreviewCodeFile: "slider_with_label.templ",
|
||||
ComponentCodeFile: "sheet.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Steps",
|
||||
ShowcaseFile: showcase.SliderWithSteps(),
|
||||
ShowcaseClass: "w-96",
|
||||
PreviewCodeFile: "slider_with_steps.templ",
|
||||
ComponentCodeFile: "sheet.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Label and Value",
|
||||
ShowcaseFile: showcase.SliderWithLabelAndValue(),
|
||||
ShowcaseClass: "w-96",
|
||||
PreviewCodeFile: "slider_with_label_and_value.templ",
|
||||
ComponentCodeFile: "sheet.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Disabled",
|
||||
ShowcaseFile: showcase.SliderDisabled(),
|
||||
ShowcaseClass: "w-96",
|
||||
PreviewCodeFile: "slider_disabled.templ",
|
||||
ComponentCodeFile: "sheet.templ",
|
||||
})
|
||||
|
@ -15,65 +15,45 @@ templ Textarea() {
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Default",
|
||||
ShowcaseFile: showcase.TextareaDefault(),
|
||||
ShowcaseClass: "w-96",
|
||||
PreviewCodeFile: "textarea_default.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Value",
|
||||
ShowcaseFile: showcase.TextareaWithValue(),
|
||||
ShowcaseClass: "w-96",
|
||||
|
||||
SectionName: "With Value",
|
||||
ShowcaseFile: showcase.TextareaWithValue(),
|
||||
PreviewCodeFile: "textarea_with_value.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Rows",
|
||||
ShowcaseFile: showcase.TextareaWithRows(),
|
||||
ShowcaseClass: "w-96",
|
||||
|
||||
SectionName: "With Rows",
|
||||
ShowcaseFile: showcase.TextareaWithRows(),
|
||||
PreviewCodeFile: "textarea_with_rows.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Label",
|
||||
ShowcaseFile: showcase.TextareaWithLabel(),
|
||||
ShowcaseClass: "w-96",
|
||||
|
||||
PreviewCodeFile: "textarea_with_label.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Description",
|
||||
ShowcaseFile: showcase.TextareaWithDescription(),
|
||||
ShowcaseClass: "w-96",
|
||||
|
||||
PreviewCodeFile: "textarea_with_description.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Error",
|
||||
ShowcaseFile: showcase.TextareaWithError(),
|
||||
ShowcaseClass: "w-96",
|
||||
|
||||
PreviewCodeFile: "textarea_with_error.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Auto Resize",
|
||||
ShowcaseFile: showcase.TextareaAutoResize(),
|
||||
ShowcaseClass: "w-96",
|
||||
PreviewCodeFile: "textarea_auto_resize.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Disabled",
|
||||
ShowcaseFile: showcase.TextareaDisabled(),
|
||||
ShowcaseClass: "w-96",
|
||||
|
||||
SectionName: "With Label",
|
||||
ShowcaseFile: showcase.TextareaWithLabel(),
|
||||
PreviewCodeFile: "textarea_with_label.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Disabled",
|
||||
ShowcaseFile: showcase.TextareaDisabled(),
|
||||
PreviewCodeFile: "textarea_disabled.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Form",
|
||||
ShowcaseFile: showcase.TextareaForm(),
|
||||
PreviewCodeFile: "textarea_form.templ",
|
||||
ComponentCodeFile: "textarea.templ",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,50 +100,48 @@ templ ThemePreview() {
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-medium">Preferred Contact Method</label>
|
||||
@components.RadioGroup(components.RadioGroupProps{Name: "contact-method"}) {
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "email",
|
||||
ID: "contact-email",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Email"),
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "phone",
|
||||
ID: "contact-phone",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Phone"),
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "mail",
|
||||
ID: "contact-mail",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Physical Mail"),
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
}
|
||||
@components.Radio(components.RadioProps{
|
||||
Value: "email",
|
||||
ID: "contact-email",
|
||||
Name: "contact-method",
|
||||
// Label: templ.Raw("Email"),
|
||||
})
|
||||
@components.Radio(components.RadioProps{
|
||||
Value: "phone",
|
||||
ID: "contact-phone",
|
||||
Name: "contact-method",
|
||||
// Label: templ.Raw("Phone"),
|
||||
})
|
||||
@components.Radio(components.RadioProps{
|
||||
Value: "mail",
|
||||
ID: "contact-mail",
|
||||
Name: "contact-method",
|
||||
// Label: templ.Raw("Physical Mail"),
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<label class="text-sm font-medium">Preferences</label>
|
||||
<div class="space-y-2">
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "marketing",
|
||||
Name: "marketing",
|
||||
LabelRight: "Receive marketing emails",
|
||||
ID: "marketing",
|
||||
Name: "marketing",
|
||||
// LabelRight: "Receive marketing emails",
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "notifications",
|
||||
Name: "notifications",
|
||||
LabelRight: "Enable notifications",
|
||||
ID: "notifications",
|
||||
Name: "notifications",
|
||||
// LabelRight: "Enable notifications",
|
||||
Attributes: templ.Attributes{"checked": "true"},
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "beta",
|
||||
Name: "beta",
|
||||
LabelRight: "Join beta program",
|
||||
ID: "beta",
|
||||
Name: "beta",
|
||||
// LabelRight: "Join beta program",
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
</div>
|
||||
@ -153,7 +151,6 @@ templ ThemePreview() {
|
||||
ID: "terms",
|
||||
Name: "terms",
|
||||
Value: "accepted",
|
||||
Label: "I agree to the Terms and Conditions",
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@ -161,7 +158,6 @@ templ ThemePreview() {
|
||||
ID: "newsletter",
|
||||
Name: "newsletter",
|
||||
Value: "subscribed",
|
||||
Label: "Subscribe to our newsletter",
|
||||
})
|
||||
</div>
|
||||
</form>
|
||||
|
@ -18,30 +18,30 @@ templ Toggle() {
|
||||
PreviewCodeFile: "toggle_default.templ",
|
||||
ComponentCodeFile: "toggle.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Label Left",
|
||||
ShowcaseFile: showcase.ToggleLabelLeft(),
|
||||
PreviewCodeFile: "toggle_label_left.templ",
|
||||
ComponentCodeFile: "toggle.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Label Right",
|
||||
ShowcaseFile: showcase.ToggleLabelRight(),
|
||||
PreviewCodeFile: "toggle_label_right.templ",
|
||||
ComponentCodeFile: "toggle.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Checked",
|
||||
ShowcaseFile: showcase.ToggleChecked(),
|
||||
PreviewCodeFile: "toggle_checked.templ",
|
||||
ComponentCodeFile: "toggle.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "With Label",
|
||||
ShowcaseFile: showcase.ToggleWithLabel(),
|
||||
PreviewCodeFile: "toggle_with_label.templ",
|
||||
ComponentCodeFile: "toggle.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Disabled",
|
||||
ShowcaseFile: showcase.ToggleDisabled(),
|
||||
PreviewCodeFile: "toggle_disabled.templ",
|
||||
ComponentCodeFile: "toggle.templ",
|
||||
})
|
||||
@modules.ExampleWrapper(modules.ExampleWrapperProps{
|
||||
SectionName: "Form",
|
||||
ShowcaseFile: showcase.ToggleForm(),
|
||||
PreviewCodeFile: "toggle_form.templ",
|
||||
ComponentCodeFile: "toggle.templ",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ CardDefault() {
|
||||
@components.Card(components.CardProps{Class: "w-2/3"}) {
|
||||
@components.Card(components.CardProps{Class: "max-w-sm"}) {
|
||||
@components.CardHeader() {
|
||||
@components.CardTitle() {
|
||||
Card Title
|
||||
|
@ -3,20 +3,7 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ CheckboxChecked() {
|
||||
<div class="flex flex-col gap-4">
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "checked-checkbox",
|
||||
Name: "newsletter",
|
||||
Value: "subscribe",
|
||||
Label: "Checked using props",
|
||||
Checked: true,
|
||||
})
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "checked-checkbox",
|
||||
Name: "newsletter",
|
||||
Value: "subscribe",
|
||||
Label: "Checked using attributes",
|
||||
Attributes: templ.Attributes{"checked": "true"},
|
||||
})
|
||||
</div>
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
Checked: true,
|
||||
})
|
||||
}
|
||||
|
13
internals/ui/showcase/checkbox_custom_icon.templ
Normal file
13
internals/ui/showcase/checkbox_custom_icon.templ
Normal file
@ -0,0 +1,13 @@
|
||||
package showcase
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/pkg/components"
|
||||
"github.com/axzilla/goilerplate/pkg/icons"
|
||||
)
|
||||
|
||||
templ CheckboxCustomIcon() {
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
Icon: icons.Plus(icons.IconProps{Size: "12"}),
|
||||
Checked: true,
|
||||
})
|
||||
}
|
@ -3,10 +3,5 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ CheckboxDefault() {
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "default-checkbox",
|
||||
Name: "default",
|
||||
Value: "default",
|
||||
Label: "Accept terms and conditions",
|
||||
})
|
||||
@components.Checkbox(components.CheckboxProps{})
|
||||
}
|
||||
|
@ -3,20 +3,14 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ CheckboxDisabled() {
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "disabled-checkbox",
|
||||
Name: "disabled-checkbox",
|
||||
Value: "disabled-checkbox",
|
||||
Label: "Disabled using props",
|
||||
ID: "checkbox-disabled",
|
||||
Disabled: true,
|
||||
})
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "disabled-checkbox",
|
||||
Name: "disabled-checkbox",
|
||||
Value: "disabled-checkbox",
|
||||
Label: "Disabled using attributes",
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
@components.Label(components.LabelProps{
|
||||
For: "checkbox-disabled",
|
||||
Text: "Accept terms and conditions",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
61
internals/ui/showcase/checkbox_form.templ
Normal file
61
internals/ui/showcase/checkbox_form.templ
Normal file
@ -0,0 +1,61 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ CheckboxForm() {
|
||||
<div class="w-full max-w-sm">
|
||||
@components.FormItem(components.FormItemProps{}) {
|
||||
// Group Label
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
Text: "Select your interests",
|
||||
})
|
||||
// Option 1
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "c1",
|
||||
Name: "interests",
|
||||
Value: "design",
|
||||
Checked: true,
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "c1",
|
||||
Text: "Design and UX",
|
||||
})
|
||||
}
|
||||
// Option 2
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "c2",
|
||||
Name: "interests",
|
||||
Value: "development",
|
||||
Disabled: true,
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "c2",
|
||||
Text: "Development (Coming Soon)",
|
||||
})
|
||||
}
|
||||
// Option 3
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "c3",
|
||||
Name: "interests",
|
||||
Value: "business",
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "c3",
|
||||
Text: "Business and Marketing",
|
||||
})
|
||||
}
|
||||
// Description
|
||||
@components.FormDescription(components.FormDescriptionProps{}) {
|
||||
Choose all areas that interest you.
|
||||
}
|
||||
// Error Message
|
||||
@components.FormMessage(components.FormMessageProps{
|
||||
Type: "error",
|
||||
Message: "Please select at least one interest.",
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
15
internals/ui/showcase/checkbox_with_label.templ
Normal file
15
internals/ui/showcase/checkbox_with_label.templ
Normal file
@ -0,0 +1,15 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ CheckboxWithLabel() {
|
||||
<div class="flex items-center gap-2">
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "checkbox-with-label",
|
||||
})
|
||||
@components.Label(components.LabelProps{
|
||||
For: "checkbox-with-label",
|
||||
Text: "Accept terms and conditions",
|
||||
})
|
||||
</div>
|
||||
}
|
@ -3,10 +3,9 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ DatepickerCustomPlaceholder() {
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date",
|
||||
Name: "date",
|
||||
Placeholder: "When is your birthday?",
|
||||
Class: "w-full max-w-xs",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
Placeholder: "When is your birthday?",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,9 +3,7 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ DatepickerDefault() {
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "my-datepicker",
|
||||
Name: "selected-date",
|
||||
Class: "w-full max-w-xs",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Datepicker(components.DatepickerProps{})
|
||||
</div>
|
||||
}
|
||||
|
@ -2,28 +2,12 @@ package showcase
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/pkg/components"
|
||||
"time"
|
||||
)
|
||||
|
||||
templ DatepickerDisabled() {
|
||||
<div class="w-full max-w-xs flex flex-col gap-4">
|
||||
// Disabled using attributes
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "my-datepicker",
|
||||
Name: "selected-date",
|
||||
Placeholder: "Select a date",
|
||||
Value: time.Now(),
|
||||
Class: "w-full max-w-xs",
|
||||
Attributes: templ.Attributes{"disabled": true},
|
||||
})
|
||||
// Disabled using props
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "my-datepicker-2",
|
||||
Name: "selected-date-2",
|
||||
Placeholder: "Select a date",
|
||||
Value: time.Now(),
|
||||
Class: "w-full max-w-xs",
|
||||
Disabled: true,
|
||||
Disabled: true,
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
26
internals/ui/showcase/datepicker_form.templ
Normal file
26
internals/ui/showcase/datepicker_form.templ
Normal file
@ -0,0 +1,26 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ DatepickerForm() {
|
||||
<div class="w-full max-w-sm">
|
||||
@components.FormItem(components.FormItemProps{}) {
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
Text: "Select a date",
|
||||
For: "datepicker-form",
|
||||
})
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "datepicker-form",
|
||||
Name: "datepicker-form",
|
||||
HasError: true,
|
||||
})
|
||||
@components.FormDescription(components.FormDescriptionProps{}) {
|
||||
Select a date from the calendar.
|
||||
}
|
||||
@components.FormMessage(components.FormMessageProps{
|
||||
Message: "Please select a date",
|
||||
Type: "error",
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
@ -6,71 +6,58 @@ import (
|
||||
)
|
||||
|
||||
templ DatepickerFormats() {
|
||||
<div class="w-full max-w-xs flex flex-col gap-4">
|
||||
// Default ISO
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-iso",
|
||||
Name: "date_iso",
|
||||
Config: components.DatePickerISO,
|
||||
Value: time.Now(),
|
||||
})
|
||||
// Default EU
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-eu",
|
||||
Name: "date_eu",
|
||||
Config: components.DatePickerEU,
|
||||
Value: time.Now(),
|
||||
})
|
||||
// Default UK
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-uk",
|
||||
Name: "date_uk",
|
||||
Config: components.DatePickerUK,
|
||||
Value: time.Now(),
|
||||
})
|
||||
// Default US
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-us",
|
||||
Name: "date_us",
|
||||
Config: components.DatePickerUS,
|
||||
Value: time.Now(),
|
||||
})
|
||||
// Default LONG
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-long",
|
||||
Name: "date_long",
|
||||
Config: components.DatePickerLONG,
|
||||
Value: time.Now(),
|
||||
})
|
||||
// Custom Config
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-es",
|
||||
Name: "date_es",
|
||||
Config: components.NewDatepickerConfig(
|
||||
components.DateFormatLONG,
|
||||
components.DateLocaleSpanish,
|
||||
),
|
||||
Value: time.Now().AddDate(0, 0, -30), // 30 days ago
|
||||
Placeholder: "Seleccionar fecha",
|
||||
})
|
||||
// Custom Format (Japanese LONG)
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-custom",
|
||||
Name: "date_custom",
|
||||
Config: components.NewDatepickerConfig(
|
||||
components.DateFormatLONG,
|
||||
components.DateLocale{
|
||||
MonthNames: []string{
|
||||
"1月", "2月", "3月", "4月", "5月", "6月",
|
||||
"7月", "8月", "9月", "10月", "11月", "12月",
|
||||
},
|
||||
DayNames: []string{
|
||||
"日", "月", "火", "水", "木", "金", "土",
|
||||
},
|
||||
},
|
||||
),
|
||||
Value: time.Now().AddDate(0, 0, -30), // 30 days ago
|
||||
Placeholder: "Seleccionar fecha",
|
||||
})
|
||||
<div class="w-full max-w-sm flex flex-col gap-4">
|
||||
<div class="space-y-2">
|
||||
@components.Label(components.LabelProps{Text: "Default ISO", For: "datepicker-iso-format"})
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "datepicker-iso-format",
|
||||
Config: components.DatePickerISO,
|
||||
Value: time.Now(),
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@components.Label(components.LabelProps{Text: "Default EU", For: "datepicker-eu-format"})
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "datepicker-eu-format",
|
||||
Config: components.DatePickerEU,
|
||||
Value: time.Now(),
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@components.Label(components.LabelProps{Text: "UK Format", For: "datepicker-uk-format"})
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "datepicker-uk-format",
|
||||
Config: components.DatePickerUK,
|
||||
Value: time.Now(),
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@components.Label(components.LabelProps{Text: "US Format", For: "datepicker-us-format"})
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "datepicker-us-format",
|
||||
Config: components.DatePickerUS,
|
||||
Value: time.Now(),
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@components.Label(components.LabelProps{Text: "LONG Format", For: "date-long-format"})
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-long-format",
|
||||
Config: components.DatePickerLONG,
|
||||
Value: time.Now(),
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@components.Label(components.LabelProps{Text: "LONG Format (Spanish)", For: "date-es-long-format"})
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "date-es-custom-config",
|
||||
Config: components.NewDatepickerConfig(
|
||||
components.DateFormatLONG,
|
||||
components.DateLocaleSpanish,
|
||||
),
|
||||
Value: time.Now().AddDate(0, 0, -30), // 30 days ago
|
||||
Placeholder: "Seleccionar fecha",
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
package showcase
|
||||
|
||||
import (
|
||||
@ -6,11 +7,9 @@ import (
|
||||
)
|
||||
|
||||
templ DatepickerSelectedDate() {
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "my-datepicker",
|
||||
Name: "selected-date",
|
||||
Placeholder: "Select a date",
|
||||
Value: time.Now(),
|
||||
Class: "w-full max-w-xs",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
Value: time.Now(),
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
17
internals/ui/showcase/datepicker_with_label.templ
Normal file
17
internals/ui/showcase/datepicker_with_label.templ
Normal file
@ -0,0 +1,17 @@
|
||||
package showcase
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/pkg/components"
|
||||
)
|
||||
|
||||
templ DatepickerWithLabel() {
|
||||
<div class="w-full max-w-sm space-y-2">
|
||||
@components.Label(components.LabelProps{
|
||||
Text: "Pick a date",
|
||||
For: "datepicker-with-label",
|
||||
})
|
||||
@components.Datepicker(components.DatepickerProps{
|
||||
ID: "datepicker-with-label",
|
||||
})
|
||||
</div>
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputAdvanced() {
|
||||
@components.Input(components.InputProps{
|
||||
ID: "username",
|
||||
Label: "Username",
|
||||
Placeholder: "e.g. john123",
|
||||
Description: "This is your public display name.",
|
||||
Value: "",
|
||||
Error: "Username must be more then 2 characters",
|
||||
})
|
||||
}
|
@ -3,7 +3,10 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputDefault() {
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "Email",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,18 +3,11 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputDisabled() {
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Label: "Disabled using props",
|
||||
Placeholder: "e.g. john@doe.com",
|
||||
Placeholder: "Email",
|
||||
Disabled: true,
|
||||
})
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Label: "Disabled using attributes",
|
||||
Placeholder: "e.g. john@doe.com",
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputFile() {
|
||||
@components.Input(components.InputProps{
|
||||
Type: "file",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Input(components.InputProps{
|
||||
Type: "file",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
29
internals/ui/showcase/input_form.templ
Normal file
29
internals/ui/showcase/input_form.templ
Normal file
@ -0,0 +1,29 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputForm() {
|
||||
<div class="w-full max-w-sm">
|
||||
@components.FormItem(components.FormItemProps{}) {
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
Text: "Email",
|
||||
For: "email-form",
|
||||
})
|
||||
@components.Input(components.InputProps{
|
||||
ID: "email-form",
|
||||
Type: "email",
|
||||
Name: "email",
|
||||
Placeholder: "m@example.com",
|
||||
HasError: true,
|
||||
Disabled: true,
|
||||
})
|
||||
@components.FormDescription(components.FormDescriptionProps{}) {
|
||||
Enter your email address for notifications.
|
||||
}
|
||||
@components.FormMessage(components.FormMessageProps{
|
||||
Message: "Please enter a valid email address",
|
||||
Type: "error",
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputWithDescription() {
|
||||
@components.Input(components.InputProps{
|
||||
ID: "email",
|
||||
Type: "email",
|
||||
Description: "This is your accounts email address.",
|
||||
})
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputWithError() {
|
||||
@components.Input(components.InputProps{
|
||||
ID: "username",
|
||||
Error: "Username must be more then 2 characters",
|
||||
})
|
||||
}
|
@ -3,9 +3,12 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputWithLabel() {
|
||||
@components.Input(components.InputProps{
|
||||
ID: "email",
|
||||
Type: "email",
|
||||
Label: "Email",
|
||||
})
|
||||
<div class="w-full max-w-sm grid gap-2">
|
||||
@components.Label(components.LabelProps{Text: "Email", For: "email"})
|
||||
@components.Input(components.InputProps{
|
||||
ID: "email",
|
||||
Type: "email",
|
||||
Placeholder: "Email",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputWithPlaceholder() {
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "e.g. john@doe.com",
|
||||
})
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ InputWithValues() {
|
||||
<div class="flex flex-col gap-4">
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "Enter text",
|
||||
Value: "Value using props",
|
||||
})
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "Enter text",
|
||||
Attributes: templ.Attributes{
|
||||
"value": "Value using attributes",
|
||||
},
|
||||
})
|
||||
</div>
|
||||
}
|
9
internals/ui/showcase/radio_checked.templ
Normal file
9
internals/ui/showcase/radio_checked.templ
Normal file
@ -0,0 +1,9 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ RadioChecked() {
|
||||
@components.Radio(components.RadioProps{
|
||||
Checked: true,
|
||||
})
|
||||
}
|
9
internals/ui/showcase/radio_default.templ
Normal file
9
internals/ui/showcase/radio_default.templ
Normal file
@ -0,0 +1,9 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ RadioDefault() {
|
||||
<div class="flex gap-2 items-center">
|
||||
@components.Radio(components.RadioProps{})
|
||||
</div>
|
||||
}
|
16
internals/ui/showcase/radio_disabled.templ
Normal file
16
internals/ui/showcase/radio_disabled.templ
Normal file
@ -0,0 +1,16 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ RadioDisabled() {
|
||||
<div class="flex gap-2 items-center">
|
||||
@components.Radio(components.RadioProps{
|
||||
ID: "radio-disabled",
|
||||
Disabled: true,
|
||||
})
|
||||
@components.Label(components.LabelProps{
|
||||
For: "radio-disabled",
|
||||
Text: "Disabled",
|
||||
})
|
||||
</div>
|
||||
}
|
61
internals/ui/showcase/radio_form.templ
Normal file
61
internals/ui/showcase/radio_form.templ
Normal file
@ -0,0 +1,61 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ RadioForm() {
|
||||
<div class="w-full max-w-sm">
|
||||
@components.FormItem(components.FormItemProps{}) {
|
||||
// Group Label
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
Text: "Notify me about new products",
|
||||
})
|
||||
// Option 1
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Radio(components.RadioProps{
|
||||
ID: "r1",
|
||||
Name: "notify",
|
||||
Value: "all",
|
||||
Checked: true,
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "r1",
|
||||
Text: "All new products",
|
||||
})
|
||||
}
|
||||
// Option 2
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Radio(components.RadioProps{
|
||||
ID: "r2",
|
||||
Name: "notify",
|
||||
Value: "wishlist",
|
||||
Disabled: true,
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "r2",
|
||||
Text: "Create a wishlist (Coming Soon)",
|
||||
})
|
||||
}
|
||||
// Option 3
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Radio(components.RadioProps{
|
||||
ID: "r3",
|
||||
Name: "notify",
|
||||
Value: "none",
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "r3",
|
||||
Text: "No notifications",
|
||||
})
|
||||
}
|
||||
// Description
|
||||
@components.FormDescription(components.FormDescriptionProps{}) {
|
||||
You can change your preferences at any time.
|
||||
}
|
||||
// Error Message
|
||||
@components.FormMessage(components.FormMessageProps{
|
||||
Type: "error",
|
||||
Message: "We will send you an email when new products are available.",
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ RadioGroupAttributes() {
|
||||
@components.RadioGroup(components.RadioGroupProps{}) {
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "default",
|
||||
ID: "r1",
|
||||
Name: "atrrs",
|
||||
Label: templ.Raw("Default"),
|
||||
Attributes: templ.Attributes{"checked": true},
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "comfortable",
|
||||
ID: "r2",
|
||||
Name: "atrrs",
|
||||
Label: templ.Raw("Disabled"),
|
||||
Attributes: templ.Attributes{"disabled": true},
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "compact",
|
||||
ID: "r3",
|
||||
Name: "atrrs",
|
||||
Label: templ.Raw("Compact"),
|
||||
})
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ RadioGroupProps() {
|
||||
@components.RadioGroup(components.RadioGroupProps{}) {
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "default",
|
||||
ID: "r1",
|
||||
Name: "props",
|
||||
Label: templ.Raw("Default"),
|
||||
Checked: true,
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "comfortable",
|
||||
ID: "r2",
|
||||
Name: "props",
|
||||
Label: templ.Raw("Disabled"),
|
||||
Disabled: true,
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "compact",
|
||||
ID: "r3",
|
||||
Name: "props",
|
||||
Label: templ.Raw("Compact"),
|
||||
})
|
||||
}
|
||||
}
|
15
internals/ui/showcase/radio_with_label.templ
Normal file
15
internals/ui/showcase/radio_with_label.templ
Normal file
@ -0,0 +1,15 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ RadioWithLabel() {
|
||||
<div class="flex gap-2 items-center">
|
||||
@components.Radio(components.RadioProps{
|
||||
ID: "radio-with-label",
|
||||
})
|
||||
@components.Label(components.LabelProps{
|
||||
For: "radio-with-label",
|
||||
Text: "Label",
|
||||
})
|
||||
</div>
|
||||
}
|
@ -3,14 +3,14 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SelectDefault() {
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "fruit",
|
||||
Name: "fruit",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange"},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
<div class="w-full max-w-md">
|
||||
@components.Select(components.SelectProps{
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange"},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,25 +3,17 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SelectDisabled() {
|
||||
<div class="flex flex-col gap-4">
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Placeholder: "Disabled using props",
|
||||
Disabled: true,
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Option 1", Value: "1"},
|
||||
{Label: "Option 2", Value: "2"},
|
||||
},
|
||||
<div class="space-y-2 w-full max-w-sm">
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
Text: "Choose a fruit",
|
||||
For: "select-disabled",
|
||||
})
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Placeholder: "Disabled using attributes",
|
||||
Attributes: templ.Attributes{":disabled": "true"},
|
||||
ID: "select-disabled",
|
||||
Disabled: true,
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Option 1", Value: "1"},
|
||||
{Label: "Option 2", Value: "2"},
|
||||
{Label: "Apple", Value: "1"},
|
||||
{Label: "Banana", Value: "2"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
|
31
internals/ui/showcase/select_form.templ
Normal file
31
internals/ui/showcase/select_form.templ
Normal file
@ -0,0 +1,31 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SelectForm() {
|
||||
<div class="w-full max-w-sm">
|
||||
@components.FormItem(components.FormItemProps{}) {
|
||||
@components.Label(components.LabelProps{
|
||||
Text: "Choose a Fruit",
|
||||
For: "fruit-form",
|
||||
})
|
||||
@components.Select(components.SelectProps{
|
||||
Name: "fruit",
|
||||
ID: "fruit-form",
|
||||
Placeholder: "Pick a fruit",
|
||||
HasError: true,
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
},
|
||||
})
|
||||
@components.FormDescription(components.FormDescriptionProps{}) {
|
||||
Select your favorite fruit from the dropdown menu.
|
||||
}
|
||||
@components.FormMessage(components.FormMessageProps{
|
||||
Type: "error",
|
||||
Message: "A fruit selection is required.",
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
@ -3,11 +3,8 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SelectSelectedValue() {
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "selected",
|
||||
Name: "selected",
|
||||
Placeholder: "Selected by props",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana", Selected: true},
|
||||
@ -15,16 +12,5 @@ templ SelectSelectedValue() {
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "selected",
|
||||
Name: "selected",
|
||||
Placeholder: "Selected by attributes",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange", Attributes: templ.Attributes{"selected": true}},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
21
internals/ui/showcase/select_with_label.templ
Normal file
21
internals/ui/showcase/select_with_label.templ
Normal file
@ -0,0 +1,21 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SelectWithLabel() {
|
||||
<div class="space-y-2 w-full max-w-sm">
|
||||
@components.Label(components.LabelProps{
|
||||
Text: "Choose a Fruit",
|
||||
For: "fruit-with-label",
|
||||
})
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "fruit-with-label",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange"},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
}
|
@ -3,15 +3,15 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SelectWithPlaceholder() {
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "fruit",
|
||||
Name: "fruit",
|
||||
Placeholder: "Select a fruit",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange"},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
<div class="w-full max-w-md">
|
||||
@components.Select(components.SelectProps{
|
||||
Placeholder: "Pick a fruit",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange"},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SliderDefault() {
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "default",
|
||||
Name: "default",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "default",
|
||||
Name: "default",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,15 +3,17 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SliderDisabled() {
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Label: "Disabled Slider",
|
||||
Value: 20,
|
||||
Min: -20,
|
||||
Max: 200,
|
||||
Step: 20,
|
||||
Disabled: true,
|
||||
ShowValue: true,
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Label: "Disabled Slider",
|
||||
Value: 20,
|
||||
Min: -20,
|
||||
Max: 200,
|
||||
Step: 20,
|
||||
Disabled: true,
|
||||
ShowValue: true,
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,13 +3,15 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SliderWithLabel() {
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "with-label",
|
||||
Name: "with-label",
|
||||
Label: "Volume",
|
||||
Value: 65,
|
||||
Min: 0,
|
||||
Max: 100,
|
||||
Step: 1,
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "with-label",
|
||||
Name: "with-label",
|
||||
Label: "Volume",
|
||||
Value: 65,
|
||||
Min: 0,
|
||||
Max: 100,
|
||||
Step: 1,
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,15 +3,17 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SliderWithLabelAndValue() {
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "temperature",
|
||||
Name: "temperature",
|
||||
Label: "Temperature",
|
||||
Value: 23,
|
||||
Min: -20,
|
||||
Max: 40,
|
||||
Step: 1,
|
||||
ShowValue: true,
|
||||
ValueFormat: "°C",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "temperature",
|
||||
Name: "temperature",
|
||||
Label: "Temperature",
|
||||
Value: 23,
|
||||
Min: -20,
|
||||
Max: 40,
|
||||
Step: 1,
|
||||
ShowValue: true,
|
||||
ValueFormat: "°C",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,15 +3,17 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SliderWithSteps() {
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "steps",
|
||||
Name: "steps",
|
||||
Label: "Zoom Level",
|
||||
Value: 100,
|
||||
Min: 0,
|
||||
Max: 200,
|
||||
Step: 25,
|
||||
ShowValue: true,
|
||||
ValueFormat: "%",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "steps",
|
||||
Name: "steps",
|
||||
Label: "Zoom Level",
|
||||
Value: 100,
|
||||
Min: 0,
|
||||
Max: 200,
|
||||
Step: 25,
|
||||
ShowValue: true,
|
||||
ValueFormat: "%",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,14 +3,16 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SliderWithValue() {
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "with-label",
|
||||
Name: "with-label",
|
||||
Value: 75,
|
||||
Min: 0,
|
||||
Max: 100,
|
||||
Step: 1,
|
||||
ShowValue: true,
|
||||
ValueFormat: "%",
|
||||
})
|
||||
<div class="w-full max-w-sm">
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "with-label",
|
||||
Name: "with-label",
|
||||
Value: 75,
|
||||
Min: 0,
|
||||
Max: 100,
|
||||
Step: 1,
|
||||
ShowValue: true,
|
||||
ValueFormat: "%",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -38,14 +38,14 @@ templ AccountTab() {
|
||||
Placeholder: "Name",
|
||||
ID: "name",
|
||||
Value: "John Doe",
|
||||
Label: "Name",
|
||||
// Label: "Name",
|
||||
})
|
||||
@components.Input(components.InputProps{
|
||||
Type: components.InputTypeText,
|
||||
Placeholder: "Username",
|
||||
ID: "username",
|
||||
Value: "@johndoe",
|
||||
Label: "Username",
|
||||
// Label: "Username",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
@ -71,13 +71,13 @@ templ PasswordTab() {
|
||||
Type: components.InputTypePassword,
|
||||
Placeholder: "Current Password",
|
||||
ID: "current_password",
|
||||
Label: "Current Password",
|
||||
// Label: "Current Password",
|
||||
})
|
||||
@components.Input(components.InputProps{
|
||||
Type: components.InputTypePassword,
|
||||
Placeholder: "New Password",
|
||||
ID: "new_password",
|
||||
Label: "New Password",
|
||||
// Label: "New Password",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,13 +3,10 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaAutoResize() {
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "auto-resize",
|
||||
Name: "auto-resize",
|
||||
Label: "Your Message",
|
||||
Description: "This textarea will grow as you type.",
|
||||
Placeholder: "Start typing to see the magic...",
|
||||
Rows: 3,
|
||||
AutoResize: true,
|
||||
})
|
||||
<div class="w-full max-w-md">
|
||||
@components.Textarea(components.TextareaProps{
|
||||
Placeholder: "Start typing to see the magic...",
|
||||
AutoResize: true,
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,9 +3,7 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaDefault() {
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "default",
|
||||
Name: "default",
|
||||
Placeholder: "Type your message here.",
|
||||
})
|
||||
<div class="w-full max-w-md">
|
||||
@components.Textarea(components.TextareaProps{})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,18 +3,15 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaDisabled() {
|
||||
<div class="flex flex-col gap-4">
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Value: "Disabled using attributes",
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
<div class="space-y-2 w-full max-w-md">
|
||||
@components.Label(components.LabelProps{
|
||||
Text: "Your Message",
|
||||
For: "textarea-disabled",
|
||||
})
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Value: "Disabled using props",
|
||||
Disabled: true,
|
||||
ID: "textarea-disabled",
|
||||
Disabled: true,
|
||||
Placeholder: "This textarea is disabled.",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
26
internals/ui/showcase/textarea_form.templ
Normal file
26
internals/ui/showcase/textarea_form.templ
Normal file
@ -0,0 +1,26 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaForm() {
|
||||
<div class="w-full max-w-md">
|
||||
@components.FormItem(components.FormItemProps{}) {
|
||||
@components.Label(components.LabelProps{
|
||||
Text: "Your Message",
|
||||
For: "textarea-form",
|
||||
})
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "textarea-form",
|
||||
Name: "message",
|
||||
Placeholder: "Type your message here",
|
||||
})
|
||||
@components.FormDescription(components.FormDescriptionProps{}) {
|
||||
Please type your message in the textarea.
|
||||
}
|
||||
@components.FormMessage(components.FormMessageProps{
|
||||
Type: "error",
|
||||
Message: "This message is required.",
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaWithDescription() {
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "with-label",
|
||||
Name: "with-label",
|
||||
Label: "Your Message",
|
||||
Description: "Write a detailed description of your request.",
|
||||
Rows: 4,
|
||||
})
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaWithError() {
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "with-error",
|
||||
Name: "with-error",
|
||||
Label: "Your Message",
|
||||
Error: "Message is required",
|
||||
Placeholder: "Type your message here.",
|
||||
})
|
||||
}
|
@ -3,11 +3,14 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaWithLabel() {
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "with-label",
|
||||
Name: "with-label",
|
||||
Label: "Your Message",
|
||||
Placeholder: "Type your message here.",
|
||||
Rows: 4,
|
||||
})
|
||||
<div class="space-y-2 w-full max-w-md">
|
||||
@components.Label(components.LabelProps{
|
||||
Text: "Your Message",
|
||||
For: "textarea-with-label",
|
||||
})
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "textarea-with-label",
|
||||
Rows: 4,
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaWithRows() {
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "tall",
|
||||
Name: "tall",
|
||||
Placeholder: "Type your message here.",
|
||||
Rows: 6,
|
||||
})
|
||||
<div class="w-full max-w-md">
|
||||
@components.Textarea(components.TextareaProps{
|
||||
Placeholder: "Type your message here.",
|
||||
Rows: 6,
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
@ -1,20 +1,12 @@
|
||||
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaWithValue() {
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="w-full max-w-md">
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Value: "Value using props",
|
||||
Value: "This is a text area with a value.",
|
||||
})
|
||||
<div x-data="{ message: 'Value using attributes', }">
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Attributes: templ.Attributes{":value": "message"},
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -3,18 +3,7 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ ToggleChecked() {
|
||||
<div class="flex flex-col gap-4">
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-checked",
|
||||
Name: "toggle-checked",
|
||||
LabelRight: "Checked using props",
|
||||
Checked: true,
|
||||
})
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-checked",
|
||||
Name: "toggle-checked",
|
||||
LabelRight: "Checked using attributes",
|
||||
Attributes: templ.Attributes{"x-bind:checked": "true"},
|
||||
})
|
||||
</div>
|
||||
@components.Toggle(components.ToggleProps{
|
||||
Checked: true,
|
||||
})
|
||||
}
|
||||
|
@ -3,8 +3,5 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ ToggleDefault() {
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle",
|
||||
Name: "toggle",
|
||||
})
|
||||
@components.Toggle(components.ToggleProps{})
|
||||
}
|
||||
|
@ -3,18 +3,14 @@ package showcase
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ ToggleDisabled() {
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-disabled",
|
||||
Name: "toggle-disabled",
|
||||
LabelRight: "Disabled using props",
|
||||
Disabled: true,
|
||||
ID: "toggle-disabled",
|
||||
Disabled: true,
|
||||
})
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-disabled",
|
||||
Name: "toggle-disabled",
|
||||
LabelRight: "Disabled using attributes",
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
@components.Label(components.LabelProps{
|
||||
For: "toggle-disabled",
|
||||
Text: "Airplane Mode",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
|
52
internals/ui/showcase/toggle_form.templ
Normal file
52
internals/ui/showcase/toggle_form.templ
Normal file
@ -0,0 +1,52 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ ToggleForm() {
|
||||
<div class="w-full max-w-sm">
|
||||
@components.FormItem(components.FormItemProps{}) {
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
Text: "Connectivity Settings",
|
||||
})
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "airplane-mode",
|
||||
Name: "airplane",
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "airplane-mode",
|
||||
Text: "Airplane Mode",
|
||||
})
|
||||
}
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "wifi-mode",
|
||||
Name: "wifi",
|
||||
Disabled: true,
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "wifi-mode",
|
||||
Text: "WiFi (Not Available)",
|
||||
})
|
||||
}
|
||||
@components.FormItemFlex(components.FormItemProps{}) {
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "bluetooth-mode",
|
||||
Name: "bluetooth",
|
||||
Checked: true,
|
||||
})
|
||||
@components.FormLabel(components.FormLabelProps{
|
||||
For: "bluetooth-mode",
|
||||
Text: "Bluetooth",
|
||||
})
|
||||
}
|
||||
@components.FormDescription(components.FormDescriptionProps{}) {
|
||||
Manage your device's connectivity options.
|
||||
}
|
||||
@components.FormMessage(components.FormMessageProps{
|
||||
Type: "error",
|
||||
Message: "Please configure your connectivity settings.",
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ ToggleLabelLeft() {
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-left",
|
||||
Name: "toggle-left",
|
||||
LabelLeft: "Label Left",
|
||||
})
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ ToggleLabelRight() {
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-right",
|
||||
Name: "toggle-right",
|
||||
LabelRight: "Label Right",
|
||||
})
|
||||
}
|
15
internals/ui/showcase/toggle_with_label.templ
Normal file
15
internals/ui/showcase/toggle_with_label.templ
Normal file
@ -0,0 +1,15 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ ToggleWithLabel() {
|
||||
<div class="flex items-center gap-2">
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-with-label",
|
||||
})
|
||||
@components.Label(components.LabelProps{
|
||||
For: "toggle-with-label",
|
||||
Text: "Airplane Mode",
|
||||
})
|
||||
</div>
|
||||
}
|
@ -39,7 +39,7 @@ type AccordionProps struct {
|
||||
// - Attributes: Additional HTML attributes (e.g. data-testid)
|
||||
templ Accordion(props AccordionProps) {
|
||||
<div
|
||||
x-data="{
|
||||
x-data="{
|
||||
activeItem: null,
|
||||
toggleItem(itemId) {
|
||||
this.activeItem = this.activeItem === itemId ? null : itemId;
|
||||
|
@ -71,7 +71,7 @@ func Accordion(props AccordionProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-data=\"{ \n\t\t\tactiveItem: null,\n\t\t\ttoggleItem(itemId) {\n\t\t\t\tthis.activeItem = this.activeItem === itemId ? null : itemId;\n\t\t\t}\n\t\t}\" class=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-data=\"{\n\t\t\tactiveItem: null,\n\t\t\ttoggleItem(itemId) {\n\t\t\t\tthis.activeItem = this.activeItem === itemId ? null : itemId;\n\t\t\t}\n\t\t}\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ templ Card(props CardProps) {
|
||||
<div
|
||||
class={
|
||||
utils.TwMerge(
|
||||
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
||||
"w-full rounded-lg border bg-card text-card-foreground shadow-sm",
|
||||
props.Class,
|
||||
),
|
||||
templ.KV("flex overflow-hidden", props.Horizontal),
|
||||
|
@ -65,7 +65,7 @@ func Card(props CardProps) templ.Component {
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{
|
||||
utils.TwMerge(
|
||||
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
||||
"w-full rounded-lg border bg-card text-card-foreground shadow-sm",
|
||||
props.Class,
|
||||
),
|
||||
templ.KV("flex overflow-hidden", props.Horizontal),
|
||||
|
@ -5,83 +5,74 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// CheckboxProps configures the Checkbox component
|
||||
type CheckboxProps struct {
|
||||
// ID uniquely identifies the checkbox input
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Value sets the checkbox value
|
||||
Value string
|
||||
|
||||
// Label displays text next to checkbox
|
||||
// Empty string hides the label
|
||||
Label string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Disabled sets the checkbox to disabled state
|
||||
Disabled bool
|
||||
|
||||
// Checked sets the checkbox to checked state
|
||||
Checked bool
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Value string // Checkbox value
|
||||
Disabled bool // Prevents interaction
|
||||
Checked bool // Selected state
|
||||
Icon templ.Component // Custom check icon
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Control that allows selecting multiple options from a list.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/checkbox
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier for the input
|
||||
// - Name: Form field name
|
||||
// - Value: Checkbox value
|
||||
// - Label: Optional text label
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
// Checkbox renders a styled checkbox input with customizable icon
|
||||
templ Checkbox(props CheckboxProps) {
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ utils.TwMerge(
|
||||
"flex cursor-pointer items-center gap-2 text-sm font-medium",
|
||||
"text-muted-foreground [&:has(input:checked)]:text-foreground",
|
||||
"[&:has(input:disabled)]:opacity-50 [&:has(input:disabled)]:cursor-not-allowed",
|
||||
props.Class,
|
||||
) }
|
||||
>
|
||||
<div class="relative flex items-center">
|
||||
<input
|
||||
checked?={ props.Checked }
|
||||
disabled?={ props.Disabled }
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
value={ props.Value }
|
||||
type="checkbox"
|
||||
class="before:content[''] peer relative size-4 cursor-pointer appearance-none overflow-hidden
|
||||
rounded-sm border border-2 border-primary
|
||||
bg-background before:absolute before:inset-0
|
||||
checked:before:bg-primary
|
||||
focus:outline focus:outline-2 focus:outline-offset-2
|
||||
focus:outline-ring checked:focus:outline-primary
|
||||
active:outline-offset-0
|
||||
disabled:cursor-not-allowed
|
||||
transition-colors"
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
<div
|
||||
class="pointer-events-none invisible absolute left-1/2 top-1/2 size-3
|
||||
-translate-x-1/2 -translate-y-1/2 text-primary-foreground
|
||||
peer-checked:visible"
|
||||
>
|
||||
if props.ID == "" {
|
||||
{{ props.ID = utils.RandomID() }}
|
||||
}
|
||||
<div class="relative flex items-center">
|
||||
<input
|
||||
x-ref={ props.ID }
|
||||
data-input-id={ props.ID }
|
||||
data-testid={ props.ID }
|
||||
checked?={ props.Checked }
|
||||
disabled?={ props.Disabled }
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
value={ props.Value }
|
||||
type="checkbox"
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"relative size-4 overflow-hidden peer",
|
||||
"before:absolute before:inset-0 before:content['']",
|
||||
|
||||
// Styling
|
||||
"appearance-none rounded-sm border-2 border-primary bg-background",
|
||||
"cursor-pointer transition-colors",
|
||||
|
||||
// States
|
||||
"checked:before:bg-primary",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
<div
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
|
||||
|
||||
// Styling
|
||||
"size-3 text-primary-foreground pointer-events-none opacity-0",
|
||||
|
||||
// States
|
||||
"peer-checked:opacity-100",
|
||||
),
|
||||
}
|
||||
:class="{ 'visible': document.getElementById($el.dataset.inputId).checked }"
|
||||
>
|
||||
if props.Icon != nil {
|
||||
@props.Icon
|
||||
} else {
|
||||
@icons.Check(icons.IconProps{Size: "12"})
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
if props.Label != "" {
|
||||
<span>{ props.Label }</span>
|
||||
}
|
||||
</label>
|
||||
</div>
|
||||
}
|
||||
|
@ -13,44 +13,19 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// CheckboxProps configures the Checkbox component
|
||||
type CheckboxProps struct {
|
||||
// ID uniquely identifies the checkbox input
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Value sets the checkbox value
|
||||
Value string
|
||||
|
||||
// Label displays text next to checkbox
|
||||
// Empty string hides the label
|
||||
Label string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Disabled sets the checkbox to disabled state
|
||||
Disabled bool
|
||||
|
||||
// Checked sets the checkbox to checked state
|
||||
Checked bool
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Value string // Checkbox value
|
||||
Disabled bool // Prevents interaction
|
||||
Checked bool // Selected state
|
||||
Icon templ.Component // Custom check icon
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Control that allows selecting multiple options from a list.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/checkbox
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier for the input
|
||||
// - Name: Form field name
|
||||
// - Value: Checkbox value
|
||||
// - Label: Optional text label
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
// Checkbox renders a styled checkbox input with customizable icon
|
||||
func Checkbox(props CheckboxProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
@ -72,43 +47,75 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
|
||||
"flex cursor-pointer items-center gap-2 text-sm font-medium",
|
||||
"text-muted-foreground [&:has(input:checked)]:text-foreground",
|
||||
"[&:has(input:disabled)]:opacity-50 [&:has(input:disabled)]:cursor-not-allowed",
|
||||
props.Class,
|
||||
)}
|
||||
if props.ID == "" {
|
||||
props.ID = utils.RandomID()
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative flex items-center\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"relative size-4 overflow-hidden peer",
|
||||
"before:absolute before:inset-0 before:content['']",
|
||||
|
||||
// Styling
|
||||
"appearance-none rounded-sm border-2 border-primary bg-background",
|
||||
"cursor-pointer transition-colors",
|
||||
|
||||
// States
|
||||
"checked:before:bg-primary",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<input x-ref=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 48, Col: 16}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 27, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" data-input-id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 1, Col: 0}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 28, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><div class=\"relative flex items-center\"><input")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" data-testid=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 29, Col: 25}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -128,12 +135,12 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 60, Col: 17}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 32, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -141,12 +148,12 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 61, Col: 21}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 33, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -154,16 +161,29 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 62, Col: 23}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 34, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" type=\"checkbox\" class=\"before:content[''] peer relative size-4 cursor-pointer appearance-none overflow-hidden \n rounded-sm border border-2 border-primary\n bg-background before:absolute before:inset-0 \n checked:before:bg-primary\n focus:outline focus:outline-2 focus:outline-offset-2 \n focus:outline-ring checked:focus:outline-primary \n active:outline-offset-0 \n disabled:cursor-not-allowed\n transition-colors\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" type=\"checkbox\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -171,41 +191,58 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("><div class=\"pointer-events-none invisible absolute left-1/2 top-1/2 size-3 \n -translate-x-1/2 -translate-y-1/2 text-primary-foreground \n peer-checked:visible\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = icons.Check(icons.IconProps{Size: "12"}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
var templ_7745c5c3_Var10 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
|
||||
|
||||
// Styling
|
||||
"size-3 text-primary-foreground pointer-events-none opacity-0",
|
||||
|
||||
// States
|
||||
"peer-checked:opacity-100",
|
||||
),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" :class=\"{ 'visible': document.getElementById($el.dataset.inputId).checked }\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Icon != nil {
|
||||
templ_7745c5c3_Err = props.Icon.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = icons.Check(icons.IconProps{Size: "12"}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 84, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
@ -6,20 +6,15 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// DateFormat defines the available date formatting styles
|
||||
// DateFormat defines date formatting options
|
||||
type DateFormat string
|
||||
|
||||
const (
|
||||
// DateFormatISO represents ISO format (YYYY-MM-DD)
|
||||
DateFormatISO DateFormat = "iso"
|
||||
// DateFormatEU represents European format (DD.MM.YYYY)
|
||||
DateFormatEU DateFormat = "eu"
|
||||
// DateFormatUK represents UK format (DD/MM/YYYY)
|
||||
DateFormatUK DateFormat = "uk"
|
||||
// DateFormatUS represents US format (MM/DD/YYYY)
|
||||
DateFormatUS DateFormat = "us"
|
||||
// DateFormatLONG represents long format (Month DD, YYYY)
|
||||
DateFormatLONG DateFormat = "long"
|
||||
DateFormatISO DateFormat = "iso" // ISO format (YYYY-MM-DD)
|
||||
DateFormatEU DateFormat = "eu" // European format (DD.MM.YYYY)
|
||||
DateFormatUK DateFormat = "uk" // UK format (DD/MM/YYYY)
|
||||
DateFormatUS DateFormat = "us" // US format (MM/DD/YYYY)
|
||||
DateFormatLONG DateFormat = "long" // Long format (Month DD, YYYY)
|
||||
)
|
||||
|
||||
// dateFormatMapping maps DateFormat to Go time format strings
|
||||
@ -31,15 +26,13 @@ var dateFormatMapping = map[DateFormat]string{
|
||||
DateFormatLONG: "January 2, 2006",
|
||||
}
|
||||
|
||||
// DateLocale defines localization settings for the datepicker
|
||||
// DateLocale configures locale-specific settings
|
||||
type DateLocale struct {
|
||||
// MonthNames contains the localized names of months
|
||||
MonthNames []string
|
||||
// DayNames contains the localized abbreviated day names
|
||||
DayNames []string
|
||||
MonthNames []string // Localized month names
|
||||
DayNames []string // Localized day names
|
||||
}
|
||||
|
||||
// DateLocaleDefault provides English localization
|
||||
// DateLocaleDefault and other locale presets
|
||||
var DateLocaleDefault = DateLocale{
|
||||
MonthNames: []string{"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"},
|
||||
@ -75,13 +68,14 @@ var (
|
||||
"Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"},
|
||||
DayNames: []string{"Lu", "Ma", "Me", "Gi", "Ve", "Sa", "Do"},
|
||||
}
|
||||
)
|
||||
|
||||
// DatepickerConfig combines format and locale settings
|
||||
type DatepickerConfig struct {
|
||||
Format DateFormat
|
||||
Locale DateLocale
|
||||
}
|
||||
// DateLocaleJapanese provides Japanese localization
|
||||
DateLocaleJapanese = DateLocale{
|
||||
MonthNames: []string{"1月", "2月", "3月", "4月", "5月", "6月",
|
||||
"7月", "8月", "9月", "10月", "11月", "12月"},
|
||||
DayNames: []string{"日", "月", "火", "水", "木", "金", "土"},
|
||||
}
|
||||
)
|
||||
|
||||
// Pre-defined datepicker configurations
|
||||
var (
|
||||
@ -132,48 +126,31 @@ func (c DatepickerConfig) GetGoFormat() string {
|
||||
return dateFormatMapping[DateFormatISO] // Default to ISO
|
||||
}
|
||||
|
||||
// DatepickerProps defines all available props for the Datepicker component
|
||||
type DatepickerProps struct {
|
||||
// ID sets the input element's ID
|
||||
ID string
|
||||
// Name sets the input element's name
|
||||
Name string
|
||||
// Value sets the initial date
|
||||
Value time.Time
|
||||
// Config provides format and locale settings
|
||||
Config DatepickerConfig
|
||||
// Placeholder sets the input placeholder text
|
||||
Placeholder string
|
||||
// Disabled controls whether the datepicker can be interacted with
|
||||
Disabled bool
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
// Attributes allows additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
// DatepickerConfig combines format and locale settings
|
||||
type DatepickerConfig struct {
|
||||
Format DateFormat // Date format style
|
||||
Locale DateLocale // Localization settings
|
||||
}
|
||||
|
||||
// Calendar interface for selecting and formatting dates.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/datepicker
|
||||
//
|
||||
// Features:
|
||||
// - Multiple date formats (ISO, EU, US, UK, Long)
|
||||
// - Localization support for months and weekdays
|
||||
// - Popup calendar for date selection
|
||||
// - Keyboard navigation support
|
||||
// - Responsive positioning
|
||||
// - Custom styling support
|
||||
//
|
||||
// Props:
|
||||
// - ID: Input element identifier
|
||||
// - Name: Form field name
|
||||
// - Value: Initial date value
|
||||
// - Config: Format and locale settings
|
||||
// - Placeholder: Input placeholder text
|
||||
// - Disabled: Interactivity state
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
// DatepickerProps configures the Datepicker component
|
||||
type DatepickerProps struct {
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Value time.Time // Selected date
|
||||
Config DatepickerConfig // Format and locale config
|
||||
Placeholder string // Helper text shown when empty
|
||||
Required bool // Marks input as mandatory
|
||||
Disabled bool // Prevents interaction
|
||||
HasError bool // Error state styling
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Datepicker renders a date selection input with calendar popup
|
||||
templ Datepicker(props DatepickerProps) {
|
||||
if props.Placeholder == "" {
|
||||
{{ props.Placeholder = "Select a date" }}
|
||||
}
|
||||
<div
|
||||
class={ utils.TwMerge("relative", props.Class) }
|
||||
if props.Value != (time.Time{}) {
|
||||
@ -182,6 +159,7 @@ templ Datepicker(props DatepickerProps) {
|
||||
data-format={ string(props.Config.Format) }
|
||||
data-monthnames={ templ.JSONString(props.Config.Locale.MonthNames) }
|
||||
data-daynames={ templ.JSONString(props.Config.Locale.DayNames) }
|
||||
data-input-id={ props.ID }
|
||||
x-data="{
|
||||
open: false,
|
||||
value: null,
|
||||
@ -214,7 +192,7 @@ templ Datepicker(props DatepickerProps) {
|
||||
},
|
||||
|
||||
updatePosition() {
|
||||
const trigger = this.$refs.datePickerInput;
|
||||
const trigger = document.getElementById($el.dataset.inputId);
|
||||
const popup = this.$refs.datePickerPopup;
|
||||
const rect = trigger.getBoundingClientRect();
|
||||
const popupRect = popup.getBoundingClientRect();
|
||||
@ -259,15 +237,14 @@ templ Datepicker(props DatepickerProps) {
|
||||
switch(this.format) {
|
||||
case 'eu':
|
||||
return `${d}.${m}.${y}`;
|
||||
case 'uk':
|
||||
return `${d}/${m}/${y}`;
|
||||
case 'uk':
|
||||
return `${d}/${m}/${y}`;
|
||||
case 'us':
|
||||
return `${m}/${d}/${y}`;
|
||||
case 'long':
|
||||
// Use the months array from the provided locale
|
||||
return `${this.months[date.getMonth()]} ${d}, ${y}`;
|
||||
// case 'iso'
|
||||
default:
|
||||
default: // iso
|
||||
return `${y}-${m}-${d}`;
|
||||
}
|
||||
},
|
||||
@ -294,29 +271,41 @@ templ Datepicker(props DatepickerProps) {
|
||||
@resize.window="if (open) updatePosition()"
|
||||
>
|
||||
<div class="relative">
|
||||
<input
|
||||
x-ref="datePickerInput"
|
||||
type="text"
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
if props.Placeholder != "" {
|
||||
placeholder={ props.Placeholder }
|
||||
} else {
|
||||
placeholder="Select date"
|
||||
}
|
||||
disabled?={ props.Disabled }
|
||||
:value="value"
|
||||
x-modelable="value"
|
||||
@click="toggleDatePicker()"
|
||||
readonly
|
||||
class="peer flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
@Input(InputProps{
|
||||
ID: props.ID,
|
||||
Name: props.Name,
|
||||
Value: props.Value.Format(props.Config.GetGoFormat()),
|
||||
Placeholder: props.Placeholder,
|
||||
Disabled: props.Disabled,
|
||||
Class: utils.TwMerge(props.Class, "peer"),
|
||||
HasError: props.HasError,
|
||||
Type: "text",
|
||||
Readonly: true,
|
||||
Attributes: utils.MergeAttributes(
|
||||
templ.Attributes{
|
||||
"x-ref": "datePickerInput",
|
||||
"x-modelable": "value",
|
||||
":value": "value",
|
||||
"@click": "toggleDatePicker()",
|
||||
},
|
||||
props.Attributes,
|
||||
),
|
||||
})
|
||||
<button
|
||||
type="button"
|
||||
@click="toggleDatePicker()"
|
||||
disabled?={ props.Disabled }
|
||||
class="peer-disabled:pointer-events-none peer-disabled:opacity-50 absolute top-0 right-0 px-3 py-2 cursor-pointer text-muted-foreground hover:text-foreground"
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"absolute top-0 right-0 px-3 py-2",
|
||||
// Styling
|
||||
"cursor-pointer text-muted-foreground",
|
||||
// States
|
||||
"hover:text-foreground",
|
||||
"peer-disabled:pointer-events-none peer-disabled:opacity-50",
|
||||
),
|
||||
}
|
||||
>
|
||||
@icons.Calendar(icons.IconProps{})
|
||||
</button>
|
||||
@ -326,7 +315,16 @@ templ Datepicker(props DatepickerProps) {
|
||||
x-ref="datePickerPopup"
|
||||
@click.away="open = false"
|
||||
x-transition.opacity
|
||||
class="absolute left-0 z-50 mt-1 w-64 rounded-lg border bg-popover p-4 shadow-md"
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"absolute left-0 z-50 w-64 p-4",
|
||||
// Styling
|
||||
"rounded-lg border bg-popover shadow-md",
|
||||
// States
|
||||
"top-full mt-1",
|
||||
),
|
||||
}
|
||||
:class="{'top-full mt-1': position === 'bottom','bottom-full mb-1': position === 'top'}"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
|
@ -14,20 +14,15 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// DateFormat defines the available date formatting styles
|
||||
// DateFormat defines date formatting options
|
||||
type DateFormat string
|
||||
|
||||
const (
|
||||
// DateFormatISO represents ISO format (YYYY-MM-DD)
|
||||
DateFormatISO DateFormat = "iso"
|
||||
// DateFormatEU represents European format (DD.MM.YYYY)
|
||||
DateFormatEU DateFormat = "eu"
|
||||
// DateFormatUK represents UK format (DD/MM/YYYY)
|
||||
DateFormatUK DateFormat = "uk"
|
||||
// DateFormatUS represents US format (MM/DD/YYYY)
|
||||
DateFormatUS DateFormat = "us"
|
||||
// DateFormatLONG represents long format (Month DD, YYYY)
|
||||
DateFormatLONG DateFormat = "long"
|
||||
DateFormatISO DateFormat = "iso" // ISO format (YYYY-MM-DD)
|
||||
DateFormatEU DateFormat = "eu" // European format (DD.MM.YYYY)
|
||||
DateFormatUK DateFormat = "uk" // UK format (DD/MM/YYYY)
|
||||
DateFormatUS DateFormat = "us" // US format (MM/DD/YYYY)
|
||||
DateFormatLONG DateFormat = "long" // Long format (Month DD, YYYY)
|
||||
)
|
||||
|
||||
// dateFormatMapping maps DateFormat to Go time format strings
|
||||
@ -39,15 +34,13 @@ var dateFormatMapping = map[DateFormat]string{
|
||||
DateFormatLONG: "January 2, 2006",
|
||||
}
|
||||
|
||||
// DateLocale defines localization settings for the datepicker
|
||||
// DateLocale configures locale-specific settings
|
||||
type DateLocale struct {
|
||||
// MonthNames contains the localized names of months
|
||||
MonthNames []string
|
||||
// DayNames contains the localized abbreviated day names
|
||||
DayNames []string
|
||||
MonthNames []string // Localized month names
|
||||
DayNames []string // Localized day names
|
||||
}
|
||||
|
||||
// DateLocaleDefault provides English localization
|
||||
// DateLocaleDefault and other locale presets
|
||||
var DateLocaleDefault = DateLocale{
|
||||
MonthNames: []string{"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"},
|
||||
@ -83,13 +76,14 @@ var (
|
||||
"Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"},
|
||||
DayNames: []string{"Lu", "Ma", "Me", "Gi", "Ve", "Sa", "Do"},
|
||||
}
|
||||
)
|
||||
|
||||
// DatepickerConfig combines format and locale settings
|
||||
type DatepickerConfig struct {
|
||||
Format DateFormat
|
||||
Locale DateLocale
|
||||
}
|
||||
// DateLocaleJapanese provides Japanese localization
|
||||
DateLocaleJapanese = DateLocale{
|
||||
MonthNames: []string{"1月", "2月", "3月", "4月", "5月", "6月",
|
||||
"7月", "8月", "9月", "10月", "11月", "12月"},
|
||||
DayNames: []string{"日", "月", "火", "水", "木", "金", "土"},
|
||||
}
|
||||
)
|
||||
|
||||
// Pre-defined datepicker configurations
|
||||
var (
|
||||
@ -140,47 +134,27 @@ func (c DatepickerConfig) GetGoFormat() string {
|
||||
return dateFormatMapping[DateFormatISO] // Default to ISO
|
||||
}
|
||||
|
||||
// DatepickerProps defines all available props for the Datepicker component
|
||||
type DatepickerProps struct {
|
||||
// ID sets the input element's ID
|
||||
ID string
|
||||
// Name sets the input element's name
|
||||
Name string
|
||||
// Value sets the initial date
|
||||
Value time.Time
|
||||
// Config provides format and locale settings
|
||||
Config DatepickerConfig
|
||||
// Placeholder sets the input placeholder text
|
||||
Placeholder string
|
||||
// Disabled controls whether the datepicker can be interacted with
|
||||
Disabled bool
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
// Attributes allows additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
// DatepickerConfig combines format and locale settings
|
||||
type DatepickerConfig struct {
|
||||
Format DateFormat // Date format style
|
||||
Locale DateLocale // Localization settings
|
||||
}
|
||||
|
||||
// Calendar interface for selecting and formatting dates.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/datepicker
|
||||
//
|
||||
// Features:
|
||||
// - Multiple date formats (ISO, EU, US, UK, Long)
|
||||
// - Localization support for months and weekdays
|
||||
// - Popup calendar for date selection
|
||||
// - Keyboard navigation support
|
||||
// - Responsive positioning
|
||||
// - Custom styling support
|
||||
//
|
||||
// Props:
|
||||
// - ID: Input element identifier
|
||||
// - Name: Form field name
|
||||
// - Value: Initial date value
|
||||
// - Config: Format and locale settings
|
||||
// - Placeholder: Input placeholder text
|
||||
// - Disabled: Interactivity state
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
// DatepickerProps configures the Datepicker component
|
||||
type DatepickerProps struct {
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Value time.Time // Selected date
|
||||
Config DatepickerConfig // Format and locale config
|
||||
Placeholder string // Helper text shown when empty
|
||||
Required bool // Marks input as mandatory
|
||||
Disabled bool // Prevents interaction
|
||||
HasError bool // Error state styling
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Datepicker renders a date selection input with calendar popup
|
||||
func Datepicker(props DatepickerProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
@ -202,6 +176,9 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if props.Placeholder == "" {
|
||||
props.Placeholder = "Select a date"
|
||||
}
|
||||
var templ_7745c5c3_Var2 = []any{utils.TwMerge("relative", props.Class)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -232,7 +209,7 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value.Format(props.Config.GetGoFormat()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 180, Col: 62}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 157, Col: 62}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -250,7 +227,7 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(string(props.Config.Format))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 182, Col: 43}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 159, Col: 43}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -263,7 +240,7 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.JSONString(props.Config.Locale.MonthNames))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 183, Col: 68}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 160, Col: 68}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -276,81 +253,68 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.JSONString(props.Config.Locale.DayNames))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 184, Col: 64}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 161, Col: 64}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-data=\"{\n open: false,\n value: null,\n format: $el.dataset.format,\n currentMonth: 5,\n currentYear: new Date().getFullYear(),\n monthDays: [],\n blankDays: [],\n months: JSON.parse($el.dataset.monthnames) || ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n days: JSON.parse($el.dataset.daynames) || ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],\n\n position: 'bottom',\n\n init() {\n const initialDate = $el.dataset.value ? new Date(this.parseDate($el.dataset.value)) : new Date();\n this.currentMonth = initialDate.getMonth();\n this.currentYear = initialDate.getFullYear();\n this.calculateDays();\n // Format the initial value using the correct locale\n if ($el.dataset.value) {\n this.value = this.formatDate(initialDate);\n }\n },\n\n toggleDatePicker() {\n this.open = !this.open;\n if (this.open) {\n this.$nextTick(() => this.updatePosition());\n }\n },\n\n updatePosition() {\n const trigger = this.$refs.datePickerInput;\n const popup = this.$refs.datePickerPopup;\n const rect = trigger.getBoundingClientRect();\n const popupRect = popup.getBoundingClientRect();\n const viewportHeight = window.innerHeight || document.documentElement.clientHeight;\n \n if (rect.bottom + popupRect.height > viewportHeight && rect.top > popupRect.height) {\n this.position = 'top';\n } else {\n this.position = 'bottom';\n }\n },\n\n calculateDays() {\n const firstDay = new Date(this.currentYear, this.currentMonth, 1).getDay();\n const daysInMonth = new Date(this.currentYear, this.currentMonth + 1, 0).getDate();\n \n this.blankDays = Array.from({ length: firstDay }, (_, i) => i);\n this.monthDays = Array.from({ length: daysInMonth }, (_, i) => i + 1);\n },\n\n\t\t\tparseDate(dateStr) {\n\t\t\t\tconst parts = dateStr.split(/[-/.]/);\n\t\t\t\tswitch(this.format) {\n\t\t\t\t\tcase 'eu':\n\t\t\t\t\t\treturn `${parts[2]}-${parts[1]}-${parts[0]}`;\n\t\t\t\t\tcase 'us':\n\t\t\t\t\t\treturn `${parts[2]}-${parts[0]}-${parts[1]}`;\n\t\t\t\t\tcase 'uk':\n\t\t\t\t\t\treturn `${parts[2]}-${parts[1]}-${parts[0]}`;\n\t\t\t\t\tcase 'long':\n\t\t\t\t\tcase 'iso':\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn dateStr; // Für ISO und long Format das Datum unverändert lassen\n\t\t\t\t}\n\t\t\t}, \n\n\t\t\tformatDate(date) {\n const d = date.getDate().toString().padStart(2, '0');\n const m = (date.getMonth() + 1).toString().padStart(2, '0');\n const y = date.getFullYear();\n\n switch(this.format) {\n case 'eu':\n return `${d}.${m}.${y}`;\n\t\t\t\t\tcase 'uk':\n\t\t\t\t\t\treturn `${d}/${m}/${y}`;\n case 'us':\n return `${m}/${d}/${y}`;\n case 'long':\n // Use the months array from the provided locale\n return `${this.months[date.getMonth()]} ${d}, ${y}`;\n\t\t\t\t\t// case 'iso'\n default:\n return `${y}-${m}-${d}`;\n }\n },\n\n isToday(day) {\n const today = new Date();\n const date = new Date(this.currentYear, this.currentMonth, day);\n return date.toDateString() === today.toDateString();\n },\n\n isSelected(day) {\n if (!this.value) return false;\n const date = new Date(this.currentYear, this.currentMonth, day);\n const selected = new Date(this.parseDate(this.value));\n return date.toDateString() === selected.toDateString();\n },\n\n selectDate(day) {\n const date = new Date(this.currentYear, this.currentMonth, day);\n this.value = this.formatDate(date);\n this.open = false;\n }\n }\" @resize.window=\"if (open) updatePosition()\"><div class=\"relative\"><input x-ref=\"datePickerInput\" type=\"text\" id=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" data-input-id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 300, Col: 17}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 162, Col: 26}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-data=\"{\n open: false,\n value: null,\n format: $el.dataset.format,\n currentMonth: 5,\n currentYear: new Date().getFullYear(),\n monthDays: [],\n blankDays: [],\n months: JSON.parse($el.dataset.monthnames) || ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n days: JSON.parse($el.dataset.daynames) || ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],\n\n position: 'bottom',\n\n init() {\n const initialDate = $el.dataset.value ? new Date(this.parseDate($el.dataset.value)) : new Date();\n this.currentMonth = initialDate.getMonth();\n this.currentYear = initialDate.getFullYear();\n this.calculateDays();\n // Format the initial value using the correct locale\n if ($el.dataset.value) {\n this.value = this.formatDate(initialDate);\n }\n },\n\n toggleDatePicker() {\n this.open = !this.open;\n if (this.open) {\n this.$nextTick(() => this.updatePosition());\n }\n },\n\n updatePosition() {\n const trigger = document.getElementById($el.dataset.inputId);\n const popup = this.$refs.datePickerPopup;\n const rect = trigger.getBoundingClientRect();\n const popupRect = popup.getBoundingClientRect();\n const viewportHeight = window.innerHeight || document.documentElement.clientHeight;\n \n if (rect.bottom + popupRect.height > viewportHeight && rect.top > popupRect.height) {\n this.position = 'top';\n } else {\n this.position = 'bottom';\n }\n },\n\n calculateDays() {\n const firstDay = new Date(this.currentYear, this.currentMonth, 1).getDay();\n const daysInMonth = new Date(this.currentYear, this.currentMonth + 1, 0).getDate();\n \n this.blankDays = Array.from({ length: firstDay }, (_, i) => i);\n this.monthDays = Array.from({ length: daysInMonth }, (_, i) => i + 1);\n },\n\n\t\t\tparseDate(dateStr) {\n\t\t\t\tconst parts = dateStr.split(/[-/.]/);\n\t\t\t\tswitch(this.format) {\n\t\t\t\t\tcase 'eu':\n\t\t\t\t\t\treturn `${parts[2]}-${parts[1]}-${parts[0]}`;\n\t\t\t\t\tcase 'us':\n\t\t\t\t\t\treturn `${parts[2]}-${parts[0]}-${parts[1]}`;\n\t\t\t\t\tcase 'uk':\n\t\t\t\t\t\treturn `${parts[2]}-${parts[1]}-${parts[0]}`;\n\t\t\t\t\tcase 'long':\n\t\t\t\t\tcase 'iso':\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn dateStr; // Für ISO und long Format das Datum unverändert lassen\n\t\t\t\t}\n\t\t\t}, \n\n\t\t\tformatDate(date) {\n const d = date.getDate().toString().padStart(2, '0');\n const m = (date.getMonth() + 1).toString().padStart(2, '0');\n const y = date.getFullYear();\n\n switch(this.format) {\n case 'eu':\n return `${d}.${m}.${y}`;\n\t\t\t\t\t case 'uk':\n\t\t\t\t\t\t return `${d}/${m}/${y}`;\n case 'us':\n return `${m}/${d}/${y}`;\n case 'long':\n // Use the months array from the provided locale\n return `${this.months[date.getMonth()]} ${d}, ${y}`;\n default: // iso\n return `${y}-${m}-${d}`;\n }\n },\n\n isToday(day) {\n const today = new Date();\n const date = new Date(this.currentYear, this.currentMonth, day);\n return date.toDateString() === today.toDateString();\n },\n\n isSelected(day) {\n if (!this.value) return false;\n const date = new Date(this.currentYear, this.currentMonth, day);\n const selected = new Date(this.parseDate(this.value));\n return date.toDateString() === selected.toDateString();\n },\n\n selectDate(day) {\n const date = new Date(this.currentYear, this.currentMonth, day);\n this.value = this.formatDate(date);\n this.open = false;\n }\n }\" @resize.window=\"if (open) updatePosition()\"><div class=\"relative\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 301, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
templ_7745c5c3_Err = Input(InputProps{
|
||||
ID: props.ID,
|
||||
Name: props.Name,
|
||||
Value: props.Value.Format(props.Config.GetGoFormat()),
|
||||
Placeholder: props.Placeholder,
|
||||
Disabled: props.Disabled,
|
||||
Class: utils.TwMerge(props.Class, "peer"),
|
||||
HasError: props.HasError,
|
||||
Type: "text",
|
||||
Readonly: true,
|
||||
Attributes: utils.MergeAttributes(
|
||||
templ.Attributes{
|
||||
"x-ref": "datePickerInput",
|
||||
"x-modelable": "value",
|
||||
":value": "value",
|
||||
"@click": "toggleDatePicker()",
|
||||
},
|
||||
props.Attributes,
|
||||
),
|
||||
}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
var templ_7745c5c3_Var9 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"absolute top-0 right-0 px-3 py-2",
|
||||
// Styling
|
||||
"cursor-pointer text-muted-foreground",
|
||||
// States
|
||||
"hover:text-foreground",
|
||||
"peer-disabled:pointer-events-none peer-disabled:opacity-50",
|
||||
),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Placeholder != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" placeholder=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 303, Col: 36}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" placeholder=\"Select date\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.Disabled {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" :value=\"value\" x-modelable=\"value\" @click=\"toggleDatePicker()\" readonly class=\"peer flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, props.Attributes)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("> <button type=\"button\" @click=\"toggleDatePicker()\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<button type=\"button\" @click=\"toggleDatePicker()\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -360,7 +324,20 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" class=\"peer-disabled:pointer-events-none peer-disabled:opacity-50 absolute top-0 right-0 px-3 py-2 cursor-pointer text-muted-foreground hover:text-foreground\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var9).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -368,7 +345,38 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button></div><div x-show=\"open\" x-ref=\"datePickerPopup\" @click.away=\"open = false\" x-transition.opacity class=\"absolute left-0 z-50 mt-1 w-64 rounded-lg border bg-popover p-4 shadow-md\" :class=\"{'top-full mt-1': position === 'bottom','bottom-full mb-1': position === 'top'}\"><div class=\"flex items-center justify-between mb-4\"><span x-text=\"months[currentMonth] + ' ' + currentYear\" class=\"text-sm font-medium\"></span><div class=\"flex gap-1\"><button type=\"button\" @click=\"currentMonth--; if(currentMonth < 0) { currentMonth = 11; currentYear--; } calculateDays()\" class=\"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground h-7 w-7\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"absolute left-0 z-50 w-64 p-4",
|
||||
// Styling
|
||||
"rounded-lg border bg-popover shadow-md",
|
||||
// States
|
||||
"top-full mt-1",
|
||||
),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var11...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-show=\"open\" x-ref=\"datePickerPopup\" @click.away=\"open = false\" x-transition.opacity class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var11).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" :class=\"{'top-full mt-1': position === 'bottom','bottom-full mb-1': position === 'top'}\"><div class=\"flex items-center justify-between mb-4\"><span x-text=\"months[currentMonth] + ' ' + currentYear\" class=\"text-sm font-medium\"></span><div class=\"flex gap-1\"><button type=\"button\" @click=\"currentMonth--; if(currentMonth < 0) { currentMonth = 11; currentYear--; } calculateDays()\" class=\"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground h-7 w-7\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ templ renderMenuItem(item DropdownMenuItem, index int, depth int) {
|
||||
// - ARIA support
|
||||
templ DropdownMenu(props DropdownMenuProps) {
|
||||
<div
|
||||
x-data="{
|
||||
x-data="{
|
||||
open: false,
|
||||
position: $el.dataset.position,
|
||||
verticalPosition: 'bottom',
|
||||
@ -181,7 +181,7 @@ templ DropdownMenu(props DropdownMenuProps) {
|
||||
const rect = menu.getBoundingClientRect();
|
||||
const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
|
||||
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
|
||||
|
||||
|
||||
if (this.position === 'left' && rect.left < 0) {
|
||||
this.position = 'right';
|
||||
} else if (this.position !== 'left' && rect.right > viewportWidth) {
|
||||
|
@ -441,7 +441,7 @@ func DropdownMenu(props DropdownMenuProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-data=\"{ \n\t\t\topen: false,\n\t\t\tposition: $el.dataset.position,\n\t\t\tverticalPosition: 'bottom',\n\t\t\tupdatePosition() {\n\t\t\t\tconst menu = this.$refs.menu;\n\t\t\t\tconst rect = menu.getBoundingClientRect();\n\t\t\t\tconst viewportWidth = window.innerWidth || document.documentElement.clientWidth;\n\t\t\t\tconst viewportHeight = window.innerHeight || document.documentElement.clientHeight;\n\t\t\t\t\n\t\t\t\tif (this.position === 'left' && rect.left < 0) {\n\t\t\t\t\tthis.position = 'right';\n\t\t\t\t} else if (this.position !== 'left' && rect.right > viewportWidth) {\n\t\t\t\t\tthis.position = 'left';\n\t\t\t\t}\n\n\t\t\t\tif (this.verticalPosition === 'bottom' && rect.bottom > viewportHeight) {\n\t\t\t\t\tthis.verticalPosition = 'top';\n\t\t\t\t} else if (this.verticalPosition === 'top' && rect.top < 0) {\n\t\t\t\t\tthis.verticalPosition = 'bottom';\n\t\t\t\t}\n\t\t\t}\n\t\t}\" @resize.window=\"if (open) updatePosition()\" class=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-data=\"{\n\t\t\topen: false,\n\t\t\tposition: $el.dataset.position,\n\t\t\tverticalPosition: 'bottom',\n\t\t\tupdatePosition() {\n\t\t\t\tconst menu = this.$refs.menu;\n\t\t\t\tconst rect = menu.getBoundingClientRect();\n\t\t\t\tconst viewportWidth = window.innerWidth || document.documentElement.clientWidth;\n\t\t\t\tconst viewportHeight = window.innerHeight || document.documentElement.clientHeight;\n\n\t\t\t\tif (this.position === 'left' && rect.left < 0) {\n\t\t\t\t\tthis.position = 'right';\n\t\t\t\t} else if (this.position !== 'left' && rect.right > viewportWidth) {\n\t\t\t\t\tthis.position = 'left';\n\t\t\t\t}\n\n\t\t\t\tif (this.verticalPosition === 'bottom' && rect.bottom > viewportHeight) {\n\t\t\t\t\tthis.verticalPosition = 'top';\n\t\t\t\t} else if (this.verticalPosition === 'top' && rect.top < 0) {\n\t\t\t\t\tthis.verticalPosition = 'bottom';\n\t\t\t\t}\n\t\t\t}\n\t\t}\" @resize.window=\"if (open) updatePosition()\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
75
pkg/components/form.templ
Normal file
75
pkg/components/form.templ
Normal file
@ -0,0 +1,75 @@
|
||||
package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// FormItemProps represents a form container's properties
|
||||
type FormItemProps struct {
|
||||
ID string // Optional container ID
|
||||
Class string // Custom classes
|
||||
}
|
||||
|
||||
// FormItem wraps form elements in a vertical layout
|
||||
templ FormItem(props FormItemProps) {
|
||||
<div class={ utils.TwMerge("space-y-2", props.Class) }>
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
// FormItemFlex wraps form elements in a horizontal layout
|
||||
templ FormItemFlex(props FormItemProps) {
|
||||
<div class={ utils.TwMerge("items-center flex space-x-2", props.Class) }>
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
// FormLabelProps represents label properties
|
||||
type FormLabelProps struct {
|
||||
For string // Target form element ID
|
||||
Text string // Label text
|
||||
Class string // Custom classes
|
||||
DisabledClass string // Classes applied when input is disabled
|
||||
}
|
||||
|
||||
// FormLabel renders a form label
|
||||
templ FormLabel(props FormLabelProps) {
|
||||
@Label(LabelProps{
|
||||
For: props.For,
|
||||
Class: props.Class,
|
||||
Text: props.Text,
|
||||
DisabledClass: props.DisabledClass,
|
||||
})
|
||||
}
|
||||
|
||||
// FormDescriptionProps represents helper text properties
|
||||
type FormDescriptionProps struct {
|
||||
Class string // Custom classes
|
||||
}
|
||||
|
||||
// FormDescription renders helper text below form elements
|
||||
templ FormDescription(props FormDescriptionProps) {
|
||||
<p class={ utils.TwMerge("text-sm text-muted-foreground", props.Class) }>
|
||||
{ children... }
|
||||
</p>
|
||||
}
|
||||
|
||||
// FormMessageProps represents feedback message properties
|
||||
type FormMessageProps struct {
|
||||
Type string // error, success, warning, info
|
||||
Message string // Message text
|
||||
Class string // Custom classes
|
||||
}
|
||||
|
||||
// FormMessage renders feedback messages
|
||||
templ FormMessage(props FormMessageProps) {
|
||||
<p
|
||||
class={
|
||||
utils.TwMerge(
|
||||
"text-sm font-medium",
|
||||
props.Class,
|
||||
),
|
||||
templ.KV("text-destructive", props.Type == "error"),
|
||||
}
|
||||
>
|
||||
{ props.Message }
|
||||
</p>
|
||||
}
|
309
pkg/components/form_templ.go
Normal file
309
pkg/components/form_templ.go
Normal file
@ -0,0 +1,309 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// FormItemProps represents a form container's properties
|
||||
type FormItemProps struct {
|
||||
ID string // Optional container ID
|
||||
Class string // Custom classes
|
||||
}
|
||||
|
||||
// FormItem wraps form elements in a vertical layout
|
||||
func FormItem(props FormItemProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{utils.TwMerge("space-y-2", props.Class)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/form.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
// FormItemFlex wraps form elements in a horizontal layout
|
||||
func FormItemFlex(props FormItemProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var5 = []any{utils.TwMerge("items-center flex space-x-2", props.Class)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var5).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/form.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var4.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
// FormLabelProps represents label properties
|
||||
type FormLabelProps struct {
|
||||
For string // Target form element ID
|
||||
Text string // Label text
|
||||
Class string // Custom classes
|
||||
DisabledClass string // Classes applied when input is disabled
|
||||
}
|
||||
|
||||
// FormLabel renders a form label
|
||||
func FormLabel(props FormLabelProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var7 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var7 == nil {
|
||||
templ_7745c5c3_Var7 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = Label(LabelProps{
|
||||
For: props.For,
|
||||
Class: props.Class,
|
||||
Text: props.Text,
|
||||
DisabledClass: props.DisabledClass,
|
||||
}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
// FormDescriptionProps represents helper text properties
|
||||
type FormDescriptionProps struct {
|
||||
Class string // Custom classes
|
||||
}
|
||||
|
||||
// FormDescription renders helper text below form elements
|
||||
func FormDescription(props FormDescriptionProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var8 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var8 == nil {
|
||||
templ_7745c5c3_Var8 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var9 = []any{utils.TwMerge("text-sm text-muted-foreground", props.Class)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var9).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/form.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var8.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
// FormMessageProps represents feedback message properties
|
||||
type FormMessageProps struct {
|
||||
Type string // error, success, warning, info
|
||||
Message string // Message text
|
||||
Class string // Custom classes
|
||||
}
|
||||
|
||||
// FormMessage renders feedback messages
|
||||
func FormMessage(props FormMessageProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var11 == nil {
|
||||
templ_7745c5c3_Var11 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var12 = []any{
|
||||
utils.TwMerge(
|
||||
"text-sm font-medium",
|
||||
props.Class,
|
||||
),
|
||||
templ.KV("text-destructive", props.Type == "error"),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/form.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(props.Message)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/form.templ`, Line: 73, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -2,11 +2,10 @@ package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// InputType defines the available input field types
|
||||
// InputType defines the type of input field
|
||||
type InputType string
|
||||
|
||||
const (
|
||||
// Standard text inputs
|
||||
InputTypeText InputType = "text"
|
||||
InputTypePassword InputType = "password"
|
||||
InputTypeEmail InputType = "email"
|
||||
@ -14,108 +13,63 @@ const (
|
||||
InputTypeTel InputType = "tel"
|
||||
InputTypeURL InputType = "url"
|
||||
InputTypeSearch InputType = "search"
|
||||
|
||||
// Date and time inputs
|
||||
InputTypeDate InputType = "date"
|
||||
InputTypeTime InputType = "time"
|
||||
|
||||
// File upload input
|
||||
InputTypeFile InputType = "file"
|
||||
InputTypeDate InputType = "date"
|
||||
InputTypeTime InputType = "time"
|
||||
InputTypeFile InputType = "file"
|
||||
)
|
||||
|
||||
// InputProps configures the Input component
|
||||
type InputProps struct {
|
||||
// Type sets the input field behavior
|
||||
Type InputType
|
||||
|
||||
// Placeholder shows helper text when empty
|
||||
Placeholder string
|
||||
|
||||
// Value sets the current input content
|
||||
Value string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// ID uniquely identifies the input
|
||||
ID string
|
||||
|
||||
// Label displays text above input
|
||||
Label string
|
||||
|
||||
// Disabled sets the input to disabled state
|
||||
Disabled bool
|
||||
|
||||
// Description shows helper text below input
|
||||
Description string
|
||||
|
||||
// Error displays validation message
|
||||
Error string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// FileAccept limits allowed file types
|
||||
// Only used when Type is InputTypeFile
|
||||
FileAccept string
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
Type InputType // Input field type
|
||||
Placeholder string // Helper text shown when empty
|
||||
Value string // Current input value
|
||||
Name string // Form field name
|
||||
ID string // DOM identifier
|
||||
Disabled bool // Prevents interaction
|
||||
Readonly bool // Allows selection only
|
||||
Class string // Additional CSS classes
|
||||
FileAccept string // Allowed file types
|
||||
HasError bool // Error state styling
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Text field that allows users to enter and edit values.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/input
|
||||
//
|
||||
// Props:
|
||||
// - Type: Input field behavior type
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Value: Current input value
|
||||
// - Name: Form field name
|
||||
// - ID: Unique identifier
|
||||
// - Label: Text label
|
||||
// - Description: Helper text
|
||||
// - Error: Validation message
|
||||
// - Class: Additional CSS classes
|
||||
// - FileAccept: Allowed file types
|
||||
// - Attributes: Additional HTML attributes
|
||||
// Input renders a styled form input field
|
||||
templ Input(props InputProps) {
|
||||
<span class="space-y-2">
|
||||
if props.Label != "" {
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
templ.KV("text-destructive", len(props.Error)>0) }
|
||||
>
|
||||
{ props.Label }
|
||||
</label>
|
||||
<input
|
||||
x-ref={ props.ID }
|
||||
type={ string(props.Type) }
|
||||
placeholder={ props.Placeholder }
|
||||
disabled?={ props.Disabled }
|
||||
readonly?={ props.Readonly }
|
||||
name={ props.Name }
|
||||
if props.Value != "" {
|
||||
value={ props.Value }
|
||||
}
|
||||
<input
|
||||
type={ string(props.Type) }
|
||||
placeholder={ props.Placeholder }
|
||||
disabled?={ props.Disabled }
|
||||
name={ props.Name }
|
||||
if props.Value != "" {
|
||||
value={ props.Value }
|
||||
}
|
||||
id={ props.ID }
|
||||
class={
|
||||
utils.TwMerge("flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
||||
"file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"file:text-foreground dark:file:text-foreground",
|
||||
props.Class),
|
||||
}
|
||||
if props.Type == InputTypeFile {
|
||||
accept={ props.FileAccept }
|
||||
}
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
if props.Description != "" {
|
||||
<p class="text-sm text-muted-foreground m-0">{ props.Description }</p>
|
||||
id={ props.ID }
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"peer flex h-10 w-full px-3 py-2",
|
||||
|
||||
// Styling
|
||||
"rounded-md border border-input bg-background text-sm ring-offset-background",
|
||||
"file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground ",
|
||||
"placeholder:text-muted-foreground",
|
||||
|
||||
// States
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
// Conditional
|
||||
utils.TwIf("border-destructive ring-destructive", props.HasError),
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
if props.Error != "" {
|
||||
<p class="text-sm font-medium text-destructive">{ props.Error }</p>
|
||||
if props.Type == InputTypeFile {
|
||||
accept={ props.FileAccept }
|
||||
}
|
||||
</span>
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
}
|
||||
|
@ -10,11 +10,10 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// InputType defines the available input field types
|
||||
// InputType defines the type of input field
|
||||
type InputType string
|
||||
|
||||
const (
|
||||
// Standard text inputs
|
||||
InputTypeText InputType = "text"
|
||||
InputTypePassword InputType = "password"
|
||||
InputTypeEmail InputType = "email"
|
||||
@ -22,70 +21,27 @@ const (
|
||||
InputTypeTel InputType = "tel"
|
||||
InputTypeURL InputType = "url"
|
||||
InputTypeSearch InputType = "search"
|
||||
|
||||
// Date and time inputs
|
||||
InputTypeDate InputType = "date"
|
||||
InputTypeTime InputType = "time"
|
||||
|
||||
// File upload input
|
||||
InputTypeFile InputType = "file"
|
||||
InputTypeDate InputType = "date"
|
||||
InputTypeTime InputType = "time"
|
||||
InputTypeFile InputType = "file"
|
||||
)
|
||||
|
||||
// InputProps configures the Input component
|
||||
type InputProps struct {
|
||||
// Type sets the input field behavior
|
||||
Type InputType
|
||||
|
||||
// Placeholder shows helper text when empty
|
||||
Placeholder string
|
||||
|
||||
// Value sets the current input content
|
||||
Value string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// ID uniquely identifies the input
|
||||
ID string
|
||||
|
||||
// Label displays text above input
|
||||
Label string
|
||||
|
||||
// Disabled sets the input to disabled state
|
||||
Disabled bool
|
||||
|
||||
// Description shows helper text below input
|
||||
Description string
|
||||
|
||||
// Error displays validation message
|
||||
Error string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// FileAccept limits allowed file types
|
||||
// Only used when Type is InputTypeFile
|
||||
FileAccept string
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
Type InputType // Input field type
|
||||
Placeholder string // Helper text shown when empty
|
||||
Value string // Current input value
|
||||
Name string // Form field name
|
||||
ID string // DOM identifier
|
||||
Disabled bool // Prevents interaction
|
||||
Readonly bool // Allows selection only
|
||||
Class string // Additional CSS classes
|
||||
FileAccept string // Allowed file types
|
||||
HasError bool // Error state styling
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Text field that allows users to enter and edit values.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/input
|
||||
//
|
||||
// Props:
|
||||
// - Type: Input field behavior type
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Value: Current input value
|
||||
// - Name: Form field name
|
||||
// - ID: Unique identifier
|
||||
// - Label: Text label
|
||||
// - Description: Helper text
|
||||
// - Error: Validation message
|
||||
// - Class: Additional CSS classes
|
||||
// - FileAccept: Allowed file types
|
||||
// - Attributes: Additional HTML attributes
|
||||
// Input renders a styled form input field
|
||||
func Input(props InputProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
@ -107,83 +63,54 @@ func Input(props InputProps) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"space-y-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != "" {
|
||||
var templ_7745c5c3_Var2 = []any{"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
templ.KV("text-destructive", len(props.Error) > 0)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 85, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 89, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
var templ_7745c5c3_Var6 = []any{
|
||||
utils.TwMerge("flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
||||
"file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground",
|
||||
var templ_7745c5c3_Var2 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"peer flex h-10 w-full px-3 py-2",
|
||||
|
||||
// Styling
|
||||
"rounded-md border border-input bg-background text-sm ring-offset-background",
|
||||
"file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground ",
|
||||
"placeholder:text-muted-foreground",
|
||||
|
||||
// States
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"file:text-foreground dark:file:text-foreground",
|
||||
props.Class),
|
||||
|
||||
// Conditional
|
||||
utils.TwIf("border-destructive ring-destructive", props.HasError),
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<input type=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<input x-ref=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(string(props.Type))
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 93, Col: 28}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 39, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" type=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(string(props.Type))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 40, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -191,12 +118,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 94, Col: 34}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 41, Col: 33}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -210,16 +137,22 @@ func Input(props InputProps) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.Readonly {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" readonly")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 96, Col: 20}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 44, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -232,12 +165,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 98, Col: 23}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 46, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -250,12 +183,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 100, Col: 16}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 48, Col: 15}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -263,12 +196,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -281,12 +214,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(props.FileAccept)
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.FileAccept)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 110, Col: 29}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 71, Col: 28}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -299,49 +232,7 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Description != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm text-muted-foreground m-0\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(props.Description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 115, Col: 67}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.Error != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm font-medium text-destructive\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(props.Error)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 118, Col: 64}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
37
pkg/components/label.templ
Normal file
37
pkg/components/label.templ
Normal file
@ -0,0 +1,37 @@
|
||||
package components
|
||||
|
||||
// LabelProps represents label properties
|
||||
type LabelProps struct {
|
||||
ID string // Optional label ID
|
||||
For string // Target input ID
|
||||
Text string // Label text
|
||||
Error string // Error message
|
||||
Class string // Custom classes
|
||||
DisabledClass string // Classes applied when input is disabled
|
||||
}
|
||||
|
||||
// Label renders a form label with error and disabled states
|
||||
templ Label(props LabelProps) {
|
||||
<label
|
||||
id={ props.ID }
|
||||
for={ props.For }
|
||||
class={
|
||||
// Styling
|
||||
"text-sm font-medium leading-none",
|
||||
|
||||
// Utility
|
||||
templ.KV("text-destructive", len(props.Error) > 0),
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
}
|
||||
if props.DisabledClass != "" {
|
||||
data-disabled-style={ props.DisabledClass }
|
||||
} else {
|
||||
data-disabled-style="opacity-50 cursor-not-allowed"
|
||||
}
|
||||
x-bind:class="{ [$el.dataset.disabledStyle]: $refs[$el.getAttribute('for')]?.disabled }"
|
||||
>
|
||||
{ props.Text }
|
||||
</label>
|
||||
}
|
145
pkg/components/label_templ.go
Normal file
145
pkg/components/label_templ.go
Normal file
@ -0,0 +1,145 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
// LabelProps represents label properties
|
||||
type LabelProps struct {
|
||||
ID string // Optional label ID
|
||||
For string // Target input ID
|
||||
Text string // Label text
|
||||
Error string // Error message
|
||||
Class string // Custom classes
|
||||
DisabledClass string // Classes applied when input is disabled
|
||||
}
|
||||
|
||||
// Label renders a form label with error and disabled states
|
||||
func Label(props LabelProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{
|
||||
// Styling
|
||||
"text-sm font-medium leading-none",
|
||||
|
||||
// Utility
|
||||
templ.KV("text-destructive", len(props.Error) > 0),
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/label.templ`, Line: 16, Col: 15}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.For)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/label.templ`, Line: 17, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/label.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.DisabledClass != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" data-disabled-style=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.DisabledClass)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/label.templ`, Line: 29, Col: 44}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" data-disabled-style=\"opacity-50 cursor-not-allowed\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" x-bind:class=\"{ [$el.dataset.disabledStyle]: $refs[$el.getAttribute('for')]?.disabled }\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Text)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/label.templ`, Line: 35, Col: 14}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
51
pkg/components/radio.templ
Normal file
51
pkg/components/radio.templ
Normal file
@ -0,0 +1,51 @@
|
||||
package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// RadioProps configures the Radio component
|
||||
type RadioProps struct {
|
||||
Value string // Radio button value
|
||||
Name string // Form field name
|
||||
ID string // DOM identifier
|
||||
Disabled bool // Prevents interaction
|
||||
Checked bool // Selected state
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Radio renders a styled radio input button
|
||||
templ Radio(props RadioProps) {
|
||||
<input
|
||||
x-ref={ props.ID }
|
||||
type="radio"
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
value={ props.Value }
|
||||
checked?={ props.Checked }
|
||||
disabled?={ props.Disabled }
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"relative h-4 w-4",
|
||||
"before:absolute before:left-1/2 before:top-1/2",
|
||||
"before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2",
|
||||
|
||||
// Styling
|
||||
"appearance-none rounded-full",
|
||||
"border border-2 border-primary",
|
||||
"before:content[''] before:rounded-full before:bg-background",
|
||||
|
||||
// States
|
||||
"checked:border-primary checked:bg-primary",
|
||||
"checked:before:visible",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
"focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
||||
"disabled:cursor-not-allowed",
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
type RadioGroupProps struct {
|
||||
// Name groups related radio buttons
|
||||
Name string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
type RadioGroupItemProps struct {
|
||||
// Value sets the radio button value
|
||||
Value string
|
||||
|
||||
// Name matches parent RadioGroup name
|
||||
Name string
|
||||
|
||||
// ID uniquely identifies the radio button
|
||||
ID string
|
||||
|
||||
// Label displays text next to radio button
|
||||
Label templ.Component
|
||||
|
||||
// Disabled sets the radio button to disabled
|
||||
Disabled bool
|
||||
|
||||
// Checked sets the radio button to checked
|
||||
Checked bool
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// RadioGroup renders a set of mutually exclusive radio button options.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/radio-group
|
||||
//
|
||||
// Props:
|
||||
// - Name: Groups related radio buttons
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ RadioGroup(props RadioGroupProps) {
|
||||
<div
|
||||
role="radiogroup"
|
||||
class={ utils.TwMerge("space-y-2", props.Class) }
|
||||
{ props.Attributes... }
|
||||
>
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
// Control for selecting a single option from a list of choices.
|
||||
// Must be used within a RadioGroup component.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/radio-group
|
||||
//
|
||||
// Props:
|
||||
// - Value: Radio button value
|
||||
// - Name: Matches parent group name
|
||||
// - ID: Unique identifier
|
||||
// - Label: Button label
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ RadioGroupItem(props RadioGroupItemProps) {
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ utils.TwMerge(
|
||||
"flex items-center gap-2 cursor-pointer text-sm font-medium",
|
||||
"text-muted-foreground [&:has(input:checked)]:text-foreground",
|
||||
"[&:has(input:disabled)]:cursor-not-allowed [&:has(input:disabled)]:opacity-50",
|
||||
props.Class,
|
||||
) }
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
value={ props.Value }
|
||||
checked?={ props.Checked }
|
||||
disabled?={ props.Disabled }
|
||||
class="before:content[''] relative h-4 w-4 appearance-none rounded-full
|
||||
border border-2 border-primary
|
||||
checked:border-primary checked:bg-primary
|
||||
before:absolute before:left-1/2 before:top-1/2
|
||||
before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2
|
||||
before:rounded-full before:bg-background
|
||||
checked:before:visible
|
||||
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring
|
||||
focus-visible:ring-offset-2 focus-visible:ring-offset-background
|
||||
disabled:cursor-not-allowed"
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
if props.Label != nil {
|
||||
@props.Label
|
||||
} else {
|
||||
<span>{ props.Value }</span>
|
||||
}
|
||||
</label>
|
||||
}
|
@ -1,288 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
type RadioGroupProps struct {
|
||||
// Name groups related radio buttons
|
||||
Name string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
type RadioGroupItemProps struct {
|
||||
// Value sets the radio button value
|
||||
Value string
|
||||
|
||||
// Name matches parent RadioGroup name
|
||||
Name string
|
||||
|
||||
// ID uniquely identifies the radio button
|
||||
ID string
|
||||
|
||||
// Label displays text next to radio button
|
||||
Label templ.Component
|
||||
|
||||
// Disabled sets the radio button to disabled
|
||||
Disabled bool
|
||||
|
||||
// Checked sets the radio button to checked
|
||||
Checked bool
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// RadioGroup renders a set of mutually exclusive radio button options.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/radio-group
|
||||
//
|
||||
// Props:
|
||||
// - Name: Groups related radio buttons
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
func RadioGroup(props RadioGroupProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{utils.TwMerge("space-y-2", props.Class)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div role=\"radiogroup\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, props.Attributes)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
// Control for selecting a single option from a list of choices.
|
||||
// Must be used within a RadioGroup component.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/radio-group
|
||||
//
|
||||
// Props:
|
||||
// - Value: Radio button value
|
||||
// - Name: Matches parent group name
|
||||
// - ID: Unique identifier
|
||||
// - Label: Button label
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
func RadioGroupItem(props RadioGroupItemProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var5 = []any{utils.TwMerge(
|
||||
"flex items-center gap-2 cursor-pointer text-sm font-medium",
|
||||
"text-muted-foreground [&:has(input:checked)]:text-foreground",
|
||||
"[&:has(input:disabled)]:cursor-not-allowed [&:has(input:disabled)]:opacity-50",
|
||||
props.Class,
|
||||
)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 73, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var5).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><input type=\"radio\" id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 83, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 84, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 85, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Checked {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" checked")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.Disabled {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" class=\"before:content[''] relative h-4 w-4 appearance-none rounded-full \n border border-2 border-primary \n checked:border-primary checked:bg-primary\n before:absolute before:left-1/2 before:top-1/2 \n before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2 \n before:rounded-full before:bg-background\n checked:before:visible\n focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring \n focus-visible:ring-offset-2 focus-visible:ring-offset-background\n disabled:cursor-not-allowed\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, props.Attributes)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != nil {
|
||||
templ_7745c5c3_Err = props.Label.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 103, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
170
pkg/components/radio_templ.go
Normal file
170
pkg/components/radio_templ.go
Normal file
@ -0,0 +1,170 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// RadioProps configures the Radio component
|
||||
type RadioProps struct {
|
||||
Value string // Radio button value
|
||||
Name string // Form field name
|
||||
ID string // DOM identifier
|
||||
Disabled bool // Prevents interaction
|
||||
Checked bool // Selected state
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Radio renders a styled radio input button
|
||||
func Radio(props RadioProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"relative h-4 w-4",
|
||||
"before:absolute before:left-1/2 before:top-1/2",
|
||||
"before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2",
|
||||
|
||||
// Styling
|
||||
"appearance-none rounded-full",
|
||||
"border border-2 border-primary",
|
||||
"before:content[''] before:rounded-full before:bg-background",
|
||||
|
||||
// States
|
||||
"checked:border-primary checked:bg-primary",
|
||||
"checked:before:visible",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
"focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
||||
"disabled:cursor-not-allowed",
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<input x-ref=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio.templ`, Line: 19, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" type=\"radio\" id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio.templ`, Line: 21, Col: 15}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio.templ`, Line: 22, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio.templ`, Line: 23, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Checked {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" checked")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.Disabled {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, props.Attributes)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -5,66 +5,52 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// SelectProps configures the Select component
|
||||
type SelectProps struct {
|
||||
// ID uniquely identifies the select input
|
||||
ID string
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
// Placeholder shows text when no option selected
|
||||
Placeholder string
|
||||
// Options defines available choices
|
||||
Options []SelectOption
|
||||
// Disabled sets the checkbox to disabled state
|
||||
Disabled bool
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Placeholder string // Helper text shown when empty
|
||||
Options []SelectOption // Available choices
|
||||
Disabled bool // Prevents interaction
|
||||
HasError bool // Error state styling
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// SelectOption configures a single select option
|
||||
type SelectOption struct {
|
||||
// Label displays text in dropdown
|
||||
Label string
|
||||
// Value sets the option's form value
|
||||
Value string
|
||||
// Selected sets the option as default
|
||||
Selected bool
|
||||
// Attributes for disabled state or other HTML attributes
|
||||
Attributes templ.Attributes
|
||||
Label string // Display text
|
||||
Value string // Form value
|
||||
Selected bool // Default selection
|
||||
Attributes templ.Attributes // Extra HTML attributes
|
||||
}
|
||||
|
||||
// Dropdown control for choosing from predefined options
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/select
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - Placeholder: Default text
|
||||
// - Options: Available choices
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
//
|
||||
// Features:
|
||||
// - Keyboard navigation
|
||||
// - Disabled state support
|
||||
// - Alpine.js integration
|
||||
// - Custom styling via Tailwind
|
||||
// Select renders a styled dropdown selection input
|
||||
templ Select(props SelectProps) {
|
||||
<div
|
||||
class={ utils.TwMerge(
|
||||
"relative w-full", // Make it full width by default
|
||||
props.Class, // Allow custom classes to override
|
||||
) }
|
||||
>
|
||||
<div class={ utils.TwMerge("relative w-full", props.Class) }>
|
||||
<select
|
||||
x-ref={ props.ID }
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
disabled?={ props.Disabled }
|
||||
class="peer h-10 w-full appearance-none rounded-md border border-input bg-background px-3 py-2 text-sm
|
||||
ring-offset-background placeholder:text-muted-foreground
|
||||
focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
|
||||
disabled:cursor-not-allowed disabled:opacity-50"
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"peer h-10 w-full px-3 py-2",
|
||||
|
||||
// Styling
|
||||
"rounded-md border border-input bg-background text-sm",
|
||||
"appearance-none ring-offset-background",
|
||||
"placeholder:text-muted-foreground",
|
||||
|
||||
// States
|
||||
"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
// Conditional
|
||||
utils.TwIf("border-destructive ring-destructive", props.HasError),
|
||||
),
|
||||
}
|
||||
{ props.Attributes... }
|
||||
>
|
||||
if props.Placeholder != "" {
|
||||
@ -80,8 +66,24 @@ templ Select(props SelectProps) {
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
<div class="absolute right-3 top-3 pointer-events-none peer-disabled:opacity-50">
|
||||
@icons.ChevronDown(icons.IconProps{Size: "16", Class: "text-muted-foreground"})
|
||||
<div
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"absolute right-3 top-3",
|
||||
|
||||
// Styling
|
||||
"pointer-events-none",
|
||||
|
||||
// States
|
||||
"peer-disabled:opacity-50",
|
||||
),
|
||||
}
|
||||
>
|
||||
@icons.ChevronDown(icons.IconProps{
|
||||
Size: "16",
|
||||
Class: "text-muted-foreground",
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -13,51 +13,27 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// SelectProps configures the Select component
|
||||
type SelectProps struct {
|
||||
// ID uniquely identifies the select input
|
||||
ID string
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
// Placeholder shows text when no option selected
|
||||
Placeholder string
|
||||
// Options defines available choices
|
||||
Options []SelectOption
|
||||
// Disabled sets the checkbox to disabled state
|
||||
Disabled bool
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Placeholder string // Helper text shown when empty
|
||||
Options []SelectOption // Available choices
|
||||
Disabled bool // Prevents interaction
|
||||
HasError bool // Error state styling
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// SelectOption configures a single select option
|
||||
type SelectOption struct {
|
||||
// Label displays text in dropdown
|
||||
Label string
|
||||
// Value sets the option's form value
|
||||
Value string
|
||||
// Selected sets the option as default
|
||||
Selected bool
|
||||
// Attributes for disabled state or other HTML attributes
|
||||
Attributes templ.Attributes
|
||||
Label string // Display text
|
||||
Value string // Form value
|
||||
Selected bool // Default selection
|
||||
Attributes templ.Attributes // Extra HTML attributes
|
||||
}
|
||||
|
||||
// Dropdown control for choosing from predefined options
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/select
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - Placeholder: Default text
|
||||
// - Options: Available choices
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
//
|
||||
// Features:
|
||||
// - Keyboard navigation
|
||||
// - Disabled state support
|
||||
// - Alpine.js integration
|
||||
// - Custom styling via Tailwind
|
||||
// Select renders a styled dropdown selection input
|
||||
func Select(props SelectProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
@ -79,10 +55,7 @@ func Select(props SelectProps) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
|
||||
"relative w-full", // Make it full width by default
|
||||
props.Class, // Allow custom classes to override
|
||||
)}
|
||||
var templ_7745c5c3_Var2 = []any{utils.TwMerge("relative w-full", props.Class)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
@ -100,16 +73,55 @@ func Select(props SelectProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><select id=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 61, Col: 16}
|
||||
var templ_7745c5c3_Var4 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"peer h-10 w-full px-3 py-2",
|
||||
|
||||
// Styling
|
||||
"rounded-md border border-input bg-background text-sm",
|
||||
"appearance-none ring-offset-background",
|
||||
"placeholder:text-muted-foreground",
|
||||
|
||||
// States
|
||||
"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
// Conditional
|
||||
utils.TwIf("border-destructive ring-destructive", props.HasError),
|
||||
),
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<select x-ref=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 32, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 33, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -117,12 +129,12 @@ func Select(props SelectProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 62, Col: 20}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 34, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -136,7 +148,20 @@ func Select(props SelectProps) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" class=\"peer h-10 w-full appearance-none rounded-md border border-input bg-background px-3 py-2 text-sm\n ring-offset-background placeholder:text-muted-foreground\n focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\n disabled:cursor-not-allowed disabled:opacity-50\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -153,12 +178,12 @@ func Select(props SelectProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 71, Col: 65}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 57, Col: 65}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -172,12 +197,12 @@ func Select(props SelectProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(option.Value)
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(option.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 75, Col: 25}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 61, Col: 25}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -199,12 +224,12 @@ func Select(props SelectProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(option.Label)
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(option.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 79, Col: 19}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 65, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -213,11 +238,47 @@ func Select(props SelectProps) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select><div class=\"absolute right-3 top-3 pointer-events-none peer-disabled:opacity-50\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = icons.ChevronDown(icons.IconProps{Size: "16", Class: "text-muted-foreground"}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
var templ_7745c5c3_Var12 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"absolute right-3 top-3",
|
||||
|
||||
// Styling
|
||||
"pointer-events-none",
|
||||
|
||||
// States
|
||||
"peer-disabled:opacity-50",
|
||||
),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = icons.ChevronDown(icons.IconProps{
|
||||
Size: "16",
|
||||
Class: "text-muted-foreground",
|
||||
}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -5,102 +5,58 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TextareaProps configures the Textarea component
|
||||
type TextareaProps struct {
|
||||
// ID uniquely identifies the textarea
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Value sets initial content
|
||||
Value string
|
||||
|
||||
// Placeholder shows when empty
|
||||
Placeholder string
|
||||
|
||||
// Label displays text above textarea
|
||||
Label string
|
||||
|
||||
// Description shows helper text below
|
||||
Description string
|
||||
|
||||
// Error displays validation message
|
||||
Error string
|
||||
|
||||
// Rows sets visible text lines height
|
||||
Rows int
|
||||
|
||||
// Disabled prevents user input
|
||||
Disabled bool
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// AutoResize enables dynamic height adjustment
|
||||
AutoResize bool
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Value string // Initial content
|
||||
Placeholder string // Helper text shown when empty
|
||||
Rows int // Visible lines of text
|
||||
Disabled bool // Prevents interaction
|
||||
Class string // Additional CSS classes
|
||||
AutoResize bool // Enables dynamic resizing
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Multi-line text field for longer form content.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/textarea
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - Value: Initial content
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Label: Text label
|
||||
// - Description: Helper text
|
||||
// - Error: Validation message
|
||||
// - Rows: Initial height in lines
|
||||
// - Class: Additional CSS classes
|
||||
// - AutoResize: Enable dynamic sizing
|
||||
// - Attributes: Additional HTML attributes
|
||||
// Textarea renders a multi-line text input field
|
||||
templ Textarea(props TextareaProps) {
|
||||
<div class="space-y-2">
|
||||
if props.Label != "" {
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
templ.KV("text-destructive", len(props.Error) > 0) }
|
||||
>
|
||||
{ props.Label }
|
||||
</label>
|
||||
<textarea
|
||||
x-ref={ props.ID }
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
placeholder={ props.Placeholder }
|
||||
disabled?={ props.Disabled }
|
||||
if props.Rows != 0 {
|
||||
rows={ strconv.Itoa(props.Rows) }
|
||||
}
|
||||
<textarea
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
placeholder={ props.Placeholder }
|
||||
disabled?={ props.Disabled }
|
||||
if props.Rows != 0 {
|
||||
rows={ strconv.Itoa(props.Rows) }
|
||||
}
|
||||
class={ utils.TwMerge(
|
||||
"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
||||
"min-h-[80px] placeholder:text-muted-foreground",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
props.Class,
|
||||
) }
|
||||
if props.AutoResize {
|
||||
x-data="{ resize() { $el.style.height = '80px'; $el.style.height = $el.scrollHeight + 'px' } }"
|
||||
x-init="resize()"
|
||||
@input="resize()"
|
||||
}
|
||||
{ props.Attributes... }
|
||||
>
|
||||
if props.Value != "" {
|
||||
{ props.Value }
|
||||
}
|
||||
</textarea>
|
||||
if props.Description != "" {
|
||||
<p class="text-sm text-muted-foreground">{ props.Description }</p>
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"flex w-full px-3 py-2",
|
||||
"min-h-[80px]",
|
||||
|
||||
// Styling
|
||||
"rounded-md border border-input bg-background text-sm",
|
||||
"ring-offset-background",
|
||||
"placeholder:text-muted-foreground",
|
||||
|
||||
// States
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
if props.Error != "" {
|
||||
<p class="text-sm font-medium text-destructive">{ props.Error }</p>
|
||||
if props.AutoResize {
|
||||
x-data="{ resize() { $el.style.height = '80px'; $el.style.height = $el.scrollHeight + 'px' } }"
|
||||
x-init="resize()"
|
||||
@input="resize()"
|
||||
}
|
||||
</div>
|
||||
{ props.Attributes... }
|
||||
>
|
||||
if props.Value != "" {
|
||||
{ props.Value }
|
||||
}
|
||||
</textarea>
|
||||
}
|
||||
|
@ -13,60 +13,20 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// TextareaProps configures the Textarea component
|
||||
type TextareaProps struct {
|
||||
// ID uniquely identifies the textarea
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Value sets initial content
|
||||
Value string
|
||||
|
||||
// Placeholder shows when empty
|
||||
Placeholder string
|
||||
|
||||
// Label displays text above textarea
|
||||
Label string
|
||||
|
||||
// Description shows helper text below
|
||||
Description string
|
||||
|
||||
// Error displays validation message
|
||||
Error string
|
||||
|
||||
// Rows sets visible text lines height
|
||||
Rows int
|
||||
|
||||
// Disabled prevents user input
|
||||
Disabled bool
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// AutoResize enables dynamic height adjustment
|
||||
AutoResize bool
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Value string // Initial content
|
||||
Placeholder string // Helper text shown when empty
|
||||
Rows int // Visible lines of text
|
||||
Disabled bool // Prevents interaction
|
||||
Class string // Additional CSS classes
|
||||
AutoResize bool // Enables dynamic resizing
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Multi-line text field for longer form content.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/textarea
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - Value: Initial content
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Label: Text label
|
||||
// - Description: Helper text
|
||||
// - Error: Validation message
|
||||
// - Rows: Initial height in lines
|
||||
// - Class: Additional CSS classes
|
||||
// - AutoResize: Enable dynamic sizing
|
||||
// - Attributes: Additional HTML attributes
|
||||
// Textarea renders a multi-line text input field
|
||||
func Textarea(props TextareaProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
@ -88,82 +48,52 @@ func Textarea(props TextareaProps) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"space-y-2\">")
|
||||
var templ_7745c5c3_Var2 = []any{
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"flex w-full px-3 py-2",
|
||||
"min-h-[80px]",
|
||||
|
||||
// Styling
|
||||
"rounded-md border border-input bg-background text-sm",
|
||||
"ring-offset-background",
|
||||
"placeholder:text-muted-foreground",
|
||||
|
||||
// States
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != "" {
|
||||
var templ_7745c5c3_Var2 = []any{"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
templ.KV("text-destructive", len(props.Error) > 0)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 66, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 70, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
|
||||
"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
||||
"min-h-[80px] placeholder:text-muted-foreground",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
props.Class,
|
||||
)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<textarea x-ref=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<textarea id=\"")
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 24, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 74, Col: 16}
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 25, Col: 15}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -171,12 +101,12 @@ func Textarea(props TextareaProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 75, Col: 20}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 26, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -184,12 +114,12 @@ func Textarea(props TextareaProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 76, Col: 34}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 27, Col: 33}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -208,12 +138,12 @@ func Textarea(props TextareaProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(props.Rows))
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(props.Rows))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 79, Col: 35}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 30, Col: 34}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -226,12 +156,12 @@ func Textarea(props TextareaProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -254,59 +184,17 @@ func Textarea(props TextareaProps) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Value != "" {
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 96, Col: 17}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 59, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</textarea> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Description != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm text-muted-foreground\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(props.Description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 100, Col: 63}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.Error != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm font-medium text-destructive\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(props.Error)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 103, Col: 64}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</textarea>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -1,73 +1,60 @@
|
||||
package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// ToggleProps configures the Toggle component
|
||||
type ToggleProps struct {
|
||||
// ID uniquely identifies the toggle
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// LabelLeft displays text before toggle
|
||||
LabelLeft string
|
||||
|
||||
// LabelRight displays text after toggle
|
||||
LabelRight string
|
||||
|
||||
// Disabled sets the toggle to disabled state
|
||||
Disabled bool
|
||||
|
||||
// Checked sets the toggle to checked state
|
||||
Checked bool
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
ID string // DOM identifier
|
||||
Name string // Form field name
|
||||
Disabled bool // Prevents interaction
|
||||
Checked bool // Toggled state
|
||||
Class string // Additional CSS classes
|
||||
Attributes templ.Attributes // Extra HTML/Alpine attributes
|
||||
}
|
||||
|
||||
// Two-state button that can be switched on or off.
|
||||
//
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/toggle
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - LabelLeft: Text before toggle
|
||||
// - LabelRight: Text after toggle
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
//
|
||||
// Features:
|
||||
// - Animated switching
|
||||
// - Keyboard navigation
|
||||
// - Label placement options
|
||||
// - ARIA support
|
||||
// Toggle renders a styled switch input
|
||||
templ Toggle(props ToggleProps) {
|
||||
if props.ID == "" {
|
||||
{{ props.ID = utils.RandomID() }}
|
||||
}
|
||||
<label for={ props.ID } class="inline-flex cursor-pointer items-center gap-2">
|
||||
<input
|
||||
x-ref={ props.ID }
|
||||
checked?={ props.Checked }
|
||||
disabled?={ props.Disabled }
|
||||
id={ props.ID }
|
||||
type="checkbox"
|
||||
name={ props.Name }
|
||||
class="peer sr-only"
|
||||
class="peer hidden"
|
||||
role="switch"
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
if props.LabelLeft != "" {
|
||||
<span class="text-sm select-none text-muted-foreground peer-checked:text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50">
|
||||
{ props.LabelLeft }
|
||||
</span>
|
||||
}
|
||||
<div
|
||||
class="relative h-6 w-10 rounded-full bg-neutral-200 after:h-5 after:w-5 peer-checked:after:translate-x-[16px] after:absolute after:left-0.5 after:top-0.5 after:rounded-full after:bg-muted-foreground after:transition-all after:content-[''] peer-checked:bg-primary peer-checked:after:bg-secondary peer-disabled:opacity-50 peer-disabled:cursor-not-allowed"
|
||||
class={
|
||||
utils.TwMerge(
|
||||
// Layout
|
||||
"relative h-6 w-10",
|
||||
"after:absolute after:left-0.5 after:top-0.5",
|
||||
"after:h-5 after:w-5",
|
||||
|
||||
// Styling
|
||||
"rounded-full bg-neutral-200",
|
||||
"after:rounded-full after:bg-muted-foreground",
|
||||
"after:content-['']",
|
||||
|
||||
// States
|
||||
"after:transition-all",
|
||||
"peer-checked:bg-primary",
|
||||
"peer-checked:after:translate-x-[16px]",
|
||||
"peer-checked:after:bg-secondary",
|
||||
"peer-disabled:opacity-50",
|
||||
"peer-disabled:cursor-not-allowed",
|
||||
|
||||
// Custom
|
||||
props.Class,
|
||||
),
|
||||
}
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
if props.LabelRight != "" {
|
||||
<span class="text-sm select-none text-muted-foreground peer-checked:text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50">
|
||||
{ props.LabelRight }
|
||||
</span>
|
||||
}
|
||||
</label>
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user