@skra/ui 0.3.1 → 0.4.0

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.
@@ -58,7 +58,7 @@ Violating these is a review blocker in a consumer repo just as inside Skra.
58
58
  | **Accessible names** | `accessible-names.md` | Naming buttons, icon-only controls, overlays; using `skra-sr-only` | ✅ draft |
59
59
  | **Theming & encapsulation** | `theming-and-encapsulation.md` | Skins, dark mode, density; mounting under Shadow DOM / a microfrontend / an iframe | ✅ draft |
60
60
  | **Overlays** | `overlays.md` | Dialog / tooltip / popover / menu / select in the top layer; shadow & iframe limits | ✅ draft |
61
- | **Layout** | `layout.md` | Spacing & composition with Stack / Box / Grid; the gap scale | ✅ draft |
61
+ | **Layout** | `layout.md` | Spacing & composition with Stack / Box / Surface / Grid; building a card; the gap scale | ✅ draft |
62
62
  | **Wrapping Skra** | `wrapping-patterns.md` | Building your own higher-level components over Skra atoms (simplified API) | ✅ draft |
63
63
 
64
64
  ---
@@ -75,6 +75,7 @@ Violating these is a review blocker in a consumer repo just as inside Skra.
75
75
  | Mount Skra inside a Web Component / microfrontend | `theming-and-encapsulation.md` |
76
76
  | Open a dialog or tooltip | `overlays.md` |
77
77
  | Space components apart | `layout.md` |
78
+ | Build a card / panel / tile (there is no `skra-card`) | `layout.md` (Surface) |
78
79
  | Wrap a Skra atom in a project-specific component | `wrapping-patterns.md` |
79
80
 
80
81
  ---
@@ -69,6 +69,85 @@ A semantically-neutral padding primitive. Does **not** arrange children (no list
69
69
  <section skraBox padding="lg">…</section>
70
70
  ```
71
71
 
72
+ ## Surface — the painted container (`[skraSurface]`)
73
+
74
+ Box's **painting** sibling: background, border, radius, shadow — plus its own padding. Same
75
+ host allowlist as Box (`div`/`section`/`article`/`main`/`nav`/`aside`/`header`/`footer`/`figure`).
76
+
77
+ | Input | Values | Default |
78
+ | --- | --- | --- |
79
+ | `padding` | `none` \| `sm` \| `md` \| `lg` | **`md`** |
80
+
81
+ That is the whole API. Note the default differs from Box's `none` — Box is spacing-neutral by
82
+ construction, a painted container is not.
83
+
84
+ **Pick Box _or_ Surface per host, never both.** Box = spacing only; Surface = spacing + paint.
85
+
86
+ ### There is no `<skra-card>`, and you do not need one
87
+
88
+ "Card", "panel", "tile", "row" and "list item" are **compositions you write**, not Skra
89
+ components (ADR 0053). Strip padding, inner arrangement and sectioning semantics from a card
90
+ and what is left is a painted container — that is Surface, and that is all Skra ships:
91
+
92
+ ```html
93
+ <article skraSurface padding="lg" aria-labelledby="run-title">
94
+ <div skraStack direction="column" gap="md">
95
+ <h3 id="run-title" skraTypography="title-small">Morning run</h3>
96
+ <p skraTypography="body-medium">5.2 km · 24:31</p>
97
+ </div>
98
+ </article>
99
+ ```
100
+
101
+ You own the sectioning element and the accessible name — Surface sets **no** `role`, no
102
+ `tabindex` and no `aria-*`. Pair it with `[skraGrid]` above for a responsive card grid with no
103
+ breakpoints.
104
+
105
+ ### Selection: Surface READS your markup, it never owns state
106
+
107
+ There is no `selected` input, and there never will be one — `aria-selected` is only valid on
108
+ `option`/`row`/`gridcell`/`tab` roles, so a component that bakes no role cannot emit it without
109
+ producing invalid ARIA. Instead, Surface paints a selected state when **your own markup** says
110
+ so, from exactly two signals:
111
+
112
+ | Your markup | When it is the right one |
113
+ | --- | --- |
114
+ | `aria-current="true"` (or `page` / `step` / `date`) on the Surface host | the current item of a set — a global ARIA state, so it is valid on a role-less `<article>` |
115
+ | `aria-selected="true"` on a host that **already** carries `option`/`row`/`gridcell`/`tab` | only inside a listbox / grid / tablist you actually built |
116
+
117
+ ```html
118
+ <article skraSurface padding="md" aria-current="true" aria-labelledby="t">…</article>
119
+ ```
120
+
121
+ `aria-current="false"` and `aria-selected="false"` are explicit *not*-current and paint as
122
+ resting.
123
+
124
+ **Gotcha — a checked control inside the card is NOT a signal.** A card wrapping a checked
125
+ `<input type="checkbox">`/`radio` does **not** light up, deliberately: `[skraSwitch]` and
126
+ `<skra-star-rating>` are themselves native checkbox/radio hosts, so inferring selection from a
127
+ descendant would paint every settings card and every rating card as "selected" while nothing in
128
+ the accessibility tree said so.
129
+
130
+ So for a **radio-group card picker** today, the selected state is carried by the radio's own
131
+ indicator and the card stays neutral. Do **not** reach for `aria-current` to force the paint
132
+ there: the radio already announces "selected", and adding `aria-current` makes assistive
133
+ technology announce one fact twice under two names. A dedicated marker for that shape is a known
134
+ gap (Skra-side `[skraSurfaceSelect]`), not something to emulate with a class.
135
+
136
+ ### Interactive (clickable) cards are not shipped yet
137
+
138
+ Surface is a container, not a widget, and the host allowlist deliberately excludes `a` and
139
+ `button`: `<button>` cannot legally contain flow content (its content model is phrasing content
140
+ with no interactive descendant), and an `<a>` wrapping the whole card takes the card's **entire**
141
+ text as its accessible name — which `aria-label` may not fix (Iron Rule 3).
142
+
143
+ Until the stretched-link marker ships, put a normal `a[skraLink]`/`button[skraButton]` **inside**
144
+ the card and let it be the target. Do not make the card itself clickable with a `(click)` on a
145
+ `<div>` — that fails keyboard access (WCAG 2.1.1) and has no role.
146
+
147
+ **Hover:** Surface has no hover state in v1, and there is no `hoverable` input — an
148
+ informational card correctly stays inert. If you add your own hover paint in app CSS, gate it
149
+ behind `@media (hover: hover) and (pointer: fine)`, or it will latch after every tap on touch.
150
+
72
151
  ## Grid — 2D (`[skraGrid]`)
73
152
 
74
153
  Bucket-only CSS Grid. The default `columns="auto-fit"` + `min` gives an intrinsically
@@ -16,7 +16,7 @@ entry exports nothing — always import from a `@skra/ui/<entry>` subpath.
16
16
  | `@skra/ui/link` | `a[skraLink]` |
17
17
  | `@skra/ui/icon` | icon container atom |
18
18
  | `@skra/ui/typography` | `[skraTypography]` |
19
- | `@skra/ui/layout` | `[skraStack]`, `[skraBox]`, `[skraGrid]` |
19
+ | `@skra/ui/layout` | `[skraStack]`, `[skraBox]`, `[skraGrid]`, `[skraSurface]` |
20
20
  | `@skra/ui/kbd` | `kbd[skraKbd]` |
21
21
  | `@skra/ui/field` | `<skra-field>`, `[skraLabel]`, `[skraHint]`, `[skraError]`, `fieldset[skraFieldset]`, `legend[skraLegend]`, `SkraFieldContext` |
22
22
  | `@skra/ui/input` | `input[skraInput]` |
@@ -95,7 +95,7 @@ on an ancestor**, never inline:
95
95
  ## Gotcha 3 — components carry `margin: 0` (ADR 022)
96
96
 
97
97
  Spacing between components is **never** a margin on the component. Use a layout atom
98
- (`[skraStack]`/`[skraBox]`/`[skraGrid]`) — see `layout.md`.
98
+ (`[skraStack]`/`[skraBox]`/`[skraGrid]`) — see `layout.md`. A painted container (card / panel) is `[skraSurface]`, which owns its own padding.
99
99
 
100
100
  ## Gotcha 4 — `skraTypography` takes its role **on the selector**, not a `role` input
101
101
 
@@ -123,9 +123,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImpor
123
123
  }, styles: [":host{display:grid;margin:0;box-sizing:border-box}:host[data-skra-min=sm]{--skra-comp-grid-track-min: var(--skra-comp-grid-min-sm)}:host[data-skra-min=md]{--skra-comp-grid-track-min: var(--skra-comp-grid-min-md)}:host[data-skra-min=lg]{--skra-comp-grid-track-min: var(--skra-comp-grid-min-lg)}:host[data-skra-columns=\"1\"]{grid-template-columns:repeat(1,minmax(0,1fr))}:host[data-skra-columns=\"2\"]{grid-template-columns:repeat(2,minmax(0,1fr))}:host[data-skra-columns=\"3\"]{grid-template-columns:repeat(3,minmax(0,1fr))}:host[data-skra-columns=\"4\"]{grid-template-columns:repeat(4,minmax(0,1fr))}:host[data-skra-columns=\"5\"]{grid-template-columns:repeat(5,minmax(0,1fr))}:host[data-skra-columns=\"6\"]{grid-template-columns:repeat(6,minmax(0,1fr))}:host[data-skra-columns=auto-fit]{grid-template-columns:repeat(auto-fit,minmax(var(--skra-comp-grid-track-min),1fr))}:host[data-skra-columns=auto-fill]{grid-template-columns:repeat(auto-fill,minmax(var(--skra-comp-grid-track-min),1fr))}:host[data-skra-gap=none]{gap:0}:host[data-skra-gap=sm]{gap:var(--skra-comp-grid-gap-sm)}:host[data-skra-gap=md]{gap:var(--skra-comp-grid-gap-md)}:host[data-skra-gap=lg]{gap:var(--skra-comp-grid-gap-lg)}:host[data-skra-flow=row]{grid-auto-flow:row}:host[data-skra-flow=column]{grid-auto-flow:column}:host[data-skra-flow=dense]{grid-auto-flow:row dense}:host[data-skra-align=start]{align-items:start}:host[data-skra-align=center]{align-items:center}:host[data-skra-align=end]{align-items:end}:host[data-skra-align=stretch]{align-items:stretch}:host[data-skra-justify-items=start]{justify-items:start}:host[data-skra-justify-items=center]{justify-items:center}:host[data-skra-justify-items=end]{justify-items:end}:host[data-skra-justify-items=stretch]{justify-items:stretch}:host(ul),:host(ol),:host(menu){list-style:none;padding-inline-start:0}\n"] }]
124
124
  }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], flow: [{ type: i0.Input, args: [{ isSignal: true, alias: "flow", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], justifyItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "justifyItems", required: false }] }] } });
125
125
 
126
+ /**
127
+ * SkraSurface — the painted container primitive (ADR 0053), Box's painting sibling.
128
+ *
129
+ * Component-on-native-host: layers onto a generic flow/sectioning container via the
130
+ * bounded host allowlist below — NEVER a `<skra-surface>` custom element, and never
131
+ * an interactive host (ADR 0055 R3.1: `a[skraSurface]` / `button[skraSurface]` are
132
+ * unsupported). "Card", "Panel" and "Tile" are consumer compositions of Surface +
133
+ * `[skraStack]`/`[skraBox]` + a heading — not Skra components (ADR 0053 rule 1).
134
+ *
135
+ * **State-reading doctrine (ADR 0055).** Surface is a READER of state, never an
136
+ * OWNER of state. It exposes no `interactive`/`hoverable`/`selected`/`elevation`
137
+ * input and emits no `role`/`tabindex`/`aria-*`. Focus and selection are READ from
138
+ * the markup the consumer authored (see surface.scss) — which is why an
139
+ * informational card gets no interactive paint with zero API, and why a selected
140
+ * card can never disagree with what assistive technology announces.
141
+ *
142
+ * Zero baked semantics: sectioning role and accessible name are 100% consumer-owned
143
+ * (ADR 0053 rule 6). No `container-type` in v1 (ADR 0055 R7.1).
144
+ */
145
+ class SkraSurface {
146
+ /**
147
+ * Semantic padding preset, reusing Box's enum for cross-atom consistency
148
+ * (ADR 0053 rule 4). Defaults to `md` rather than Box's `none` — Box is
149
+ * spacing-neutral by construction, a painted container is not (ADR 0055 R1).
150
+ */
151
+ padding = input('md', /* @ts-ignore */
152
+ ...(ngDevMode ? [{ debugName: "padding" }] : /* istanbul ignore next */ []));
153
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraSurface, deps: [], target: i0.ɵɵFactoryTarget.Component });
154
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.1", type: SkraSurface, isStandalone: true, selector: "div[skraSurface], section[skraSurface], article[skraSurface], main[skraSurface], nav[skraSurface], aside[skraSurface], header[skraSurface], footer[skraSurface], figure[skraSurface]", inputs: { padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-skra-padding": "padding()" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{display:block;margin:0;box-sizing:border-box;background:var(--skra-comp-surface-background);color:var(--skra-comp-surface-foreground);border-color:var(--skra-comp-surface-border-color);border-width:var(--skra-comp-surface-border-width);border-style:var(--skra-comp-surface-border-style);border-radius:var(--skra-comp-surface-radius);box-shadow:var(--skra-comp-surface-shadow);padding-block:var(--skra-comp-surface-padding-block);padding-inline:var(--skra-comp-surface-padding-inline);transition:background-color var(--skra-comp-surface-motion-duration) var(--skra-comp-surface-motion-easing),border-color var(--skra-comp-surface-motion-duration) var(--skra-comp-surface-motion-easing)}:host[data-skra-padding=none]{padding-block:0;padding-inline:0}:host[data-skra-padding=sm]{padding-block:var(--skra-comp-surface-padding-block-sm);padding-inline:var(--skra-comp-surface-padding-inline-sm)}:host[data-skra-padding=md]{padding-block:var(--skra-comp-surface-padding-block);padding-inline:var(--skra-comp-surface-padding-inline)}:host[data-skra-padding=lg]{padding-block:var(--skra-comp-surface-padding-block-lg);padding-inline:var(--skra-comp-surface-padding-inline-lg)}:host([aria-current]),:host([aria-selected=true]){background:var(--skra-comp-surface-background-selected);border-color:var(--skra-comp-surface-border-color-selected);border-width:var(--skra-comp-surface-border-width-selected)}:host([aria-current=false]),:host([aria-selected=false]){background:var(--skra-comp-surface-background);border-color:var(--skra-comp-surface-border-color);border-width:var(--skra-comp-surface-border-width)}:host(:focus-visible){outline:var(--skra-comp-surface-focus-ring-width) solid var(--skra-comp-surface-focus-ring-color);outline-offset:var(--skra-comp-surface-focus-ring-width)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
155
+ }
156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: SkraSurface, decorators: [{
157
+ type: Component,
158
+ args: [{ selector: 'div[skraSurface], section[skraSurface], article[skraSurface], main[skraSurface], nav[skraSurface], aside[skraSurface], header[skraSurface], footer[skraSurface], figure[skraSurface]', standalone: true, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
159
+ // CSP-Safe State Reflection (ADR 021) — NO inline styles. This is the ONLY
160
+ // host attribute Surface emits (ADR 0055 R2): no role, no tabindex, no aria-*.
161
+ '[attr.data-skra-padding]': 'padding()',
162
+ }, styles: [":host{display:block;margin:0;box-sizing:border-box;background:var(--skra-comp-surface-background);color:var(--skra-comp-surface-foreground);border-color:var(--skra-comp-surface-border-color);border-width:var(--skra-comp-surface-border-width);border-style:var(--skra-comp-surface-border-style);border-radius:var(--skra-comp-surface-radius);box-shadow:var(--skra-comp-surface-shadow);padding-block:var(--skra-comp-surface-padding-block);padding-inline:var(--skra-comp-surface-padding-inline);transition:background-color var(--skra-comp-surface-motion-duration) var(--skra-comp-surface-motion-easing),border-color var(--skra-comp-surface-motion-duration) var(--skra-comp-surface-motion-easing)}:host[data-skra-padding=none]{padding-block:0;padding-inline:0}:host[data-skra-padding=sm]{padding-block:var(--skra-comp-surface-padding-block-sm);padding-inline:var(--skra-comp-surface-padding-inline-sm)}:host[data-skra-padding=md]{padding-block:var(--skra-comp-surface-padding-block);padding-inline:var(--skra-comp-surface-padding-inline)}:host[data-skra-padding=lg]{padding-block:var(--skra-comp-surface-padding-block-lg);padding-inline:var(--skra-comp-surface-padding-inline-lg)}:host([aria-current]),:host([aria-selected=true]){background:var(--skra-comp-surface-background-selected);border-color:var(--skra-comp-surface-border-color-selected);border-width:var(--skra-comp-surface-border-width-selected)}:host([aria-current=false]),:host([aria-selected=false]){background:var(--skra-comp-surface-background);border-color:var(--skra-comp-surface-border-color);border-width:var(--skra-comp-surface-border-width)}:host(:focus-visible){outline:var(--skra-comp-surface-focus-ring-width) solid var(--skra-comp-surface-focus-ring-color);outline-offset:var(--skra-comp-surface-focus-ring-width)}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"] }]
163
+ }], propDecorators: { padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }] } });
164
+
126
165
  /**
127
166
  * Generated bundle index. Do not edit.
128
167
  */
129
168
 
130
- export { SkraBox, SkraGrid, SkraStack };
169
+ export { SkraBox, SkraGrid, SkraStack, SkraSurface };
131
170
  //# sourceMappingURL=skra-ui-layout.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-layout.mjs","sources":["../../../../libs/ui/layout/src/lib/box/box.ts","../../../../libs/ui/layout/src/lib/stack/stack.ts","../../../../libs/ui/layout/src/lib/grid/grid.ts","../../../../libs/ui/layout/src/skra-ui-layout.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type BoxPadding = 'none' | 'sm' | 'md' | 'lg';\r\nexport type BoxDisplay = 'block' | 'inline-block' | 'flex';\r\n\r\n/**\r\n * SkraBox — semantically-neutral spacing/padding primitive (ADR 041).\r\n *\r\n * Component-on-native-host: layers onto a generic flow/sectioning container via\r\n * the bounded host allowlist below — NEVER a `<skra-box>` custom element\r\n * (ADR 012 §3.1 / ADR 041). Box does NOT arrange children, so list hosts\r\n * (`ul`/`ol`/`menu`) are intentionally excluded from its allowlist.\r\n *\r\n * Box is a pure spacing primitive: it MUST NOT establish a container-query\r\n * context (`container-type`/`container-name`) — that is an app-level concern\r\n * (ADR 016 §3.3, amended by ADR 041).\r\n */\r\n@Component({\r\n selector:\r\n 'div[skraBox], section[skraBox], article[skraBox], main[skraBox], nav[skraBox], aside[skraBox], header[skraBox], footer[skraBox], form[skraBox], figure[skraBox]',\r\n standalone: true,\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './box.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // CSP-Safe State Reflection (ADR 021) — NO inline styles! The layout reset\r\n // (margin/box-sizing) + figure UA-margin normalization live in box.scss\r\n // `:host` (ADR 022 / ADR 041 Host Normalization Contract); host-metadata\r\n // bare keys would render as junk attributes, not styles.\r\n '[attr.data-skra-padding]': 'padding()',\r\n '[attr.data-skra-display]': 'display()',\r\n },\r\n})\r\nexport class SkraBox {\r\n readonly padding = input<BoxPadding>('none');\r\n readonly display = input<BoxDisplay>('block');\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n booleanAttribute,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type StackDirection = 'row' | 'column';\r\nexport type StackGap = 'none' | 'sm' | 'md' | 'lg';\r\nexport type StackAlign = 'start' | 'center' | 'end' | 'stretch';\r\nexport type StackJustify = 'start' | 'center' | 'end' | 'between' | 'around';\r\n\r\n/**\r\n * SkraStack — flex layout primitive that arranges its children (ADR 041).\r\n *\r\n * Component-on-native-host via the bounded allowlist below. As a child-arranger\r\n * it additionally accepts list hosts (`ul`/`ol`/`menu`) — their UA list styling\r\n * is normalized in stack.scss per the Host Normalization Contract. List markers\r\n * are restorable without `!important` via a direct `li {}` rule (a direct\r\n * declaration beats the inherited `list-style: none`).\r\n *\r\n * Stack consumes `@container`; it MUST NOT establish a container-query context\r\n * (ADR 016 §3.3, amended by ADR 041).\r\n */\r\n@Component({\r\n selector:\r\n 'div[skraStack], section[skraStack], article[skraStack], main[skraStack], nav[skraStack], aside[skraStack], header[skraStack], footer[skraStack], form[skraStack], figure[skraStack], ul[skraStack], ol[skraStack], menu[skraStack]',\r\n standalone: true,\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './stack.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // CSP-Safe State Reflection — only data-attributes, no [style.*]. The\r\n // layout reset (margin/box-sizing) + list/UA normalization live in\r\n // stack.scss `:host` (ADR 022 / ADR 041 Host Normalization Contract);\r\n // host-metadata bare keys would render as junk attributes, not styles.\r\n '[attr.data-skra-direction]': 'direction()',\r\n '[attr.data-skra-gap]': 'gap()',\r\n '[attr.data-skra-align]': 'align()',\r\n '[attr.data-skra-justify]': 'justify()',\r\n '[attr.data-skra-wrap]': 'wrap() ? \"\" : null',\r\n },\r\n})\r\nexport class SkraStack {\r\n readonly direction = input<StackDirection>('column');\r\n readonly gap = input<StackGap>('md');\r\n readonly align = input<StackAlign>('stretch');\r\n readonly justify = input<StackJustify>('start');\r\n readonly wrap = input(false, { transform: booleanAttribute });\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type GridColumns =\r\n | '1'\r\n | '2'\r\n | '3'\r\n | '4'\r\n | '5'\r\n | '6'\r\n | 'auto-fit'\r\n | 'auto-fill';\r\nexport type GridMin = 'sm' | 'md' | 'lg';\r\nexport type GridGap = 'none' | 'sm' | 'md' | 'lg';\r\nexport type GridFlow = 'row' | 'column' | 'dense';\r\nexport type GridAlign = 'start' | 'center' | 'end' | 'stretch';\r\n\r\n/**\r\n * SkraGrid — 2D layout primitive that arranges its children in a CSS Grid\r\n * (ADR 041, scope O-3). The bucket-only companion to Stack (1D) and Box (spacing).\r\n *\r\n * Component-on-native-host via the bounded allowlist below. As a child-arranger\r\n * it additionally accepts list hosts (`ul`/`ol`/`menu`) — their UA list styling\r\n * is normalized in grid.scss per the Host Normalization Contract.\r\n *\r\n * Bucket-only by design: every axis is an enumerated input reflected as a\r\n * `data-skra-*` attribute → token. Arbitrary track lists, `grid-template-areas`,\r\n * named lines and per-item placement are OUT of scope (bespoke = native CSS) —\r\n * exposing them would force an `[style.*]` host binding (ADR 021 violation).\r\n *\r\n * Responsiveness: `columns=\"auto-fit\"` (default) + `min` produce an intrinsically\r\n * responsive card grid via `repeat(auto-fit, minmax(var(--min), 1fr))` — column\r\n * count tracks available width with NO media/container queries. Grid consumes\r\n * `@container`; it MUST NOT establish a container-query context (ADR 041 §3.3).\r\n */\r\n@Component({\r\n selector:\r\n 'div[skraGrid], section[skraGrid], article[skraGrid], main[skraGrid], nav[skraGrid], aside[skraGrid], header[skraGrid], footer[skraGrid], form[skraGrid], figure[skraGrid], ul[skraGrid], ol[skraGrid], menu[skraGrid]',\r\n standalone: true,\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './grid.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // CSP-Safe State Reflection — only data-attributes, no [style.*]. The layout\r\n // reset (margin/box-sizing/display:grid) + list/UA normalization live in\r\n // grid.scss `:host` (ADR 022 / ADR 041 Host Normalization Contract);\r\n // host-metadata bare keys would render as junk attributes, not styles.\r\n '[attr.data-skra-columns]': 'columns()',\r\n '[attr.data-skra-min]': 'min()',\r\n '[attr.data-skra-gap]': 'gap()',\r\n '[attr.data-skra-flow]': 'flow()',\r\n '[attr.data-skra-align]': 'align()',\r\n '[attr.data-skra-justify-items]': 'justifyItems()',\r\n },\r\n})\r\nexport class SkraGrid {\r\n readonly columns = input<GridColumns>('auto-fit');\r\n readonly min = input<GridMin>('md');\r\n readonly gap = input<GridGap>('md');\r\n readonly flow = input<GridFlow>('row');\r\n readonly align = input<GridAlign>('stretch');\r\n readonly justifyItems = input<GridAlign>('stretch');\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skra-ui-layout.mjs","sources":["../../../../libs/ui/layout/src/lib/box/box.ts","../../../../libs/ui/layout/src/lib/stack/stack.ts","../../../../libs/ui/layout/src/lib/grid/grid.ts","../../../../libs/ui/layout/src/lib/surface/surface.ts","../../../../libs/ui/layout/src/skra-ui-layout.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type BoxPadding = 'none' | 'sm' | 'md' | 'lg';\r\nexport type BoxDisplay = 'block' | 'inline-block' | 'flex';\r\n\r\n/**\r\n * SkraBox — semantically-neutral spacing/padding primitive (ADR 041).\r\n *\r\n * Component-on-native-host: layers onto a generic flow/sectioning container via\r\n * the bounded host allowlist below — NEVER a `<skra-box>` custom element\r\n * (ADR 012 §3.1 / ADR 041). Box does NOT arrange children, so list hosts\r\n * (`ul`/`ol`/`menu`) are intentionally excluded from its allowlist.\r\n *\r\n * Box is a pure spacing primitive: it MUST NOT establish a container-query\r\n * context (`container-type`/`container-name`) — that is an app-level concern\r\n * (ADR 016 §3.3, amended by ADR 041).\r\n */\r\n@Component({\r\n selector:\r\n 'div[skraBox], section[skraBox], article[skraBox], main[skraBox], nav[skraBox], aside[skraBox], header[skraBox], footer[skraBox], form[skraBox], figure[skraBox]',\r\n standalone: true,\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './box.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // CSP-Safe State Reflection (ADR 021) — NO inline styles! The layout reset\r\n // (margin/box-sizing) + figure UA-margin normalization live in box.scss\r\n // `:host` (ADR 022 / ADR 041 Host Normalization Contract); host-metadata\r\n // bare keys would render as junk attributes, not styles.\r\n '[attr.data-skra-padding]': 'padding()',\r\n '[attr.data-skra-display]': 'display()',\r\n },\r\n})\r\nexport class SkraBox {\r\n readonly padding = input<BoxPadding>('none');\r\n readonly display = input<BoxDisplay>('block');\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n booleanAttribute,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type StackDirection = 'row' | 'column';\r\nexport type StackGap = 'none' | 'sm' | 'md' | 'lg';\r\nexport type StackAlign = 'start' | 'center' | 'end' | 'stretch';\r\nexport type StackJustify = 'start' | 'center' | 'end' | 'between' | 'around';\r\n\r\n/**\r\n * SkraStack — flex layout primitive that arranges its children (ADR 041).\r\n *\r\n * Component-on-native-host via the bounded allowlist below. As a child-arranger\r\n * it additionally accepts list hosts (`ul`/`ol`/`menu`) — their UA list styling\r\n * is normalized in stack.scss per the Host Normalization Contract. List markers\r\n * are restorable without `!important` via a direct `li {}` rule (a direct\r\n * declaration beats the inherited `list-style: none`).\r\n *\r\n * Stack consumes `@container`; it MUST NOT establish a container-query context\r\n * (ADR 016 §3.3, amended by ADR 041).\r\n */\r\n@Component({\r\n selector:\r\n 'div[skraStack], section[skraStack], article[skraStack], main[skraStack], nav[skraStack], aside[skraStack], header[skraStack], footer[skraStack], form[skraStack], figure[skraStack], ul[skraStack], ol[skraStack], menu[skraStack]',\r\n standalone: true,\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './stack.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // CSP-Safe State Reflection — only data-attributes, no [style.*]. The\r\n // layout reset (margin/box-sizing) + list/UA normalization live in\r\n // stack.scss `:host` (ADR 022 / ADR 041 Host Normalization Contract);\r\n // host-metadata bare keys would render as junk attributes, not styles.\r\n '[attr.data-skra-direction]': 'direction()',\r\n '[attr.data-skra-gap]': 'gap()',\r\n '[attr.data-skra-align]': 'align()',\r\n '[attr.data-skra-justify]': 'justify()',\r\n '[attr.data-skra-wrap]': 'wrap() ? \"\" : null',\r\n },\r\n})\r\nexport class SkraStack {\r\n readonly direction = input<StackDirection>('column');\r\n readonly gap = input<StackGap>('md');\r\n readonly align = input<StackAlign>('stretch');\r\n readonly justify = input<StackJustify>('start');\r\n readonly wrap = input(false, { transform: booleanAttribute });\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type GridColumns =\r\n | '1'\r\n | '2'\r\n | '3'\r\n | '4'\r\n | '5'\r\n | '6'\r\n | 'auto-fit'\r\n | 'auto-fill';\r\nexport type GridMin = 'sm' | 'md' | 'lg';\r\nexport type GridGap = 'none' | 'sm' | 'md' | 'lg';\r\nexport type GridFlow = 'row' | 'column' | 'dense';\r\nexport type GridAlign = 'start' | 'center' | 'end' | 'stretch';\r\n\r\n/**\r\n * SkraGrid — 2D layout primitive that arranges its children in a CSS Grid\r\n * (ADR 041, scope O-3). The bucket-only companion to Stack (1D) and Box (spacing).\r\n *\r\n * Component-on-native-host via the bounded allowlist below. As a child-arranger\r\n * it additionally accepts list hosts (`ul`/`ol`/`menu`) — their UA list styling\r\n * is normalized in grid.scss per the Host Normalization Contract.\r\n *\r\n * Bucket-only by design: every axis is an enumerated input reflected as a\r\n * `data-skra-*` attribute → token. Arbitrary track lists, `grid-template-areas`,\r\n * named lines and per-item placement are OUT of scope (bespoke = native CSS) —\r\n * exposing them would force an `[style.*]` host binding (ADR 021 violation).\r\n *\r\n * Responsiveness: `columns=\"auto-fit\"` (default) + `min` produce an intrinsically\r\n * responsive card grid via `repeat(auto-fit, minmax(var(--min), 1fr))` — column\r\n * count tracks available width with NO media/container queries. Grid consumes\r\n * `@container`; it MUST NOT establish a container-query context (ADR 041 §3.3).\r\n */\r\n@Component({\r\n selector:\r\n 'div[skraGrid], section[skraGrid], article[skraGrid], main[skraGrid], nav[skraGrid], aside[skraGrid], header[skraGrid], footer[skraGrid], form[skraGrid], figure[skraGrid], ul[skraGrid], ol[skraGrid], menu[skraGrid]',\r\n standalone: true,\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './grid.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // CSP-Safe State Reflection — only data-attributes, no [style.*]. The layout\r\n // reset (margin/box-sizing/display:grid) + list/UA normalization live in\r\n // grid.scss `:host` (ADR 022 / ADR 041 Host Normalization Contract);\r\n // host-metadata bare keys would render as junk attributes, not styles.\r\n '[attr.data-skra-columns]': 'columns()',\r\n '[attr.data-skra-min]': 'min()',\r\n '[attr.data-skra-gap]': 'gap()',\r\n '[attr.data-skra-flow]': 'flow()',\r\n '[attr.data-skra-align]': 'align()',\r\n '[attr.data-skra-justify-items]': 'justifyItems()',\r\n },\r\n})\r\nexport class SkraGrid {\r\n readonly columns = input<GridColumns>('auto-fit');\r\n readonly min = input<GridMin>('md');\r\n readonly gap = input<GridGap>('md');\r\n readonly flow = input<GridFlow>('row');\r\n readonly align = input<GridAlign>('stretch');\r\n readonly justifyItems = input<GridAlign>('stretch');\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ViewEncapsulation,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type SurfacePadding = 'none' | 'sm' | 'md' | 'lg';\r\n\r\n/**\r\n * SkraSurface — the painted container primitive (ADR 0053), Box's painting sibling.\r\n *\r\n * Component-on-native-host: layers onto a generic flow/sectioning container via the\r\n * bounded host allowlist below — NEVER a `<skra-surface>` custom element, and never\r\n * an interactive host (ADR 0055 R3.1: `a[skraSurface]` / `button[skraSurface]` are\r\n * unsupported). \"Card\", \"Panel\" and \"Tile\" are consumer compositions of Surface +\r\n * `[skraStack]`/`[skraBox]` + a heading — not Skra components (ADR 0053 rule 1).\r\n *\r\n * **State-reading doctrine (ADR 0055).** Surface is a READER of state, never an\r\n * OWNER of state. It exposes no `interactive`/`hoverable`/`selected`/`elevation`\r\n * input and emits no `role`/`tabindex`/`aria-*`. Focus and selection are READ from\r\n * the markup the consumer authored (see surface.scss) — which is why an\r\n * informational card gets no interactive paint with zero API, and why a selected\r\n * card can never disagree with what assistive technology announces.\r\n *\r\n * Zero baked semantics: sectioning role and accessible name are 100% consumer-owned\r\n * (ADR 0053 rule 6). No `container-type` in v1 (ADR 0055 R7.1).\r\n */\r\n@Component({\r\n selector:\r\n 'div[skraSurface], section[skraSurface], article[skraSurface], main[skraSurface], nav[skraSurface], aside[skraSurface], header[skraSurface], footer[skraSurface], figure[skraSurface]',\r\n standalone: true,\r\n template: '<ng-content></ng-content>',\r\n styleUrl: './surface.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n host: {\r\n // CSP-Safe State Reflection (ADR 021) — NO inline styles. This is the ONLY\r\n // host attribute Surface emits (ADR 0055 R2): no role, no tabindex, no aria-*.\r\n '[attr.data-skra-padding]': 'padding()',\r\n },\r\n})\r\nexport class SkraSurface {\r\n /**\r\n * Semantic padding preset, reusing Box's enum for cross-atom consistency\r\n * (ADR 0053 rule 4). Defaults to `md` rather than Box's `none` — Box is\r\n * spacing-neutral by construction, a painted container is not (ADR 0055 R1).\r\n */\r\n readonly padding = input<SurfacePadding>('md');\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAUA;;;;;;;;;;;AAWG;MAkBU,OAAO,CAAA;IACT,OAAO,GAAG,KAAK,CAAa,MAAM;gFAAC;IACnC,OAAO,GAAG,KAAK,CAAa,OAAO;gFAAC;uGAFlC,OAAO,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAP,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,OAAO,2kBAbR,2BAA2B,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,8bAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAa1B,OAAO,EAAA,UAAA,EAAA,CAAA;kBAjBnB,SAAS;AAEN,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iKAAiK,EAAA,UAAA,EACvJ,IAAI,EAAA,QAAA,EACN,2BAA2B,EAAA,eAAA,EAEpB,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;;;;AAKJ,wBAAA,0BAA0B,EAAE,WAAW;AACvC,wBAAA,0BAA0B,EAAE,WAAW;AACxC,qBAAA,EAAA,MAAA,EAAA,CAAA,8bAAA,CAAA,EAAA;;;ACxBH;;;;;;;;;;;AAWG;MAqBU,SAAS,CAAA;IACX,SAAS,GAAG,KAAK,CAAiB,QAAQ;kFAAC;IAC3C,GAAG,GAAG,KAAK,CAAW,IAAI;4EAAC;IAC3B,KAAK,GAAG,KAAK,CAAa,SAAS;8EAAC;IACpC,OAAO,GAAG,KAAK,CAAe,OAAO;gFAAC;IACtC,IAAI,GAAG,KAAK,CAAC,KAAK,4EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGALlD,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAT,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,SAAS,wmCAhBV,2BAA2B,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,q8BAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAgB1B,SAAS,EAAA,UAAA,EAAA,CAAA;kBApBrB,SAAS;AAEN,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oOAAoO,EAAA,UAAA,EAC1N,IAAI,EAAA,QAAA,EACN,2BAA2B,EAAA,eAAA,EAEpB,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;;;;AAKJ,wBAAA,4BAA4B,EAAE,aAAa;AAC3C,wBAAA,sBAAsB,EAAE,OAAO;AAC/B,wBAAA,wBAAwB,EAAE,SAAS;AACnC,wBAAA,0BAA0B,EAAE,WAAW;AACvC,wBAAA,uBAAuB,EAAE,oBAAoB;AAC9C,qBAAA,EAAA,MAAA,EAAA,CAAA,q8BAAA,CAAA,EAAA;;;ACtBH;;;;;;;;;;;;;;;;;AAiBG;MAsBU,QAAQ,CAAA;IACV,OAAO,GAAG,KAAK,CAAc,UAAU;gFAAC;IACxC,GAAG,GAAG,KAAK,CAAU,IAAI;4EAAC;IAC1B,GAAG,GAAG,KAAK,CAAU,IAAI;4EAAC;IAC1B,IAAI,GAAG,KAAK,CAAW,KAAK;6EAAC;IAC7B,KAAK,GAAG,KAAK,CAAY,SAAS;8EAAC;IACnC,YAAY,GAAG,KAAK,CAAY,SAAS;qFAAC;uGANxC,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,8uCAjBT,2BAA2B,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,8yDAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAiB1B,QAAQ,EAAA,UAAA,EAAA,CAAA;kBArBpB,SAAS;AAEN,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,uNAAuN,EAAA,UAAA,EAC7M,IAAI,EAAA,QAAA,EACN,2BAA2B,EAAA,eAAA,EAEpB,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;;;;AAKJ,wBAAA,0BAA0B,EAAE,WAAW;AACvC,wBAAA,sBAAsB,EAAE,OAAO;AAC/B,wBAAA,sBAAsB,EAAE,OAAO;AAC/B,wBAAA,uBAAuB,EAAE,QAAQ;AACjC,wBAAA,wBAAwB,EAAE,SAAS;AACnC,wBAAA,gCAAgC,EAAE,gBAAgB;AACnD,qBAAA,EAAA,MAAA,EAAA,CAAA,8yDAAA,CAAA,EAAA;;;ACjDH;;;;;;;;;;;;;;;;;;AAkBG;MAeU,WAAW,CAAA;AACtB;;;;AAIG;IACM,OAAO,GAAG,KAAK,CAAiB,IAAI;gFAAC;uGANnC,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,2bAVZ,2BAA2B,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,wzDAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAU1B,WAAW,EAAA,UAAA,EAAA,CAAA;kBAdvB,SAAS;AAEN,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sLAAsL,EAAA,UAAA,EAC5K,IAAI,EAAA,QAAA,EACN,2BAA2B,EAAA,eAAA,EAEpB,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;;AAGJ,wBAAA,0BAA0B,EAAE,WAAW;AACxC,qBAAA,EAAA,MAAA,EAAA,CAAA,wzDAAA,CAAA,EAAA;;;ACxCH;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skra/ui",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "license": "Apache-2.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -10,7 +10,7 @@
10
10
  "@angular/core": ">=22.0.0 <23.0.0",
11
11
  "@angular/common": ">=22.0.0 <23.0.0",
12
12
  "@angular/cdk": ">=22.0.0 <23.0.0",
13
- "@skra/tokens": "^0.3.1"
13
+ "@skra/tokens": "^0.4.0"
14
14
  },
15
15
  "dependencies": {
16
16
  "@floating-ui/dom": "^1.7.6",
@@ -172,4 +172,4 @@
172
172
  }
173
173
  },
174
174
  "type": "module"
175
- }
175
+ }
@@ -81,6 +81,37 @@ declare class SkraGrid {
81
81
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<SkraGrid, "div[skraGrid], section[skraGrid], article[skraGrid], main[skraGrid], nav[skraGrid], aside[skraGrid], header[skraGrid], footer[skraGrid], form[skraGrid], figure[skraGrid], ul[skraGrid], ol[skraGrid], menu[skraGrid]", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; "flow": { "alias": "flow"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "justifyItems": { "alias": "justifyItems"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
82
82
  }
83
83
 
84
- export { SkraBox, SkraGrid, SkraStack };
85
- export type { BoxDisplay, BoxPadding, GridAlign, GridColumns, GridFlow, GridGap, GridMin, StackAlign, StackDirection, StackGap, StackJustify };
84
+ type SurfacePadding = 'none' | 'sm' | 'md' | 'lg';
85
+ /**
86
+ * SkraSurface — the painted container primitive (ADR 0053), Box's painting sibling.
87
+ *
88
+ * Component-on-native-host: layers onto a generic flow/sectioning container via the
89
+ * bounded host allowlist below — NEVER a `<skra-surface>` custom element, and never
90
+ * an interactive host (ADR 0055 R3.1: `a[skraSurface]` / `button[skraSurface]` are
91
+ * unsupported). "Card", "Panel" and "Tile" are consumer compositions of Surface +
92
+ * `[skraStack]`/`[skraBox]` + a heading — not Skra components (ADR 0053 rule 1).
93
+ *
94
+ * **State-reading doctrine (ADR 0055).** Surface is a READER of state, never an
95
+ * OWNER of state. It exposes no `interactive`/`hoverable`/`selected`/`elevation`
96
+ * input and emits no `role`/`tabindex`/`aria-*`. Focus and selection are READ from
97
+ * the markup the consumer authored (see surface.scss) — which is why an
98
+ * informational card gets no interactive paint with zero API, and why a selected
99
+ * card can never disagree with what assistive technology announces.
100
+ *
101
+ * Zero baked semantics: sectioning role and accessible name are 100% consumer-owned
102
+ * (ADR 0053 rule 6). No `container-type` in v1 (ADR 0055 R7.1).
103
+ */
104
+ declare class SkraSurface {
105
+ /**
106
+ * Semantic padding preset, reusing Box's enum for cross-atom consistency
107
+ * (ADR 0053 rule 4). Defaults to `md` rather than Box's `none` — Box is
108
+ * spacing-neutral by construction, a painted container is not (ADR 0055 R1).
109
+ */
110
+ readonly padding: _angular_core.InputSignal<SurfacePadding>;
111
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SkraSurface, never>;
112
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SkraSurface, "div[skraSurface], section[skraSurface], article[skraSurface], main[skraSurface], nav[skraSurface], aside[skraSurface], header[skraSurface], footer[skraSurface], figure[skraSurface]", never, { "padding": { "alias": "padding"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
113
+ }
114
+
115
+ export { SkraBox, SkraGrid, SkraStack, SkraSurface };
116
+ export type { BoxDisplay, BoxPadding, GridAlign, GridColumns, GridFlow, GridGap, GridMin, StackAlign, StackDirection, StackGap, StackJustify, SurfacePadding };
86
117
  //# sourceMappingURL=skra-ui-layout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skra-ui-layout.d.ts","sources":["../../../../libs/ui/layout/src/lib/box/box.ts","../../../../libs/ui/layout/src/lib/stack/stack.ts","../../../../libs/ui/layout/src/lib/grid/grid.ts"],"mappings":";;AAOM,KAAM,UAAU;AAChB,KAAM,UAAU;AAEtB;;;;;;;;;;;AAWG;AACH,cAiBa,OAAO;sBACF,aAAA,CAAA,WAAA,CAAA,UAAA;sBACA,aAAA,CAAA,WAAA,CAAA,UAAA;oDAFL,OAAO;sDAAP,OAAO;AAGnB;;KClCW,cAAc;AACpB,KAAM,QAAQ;AACd,KAAM,UAAU;AAChB,KAAM,YAAY;AAExB;;;;;;;;;;;AAWG;AACH,cAoBa,SAAS;wBACF,aAAA,CAAA,WAAA,CAAA,cAAA;kBACN,aAAA,CAAA,WAAA,CAAA,QAAA;oBACE,aAAA,CAAA,WAAA,CAAA,UAAA;sBACE,aAAA,CAAA,WAAA,CAAA,YAAA;mBACH,aAAA,CAAA,wBAAA;oDALF,SAAS;sDAAT,SAAS;AAMrB;;KC5CW,WAAW;AASjB,KAAM,OAAO;AACb,KAAM,OAAO;AACb,KAAM,QAAQ;AACd,KAAM,SAAS;AAErB;;;;;;;;;;;;;;;;;AAiBG;AACH,cAqBa,QAAQ;sBACH,aAAA,CAAA,WAAA,CAAA,WAAA;kBACJ,aAAA,CAAA,WAAA,CAAA,OAAA;kBACA,aAAA,CAAA,WAAA,CAAA,OAAA;mBACC,aAAA,CAAA,WAAA,CAAA,QAAA;oBACC,aAAA,CAAA,WAAA,CAAA,SAAA;2BACO,aAAA,CAAA,WAAA,CAAA,SAAA;oDANV,QAAQ;sDAAR,QAAQ;AAOpB;;;;","names":[]}
1
+ {"version":3,"file":"skra-ui-layout.d.ts","sources":["../../../../libs/ui/layout/src/lib/box/box.ts","../../../../libs/ui/layout/src/lib/stack/stack.ts","../../../../libs/ui/layout/src/lib/grid/grid.ts","../../../../libs/ui/layout/src/lib/surface/surface.ts"],"mappings":";;AAOM,KAAM,UAAU;AAChB,KAAM,UAAU;AAEtB;;;;;;;;;;;AAWG;AACH,cAiBa,OAAO;sBACF,aAAA,CAAA,WAAA,CAAA,UAAA;sBACA,aAAA,CAAA,WAAA,CAAA,UAAA;oDAFL,OAAO;sDAAP,OAAO;AAGnB;;KClCW,cAAc;AACpB,KAAM,QAAQ;AACd,KAAM,UAAU;AAChB,KAAM,YAAY;AAExB;;;;;;;;;;;AAWG;AACH,cAoBa,SAAS;wBACF,aAAA,CAAA,WAAA,CAAA,cAAA;kBACN,aAAA,CAAA,WAAA,CAAA,QAAA;oBACE,aAAA,CAAA,WAAA,CAAA,UAAA;sBACE,aAAA,CAAA,WAAA,CAAA,YAAA;mBACH,aAAA,CAAA,wBAAA;oDALF,SAAS;sDAAT,SAAS;AAMrB;;KC5CW,WAAW;AASjB,KAAM,OAAO;AACb,KAAM,OAAO;AACb,KAAM,QAAQ;AACd,KAAM,SAAS;AAErB;;;;;;;;;;;;;;;;;AAiBG;AACH,cAqBa,QAAQ;sBACH,aAAA,CAAA,WAAA,CAAA,WAAA;kBACJ,aAAA,CAAA,WAAA,CAAA,OAAA;kBACA,aAAA,CAAA,WAAA,CAAA,OAAA;mBACC,aAAA,CAAA,WAAA,CAAA,QAAA;oBACC,aAAA,CAAA,WAAA,CAAA,SAAA;2BACO,aAAA,CAAA,WAAA,CAAA,SAAA;oDANV,QAAQ;sDAAR,QAAQ;AAOpB;;AC5DK,KAAM,cAAc;AAE1B;;;;;;;;;;;;;;;;;;AAkBG;AACH,cAca,WAAW;AACtB;;;;AAIG;sBACa,aAAA,CAAA,WAAA,CAAA,cAAA;oDANL,WAAW;sDAAX,WAAW;AAOvB;;;;","names":[]}