xtablo-source/backend/internal/web/ui/variants.go
Arthur Belleville 1ff8e681da feat(01-02): add ui package enums, helpers, base CSS
- tokens.go: semantic token constants
- variants.go: Size/ButtonVariant/ButtonTone/BadgeVariant enums + Normalized*
- helpers.go: mergeAttrs for templ.Attributes
- base.css: resets, :focus-visible ring (no nesting)
2026-05-14 18:45:15 +02:00

105 lines
3.1 KiB
Go

package ui
// Size is the canonical component size enum. Phase 1 only renders SizeMD via
// CSS, but every component normalizes Size so future phases can drop in
// `.ui-button-...-sm` / `.ui-button-...-lg` rules without changing call sites.
type Size string
const (
SizeSM Size = "sm"
SizeMD Size = "md"
SizeLG Size = "lg"
)
// ButtonVariant is the semantic-color enum for Button.
type ButtonVariant string
const (
ButtonVariantDefault ButtonVariant = "default"
ButtonVariantNeutral ButtonVariant = "neutral"
ButtonVariantWarning ButtonVariant = "warning"
ButtonVariantSuccess ButtonVariant = "success"
ButtonVariantDanger ButtonVariant = "danger"
)
// ButtonTone is the visual-weight enum for Button (solid vs. soft).
type ButtonTone string
const (
ButtonToneSolid ButtonTone = "solid"
ButtonToneSoft ButtonTone = "soft"
)
// BadgeVariant is the semantic-color enum for Badge.
type BadgeVariant string
const (
BadgeVariantInfo BadgeVariant = "info"
BadgeVariantWarning BadgeVariant = "warning"
BadgeVariantSuccess BadgeVariant = "success"
BadgeVariantDanger BadgeVariant = "danger"
)
// NormalizedSize returns the safe default (SizeMD) for the zero value and any
// value not in the declared set.
func NormalizedSize(size Size) Size {
switch size {
case SizeSM, SizeLG:
return size
default:
return SizeMD
}
}
// NormalizedButtonVariant returns the safe default (ButtonVariantDefault) for
// the zero value and any value not in the declared set.
func NormalizedButtonVariant(variant ButtonVariant) ButtonVariant {
switch variant {
case ButtonVariantNeutral, ButtonVariantWarning, ButtonVariantSuccess, ButtonVariantDanger:
return variant
default:
return ButtonVariantDefault
}
}
// NormalizedButtonTone returns the safe default (ButtonToneSolid) for the zero
// value and any value not in the declared set.
func NormalizedButtonTone(tone ButtonTone) ButtonTone {
switch tone {
case ButtonToneSoft:
return tone
default:
return ButtonToneSolid
}
}
// NormalizedBadgeVariant returns the safe default (BadgeVariantInfo) for the
// zero value and any value not in the declared set.
func NormalizedBadgeVariant(variant BadgeVariant) BadgeVariant {
switch variant {
case BadgeVariantWarning, BadgeVariantSuccess, BadgeVariantDanger:
return variant
default:
return BadgeVariantInfo
}
}
// ButtonClass assembles the deterministic class string for a Button. Inputs
// are normalized before assembly so callers can pass zero values safely.
//
// Example: ButtonClass(ButtonVariantDefault, ButtonToneSolid, SizeMD) ==
// "ui-button ui-button-solid-default-md".
func ButtonClass(variant ButtonVariant, tone ButtonTone, size Size) string {
v := NormalizedButtonVariant(variant)
t := NormalizedButtonTone(tone)
s := NormalizedSize(size)
return "ui-button ui-button-" + string(t) + "-" + string(v) + "-" + string(s)
}
// BadgeClass assembles the deterministic class string for a Badge.
//
// Example: BadgeClass(BadgeVariantInfo) == "ui-badge ui-badge-info".
func BadgeClass(variant BadgeVariant) string {
v := NormalizedBadgeVariant(variant)
return "ui-badge ui-badge-" + string(v)
}