@ -1,5 +1,104 @@
< script lang = "ts" >
< script lang = "ts" >
import { Box } from '$uix/eidos/components/box';
import { Box , type BoxProps } from '$uix/eidos/components/box';
import { compileMorfo } from '$uix/morfo';
import { boxMorfo } from '@/uix/morfo/components/box';
type Tab = 'live' | 'api' | 'morfo' | 'sema' | 'recipe' | 'a11y';
type TraceEntry = { event : string ; family : string ; intent? : string ; at : number } ;
let tab = $state< Tab > ('live');
let trace = $state< TraceEntry [ ] > ([]);
let stageRef = $state< HTMLElement | null > (null);
// ── Live state ────────────────────────────────────────────────────────
// Box has 40+ props; we expose the most-used ones as live controls
// and document the rest in the API table.
let display = $state< 'block' | 'flex' | 'inline-flex' | 'grid' | 'inline-grid' | 'inline' | 'inline-block' | 'contents' | 'none'>('flex');
let padding = $state< number > (4);
let gap = $state< number > (3);
let width = $state< string > ('');
let height = $state< string > ('');
let overflow = $state< 'visible' | 'hidden' | 'auto' | 'scroll' | 'clip' | ''>('');
let position = $state< 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky' | ''>('');
const displayOptions = ['block', 'flex', 'inline-flex', 'grid', 'inline-grid', 'inline', 'inline-block', 'contents', 'none'] as const;
const overflowOptions = ['', 'visible', 'hidden', 'auto', 'scroll', 'clip'] as const;
const positionOptions = ['', 'static', 'relative', 'absolute', 'fixed', 'sticky'] as const;
const boxProps = $derived< Partial < BoxProps > >({
display,
padding,
gap: gap || undefined,
width: width || undefined,
height: height || undefined,
overflow: overflow || undefined,
position: position || undefined
});
// ── Compiled morfo ────────────────────────────────────────────────────
const compiled = compileMorfo(boxMorfo);
const partsList = $derived([...compiled.parts.byKebab.values()]);
const events = $derived([...compiled.actions.byName.values()]);
$effect(() => {
const el = stageRef;
if (!el) return;
const obs = new MutationObserver((mutations) => {
for (const m of mutations) {
if (m.attributeName !== 'data-event') continue;
const target = m.target as Element;
const ev = target.getAttribute('data-event');
if (!ev) continue;
trace = [
{
event: ev,
family: target.getAttribute('data-event-family') ?? '—',
intent: target.getAttribute('data-event-intent') ?? undefined,
at: Date.now()
},
...trace
].slice(0, 6);
}
});
obs.observe(el, { attributes : true , subtree : true , attributeFilter : [ 'data-event' ] } );
return () => obs.disconnect();
});
// ── Code snippets ─────────────────────────────────────────────────────
const somaSnippet = $derived(
[
'<!-- Box is eidos - native — no soma layer. --> ',
'<!-- Equivalent semantic markup (not real soma): --> ',
'',
'< div ' ,
' data-box',
' style="display: var(--box-display); padding: var(--box-padding); gap: var(--box-gap);"',
'>',
' …',
'< / div > '
].join('\n')
);
const eidosSnippet = $derived(
[
"< script lang = 'ts' > " ,
" import { Box } from '$uix/eidos/components/box';",
'< /' + 'script>',
'',
'< Box ' ,
display !== 'flex' && ` display="${ display } "`,
padding !== 0 && ` padding={ $ { padding }} `,
gap > 0 && ` gap={ $ { gap }} `,
width && ` width="${ width } "`,
height && ` height="${ height } "`,
overflow && ` overflow="${ overflow } "`,
position && ` position="${ position } "`,
'>',
' …',
'< / Box > '
]
.filter(Boolean)
.join('\n')
);
< / script >
< / script >
< div data-uix-canvas-inner >
< div data-uix-canvas-inner >
@ -7,127 +106,336 @@
< div data-uix-eyebrow > Layout · Box< / div >
< div data-uix-eyebrow > Layout · Box< / div >
< h1 data-uix-page-title > Box< / h1 >
< h1 data-uix-page-title > Box< / h1 >
< p data-uix-page-lede >
< p data-uix-page-lede >
Universal box-model utility. Every prop maps to a CSS custom property; unset
Universal box-model utility — size, padding/margin, position, overflow, plus flex/grid
props fall through to the normal cascade.
< em > item< / em > props (alignment, placement, order). Container-side flex/grid props (direction,
align, justify, wrap, templateColumns, …) live in
< a href = "/uix/components/flex" > < Flex> < / a > and
< a href = "/uix/components/grid" > < Grid> < / a > — UIX follows the Radix Themes split, not the
Chakra/MUI everything-on-Box model. Every prop maps to a < code > --box-*< / code > CSS custom
property emitted inline; unset props fall through via < code > revert-layer< / code > .
Eidos-native: no soma backing, no semantic events.
< / p >
< / p >
< div data-uix-page-meta >
< span data-uix-meta-pill >
< span data-uix-meta-key > parts</ span > { compiled . parts . order . length }
< / span >
< span data-uix-meta-pill >
< span data-uix-meta-key > events< / span > 0
< / span >
< span data-uix-meta-pill >
< span data-uix-meta-key > props< / span > 40+
< / span >
< span data-uix-meta-pill >
< span data-uix-meta-key > scope< / span > eidos
< / span >
< / div >
< / header >
< / header >
< section >
<!-- Live preview always rendered -->
< h2 > Live example< / h2 >
< div data-uix-stage >
< Box
< div data-uix-stage-area bind:this = { stageRef } >
padding={ 4 }
< Box {... boxProps } style = "border: 1px dashed var(--color-border-default); border-radius: var(--radius-md); min-width: 16rem;" >
maxWidth={ 480 }
< Box padding = { 2 } style="border: 1px solid var ( --color-primary-border ); border-radius: var ( --radius-sm ); background: var ( --color-primary-track ); color: var ( --color-primary-text );" > Cell A</ Box >
display="flex"
< Box padding = { 2 } style="border: 1px solid var ( --color-affirm-border ); border-radius: var ( --radius-sm ); background: var ( --color-affirm-track ); color: var ( --color-affirm-text );" > Cell B</ Box >
gap={ 3 }
< Box padding = { 2 } style="border: 1px solid var ( --color-risk-border ); border-radius: var ( --radius-sm ); background: var ( --color-risk-track ); color: var ( --color-risk-text );" > Cell C</ Box >
style="background: var(--color-surface-1); border: 1px solid var(--color-border); border-radius: 8px"
>
< Box padding = { 2 } style="background: var ( --color-surface-2 ); border-radius: 4px " >
Cell A
< / Box >
< / Box >
< Box padding = { 2 } style="background: var ( --color-surface-2 ); border-radius: 4px " >
< / div >
Cell B
< div data-uix-stage-trace >
< / Box >
< span data-uix-stage-trace-key > trace< / span >
< Box padding = { 2 } style="background: var ( --color-surface-2 ); border-radius: 4px " >
< span > { trace . length === 0 ? 'no semantic events' : `$ { trace . length } event ( s ) ` } </ span >
Cell C
< span style = "color: var(--uix-text-faint)" > ·< / span >
< / Box >
< span data-uix-stage-trace-key > display< / span >
< / Box >
< span > { display } </ span >
< / section >
< span style = "margin-inline-start: auto;" >
< span data-uix-stage-trace-key > padding< / span >
< section >
{ padding } · < span data-uix-stage-trace-key > gap</ span > { gap }
< h2 > Props< / h2 >
< / span >
< table >
< / div >
< thead >
< / div >
< tr >
< th > Prop< / th >
< div data-uix-tabs role = "tablist" >
< th > Type< / th >
< button data-uix-tab data-active = { tab === 'live' } onclick= {() => ( tab = 'live' )} > Live</ button >
< th > Notes< / th >
< button data-uix-tab data-active = { tab === 'api' } onclick= {() => ( tab = 'api' )} >
< / tr >
API < span data-uix-tab-count > 40+< / span >
< / thead >
< / button >
< tbody >
< button data-uix-tab data-active = { tab === 'morfo' } onclick= {() => ( tab = 'morfo' )} >
< tr >
< span data-uix-layer-badge = "morfo" > morfo< / span >
< td > < code > display< / code > < / td >
< span data-uix-tab-count > { partsList . length } p · 0e</ span >
< td > LayoutDisplay< / td >
< / button >
< td > block · inline · flex · grid · …< / td >
< button data-uix-tab data-active = { tab === 'sema' } onclick= {() => ( tab = 'sema' )} >
< / tr >
< span data-uix-layer-badge = "sema" > sema< / span >
< tr >
< span data-uix-tab-count > { events . length } </ span >
< td > < code > width< / code > / < code > minWidth< / code > / < code > maxWidth< / code > < / td >
< / button >
< td > number | string< / td >
< button data-uix-tab data-active = { tab === 'recipe' } onclick= {() => ( tab = 'recipe' )} > Recipe</ button >
< td > number → px, string passes through< / td >
< button data-uix-tab data-active = { tab === 'a11y' } onclick= {() => ( tab = 'a11y' )} > A11y</ button >
< / tr >
< / div >
< tr >
< td > < code > height< / code > / < code > minHeight< / code > / < code > maxHeight< / code > < / td >
{ #if tab === 'live' }
< td > number | string< / td >
< section data-uix-section >
< td > same as above< / td >
< h2 data-uix-section-title > Controls< / h2 >
< / tr >
< p data-uix-section-desc >
< tr >
Box is eidos-native — no < span data-uix-layer-badge = "soma" > soma< / span > split. Each prop
< td > < code > padding< / code > / < code > paddingX< / code > / < code > paddingY< / code > < / td >
maps to a < code > --box-*< / code > custom property; numeric space values resolve to
< td > number | string< / td >
< code > var(--space-N)</ code > , numeric length values to < code > { `{N}px` } </ code > , strings pass
< td > number → < code > var(--space-N)< / code > < / td >
through. Unset props fall back to the cascade via < code > revert-layer< / code > .
< / tr >
< / p >
< tr >
< td >
< div data-uix-subsection-head >
< code > paddingTop< / code > / < code > paddingRight< / code > /
< span data-uix-layer-badge = "eidos" > eidos< / span > props · visual treatment
< code > paddingBottom< / code > / < code > paddingLeft< / code >
< / div >
< / td >
< div data-uix-controls >
< td > number | string< / td >
< label data-uix-control >
< td > per-side overrides< / td >
< span data-uix-control-label > display< / span >
< / tr >
< span data-uix-chips role = "radiogroup" >
< tr >
{ #each displayOptions as opt }
< td > < code > margin< / code > / < code > marginX< / code > / < code > marginY< / code > / sides< / td >
< button data-uix-chip data-active = { display === opt } onclick= {() => ( display = opt )} > { opt } </ button >
< td > number | string< / td >
{ /each }
< td > same mapping as padding< / td >
< / span >
< / tr >
< / label >
< tr >
< label data-uix-control >
< td > < code > gap< / code > < / td >
< span data-uix-control-label > padding < span data-uix-control-hint > 0– 8 → var(--space-N)< / span > < / span >
< td > number | string< / td >
< input type = "number" min = "0" max = "8" step = "1" bind:value = { padding } style="inline-size: 6rem ;" />
< td > for flex/grid containers< / td >
< / label >
< / tr >
< label data-uix-control >
< tr >
< span data-uix-control-label > gap < span data-uix-control-hint > 0– 8 → var(--space-N)< / span > < / span >
< td >
< input type = "number" min = "0" max = "8" step = "1" bind:value = { gap } style="inline-size: 6rem ;" />
< code > position< / code > / < code > top< / code > / < code > right< / code > /
< / label >
< code > bottom< / code > / < code > left< / code >
< label data-uix-control >
< / td >
< span data-uix-control-label > width < span data-uix-control-hint > e.g. 320px, 50%, auto< / span > < / span >
< td > various< / td >
< input type = "text" placeholder = "(auto)" bind:value = { width } style="inline-size: 8rem ;" />
< td > position + insets< / td >
< / label >
< / tr >
< label data-uix-control >
< tr >
< span data-uix-control-label > height < span data-uix-control-hint > e.g. 200px, auto< / span > < / span >
< td > < code > inset< / code > / < code > insetX< / code > / < code > insetY< / code > < / td >
< input type = "text" placeholder = "(auto)" bind:value = { height } style="inline-size: 8rem ;" />
< td > number | string< / td >
< / label >
< td > shorthand insets< / td >
< label data-uix-control >
< / tr >
< span data-uix-control-label > overflow< / span >
< tr >
< span data-uix-chips role = "radiogroup" >
< td > < code > overflow< / code > / < code > overflowX< / code > / < code > overflowY< / code > < / td >
{ #each overflowOptions as opt }
< td > LayoutOverflow< / td >
< button data-uix-chip data-active = { overflow === opt } onclick= {() => ( overflow = opt )} > { opt || '(unset)' } </ button >
< td > visible · hidden · clip · scroll · auto< / td >
{ /each }
< / tr >
< / span >
< tr >
< / label >
< td >
< label data-uix-control >
< code > flex< / code > / < code > grow< / code > / < code > shrink< / code > / < code > basis< / code > /
< span data-uix-control-label > position< / span >
< code > order< / code > / < code > alignSelf< / code > / < code > justifySelf< / code >
< span data-uix-chips role = "radiogroup" >
< / td >
{ #each positionOptions as opt }
< td > various< / td >
< button data-uix-chip data-active = { position === opt } onclick= {() => ( position = opt )} > { opt || '(unset)' } </ button >
< td > item-side flex/grid props< / td >
{ /each }
< / tr >
< / span >
< tr >
< / label >
< td > < code > style< / code > < / td >
< / div >
< td > string< / td >
< td > extra inline style; merged after Box vars< / td >
<!-- ── Code snippets per layer ─────────────────────────────────── -->
< / tr >
< div data-uix-code >
< / tbody >
< div data-uix-code-head >
< / table >
< span data-uix-layer-badge = "soma" > soma< / span >
< / section >
< span > n/a · box is eidos-native — equivalent markup shown< / span >
< span data-uix-code-lang > svelte< / span >
< section >
< / div >
< h2 > Reference< / h2 >
< pre >< code > { somaSnippet } </ code ></ pre >
< ul >
< / div >
< li >
< strong > radix-themes Box< / strong > — same idea: token-driven shorthand for the
< div data-uix-code style = "margin-top: var(--uix-space-3);" >
box model; we mirror the responsive prop shape.
< div data-uix-code-head >
< / li >
< span data-uix-layer-badge = "eidos" > eidos< / span >
< li >
< span > visual · every prop maps to a --box-* CSS variable< / span >
< strong > chakra-ui Box< / strong > — origin of the per-side / shorthand prop split
< span data-uix-code-lang > svelte< / span >
(< code > paddingX< / code > , < code > paddingY< / code > , …).
< / div >
< / li >
< pre >< code > { eidosSnippet } </ code ></ pre >
< / ul >
< / div >
< / section >
< / section >
{ /if }
{ #if tab === 'api' }
< section data-uix-section >
< h2 data-uix-section-title > API reference< / h2 >
< p data-uix-section-desc >
Numeric values for space props (< code > padding*< / code > , < code > margin*< / code > ,
< code > gap< / code > ) resolve to < code > var(--space-N)< / code > . Numeric values for length props
(< code > width</ code > , < code > height</ code > , insets) resolve to < code > { `{N}px` } </ code > . String
values pass through unchanged. < code > revert-layer< / code > is the fallback for any unset prop.
< / p >
< div data-uix-subsection-head > Sizing< / div >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Prop< / th > < th > Type< / th > < th > Notes< / th > < / tr > < / thead >
< tbody >
< tr > < td class = "name" > width / minWidth / maxWidth< / td > < td class = "type" > number | string< / td > < td > Number → px, string passes through.< / td > < / tr >
< tr > < td class = "name" > height / minHeight / maxHeight< / td > < td class = "type" > number | string< / td > < td > Same as width.< / td > < / tr >
< / tbody >
< / table >
< / div >
< div data-uix-subsection-head > Spacing< / div >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Prop< / th > < th > Type< / th > < th > Notes< / th > < / tr > < / thead >
< tbody >
< tr > < td class = "name" > padding / paddingX / paddingY< / td > < td class = "type" > number | string< / td > < td > Number → < code > var(--space-N)< / code > .< / td > < / tr >
< tr > < td class = "name" > paddingTop / paddingRight / paddingBottom / paddingLeft< / td > < td class = "type" > number | string< / td > < td > Per-side overrides; cascade < code > paddingX/Y< / code > → < code > padding< / code > .< / td > < / tr >
< tr > < td class = "name" > margin / marginX / marginY< / td > < td class = "type" > number | string< / td > < td > Same as padding mapping.< / td > < / tr >
< tr > < td class = "name" > marginTop / marginRight / marginBottom / marginLeft< / td > < td class = "type" > number | string< / td > < td > Per-side overrides.< / td > < / tr >
< tr > < td class = "name" > gap< / td > < td class = "type" > number | string< / td > < td > Useful with display flex/grid.< / td > < / tr >
< / tbody >
< / table >
< / div >
< div data-uix-subsection-head > Display + position< / div >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Prop< / th > < th > Type< / th > < th > Notes< / th > < / tr > < / thead >
< tbody >
< tr > < td class = "name" > display< / td > < td class = "type" > block | inline | inline-block | flex | inline-flex | grid | inline-grid | contents | none< / td > < td > —< / td > < / tr >
< tr > < td class = "name" > position< / td > < td class = "type" > static | relative | absolute | fixed | sticky< / td > < td > —< / td > < / tr >
< tr > < td class = "name" > top / right / bottom / left< / td > < td class = "type" > number | string< / td > < td > Number → px.< / td > < / tr >
< tr > < td class = "name" > inset / insetX / insetY< / td > < td class = "type" > number | string< / td > < td > Shorthand insets.< / td > < / tr >
< tr > < td class = "name" > overflow / overflowX / overflowY< / td > < td class = "type" > visible | hidden | clip | scroll | auto< / td > < td > —< / td > < / tr >
< / tbody >
< / table >
< / div >
< div data-uix-subsection-head > Flex / grid item< / div >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Prop< / th > < th > Type< / th > < th > Notes< / th > < / tr > < / thead >
< tbody >
< tr > < td class = "name" > flex / grow / shrink< / td > < td class = "type" > number | string< / td > < td > Item-side flex props.< / td > < / tr >
< tr > < td class = "name" > basis< / td > < td class = "type" > number | string< / td > < td > Number → px.< / td > < / tr >
< tr > < td class = "name" > order< / td > < td class = "type" > number< / td > < td > —< / td > < / tr >
< tr > < td class = "name" > alignSelf< / td > < td class = "type" > auto | start | end | center | stretch | baseline< / td > < td > —< / td > < / tr >
< tr > < td class = "name" > justifySelf< / td > < td class = "type" > auto | start | end | center | stretch< / td > < td > —< / td > < / tr >
< tr > < td class = "name" > placeSelf< / td > < td class = "type" > string< / td > < td > Shorthand for align-self + justify-self.< / td > < / tr >
< tr > < td class = "name" > gridColumn / gridRow< / td > < td class = "type" > string< / td > < td > Grid item placement. e.g. < code > "1 / 3"< / code > , < code > "span 2"< / code > .< / td > < / tr >
< tr > < td class = "name" > gridArea< / td > < td class = "type" > string< / td > < td > Named grid area, e.g. < code > "header"< / code > .< / td > < / tr >
< / tbody >
< / table >
< / div >
< div data-uix-subsection-head > Escape hatch< / div >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Prop< / th > < th > Type< / th > < th > Notes< / th > < / tr > < / thead >
< tbody >
< tr > < td class = "name" > style< / td > < td class = "type" > string< / td > < td > Extra inline CSS appended after Box's variable declarations. Use for one-offs the prop surface doesn't cover.< / td > < / tr >
< / tbody >
< / table >
< / div >
< div data-uix-subsection-head > Reference comparison< / div >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Library< / th > < th > Closest equivalent< / th > < th > Difference< / th > < / tr > < / thead >
< tbody >
< tr > < td class = "name" > radix-themes< / td > < td > < code > < Box> < / code > < / td > < td > Radix exposes spacing props as < code > p< / code > /< code > px< / code > shorthands; UIX uses full names. Both compile to CSS vars.< / td > < / tr >
< tr > < td class = "name" > chakra-ui< / td > < td > < code > < Box> < / code > < / td > < td > Chakra mixes the style-props system with theme aliases (< code > bg< / code > , < code > color< / code > ); UIX Box is layout-only — color / typography live elsewhere.< / td > < / tr >
< tr > < td class = "name" > mantine< / td > < td > < code > < Box> < / code > < / td > < td > Mantine compiles styles to classnames; UIX writes inline CSS variables for transparent debugging.< / td > < / tr >
< / tbody >
< / table >
< / div >
< / section >
{ /if }
{ #if tab === 'morfo' }
< section data-uix-section >
< h2 data-uix-section-title > Morfo contract< / h2 >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Field< / th > < th > Value< / th > < / tr > < / thead >
< tbody >
< tr >< td class = "name" > name</ td >< td > { boxMorfo . name } </ td ></ tr >
< tr >< td class = "name" > kebab</ td >< td >< code > { boxMorfo . kebab } </ code ></ td ></ tr >
< tr >< td class = "name" > scope</ td >< td > { boxMorfo . scope . join ( ', ' )} </ td ></ tr >
< tr >< td class = "name" > parts</ td >< td > { partsList . length } </ td ></ tr >
< tr > < td class = "name" > events< / td > < td > 0< / td > < / tr >
< / tbody >
< / table >
< / div >
< div data-uix-subsection-head > Parts< / div >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > kebab< / th > < th > marker< / th > < th > element< / th > < th > archetype< / th > < th > optional< / th > < / tr > < / thead >
< tbody >
{ #each partsList as part }
< tr >
< td class = "name" > { part . kebab } </ td >
< td >< code data-uix-part-marker > [{ part . marker } ]</ code ></ td >
< td class = "type" > < { part . defaultElement } > </ td >
< td class = "type" > { part . archetype } </ td >
< td class = "default" > { part . optional ? 'yes' : 'no' } </ td >
< / tr >
{ /each }
< / tbody >
< / table >
< / div >
< p data-uix-section-desc style = "margin-top: var(--uix-space-4);" >
The Provider part emits only the < code > data-box< / code > marker — no states, no data
properties, no aria attributes, no keyboard. The recipe consumes the
< code > --box-*< / code > CSS variables the component writes inline.
< / p >
< / section >
{ /if }
{ #if tab === 'sema' }
< section data-uix-section >
< h2 data-uix-section-title >
< span data-uix-layer-badge = "sema" > sema< / span > · events
< / h2 >
< p data-uix-section-desc >
Box declares no semantic events. As a passive layout primitive, it does not commit, emerge,
or react to anything — it just styles its children. Components that animate or change state
on appearance should compose Box with an interactive primitive (popover, drawer,
collapsible) that owns the relevant sema verbs.
< / p >
< / section >
{ /if }
{ #if tab === 'recipe' }
< section data-uix-section >
< h2 data-uix-section-title > Eidos recipe< / h2 >
< p data-uix-section-desc >
Recipe lives in < code > src/uix/eidos/components/box/box.css< / code > . Every property reads
its own < code > --box-*< / code > custom property and falls back via
< code > revert-layer< / code > so consumers can mix Box with any other styling.
< / p >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Selector< / th > < th > Owner< / th > < th > Purpose< / th > < / tr > < / thead >
< tbody >
< tr >
< td class = "name" > < code > [data-box]< / code > < / td >
< td > < span data-uix-tag data-kind = "morfo" > morfo< / span > < / td >
< td > Provider marker. Single root element emitted by the component.< / td >
< / tr >
< tr >
< td class = "name" >< code > [data-box] { `{ display: var(--box-display, revert-layer); … }` } </ code ></ td >
< td > < span data-uix-tag data-kind = "eidos" > eidos< / span > < / td >
< td > Read every < code > --box-*< / code > custom property, fall back to the cascade when unset.< / td >
< / tr >
< / tbody >
< / table >
< / div >
< / section >
{ /if }
{ #if tab === 'a11y' }
< section data-uix-section >
< h2 data-uix-section-title > Accessibility< / h2 >
< div data-uix-table-wrap >
< table data-uix-table >
< thead > < tr > < th > Concern< / th > < th > Contract< / th > < / tr > < / thead >
< tbody >
< tr > < td class = "name" > Role< / td > < td > None implicit. Default element is < code > < div> < / code > — semantically neutral. Use a semantic wrapper (< code > < main> < / code > , < code > < section> < / code > , < code > < article> < / code > ) around Box when content needs a landmark.< / td > < / tr >
< tr > < td class = "name" > Label< / td > < td > Not applicable — Box has no content semantics. Labels belong to the interactive child the Box wraps.< / td > < / tr >
< tr > < td class = "name" > Keyboard< / td > < td > Box is not focusable. Tab order follows children.< / td > < / tr >
< tr > < td class = "name" > Focus visible< / td > < td > Box does not paint a focus ring. Focus styling belongs to the interactive children.< / td > < / tr >
< / tbody >
< / table >
< / div >
< / section >
{ /if }
< / div >
< / div >