From c89f52678046d49646a7b62d1fa3ab517421f716 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sun, 10 May 2026 10:04:39 +0200 Subject: [PATCH] docs: add spacing primitives design spec --- ...10-go-backend-spacing-primitives-design.md | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-10-go-backend-spacing-primitives-design.md diff --git a/docs/superpowers/specs/2026-05-10-go-backend-spacing-primitives-design.md b/docs/superpowers/specs/2026-05-10-go-backend-spacing-primitives-design.md new file mode 100644 index 0000000..c3f122a --- /dev/null +++ b/docs/superpowers/specs/2026-05-10-go-backend-spacing-primitives-design.md @@ -0,0 +1,178 @@ +# Go Backend Spacing Primitives Design + +**Date:** 2026-05-10 + +**Goal** + +Add fixed-size spacing primitives to the Go backend UI library so templates can insert consistent horizontal and vertical gaps between other components without relying on ad hoc inline markup. + +**Chosen Approach** + +Introduce two small presentational primitives: + +- `SpaceX` for horizontal spacing +- `SpaceY` for vertical spacing + +Both primitives will use the same named spacing scale: + +- `xs` +- `sm` +- `md` +- `lg` +- `xl` + +This keeps call sites explicit, matches the primitive-oriented structure of the Go UI library, and avoids introducing a child-owning layout abstraction such as `Stack` for this slice. + +**Scope** + +- Add shared spacing step tokens for UI primitives. +- Add `SpaceX` and `SpaceY` templ components. +- Add stylesheet classes for all supported spacing steps. +- Add catalog examples and a dedicated catalog page for spacing. +- Add direct UI tests and catalog coverage tests. + +**Out Of Scope** + +- Flexible or grow-to-fill spacers +- Stack or layout wrapper primitives +- Responsive spacing props +- Margin utility generation +- Replacing existing manual spacing usage across the app + +**API** + +Add: + +- `type SpacingStep string` + +Supported values: + +- `SpacingStepXS` +- `SpacingStepSM` +- `SpacingStepMD` +- `SpacingStepLG` +- `SpacingStepXL` + +Add a shared prop shape: + +- `type SpaceProps struct { Size SpacingStep }` + +Add two primitives: + +- `SpaceX(SpaceProps)` +- `SpaceY(SpaceProps)` + +Default behavior: + +- missing or unknown `Size` normalizes to `SpacingStepMD` + +**Rendering Contract** + +`SpaceX`: + +- renders a presentational `span` +- includes `aria-hidden="true"` +- applies a fixed-width class such as `ui-space-x-md` +- uses `display: inline-block` +- uses `flex-shrink: 0` + +`SpaceY`: + +- renders a presentational `div` +- includes `aria-hidden="true"` +- applies a fixed-height class such as `ui-space-y-md` + +These primitives are empty elements. They do not accept children and do not carry semantic meaning. + +**CSS Contract** + +Add classes for each step: + +- `.ui-space-x-xs` through `.ui-space-x-xl` +- `.ui-space-y-xs` through `.ui-space-y-xl` + +Class responsibilities: + +- horizontal classes set width only +- vertical classes set height only + +Base element behavior should come from the rendered element plus a small shared class contract, not from inline styles. + +Recommended scale for this slice: + +- `xs`: `0.25rem` +- `sm`: `0.5rem` +- `md`: `0.75rem` +- `lg`: `1rem` +- `xl`: `1.5rem` + +This is intentionally small and practical for the current design system. If the library later adopts a broader token system, these values can be remapped behind the same API. + +**Normalization And Helpers** + +Follow the existing UI pattern of centralizing normalization logic: + +- add a `normalizedSpacingStep` helper +- add `spaceXClass` and `spaceYClass` helpers + +This keeps templ files simple and makes invalid values deterministic. + +**Catalog** + +Add a `spacing` catalog page with examples for: + +- horizontal spacing between two buttons using `SpaceX` +- vertical spacing between stacked content blocks using `SpaceY` + +The examples should render the real primitives rather than static HTML snippets. + +**Testing** + +Add UI tests that verify: + +- `SpaceX` defaults to `md` +- `SpaceY` defaults to `md` +- explicit step selection renders the expected class +- spacers render `aria-hidden="true"` + +Add stylesheet coverage checks for: + +- `.ui-space-x-md` +- `.ui-space-y-md` + +Add catalog tests that verify: + +- the `spacing` page exists +- the first spacing example renders real spacer markup + +**Implementation Notes** + +Files expected for this slice: + +- `go-backend/internal/web/ui/space.templ` +- `go-backend/internal/web/ui/space_templ.go` +- updates to `go-backend/internal/web/ui/variants.go` or a nearby helper file for spacing normalization +- updates to `go-backend/internal/web/ui/catalog/examples.go` +- updates to `go-backend/internal/web/ui/catalog/pages.go` +- updates to `go-backend/internal/web/ui/ui_test.go` +- updates to `go-backend/internal/web/ui/catalog/catalog_test.go` +- updates to `go-backend/static/styles.css` + +No application call sites need to change as part of this slice. The deliverable is the primitive itself plus documentation and tests. + +**Open Decisions Resolved** + +- API shape: separate `SpaceX` and `SpaceY` +- sizing model: named spacing steps +- behavior: fixed width and fixed height only +- fallback behavior: default invalid or empty size to `md` + +**Success Criteria** + +This work is complete when: + +- the UI library exposes `SpaceX` and `SpaceY` +- both components render stable classes from the shared spacing scale +- the spacing catalog page documents horizontal and vertical usage +- tests cover primitive markup and catalog registration +- the existing Go backend web UI tests remain green