fold-ng 0.6.0 → 0.6.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 +31 -1
- package/fesm2022/fold-ng.mjs +4 -4
- package/fesm2022/fold-ng.mjs.map +1 -1
- package/package.json +1 -1
- package/tokens/semantic.css +5 -0
- package/types/fold-ng.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,35 @@ All notable changes to **fold-ng** are documented here. The format follows
|
|
|
8
8
|
|
|
9
9
|
_Nothing yet._
|
|
10
10
|
|
|
11
|
+
## [0.6.1] - 2026-07-28
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **`fold-tab-panel` now owns the vertical rhythm between its children.** It was
|
|
16
|
+
a neutral `display: block` with no spacing, so stacked `fold-page-section`s (or
|
|
17
|
+
cards) inside a panel sat flush against each other — the page gap only reaches
|
|
18
|
+
the _direct_ children of `.page-body`, and a tab panel isn't one. A panel is a
|
|
19
|
+
content region, like `.page-body`, so it now lays its children out as a flex
|
|
20
|
+
column with a `gap`. The gap is the new **`--fold-panel-gap`** token — fluid
|
|
21
|
+
`16 → 24px`, deliberately one notch tighter than `--fold-page-gap` (`20 → 32px`)
|
|
22
|
+
so panel content reads as one screen rather than distinct page bands. Escape
|
|
23
|
+
hatch unchanged from `.page-body`: wrap two elements in a container to tighten
|
|
24
|
+
them (a single child gets no gap at all). Consumers that re-established this
|
|
25
|
+
spacing by hand on the panel can drop it.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **`fold-page-layout` header no longer starves the title/description on narrow
|
|
30
|
+
screens.** The head was a permanent `space-between` row: the actions slot held
|
|
31
|
+
its intrinsic width (`flex: none`) while the text column carried `min-width: 0`,
|
|
32
|
+
so wide `[pageActions]` (e.g. two full-label buttons) squeezed the description
|
|
33
|
+
down to its longest word — one word per line, stacked vertically. Below `640px`
|
|
34
|
+
the head now stacks: title/description take the full width and the actions drop
|
|
35
|
+
onto their own row beneath. Keyed to **both** the viewport (`@media`) and an
|
|
36
|
+
ancestor container (`@container`, for the gallery's responsive preview), mirroring
|
|
37
|
+
`app-shell`. The actions slot also gained `flex-wrap` so several wide buttons
|
|
38
|
+
wrap among themselves instead of overflowing the gutter.
|
|
39
|
+
|
|
11
40
|
## [0.6.0] - 2026-07-28
|
|
12
41
|
|
|
13
42
|
### Added
|
|
@@ -621,7 +650,8 @@ design-token stylesheet.
|
|
|
621
650
|
`currentColor`; `prefers-reduced-motion` + `forced-colors` are respected;
|
|
622
651
|
strings localise via inputs / providers (`provideFoldPanelLabels`).
|
|
623
652
|
|
|
624
|
-
[unreleased]: https://github.com/hugoheynard/fold-ng/compare/v0.6.
|
|
653
|
+
[unreleased]: https://github.com/hugoheynard/fold-ng/compare/v0.6.1...HEAD
|
|
654
|
+
[0.6.1]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.6.1
|
|
625
655
|
[0.6.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.6.0
|
|
626
656
|
[0.5.2]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.5.2
|
|
627
657
|
[0.5.1]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.5.1
|
package/fesm2022/fold-ng.mjs
CHANGED
|
@@ -7375,11 +7375,11 @@ class FoldPageLayoutComponent {
|
|
|
7375
7375
|
customTitle = contentChild(FoldPageTitleDirective, /* @ts-ignore */
|
|
7376
7376
|
...(ngDevMode ? [{ debugName: "customTitle" }] : /* istanbul ignore next */ []));
|
|
7377
7377
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldPageLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7378
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldPageLayoutComponent, isStandalone: true, selector: "fold-page-layout", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.title": "null" } }, queries: [{ propertyName: "customTitle", first: true, predicate: FoldPageTitleDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (title() || customTitle()) {\n <header class=\"page-head\">\n <div class=\"page-head-text\">\n <h1 class=\"page-title\">\n @if (title(); as t) {\n @if (icon(); as ic) {\n <fold-icon class=\"page-icon\" [name]=\"ic\" [size]=\"22\" />\n }\n <span>{{ t }}</span>\n }\n <ng-content select=\"[pageTitle]\" />\n <span class=\"page-title-badge\"\n ><ng-content select=\"[titleBadge]\"\n /></span>\n </h1>\n <div class=\"page-desc\"><ng-content select=\"p[description]\" /></div>\n </div>\n <div class=\"page-actions\"><ng-content select=\"[pageActions]\" /></div>\n </header>\n}\n<div class=\"page-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px);box-sizing:border-box;padding-block:var(--fold-page-pad-top, 28px) var(--fold-page-pad-bottom, 40px);padding-inline:var(--fold-page-gutter, 32px);flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fold-space-lg)}.page-head-text{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.page-title{margin:0;display:flex;align-items:center;gap:var(--fold-space-sm);font-size:var(--fold-text-xl);font-weight:700;letter-spacing:-.02em;line-height:1.2;color:var(--fold-color-text)}.page-icon{flex:none;color:var(--fold-color-primary-text)}.page-title-badge{display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-title-badge:empty{display:none}.page-desc{font-size:var(--fold-text-sm);line-height:1.5;max-width:var(--fold-page-desc-measure, none);color:var(--fold-color-text-muted)}.page-desc:empty{display:none}.page-desc>*{margin:0}.page-actions{flex:none;display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-actions:empty{display:none}.page-body{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
|
|
7378
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldPageLayoutComponent, isStandalone: true, selector: "fold-page-layout", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.title": "null" } }, queries: [{ propertyName: "customTitle", first: true, predicate: FoldPageTitleDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (title() || customTitle()) {\n <header class=\"page-head\">\n <div class=\"page-head-text\">\n <h1 class=\"page-title\">\n @if (title(); as t) {\n @if (icon(); as ic) {\n <fold-icon class=\"page-icon\" [name]=\"ic\" [size]=\"22\" />\n }\n <span>{{ t }}</span>\n }\n <ng-content select=\"[pageTitle]\" />\n <span class=\"page-title-badge\"\n ><ng-content select=\"[titleBadge]\"\n /></span>\n </h1>\n <div class=\"page-desc\"><ng-content select=\"p[description]\" /></div>\n </div>\n <div class=\"page-actions\"><ng-content select=\"[pageActions]\" /></div>\n </header>\n}\n<div class=\"page-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px);box-sizing:border-box;padding-block:var(--fold-page-pad-top, 28px) var(--fold-page-pad-bottom, 40px);padding-inline:var(--fold-page-gutter, 32px);flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fold-space-lg)}.page-head-text{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.page-title{margin:0;display:flex;align-items:center;gap:var(--fold-space-sm);font-size:var(--fold-text-xl);font-weight:700;letter-spacing:-.02em;line-height:1.2;color:var(--fold-color-text)}.page-icon{flex:none;color:var(--fold-color-primary-text)}.page-title-badge{display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-title-badge:empty{display:none}.page-desc{font-size:var(--fold-text-sm);line-height:1.5;max-width:var(--fold-page-desc-measure, none);color:var(--fold-color-text-muted)}.page-desc:empty{display:none}.page-desc>*{margin:0}.page-actions{flex:none;display:inline-flex;align-items:center;flex-wrap:wrap;gap:var(--fold-space-sm)}.page-actions:empty{display:none}@media(max-width:640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}}@container (max-width: 640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}}.page-body{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
|
|
7379
7379
|
}
|
|
7380
7380
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldPageLayoutComponent, decorators: [{
|
|
7381
7381
|
type: Component,
|
|
7382
|
-
args: [{ selector: "fold-page-layout", standalone: true, imports: [FoldIconComponent], host: { "[attr.title]": "null" }, template: "@if (title() || customTitle()) {\n <header class=\"page-head\">\n <div class=\"page-head-text\">\n <h1 class=\"page-title\">\n @if (title(); as t) {\n @if (icon(); as ic) {\n <fold-icon class=\"page-icon\" [name]=\"ic\" [size]=\"22\" />\n }\n <span>{{ t }}</span>\n }\n <ng-content select=\"[pageTitle]\" />\n <span class=\"page-title-badge\"\n ><ng-content select=\"[titleBadge]\"\n /></span>\n </h1>\n <div class=\"page-desc\"><ng-content select=\"p[description]\" /></div>\n </div>\n <div class=\"page-actions\"><ng-content select=\"[pageActions]\" /></div>\n </header>\n}\n<div class=\"page-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px);box-sizing:border-box;padding-block:var(--fold-page-pad-top, 28px) var(--fold-page-pad-bottom, 40px);padding-inline:var(--fold-page-gutter, 32px);flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fold-space-lg)}.page-head-text{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.page-title{margin:0;display:flex;align-items:center;gap:var(--fold-space-sm);font-size:var(--fold-text-xl);font-weight:700;letter-spacing:-.02em;line-height:1.2;color:var(--fold-color-text)}.page-icon{flex:none;color:var(--fold-color-primary-text)}.page-title-badge{display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-title-badge:empty{display:none}.page-desc{font-size:var(--fold-text-sm);line-height:1.5;max-width:var(--fold-page-desc-measure, none);color:var(--fold-color-text-muted)}.page-desc:empty{display:none}.page-desc>*{margin:0}.page-actions{flex:none;display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-actions:empty{display:none}.page-body{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px)}\n"] }]
|
|
7382
|
+
args: [{ selector: "fold-page-layout", standalone: true, imports: [FoldIconComponent], host: { "[attr.title]": "null" }, template: "@if (title() || customTitle()) {\n <header class=\"page-head\">\n <div class=\"page-head-text\">\n <h1 class=\"page-title\">\n @if (title(); as t) {\n @if (icon(); as ic) {\n <fold-icon class=\"page-icon\" [name]=\"ic\" [size]=\"22\" />\n }\n <span>{{ t }}</span>\n }\n <ng-content select=\"[pageTitle]\" />\n <span class=\"page-title-badge\"\n ><ng-content select=\"[titleBadge]\"\n /></span>\n </h1>\n <div class=\"page-desc\"><ng-content select=\"p[description]\" /></div>\n </div>\n <div class=\"page-actions\"><ng-content select=\"[pageActions]\" /></div>\n </header>\n}\n<div class=\"page-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px);box-sizing:border-box;padding-block:var(--fold-page-pad-top, 28px) var(--fold-page-pad-bottom, 40px);padding-inline:var(--fold-page-gutter, 32px);flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fold-space-lg)}.page-head-text{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.page-title{margin:0;display:flex;align-items:center;gap:var(--fold-space-sm);font-size:var(--fold-text-xl);font-weight:700;letter-spacing:-.02em;line-height:1.2;color:var(--fold-color-text)}.page-icon{flex:none;color:var(--fold-color-primary-text)}.page-title-badge{display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-title-badge:empty{display:none}.page-desc{font-size:var(--fold-text-sm);line-height:1.5;max-width:var(--fold-page-desc-measure, none);color:var(--fold-color-text-muted)}.page-desc:empty{display:none}.page-desc>*{margin:0}.page-actions{flex:none;display:inline-flex;align-items:center;flex-wrap:wrap;gap:var(--fold-space-sm)}.page-actions:empty{display:none}@media(max-width:640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}}@container (max-width: 640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}}.page-body{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px)}\n"] }]
|
|
7383
7383
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], customTitle: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FoldPageTitleDirective), { isSignal: true }] }] } });
|
|
7384
7384
|
|
|
7385
7385
|
/**
|
|
@@ -8060,7 +8060,7 @@ class FoldTabPanelComponent {
|
|
|
8060
8060
|
labelledBy = computed(() => this.tabs().tabId(this.key()), /* @ts-ignore */
|
|
8061
8061
|
...(ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []));
|
|
8062
8062
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldTabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8063
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: FoldTabPanelComponent, isStandalone: true, selector: "fold-tab-panel", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "role": "tabpanel" }, properties: { "id": "panelId()", "attr.aria-labelledby": "labelledBy()", "attr.tabindex": "isActive() ? 0 : null", "hidden": "!isActive()" } }, ngImport: i0, template: "<ng-content />", isInline: true, styles: [":host{display:
|
|
8063
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: FoldTabPanelComponent, isStandalone: true, selector: "fold-tab-panel", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "role": "tabpanel" }, properties: { "id": "panelId()", "attr.aria-labelledby": "labelledBy()", "attr.tabindex": "isActive() ? 0 : null", "hidden": "!isActive()" } }, ngImport: i0, template: "<ng-content />", isInline: true, styles: [":host{display:flex;flex-direction:column;gap:var(--fold-panel-gap)}:host([hidden]){display:none}\n"] });
|
|
8064
8064
|
}
|
|
8065
8065
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldTabPanelComponent, decorators: [{
|
|
8066
8066
|
type: Component,
|
|
@@ -8070,7 +8070,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
8070
8070
|
"[attr.aria-labelledby]": "labelledBy()",
|
|
8071
8071
|
"[attr.tabindex]": "isActive() ? 0 : null",
|
|
8072
8072
|
"[hidden]": "!isActive()",
|
|
8073
|
-
}, template: "<ng-content />", styles: [":host{display:
|
|
8073
|
+
}, template: "<ng-content />", styles: [":host{display:flex;flex-direction:column;gap:var(--fold-panel-gap)}:host([hidden]){display:none}\n"] }]
|
|
8074
8074
|
}], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }] } });
|
|
8075
8075
|
|
|
8076
8076
|
/** Variant → leading status icon. */
|