diff --git a/src/uix/morfo/components/flex.ts b/src/uix/morfo/components/flex.ts new file mode 100644 index 000000000..eaf9b09f7 --- /dev/null +++ b/src/uix/morfo/components/flex.ts @@ -0,0 +1,29 @@ +import type { Morfo } from '../types'; + +/** + * Flex — `display:flex` container (layout primitive). + * + * Eidos-native: every public prop maps to a `--flex-*` (or inherited + * `--box-*`) custom property. The provider is a single `
- display:flex container with direction, wrap, alignment and gap.
+ display:flex container. Adds direction / align /
+ justify / wrap / rowGap / columnGap
+ on top of every <Box> prop. For grid containers
+ use <Grid>; for flex/grid item props
+ (alignSelf, gridColumn, order, basis, …) use <Box> on the child.
| Prop | -Default | -Notes | -
|---|---|---|
inline |
- false | -switch to inline-flex |
-
direction |
- 'row' | -row · row-reverse · column · column-reverse | -
wrap |
- 'nowrap' | -nowrap · wrap · wrap-reverse | -
align |
- — | -stretch · start · center · end · baseline | -
justify |
- — | -start · center · end · space-between · space-around · space-evenly | -
gap / rowGap / columnGap |
- — | -row/columnGap override gap per axis |
-
… plus every BoxProps prop except display |
- ||
direction,
- align, justify, wrap, gap).
-
+ Flex is eidos-native — no soma split. The 7
+ container-side props below map to --flex-* CSS variables. Flex also inherits
+ every Box prop (padding, margin, size, position) by
+ composition.
+
{somaSnippet}
+ {eidosSnippet}
+
+ Flex adds container-side flex props on top of every BoxProps field. Pass
+ inline to switch to inline-flex; otherwise the provider renders
+ with display:flex. Item-side props (flex, grow,
+ shrink, basis, order, alignSelf,
+ justifySelf, placeSelf) live on the child
+ <Box>.
+
| Prop | Type | Default | Notes |
|---|---|---|---|
| inline | boolean | false | Switches to display:inline-flex. |
| direction | row | row-reverse | column | column-reverse | 'row' | flex-direction. |
| align | stretch | start | center | end | baseline | flex-start | flex-end | — | align-items — cross-axis. |
| justify | start | center | end | space-between | space-around | space-evenly | stretch | flex-start | flex-end | — | justify-content — main-axis. |
| wrap | nowrap | wrap | wrap-reverse | 'nowrap' | flex-wrap. |
| gap | number | string | — | Number → var(--space-N). |
| rowGap / columnGap | number | string | — | Per-axis gap override; takes precedence over gap. |
+ Every BoxProps field is forwarded:
+ padding*, margin*, width, height,
+ position, top/right/bottom/left, overflow*, plus
+ item-side props that apply when this Flex is itself an item of a parent flex/grid
+ (alignSelf, gridColumn, …).
+
| Library | Closest equivalent | Difference |
|---|---|---|
| radix-themes | <Flex> | Same shape: container props on Flex, item props on Box. Radix uses flexShrink spelling; UIX uses shrink. |
| chakra-ui | <Flex> / <HStack> / <VStack> | Chakra also exposes <HStack>/<VStack> as direction-specific helpers. UIX uses <Stack> with a direction prop. |
| mantine | <Flex> / <Group> | Mantine splits row-only into <Group>; UIX has the same split. |
| Field | Value |
|---|---|
| name | {flexMorfo.name} |
| kebab | {flexMorfo.kebab} |
| scope | {flexMorfo.scope.join(', ')} |
| parts | {partsList.length} |
| events | 0 |
| kebab | marker | element | archetype | optional |
|---|---|---|---|---|
| {part.kebab} | +[{part.marker}] |
+ <{part.defaultElement}> | +{part.archetype} | +{part.optional ? 'yes' : 'no'} | +
+ Flex composes through <Box>, so the rendered DOM is a single
+ div[data-box][data-flex] shell. Recipe lives at
+ src/uix/eidos/components/flex/flex.css and layers on top of the Box
+ recipe.
+
+ Flex declares no semantic events. As a passive layout primitive, it does not commit, + emerge, or react to anything — it just arranges its children. Components that animate + on appearance should compose Flex with an interactive primitive (popover, drawer, + collapsible) that owns the relevant sema verbs. +
+
+ Recipe lives in src/uix/eidos/components/flex/flex.css and layers on top
+ of the Box recipe. The provider element carries both data-box and
+ data-flex markers because Flex renders through Box.
+
| Selector | Owner | Purpose |
|---|---|---|
[data-flex] |
+ morfo | +Provider marker. | +
[data-box][data-flex] {`{ display: flex | inline-flex; flex-direction: var(--flex-direction, row); … }`} |
+ eidos | +Layer container-side flex properties on the Box recipe. | +
| Concern | Contract |
|---|---|
| Role | None implicit. Default element is <div> — semantically neutral. Use a semantic wrapper (<nav>, <header>, <ul role="list">) around Flex when content needs a landmark or list semantics. |
| Label | Not applicable — Flex has no content semantics. Labels belong to the interactive children. |
| Keyboard | Flex is not focusable. Tab order follows DOM order even when direction visually reverses (row-reverse / column-reverse). Verify visual order matches focus order for keyboard users. |
| Reduced motion | Flex does not animate. Layout shifts on resize follow CSS defaults — no transition on the recipe. |