@kerfjs/ui 5.0.0-beta.32 → 5.0.0-beta.34
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 +8 -1
- package/ai/component-catalog-v2-overrides.json +10 -0
- package/ai/component-catalog-v2.json +78 -2
- package/ai/component-catalog.json +90 -3
- package/ai/public-api-signatures-v1.md +8 -3
- package/ai/skill.md +11 -2
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/browser/row.js +3 -0
- package/dist/catalog.js +2 -1
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-RL6COPKF.js → chunk-7JQAQWVC.js} +6 -1
- package/dist/chunk-7JQAQWVC.js.map +1 -0
- package/dist/chunk-OKRCKIVO.js +39 -0
- package/dist/chunk-OKRCKIVO.js.map +1 -0
- package/dist/chunk-R3EBGEAW.js +46 -0
- package/dist/chunk-R3EBGEAW.js.map +1 -0
- package/dist/flex-alignment-CF8NLj7i.d.ts +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -4
- package/dist/list.d.ts +7 -2
- package/dist/list.js +2 -1
- package/dist/row.d.ts +21 -0
- package/dist/row.js +5 -0
- package/dist/row.js.map +1 -0
- package/dist/select-register.js +126 -1
- package/dist/select-register.js.map +1 -1
- package/dist/styles/list.css +29 -0
- package/dist/styles/row.css +45 -0
- package/dist/styles/styles.css +1 -0
- package/docs/accessibility.md +13 -0
- package/docs/component-selection.md +6 -4
- package/docs/layout.md +19 -1
- package/llms.txt +8 -2
- package/package.json +7 -1
- package/dist/chunk-RL6COPKF.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/list.tsx"],"names":[],"mappings":";;;;AAgBA,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;AAoBO,SAAS,IAAA,CAAK;AAAA,EACnB,QAAA;AAAA,EACA,GAAA,GAAM,KAAA;AAAA,EACN,IAAA,GAAO,KAAA;AAAA,EACP,MAAA,GAAS,MAAA;AAAA,EACT,MAAA,GAAS,KAAA;AAAA,EACT,UAAA,GAAa,KAAA;AAAA,EACb,YAAA,GAAe,EAAA;AAAA,EACf,SAAA,GAAY;AACd,CAAA,EAAc;AACZ,EAAA,MAAM,QAAA,GACJ,GAAA,KAAQ,IAAA,GACJ,qBAAA,GACA,UAAA,CAAW,QAAA,CAAS,GAAkB,CAAA,GACpC,KAAA,CAAM,GAAkB,CAAA,GACxB,GAAA,IAAO,MAAA;AACf,EAAA,MAAM,SAAA,GAAY,IAAA,KAAS,IAAA,GAAO,UAAA,GAAa,IAAA,IAAQ,MAAA;AACvD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,QAAA,GAAW,CAAA,gBAAA,EAAmB,QAAQ,CAAA,CAAA,GAAK,EAAA;AAAA,IAC3C,SAAA,GAAY,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,GAAK;AAAA,GAChD,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEX,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,SAAA,EAAY,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACpC,gBAAA,EAAe,MAAA;AAAA,MACf,UAAA,EAAU,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA,MAC7B,WAAA,EAAW,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,MAC/B,cAAA,EAAc,oBAAoB,MAAM,CAAA;AAAA,MACxC,cAAA,EAAc,kBAAkB,MAAM,CAAA;AAAA,MACtC,iBAAA,EAAiB,OAAO,UAAU,CAAA;AAAA,MAClC,iBAAe,YAAA,IAAgB,MAAA;AAAA,MAC/B,OAAO,KAAA,IAAS,MAAA;AAAA,MAEf;AAAA;AAAA,GACH;AAEJ","file":"chunk-7JQAQWVC.js","sourcesContent":["import {\n type CssFlex,\n type CssFlexKeyword,\n type CssLength,\n space,\n type UiSpaceName,\n} from './css-values.js';\nimport type { DividerSides } from './divider-sides.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 ListProps {\n children?: KerfUiContent;\n /** Use the standard item gap, a named UI spacing token, or a typed CSS length. Defaults to no gap. */\n gap?: boolean | UiSpaceName | CssLength;\n /** Allow this list to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */\n flex?: boolean | CssFlexKeyword | CssFlex;\n /** Horizontal alignment. Defaults to full to preserve stretch-aligned list children. */\n hAlign?: HorizontalAlignment;\n /** Vertical distribution. Defaults to top. */\n vAlign?: VerticalAlignment;\n /** Own vertical scrolling and overscroll containment. */\n scrollable?: boolean;\n /** Physical divider edges in canonical top/right/bottom/left order. */\n dividerSides?: DividerSides;\n className?: string;\n}\n\n/** A stretch-aligned vertical stack with optional gap, flex, scroll, and dividers. */\nexport function List({\n children,\n gap = false,\n flex = false,\n hAlign = 'full',\n vAlign = 'top',\n scrollable = false,\n dividerSides = '',\n className = '',\n}: ListProps) {\n const gapValue =\n gap === true\n ? 'var(--kui-list-gap)'\n : spaceNames.includes(gap as UiSpaceName)\n ? space(gap as UiSpaceName)\n : gap || undefined;\n const flexValue = flex === true ? '1 1 auto' : flex || undefined;\n const style = [\n gapValue ? `--_kui-list-gap:${gapValue}` : '',\n flexValue ? `--_kui-list-flex:${flexValue}` : '',\n ]\n .filter(Boolean)\n .join(';');\n\n return (\n <div\n class={`kui-list ${className}`.trim()}\n data-component=\"list\"\n data-gap={String(Boolean(gap))}\n data-flex={String(Boolean(flex))}\n data-h-align={horizontalAlignment(hAlign)}\n data-v-align={verticalAlignment(vAlign)}\n data-scrollable={String(scrollable)}\n divider-sides={dividerSides || undefined}\n style={style || undefined}\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 { DividerSides } from './divider-sides.js';\nexport type {\n HorizontalAlignment,\n VerticalAlignment,\n} from './flex-alignment.js';\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { verticalAlignment, horizontalAlignment } from './chunk-R3EBGEAW.js';
|
|
2
|
+
import { space } from './chunk-OL4TC3U2.js';
|
|
3
|
+
import { jsx } from 'kerfjs/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var spaceNames = [
|
|
6
|
+
"none",
|
|
7
|
+
"2xs",
|
|
8
|
+
"xs",
|
|
9
|
+
"s",
|
|
10
|
+
"m",
|
|
11
|
+
"l",
|
|
12
|
+
"xl"
|
|
13
|
+
];
|
|
14
|
+
function Row({
|
|
15
|
+
children,
|
|
16
|
+
hAlign = "left",
|
|
17
|
+
vAlign = "full",
|
|
18
|
+
gap = "xs",
|
|
19
|
+
wrap = false,
|
|
20
|
+
className = ""
|
|
21
|
+
}) {
|
|
22
|
+
const gapValue = spaceNames.includes(gap) ? space(gap) : gap;
|
|
23
|
+
return /* @__PURE__ */ jsx(
|
|
24
|
+
"div",
|
|
25
|
+
{
|
|
26
|
+
class: `kui-row ${className}`.trim(),
|
|
27
|
+
"data-component": "row",
|
|
28
|
+
"data-h-align": horizontalAlignment(hAlign),
|
|
29
|
+
"data-v-align": verticalAlignment(vAlign),
|
|
30
|
+
"data-wrap": String(wrap),
|
|
31
|
+
style: `--_kui-row-gap:${gapValue}`,
|
|
32
|
+
children
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { Row };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=chunk-OKRCKIVO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// src/flex-alignment.ts
|
|
2
|
+
function horizontalAlignment(value) {
|
|
3
|
+
switch (value) {
|
|
4
|
+
case "left":
|
|
5
|
+
case "l":
|
|
6
|
+
case "flex-start":
|
|
7
|
+
return "left";
|
|
8
|
+
case "center":
|
|
9
|
+
case "c":
|
|
10
|
+
case "space-around":
|
|
11
|
+
return "center";
|
|
12
|
+
case "right":
|
|
13
|
+
case "r":
|
|
14
|
+
case "flex-end":
|
|
15
|
+
return "right";
|
|
16
|
+
case "full":
|
|
17
|
+
case "f":
|
|
18
|
+
case "space-between":
|
|
19
|
+
return "full";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function verticalAlignment(value) {
|
|
23
|
+
switch (value) {
|
|
24
|
+
case "top":
|
|
25
|
+
case "t":
|
|
26
|
+
case "flex-start":
|
|
27
|
+
return "top";
|
|
28
|
+
case "middle":
|
|
29
|
+
case "m":
|
|
30
|
+
case "c":
|
|
31
|
+
case "space-around":
|
|
32
|
+
return "middle";
|
|
33
|
+
case "bottom":
|
|
34
|
+
case "b":
|
|
35
|
+
case "flex-end":
|
|
36
|
+
return "bottom";
|
|
37
|
+
case "full":
|
|
38
|
+
case "f":
|
|
39
|
+
case "space-between":
|
|
40
|
+
return "full";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { horizontalAlignment, verticalAlignment };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=chunk-R3EBGEAW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/flex-alignment.ts"],"names":[],"mappings":";AAgCO,SAAS,oBACd,KAAA,EAC8B;AAC9B,EAAA,QAAQ,KAAA;AAAO,IACb,KAAK,MAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,YAAA;AACH,MAAA,OAAO,MAAA;AAAA,IACT,KAAK,QAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,cAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,OAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,UAAA;AACH,MAAA,OAAO,OAAA;AAAA,IACT,KAAK,MAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,eAAA;AACH,MAAA,OAAO,MAAA;AAAA;AAEb;AAEO,SAAS,kBACd,KAAA,EAC4B;AAC5B,EAAA,QAAQ,KAAA;AAAO,IACb,KAAK,KAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,YAAA;AACH,MAAA,OAAO,KAAA;AAAA,IACT,KAAK,QAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,cAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,QAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,UAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,MAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,eAAA;AACH,MAAA,OAAO,MAAA;AAAA;AAEb","file":"chunk-R3EBGEAW.js","sourcesContent":["export type HorizontalAlignment =\n | 'left'\n | 'l'\n | 'flex-start'\n | 'center'\n | 'c'\n | 'space-around'\n | 'right'\n | 'r'\n | 'flex-end'\n | 'full'\n | 'f'\n | 'space-between';\n\nexport type VerticalAlignment =\n | 'top'\n | 't'\n | 'flex-start'\n | 'middle'\n | 'm'\n | 'c'\n | 'space-around'\n | 'bottom'\n | 'b'\n | 'flex-end'\n | 'full'\n | 'f'\n | 'space-between';\n\nexport type CanonicalHorizontalAlignment = 'left' | 'center' | 'right' | 'full';\nexport type CanonicalVerticalAlignment = 'top' | 'middle' | 'bottom' | 'full';\n\nexport function horizontalAlignment(\n value: HorizontalAlignment,\n): CanonicalHorizontalAlignment {\n switch (value) {\n case 'left':\n case 'l':\n case 'flex-start':\n return 'left';\n case 'center':\n case 'c':\n case 'space-around':\n return 'center';\n case 'right':\n case 'r':\n case 'flex-end':\n return 'right';\n case 'full':\n case 'f':\n case 'space-between':\n return 'full';\n }\n}\n\nexport function verticalAlignment(\n value: VerticalAlignment,\n): CanonicalVerticalAlignment {\n switch (value) {\n case 'top':\n case 't':\n case 'flex-start':\n return 'top';\n case 'middle':\n case 'm':\n case 'c':\n case 'space-around':\n return 'middle';\n case 'bottom':\n case 'b':\n case 'flex-end':\n return 'bottom';\n case 'full':\n case 'f':\n case 'space-between':\n return 'full';\n }\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
type HorizontalAlignment = 'left' | 'l' | 'flex-start' | 'center' | 'c' | 'space-around' | 'right' | 'r' | 'flex-end' | 'full' | 'f' | 'space-between';
|
|
2
|
+
type VerticalAlignment = 'top' | 't' | 'flex-start' | 'middle' | 'm' | 'c' | 'space-around' | 'bottom' | 'b' | 'flex-end' | 'full' | 'f' | 'space-between';
|
|
3
|
+
|
|
4
|
+
export type { HorizontalAlignment as H, VerticalAlignment as V };
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export { LoadingSpinner, LoadingSpinnerProps } from './loading-spinner.js';
|
|
|
13
13
|
export { LucideIcon, LucideIconProps, LucideNode } from './lucide-icon.js';
|
|
14
14
|
export { Pane, PaneContentElement, PaneElement, PaneProps, PaneSeparatorSide } from './pane.js';
|
|
15
15
|
export { ResizableRegion, ResizableRegionAxis, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionEdge, ResizableRegionPresentation, ResizableRegionProps, ResizableRegionRestorePosition, ResizableRegionSeparator, clampRegionSize, resizeRegionFromPointer } from './resizable-region.js';
|
|
16
|
+
export { Row, RowProps } from './row.js';
|
|
16
17
|
export { SegmentedControl, SegmentedControlAppearance, SegmentedControlChoice, SegmentedControlLayout, SegmentedControlProps, SegmentedControlShape, SegmentedControlSize } from './segmented-control.js';
|
|
17
18
|
export { Select, SelectChoice, SelectFocusRingOwner, SelectPresentation, SelectProps, SelectSelectedPresentation, SelectSize } from './select.js';
|
|
18
19
|
export { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
@@ -30,5 +31,6 @@ export { ResizeCommit, WireResizableRegionsOptions, wireResizableRegions } from
|
|
|
30
31
|
export { TabDropPosition, TabReorder, TabReorderSource, WireTabBarsOptions, reorderTabs, wireTabBars } from './wire-tab-bars.js';
|
|
31
32
|
export { TokenSearchCollapsibleOptions, TokenSearchEdit, TokenSearchFieldsHandle, TokenSearchSubmit, WireTokenSearchFieldsOptions, wireTokenSearchFields } from './wire-token-search-fields.js';
|
|
32
33
|
export { D as DividerSides } from './divider-sides-267FA7sY.js';
|
|
34
|
+
export { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-CF8NLj7i.js';
|
|
33
35
|
import 'kerfjs';
|
|
34
36
|
import 'lucide';
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
export { wireResizableRegions } from './chunk-WN52USHV.js';
|
|
1
2
|
export { reorderTabs, wireTabBars } from './chunk-UKKSMZYT.js';
|
|
2
3
|
export { wireTokenSearchFields } from './chunk-VDUJZF5G.js';
|
|
4
|
+
export { TokenSearchField, placeTokenSearchCaret, readTokenSearchField } from './chunk-TIGSG6BX.js';
|
|
3
5
|
export { ValueTable, ValueTableRow } from './chunk-V6HCTCVD.js';
|
|
4
|
-
export {
|
|
6
|
+
export { Select } from './chunk-CK6P5AUK.js';
|
|
5
7
|
export { StateBanner } from './chunk-UDHHKZWO.js';
|
|
6
8
|
export { SunkenPanel } from './chunk-SOK5EUF7.js';
|
|
7
9
|
export { DialogSurface, PopupSurface } from './chunk-WSXUPSID.js';
|
|
8
10
|
export { TabBar } from './chunk-ZPWZIVI6.js';
|
|
9
|
-
export { TokenSearchField, placeTokenSearchCaret, readTokenSearchField } from './chunk-TIGSG6BX.js';
|
|
10
11
|
export { ToolbarText } from './chunk-V6GQKOX2.js';
|
|
11
12
|
export { ResizableRegion, clampRegionSize, resizeRegionFromPointer } from './chunk-CAB6NQ2T.js';
|
|
13
|
+
export { Row } from './chunk-OKRCKIVO.js';
|
|
12
14
|
export { SegmentedControl } from './chunk-E34TE2ZI.js';
|
|
13
|
-
export { Select } from './chunk-CK6P5AUK.js';
|
|
14
15
|
export { FloatingToolbar } from './chunk-DYBPI5O2.js';
|
|
15
16
|
export { ListActionRow } from './chunk-DAO2VFTT.js';
|
|
16
17
|
export { ListInsetControl } from './chunk-MFR2IIFG.js';
|
|
@@ -21,7 +22,8 @@ export { Toolbar } from './chunk-VXFGMDA7.js';
|
|
|
21
22
|
export { Pane } from './chunk-I4V3UDSA.js';
|
|
22
23
|
export { ListHeader } from './chunk-OC275HHS.js';
|
|
23
24
|
export { ListItem } from './chunk-I45QO2IZ.js';
|
|
24
|
-
export { List } from './chunk-
|
|
25
|
+
export { List } from './chunk-7JQAQWVC.js';
|
|
26
|
+
|
|
25
27
|
|
|
26
28
|
export { Skeleton } from './chunk-T7DOWS6T.js';
|
|
27
29
|
export { calc, colorVar, em, flex, lengthVar, pct, plus, px, rem, space, uiColor } from './chunk-OL4TC3U2.js';
|
package/dist/list.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as kerfjs from 'kerfjs';
|
|
2
2
|
import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
|
|
3
3
|
import { D as DividerSides } from './divider-sides-267FA7sY.js';
|
|
4
|
+
import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-CF8NLj7i.js';
|
|
4
5
|
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
5
6
|
|
|
6
7
|
interface ListProps {
|
|
@@ -9,6 +10,10 @@ interface ListProps {
|
|
|
9
10
|
gap?: boolean | UiSpaceName | CssLength;
|
|
10
11
|
/** Allow this list to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
|
|
11
12
|
flex?: boolean | CssFlexKeyword | CssFlex;
|
|
13
|
+
/** Horizontal alignment. Defaults to full to preserve stretch-aligned list children. */
|
|
14
|
+
hAlign?: HorizontalAlignment;
|
|
15
|
+
/** Vertical distribution. Defaults to top. */
|
|
16
|
+
vAlign?: VerticalAlignment;
|
|
12
17
|
/** Own vertical scrolling and overscroll containment. */
|
|
13
18
|
scrollable?: boolean;
|
|
14
19
|
/** Physical divider edges in canonical top/right/bottom/left order. */
|
|
@@ -16,6 +21,6 @@ interface ListProps {
|
|
|
16
21
|
className?: string;
|
|
17
22
|
}
|
|
18
23
|
/** A stretch-aligned vertical stack with optional gap, flex, scroll, and dividers. */
|
|
19
|
-
declare function List({ children, gap, flex, scrollable, dividerSides, className, }: ListProps): kerfjs.SafeHtml;
|
|
24
|
+
declare function List({ children, gap, flex, hAlign, vAlign, scrollable, dividerSides, className, }: ListProps): kerfjs.SafeHtml;
|
|
20
25
|
|
|
21
|
-
export { CssFlex, CssFlexKeyword, CssLength, DividerSides, List, type ListProps, UiSpaceName };
|
|
26
|
+
export { CssFlex, CssFlexKeyword, CssLength, DividerSides, HorizontalAlignment, List, type ListProps, UiSpaceName, VerticalAlignment };
|
package/dist/list.js
CHANGED
package/dist/row.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as kerfjs from 'kerfjs';
|
|
2
|
+
import { UiSpaceName, CssLength } from './css-values.js';
|
|
3
|
+
import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-CF8NLj7i.js';
|
|
4
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
5
|
+
|
|
6
|
+
interface RowProps {
|
|
7
|
+
children?: KerfUiContent;
|
|
8
|
+
/** Horizontal distribution. Defaults to left. */
|
|
9
|
+
hAlign?: HorizontalAlignment;
|
|
10
|
+
/** Vertical alignment and wrapped-line distribution. Defaults to full. */
|
|
11
|
+
vAlign?: VerticalAlignment;
|
|
12
|
+
/** A named UI spacing token or typed CSS length. Defaults to xs. */
|
|
13
|
+
gap?: UiSpaceName | CssLength;
|
|
14
|
+
/** Allow children to wrap onto additional lines. */
|
|
15
|
+
wrap?: boolean;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
/** A horizontal flex row with explicit physical-axis alignment and spacing. */
|
|
19
|
+
declare function Row({ children, hAlign, vAlign, gap, wrap, className, }: RowProps): kerfjs.SafeHtml;
|
|
20
|
+
|
|
21
|
+
export { CssLength, HorizontalAlignment, Row, type RowProps, UiSpaceName, VerticalAlignment };
|
package/dist/row.js
ADDED
package/dist/row.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"row.js"}
|
package/dist/select-register.js
CHANGED
|
@@ -3,9 +3,134 @@ import '@awesome.me/webawesome/dist/components/divider/divider.js';
|
|
|
3
3
|
import '@awesome.me/webawesome/dist/components/dropdown/dropdown.js';
|
|
4
4
|
import '@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js';
|
|
5
5
|
import '@awesome.me/webawesome/dist/components/option/option.js';
|
|
6
|
-
import '@awesome.me/webawesome/dist/components/select/select.js';
|
|
6
|
+
import WaSelect from '@awesome.me/webawesome/dist/components/select/select.js';
|
|
7
|
+
import { WaAfterHideEvent } from '@awesome.me/webawesome/dist/events/after-hide.js';
|
|
8
|
+
import { WaAfterShowEvent } from '@awesome.me/webawesome/dist/events/after-show.js';
|
|
9
|
+
import { WaHideEvent } from '@awesome.me/webawesome/dist/events/hide.js';
|
|
10
|
+
import { WaShowEvent } from '@awesome.me/webawesome/dist/events/show.js';
|
|
7
11
|
|
|
8
12
|
// src/select-register.ts
|
|
13
|
+
|
|
14
|
+
// src/animate-select-popup.ts
|
|
15
|
+
function animateSelectPopup(popup, phase, signal) {
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
let settled = false;
|
|
18
|
+
let frame = 0;
|
|
19
|
+
const finish = () => {
|
|
20
|
+
if (settled) return;
|
|
21
|
+
settled = true;
|
|
22
|
+
window.cancelAnimationFrame(frame);
|
|
23
|
+
signal.removeEventListener("abort", finish);
|
|
24
|
+
popup.classList.remove(phase);
|
|
25
|
+
resolve();
|
|
26
|
+
};
|
|
27
|
+
signal.addEventListener("abort", finish, { once: true });
|
|
28
|
+
popup.classList.add(phase);
|
|
29
|
+
frame = window.requestAnimationFrame(() => {
|
|
30
|
+
void Promise.all(
|
|
31
|
+
popup.getAnimations().map((animation) => animation.finished.catch(() => void 0))
|
|
32
|
+
).then(finish);
|
|
33
|
+
});
|
|
34
|
+
if (signal.aborted) finish();
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/install-select-lifecycle.ts
|
|
39
|
+
function installSelectLifecycle(prototype) {
|
|
40
|
+
const installed = /* @__PURE__ */ Symbol.for("@kerfjs/ui/select-lifecycle");
|
|
41
|
+
if (Object.prototype.hasOwnProperty.call(prototype, installed)) return;
|
|
42
|
+
Object.defineProperty(prototype, installed, { value: true });
|
|
43
|
+
const original = prototype.handleOpenChange;
|
|
44
|
+
const originalDisabled = prototype.handleDisabledChange;
|
|
45
|
+
prototype.handleDisabledChange = function() {
|
|
46
|
+
const host = this;
|
|
47
|
+
const wasOpen = host.open;
|
|
48
|
+
originalDisabled.call(this);
|
|
49
|
+
if (host.dataset.component === "select" && wasOpen && !host.open) {
|
|
50
|
+
void host.handleOpenChange();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const transitions = /* @__PURE__ */ new WeakMap();
|
|
54
|
+
const restorations = /* @__PURE__ */ new WeakMap();
|
|
55
|
+
prototype.handleOpenChange = async function() {
|
|
56
|
+
const host = this;
|
|
57
|
+
if (host.dataset.component !== "select") return original.call(this);
|
|
58
|
+
const restoring = restorations.get(host)?.open === host.open;
|
|
59
|
+
restorations.delete(host);
|
|
60
|
+
if (restoring) return;
|
|
61
|
+
const transition = new AbortController();
|
|
62
|
+
const opening = host.open && !host.disabled;
|
|
63
|
+
const current = () => !transition.signal.aborted && host.isConnected && (host.open && !host.disabled) === opening;
|
|
64
|
+
try {
|
|
65
|
+
if (!host.isConnected) return;
|
|
66
|
+
if (opening) {
|
|
67
|
+
host.setCurrentOption(host.selectedOptions[0] || host.getFirstOption());
|
|
68
|
+
}
|
|
69
|
+
const event = opening ? new WaShowEvent() : new WaHideEvent();
|
|
70
|
+
host.dispatchEvent(event);
|
|
71
|
+
if (event.defaultPrevented) {
|
|
72
|
+
host.open = !opening;
|
|
73
|
+
const restoration = { open: host.open };
|
|
74
|
+
restorations.set(host, restoration);
|
|
75
|
+
void host.updateComplete.then(() => {
|
|
76
|
+
if (restorations.get(host) === restoration) restorations.delete(host);
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!current()) return;
|
|
81
|
+
transitions.get(host)?.abort();
|
|
82
|
+
transitions.set(host, transition);
|
|
83
|
+
if (opening) {
|
|
84
|
+
host.addOpenListeners();
|
|
85
|
+
host.listbox.hidden = false;
|
|
86
|
+
host.popup.active = true;
|
|
87
|
+
window.requestAnimationFrame(() => {
|
|
88
|
+
if (current()) host.setCurrentOption(host.currentOption);
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
host.removeOpenListeners();
|
|
92
|
+
}
|
|
93
|
+
await animateSelectPopup(
|
|
94
|
+
host.popup.popup,
|
|
95
|
+
opening ? "show" : "hide",
|
|
96
|
+
transition.signal
|
|
97
|
+
);
|
|
98
|
+
if (!transition.signal.aborted && !host.isConnected) {
|
|
99
|
+
host.removeOpenListeners();
|
|
100
|
+
host.listbox.hidden = true;
|
|
101
|
+
host.popup.active = false;
|
|
102
|
+
}
|
|
103
|
+
if (!current()) return;
|
|
104
|
+
if (opening) {
|
|
105
|
+
const option = host.currentOption;
|
|
106
|
+
if (option) {
|
|
107
|
+
const list = host.listbox;
|
|
108
|
+
const offset = Math.round(
|
|
109
|
+
option.getBoundingClientRect().top - list.getBoundingClientRect().top
|
|
110
|
+
);
|
|
111
|
+
if (offset < 0)
|
|
112
|
+
list.scrollTo({ top: list.scrollTop + offset, behavior: "auto" });
|
|
113
|
+
else if (offset + option.clientHeight > list.offsetHeight) {
|
|
114
|
+
list.scrollTo({
|
|
115
|
+
top: list.scrollTop + offset - list.offsetHeight + option.clientHeight,
|
|
116
|
+
behavior: "auto"
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
host.dispatchEvent(new WaAfterShowEvent());
|
|
121
|
+
} else {
|
|
122
|
+
host.listbox.hidden = true;
|
|
123
|
+
host.popup.active = false;
|
|
124
|
+
host.dispatchEvent(new WaAfterHideEvent());
|
|
125
|
+
}
|
|
126
|
+
} finally {
|
|
127
|
+
if (transitions.get(host) === transition) transitions.delete(host);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/select-register.ts
|
|
133
|
+
installSelectLifecycle(WaSelect.prototype);
|
|
9
134
|
var selectElementsRegistered = true;
|
|
10
135
|
|
|
11
136
|
export { selectElementsRegistered };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/select-register.ts"],"names":[],"mappings":";;;;;;;;AAYO,IAAM,wBAAA,GAA2B","file":"select-register.js","sourcesContent":["import '@awesome.me/webawesome/dist/components/button/button.js';\nimport '@awesome.me/webawesome/dist/components/divider/divider.js';\nimport '@awesome.me/webawesome/dist/components/dropdown/dropdown.js';\nimport '@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js';\nimport '@awesome.me/webawesome/dist/components/option/option.js';\nimport '@awesome.me/webawesome/dist/components/select/select.js';\n\n/**\n * Marker export for tests and tooling; importing this module performs registration.\n * Registers both the `Select` elements and the `Catalog` related-entries popup-menu\n * elements (`wa-dropdown` / `wa-dropdown-item` / `wa-button`).\n */\nexport const selectElementsRegistered = true;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/animate-select-popup.ts","../src/install-select-lifecycle.ts","../src/select-register.ts"],"names":[],"mappings":"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","file":"select-register.js","sourcesContent":["/** Run one native Select CSS animation; a reversal owns cancellation and cleanup. */\nexport function animateSelectPopup(\n popup: HTMLElement,\n phase: 'show' | 'hide',\n signal: AbortSignal,\n): Promise<void> {\n return new Promise((resolve) => {\n let settled = false;\n let frame = 0;\n const finish = () => {\n if (settled) return;\n settled = true;\n window.cancelAnimationFrame(frame);\n signal.removeEventListener('abort', finish);\n popup.classList.remove(phase);\n resolve();\n };\n signal.addEventListener('abort', finish, { once: true });\n popup.classList.add(phase);\n // Activation renders asynchronously. Check for reduced/absent motion only\n // after the native popup has had its normal render opportunity.\n frame = window.requestAnimationFrame(() => {\n // Observe these exact animations. An old CSS animationcancel event can\n // arrive after the next phase starts and must not finish that new phase.\n void Promise.all(\n popup\n .getAnimations()\n .map((animation) => animation.finished.catch(() => undefined)),\n ).then(finish);\n });\n if (signal.aborted) finish();\n });\n}\n","import type WaSelect from '@awesome.me/webawesome/dist/components/select/select.js';\nimport { WaAfterHideEvent } from '@awesome.me/webawesome/dist/events/after-hide.js';\nimport { WaAfterShowEvent } from '@awesome.me/webawesome/dist/events/after-show.js';\nimport { WaHideEvent } from '@awesome.me/webawesome/dist/events/hide.js';\nimport { WaShowEvent } from '@awesome.me/webawesome/dist/events/show.js';\n\nimport { animateSelectPopup } from './animate-select-popup.js';\n\n// Web Awesome 3.12/3.13 expose the lifecycle method but not these helper types.\n// Keep this integration boundary local: native option selection, dismissal\n// listeners, popup positioning and rendering remain owned by Web Awesome.\ninterface SelectHost extends Pick<\n WaSelect,\n | 'open'\n | 'disabled'\n | 'isConnected'\n | 'dataset'\n | 'popup'\n | 'listbox'\n | 'currentOption'\n | 'selectedOptions'\n | 'dispatchEvent'\n | 'handleOpenChange'\n | 'updateComplete'\n> {\n getFirstOption(): WaSelect['currentOption'];\n setCurrentOption(option: WaSelect['currentOption']): void;\n addOpenListeners(): void;\n removeOpenListeners(): void;\n}\n\n/** Install once at the explicit registration boundary, only for Kerf Selects. */\nexport function installSelectLifecycle(\n prototype: Pick<WaSelect, 'handleOpenChange' | 'handleDisabledChange'>,\n): void {\n const installed = Symbol.for('@kerfjs/ui/select-lifecycle');\n if (Object.prototype.hasOwnProperty.call(prototype, installed)) return;\n Object.defineProperty(prototype, installed, { value: true });\n const original = prototype.handleOpenChange;\n const originalDisabled = prototype.handleDisabledChange;\n prototype.handleDisabledChange = function () {\n const host = this as unknown as SelectHost;\n const wasOpen = host.open;\n originalDisabled.call(this);\n // WA's disabled watcher runs after its open watcher in the same Lit update.\n // Its open=false mutation otherwise misses the open lifecycle altogether.\n if (host.dataset.component === 'select' && wasOpen && !host.open) {\n void host.handleOpenChange();\n }\n };\n const transitions = new WeakMap<SelectHost, AbortController>();\n const restorations = new WeakMap<SelectHost, { open: boolean }>();\n prototype.handleOpenChange = async function () {\n const host = this as unknown as SelectHost;\n if (host.dataset.component !== 'select') return original.call(this);\n const restoring = restorations.get(host)?.open === host.open;\n restorations.delete(host);\n if (restoring) return;\n const transition = new AbortController();\n const opening = host.open && !host.disabled;\n const current = () =>\n !transition.signal.aborted &&\n host.isConnected &&\n (host.open && !host.disabled) === opening;\n try {\n if (!host.isConnected) return;\n if (opening) {\n host.setCurrentOption(host.selectedOptions[0] || host.getFirstOption());\n }\n const event = opening ? new WaShowEvent() : new WaHideEvent();\n host.dispatchEvent(event);\n if (event.defaultPrevented) {\n // Restore the accepted state without emitting the opposite transition.\n // Clear at the update checkpoint too: Lit can coalesce a restoration.\n host.open = !opening;\n const restoration = { open: host.open };\n restorations.set(host, restoration);\n void host.updateComplete.then(() => {\n if (restorations.get(host) === restoration) restorations.delete(host);\n });\n return;\n }\n // A consumer can reverse the request synchronously in a lifecycle event.\n if (!current()) return;\n // A rejected reversal must not cancel the previously accepted animation.\n transitions.get(host)?.abort();\n transitions.set(host, transition);\n if (opening) {\n host.addOpenListeners();\n host.listbox.hidden = false;\n host.popup.active = true;\n window.requestAnimationFrame(() => {\n if (current()) host.setCurrentOption(host.currentOption);\n });\n } else {\n host.removeOpenListeners();\n }\n await animateSelectPopup(\n host.popup.popup,\n opening ? 'show' : 'hide',\n transition.signal,\n );\n if (!transition.signal.aborted && !host.isConnected) {\n host.removeOpenListeners();\n host.listbox.hidden = true;\n host.popup.active = false;\n }\n if (!current()) return;\n if (opening) {\n // Match native vertical, immediate option reveal without scrolling an\n // ancestor page or moving focus after animation completion.\n const option = host.currentOption;\n if (option) {\n const list = host.listbox;\n const offset = Math.round(\n option.getBoundingClientRect().top -\n list.getBoundingClientRect().top,\n );\n if (offset < 0)\n list.scrollTo({ top: list.scrollTop + offset, behavior: 'auto' });\n else if (offset + option.clientHeight > list.offsetHeight) {\n list.scrollTo({\n top:\n list.scrollTop +\n offset -\n list.offsetHeight +\n option.clientHeight,\n behavior: 'auto',\n });\n }\n }\n host.dispatchEvent(new WaAfterShowEvent());\n } else {\n host.listbox.hidden = true;\n host.popup.active = false;\n host.dispatchEvent(new WaAfterHideEvent());\n }\n } finally {\n if (transitions.get(host) === transition) transitions.delete(host);\n }\n };\n}\n","import '@awesome.me/webawesome/dist/components/button/button.js';\nimport '@awesome.me/webawesome/dist/components/divider/divider.js';\nimport '@awesome.me/webawesome/dist/components/dropdown/dropdown.js';\nimport '@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js';\nimport '@awesome.me/webawesome/dist/components/option/option.js';\n\nimport WaSelect from '@awesome.me/webawesome/dist/components/select/select.js';\n\nimport { installSelectLifecycle } from './install-select-lifecycle.js';\n\ninstallSelectLifecycle(WaSelect.prototype);\n\n/**\n * Marker export for tests and tooling; importing this module performs registration.\n * Registers both the `Select` elements and the `Catalog` related-entries popup-menu\n * elements (`wa-dropdown` / `wa-dropdown-item` / `wa-button`).\n */\nexport const selectElementsRegistered = true;\n"]}
|
package/dist/styles/list.css
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
flex: var(--_kui-list-flex, initial);
|
|
14
14
|
flex-direction: column;
|
|
15
15
|
align-items: stretch;
|
|
16
|
+
align-content: space-between;
|
|
17
|
+
justify-content: flex-start;
|
|
16
18
|
gap: var(--_kui-list-gap, 0);
|
|
17
19
|
box-shadow:
|
|
18
20
|
inset 0 1px var(--_kui-list-divider-top),
|
|
@@ -21,6 +23,33 @@
|
|
|
21
23
|
inset 1px 0 var(--_kui-list-divider-left);
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
.kui-list[data-h-align="left"] {
|
|
27
|
+
align-items: flex-start;
|
|
28
|
+
align-content: flex-start;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.kui-list[data-h-align="center"] {
|
|
32
|
+
align-items: center;
|
|
33
|
+
align-content: space-around;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.kui-list[data-h-align="right"] {
|
|
37
|
+
align-items: flex-end;
|
|
38
|
+
align-content: flex-end;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.kui-list[data-v-align="middle"] {
|
|
42
|
+
justify-content: space-around;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.kui-list[data-v-align="bottom"] {
|
|
46
|
+
justify-content: flex-end;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.kui-list[data-v-align="full"] {
|
|
50
|
+
justify-content: space-between;
|
|
51
|
+
}
|
|
52
|
+
|
|
24
53
|
.kui-list[data-scrollable="true"] {
|
|
25
54
|
overflow-y: auto;
|
|
26
55
|
overscroll-behavior-y: contain;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
.kui-row {
|
|
2
|
+
--kui-row-gap: var(--kui-layout-item-gap, 0.5rem);
|
|
3
|
+
|
|
4
|
+
display: flex;
|
|
5
|
+
min-width: 0;
|
|
6
|
+
min-height: 0;
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
flex-direction: row;
|
|
9
|
+
flex-wrap: nowrap;
|
|
10
|
+
align-items: stretch;
|
|
11
|
+
align-content: space-between;
|
|
12
|
+
justify-content: flex-start;
|
|
13
|
+
gap: var(--_kui-row-gap, var(--kui-row-gap));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.kui-row[data-wrap="true"] {
|
|
17
|
+
flex-wrap: wrap;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.kui-row[data-h-align="center"] {
|
|
21
|
+
justify-content: space-around;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.kui-row[data-h-align="right"] {
|
|
25
|
+
justify-content: flex-end;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.kui-row[data-h-align="full"] {
|
|
29
|
+
justify-content: space-between;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.kui-row[data-v-align="top"] {
|
|
33
|
+
align-items: flex-start;
|
|
34
|
+
align-content: flex-start;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.kui-row[data-v-align="middle"] {
|
|
38
|
+
align-items: center;
|
|
39
|
+
align-content: space-around;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.kui-row[data-v-align="bottom"] {
|
|
43
|
+
align-items: flex-end;
|
|
44
|
+
align-content: flex-end;
|
|
45
|
+
}
|
package/dist/styles/styles.css
CHANGED
package/docs/accessibility.md
CHANGED
|
@@ -54,6 +54,19 @@ variants. `tests/browser/select-accessibility.spec.ts` verifies actual accessibl
|
|
|
54
54
|
names, unchanged unlabeled geometry, keyboard selection, controlled rerenders,
|
|
55
55
|
native hint wiring, and wide/narrow presentation in Chromium, Firefox, and WebKit.
|
|
56
56
|
|
|
57
|
+
The explicit `@kerfjs/ui/select/register` import also installs the canonical
|
|
58
|
+
Select lifecycle adapter. The latest open/close request owns animation completion
|
|
59
|
+
and deferred option focus. A stale close cannot hide a reopened popup after
|
|
60
|
+
resize; stale completion events are not emitted. Preventing `wa-show` or
|
|
61
|
+
`wa-hide` retains the accepted closed/open state, and removal prevents deferred
|
|
62
|
+
activation. Native option selection, keyboard behavior, dismissal listeners,
|
|
63
|
+
and popup anchor placement remain with Web Awesome. Raw `wa-select` elements
|
|
64
|
+
without the canonical `data-component="select"` marker are unchanged.
|
|
65
|
+
`tests/unit/select-lifecycle.test.ts` and `animate-select-popup.test.ts` cover
|
|
66
|
+
repeated and out-of-order completions, cancellation, instance isolation, and
|
|
67
|
+
removal. `tests/browser/select-lifecycle.spec.ts` repeats animation/resize/reopen
|
|
68
|
+
sequences at wide and narrow widths in Chromium, Firefox, and WebKit.
|
|
69
|
+
|
|
57
70
|
## ListActionRow
|
|
58
71
|
|
|
59
72
|
`ListActionRow` renders a noninteractive visual root containing primary and
|
|
@@ -38,7 +38,7 @@ foreground/background contrast relationships and visible focus ring.
|
|
|
38
38
|
|
|
39
39
|
### Typed runtime dimensions
|
|
40
40
|
|
|
41
|
-
Use `List` spacing shorthands for the common case: `gap="xs"`, `gap="m"`, and
|
|
41
|
+
Use `Row` or `List` spacing shorthands for the common case: `gap="xs"`, `gap="m"`, and
|
|
42
42
|
the other `UiSpaceName` values resolve to their matching `--kui-space-*` token.
|
|
43
43
|
The canonical rhythm is `none`, `2xs`, `xs`, `m`, and `l`; use `s` and `xl`
|
|
44
44
|
only as deliberate exceptions.
|
|
@@ -47,19 +47,21 @@ When a value cannot be expressed by one spacing step, import the CSS-free
|
|
|
47
47
|
`@kerfjs/ui/css-values` subpath. `px`, `rem`, `em`, and `pct` create typed
|
|
48
48
|
`CssLength` values; `space` and `lengthVar` reference spacing or
|
|
49
49
|
application-owned length tokens. `plus` creates a non-standalone
|
|
50
|
-
`CssLengthExpression`, so wrap it with `calc` before passing it to
|
|
50
|
+
`CssLengthExpression`, so wrap it with `calc` before passing it to a gap prop:
|
|
51
51
|
|
|
52
52
|
```tsx
|
|
53
53
|
import { calc, pct, plus, rem, space } from "@kerfjs/ui/css-values";
|
|
54
54
|
import { List } from "@kerfjs/ui/list";
|
|
55
|
+
import { Row } from "@kerfjs/ui/row";
|
|
55
56
|
|
|
56
57
|
<List gap="xs">...</List>;
|
|
58
|
+
<Row hAlign="full" vAlign="middle" gap="m">...</Row>;
|
|
57
59
|
<List gap={space("m")}>...</List>;
|
|
58
60
|
<List gap={calc(plus(rem(0.25), pct(10)))}>...</List>;
|
|
59
61
|
```
|
|
60
62
|
|
|
61
63
|
`CssValue` is the common branded base, not an arbitrary-string constructor.
|
|
62
|
-
Raw strings such as `"0.25rem"` no longer satisfy `List.gap`; this breaking
|
|
64
|
+
Raw strings such as `"0.25rem"` no longer satisfy `Row.gap` or `List.gap`; this breaking
|
|
63
65
|
contract lands before the 5.0 stable release so misspelled tokens and incomplete
|
|
64
66
|
expressions fail during typechecking rather than in the browser.
|
|
65
67
|
|
|
@@ -141,7 +143,7 @@ an upstream component or recipe request.
|
|
|
141
143
|
| Key/value facts — `ValueTable`, `ValueTableRow` | Read-only labels and values form a semantic definition list, optionally with a leading icon. | Do not use it for editable form fields or a row/column data grid; use native form or table semantics. | Compose typed `ValueTableRow` entries; pass `icon` when a 24px leading icon adds useful context. | Values, formatting, icon meaning, and empty/loading policy. | `@kerfjs/ui/value-table` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
142
144
|
| Indeterminate activity — `LoadingSpinner` | A Kerf surface needs compact, labeled or decorative indeterminate progress. | Do not use it for known progress; use Web Awesome `wa-progress-bar` or `wa-progress-ring`. Direct Web Awesome UI may use `wa-spinner`; do not mix spinner systems within one surface. | None; pass a label when the spinner conveys status. | Loading lifecycle and adjacent status copy. | `@kerfjs/ui/loading-spinner` | [Accessibility](./accessibility.md#shared-rules) |
|
|
143
145
|
| Loading placeholder — `Skeleton` + a component's `placeholder` prop | A value or a whole component is still loading and should hold its space as a subtle, unanimated block, keeping the layout stable — an inspector or detail view rendering its real chrome with per-record values absent. | Do not use it for known progress (use `LoadingSpinner`), do not animate it, and do not hand-rebuild a component's empty state — set `placeholder` on the component instead. Prefer it over `wa-skeleton`, which the pure-Kerf primitives avoid to stay Web-Awesome-free. | Set `placeholder` on a value-bearing component (`Select`, `ListHeader`, `ListItem`, `ValueTableRow`, `SegmentedControl`, `StateBanner`, `AppTab`, `ToolbarText`, `ListActionRow`) to render skeletons in its value slots with interactivity disabled; use the standalone `Skeleton` for a custom slot. | Loading lifecycle, which slots are unknown, and announcing the loading region. | `@kerfjs/ui/skeleton` | [Accessibility](./accessibility.md#shared-rules) |
|
|
144
|
-
| Value selection — `Select` | A controlled form, toolbar, or compact navigation value comes from a moderate or long choice list, possibly grouped, icon-bearing, icon-only when closed, or truncating. | Do not use it for commands; use a real action menu. Do not use it for a small visible choice set; use `SegmentedControl`. Prefer it over direct `wa-select`, `wa-option`, or value-like `wa-dropdown`/`wa-dropdown-item` composition. | Import `@kerfjs/ui/select/register` once; listen for standard input/change events. Use typed presentation props rather than consumer `::part()` overrides; let the parent own placement.
|
|
146
|
+
| Value selection — `Select` | A controlled form, toolbar, or compact navigation value comes from a moderate or long choice list, possibly grouped, icon-bearing, icon-only when closed, or truncating. | Do not use it for commands; use a real action menu. Do not use it for a small visible choice set; use `SegmentedControl`. Prefer it over direct `wa-select`, `wa-option`, or value-like `wa-dropdown`/`wa-dropdown-item` composition. | Import `@kerfjs/ui/select/register` once for registration and current-request animation ownership; listen for standard input/change events. Do not add consumer popup timing or positioning repairs. Use typed presentation props rather than consumer `::part()` overrides; let the parent own placement. | Controlled value, validation, choices, domain mapping, and outer placement. | `@kerfjs/ui/select` | [Web Awesome integration](../README.md#web-awesome-theme) |
|
|
145
147
|
| Small exclusive choice — `SegmentedControl` | A few visible choices switch a compact view or setting, with toolbar, rounded, or pill presentation. | Do not use it for tabpanel semantics; use `TabBar`. Do not use it for many choices; use `Select`. Prefer it over `wa-button-group` when the controls select one value. | Delegate its action, read `data-segment-value`, update `value`, and rerender. | Controlled value, labels, action, and persistence. | `@kerfjs/ui/segmented-control` | [SegmentedControl contract](./accessibility.md#segmentedcontrol) |
|
|
146
148
|
| Structured search editor — `TokenSearchField`, `readTokenSearchField`, `placeTokenSearchCaret`, `wireTokenSearchFields` | Free text and ordered, editable, removable filter tokens share one searchbox; enable `collapsible` when an empty, unfocused field should reduce to one iconic action, standalone or in a toolbar group. | Do not use it for ordinary text entry; use a native input or Web Awesome `wa-input`. Do not use it when filters belong in separate form controls. | Read DOM-owned text on input, empty `textContent` on clear, and use `placeTokenSearchCaret` after explicit controlled focus changes. Call `wireTokenSearchFields` from `@kerfjs/ui/wire-token-search-fields` once so Enter submits without adding a line break and keyboard chip deletion restores focus plus the text-relative caret after controlled replacement. In `collapsible` mode it also manages the transient expand/collapse/focus by default (activate to reveal + focus, Escape or empty blur to collapse); bind the field's `expanded` to the signal on the returned handle (`handle.expanded(id)`) or adopt your own via `collapsible.signals`, and opt out per behavior only when the app must own it. | Parsing, suggestions, tokens, query execution, results, announcements, and — only if overriding the default — the collapsible `expanded` signal. | `@kerfjs/ui/token-search-field` | [TokenSearchField contract](./accessibility.md#tokensearchfield) |
|
|
147
149
|
| Persistent inline status — `StateBanner` | A neutral, info, pop, success, warning, or danger message belongs next to the affected work; pop highlights featured or novel content without implying status. | Do not use pop as a success, warning, or danger substitute. Do not use StateBanner for a no-content screen; use `EmptyState`. Do not use it for transient confirmation; use a toast. Web Awesome `wa-callout` is the ecosystem alternative for Web Awesome-owned content. | Delegate an optional action; choose alert urgency only for attention-requiring failure. Use the optional tone-tinted `badge` for a terse count or status beside the title, not as the only expression of meaning. | State mapping, message lifetime, retry/action behavior, badge content, and copy. | `@kerfjs/ui/state-banner` | [Feedback accessibility](./accessibility.md#shared-rules) |
|
package/docs/layout.md
CHANGED
|
@@ -112,12 +112,30 @@ The two relationships that get confused most are 8px vs 24px: 8px is _inside_ a
|
|
|
112
112
|
group, 24px is _between_ major, differing regions. 16px sits between them for
|
|
113
113
|
same-kind groups.
|
|
114
114
|
|
|
115
|
-
For `List.gap`, pass these token names directly (`gap="xs"`, `gap="m"`) or use
|
|
115
|
+
For `Row.gap` and `List.gap`, pass these token names directly (`gap="xs"`, `gap="m"`) or use
|
|
116
116
|
`space('xs')` from `@kerfjs/ui/css-values` when composing a value in JavaScript.
|
|
117
117
|
Use `rem`, `em`, `px`, `pct`, `lengthVar`, and `calc(plus(...))` only when a
|
|
118
118
|
named spacing relationship does not express the requirement; do not pass raw
|
|
119
119
|
CSS strings.
|
|
120
120
|
|
|
121
|
+
## Row and List alignment
|
|
122
|
+
|
|
123
|
+
Use `Row` for a horizontal flex layout and `List` for a vertical one. `Row`
|
|
124
|
+
defaults to `hAlign="left"`, `vAlign="full"`, `gap="xs"`, and no wrapping;
|
|
125
|
+
`List` retains its existing full-width, top-aligned defaults and zero gap.
|
|
126
|
+
Both components accept the same physical-axis vocabulary:
|
|
127
|
+
|
|
128
|
+
| Axis | Values and aliases | Flex behavior |
|
|
129
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- |
|
|
130
|
+
| Horizontal | `left` / `l` / `flex-start`; `center` / `c` / `space-around`; `right` / `r` / `flex-end`; `full` / `f` / `space-between` | Distributes a Row's children; aligns a List's children across its width. |
|
|
131
|
+
| Vertical | `top` / `t` / `flex-start`; `middle` / `m` / `c` / `space-around`; `bottom` / `b` / `flex-end`; `full` / `f` / `space-between` | Aligns a Row's children across its height; distributes a List's children. |
|
|
132
|
+
|
|
133
|
+
Cross-axis `space-around` and `space-between` are not valid `align-items`
|
|
134
|
+
values. Kerf therefore maps `middle` to centered items and `full` to stretched
|
|
135
|
+
items, while applying the requested distribution to `align-content` when a
|
|
136
|
+
Row wraps. Prefer the descriptive values in application code; the short and
|
|
137
|
+
CSS-shaped aliases are provided for compact or migrated call sites.
|
|
138
|
+
|
|
121
139
|
`--kui-space-s` (12px) and `--kui-space-xl` (32px) exist but are **off the
|
|
122
140
|
canonical rhythm** — reach for them only as a deliberate exception, never as a
|
|
123
141
|
default step. Prefer the five canonical tokens so spacing stays legible and
|