fold-ng 0.3.0 → 0.5.1
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/CHANGELOG.md +376 -1
- package/README.md +136 -50
- package/fesm2022/fold-ng.mjs +3968 -1251
- package/fesm2022/fold-ng.mjs.map +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/tokens/primitives.css +19 -0
- package/tokens/scales.css +11 -0
- package/tokens/semantic.css +238 -0
- package/types/fold-ng.d.ts +1443 -72
- package/types/fold-ng.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -90,12 +90,14 @@ set `data-theme` on an ancestor — usually `<html>`:
|
|
|
90
90
|
<html data-theme="lumen"></html>
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
`bubbly`
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
93
|
+
Five themes ship: `umbra` (the dark base, no attribute), `lumen` (light),
|
|
94
|
+
`bubbly` (festive lavender, violet brand, rounded), `navi` (dark chrome, light
|
|
95
|
+
page) and `titan` (brushed titanium — a light brushed-steel ground with a
|
|
96
|
+
frameless top and floating rails, bright cards, a heat-anodized copper-orange
|
|
97
|
+
brand, solid steel borders, iPhone-soft corners). The extras exist to prove the point — each
|
|
98
|
+
is the umbra or lumen block with its primitive families re-pointed. Adding a
|
|
99
|
+
sixth is a new `[data-theme]` block in `semantic.css` plus the primitives it
|
|
100
|
+
names.
|
|
99
101
|
|
|
100
102
|
`bubbly` and `navi` also change their corners — **radius is the one scale a theme may
|
|
101
103
|
re-declare**, because corner softness is a brand axis (friendly vs
|
|
@@ -111,6 +113,81 @@ roles cannot express. It gets there by re-declaring those roles on
|
|
|
111
113
|
theme never names a component's internals. Variables only. If mixed chrome ever
|
|
112
114
|
stops being a demo, the catalogue should grow real `*-on-chrome` roles.
|
|
113
115
|
|
|
116
|
+
## Auto-inverting surfaces
|
|
117
|
+
|
|
118
|
+
The same `[data-surface]` seam powers an **accent** surface — a region filled
|
|
119
|
+
with the brand accent whose entire content sub-tree flips to a compatible
|
|
120
|
+
on-accent palette **with no per-component code**. Drop a `fold-card` in a grid
|
|
121
|
+
and set `surface="accent"` (or stamp `foldSurface="accent"` on any element):
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<fold-card surface="accent">
|
|
125
|
+
<h3>Studio plan</h3>
|
|
126
|
+
<p>Everything in Pro, plus shared workspaces.</p>
|
|
127
|
+
<fold-badge content="Popular" variant="accent" />
|
|
128
|
+
<fold-link href="/plans">Compare plans</fold-link>
|
|
129
|
+
<button foldButton>Choose</button>
|
|
130
|
+
</fold-card>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Every nested thing — the text ramp, the hairline border, a raised band, the
|
|
134
|
+
badge, the link, the button, even a filled icon tile — reads correctly on the
|
|
135
|
+
accent. Not because the card special-cases them, but because the region
|
|
136
|
+
**re-points the semantic roles** they already resolve against.
|
|
137
|
+
|
|
138
|
+
### How it works (and why it survives a solid button)
|
|
139
|
+
|
|
140
|
+
An inverting surface has to do something a chrome surface never does: **swap the
|
|
141
|
+
brand pair**. On the accent, `--fold-color-primary` should become the light ink
|
|
142
|
+
(so a link or a filled tile's ground reads), and `--fold-color-on-primary` should
|
|
143
|
+
become the accent itself (so the label _on_ that tile reads). Written naively
|
|
144
|
+
that's a CSS custom-property cycle (`a: var(b); b: var(a)` → both invalid).
|
|
145
|
+
|
|
146
|
+
The trick: **capture on the surface, invert on the descendants.** The surface
|
|
147
|
+
element records the accent and its ink into two private vars _while the tokens
|
|
148
|
+
still hold their normal values_, and the inverted role-set is applied to
|
|
149
|
+
descendants from those captures — so a role can reference the pre-inversion value
|
|
150
|
+
it is replacing, no cycle:
|
|
151
|
+
|
|
152
|
+
```css
|
|
153
|
+
[data-surface="accent"] {
|
|
154
|
+
--_accent-ink: var(--fold-color-on-primary); /* captured here… */
|
|
155
|
+
--_accent-fill: var(--fold-color-primary);
|
|
156
|
+
}
|
|
157
|
+
[data-surface="accent"] * {
|
|
158
|
+
--fold-color-text: var(--_accent-ink); /* …consumed here */
|
|
159
|
+
--fold-color-primary: var(--_accent-ink); /* fill → light ink */
|
|
160
|
+
--fold-color-on-primary: var(--_accent-fill); /* on-fill → the accent */
|
|
161
|
+
/* …surfaces/borders as color-mix of the captured pair… */
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Every value is a `color-mix` of the captured pair, so it is **derived, not
|
|
166
|
+
authored** — one definition holds on all five themes, and the surface/band steps
|
|
167
|
+
stay a lighter shade of the accent (gradation kept in-hue).
|
|
168
|
+
|
|
169
|
+
### Overriding per theme
|
|
170
|
+
|
|
171
|
+
None of this is a cage. Writing your own CSS in a card is always free — raw
|
|
172
|
+
values don't reference the roles, so a surface never touches them. An _override_
|
|
173
|
+
isn't a hack: it re-anchors one **relationship** (text ↔ ground ↔ accent) inside
|
|
174
|
+
a controlled frame, and coherence follows because the ratios are preserved. Speak
|
|
175
|
+
in roles and gain the adaptation, or paint a pixel and own it — both coexist.
|
|
176
|
+
|
|
177
|
+
The derived defaults are good, not sacred. A theme that wants a different
|
|
178
|
+
on-accent ramp (a light accent might want darker text, say) overrides any role by
|
|
179
|
+
nesting its own theme selector under the surface — the same seam chrome uses:
|
|
180
|
+
|
|
181
|
+
```css
|
|
182
|
+
[data-theme="titan"] [data-surface="accent"] * {
|
|
183
|
+
--fold-color-text: var(--fold-ref-steel-900); /* dark ink on a light accent */
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The one honest limit: an accent surface is a _single_ ground, so `surface`
|
|
188
|
+
stays one axis — there is no `accent` × `sunken`. That is a feature (a card in a
|
|
189
|
+
grid has one job: stand out), not a gap.
|
|
190
|
+
|
|
114
191
|
Then style against the semantic tokens — never a raw colour:
|
|
115
192
|
|
|
116
193
|
```css
|
|
@@ -210,50 +287,59 @@ radius / text / icon-size / space / motion / blur scales — see
|
|
|
210
287
|
All standalone, signals-first, styled against the semantic tokens. Import from
|
|
211
288
|
the package root.
|
|
212
289
|
|
|
213
|
-
| Component | Selector | What it is
|
|
214
|
-
| -------------------------------------------------------- | -------------------------------------- |
|
|
215
|
-
| `FoldAppShellComponent` | `fold-app-shell` | Responsive app skeleton (rails + header + content + self-collapsing `footer` slots; `headerLayout`/`footerLayout` inset·full, `footerBehavior` pinned·scroll; `mobileNav` drawer·none — `[(mobileNavOpen)]` off-canvas drawer for the primary rail on mobile, or `none` to compose an `fold-nav-launcher`; `contentScroll` clip·auto; built-in skip-link to a focusable `<main>`. Regions float per-surface via `foldElevated`, not a shell flag).
|
|
216
|
-
| `FoldMenuComponent` (+ `Item` / `Section` / `Separator`) | `fold-menu` | Collapsible nav rail — coloured sections, `tint="follow"`, depth `level`, collapse-toggle placement. Items are `a[fold-menu-item]`.
|
|
217
|
-
| `FoldNavLauncherComponent` (+ `FoldNavTileComponent`) | `fold-nav-launcher` | Full-screen mobile nav launcher — a centred tile grid over a blurred scrim (scrim / `Escape` / close dismissal, focus-trap, scroll-lock). `columns="auto"` scales tiles to the count. Pairs with `fold-app-shell mobileNav="none"`. Tiles are `a[fold-nav-tile]` — `variant="surface"`·`filled`.
|
|
218
|
-
| `FoldPageLayoutComponent` | `fold-page-layout` | Page scaffold — gutter + header + body rhythm; fills its container (width is a content concern). Tokens `--fold-page-gutter` / `--fold-page-gap`; sections can `bleed` edge-to-edge.
|
|
219
|
-
| `FoldPageSectionComponent` | `fold-page-section` | Semantic `<section>` grouping — eyebrow title (names the region via `aria-labelledby`) + description + actions; `stack` / `bleed` helpers. Not a box — compose a `fold-card` inside for that.
|
|
220
|
-
| `FoldHeroSectionComponent` | `fold-hero-section` | Full-bleed page splash — the borderless intro band at the top of a page (carries the `<h1>`). Direct child of `fold-page-layout`: cancels the gutter + top pad to sit flush, brand-tinted wash + hairline. `align` center·start, `wash`, `[heroBackdrop]` decorative lane. (For a bordered header card, see `fold-hero-card`.)
|
|
221
|
-
| `FoldAsideLayoutComponent` | `fold-aside-layout` | Detail-page grid — a centred column flanked by up to two sticky rails (`[asideLeft]` / `[asideRight]`), collapsing to one column on its own container width (`:has()`-driven, container queries). Labelled rails become `complementary` landmarks; every track is a CSS var.
|
|
222
|
-
| `FoldNavLayoutComponent` | `fold-nav-layout` | Places a bar (`[tabNav]` — a `fold-view-nav` or a `fold-tabs`) with its content — `placement="top"` or a `side` rail that folds back on top (hysteretic, on its own width) below `foldAt`. `exportAs="foldNavLayout"` exposes `stacked()` so the projected bar follows in one binding.
|
|
223
|
-
| `FoldCardComponent` | `fold-card` | Raised content surface (`surface
|
|
224
|
-
| `FoldContextCardComponent` | `fold-context-card` | Titled info card: icon header + body + optional footer action.
|
|
225
|
-
| `FoldHeroCardComponent` | `fold-hero-card` | Prominent header **card** — bordered surface × accent overlay + optional accent bar. (For a full-bleed page splash, see `fold-hero-section`.)
|
|
226
|
-
| `FoldElementTitleComponent` | `fold-element-title` | Uppercase section/card mini-title (eyebrow · bar variants).
|
|
227
|
-
| `FoldFieldListComponent` / `…Field` | `fold-field-list` | Read-only `dl/dt/dd` recap — label/value pairs (`[empty]` placeholder). The _display_ half of a record; `fold-input` is the _edit_ half.
|
|
228
|
-
| `FoldInputComponent` | `fold-input` | Text-input control (`value: string`) — Signal Forms (`[formField]`) or standalone `[(value)]`; size × align × variant, `label` / `required` / `hint`. The _edit_ half of a record (`fold-field` reads).
|
|
229
|
-
| `FoldNumberInputComponent` | `fold-number-input` | Numeric sibling of `fold-input` (`value: number \| null`, empty ⇒ `null`); owns `min` / `max` / `step` + `label` / `required` / `hint`. Split so each control keeps its true type.
|
|
230
|
-
| `
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
234
|
-
| `
|
|
235
|
-
| `
|
|
236
|
-
| `
|
|
237
|
-
| `
|
|
238
|
-
| `
|
|
239
|
-
| `
|
|
240
|
-
| `
|
|
241
|
-
| `
|
|
242
|
-
| `
|
|
243
|
-
| `
|
|
244
|
-
| `
|
|
245
|
-
| `
|
|
246
|
-
| `
|
|
247
|
-
| `
|
|
248
|
-
| `
|
|
249
|
-
| `
|
|
250
|
-
| `
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
290
|
+
| Component | Selector | What it is |
|
|
291
|
+
| -------------------------------------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
292
|
+
| `FoldAppShellComponent` | `fold-app-shell` | Responsive app skeleton (rails + header + content + self-collapsing `footer` slots; `headerLayout`/`footerLayout` inset·full, `footerBehavior` pinned·scroll; `mobileNav` drawer·none — `[(mobileNavOpen)]` off-canvas drawer for the primary rail on mobile, or `none` to compose an `fold-nav-launcher`; `contentScroll` clip·auto; built-in skip-link to a focusable `<main>`. Regions float per-surface via `foldElevated`, not a shell flag). |
|
|
293
|
+
| `FoldMenuComponent` (+ `Item` / `Section` / `Separator`) | `fold-menu` | Collapsible nav rail — coloured sections, `tint="follow"`, depth `level`, collapse-toggle placement. Items are `a[fold-menu-item]`. |
|
|
294
|
+
| `FoldNavLauncherComponent` (+ `FoldNavTileComponent`) | `fold-nav-launcher` | Full-screen mobile nav launcher — a centred tile grid over a blurred scrim (scrim / `Escape` / close dismissal, focus-trap, scroll-lock). `columns="auto"` scales tiles to the count. Pairs with `fold-app-shell mobileNav="none"`. Tiles are `a[fold-nav-tile]` — `variant="surface"`·`filled`. |
|
|
295
|
+
| `FoldPageLayoutComponent` | `fold-page-layout` | Page scaffold — gutter + header + body rhythm; fills its container (width is a content concern). Tokens `--fold-page-gutter` / `--fold-page-gap`; sections can `bleed` edge-to-edge. |
|
|
296
|
+
| `FoldPageSectionComponent` | `fold-page-section` | Semantic `<section>` grouping — eyebrow title (names the region via `aria-labelledby`) + description + actions; `stack` / `bleed` helpers. Not a box — compose a `fold-card` inside for that. |
|
|
297
|
+
| `FoldHeroSectionComponent` | `fold-hero-section` | Full-bleed page splash — the borderless intro band at the top of a page (carries the `<h1>`). Direct child of `fold-page-layout`: cancels the gutter + top pad to sit flush, brand-tinted wash + hairline. `align` center·start, `wash`, `[heroBackdrop]` decorative lane. (For a bordered header card, see `fold-hero-card`.) |
|
|
298
|
+
| `FoldAsideLayoutComponent` | `fold-aside-layout` | Detail-page grid — a centred column flanked by up to two sticky rails (`[asideLeft]` / `[asideRight]`), collapsing to one column on its own container width (`:has()`-driven, container queries). Labelled rails become `complementary` landmarks; every track is a CSS var. |
|
|
299
|
+
| `FoldNavLayoutComponent` | `fold-nav-layout` | Places a bar (`[tabNav]` — a `fold-view-nav` or a `fold-tabs`) with its content — `placement="top"` or a `side` rail that folds back on top (hysteretic, on its own width) below `foldAt`. `exportAs="foldNavLayout"` exposes `stacked()` so the projected bar follows in one binding. |
|
|
300
|
+
| `FoldCardComponent` | `fold-card` | Raised content surface (`surface` = `card`/`sunken`/`accent`, hairline border, consistent radius). `accent` is an **auto-inverting** accent-filled card: the whole content sub-tree re-points to a compatible on-accent palette (text, borders, band gradation, nested buttons/links/icon-tiles) — every value a `color-mix` of the accent, so it holds on all themes (see [auto-inverting surfaces](#auto-inverting-surfaces)). Optional projected `[cardHeader]`/`[cardFooter]` bands with per-band chrome (`separators`/`raisedBands` = `none`/`header`/`footer`/`both`); the body padding never shifts when a band toggles. `interactive` makes the whole card an accessible button (`role`/`tabindex`, focus ring, Enter/Space/click → `(activated)`). |
|
|
301
|
+
| `FoldContextCardComponent` | `fold-context-card` | Titled info card: icon header + body + optional footer action. |
|
|
302
|
+
| `FoldHeroCardComponent` | `fold-hero-card` | Prominent header **card** — bordered surface × accent overlay + optional accent bar. (For a full-bleed page splash, see `fold-hero-section`.) |
|
|
303
|
+
| `FoldElementTitleComponent` | `fold-element-title` | Uppercase section/card mini-title (eyebrow · bar variants). |
|
|
304
|
+
| `FoldFieldListComponent` / `…Field` | `fold-field-list` | Read-only `dl/dt/dd` recap — label/value pairs (`[empty]` placeholder). The _display_ half of a record; `fold-input` is the _edit_ half. |
|
|
305
|
+
| `FoldInputComponent` | `fold-input` | Text-input control (`value: string`) — Signal Forms (`[formField]`) or standalone `[(value)]`; size × align × variant, `label` / `required` / `hint`. The _edit_ half of a record (`fold-field` reads). |
|
|
306
|
+
| `FoldNumberInputComponent` | `fold-number-input` | Numeric sibling of `fold-input` (`value: number \| null`, empty ⇒ `null`); owns `min` / `max` / `step` + `label` / `required` / `hint`. Split so each control keeps its true type. |
|
|
307
|
+
| `FoldCheckboxComponent` | `fold-checkbox` | Boolean control — a native `<input type="checkbox">` (keyboard, `indeterminate`, forms) restyled to tokens. Signal Forms (`[formField]`, a `FormCheckboxControl`) or standalone `[(checked)]`; `indeterminate`, `label`/`ariaLabel`, `hint`/`errors`, `size`. |
|
|
308
|
+
| `FoldPasswordFieldComponent` | `fold-password-field` | Password input + a live requirements checklist (a dot/tick per rule). Rules injected via `FoldPasswordRule` (`{ label, test }` — regex/zod/anything); `revealable` eye (a `fold-input` capability); `marker` dot/check; `[rules]` slot to redesign the list; `validChange`; Signal Forms. |
|
|
309
|
+
| `FoldViewToggleComponent` | `fold-view-toggle` | Segmented single-select (Cards/Table, density, chart-mode…). Generic `options` (`{ value, icon?, label?, ariaLabel?, disabled? }`) + `[(value)]`; a real `role="radiogroup"` — roving tabindex, arrow keys, Home/End, disabled-skip; `size`, `iconOnly`, `activeStyle` (raised / accent). |
|
|
310
|
+
| `FoldSearchComponent` | `fold-search` | Debounced search box — an `fold-input` that emits `searchChange` once typing settles (`delayMs`), trimmed + de-duplicated. |
|
|
311
|
+
| `FoldListboxComponent` / `FoldOptionComponent` | `fold-listbox` / `fold-option` | Styleable single-select — the richer sibling of `fold-select` (native `<select>`) for options that need custom rows (icon, second line, status). On `fold-popover`; `role="listbox"` + `aria-activedescendant`, full keyboard (↑/↓, `Home`/`End`, type-ahead, `Enter`). Signal Forms (`FormValueControl<string>`, `[formField]`/`[(value)]`); shares `fold-input`'s box chrome. |
|
|
312
|
+
| `FoldMultiselectComponent` | `fold-multiselect` | Multi-select sibling of `fold-listbox` (same popover + `fold-option` rows). Value is a set (`readonly string[]`); activating a row toggles it and the panel stays open. Separate component — not a `multiple` flag — so the Signal-Forms value type stays honest. `role="listbox"` + `aria-multiselectable`; the trigger summarises the picks. |
|
|
313
|
+
| `FoldSliderComponent` | `fold-slider` | Single-value range slider — a styled native `<input type="range">` (design-system track/fill/thumb). Signal Forms (`[formField]`, a `FormValueControl<number>`) or `[(value)]`; real `<label for>`, `aria-valuetext`, `hint`/`errors`, focus ring. |
|
|
314
|
+
| `FoldRangeSliderComponent` | `fold-range-slider` | Dual-thumb range slider selecting a `{ min, max }` window (shares the slider track/thumb). Two-way `[(value)]`; a labelled `role="group"`, per-thumb i18n aria (`minLabel`/`maxLabel`) + formatted `aria-valuetext`, `disabled`. |
|
|
315
|
+
| `FoldRangeSliderComponent` | `fold-range-slider` | Dual-thumb slider selecting a `{ min, max }` window over `[min, max]`; shares the slider track/fill/thumb. |
|
|
316
|
+
| `FoldFileDropzoneComponent` | `fold-file-dropzone` | File-picker dropzone — drag-over visuals, keyboard activation, hidden `<input type=file>` plumbing; emits the picked `File[]` (presentational — never uploads). |
|
|
317
|
+
| `FoldLinkComponent` | `fold-link` | Inline text link / link-button (icons, accent · muted). |
|
|
318
|
+
| `FoldButtonComponent` | `button[foldButton]` · `a[foldButton]` | Action button — applied to a real `<button>` **or** `<a>` (link that looks like a button, gets `href`/`routerLink`); orthogonal `emphasis` (solid·soft·outline) × `intent` (primary·neutral·warning·danger) × 3 sizes × shape/`block`; `icon`/`iconTrailing` shorthand (auto-sized) or project content; `loading` (spinner + `aria-busy`). Use native `(click)`. |
|
|
319
|
+
| `FoldButtonIconComponent` | `fold-button-icon` | Icon-only **momentary** button — shape × size × tone; a one-shot action (no pressed state). For a text button use `fold-button`; for on/off use `fold-toggle-icon`. |
|
|
320
|
+
| `FoldToggleIconComponent` | `fold-toggle-icon` | Icon-only **toggle** — the same surface as `fold-button-icon`, plus `[(active)]` + `aria-pressed` (true/false) and a pressed state. Emits `toggled`. |
|
|
321
|
+
| `FoldInlineConfirmComponent` | `fold-inline-confirm` | In-place “are you sure?” guard — the projected trigger swaps to a confirm/cancel row (no modal). Simple (`confirmed` emits `""`), type-to-confirm (`[match]`), or secret (`password`, masked, emits the value). `confirmIcon` + a chosen `cancelIcon`; `Escape` cancels; `message` announced via `aria-describedby`; focus in-then-back; controlled `[(open)]` + `keepOpenOnConfirm` for async pending; i18n via `provideFoldInlineConfirmLabels`. |
|
|
322
|
+
| `FoldDataTableComponent` | `fold-data-table` | Controlled roster table — sortable sticky header, tone rows, controlled selection (checkbox column), roving-keyboard nav, `mobileLayout` (scroll / auto-cards / custom `foldRowCard`), an optional `foldToolbar` bar, sticky-first, density. |
|
|
323
|
+
| `FoldPaginatorComponent` | `fold-paginator` | Server-side paginator (size selector + range + page nav). |
|
|
324
|
+
| `FoldTimelineComponent` | `fold-timeline` | Connected rail of nodes (dot + optional date + label) — `vertical` navigable history or `horizontal` step progress; nodes optionally clickable. |
|
|
325
|
+
| `FoldBadgeComponent` | `fold-badge` | Status / count pill (accent/info/warning/alert/success). |
|
|
326
|
+
| `FoldStatusBadgeComponent` | `fold-status-badge` | Status→colour badge (maps a domain status key to a tone). |
|
|
327
|
+
| `FoldChoiceRowComponent` | `fold-choice-row` | Segmented / chip selector. |
|
|
328
|
+
| `FoldViewNavComponent` | `fold-view-nav` | Navigation bar styled as tabs. Items carry a `link` (routerLink → a real `<a>`: cmd-click, deep-links, active state auto), an `href`, or nothing (a button); `aria-current="page"` on the active one. `direction="auto"` follows a wrapping `fold-nav-layout`; `collapsed` for an icon rail. For in-page panel switching use `fold-tabs` instead. |
|
|
329
|
+
| `FoldTabsComponent` + `FoldTabPanelComponent` | `fold-tabs` + `fold-tab-panel` | The in-page ARIA Tabs widget: `role="tablist"` + roving arrow-key keyboard, `aria-selected`/`aria-orientation`, each tab wired to its `fold-tab-panel` (`aria-controls` ↔ `aria-labelledby`). Panels take the bar by ref (`[tabs]="t"`) so they coordinate across `fold-nav-layout` slots. |
|
|
330
|
+
| `FoldIconComponent` | `fold-icon` | SVG icon (114-icon built-in set + `FoldIconRegistry`). |
|
|
331
|
+
| `FoldSpinnerComponent` | `fold-spinner` | Indeterminate loading arc (`currentColor`, icon-sized, reduced-motion aware). Decorative by default; `label` → `role="status"`. Powers `loading` on the buttons. |
|
|
332
|
+
| `FoldAvatarComponent` / `…Detail` | `fold-avatar` | Initials/image avatar (square, muted, status ring) + identity cell. |
|
|
333
|
+
| `FoldAvatarListComponent` | `fold-avatar-list` | Overlapping avatar cluster (per-face variant, `limit` + a `+N` overflow chip). |
|
|
334
|
+
| `FoldToastComponent` / `…Container` | `fold-toast` | Frosted snackbar (variant glyph + dismiss) + queue host (+ `FoldToastService`). |
|
|
335
|
+
| `FoldLoadingStateComponent` | `fold-loading` | Loading placeholder — `fold-spinner` + message, in a `role="status"` region; `size` input; stretches to fill. |
|
|
336
|
+
| `FoldEmptyStateComponent` | `fold-empty-state` | Empty-state block (icon + title + message + optional action). |
|
|
337
|
+
| `FoldCalloutComponent` | `fold-callout` | Tinted message row — status colour + icon + message + optional trailing actions; `inset` (bordered, in-flow) appearance. |
|
|
338
|
+
| `FoldDisclosureComponent` | `fold-disclosure` | One summary toggling one collapsible panel — the accordion primitive (open-state is the consumer's to bind); keeps content mounted, unlike native `<details>`. |
|
|
339
|
+
| `FoldPanelHostComponent` | `fold-panel-host` | Side-panel / overlay host (+ `FoldPanelHostService` / `FoldPanelRef` / `FoldPanelToggle`). Modal: accessible name, `inert` background barrier, top-most focus trap, scroll-lock. Localise the close label once via `provideFoldPanelLabels({ close })`. |
|
|
340
|
+
| `FoldPanelHeaderComponent` | `fold-panel-header` | Standard panel header (title/eyebrow, self-closing). Names its dialog (`aria-labelledby`) and reads the app-wide close label. |
|
|
341
|
+
| `FoldPopoverComponent` | `fold-popover` | Anchored floating layer — projected content in the native top layer (escapes `overflow`/`z-index`), positioned by a dependency-free **flip → size → shift** engine (`computePlacement`): a tall panel gets a `max-height` and scrolls inside the viewport. `[(open)]`; `autoUpdate` (ResizeObserver); optional `arrow`; native CSS enter/exit (`@starting-style` + `allow-discrete`); outside-click + `Escape` dismissal, focus-return, auto-wired `aria-haspopup`/`expanded`/`controls`. |
|
|
342
|
+
| `FoldDropdownComponent` | `fold-dropdown` | Actions menu on `fold-popover` — `role="menu"` with `<fold-dropdown-item>`s, ↑/↓ roving, `Home`/`End`, type-ahead; opens onto the first enabled item, closes returning focus to the trigger. Give the trigger `foldPopoverTrigger="menu"`. |
|
|
257
343
|
|
|
258
344
|
Directives worth knowing: **`foldSurface`** (`page`·`chrome` — the seam a mixed
|
|
259
345
|
theme re-colours across), **`foldElevated`** (raise any bg-owning element into
|