@guildofgleks/ui 21.3.2 → 21.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +212 -10
- package/README.md +102 -271
- package/TOKENS.md +2 -2
- package/fesm2022/guildofgleks-ui.mjs +641 -64
- package/fesm2022/guildofgleks-ui.mjs.map +1 -1
- package/package.json +11 -1
- package/src/styles/button.css +193 -0
- package/src/styles/index.css +2 -0
- package/src/styles/theme.css +6 -0
- package/styles/button.css +193 -0
- package/styles/index.css +2 -0
- package/styles/theme.css +6 -0
- package/types/guildofgleks-ui.d.ts +394 -15
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, input, ChangeDetectionStrategy, Component, output, computed, DestroyRef,
|
|
2
|
+
import { InjectionToken, inject, input, ChangeDetectionStrategy, Component, output, computed, DestroyRef, booleanAttribute, Directive, isDevMode, TemplateRef, model, contentChild, ElementRef, signal, effect, untracked, PLATFORM_ID, ApplicationRef, viewChild, afterNextRender, Renderer2, viewChildren, contentChildren, forwardRef, Injectable, Injector, afterRenderEffect, ViewContainerRef, linkedSignal } from '@angular/core';
|
|
3
3
|
import { Subject, timer } from 'rxjs';
|
|
4
4
|
import { throttle } from 'rxjs/operators';
|
|
5
5
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
@@ -118,7 +118,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
118
118
|
|
|
119
119
|
const DEFAULT_DEBOUNCE = 300;
|
|
120
120
|
/** Built-in default, used when neither the instance input nor `GOG_CONFIG` supplies one. */
|
|
121
|
-
const DEFAULT_SIZE$
|
|
121
|
+
const DEFAULT_SIZE$a = 'md';
|
|
122
122
|
class ButtonComponent {
|
|
123
123
|
variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
124
124
|
/** Unset, falls back to `GOG_CONFIG.control.size`, then to `'md'`. */
|
|
@@ -157,7 +157,7 @@ class ButtonComponent {
|
|
|
157
157
|
};
|
|
158
158
|
globalConfig = inject(GOG_CONFIG);
|
|
159
159
|
/** Instance input → `GOG_CONFIG` → the component's own default. See `resolveConfigured`. */
|
|
160
|
-
resolvedSize = computed(() => resolveConfigured(this.size(), this.globalConfig.control?.size, DEFAULT_SIZE$
|
|
160
|
+
resolvedSize = computed(() => resolveConfigured(this.size(), this.globalConfig.control?.size, DEFAULT_SIZE$a), ...(ngDevMode ? [{ debugName: "resolvedSize" }] : /* istanbul ignore next */ []));
|
|
161
161
|
spinnerSize = computed(() => ButtonComponent.SPINNER_SIZE_BY_BUTTON_SIZE[this.resolvedSize()], ...(ngDevMode ? [{ debugName: "spinnerSize" }] : /* istanbul ignore next */ []));
|
|
162
162
|
resolvedDebounce = computed(() => resolveConfigured(this.debounce(), this.globalConfig.button?.debounce, DEFAULT_DEBOUNCE), ...(ngDevMode ? [{ debugName: "resolvedDebounce" }] : /* istanbul ignore next */ []));
|
|
163
163
|
/**
|
|
@@ -178,7 +178,7 @@ class ButtonComponent {
|
|
|
178
178
|
this.click$.next(event);
|
|
179
179
|
}
|
|
180
180
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
181
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ButtonComponent, isStandalone: true, selector: "gog-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, debounce: { classPropertyName: "debounce", publicName: "debounce", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { gogClick: "gogClick" }, host: { properties: { "class.gog-host--full-width": "fullWidth()" } }, ngImport: i0, template: "<button\r\n (click)=\"onClick($event)\"\r\n [attr.aria-busy]=\"loading() ? 'true' : null\"\r\n [attr.aria-disabled]=\"isDisabled() && !isNativeDisabled() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel()\"\r\n [attr.disabled]=\"isNativeDisabled() ? true : null\"\r\n [class.gog-btn--ghost]=\"variant() === 'ghost'\"\r\n [class.gog-btn--loading]=\"loading()\"\r\n [class.gog-btn--outline]=\"variant() === 'outline'\"\r\n [class.gog-btn--primary]=\"variant() === 'primary'\"\r\n [class.gog-btn--secondary]=\"variant() === 'secondary'\"\r\n [class.gog-cursor-not-allowed]=\"isDisabled()\"\r\n [class.gog-cursor-pointer]=\"!isDisabled()\"\r\n [class.gog-cursor-wait]=\"loading()\"\r\n [type]=\"type()\"\r\n class=\"gog-btn gog-inline-center gog-contained-layout\"\r\n [class]=\"sizeClass()\"\r\n>\r\n @if (loading()) {\r\n <gog-spinner [size]=\"spinnerSize()\" aria-hidden=\"true\" class=\"gog-btn__spinner\" />\r\n }\r\n\r\n <span [class.gog-btn__content--hidden]=\"loading()\" class=\"gog-btn__content\">\r\n <ng-content></ng-content>\r\n </span>\r\n</button>\r\n", styles: ["
|
|
181
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ButtonComponent, isStandalone: true, selector: "gog-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, debounce: { classPropertyName: "debounce", publicName: "debounce", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { gogClick: "gogClick" }, host: { properties: { "class.gog-host--full-width": "fullWidth()" } }, ngImport: i0, template: "<button\r\n (click)=\"onClick($event)\"\r\n [attr.aria-busy]=\"loading() ? 'true' : null\"\r\n [attr.aria-disabled]=\"isDisabled() && !isNativeDisabled() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel()\"\r\n [attr.disabled]=\"isNativeDisabled() ? true : null\"\r\n [class.gog-btn--ghost]=\"variant() === 'ghost'\"\r\n [class.gog-btn--loading]=\"loading()\"\r\n [class.gog-btn--outline]=\"variant() === 'outline'\"\r\n [class.gog-btn--primary]=\"variant() === 'primary'\"\r\n [class.gog-btn--secondary]=\"variant() === 'secondary'\"\r\n [class.gog-cursor-not-allowed]=\"isDisabled()\"\r\n [class.gog-cursor-pointer]=\"!isDisabled()\"\r\n [class.gog-cursor-wait]=\"loading()\"\r\n [type]=\"type()\"\r\n class=\"gog-btn gog-inline-center gog-contained-layout\"\r\n [class]=\"sizeClass()\"\r\n>\r\n @if (loading()) {\r\n <gog-spinner [size]=\"spinnerSize()\" aria-hidden=\"true\" class=\"gog-btn__spinner\" />\r\n }\r\n\r\n <span [class.gog-btn__content--hidden]=\"loading()\" class=\"gog-btn__content\">\r\n <ng-content></ng-content>\r\n </span>\r\n</button>\r\n", styles: ["@charset \"UTF-8\";:host(.gog-host--full-width){display:flex}:host(.gog-host--full-width) .gog-btn{width:100%}\n"], dependencies: [{ kind: "component", type: SpinnerComponent, selector: "gog-spinner", inputs: ["size", "overlay", "ariaLabel", "variant"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
182
182
|
}
|
|
183
183
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
184
184
|
type: Component,
|
|
@@ -186,9 +186,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
186
186
|
// Drives the :host(.gog-host--full-width) rules in the stylesheet — without this
|
|
187
187
|
// binding the `fullWidth` input has no visible effect.
|
|
188
188
|
'[class.gog-host--full-width]': 'fullWidth()',
|
|
189
|
-
}, template: "<button\r\n (click)=\"onClick($event)\"\r\n [attr.aria-busy]=\"loading() ? 'true' : null\"\r\n [attr.aria-disabled]=\"isDisabled() && !isNativeDisabled() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel()\"\r\n [attr.disabled]=\"isNativeDisabled() ? true : null\"\r\n [class.gog-btn--ghost]=\"variant() === 'ghost'\"\r\n [class.gog-btn--loading]=\"loading()\"\r\n [class.gog-btn--outline]=\"variant() === 'outline'\"\r\n [class.gog-btn--primary]=\"variant() === 'primary'\"\r\n [class.gog-btn--secondary]=\"variant() === 'secondary'\"\r\n [class.gog-cursor-not-allowed]=\"isDisabled()\"\r\n [class.gog-cursor-pointer]=\"!isDisabled()\"\r\n [class.gog-cursor-wait]=\"loading()\"\r\n [type]=\"type()\"\r\n class=\"gog-btn gog-inline-center gog-contained-layout\"\r\n [class]=\"sizeClass()\"\r\n>\r\n @if (loading()) {\r\n <gog-spinner [size]=\"spinnerSize()\" aria-hidden=\"true\" class=\"gog-btn__spinner\" />\r\n }\r\n\r\n <span [class.gog-btn__content--hidden]=\"loading()\" class=\"gog-btn__content\">\r\n <ng-content></ng-content>\r\n </span>\r\n</button>\r\n", styles: ["
|
|
189
|
+
}, template: "<button\r\n (click)=\"onClick($event)\"\r\n [attr.aria-busy]=\"loading() ? 'true' : null\"\r\n [attr.aria-disabled]=\"isDisabled() && !isNativeDisabled() ? 'true' : null\"\r\n [attr.aria-label]=\"ariaLabel()\"\r\n [attr.disabled]=\"isNativeDisabled() ? true : null\"\r\n [class.gog-btn--ghost]=\"variant() === 'ghost'\"\r\n [class.gog-btn--loading]=\"loading()\"\r\n [class.gog-btn--outline]=\"variant() === 'outline'\"\r\n [class.gog-btn--primary]=\"variant() === 'primary'\"\r\n [class.gog-btn--secondary]=\"variant() === 'secondary'\"\r\n [class.gog-cursor-not-allowed]=\"isDisabled()\"\r\n [class.gog-cursor-pointer]=\"!isDisabled()\"\r\n [class.gog-cursor-wait]=\"loading()\"\r\n [type]=\"type()\"\r\n class=\"gog-btn gog-inline-center gog-contained-layout\"\r\n [class]=\"sizeClass()\"\r\n>\r\n @if (loading()) {\r\n <gog-spinner [size]=\"spinnerSize()\" aria-hidden=\"true\" class=\"gog-btn__spinner\" />\r\n }\r\n\r\n <span [class.gog-btn__content--hidden]=\"loading()\" class=\"gog-btn__content\">\r\n <ng-content></ng-content>\r\n </span>\r\n</button>\r\n", styles: ["@charset \"UTF-8\";:host(.gog-host--full-width){display:flex}:host(.gog-host--full-width) .gog-btn{width:100%}\n"] }]
|
|
190
190
|
}], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], debounce: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounce", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], gogClick: [{ type: i0.Output, args: ["gogClick"] }] } });
|
|
191
191
|
|
|
192
|
+
/** Built-in default, used when neither the instance input nor `GOG_CONFIG` supplies one. */
|
|
193
|
+
const DEFAULT_SIZE$9 = 'md';
|
|
194
|
+
/**
|
|
195
|
+
* Makes a consumer's own `<a>` or `<button>` look like a `gog-button`.
|
|
196
|
+
*
|
|
197
|
+
* ```html
|
|
198
|
+
* <a gogButton routerLink="/pricing">See pricing</a>
|
|
199
|
+
* <a gogButton variant="ghost" href="https://example.com" target="_blank" rel="noreferrer">Docs</a>
|
|
200
|
+
* <button gogButton variant="outline" size="sm" type="submit">Save</button>
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* ## Why this exists next to `gog-button`
|
|
204
|
+
*
|
|
205
|
+
* `gog-button` renders its own `<button>`, so it can never *be* a link — and making it one would
|
|
206
|
+
* mean brokering the router's entire input surface (`routerLink`, `routerLinkActive`,
|
|
207
|
+
* `queryParams`, `fragment`, `state`, …) through a component that would then have to depend on
|
|
208
|
+
* `@angular/router`. This package has four peer dependencies and no router, and a navigation
|
|
209
|
+
* button is not worth a fifth.
|
|
210
|
+
*
|
|
211
|
+
* Inverting it costs nothing: the consumer keeps their own element, so `routerLink`, `href`,
|
|
212
|
+
* `target`, `download`, `type="submit"`, `disabled` and every future directive keep working
|
|
213
|
+
* because they were never taken away. This is the "headless primitive" axis of
|
|
214
|
+
* `api-design.instructions.md` — expose the behaviour, not another input.
|
|
215
|
+
*
|
|
216
|
+
* ## Which to use
|
|
217
|
+
*
|
|
218
|
+
* Use `gog-button` for a button that *does* something in the page — it adds `loading` with a
|
|
219
|
+
* centred spinner, `debounce` click throttling and the `gogClick` output, none of which a bare
|
|
220
|
+
* element can provide. Use `[gogButton]` when the element must be a link, or when you need to
|
|
221
|
+
* keep directives of your own on it.
|
|
222
|
+
*
|
|
223
|
+
* ## Accessibility
|
|
224
|
+
*
|
|
225
|
+
* The element stays yours, so its semantics stay correct by construction: a link is a link and a
|
|
226
|
+
* button is a button. Two things this deliberately does **not** do:
|
|
227
|
+
*
|
|
228
|
+
* - It does not add `disabled` handling to an `<a>`. There is no such thing — a disabled link is
|
|
229
|
+
* just a link. Remove the `href` or render a real `<button>`.
|
|
230
|
+
* - It does not fake a loading state. `gog-button`'s spinner is a projected child; a directive
|
|
231
|
+
* cannot add one without taking over the element's content.
|
|
232
|
+
*/
|
|
233
|
+
class GogButtonDirective {
|
|
234
|
+
variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
235
|
+
/** Unset, falls back to `GOG_CONFIG.control.size`, then to `'md'` — as on `gog-button`. */
|
|
236
|
+
size = input(undefined, ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
237
|
+
/**
|
|
238
|
+
* Stretches the element to its container's width. A bare attribute is enough:
|
|
239
|
+
* `<a gogButton fullWidth>`.
|
|
240
|
+
*/
|
|
241
|
+
fullWidth = input(false, { ...(ngDevMode ? { debugName: "fullWidth" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
242
|
+
globalConfig = inject(GOG_CONFIG);
|
|
243
|
+
resolvedSize = computed(() => resolveConfigured(this.size(), this.globalConfig.control?.size, DEFAULT_SIZE$9), ...(ngDevMode ? [{ debugName: "resolvedSize" }] : /* istanbul ignore next */ []));
|
|
244
|
+
variantClass = computed(() => `gog-btn--${this.variant()}`, ...(ngDevMode ? [{ debugName: "variantClass" }] : /* istanbul ignore next */ []));
|
|
245
|
+
/**
|
|
246
|
+
* Unlike `gog-button`, this emits a class for `'md'` too. The component can leave the default
|
|
247
|
+
* size unclassed because its own stylesheet bottoms out at `--gog-btn-md-*`; here the class is
|
|
248
|
+
* also what a consumer reads in devtools to see which size is applied, and a silently absent
|
|
249
|
+
* one reads as "no size resolved".
|
|
250
|
+
*/
|
|
251
|
+
sizeClass = computed(() => `gog-btn--${this.resolvedSize()}`, ...(ngDevMode ? [{ debugName: "sizeClass" }] : /* istanbul ignore next */ []));
|
|
252
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: GogButtonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
253
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: GogButtonDirective, isStandalone: true, selector: "a[gogButton], button[gogButton]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "variantClass() + \" \" + sizeClass()", "class.gog-btn--full-width": "fullWidth()" }, classAttribute: "gog-btn gog-inline-center gog-contained-layout" }, ngImport: i0 });
|
|
254
|
+
}
|
|
255
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: GogButtonDirective, decorators: [{
|
|
256
|
+
type: Directive,
|
|
257
|
+
args: [{
|
|
258
|
+
// Restricted to `a` and `button` rather than a bare `[gogButton]`: on a `<div>` or `<span>` the
|
|
259
|
+
// result looks like a button and is invisible to the keyboard and to assistive tech, and that
|
|
260
|
+
// is exactly the mistake this directive would otherwise make easy.
|
|
261
|
+
selector: 'a[gogButton], button[gogButton]',
|
|
262
|
+
host: {
|
|
263
|
+
class: 'gog-btn gog-inline-center gog-contained-layout',
|
|
264
|
+
'[class]': 'variantClass() + " " + sizeClass()',
|
|
265
|
+
'[class.gog-btn--full-width]': 'fullWidth()',
|
|
266
|
+
},
|
|
267
|
+
}]
|
|
268
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }] } });
|
|
269
|
+
|
|
192
270
|
const VERTICAL_ARROWS = ['ArrowDown', 'ArrowUp'];
|
|
193
271
|
const HORIZONTAL_ARROWS = ['ArrowRight', 'ArrowLeft'];
|
|
194
272
|
const EDGE_KEYS = ['Home', 'End'];
|
|
@@ -273,6 +351,31 @@ function handleRovingFocusKeydown(event, items, options = {}) {
|
|
|
273
351
|
return true;
|
|
274
352
|
}
|
|
275
353
|
|
|
354
|
+
/*
|
|
355
|
+
* The glyphs are from **Lucide** (https://lucide.dev), ISC licensed:
|
|
356
|
+
*
|
|
357
|
+
* Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2022 as part of Feather
|
|
358
|
+
* (MIT). All other copyright (c) for Lucide are held by Lucide Contributors 2022.
|
|
359
|
+
*
|
|
360
|
+
* Permission to use, copy, modify, and/or distribute this software for any purpose with or
|
|
361
|
+
* without fee is hereby granted, provided that the above copyright notice and this permission
|
|
362
|
+
* notice appear in all copies.
|
|
363
|
+
*
|
|
364
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
|
365
|
+
* THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
|
|
366
|
+
* SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
|
|
367
|
+
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
|
368
|
+
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
|
369
|
+
* OR PERFORMANCE OF THIS SOFTWARE.
|
|
370
|
+
*
|
|
371
|
+
* They are inlined rather than pulled from `lucide` so the package keeps zero runtime
|
|
372
|
+
* dependencies. Anything added here must be a Lucide glyph too: a 24×24 grid, `stroke-width`
|
|
373
|
+
* 2, round caps and joins. Mixing in a set drawn for a different weight (Heroicons is drawn for
|
|
374
|
+
* 1.5) shows up immediately as uneven visual mass in a row of icons.
|
|
375
|
+
*
|
|
376
|
+
* An app that wants a different set does not need a fork — `provideGogIcons` overrides any of
|
|
377
|
+
* these by name.
|
|
378
|
+
*/
|
|
276
379
|
const ICON_DEFS = {
|
|
277
380
|
check: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5"/></svg>`,
|
|
278
381
|
close: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`,
|
|
@@ -294,38 +397,150 @@ const ICON_DEFS = {
|
|
|
294
397
|
eye: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye-icon lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg>`,
|
|
295
398
|
'eye-off': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye-off-icon lucide-eye-off"><path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"/><path d="m2 2 20 20"/></svg>`,
|
|
296
399
|
copy: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy-icon lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>`,
|
|
400
|
+
/* ── Actions ─────────────────────────────────────────────────────────────── */
|
|
401
|
+
search: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>`,
|
|
402
|
+
plus: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>`,
|
|
403
|
+
minus: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-minus"><path d="M5 12h14"/></svg>`,
|
|
404
|
+
trash: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash-2"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>`,
|
|
405
|
+
pencil: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pencil"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/></svg>`,
|
|
406
|
+
download: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>`,
|
|
407
|
+
upload: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-upload"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></svg>`,
|
|
408
|
+
refresh: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/></svg>`,
|
|
409
|
+
filter: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-filter"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>`,
|
|
410
|
+
'external-link': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link"><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>`,
|
|
411
|
+
/* ── Navigation & chrome ─────────────────────────────────────────────────── */
|
|
412
|
+
menu: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-menu"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>`,
|
|
413
|
+
'more-horizontal': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ellipsis"><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></svg>`,
|
|
414
|
+
'more-vertical': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ellipsis-vertical"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>`,
|
|
415
|
+
'arrow-left': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left"><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg>`,
|
|
416
|
+
'arrow-right': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-right"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>`,
|
|
417
|
+
/* ── Objects & state ─────────────────────────────────────────────────────── */
|
|
418
|
+
user: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-user"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>`,
|
|
419
|
+
settings: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>`,
|
|
420
|
+
lock: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lock"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>`,
|
|
421
|
+
mail: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mail"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>`,
|
|
422
|
+
star: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-star"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>`,
|
|
423
|
+
'star-filled': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-star"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" fill="currentColor"/></svg>`,
|
|
297
424
|
};
|
|
298
425
|
|
|
426
|
+
/**
|
|
427
|
+
* Icons an app has registered, keyed by the name `gog-icon` will be asked for. Resolves to `{}`
|
|
428
|
+
* — only the built-ins are available — until a `provideGogIcons(...)` call fills it in.
|
|
429
|
+
*
|
|
430
|
+
* Values are raw `<svg>` markup, injected with `bypassSecurityTrustHtml` exactly like the
|
|
431
|
+
* built-ins. See `provideGogIcons` for what that means for you.
|
|
432
|
+
*/
|
|
433
|
+
const GOG_ICONS = new InjectionToken('GOG_ICONS', {
|
|
434
|
+
providedIn: 'root',
|
|
435
|
+
factory: () => ({}),
|
|
436
|
+
});
|
|
437
|
+
/**
|
|
438
|
+
* Registers icons by name, so `<gog-icon name="cart" />` works for glyphs the library does not
|
|
439
|
+
* ship. This is the supported way to use your own icon set: the alternative — a `TemplateRef`
|
|
440
|
+
* per instance through the `template` input — costs a `<ng-template>` at every use site and is
|
|
441
|
+
* meant for one-offs, not for an icon set.
|
|
442
|
+
*
|
|
443
|
+
* ```ts
|
|
444
|
+
* // app.config.ts
|
|
445
|
+
* providers: [
|
|
446
|
+
* provideGogIcons({
|
|
447
|
+
* cart: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">…</svg>',
|
|
448
|
+
* user: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">…</svg>',
|
|
449
|
+
* }),
|
|
450
|
+
* ]
|
|
451
|
+
* ```
|
|
452
|
+
*
|
|
453
|
+
* **A registered name overrides a built-in of the same name**, which is how you swap the
|
|
454
|
+
* library's checkmark or chevron for your own without touching every component that renders one.
|
|
455
|
+
*
|
|
456
|
+
* **Providing this again further down the injector tree layers onto the parent's set** rather
|
|
457
|
+
* than replacing it, matching `provideGogConfig`: a lazy feature can register the three icons
|
|
458
|
+
* only it uses, and the app-wide set stays available inside it.
|
|
459
|
+
*
|
|
460
|
+
* ## What to put in the SVG
|
|
461
|
+
*
|
|
462
|
+
* Use `stroke="currentColor"` (or `fill="currentColor"`) and a `viewBox`, and leave the sizing
|
|
463
|
+
* alone — `gog-icon`'s stylesheet drives width, height and stroke width from the
|
|
464
|
+
* `--gog-icon-*` tokens, so an icon inherits size and colour from wherever it is used, the same
|
|
465
|
+
* as a built-in.
|
|
466
|
+
*
|
|
467
|
+
* ## Security
|
|
468
|
+
*
|
|
469
|
+
* The markup is inserted with `DomSanitizer.bypassSecurityTrustHtml`, because Angular's HTML
|
|
470
|
+
* sanitizer strips SVG and would leave you with nothing. That is safe for what this is for —
|
|
471
|
+
* static icon markup you wrote or imported at build time — and unsafe for anything derived from
|
|
472
|
+
* user input or fetched at runtime. **Never build a registered icon string from data you did
|
|
473
|
+
* not author.** If you need remote icons, fetch them yourself, sanitize them with a real SVG
|
|
474
|
+
* sanitizer, and register the result.
|
|
475
|
+
*/
|
|
476
|
+
function provideGogIcons(icons) {
|
|
477
|
+
return {
|
|
478
|
+
provide: GOG_ICONS,
|
|
479
|
+
// skipSelf so this reads the *parent* injector's set rather than recursing into the provider
|
|
480
|
+
// being defined here; optional because at the root there is no parent providing it.
|
|
481
|
+
useFactory: () => ({
|
|
482
|
+
...(inject(GOG_ICONS, { skipSelf: true, optional: true }) ?? {}),
|
|
483
|
+
...icons,
|
|
484
|
+
}),
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Names already warned about, so a missing icon rendered in a `@for` logs once rather than once
|
|
490
|
+
* per row. Module-level because the point is one message per name per page, not per component.
|
|
491
|
+
*/
|
|
492
|
+
const warnedNames = new Set();
|
|
299
493
|
class IconComponent {
|
|
300
494
|
sanitizer = inject(DomSanitizer);
|
|
495
|
+
/** App-registered icons; overrides a built-in of the same name. See `provideGogIcons`. */
|
|
496
|
+
registered = inject(GOG_ICONS);
|
|
497
|
+
/** A built-in name, or one registered through `provideGogIcons(...)`. */
|
|
301
498
|
name = input('close', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
302
499
|
template = input(null, ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
303
500
|
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
304
501
|
ariaHidden = input(true, ...(ngDevMode ? [{ debugName: "ariaHidden" }] : /* istanbul ignore next */ []));
|
|
305
502
|
ariaLabel = computed(() => this.ariaHidden() ? null : this.title() || this.name(), ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
306
|
-
|
|
503
|
+
/**
|
|
504
|
+
* The markup to render, or `null` when the name resolves to nothing.
|
|
505
|
+
*
|
|
506
|
+
* An unknown name renders **nothing** and warns in dev mode — it never throws. An icon is
|
|
507
|
+
* decoration: taking an app down mid-render over a typo in a glyph name would be a far worse
|
|
508
|
+
* failure than the missing glyph, and the warning is what gets the typo fixed.
|
|
509
|
+
*/
|
|
510
|
+
iconSvg = computed(() => {
|
|
511
|
+
const name = this.name();
|
|
512
|
+
const markup = this.registered[name] ?? ICON_DEFS[name];
|
|
513
|
+
if (!markup) {
|
|
514
|
+
if (isDevMode() && !warnedNames.has(name)) {
|
|
515
|
+
warnedNames.add(name);
|
|
516
|
+
console.warn(`[gog-icon] No icon named "${name}". Register it with provideGogIcons({ '${name}': '<svg…>' }), or use one of the built-ins.`);
|
|
517
|
+
}
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
return this.sanitizer.bypassSecurityTrustHtml(markup);
|
|
521
|
+
}, ...(ngDevMode ? [{ debugName: "iconSvg" }] : /* istanbul ignore next */ []));
|
|
307
522
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
308
523
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: IconComponent, isStandalone: true, selector: "gog-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, ariaHidden: { classPropertyName: "ariaHidden", publicName: "ariaHidden", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-hidden": "ariaHidden() ? \"true\" : null", "attr.aria-label": "ariaHidden() ? null : ariaLabel()" }, classAttribute: "gog-icon" }, ngImport: i0, template: `
|
|
309
524
|
@if (template(); as iconTpl) {
|
|
310
525
|
<ng-container *ngTemplateOutlet="iconTpl" />
|
|
311
|
-
} @else {
|
|
312
|
-
<span [innerHTML]="
|
|
526
|
+
} @else if (iconSvg(); as svg) {
|
|
527
|
+
<span [innerHTML]="svg"></span>
|
|
313
528
|
}
|
|
314
|
-
`, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}:host ::ng-deep svg{width:var(--gog-icon-size, var(--gog-icon-fallback-size));height:var(--gog-icon-size, var(--gog-icon-fallback-size));display:block;color:currentColor}:host ::ng-deep svg path,:host ::ng-deep svg circle,:host ::ng-deep svg rect{stroke-width:var(--gog-icon-stroke-width)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
529
|
+
`, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}:host ::ng-deep svg{width:var(--gog-icon-size, var(--gog-icon-fallback-size));height:var(--gog-icon-size, var(--gog-icon-fallback-size));display:block;color:currentColor}:host ::ng-deep svg path,:host ::ng-deep svg circle,:host ::ng-deep svg rect,:host ::ng-deep svg ellipse,:host ::ng-deep svg line,:host ::ng-deep svg polyline,:host ::ng-deep svg polygon{stroke-width:var(--gog-icon-stroke-width)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
315
530
|
}
|
|
316
531
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: IconComponent, decorators: [{
|
|
317
532
|
type: Component,
|
|
318
533
|
args: [{ selector: 'gog-icon', imports: [NgTemplateOutlet], template: `
|
|
319
534
|
@if (template(); as iconTpl) {
|
|
320
535
|
<ng-container *ngTemplateOutlet="iconTpl" />
|
|
321
|
-
} @else {
|
|
322
|
-
<span [innerHTML]="
|
|
536
|
+
} @else if (iconSvg(); as svg) {
|
|
537
|
+
<span [innerHTML]="svg"></span>
|
|
323
538
|
}
|
|
324
539
|
`, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
325
540
|
class: 'gog-icon',
|
|
326
541
|
'[attr.aria-hidden]': 'ariaHidden() ? "true" : null',
|
|
327
542
|
'[attr.aria-label]': 'ariaHidden() ? null : ariaLabel()',
|
|
328
|
-
}, styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}:host ::ng-deep svg{width:var(--gog-icon-size, var(--gog-icon-fallback-size));height:var(--gog-icon-size, var(--gog-icon-fallback-size));display:block;color:currentColor}:host ::ng-deep svg path,:host ::ng-deep svg circle,:host ::ng-deep svg rect{stroke-width:var(--gog-icon-stroke-width)}\n"] }]
|
|
543
|
+
}, styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}:host ::ng-deep svg{width:var(--gog-icon-size, var(--gog-icon-fallback-size));height:var(--gog-icon-size, var(--gog-icon-fallback-size));display:block;color:currentColor}:host ::ng-deep svg path,:host ::ng-deep svg circle,:host ::ng-deep svg rect,:host ::ng-deep svg ellipse,:host ::ng-deep svg line,:host ::ng-deep svg polyline,:host ::ng-deep svg polygon{stroke-width:var(--gog-icon-stroke-width)}\n"] }]
|
|
329
544
|
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], template: [{ type: i0.Input, args: [{ isSignal: true, alias: "template", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], ariaHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaHidden", required: false }] }] } });
|
|
330
545
|
|
|
331
546
|
class SkeletonComponent {
|
|
@@ -621,6 +836,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
621
836
|
}]
|
|
622
837
|
}] });
|
|
623
838
|
|
|
839
|
+
/**
|
|
840
|
+
* Which `data-theme` an overlay rendered into `<body>` has to carry, if any.
|
|
841
|
+
*
|
|
842
|
+
* A panel or tooltip bubble is appended to `<body>`, which puts it outside whatever subtree it
|
|
843
|
+
* was opened from. `data-theme` can be scoped to any subtree — several themes rendering side by
|
|
844
|
+
* side is a documented use — so an overlay opened inside one of those has to be told which theme
|
|
845
|
+
* it belongs to, or it silently picks up the document's instead.
|
|
846
|
+
*
|
|
847
|
+
* **But only when the theme really is scoped.** When the nearest themed ancestor is the document
|
|
848
|
+
* element, copying the attribute is not merely redundant, it is actively wrong: the overlay
|
|
849
|
+
* already inherits everything from `<html>` through `<body>`, and re-stating `data-theme` on it
|
|
850
|
+
* makes it match `theme.css`'s derived layer (`:root, [data-theme]`) *locally*. That re-declares
|
|
851
|
+
* every component token on the overlay itself, resolved against the plain preset palette — which
|
|
852
|
+
* discards anything set on `<html>` that is not part of that preset. Custom properties written
|
|
853
|
+
* inline on `:root` are the case that bites: a live theme editor sets them there, the page
|
|
854
|
+
* follows, and every portal keeps rendering the un-edited theme.
|
|
855
|
+
*
|
|
856
|
+
* So: return the theme only for a genuinely scoped ancestor, and let inheritance do the work
|
|
857
|
+
* otherwise.
|
|
858
|
+
*
|
|
859
|
+
* Known limitation, currently unreachable: a *scoped* theme that is itself being edited through
|
|
860
|
+
* inline custom properties would still lose those on the overlay, since only the attribute is
|
|
861
|
+
* carried across. Copying resolved values instead would mean reading ~1200 properties on every
|
|
862
|
+
* open, which is not worth it for a case nothing does yet.
|
|
863
|
+
*/
|
|
864
|
+
function scopedOverlayTheme(themeSource, documentElement) {
|
|
865
|
+
const themedAncestor = themeSource?.closest('[data-theme]');
|
|
866
|
+
if (!themedAncestor || themedAncestor === documentElement)
|
|
867
|
+
return null;
|
|
868
|
+
return themedAncestor.getAttribute('data-theme');
|
|
869
|
+
}
|
|
870
|
+
|
|
624
871
|
/**
|
|
625
872
|
* Renders a template into `document.body` while keeping it wired to the declaring
|
|
626
873
|
* component: the view is stamped with that component's style encapsulation and reads
|
|
@@ -651,11 +898,9 @@ class GogDropdownOverlay {
|
|
|
651
898
|
this.detach();
|
|
652
899
|
this.hostEl = this.document.createElement('div');
|
|
653
900
|
this.hostEl.classList.add('gog-overlay-host');
|
|
654
|
-
//
|
|
655
|
-
//
|
|
656
|
-
|
|
657
|
-
const themedAncestor = themeSource?.closest('[data-theme]');
|
|
658
|
-
const theme = themedAncestor?.getAttribute('data-theme');
|
|
901
|
+
// Only for a genuinely scoped theme — see `scopedOverlayTheme` for why copying it when the
|
|
902
|
+
// theme sits on `<html>` breaks live-edited themes.
|
|
903
|
+
const theme = scopedOverlayTheme(themeSource, this.document.documentElement);
|
|
659
904
|
if (theme) {
|
|
660
905
|
this.hostEl.setAttribute('data-theme', theme);
|
|
661
906
|
}
|
|
@@ -3244,7 +3489,7 @@ const DEFAULT_LOCALE$1 = 'en-US';
|
|
|
3244
3489
|
* input nor `GOG_CONFIG.labels` supplies one. Kept as one object so `resolvedLabels` stays a
|
|
3245
3490
|
* single `computed` instead of nine, and so the set is obvious at a glance.
|
|
3246
3491
|
*/
|
|
3247
|
-
const DEFAULT_LABELS$
|
|
3492
|
+
const DEFAULT_LABELS$3 = {
|
|
3248
3493
|
today: 'Today',
|
|
3249
3494
|
thisMonth: 'This month',
|
|
3250
3495
|
previousMonth: 'Previous month',
|
|
@@ -3338,15 +3583,15 @@ class CalendarComponent {
|
|
|
3338
3583
|
resolvedLabels = computed(() => {
|
|
3339
3584
|
const configured = this.globalConfig.labels ?? {};
|
|
3340
3585
|
return {
|
|
3341
|
-
today: resolveConfigured(this.todayLabel(), configured.today, DEFAULT_LABELS$
|
|
3342
|
-
thisMonth: resolveConfigured(this.thisMonthLabel(), configured.thisMonth, DEFAULT_LABELS$
|
|
3343
|
-
previousMonth: resolveConfigured(this.previousMonthLabel(), configured.previousMonth, DEFAULT_LABELS$
|
|
3344
|
-
nextMonth: resolveConfigured(this.nextMonthLabel(), configured.nextMonth, DEFAULT_LABELS$
|
|
3345
|
-
previousYear: resolveConfigured(this.previousYearLabel(), configured.previousYear, DEFAULT_LABELS$
|
|
3346
|
-
nextYear: resolveConfigured(this.nextYearLabel(), configured.nextYear, DEFAULT_LABELS$
|
|
3347
|
-
hours: resolveConfigured(this.hoursLabel(), configured.hours, DEFAULT_LABELS$
|
|
3348
|
-
minutes: resolveConfigured(this.minutesLabel(), configured.minutes, DEFAULT_LABELS$
|
|
3349
|
-
seconds: resolveConfigured(this.secondsLabel(), configured.seconds, DEFAULT_LABELS$
|
|
3586
|
+
today: resolveConfigured(this.todayLabel(), configured.today, DEFAULT_LABELS$3.today),
|
|
3587
|
+
thisMonth: resolveConfigured(this.thisMonthLabel(), configured.thisMonth, DEFAULT_LABELS$3.thisMonth),
|
|
3588
|
+
previousMonth: resolveConfigured(this.previousMonthLabel(), configured.previousMonth, DEFAULT_LABELS$3.previousMonth),
|
|
3589
|
+
nextMonth: resolveConfigured(this.nextMonthLabel(), configured.nextMonth, DEFAULT_LABELS$3.nextMonth),
|
|
3590
|
+
previousYear: resolveConfigured(this.previousYearLabel(), configured.previousYear, DEFAULT_LABELS$3.previousYear),
|
|
3591
|
+
nextYear: resolveConfigured(this.nextYearLabel(), configured.nextYear, DEFAULT_LABELS$3.nextYear),
|
|
3592
|
+
hours: resolveConfigured(this.hoursLabel(), configured.hours, DEFAULT_LABELS$3.hours),
|
|
3593
|
+
minutes: resolveConfigured(this.minutesLabel(), configured.minutes, DEFAULT_LABELS$3.minutes),
|
|
3594
|
+
seconds: resolveConfigured(this.secondsLabel(), configured.seconds, DEFAULT_LABELS$3.seconds),
|
|
3350
3595
|
};
|
|
3351
3596
|
}, ...(ngDevMode ? [{ debugName: "resolvedLabels" }] : /* istanbul ignore next */ []));
|
|
3352
3597
|
/** First of the leftmost visible month. */
|
|
@@ -4958,7 +5203,7 @@ function toAnnouncement(toast) {
|
|
|
4958
5203
|
const DEFAULT_SIZE$1 = 'md';
|
|
4959
5204
|
const DEFAULT_ERROR_DISPLAY$2 = 'manual';
|
|
4960
5205
|
const DEFAULT_SHOW_SPIN_BUTTONS = true;
|
|
4961
|
-
const DEFAULT_LABELS$
|
|
5206
|
+
const DEFAULT_LABELS$2 = {
|
|
4962
5207
|
clear: 'Clear',
|
|
4963
5208
|
increment: 'Increment',
|
|
4964
5209
|
decrement: 'Decrement',
|
|
@@ -5156,9 +5401,9 @@ class InputfieldComponent {
|
|
|
5156
5401
|
*/
|
|
5157
5402
|
sizeClass = computed(() => this.resolvedSize() === 'md' ? '' : `gog-input-wrapper--${this.resolvedSize()}`, ...(ngDevMode ? [{ debugName: "sizeClass" }] : /* istanbul ignore next */ []));
|
|
5158
5403
|
/** Instance input → `GOG_CONFIG.labels` → the built-in English default. */
|
|
5159
|
-
resolvedClearLabel = computed(() => resolveConfigured(this.clearAriaLabel(), this.globalConfig.labels?.clear, DEFAULT_LABELS$
|
|
5160
|
-
resolvedIncrementLabel = computed(() => resolveConfigured(this.incrementLabel(), this.globalConfig.labels?.increment, DEFAULT_LABELS$
|
|
5161
|
-
resolvedDecrementLabel = computed(() => resolveConfigured(this.decrementLabel(), this.globalConfig.labels?.decrement, DEFAULT_LABELS$
|
|
5404
|
+
resolvedClearLabel = computed(() => resolveConfigured(this.clearAriaLabel(), this.globalConfig.labels?.clear, DEFAULT_LABELS$2.clear), ...(ngDevMode ? [{ debugName: "resolvedClearLabel" }] : /* istanbul ignore next */ []));
|
|
5405
|
+
resolvedIncrementLabel = computed(() => resolveConfigured(this.incrementLabel(), this.globalConfig.labels?.increment, DEFAULT_LABELS$2.increment), ...(ngDevMode ? [{ debugName: "resolvedIncrementLabel" }] : /* istanbul ignore next */ []));
|
|
5406
|
+
resolvedDecrementLabel = computed(() => resolveConfigured(this.decrementLabel(), this.globalConfig.labels?.decrement, DEFAULT_LABELS$2.decrement), ...(ngDevMode ? [{ debugName: "resolvedDecrementLabel" }] : /* istanbul ignore next */ []));
|
|
5162
5407
|
resolvedShowSpinButtons = computed(() => resolveConfigured(this.showSpinButtons(), this.globalConfig.inputfield?.showSpinButtons, DEFAULT_SHOW_SPIN_BUTTONS), ...(ngDevMode ? [{ debugName: "resolvedShowSpinButtons" }] : /* istanbul ignore next */ []));
|
|
5163
5408
|
isDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
5164
5409
|
/** Disabled and read-only both refuse edits; the affordances that offer one key off this. */
|
|
@@ -5224,8 +5469,8 @@ class InputfieldComponent {
|
|
|
5224
5469
|
if (!this.isPasswordField())
|
|
5225
5470
|
return this.iconEndLabel();
|
|
5226
5471
|
return this.passwordVisible()
|
|
5227
|
-
? resolveConfigured(this.hidePasswordLabel(), this.globalConfig.labels?.hidePassword, DEFAULT_LABELS$
|
|
5228
|
-
: resolveConfigured(this.showPasswordLabel(), this.globalConfig.labels?.showPassword, DEFAULT_LABELS$
|
|
5472
|
+
? resolveConfigured(this.hidePasswordLabel(), this.globalConfig.labels?.hidePassword, DEFAULT_LABELS$2.hidePassword)
|
|
5473
|
+
: resolveConfigured(this.showPasswordLabel(), this.globalConfig.labels?.showPassword, DEFAULT_LABELS$2.showPassword);
|
|
5229
5474
|
}, ...(ngDevMode ? [{ debugName: "effectiveIconEndLabel" }] : /* istanbul ignore next */ []));
|
|
5230
5475
|
hasIconEnd = computed(() => this.showClear() ||
|
|
5231
5476
|
!!this.addonEnd() ||
|
|
@@ -5788,11 +6033,8 @@ class GogTooltipOverlay {
|
|
|
5788
6033
|
this.detach();
|
|
5789
6034
|
this.componentRef = this.viewContainerRef.createComponent(GogTooltipBubbleComponent);
|
|
5790
6035
|
const el = this.componentRef.location.nativeElement;
|
|
5791
|
-
//
|
|
5792
|
-
|
|
5793
|
-
// assumed from the document.
|
|
5794
|
-
const themedAncestor = themeSource?.closest('[data-theme]');
|
|
5795
|
-
const theme = themedAncestor?.getAttribute('data-theme');
|
|
6036
|
+
// Only for a genuinely scoped theme — see `scopedOverlayTheme`.
|
|
6037
|
+
const theme = scopedOverlayTheme(themeSource, this.document.documentElement);
|
|
5796
6038
|
if (theme) {
|
|
5797
6039
|
el.setAttribute('data-theme', theme);
|
|
5798
6040
|
}
|
|
@@ -6571,10 +6813,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
6571
6813
|
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], showThumb: [{ type: i0.Input, args: [{ isSignal: true, alias: "showThumb", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], errorDisplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorDisplay", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], range: [{ type: i0.Input, args: [{ isSignal: true, alias: "range", required: false }] }], startAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAriaLabel", required: false }] }], endAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "endAriaLabel", required: false }] }], startDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "startDisabled", required: false }] }], endDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "endDisabled", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], rangeValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeValue", required: false }] }, { type: i0.Output, args: ["rangeValueChange"] }] } });
|
|
6572
6814
|
|
|
6573
6815
|
/** Built-in defaults, used when neither the instance input nor `GOG_CONFIG.labels` supplies one. */
|
|
6574
|
-
const
|
|
6816
|
+
const DEFAULT_PAGE_SIZE = 10;
|
|
6817
|
+
const DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 30, 40, 50];
|
|
6818
|
+
/** Off by default: a paginator that silently grew a control would change every existing layout. */
|
|
6819
|
+
const DEFAULT_SHOW_PAGE_SIZE_SELECT = false;
|
|
6820
|
+
const DEFAULT_LABELS$1 = {
|
|
6575
6821
|
pagination: 'Pagination',
|
|
6576
6822
|
previousPage: 'Previous page',
|
|
6577
6823
|
nextPage: 'Next page',
|
|
6824
|
+
rowsPerPage: 'Rows per page',
|
|
6578
6825
|
page: (page, isCurrent) => isCurrent ? `Page ${page}, current page` : `Go to page ${page}`,
|
|
6579
6826
|
};
|
|
6580
6827
|
class PaginatorComponent {
|
|
@@ -6585,7 +6832,35 @@ class PaginatorComponent {
|
|
|
6585
6832
|
* buttons instead.
|
|
6586
6833
|
*/
|
|
6587
6834
|
fullWidth = input(true, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
|
|
6835
|
+
/**
|
|
6836
|
+
* How many pages there are. Ignored when `totalRecords` is given — see there.
|
|
6837
|
+
*/
|
|
6588
6838
|
totalPages = input(1, ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
6839
|
+
/**
|
|
6840
|
+
* How many rows exist in total. Given this, the paginator computes the page count itself from
|
|
6841
|
+
* `pageSize`, which is what removes the `computed(() => Math.ceil(total / size))` a consumer
|
|
6842
|
+
* would otherwise have to write and keep in sync with the select below.
|
|
6843
|
+
*
|
|
6844
|
+
* `null` (the default) keeps the old contract: you tell it `totalPages` directly.
|
|
6845
|
+
*/
|
|
6846
|
+
totalRecords = input(null, ...(ngDevMode ? [{ debugName: "totalRecords" }] : /* istanbul ignore next */ []));
|
|
6847
|
+
/**
|
|
6848
|
+
* Rows per page. Two-way bindable — `[(pageSize)]="size"` — which is the whole point once
|
|
6849
|
+
* `showPageSizeSelect` is on: the select writes back through this, and nothing has to be
|
|
6850
|
+
* ferried between components by hand. `gog-table` binds its own `pageSize` model straight to
|
|
6851
|
+
* this one.
|
|
6852
|
+
*/
|
|
6853
|
+
pageSize = model(DEFAULT_PAGE_SIZE, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
6854
|
+
/**
|
|
6855
|
+
* Whether to offer the rows-per-page select. Unset, falls back to
|
|
6856
|
+
* `GOG_CONFIG.paginator.showPageSizeSelect`, then to `false`.
|
|
6857
|
+
*/
|
|
6858
|
+
showPageSizeSelect = input(undefined, ...(ngDevMode ? [{ debugName: "showPageSizeSelect" }] : /* istanbul ignore next */ []));
|
|
6859
|
+
/**
|
|
6860
|
+
* The choices the select offers. Unset, falls back to
|
|
6861
|
+
* `GOG_CONFIG.paginator.pageSizeOptions`, then to `[10, 20, 30, 40, 50]`.
|
|
6862
|
+
*/
|
|
6863
|
+
pageSizeOptions = input(undefined, ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
|
|
6589
6864
|
/**
|
|
6590
6865
|
* `window` (default): a fixed number of page buttons (`visiblePages`) that slides to keep
|
|
6591
6866
|
* the current page centered, clamped at the edges — no ellipsis, no pinned boundaries
|
|
@@ -6612,34 +6887,58 @@ class PaginatorComponent {
|
|
|
6612
6887
|
ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
6613
6888
|
globalConfig = inject(GOG_CONFIG);
|
|
6614
6889
|
/** Instance input → `GOG_CONFIG.labels` → the built-in English default. */
|
|
6615
|
-
resolvedAriaLabel = computed(() => resolveConfigured(this.ariaLabel(), this.globalConfig.labels?.pagination, DEFAULT_LABELS.pagination), ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
6890
|
+
resolvedAriaLabel = computed(() => resolveConfigured(this.ariaLabel(), this.globalConfig.labels?.pagination, DEFAULT_LABELS$1.pagination), ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
6616
6891
|
/**
|
|
6617
6892
|
* The two step buttons. Config-only: unlike the `<nav>` name, these say the same thing on
|
|
6618
6893
|
* every paginator in an app, so a per-instance input would be dead weight.
|
|
6619
6894
|
*/
|
|
6620
|
-
resolvedPreviousLabel = computed(() => resolveConfigured(undefined, this.globalConfig.labels?.previousPage, DEFAULT_LABELS.previousPage), ...(ngDevMode ? [{ debugName: "resolvedPreviousLabel" }] : /* istanbul ignore next */ []));
|
|
6621
|
-
resolvedNextLabel = computed(() => resolveConfigured(undefined, this.globalConfig.labels?.nextPage, DEFAULT_LABELS.nextPage), ...(ngDevMode ? [{ debugName: "resolvedNextLabel" }] : /* istanbul ignore next */ []));
|
|
6895
|
+
resolvedPreviousLabel = computed(() => resolveConfigured(undefined, this.globalConfig.labels?.previousPage, DEFAULT_LABELS$1.previousPage), ...(ngDevMode ? [{ debugName: "resolvedPreviousLabel" }] : /* istanbul ignore next */ []));
|
|
6896
|
+
resolvedNextLabel = computed(() => resolveConfigured(undefined, this.globalConfig.labels?.nextPage, DEFAULT_LABELS$1.nextPage), ...(ngDevMode ? [{ debugName: "resolvedNextLabel" }] : /* istanbul ignore next */ []));
|
|
6622
6897
|
/**
|
|
6623
6898
|
* Names one page button. A method rather than a `computed`, since it takes the page number —
|
|
6624
6899
|
* the formatter itself is resolved once and only re-read when the config object changes.
|
|
6625
6900
|
*/
|
|
6626
6901
|
pageLabel(page) {
|
|
6627
|
-
const format = this.globalConfig.labels?.page ?? DEFAULT_LABELS.page;
|
|
6902
|
+
const format = this.globalConfig.labels?.page ?? DEFAULT_LABELS$1.page;
|
|
6628
6903
|
return format(page, page === this.page());
|
|
6629
6904
|
}
|
|
6905
|
+
resolvedShowPageSizeSelect = computed(() => resolveConfigured(this.showPageSizeSelect(), this.globalConfig.paginator?.showPageSizeSelect, DEFAULT_SHOW_PAGE_SIZE_SELECT), ...(ngDevMode ? [{ debugName: "resolvedShowPageSizeSelect" }] : /* istanbul ignore next */ []));
|
|
6906
|
+
resolvedRowsPerPageLabel = computed(() => resolveConfigured(undefined, this.globalConfig.labels?.rowsPerPage, DEFAULT_LABELS$1.rowsPerPage), ...(ngDevMode ? [{ debugName: "resolvedRowsPerPageLabel" }] : /* istanbul ignore next */ []));
|
|
6907
|
+
/**
|
|
6908
|
+
* The select takes `{ id, name }` objects because that is `GogDropdownOption`'s default shape —
|
|
6909
|
+
* `optionLabel`/`optionValue` accessors for a list of plain numbers would be more API than the
|
|
6910
|
+
* mapping saves. The current `pageSize` is included even when it is not one of the offered
|
|
6911
|
+
* options, so a programmatic `[pageSize]="15"` shows 15 rather than an empty trigger.
|
|
6912
|
+
*/
|
|
6913
|
+
resolvedPageSizeOptions = computed(() => {
|
|
6914
|
+
const options = resolveConfigured(this.pageSizeOptions(), this.globalConfig.paginator?.pageSizeOptions, DEFAULT_PAGE_SIZE_OPTIONS);
|
|
6915
|
+
const current = this.pageSize();
|
|
6916
|
+
const all = options.includes(current) ? options : [...options, current].sort((a, b) => a - b);
|
|
6917
|
+
return all.map((size) => ({ id: size, name: String(size) }));
|
|
6918
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedPageSizeOptions" }] : /* istanbul ignore next */ []));
|
|
6919
|
+
/**
|
|
6920
|
+
* `totalRecords` when supplied, `totalPages` otherwise — every internal read goes through this
|
|
6921
|
+
* so the two inputs cannot disagree anywhere.
|
|
6922
|
+
*/
|
|
6923
|
+
resolvedTotalPages = computed(() => {
|
|
6924
|
+
const records = this.totalRecords();
|
|
6925
|
+
if (records === null)
|
|
6926
|
+
return Math.max(1, this.totalPages());
|
|
6927
|
+
return Math.max(1, Math.ceil(Math.max(0, records) / Math.max(1, this.pageSize())));
|
|
6928
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedTotalPages" }] : /* istanbul ignore next */ []));
|
|
6630
6929
|
pageNumbers = computed(() => {
|
|
6631
|
-
const total =
|
|
6930
|
+
const total = this.resolvedTotalPages();
|
|
6632
6931
|
const current = this.page();
|
|
6633
6932
|
return this.rangeMode() === 'ellipsis'
|
|
6634
6933
|
? this.ellipsisRange(total, current)
|
|
6635
6934
|
: this.windowRange(total, current);
|
|
6636
6935
|
}, ...(ngDevMode ? [{ debugName: "pageNumbers" }] : /* istanbul ignore next */ []));
|
|
6637
6936
|
constructor() {
|
|
6638
|
-
// Self-clamps whenever
|
|
6937
|
+
// Self-clamps whenever the page count shrinks below the current page (or a consumer
|
|
6639
6938
|
// passes an out-of-range value directly), so every consumer gets correct bounds for
|
|
6640
6939
|
// free instead of reimplementing this per usage.
|
|
6641
6940
|
effect(() => {
|
|
6642
|
-
const total =
|
|
6941
|
+
const total = this.resolvedTotalPages();
|
|
6643
6942
|
const current = this.page();
|
|
6644
6943
|
if (current > total) {
|
|
6645
6944
|
this.page.set(total);
|
|
@@ -6648,6 +6947,26 @@ class PaginatorComponent {
|
|
|
6648
6947
|
this.page.set(1);
|
|
6649
6948
|
}
|
|
6650
6949
|
});
|
|
6950
|
+
/*
|
|
6951
|
+
* A new page size invalidates the current page: "page 5" of 10-row pages is not "page 5" of
|
|
6952
|
+
* 50-row ones, and clamping alone would leave the user somewhere they did not ask to be.
|
|
6953
|
+
* Back to page 1, which is the only position that means the same thing at every size.
|
|
6954
|
+
* `untracked` so this reacts to the size and not to its own write.
|
|
6955
|
+
*/
|
|
6956
|
+
let previousSize = null;
|
|
6957
|
+
effect(() => {
|
|
6958
|
+
const size = this.pageSize();
|
|
6959
|
+
// Guarded on an actual change, not on the effect running: the first run must leave an
|
|
6960
|
+
// initial `[page]="3"` alone, and re-running for an unrelated dependency must not snap the
|
|
6961
|
+
// user back to page 1.
|
|
6962
|
+
if (previousSize !== null && previousSize !== size) {
|
|
6963
|
+
untracked(() => {
|
|
6964
|
+
if (this.page() !== 1)
|
|
6965
|
+
this.page.set(1);
|
|
6966
|
+
});
|
|
6967
|
+
}
|
|
6968
|
+
previousSize = size;
|
|
6969
|
+
});
|
|
6651
6970
|
}
|
|
6652
6971
|
windowRange(total, current) {
|
|
6653
6972
|
const windowSize = Math.min(Math.max(1, this.visiblePages()), total);
|
|
@@ -6685,7 +7004,7 @@ class PaginatorComponent {
|
|
|
6685
7004
|
return typeof value === 'number';
|
|
6686
7005
|
}
|
|
6687
7006
|
goTo(target) {
|
|
6688
|
-
if (this.disabled() || target < 1 || target > this.
|
|
7007
|
+
if (this.disabled() || target < 1 || target > this.resolvedTotalPages())
|
|
6689
7008
|
return;
|
|
6690
7009
|
this.page.set(target);
|
|
6691
7010
|
}
|
|
@@ -6695,12 +7014,16 @@ class PaginatorComponent {
|
|
|
6695
7014
|
next() {
|
|
6696
7015
|
this.goTo(this.page() + 1);
|
|
6697
7016
|
}
|
|
7017
|
+
onPageSizeChange(size) {
|
|
7018
|
+
if (size !== null)
|
|
7019
|
+
this.pageSize.set(size);
|
|
7020
|
+
}
|
|
6698
7021
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: PaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6699
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: PaginatorComponent, isStandalone: true, selector: "gog-paginator", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, totalPages: { classPropertyName: "totalPages", publicName: "totalPages", isSignal: true, isRequired: false, transformFunction: null }, rangeMode: { classPropertyName: "rangeMode", publicName: "rangeMode", isSignal: true, isRequired: false, transformFunction: null }, visiblePages: { classPropertyName: "visiblePages", publicName: "visiblePages", isSignal: true, isRequired: false, transformFunction: null }, showFirstPage: { classPropertyName: "showFirstPage", publicName: "showFirstPage", isSignal: true, isRequired: false, transformFunction: null }, showLastPage: { classPropertyName: "showLastPage", publicName: "showLastPage", isSignal: true, isRequired: false, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "pageChange" }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "resolvedAriaLabel()", "class.gog-host--auto-width": "!fullWidth()" }, classAttribute: "gog-paginator" }, ngImport: i0, template: "<gog-button\r\n variant=\"ghost\"\r\n [size]=\"size()\"\r\n [disabled]=\"disabled() || page() === 1\"\r\n [ariaLabel]=\"resolvedPreviousLabel()\"\r\n (gogClick)=\"prev()\"\r\n >\u2039</gog-button\r\n>\r\n\r\n@for (item of pageNumbers(); track $index) {\r\n @if (isNumber(item)) {\r\n <gog-button\r\n [size]=\"size()\"\r\n [variant]=\"item === page() ? 'primary' : 'ghost'\"\r\n [disabled]=\"disabled()\"\r\n [ariaLabel]=\"pageLabel(item)\"\r\n (gogClick)=\"goTo(item)\"\r\n >{{ item }}</gog-button\r\n >\r\n } @else {\r\n <span class=\"gog-paginator__ellipsis\">\u2026</span>\r\n }\r\n}\r\n\r\n<gog-button\r\n variant=\"ghost\"\r\n [size]=\"size()\"\r\n [disabled]=\"disabled() || page() ===
|
|
7022
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: PaginatorComponent, isStandalone: true, selector: "gog-paginator", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, totalPages: { classPropertyName: "totalPages", publicName: "totalPages", isSignal: true, isRequired: false, transformFunction: null }, totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, showPageSizeSelect: { classPropertyName: "showPageSizeSelect", publicName: "showPageSizeSelect", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, rangeMode: { classPropertyName: "rangeMode", publicName: "rangeMode", isSignal: true, isRequired: false, transformFunction: null }, visiblePages: { classPropertyName: "visiblePages", publicName: "visiblePages", isSignal: true, isRequired: false, transformFunction: null }, showFirstPage: { classPropertyName: "showFirstPage", publicName: "showFirstPage", isSignal: true, isRequired: false, transformFunction: null }, showLastPage: { classPropertyName: "showLastPage", publicName: "showLastPage", isSignal: true, isRequired: false, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "pageChange", pageSize: "pageSizeChange" }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "resolvedAriaLabel()", "class.gog-host--auto-width": "!fullWidth()" }, classAttribute: "gog-paginator" }, ngImport: i0, template: "<gog-button\r\n variant=\"ghost\"\r\n [size]=\"size()\"\r\n [disabled]=\"disabled() || page() === 1\"\r\n [ariaLabel]=\"resolvedPreviousLabel()\"\r\n (gogClick)=\"prev()\"\r\n >\u2039</gog-button\r\n>\r\n\r\n@for (item of pageNumbers(); track $index) {\r\n @if (isNumber(item)) {\r\n <gog-button\r\n [size]=\"size()\"\r\n [variant]=\"item === page() ? 'primary' : 'ghost'\"\r\n [disabled]=\"disabled()\"\r\n [ariaLabel]=\"pageLabel(item)\"\r\n (gogClick)=\"goTo(item)\"\r\n >{{ item }}</gog-button\r\n >\r\n } @else {\r\n <span class=\"gog-paginator__ellipsis\">\u2026</span>\r\n }\r\n}\r\n\r\n<gog-button\r\n variant=\"ghost\"\r\n [size]=\"size()\"\r\n [disabled]=\"disabled() || page() === resolvedTotalPages()\"\r\n [ariaLabel]=\"resolvedNextLabel()\"\r\n (gogClick)=\"next()\"\r\n >\u203A</gog-button\r\n>\r\n\r\n@if (resolvedShowPageSizeSelect()) {\r\n <!--\r\n Bound with `[(pageSize)]`'s writable half, so choosing a size writes straight back through the\r\n model the consumer bound \u2014 there is no intermediate state to keep in sync. `fullWidth` off so\r\n the select sizes to its content instead of stretching the paginator row.\r\n\r\n A plain `@if`, not `@defer`, and that was measured rather than assumed: `@defer` does move\r\n `SelectComponent` out of this component's static `dependencies` and into\r\n `deferBlockDependencies`, but ng-packagr flattens the whole library into one FESM, so the\r\n deferred reference compiles to `Promise.resolve().then(() => select_component)` \u2014 a binding in\r\n the *same module*, not a dynamic `import()`. With no import boundary there is nothing for a\r\n bundler to split on and nothing it may drop, so the consumer ships exactly the same bytes,\r\n minus a placeholder and an SSR pop-in. Making this genuinely lazy needs secondary entry\r\n points (`@guildofgleks/ui/select`), which is a packaging decision, not a template one.\r\n -->\r\n <gog-select\r\n class=\"gog-paginator__page-size\"\r\n [options]=\"resolvedPageSizeOptions()\"\r\n [value]=\"pageSize()\"\r\n [disabled]=\"disabled()\"\r\n [fullWidth]=\"false\"\r\n [size]=\"size()\"\r\n [ariaLabel]=\"resolvedRowsPerPageLabel()\"\r\n (valueChange)=\"onPageSizeChange($event)\"\r\n />\r\n}\r\n", styles: [":host{display:flex;align-items:center;gap:var(--gog-paginator-gap);flex-wrap:wrap}:host(.gog-host--auto-width){width:fit-content}.gog-paginator__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:var(--gog-paginator-ellipsis-min-width);color:var(--gog-paginator-ellipsis-color);font-family:var(--gog-paginator-ellipsis-font-family);font-size:var(--gog-paginator-ellipsis-font-size);-webkit-user-select:none;user-select:none}.gog-paginator__page-size{margin-inline-start:auto;min-width:var(--gog-paginator-page-size-min-width)}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "gog-button", inputs: ["variant", "size", "disabled", "fullWidth", "type", "loading", "debounce", "ariaLabel"], outputs: ["gogClick"] }, { kind: "component", type: SelectComponent, selector: "gog-select", inputs: ["inputId", "value"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6700
7023
|
}
|
|
6701
7024
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: PaginatorComponent, decorators: [{
|
|
6702
7025
|
type: Component,
|
|
6703
|
-
args: [{ selector: 'gog-paginator', imports: [ButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
7026
|
+
args: [{ selector: 'gog-paginator', imports: [ButtonComponent, SelectComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
6704
7027
|
class: 'gog-paginator',
|
|
6705
7028
|
role: 'navigation',
|
|
6706
7029
|
'[attr.aria-label]': 'resolvedAriaLabel()',
|
|
@@ -6709,8 +7032,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
6709
7032
|
// full-width class: this control is full width by default, so the class only
|
|
6710
7033
|
// appears once a consumer opts *out* of that.
|
|
6711
7034
|
'[class.gog-host--auto-width]': '!fullWidth()',
|
|
6712
|
-
}, template: "<gog-button\r\n variant=\"ghost\"\r\n [size]=\"size()\"\r\n [disabled]=\"disabled() || page() === 1\"\r\n [ariaLabel]=\"resolvedPreviousLabel()\"\r\n (gogClick)=\"prev()\"\r\n >\u2039</gog-button\r\n>\r\n\r\n@for (item of pageNumbers(); track $index) {\r\n @if (isNumber(item)) {\r\n <gog-button\r\n [size]=\"size()\"\r\n [variant]=\"item === page() ? 'primary' : 'ghost'\"\r\n [disabled]=\"disabled()\"\r\n [ariaLabel]=\"pageLabel(item)\"\r\n (gogClick)=\"goTo(item)\"\r\n >{{ item }}</gog-button\r\n >\r\n } @else {\r\n <span class=\"gog-paginator__ellipsis\">\u2026</span>\r\n }\r\n}\r\n\r\n<gog-button\r\n variant=\"ghost\"\r\n [size]=\"size()\"\r\n [disabled]=\"disabled() || page() ===
|
|
6713
|
-
}], ctorParameters: () => [], propDecorators: { page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], totalPages: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPages", required: false }] }], rangeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeMode", required: false }] }], visiblePages: [{ type: i0.Input, args: [{ isSignal: true, alias: "visiblePages", required: false }] }], showFirstPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFirstPage", required: false }] }], showLastPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLastPage", required: false }] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
|
|
7035
|
+
}, template: "<gog-button\r\n variant=\"ghost\"\r\n [size]=\"size()\"\r\n [disabled]=\"disabled() || page() === 1\"\r\n [ariaLabel]=\"resolvedPreviousLabel()\"\r\n (gogClick)=\"prev()\"\r\n >\u2039</gog-button\r\n>\r\n\r\n@for (item of pageNumbers(); track $index) {\r\n @if (isNumber(item)) {\r\n <gog-button\r\n [size]=\"size()\"\r\n [variant]=\"item === page() ? 'primary' : 'ghost'\"\r\n [disabled]=\"disabled()\"\r\n [ariaLabel]=\"pageLabel(item)\"\r\n (gogClick)=\"goTo(item)\"\r\n >{{ item }}</gog-button\r\n >\r\n } @else {\r\n <span class=\"gog-paginator__ellipsis\">\u2026</span>\r\n }\r\n}\r\n\r\n<gog-button\r\n variant=\"ghost\"\r\n [size]=\"size()\"\r\n [disabled]=\"disabled() || page() === resolvedTotalPages()\"\r\n [ariaLabel]=\"resolvedNextLabel()\"\r\n (gogClick)=\"next()\"\r\n >\u203A</gog-button\r\n>\r\n\r\n@if (resolvedShowPageSizeSelect()) {\r\n <!--\r\n Bound with `[(pageSize)]`'s writable half, so choosing a size writes straight back through the\r\n model the consumer bound \u2014 there is no intermediate state to keep in sync. `fullWidth` off so\r\n the select sizes to its content instead of stretching the paginator row.\r\n\r\n A plain `@if`, not `@defer`, and that was measured rather than assumed: `@defer` does move\r\n `SelectComponent` out of this component's static `dependencies` and into\r\n `deferBlockDependencies`, but ng-packagr flattens the whole library into one FESM, so the\r\n deferred reference compiles to `Promise.resolve().then(() => select_component)` \u2014 a binding in\r\n the *same module*, not a dynamic `import()`. With no import boundary there is nothing for a\r\n bundler to split on and nothing it may drop, so the consumer ships exactly the same bytes,\r\n minus a placeholder and an SSR pop-in. Making this genuinely lazy needs secondary entry\r\n points (`@guildofgleks/ui/select`), which is a packaging decision, not a template one.\r\n -->\r\n <gog-select\r\n class=\"gog-paginator__page-size\"\r\n [options]=\"resolvedPageSizeOptions()\"\r\n [value]=\"pageSize()\"\r\n [disabled]=\"disabled()\"\r\n [fullWidth]=\"false\"\r\n [size]=\"size()\"\r\n [ariaLabel]=\"resolvedRowsPerPageLabel()\"\r\n (valueChange)=\"onPageSizeChange($event)\"\r\n />\r\n}\r\n", styles: [":host{display:flex;align-items:center;gap:var(--gog-paginator-gap);flex-wrap:wrap}:host(.gog-host--auto-width){width:fit-content}.gog-paginator__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:var(--gog-paginator-ellipsis-min-width);color:var(--gog-paginator-ellipsis-color);font-family:var(--gog-paginator-ellipsis-font-family);font-size:var(--gog-paginator-ellipsis-font-size);-webkit-user-select:none;user-select:none}.gog-paginator__page-size{margin-inline-start:auto;min-width:var(--gog-paginator-page-size-min-width)}\n"] }]
|
|
7036
|
+
}], ctorParameters: () => [], propDecorators: { page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], totalPages: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPages", required: false }] }], totalRecords: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalRecords", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], showPageSizeSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPageSizeSelect", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], rangeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeMode", required: false }] }], visiblePages: [{ type: i0.Input, args: [{ isSignal: true, alias: "visiblePages", required: false }] }], showFirstPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFirstPage", required: false }] }], showLastPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLastPage", required: false }] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
|
|
6714
7037
|
|
|
6715
7038
|
class SpinnerOverlayComponent {
|
|
6716
7039
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
@@ -6864,6 +7187,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
6864
7187
|
}]
|
|
6865
7188
|
}], propDecorators: { template: [{ type: i0.Input, args: [{ isSignal: true, alias: "template", required: true }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }] } });
|
|
6866
7189
|
|
|
7190
|
+
/** Built-in defaults, used when `GOG_CONFIG.labels` doesn't supply one. */
|
|
7191
|
+
const DEFAULT_LABELS = {
|
|
7192
|
+
total: 'Total',
|
|
7193
|
+
pagination: 'Table pagination',
|
|
7194
|
+
selectRow: 'Select row',
|
|
7195
|
+
selectAllRows: 'Select all rows on this page',
|
|
7196
|
+
};
|
|
6867
7197
|
class TableComponent {
|
|
6868
7198
|
/**
|
|
6869
7199
|
* The single size modifier, replacing one `[class.gog-table--<size>]` binding per size.
|
|
@@ -6876,8 +7206,96 @@ class TableComponent {
|
|
|
6876
7206
|
* its columns' content instead.
|
|
6877
7207
|
*/
|
|
6878
7208
|
fullWidth = input(true, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
|
|
6879
|
-
/**
|
|
6880
|
-
|
|
7209
|
+
/**
|
|
7210
|
+
* Rows per page; `0` (the default) means no pagination at all.
|
|
7211
|
+
*
|
|
7212
|
+
* A **`model`**, not an input, so `[pageSize]="20"` still works exactly as before *and*
|
|
7213
|
+
* `[(pageSize)]="size"` becomes possible. That is what lets `showPageSizeSelect` work without
|
|
7214
|
+
* any wiring: the table binds this model straight to its own paginator's `pageSize`, the
|
|
7215
|
+
* select writes back through it, and a consumer who wants to observe or persist the choice
|
|
7216
|
+
* binds two-way. Nothing is ferried between the two components by hand.
|
|
7217
|
+
*
|
|
7218
|
+
* In `lazy` mode a change here is a refetch signal, same as `gogPageChange` — bind
|
|
7219
|
+
* `[(pageSize)]` and reload from it. Changing the size always returns to page 1.
|
|
7220
|
+
*/
|
|
7221
|
+
pageSize = model(0, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
7222
|
+
/**
|
|
7223
|
+
* Whether the paginator offers a rows-per-page select. Forwarded straight to `gog-paginator`;
|
|
7224
|
+
* unset, it falls back to `GOG_CONFIG.paginator.showPageSizeSelect`, then to `false`.
|
|
7225
|
+
*/
|
|
7226
|
+
showPageSizeSelect = input(undefined, ...(ngDevMode ? [{ debugName: "showPageSizeSelect" }] : /* istanbul ignore next */ []));
|
|
7227
|
+
/**
|
|
7228
|
+
* The sizes that select offers. Forwarded to `gog-paginator`; unset, falls back to
|
|
7229
|
+
* `GOG_CONFIG.paginator.pageSizeOptions`, then to `[10, 20, 30, 40, 50]`.
|
|
7230
|
+
*/
|
|
7231
|
+
pageSizeOptions = input(undefined, ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
|
|
7232
|
+
/**
|
|
7233
|
+
* Hands sorting and paging to the server.
|
|
7234
|
+
*
|
|
7235
|
+
* Off (the default), the table owns the whole data set: it sorts and slices `value` itself, and
|
|
7236
|
+
* `totalPages` comes from `value.length`. On, `value` is **the current page, already sorted** —
|
|
7237
|
+
* the table renders it as given and never re-orders or re-slices it. Supply `totalRecords` so
|
|
7238
|
+
* the paginator knows how many pages exist, and refetch in response to `gogSortChange` /
|
|
7239
|
+
* `gogPageChange`.
|
|
7240
|
+
*
|
|
7241
|
+
* ```html
|
|
7242
|
+
* <gog-table
|
|
7243
|
+
* [value]="page()"
|
|
7244
|
+
* [lazy]="true"
|
|
7245
|
+
* [totalRecords]="total()"
|
|
7246
|
+
* [pageSize]="20"
|
|
7247
|
+
* [loading]="loading()"
|
|
7248
|
+
* (gogSortChange)="sort.set($event); reload()"
|
|
7249
|
+
* (gogPageChange)="page$.set($event); reload()"
|
|
7250
|
+
* />
|
|
7251
|
+
* ```
|
|
7252
|
+
*/
|
|
7253
|
+
lazy = input(false, ...(ngDevMode ? [{ debugName: "lazy" }] : /* istanbul ignore next */ []));
|
|
7254
|
+
/**
|
|
7255
|
+
* How many rows exist on the server, across all pages. `lazy` only — without it the table
|
|
7256
|
+
* cannot know how many pages to offer, and pagination is disabled. Ignored when `lazy` is off,
|
|
7257
|
+
* where `value.length` is the truth.
|
|
7258
|
+
*/
|
|
7259
|
+
totalRecords = input(null, ...(ngDevMode ? [{ debugName: "totalRecords" }] : /* istanbul ignore next */ []));
|
|
7260
|
+
/**
|
|
7261
|
+
* Makes rows focusable and styles them as clickable, for a table whose rows navigate or open
|
|
7262
|
+
* something. `gogRowClick` fires on a plain click regardless; this is what makes that
|
|
7263
|
+
* affordance **discoverable and reachable by keyboard** (Enter and Space activate the focused
|
|
7264
|
+
* row), which a bare `(gogRowClick)` on a `<tr>` is not.
|
|
7265
|
+
*
|
|
7266
|
+
* If the row's action is better expressed as a control — a link to a detail page, a delete
|
|
7267
|
+
* button — put that in a cell instead. This is for the whole-row-is-the-target case.
|
|
7268
|
+
*/
|
|
7269
|
+
interactiveRows = input(false, ...(ngDevMode ? [{ debugName: "interactiveRows" }] : /* istanbul ignore next */ []));
|
|
7270
|
+
/**
|
|
7271
|
+
* Turns on row selection. `'single'` keeps at most one row selected, `'multiple'` any number.
|
|
7272
|
+
*
|
|
7273
|
+
* The selection itself is always a `T[]` (`[(selection)]`), including in `'single'` mode where
|
|
7274
|
+
* it holds zero or one row — one shape rather than a `T | T[] | null` union the consumer has to
|
|
7275
|
+
* narrow on every read.
|
|
7276
|
+
*/
|
|
7277
|
+
selectionMode = input('none', ...(ngDevMode ? [{ debugName: "selectionMode" }] : /* istanbul ignore next */ []));
|
|
7278
|
+
/**
|
|
7279
|
+
* Two-way bindable selected rows: `[(selection)]="selected"`.
|
|
7280
|
+
*
|
|
7281
|
+
* Rows are matched by `dataKey` when one is set, and by object identity otherwise — so with no
|
|
7282
|
+
* `dataKey`, a refetch that produces new objects drops the selection. In `lazy` mode that is
|
|
7283
|
+
* almost always the wrong behaviour: set `dataKey`.
|
|
7284
|
+
*/
|
|
7285
|
+
selection = model([], ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
|
|
7286
|
+
/**
|
|
7287
|
+
* Field name (or dot-path) uniquely identifying a row — `'id'` in most data sets.
|
|
7288
|
+
*
|
|
7289
|
+
* Used for selection identity and, when set, as the `@for` track key, which is what lets the
|
|
7290
|
+
* DOM survive a re-fetch of the same page instead of being torn down and rebuilt.
|
|
7291
|
+
*/
|
|
7292
|
+
dataKey = input('', ...(ngDevMode ? [{ debugName: "dataKey" }] : /* istanbul ignore next */ []));
|
|
7293
|
+
/**
|
|
7294
|
+
* Whether the checkbox column renders. On by default once `selectionMode` is set; turn it off
|
|
7295
|
+
* for a table that selects by clicking the row itself, and pair it with `interactiveRows` so
|
|
7296
|
+
* that stays reachable by keyboard.
|
|
7297
|
+
*/
|
|
7298
|
+
showSelectionColumn = input(true, ...(ngDevMode ? [{ debugName: "showSelectionColumn" }] : /* istanbul ignore next */ []));
|
|
6881
7299
|
showRowNumbers = input(true, ...(ngDevMode ? [{ debugName: "showRowNumbers" }] : /* istanbul ignore next */ []));
|
|
6882
7300
|
showTotal = input(false, ...(ngDevMode ? [{ debugName: "showTotal" }] : /* istanbul ignore next */ []));
|
|
6883
7301
|
emptyPlaceholder = input('-', ...(ngDevMode ? [{ debugName: "emptyPlaceholder" }] : /* istanbul ignore next */ []));
|
|
@@ -6893,10 +7311,30 @@ class TableComponent {
|
|
|
6893
7311
|
stickyHeader = input(false, ...(ngDevMode ? [{ debugName: "stickyHeader" }] : /* istanbul ignore next */ []));
|
|
6894
7312
|
/** Row density: lg (default) / md (compact) / sm (dense) */
|
|
6895
7313
|
size = input('lg', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
7314
|
+
/**
|
|
7315
|
+
* Fires when a header cell changes the sort — including the third click that clears it, which
|
|
7316
|
+
* emits `{ field: '', direction: null }`. In `lazy` mode this is the refetch signal; the table
|
|
7317
|
+
* has already reset to page 1 by the time it fires.
|
|
7318
|
+
*/
|
|
7319
|
+
gogSortChange = output();
|
|
7320
|
+
/**
|
|
7321
|
+
* Fires when the page changes, with the new 1-based page. Only ever fires for a *user* action
|
|
7322
|
+
* or a clamp — not for the initial render.
|
|
7323
|
+
*/
|
|
7324
|
+
gogPageChange = output();
|
|
7325
|
+
/** Fires when a row is clicked, or activated with Enter/Space when `interactiveRows` is on. */
|
|
7326
|
+
gogRowClick = output();
|
|
6896
7327
|
columns = contentChildren(GogColumn, ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
6897
7328
|
templates = contentChildren(TemplateDirective, ...(ngDevMode ? [{ debugName: "templates" }] : /* istanbul ignore next */ []));
|
|
6898
7329
|
sortState = signal({ field: '', direction: null }, ...(ngDevMode ? [{ debugName: "sortState" }] : /* istanbul ignore next */ []));
|
|
7330
|
+
/**
|
|
7331
|
+
* In `lazy` mode `value` is the server's answer — already sorted, already the right page — so
|
|
7332
|
+
* both this and `visibleRows` become pass-throughs. Re-sorting it locally would reorder one
|
|
7333
|
+
* page against a global ordering, which looks like corruption rather than a bug.
|
|
7334
|
+
*/
|
|
6899
7335
|
sortedData = computed(() => {
|
|
7336
|
+
if (this.lazy())
|
|
7337
|
+
return this.value();
|
|
6900
7338
|
const { field, direction } = this.sortState();
|
|
6901
7339
|
const rows = [...this.value()];
|
|
6902
7340
|
if (!field || !direction)
|
|
@@ -6917,11 +7355,16 @@ class TableComponent {
|
|
|
6917
7355
|
return direction === 'asc' ? cmp : -cmp;
|
|
6918
7356
|
});
|
|
6919
7357
|
}, ...(ngDevMode ? [{ debugName: "sortedData" }] : /* istanbul ignore next */ []));
|
|
7358
|
+
/**
|
|
7359
|
+
* How many rows the paginator is dividing. `value.length` normally; `totalRecords` in `lazy`
|
|
7360
|
+
* mode, where `value` is only the current page. Also what `showTotal` reports.
|
|
7361
|
+
*/
|
|
7362
|
+
rowCount = computed(() => this.lazy() ? Math.max(0, this.totalRecords() ?? 0) : this.value().length, ...(ngDevMode ? [{ debugName: "rowCount" }] : /* istanbul ignore next */ []));
|
|
6920
7363
|
totalPages = computed(() => {
|
|
6921
7364
|
const size = this.pageSize();
|
|
6922
7365
|
if (!size)
|
|
6923
7366
|
return 1;
|
|
6924
|
-
return Math.max(1, Math.ceil(this.
|
|
7367
|
+
return Math.max(1, Math.ceil(this.rowCount() / size));
|
|
6925
7368
|
}, ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
6926
7369
|
/**
|
|
6927
7370
|
* Resets to page 1 whenever the sort changes (a new sort re-orders the whole data set,
|
|
@@ -6930,22 +7373,128 @@ class TableComponent {
|
|
|
6930
7373
|
* wherever the paginator navigated to. `gog-paginator`'s own `page` model additionally
|
|
6931
7374
|
* self-clamps against `totalPages` on its own, so this only has to handle the reset case.
|
|
6932
7375
|
*/
|
|
6933
|
-
currentPage = linkedSignal({ ...(ngDevMode ? { debugName: "currentPage" } : /* istanbul ignore next */ {}), source: () => ({
|
|
7376
|
+
currentPage = linkedSignal({ ...(ngDevMode ? { debugName: "currentPage" } : /* istanbul ignore next */ {}), source: () => ({
|
|
7377
|
+
total: this.totalPages(),
|
|
7378
|
+
sortState: this.sortState(),
|
|
7379
|
+
pageSize: this.pageSize(),
|
|
7380
|
+
}),
|
|
6934
7381
|
computation: (src, previous) => {
|
|
6935
|
-
if (!previous
|
|
7382
|
+
if (!previous)
|
|
7383
|
+
return 1;
|
|
7384
|
+
// A new sort re-orders everything, and a new page size redraws the boundaries — in both
|
|
7385
|
+
// cases the page the user was on no longer denotes the same rows.
|
|
7386
|
+
if (previous.source.sortState !== src.sortState)
|
|
7387
|
+
return 1;
|
|
7388
|
+
if (previous.source.pageSize !== src.pageSize)
|
|
6936
7389
|
return 1;
|
|
6937
7390
|
return Math.min(Math.max(1, previous.value), src.total);
|
|
6938
7391
|
} });
|
|
7392
|
+
/** In `lazy` mode the server already sliced the page — see `sortedData`. */
|
|
6939
7393
|
visibleRows = computed(() => {
|
|
6940
7394
|
const size = this.pageSize();
|
|
6941
|
-
if (!size)
|
|
7395
|
+
if (this.lazy() || !size)
|
|
6942
7396
|
return this.sortedData();
|
|
6943
7397
|
const page = this.currentPage();
|
|
6944
7398
|
const start = (page - 1) * size;
|
|
6945
7399
|
return this.sortedData().slice(start, start + size);
|
|
6946
7400
|
}, ...(ngDevMode ? [{ debugName: "visibleRows" }] : /* istanbul ignore next */ []));
|
|
6947
|
-
|
|
6948
|
-
|
|
7401
|
+
/**
|
|
7402
|
+
* Resolved the same way `gog-paginator` resolves it, because the footer's own visibility
|
|
7403
|
+
* depends on it — see `hasPagination`.
|
|
7404
|
+
*/
|
|
7405
|
+
showsPageSizeSelect = computed(() => resolveConfigured(this.showPageSizeSelect(), this.globalConfig.paginator?.showPageSizeSelect, false), ...(ngDevMode ? [{ debugName: "showsPageSizeSelect" }] : /* istanbul ignore next */ []));
|
|
7406
|
+
/**
|
|
7407
|
+
* Normally the paginator only earns its space once there is more than one page — but the
|
|
7408
|
+
* rows-per-page select lives inside it, and hiding the whole thing at one page would strand the
|
|
7409
|
+
* user on whatever size produced that single page with no way back to a smaller one.
|
|
7410
|
+
*/
|
|
7411
|
+
hasPagination = computed(() => !this.loading() &&
|
|
7412
|
+
this.pageSize() > 0 &&
|
|
7413
|
+
(this.totalPages() > 1 || this.showsPageSizeSelect()), ...(ngDevMode ? [{ debugName: "hasPagination" }] : /* istanbul ignore next */ []));
|
|
7414
|
+
globalConfig = inject(GOG_CONFIG);
|
|
7415
|
+
/** `GOG_CONFIG.labels` → the built-in English defaults. No per-instance inputs: these name
|
|
7416
|
+
* table chrome, and an app that relabels them does so once. */
|
|
7417
|
+
resolvedLabels = computed(() => {
|
|
7418
|
+
const configured = this.globalConfig.labels ?? {};
|
|
7419
|
+
return {
|
|
7420
|
+
total: resolveConfigured(undefined, configured.total, DEFAULT_LABELS.total),
|
|
7421
|
+
pagination: resolveConfigured(undefined, configured.tablePagination, DEFAULT_LABELS.pagination),
|
|
7422
|
+
selectRow: resolveConfigured(undefined, configured.selectRow, DEFAULT_LABELS.selectRow),
|
|
7423
|
+
selectAllRows: resolveConfigured(undefined, configured.selectAllRows, DEFAULT_LABELS.selectAllRows),
|
|
7424
|
+
};
|
|
7425
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedLabels" }] : /* istanbul ignore next */ []));
|
|
7426
|
+
hasSelection = computed(() => this.selectionMode() !== 'none', ...(ngDevMode ? [{ debugName: "hasSelection" }] : /* istanbul ignore next */ []));
|
|
7427
|
+
hasSelectionColumn = computed(() => this.hasSelection() && this.showSelectionColumn(), ...(ngDevMode ? [{ debugName: "hasSelectionColumn" }] : /* istanbul ignore next */ []));
|
|
7428
|
+
emptyColspan = computed(() => this.columns().length + (this.showRowNumbers() ? 1 : 0) + (this.hasSelectionColumn() ? 1 : 0), ...(ngDevMode ? [{ debugName: "emptyColspan" }] : /* istanbul ignore next */ []));
|
|
7429
|
+
/**
|
|
7430
|
+
* Identity for selection and `@for` tracking. `dataKey`'s value when set, the row object
|
|
7431
|
+
* otherwise — the object works for a static data set and breaks the moment rows are re-fetched,
|
|
7432
|
+
* which is exactly what `dataKey` is for.
|
|
7433
|
+
*/
|
|
7434
|
+
rowKey(row) {
|
|
7435
|
+
const key = this.dataKey();
|
|
7436
|
+
return key ? getByPath(row, key) : row;
|
|
7437
|
+
}
|
|
7438
|
+
isSelected(row) {
|
|
7439
|
+
const key = this.rowKey(row);
|
|
7440
|
+
return this.selection().some((selected) => this.rowKey(selected) === key);
|
|
7441
|
+
}
|
|
7442
|
+
/** All rows on the current page are selected — drives the header checkbox. */
|
|
7443
|
+
allPageRowsSelected = computed(() => {
|
|
7444
|
+
const rows = this.visibleRows();
|
|
7445
|
+
return rows.length > 0 && rows.every((row) => this.isSelected(row));
|
|
7446
|
+
}, ...(ngDevMode ? [{ debugName: "allPageRowsSelected" }] : /* istanbul ignore next */ []));
|
|
7447
|
+
/** Some but not all — the header checkbox's indeterminate state. */
|
|
7448
|
+
somePageRowsSelected = computed(() => {
|
|
7449
|
+
const rows = this.visibleRows();
|
|
7450
|
+
return rows.some((row) => this.isSelected(row)) && !this.allPageRowsSelected();
|
|
7451
|
+
}, ...(ngDevMode ? [{ debugName: "somePageRowsSelected" }] : /* istanbul ignore next */ []));
|
|
7452
|
+
toggleRowSelection(row, selected) {
|
|
7453
|
+
if (this.selectionMode() === 'single') {
|
|
7454
|
+
this.selection.set(selected ? [row] : []);
|
|
7455
|
+
return;
|
|
7456
|
+
}
|
|
7457
|
+
const key = this.rowKey(row);
|
|
7458
|
+
const without = this.selection().filter((entry) => this.rowKey(entry) !== key);
|
|
7459
|
+
this.selection.set(selected ? [...without, row] : without);
|
|
7460
|
+
}
|
|
7461
|
+
/**
|
|
7462
|
+
* Header checkbox: selects or clears **the current page**, not the whole data set. Anything
|
|
7463
|
+
* else would be a lie in `lazy` mode, where the table has never seen the other pages — and
|
|
7464
|
+
* inconsistent between the two modes, which is worse than either behaviour alone.
|
|
7465
|
+
*/
|
|
7466
|
+
toggleAllOnPage(selected) {
|
|
7467
|
+
const rows = this.visibleRows();
|
|
7468
|
+
const pageKeys = new Set(rows.map((row) => this.rowKey(row)));
|
|
7469
|
+
const offPage = this.selection().filter((entry) => !pageKeys.has(this.rowKey(entry)));
|
|
7470
|
+
this.selection.set(selected ? [...offPage, ...rows] : offPage);
|
|
7471
|
+
}
|
|
7472
|
+
constructor() {
|
|
7473
|
+
/*
|
|
7474
|
+
* `gogPageChange` for user navigation and clamps, but *not* for the reset that follows a new
|
|
7475
|
+
* sort: `currentPage` snapping back to 1 there is part of the sort, and a lazy consumer
|
|
7476
|
+
* refetching from both events would fire two requests for one user action. Detected by the
|
|
7477
|
+
* sort having changed in the same computation, and skipped.
|
|
7478
|
+
*/
|
|
7479
|
+
let previous = null;
|
|
7480
|
+
effect(() => {
|
|
7481
|
+
const page = this.currentPage();
|
|
7482
|
+
const sort = this.sortState();
|
|
7483
|
+
const size = this.pageSize();
|
|
7484
|
+
const causedByOther = previous && (previous.sort !== sort || previous.size !== size);
|
|
7485
|
+
if (previous && previous.page !== page && !causedByOther) {
|
|
7486
|
+
this.gogPageChange.emit(page);
|
|
7487
|
+
}
|
|
7488
|
+
previous = { page, sort, size };
|
|
7489
|
+
});
|
|
7490
|
+
effect(() => {
|
|
7491
|
+
if (!isDevMode() || !this.lazy() || this.pageSize() <= 0)
|
|
7492
|
+
return;
|
|
7493
|
+
if (this.totalRecords() === null) {
|
|
7494
|
+
console.warn("[gog-table] `lazy` with a `pageSize` but no `totalRecords`: the table cannot know how many pages exist, so pagination stays hidden. Pass the server's total row count.");
|
|
7495
|
+
}
|
|
7496
|
+
});
|
|
7497
|
+
}
|
|
6949
7498
|
/**
|
|
6950
7499
|
* A `gogColumnBody` template declared inside the column wins; the string-keyed
|
|
6951
7500
|
* `<ng-template template="field" type="body">` is the deprecated fallback.
|
|
@@ -6968,6 +7517,10 @@ class TableComponent {
|
|
|
6968
7517
|
headerContext(col) {
|
|
6969
7518
|
return { $implicit: col.header(), field: col.field() };
|
|
6970
7519
|
}
|
|
7520
|
+
/**
|
|
7521
|
+
* Cycles the clicked column asc → desc → unsorted, and emits the result. The emit is last, so
|
|
7522
|
+
* a `lazy` consumer refetching from it already sees `currentPage` reset to 1.
|
|
7523
|
+
*/
|
|
6971
7524
|
toggleSort(col) {
|
|
6972
7525
|
if (!col.sortable())
|
|
6973
7526
|
return;
|
|
@@ -6982,6 +7535,20 @@ class TableComponent {
|
|
|
6982
7535
|
else {
|
|
6983
7536
|
this.sortState.set({ field: '', direction: null });
|
|
6984
7537
|
}
|
|
7538
|
+
this.gogSortChange.emit(this.sortState());
|
|
7539
|
+
}
|
|
7540
|
+
/** Click, or Enter/Space on a focused row when `interactiveRows` is on. */
|
|
7541
|
+
emitRowClick(row, index, originalEvent) {
|
|
7542
|
+
this.gogRowClick.emit({ row, index, originalEvent });
|
|
7543
|
+
}
|
|
7544
|
+
/** Enter and Space activate the focused row; Space must not also scroll the page. */
|
|
7545
|
+
onRowKeydown(row, index, event) {
|
|
7546
|
+
if (!this.interactiveRows())
|
|
7547
|
+
return;
|
|
7548
|
+
if (event.key !== 'Enter' && event.key !== ' ')
|
|
7549
|
+
return;
|
|
7550
|
+
event.preventDefault();
|
|
7551
|
+
this.emitRowClick(row, index, event);
|
|
6985
7552
|
}
|
|
6986
7553
|
getSortDirection(field) {
|
|
6987
7554
|
const s = this.sortState();
|
|
@@ -7039,16 +7606,23 @@ class TableComponent {
|
|
|
7039
7606
|
return map;
|
|
7040
7607
|
}, ...(ngDevMode ? [{ debugName: "headerTemplateMap" }] : /* istanbul ignore next */ []));
|
|
7041
7608
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7042
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TableComponent, isStandalone: true, selector: "gog-table", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, showRowNumbers: { classPropertyName: "showRowNumbers", publicName: "showRowNumbers", isSignal: true, isRequired: false, transformFunction: null }, showTotal: { classPropertyName: "showTotal", publicName: "showTotal", isSignal: true, isRequired: false, transformFunction: null }, emptyPlaceholder: { classPropertyName: "emptyPlaceholder", publicName: "emptyPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, paginatorPosition: { classPropertyName: "paginatorPosition", publicName: "paginatorPosition", isSignal: true, isRequired: false, transformFunction: null }, totalPosition: { classPropertyName: "totalPosition", publicName: "totalPosition", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showColumnBorders: { classPropertyName: "showColumnBorders", publicName: "showColumnBorders", isSignal: true, isRequired: false, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.display": "\"block\"", "style.width": "fullWidth() ? \"100%\" : \"fit-content\"" }, classAttribute: "gog-table-host" }, queries: [{ propertyName: "columns", predicate: GogColumn, isSignal: true }, { propertyName: "templates", predicate: TemplateDirective, isSignal: true }], ngImport: i0, template: "<div class=\"gog-table-wrapper gog-contained-layout\">\r\n <gog-scroll axis=\"horizontal\" class=\"gog-table-scroll\">\r\n <table\r\n class=\"gog-table\"\r\n [class]=\"sizeClass()\"\r\n [class.gog-table--col-borders]=\"showColumnBorders()\"\r\n [class.gog-table--loading]=\"loading()\"\r\n [class.gog-table--sticky-header]=\"stickyHeader()\"\r\n [style.width]=\"fullWidth() ? '100%' : 'fit-content'\"\r\n >\r\n <colgroup>\r\n @if (showRowNumbers()) {\r\n <col class=\"gog-table__col--num\" />\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <col\r\n [style.width]=\"col.width() || null\"\r\n [style.min-width]=\"col.minWidth() || null\"\r\n [style.max-width]=\"col.maxWidth() || null\"\r\n />\r\n }\r\n </colgroup>\r\n <thead>\r\n <tr>\r\n @if (showRowNumbers()) {\r\n <th class=\"gog-table__th gog-table__th--num\" scope=\"col\">#</th>\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <th\r\n class=\"gog-table__th\"\r\n scope=\"col\"\r\n [class.gog-table__th--sortable]=\"col.sortable() && !loading()\"\r\n [class.gog-table__th--sorted]=\"getSortDirection(col.field())\"\r\n [attr.aria-sort]=\"getAriaSort(col.field())\"\r\n [attr.tabindex]=\"col.sortable() && !loading() ? 0 : null\"\r\n (click)=\"handleSortClick(col)\"\r\n (keydown.enter)=\"handleSortClick(col)\"\r\n (keydown.space)=\"handleSortClick(col); $event.preventDefault()\"\r\n >\r\n @if (getHeaderTemplate(col); as headerTpl) {\r\n <ng-container *ngTemplateOutlet=\"headerTpl; context: headerContext(col)\" />\r\n } @else {\r\n <span class=\"gog-table__th-inner\">\r\n {{ col.header() || col.field() }}\r\n @if (col.sortable() && !loading()) {\r\n <span class=\"gog-table__sort-icon\" aria-hidden=\"true\">\r\n @if (getSortDirection(col.field()) === 'asc') {\r\n <gog-icon name=\"sort-up\" />\r\n } @else if (getSortDirection(col.field()) === 'desc') {\r\n <gog-icon name=\"sort-down\" />\r\n } @else {\r\n <gog-icon name=\"sort\" />\r\n }\r\n </span>\r\n }\r\n </span>\r\n }\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @if (loading()) {\r\n <tr>\r\n <td class=\"gog-table__loading-cell\" [attr.colspan]=\"emptyColspan()\">\r\n <gog-spinner size=\"md\" />\r\n </td>\r\n </tr>\r\n } @else if (visibleRows().length === 0) {\r\n <tr>\r\n <td class=\"gog-table__empty\" [attr.colspan]=\"emptyColspan()\">\u2014</td>\r\n </tr>\r\n } @else {\r\n @for (row of visibleRows(); track $index; let i = $index) {\r\n <tr class=\"gog-table__row\">\r\n @if (showRowNumbers()) {\r\n <td class=\"gog-table__td gog-table__td--num\">{{ globalRowIndex(i) }}</td>\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <td class=\"gog-table__td\">\r\n @if (getBodyTemplate(col); as bodyTpl) {\r\n <ng-container *ngTemplateOutlet=\"bodyTpl; context: bodyContext(row, col, i)\" />\r\n } @else {\r\n {{ formatCellValue(row, col.field()) }}\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </gog-scroll>\r\n\r\n @if (hasPagination() || showTotal()) {\r\n <div class=\"gog-table__footer\">\r\n @if (showTotal()) {\r\n <span class=\"gog-table__total\" [style.grid-area]=\"totalGridArea()\">\r\n Total: {{ value().length }}\r\n </span>\r\n }\r\n\r\n @if (hasPagination()) {\r\n <gog-paginator\r\n class=\"gog-table__pagination\"\r\n [style.grid-area]=\"paginatorGridArea()\"\r\n [(page)]=\"currentPage\"\r\n [totalPages]=\"totalPages()\"\r\n rangeMode=\"ellipsis\"\r\n size=\"sm\"\r\n ariaLabel=\"Table pagination\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".gog-table-wrapper{display:flex;flex-direction:column;gap:var(--gog-table-gap);width:100%;overflow-anchor:none}.gog-table-scroll{width:100%}.gog-table{width:100%;border-collapse:collapse;border:var(--gog-table-border-width) var(--gog-table-border-style) var(--gog-table-border-color);background-color:var(--gog-table-surface);color:var(--gog-table-text-color);font-family:var(--gog-table-font-family);table-layout:fixed}.gog-table--slg{--gog-table-size-th-padding-v: var(--gog-table-slg-padding-v);--gog-table-size-td-padding-v: var(--gog-table-slg-padding-v);--gog-table-size-th-font-size: var(--gog-table-slg-th-font-size);--gog-table-size-td-font-size: var(--gog-table-slg-td-font-size)}.gog-table--md{--gog-table-size-th-padding-v: var(--gog-table-md-padding-v);--gog-table-size-td-padding-v: var(--gog-table-md-padding-v);--gog-table-size-th-font-size: var(--gog-table-md-th-font-size);--gog-table-size-td-font-size: var(--gog-table-md-td-font-size)}.gog-table--sm{--gog-table-size-th-padding-v: var(--gog-table-sm-padding-v);--gog-table-size-td-padding-v: var(--gog-table-sm-padding-v);--gog-table-size-th-font-size: var(--gog-table-sm-th-font-size);--gog-table-size-td-font-size: var(--gog-table-sm-td-font-size)}.gog-table--xsm{--gog-table-size-th-padding-v: var(--gog-table-xsm-padding-v);--gog-table-size-td-padding-v: var(--gog-table-xsm-padding-v);--gog-table-size-th-font-size: var(--gog-table-xsm-th-font-size);--gog-table-size-td-font-size: var(--gog-table-xsm-td-font-size)}.gog-table__col--num{width:var(--gog-table-num-col-width)}.gog-table__th{padding:var(--gog-table-th-padding-v, var(--gog-table-size-th-padding-v, var(--gog-table-lg-padding-v))) var(--gog-table-padding-h);text-align:left;font-family:var(--gog-table-header-font-family);font-size:var(--gog-table-th-font-size, var(--gog-table-size-th-font-size, var(--gog-table-lg-th-font-size)));text-transform:var(--gog-table-header-text-transform);letter-spacing:var(--gog-table-header-letter-spacing);color:var(--gog-table-accent-color);background-color:var(--gog-table-surface);border-bottom:var(--gog-table-border-width) var(--gog-table-border-style) var(--gog-table-border-color);white-space:normal;overflow:hidden}.gog-table--sticky-header .gog-table__th{position:sticky;top:0;z-index:1}.gog-table__th--num{width:var(--gog-table-num-col-width);text-align:center;color:var(--gog-table-muted-color)}.gog-table__th--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.gog-table__th--sortable:focus-visible{outline:var(--gog-table-focus-ring-width) solid var(--gog-table-focus-ring);outline-offset:calc(var(--gog-table-focus-ring-width) * -1)}.gog-table__th--sortable:hover,.gog-table__th--sorted{color:var(--gog-table-accent-bright)}.gog-table__th-inner{display:inline-flex;align-items:center;gap:var(--gog-table-th-inner-gap);width:100%}.gog-table__sort-icon{display:inline-block;width:var(--gog-table-sort-icon-width);text-align:center;font-size:var(--gog-table-sort-icon-size);opacity:var(--gog-table-sort-icon-opacity);flex-shrink:0}.gog-table__th--sorted .gog-table__sort-icon{opacity:1}.gog-table__td{padding:var(--gog-table-td-padding-v, var(--gog-table-size-td-padding-v, var(--gog-table-lg-padding-v))) var(--gog-table-padding-h);font-size:var(--gog-table-td-font-size, var(--gog-table-size-td-font-size, var(--gog-table-lg-td-font-size)));border-bottom:var(--gog-table-row-border-width) var(--gog-table-border-style) var(--gog-table-border-color);vertical-align:middle;overflow-wrap:break-word;word-break:break-word;overflow:hidden}.gog-table__td--num{text-align:center;color:var(--gog-table-muted-color);font-size:var(--gog-table-num-font-size);font-family:var(--gog-table-numeric-font-family);width:var(--gog-table-num-col-width)}.gog-table__row:last-child .gog-table__td{border-bottom:none}.gog-table__row{transition:background-color var(--gog-table-row-transition-duration) var(--gog-easing)}.gog-table__row:hover{background-color:var(--gog-table-hover-bg)}.gog-table__empty{padding:var(--gog-table-empty-padding);text-align:center;color:var(--gog-table-muted-color);font-size:var(--gog-table-empty-font-size)}.gog-table--loading thead{opacity:var(--gog-table-loading-opacity);pointer-events:none}.gog-table__loading-cell{padding:var(--gog-table-loading-padding);text-align:center}.gog-table--col-borders .gog-table__th:not(:last-child),.gog-table--col-borders .gog-table__td:not(:last-child){border-right:var(--gog-table-row-border-width) var(--gog-table-border-style) var(--gog-table-border-color)}.gog-table__footer{display:grid;grid-template-columns:1fr auto 1fr;grid-template-areas:\"left center right\";align-items:center;min-height:var(--gog-table-footer-min-height);gap:var(--gog-table-footer-gap)}.gog-table__total{font-size:var(--gog-table-total-font-size);color:var(--gog-table-muted-color);font-family:var(--gog-table-numeric-font-family);text-transform:var(--gog-table-total-text-transform);letter-spacing:var(--gog-table-total-letter-spacing)}.gog-table__total[style*=\"grid-area: right\"]{text-align:right}.gog-table__pagination[style*=\"grid-area: left\"]{justify-content:flex-start}.gog-table__pagination[style*=\"grid-area: center\"]{justify-content:center}.gog-table__pagination[style*=\"grid-area: right\"]{justify-content:flex-end}@media(prefers-reduced-motion:reduce){.gog-table__row{transition:none}}\n"], dependencies: [{ kind: "component", type: SpinnerComponent, selector: "gog-spinner", inputs: ["size", "overlay", "ariaLabel", "variant"] }, { kind: "component", type: PaginatorComponent, selector: "gog-paginator", inputs: ["page", "fullWidth", "totalPages", "rangeMode", "visiblePages", "showFirstPage", "showLastPage", "siblingCount", "size", "disabled", "ariaLabel"], outputs: ["pageChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "gog-icon", inputs: ["name", "template", "title", "ariaHidden"] }, { kind: "component", type: ScrollComponent, selector: "gog-scroll", inputs: ["axis", "size", "autoHide", "hideDelay", "reachThreshold", "focusable", "ariaLabel", "overscrollBehavior", "showTrack"], outputs: ["gogScroll", "gogReachStart", "gogReachEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7609
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TableComponent, isStandalone: true, selector: "gog-table", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, showPageSizeSelect: { classPropertyName: "showPageSizeSelect", publicName: "showPageSizeSelect", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null }, totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: false, transformFunction: null }, interactiveRows: { classPropertyName: "interactiveRows", publicName: "interactiveRows", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, showSelectionColumn: { classPropertyName: "showSelectionColumn", publicName: "showSelectionColumn", isSignal: true, isRequired: false, transformFunction: null }, showRowNumbers: { classPropertyName: "showRowNumbers", publicName: "showRowNumbers", isSignal: true, isRequired: false, transformFunction: null }, showTotal: { classPropertyName: "showTotal", publicName: "showTotal", isSignal: true, isRequired: false, transformFunction: null }, emptyPlaceholder: { classPropertyName: "emptyPlaceholder", publicName: "emptyPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, paginatorPosition: { classPropertyName: "paginatorPosition", publicName: "paginatorPosition", isSignal: true, isRequired: false, transformFunction: null }, totalPosition: { classPropertyName: "totalPosition", publicName: "totalPosition", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showColumnBorders: { classPropertyName: "showColumnBorders", publicName: "showColumnBorders", isSignal: true, isRequired: false, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageSize: "pageSizeChange", selection: "selectionChange", gogSortChange: "gogSortChange", gogPageChange: "gogPageChange", gogRowClick: "gogRowClick" }, host: { properties: { "style.display": "\"block\"", "style.width": "fullWidth() ? \"100%\" : \"fit-content\"" }, classAttribute: "gog-table-host" }, queries: [{ propertyName: "columns", predicate: GogColumn, isSignal: true }, { propertyName: "templates", predicate: TemplateDirective, isSignal: true }], ngImport: i0, template: "<div class=\"gog-table-wrapper gog-contained-layout\">\r\n <gog-scroll axis=\"horizontal\" class=\"gog-table-scroll\">\r\n <table\r\n class=\"gog-table\"\r\n [class]=\"sizeClass()\"\r\n [class.gog-table--col-borders]=\"showColumnBorders()\"\r\n [class.gog-table--loading]=\"loading()\"\r\n [class.gog-table--sticky-header]=\"stickyHeader()\"\r\n [style.width]=\"fullWidth() ? '100%' : 'fit-content'\"\r\n >\r\n <colgroup>\r\n @if (hasSelectionColumn()) {\r\n <col class=\"gog-table__col--select\" />\r\n }\r\n @if (showRowNumbers()) {\r\n <col class=\"gog-table__col--num\" />\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <col\r\n [style.width]=\"col.width() || null\"\r\n [style.min-width]=\"col.minWidth() || null\"\r\n [style.max-width]=\"col.maxWidth() || null\"\r\n />\r\n }\r\n </colgroup>\r\n <thead>\r\n <tr>\r\n @if (hasSelectionColumn()) {\r\n <th class=\"gog-table__th gog-table__th--select\" scope=\"col\">\r\n <!--\r\n Only `multiple` gets a select-all: in `single` mode there is nothing to select\r\n all of, and a checkbox that can only ever check one row is a lie.\r\n -->\r\n @if (selectionMode() === 'multiple') {\r\n <gog-checkbox\r\n [checked]=\"allPageRowsSelected()\"\r\n [indeterminate]=\"somePageRowsSelected()\"\r\n [disabled]=\"loading() || visibleRows().length === 0\"\r\n [ariaLabel]=\"resolvedLabels().selectAllRows\"\r\n (checkedChange)=\"toggleAllOnPage($event)\"\r\n />\r\n }\r\n </th>\r\n }\r\n @if (showRowNumbers()) {\r\n <th class=\"gog-table__th gog-table__th--num\" scope=\"col\">#</th>\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <th\r\n class=\"gog-table__th\"\r\n scope=\"col\"\r\n [class.gog-table__th--sortable]=\"col.sortable() && !loading()\"\r\n [class.gog-table__th--sorted]=\"getSortDirection(col.field())\"\r\n [attr.aria-sort]=\"getAriaSort(col.field())\"\r\n [attr.tabindex]=\"col.sortable() && !loading() ? 0 : null\"\r\n (click)=\"handleSortClick(col)\"\r\n (keydown.enter)=\"handleSortClick(col)\"\r\n (keydown.space)=\"handleSortClick(col); $event.preventDefault()\"\r\n >\r\n @if (getHeaderTemplate(col); as headerTpl) {\r\n <ng-container *ngTemplateOutlet=\"headerTpl; context: headerContext(col)\" />\r\n } @else {\r\n <span class=\"gog-table__th-inner\">\r\n {{ col.header() || col.field() }}\r\n @if (col.sortable() && !loading()) {\r\n <span class=\"gog-table__sort-icon\" aria-hidden=\"true\">\r\n @if (getSortDirection(col.field()) === 'asc') {\r\n <gog-icon name=\"sort-up\" />\r\n } @else if (getSortDirection(col.field()) === 'desc') {\r\n <gog-icon name=\"sort-down\" />\r\n } @else {\r\n <gog-icon name=\"sort\" />\r\n }\r\n </span>\r\n }\r\n </span>\r\n }\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @if (loading()) {\r\n <tr>\r\n <td class=\"gog-table__loading-cell\" [attr.colspan]=\"emptyColspan()\">\r\n <gog-spinner size=\"md\" />\r\n </td>\r\n </tr>\r\n } @else if (visibleRows().length === 0) {\r\n <tr>\r\n <td class=\"gog-table__empty\" [attr.colspan]=\"emptyColspan()\">\u2014</td>\r\n </tr>\r\n } @else {\r\n @for (row of visibleRows(); track rowKey(row); let i = $index) {\r\n <tr\r\n class=\"gog-table__row\"\r\n [class.gog-table__row--interactive]=\"interactiveRows()\"\r\n [class.gog-table__row--selected]=\"isSelected(row)\"\r\n [attr.tabindex]=\"interactiveRows() ? 0 : null\"\r\n [attr.aria-selected]=\"hasSelection() ? isSelected(row) : null\"\r\n (click)=\"emitRowClick(row, i, $event)\"\r\n (keydown)=\"onRowKeydown(row, i, $event)\"\r\n >\r\n @if (hasSelectionColumn()) {\r\n <td class=\"gog-table__td gog-table__td--select\">\r\n <!--\r\n `$event.stopPropagation()` so ticking the box does not also count as a row\r\n click: with `interactiveRows` those are two different intents, and firing both\r\n from one gesture is how a \"select\" ends up navigating away.\r\n -->\r\n <gog-checkbox\r\n [checked]=\"isSelected(row)\"\r\n [ariaLabel]=\"resolvedLabels().selectRow\"\r\n (click)=\"$event.stopPropagation()\"\r\n (checkedChange)=\"toggleRowSelection(row, $event)\"\r\n />\r\n </td>\r\n }\r\n @if (showRowNumbers()) {\r\n <td class=\"gog-table__td gog-table__td--num\">{{ globalRowIndex(i) }}</td>\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <td class=\"gog-table__td\">\r\n @if (getBodyTemplate(col); as bodyTpl) {\r\n <ng-container *ngTemplateOutlet=\"bodyTpl; context: bodyContext(row, col, i)\" />\r\n } @else {\r\n {{ formatCellValue(row, col.field()) }}\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </gog-scroll>\r\n\r\n @if (hasPagination() || showTotal()) {\r\n <div class=\"gog-table__footer\">\r\n @if (showTotal()) {\r\n <span class=\"gog-table__total\" [style.grid-area]=\"totalGridArea()\">\r\n {{ resolvedLabels().total }}: {{ rowCount() }}\r\n </span>\r\n }\r\n\r\n @if (hasPagination()) {\r\n <!--\r\n `[(pageSize)]` straight through to the table's own model: the rows-per-page select\r\n writes back here, and a consumer binding `[(pageSize)]` on the table sees it. No\r\n intermediate signal, in either direction.\r\n -->\r\n <gog-paginator\r\n class=\"gog-table__pagination\"\r\n [style.grid-area]=\"paginatorGridArea()\"\r\n [(page)]=\"currentPage\"\r\n [(pageSize)]=\"pageSize\"\r\n [totalPages]=\"totalPages()\"\r\n [showPageSizeSelect]=\"showPageSizeSelect()\"\r\n [pageSizeOptions]=\"pageSizeOptions()\"\r\n rangeMode=\"ellipsis\"\r\n size=\"sm\"\r\n [ariaLabel]=\"resolvedLabels().pagination\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.gog-table-wrapper{display:flex;flex-direction:column;gap:var(--gog-table-gap);width:100%;overflow-anchor:none}.gog-table-scroll{width:100%}.gog-table{width:100%;border-collapse:collapse;border:var(--gog-table-border-width) var(--gog-table-border-style) var(--gog-table-border-color);background-color:var(--gog-table-surface);color:var(--gog-table-text-color);font-family:var(--gog-table-font-family);table-layout:fixed}.gog-table--slg{--gog-table-size-th-padding-v: var(--gog-table-slg-padding-v);--gog-table-size-td-padding-v: var(--gog-table-slg-padding-v);--gog-table-size-th-font-size: var(--gog-table-slg-th-font-size);--gog-table-size-td-font-size: var(--gog-table-slg-td-font-size)}.gog-table--md{--gog-table-size-th-padding-v: var(--gog-table-md-padding-v);--gog-table-size-td-padding-v: var(--gog-table-md-padding-v);--gog-table-size-th-font-size: var(--gog-table-md-th-font-size);--gog-table-size-td-font-size: var(--gog-table-md-td-font-size)}.gog-table--sm{--gog-table-size-th-padding-v: var(--gog-table-sm-padding-v);--gog-table-size-td-padding-v: var(--gog-table-sm-padding-v);--gog-table-size-th-font-size: var(--gog-table-sm-th-font-size);--gog-table-size-td-font-size: var(--gog-table-sm-td-font-size)}.gog-table--xsm{--gog-table-size-th-padding-v: var(--gog-table-xsm-padding-v);--gog-table-size-td-padding-v: var(--gog-table-xsm-padding-v);--gog-table-size-th-font-size: var(--gog-table-xsm-th-font-size);--gog-table-size-td-font-size: var(--gog-table-xsm-td-font-size)}.gog-table__col--num{width:var(--gog-table-num-col-width)}.gog-table__th{padding:var(--gog-table-th-padding-v, var(--gog-table-size-th-padding-v, var(--gog-table-lg-padding-v))) var(--gog-table-padding-h);text-align:left;font-family:var(--gog-table-header-font-family);font-size:var(--gog-table-th-font-size, var(--gog-table-size-th-font-size, var(--gog-table-lg-th-font-size)));text-transform:var(--gog-table-header-text-transform);letter-spacing:var(--gog-table-header-letter-spacing);color:var(--gog-table-accent-color);background-color:var(--gog-table-surface);border-bottom:var(--gog-table-border-width) var(--gog-table-border-style) var(--gog-table-border-color);white-space:normal;overflow:hidden}.gog-table--sticky-header .gog-table__th{position:sticky;top:0;z-index:1}.gog-table__th--num{width:var(--gog-table-num-col-width);text-align:center;color:var(--gog-table-muted-color)}.gog-table__th--select,.gog-table__td--select{width:var(--gog-table-select-col-width);text-align:center}.gog-table__th--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.gog-table__th--sortable:focus-visible{outline:var(--gog-table-focus-ring-width) solid var(--gog-table-focus-ring);outline-offset:calc(var(--gog-table-focus-ring-width) * -1)}.gog-table__th--sortable:hover,.gog-table__th--sorted{color:var(--gog-table-accent-bright)}.gog-table__th-inner{display:inline-flex;align-items:center;gap:var(--gog-table-th-inner-gap);width:100%}.gog-table__sort-icon{display:inline-block;width:var(--gog-table-sort-icon-width);text-align:center;font-size:var(--gog-table-sort-icon-size);opacity:var(--gog-table-sort-icon-opacity);flex-shrink:0}.gog-table__th--sorted .gog-table__sort-icon{opacity:1}.gog-table__td{padding:var(--gog-table-td-padding-v, var(--gog-table-size-td-padding-v, var(--gog-table-lg-padding-v))) var(--gog-table-padding-h);font-size:var(--gog-table-td-font-size, var(--gog-table-size-td-font-size, var(--gog-table-lg-td-font-size)));border-bottom:var(--gog-table-row-border-width) var(--gog-table-border-style) var(--gog-table-border-color);vertical-align:middle;overflow-wrap:break-word;word-break:break-word;overflow:hidden}.gog-table__td--num{text-align:center;color:var(--gog-table-muted-color);font-size:var(--gog-table-num-font-size);font-family:var(--gog-table-numeric-font-family);width:var(--gog-table-num-col-width)}.gog-table__row:last-child .gog-table__td{border-bottom:none}.gog-table__row{transition:background-color var(--gog-table-row-transition-duration) var(--gog-easing)}.gog-table__row--interactive{cursor:pointer}.gog-table__row--interactive:focus-visible{outline:var(--gog-table-focus-ring-width) solid var(--gog-table-focus-ring);outline-offset:calc(var(--gog-table-focus-ring-width) * -1)}.gog-table__row:hover{background-color:var(--gog-table-hover-bg)}.gog-table__row--selected,.gog-table__row--selected:hover{background-color:var(--gog-table-selected-bg)}.gog-table__empty{padding:var(--gog-table-empty-padding);text-align:center;color:var(--gog-table-muted-color);font-size:var(--gog-table-empty-font-size)}.gog-table--loading thead{opacity:var(--gog-table-loading-opacity);pointer-events:none}.gog-table__loading-cell{padding:var(--gog-table-loading-padding);text-align:center}.gog-table--col-borders .gog-table__th:not(:last-child),.gog-table--col-borders .gog-table__td:not(:last-child){border-right:var(--gog-table-row-border-width) var(--gog-table-border-style) var(--gog-table-border-color)}.gog-table__footer{display:grid;grid-template-columns:1fr auto 1fr;grid-template-areas:\"left center right\";align-items:center;min-height:var(--gog-table-footer-min-height);gap:var(--gog-table-footer-gap)}.gog-table__total{font-size:var(--gog-table-total-font-size);color:var(--gog-table-muted-color);font-family:var(--gog-table-numeric-font-family);text-transform:var(--gog-table-total-text-transform);letter-spacing:var(--gog-table-total-letter-spacing)}.gog-table__total[style*=\"grid-area: right\"]{text-align:right}.gog-table__pagination[style*=\"grid-area: left\"]{justify-content:flex-start}.gog-table__pagination[style*=\"grid-area: center\"]{justify-content:center}.gog-table__pagination[style*=\"grid-area: right\"]{justify-content:flex-end}@media(prefers-reduced-motion:reduce){.gog-table__row{transition:none}}\n"], dependencies: [{ kind: "component", type: SpinnerComponent, selector: "gog-spinner", inputs: ["size", "overlay", "ariaLabel", "variant"] }, { kind: "component", type: PaginatorComponent, selector: "gog-paginator", inputs: ["page", "fullWidth", "totalPages", "totalRecords", "pageSize", "showPageSizeSelect", "pageSizeOptions", "rangeMode", "visiblePages", "showFirstPage", "showLastPage", "siblingCount", "size", "disabled", "ariaLabel"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "gog-icon", inputs: ["name", "template", "title", "ariaHidden"] }, { kind: "component", type: ScrollComponent, selector: "gog-scroll", inputs: ["axis", "size", "autoHide", "hideDelay", "reachThreshold", "focusable", "ariaLabel", "overscrollBehavior", "showTrack"], outputs: ["gogScroll", "gogReachStart", "gogReachEnd"] }, { kind: "component", type: CheckboxComponent, selector: "gog-checkbox", inputs: ["label", "ariaLabel", "size", "indeterminate", "disabled", "fullWidth", "checkIconTemplate", "checked"], outputs: ["checkedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7043
7610
|
}
|
|
7044
7611
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableComponent, decorators: [{
|
|
7045
7612
|
type: Component,
|
|
7046
|
-
args: [{ selector: 'gog-table', imports: [
|
|
7613
|
+
args: [{ selector: 'gog-table', imports: [
|
|
7614
|
+
SpinnerComponent,
|
|
7615
|
+
PaginatorComponent,
|
|
7616
|
+
NgTemplateOutlet,
|
|
7617
|
+
IconComponent,
|
|
7618
|
+
ScrollComponent,
|
|
7619
|
+
CheckboxComponent,
|
|
7620
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
7047
7621
|
class: 'gog-table-host',
|
|
7048
7622
|
'[style.display]': '"block"',
|
|
7049
7623
|
'[style.width]': 'fullWidth() ? "100%" : "fit-content"',
|
|
7050
|
-
}, template: "<div class=\"gog-table-wrapper gog-contained-layout\">\r\n <gog-scroll axis=\"horizontal\" class=\"gog-table-scroll\">\r\n <table\r\n class=\"gog-table\"\r\n [class]=\"sizeClass()\"\r\n [class.gog-table--col-borders]=\"showColumnBorders()\"\r\n [class.gog-table--loading]=\"loading()\"\r\n [class.gog-table--sticky-header]=\"stickyHeader()\"\r\n [style.width]=\"fullWidth() ? '100%' : 'fit-content'\"\r\n >\r\n <colgroup>\r\n @if (showRowNumbers()) {\r\n <col class=\"gog-table__col--num\" />\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <col\r\n [style.width]=\"col.width() || null\"\r\n [style.min-width]=\"col.minWidth() || null\"\r\n [style.max-width]=\"col.maxWidth() || null\"\r\n />\r\n }\r\n </colgroup>\r\n <thead>\r\n <tr>\r\n @if (showRowNumbers()) {\r\n <th class=\"gog-table__th gog-table__th--num\" scope=\"col\">#</th>\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <th\r\n class=\"gog-table__th\"\r\n scope=\"col\"\r\n [class.gog-table__th--sortable]=\"col.sortable() && !loading()\"\r\n [class.gog-table__th--sorted]=\"getSortDirection(col.field())\"\r\n [attr.aria-sort]=\"getAriaSort(col.field())\"\r\n [attr.tabindex]=\"col.sortable() && !loading() ? 0 : null\"\r\n (click)=\"handleSortClick(col)\"\r\n (keydown.enter)=\"handleSortClick(col)\"\r\n (keydown.space)=\"handleSortClick(col); $event.preventDefault()\"\r\n >\r\n @if (getHeaderTemplate(col); as headerTpl) {\r\n <ng-container *ngTemplateOutlet=\"headerTpl; context: headerContext(col)\" />\r\n } @else {\r\n <span class=\"gog-table__th-inner\">\r\n {{ col.header() || col.field() }}\r\n @if (col.sortable() && !loading()) {\r\n <span class=\"gog-table__sort-icon\" aria-hidden=\"true\">\r\n @if (getSortDirection(col.field()) === 'asc') {\r\n <gog-icon name=\"sort-up\" />\r\n } @else if (getSortDirection(col.field()) === 'desc') {\r\n <gog-icon name=\"sort-down\" />\r\n } @else {\r\n <gog-icon name=\"sort\" />\r\n }\r\n </span>\r\n }\r\n </span>\r\n }\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @if (loading()) {\r\n <tr>\r\n <td class=\"gog-table__loading-cell\" [attr.colspan]=\"emptyColspan()\">\r\n <gog-spinner size=\"md\" />\r\n </td>\r\n </tr>\r\n } @else if (visibleRows().length === 0) {\r\n <tr>\r\n <td class=\"gog-table__empty\" [attr.colspan]=\"emptyColspan()\">\u2014</td>\r\n </tr>\r\n } @else {\r\n @for (row of visibleRows(); track $index; let i = $index) {\r\n <tr class=\"gog-table__row\">\r\n @if (showRowNumbers()) {\r\n <td class=\"gog-table__td gog-table__td--num\">{{ globalRowIndex(i) }}</td>\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <td class=\"gog-table__td\">\r\n @if (getBodyTemplate(col); as bodyTpl) {\r\n <ng-container *ngTemplateOutlet=\"bodyTpl; context: bodyContext(row, col, i)\" />\r\n } @else {\r\n {{ formatCellValue(row, col.field()) }}\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </gog-scroll>\r\n\r\n @if (hasPagination() || showTotal()) {\r\n <div class=\"gog-table__footer\">\r\n @if (showTotal()) {\r\n <span class=\"gog-table__total\" [style.grid-area]=\"totalGridArea()\">\r\n Total: {{ value().length }}\r\n </span>\r\n }\r\n\r\n @if (hasPagination()) {\r\n <gog-paginator\r\n class=\"gog-table__pagination\"\r\n [style.grid-area]=\"paginatorGridArea()\"\r\n [(page)]=\"currentPage\"\r\n [totalPages]=\"totalPages()\"\r\n rangeMode=\"ellipsis\"\r\n size=\"sm\"\r\n ariaLabel=\"Table pagination\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".gog-table-wrapper{display:flex;flex-direction:column;gap:var(--gog-table-gap);width:100%;overflow-anchor:none}.gog-table-scroll{width:100%}.gog-table{width:100%;border-collapse:collapse;border:var(--gog-table-border-width) var(--gog-table-border-style) var(--gog-table-border-color);background-color:var(--gog-table-surface);color:var(--gog-table-text-color);font-family:var(--gog-table-font-family);table-layout:fixed}.gog-table--slg{--gog-table-size-th-padding-v: var(--gog-table-slg-padding-v);--gog-table-size-td-padding-v: var(--gog-table-slg-padding-v);--gog-table-size-th-font-size: var(--gog-table-slg-th-font-size);--gog-table-size-td-font-size: var(--gog-table-slg-td-font-size)}.gog-table--md{--gog-table-size-th-padding-v: var(--gog-table-md-padding-v);--gog-table-size-td-padding-v: var(--gog-table-md-padding-v);--gog-table-size-th-font-size: var(--gog-table-md-th-font-size);--gog-table-size-td-font-size: var(--gog-table-md-td-font-size)}.gog-table--sm{--gog-table-size-th-padding-v: var(--gog-table-sm-padding-v);--gog-table-size-td-padding-v: var(--gog-table-sm-padding-v);--gog-table-size-th-font-size: var(--gog-table-sm-th-font-size);--gog-table-size-td-font-size: var(--gog-table-sm-td-font-size)}.gog-table--xsm{--gog-table-size-th-padding-v: var(--gog-table-xsm-padding-v);--gog-table-size-td-padding-v: var(--gog-table-xsm-padding-v);--gog-table-size-th-font-size: var(--gog-table-xsm-th-font-size);--gog-table-size-td-font-size: var(--gog-table-xsm-td-font-size)}.gog-table__col--num{width:var(--gog-table-num-col-width)}.gog-table__th{padding:var(--gog-table-th-padding-v, var(--gog-table-size-th-padding-v, var(--gog-table-lg-padding-v))) var(--gog-table-padding-h);text-align:left;font-family:var(--gog-table-header-font-family);font-size:var(--gog-table-th-font-size, var(--gog-table-size-th-font-size, var(--gog-table-lg-th-font-size)));text-transform:var(--gog-table-header-text-transform);letter-spacing:var(--gog-table-header-letter-spacing);color:var(--gog-table-accent-color);background-color:var(--gog-table-surface);border-bottom:var(--gog-table-border-width) var(--gog-table-border-style) var(--gog-table-border-color);white-space:normal;overflow:hidden}.gog-table--sticky-header .gog-table__th{position:sticky;top:0;z-index:1}.gog-table__th--num{width:var(--gog-table-num-col-width);text-align:center;color:var(--gog-table-muted-color)}.gog-table__th--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.gog-table__th--sortable:focus-visible{outline:var(--gog-table-focus-ring-width) solid var(--gog-table-focus-ring);outline-offset:calc(var(--gog-table-focus-ring-width) * -1)}.gog-table__th--sortable:hover,.gog-table__th--sorted{color:var(--gog-table-accent-bright)}.gog-table__th-inner{display:inline-flex;align-items:center;gap:var(--gog-table-th-inner-gap);width:100%}.gog-table__sort-icon{display:inline-block;width:var(--gog-table-sort-icon-width);text-align:center;font-size:var(--gog-table-sort-icon-size);opacity:var(--gog-table-sort-icon-opacity);flex-shrink:0}.gog-table__th--sorted .gog-table__sort-icon{opacity:1}.gog-table__td{padding:var(--gog-table-td-padding-v, var(--gog-table-size-td-padding-v, var(--gog-table-lg-padding-v))) var(--gog-table-padding-h);font-size:var(--gog-table-td-font-size, var(--gog-table-size-td-font-size, var(--gog-table-lg-td-font-size)));border-bottom:var(--gog-table-row-border-width) var(--gog-table-border-style) var(--gog-table-border-color);vertical-align:middle;overflow-wrap:break-word;word-break:break-word;overflow:hidden}.gog-table__td--num{text-align:center;color:var(--gog-table-muted-color);font-size:var(--gog-table-num-font-size);font-family:var(--gog-table-numeric-font-family);width:var(--gog-table-num-col-width)}.gog-table__row:last-child .gog-table__td{border-bottom:none}.gog-table__row{transition:background-color var(--gog-table-row-transition-duration) var(--gog-easing)}.gog-table__row:hover{background-color:var(--gog-table-hover-bg)}.gog-table__empty{padding:var(--gog-table-empty-padding);text-align:center;color:var(--gog-table-muted-color);font-size:var(--gog-table-empty-font-size)}.gog-table--loading thead{opacity:var(--gog-table-loading-opacity);pointer-events:none}.gog-table__loading-cell{padding:var(--gog-table-loading-padding);text-align:center}.gog-table--col-borders .gog-table__th:not(:last-child),.gog-table--col-borders .gog-table__td:not(:last-child){border-right:var(--gog-table-row-border-width) var(--gog-table-border-style) var(--gog-table-border-color)}.gog-table__footer{display:grid;grid-template-columns:1fr auto 1fr;grid-template-areas:\"left center right\";align-items:center;min-height:var(--gog-table-footer-min-height);gap:var(--gog-table-footer-gap)}.gog-table__total{font-size:var(--gog-table-total-font-size);color:var(--gog-table-muted-color);font-family:var(--gog-table-numeric-font-family);text-transform:var(--gog-table-total-text-transform);letter-spacing:var(--gog-table-total-letter-spacing)}.gog-table__total[style*=\"grid-area: right\"]{text-align:right}.gog-table__pagination[style*=\"grid-area: left\"]{justify-content:flex-start}.gog-table__pagination[style*=\"grid-area: center\"]{justify-content:center}.gog-table__pagination[style*=\"grid-area: right\"]{justify-content:flex-end}@media(prefers-reduced-motion:reduce){.gog-table__row{transition:none}}\n"] }]
|
|
7051
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], showRowNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRowNumbers", required: false }] }], showTotal: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTotal", required: false }] }], emptyPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyPlaceholder", required: false }] }], paginatorPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginatorPosition", required: false }] }], totalPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPosition", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showColumnBorders: [{ type: i0.Input, args: [{ isSignal: true, alias: "showColumnBorders", required: false }] }], stickyHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyHeader", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], columns: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => GogColumn), { isSignal: true }] }], templates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TemplateDirective), { isSignal: true }] }] } });
|
|
7624
|
+
}, template: "<div class=\"gog-table-wrapper gog-contained-layout\">\r\n <gog-scroll axis=\"horizontal\" class=\"gog-table-scroll\">\r\n <table\r\n class=\"gog-table\"\r\n [class]=\"sizeClass()\"\r\n [class.gog-table--col-borders]=\"showColumnBorders()\"\r\n [class.gog-table--loading]=\"loading()\"\r\n [class.gog-table--sticky-header]=\"stickyHeader()\"\r\n [style.width]=\"fullWidth() ? '100%' : 'fit-content'\"\r\n >\r\n <colgroup>\r\n @if (hasSelectionColumn()) {\r\n <col class=\"gog-table__col--select\" />\r\n }\r\n @if (showRowNumbers()) {\r\n <col class=\"gog-table__col--num\" />\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <col\r\n [style.width]=\"col.width() || null\"\r\n [style.min-width]=\"col.minWidth() || null\"\r\n [style.max-width]=\"col.maxWidth() || null\"\r\n />\r\n }\r\n </colgroup>\r\n <thead>\r\n <tr>\r\n @if (hasSelectionColumn()) {\r\n <th class=\"gog-table__th gog-table__th--select\" scope=\"col\">\r\n <!--\r\n Only `multiple` gets a select-all: in `single` mode there is nothing to select\r\n all of, and a checkbox that can only ever check one row is a lie.\r\n -->\r\n @if (selectionMode() === 'multiple') {\r\n <gog-checkbox\r\n [checked]=\"allPageRowsSelected()\"\r\n [indeterminate]=\"somePageRowsSelected()\"\r\n [disabled]=\"loading() || visibleRows().length === 0\"\r\n [ariaLabel]=\"resolvedLabels().selectAllRows\"\r\n (checkedChange)=\"toggleAllOnPage($event)\"\r\n />\r\n }\r\n </th>\r\n }\r\n @if (showRowNumbers()) {\r\n <th class=\"gog-table__th gog-table__th--num\" scope=\"col\">#</th>\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <th\r\n class=\"gog-table__th\"\r\n scope=\"col\"\r\n [class.gog-table__th--sortable]=\"col.sortable() && !loading()\"\r\n [class.gog-table__th--sorted]=\"getSortDirection(col.field())\"\r\n [attr.aria-sort]=\"getAriaSort(col.field())\"\r\n [attr.tabindex]=\"col.sortable() && !loading() ? 0 : null\"\r\n (click)=\"handleSortClick(col)\"\r\n (keydown.enter)=\"handleSortClick(col)\"\r\n (keydown.space)=\"handleSortClick(col); $event.preventDefault()\"\r\n >\r\n @if (getHeaderTemplate(col); as headerTpl) {\r\n <ng-container *ngTemplateOutlet=\"headerTpl; context: headerContext(col)\" />\r\n } @else {\r\n <span class=\"gog-table__th-inner\">\r\n {{ col.header() || col.field() }}\r\n @if (col.sortable() && !loading()) {\r\n <span class=\"gog-table__sort-icon\" aria-hidden=\"true\">\r\n @if (getSortDirection(col.field()) === 'asc') {\r\n <gog-icon name=\"sort-up\" />\r\n } @else if (getSortDirection(col.field()) === 'desc') {\r\n <gog-icon name=\"sort-down\" />\r\n } @else {\r\n <gog-icon name=\"sort\" />\r\n }\r\n </span>\r\n }\r\n </span>\r\n }\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @if (loading()) {\r\n <tr>\r\n <td class=\"gog-table__loading-cell\" [attr.colspan]=\"emptyColspan()\">\r\n <gog-spinner size=\"md\" />\r\n </td>\r\n </tr>\r\n } @else if (visibleRows().length === 0) {\r\n <tr>\r\n <td class=\"gog-table__empty\" [attr.colspan]=\"emptyColspan()\">\u2014</td>\r\n </tr>\r\n } @else {\r\n @for (row of visibleRows(); track rowKey(row); let i = $index) {\r\n <tr\r\n class=\"gog-table__row\"\r\n [class.gog-table__row--interactive]=\"interactiveRows()\"\r\n [class.gog-table__row--selected]=\"isSelected(row)\"\r\n [attr.tabindex]=\"interactiveRows() ? 0 : null\"\r\n [attr.aria-selected]=\"hasSelection() ? isSelected(row) : null\"\r\n (click)=\"emitRowClick(row, i, $event)\"\r\n (keydown)=\"onRowKeydown(row, i, $event)\"\r\n >\r\n @if (hasSelectionColumn()) {\r\n <td class=\"gog-table__td gog-table__td--select\">\r\n <!--\r\n `$event.stopPropagation()` so ticking the box does not also count as a row\r\n click: with `interactiveRows` those are two different intents, and firing both\r\n from one gesture is how a \"select\" ends up navigating away.\r\n -->\r\n <gog-checkbox\r\n [checked]=\"isSelected(row)\"\r\n [ariaLabel]=\"resolvedLabels().selectRow\"\r\n (click)=\"$event.stopPropagation()\"\r\n (checkedChange)=\"toggleRowSelection(row, $event)\"\r\n />\r\n </td>\r\n }\r\n @if (showRowNumbers()) {\r\n <td class=\"gog-table__td gog-table__td--num\">{{ globalRowIndex(i) }}</td>\r\n }\r\n @for (col of columns(); track col.field()) {\r\n <td class=\"gog-table__td\">\r\n @if (getBodyTemplate(col); as bodyTpl) {\r\n <ng-container *ngTemplateOutlet=\"bodyTpl; context: bodyContext(row, col, i)\" />\r\n } @else {\r\n {{ formatCellValue(row, col.field()) }}\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </gog-scroll>\r\n\r\n @if (hasPagination() || showTotal()) {\r\n <div class=\"gog-table__footer\">\r\n @if (showTotal()) {\r\n <span class=\"gog-table__total\" [style.grid-area]=\"totalGridArea()\">\r\n {{ resolvedLabels().total }}: {{ rowCount() }}\r\n </span>\r\n }\r\n\r\n @if (hasPagination()) {\r\n <!--\r\n `[(pageSize)]` straight through to the table's own model: the rows-per-page select\r\n writes back here, and a consumer binding `[(pageSize)]` on the table sees it. No\r\n intermediate signal, in either direction.\r\n -->\r\n <gog-paginator\r\n class=\"gog-table__pagination\"\r\n [style.grid-area]=\"paginatorGridArea()\"\r\n [(page)]=\"currentPage\"\r\n [(pageSize)]=\"pageSize\"\r\n [totalPages]=\"totalPages()\"\r\n [showPageSizeSelect]=\"showPageSizeSelect()\"\r\n [pageSizeOptions]=\"pageSizeOptions()\"\r\n rangeMode=\"ellipsis\"\r\n size=\"sm\"\r\n [ariaLabel]=\"resolvedLabels().pagination\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.gog-table-wrapper{display:flex;flex-direction:column;gap:var(--gog-table-gap);width:100%;overflow-anchor:none}.gog-table-scroll{width:100%}.gog-table{width:100%;border-collapse:collapse;border:var(--gog-table-border-width) var(--gog-table-border-style) var(--gog-table-border-color);background-color:var(--gog-table-surface);color:var(--gog-table-text-color);font-family:var(--gog-table-font-family);table-layout:fixed}.gog-table--slg{--gog-table-size-th-padding-v: var(--gog-table-slg-padding-v);--gog-table-size-td-padding-v: var(--gog-table-slg-padding-v);--gog-table-size-th-font-size: var(--gog-table-slg-th-font-size);--gog-table-size-td-font-size: var(--gog-table-slg-td-font-size)}.gog-table--md{--gog-table-size-th-padding-v: var(--gog-table-md-padding-v);--gog-table-size-td-padding-v: var(--gog-table-md-padding-v);--gog-table-size-th-font-size: var(--gog-table-md-th-font-size);--gog-table-size-td-font-size: var(--gog-table-md-td-font-size)}.gog-table--sm{--gog-table-size-th-padding-v: var(--gog-table-sm-padding-v);--gog-table-size-td-padding-v: var(--gog-table-sm-padding-v);--gog-table-size-th-font-size: var(--gog-table-sm-th-font-size);--gog-table-size-td-font-size: var(--gog-table-sm-td-font-size)}.gog-table--xsm{--gog-table-size-th-padding-v: var(--gog-table-xsm-padding-v);--gog-table-size-td-padding-v: var(--gog-table-xsm-padding-v);--gog-table-size-th-font-size: var(--gog-table-xsm-th-font-size);--gog-table-size-td-font-size: var(--gog-table-xsm-td-font-size)}.gog-table__col--num{width:var(--gog-table-num-col-width)}.gog-table__th{padding:var(--gog-table-th-padding-v, var(--gog-table-size-th-padding-v, var(--gog-table-lg-padding-v))) var(--gog-table-padding-h);text-align:left;font-family:var(--gog-table-header-font-family);font-size:var(--gog-table-th-font-size, var(--gog-table-size-th-font-size, var(--gog-table-lg-th-font-size)));text-transform:var(--gog-table-header-text-transform);letter-spacing:var(--gog-table-header-letter-spacing);color:var(--gog-table-accent-color);background-color:var(--gog-table-surface);border-bottom:var(--gog-table-border-width) var(--gog-table-border-style) var(--gog-table-border-color);white-space:normal;overflow:hidden}.gog-table--sticky-header .gog-table__th{position:sticky;top:0;z-index:1}.gog-table__th--num{width:var(--gog-table-num-col-width);text-align:center;color:var(--gog-table-muted-color)}.gog-table__th--select,.gog-table__td--select{width:var(--gog-table-select-col-width);text-align:center}.gog-table__th--sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.gog-table__th--sortable:focus-visible{outline:var(--gog-table-focus-ring-width) solid var(--gog-table-focus-ring);outline-offset:calc(var(--gog-table-focus-ring-width) * -1)}.gog-table__th--sortable:hover,.gog-table__th--sorted{color:var(--gog-table-accent-bright)}.gog-table__th-inner{display:inline-flex;align-items:center;gap:var(--gog-table-th-inner-gap);width:100%}.gog-table__sort-icon{display:inline-block;width:var(--gog-table-sort-icon-width);text-align:center;font-size:var(--gog-table-sort-icon-size);opacity:var(--gog-table-sort-icon-opacity);flex-shrink:0}.gog-table__th--sorted .gog-table__sort-icon{opacity:1}.gog-table__td{padding:var(--gog-table-td-padding-v, var(--gog-table-size-td-padding-v, var(--gog-table-lg-padding-v))) var(--gog-table-padding-h);font-size:var(--gog-table-td-font-size, var(--gog-table-size-td-font-size, var(--gog-table-lg-td-font-size)));border-bottom:var(--gog-table-row-border-width) var(--gog-table-border-style) var(--gog-table-border-color);vertical-align:middle;overflow-wrap:break-word;word-break:break-word;overflow:hidden}.gog-table__td--num{text-align:center;color:var(--gog-table-muted-color);font-size:var(--gog-table-num-font-size);font-family:var(--gog-table-numeric-font-family);width:var(--gog-table-num-col-width)}.gog-table__row:last-child .gog-table__td{border-bottom:none}.gog-table__row{transition:background-color var(--gog-table-row-transition-duration) var(--gog-easing)}.gog-table__row--interactive{cursor:pointer}.gog-table__row--interactive:focus-visible{outline:var(--gog-table-focus-ring-width) solid var(--gog-table-focus-ring);outline-offset:calc(var(--gog-table-focus-ring-width) * -1)}.gog-table__row:hover{background-color:var(--gog-table-hover-bg)}.gog-table__row--selected,.gog-table__row--selected:hover{background-color:var(--gog-table-selected-bg)}.gog-table__empty{padding:var(--gog-table-empty-padding);text-align:center;color:var(--gog-table-muted-color);font-size:var(--gog-table-empty-font-size)}.gog-table--loading thead{opacity:var(--gog-table-loading-opacity);pointer-events:none}.gog-table__loading-cell{padding:var(--gog-table-loading-padding);text-align:center}.gog-table--col-borders .gog-table__th:not(:last-child),.gog-table--col-borders .gog-table__td:not(:last-child){border-right:var(--gog-table-row-border-width) var(--gog-table-border-style) var(--gog-table-border-color)}.gog-table__footer{display:grid;grid-template-columns:1fr auto 1fr;grid-template-areas:\"left center right\";align-items:center;min-height:var(--gog-table-footer-min-height);gap:var(--gog-table-footer-gap)}.gog-table__total{font-size:var(--gog-table-total-font-size);color:var(--gog-table-muted-color);font-family:var(--gog-table-numeric-font-family);text-transform:var(--gog-table-total-text-transform);letter-spacing:var(--gog-table-total-letter-spacing)}.gog-table__total[style*=\"grid-area: right\"]{text-align:right}.gog-table__pagination[style*=\"grid-area: left\"]{justify-content:flex-start}.gog-table__pagination[style*=\"grid-area: center\"]{justify-content:center}.gog-table__pagination[style*=\"grid-area: right\"]{justify-content:flex-end}@media(prefers-reduced-motion:reduce){.gog-table__row{transition:none}}\n"] }]
|
|
7625
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], showPageSizeSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPageSizeSelect", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], lazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazy", required: false }] }], totalRecords: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalRecords", required: false }] }], interactiveRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactiveRows", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], showSelectionColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSelectionColumn", required: false }] }], showRowNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRowNumbers", required: false }] }], showTotal: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTotal", required: false }] }], emptyPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyPlaceholder", required: false }] }], paginatorPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginatorPosition", required: false }] }], totalPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPosition", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showColumnBorders: [{ type: i0.Input, args: [{ isSignal: true, alias: "showColumnBorders", required: false }] }], stickyHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyHeader", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], gogSortChange: [{ type: i0.Output, args: ["gogSortChange"] }], gogPageChange: [{ type: i0.Output, args: ["gogPageChange"] }], gogRowClick: [{ type: i0.Output, args: ["gogRowClick"] }], columns: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => GogColumn), { isSignal: true }] }], templates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TemplateDirective), { isSignal: true }] }] } });
|
|
7052
7626
|
|
|
7053
7627
|
/** Built-in defaults, used when `GOG_CONFIG.theme` doesn't supply one. */
|
|
7054
7628
|
const DEFAULT_THEME = 'light';
|
|
@@ -8168,6 +8742,7 @@ const GOG_TOKEN_GROUPS = [
|
|
|
8168
8742
|
'--gog-paginator-ellipsis-font-size',
|
|
8169
8743
|
'--gog-paginator-ellipsis-min-width',
|
|
8170
8744
|
'--gog-paginator-gap',
|
|
8745
|
+
'--gog-paginator-page-size-min-width',
|
|
8171
8746
|
],
|
|
8172
8747
|
},
|
|
8173
8748
|
{
|
|
@@ -8438,6 +9013,8 @@ const GOG_TOKEN_GROUPS = [
|
|
|
8438
9013
|
'--gog-table-padding-h',
|
|
8439
9014
|
'--gog-table-row-border-width',
|
|
8440
9015
|
'--gog-table-row-transition-duration',
|
|
9016
|
+
'--gog-table-select-col-width',
|
|
9017
|
+
'--gog-table-selected-bg',
|
|
8441
9018
|
'--gog-table-slg-padding-v',
|
|
8442
9019
|
'--gog-table-slg-td-font-size',
|
|
8443
9020
|
'--gog-table-slg-th-font-size',
|
|
@@ -8777,5 +9354,5 @@ const GOG_TOKEN_GROUPS = [
|
|
|
8777
9354
|
* Generated bundle index. Do not edit.
|
|
8778
9355
|
*/
|
|
8779
9356
|
|
|
8780
|
-
export { AccordionComponent, AutocompleteComponent, ButtonComponent, ButtonToggleGroupComponent, CalendarComponent, CheckboxComponent, ChipComponent, CollapsibleComponent, Column, ConfirmationDialogComponent, DIALOG_DATA, DIALOG_REF, DatepickerComponent, DialogComponent, DialogService, DividerComponent, GOG_CONFIG, GOG_TABS_STATE, GOG_TOKEN_GROUPS, GogAccordionChevronDirective, GogAccordionContentDirective, GogAccordionHeaderDirective, GogBadgeDirective, GogButtonToggleOptionDirective, GogCheckboxIconDirective, GogCollapsibleContentDirective, GogCollapsibleTriggerDirective, GogColumn, GogColumnBodyDirective, GogColumnHeaderDirective, GogDropdownBase, GogDropdownChevronDirective, GogDropdownOptionDirective, GogFloatLabelState, GogInputAddonEndDirective, GogInputAddonStartDirective, GogMultiselectClearIconDirective, GogTabContentDirective, GogTabHeaderDirective, GogTagIconDirective, GogTooltipDirective, ICON_DEFS, IconComponent, InputfieldComponent, MultiselectComponent, PaginatorComponent, ProgressbarComponent, RadioGroupComponent, ScrollComponent, SelectComponent, SkeletonComponent, SliderComponent, SpinnerComponent, SpinnerOverlayComponent, TabComponent, TableComponent, TabsComponent, TagComponent, TemplateDirective, TextareaComponent, ThemeService, ToastComponent, ToastContainerComponent, ToastService, ToggleComponent, addDays, addMonths, addYears, buildMonthGrid, clampDate, copyTimeOnto, daysInMonth, defaultCompare, formatDate, getByPath, isAfterDay, isBeforeDay, isInRange, isSameDay, isSameMonth, isSameOptionValue, isWithinBounds, localeFirstDayOfWeek, monthNames, parseDate, provideGogConfig, readOption, resolveConfigured, startOfDay, weekdayNames, withTime };
|
|
9357
|
+
export { AccordionComponent, AutocompleteComponent, ButtonComponent, ButtonToggleGroupComponent, CalendarComponent, CheckboxComponent, ChipComponent, CollapsibleComponent, Column, ConfirmationDialogComponent, DIALOG_DATA, DIALOG_REF, DatepickerComponent, DialogComponent, DialogService, DividerComponent, GOG_CONFIG, GOG_ICONS, GOG_TABS_STATE, GOG_TOKEN_GROUPS, GogAccordionChevronDirective, GogAccordionContentDirective, GogAccordionHeaderDirective, GogBadgeDirective, GogButtonDirective, GogButtonToggleOptionDirective, GogCheckboxIconDirective, GogCollapsibleContentDirective, GogCollapsibleTriggerDirective, GogColumn, GogColumnBodyDirective, GogColumnHeaderDirective, GogDropdownBase, GogDropdownChevronDirective, GogDropdownOptionDirective, GogFloatLabelState, GogInputAddonEndDirective, GogInputAddonStartDirective, GogMultiselectClearIconDirective, GogTabContentDirective, GogTabHeaderDirective, GogTagIconDirective, GogTooltipDirective, ICON_DEFS, IconComponent, InputfieldComponent, MultiselectComponent, PaginatorComponent, ProgressbarComponent, RadioGroupComponent, ScrollComponent, SelectComponent, SkeletonComponent, SliderComponent, SpinnerComponent, SpinnerOverlayComponent, TabComponent, TableComponent, TabsComponent, TagComponent, TemplateDirective, TextareaComponent, ThemeService, ToastComponent, ToastContainerComponent, ToastService, ToggleComponent, addDays, addMonths, addYears, buildMonthGrid, clampDate, copyTimeOnto, daysInMonth, defaultCompare, formatDate, getByPath, isAfterDay, isBeforeDay, isInRange, isSameDay, isSameMonth, isSameOptionValue, isWithinBounds, localeFirstDayOfWeek, monthNames, parseDate, provideGogConfig, provideGogIcons, readOption, resolveConfigured, startOfDay, weekdayNames, withTime };
|
|
8781
9358
|
//# sourceMappingURL=guildofgleks-ui.mjs.map
|