docs: add spacing primitives design spec

This commit is contained in:
Arthur Belleville 2026-05-10 10:04:39 +02:00
parent cf64404d25
commit c89f526780
No known key found for this signature in database

View file

@ -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