@kerfjs/ui 5.0.0-beta.34 → 5.0.0-beta.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/ai/component-catalog-v2.json +12 -2
- package/ai/component-catalog.json +16 -4
- package/ai/public-api-signatures-v1.md +79 -1
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/{chunk-OKRCKIVO.js → chunk-QHCBZTDK.js} +9 -2
- package/dist/chunk-QHCBZTDK.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/row.d.ts +5 -3
- package/dist/row.js +1 -1
- package/dist/styles/row.css +1 -0
- package/docs/component-contract.md +3 -2
- package/docs/component-integration.md +63 -0
- package/docs/component-selection.md +1 -1
- package/docs/layout.md +7 -0
- package/docs/ux-demo.md +10 -0
- package/package.json +9 -3
- package/dist/chunk-OKRCKIVO.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,6 +4,15 @@ Accessible, composable UI primitives for [kerf](https://github.com/brianwestphal
|
|
|
4
4
|
|
|
5
5
|
Start interface work with the [need-first component selection matrix](./docs/component-selection.md). It distinguishes direct reuse, composition, thin application adapters, and genuinely custom semantics, with imports, required wiring, application ownership, alternatives, and recipes for every public primitive.
|
|
6
6
|
|
|
7
|
+
When adding a first-party public component, follow the
|
|
8
|
+
[component integration workflow](./docs/component-integration.md). The catalog
|
|
9
|
+
entry drives one validator across package, build, barrel, CSS, demo, route, and
|
|
10
|
+
AI signature projections, with a non-mutating dry-run report.
|
|
11
|
+
|
|
12
|
+
Browser verification always builds current source: both `npm run test:e2e`
|
|
13
|
+
and direct focused Playwright commands run the catalog/conformance preflights
|
|
14
|
+
and production build before preview. See the [UX catalog contract](./docs/ux-demo.md).
|
|
15
|
+
|
|
7
16
|
When authoring a component gallery, follow the single
|
|
8
17
|
[Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract)
|
|
9
18
|
for focused-versus-composition modes, helper nesting, specimen selection,
|
|
@@ -132,7 +141,7 @@ defaults to left/full alignment, the `xs` gap, and `wrap={false}`; List keeps
|
|
|
132
141
|
its existing full/top alignment and zero-gap defaults.
|
|
133
142
|
|
|
134
143
|
The same property-specific boundary applies beyond spacing: use `flex()` (or a
|
|
135
|
-
finite keyword) for `List.flex`; length builders and intrinsic-size keywords for
|
|
144
|
+
finite keyword) for `Row.flex` and `List.flex`; length builders and intrinsic-size keywords for
|
|
136
145
|
`Skeleton.width`/`height`; length builders for `Skeleton.radius`; and
|
|
137
146
|
`uiColor()` or `colorVar()` for `SelectChoice.color`. These grammars are not
|
|
138
147
|
interchangeable. `ListItem` and `ListActionRow` deliberately expose no raw
|
|
@@ -1424,7 +1424,7 @@
|
|
|
1424
1424
|
"required": false
|
|
1425
1425
|
},
|
|
1426
1426
|
{
|
|
1427
|
-
"id": "typed gap
|
|
1427
|
+
"id": "typed gap and flex choices",
|
|
1428
1428
|
"owner": "application",
|
|
1429
1429
|
"required": false
|
|
1430
1430
|
}
|
|
@@ -1438,7 +1438,7 @@
|
|
|
1438
1438
|
"border": "none",
|
|
1439
1439
|
"padding": "none",
|
|
1440
1440
|
"notes": [
|
|
1441
|
-
"Row adds no margin, border, or padding; it owns only flex alignment, wrapping, and the gap between children."
|
|
1441
|
+
"Row adds no margin, border, or padding; it owns only flex participation, alignment, wrapping, and the gap between children."
|
|
1442
1442
|
]
|
|
1443
1443
|
}
|
|
1444
1444
|
},
|
|
@@ -1463,6 +1463,16 @@
|
|
|
1463
1463
|
"gap={space(\"m\")}",
|
|
1464
1464
|
"gap={calc(plus(rem(0.25), pct(10)))}"
|
|
1465
1465
|
]
|
|
1466
|
+
},
|
|
1467
|
+
{
|
|
1468
|
+
"path": "flex",
|
|
1469
|
+
"grammar": "flex",
|
|
1470
|
+
"helpers": ["flex"],
|
|
1471
|
+
"shorthands": ["none", "auto", "initial"],
|
|
1472
|
+
"canonicalShorthands": ["none", "auto", "initial"],
|
|
1473
|
+
"exceptionalShorthands": [],
|
|
1474
|
+
"rawPolicy": "forbid",
|
|
1475
|
+
"examples": ["flex", "flex=\"none\"", "flex={flex(1, 1, rem(20))}"]
|
|
1466
1476
|
}
|
|
1467
1477
|
],
|
|
1468
1478
|
"boundaries": {
|
|
@@ -1642,7 +1642,7 @@
|
|
|
1642
1642
|
"category": "Structure",
|
|
1643
1643
|
"kind": "component",
|
|
1644
1644
|
"source": "kerf",
|
|
1645
|
-
"description": "A horizontal flex row with physical-axis alignment, a typed xs gap by default, and opt-in wrapping.",
|
|
1645
|
+
"description": "A horizontal flex row with physical-axis alignment, a typed xs gap by default, flex participation, and opt-in wrapping.",
|
|
1646
1646
|
"uses": [],
|
|
1647
1647
|
"purpose": "Arrange related content horizontally with consistent spacing and explicit left/center/right/full plus top/middle/bottom/full alignment instead of application-owned flex wrappers.",
|
|
1648
1648
|
"publicExports": ["Row"],
|
|
@@ -1657,16 +1657,27 @@
|
|
|
1657
1657
|
"exceptionalShorthands": ["s", "xl"],
|
|
1658
1658
|
"rawPolicy": "forbid",
|
|
1659
1659
|
"examples": ["gap=\"xs\"", "gap={space(\"m\")}", "gap={calc(plus(rem(0.25), pct(10)))}"]
|
|
1660
|
+
},
|
|
1661
|
+
{
|
|
1662
|
+
"path": "flex",
|
|
1663
|
+
"grammar": "flex",
|
|
1664
|
+
"helpers": ["flex"],
|
|
1665
|
+
"shorthands": ["none", "auto", "initial"],
|
|
1666
|
+
"canonicalShorthands": ["none", "auto", "initial"],
|
|
1667
|
+
"exceptionalShorthands": [],
|
|
1668
|
+
"rawPolicy": "forbid",
|
|
1669
|
+
"examples": ["flex", "flex=\"none\"", "flex={flex(1, 1, rem(20))}"]
|
|
1660
1670
|
}
|
|
1661
1671
|
],
|
|
1662
1672
|
"useWhen": [
|
|
1663
1673
|
"Arrange a group of sibling components horizontally.",
|
|
1664
1674
|
"Choose physical horizontal distribution and vertical alignment without writing one-off flex CSS.",
|
|
1675
|
+
"Use a finite flex keyword or the flex() builder when Row participates in a flexible parent layout.",
|
|
1665
1676
|
"Allow a bounded group to wrap while retaining the same typed gap and alignment contract."
|
|
1666
1677
|
],
|
|
1667
1678
|
"avoidWhen": [
|
|
1668
1679
|
"Do not use Row when content belongs in a semantic list or when a named-zone component such as Toolbar owns the composition.",
|
|
1669
|
-
"Do not pass raw CSS strings to gap or use s/xl spacing steps without a deliberate exception.",
|
|
1680
|
+
"Do not pass raw CSS strings to gap or flex, mix their distinct grammars, or use s/xl spacing steps without a deliberate exception.",
|
|
1670
1681
|
"Do not use alignment to replace semantic grouping or responsive relocation."
|
|
1671
1682
|
],
|
|
1672
1683
|
"alternatives": [
|
|
@@ -1684,13 +1695,14 @@
|
|
|
1684
1695
|
"appOwns": [
|
|
1685
1696
|
"child semantics and content",
|
|
1686
1697
|
"alignment and wrapping policy",
|
|
1687
|
-
"typed gap
|
|
1698
|
+
"typed gap and flex choices"
|
|
1688
1699
|
],
|
|
1689
1700
|
"variants": [
|
|
1690
1701
|
"left/center/right/full horizontal alignment with l/c/r/f and flex aliases",
|
|
1691
1702
|
"top/middle/bottom/full vertical alignment with t/m/c/b/f and flex aliases",
|
|
1692
1703
|
"named none/2xs/xs/s/m/l/xl token gap",
|
|
1693
1704
|
"typed CssLength gap",
|
|
1705
|
+
"boolean, finite-keyword, or typed CssFlex flex",
|
|
1694
1706
|
"nowrap or wrapping"
|
|
1695
1707
|
],
|
|
1696
1708
|
"accessibility": [
|
|
@@ -1702,7 +1714,7 @@
|
|
|
1702
1714
|
"border": "none",
|
|
1703
1715
|
"padding": "none",
|
|
1704
1716
|
"notes": [
|
|
1705
|
-
"Row adds no margin, border, or padding; it owns only flex alignment, wrapping, and the gap between children."
|
|
1717
|
+
"Row adds no margin, border, or padding; it owns only flex participation, alignment, wrapping, and the gap between children."
|
|
1706
1718
|
]
|
|
1707
1719
|
},
|
|
1708
1720
|
"delivery": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Public API signatures for the UI authoring corpus
|
|
2
2
|
|
|
3
|
-
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.
|
|
3
|
+
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.35` and `kerfjs@5.0.0-beta.35`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
|
|
4
4
|
|
|
5
5
|
## `@kerfjs/ui/css-values`
|
|
6
6
|
|
|
@@ -1940,3 +1940,81 @@ declare function delegateActions<E extends Element = Element>(root: HTMLElement,
|
|
|
1940
1940
|
|
|
1941
1941
|
export { type ActionHandler, type DelegateActionsOptions, action, delegateActions };
|
|
1942
1942
|
```
|
|
1943
|
+
|
|
1944
|
+
## `@kerfjs/ui/lucide-icon`
|
|
1945
|
+
|
|
1946
|
+
```ts
|
|
1947
|
+
import * as kerfjs from 'kerfjs';
|
|
1948
|
+
import { IconNode } from 'lucide';
|
|
1949
|
+
|
|
1950
|
+
type LucideNode = IconNode;
|
|
1951
|
+
interface LucideIconProps {
|
|
1952
|
+
icon: LucideNode;
|
|
1953
|
+
name: string;
|
|
1954
|
+
className?: string;
|
|
1955
|
+
label?: string;
|
|
1956
|
+
}
|
|
1957
|
+
/** Render a Lucide-compatible icon node without copying icon SVG strings. */
|
|
1958
|
+
declare function LucideIcon({ icon, name, className, label }: LucideIconProps): kerfjs.SafeHtml;
|
|
1959
|
+
|
|
1960
|
+
export { LucideIcon, type LucideIconProps, type LucideNode };
|
|
1961
|
+
```
|
|
1962
|
+
|
|
1963
|
+
## `@kerfjs/ui/surface-scaffold`
|
|
1964
|
+
|
|
1965
|
+
```ts
|
|
1966
|
+
import * as kerfjs from 'kerfjs';
|
|
1967
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
1968
|
+
|
|
1969
|
+
type DialogSurfaceSize = 'small' | 'medium' | 'large';
|
|
1970
|
+
type DialogSurfacePresentation = 'modal' | 'side-sheet' | 'fullscreen';
|
|
1971
|
+
type SurfaceInset = 'none' | 'compact' | 'comfortable';
|
|
1972
|
+
interface DialogSurfaceProps {
|
|
1973
|
+
children: KerfUiContent;
|
|
1974
|
+
size?: DialogSurfaceSize;
|
|
1975
|
+
presentation?: DialogSurfacePresentation;
|
|
1976
|
+
bodyInset?: SurfaceInset;
|
|
1977
|
+
footerInset?: SurfaceInset;
|
|
1978
|
+
className?: string;
|
|
1979
|
+
}
|
|
1980
|
+
/** Configure recurring Web Awesome dialog geometry without consumer ::part() CSS. */
|
|
1981
|
+
declare function DialogSurface({ children, size, presentation, bodyInset, footerInset, className, }: DialogSurfaceProps): kerfjs.SafeHtml;
|
|
1982
|
+
type PopupSurfaceInset = 'standard' | 'compact' | 'list-zero';
|
|
1983
|
+
interface PopupSurfaceProps {
|
|
1984
|
+
children: KerfUiContent;
|
|
1985
|
+
inset?: PopupSurfaceInset;
|
|
1986
|
+
className?: string;
|
|
1987
|
+
}
|
|
1988
|
+
/** Configure recurring Web Awesome dropdown-menu geometry without consumer ::part() CSS. */
|
|
1989
|
+
declare function PopupSurface({ children, inset, className, }: PopupSurfaceProps): kerfjs.SafeHtml;
|
|
1990
|
+
|
|
1991
|
+
export { DialogSurface, type DialogSurfacePresentation, type DialogSurfaceProps, type DialogSurfaceSize, PopupSurface, type PopupSurfaceInset, type PopupSurfaceProps, type SurfaceInset };
|
|
1992
|
+
```
|
|
1993
|
+
|
|
1994
|
+
## `@kerfjs/ui/row`
|
|
1995
|
+
|
|
1996
|
+
```ts
|
|
1997
|
+
import * as kerfjs from 'kerfjs';
|
|
1998
|
+
import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
|
|
1999
|
+
import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-CF8NLj7i.js';
|
|
2000
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
2001
|
+
|
|
2002
|
+
interface RowProps {
|
|
2003
|
+
children?: KerfUiContent;
|
|
2004
|
+
/** Horizontal distribution. Defaults to left. */
|
|
2005
|
+
hAlign?: HorizontalAlignment;
|
|
2006
|
+
/** Vertical alignment and wrapped-line distribution. Defaults to full. */
|
|
2007
|
+
vAlign?: VerticalAlignment;
|
|
2008
|
+
/** A named UI spacing token or typed CSS length. Defaults to xs. */
|
|
2009
|
+
gap?: UiSpaceName | CssLength;
|
|
2010
|
+
/** Allow this row to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
|
|
2011
|
+
flex?: boolean | CssFlexKeyword | CssFlex;
|
|
2012
|
+
/** Allow children to wrap onto additional lines. */
|
|
2013
|
+
wrap?: boolean;
|
|
2014
|
+
className?: string;
|
|
2015
|
+
}
|
|
2016
|
+
/** A horizontal flex row with explicit physical-axis alignment and spacing. */
|
|
2017
|
+
declare function Row({ children, hAlign, vAlign, gap, flex, wrap, className, }: RowProps): kerfjs.SafeHtml;
|
|
2018
|
+
|
|
2019
|
+
export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, Row, type RowProps, UiSpaceName, VerticalAlignment };
|
|
2020
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Web Awesome JSX signatures for the UI authoring corpus
|
|
2
2
|
|
|
3
|
-
Generated from the emitted `@kerfjs/ui@5.0.0-beta.
|
|
3
|
+
Generated from the emitted `@kerfjs/ui@5.0.0-beta.35` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
6
|
import { KerfCustomElement } from 'kerfjs/jsx-runtime';
|
|
@@ -16,10 +16,16 @@ function Row({
|
|
|
16
16
|
hAlign = "left",
|
|
17
17
|
vAlign = "full",
|
|
18
18
|
gap = "xs",
|
|
19
|
+
flex = false,
|
|
19
20
|
wrap = false,
|
|
20
21
|
className = ""
|
|
21
22
|
}) {
|
|
22
23
|
const gapValue = spaceNames.includes(gap) ? space(gap) : gap;
|
|
24
|
+
const flexValue = flex === true ? "1 1 auto" : flex || void 0;
|
|
25
|
+
const style = [
|
|
26
|
+
`--_kui-row-gap:${gapValue}`,
|
|
27
|
+
flexValue ? `--_kui-row-flex:${flexValue}` : ""
|
|
28
|
+
].filter(Boolean).join(";");
|
|
23
29
|
return /* @__PURE__ */ jsx(
|
|
24
30
|
"div",
|
|
25
31
|
{
|
|
@@ -27,8 +33,9 @@ function Row({
|
|
|
27
33
|
"data-component": "row",
|
|
28
34
|
"data-h-align": horizontalAlignment(hAlign),
|
|
29
35
|
"data-v-align": verticalAlignment(vAlign),
|
|
36
|
+
"data-flex": String(Boolean(flex)),
|
|
30
37
|
"data-wrap": String(wrap),
|
|
31
|
-
style
|
|
38
|
+
style,
|
|
32
39
|
children
|
|
33
40
|
}
|
|
34
41
|
);
|
|
@@ -36,4 +43,4 @@ function Row({
|
|
|
36
43
|
|
|
37
44
|
export { Row };
|
|
38
45
|
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
46
|
+
//# sourceMappingURL=chunk-QHCBZTDK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/row.tsx"],"names":[],"mappings":";;;;AAeA,IAAM,UAAA,GAAqC;AAAA,EACzC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA;AAkBO,SAAS,GAAA,CAAI;AAAA,EAClB,QAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,MAAA,GAAS,MAAA;AAAA,EACT,GAAA,GAAM,IAAA;AAAA,EACN,IAAA,GAAO,KAAA;AAAA,EACP,IAAA,GAAO,KAAA;AAAA,EACP,SAAA,GAAY;AACd,CAAA,EAAa;AACX,EAAA,MAAM,WAAW,UAAA,CAAW,QAAA,CAAS,GAAkB,CAAA,GACnD,KAAA,CAAM,GAAkB,CAAA,GACxB,GAAA;AACJ,EAAA,MAAM,SAAA,GAAY,IAAA,KAAS,IAAA,GAAO,UAAA,GAAa,IAAA,IAAQ,MAAA;AACvD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,kBAAkB,QAAQ,CAAA,CAAA;AAAA,IAC1B,SAAA,GAAY,CAAA,gBAAA,EAAmB,SAAS,CAAA,CAAA,GAAK;AAAA,GAC/C,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEX,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,QAAA,EAAW,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACnC,gBAAA,EAAe,KAAA;AAAA,MACf,cAAA,EAAc,oBAAoB,MAAM,CAAA;AAAA,MACxC,cAAA,EAAc,kBAAkB,MAAM,CAAA;AAAA,MACtC,WAAA,EAAW,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,MAC/B,WAAA,EAAW,OAAO,IAAI,CAAA;AAAA,MACtB,KAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-QHCBZTDK.js","sourcesContent":["import {\n type CssFlex,\n type CssFlexKeyword,\n type CssLength,\n space,\n type UiSpaceName,\n} from './css-values.js';\nimport {\n type HorizontalAlignment,\n horizontalAlignment,\n type VerticalAlignment,\n verticalAlignment,\n} from './flex-alignment.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nconst spaceNames: readonly UiSpaceName[] = [\n 'none',\n '2xs',\n 'xs',\n 's',\n 'm',\n 'l',\n 'xl',\n];\n\nexport interface RowProps {\n children?: KerfUiContent;\n /** Horizontal distribution. Defaults to left. */\n hAlign?: HorizontalAlignment;\n /** Vertical alignment and wrapped-line distribution. Defaults to full. */\n vAlign?: VerticalAlignment;\n /** A named UI spacing token or typed CSS length. Defaults to xs. */\n gap?: UiSpaceName | CssLength;\n /** Allow this row to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */\n flex?: boolean | CssFlexKeyword | CssFlex;\n /** Allow children to wrap onto additional lines. */\n wrap?: boolean;\n className?: string;\n}\n\n/** A horizontal flex row with explicit physical-axis alignment and spacing. */\nexport function Row({\n children,\n hAlign = 'left',\n vAlign = 'full',\n gap = 'xs',\n flex = false,\n wrap = false,\n className = '',\n}: RowProps) {\n const gapValue = spaceNames.includes(gap as UiSpaceName)\n ? space(gap as UiSpaceName)\n : gap;\n const flexValue = flex === true ? '1 1 auto' : flex || undefined;\n const style = [\n `--_kui-row-gap:${gapValue}`,\n flexValue ? `--_kui-row-flex:${flexValue}` : '',\n ]\n .filter(Boolean)\n .join(';');\n\n return (\n <div\n class={`kui-row ${className}`.trim()}\n data-component=\"row\"\n data-h-align={horizontalAlignment(hAlign)}\n data-v-align={verticalAlignment(vAlign)}\n data-flex={String(Boolean(flex))}\n data-wrap={String(wrap)}\n style={style}\n >\n {children}\n </div>\n );\n}\n\nexport type {\n CssFlex,\n CssFlexKeyword,\n CssLength,\n UiSpaceName,\n} from './css-values.js';\nexport type {\n HorizontalAlignment,\n VerticalAlignment,\n} from './flex-alignment.js';\n"]}
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ export { DialogSurface, PopupSurface } from './chunk-WSXUPSID.js';
|
|
|
10
10
|
export { TabBar } from './chunk-ZPWZIVI6.js';
|
|
11
11
|
export { ToolbarText } from './chunk-V6GQKOX2.js';
|
|
12
12
|
export { ResizableRegion, clampRegionSize, resizeRegionFromPointer } from './chunk-CAB6NQ2T.js';
|
|
13
|
-
export { Row } from './chunk-
|
|
13
|
+
export { Row } from './chunk-QHCBZTDK.js';
|
|
14
14
|
export { SegmentedControl } from './chunk-E34TE2ZI.js';
|
|
15
15
|
export { FloatingToolbar } from './chunk-DYBPI5O2.js';
|
|
16
16
|
export { ListActionRow } from './chunk-DAO2VFTT.js';
|
package/dist/row.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as kerfjs from 'kerfjs';
|
|
2
|
-
import { UiSpaceName, CssLength } from './css-values.js';
|
|
2
|
+
import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
|
|
3
3
|
import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-CF8NLj7i.js';
|
|
4
4
|
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
5
5
|
|
|
@@ -11,11 +11,13 @@ interface RowProps {
|
|
|
11
11
|
vAlign?: VerticalAlignment;
|
|
12
12
|
/** A named UI spacing token or typed CSS length. Defaults to xs. */
|
|
13
13
|
gap?: UiSpaceName | CssLength;
|
|
14
|
+
/** Allow this row to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
|
|
15
|
+
flex?: boolean | CssFlexKeyword | CssFlex;
|
|
14
16
|
/** Allow children to wrap onto additional lines. */
|
|
15
17
|
wrap?: boolean;
|
|
16
18
|
className?: string;
|
|
17
19
|
}
|
|
18
20
|
/** A horizontal flex row with explicit physical-axis alignment and spacing. */
|
|
19
|
-
declare function Row({ children, hAlign, vAlign, gap, wrap, className, }: RowProps): kerfjs.SafeHtml;
|
|
21
|
+
declare function Row({ children, hAlign, vAlign, gap, flex, wrap, className, }: RowProps): kerfjs.SafeHtml;
|
|
20
22
|
|
|
21
|
-
export { CssLength, HorizontalAlignment, Row, type RowProps, UiSpaceName, VerticalAlignment };
|
|
23
|
+
export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, Row, type RowProps, UiSpaceName, VerticalAlignment };
|
package/dist/row.js
CHANGED
package/dist/styles/row.css
CHANGED
|
@@ -269,7 +269,8 @@ Logical-edge separator lines are independently opt-in and default off.
|
|
|
269
269
|
geometry classes.
|
|
270
270
|
`List` is the corresponding layout-only vertical stack: its children stretch by
|
|
271
271
|
default, while `gap`, `flex`, and `scrollable` opt into typed spacing,
|
|
272
|
-
flex growth, and vertical scroll ownership. `
|
|
272
|
+
flex growth, and vertical scroll ownership. `Row.flex` uses the same typed flex
|
|
273
|
+
participation contract on the horizontal counterpart. `dividerSides` accepts canonical
|
|
273
274
|
physical top/right/bottom/left combinations such as `tr` and `trbl`; the stack
|
|
274
275
|
adds no list semantics, margin, or padding of its own. Use a direct finite
|
|
275
276
|
spacing shorthand such as `gap="2xs"`, or pass a `CssLength` created by the
|
|
@@ -280,7 +281,7 @@ length. Raw CSS strings and source-only `remify(4px)` are not valid runtime
|
|
|
280
281
|
props. The `CssLength` name intentionally includes percentages for UI dimension
|
|
281
282
|
props. Its opaque string brand improves authoring correctness; it is not a CSS
|
|
282
283
|
sanitizer or security boundary.
|
|
283
|
-
`List.flex` likewise
|
|
284
|
+
`Row.flex` and `List.flex` likewise accept their boolean default, finite keywords, or `CssFlex`
|
|
284
285
|
from `flex(grow, shrink, basis)`. `Skeleton` width/height use `CssSize`, radius
|
|
285
286
|
uses `CssLength`, and `SelectChoice.color` uses `CssColor` from `uiColor()` or
|
|
286
287
|
`colorVar()`. Never exchange these property grammars. List rows expose
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Public component integration workflow
|
|
2
|
+
|
|
3
|
+
The canonical `ai/component-catalog.json` is also the integration manifest for
|
|
4
|
+
first-party public components. Every entry with `source: "kerf"` and
|
|
5
|
+
`kind: "component"` projects into the package, build, root API, catalog demo,
|
|
6
|
+
and AI authoring surfaces. This keeps a new List-like primitive from reaching a
|
|
7
|
+
late build or release gate before an omitted surface is discovered.
|
|
8
|
+
|
|
9
|
+
Author the implementation, CSS, catalog facts, demo, and behavior tests first.
|
|
10
|
+
Then run:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm run component-integrations:dry-run
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The dry run reports every mismatched projection together, using diff-like
|
|
17
|
+
`expected` and `actual` lines without changing files or failing the command.
|
|
18
|
+
Resolve the complete report, build the package, regenerate signatures with
|
|
19
|
+
`npm run ai:signatures:sync`, and refresh reviewed compatibility digests with
|
|
20
|
+
`npm run ai:compatibility:sync`. `npm run check:component-integrations` runs the
|
|
21
|
+
same validator in failing CI mode, and the package `check` gate includes it.
|
|
22
|
+
|
|
23
|
+
For each catalog component, the validator checks:
|
|
24
|
+
|
|
25
|
+
- the source module and stylesheet;
|
|
26
|
+
- the tsup entry and typed package subpath, including the browser-conditioned
|
|
27
|
+
entry when the catalog declares `browserImport`;
|
|
28
|
+
- the CSS package export;
|
|
29
|
+
- root-barrel exposure for browser-conditioned components;
|
|
30
|
+
- the stable catalog route, demo module, and exhaustive demo registry; and
|
|
31
|
+
- inclusion of the public subpath in the generated AI signature reference.
|
|
32
|
+
|
|
33
|
+
The existing catalog sync and compatibility gates remain responsible for the
|
|
34
|
+
typed catalog projections, catalog count/order, and artifact digests. Public
|
|
35
|
+
API signatures derive component subpaths from the catalog, so a newly cataloged
|
|
36
|
+
component can no longer be silently omitted from that corpus.
|
|
37
|
+
|
|
38
|
+
Non-component helpers, wiring modules, compositions, recipes, and development
|
|
39
|
+
tools remain explicit package surfaces. They do not masquerade as visual
|
|
40
|
+
components merely to enter this workflow.
|
|
41
|
+
|
|
42
|
+
## Change-local verification and bundle review
|
|
43
|
+
|
|
44
|
+
Run `npm run check:change` after changing a public component. It synchronizes
|
|
45
|
+
both catalog projections, declarations, AI signatures, and compatibility
|
|
46
|
+
digests; names every checked-in projection changed by that synchronization;
|
|
47
|
+
runs the catalog/component contracts, unit coverage, consumer bundle tests,
|
|
48
|
+
source and packed type contracts; builds the production catalog; and reports
|
|
49
|
+
the exact gzip byte delta from the last reviewed baseline. The broader
|
|
50
|
+
`npm run check` remains the release gate.
|
|
51
|
+
|
|
52
|
+
Intentional bundle changes use the same workflow with an explicit review
|
|
53
|
+
reason:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm run check:change -- --update-bundle-budget \
|
|
57
|
+
--reason "Added the reviewed List detail states and keyboard behavior"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
That mode writes `demo-bundle-budget.json`, records the previous and new exact
|
|
61
|
+
measurements and budgets with the reason and timestamp, and rounds the total
|
|
62
|
+
budget to the next 100 bytes. Do not edit the budget or add a history comment
|
|
63
|
+
by hand.
|
|
@@ -66,7 +66,7 @@ contract lands before the 5.0 stable release so misspelled tokens and incomplete
|
|
|
66
66
|
expressions fail during typechecking rather than in the browser.
|
|
67
67
|
|
|
68
68
|
Other CSS-valued props use distinct contracts: `flex()` creates `CssFlex` for
|
|
69
|
-
`List.flex`; `Skeleton` dimensions take typed lengths (plus finite intrinsic
|
|
69
|
+
`Row.flex` and `List.flex`; `Skeleton` dimensions take typed lengths (plus finite intrinsic
|
|
70
70
|
keywords for width/height); and `uiColor()`/`colorVar()` create `CssColor` for
|
|
71
71
|
`SelectChoice.color`. Do not substitute one brand for another. Row components
|
|
72
72
|
have no declaration-string `style` prop; use `className`, documented public
|
package/docs/layout.md
CHANGED
|
@@ -136,6 +136,13 @@ items, while applying the requested distribution to `align-content` when a
|
|
|
136
136
|
Row wraps. Prefer the descriptive values in application code; the short and
|
|
137
137
|
CSS-shaped aliases are provided for compact or migrated call sites.
|
|
138
138
|
|
|
139
|
+
`Row.flex` and `List.flex` share one typed participation contract. Omit the prop
|
|
140
|
+
for the CSS initial value, pass `true` for `1 1 auto`, select the finite
|
|
141
|
+
`"none"`, `"auto"`, or `"initial"` keyword, or use
|
|
142
|
+
`flex(grow, shrink, basis)` from `@kerfjs/ui/css-values` for a complete branded
|
|
143
|
+
shorthand. A `CssLength` is not a flex shorthand, and arbitrary strings are
|
|
144
|
+
rejected by the type contract.
|
|
145
|
+
|
|
139
146
|
`--kui-space-s` (12px) and `--kui-space-xl` (32px) exist but are **off the
|
|
140
147
|
canonical rhythm** — reach for them only as a deliberate exception, never as a
|
|
141
148
|
default step. Prefer the five canonical tokens so spacing stays legible and
|
package/docs/ux-demo.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Run `npm run dev` from `ui/`. The catalog is a development and review surface, not a second implementation. The development server allows repo-owned assets used by the catalog, and its production bundle uses relative asset URLs so the complete catalog remains intact below preview and proxy paths.
|
|
4
4
|
|
|
5
|
+
Every Playwright entry point builds current source before the preview server
|
|
6
|
+
starts. `npm run test:e2e -- tests/browser/row.spec.ts` and a direct focused
|
|
7
|
+
`npx playwright test tests/browser/row.spec.ts` both run catalog generation and
|
|
8
|
+
demo-conformance preflights, build the package and production catalog, then
|
|
9
|
+
launch Chromium, Firefox, and WebKit. The build emits
|
|
10
|
+
`source-freshness.json`; browser coverage compares it with an independent hash
|
|
11
|
+
of the current `src/` and `ux-demo/` inputs, so a stale `dist-demo` cannot pass
|
|
12
|
+
after a route or component edit. `npm run demo:serve` remains a preview-only
|
|
13
|
+
command for an already-built catalog.
|
|
14
|
+
|
|
5
15
|
Seven lazy production-composition routes live under the `Recipes` category.
|
|
6
16
|
Each `?component=recipe-*` route uses public package primitives, real wiring,
|
|
7
17
|
deterministic state, and semantic layout owners from the [recipe guide](./recipes.md).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kerfjs/ui",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.35",
|
|
4
4
|
"description": "Accessible, composable UI primitives for kerf applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -329,11 +329,15 @@
|
|
|
329
329
|
"dev": "npm run build && vite --config ux-demo/vite.config.ts",
|
|
330
330
|
"demo:build": "npm run build && vite build --config ux-demo/vite.config.ts && node scripts/check-demo-bundle.mjs",
|
|
331
331
|
"demo:serve": "vite preview --config ux-demo/vite.config.ts",
|
|
332
|
+
"test:e2e:serve": "npm run check:catalog && npm run check:demo-conformance && npm run demo:build && npm run demo:serve",
|
|
332
333
|
"format": "prettier --write . --ignore-unknown",
|
|
333
334
|
"format:css": "prettier --write \"src/**/*.css\" \"ux-demo/**/*.css\"",
|
|
334
335
|
"check:format": "prettier --check . --ignore-unknown",
|
|
335
336
|
"catalog:sync": "node scripts/sync-component-catalog.mjs && node scripts/sync-component-catalog-v2.mjs",
|
|
336
337
|
"catalog:v2:sync": "node scripts/sync-component-catalog-v2.mjs",
|
|
338
|
+
"check:component-integrations": "node scripts/check-component-integrations.mjs",
|
|
339
|
+
"component-integrations:dry-run": "node scripts/check-component-integrations.mjs --dry-run",
|
|
340
|
+
"check:change": "node scripts/check-ui-change.mjs",
|
|
337
341
|
"check:catalog": "node scripts/sync-component-catalog.mjs --check && node scripts/sync-component-catalog-v2.mjs --check && node scripts/check-component-catalog.mjs",
|
|
338
342
|
"check:profile": "node scripts/check-application-ui-profile.mjs",
|
|
339
343
|
"check:demo-conformance": "node scripts/check-catalog-demo-conformance.mjs",
|
|
@@ -341,6 +345,8 @@
|
|
|
341
345
|
"check:ai-regressions": "node scripts/check-ai-regressions.mjs && node scripts/audit-ai-regression-results.mjs && node scripts/audit-ai-regression-results-v3.mjs",
|
|
342
346
|
"check:ai-signatures": "node scripts/sync-ai-public-signatures.mjs --check",
|
|
343
347
|
"ai:signatures:sync": "npm run build && node scripts/sync-ai-public-signatures.mjs",
|
|
348
|
+
"check:ai-compatibility": "node scripts/sync-ai-compatibility.mjs",
|
|
349
|
+
"ai:compatibility:sync": "node scripts/sync-ai-compatibility.mjs --write",
|
|
344
350
|
"ai:regressions:compile": "node scripts/compile-ai-regression-response.mjs",
|
|
345
351
|
"ai:regressions:prepare": "node scripts/prepare-ai-regression.mjs",
|
|
346
352
|
"ai:regressions:record": "node scripts/record-ai-regression-run.mjs",
|
|
@@ -360,8 +366,8 @@
|
|
|
360
366
|
"test:contract-types:source": "node node_modules/typescript7/bin/tsc -p tests/consumer-types/contracts/tsconfig.source.json",
|
|
361
367
|
"test:contract-types:packed": "node scripts/check-packed-type-contracts.mjs",
|
|
362
368
|
"test:consumer-types": "npm run test:contract-types:source && npm run build && node node_modules/typescript7/bin/tsc -p tests/consumer-types/webawesome/tsconfig.json && npm run test:contract-types:packed",
|
|
363
|
-
"test:e2e": "
|
|
364
|
-
"check": "npm run check:catalog && npm run check:profile && npm run check:demo-conformance && npm run check:recipes && npm run check:guidance && npm run check:ai-regressions && npm run lint && npm run typecheck && npm test && npm run test:consumer-types && npm run check:ai-signatures && npm run demo:build && npm run check:design-templates && npm pack --dry-run",
|
|
369
|
+
"test:e2e": "playwright test",
|
|
370
|
+
"check": "npm run check:catalog && npm run check:component-integrations && npm run check:profile && npm run check:demo-conformance && npm run check:recipes && npm run check:guidance && npm run check:ai-compatibility && npm run check:ai-regressions && npm run lint && npm run typecheck && npm test && npm run test:consumer-types && npm run check:ai-signatures && npm run demo:build && npm run check:design-templates && npm pack --dry-run",
|
|
365
371
|
"prepublishOnly": "npm run check",
|
|
366
372
|
"check:design-templates": "node scripts/check-design-templates.mjs",
|
|
367
373
|
"check:design-templates:drift": "node scripts/check-design-templates-drift.mjs",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/row.tsx"],"names":[],"mappings":";;;;AASA,IAAM,UAAA,GAAqC;AAAA,EACzC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA;AAgBO,SAAS,GAAA,CAAI;AAAA,EAClB,QAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,MAAA,GAAS,MAAA;AAAA,EACT,GAAA,GAAM,IAAA;AAAA,EACN,IAAA,GAAO,KAAA;AAAA,EACP,SAAA,GAAY;AACd,CAAA,EAAa;AACX,EAAA,MAAM,WAAW,UAAA,CAAW,QAAA,CAAS,GAAkB,CAAA,GACnD,KAAA,CAAM,GAAkB,CAAA,GACxB,GAAA;AAEJ,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,QAAA,EAAW,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACnC,gBAAA,EAAe,KAAA;AAAA,MACf,cAAA,EAAc,oBAAoB,MAAM,CAAA;AAAA,MACxC,cAAA,EAAc,kBAAkB,MAAM,CAAA;AAAA,MACtC,WAAA,EAAW,OAAO,IAAI,CAAA;AAAA,MACtB,KAAA,EAAO,kBAAkB,QAAQ,CAAA,CAAA;AAAA,MAEhC;AAAA;AAAA,GACH;AAEJ","file":"chunk-OKRCKIVO.js","sourcesContent":["import { type CssLength, space, type UiSpaceName } from './css-values.js';\nimport {\n type HorizontalAlignment,\n horizontalAlignment,\n type VerticalAlignment,\n verticalAlignment,\n} from './flex-alignment.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nconst spaceNames: readonly UiSpaceName[] = [\n 'none',\n '2xs',\n 'xs',\n 's',\n 'm',\n 'l',\n 'xl',\n];\n\nexport interface RowProps {\n children?: KerfUiContent;\n /** Horizontal distribution. Defaults to left. */\n hAlign?: HorizontalAlignment;\n /** Vertical alignment and wrapped-line distribution. Defaults to full. */\n vAlign?: VerticalAlignment;\n /** A named UI spacing token or typed CSS length. Defaults to xs. */\n gap?: UiSpaceName | CssLength;\n /** Allow children to wrap onto additional lines. */\n wrap?: boolean;\n className?: string;\n}\n\n/** A horizontal flex row with explicit physical-axis alignment and spacing. */\nexport function Row({\n children,\n hAlign = 'left',\n vAlign = 'full',\n gap = 'xs',\n wrap = false,\n className = '',\n}: RowProps) {\n const gapValue = spaceNames.includes(gap as UiSpaceName)\n ? space(gap as UiSpaceName)\n : gap;\n\n return (\n <div\n class={`kui-row ${className}`.trim()}\n data-component=\"row\"\n data-h-align={horizontalAlignment(hAlign)}\n data-v-align={verticalAlignment(vAlign)}\n data-wrap={String(wrap)}\n style={`--_kui-row-gap:${gapValue}`}\n >\n {children}\n </div>\n );\n}\n\nexport type { CssLength, UiSpaceName } from './css-values.js';\nexport type {\n HorizontalAlignment,\n VerticalAlignment,\n} from './flex-alignment.js';\n"]}
|