jixoai-ui
the terminal design language
loading the style sheet…
Skip to content
docs · print medium: screen

registry:ui · Layout · alpha

prototype-flex — the standardized flex row

The layout family, alpha track: the design studio's property panel edits these exact props. Every value is a native CSS token passed through 1:1 (no vocabulary mapping layer), styling is inline-style only — zero Tailwind, zero theme tokens, zero dependencies — so the item renders in any host. Single root + rest spread: the stamp mechanism's family precondition, proven here first.

install — prototype-flex

$npx jixoai-ui add prototype-flex

https://ui.jixoai.com/r/prototype-flex.json

alpha track inline style only single root + rest spread zero translation zero dependencies

overview

Overview

Three laws define the alpha lane: single root + rest spread, zero translation, inline style only — and the eight axes forward without opinion.

SINGLE ROOT + REST SPREAD — the whole component is one div; the consumer's attributes spread first and the family's stamps land after (replace, never merge): data-jx-prototype-flex, data-density and the dark class. This is the stamp mechanism's family precondition, proven here first — a studio edit or a consumer testid lands on the same node the layout styles.

ZERO TRANSLATION — direction, wrap, align and justify ARE the CSS Box Alignment tokens, passed through verbatim (measured live in the rig below: every control's change lands in the container's computed style byte-identical). There is no "between" → "space-between" mapping layer to learn or fight; the one type coercion is gap number → px (a bare number is not a CSS length). INLINE STYLE ONLY — no Tailwind, no theme tokens, no css file: the alpha lane's reason to exist apart from utility-first Tier-1 is that it installs and renders in any host. The dispatch expectation that gap might ride the space tokens is deliberately FALSE here — the family law is zero tokens.

The eight axes are FORWARDERS, not opinions — the first-time contract declares all no-own, and the family paints nothing for them: the carriers join the consumer style attr (measured), density stamps its rung for descendants that read the kernel channels, theme rides the .dark bridge, and size echoes on the root so em-inheriting children reflow. One accessibility truth to hold: direction="row-reverse" and "column-reverse" flip the VISUAL order against the DOM order — screen readers follow the DOM, so reserve the reversed rungs for genuinely reversed contexts.

The layout trio, cross-referenced: prototype-flex — the row prototype-grid — the tracks prototype-waterfall — the columns — one contract, three engines.

prototype-flex · the rig

The property panel, live: every control below binds a real prop 1:1 — measured end-to-end in task 35, each change lands in the container's computed style (flex-direction / flex-wrap / align-items / justify-content / gap). The controls live in the stage body by design: the canvas mounts its playground snippet lazily (the collapsible dock), so anything that must stay driveable belongs beside the specimen, not in the snippet.

alphabetagamma
  • direction
  • wrap
  • align
  • justify
  • gap (px)
prototype-flex-usage.svelte svelte
<PrototypeFlex
  direction="row"
  wrap="nowrap"
  align="stretch"
  justify="space-between"
  gap={12}
>
  <span>alpha</span><span>beta</span><span>gamma</span>
</PrototypeFlex>

law

The alpha contract

Three laws make the primitive studio-editable and host-agnostic — they are also why this family deliberately has no tokens.

1 · SINGLE ROOT + REST SPREAD — one div, consumer attributes first, family stamps after; the studio's edits and the layout's stamps can never fight over separate nodes. 2 · ZERO TRANSLATION — the props are the CSS: no alias vocabulary, no mapping layer to drift; the property panel edits CSS truth. 3 · INLINE STYLE ONLY — no utility classes and no theme tokens, so the item renders identically in any host and the gap value you pass is the gap that renders (there are no space tokens to inherit or collide with).

types

Types — the justify ladder, rendered

The control inventory rendered: all six justify-content union members on identical rows (three fixed-width chips, 1px frames, gap 12). align and wrap ride the rig above.

prototype-flex · justify ladder

start
a b c
center
a b c
end
a b c
space-between
a b c
space-around
a b c
space-evenly
a b c
prototype-flex-usage.svelte svelte
<PrototypeFlex gap={12} align="center">
  <span>first</span>
  <span>second</span>
  <span>third</span>
</PrototypeFlex>

<!-- every prop is a native CSS token, passed through 1:1 -->
<PrototypeFlex direction="column" justify="space-between" wrap="wrap" gap="0.75rem" />

usage

Usage

One element, five optional props — omitted props inject no declaration; the CSS initial value serves.

PrototypeFlex usage
<PrototypeFlex gap={12} align="center">
  <span>first</span>
  <span>second</span>
  <span>third</span>
</PrototypeFlex>

<!-- every prop is a native CSS token, passed through 1:1 -->
<PrototypeFlex direction="column" justify="space-between" wrap="wrap" gap="0.75rem" />

api

API

Props map to CSS 1:1 — the one type coercion: gap number → px. Everything else rides through as native div attributes.

Properties

PropertyTypeDefaultDescription
direction 'row' | 'row-reverse' | 'column' | 'column-reverse'—flex-direction, verbatim. Omitted → no declaration (the CSS initial: row).
wrap 'nowrap' | 'wrap' | 'wrap-reverse'—flex-wrap, verbatim.
align 'start' | 'center' | 'end' | 'stretch' | 'baseline'—align-items, verbatim (logical-axis Box Alignment spellings).
justify 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly'—justify-content, verbatim.
gap number | string—gap: number → px, string verbatim (the one type coercion).
class string—Passed through verbatim — the component owns no class of its own.
...rest HTMLAttributes<HTMLDivElement>spreadEvery other attribute lands on the single root (stamped data-jx-prototype-flex after the spread — replace, never merge).

Universal props

PropertyTypeDefaultDescription
size'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopethe base scale — root font-size; parts size in em
shape'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto''auto' · ambient scopecorner geometry (CSS corner-shape; §14 degrade table)
radius'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopecorner size; auto = the concentric broadcast (§3)
density'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopespacing/leading scale over the kernel channels (§4)
color'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string'auto' · ambient scopethe hue axis of the fixed oklch primary system (§5)
theme'light' | 'dark' | 'system' | 'auto''auto' · ambient scopelight/dark profile; system = the JS-mutable global (§6)
elevation'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number'auto' · ambient scopeofficial M3 levels over the surface ladder (§7)
motion'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number'auto' · ambient scopeintensity across the motion kernels (§8)

axes

The eight axes on prototype-flex

The zero-translation posture extends to paint: the first-time contract is ALL NO-OWN, and the family paints nothing for any axis — carriers join the consumer style attr, density stamps its rung for descendants, theme rides the .dark bridge, size echoes on the root. Every row below is a forwarder, measured by stamp receipts rather than paint (there is no family paint to measure).

PropertyTypeDefaultDescription
density '2xs' | 'xs' | 'sm' | 'default' | 'lg' | 'auto' | number (+ the five legacy spellings)'auto'FORWARDER — the resolved rung stamps data-density on the flex root (measured data-density=lg with an explicit lane; null ambient), opening the kernel channels for DESCENDANTS that read them; the flex layout itself consumes none. Number unit: coefficient.
size 'small' | 'medium' | 'large' | 'auto' | number'auto'FORWARDER, ECHO MEASURED — the §11 stamp lands inline on the root as font-size: var(--jx-size-effective, 1rem) (the carrier chain, measured in the style attr), so em-inheriting children reflow around it; the flex geometry (direction/wrap/gap) is untouched. Number unit: px.
shape 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto''auto'FORWARDER — the carrier joins the style attr; zero family readers (the alpha lane paints nothing). Number unit: none.
radius 'small' | 'medium' | 'large' | 'auto' | number'auto'FORWARDER — carrier stamp only; zero family readers. Number unit: px.
color 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string'auto'FORWARDER — carrier stamp only; children re-tint through the ambient chain if they read it. Zero family readers. Number unit: hue degrees.
theme 'light' | 'dark' | 'system' | 'auto''auto'FORWARDER — dark rides the .dark class bridge on the flex root (class:dark measured with theme="dark"), re-scoping the token chains for the subtree; the layout itself is theme-blind. No number lane.
elevation 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number'auto'FORWARDER — carrier stamp only; zero family readers. Number unit: dp.
motion 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number'auto'FORWARDER — carrier stamp only; the layout has no transitions of its own (grep receipt: zero transition declarations in the family). Number unit: coefficient.

Receipts: the rig's five controls each measured end-to-end (select/number change → computed flex-direction / flex-wrap / align-items / justify-content / gap update on the container, task 35); the density rung stamp (data-density=lg explicit, null ambient), the size echo (font-size 18px inline at size=18) and the dark class bridge were measured on this page's served DOM; the zero-reader rows carry grep receipts over ui/prototype-flex/ (an inline-style-only family — no css file, no tokens). The query() seat below rides the md viewport key (48rem) through the gap number→px coercion.

one real query() case
<script lang="ts">
  import PrototypeFlex from '@ui/prototype-flex.svelte';
  import { query } from '@lib/universal-props-query.svelte';
</script>

<!-- below 48rem the base (13px root) applies; at 48rem+ the md case
     (18px) wins — the §11 stamp scales the root, children reflow -->
<PrototypeFlex size={query({ md: 18 }, 13)} gap={12}>…</PrototypeFlex>

prototype-flex · query()

13px → 18px at 48rem size

Media keys are min-width: below 48rem the base (13px root) applies; at 48rem and wider the md case wins (18px) — the §11 stamp scales the root and em-inheriting children reflow. The number lane goes bare. Note the boundary this exposes: the AXES accept query() (they are lanes), the LAYOUT props (gap, direction…) do not — they are native CSS passthroughs, number | string only. Resize across 48rem.

prototype-flex-query-demo.svelte svelte
<script lang="ts">
  import PrototypeFlex from '@ui/prototype-flex.svelte';
  import { query } from '@lib/universal-props-query.svelte';
</script>

<!-- below 48rem the base (13px root) applies; at 48rem+ the md case
     (18px) wins — the §11 stamp scales the root, children reflow -->
<PrototypeFlex size={query({ md: 18 }, 13)} gap={12}>…</PrototypeFlex>

PrototypeFlex · universal props

onetwothree
namedsteps
darklg rung
string gapcolumn
prototype-flex-universal.svelte svelte
<PrototypeFlex size={18} density="small">…</PrototypeFlex>

a11y

Accessibility

A layout primitive: no role, no keys, no announcements of its own — its a11y story is ORDER and what consumers land on the root.

Keyboard

KeyAction
—Not a focus stop and no keys of its own — a plain div wrapper

ARIA

AttributeValueDescription
visual vs DOM orderthe row-reverse tradedirection="row-reverse" / "column-reverse" flip the VISUAL order against the DOM order — screen readers follow the DOM (WCAG 1.3.2: meaningful sequence); reserve the reversed rungs for genuinely reversed reading contexts.
rest-spread ARIAverbatimaria-label, role, data-* — anything in the rest lane lands on the single root after the spread, so consumer semantics compose with the layout stamps.
rolenone authoredThe container is a plain div; give it a role only when its children need grouping semantics (e.g. role="list" with role="listitem" children).
theme / density stampssubtree-scopedThe .dark bridge and data-density rung re-scope token chains for descendants — visible only to children that read them.
jixoai-ui ui.jixoai.com the jixoai design language

Theme

Brand hue

0°

Auto cycle · 24h