xtablo-source/backend/internal/web/ui/select_helpers.go
Arthur Belleville 52fb77d4f8
feat(13-03): port select + form-field components with CSS and helpers (GREEN)
- select_helpers.go: 9 helper functions verbatim from go-backend
- select.templ: SelectProps/SelectOption structs, inline JS with __uiSelectInitAll
  and htmx:afterSwap re-init listener (Pitfall 6)
- select.css: .ui-select-control (min-height 44px), .ui-select-menu (max-height 16rem)
- form_field.templ: FormFieldProps with Label/For/Field/Error/Hint; conditional regions
- form-field.css: .ui-form-field/.ui-form-label/.ui-form-hint/.ui-form-error
- tailwind.input.css: add @import for select.css and form-field.css
- All 6 TestSelect/TestFormField tests passing; full go test ./... is green
2026-05-16 14:00:51 +02:00

104 lines
1.8 KiB
Go

package ui
import (
"strings"
"github.com/a-h/templ"
)
func selectPlaceholder(props SelectProps) string {
if props.Placeholder != "" {
return props.Placeholder
}
if props.Multiple {
return "Select values"
}
return "Select an option"
}
func selectNativeID(id string, name string) string {
baseID := inputID(id, name)
if baseID == "" {
return "ui-select-native"
}
return baseID + "-native"
}
func selectMenuID(id string, name string) string {
baseID := inputID(id, name)
if baseID == "" {
return "ui-select-menu"
}
return baseID + "-menu"
}
func selectBoolData(value bool) string {
if value {
return "true"
}
return "false"
}
func selectSelectedValues(props SelectProps) []string {
if props.Multiple {
return props.Values
}
if props.Value == "" {
return nil
}
return []string{props.Value}
}
func selectOptionSelected(props SelectProps, value string) bool {
for _, selected := range selectSelectedValues(props) {
if selected == value {
return true
}
}
return false
}
func selectSelectedLabels(props SelectProps) []string {
var labels []string
for _, option := range props.Options {
if selectOptionSelected(props, option.Value) {
labels = append(labels, option.Label)
}
}
return labels
}
func selectSelectedLabel(props SelectProps) string {
return strings.Join(selectSelectedLabels(props), ", ")
}
func selectMenuOptionClass(selected bool, disabled bool) string {
className := "ui-select-option"
if selected {
className += " is-selected"
}
if disabled {
className += " is-disabled"
}
return className
}
func selectIsDisabled(attrs templ.Attributes) bool {
if attrs == nil {
return false
}
value, ok := attrs["disabled"]
if !ok {
return false
}
switch typed := value.(type) {
case bool:
return typed
case string:
return typed != "" && typed != "false"
default:
return true
}
}