fold-ng 0.18.0 → 0.20.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.
- package/CHANGELOG.md +61 -1
- package/fesm2022/fold-ng.mjs +129 -14
- package/fesm2022/fold-ng.mjs.map +1 -1
- package/package.json +1 -1
- package/tmp-esm2022/tsconfig.lib.tsbuildinfo +1 -1
- package/types/fold-ng.d.ts +75 -4
- package/types/fold-ng.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,64 @@ All notable changes to **fold-ng** are documented here. The format follows
|
|
|
8
8
|
|
|
9
9
|
_Nothing yet._
|
|
10
10
|
|
|
11
|
+
## [0.20.0] - 2026-08-29
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`fold-data-table` : le tiroir de détail**, ouvert EN PLACE sous sa propre
|
|
16
|
+
ligne. On projette un `<ng-template foldRowDetail let-row>` et la table fait
|
|
17
|
+
le reste : une colonne de bascule en fin de rangée, un tiroir pleine largeur
|
|
18
|
+
sous la ligne, et — en vue étroite — le même tiroir DANS la carte.
|
|
19
|
+
|
|
20
|
+
Sa présence est l'interrupteur : une table sans gabarit de détail se comporte
|
|
21
|
+
exactement comme avant. `[(expanded)]` est un modèle à double sens, comme
|
|
22
|
+
`selected` ; `expandMode` décide si ouvrir une ligne ferme les autres —
|
|
23
|
+
`single` par défaut, parce qu'un tiroir se lit et ne se compare pas, et que
|
|
24
|
+
deux tiroirs ouverts chassent le reste de la liste hors de l'écran.
|
|
25
|
+
|
|
26
|
+
Pourquoi en place plutôt qu'un panneau : on ouvre une ligne pour regarder une
|
|
27
|
+
chose, pas pour quitter l'endroit qu'on a mis du temps à trouver. C'est aussi
|
|
28
|
+
pourquoi la vue en cartes garde le tiroir dans la carte au lieu de basculer
|
|
29
|
+
vers une autre surface — même promesse, même geste, quelle que soit la
|
|
30
|
+
largeur.
|
|
31
|
+
|
|
32
|
+
Le bouton porte `aria-expanded` et **pointe** son tiroir par `aria-controls` :
|
|
33
|
+
sans lui, un lecteur d'écran annonce « développé » sans dire ce qui s'est
|
|
34
|
+
ouvert. La colonne de bascule a un en-tête vide à l'œil seulement — le
|
|
35
|
+
libellé reste dans l'arbre, sinon la dernière colonne s'annonce « colonne 8 ».
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **Navigation clavier : les flèches enjambent un tiroir ouvert.** Les aides
|
|
40
|
+
de focus prenaient le frère IMMÉDIAT ; avec un tiroir intercalé, la flèche
|
|
41
|
+
visait une rangée sans `tabindex` et le focus ne bougeait plus — la
|
|
42
|
+
navigation semblait se bloquer exactement sur les lignes qu'on venait
|
|
43
|
+
d'ouvrir. `Fin` avait le même défaut quand la dernière ligne était ouverte.
|
|
44
|
+
|
|
45
|
+
## [0.19.0] - 2026-08-28
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- **`fold-element-title` : la variante `caps`** — les capitales à la taille et à
|
|
50
|
+
l'encre du titre, pour une RÉGION qui s'annonce : un puits, un rail, une
|
|
51
|
+
bande.
|
|
52
|
+
|
|
53
|
+
`eyebrow` chuchote au-dessus d'une chose, `caps` NOMME la chose — d'où
|
|
54
|
+
l'encre pleine et non la teinte atténuée. Elle comblait un trou réel : entre
|
|
55
|
+
un sur-titre de 10 px et un titre en bas de casse, il n'existait aucun
|
|
56
|
+
registre pour la tête d'une section qui doit se lire d'un bout de l'écran à
|
|
57
|
+
l'autre.
|
|
58
|
+
|
|
59
|
+
⚠️ Son interlettrage reste **positif** (`--fold-tracking-caps`). Des capitales
|
|
60
|
+
ont besoin d'air entre les fûts : le resserrement qui flatte une grande ligne
|
|
61
|
+
d'affichage les soude à cette taille-là. C'est un défaut qui ne se voit que
|
|
62
|
+
sur fond clair — sur un fond sombre, la halation du texte le rattrape — et
|
|
63
|
+
qui fait donc rendre deux titres différemment pour des règles identiques.
|
|
64
|
+
|
|
65
|
+
Le glyphe de tête y reste **plein**, sans la tuile de 40 px du variant
|
|
66
|
+
`title` : une tuile à côté d'une ligne de capitales de 14 px pèserait plus
|
|
67
|
+
lourd que les mots qu'elle introduit.
|
|
68
|
+
|
|
11
69
|
## [0.18.0] - 2026-08-28
|
|
12
70
|
|
|
13
71
|
### Added
|
|
@@ -2246,7 +2304,9 @@ design-token stylesheet.
|
|
|
2246
2304
|
`currentColor`; `prefers-reduced-motion` + `forced-colors` are respected;
|
|
2247
2305
|
strings localise via inputs / providers (`provideFoldPanelLabels`).
|
|
2248
2306
|
|
|
2249
|
-
[unreleased]: https://github.com/hugoheynard/fold-ng/compare/v0.
|
|
2307
|
+
[unreleased]: https://github.com/hugoheynard/fold-ng/compare/v0.20.0...HEAD
|
|
2308
|
+
[0.20.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.20.0
|
|
2309
|
+
[0.19.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.19.0
|
|
2250
2310
|
[0.18.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.18.0
|
|
2251
2311
|
[0.17.1]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.17.1
|
|
2252
2312
|
[0.17.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.17.0
|
package/fesm2022/fold-ng.mjs
CHANGED
|
@@ -3682,6 +3682,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
3682
3682
|
* - `title` — normal-case, `text-md`, primary. A card/panel heading; a leading
|
|
3683
3683
|
* `icon` renders in a tile whose tone is set by `iconTone`
|
|
3684
3684
|
* (`neutral` raised · `primary` filled brand · `faded` dim).
|
|
3685
|
+
* - `caps` — uppercase at the title's size and in primary ink. The register for
|
|
3686
|
+
* a REGION that announces itself: a well, a rail, a band. `eyebrow` whispers
|
|
3687
|
+
* above a thing, `caps` names the thing — which is why it takes the full text
|
|
3688
|
+
* colour and not the muted one.
|
|
3685
3689
|
*
|
|
3686
3690
|
* A trailing action (edit/add button, lock badge) projects into `[titleAction]`,
|
|
3687
3691
|
* right-aligned. The title — not the action — is the heading for assistive tech.
|
|
@@ -3692,6 +3696,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
3692
3696
|
* ```html
|
|
3693
3697
|
* <fold-element-title title="Documents" variant="bar" />
|
|
3694
3698
|
* <fold-element-title variant="title" icon="company" title="Contexte" subtitle="Activité de l'espace" />
|
|
3699
|
+
* <fold-element-title variant="caps" title="Mes suivis" subtitle="3 en cours" />
|
|
3695
3700
|
* <fold-element-title title="Poste">
|
|
3696
3701
|
* <button titleAction (click)="edit()">✎</button>
|
|
3697
3702
|
* </fold-element-title>
|
|
@@ -3710,7 +3715,8 @@ class FoldElementTitleComponent {
|
|
|
3710
3715
|
/** Optional secondary line under the title. */
|
|
3711
3716
|
subtitle = input(/* @ts-ignore */
|
|
3712
3717
|
...(ngDevMode ? [undefined, { debugName: "subtitle" }] : /* istanbul ignore next */ []));
|
|
3713
|
-
/** Emphasis — `eyebrow` (10px muted), `bar` (11px secondary), `title` (text-md,
|
|
3718
|
+
/** Emphasis — `eyebrow` (10px muted), `bar` (11px secondary), `title` (text-md,
|
|
3719
|
+
* normal-case), `caps` (title-size uppercase, primary ink). */
|
|
3714
3720
|
variant = input("eyebrow", /* @ts-ignore */
|
|
3715
3721
|
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
3716
3722
|
/** Heading outline depth exposed to assistive tech (`aria-level`). */
|
|
@@ -3723,19 +3729,20 @@ class FoldElementTitleComponent {
|
|
|
3723
3729
|
iconSize = computed(() => this.variant() === "title" ? "md" : "sm", /* @ts-ignore */
|
|
3724
3730
|
...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
|
|
3725
3731
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldElementTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3726
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldElementTitleComponent, isStandalone: true, selector: "fold-element-title", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconTone: { classPropertyName: "iconTone", publicName: "iconTone", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, headingId: { classPropertyName: "headingId", publicName: "headingId", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.v-bar": "variant() === 'bar'", "class.v-title": "variant() === 'title'", "class.it-primary": "iconTone() === 'primary'", "class.it-faded": "iconTone() === 'faded'", "attr.title": "null" } }, ngImport: i0, template: "@if (icon(); as ic) {\n <span class=\"et-icon\"><fold-icon [name]=\"ic\" [size]=\"iconSize()\" /></span>\n}\n<span class=\"et-main\">\n <span class=\"et-row\">\n <span\n class=\"et-label\"\n role=\"heading\"\n [attr.id]=\"headingId()\"\n [attr.aria-level]=\"level()\"\n >{{ title() }}</span\n >\n <span class=\"et-action\"><ng-content select=\"[titleAction]\" /></span>\n </span>\n @if (subtitle(); as s) {\n <span class=\"et-sub\">{{ s }}</span>\n }\n</span>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:center;gap:var(--fold-space-md);margin:0}.et-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.et-row{display:flex;align-items:center;justify-content:space-between;gap:var(--fold-space-sm)}.et-label{min-width:0;font-family:var(--fold-font-label);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-caps);text-transform:uppercase;color:var(--fold-color-text-muted)}:host(.v-bar) .et-label{font-size:var(--fold-text-xs);color:var(--fold-color-text-secondary)}:host(.v-title) .et-label{font-size:var(--fold-text-base);letter-spacing:var(--fold-tracking-normal);text-transform:none;color:var(--fold-color-text)}.et-sub{font-size:var(--fold-text-xs);color:var(--fold-color-text-muted)}.et-action{flex:none;display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.et-action:empty{display:none}.et-icon{flex:none;display:grid;place-items:center;color:var(--fold-color-primary)}:host(.v-title) .et-icon{width:40px;height:40px;border-radius:var(--fold-radius-md);border:1px solid var(--fold-color-border);background:var(--fold-color-surface-raised)}:host(.v-title.it-primary) .et-icon{background:var(--fold-color-primary);border-color:var(--fold-color-primary);color:var(--fold-color-on-primary)}:host(.v-title.it-faded) .et-icon{background:var(--fold-color-surface-sunken);border-color:var(--fold-color-border-subtle);color:var(--fold-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
|
|
3732
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldElementTitleComponent, isStandalone: true, selector: "fold-element-title", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconTone: { classPropertyName: "iconTone", publicName: "iconTone", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, headingId: { classPropertyName: "headingId", publicName: "headingId", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.v-bar": "variant() === 'bar'", "class.v-title": "variant() === 'title'", "class.v-caps": "variant() === 'caps'", "class.it-primary": "iconTone() === 'primary'", "class.it-faded": "iconTone() === 'faded'", "attr.title": "null" } }, ngImport: i0, template: "@if (icon(); as ic) {\n <span class=\"et-icon\"><fold-icon [name]=\"ic\" [size]=\"iconSize()\" /></span>\n}\n<span class=\"et-main\">\n <span class=\"et-row\">\n <span\n class=\"et-label\"\n role=\"heading\"\n [attr.id]=\"headingId()\"\n [attr.aria-level]=\"level()\"\n >{{ title() }}</span\n >\n <span class=\"et-action\"><ng-content select=\"[titleAction]\" /></span>\n </span>\n @if (subtitle(); as s) {\n <span class=\"et-sub\">{{ s }}</span>\n }\n</span>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:center;gap:var(--fold-space-md);margin:0}.et-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.et-row{display:flex;align-items:center;justify-content:space-between;gap:var(--fold-space-sm)}.et-label{min-width:0;font-family:var(--fold-font-label);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-caps);text-transform:uppercase;color:var(--fold-color-text-muted)}:host(.v-bar) .et-label{font-size:var(--fold-text-xs);color:var(--fold-color-text-secondary)}:host(.v-caps) .et-label{font-size:var(--fold-text-base);font-weight:var(--fold-weight-extrabold);letter-spacing:var(--fold-tracking-caps);color:var(--fold-color-text)}:host(.v-title) .et-label{font-size:var(--fold-text-base);letter-spacing:var(--fold-tracking-normal);text-transform:none;color:var(--fold-color-text)}.et-sub{font-size:var(--fold-text-xs);color:var(--fold-color-text-muted)}.et-action{flex:none;display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.et-action:empty{display:none}.et-icon{flex:none;display:grid;place-items:center;color:var(--fold-color-primary)}:host(.v-title) .et-icon{width:40px;height:40px;border-radius:var(--fold-radius-md);border:1px solid var(--fold-color-border);background:var(--fold-color-surface-raised)}:host(.v-title.it-primary) .et-icon{background:var(--fold-color-primary);border-color:var(--fold-color-primary);color:var(--fold-color-on-primary)}:host(.v-title.it-faded) .et-icon{background:var(--fold-color-surface-sunken);border-color:var(--fold-color-border-subtle);color:var(--fold-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
|
|
3727
3733
|
}
|
|
3728
3734
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldElementTitleComponent, decorators: [{
|
|
3729
3735
|
type: Component,
|
|
3730
3736
|
args: [{ selector: "fold-element-title", standalone: true, imports: [FoldIconComponent], host: {
|
|
3731
3737
|
"[class.v-bar]": "variant() === 'bar'",
|
|
3732
3738
|
"[class.v-title]": "variant() === 'title'",
|
|
3739
|
+
"[class.v-caps]": "variant() === 'caps'",
|
|
3733
3740
|
"[class.it-primary]": "iconTone() === 'primary'",
|
|
3734
3741
|
"[class.it-faded]": "iconTone() === 'faded'",
|
|
3735
3742
|
// `title` is a heading input — strip the reflected native attribute so it
|
|
3736
3743
|
// never doubles as a browser tooltip.
|
|
3737
3744
|
"[attr.title]": "null",
|
|
3738
|
-
}, template: "@if (icon(); as ic) {\n <span class=\"et-icon\"><fold-icon [name]=\"ic\" [size]=\"iconSize()\" /></span>\n}\n<span class=\"et-main\">\n <span class=\"et-row\">\n <span\n class=\"et-label\"\n role=\"heading\"\n [attr.id]=\"headingId()\"\n [attr.aria-level]=\"level()\"\n >{{ title() }}</span\n >\n <span class=\"et-action\"><ng-content select=\"[titleAction]\" /></span>\n </span>\n @if (subtitle(); as s) {\n <span class=\"et-sub\">{{ s }}</span>\n }\n</span>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:center;gap:var(--fold-space-md);margin:0}.et-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.et-row{display:flex;align-items:center;justify-content:space-between;gap:var(--fold-space-sm)}.et-label{min-width:0;font-family:var(--fold-font-label);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-caps);text-transform:uppercase;color:var(--fold-color-text-muted)}:host(.v-bar) .et-label{font-size:var(--fold-text-xs);color:var(--fold-color-text-secondary)}:host(.v-title) .et-label{font-size:var(--fold-text-base);letter-spacing:var(--fold-tracking-normal);text-transform:none;color:var(--fold-color-text)}.et-sub{font-size:var(--fold-text-xs);color:var(--fold-color-text-muted)}.et-action{flex:none;display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.et-action:empty{display:none}.et-icon{flex:none;display:grid;place-items:center;color:var(--fold-color-primary)}:host(.v-title) .et-icon{width:40px;height:40px;border-radius:var(--fold-radius-md);border:1px solid var(--fold-color-border);background:var(--fold-color-surface-raised)}:host(.v-title.it-primary) .et-icon{background:var(--fold-color-primary);border-color:var(--fold-color-primary);color:var(--fold-color-on-primary)}:host(.v-title.it-faded) .et-icon{background:var(--fold-color-surface-sunken);border-color:var(--fold-color-border-subtle);color:var(--fold-color-text-muted)}\n"] }]
|
|
3745
|
+
}, template: "@if (icon(); as ic) {\n <span class=\"et-icon\"><fold-icon [name]=\"ic\" [size]=\"iconSize()\" /></span>\n}\n<span class=\"et-main\">\n <span class=\"et-row\">\n <span\n class=\"et-label\"\n role=\"heading\"\n [attr.id]=\"headingId()\"\n [attr.aria-level]=\"level()\"\n >{{ title() }}</span\n >\n <span class=\"et-action\"><ng-content select=\"[titleAction]\" /></span>\n </span>\n @if (subtitle(); as s) {\n <span class=\"et-sub\">{{ s }}</span>\n }\n</span>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:center;gap:var(--fold-space-md);margin:0}.et-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.et-row{display:flex;align-items:center;justify-content:space-between;gap:var(--fold-space-sm)}.et-label{min-width:0;font-family:var(--fold-font-label);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-caps);text-transform:uppercase;color:var(--fold-color-text-muted)}:host(.v-bar) .et-label{font-size:var(--fold-text-xs);color:var(--fold-color-text-secondary)}:host(.v-caps) .et-label{font-size:var(--fold-text-base);font-weight:var(--fold-weight-extrabold);letter-spacing:var(--fold-tracking-caps);color:var(--fold-color-text)}:host(.v-title) .et-label{font-size:var(--fold-text-base);letter-spacing:var(--fold-tracking-normal);text-transform:none;color:var(--fold-color-text)}.et-sub{font-size:var(--fold-text-xs);color:var(--fold-color-text-muted)}.et-action{flex:none;display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.et-action:empty{display:none}.et-icon{flex:none;display:grid;place-items:center;color:var(--fold-color-primary)}:host(.v-title) .et-icon{width:40px;height:40px;border-radius:var(--fold-radius-md);border:1px solid var(--fold-color-border);background:var(--fold-color-surface-raised)}:host(.v-title.it-primary) .et-icon{background:var(--fold-color-primary);border-color:var(--fold-color-primary);color:var(--fold-color-on-primary)}:host(.v-title.it-faded) .et-icon{background:var(--fold-color-surface-sunken);border-color:var(--fold-color-border-subtle);color:var(--fold-color-text-muted)}\n"] }]
|
|
3739
3746
|
}], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconTone: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconTone", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], headingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingId", required: false }] }] } });
|
|
3740
3747
|
|
|
3741
3748
|
/**
|
|
@@ -5184,28 +5191,82 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
5184
5191
|
args: [{ selector: "ng-template[foldRowCard]", standalone: true }]
|
|
5185
5192
|
}] });
|
|
5186
5193
|
|
|
5194
|
+
/**
|
|
5195
|
+
* Marks the `<ng-template>` that renders a row's **detail drawer**, opened in
|
|
5196
|
+
* place under the row it belongs to:
|
|
5197
|
+
*
|
|
5198
|
+
* ```html
|
|
5199
|
+
* <ng-template foldRowDetail let-row let-i="index"> … </ng-template>
|
|
5200
|
+
* ```
|
|
5201
|
+
*
|
|
5202
|
+
* The template context is `{ $implicit: row, index }`.
|
|
5203
|
+
*
|
|
5204
|
+
* Its presence is what turns the feature on: the table grows a trailing toggle
|
|
5205
|
+
* column, and each row can open a full-width drawer beneath itself. Nothing to
|
|
5206
|
+
* enable, nothing to configure — a table with no detail template behaves
|
|
5207
|
+
* exactly as before.
|
|
5208
|
+
*
|
|
5209
|
+
* **In place, and not elsewhere.** A drawer keeps the list under the reader's
|
|
5210
|
+
* eyes: they opened a row to look at one thing, not to leave the place they
|
|
5211
|
+
* spent time finding. That is also why the drawer lives inside the CARD on a
|
|
5212
|
+
* narrow screen rather than falling back to a panel — same promise, same
|
|
5213
|
+
* gesture, whatever the width.
|
|
5214
|
+
*
|
|
5215
|
+
* As with cell templates, `let-row` is untyped by design — annotate through the
|
|
5216
|
+
* parent component's typed helpers.
|
|
5217
|
+
*/
|
|
5218
|
+
class FoldDataTableRowDetailDirective {
|
|
5219
|
+
template = inject(TemplateRef);
|
|
5220
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldDataTableRowDetailDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
5221
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: FoldDataTableRowDetailDirective, isStandalone: true, selector: "ng-template[foldRowDetail]", ngImport: i0 });
|
|
5222
|
+
}
|
|
5223
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldDataTableRowDetailDirective, decorators: [{
|
|
5224
|
+
type: Directive,
|
|
5225
|
+
args: [{ selector: "ng-template[foldRowDetail]", standalone: true }]
|
|
5226
|
+
}] });
|
|
5227
|
+
|
|
5187
5228
|
/**
|
|
5188
5229
|
* Roving-tabindex DOM helpers for `fold-data-table` body rows — pure functions
|
|
5189
5230
|
* that move focus between `<tr>` siblings, so the component's keydown handler
|
|
5190
5231
|
* stays thin and they are unit-testable without a component fixture.
|
|
5191
5232
|
*/
|
|
5192
|
-
/**
|
|
5233
|
+
/**
|
|
5234
|
+
* Is this element part of the roving group?
|
|
5235
|
+
*
|
|
5236
|
+
* A body row carries `tabindex`; a detail drawer does not. Without this test,
|
|
5237
|
+
* an arrow key landing on an open drawer would call `focus()` on something that
|
|
5238
|
+
* cannot take it — focus would stay put and the navigation would appear to jam
|
|
5239
|
+
* on exactly the rows the reader had opened.
|
|
5240
|
+
*/
|
|
5241
|
+
function navigable(node) {
|
|
5242
|
+
return node instanceof HTMLElement && node.hasAttribute("tabindex");
|
|
5243
|
+
}
|
|
5244
|
+
/** Focus the adjacent NAVIGABLE row (Arrow Up/Down), skipping any drawer. */
|
|
5193
5245
|
function focusAdjacentRow(from, edge) {
|
|
5194
5246
|
if (!(from instanceof Element)) {
|
|
5195
5247
|
return;
|
|
5196
5248
|
}
|
|
5197
|
-
|
|
5198
|
-
|
|
5249
|
+
let sibling = from[edge];
|
|
5250
|
+
while (sibling !== null && !navigable(sibling)) {
|
|
5251
|
+
sibling = sibling[edge];
|
|
5252
|
+
}
|
|
5253
|
+
if (navigable(sibling)) {
|
|
5199
5254
|
sibling.focus();
|
|
5200
5255
|
}
|
|
5201
5256
|
}
|
|
5202
|
-
/** Focus the first / last row in the same body (Home / End). */
|
|
5257
|
+
/** Focus the first / last navigable row in the same body (Home / End). */
|
|
5203
5258
|
function focusEdgeRow(from, edge) {
|
|
5204
5259
|
if (!(from instanceof Element)) {
|
|
5205
5260
|
return;
|
|
5206
5261
|
}
|
|
5207
|
-
|
|
5208
|
-
|
|
5262
|
+
let target = from.parentElement?.[edge] ?? null;
|
|
5263
|
+
const step = edge === "firstElementChild"
|
|
5264
|
+
? "nextElementSibling"
|
|
5265
|
+
: "previousElementSibling";
|
|
5266
|
+
while (target !== null && !navigable(target)) {
|
|
5267
|
+
target = target[step];
|
|
5268
|
+
}
|
|
5269
|
+
if (navigable(target)) {
|
|
5209
5270
|
target.focus();
|
|
5210
5271
|
}
|
|
5211
5272
|
}
|
|
@@ -5369,6 +5430,8 @@ const FOLD_DATA_TABLE_DEFAULT_LABELS = {
|
|
|
5369
5430
|
selectRow: "Select row",
|
|
5370
5431
|
sortBy: (column) => `Sort by ${column}`,
|
|
5371
5432
|
loading: "Loading…",
|
|
5433
|
+
expandRow: "Show details",
|
|
5434
|
+
collapseRow: "Hide details",
|
|
5372
5435
|
};
|
|
5373
5436
|
/** App-wide data-table labels; defaults to English. */
|
|
5374
5437
|
const FOLD_DATA_TABLE_LABELS = new InjectionToken("FOLD_DATA_TABLE_LABELS", { factory: () => FOLD_DATA_TABLE_DEFAULT_LABELS });
|
|
@@ -5408,6 +5471,13 @@ const CARDS_AT = 600;
|
|
|
5408
5471
|
* current rows), and the selected-row tint. Bind it one-way (`[selected]`) to
|
|
5409
5472
|
* stay fully controlled.
|
|
5410
5473
|
*
|
|
5474
|
+
* A row can open a **detail drawer in place**: project a
|
|
5475
|
+
* `<ng-template foldRowDetail let-row>` and the table grows a trailing toggle
|
|
5476
|
+
* column, opening the drawer beneath its row (inside the card, in the card
|
|
5477
|
+
* layout). Bind `[(expanded)]` with a set of row keys to control it, or let the
|
|
5478
|
+
* table own it. `expandMode` decides whether opening one closes the others —
|
|
5479
|
+
* `single` by default, because a drawer is usually read one at a time.
|
|
5480
|
+
*
|
|
5411
5481
|
* The narrow-screen behaviour is the parent's choice, not an imposed one, via
|
|
5412
5482
|
* `mobileLayout`: `scroll` (default — stay tabular, scroll horizontally),
|
|
5413
5483
|
* `auto-cards` (each row stacks into a label/value card), or `custom` (the
|
|
@@ -5505,6 +5575,22 @@ class FoldDataTableComponent {
|
|
|
5505
5575
|
/** Per-instance label overrides (merged over the app-wide / English defaults). */
|
|
5506
5576
|
labels = input(/* @ts-ignore */
|
|
5507
5577
|
...(ngDevMode ? [undefined, { debugName: "labels" }] : /* istanbul ignore next */ []));
|
|
5578
|
+
/**
|
|
5579
|
+
* The open rows, by key. A two-way model, exactly like `selected`: bind
|
|
5580
|
+
* `[(expanded)]` and the table writes the next set on every toggle, or bind
|
|
5581
|
+
* one-way to stay fully controlled.
|
|
5582
|
+
*/
|
|
5583
|
+
expanded = model(new Set(), /* @ts-ignore */
|
|
5584
|
+
...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
5585
|
+
/**
|
|
5586
|
+
* Whether opening a row closes the others.
|
|
5587
|
+
*
|
|
5588
|
+
* `single` by default — a drawer is read, not compared, and two open at once
|
|
5589
|
+
* push the rest of the list off the screen for no gain. `multi` when the
|
|
5590
|
+
* drawers ARE the comparison.
|
|
5591
|
+
*/
|
|
5592
|
+
expandMode = input("single", /* @ts-ignore */
|
|
5593
|
+
...(ngDevMode ? [{ debugName: "expandMode" }] : /* istanbul ignore next */ []));
|
|
5508
5594
|
/** Emits the clicked sortable column's `key`. */
|
|
5509
5595
|
sortChange = output();
|
|
5510
5596
|
rowClick = output();
|
|
@@ -5570,6 +5656,33 @@ class FoldDataTableComponent {
|
|
|
5570
5656
|
return map;
|
|
5571
5657
|
}, /* @ts-ignore */
|
|
5572
5658
|
...(ngDevMode ? [{ debugName: "cellMap" }] : /* istanbul ignore next */ []));
|
|
5659
|
+
rowDetail = contentChild(FoldDataTableRowDetailDirective, /* @ts-ignore */
|
|
5660
|
+
...(ngDevMode ? [{ debugName: "rowDetail" }] : /* istanbul ignore next */ []));
|
|
5661
|
+
/** The drawer template, or `null`. Its PRESENCE is the feature switch. */
|
|
5662
|
+
rowDetailTemplate = computed(() => this.rowDetail()?.template ?? null, /* @ts-ignore */
|
|
5663
|
+
...(ngDevMode ? [{ debugName: "rowDetailTemplate" }] : /* istanbul ignore next */ []));
|
|
5664
|
+
expandable = computed(() => this.rowDetailTemplate() !== null, /* @ts-ignore */
|
|
5665
|
+
...(ngDevMode ? [{ debugName: "expandable" }] : /* istanbul ignore next */ []));
|
|
5666
|
+
/** Stable prefix for the drawer ids the toggles point at with `aria-controls`. */
|
|
5667
|
+
uid = inject(FoldIdService).next("fold-data-table");
|
|
5668
|
+
detailId(row, index) {
|
|
5669
|
+
return `${this.uid}-detail-${this.keyOf(row, index)}`;
|
|
5670
|
+
}
|
|
5671
|
+
isRowExpanded(row, index) {
|
|
5672
|
+
return this.expanded().has(this.keyOf(row, index));
|
|
5673
|
+
}
|
|
5674
|
+
/** Toggles a row's drawer, honouring {@link expandMode}. */
|
|
5675
|
+
toggleExpand(row, index) {
|
|
5676
|
+
const key = this.keyOf(row, index);
|
|
5677
|
+
const open = this.expanded();
|
|
5678
|
+
if (open.has(key)) {
|
|
5679
|
+
const next = new Set(open);
|
|
5680
|
+
next.delete(key);
|
|
5681
|
+
this.expanded.set(next);
|
|
5682
|
+
return;
|
|
5683
|
+
}
|
|
5684
|
+
this.expanded.set(this.expandMode() === "single" ? new Set([key]) : new Set(open).add(key));
|
|
5685
|
+
}
|
|
5573
5686
|
rowCard = contentChild(FoldDataTableRowCardDirective, /* @ts-ignore */
|
|
5574
5687
|
...(ngDevMode ? [{ debugName: "rowCard" }] : /* istanbul ignore next */ []));
|
|
5575
5688
|
/**
|
|
@@ -5629,7 +5742,9 @@ class FoldDataTableComponent {
|
|
|
5629
5742
|
primaryKey = computed(() => this.columns()[0]?.key ?? "", /* @ts-ignore */
|
|
5630
5743
|
...(ngDevMode ? [{ debugName: "primaryKey" }] : /* istanbul ignore next */ []));
|
|
5631
5744
|
/** Total ARIA column count (data columns + the checkbox column). */
|
|
5632
|
-
colCount = computed(() => this.columns().length +
|
|
5745
|
+
colCount = computed(() => this.columns().length +
|
|
5746
|
+
(this.selectable() ? 1 : 0) +
|
|
5747
|
+
(this.expandable() ? 1 : 0), /* @ts-ignore */
|
|
5633
5748
|
...(ngDevMode ? [{ debugName: "colCount" }] : /* istanbul ignore next */ []));
|
|
5634
5749
|
/** Current row keys, in order — the roving-nav anchor set. */
|
|
5635
5750
|
rowKeys = computed(() => this.rows().map((row, i) => this.keyOf(row, i)), /* @ts-ignore */
|
|
@@ -5768,7 +5883,7 @@ class FoldDataTableComponent {
|
|
|
5768
5883
|
}
|
|
5769
5884
|
}
|
|
5770
5885
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5771
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldDataTableComponent, isStandalone: true, selector: "fold-data-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null }, rowTone: { classPropertyName: "rowTone", publicName: "rowTone", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, empty: { classPropertyName: "empty", publicName: "empty", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, zebra: { classPropertyName: "zebra", publicName: "zebra", isSignal: true, isRequired: false, transformFunction: null }, hover: { classPropertyName: "hover", publicName: "hover", isSignal: true, isRequired: false, transformFunction: null }, narrowLayout: { classPropertyName: "narrowLayout", publicName: "narrowLayout", isSignal: true, isRequired: false, transformFunction: null }, cardsAt: { classPropertyName: "cardsAt", publicName: "cardsAt", isSignal: true, isRequired: false, transformFunction: null }, rowCardChrome: { classPropertyName: "rowCardChrome", publicName: "rowCardChrome", isSignal: true, isRequired: false, transformFunction: null }, mobileLayout: { classPropertyName: "mobileLayout", publicName: "mobileLayout", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, stickyFirst: { classPropertyName: "stickyFirst", publicName: "stickyFirst", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, selectionLabel: { classPropertyName: "selectionLabel", publicName: "selectionLabel", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, toolbarSurface: { classPropertyName: "toolbarSurface", publicName: "toolbarSurface", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange", sortChange: "sortChange", rowClick: "rowClick" }, queries: [{ propertyName: "cells", predicate: FoldDataTableCellDirective, isSignal: true }, { propertyName: "rowCard", first: true, predicate: FoldDataTableRowCardDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"folddt-wrap\"\n [class.folddt--zebra]=\"zebra()\"\n [class.folddt--hover]=\"hover()\"\n [class.folddt--narrow]=\"isNarrow()\"\n [class.folddt--compact]=\"density() === 'compact'\"\n [class.folddt--sticky-first]=\"stickyFirst()\"\n [class.folddt--select]=\"selectable()\"\n>\n <div\n class=\"folddt-toolbar\"\n [class.folddt-toolbar--sunken]=\"toolbarSurface() === 'sunken'\"\n [class.folddt-toolbar--raised]=\"toolbarSurface() === 'raised'\"\n [class.folddt-toolbar--accent]=\"toolbarSurface() === 'accent'\"\n [attr.data-surface]=\"toolbarSurface() === 'accent' ? 'accent' : null\"\n >\n <ng-content select=\"[foldToolbar]\" />\n </div>\n @if (!cardMode()) {\n <div class=\"folddt-scroll\">\n <table class=\"folddt\" [attr.aria-colcount]=\"colCount()\">\n @if (caption(); as cap) {\n <caption class=\"folddt-caption\">\n {{\n cap\n }}\n </caption>\n }\n <thead>\n <tr>\n @if (selectable()) {\n <th scope=\"col\" class=\"folddt-select-h\">\n <fold-checkbox\n size=\"sm\"\n [ariaLabel]=\"l().selectAll\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (checkedChange)=\"toggleAll()\"\n />\n </th>\n }\n @for (col of columns(); track col.key) {\n <th\n scope=\"col\"\n [class.is-primary-h]=\"col.key === primaryKey()\"\n [style.width]=\"col.width || null\"\n [attr.aria-sort]=\"col.sortable ? ariaSort(col.key) : null\"\n >\n @if (col.sortable) {\n <button\n type=\"button\"\n class=\"folddt-th-sort\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [attr.aria-label]=\"l().sortBy(col.label)\"\n (click)=\"sortChange.emit(col.key)\"\n >\n <span>{{ col.label }}</span>\n <fold-icon\n class=\"folddt-arrow\"\n [class.on]=\"isSorted(col.key)\"\n [name]=\"sortIcon(col.key)\"\n [size]=\"14\"\n />\n </button>\n } @else {\n <span\n class=\"folddt-th-plain\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n >{{ col.label }}</span\n >\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track keyOf(row, $index); let i = $index) {\n @let tone = toneOf(row);\n <tr\n class=\"folddt-row\"\n [class.tone-warning]=\"tone === 'warning'\"\n [class.tone-alert]=\"tone === 'alert'\"\n [class.tone-success]=\"tone === 'success'\"\n [class.clickable]=\"clickable()\"\n [class.is-selected]=\"selectable() && isRowSelected(row, i)\"\n [attr.tabindex]=\"rowTabIndex(row, i)\"\n [attr.aria-selected]=\"selectable() ? isRowSelected(row, i) : null\"\n (click)=\"onRowActivate(row)\"\n (focus)=\"onRowFocus(row, i)\"\n (keydown)=\"onRowKeydown($event, row)\"\n >\n @if (selectable()) {\n <td class=\"folddt-cell folddt-cell--select\">\n <fold-checkbox\n size=\"sm\"\n [ariaLabel]=\"labelFor(row)\"\n [checked]=\"isRowSelected(row, i)\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"toggleRow(row, i)\"\n />\n </td>\n }\n @for (col of columns(); track col.key) {\n @if (col.key === primaryKey()) {\n <th\n scope=\"row\"\n class=\"folddt-cell is-primary\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [class.truncate]=\"col.truncate\"\n [ngClass]=\"col.cellClass || ''\"\n [attr.data-label]=\"col.label\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </th>\n } @else {\n <td\n class=\"folddt-cell\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [class.truncate]=\"col.truncate\"\n [ngClass]=\"col.cellClass || ''\"\n [attr.data-label]=\"col.label\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </td>\n }\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <!-- `role=\"list\"` on a <ul> looks redundant and is not: `list-style: none`\n strips list semantics in Safari, which is exactly what the styling\n does. One list, one shell \u2014 the projected template supplies the\n CONTENT, the shell supplies the chrome (outline, tone, selection), so a\n consumer never reinvents them. -->\n <ul class=\"folddt-cardlist\" role=\"list\">\n @for (row of rows(); track keyOf(row, $index); let i = $index) {\n @let tone = toneOf(row);\n <li\n class=\"folddt-card\"\n [class.is-bare]=\"rowCardChrome() === 'none' && rowCardTemplate()\"\n [class.tone-warning]=\"tone === 'warning'\"\n [class.tone-alert]=\"tone === 'alert'\"\n [class.tone-success]=\"tone === 'success'\"\n [class.is-selected]=\"selectable() && isRowSelected(row, i)\"\n [attr.aria-selected]=\"selectable() ? isRowSelected(row, i) : null\"\n >\n @if (\n selectable() && !(rowCardChrome() === \"none\" && rowCardTemplate())\n ) {\n <fold-checkbox\n class=\"folddt-card-select\"\n size=\"sm\"\n [ariaLabel]=\"labelFor(row)\"\n [checked]=\"isRowSelected(row, i)\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"toggleRow(row, i)\"\n />\n }\n <div class=\"folddt-card-body\">\n @if (rowCardTemplate(); as card) {\n <ng-container\n [ngTemplateOutlet]=\"card\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n @if (overlineColumn(); as col) {\n <p class=\"folddt-card-overline\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </p>\n }\n @if (identityColumn(); as col) {\n <p class=\"folddt-card-identity\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </p>\n }\n <!-- A <dl> and not a `::before { content: attr(data-label) }`:\n generated content is not reliably announced, and a label/value\n pair IS a description list. It also lets the values line up in\n columns, which matters for amounts. -->\n <dl class=\"folddt-card-grid\">\n @for (col of gridColumns(); track col.key) {\n <!-- A <div> around each pair is valid inside a <dl> and is\n what puts the label ABOVE its value in one grid cell. -->\n <div class=\"folddt-card-pair\">\n <dt>{{ col.label }}</dt>\n <dd [class.right]=\"col.align === 'right'\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </dd>\n </div>\n }\n </dl>\n }\n </div>\n </li>\n }\n </ul>\n }\n\n @if (loading()) {\n <div class=\"folddt-loading\">\n <fold-spinner [label]=\"l().loading\" />\n </div>\n } @else if (rows().length === 0 && empty(); as e) {\n <div class=\"folddt-empty\">\n <div class=\"folddt-empty-t\">{{ e.title }}</div>\n @if (e.subtitle) {\n <div class=\"folddt-empty-s\">{{ e.subtitle }}</div>\n }\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;min-height:0}.folddt-wrap{--folddt-sel-w: 0px;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;border:1px solid var(--fold-color-border-subtle);border-radius:var(--fold-radius-lg);background:var(--fold-color-surface-sunken);box-shadow:var(--fold-shadow-md)}.folddt--select{--folddt-sel-w: 44px}.folddt-scroll{flex:1 1 auto;min-height:0;overflow:auto}.folddt-toolbar{padding:var(--fold-space-md) var(--fold-space-lg);border-bottom:1px solid var(--fold-color-border);color:var(--fold-color-text);background:color-mix(in srgb,var(--fold-color-surface-sunken) 50%,var(--fold-color-surface-card))}.folddt-toolbar:not(:has(*)){display:none}.folddt-toolbar--sunken{background:var(--fold-color-surface-sunken)}.folddt-toolbar--raised{background:var(--fold-color-surface-raised)}.folddt-toolbar--accent{background:var(--fold-color-primary);border-bottom-color:var(--fold-color-primary);color:var(--fold-color-on-primary)}.folddt{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fold-text-sm)}.folddt-caption{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.folddt thead th{position:sticky;top:0;z-index:2;padding:0;text-align:left;background:color-mix(in srgb,var(--fold-color-surface-sunken) 50%,var(--fold-color-surface-card));border-bottom:1px solid var(--fold-color-border)}.folddt-th-sort,.folddt-th-plain{display:inline-flex;align-items:center;padding:var(--fold-space-md) var(--fold-space-lg);color:var(--fold-color-text-muted);font-family:var(--fold-font-label);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);text-transform:uppercase;letter-spacing:var(--fold-tracking-caps)}.folddt-th-sort{gap:var(--fold-space-sm);width:100%;border:0;background:transparent;cursor:pointer;transition:color var(--fold-motion-fast)}.folddt-th-sort:hover{color:var(--fold-color-text)}.folddt-th-sort.right{justify-content:flex-end}.folddt-th-plain.right{justify-content:flex-end;width:100%}.folddt-arrow{display:inline-flex;color:var(--fold-color-text-faded);transition:color var(--fold-motion-fast)}.folddt-arrow.on{color:var(--fold-color-primary-text)}.folddt-row{transition:background var(--fold-motion-fast)}.folddt-row.clickable{cursor:pointer}.folddt-row .folddt-cell{border-bottom:1px solid var(--fold-color-border-subtle)}.folddt-row:last-child .folddt-cell{border-bottom:0}.folddt-row:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:-2px}.folddt--zebra .folddt-row:nth-child(2n):not(.tone-warning):not(.tone-alert):not(.tone-success) .folddt-cell{background:var(--fold-color-surface-subtle)}.folddt--zebra .folddt-row .folddt-cell{border-bottom-color:transparent}.folddt--hover .folddt-row:hover .folddt-cell{background:var(--fold-color-surface-raised)}.folddt--hover .folddt-row.tone-warning:hover .folddt-cell{background:color-mix(in srgb,var(--fold-color-warning) 16%,transparent)}.folddt--hover .folddt-row.tone-alert:hover .folddt-cell{background:color-mix(in srgb,var(--fold-color-alert) 17%,transparent)}.folddt-cell{padding:var(--fold-space-md) var(--fold-space-lg);color:var(--fold-color-text);font-weight:inherit;text-align:left;white-space:nowrap;vertical-align:middle}.folddt-cell.right{text-align:right}.folddt-cell.center{text-align:center}.folddt-cell.truncate{max-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.folddt-row.tone-warning .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-warning)}.folddt-row.tone-warning .folddt-cell{background:color-mix(in srgb,var(--fold-color-warning) 10%,transparent)}.folddt-row.tone-alert .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-alert)}.folddt-row.tone-alert .folddt-cell{background:color-mix(in srgb,var(--fold-color-alert) 11%,transparent)}.folddt-row.tone-success .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-success)}.folddt-row.tone-success .folddt-cell{background:color-mix(in srgb,var(--fold-color-success) 9%,transparent)}.folddt-loading{display:flex;align-items:center;justify-content:center;padding:var(--fold-space-5xl) var(--fold-space-2xl)}.folddt-empty{padding:var(--fold-space-5xl) var(--fold-space-2xl);text-align:center}.folddt-empty-t{font-size:var(--fold-text-base);font-weight:var(--fold-weight-semibold);color:var(--fold-color-text)}.folddt-empty-s{font-size:var(--fold-text-sm);color:var(--fold-color-text-muted);margin-top:var(--fold-space-xs)}.folddt-cardlist{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.folddt-card{display:flex;gap:var(--fold-space-md);align-items:flex-start;padding:var(--fold-space-md) var(--fold-space-lg);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border);border-radius:var(--fold-radius-lg);box-shadow:var(--fold-shadow-sm)}.folddt-card-body{flex:1 1 auto;min-width:0}.folddt-card.tone-warning{border-inline-start:3px solid var(--fold-color-warning)}.folddt-card.tone-alert{border-inline-start:3px solid var(--fold-color-alert)}.folddt-card.tone-success{border-inline-start:3px solid var(--fold-color-success)}.folddt-card.is-selected{background:var(--fold-color-primary-surface);border-color:var(--fold-color-primary)}.folddt-card.is-bare,.folddt-card.is-bare.is-selected,.folddt-card.is-bare.tone-warning,.folddt-card.is-bare.tone-alert,.folddt-card.is-bare.tone-success{padding:0;background:none;border:0;border-radius:0;box-shadow:none}.folddt-select-h,.folddt-cell--select{width:var(--folddt-sel-w);padding-left:var(--fold-space-lg);padding-right:0;text-align:left;white-space:nowrap}.folddt-select-h{vertical-align:middle}.folddt-row.is-selected .folddt-cell{background:color-mix(in srgb,var(--fold-color-primary) 8%,transparent)}.folddt-row.is-selected .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-primary)}.folddt--compact .folddt-cell,.folddt--compact .folddt-th-sort,.folddt--compact .folddt-th-plain{padding:var(--fold-space-sm) var(--fold-space-md)}.folddt--compact .folddt-cell--select{padding-left:var(--fold-space-md);padding-right:0}.folddt--sticky-first .folddt-cell--select,.folddt--sticky-first .folddt-select-h{position:sticky;left:0;background:var(--fold-color-surface-sunken)}.folddt--sticky-first .folddt-select-h{z-index:3}.folddt--sticky-first .folddt-cell.is-primary{position:sticky;left:var(--folddt-sel-w);z-index:1;background:var(--fold-color-surface-sunken)}.folddt--sticky-first thead th.is-primary-h{position:sticky;left:var(--folddt-sel-w);z-index:3}.folddt--sticky-first .folddt-row.tone-warning .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-warning) 10%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.tone-alert .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-alert) 11%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.tone-success .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-success) 9%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.is-selected .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-primary) 8%,var(--fold-color-surface-sunken))}@media(prefers-reduced-motion:reduce){.folddt-row,.folddt-th-sort,.folddt-arrow{transition:none}}@media(forced-colors:active){.folddt-row.is-selected .folddt-cell:first-child,.folddt-row.tone-warning .folddt-cell:first-child,.folddt-row.tone-alert .folddt-cell:first-child,.folddt-row.tone-success .folddt-cell:first-child{border-inline-start:3px solid Highlight}.folddt-row:focus-visible{outline-color:Highlight}}.folddt-cardlist{gap:var(--fold-space-sm)}.folddt-card-overline{margin:0 0 var(--fold-space-xs);color:var(--fold-color-text-muted);font-size:var(--fold-text-xs);font-weight:var(--fold-weight-medium);overflow-wrap:anywhere}.folddt-card-identity{margin:0;color:var(--fold-color-text);font-size:var(--fold-text-base);font-weight:var(--fold-weight-semibold);letter-spacing:var(--fold-tracking-tight)}.folddt-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--fold-space-sm) var(--fold-space-md);margin:var(--fold-space-md) 0 0}.folddt-card-pair{min-width:0}.folddt-card-grid dt{color:var(--fold-color-text-muted);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-caps);text-transform:uppercase}.folddt-card-grid dd{margin:var(--fold-space-xs) 0 0;color:var(--fold-color-text);font-size:var(--fold-text-sm)}.folddt-card-grid dd.right{font-variant-numeric:tabular-nums}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldSpinnerComponent, selector: "fold-spinner", inputs: ["size", "label"] }, { kind: "component", type: FoldCheckboxComponent, selector: "fold-checkbox", inputs: ["checked", "disabled", "touched", "errors", "indeterminate", "label", "ariaLabel", "hint", "required", "size"], outputs: ["checkedChange", "touchedChange"] }] });
|
|
5886
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldDataTableComponent, isStandalone: true, selector: "fold-data-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null }, rowTone: { classPropertyName: "rowTone", publicName: "rowTone", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, empty: { classPropertyName: "empty", publicName: "empty", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, zebra: { classPropertyName: "zebra", publicName: "zebra", isSignal: true, isRequired: false, transformFunction: null }, hover: { classPropertyName: "hover", publicName: "hover", isSignal: true, isRequired: false, transformFunction: null }, narrowLayout: { classPropertyName: "narrowLayout", publicName: "narrowLayout", isSignal: true, isRequired: false, transformFunction: null }, cardsAt: { classPropertyName: "cardsAt", publicName: "cardsAt", isSignal: true, isRequired: false, transformFunction: null }, rowCardChrome: { classPropertyName: "rowCardChrome", publicName: "rowCardChrome", isSignal: true, isRequired: false, transformFunction: null }, mobileLayout: { classPropertyName: "mobileLayout", publicName: "mobileLayout", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, stickyFirst: { classPropertyName: "stickyFirst", publicName: "stickyFirst", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, selectionLabel: { classPropertyName: "selectionLabel", publicName: "selectionLabel", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null }, expandMode: { classPropertyName: "expandMode", publicName: "expandMode", isSignal: true, isRequired: false, transformFunction: null }, toolbarSurface: { classPropertyName: "toolbarSurface", publicName: "toolbarSurface", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange", expanded: "expandedChange", sortChange: "sortChange", rowClick: "rowClick" }, queries: [{ propertyName: "cells", predicate: FoldDataTableCellDirective, isSignal: true }, { propertyName: "rowDetail", first: true, predicate: FoldDataTableRowDetailDirective, descendants: true, isSignal: true }, { propertyName: "rowCard", first: true, predicate: FoldDataTableRowCardDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"folddt-wrap\"\n [class.folddt--zebra]=\"zebra()\"\n [class.folddt--hover]=\"hover()\"\n [class.folddt--narrow]=\"isNarrow()\"\n [class.folddt--compact]=\"density() === 'compact'\"\n [class.folddt--sticky-first]=\"stickyFirst()\"\n [class.folddt--select]=\"selectable()\"\n>\n <div\n class=\"folddt-toolbar\"\n [class.folddt-toolbar--sunken]=\"toolbarSurface() === 'sunken'\"\n [class.folddt-toolbar--raised]=\"toolbarSurface() === 'raised'\"\n [class.folddt-toolbar--accent]=\"toolbarSurface() === 'accent'\"\n [attr.data-surface]=\"toolbarSurface() === 'accent' ? 'accent' : null\"\n >\n <ng-content select=\"[foldToolbar]\" />\n </div>\n @if (!cardMode()) {\n <div class=\"folddt-scroll\">\n <table class=\"folddt\" [attr.aria-colcount]=\"colCount()\">\n @if (caption(); as cap) {\n <caption class=\"folddt-caption\">\n {{\n cap\n }}\n </caption>\n }\n <thead>\n <tr>\n @if (selectable()) {\n <th scope=\"col\" class=\"folddt-select-h\">\n <fold-checkbox\n size=\"sm\"\n [ariaLabel]=\"l().selectAll\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (checkedChange)=\"toggleAll()\"\n />\n </th>\n }\n @for (col of columns(); track col.key) {\n <th\n scope=\"col\"\n [class.is-primary-h]=\"col.key === primaryKey()\"\n [style.width]=\"col.width || null\"\n [attr.aria-sort]=\"col.sortable ? ariaSort(col.key) : null\"\n >\n @if (col.sortable) {\n <button\n type=\"button\"\n class=\"folddt-th-sort\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [attr.aria-label]=\"l().sortBy(col.label)\"\n (click)=\"sortChange.emit(col.key)\"\n >\n <span>{{ col.label }}</span>\n <fold-icon\n class=\"folddt-arrow\"\n [class.on]=\"isSorted(col.key)\"\n [name]=\"sortIcon(col.key)\"\n [size]=\"14\"\n />\n </button>\n } @else {\n <span\n class=\"folddt-th-plain\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n >{{ col.label }}</span\n >\n }\n </th>\n }\n @if (expandable()) {\n <!-- Une colonne sans nom : son en-t\u00EAte est vide \u00C0 DESSEIN, mais\n pas muette \u2014 le libell\u00E9 part en texte masqu\u00E9, sinon la\n derni\u00E8re colonne est annonc\u00E9e \u00AB colonne 8 \u00BB. -->\n <th scope=\"col\" class=\"folddt-expand-h\">\n <span class=\"folddt-sr\">{{ l().expandRow }}</span>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track keyOf(row, $index); let i = $index) {\n @let tone = toneOf(row);\n <tr\n class=\"folddt-row\"\n [class.tone-warning]=\"tone === 'warning'\"\n [class.tone-alert]=\"tone === 'alert'\"\n [class.tone-success]=\"tone === 'success'\"\n [class.clickable]=\"clickable()\"\n [class.is-selected]=\"selectable() && isRowSelected(row, i)\"\n [attr.tabindex]=\"rowTabIndex(row, i)\"\n [attr.aria-selected]=\"selectable() ? isRowSelected(row, i) : null\"\n (click)=\"onRowActivate(row)\"\n (focus)=\"onRowFocus(row, i)\"\n (keydown)=\"onRowKeydown($event, row)\"\n >\n @if (selectable()) {\n <td class=\"folddt-cell folddt-cell--select\">\n <fold-checkbox\n size=\"sm\"\n [ariaLabel]=\"labelFor(row)\"\n [checked]=\"isRowSelected(row, i)\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"toggleRow(row, i)\"\n />\n </td>\n }\n @for (col of columns(); track col.key) {\n @if (col.key === primaryKey()) {\n <th\n scope=\"row\"\n class=\"folddt-cell is-primary\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [class.truncate]=\"col.truncate\"\n [ngClass]=\"col.cellClass || ''\"\n [attr.data-label]=\"col.label\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </th>\n } @else {\n <td\n class=\"folddt-cell\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [class.truncate]=\"col.truncate\"\n [ngClass]=\"col.cellClass || ''\"\n [attr.data-label]=\"col.label\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </td>\n }\n }\n @if (expandable()) {\n <td class=\"folddt-cell folddt-cell--expand\">\n <button\n type=\"button\"\n class=\"folddt-expand\"\n [attr.aria-expanded]=\"isRowExpanded(row, i)\"\n [attr.aria-controls]=\"detailId(row, i)\"\n [attr.aria-label]=\"\n isRowExpanded(row, i) ? l().collapseRow : l().expandRow\n \"\n (click)=\"$event.stopPropagation(); toggleExpand(row, i)\"\n >\n <fold-icon\n [name]=\"\n isRowExpanded(row, i) ? 'chevron-up' : 'chevron-down'\n \"\n [size]=\"16\"\n />\n </button>\n </td>\n }\n </tr>\n @if (expandable() && isRowExpanded(row, i)) {\n <!-- La rang\u00E9e du tiroir ne porte PAS de `tabindex` : elle reste\n hors du groupe \u00E0 navigation par fl\u00E8ches, que les helpers\n savent enjamber. Une rang\u00E9e focusable de plus ferait deux\n arr\u00EAts pour une seule ligne de tableau. -->\n <tr class=\"folddt-detail-row\">\n <td\n class=\"folddt-detail\"\n [id]=\"detailId(row, i)\"\n [attr.colspan]=\"colCount()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowDetailTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n } @else {\n <!-- `role=\"list\"` on a <ul> looks redundant and is not: `list-style: none`\n strips list semantics in Safari, which is exactly what the styling\n does. One list, one shell \u2014 the projected template supplies the\n CONTENT, the shell supplies the chrome (outline, tone, selection), so a\n consumer never reinvents them. -->\n <ul class=\"folddt-cardlist\" role=\"list\">\n @for (row of rows(); track keyOf(row, $index); let i = $index) {\n @let tone = toneOf(row);\n <li\n class=\"folddt-card\"\n [class.is-bare]=\"rowCardChrome() === 'none' && rowCardTemplate()\"\n [class.tone-warning]=\"tone === 'warning'\"\n [class.tone-alert]=\"tone === 'alert'\"\n [class.tone-success]=\"tone === 'success'\"\n [class.is-selected]=\"selectable() && isRowSelected(row, i)\"\n [attr.aria-selected]=\"selectable() ? isRowSelected(row, i) : null\"\n >\n @if (\n selectable() && !(rowCardChrome() === \"none\" && rowCardTemplate())\n ) {\n <fold-checkbox\n class=\"folddt-card-select\"\n size=\"sm\"\n [ariaLabel]=\"labelFor(row)\"\n [checked]=\"isRowSelected(row, i)\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"toggleRow(row, i)\"\n />\n }\n <div class=\"folddt-card-body\">\n @if (rowCardTemplate(); as card) {\n <ng-container\n [ngTemplateOutlet]=\"card\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n @if (overlineColumn(); as col) {\n <p class=\"folddt-card-overline\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </p>\n }\n @if (identityColumn(); as col) {\n <p class=\"folddt-card-identity\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </p>\n }\n <!-- A <dl> and not a `::before { content: attr(data-label) }`:\n generated content is not reliably announced, and a label/value\n pair IS a description list. It also lets the values line up in\n columns, which matters for amounts. -->\n <dl class=\"folddt-card-grid\">\n @for (col of gridColumns(); track col.key) {\n <!-- A <div> around each pair is valid inside a <dl> and is\n what puts the label ABOVE its value in one grid cell. -->\n <div class=\"folddt-card-pair\">\n <dt>{{ col.label }}</dt>\n <dd [class.right]=\"col.align === 'right'\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </dd>\n </div>\n }\n </dl>\n }\n @if (expandable()) {\n <button\n type=\"button\"\n class=\"folddt-expand folddt-expand--card\"\n [attr.aria-expanded]=\"isRowExpanded(row, i)\"\n [attr.aria-controls]=\"detailId(row, i)\"\n [attr.aria-label]=\"\n isRowExpanded(row, i) ? l().collapseRow : l().expandRow\n \"\n (click)=\"toggleExpand(row, i)\"\n >\n <fold-icon\n [name]=\"isRowExpanded(row, i) ? 'chevron-up' : 'chevron-down'\"\n [size]=\"16\"\n />\n </button>\n @if (isRowExpanded(row, i)) {\n <!-- DANS la carte, et non sous la liste : c'est la m\u00EAme\n promesse que sur la table large \u2014 on ouvre une ligne sans\n quitter la place qu'on a mis du temps \u00E0 trouver. -->\n <div class=\"folddt-detail\" [id]=\"detailId(row, i)\">\n <ng-container\n [ngTemplateOutlet]=\"rowDetailTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </div>\n }\n }\n </div>\n </li>\n }\n </ul>\n }\n\n @if (loading()) {\n <div class=\"folddt-loading\">\n <fold-spinner [label]=\"l().loading\" />\n </div>\n } @else if (rows().length === 0 && empty(); as e) {\n <div class=\"folddt-empty\">\n <div class=\"folddt-empty-t\">{{ e.title }}</div>\n @if (e.subtitle) {\n <div class=\"folddt-empty-s\">{{ e.subtitle }}</div>\n }\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;min-height:0}.folddt-wrap{--folddt-sel-w: 0px;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;border:1px solid var(--fold-color-border-subtle);border-radius:var(--fold-radius-lg);background:var(--fold-color-surface-sunken);box-shadow:var(--fold-shadow-md)}.folddt--select{--folddt-sel-w: 44px}.folddt-scroll{flex:1 1 auto;min-height:0;overflow:auto}.folddt-toolbar{padding:var(--fold-space-md) var(--fold-space-lg);border-bottom:1px solid var(--fold-color-border);color:var(--fold-color-text);background:color-mix(in srgb,var(--fold-color-surface-sunken) 50%,var(--fold-color-surface-card))}.folddt-toolbar:not(:has(*)){display:none}.folddt-toolbar--sunken{background:var(--fold-color-surface-sunken)}.folddt-toolbar--raised{background:var(--fold-color-surface-raised)}.folddt-toolbar--accent{background:var(--fold-color-primary);border-bottom-color:var(--fold-color-primary);color:var(--fold-color-on-primary)}.folddt{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fold-text-sm)}.folddt-caption{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.folddt thead th{position:sticky;top:0;z-index:2;padding:0;text-align:left;background:color-mix(in srgb,var(--fold-color-surface-sunken) 50%,var(--fold-color-surface-card));border-bottom:1px solid var(--fold-color-border)}.folddt-th-sort,.folddt-th-plain{display:inline-flex;align-items:center;padding:var(--fold-space-md) var(--fold-space-lg);color:var(--fold-color-text-muted);font-family:var(--fold-font-label);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);text-transform:uppercase;letter-spacing:var(--fold-tracking-caps)}.folddt-th-sort{gap:var(--fold-space-sm);width:100%;border:0;background:transparent;cursor:pointer;transition:color var(--fold-motion-fast)}.folddt-th-sort:hover{color:var(--fold-color-text)}.folddt-th-sort.right{justify-content:flex-end}.folddt-th-plain.right{justify-content:flex-end;width:100%}.folddt-arrow{display:inline-flex;color:var(--fold-color-text-faded);transition:color var(--fold-motion-fast)}.folddt-arrow.on{color:var(--fold-color-primary-text)}.folddt-row{transition:background var(--fold-motion-fast)}.folddt-row.clickable{cursor:pointer}.folddt-row .folddt-cell{border-bottom:1px solid var(--fold-color-border-subtle)}.folddt-row:last-child .folddt-cell{border-bottom:0}.folddt-row:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:-2px}.folddt--zebra .folddt-row:nth-child(2n):not(.tone-warning):not(.tone-alert):not(.tone-success) .folddt-cell{background:var(--fold-color-surface-subtle)}.folddt--zebra .folddt-row .folddt-cell{border-bottom-color:transparent}.folddt--hover .folddt-row:hover .folddt-cell{background:var(--fold-color-surface-raised)}.folddt--hover .folddt-row.tone-warning:hover .folddt-cell{background:color-mix(in srgb,var(--fold-color-warning) 16%,transparent)}.folddt--hover .folddt-row.tone-alert:hover .folddt-cell{background:color-mix(in srgb,var(--fold-color-alert) 17%,transparent)}.folddt-cell{padding:var(--fold-space-md) var(--fold-space-lg);color:var(--fold-color-text);font-weight:inherit;text-align:left;white-space:nowrap;vertical-align:middle}.folddt-cell.right{text-align:right}.folddt-cell.center{text-align:center}.folddt-cell.truncate{max-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.folddt-row.tone-warning .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-warning)}.folddt-row.tone-warning .folddt-cell{background:color-mix(in srgb,var(--fold-color-warning) 10%,transparent)}.folddt-row.tone-alert .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-alert)}.folddt-row.tone-alert .folddt-cell{background:color-mix(in srgb,var(--fold-color-alert) 11%,transparent)}.folddt-row.tone-success .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-success)}.folddt-row.tone-success .folddt-cell{background:color-mix(in srgb,var(--fold-color-success) 9%,transparent)}.folddt-loading{display:flex;align-items:center;justify-content:center;padding:var(--fold-space-5xl) var(--fold-space-2xl)}.folddt-empty{padding:var(--fold-space-5xl) var(--fold-space-2xl);text-align:center}.folddt-empty-t{font-size:var(--fold-text-base);font-weight:var(--fold-weight-semibold);color:var(--fold-color-text)}.folddt-empty-s{font-size:var(--fold-text-sm);color:var(--fold-color-text-muted);margin-top:var(--fold-space-xs)}.folddt-cardlist{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.folddt-card{display:flex;gap:var(--fold-space-md);align-items:flex-start;padding:var(--fold-space-md) var(--fold-space-lg);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border);border-radius:var(--fold-radius-lg);box-shadow:var(--fold-shadow-sm)}.folddt-card-body{flex:1 1 auto;min-width:0}.folddt-card.tone-warning{border-inline-start:3px solid var(--fold-color-warning)}.folddt-card.tone-alert{border-inline-start:3px solid var(--fold-color-alert)}.folddt-card.tone-success{border-inline-start:3px solid var(--fold-color-success)}.folddt-card.is-selected{background:var(--fold-color-primary-surface);border-color:var(--fold-color-primary)}.folddt-card.is-bare,.folddt-card.is-bare.is-selected,.folddt-card.is-bare.tone-warning,.folddt-card.is-bare.tone-alert,.folddt-card.is-bare.tone-success{padding:0;background:none;border:0;border-radius:0;box-shadow:none}.folddt-select-h,.folddt-cell--select{width:var(--folddt-sel-w);padding-left:var(--fold-space-lg);padding-right:0;text-align:left;white-space:nowrap}.folddt-select-h{vertical-align:middle}.folddt-row.is-selected .folddt-cell{background:color-mix(in srgb,var(--fold-color-primary) 8%,transparent)}.folddt-row.is-selected .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-primary)}.folddt--compact .folddt-cell,.folddt--compact .folddt-th-sort,.folddt--compact .folddt-th-plain{padding:var(--fold-space-sm) var(--fold-space-md)}.folddt--compact .folddt-cell--select{padding-left:var(--fold-space-md);padding-right:0}.folddt--sticky-first .folddt-cell--select,.folddt--sticky-first .folddt-select-h{position:sticky;left:0;background:var(--fold-color-surface-sunken)}.folddt--sticky-first .folddt-select-h{z-index:3}.folddt--sticky-first .folddt-cell.is-primary{position:sticky;left:var(--folddt-sel-w);z-index:1;background:var(--fold-color-surface-sunken)}.folddt--sticky-first thead th.is-primary-h{position:sticky;left:var(--folddt-sel-w);z-index:3}.folddt--sticky-first .folddt-row.tone-warning .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-warning) 10%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.tone-alert .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-alert) 11%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.tone-success .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-success) 9%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.is-selected .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-primary) 8%,var(--fold-color-surface-sunken))}@media(prefers-reduced-motion:reduce){.folddt-row,.folddt-th-sort,.folddt-arrow{transition:none}}@media(forced-colors:active){.folddt-row.is-selected .folddt-cell:first-child,.folddt-row.tone-warning .folddt-cell:first-child,.folddt-row.tone-alert .folddt-cell:first-child,.folddt-row.tone-success .folddt-cell:first-child{border-inline-start:3px solid Highlight}.folddt-row:focus-visible{outline-color:Highlight}}.folddt-cardlist{gap:var(--fold-space-sm)}.folddt-card-overline{margin:0 0 var(--fold-space-xs);color:var(--fold-color-text-muted);font-size:var(--fold-text-xs);font-weight:var(--fold-weight-medium);overflow-wrap:anywhere}.folddt-card-identity{margin:0;color:var(--fold-color-text);font-size:var(--fold-text-base);font-weight:var(--fold-weight-semibold);letter-spacing:var(--fold-tracking-tight)}.folddt-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--fold-space-sm) var(--fold-space-md);margin:var(--fold-space-md) 0 0}.folddt-card-pair{min-width:0}.folddt-card-grid dt{color:var(--fold-color-text-muted);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-caps);text-transform:uppercase}.folddt-card-grid dd{margin:var(--fold-space-xs) 0 0;color:var(--fold-color-text);font-size:var(--fold-text-sm)}.folddt-card-grid dd.right{font-variant-numeric:tabular-nums}.folddt-detail-row>.folddt-detail{padding:0;border-top:0;background:var(--fold-color-surface-sunken);box-shadow:inset 0 1px 0 var(--fold-color-border-subtle)}.folddt-detail{padding:var(--fold-space-md) var(--fold-space-lg)}.folddt-cardlist .folddt-detail{margin-top:var(--fold-space-sm);border-radius:var(--fold-radius-md);background:var(--fold-color-surface-sunken);padding:var(--fold-space-md)}.folddt-expand-h{width:1%}.folddt-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.folddt-cell--expand{width:1%;text-align:right}.folddt-expand{display:grid;place-items:center;width:32px;height:32px;padding:0;border:1px solid var(--fold-color-border);border-radius:var(--fold-radius-pill);background:var(--fold-color-surface-card);color:var(--fold-color-text-muted);cursor:pointer}.folddt-expand:hover{color:var(--fold-color-text)}.folddt-card{position:relative}.folddt-expand--card{position:absolute;top:var(--fold-space-sm);right:var(--fold-space-sm)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldSpinnerComponent, selector: "fold-spinner", inputs: ["size", "label"] }, { kind: "component", type: FoldCheckboxComponent, selector: "fold-checkbox", inputs: ["checked", "disabled", "touched", "errors", "indeterminate", "label", "ariaLabel", "hint", "required", "size"], outputs: ["checkedChange", "touchedChange"] }] });
|
|
5772
5887
|
}
|
|
5773
5888
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldDataTableComponent, decorators: [{
|
|
5774
5889
|
type: Component,
|
|
@@ -5778,8 +5893,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
5778
5893
|
FoldIconComponent,
|
|
5779
5894
|
FoldSpinnerComponent,
|
|
5780
5895
|
FoldCheckboxComponent,
|
|
5781
|
-
], template: "<div\n class=\"folddt-wrap\"\n [class.folddt--zebra]=\"zebra()\"\n [class.folddt--hover]=\"hover()\"\n [class.folddt--narrow]=\"isNarrow()\"\n [class.folddt--compact]=\"density() === 'compact'\"\n [class.folddt--sticky-first]=\"stickyFirst()\"\n [class.folddt--select]=\"selectable()\"\n>\n <div\n class=\"folddt-toolbar\"\n [class.folddt-toolbar--sunken]=\"toolbarSurface() === 'sunken'\"\n [class.folddt-toolbar--raised]=\"toolbarSurface() === 'raised'\"\n [class.folddt-toolbar--accent]=\"toolbarSurface() === 'accent'\"\n [attr.data-surface]=\"toolbarSurface() === 'accent' ? 'accent' : null\"\n >\n <ng-content select=\"[foldToolbar]\" />\n </div>\n @if (!cardMode()) {\n <div class=\"folddt-scroll\">\n <table class=\"folddt\" [attr.aria-colcount]=\"colCount()\">\n @if (caption(); as cap) {\n <caption class=\"folddt-caption\">\n {{\n cap\n }}\n </caption>\n }\n <thead>\n <tr>\n @if (selectable()) {\n <th scope=\"col\" class=\"folddt-select-h\">\n <fold-checkbox\n size=\"sm\"\n [ariaLabel]=\"l().selectAll\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (checkedChange)=\"toggleAll()\"\n />\n </th>\n }\n @for (col of columns(); track col.key) {\n <th\n scope=\"col\"\n [class.is-primary-h]=\"col.key === primaryKey()\"\n [style.width]=\"col.width || null\"\n [attr.aria-sort]=\"col.sortable ? ariaSort(col.key) : null\"\n >\n @if (col.sortable) {\n <button\n type=\"button\"\n class=\"folddt-th-sort\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [attr.aria-label]=\"l().sortBy(col.label)\"\n (click)=\"sortChange.emit(col.key)\"\n >\n <span>{{ col.label }}</span>\n <fold-icon\n class=\"folddt-arrow\"\n [class.on]=\"isSorted(col.key)\"\n [name]=\"sortIcon(col.key)\"\n [size]=\"14\"\n />\n </button>\n } @else {\n <span\n class=\"folddt-th-plain\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n >{{ col.label }}</span\n >\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track keyOf(row, $index); let i = $index) {\n @let tone = toneOf(row);\n <tr\n class=\"folddt-row\"\n [class.tone-warning]=\"tone === 'warning'\"\n [class.tone-alert]=\"tone === 'alert'\"\n [class.tone-success]=\"tone === 'success'\"\n [class.clickable]=\"clickable()\"\n [class.is-selected]=\"selectable() && isRowSelected(row, i)\"\n [attr.tabindex]=\"rowTabIndex(row, i)\"\n [attr.aria-selected]=\"selectable() ? isRowSelected(row, i) : null\"\n (click)=\"onRowActivate(row)\"\n (focus)=\"onRowFocus(row, i)\"\n (keydown)=\"onRowKeydown($event, row)\"\n >\n @if (selectable()) {\n <td class=\"folddt-cell folddt-cell--select\">\n <fold-checkbox\n size=\"sm\"\n [ariaLabel]=\"labelFor(row)\"\n [checked]=\"isRowSelected(row, i)\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"toggleRow(row, i)\"\n />\n </td>\n }\n @for (col of columns(); track col.key) {\n @if (col.key === primaryKey()) {\n <th\n scope=\"row\"\n class=\"folddt-cell is-primary\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [class.truncate]=\"col.truncate\"\n [ngClass]=\"col.cellClass || ''\"\n [attr.data-label]=\"col.label\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </th>\n } @else {\n <td\n class=\"folddt-cell\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [class.truncate]=\"col.truncate\"\n [ngClass]=\"col.cellClass || ''\"\n [attr.data-label]=\"col.label\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </td>\n }\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <!-- `role=\"list\"` on a <ul> looks redundant and is not: `list-style: none`\n strips list semantics in Safari, which is exactly what the styling\n does. One list, one shell \u2014 the projected template supplies the\n CONTENT, the shell supplies the chrome (outline, tone, selection), so a\n consumer never reinvents them. -->\n <ul class=\"folddt-cardlist\" role=\"list\">\n @for (row of rows(); track keyOf(row, $index); let i = $index) {\n @let tone = toneOf(row);\n <li\n class=\"folddt-card\"\n [class.is-bare]=\"rowCardChrome() === 'none' && rowCardTemplate()\"\n [class.tone-warning]=\"tone === 'warning'\"\n [class.tone-alert]=\"tone === 'alert'\"\n [class.tone-success]=\"tone === 'success'\"\n [class.is-selected]=\"selectable() && isRowSelected(row, i)\"\n [attr.aria-selected]=\"selectable() ? isRowSelected(row, i) : null\"\n >\n @if (\n selectable() && !(rowCardChrome() === \"none\" && rowCardTemplate())\n ) {\n <fold-checkbox\n class=\"folddt-card-select\"\n size=\"sm\"\n [ariaLabel]=\"labelFor(row)\"\n [checked]=\"isRowSelected(row, i)\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"toggleRow(row, i)\"\n />\n }\n <div class=\"folddt-card-body\">\n @if (rowCardTemplate(); as card) {\n <ng-container\n [ngTemplateOutlet]=\"card\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n @if (overlineColumn(); as col) {\n <p class=\"folddt-card-overline\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </p>\n }\n @if (identityColumn(); as col) {\n <p class=\"folddt-card-identity\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </p>\n }\n <!-- A <dl> and not a `::before { content: attr(data-label) }`:\n generated content is not reliably announced, and a label/value\n pair IS a description list. It also lets the values line up in\n columns, which matters for amounts. -->\n <dl class=\"folddt-card-grid\">\n @for (col of gridColumns(); track col.key) {\n <!-- A <div> around each pair is valid inside a <dl> and is\n what puts the label ABOVE its value in one grid cell. -->\n <div class=\"folddt-card-pair\">\n <dt>{{ col.label }}</dt>\n <dd [class.right]=\"col.align === 'right'\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </dd>\n </div>\n }\n </dl>\n }\n </div>\n </li>\n }\n </ul>\n }\n\n @if (loading()) {\n <div class=\"folddt-loading\">\n <fold-spinner [label]=\"l().loading\" />\n </div>\n } @else if (rows().length === 0 && empty(); as e) {\n <div class=\"folddt-empty\">\n <div class=\"folddt-empty-t\">{{ e.title }}</div>\n @if (e.subtitle) {\n <div class=\"folddt-empty-s\">{{ e.subtitle }}</div>\n }\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;min-height:0}.folddt-wrap{--folddt-sel-w: 0px;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;border:1px solid var(--fold-color-border-subtle);border-radius:var(--fold-radius-lg);background:var(--fold-color-surface-sunken);box-shadow:var(--fold-shadow-md)}.folddt--select{--folddt-sel-w: 44px}.folddt-scroll{flex:1 1 auto;min-height:0;overflow:auto}.folddt-toolbar{padding:var(--fold-space-md) var(--fold-space-lg);border-bottom:1px solid var(--fold-color-border);color:var(--fold-color-text);background:color-mix(in srgb,var(--fold-color-surface-sunken) 50%,var(--fold-color-surface-card))}.folddt-toolbar:not(:has(*)){display:none}.folddt-toolbar--sunken{background:var(--fold-color-surface-sunken)}.folddt-toolbar--raised{background:var(--fold-color-surface-raised)}.folddt-toolbar--accent{background:var(--fold-color-primary);border-bottom-color:var(--fold-color-primary);color:var(--fold-color-on-primary)}.folddt{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fold-text-sm)}.folddt-caption{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.folddt thead th{position:sticky;top:0;z-index:2;padding:0;text-align:left;background:color-mix(in srgb,var(--fold-color-surface-sunken) 50%,var(--fold-color-surface-card));border-bottom:1px solid var(--fold-color-border)}.folddt-th-sort,.folddt-th-plain{display:inline-flex;align-items:center;padding:var(--fold-space-md) var(--fold-space-lg);color:var(--fold-color-text-muted);font-family:var(--fold-font-label);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);text-transform:uppercase;letter-spacing:var(--fold-tracking-caps)}.folddt-th-sort{gap:var(--fold-space-sm);width:100%;border:0;background:transparent;cursor:pointer;transition:color var(--fold-motion-fast)}.folddt-th-sort:hover{color:var(--fold-color-text)}.folddt-th-sort.right{justify-content:flex-end}.folddt-th-plain.right{justify-content:flex-end;width:100%}.folddt-arrow{display:inline-flex;color:var(--fold-color-text-faded);transition:color var(--fold-motion-fast)}.folddt-arrow.on{color:var(--fold-color-primary-text)}.folddt-row{transition:background var(--fold-motion-fast)}.folddt-row.clickable{cursor:pointer}.folddt-row .folddt-cell{border-bottom:1px solid var(--fold-color-border-subtle)}.folddt-row:last-child .folddt-cell{border-bottom:0}.folddt-row:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:-2px}.folddt--zebra .folddt-row:nth-child(2n):not(.tone-warning):not(.tone-alert):not(.tone-success) .folddt-cell{background:var(--fold-color-surface-subtle)}.folddt--zebra .folddt-row .folddt-cell{border-bottom-color:transparent}.folddt--hover .folddt-row:hover .folddt-cell{background:var(--fold-color-surface-raised)}.folddt--hover .folddt-row.tone-warning:hover .folddt-cell{background:color-mix(in srgb,var(--fold-color-warning) 16%,transparent)}.folddt--hover .folddt-row.tone-alert:hover .folddt-cell{background:color-mix(in srgb,var(--fold-color-alert) 17%,transparent)}.folddt-cell{padding:var(--fold-space-md) var(--fold-space-lg);color:var(--fold-color-text);font-weight:inherit;text-align:left;white-space:nowrap;vertical-align:middle}.folddt-cell.right{text-align:right}.folddt-cell.center{text-align:center}.folddt-cell.truncate{max-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.folddt-row.tone-warning .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-warning)}.folddt-row.tone-warning .folddt-cell{background:color-mix(in srgb,var(--fold-color-warning) 10%,transparent)}.folddt-row.tone-alert .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-alert)}.folddt-row.tone-alert .folddt-cell{background:color-mix(in srgb,var(--fold-color-alert) 11%,transparent)}.folddt-row.tone-success .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-success)}.folddt-row.tone-success .folddt-cell{background:color-mix(in srgb,var(--fold-color-success) 9%,transparent)}.folddt-loading{display:flex;align-items:center;justify-content:center;padding:var(--fold-space-5xl) var(--fold-space-2xl)}.folddt-empty{padding:var(--fold-space-5xl) var(--fold-space-2xl);text-align:center}.folddt-empty-t{font-size:var(--fold-text-base);font-weight:var(--fold-weight-semibold);color:var(--fold-color-text)}.folddt-empty-s{font-size:var(--fold-text-sm);color:var(--fold-color-text-muted);margin-top:var(--fold-space-xs)}.folddt-cardlist{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.folddt-card{display:flex;gap:var(--fold-space-md);align-items:flex-start;padding:var(--fold-space-md) var(--fold-space-lg);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border);border-radius:var(--fold-radius-lg);box-shadow:var(--fold-shadow-sm)}.folddt-card-body{flex:1 1 auto;min-width:0}.folddt-card.tone-warning{border-inline-start:3px solid var(--fold-color-warning)}.folddt-card.tone-alert{border-inline-start:3px solid var(--fold-color-alert)}.folddt-card.tone-success{border-inline-start:3px solid var(--fold-color-success)}.folddt-card.is-selected{background:var(--fold-color-primary-surface);border-color:var(--fold-color-primary)}.folddt-card.is-bare,.folddt-card.is-bare.is-selected,.folddt-card.is-bare.tone-warning,.folddt-card.is-bare.tone-alert,.folddt-card.is-bare.tone-success{padding:0;background:none;border:0;border-radius:0;box-shadow:none}.folddt-select-h,.folddt-cell--select{width:var(--folddt-sel-w);padding-left:var(--fold-space-lg);padding-right:0;text-align:left;white-space:nowrap}.folddt-select-h{vertical-align:middle}.folddt-row.is-selected .folddt-cell{background:color-mix(in srgb,var(--fold-color-primary) 8%,transparent)}.folddt-row.is-selected .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-primary)}.folddt--compact .folddt-cell,.folddt--compact .folddt-th-sort,.folddt--compact .folddt-th-plain{padding:var(--fold-space-sm) var(--fold-space-md)}.folddt--compact .folddt-cell--select{padding-left:var(--fold-space-md);padding-right:0}.folddt--sticky-first .folddt-cell--select,.folddt--sticky-first .folddt-select-h{position:sticky;left:0;background:var(--fold-color-surface-sunken)}.folddt--sticky-first .folddt-select-h{z-index:3}.folddt--sticky-first .folddt-cell.is-primary{position:sticky;left:var(--folddt-sel-w);z-index:1;background:var(--fold-color-surface-sunken)}.folddt--sticky-first thead th.is-primary-h{position:sticky;left:var(--folddt-sel-w);z-index:3}.folddt--sticky-first .folddt-row.tone-warning .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-warning) 10%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.tone-alert .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-alert) 11%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.tone-success .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-success) 9%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.is-selected .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-primary) 8%,var(--fold-color-surface-sunken))}@media(prefers-reduced-motion:reduce){.folddt-row,.folddt-th-sort,.folddt-arrow{transition:none}}@media(forced-colors:active){.folddt-row.is-selected .folddt-cell:first-child,.folddt-row.tone-warning .folddt-cell:first-child,.folddt-row.tone-alert .folddt-cell:first-child,.folddt-row.tone-success .folddt-cell:first-child{border-inline-start:3px solid Highlight}.folddt-row:focus-visible{outline-color:Highlight}}.folddt-cardlist{gap:var(--fold-space-sm)}.folddt-card-overline{margin:0 0 var(--fold-space-xs);color:var(--fold-color-text-muted);font-size:var(--fold-text-xs);font-weight:var(--fold-weight-medium);overflow-wrap:anywhere}.folddt-card-identity{margin:0;color:var(--fold-color-text);font-size:var(--fold-text-base);font-weight:var(--fold-weight-semibold);letter-spacing:var(--fold-tracking-tight)}.folddt-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--fold-space-sm) var(--fold-space-md);margin:var(--fold-space-md) 0 0}.folddt-card-pair{min-width:0}.folddt-card-grid dt{color:var(--fold-color-text-muted);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-caps);text-transform:uppercase}.folddt-card-grid dd{margin:var(--fold-space-xs) 0 0;color:var(--fold-color-text);font-size:var(--fold-text-sm)}.folddt-card-grid dd.right{font-variant-numeric:tabular-nums}\n"] }]
|
|
5782
|
-
}], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], rowTone: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowTone", required: false }] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }], empty: [{ type: i0.Input, args: [{ isSignal: true, alias: "empty", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], zebra: [{ type: i0.Input, args: [{ isSignal: true, alias: "zebra", required: false }] }], hover: [{ type: i0.Input, args: [{ isSignal: true, alias: "hover", required: false }] }], narrowLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "narrowLayout", required: false }] }], cardsAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardsAt", required: false }] }], rowCardChrome: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowCardChrome", required: false }] }], mobileLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileLayout", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], stickyFirst: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyFirst", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], selectionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionLabel", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cells: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FoldDataTableCellDirective), { isSignal: true }] }], rowCard: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FoldDataTableRowCardDirective), { isSignal: true }] }], toolbarSurface: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbarSurface", required: false }] }] } });
|
|
5896
|
+
], template: "<div\n class=\"folddt-wrap\"\n [class.folddt--zebra]=\"zebra()\"\n [class.folddt--hover]=\"hover()\"\n [class.folddt--narrow]=\"isNarrow()\"\n [class.folddt--compact]=\"density() === 'compact'\"\n [class.folddt--sticky-first]=\"stickyFirst()\"\n [class.folddt--select]=\"selectable()\"\n>\n <div\n class=\"folddt-toolbar\"\n [class.folddt-toolbar--sunken]=\"toolbarSurface() === 'sunken'\"\n [class.folddt-toolbar--raised]=\"toolbarSurface() === 'raised'\"\n [class.folddt-toolbar--accent]=\"toolbarSurface() === 'accent'\"\n [attr.data-surface]=\"toolbarSurface() === 'accent' ? 'accent' : null\"\n >\n <ng-content select=\"[foldToolbar]\" />\n </div>\n @if (!cardMode()) {\n <div class=\"folddt-scroll\">\n <table class=\"folddt\" [attr.aria-colcount]=\"colCount()\">\n @if (caption(); as cap) {\n <caption class=\"folddt-caption\">\n {{\n cap\n }}\n </caption>\n }\n <thead>\n <tr>\n @if (selectable()) {\n <th scope=\"col\" class=\"folddt-select-h\">\n <fold-checkbox\n size=\"sm\"\n [ariaLabel]=\"l().selectAll\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (checkedChange)=\"toggleAll()\"\n />\n </th>\n }\n @for (col of columns(); track col.key) {\n <th\n scope=\"col\"\n [class.is-primary-h]=\"col.key === primaryKey()\"\n [style.width]=\"col.width || null\"\n [attr.aria-sort]=\"col.sortable ? ariaSort(col.key) : null\"\n >\n @if (col.sortable) {\n <button\n type=\"button\"\n class=\"folddt-th-sort\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [attr.aria-label]=\"l().sortBy(col.label)\"\n (click)=\"sortChange.emit(col.key)\"\n >\n <span>{{ col.label }}</span>\n <fold-icon\n class=\"folddt-arrow\"\n [class.on]=\"isSorted(col.key)\"\n [name]=\"sortIcon(col.key)\"\n [size]=\"14\"\n />\n </button>\n } @else {\n <span\n class=\"folddt-th-plain\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n >{{ col.label }}</span\n >\n }\n </th>\n }\n @if (expandable()) {\n <!-- Une colonne sans nom : son en-t\u00EAte est vide \u00C0 DESSEIN, mais\n pas muette \u2014 le libell\u00E9 part en texte masqu\u00E9, sinon la\n derni\u00E8re colonne est annonc\u00E9e \u00AB colonne 8 \u00BB. -->\n <th scope=\"col\" class=\"folddt-expand-h\">\n <span class=\"folddt-sr\">{{ l().expandRow }}</span>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track keyOf(row, $index); let i = $index) {\n @let tone = toneOf(row);\n <tr\n class=\"folddt-row\"\n [class.tone-warning]=\"tone === 'warning'\"\n [class.tone-alert]=\"tone === 'alert'\"\n [class.tone-success]=\"tone === 'success'\"\n [class.clickable]=\"clickable()\"\n [class.is-selected]=\"selectable() && isRowSelected(row, i)\"\n [attr.tabindex]=\"rowTabIndex(row, i)\"\n [attr.aria-selected]=\"selectable() ? isRowSelected(row, i) : null\"\n (click)=\"onRowActivate(row)\"\n (focus)=\"onRowFocus(row, i)\"\n (keydown)=\"onRowKeydown($event, row)\"\n >\n @if (selectable()) {\n <td class=\"folddt-cell folddt-cell--select\">\n <fold-checkbox\n size=\"sm\"\n [ariaLabel]=\"labelFor(row)\"\n [checked]=\"isRowSelected(row, i)\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"toggleRow(row, i)\"\n />\n </td>\n }\n @for (col of columns(); track col.key) {\n @if (col.key === primaryKey()) {\n <th\n scope=\"row\"\n class=\"folddt-cell is-primary\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [class.truncate]=\"col.truncate\"\n [ngClass]=\"col.cellClass || ''\"\n [attr.data-label]=\"col.label\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </th>\n } @else {\n <td\n class=\"folddt-cell\"\n [class.right]=\"col.align === 'right'\"\n [class.center]=\"col.align === 'center'\"\n [class.truncate]=\"col.truncate\"\n [ngClass]=\"col.cellClass || ''\"\n [attr.data-label]=\"col.label\"\n >\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </td>\n }\n }\n @if (expandable()) {\n <td class=\"folddt-cell folddt-cell--expand\">\n <button\n type=\"button\"\n class=\"folddt-expand\"\n [attr.aria-expanded]=\"isRowExpanded(row, i)\"\n [attr.aria-controls]=\"detailId(row, i)\"\n [attr.aria-label]=\"\n isRowExpanded(row, i) ? l().collapseRow : l().expandRow\n \"\n (click)=\"$event.stopPropagation(); toggleExpand(row, i)\"\n >\n <fold-icon\n [name]=\"\n isRowExpanded(row, i) ? 'chevron-up' : 'chevron-down'\n \"\n [size]=\"16\"\n />\n </button>\n </td>\n }\n </tr>\n @if (expandable() && isRowExpanded(row, i)) {\n <!-- La rang\u00E9e du tiroir ne porte PAS de `tabindex` : elle reste\n hors du groupe \u00E0 navigation par fl\u00E8ches, que les helpers\n savent enjamber. Une rang\u00E9e focusable de plus ferait deux\n arr\u00EAts pour une seule ligne de tableau. -->\n <tr class=\"folddt-detail-row\">\n <td\n class=\"folddt-detail\"\n [id]=\"detailId(row, i)\"\n [attr.colspan]=\"colCount()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowDetailTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n } @else {\n <!-- `role=\"list\"` on a <ul> looks redundant and is not: `list-style: none`\n strips list semantics in Safari, which is exactly what the styling\n does. One list, one shell \u2014 the projected template supplies the\n CONTENT, the shell supplies the chrome (outline, tone, selection), so a\n consumer never reinvents them. -->\n <ul class=\"folddt-cardlist\" role=\"list\">\n @for (row of rows(); track keyOf(row, $index); let i = $index) {\n @let tone = toneOf(row);\n <li\n class=\"folddt-card\"\n [class.is-bare]=\"rowCardChrome() === 'none' && rowCardTemplate()\"\n [class.tone-warning]=\"tone === 'warning'\"\n [class.tone-alert]=\"tone === 'alert'\"\n [class.tone-success]=\"tone === 'success'\"\n [class.is-selected]=\"selectable() && isRowSelected(row, i)\"\n [attr.aria-selected]=\"selectable() ? isRowSelected(row, i) : null\"\n >\n @if (\n selectable() && !(rowCardChrome() === \"none\" && rowCardTemplate())\n ) {\n <fold-checkbox\n class=\"folddt-card-select\"\n size=\"sm\"\n [ariaLabel]=\"labelFor(row)\"\n [checked]=\"isRowSelected(row, i)\"\n (click)=\"$event.stopPropagation()\"\n (checkedChange)=\"toggleRow(row, i)\"\n />\n }\n <div class=\"folddt-card-body\">\n @if (rowCardTemplate(); as card) {\n <ng-container\n [ngTemplateOutlet]=\"card\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n @if (overlineColumn(); as col) {\n <p class=\"folddt-card-overline\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </p>\n }\n @if (identityColumn(); as col) {\n <p class=\"folddt-card-identity\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </p>\n }\n <!-- A <dl> and not a `::before { content: attr(data-label) }`:\n generated content is not reliably announced, and a label/value\n pair IS a description list. It also lets the values line up in\n columns, which matters for amounts. -->\n <dl class=\"folddt-card-grid\">\n @for (col of gridColumns(); track col.key) {\n <!-- A <div> around each pair is valid inside a <dl> and is\n what puts the label ABOVE its value in one grid cell. -->\n <div class=\"folddt-card-pair\">\n <dt>{{ col.label }}</dt>\n <dd [class.right]=\"col.align === 'right'\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate(col.key)\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </dd>\n </div>\n }\n </dl>\n }\n @if (expandable()) {\n <button\n type=\"button\"\n class=\"folddt-expand folddt-expand--card\"\n [attr.aria-expanded]=\"isRowExpanded(row, i)\"\n [attr.aria-controls]=\"detailId(row, i)\"\n [attr.aria-label]=\"\n isRowExpanded(row, i) ? l().collapseRow : l().expandRow\n \"\n (click)=\"toggleExpand(row, i)\"\n >\n <fold-icon\n [name]=\"isRowExpanded(row, i) ? 'chevron-up' : 'chevron-down'\"\n [size]=\"16\"\n />\n </button>\n @if (isRowExpanded(row, i)) {\n <!-- DANS la carte, et non sous la liste : c'est la m\u00EAme\n promesse que sur la table large \u2014 on ouvre une ligne sans\n quitter la place qu'on a mis du temps \u00E0 trouver. -->\n <div class=\"folddt-detail\" [id]=\"detailId(row, i)\">\n <ng-container\n [ngTemplateOutlet]=\"rowDetailTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n </div>\n }\n }\n </div>\n </li>\n }\n </ul>\n }\n\n @if (loading()) {\n <div class=\"folddt-loading\">\n <fold-spinner [label]=\"l().loading\" />\n </div>\n } @else if (rows().length === 0 && empty(); as e) {\n <div class=\"folddt-empty\">\n <div class=\"folddt-empty-t\">{{ e.title }}</div>\n @if (e.subtitle) {\n <div class=\"folddt-empty-s\">{{ e.subtitle }}</div>\n }\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;min-height:0}.folddt-wrap{--folddt-sel-w: 0px;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;border:1px solid var(--fold-color-border-subtle);border-radius:var(--fold-radius-lg);background:var(--fold-color-surface-sunken);box-shadow:var(--fold-shadow-md)}.folddt--select{--folddt-sel-w: 44px}.folddt-scroll{flex:1 1 auto;min-height:0;overflow:auto}.folddt-toolbar{padding:var(--fold-space-md) var(--fold-space-lg);border-bottom:1px solid var(--fold-color-border);color:var(--fold-color-text);background:color-mix(in srgb,var(--fold-color-surface-sunken) 50%,var(--fold-color-surface-card))}.folddt-toolbar:not(:has(*)){display:none}.folddt-toolbar--sunken{background:var(--fold-color-surface-sunken)}.folddt-toolbar--raised{background:var(--fold-color-surface-raised)}.folddt-toolbar--accent{background:var(--fold-color-primary);border-bottom-color:var(--fold-color-primary);color:var(--fold-color-on-primary)}.folddt{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fold-text-sm)}.folddt-caption{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.folddt thead th{position:sticky;top:0;z-index:2;padding:0;text-align:left;background:color-mix(in srgb,var(--fold-color-surface-sunken) 50%,var(--fold-color-surface-card));border-bottom:1px solid var(--fold-color-border)}.folddt-th-sort,.folddt-th-plain{display:inline-flex;align-items:center;padding:var(--fold-space-md) var(--fold-space-lg);color:var(--fold-color-text-muted);font-family:var(--fold-font-label);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);text-transform:uppercase;letter-spacing:var(--fold-tracking-caps)}.folddt-th-sort{gap:var(--fold-space-sm);width:100%;border:0;background:transparent;cursor:pointer;transition:color var(--fold-motion-fast)}.folddt-th-sort:hover{color:var(--fold-color-text)}.folddt-th-sort.right{justify-content:flex-end}.folddt-th-plain.right{justify-content:flex-end;width:100%}.folddt-arrow{display:inline-flex;color:var(--fold-color-text-faded);transition:color var(--fold-motion-fast)}.folddt-arrow.on{color:var(--fold-color-primary-text)}.folddt-row{transition:background var(--fold-motion-fast)}.folddt-row.clickable{cursor:pointer}.folddt-row .folddt-cell{border-bottom:1px solid var(--fold-color-border-subtle)}.folddt-row:last-child .folddt-cell{border-bottom:0}.folddt-row:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:-2px}.folddt--zebra .folddt-row:nth-child(2n):not(.tone-warning):not(.tone-alert):not(.tone-success) .folddt-cell{background:var(--fold-color-surface-subtle)}.folddt--zebra .folddt-row .folddt-cell{border-bottom-color:transparent}.folddt--hover .folddt-row:hover .folddt-cell{background:var(--fold-color-surface-raised)}.folddt--hover .folddt-row.tone-warning:hover .folddt-cell{background:color-mix(in srgb,var(--fold-color-warning) 16%,transparent)}.folddt--hover .folddt-row.tone-alert:hover .folddt-cell{background:color-mix(in srgb,var(--fold-color-alert) 17%,transparent)}.folddt-cell{padding:var(--fold-space-md) var(--fold-space-lg);color:var(--fold-color-text);font-weight:inherit;text-align:left;white-space:nowrap;vertical-align:middle}.folddt-cell.right{text-align:right}.folddt-cell.center{text-align:center}.folddt-cell.truncate{max-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.folddt-row.tone-warning .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-warning)}.folddt-row.tone-warning .folddt-cell{background:color-mix(in srgb,var(--fold-color-warning) 10%,transparent)}.folddt-row.tone-alert .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-alert)}.folddt-row.tone-alert .folddt-cell{background:color-mix(in srgb,var(--fold-color-alert) 11%,transparent)}.folddt-row.tone-success .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-success)}.folddt-row.tone-success .folddt-cell{background:color-mix(in srgb,var(--fold-color-success) 9%,transparent)}.folddt-loading{display:flex;align-items:center;justify-content:center;padding:var(--fold-space-5xl) var(--fold-space-2xl)}.folddt-empty{padding:var(--fold-space-5xl) var(--fold-space-2xl);text-align:center}.folddt-empty-t{font-size:var(--fold-text-base);font-weight:var(--fold-weight-semibold);color:var(--fold-color-text)}.folddt-empty-s{font-size:var(--fold-text-sm);color:var(--fold-color-text-muted);margin-top:var(--fold-space-xs)}.folddt-cardlist{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.folddt-card{display:flex;gap:var(--fold-space-md);align-items:flex-start;padding:var(--fold-space-md) var(--fold-space-lg);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border);border-radius:var(--fold-radius-lg);box-shadow:var(--fold-shadow-sm)}.folddt-card-body{flex:1 1 auto;min-width:0}.folddt-card.tone-warning{border-inline-start:3px solid var(--fold-color-warning)}.folddt-card.tone-alert{border-inline-start:3px solid var(--fold-color-alert)}.folddt-card.tone-success{border-inline-start:3px solid var(--fold-color-success)}.folddt-card.is-selected{background:var(--fold-color-primary-surface);border-color:var(--fold-color-primary)}.folddt-card.is-bare,.folddt-card.is-bare.is-selected,.folddt-card.is-bare.tone-warning,.folddt-card.is-bare.tone-alert,.folddt-card.is-bare.tone-success{padding:0;background:none;border:0;border-radius:0;box-shadow:none}.folddt-select-h,.folddt-cell--select{width:var(--folddt-sel-w);padding-left:var(--fold-space-lg);padding-right:0;text-align:left;white-space:nowrap}.folddt-select-h{vertical-align:middle}.folddt-row.is-selected .folddt-cell{background:color-mix(in srgb,var(--fold-color-primary) 8%,transparent)}.folddt-row.is-selected .folddt-cell:first-child{box-shadow:inset 3px 0 0 var(--fold-color-primary)}.folddt--compact .folddt-cell,.folddt--compact .folddt-th-sort,.folddt--compact .folddt-th-plain{padding:var(--fold-space-sm) var(--fold-space-md)}.folddt--compact .folddt-cell--select{padding-left:var(--fold-space-md);padding-right:0}.folddt--sticky-first .folddt-cell--select,.folddt--sticky-first .folddt-select-h{position:sticky;left:0;background:var(--fold-color-surface-sunken)}.folddt--sticky-first .folddt-select-h{z-index:3}.folddt--sticky-first .folddt-cell.is-primary{position:sticky;left:var(--folddt-sel-w);z-index:1;background:var(--fold-color-surface-sunken)}.folddt--sticky-first thead th.is-primary-h{position:sticky;left:var(--folddt-sel-w);z-index:3}.folddt--sticky-first .folddt-row.tone-warning .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-warning) 10%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.tone-alert .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-alert) 11%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.tone-success .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-success) 9%,var(--fold-color-surface-sunken))}.folddt--sticky-first .folddt-row.is-selected .folddt-cell.is-primary{background:color-mix(in srgb,var(--fold-color-primary) 8%,var(--fold-color-surface-sunken))}@media(prefers-reduced-motion:reduce){.folddt-row,.folddt-th-sort,.folddt-arrow{transition:none}}@media(forced-colors:active){.folddt-row.is-selected .folddt-cell:first-child,.folddt-row.tone-warning .folddt-cell:first-child,.folddt-row.tone-alert .folddt-cell:first-child,.folddt-row.tone-success .folddt-cell:first-child{border-inline-start:3px solid Highlight}.folddt-row:focus-visible{outline-color:Highlight}}.folddt-cardlist{gap:var(--fold-space-sm)}.folddt-card-overline{margin:0 0 var(--fold-space-xs);color:var(--fold-color-text-muted);font-size:var(--fold-text-xs);font-weight:var(--fold-weight-medium);overflow-wrap:anywhere}.folddt-card-identity{margin:0;color:var(--fold-color-text);font-size:var(--fold-text-base);font-weight:var(--fold-weight-semibold);letter-spacing:var(--fold-tracking-tight)}.folddt-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--fold-space-sm) var(--fold-space-md);margin:var(--fold-space-md) 0 0}.folddt-card-pair{min-width:0}.folddt-card-grid dt{color:var(--fold-color-text-muted);font-size:var(--fold-text-2xs);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-caps);text-transform:uppercase}.folddt-card-grid dd{margin:var(--fold-space-xs) 0 0;color:var(--fold-color-text);font-size:var(--fold-text-sm)}.folddt-card-grid dd.right{font-variant-numeric:tabular-nums}.folddt-detail-row>.folddt-detail{padding:0;border-top:0;background:var(--fold-color-surface-sunken);box-shadow:inset 0 1px 0 var(--fold-color-border-subtle)}.folddt-detail{padding:var(--fold-space-md) var(--fold-space-lg)}.folddt-cardlist .folddt-detail{margin-top:var(--fold-space-sm);border-radius:var(--fold-radius-md);background:var(--fold-color-surface-sunken);padding:var(--fold-space-md)}.folddt-expand-h{width:1%}.folddt-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.folddt-cell--expand{width:1%;text-align:right}.folddt-expand{display:grid;place-items:center;width:32px;height:32px;padding:0;border:1px solid var(--fold-color-border);border-radius:var(--fold-radius-pill);background:var(--fold-color-surface-card);color:var(--fold-color-text-muted);cursor:pointer}.folddt-expand:hover{color:var(--fold-color-text)}.folddt-card{position:relative}.folddt-expand--card{position:absolute;top:var(--fold-space-sm);right:var(--fold-space-sm)}\n"] }]
|
|
5897
|
+
}], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], rowTone: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowTone", required: false }] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }], empty: [{ type: i0.Input, args: [{ isSignal: true, alias: "empty", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], zebra: [{ type: i0.Input, args: [{ isSignal: true, alias: "zebra", required: false }] }], hover: [{ type: i0.Input, args: [{ isSignal: true, alias: "hover", required: false }] }], narrowLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "narrowLayout", required: false }] }], cardsAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardsAt", required: false }] }], rowCardChrome: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowCardChrome", required: false }] }], mobileLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileLayout", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], stickyFirst: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyFirst", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], selectionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionLabel", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], expandMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandMode", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cells: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FoldDataTableCellDirective), { isSignal: true }] }], rowDetail: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FoldDataTableRowDetailDirective), { isSignal: true }] }], rowCard: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FoldDataTableRowCardDirective), { isSignal: true }] }], toolbarSurface: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbarSurface", required: false }] }] } });
|
|
5783
5898
|
|
|
5784
5899
|
/**
|
|
5785
5900
|
* `[foldStickyColumn]` — turns its host into a sticky side column: a vertical
|
|
@@ -14710,5 +14825,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
14710
14825
|
* Generated bundle index. Do not edit.
|
|
14711
14826
|
*/
|
|
14712
14827
|
|
|
14713
|
-
export { FOLD_AUTO_PALETTES, FOLD_BLUR_TOKENS, FOLD_BUILTIN_ICONS, FOLD_BUILTIN_ICON_CATEGORIES, FOLD_CALENDAR_DEFAULT_LABELS, FOLD_CALENDAR_FORMATS, FOLD_CALENDAR_LABELS, FOLD_COMMON_DEFAULT_LABELS, FOLD_COMMON_LABELS, FOLD_DATA_TABLE_DEFAULT_LABELS, FOLD_DATA_TABLE_LABELS, FOLD_DEFAULT_WEEKEND_DAYS, FOLD_FALLBACK_WEEK_INFO, FOLD_FONT_TOKENS, FOLD_INLINE_CONFIRM_DEFAULT_LABELS, FOLD_INLINE_CONFIRM_LABELS, FOLD_LEADING_TOKENS, FOLD_MINUTES_PER_DAY, FOLD_MOTION_TOKENS, FOLD_PAGINATOR_DEFAULT_LABELS, FOLD_PAGINATOR_LABELS, FOLD_PALETTE_DEFAULT, FOLD_PANEL_CLOSE_LABEL, FOLD_PANEL_DEFAULTS, FOLD_RADIUS_TOKENS, FOLD_SEMANTIC_COLOR_TOKENS, FOLD_SHADOW_TOKENS, FOLD_SPACE_TOKENS, FOLD_TEXT_TOKENS, FOLD_TOAST_CONFIG, FOLD_TRACKING_TOKENS, FOLD_WEIGHT_TOKENS, FoldAppShellComponent, FoldAsideLayoutComponent, FoldAvatarComponent, FoldAvatarDetailComponent, FoldAvatarListComponent, FoldBackLinkComponent, FoldBadgeComponent, FoldBreadcrumbComponent, FoldButtonComponent, FoldButtonIconComponent, FoldCalendarAgendaComponent, FoldCalendarChromeDirective, FoldCalendarDayComponent, FoldCalendarDayDirective, FoldCalendarEventDirective, FoldCalendarHeadingDirective, FoldCalendarListComponent, FoldCalendarMonthComponent, FoldCalendarOverflowDirective, FoldCalendarSourceFilterComponent, FoldCalendarTimegridComponent, FoldCalendarTitleDirective, FoldCalendarToolbarComponent, FoldCalendarWeekComponent, FoldCalloutComponent, FoldCardComponent, FoldCheckboxComponent, FoldChecklistComponent, FoldChoiceRowComponent, FoldContextCardComponent, FoldDangerZoneComponent, FoldDataTableCellDirective, FoldDataTableComponent, FoldDataTableRowCardDirective, FoldDateComponent, FoldDisclosureComponent, FoldDropdownComponent, FoldDropdownItemComponent, FoldElementTitleComponent, FoldElevatedDirective, FoldEmptyStateComponent, FoldFieldComponent, FoldFieldIdDirective, FoldFieldListComponent, FoldFieldsetComponent, FoldFileDropzoneComponent, FoldHeroCardComponent, FoldHeroSectionComponent, FoldIconComponent, FoldIconRegistry, FoldIdService, FoldInfoComponent, FoldInlineConfirmComponent, FoldInputComponent, FoldLinkComponent, FoldListboxComponent, FoldLoadingStateComponent, FoldMenuComponent, FoldMenuItemComponent, FoldMenuSectionComponent, FoldMenuSeparatorComponent, FoldMeterComponent, FoldMultiselectComponent, FoldNavGroupComponent, FoldNavLauncherComponent, FoldNavLayoutComponent, FoldNavTileComponent, FoldNumberInputComponent, FoldOptgroupComponent, FoldOptionComponent, FoldPageLayoutComponent, FoldPageSectionComponent, FoldPageTitleDirective, FoldPaginatorComponent, FoldPaletteRegistry, FoldPanelBodyComponent, FoldPanelComponentOutletDirective, FoldPanelFooterComponent, FoldPanelHeaderComponent, FoldPanelHostComponent, FoldPanelHostService, FoldPanelRef, FoldPanelToggle, FoldPasswordFieldComponent, FoldPopoverComponent, FoldPopoverTriggerDirective, FoldRangeSliderComponent, FoldRepeatPressDirective, FoldScrollRegionDirective, FoldSearchComponent, FoldSelectComponent, FoldSliderComponent, FoldSpinnerComponent, FoldStatusBadgeComponent, FoldStickyColumnDirective, FoldSurfaceDirective, FoldTabPanelComponent, FoldTabsComponent, FoldTextareaComponent, FoldTimeComponent, FoldTimelineComponent, FoldToastComponent, FoldToastContainerComponent, FoldToastService, FoldToggleIconComponent, FoldViewNavComponent, FoldViewToggleComponent, ScrollRegionRegistry, autoUpdate, computePlacement, foldAddDays, foldAddMinutes, foldAddMonths, foldBlurVar, foldBuildAgenda, foldBuildDay, foldBuildMonthGrid, foldBuildTimeGrid, foldBuildWeek, foldCalendarNextFocus, foldCardBandChrome, foldColorProperty, foldColorVar, foldCountActionable, foldDaysBetween, foldDefaultPasswordRules, foldEndOfMonth, foldEventsInRange, foldEventsOnDay, foldFilterBySource, foldFontVar, foldFromMinutes, foldFromNativeDate, foldFromTemporal, foldHashSeed, foldIsActionable, foldIsCalendarDate, foldIsCalendarTime, foldIsTimed, foldIsWeekend, foldIsoWeek, foldIsoWeekYear, foldLayOutOverlaps, foldLeadingVar, foldLocaleWeekInfo, foldMotionVar, foldRadiusVar, foldRangeForView, foldRegexRule, foldResolvePalette, foldShadowVar, foldShiftDate, foldSpaceVar, foldStartOfMonth, foldStartOfWeek, foldTextVar, foldToMinutes, foldToNativeDate, foldToday, foldTrackingVar, foldViewTitle, foldWeekdayIndex, foldWeekdayOf, foldWeightVar, isFoldSelectOptionGroup, observeElementWidth, provideFoldCalendarLabels, provideFoldCommonLabels, provideFoldDataTableLabels, provideFoldIcons, provideFoldInlineConfirmLabels, provideFoldPaginatorLabels, provideFoldPalette, provideFoldPanelDefaults, provideFoldPanelLabels, provideFoldToasts };
|
|
14828
|
+
export { FOLD_AUTO_PALETTES, FOLD_BLUR_TOKENS, FOLD_BUILTIN_ICONS, FOLD_BUILTIN_ICON_CATEGORIES, FOLD_CALENDAR_DEFAULT_LABELS, FOLD_CALENDAR_FORMATS, FOLD_CALENDAR_LABELS, FOLD_COMMON_DEFAULT_LABELS, FOLD_COMMON_LABELS, FOLD_DATA_TABLE_DEFAULT_LABELS, FOLD_DATA_TABLE_LABELS, FOLD_DEFAULT_WEEKEND_DAYS, FOLD_FALLBACK_WEEK_INFO, FOLD_FONT_TOKENS, FOLD_INLINE_CONFIRM_DEFAULT_LABELS, FOLD_INLINE_CONFIRM_LABELS, FOLD_LEADING_TOKENS, FOLD_MINUTES_PER_DAY, FOLD_MOTION_TOKENS, FOLD_PAGINATOR_DEFAULT_LABELS, FOLD_PAGINATOR_LABELS, FOLD_PALETTE_DEFAULT, FOLD_PANEL_CLOSE_LABEL, FOLD_PANEL_DEFAULTS, FOLD_RADIUS_TOKENS, FOLD_SEMANTIC_COLOR_TOKENS, FOLD_SHADOW_TOKENS, FOLD_SPACE_TOKENS, FOLD_TEXT_TOKENS, FOLD_TOAST_CONFIG, FOLD_TRACKING_TOKENS, FOLD_WEIGHT_TOKENS, FoldAppShellComponent, FoldAsideLayoutComponent, FoldAvatarComponent, FoldAvatarDetailComponent, FoldAvatarListComponent, FoldBackLinkComponent, FoldBadgeComponent, FoldBreadcrumbComponent, FoldButtonComponent, FoldButtonIconComponent, FoldCalendarAgendaComponent, FoldCalendarChromeDirective, FoldCalendarDayComponent, FoldCalendarDayDirective, FoldCalendarEventDirective, FoldCalendarHeadingDirective, FoldCalendarListComponent, FoldCalendarMonthComponent, FoldCalendarOverflowDirective, FoldCalendarSourceFilterComponent, FoldCalendarTimegridComponent, FoldCalendarTitleDirective, FoldCalendarToolbarComponent, FoldCalendarWeekComponent, FoldCalloutComponent, FoldCardComponent, FoldCheckboxComponent, FoldChecklistComponent, FoldChoiceRowComponent, FoldContextCardComponent, FoldDangerZoneComponent, FoldDataTableCellDirective, FoldDataTableComponent, FoldDataTableRowCardDirective, FoldDataTableRowDetailDirective, FoldDateComponent, FoldDisclosureComponent, FoldDropdownComponent, FoldDropdownItemComponent, FoldElementTitleComponent, FoldElevatedDirective, FoldEmptyStateComponent, FoldFieldComponent, FoldFieldIdDirective, FoldFieldListComponent, FoldFieldsetComponent, FoldFileDropzoneComponent, FoldHeroCardComponent, FoldHeroSectionComponent, FoldIconComponent, FoldIconRegistry, FoldIdService, FoldInfoComponent, FoldInlineConfirmComponent, FoldInputComponent, FoldLinkComponent, FoldListboxComponent, FoldLoadingStateComponent, FoldMenuComponent, FoldMenuItemComponent, FoldMenuSectionComponent, FoldMenuSeparatorComponent, FoldMeterComponent, FoldMultiselectComponent, FoldNavGroupComponent, FoldNavLauncherComponent, FoldNavLayoutComponent, FoldNavTileComponent, FoldNumberInputComponent, FoldOptgroupComponent, FoldOptionComponent, FoldPageLayoutComponent, FoldPageSectionComponent, FoldPageTitleDirective, FoldPaginatorComponent, FoldPaletteRegistry, FoldPanelBodyComponent, FoldPanelComponentOutletDirective, FoldPanelFooterComponent, FoldPanelHeaderComponent, FoldPanelHostComponent, FoldPanelHostService, FoldPanelRef, FoldPanelToggle, FoldPasswordFieldComponent, FoldPopoverComponent, FoldPopoverTriggerDirective, FoldRangeSliderComponent, FoldRepeatPressDirective, FoldScrollRegionDirective, FoldSearchComponent, FoldSelectComponent, FoldSliderComponent, FoldSpinnerComponent, FoldStatusBadgeComponent, FoldStickyColumnDirective, FoldSurfaceDirective, FoldTabPanelComponent, FoldTabsComponent, FoldTextareaComponent, FoldTimeComponent, FoldTimelineComponent, FoldToastComponent, FoldToastContainerComponent, FoldToastService, FoldToggleIconComponent, FoldViewNavComponent, FoldViewToggleComponent, ScrollRegionRegistry, autoUpdate, computePlacement, foldAddDays, foldAddMinutes, foldAddMonths, foldBlurVar, foldBuildAgenda, foldBuildDay, foldBuildMonthGrid, foldBuildTimeGrid, foldBuildWeek, foldCalendarNextFocus, foldCardBandChrome, foldColorProperty, foldColorVar, foldCountActionable, foldDaysBetween, foldDefaultPasswordRules, foldEndOfMonth, foldEventsInRange, foldEventsOnDay, foldFilterBySource, foldFontVar, foldFromMinutes, foldFromNativeDate, foldFromTemporal, foldHashSeed, foldIsActionable, foldIsCalendarDate, foldIsCalendarTime, foldIsTimed, foldIsWeekend, foldIsoWeek, foldIsoWeekYear, foldLayOutOverlaps, foldLeadingVar, foldLocaleWeekInfo, foldMotionVar, foldRadiusVar, foldRangeForView, foldRegexRule, foldResolvePalette, foldShadowVar, foldShiftDate, foldSpaceVar, foldStartOfMonth, foldStartOfWeek, foldTextVar, foldToMinutes, foldToNativeDate, foldToday, foldTrackingVar, foldViewTitle, foldWeekdayIndex, foldWeekdayOf, foldWeightVar, isFoldSelectOptionGroup, observeElementWidth, provideFoldCalendarLabels, provideFoldCommonLabels, provideFoldDataTableLabels, provideFoldIcons, provideFoldInlineConfirmLabels, provideFoldPaginatorLabels, provideFoldPalette, provideFoldPanelDefaults, provideFoldPanelLabels, provideFoldToasts };
|
|
14714
14829
|
//# sourceMappingURL=fold-ng.mjs.map
|