@besaitech/ng-design-system 0.0.66 → 0.0.67
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/README.md +15 -2
- package/fesm2022/besaitech-ng-design-system.mjs +1569 -321
- package/fesm2022/besaitech-ng-design-system.mjs.map +1 -1
- package/index.d.ts +468 -48
- package/package.json +1 -1
|
@@ -310,7 +310,7 @@ const VARIANTS$2 = {
|
|
|
310
310
|
'dark:hover:bg-white/10 dark:active:bg-white/15',
|
|
311
311
|
danger: 'bg-danger text-white shadow-sm hover:brightness-95 active:brightness-90',
|
|
312
312
|
};
|
|
313
|
-
const SIZES$
|
|
313
|
+
const SIZES$e = {
|
|
314
314
|
sm: 'h-8 px-3 text-sm',
|
|
315
315
|
md: 'h-10 px-4 text-sm',
|
|
316
316
|
lg: 'h-12 px-5 text-base',
|
|
@@ -370,7 +370,7 @@ class SdsButton {
|
|
|
370
370
|
BASE,
|
|
371
371
|
this.shape() === 'pill' ? 'rounded-full' : 'rounded-control',
|
|
372
372
|
VARIANTS$2[this.variant()],
|
|
373
|
-
SIZES$
|
|
373
|
+
SIZES$e[size],
|
|
374
374
|
this.iconOnly() ? ICON_ONLY[size] : '',
|
|
375
375
|
this.block() ? 'w-full' : '',
|
|
376
376
|
]
|
|
@@ -422,8 +422,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
422
422
|
`, styles: [".sds-spinner{width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;border-radius:9999px;animation:sds-spin .6s linear infinite}@keyframes sds-spin{to{transform:rotate(360deg)}}\n"] }]
|
|
423
423
|
}], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], block: [{ type: i0.Input, args: [{ isSignal: true, alias: "block", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
|
|
424
424
|
|
|
425
|
-
let nextId$
|
|
426
|
-
const SIZES$
|
|
425
|
+
let nextId$p = 0;
|
|
426
|
+
const SIZES$d = {
|
|
427
427
|
sm: 'h-9 text-sm',
|
|
428
428
|
md: 'h-10 text-sm',
|
|
429
429
|
lg: 'h-12 text-base',
|
|
@@ -435,7 +435,7 @@ const SIZES$c = {
|
|
|
435
435
|
* sidebar search field).
|
|
436
436
|
*/
|
|
437
437
|
class SdsInput {
|
|
438
|
-
autoId = `sds-input-${nextId$
|
|
438
|
+
autoId = `sds-input-${nextId$p++}`;
|
|
439
439
|
/**
|
|
440
440
|
* `id` of the native `<input>` — for a `<label for>` outside the component, or to focus the field with
|
|
441
441
|
* `document.getElementById(id).focus()` (after adding a row, say). Empty (default) generates one. Set it
|
|
@@ -539,7 +539,7 @@ class SdsInput {
|
|
|
539
539
|
}, ...(ngDevMode ? [{ debugName: "fieldPadding" }] : []));
|
|
540
540
|
wrapperClasses = computed(() => {
|
|
541
541
|
const danger = !!this.error() || this.invalid();
|
|
542
|
-
const parts = [SIZES$
|
|
542
|
+
const parts = [SIZES$d[this.size()], this.pill() ? 'rounded-full' : 'rounded-control'];
|
|
543
543
|
if (this.isDisabled())
|
|
544
544
|
parts.push('opacity-60 cursor-not-allowed');
|
|
545
545
|
if (this.filled()) {
|
|
@@ -795,7 +795,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
795
795
|
`, styles: ["input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{transition:background-color 100000s ease-in-out 0s;-webkit-text-fill-color:currentColor;caret-color:currentColor}\n"] }]
|
|
796
796
|
}], propDecorators: { inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], trailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingIcon", required: false }] }], trailingAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingAction", required: false }] }], trailingActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingActionLabel", required: false }] }], trailingActionPressed: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingActionPressed", required: false }] }], trailingActionClick: [{ type: i0.Output, args: ["trailingActionClick"] }] } });
|
|
797
797
|
|
|
798
|
-
let nextId$
|
|
798
|
+
let nextId$o = 0;
|
|
799
799
|
const HEIGHTS = {
|
|
800
800
|
sm: 'h-9',
|
|
801
801
|
md: 'h-10',
|
|
@@ -823,7 +823,7 @@ const TEXT = {
|
|
|
823
823
|
* with "." ("1.234" in nl-BE) stays a thousands separator.
|
|
824
824
|
*/
|
|
825
825
|
class SdsInputNumber {
|
|
826
|
-
inputId = `sds-input-number-${nextId$
|
|
826
|
+
inputId = `sds-input-number-${nextId$o++}`;
|
|
827
827
|
fieldRef = viewChild('field', ...(ngDevMode ? [{ debugName: "fieldRef" }] : []));
|
|
828
828
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
829
829
|
/** Accessible name used when no visible [label] is provided. */
|
|
@@ -1607,8 +1607,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
1607
1607
|
}]
|
|
1608
1608
|
}], ctorParameters: () => [], propDecorators: { fieldRef: [{ type: i0.ViewChild, args: ['field', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], currency: [{ type: i0.Input, args: [{ isSignal: true, alias: "currency", required: false }] }], currencyDisplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "currencyDisplay", required: false }] }], useGrouping: [{ type: i0.Input, args: [{ isSignal: true, alias: "useGrouping", required: false }] }], minFractionDigits: [{ type: i0.Input, args: [{ isSignal: true, alias: "minFractionDigits", required: false }] }], maxFractionDigits: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFractionDigits", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", 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 }] }], showButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showButtons", required: false }] }], buttonLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLayout", required: false }] }], incrementIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "incrementIcon", required: false }] }], decrementIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "decrementIcon", required: false }] }], allowEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowEmpty", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], incrementLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "incrementLabel", required: false }] }], decrementLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "decrementLabel", required: false }] }] } });
|
|
1609
1609
|
|
|
1610
|
-
let nextId$
|
|
1611
|
-
const SIZES$
|
|
1610
|
+
let nextId$n = 0;
|
|
1611
|
+
const SIZES$c = {
|
|
1612
1612
|
sm: 'h-9 text-sm',
|
|
1613
1613
|
md: 'h-10 text-sm',
|
|
1614
1614
|
lg: 'h-12 text-base',
|
|
@@ -1648,7 +1648,7 @@ function parseTime(value) {
|
|
|
1648
1648
|
* <sds-time-input [ariaLabel]="'Closes at'" [ngModel]="end()" (ngModelChange)="end.set($event)" clearable />
|
|
1649
1649
|
*/
|
|
1650
1650
|
class SdsTimeInput {
|
|
1651
|
-
fieldId = `sds-time-input-${nextId$
|
|
1651
|
+
fieldId = `sds-time-input-${nextId$n++}`;
|
|
1652
1652
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
1653
1653
|
/** Accessible name of the field when there is no visible [label]. */
|
|
1654
1654
|
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
@@ -1695,7 +1695,7 @@ class SdsTimeInput {
|
|
|
1695
1695
|
return null;
|
|
1696
1696
|
}, ...(ngDevMode ? [{ debugName: "describedBy" }] : []));
|
|
1697
1697
|
wrapperClasses = computed(() => {
|
|
1698
|
-
const parts = [SIZES$
|
|
1698
|
+
const parts = [SIZES$c[this.size()], 'rounded-control'];
|
|
1699
1699
|
if (this.isDisabled())
|
|
1700
1700
|
parts.push('opacity-60 cursor-not-allowed');
|
|
1701
1701
|
if (this.appearance() === 'filled') {
|
|
@@ -2177,8 +2177,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
2177
2177
|
}]
|
|
2178
2178
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], showIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcon", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], withSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "withSeconds", required: false }] }], placeholderText: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholderText", required: false }] }], hoursLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoursLabel", required: false }] }], minutesLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "minutesLabel", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], hoursEl: [{ type: i0.ViewChild, args: ['hoursEl', { isSignal: true }] }], minutesEl: [{ type: i0.ViewChild, args: ['minutesEl', { isSignal: true }] }] } });
|
|
2179
2179
|
|
|
2180
|
-
let nextId$
|
|
2181
|
-
const SIZES$
|
|
2180
|
+
let nextId$m = 0;
|
|
2181
|
+
const SIZES$b = {
|
|
2182
2182
|
sm: 'min-h-9 text-sm',
|
|
2183
2183
|
md: 'min-h-10 text-sm',
|
|
2184
2184
|
lg: 'min-h-12 text-base',
|
|
@@ -2200,7 +2200,7 @@ const SIZES$a = {
|
|
|
2200
2200
|
* `<sds-localized-input [languages]="['fr','nl','en']" [(ngModel)]="title" />`.
|
|
2201
2201
|
*/
|
|
2202
2202
|
class SdsLocalizedInput {
|
|
2203
|
-
autoId = `sds-localized-input-${nextId$
|
|
2203
|
+
autoId = `sds-localized-input-${nextId$m++}`;
|
|
2204
2204
|
/** The native field's id; a generated one when empty (set it to pair an external `<label for>`). */
|
|
2205
2205
|
inputId = input('', ...(ngDevMode ? [{ debugName: "inputId" }] : []));
|
|
2206
2206
|
/** The native field's id: {@link inputId} or the generated one. */
|
|
@@ -2251,7 +2251,7 @@ class SdsLocalizedInput {
|
|
|
2251
2251
|
cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : []));
|
|
2252
2252
|
isDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
2253
2253
|
wrapperClasses = computed(() => {
|
|
2254
|
-
const parts = [SIZES$
|
|
2254
|
+
const parts = [SIZES$b[this.size()]];
|
|
2255
2255
|
const danger = !!this.error() || this.invalid();
|
|
2256
2256
|
parts.push(this.isDisabled()
|
|
2257
2257
|
? 'border-border opacity-60 cursor-not-allowed'
|
|
@@ -2560,8 +2560,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
2560
2560
|
}]
|
|
2561
2561
|
}], propDecorators: { inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], requiredLanguages: [{ type: i0.Input, args: [{ isSignal: true, alias: "requiredLanguages", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], showCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCount", required: false }] }], languages: [{ type: i0.Input, args: [{ isSignal: true, alias: "languages", required: false }] }], currentLanguage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentLanguage", required: false }] }], multiline: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiline", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], languageSwitcherLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "languageSwitcherLabel", required: false }] }], untranslatedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "untranslatedLabel", required: false }] }], requiredLanguageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "requiredLanguageLabel", required: false }] }] } });
|
|
2562
2562
|
|
|
2563
|
-
let nextId$
|
|
2564
|
-
const SIZES$
|
|
2563
|
+
let nextId$l = 0;
|
|
2564
|
+
const SIZES$a = {
|
|
2565
2565
|
md: 'h-12 w-11 text-lg',
|
|
2566
2566
|
lg: 'h-14 w-12 text-xl',
|
|
2567
2567
|
};
|
|
@@ -2577,7 +2577,7 @@ const SIZES$9 = {
|
|
|
2577
2577
|
* first box and have it land correctly.
|
|
2578
2578
|
*/
|
|
2579
2579
|
class SdsOtpInput {
|
|
2580
|
-
groupId = `sds-otp-${nextId$
|
|
2580
|
+
groupId = `sds-otp-${nextId$l++}`;
|
|
2581
2581
|
/** How many boxes / characters the code has. */
|
|
2582
2582
|
length = input(6, ...(ngDevMode ? [{ debugName: "length", transform: numberAttribute }] : [{ transform: numberAttribute }]));
|
|
2583
2583
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
@@ -2613,7 +2613,7 @@ class SdsOtpInput {
|
|
|
2613
2613
|
return null;
|
|
2614
2614
|
}, ...(ngDevMode ? [{ debugName: "describedBy" }] : []));
|
|
2615
2615
|
cellClasses = computed(() => {
|
|
2616
|
-
const parts = ['rounded-control border', SIZES$
|
|
2616
|
+
const parts = ['rounded-control border', SIZES$a[this.size()]];
|
|
2617
2617
|
parts.push(this.error()
|
|
2618
2618
|
? 'border-danger focus:border-danger focus:ring-2 focus:ring-danger/25'
|
|
2619
2619
|
: 'border-border text-ink focus:border-brand-500 focus:ring-2 focus:ring-brand-500/25');
|
|
@@ -2877,8 +2877,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
2877
2877
|
}]
|
|
2878
2878
|
}], ctorParameters: () => [], propDecorators: { length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], inputMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputMode", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], cellLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellLabel", required: false }] }], completed: [{ type: i0.Output, args: ["completed"] }], cells: [{ type: i0.ViewChildren, args: ['cell', { isSignal: true }] }] } });
|
|
2879
2879
|
|
|
2880
|
-
let nextId$
|
|
2881
|
-
const SIZES$
|
|
2880
|
+
let nextId$k = 0;
|
|
2881
|
+
const SIZES$9 = {
|
|
2882
2882
|
sm: 'text-sm px-3 py-2',
|
|
2883
2883
|
md: 'text-sm px-3.5 py-2.5',
|
|
2884
2884
|
lg: 'text-base px-4 py-3',
|
|
@@ -2889,7 +2889,7 @@ const SIZES$8 = {
|
|
|
2889
2889
|
* [(ngModel)].
|
|
2890
2890
|
*/
|
|
2891
2891
|
class SdsTextarea {
|
|
2892
|
-
fieldId = `sds-textarea-${nextId$
|
|
2892
|
+
fieldId = `sds-textarea-${nextId$k++}`;
|
|
2893
2893
|
field = viewChild('field', ...(ngDevMode ? [{ debugName: "field" }] : []));
|
|
2894
2894
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
2895
2895
|
/** Accessible name used when no visible [label] is provided. */
|
|
@@ -2946,7 +2946,7 @@ class SdsTextarea {
|
|
|
2946
2946
|
fieldClasses = computed(() => {
|
|
2947
2947
|
const parts = [
|
|
2948
2948
|
'block w-full rounded-control border text-ink outline-none transition-colors placeholder:text-ink-faint',
|
|
2949
|
-
SIZES$
|
|
2949
|
+
SIZES$9[this.size()],
|
|
2950
2950
|
];
|
|
2951
2951
|
if (this.autoResize())
|
|
2952
2952
|
parts.push('overflow-hidden');
|
|
@@ -3156,8 +3156,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
3156
3156
|
}]
|
|
3157
3157
|
}], ctorParameters: () => [], propDecorators: { field: [{ type: i0.ViewChild, args: ['field', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], autoResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoResize", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], showCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCount", required: false }] }], countLimitLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "countLimitLabel", required: false }] }], countLabelTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "countLabelTemplate", required: false }] }], resize: [{ type: i0.Input, args: [{ isSignal: true, alias: "resize", required: false }] }] } });
|
|
3158
3158
|
|
|
3159
|
-
let nextId$
|
|
3160
|
-
const SIZES$
|
|
3159
|
+
let nextId$j = 0;
|
|
3160
|
+
const SIZES$8 = {
|
|
3161
3161
|
sm: { track: 'h-5 w-9', knob: 'h-4 w-4', on: 'translate-x-4', icon: 11 },
|
|
3162
3162
|
md: { track: 'h-6 w-11', knob: 'h-5 w-5', on: 'translate-x-5', icon: 13 },
|
|
3163
3163
|
lg: { track: 'h-7 w-[3.4rem]', knob: 'h-6 w-6', on: 'translate-x-7', icon: 15 },
|
|
@@ -3169,7 +3169,7 @@ const SIZES$7 = {
|
|
|
3169
3169
|
* states.
|
|
3170
3170
|
*/
|
|
3171
3171
|
class SdsToggleSwitch {
|
|
3172
|
-
fieldId = `sds-toggle-switch-${nextId$
|
|
3172
|
+
fieldId = `sds-toggle-switch-${nextId$j++}`;
|
|
3173
3173
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
3174
3174
|
/** Accessible name used when no visible [label] is provided. */
|
|
3175
3175
|
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
@@ -3197,7 +3197,7 @@ class SdsToggleSwitch {
|
|
|
3197
3197
|
cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : []));
|
|
3198
3198
|
checked = computed(() => this.value() === this.trueValue(), ...(ngDevMode ? [{ debugName: "checked" }] : []));
|
|
3199
3199
|
isDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
3200
|
-
sizing = computed(() => SIZES$
|
|
3200
|
+
sizing = computed(() => SIZES$8[this.size()], ...(ngDevMode ? [{ debugName: "sizing" }] : []));
|
|
3201
3201
|
describedBy = computed(() => {
|
|
3202
3202
|
if (this.error())
|
|
3203
3203
|
return `${this.fieldId}-err`;
|
|
@@ -3416,7 +3416,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
3416
3416
|
}]
|
|
3417
3417
|
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], trueValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "trueValue", required: false }] }], falseValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "falseValue", required: false }] }], onIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "onIcon", required: false }] }], offIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "offIcon", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }] } });
|
|
3418
3418
|
|
|
3419
|
-
let nextId$
|
|
3419
|
+
let nextId$i = 0;
|
|
3420
3420
|
/**
|
|
3421
3421
|
* Boolean checkbox. Implements ControlValueAccessor — use with reactive forms
|
|
3422
3422
|
* or `[(ngModel)]`. Renders a styled box (brand-filled with a check when on)
|
|
@@ -3431,7 +3431,7 @@ let nextId$h = 0;
|
|
|
3431
3431
|
* <sds-checkbox label="Auto-merge" [(ngModel)]="autoMerge" />
|
|
3432
3432
|
*/
|
|
3433
3433
|
class SdsCheckbox {
|
|
3434
|
-
id = `sds-checkbox-${nextId$
|
|
3434
|
+
id = `sds-checkbox-${nextId$i++}`;
|
|
3435
3435
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
3436
3436
|
/** Accessible name used when no visible [label] is provided. */
|
|
3437
3437
|
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
@@ -3579,7 +3579,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
3579
3579
|
}]
|
|
3580
3580
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }] } });
|
|
3581
3581
|
|
|
3582
|
-
let nextId$
|
|
3582
|
+
let nextId$h = 0;
|
|
3583
3583
|
/**
|
|
3584
3584
|
* Mounted radios by group name. A pick updates the rest of its group, because a native radio says
|
|
3585
3585
|
* nothing when the browser unchecks it — without this a reactive form would leave the old choice drawn.
|
|
@@ -3605,7 +3605,7 @@ const groups = new Map();
|
|
|
3605
3605
|
* <sds-radio name="size" value="large" label="Grand" [(ngModel)]="size" />
|
|
3606
3606
|
*/
|
|
3607
3607
|
class SdsRadio {
|
|
3608
|
-
id = `sds-radio-${nextId$
|
|
3608
|
+
id = `sds-radio-${nextId$h++}`;
|
|
3609
3609
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
3610
3610
|
/** Accessible name used when no visible [label] is provided. */
|
|
3611
3611
|
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
@@ -4181,7 +4181,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
4181
4181
|
|
|
4182
4182
|
/** Activation order: none → contains → may-contain → none. */
|
|
4183
4183
|
const ORDER = ['none', 'contains', 'may-contain'];
|
|
4184
|
-
let nextId$
|
|
4184
|
+
let nextId$g = 0;
|
|
4185
4185
|
/**
|
|
4186
4186
|
* A chip that cycles through three states — `none`, `contains`, `may-contain` — built for the 14-tile
|
|
4187
4187
|
* allergen declaration grid, but generic (any "no / yes / maybe" declaration).
|
|
@@ -4201,7 +4201,7 @@ let nextId$f = 0;
|
|
|
4201
4201
|
* containsLabel="Contains" mayContainLabel="May contain" noneLabel="Not present" />
|
|
4202
4202
|
*/
|
|
4203
4203
|
class SdsTriStateChip {
|
|
4204
|
-
chipId = `sds-tri-state-chip-${nextId$
|
|
4204
|
+
chipId = `sds-tri-state-chip-${nextId$g++}`;
|
|
4205
4205
|
/** Current state. Two-way: `[(value)]`. */
|
|
4206
4206
|
value = model('none', ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
4207
4207
|
/** Visible name (e.g. the allergen). Required — the chip has no other accessible name. */
|
|
@@ -4426,7 +4426,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
4426
4426
|
}]
|
|
4427
4427
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showState: [{ type: i0.Input, args: [{ isSignal: true, alias: "showState", required: false }] }], noneLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "noneLabel", required: false }] }], containsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "containsLabel", required: false }] }], mayContainLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "mayContainLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }] } });
|
|
4428
4428
|
|
|
4429
|
-
let nextId$
|
|
4429
|
+
let nextId$f = 0;
|
|
4430
4430
|
/**
|
|
4431
4431
|
* Segmented control: a small set of mutually exclusive options shown side by side (e.g. "Pick exactly /
|
|
4432
4432
|
* at least / up to"). Radio-group semantics: `role="radiogroup"` with `role="radio"` segments, one tab
|
|
@@ -4442,7 +4442,7 @@ let nextId$e = 0;
|
|
|
4442
4442
|
*/
|
|
4443
4443
|
class SdsSegmented {
|
|
4444
4444
|
host = inject(ElementRef);
|
|
4445
|
-
baseId = `sds-segmented-${nextId$
|
|
4445
|
+
baseId = `sds-segmented-${nextId$f++}`;
|
|
4446
4446
|
/** Options: `{ value, label, icon?, disabled? }` objects, or bare strings/numbers. */
|
|
4447
4447
|
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
4448
4448
|
/** Selected value. Two-way: `[(value)]`. */
|
|
@@ -4720,7 +4720,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
4720
4720
|
`,
|
|
4721
4721
|
}]
|
|
4722
4722
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showCheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCheck", required: false }] }] } });
|
|
4723
|
-
let nextId$
|
|
4723
|
+
let nextId$e = 0;
|
|
4724
4724
|
/**
|
|
4725
4725
|
* A set of chips: pick ONE (a filter row such as "All · Missing photo · Hidden", VAT presets, a date
|
|
4726
4726
|
* range) or, with `multiple`, SEVERAL (categories of an item, days of the week, dietary tags). Unlike
|
|
@@ -4743,7 +4743,7 @@ let nextId$d = 0;
|
|
|
4743
4743
|
*/
|
|
4744
4744
|
class SdsChipGroup {
|
|
4745
4745
|
host = inject(ElementRef);
|
|
4746
|
-
baseId = `sds-chip-group-${nextId$
|
|
4746
|
+
baseId = `sds-chip-group-${nextId$e++}`;
|
|
4747
4747
|
/** Options: `{ value, label, icon?, count?, disabled? }` objects, or bare strings/numbers. */
|
|
4748
4748
|
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
4749
4749
|
/** Picked value (single) or values (multiple). Two-way: `[(value)]`. */
|
|
@@ -5645,7 +5645,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
5645
5645
|
}]
|
|
5646
5646
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], image: [{ type: i0.Input, args: [{ isSignal: true, alias: "image", required: false }] }], imageAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageAlt", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], note: [{ type: i0.Input, args: [{ isSignal: true, alias: "note", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], busy: [{ type: i0.Input, args: [{ isSignal: true, alias: "busy", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], availableLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLabel", required: false }] }], soldOutLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "soldOutLabel", required: false }] }], hiddenLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenLabel", required: false }] }], activate: [{ type: i0.Output, args: ["activate"] }], imageError: [{ type: i0.Output, args: ["imageError"] }] } });
|
|
5647
5647
|
|
|
5648
|
-
let nextId$
|
|
5648
|
+
let nextId$d = 0;
|
|
5649
5649
|
/**
|
|
5650
5650
|
* Marks the element inside `<sds-menu>` that opens it. It may be a native button or a component that
|
|
5651
5651
|
* renders one (e.g. `<sds-button sdsMenuTrigger>`): the menu wires `aria-haspopup`, `aria-expanded` and
|
|
@@ -5693,7 +5693,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
5693
5693
|
class SdsMenu {
|
|
5694
5694
|
host = inject(ElementRef);
|
|
5695
5695
|
injector = inject(Injector);
|
|
5696
|
-
menuId = `sds-menu-${nextId$
|
|
5696
|
+
menuId = `sds-menu-${nextId$d++}`;
|
|
5697
5697
|
triggerId = `${this.menuId}-trigger`;
|
|
5698
5698
|
/** Actions and separators, in order. */
|
|
5699
5699
|
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
@@ -6289,7 +6289,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
6289
6289
|
standalone: true,
|
|
6290
6290
|
}]
|
|
6291
6291
|
}] });
|
|
6292
|
-
let nextId$
|
|
6292
|
+
let nextId$c = 0;
|
|
6293
6293
|
/** Fastest auto-scroll step, in px per animation frame (reached at the very edge). */
|
|
6294
6294
|
const AUTO_SCROLL_MAX_STEP = 18;
|
|
6295
6295
|
/** The nearest ancestor that scrolls vertically (below the document, which is handled as the window). */
|
|
@@ -6358,7 +6358,7 @@ function moveItem(list, from, to) {
|
|
|
6358
6358
|
class SdsSortableList {
|
|
6359
6359
|
host = inject(ElementRef);
|
|
6360
6360
|
injector = inject(Injector);
|
|
6361
|
-
instructionsId = `sds-sortable-${nextId$
|
|
6361
|
+
instructionsId = `sds-sortable-${nextId$c++}-help`;
|
|
6362
6362
|
/** The items, in order. Two-way: `[(items)]` receives the new order on drop. */
|
|
6363
6363
|
items = model([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
6364
6364
|
/** Property used as a stable identity for rows (strongly recommended). */
|
|
@@ -6950,7 +6950,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
6950
6950
|
}]
|
|
6951
6951
|
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }, { type: i0.Output, args: ["itemsChange"] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], labelField: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelField", required: false }] }], itemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemLabel", required: false }] }], itemDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemDisabled", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], autoScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoScroll", required: false }] }], autoScrollEdge: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoScrollEdge", required: false }] }], handleLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "handleLabel", required: false }] }], instructions: [{ type: i0.Input, args: [{ isSignal: true, alias: "instructions", required: false }] }], pickedUpMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "pickedUpMessage", required: false }] }], movedMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "movedMessage", required: false }] }], droppedMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "droppedMessage", required: false }] }], cancelledMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelledMessage", required: false }] }], reorder: [{ type: i0.Output, args: ["reorder"] }], itemTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsSortableItem), { isSignal: true }] }], handleTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsSortableHandle), { isSignal: true }] }] } });
|
|
6952
6952
|
|
|
6953
|
-
let nextId$
|
|
6953
|
+
let nextId$b = 0;
|
|
6954
6954
|
/** "1.5 MB" style size (decimal units, like file managers show them), for messages. */
|
|
6955
6955
|
function sdsFormatBytes(bytes) {
|
|
6956
6956
|
if (!Number.isFinite(bytes) || bytes < 0)
|
|
@@ -7007,7 +7007,7 @@ function sdsFileMatchesAccept(file, accept) {
|
|
|
7007
7007
|
* (files)="upload($event)" (rejected)="onRejected($event)" />
|
|
7008
7008
|
*/
|
|
7009
7009
|
class SdsFileDrop {
|
|
7010
|
-
zoneId = `sds-file-drop-${nextId$
|
|
7010
|
+
zoneId = `sds-file-drop-${nextId$b++}`;
|
|
7011
7011
|
fileInput = viewChild('fileInput', ...(ngDevMode ? [{ debugName: "fileInput" }] : []));
|
|
7012
7012
|
/** Accepted types, native `accept` syntax. Empty = anything. */
|
|
7013
7013
|
accept = input('', ...(ngDevMode ? [{ debugName: "accept" }] : []));
|
|
@@ -7389,7 +7389,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
7389
7389
|
}]
|
|
7390
7390
|
}], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], maxSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSize", required: false }] }], maxFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFiles", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], dropLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropLabel", required: false }] }], browseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "browseLabel", required: false }] }], loadingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], wrongTypeMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrongTypeMessage", required: false }] }], tooLargeMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooLargeMessage", required: false }] }], tooManyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooManyMessage", required: false }] }], files: [{ type: i0.Output, args: ["files"] }], rejected: [{ type: i0.Output, args: ["rejected"] }] } });
|
|
7391
7391
|
|
|
7392
|
-
let nextId$
|
|
7392
|
+
let nextId$a = 0;
|
|
7393
7393
|
/**
|
|
7394
7394
|
* Crops an image to a FIXED aspect ratio (e.g. the shop's card ratio): the frame is fixed and the image
|
|
7395
7395
|
* moves and zooms behind it, always covering the frame, so every crop is valid.
|
|
@@ -7407,7 +7407,7 @@ let nextId$9 = 0;
|
|
|
7407
7407
|
* <sds-button (click)="upload(await cropper.toBlob({ width: 1600 }))">Save</sds-button>
|
|
7408
7408
|
*/
|
|
7409
7409
|
class SdsImageCropper {
|
|
7410
|
-
helpId = `sds-image-cropper-${nextId$
|
|
7410
|
+
helpId = `sds-image-cropper-${nextId$a++}-help`;
|
|
7411
7411
|
viewport = viewChild('viewport', ...(ngDevMode ? [{ debugName: "viewport" }] : []));
|
|
7412
7412
|
/** Image to crop: a URL, or a Blob/File. */
|
|
7413
7413
|
src = input(null, ...(ngDevMode ? [{ debugName: "src" }] : []));
|
|
@@ -7956,6 +7956,28 @@ function formatDdMmYyyy(d) {
|
|
|
7956
7956
|
const p = (n) => String(n).padStart(2, '0');
|
|
7957
7957
|
return `${p(d.getDate())}/${p(d.getMonth() + 1)}/${d.getFullYear()}`;
|
|
7958
7958
|
}
|
|
7959
|
+
/** Whole calendar days from `a` to `b` (b − a), ignoring time-of-day and DST shifts. */
|
|
7960
|
+
function diffInDays(a, b) {
|
|
7961
|
+
const ua = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
|
|
7962
|
+
const ub = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
|
|
7963
|
+
return Math.round((ub - ua) / 86_400_000);
|
|
7964
|
+
}
|
|
7965
|
+
/**
|
|
7966
|
+
* Format an inclusive day range for display, e.g. `1–7 Oct 2026`, `28 Sept – 4 Oct 2026` or
|
|
7967
|
+
* `20 Dec 2026 – 3 Jan 2027` (en-GB). Uses `Intl.DateTimeFormat#formatRange`, which collapses the
|
|
7968
|
+
* parts both ends share; falls back to `start – end` where it is unavailable. A one-day range prints
|
|
7969
|
+
* a single date.
|
|
7970
|
+
*/
|
|
7971
|
+
function formatDateRange(range, locale = 'en-GB', options = { day: 'numeric', month: 'short', year: 'numeric' }) {
|
|
7972
|
+
const fmt = new Intl.DateTimeFormat(locale, options);
|
|
7973
|
+
if (isSameDay(range.start, range.end))
|
|
7974
|
+
return fmt.format(range.start);
|
|
7975
|
+
const withRange = fmt;
|
|
7976
|
+
if (typeof withRange.formatRange === 'function') {
|
|
7977
|
+
return withRange.formatRange(range.start, range.end);
|
|
7978
|
+
}
|
|
7979
|
+
return `${fmt.format(range.start)} – ${fmt.format(range.end)}`;
|
|
7980
|
+
}
|
|
7959
7981
|
|
|
7960
7982
|
/**
|
|
7961
7983
|
* Inline month calendar with day → month → year drill-down navigation,
|
|
@@ -8755,7 +8777,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
8755
8777
|
}]
|
|
8756
8778
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], showDone: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDone", required: false }] }], timeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLabel", required: false }] }], hoursLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoursLabel", required: false }] }], minutesLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "minutesLabel", required: false }] }], doneLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "doneLabel", required: false }] }], calendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "calendarLabel", required: false }] }], previousLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], todayActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "todayActionLabel", required: false }] }], clearActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearActionLabel", required: false }] }], dateSelect: [{ type: i0.Output, args: ["dateSelect"] }], done: [{ type: i0.Output, args: ["done"] }] } });
|
|
8757
8779
|
|
|
8758
|
-
const SIZES$
|
|
8780
|
+
const SIZES$7 = {
|
|
8759
8781
|
sm: 'h-9 text-sm',
|
|
8760
8782
|
md: 'h-10 text-sm',
|
|
8761
8783
|
lg: 'h-12 text-base',
|
|
@@ -8771,7 +8793,7 @@ const SIZES$6 = {
|
|
|
8771
8793
|
class SdsDatePicker {
|
|
8772
8794
|
host = inject(ElementRef);
|
|
8773
8795
|
injector = inject(Injector);
|
|
8774
|
-
fieldId = `sds-date-${nextId$
|
|
8796
|
+
fieldId = `sds-date-${nextId$9++}`;
|
|
8775
8797
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
8776
8798
|
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
8777
8799
|
placeholder = input('dd/mm/yyyy', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
@@ -8847,7 +8869,7 @@ class SdsDatePicker {
|
|
|
8847
8869
|
/** Whether the clear button is shown (affects the field's right padding). */
|
|
8848
8870
|
showClear = computed(() => this.clearable() && !!this.value() && !this.isDisabled(), ...(ngDevMode ? [{ debugName: "showClear" }] : []));
|
|
8849
8871
|
wrapperClasses = computed(() => {
|
|
8850
|
-
const parts = [SIZES$
|
|
8872
|
+
const parts = [SIZES$7[this.size()]];
|
|
8851
8873
|
parts.push(this.error()
|
|
8852
8874
|
? 'border-danger focus-within:border-danger focus-within:ring-2 focus-within:ring-danger/25'
|
|
8853
8875
|
: 'border-border focus-within:border-brand-500 focus-within:ring-2 focus-within:ring-brand-500/25');
|
|
@@ -9084,84 +9106,1201 @@ class SdsDatePicker {
|
|
|
9084
9106
|
[class.pr-11]="!showClear()"
|
|
9085
9107
|
/>
|
|
9086
9108
|
|
|
9087
|
-
@if (showClear()) {
|
|
9088
|
-
<button
|
|
9089
|
-
type="button"
|
|
9090
|
-
tabindex="-1"
|
|
9091
|
-
[attr.aria-label]="clearLabel()"
|
|
9092
|
-
class="absolute right-10 inline-flex h-6 w-6 items-center justify-center rounded-full text-ink-faint hover:bg-black/5 hover:text-ink-soft"
|
|
9093
|
-
(click)="clear($event)"
|
|
9109
|
+
@if (showClear()) {
|
|
9110
|
+
<button
|
|
9111
|
+
type="button"
|
|
9112
|
+
tabindex="-1"
|
|
9113
|
+
[attr.aria-label]="clearLabel()"
|
|
9114
|
+
class="absolute right-10 inline-flex h-6 w-6 items-center justify-center rounded-full text-ink-faint hover:bg-black/5 hover:text-ink-soft"
|
|
9115
|
+
(click)="clear($event)"
|
|
9116
|
+
>
|
|
9117
|
+
<sds-icon name="x" [size]="15" />
|
|
9118
|
+
</button>
|
|
9119
|
+
}
|
|
9120
|
+
|
|
9121
|
+
<button
|
|
9122
|
+
type="button"
|
|
9123
|
+
tabindex="-1"
|
|
9124
|
+
[attr.aria-label]="open() ? closeCalendarLabel() : openCalendarLabel()"
|
|
9125
|
+
class="absolute right-2 inline-flex h-7 w-7 items-center justify-center rounded-control text-ink-soft hover:bg-muted"
|
|
9126
|
+
(click)="toggle($event)"
|
|
9127
|
+
>
|
|
9128
|
+
<sds-icon name="calendar" [size]="18" />
|
|
9129
|
+
</button>
|
|
9130
|
+
</div>
|
|
9131
|
+
|
|
9132
|
+
@if (open()) {
|
|
9133
|
+
<!-- Relocated to document.body on open (appendTo body) to escape
|
|
9134
|
+
ancestor overflow/stacking; positioned via positionPanel(). -->
|
|
9135
|
+
<div
|
|
9136
|
+
class="fixed z-[1000]"
|
|
9137
|
+
role="dialog"
|
|
9138
|
+
aria-modal="false"
|
|
9139
|
+
[attr.aria-label]="panelLabel()"
|
|
9140
|
+
(keydown.escape)="onEscape($event)"
|
|
9141
|
+
(keydown)="onPanelKeydown($event)"
|
|
9142
|
+
>
|
|
9143
|
+
<sds-calendar
|
|
9144
|
+
[value]="value()"
|
|
9145
|
+
[min]="min()"
|
|
9146
|
+
[max]="max()"
|
|
9147
|
+
[firstDayOfWeek]="firstDayOfWeek()"
|
|
9148
|
+
[locale]="locale()"
|
|
9149
|
+
[showActions]="showActions()"
|
|
9150
|
+
[showTime]="showTime()"
|
|
9151
|
+
[showDone]="showTime()"
|
|
9152
|
+
[timeLabel]="timeLabel()"
|
|
9153
|
+
[hoursLabel]="hoursLabel()"
|
|
9154
|
+
[minutesLabel]="minutesLabel()"
|
|
9155
|
+
[doneLabel]="doneLabel()"
|
|
9156
|
+
[calendarLabel]="calendarLabel()"
|
|
9157
|
+
[previousLabel]="previousLabel()"
|
|
9158
|
+
[nextLabel]="nextLabel()"
|
|
9159
|
+
[todayActionLabel]="todayActionLabel()"
|
|
9160
|
+
[clearActionLabel]="clearActionLabel()"
|
|
9161
|
+
(valueChange)="onCalendarValue($event)"
|
|
9162
|
+
(dateSelect)="onDateSelect()"
|
|
9163
|
+
(done)="close(true)"
|
|
9164
|
+
/>
|
|
9165
|
+
</div>
|
|
9166
|
+
}
|
|
9167
|
+
</div>
|
|
9168
|
+
}
|
|
9169
|
+
|
|
9170
|
+
@if (hint() && !error()) {
|
|
9171
|
+
<p class="mt-1.5 text-xs text-ink-faint">{{ hint() }}</p>
|
|
9172
|
+
}
|
|
9173
|
+
@if (error()) {
|
|
9174
|
+
<p class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
|
|
9175
|
+
}
|
|
9176
|
+
`, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth", "filled"] }, { kind: "component", type: SdsCalendar, selector: "sds-calendar", inputs: ["value", "min", "max", "firstDayOfWeek", "locale", "showActions", "showTime", "showDone", "timeLabel", "hoursLabel", "minutesLabel", "doneLabel", "calendarLabel", "previousLabel", "nextLabel", "todayActionLabel", "clearActionLabel"], outputs: ["valueChange", "dateSelect", "done"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9177
|
+
}
|
|
9178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsDatePicker, decorators: [{
|
|
9179
|
+
type: Component,
|
|
9180
|
+
args: [{
|
|
9181
|
+
selector: 'sds-date-picker',
|
|
9182
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
9183
|
+
imports: [SdsIcon, SdsCalendar],
|
|
9184
|
+
providers: [
|
|
9185
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SdsDatePicker), multi: true },
|
|
9186
|
+
],
|
|
9187
|
+
host: {
|
|
9188
|
+
class: 'block',
|
|
9189
|
+
'(document:click)': 'onDocumentClick($event)',
|
|
9190
|
+
'(keydown.escape)': 'onEscape($event)',
|
|
9191
|
+
},
|
|
9192
|
+
template: `
|
|
9193
|
+
@if (label()) {
|
|
9194
|
+
<label [for]="fieldId" class="mb-1.5 block text-sm font-medium text-ink">
|
|
9195
|
+
{{ label() }}
|
|
9196
|
+
</label>
|
|
9197
|
+
}
|
|
9198
|
+
|
|
9199
|
+
@if (inline()) {
|
|
9200
|
+
<sds-calendar
|
|
9201
|
+
[value]="value()"
|
|
9202
|
+
[min]="min()"
|
|
9203
|
+
[max]="max()"
|
|
9204
|
+
[firstDayOfWeek]="firstDayOfWeek()"
|
|
9205
|
+
[locale]="locale()"
|
|
9206
|
+
[showActions]="showActions()"
|
|
9207
|
+
[showTime]="showTime()"
|
|
9208
|
+
[timeLabel]="timeLabel()"
|
|
9209
|
+
[hoursLabel]="hoursLabel()"
|
|
9210
|
+
[minutesLabel]="minutesLabel()"
|
|
9211
|
+
[calendarLabel]="calendarLabel()"
|
|
9212
|
+
[previousLabel]="previousLabel()"
|
|
9213
|
+
[nextLabel]="nextLabel()"
|
|
9214
|
+
[todayActionLabel]="todayActionLabel()"
|
|
9215
|
+
[clearActionLabel]="clearActionLabel()"
|
|
9216
|
+
(valueChange)="onCalendarValue($event)"
|
|
9217
|
+
/>
|
|
9218
|
+
} @else {
|
|
9219
|
+
<div class="relative">
|
|
9220
|
+
<div
|
|
9221
|
+
#trigger
|
|
9222
|
+
class="relative flex items-center rounded-control border bg-surface transition-colors"
|
|
9223
|
+
[class]="wrapperClasses()"
|
|
9224
|
+
(click)="toggle()"
|
|
9225
|
+
>
|
|
9226
|
+
<input
|
|
9227
|
+
[id]="fieldId"
|
|
9228
|
+
type="text"
|
|
9229
|
+
readonly
|
|
9230
|
+
[value]="displayValue()"
|
|
9231
|
+
[placeholder]="placeholder()"
|
|
9232
|
+
[disabled]="isDisabled()"
|
|
9233
|
+
[attr.aria-haspopup]="'dialog'"
|
|
9234
|
+
[attr.aria-expanded]="open()"
|
|
9235
|
+
[attr.aria-label]="!label() && ariaLabel() ? ariaLabel() : null"
|
|
9236
|
+
(keydown.enter)="onTriggerKeydown($event)"
|
|
9237
|
+
(keydown.space)="onTriggerKeydown($event)"
|
|
9238
|
+
(keydown.arrowdown)="onTriggerKeydown($event)"
|
|
9239
|
+
class="w-full cursor-pointer bg-transparent pl-3.5 text-ink outline-none placeholder:text-ink-faint disabled:cursor-not-allowed"
|
|
9240
|
+
[class.pr-20]="showClear()"
|
|
9241
|
+
[class.pr-11]="!showClear()"
|
|
9242
|
+
/>
|
|
9243
|
+
|
|
9244
|
+
@if (showClear()) {
|
|
9245
|
+
<button
|
|
9246
|
+
type="button"
|
|
9247
|
+
tabindex="-1"
|
|
9248
|
+
[attr.aria-label]="clearLabel()"
|
|
9249
|
+
class="absolute right-10 inline-flex h-6 w-6 items-center justify-center rounded-full text-ink-faint hover:bg-black/5 hover:text-ink-soft"
|
|
9250
|
+
(click)="clear($event)"
|
|
9251
|
+
>
|
|
9252
|
+
<sds-icon name="x" [size]="15" />
|
|
9253
|
+
</button>
|
|
9254
|
+
}
|
|
9255
|
+
|
|
9256
|
+
<button
|
|
9257
|
+
type="button"
|
|
9258
|
+
tabindex="-1"
|
|
9259
|
+
[attr.aria-label]="open() ? closeCalendarLabel() : openCalendarLabel()"
|
|
9260
|
+
class="absolute right-2 inline-flex h-7 w-7 items-center justify-center rounded-control text-ink-soft hover:bg-muted"
|
|
9261
|
+
(click)="toggle($event)"
|
|
9262
|
+
>
|
|
9263
|
+
<sds-icon name="calendar" [size]="18" />
|
|
9264
|
+
</button>
|
|
9265
|
+
</div>
|
|
9266
|
+
|
|
9267
|
+
@if (open()) {
|
|
9268
|
+
<!-- Relocated to document.body on open (appendTo body) to escape
|
|
9269
|
+
ancestor overflow/stacking; positioned via positionPanel(). -->
|
|
9270
|
+
<div
|
|
9271
|
+
class="fixed z-[1000]"
|
|
9272
|
+
role="dialog"
|
|
9273
|
+
aria-modal="false"
|
|
9274
|
+
[attr.aria-label]="panelLabel()"
|
|
9275
|
+
(keydown.escape)="onEscape($event)"
|
|
9276
|
+
(keydown)="onPanelKeydown($event)"
|
|
9277
|
+
>
|
|
9278
|
+
<sds-calendar
|
|
9279
|
+
[value]="value()"
|
|
9280
|
+
[min]="min()"
|
|
9281
|
+
[max]="max()"
|
|
9282
|
+
[firstDayOfWeek]="firstDayOfWeek()"
|
|
9283
|
+
[locale]="locale()"
|
|
9284
|
+
[showActions]="showActions()"
|
|
9285
|
+
[showTime]="showTime()"
|
|
9286
|
+
[showDone]="showTime()"
|
|
9287
|
+
[timeLabel]="timeLabel()"
|
|
9288
|
+
[hoursLabel]="hoursLabel()"
|
|
9289
|
+
[minutesLabel]="minutesLabel()"
|
|
9290
|
+
[doneLabel]="doneLabel()"
|
|
9291
|
+
[calendarLabel]="calendarLabel()"
|
|
9292
|
+
[previousLabel]="previousLabel()"
|
|
9293
|
+
[nextLabel]="nextLabel()"
|
|
9294
|
+
[todayActionLabel]="todayActionLabel()"
|
|
9295
|
+
[clearActionLabel]="clearActionLabel()"
|
|
9296
|
+
(valueChange)="onCalendarValue($event)"
|
|
9297
|
+
(dateSelect)="onDateSelect()"
|
|
9298
|
+
(done)="close(true)"
|
|
9299
|
+
/>
|
|
9300
|
+
</div>
|
|
9301
|
+
}
|
|
9302
|
+
</div>
|
|
9303
|
+
}
|
|
9304
|
+
|
|
9305
|
+
@if (hint() && !error()) {
|
|
9306
|
+
<p class="mt-1.5 text-xs text-ink-faint">{{ hint() }}</p>
|
|
9307
|
+
}
|
|
9308
|
+
@if (error()) {
|
|
9309
|
+
<p class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
|
|
9310
|
+
}
|
|
9311
|
+
`,
|
|
9312
|
+
}]
|
|
9313
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], inline: [{ type: i0.Input, args: [{ isSignal: true, alias: "inline", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], timeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLabel", required: false }] }], hoursLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoursLabel", required: false }] }], minutesLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "minutesLabel", required: false }] }], doneLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "doneLabel", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], openCalendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "openCalendarLabel", required: false }] }], closeCalendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeCalendarLabel", required: false }] }], panelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelLabel", required: false }] }], calendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "calendarLabel", required: false }] }], previousLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], todayActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "todayActionLabel", required: false }] }], clearActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearActionLabel", required: false }] }], calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdsCalendar), { isSignal: true }] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
|
|
9314
|
+
let nextId$9 = 0;
|
|
9315
|
+
|
|
9316
|
+
/** Same first and last day (time-of-day ignored). `null` only equals `null`. */
|
|
9317
|
+
function isSameRange(a, b) {
|
|
9318
|
+
if (!a || !b)
|
|
9319
|
+
return !a && !b;
|
|
9320
|
+
return isSameDay(a.start, b.start) && isSameDay(a.end, b.end);
|
|
9321
|
+
}
|
|
9322
|
+
/** The last `days` days, today included: `sdsLastDays(7)` = today − 6 … today. */
|
|
9323
|
+
function sdsLastDays(days, today = new Date()) {
|
|
9324
|
+
const end = startOfDay(today);
|
|
9325
|
+
return { start: addDays(end, -(Math.max(1, Math.floor(days)) - 1)), end };
|
|
9326
|
+
}
|
|
9327
|
+
/**
|
|
9328
|
+
* The last `months` months, today included: `sdsLastMonths(12)` on 13 Oct 2026 = 14 Oct 2025 …
|
|
9329
|
+
* 13 Oct 2026 (the day after the same day `months` months ago, clamped to short months).
|
|
9330
|
+
*/
|
|
9331
|
+
function sdsLastMonths(months, today = new Date()) {
|
|
9332
|
+
const end = startOfDay(today);
|
|
9333
|
+
return { start: addDays(addMonthsKeepDay(end, -Math.max(1, Math.floor(months))), 1), end };
|
|
9334
|
+
}
|
|
9335
|
+
|
|
9336
|
+
/** Viewport width (px) from which two months sit side by side — Tailwind's `sm`. */
|
|
9337
|
+
const TWO_MONTH_MIN_WIDTH = 640;
|
|
9338
|
+
/**
|
|
9339
|
+
* Range calendar: one or two side-by-side months on which a day range is picked with two clicks.
|
|
9340
|
+
* Used by `<sds-date-range-picker>`, and usable on its own (bind `[(start)]` and `[(end)]`).
|
|
9341
|
+
*
|
|
9342
|
+
* Selection rule: the first click sets `start` (and clears `end`); the second sets `end` — or, when
|
|
9343
|
+
* it lands BEFORE `start`, becomes the new `start`. Clicking the start day again gives a one-day
|
|
9344
|
+
* range. While the end is being chosen, the band previews start → hovered (or keyboard-focused) day.
|
|
9345
|
+
* `maxDays` caps the span: once a start is picked, days past `start + maxDays − 1` are disabled.
|
|
9346
|
+
*
|
|
9347
|
+
* Bare (no border / shadow / background): place it in your own card or panel.
|
|
9348
|
+
*
|
|
9349
|
+
* Keyboard: arrows move by day / week, Home / End to the week's start / end, PageUp / PageDown by
|
|
9350
|
+
* month (roving tabindex across both months); Enter / Space picks the focused day.
|
|
9351
|
+
*
|
|
9352
|
+
* @example
|
|
9353
|
+
* <sds-range-calendar [(start)]="from" [(end)]="to" [max]="today" />
|
|
9354
|
+
*/
|
|
9355
|
+
class SdsRangeCalendar {
|
|
9356
|
+
host = inject(ElementRef);
|
|
9357
|
+
injector = inject(Injector);
|
|
9358
|
+
/** First day of the range (two-way: `[(start)]`). */
|
|
9359
|
+
start = model(null, ...(ngDevMode ? [{ debugName: "start" }] : []));
|
|
9360
|
+
/** Last day of the range, inclusive (two-way: `[(end)]`). `null` while the end is being chosen. */
|
|
9361
|
+
end = model(null, ...(ngDevMode ? [{ debugName: "end" }] : []));
|
|
9362
|
+
min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : []));
|
|
9363
|
+
max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : []));
|
|
9364
|
+
/** Longest selectable span in days (start and end included). `null` = no limit. */
|
|
9365
|
+
maxDays = input(null, ...(ngDevMode ? [{ debugName: "maxDays" }] : []));
|
|
9366
|
+
/** 0 = Sunday, 1 = Monday (default, European). */
|
|
9367
|
+
firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : []));
|
|
9368
|
+
/** BCP 47 locale for month and weekday names. Defaults to `en-GB`; pass the app's locale. */
|
|
9369
|
+
locale = input('en-GB', ...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
9370
|
+
/** Months shown side by side (from the `sm` breakpoint; always one below it). */
|
|
9371
|
+
months = input(2, ...(ngDevMode ? [{ debugName: "months" }] : []));
|
|
9372
|
+
/** Accessible name of the calendar group. English default — translate it in the app. */
|
|
9373
|
+
calendarLabel = input('Calendar', ...(ngDevMode ? [{ debugName: "calendarLabel" }] : []));
|
|
9374
|
+
/** Accessible name of the icon-only "previous month" button (its ONLY name — translate it). */
|
|
9375
|
+
previousLabel = input('Previous', ...(ngDevMode ? [{ debugName: "previousLabel" }] : []));
|
|
9376
|
+
/** Accessible name of the icon-only "next month" button. See {@link previousLabel}. */
|
|
9377
|
+
nextLabel = input('Next', ...(ngDevMode ? [{ debugName: "nextLabel" }] : []));
|
|
9378
|
+
/** Emitted on every day pick (start or end). */
|
|
9379
|
+
daySelect = output();
|
|
9380
|
+
/** Emitted when a pick completes the range (both ends set). */
|
|
9381
|
+
rangeSelect = output();
|
|
9382
|
+
/** The day under the pointer / keyboard focus (`null` when the pointer leaves the grid). */
|
|
9383
|
+
dayHover = output();
|
|
9384
|
+
/** First month on screen. */
|
|
9385
|
+
viewDate = signal(startOfMonth(new Date()), ...(ngDevMode ? [{ debugName: "viewDate" }] : []));
|
|
9386
|
+
focusedDate = signal(startOfDay(new Date()), ...(ngDevMode ? [{ debugName: "focusedDate" }] : []));
|
|
9387
|
+
hovered = signal(null, ...(ngDevMode ? [{ debugName: "hovered" }] : []));
|
|
9388
|
+
wide = signal(true, ...(ngDevMode ? [{ debugName: "wide" }] : []));
|
|
9389
|
+
/** Months actually rendered: {@link months}, but one on narrow viewports. */
|
|
9390
|
+
monthsShown = computed(() => (this.months() === 2 && this.wide() ? 2 : 1), ...(ngDevMode ? [{ debugName: "monthsShown" }] : []));
|
|
9391
|
+
constructor() {
|
|
9392
|
+
this.watchViewport();
|
|
9393
|
+
// Keep a range set from outside on screen (a form writing a value, a preset). A pick inside the
|
|
9394
|
+
// grid is already visible, so this never moves the months under the pointer.
|
|
9395
|
+
effect(() => {
|
|
9396
|
+
const s = this.start();
|
|
9397
|
+
const e = this.end();
|
|
9398
|
+
untracked(() => {
|
|
9399
|
+
const anchor = e ?? s;
|
|
9400
|
+
if (anchor && !this.isVisible(anchor))
|
|
9401
|
+
this.anchorView(anchor, !!e);
|
|
9402
|
+
});
|
|
9403
|
+
});
|
|
9404
|
+
}
|
|
9405
|
+
watchViewport() {
|
|
9406
|
+
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function')
|
|
9407
|
+
return;
|
|
9408
|
+
const mq = window.matchMedia(`(min-width: ${TWO_MONTH_MIN_WIDTH}px)`);
|
|
9409
|
+
this.wide.set(mq.matches);
|
|
9410
|
+
const onChange = (e) => this.wide.set(e.matches);
|
|
9411
|
+
mq.addEventListener?.('change', onChange);
|
|
9412
|
+
inject(DestroyRef).onDestroy(() => mq.removeEventListener?.('change', onChange));
|
|
9413
|
+
}
|
|
9414
|
+
// --- styling helpers ---
|
|
9415
|
+
navBtn = 'inline-flex h-8 w-8 items-center justify-center rounded-control text-ink-soft hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 disabled:cursor-not-allowed disabled:opacity-40';
|
|
9416
|
+
// --- derived state ---
|
|
9417
|
+
weekdayLabels = computed(() => {
|
|
9418
|
+
const fmt = new Intl.DateTimeFormat(this.locale(), { weekday: 'short' });
|
|
9419
|
+
const sunday = new Date(2023, 0, 1); // a known Sunday
|
|
9420
|
+
return Array.from({ length: 7 }, (_, i) => fmt.format(addDays(sunday, (this.firstDayOfWeek() + i) % 7)));
|
|
9421
|
+
}, ...(ngDevMode ? [{ debugName: "weekdayLabels" }] : []));
|
|
9422
|
+
/** The end used for drawing: the committed end, else the previewed (hovered) one. */
|
|
9423
|
+
previewEnd = computed(() => {
|
|
9424
|
+
const s = this.start();
|
|
9425
|
+
const h = this.hovered();
|
|
9426
|
+
if (!s || this.end() || !h)
|
|
9427
|
+
return null;
|
|
9428
|
+
const day = startOfDay(h);
|
|
9429
|
+
if (day < startOfDay(s) || this.isDisabled(day))
|
|
9430
|
+
return null;
|
|
9431
|
+
return day;
|
|
9432
|
+
}, ...(ngDevMode ? [{ debugName: "previewEnd" }] : []));
|
|
9433
|
+
prevDisabled = computed(() => {
|
|
9434
|
+
const min = this.min();
|
|
9435
|
+
return !!min && this.viewDate() <= startOfMonth(min);
|
|
9436
|
+
}, ...(ngDevMode ? [{ debugName: "prevDisabled" }] : []));
|
|
9437
|
+
nextDisabled = computed(() => {
|
|
9438
|
+
const max = this.max();
|
|
9439
|
+
return !!max && addMonths(this.viewDate(), this.monthsShown() - 1) >= startOfMonth(max);
|
|
9440
|
+
}, ...(ngDevMode ? [{ debugName: "nextDisabled" }] : []));
|
|
9441
|
+
monthViews = computed(() => {
|
|
9442
|
+
const n = this.monthsShown();
|
|
9443
|
+
const first = this.viewDate();
|
|
9444
|
+
const titleFmt = new Intl.DateTimeFormat(this.locale(), { month: 'long', year: 'numeric' });
|
|
9445
|
+
const today = startOfDay(new Date());
|
|
9446
|
+
const s = this.start() ? startOfDay(this.start()) : null;
|
|
9447
|
+
const committedEnd = this.end() ? startOfDay(this.end()) : null;
|
|
9448
|
+
const preview = this.previewEnd();
|
|
9449
|
+
const e = committedEnd ?? preview;
|
|
9450
|
+
const lastVisible = new Date(first.getFullYear(), first.getMonth() + n, 0);
|
|
9451
|
+
const focus = this.focusedDate();
|
|
9452
|
+
const tabbable = focus >= first && focus <= lastVisible ? focus : first;
|
|
9453
|
+
// Re-read so the disabled state follows start / end / maxDays / min / max.
|
|
9454
|
+
this.maxDays();
|
|
9455
|
+
this.min();
|
|
9456
|
+
this.max();
|
|
9457
|
+
const out = [];
|
|
9458
|
+
for (let m = 0; m < n; m++) {
|
|
9459
|
+
const month = addMonths(first, m);
|
|
9460
|
+
const offset = (month.getDay() - this.firstDayOfWeek() + 7) % 7;
|
|
9461
|
+
const daysInMonth = new Date(month.getFullYear(), month.getMonth() + 1, 0).getDate();
|
|
9462
|
+
const weeks = [];
|
|
9463
|
+
for (let w = 0; w < 6; w++) {
|
|
9464
|
+
const row = [];
|
|
9465
|
+
for (let col = 0; col < 7; col++) {
|
|
9466
|
+
const dayNum = w * 7 + col - offset + 1;
|
|
9467
|
+
if (dayNum < 1 || dayNum > daysInMonth) {
|
|
9468
|
+
row.push(blankCell(`${isoDay(month)}-b${w}${col}`));
|
|
9469
|
+
continue;
|
|
9470
|
+
}
|
|
9471
|
+
const date = new Date(month.getFullYear(), month.getMonth(), dayNum);
|
|
9472
|
+
const isStart = isSameDay(date, s);
|
|
9473
|
+
const isEndDay = isSameDay(date, e);
|
|
9474
|
+
const hasSpan = !!s && !!e && !isSameDay(s, e);
|
|
9475
|
+
const inRange = !!s && !!e && date > s && date < e;
|
|
9476
|
+
let band = 'none';
|
|
9477
|
+
if (hasSpan) {
|
|
9478
|
+
if (inRange)
|
|
9479
|
+
band = 'full';
|
|
9480
|
+
else if (isStart)
|
|
9481
|
+
band = 'right';
|
|
9482
|
+
else if (isEndDay)
|
|
9483
|
+
band = 'left';
|
|
9484
|
+
}
|
|
9485
|
+
row.push({
|
|
9486
|
+
key: isoDay(date),
|
|
9487
|
+
date,
|
|
9488
|
+
day: dayNum,
|
|
9489
|
+
today: isSameDay(date, today),
|
|
9490
|
+
disabled: this.isDisabled(date),
|
|
9491
|
+
tabbable: isSameDay(date, tabbable),
|
|
9492
|
+
isStart,
|
|
9493
|
+
isEnd: isEndDay && !!committedEnd,
|
|
9494
|
+
isPreviewEnd: isEndDay && !committedEnd && !isStart,
|
|
9495
|
+
inRange,
|
|
9496
|
+
band,
|
|
9497
|
+
roundLeft: col === 0 || dayNum === 1,
|
|
9498
|
+
roundRight: col === 6 || dayNum === daysInMonth,
|
|
9499
|
+
});
|
|
9500
|
+
}
|
|
9501
|
+
weeks.push(row);
|
|
9502
|
+
}
|
|
9503
|
+
out.push({ key: isoDay(month), title: titleFmt.format(month), weeks });
|
|
9504
|
+
}
|
|
9505
|
+
return out;
|
|
9506
|
+
}, ...(ngDevMode ? [{ debugName: "monthViews" }] : []));
|
|
9507
|
+
// --- selection ---
|
|
9508
|
+
isDisabled(d) {
|
|
9509
|
+
if (isOutOfRange(d, this.min(), this.max()))
|
|
9510
|
+
return true;
|
|
9511
|
+
const s = this.start();
|
|
9512
|
+
const limit = this.maxDays();
|
|
9513
|
+
if (s && !this.end() && limit != null && limit > 0) {
|
|
9514
|
+
return diffInDays(s, d) >= limit;
|
|
9515
|
+
}
|
|
9516
|
+
return false;
|
|
9517
|
+
}
|
|
9518
|
+
selectDay(d) {
|
|
9519
|
+
const day = startOfDay(d);
|
|
9520
|
+
if (this.isDisabled(day))
|
|
9521
|
+
return;
|
|
9522
|
+
const s = this.start();
|
|
9523
|
+
if (!s || this.end()) {
|
|
9524
|
+
this.start.set(day);
|
|
9525
|
+
this.end.set(null);
|
|
9526
|
+
}
|
|
9527
|
+
else if (day < startOfDay(s)) {
|
|
9528
|
+
this.start.set(day);
|
|
9529
|
+
}
|
|
9530
|
+
else {
|
|
9531
|
+
this.end.set(day);
|
|
9532
|
+
this.rangeSelect.emit({ start: startOfDay(s), end: day });
|
|
9533
|
+
}
|
|
9534
|
+
this.focusedDate.set(day);
|
|
9535
|
+
this.daySelect.emit(day);
|
|
9536
|
+
}
|
|
9537
|
+
setHover(d) {
|
|
9538
|
+
if (isSameDay(d, this.hovered()) || (!d && !this.hovered()))
|
|
9539
|
+
return;
|
|
9540
|
+
this.hovered.set(d);
|
|
9541
|
+
this.dayHover.emit(d);
|
|
9542
|
+
}
|
|
9543
|
+
onDayFocus(d) {
|
|
9544
|
+
this.focusedDate.set(startOfDay(d));
|
|
9545
|
+
this.setHover(d);
|
|
9546
|
+
}
|
|
9547
|
+
// --- navigation ---
|
|
9548
|
+
shiftView(delta) {
|
|
9549
|
+
this.viewDate.set(addMonths(this.viewDate(), delta));
|
|
9550
|
+
}
|
|
9551
|
+
isVisible(d) {
|
|
9552
|
+
const first = this.viewDate();
|
|
9553
|
+
const last = new Date(first.getFullYear(), first.getMonth() + this.monthsShown(), 0);
|
|
9554
|
+
const day = startOfDay(d);
|
|
9555
|
+
return day >= first && day <= last;
|
|
9556
|
+
}
|
|
9557
|
+
/** Show `d`'s month first, or — with `last` — as the right-most month. */
|
|
9558
|
+
anchorView(d, last) {
|
|
9559
|
+
const m = startOfMonth(d);
|
|
9560
|
+
this.viewDate.set(last ? addMonths(m, -(this.monthsShown() - 1)) : m);
|
|
9561
|
+
}
|
|
9562
|
+
onGridKeydown(e) {
|
|
9563
|
+
let f = this.focusedDate();
|
|
9564
|
+
const weekPos = (f.getDay() - this.firstDayOfWeek() + 7) % 7;
|
|
9565
|
+
switch (e.key) {
|
|
9566
|
+
case 'ArrowLeft':
|
|
9567
|
+
f = addDays(f, -1);
|
|
9568
|
+
break;
|
|
9569
|
+
case 'ArrowRight':
|
|
9570
|
+
f = addDays(f, 1);
|
|
9571
|
+
break;
|
|
9572
|
+
case 'ArrowUp':
|
|
9573
|
+
f = addDays(f, -7);
|
|
9574
|
+
break;
|
|
9575
|
+
case 'ArrowDown':
|
|
9576
|
+
f = addDays(f, 7);
|
|
9577
|
+
break;
|
|
9578
|
+
case 'Home':
|
|
9579
|
+
f = addDays(f, -weekPos);
|
|
9580
|
+
break;
|
|
9581
|
+
case 'End':
|
|
9582
|
+
f = addDays(f, 6 - weekPos);
|
|
9583
|
+
break;
|
|
9584
|
+
case 'PageUp':
|
|
9585
|
+
f = addMonthsKeepDay(f, -1);
|
|
9586
|
+
break;
|
|
9587
|
+
case 'PageDown':
|
|
9588
|
+
f = addMonthsKeepDay(f, 1);
|
|
9589
|
+
break;
|
|
9590
|
+
case 'Enter':
|
|
9591
|
+
case ' ':
|
|
9592
|
+
e.preventDefault();
|
|
9593
|
+
this.selectDay(f);
|
|
9594
|
+
return;
|
|
9595
|
+
default:
|
|
9596
|
+
return;
|
|
9597
|
+
}
|
|
9598
|
+
e.preventDefault();
|
|
9599
|
+
if (!this.isVisible(f))
|
|
9600
|
+
this.anchorView(f, f > this.viewDate());
|
|
9601
|
+
this.focusedDate.set(f);
|
|
9602
|
+
this.setHover(f);
|
|
9603
|
+
this.focusCell(f);
|
|
9604
|
+
}
|
|
9605
|
+
/**
|
|
9606
|
+
* Show and focus the active day: the range's end (as the right-most month), else its start, else
|
|
9607
|
+
* today (right-most when `max` is this month or earlier, so a "past only" calendar does not open on
|
|
9608
|
+
* an all-disabled next month). Called by the picker when its panel opens.
|
|
9609
|
+
*/
|
|
9610
|
+
focusActiveCell() {
|
|
9611
|
+
const s = this.start();
|
|
9612
|
+
const e = this.end();
|
|
9613
|
+
const today = startOfDay(new Date());
|
|
9614
|
+
let target;
|
|
9615
|
+
if (e) {
|
|
9616
|
+
target = startOfDay(e);
|
|
9617
|
+
this.anchorView(target, true);
|
|
9618
|
+
}
|
|
9619
|
+
else if (s) {
|
|
9620
|
+
target = startOfDay(s);
|
|
9621
|
+
this.anchorView(target, false);
|
|
9622
|
+
}
|
|
9623
|
+
else {
|
|
9624
|
+
const max = this.max();
|
|
9625
|
+
target = max && today > startOfDay(max) ? startOfDay(max) : today;
|
|
9626
|
+
this.anchorView(target, !!max && startOfMonth(max) <= startOfMonth(today));
|
|
9627
|
+
}
|
|
9628
|
+
this.focusedDate.set(target);
|
|
9629
|
+
this.focusCell(target);
|
|
9630
|
+
}
|
|
9631
|
+
focusHandle;
|
|
9632
|
+
/**
|
|
9633
|
+
* Focus a day once it is rendered. A month change re-renders the grid, so try after the next
|
|
9634
|
+
* render AND on a timer: whichever runs once the cell exists wins (focusing twice is harmless),
|
|
9635
|
+
* and the timer still fires when nothing changed and no render is coming.
|
|
9636
|
+
*/
|
|
9637
|
+
focusCell(d) {
|
|
9638
|
+
const key = isoDay(d);
|
|
9639
|
+
const focus = () => {
|
|
9640
|
+
if (isoDay(this.focusedDate()) !== key)
|
|
9641
|
+
return; // superseded by a later move
|
|
9642
|
+
const el = this.host.nativeElement.querySelector(`[data-date="${key}"]`);
|
|
9643
|
+
if (el && document.activeElement !== el)
|
|
9644
|
+
el.focus();
|
|
9645
|
+
};
|
|
9646
|
+
clearTimeout(this.focusHandle);
|
|
9647
|
+
this.focusHandle = setTimeout(focus);
|
|
9648
|
+
afterNextRender(focus, { injector: this.injector });
|
|
9649
|
+
}
|
|
9650
|
+
// --- template helpers ---
|
|
9651
|
+
iso(d) {
|
|
9652
|
+
return isoDay(d);
|
|
9653
|
+
}
|
|
9654
|
+
fullLabel(d) {
|
|
9655
|
+
return new Intl.DateTimeFormat(this.locale(), {
|
|
9656
|
+
weekday: 'long',
|
|
9657
|
+
day: 'numeric',
|
|
9658
|
+
month: 'long',
|
|
9659
|
+
year: 'numeric',
|
|
9660
|
+
}).format(d);
|
|
9661
|
+
}
|
|
9662
|
+
bandClass(cell) {
|
|
9663
|
+
let cls = 'pointer-events-none absolute inset-y-0.5 bg-brand-50';
|
|
9664
|
+
if (cell.band === 'full') {
|
|
9665
|
+
cls += ' inset-x-0';
|
|
9666
|
+
if (cell.roundLeft)
|
|
9667
|
+
cls += ' rounded-l-full';
|
|
9668
|
+
if (cell.roundRight)
|
|
9669
|
+
cls += ' rounded-r-full';
|
|
9670
|
+
}
|
|
9671
|
+
else if (cell.band === 'right') {
|
|
9672
|
+
cls += ' left-1/2 right-0';
|
|
9673
|
+
if (cell.roundRight)
|
|
9674
|
+
cls += ' rounded-r-full';
|
|
9675
|
+
}
|
|
9676
|
+
else {
|
|
9677
|
+
cls += ' left-0 right-1/2';
|
|
9678
|
+
if (cell.roundLeft)
|
|
9679
|
+
cls += ' rounded-l-full';
|
|
9680
|
+
}
|
|
9681
|
+
return cls;
|
|
9682
|
+
}
|
|
9683
|
+
dayClass(cell) {
|
|
9684
|
+
const base = 'inline-flex h-9 w-9 items-center justify-center rounded-full text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 disabled:cursor-not-allowed disabled:opacity-40';
|
|
9685
|
+
if (cell.isStart || cell.isEnd) {
|
|
9686
|
+
return `${base} bg-brand-600 font-semibold text-white hover:bg-brand-700 ${DARK_BRAND_FILL_HOVER} focus-visible:ring-offset-1 focus-visible:ring-offset-surface`;
|
|
9687
|
+
}
|
|
9688
|
+
if (cell.isPreviewEnd) {
|
|
9689
|
+
return `${base} bg-brand-100 font-semibold text-ink ring-1 ring-inset ring-brand-300`;
|
|
9690
|
+
}
|
|
9691
|
+
if (cell.today) {
|
|
9692
|
+
return `${base} font-bold text-brand-600 ring-1 ring-inset ring-brand-300 ${cell.inRange ? 'hover:bg-brand-100' : 'hover:bg-brand-50'}`;
|
|
9693
|
+
}
|
|
9694
|
+
return `${base} text-ink ${cell.inRange ? 'hover:bg-brand-100' : 'hover:bg-brand-50'}`;
|
|
9695
|
+
}
|
|
9696
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsRangeCalendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9697
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsRangeCalendar, isStandalone: true, selector: "sds-range-calendar", inputs: { start: { classPropertyName: "start", publicName: "start", isSignal: true, isRequired: false, transformFunction: null }, end: { classPropertyName: "end", publicName: "end", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, maxDays: { classPropertyName: "maxDays", publicName: "maxDays", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, months: { classPropertyName: "months", publicName: "months", isSignal: true, isRequired: false, transformFunction: null }, calendarLabel: { classPropertyName: "calendarLabel", publicName: "calendarLabel", isSignal: true, isRequired: false, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { start: "startChange", end: "endChange", daySelect: "daySelect", rangeSelect: "rangeSelect", dayHover: "dayHover" }, host: { classAttribute: "block" }, ngImport: i0, template: `
|
|
9698
|
+
<div class="select-none" role="group" [attr.aria-label]="calendarLabel()" (mouseleave)="setHover(null)">
|
|
9699
|
+
<div class="flex flex-col gap-4 sm:flex-row sm:gap-6">
|
|
9700
|
+
@for (m of monthViews(); track m.key; let first = $first; let last = $last) {
|
|
9701
|
+
<div class="w-[17.5rem]">
|
|
9702
|
+
<div class="mb-2 flex items-center justify-between">
|
|
9703
|
+
@if (first) {
|
|
9704
|
+
<button
|
|
9705
|
+
type="button"
|
|
9706
|
+
[class]="navBtn"
|
|
9707
|
+
[disabled]="prevDisabled()"
|
|
9708
|
+
[attr.aria-label]="previousLabel()"
|
|
9709
|
+
(click)="shiftView(-1)"
|
|
9710
|
+
>
|
|
9711
|
+
<sds-icon name="chevron-left" [size]="18" />
|
|
9712
|
+
</button>
|
|
9713
|
+
} @else {
|
|
9714
|
+
<span class="h-8 w-8" aria-hidden="true"></span>
|
|
9715
|
+
}
|
|
9716
|
+
<span class="px-1 text-sm font-semibold capitalize text-ink" aria-live="polite">
|
|
9717
|
+
{{ m.title }}
|
|
9718
|
+
</span>
|
|
9719
|
+
@if (last) {
|
|
9720
|
+
<button
|
|
9721
|
+
type="button"
|
|
9722
|
+
[class]="navBtn"
|
|
9723
|
+
[disabled]="nextDisabled()"
|
|
9724
|
+
[attr.aria-label]="nextLabel()"
|
|
9725
|
+
(click)="shiftView(1)"
|
|
9726
|
+
>
|
|
9727
|
+
<sds-icon name="chevron-right" [size]="18" />
|
|
9728
|
+
</button>
|
|
9729
|
+
} @else {
|
|
9730
|
+
<span class="h-8 w-8" aria-hidden="true"></span>
|
|
9731
|
+
}
|
|
9732
|
+
</div>
|
|
9733
|
+
|
|
9734
|
+
<table class="w-full table-fixed border-collapse" role="grid" [attr.aria-label]="m.title">
|
|
9735
|
+
<thead>
|
|
9736
|
+
<tr>
|
|
9737
|
+
@for (wd of weekdayLabels(); track $index) {
|
|
9738
|
+
<th scope="col" class="pb-1 text-[11px] font-medium uppercase text-ink-faint">
|
|
9739
|
+
{{ wd }}
|
|
9740
|
+
</th>
|
|
9741
|
+
}
|
|
9742
|
+
</tr>
|
|
9743
|
+
</thead>
|
|
9744
|
+
<tbody (keydown)="onGridKeydown($event)">
|
|
9745
|
+
@for (week of m.weeks; track $index) {
|
|
9746
|
+
<tr>
|
|
9747
|
+
@for (cell of week; track cell.key) {
|
|
9748
|
+
<td class="relative p-0 text-center">
|
|
9749
|
+
@if (cell.date; as date) {
|
|
9750
|
+
@if (cell.band !== 'none') {
|
|
9751
|
+
<span aria-hidden="true" [class]="bandClass(cell)"></span>
|
|
9752
|
+
}
|
|
9753
|
+
<span class="relative flex justify-center py-0.5">
|
|
9754
|
+
<button
|
|
9755
|
+
type="button"
|
|
9756
|
+
[attr.data-date]="iso(date)"
|
|
9757
|
+
[tabindex]="cell.tabbable ? 0 : -1"
|
|
9758
|
+
[disabled]="cell.disabled"
|
|
9759
|
+
[attr.aria-selected]="cell.isStart || cell.isEnd"
|
|
9760
|
+
[attr.aria-current]="cell.today ? 'date' : null"
|
|
9761
|
+
[attr.aria-label]="fullLabel(date)"
|
|
9762
|
+
[class]="dayClass(cell)"
|
|
9763
|
+
(click)="selectDay(date)"
|
|
9764
|
+
(mouseenter)="setHover(date)"
|
|
9765
|
+
(focus)="onDayFocus(date)"
|
|
9766
|
+
>
|
|
9767
|
+
{{ cell.day }}
|
|
9768
|
+
</button>
|
|
9769
|
+
</span>
|
|
9770
|
+
}
|
|
9771
|
+
</td>
|
|
9772
|
+
}
|
|
9773
|
+
</tr>
|
|
9774
|
+
}
|
|
9775
|
+
</tbody>
|
|
9776
|
+
</table>
|
|
9777
|
+
</div>
|
|
9778
|
+
}
|
|
9779
|
+
</div>
|
|
9780
|
+
</div>
|
|
9781
|
+
`, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth", "filled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9782
|
+
}
|
|
9783
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsRangeCalendar, decorators: [{
|
|
9784
|
+
type: Component,
|
|
9785
|
+
args: [{
|
|
9786
|
+
selector: 'sds-range-calendar',
|
|
9787
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
9788
|
+
imports: [SdsIcon],
|
|
9789
|
+
host: { class: 'block' },
|
|
9790
|
+
template: `
|
|
9791
|
+
<div class="select-none" role="group" [attr.aria-label]="calendarLabel()" (mouseleave)="setHover(null)">
|
|
9792
|
+
<div class="flex flex-col gap-4 sm:flex-row sm:gap-6">
|
|
9793
|
+
@for (m of monthViews(); track m.key; let first = $first; let last = $last) {
|
|
9794
|
+
<div class="w-[17.5rem]">
|
|
9795
|
+
<div class="mb-2 flex items-center justify-between">
|
|
9796
|
+
@if (first) {
|
|
9797
|
+
<button
|
|
9798
|
+
type="button"
|
|
9799
|
+
[class]="navBtn"
|
|
9800
|
+
[disabled]="prevDisabled()"
|
|
9801
|
+
[attr.aria-label]="previousLabel()"
|
|
9802
|
+
(click)="shiftView(-1)"
|
|
9803
|
+
>
|
|
9804
|
+
<sds-icon name="chevron-left" [size]="18" />
|
|
9805
|
+
</button>
|
|
9806
|
+
} @else {
|
|
9807
|
+
<span class="h-8 w-8" aria-hidden="true"></span>
|
|
9808
|
+
}
|
|
9809
|
+
<span class="px-1 text-sm font-semibold capitalize text-ink" aria-live="polite">
|
|
9810
|
+
{{ m.title }}
|
|
9811
|
+
</span>
|
|
9812
|
+
@if (last) {
|
|
9813
|
+
<button
|
|
9814
|
+
type="button"
|
|
9815
|
+
[class]="navBtn"
|
|
9816
|
+
[disabled]="nextDisabled()"
|
|
9817
|
+
[attr.aria-label]="nextLabel()"
|
|
9818
|
+
(click)="shiftView(1)"
|
|
9819
|
+
>
|
|
9820
|
+
<sds-icon name="chevron-right" [size]="18" />
|
|
9821
|
+
</button>
|
|
9822
|
+
} @else {
|
|
9823
|
+
<span class="h-8 w-8" aria-hidden="true"></span>
|
|
9824
|
+
}
|
|
9825
|
+
</div>
|
|
9826
|
+
|
|
9827
|
+
<table class="w-full table-fixed border-collapse" role="grid" [attr.aria-label]="m.title">
|
|
9828
|
+
<thead>
|
|
9829
|
+
<tr>
|
|
9830
|
+
@for (wd of weekdayLabels(); track $index) {
|
|
9831
|
+
<th scope="col" class="pb-1 text-[11px] font-medium uppercase text-ink-faint">
|
|
9832
|
+
{{ wd }}
|
|
9833
|
+
</th>
|
|
9834
|
+
}
|
|
9835
|
+
</tr>
|
|
9836
|
+
</thead>
|
|
9837
|
+
<tbody (keydown)="onGridKeydown($event)">
|
|
9838
|
+
@for (week of m.weeks; track $index) {
|
|
9839
|
+
<tr>
|
|
9840
|
+
@for (cell of week; track cell.key) {
|
|
9841
|
+
<td class="relative p-0 text-center">
|
|
9842
|
+
@if (cell.date; as date) {
|
|
9843
|
+
@if (cell.band !== 'none') {
|
|
9844
|
+
<span aria-hidden="true" [class]="bandClass(cell)"></span>
|
|
9845
|
+
}
|
|
9846
|
+
<span class="relative flex justify-center py-0.5">
|
|
9847
|
+
<button
|
|
9848
|
+
type="button"
|
|
9849
|
+
[attr.data-date]="iso(date)"
|
|
9850
|
+
[tabindex]="cell.tabbable ? 0 : -1"
|
|
9851
|
+
[disabled]="cell.disabled"
|
|
9852
|
+
[attr.aria-selected]="cell.isStart || cell.isEnd"
|
|
9853
|
+
[attr.aria-current]="cell.today ? 'date' : null"
|
|
9854
|
+
[attr.aria-label]="fullLabel(date)"
|
|
9855
|
+
[class]="dayClass(cell)"
|
|
9856
|
+
(click)="selectDay(date)"
|
|
9857
|
+
(mouseenter)="setHover(date)"
|
|
9858
|
+
(focus)="onDayFocus(date)"
|
|
9859
|
+
>
|
|
9860
|
+
{{ cell.day }}
|
|
9861
|
+
</button>
|
|
9862
|
+
</span>
|
|
9863
|
+
}
|
|
9864
|
+
</td>
|
|
9865
|
+
}
|
|
9866
|
+
</tr>
|
|
9867
|
+
}
|
|
9868
|
+
</tbody>
|
|
9869
|
+
</table>
|
|
9870
|
+
</div>
|
|
9871
|
+
}
|
|
9872
|
+
</div>
|
|
9873
|
+
</div>
|
|
9874
|
+
`,
|
|
9875
|
+
}]
|
|
9876
|
+
}], ctorParameters: () => [], propDecorators: { start: [{ type: i0.Input, args: [{ isSignal: true, alias: "start", required: false }] }, { type: i0.Output, args: ["startChange"] }], end: [{ type: i0.Input, args: [{ isSignal: true, alias: "end", required: false }] }, { type: i0.Output, args: ["endChange"] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], maxDays: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDays", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], months: [{ type: i0.Input, args: [{ isSignal: true, alias: "months", required: false }] }], calendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "calendarLabel", required: false }] }], previousLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], daySelect: [{ type: i0.Output, args: ["daySelect"] }], rangeSelect: [{ type: i0.Output, args: ["rangeSelect"] }], dayHover: [{ type: i0.Output, args: ["dayHover"] }] } });
|
|
9877
|
+
function blankCell(key) {
|
|
9878
|
+
return {
|
|
9879
|
+
key,
|
|
9880
|
+
date: null,
|
|
9881
|
+
day: 0,
|
|
9882
|
+
today: false,
|
|
9883
|
+
disabled: true,
|
|
9884
|
+
tabbable: false,
|
|
9885
|
+
isStart: false,
|
|
9886
|
+
isEnd: false,
|
|
9887
|
+
isPreviewEnd: false,
|
|
9888
|
+
inRange: false,
|
|
9889
|
+
band: 'none',
|
|
9890
|
+
roundLeft: false,
|
|
9891
|
+
roundRight: false,
|
|
9892
|
+
};
|
|
9893
|
+
}
|
|
9894
|
+
|
|
9895
|
+
const SIZES$6 = {
|
|
9896
|
+
sm: 'h-9 text-sm',
|
|
9897
|
+
md: 'h-10 text-sm',
|
|
9898
|
+
lg: 'h-12 text-base',
|
|
9899
|
+
};
|
|
9900
|
+
/**
|
|
9901
|
+
* Date range picker: a field that opens a panel with quick ranges (presets) on the left and a
|
|
9902
|
+
* two-month range calendar on the right. A preset applies at once and closes the panel; a custom
|
|
9903
|
+
* range is picked with two clicks and stays PENDING until "Apply" (Cancel, Escape and a click away
|
|
9904
|
+
* discard it).
|
|
9905
|
+
*
|
|
9906
|
+
* The value is an inclusive `SdsDateRange` (`{ start, end }`, local midnight) or `null`, bound with
|
|
9907
|
+
* `[(value)]` (a `model`, not a ControlValueAccessor). `(presetSelect)` emits the preset `id` when
|
|
9908
|
+
* one is chosen, and `activePresetId()` tells which preset the current value equals (`null` = a
|
|
9909
|
+
* custom range), so an app can remember "30d" rather than two dates.
|
|
9910
|
+
*
|
|
9911
|
+
* Every visible and accessible string is an input with an English default — translate them all.
|
|
9912
|
+
*
|
|
9913
|
+
* @example
|
|
9914
|
+
* <sds-date-range-picker label="Period" [presets]="presets" [max]="today" [(value)]="range" />
|
|
9915
|
+
*/
|
|
9916
|
+
class SdsDateRangePicker {
|
|
9917
|
+
host = inject(ElementRef);
|
|
9918
|
+
injector = inject(Injector);
|
|
9919
|
+
uid = nextId$8++;
|
|
9920
|
+
fieldId = `sds-date-range-${this.uid}`;
|
|
9921
|
+
labelId = `${this.fieldId}-label`;
|
|
9922
|
+
valueId = `${this.fieldId}-value`;
|
|
9923
|
+
/** The selected range (two-way: `[(value)]`), `null` when none. Day granularity, end inclusive. */
|
|
9924
|
+
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
9925
|
+
/** Quick ranges listed on the left of the panel; choosing one applies it and closes the panel. */
|
|
9926
|
+
presets = input([], ...(ngDevMode ? [{ debugName: "presets" }] : []));
|
|
9927
|
+
min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : []));
|
|
9928
|
+
max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : []));
|
|
9929
|
+
/** Longest custom range in days (start and end included). `null` = no limit. */
|
|
9930
|
+
maxDays = input(null, ...(ngDevMode ? [{ debugName: "maxDays" }] : []));
|
|
9931
|
+
/** 0 = Sunday, 1 = Monday (default, European). */
|
|
9932
|
+
firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : []));
|
|
9933
|
+
/** BCP 47 locale for the calendar and the default range format. Defaults to `en-GB`. */
|
|
9934
|
+
locale = input('en-GB', ...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
9935
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
9936
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
9937
|
+
/** Months side by side in the panel (from the `sm` breakpoint; always one below it). */
|
|
9938
|
+
months = input(2, ...(ngDevMode ? [{ debugName: "months" }] : []));
|
|
9939
|
+
/**
|
|
9940
|
+
* Display formatter for the field. Default: `Intl.DateTimeFormat#formatRange` with day, short
|
|
9941
|
+
* month and year in {@link locale} (e.g. `1–7 Oct 2026`) — see `formatDateRange`.
|
|
9942
|
+
*/
|
|
9943
|
+
format = input(null, ...(ngDevMode ? [{ debugName: "format" }] : []));
|
|
9944
|
+
/** Visible label above the field. */
|
|
9945
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
9946
|
+
/** Accessible name when there is no visible {@link label}. */
|
|
9947
|
+
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
9948
|
+
/** Field text when no range is selected. */
|
|
9949
|
+
placeholder = input('Select dates', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
9950
|
+
/** Accessible name of the overlay dialog. */
|
|
9951
|
+
panelLabel = input('Choose a date range', ...(ngDevMode ? [{ debugName: "panelLabel" }] : []));
|
|
9952
|
+
/** Heading (and group name) of the presets column. */
|
|
9953
|
+
presetsLabel = input('Quick ranges', ...(ngDevMode ? [{ debugName: "presetsLabel" }] : []));
|
|
9954
|
+
/** Caption of the pending start date in the panel footer. */
|
|
9955
|
+
startLabel = input('Start', ...(ngDevMode ? [{ debugName: "startLabel" }] : []));
|
|
9956
|
+
/** Caption of the pending end date in the panel footer. */
|
|
9957
|
+
endLabel = input('End', ...(ngDevMode ? [{ debugName: "endLabel" }] : []));
|
|
9958
|
+
/** Text of the footer's apply action. */
|
|
9959
|
+
applyLabel = input('Apply', ...(ngDevMode ? [{ debugName: "applyLabel" }] : []));
|
|
9960
|
+
/** Text of the footer's cancel action. */
|
|
9961
|
+
cancelLabel = input('Cancel', ...(ngDevMode ? [{ debugName: "cancelLabel" }] : []));
|
|
9962
|
+
/** Accessible name of the calendar group (forwarded to `<sds-range-calendar>`). */
|
|
9963
|
+
calendarLabel = input('Calendar', ...(ngDevMode ? [{ debugName: "calendarLabel" }] : []));
|
|
9964
|
+
/** Accessible name of the icon-only "previous month" button. */
|
|
9965
|
+
previousLabel = input('Previous', ...(ngDevMode ? [{ debugName: "previousLabel" }] : []));
|
|
9966
|
+
/** Accessible name of the icon-only "next month" button. */
|
|
9967
|
+
nextLabel = input('Next', ...(ngDevMode ? [{ debugName: "nextLabel" }] : []));
|
|
9968
|
+
/** Emits the preset `id` when a preset is chosen (after `value` has been updated). */
|
|
9969
|
+
presetSelect = output();
|
|
9970
|
+
open = signal(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
|
|
9971
|
+
pendingStart = signal(null, ...(ngDevMode ? [{ debugName: "pendingStart" }] : []));
|
|
9972
|
+
pendingEnd = signal(null, ...(ngDevMode ? [{ debugName: "pendingEnd" }] : []));
|
|
9973
|
+
calendar = viewChild(SdsRangeCalendar, ...(ngDevMode ? [{ debugName: "calendar" }] : []));
|
|
9974
|
+
trigger = viewChild('trigger', ...(ngDevMode ? [{ debugName: "trigger" }] : []));
|
|
9975
|
+
/** The overlay panel, relocated to document.body while open. */
|
|
9976
|
+
panelEl = null;
|
|
9977
|
+
/** Id of the preset the current value equals, or `null` (no value, or a custom range). */
|
|
9978
|
+
activePresetId = computed(() => this.presetIdFor(this.value()), ...(ngDevMode ? [{ debugName: "activePresetId" }] : []));
|
|
9979
|
+
pendingPresetId = computed(() => {
|
|
9980
|
+
const s = this.pendingStart();
|
|
9981
|
+
const e = this.pendingEnd();
|
|
9982
|
+
return s && e ? this.presetIdFor({ start: s, end: e }) : null;
|
|
9983
|
+
}, ...(ngDevMode ? [{ debugName: "pendingPresetId" }] : []));
|
|
9984
|
+
displayValue = computed(() => {
|
|
9985
|
+
const v = this.value();
|
|
9986
|
+
if (!v)
|
|
9987
|
+
return '';
|
|
9988
|
+
const fmt = this.format();
|
|
9989
|
+
return fmt ? fmt(v) : formatDateRange(v, this.locale());
|
|
9990
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
9991
|
+
dayFmt = computed(() => new Intl.DateTimeFormat(this.locale(), { day: 'numeric', month: 'short', year: 'numeric' }), ...(ngDevMode ? [{ debugName: "dayFmt" }] : []));
|
|
9992
|
+
pendingStartText = computed(() => {
|
|
9993
|
+
const s = this.pendingStart();
|
|
9994
|
+
return s ? this.dayFmt().format(s) : '—';
|
|
9995
|
+
}, ...(ngDevMode ? [{ debugName: "pendingStartText" }] : []));
|
|
9996
|
+
pendingEndText = computed(() => {
|
|
9997
|
+
const e = this.pendingEnd();
|
|
9998
|
+
return e ? this.dayFmt().format(e) : '—';
|
|
9999
|
+
}, ...(ngDevMode ? [{ debugName: "pendingEndText" }] : []));
|
|
10000
|
+
canApply = computed(() => !!this.pendingStart() && !!this.pendingEnd(), ...(ngDevMode ? [{ debugName: "canApply" }] : []));
|
|
10001
|
+
triggerClasses = computed(() => {
|
|
10002
|
+
const parts = [
|
|
10003
|
+
'flex w-full items-center gap-2 rounded-control border border-border bg-surface px-3 text-left transition-colors focus-visible:border-brand-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500/25',
|
|
10004
|
+
SIZES$6[this.size()],
|
|
10005
|
+
];
|
|
10006
|
+
if (this.open())
|
|
10007
|
+
parts.push('border-brand-500 ring-2 ring-brand-500/25');
|
|
10008
|
+
parts.push(this.disabled() ? 'cursor-not-allowed opacity-60' : 'cursor-pointer hover:border-ink-faint');
|
|
10009
|
+
return parts.join(' ');
|
|
10010
|
+
}, ...(ngDevMode ? [{ debugName: "triggerClasses" }] : []));
|
|
10011
|
+
cancelBtn = 'rounded-control px-3 py-1.5 text-sm font-medium text-ink-soft hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500';
|
|
10012
|
+
applyBtn = `rounded-control bg-brand-600 px-3 py-1.5 text-sm font-semibold text-white hover:bg-brand-700 ${DARK_BRAND_FILL_HOVER} focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 focus-visible:ring-offset-1 focus-visible:ring-offset-surface disabled:cursor-not-allowed disabled:opacity-40`;
|
|
10013
|
+
presetClass(active) {
|
|
10014
|
+
const base = 'rounded-control px-2.5 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500';
|
|
10015
|
+
return active
|
|
10016
|
+
? `${base} bg-brand-50 font-semibold text-ink`
|
|
10017
|
+
: `${base} text-ink-soft hover:bg-muted hover:text-ink`;
|
|
10018
|
+
}
|
|
10019
|
+
presetIdFor(range) {
|
|
10020
|
+
if (!range)
|
|
10021
|
+
return null;
|
|
10022
|
+
return this.presets().find((p) => isSameRange(p.range(), range))?.id ?? null;
|
|
10023
|
+
}
|
|
10024
|
+
// --- open / close ---
|
|
10025
|
+
toggle(event) {
|
|
10026
|
+
event?.stopPropagation();
|
|
10027
|
+
if (this.disabled())
|
|
10028
|
+
return;
|
|
10029
|
+
this.open() ? this.close() : this.openPanel();
|
|
10030
|
+
}
|
|
10031
|
+
onTriggerArrowDown(event) {
|
|
10032
|
+
event.preventDefault();
|
|
10033
|
+
if (!this.disabled() && !this.open())
|
|
10034
|
+
this.openPanel();
|
|
10035
|
+
}
|
|
10036
|
+
openPanel() {
|
|
10037
|
+
if (this.disabled())
|
|
10038
|
+
return;
|
|
10039
|
+
const v = this.value();
|
|
10040
|
+
this.pendingStart.set(v ? startOfDay(v.start) : null);
|
|
10041
|
+
this.pendingEnd.set(v ? startOfDay(v.end) : null);
|
|
10042
|
+
this.open.set(true);
|
|
10043
|
+
// Run after the overlay is rendered, then relocate it to <body>.
|
|
10044
|
+
afterNextRender(() => {
|
|
10045
|
+
this.panelEl = this.host.nativeElement.querySelector('[role="dialog"]');
|
|
10046
|
+
this.positionPanel(); // also relocates to document.body
|
|
10047
|
+
this.addReflowListeners();
|
|
10048
|
+
this.calendar()?.focusActiveCell();
|
|
10049
|
+
}, { injector: this.injector });
|
|
10050
|
+
}
|
|
10051
|
+
/** Close the panel, discarding a pending (un-applied) custom range. */
|
|
10052
|
+
close(returnFocus = false) {
|
|
10053
|
+
if (!this.open())
|
|
10054
|
+
return;
|
|
10055
|
+
this.removeReflowListeners();
|
|
10056
|
+
this.panelEl?.remove(); // pull the body-relocated node before destroying the view
|
|
10057
|
+
this.panelEl = null;
|
|
10058
|
+
this.open.set(false);
|
|
10059
|
+
if (returnFocus)
|
|
10060
|
+
this.trigger()?.nativeElement.focus();
|
|
10061
|
+
}
|
|
10062
|
+
choosePreset(p) {
|
|
10063
|
+
const r = p.range();
|
|
10064
|
+
this.value.set({ start: startOfDay(r.start), end: startOfDay(r.end) });
|
|
10065
|
+
this.close(true);
|
|
10066
|
+
this.presetSelect.emit(p.id);
|
|
10067
|
+
}
|
|
10068
|
+
apply() {
|
|
10069
|
+
const s = this.pendingStart();
|
|
10070
|
+
const e = this.pendingEnd();
|
|
10071
|
+
if (!s || !e)
|
|
10072
|
+
return;
|
|
10073
|
+
const next = { start: startOfDay(s), end: startOfDay(e) };
|
|
10074
|
+
if (!isSameRange(next, this.value()))
|
|
10075
|
+
this.value.set(next);
|
|
10076
|
+
this.close(true);
|
|
10077
|
+
}
|
|
10078
|
+
/**
|
|
10079
|
+
* Escape closes the panel and consumes the event while it is open, so an ancestor modal does not
|
|
10080
|
+
* also dismiss on the same keystroke. When closed, the event passes through.
|
|
10081
|
+
*/
|
|
10082
|
+
onEscape(event) {
|
|
10083
|
+
if (!this.open())
|
|
10084
|
+
return;
|
|
10085
|
+
event.preventDefault();
|
|
10086
|
+
event.stopPropagation();
|
|
10087
|
+
this.close(true);
|
|
10088
|
+
}
|
|
10089
|
+
/**
|
|
10090
|
+
* Self-contained Tab trap for the overlay. The panel lives in document.body, outside any ancestor
|
|
10091
|
+
* modal's focus trap; this keeps Tab / Shift+Tab cycling within the panel's own focusables.
|
|
10092
|
+
*/
|
|
10093
|
+
onPanelKeydown(event) {
|
|
10094
|
+
if (event.key !== 'Tab' || !this.panelEl)
|
|
10095
|
+
return;
|
|
10096
|
+
const sel = 'a[href],button:not([disabled]):not([tabindex="-1"]),input:not([disabled]),' +
|
|
10097
|
+
'[tabindex]:not([tabindex="-1"])';
|
|
10098
|
+
const items = Array.from(this.panelEl.querySelectorAll(sel)).filter((el) => el.offsetParent !== null);
|
|
10099
|
+
if (items.length === 0)
|
|
10100
|
+
return;
|
|
10101
|
+
const first = items[0];
|
|
10102
|
+
const last = items[items.length - 1];
|
|
10103
|
+
const active = document.activeElement;
|
|
10104
|
+
if (event.shiftKey && (active === first || !this.panelEl.contains(active))) {
|
|
10105
|
+
event.preventDefault();
|
|
10106
|
+
last.focus();
|
|
10107
|
+
}
|
|
10108
|
+
else if (!event.shiftKey && active === last) {
|
|
10109
|
+
event.preventDefault();
|
|
10110
|
+
first.focus();
|
|
10111
|
+
}
|
|
10112
|
+
}
|
|
10113
|
+
onDocumentClick(event) {
|
|
10114
|
+
if (!this.open())
|
|
10115
|
+
return;
|
|
10116
|
+
// composedPath is fixed at dispatch time, so a click on a node re-rendered away still counts.
|
|
10117
|
+
const path = event.composedPath();
|
|
10118
|
+
const inField = path.includes(this.host.nativeElement);
|
|
10119
|
+
const inPanel = !!this.panelEl && path.includes(this.panelEl);
|
|
10120
|
+
if (!inField && !inPanel)
|
|
10121
|
+
this.close();
|
|
10122
|
+
}
|
|
10123
|
+
// --- body-appended overlay positioning ---
|
|
10124
|
+
reflow = () => this.positionPanel();
|
|
10125
|
+
listening = false;
|
|
10126
|
+
addReflowListeners() {
|
|
10127
|
+
if (this.listening)
|
|
10128
|
+
return;
|
|
10129
|
+
window.addEventListener('scroll', this.reflow, true);
|
|
10130
|
+
window.addEventListener('resize', this.reflow);
|
|
10131
|
+
this.listening = true;
|
|
10132
|
+
}
|
|
10133
|
+
removeReflowListeners() {
|
|
10134
|
+
if (!this.listening)
|
|
10135
|
+
return;
|
|
10136
|
+
window.removeEventListener('scroll', this.reflow, true);
|
|
10137
|
+
window.removeEventListener('resize', this.reflow);
|
|
10138
|
+
this.listening = false;
|
|
10139
|
+
}
|
|
10140
|
+
positionPanel() {
|
|
10141
|
+
const triggerEl = this.trigger()?.nativeElement;
|
|
10142
|
+
const panelEl = this.panelEl;
|
|
10143
|
+
if (!triggerEl || !panelEl)
|
|
10144
|
+
return;
|
|
10145
|
+
if (panelEl.parentElement !== document.body) {
|
|
10146
|
+
document.body.appendChild(panelEl);
|
|
10147
|
+
}
|
|
10148
|
+
const r = triggerEl.getBoundingClientRect();
|
|
10149
|
+
const ph = panelEl.offsetHeight || 420;
|
|
10150
|
+
const pw = panelEl.offsetWidth || 760;
|
|
10151
|
+
const gap = 6;
|
|
10152
|
+
const margin = 8;
|
|
10153
|
+
// Below the field by default; flip above when there isn't room; else clamp into the viewport.
|
|
10154
|
+
let top = r.bottom + gap;
|
|
10155
|
+
if (top + ph > window.innerHeight - margin) {
|
|
10156
|
+
if (r.top - gap - ph > margin)
|
|
10157
|
+
top = r.top - gap - ph;
|
|
10158
|
+
else
|
|
10159
|
+
top = Math.max(margin, window.innerHeight - margin - ph);
|
|
10160
|
+
}
|
|
10161
|
+
let left = r.left;
|
|
10162
|
+
if (left + pw > window.innerWidth - margin) {
|
|
10163
|
+
left = Math.max(margin, window.innerWidth - margin - pw);
|
|
10164
|
+
}
|
|
10165
|
+
panelEl.style.top = `${Math.round(top)}px`;
|
|
10166
|
+
panelEl.style.left = `${Math.round(left)}px`;
|
|
10167
|
+
}
|
|
10168
|
+
ngOnDestroy() {
|
|
10169
|
+
this.removeReflowListeners();
|
|
10170
|
+
this.panelEl?.remove();
|
|
10171
|
+
}
|
|
10172
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsDateRangePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10173
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsDateRangePicker, isStandalone: true, selector: "sds-date-range-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, presets: { classPropertyName: "presets", publicName: "presets", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, maxDays: { classPropertyName: "maxDays", publicName: "maxDays", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", 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 }, months: { classPropertyName: "months", publicName: "months", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, panelLabel: { classPropertyName: "panelLabel", publicName: "panelLabel", isSignal: true, isRequired: false, transformFunction: null }, presetsLabel: { classPropertyName: "presetsLabel", publicName: "presetsLabel", isSignal: true, isRequired: false, transformFunction: null }, startLabel: { classPropertyName: "startLabel", publicName: "startLabel", isSignal: true, isRequired: false, transformFunction: null }, endLabel: { classPropertyName: "endLabel", publicName: "endLabel", isSignal: true, isRequired: false, transformFunction: null }, applyLabel: { classPropertyName: "applyLabel", publicName: "applyLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, calendarLabel: { classPropertyName: "calendarLabel", publicName: "calendarLabel", isSignal: true, isRequired: false, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", presetSelect: "presetSelect" }, host: { listeners: { "document:click": "onDocumentClick($event)", "keydown.escape": "onEscape($event)" }, classAttribute: "block" }, viewQueries: [{ propertyName: "calendar", first: true, predicate: SdsRangeCalendar, descendants: true, isSignal: true }, { propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
10174
|
+
@if (label()) {
|
|
10175
|
+
<label [id]="labelId" [for]="fieldId" class="mb-1.5 block text-sm font-medium text-ink">
|
|
10176
|
+
{{ label() }}
|
|
10177
|
+
</label>
|
|
10178
|
+
}
|
|
10179
|
+
|
|
10180
|
+
<button
|
|
10181
|
+
#trigger
|
|
10182
|
+
type="button"
|
|
10183
|
+
[id]="fieldId"
|
|
10184
|
+
[disabled]="disabled()"
|
|
10185
|
+
aria-haspopup="dialog"
|
|
10186
|
+
[attr.aria-expanded]="open()"
|
|
10187
|
+
[attr.aria-labelledby]="label() ? labelId + ' ' + valueId : null"
|
|
10188
|
+
[attr.aria-label]="!label() && ariaLabel() ? ariaLabel() + ', ' + (displayValue() || placeholder()) : null"
|
|
10189
|
+
[class]="triggerClasses()"
|
|
10190
|
+
(click)="toggle($event)"
|
|
10191
|
+
(keydown.arrowdown)="onTriggerArrowDown($event)"
|
|
10192
|
+
>
|
|
10193
|
+
<sds-icon name="calendar" [size]="17" class="shrink-0 text-ink-soft" />
|
|
10194
|
+
<span
|
|
10195
|
+
[id]="valueId"
|
|
10196
|
+
class="min-w-0 flex-1 truncate"
|
|
10197
|
+
[class.text-ink]="!!displayValue()"
|
|
10198
|
+
[class.text-ink-faint]="!displayValue()"
|
|
10199
|
+
>
|
|
10200
|
+
{{ displayValue() || placeholder() }}
|
|
10201
|
+
</span>
|
|
10202
|
+
<span
|
|
10203
|
+
class="inline-flex shrink-0 text-ink-faint transition-transform"
|
|
10204
|
+
[class.rotate-180]="open()"
|
|
10205
|
+
aria-hidden="true"
|
|
10206
|
+
>
|
|
10207
|
+
<sds-icon name="chevron-down" [size]="16" />
|
|
10208
|
+
</span>
|
|
10209
|
+
</button>
|
|
10210
|
+
|
|
10211
|
+
@if (open()) {
|
|
10212
|
+
<!-- Relocated to document.body on open (appendTo body) to escape ancestor overflow/stacking;
|
|
10213
|
+
positioned via positionPanel(). -->
|
|
10214
|
+
<div
|
|
10215
|
+
class="fixed z-[1000] max-w-[calc(100vw-1rem)] overflow-auto rounded-card border border-border bg-surface shadow-lg"
|
|
10216
|
+
style="max-height: calc(100vh - 1rem)"
|
|
10217
|
+
role="dialog"
|
|
10218
|
+
aria-modal="false"
|
|
10219
|
+
[attr.aria-label]="panelLabel()"
|
|
10220
|
+
(keydown.escape)="onEscape($event)"
|
|
10221
|
+
(keydown)="onPanelKeydown($event)"
|
|
10222
|
+
>
|
|
10223
|
+
<div class="flex flex-col sm:flex-row">
|
|
10224
|
+
@if (presets().length) {
|
|
10225
|
+
<div
|
|
10226
|
+
class="border-b border-border p-2 sm:w-44 sm:shrink-0 sm:border-b-0 sm:border-r"
|
|
10227
|
+
role="group"
|
|
10228
|
+
[attr.aria-label]="presetsLabel()"
|
|
9094
10229
|
>
|
|
9095
|
-
<
|
|
9096
|
-
|
|
10230
|
+
<p class="px-2 pb-1.5 pt-1 text-[11px] font-semibold uppercase tracking-wide text-ink-faint">
|
|
10231
|
+
{{ presetsLabel() }}
|
|
10232
|
+
</p>
|
|
10233
|
+
<div class="flex flex-wrap gap-1 sm:flex-col sm:flex-nowrap">
|
|
10234
|
+
@for (p of presets(); track p.id) {
|
|
10235
|
+
<button
|
|
10236
|
+
type="button"
|
|
10237
|
+
[attr.aria-pressed]="p.id === pendingPresetId()"
|
|
10238
|
+
[class]="presetClass(p.id === pendingPresetId())"
|
|
10239
|
+
(click)="choosePreset(p)"
|
|
10240
|
+
>
|
|
10241
|
+
{{ p.label }}
|
|
10242
|
+
</button>
|
|
10243
|
+
}
|
|
10244
|
+
</div>
|
|
10245
|
+
</div>
|
|
9097
10246
|
}
|
|
9098
10247
|
|
|
9099
|
-
<
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
10248
|
+
<div class="flex min-w-0 flex-col">
|
|
10249
|
+
<div class="p-3">
|
|
10250
|
+
<sds-range-calendar
|
|
10251
|
+
[(start)]="pendingStart"
|
|
10252
|
+
[(end)]="pendingEnd"
|
|
10253
|
+
[min]="min()"
|
|
10254
|
+
[max]="max()"
|
|
10255
|
+
[maxDays]="maxDays()"
|
|
10256
|
+
[firstDayOfWeek]="firstDayOfWeek()"
|
|
10257
|
+
[locale]="locale()"
|
|
10258
|
+
[months]="months()"
|
|
10259
|
+
[calendarLabel]="calendarLabel()"
|
|
10260
|
+
[previousLabel]="previousLabel()"
|
|
10261
|
+
[nextLabel]="nextLabel()"
|
|
10262
|
+
/>
|
|
10263
|
+
</div>
|
|
9109
10264
|
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9136
|
-
|
|
9137
|
-
[todayActionLabel]="todayActionLabel()"
|
|
9138
|
-
[clearActionLabel]="clearActionLabel()"
|
|
9139
|
-
(valueChange)="onCalendarValue($event)"
|
|
9140
|
-
(dateSelect)="onDateSelect()"
|
|
9141
|
-
(done)="close(true)"
|
|
9142
|
-
/>
|
|
10265
|
+
<div
|
|
10266
|
+
class="flex flex-wrap items-center justify-between gap-x-4 gap-y-2 border-t border-border px-3 py-2.5"
|
|
10267
|
+
>
|
|
10268
|
+
<p class="flex items-stretch gap-2 text-sm" aria-live="polite">
|
|
10269
|
+
<span class="flex flex-col leading-tight">
|
|
10270
|
+
<span class="text-[11px] font-medium uppercase text-ink-faint">{{ startLabel() }}</span>
|
|
10271
|
+
<span class="font-medium" [class.text-ink]="pendingStart()" [class.text-ink-faint]="!pendingStart()">
|
|
10272
|
+
{{ pendingStartText() }}
|
|
10273
|
+
</span>
|
|
10274
|
+
</span>
|
|
10275
|
+
<span class="self-end text-ink-faint" aria-hidden="true">–</span>
|
|
10276
|
+
<span class="flex flex-col leading-tight">
|
|
10277
|
+
<span class="text-[11px] font-medium uppercase text-ink-faint">{{ endLabel() }}</span>
|
|
10278
|
+
<span class="font-medium" [class.text-ink]="pendingEnd()" [class.text-ink-faint]="!pendingEnd()">
|
|
10279
|
+
{{ pendingEndText() }}
|
|
10280
|
+
</span>
|
|
10281
|
+
</span>
|
|
10282
|
+
</p>
|
|
10283
|
+
<div class="ml-auto flex items-center gap-2">
|
|
10284
|
+
<button type="button" [class]="cancelBtn" (click)="close(true)">
|
|
10285
|
+
{{ cancelLabel() }}
|
|
10286
|
+
</button>
|
|
10287
|
+
<button type="button" [class]="applyBtn" [disabled]="!canApply()" (click)="apply()">
|
|
10288
|
+
{{ applyLabel() }}
|
|
10289
|
+
</button>
|
|
10290
|
+
</div>
|
|
10291
|
+
</div>
|
|
9143
10292
|
</div>
|
|
9144
|
-
|
|
10293
|
+
</div>
|
|
9145
10294
|
</div>
|
|
9146
10295
|
}
|
|
9147
|
-
|
|
9148
|
-
@if (hint() && !error()) {
|
|
9149
|
-
<p class="mt-1.5 text-xs text-ink-faint">{{ hint() }}</p>
|
|
9150
|
-
}
|
|
9151
|
-
@if (error()) {
|
|
9152
|
-
<p class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
|
|
9153
|
-
}
|
|
9154
|
-
`, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth", "filled"] }, { kind: "component", type: SdsCalendar, selector: "sds-calendar", inputs: ["value", "min", "max", "firstDayOfWeek", "locale", "showActions", "showTime", "showDone", "timeLabel", "hoursLabel", "minutesLabel", "doneLabel", "calendarLabel", "previousLabel", "nextLabel", "todayActionLabel", "clearActionLabel"], outputs: ["valueChange", "dateSelect", "done"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10296
|
+
`, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth", "filled"] }, { kind: "component", type: SdsRangeCalendar, selector: "sds-range-calendar", inputs: ["start", "end", "min", "max", "maxDays", "firstDayOfWeek", "locale", "months", "calendarLabel", "previousLabel", "nextLabel"], outputs: ["startChange", "endChange", "daySelect", "rangeSelect", "dayHover"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9155
10297
|
}
|
|
9156
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type:
|
|
10298
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsDateRangePicker, decorators: [{
|
|
9157
10299
|
type: Component,
|
|
9158
10300
|
args: [{
|
|
9159
|
-
selector: 'sds-date-picker',
|
|
10301
|
+
selector: 'sds-date-range-picker',
|
|
9160
10302
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
9161
|
-
imports: [SdsIcon,
|
|
9162
|
-
providers: [
|
|
9163
|
-
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SdsDatePicker), multi: true },
|
|
9164
|
-
],
|
|
10303
|
+
imports: [SdsIcon, SdsRangeCalendar],
|
|
9165
10304
|
host: {
|
|
9166
10305
|
class: 'block',
|
|
9167
10306
|
'(document:click)': 'onDocumentClick($event)',
|
|
@@ -9169,126 +10308,130 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
9169
10308
|
},
|
|
9170
10309
|
template: `
|
|
9171
10310
|
@if (label()) {
|
|
9172
|
-
<label [for]="fieldId" class="mb-1.5 block text-sm font-medium text-ink">
|
|
10311
|
+
<label [id]="labelId" [for]="fieldId" class="mb-1.5 block text-sm font-medium text-ink">
|
|
9173
10312
|
{{ label() }}
|
|
9174
10313
|
</label>
|
|
9175
10314
|
}
|
|
9176
10315
|
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9192
|
-
[
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
|
|
9200
|
-
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
readonly
|
|
9208
|
-
[value]="displayValue()"
|
|
9209
|
-
[placeholder]="placeholder()"
|
|
9210
|
-
[disabled]="isDisabled()"
|
|
9211
|
-
[attr.aria-haspopup]="'dialog'"
|
|
9212
|
-
[attr.aria-expanded]="open()"
|
|
9213
|
-
[attr.aria-label]="!label() && ariaLabel() ? ariaLabel() : null"
|
|
9214
|
-
(keydown.enter)="onTriggerKeydown($event)"
|
|
9215
|
-
(keydown.space)="onTriggerKeydown($event)"
|
|
9216
|
-
(keydown.arrowdown)="onTriggerKeydown($event)"
|
|
9217
|
-
class="w-full cursor-pointer bg-transparent pl-3.5 text-ink outline-none placeholder:text-ink-faint disabled:cursor-not-allowed"
|
|
9218
|
-
[class.pr-20]="showClear()"
|
|
9219
|
-
[class.pr-11]="!showClear()"
|
|
9220
|
-
/>
|
|
10316
|
+
<button
|
|
10317
|
+
#trigger
|
|
10318
|
+
type="button"
|
|
10319
|
+
[id]="fieldId"
|
|
10320
|
+
[disabled]="disabled()"
|
|
10321
|
+
aria-haspopup="dialog"
|
|
10322
|
+
[attr.aria-expanded]="open()"
|
|
10323
|
+
[attr.aria-labelledby]="label() ? labelId + ' ' + valueId : null"
|
|
10324
|
+
[attr.aria-label]="!label() && ariaLabel() ? ariaLabel() + ', ' + (displayValue() || placeholder()) : null"
|
|
10325
|
+
[class]="triggerClasses()"
|
|
10326
|
+
(click)="toggle($event)"
|
|
10327
|
+
(keydown.arrowdown)="onTriggerArrowDown($event)"
|
|
10328
|
+
>
|
|
10329
|
+
<sds-icon name="calendar" [size]="17" class="shrink-0 text-ink-soft" />
|
|
10330
|
+
<span
|
|
10331
|
+
[id]="valueId"
|
|
10332
|
+
class="min-w-0 flex-1 truncate"
|
|
10333
|
+
[class.text-ink]="!!displayValue()"
|
|
10334
|
+
[class.text-ink-faint]="!displayValue()"
|
|
10335
|
+
>
|
|
10336
|
+
{{ displayValue() || placeholder() }}
|
|
10337
|
+
</span>
|
|
10338
|
+
<span
|
|
10339
|
+
class="inline-flex shrink-0 text-ink-faint transition-transform"
|
|
10340
|
+
[class.rotate-180]="open()"
|
|
10341
|
+
aria-hidden="true"
|
|
10342
|
+
>
|
|
10343
|
+
<sds-icon name="chevron-down" [size]="16" />
|
|
10344
|
+
</span>
|
|
10345
|
+
</button>
|
|
9221
10346
|
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
10347
|
+
@if (open()) {
|
|
10348
|
+
<!-- Relocated to document.body on open (appendTo body) to escape ancestor overflow/stacking;
|
|
10349
|
+
positioned via positionPanel(). -->
|
|
10350
|
+
<div
|
|
10351
|
+
class="fixed z-[1000] max-w-[calc(100vw-1rem)] overflow-auto rounded-card border border-border bg-surface shadow-lg"
|
|
10352
|
+
style="max-height: calc(100vh - 1rem)"
|
|
10353
|
+
role="dialog"
|
|
10354
|
+
aria-modal="false"
|
|
10355
|
+
[attr.aria-label]="panelLabel()"
|
|
10356
|
+
(keydown.escape)="onEscape($event)"
|
|
10357
|
+
(keydown)="onPanelKeydown($event)"
|
|
10358
|
+
>
|
|
10359
|
+
<div class="flex flex-col sm:flex-row">
|
|
10360
|
+
@if (presets().length) {
|
|
10361
|
+
<div
|
|
10362
|
+
class="border-b border-border p-2 sm:w-44 sm:shrink-0 sm:border-b-0 sm:border-r"
|
|
10363
|
+
role="group"
|
|
10364
|
+
[attr.aria-label]="presetsLabel()"
|
|
9229
10365
|
>
|
|
9230
|
-
<
|
|
9231
|
-
|
|
10366
|
+
<p class="px-2 pb-1.5 pt-1 text-[11px] font-semibold uppercase tracking-wide text-ink-faint">
|
|
10367
|
+
{{ presetsLabel() }}
|
|
10368
|
+
</p>
|
|
10369
|
+
<div class="flex flex-wrap gap-1 sm:flex-col sm:flex-nowrap">
|
|
10370
|
+
@for (p of presets(); track p.id) {
|
|
10371
|
+
<button
|
|
10372
|
+
type="button"
|
|
10373
|
+
[attr.aria-pressed]="p.id === pendingPresetId()"
|
|
10374
|
+
[class]="presetClass(p.id === pendingPresetId())"
|
|
10375
|
+
(click)="choosePreset(p)"
|
|
10376
|
+
>
|
|
10377
|
+
{{ p.label }}
|
|
10378
|
+
</button>
|
|
10379
|
+
}
|
|
10380
|
+
</div>
|
|
10381
|
+
</div>
|
|
9232
10382
|
}
|
|
9233
10383
|
|
|
9234
|
-
<
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
10384
|
+
<div class="flex min-w-0 flex-col">
|
|
10385
|
+
<div class="p-3">
|
|
10386
|
+
<sds-range-calendar
|
|
10387
|
+
[(start)]="pendingStart"
|
|
10388
|
+
[(end)]="pendingEnd"
|
|
10389
|
+
[min]="min()"
|
|
10390
|
+
[max]="max()"
|
|
10391
|
+
[maxDays]="maxDays()"
|
|
10392
|
+
[firstDayOfWeek]="firstDayOfWeek()"
|
|
10393
|
+
[locale]="locale()"
|
|
10394
|
+
[months]="months()"
|
|
10395
|
+
[calendarLabel]="calendarLabel()"
|
|
10396
|
+
[previousLabel]="previousLabel()"
|
|
10397
|
+
[nextLabel]="nextLabel()"
|
|
10398
|
+
/>
|
|
10399
|
+
</div>
|
|
9244
10400
|
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
|
|
9262
|
-
|
|
9263
|
-
|
|
9264
|
-
|
|
9265
|
-
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
|
|
9269
|
-
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
[todayActionLabel]="todayActionLabel()"
|
|
9273
|
-
[clearActionLabel]="clearActionLabel()"
|
|
9274
|
-
(valueChange)="onCalendarValue($event)"
|
|
9275
|
-
(dateSelect)="onDateSelect()"
|
|
9276
|
-
(done)="close(true)"
|
|
9277
|
-
/>
|
|
10401
|
+
<div
|
|
10402
|
+
class="flex flex-wrap items-center justify-between gap-x-4 gap-y-2 border-t border-border px-3 py-2.5"
|
|
10403
|
+
>
|
|
10404
|
+
<p class="flex items-stretch gap-2 text-sm" aria-live="polite">
|
|
10405
|
+
<span class="flex flex-col leading-tight">
|
|
10406
|
+
<span class="text-[11px] font-medium uppercase text-ink-faint">{{ startLabel() }}</span>
|
|
10407
|
+
<span class="font-medium" [class.text-ink]="pendingStart()" [class.text-ink-faint]="!pendingStart()">
|
|
10408
|
+
{{ pendingStartText() }}
|
|
10409
|
+
</span>
|
|
10410
|
+
</span>
|
|
10411
|
+
<span class="self-end text-ink-faint" aria-hidden="true">–</span>
|
|
10412
|
+
<span class="flex flex-col leading-tight">
|
|
10413
|
+
<span class="text-[11px] font-medium uppercase text-ink-faint">{{ endLabel() }}</span>
|
|
10414
|
+
<span class="font-medium" [class.text-ink]="pendingEnd()" [class.text-ink-faint]="!pendingEnd()">
|
|
10415
|
+
{{ pendingEndText() }}
|
|
10416
|
+
</span>
|
|
10417
|
+
</span>
|
|
10418
|
+
</p>
|
|
10419
|
+
<div class="ml-auto flex items-center gap-2">
|
|
10420
|
+
<button type="button" [class]="cancelBtn" (click)="close(true)">
|
|
10421
|
+
{{ cancelLabel() }}
|
|
10422
|
+
</button>
|
|
10423
|
+
<button type="button" [class]="applyBtn" [disabled]="!canApply()" (click)="apply()">
|
|
10424
|
+
{{ applyLabel() }}
|
|
10425
|
+
</button>
|
|
10426
|
+
</div>
|
|
10427
|
+
</div>
|
|
9278
10428
|
</div>
|
|
9279
|
-
|
|
10429
|
+
</div>
|
|
9280
10430
|
</div>
|
|
9281
10431
|
}
|
|
9282
|
-
|
|
9283
|
-
@if (hint() && !error()) {
|
|
9284
|
-
<p class="mt-1.5 text-xs text-ink-faint">{{ hint() }}</p>
|
|
9285
|
-
}
|
|
9286
|
-
@if (error()) {
|
|
9287
|
-
<p class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
|
|
9288
|
-
}
|
|
9289
10432
|
`,
|
|
9290
10433
|
}]
|
|
9291
|
-
}], propDecorators: {
|
|
10434
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], presets: [{ type: i0.Input, args: [{ isSignal: true, alias: "presets", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], maxDays: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDays", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], months: [{ type: i0.Input, args: [{ isSignal: true, alias: "months", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], panelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelLabel", required: false }] }], presetsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "presetsLabel", required: false }] }], startLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "startLabel", required: false }] }], endLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "endLabel", required: false }] }], applyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "applyLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], calendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "calendarLabel", required: false }] }], previousLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], presetSelect: [{ type: i0.Output, args: ["presetSelect"] }], calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdsRangeCalendar), { isSignal: true }] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
|
|
9292
10435
|
let nextId$8 = 0;
|
|
9293
10436
|
|
|
9294
10437
|
/**
|
|
@@ -18885,12 +20028,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
18885
20028
|
}]
|
|
18886
20029
|
}], propDecorators: { env: [{ type: i0.Input, args: [{ isSignal: true, alias: "env", required: false }] }], devSrLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "devSrLabel", required: false }] }], testSrLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "testSrLabel", required: false }] }] } });
|
|
18887
20030
|
|
|
20031
|
+
/** English defaults of {@link SdsChartLabels}. Spread it to override a few keys. */
|
|
20032
|
+
const SDS_CHART_LABELS_EN = {
|
|
20033
|
+
legend: 'Legend',
|
|
20034
|
+
showTable: 'Table',
|
|
20035
|
+
showChart: 'Chart',
|
|
20036
|
+
empty: 'No data to display',
|
|
20037
|
+
noData: 'No data',
|
|
20038
|
+
chartRole: 'chart',
|
|
20039
|
+
heatmapRole: 'heatmap',
|
|
20040
|
+
lineChart: 'Line chart',
|
|
20041
|
+
barChart: 'Bar chart',
|
|
20042
|
+
donutChart: 'Donut chart',
|
|
20043
|
+
scatterChart: 'Scatter plot',
|
|
20044
|
+
heatmap: 'Heatmap',
|
|
20045
|
+
treemap: 'Treemap',
|
|
20046
|
+
breadcrumb: 'Breadcrumb',
|
|
20047
|
+
trend: 'Trend',
|
|
20048
|
+
category: 'Category',
|
|
20049
|
+
date: 'Date',
|
|
20050
|
+
value: 'Value',
|
|
20051
|
+
share: 'Share',
|
|
20052
|
+
item: 'Item',
|
|
20053
|
+
group: 'Group',
|
|
20054
|
+
size: 'Size',
|
|
20055
|
+
total: 'Total',
|
|
20056
|
+
other: 'Other',
|
|
20057
|
+
all: 'All',
|
|
20058
|
+
shareOfTotal: 'Share of total',
|
|
20059
|
+
shareOf: (parent) => `Share of ${parent}`,
|
|
20060
|
+
labelValue: (label, value) => `${label}: ${value}`,
|
|
20061
|
+
sliceCount: (n) => `${n} ${n === 1 ? 'slice' : 'slices'}`,
|
|
20062
|
+
totalOf: (value) => `total ${value}`,
|
|
20063
|
+
gridSize: (rows, columns) => `${rows} ${rows === 1 ? 'row' : 'rows'} × ${columns} ${columns === 1 ? 'column' : 'columns'}`,
|
|
20064
|
+
itemCount: (n) => `${n} ${n === 1 ? 'item' : 'items'}`,
|
|
20065
|
+
zoomedTo: (path) => `zoomed to ${path}`,
|
|
20066
|
+
versus: (y, x) => `${y} vs ${x}`,
|
|
20067
|
+
sparklineSummary: (s) => `${s.label || 'Trend'}: from ${s.first} to ${s.last} — min ${s.min}, max ${s.max}, ${s.count} ${s.count === 1 ? 'point' : 'points'}`,
|
|
20068
|
+
kpiChange: ({ direction, delta, period, good }) => {
|
|
20069
|
+
const p = period ? ` ${period}` : '';
|
|
20070
|
+
if (direction === 'flat')
|
|
20071
|
+
return `unchanged${p}`;
|
|
20072
|
+
const verdict = good === null ? '' : good ? ', favourable' : ', unfavourable';
|
|
20073
|
+
return `${direction === 'up' ? 'up' : 'down'} ${delta}${p}${verdict}`;
|
|
20074
|
+
},
|
|
20075
|
+
};
|
|
18888
20076
|
const SDS_CHART_CONFIG = new InjectionToken('SDS_CHART_CONFIG');
|
|
18889
20077
|
/**
|
|
18890
20078
|
* App-wide chart defaults.
|
|
18891
20079
|
*
|
|
18892
20080
|
* @example
|
|
18893
|
-
* providers: [
|
|
20081
|
+
* providers: [
|
|
20082
|
+
* provideSdsCharts({
|
|
20083
|
+
* locale: () => translate.currentLang(),
|
|
20084
|
+
* labels: () => (translate.currentLang() === 'fr' ? CHART_LABELS_FR : {}),
|
|
20085
|
+
* }),
|
|
20086
|
+
* ]
|
|
18894
20087
|
*/
|
|
18895
20088
|
function provideSdsCharts(config) {
|
|
18896
20089
|
return { provide: SDS_CHART_CONFIG, useValue: config };
|
|
@@ -19040,7 +20233,7 @@ const INK_HI = 'var(--sds-chart-ink-hi, #ffffff)';
|
|
|
19040
20233
|
// ---------------------------------------------------------------------------------------------------
|
|
19041
20234
|
// Locale & formatting
|
|
19042
20235
|
// ---------------------------------------------------------------------------------------------------
|
|
19043
|
-
/** Resolve the chart locale: explicit input → provideSdsCharts() → Angular LOCALE_ID. */
|
|
20236
|
+
/** Resolve the chart locale: explicit input → provideSdsCharts() → Angular LOCALE_ID → en-GB. */
|
|
19044
20237
|
function chartLocale(explicit) {
|
|
19045
20238
|
const config = inject(SDS_CHART_CONFIG, { optional: true });
|
|
19046
20239
|
const ngLocale = inject(LOCALE_ID);
|
|
@@ -19050,7 +20243,19 @@ function chartLocale(explicit) {
|
|
|
19050
20243
|
return own;
|
|
19051
20244
|
const cfg = config?.locale;
|
|
19052
20245
|
const resolved = typeof cfg === 'function' ? cfg() : cfg;
|
|
19053
|
-
return resolved || ngLocale || '
|
|
20246
|
+
return resolved || ngLocale || 'en-GB';
|
|
20247
|
+
});
|
|
20248
|
+
}
|
|
20249
|
+
/**
|
|
20250
|
+
* The chart strings: provideSdsCharts({ labels }) merged over the English defaults. The function
|
|
20251
|
+
* form is called inside the computed, so labels returned from a signal switch language live.
|
|
20252
|
+
*/
|
|
20253
|
+
function chartLabels() {
|
|
20254
|
+
const config = inject(SDS_CHART_CONFIG, { optional: true });
|
|
20255
|
+
return computed(() => {
|
|
20256
|
+
const own = config?.labels;
|
|
20257
|
+
const resolved = typeof own === 'function' ? own() : own;
|
|
20258
|
+
return resolved ? { ...SDS_CHART_LABELS_EN, ...resolved } : SDS_CHART_LABELS_EN;
|
|
19054
20259
|
});
|
|
19055
20260
|
}
|
|
19056
20261
|
function chartAnimates(explicit) {
|
|
@@ -19512,18 +20717,18 @@ class SdsChartFrame {
|
|
|
19512
20717
|
subtitle = input('', ...(ngDevMode ? [{ debugName: "subtitle" }] : []));
|
|
19513
20718
|
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
19514
20719
|
legend = input('top', ...(ngDevMode ? [{ debugName: "legend" }] : []));
|
|
19515
|
-
legendLabel = input('Légende', ...(ngDevMode ? [{ debugName: "legendLabel" }] : []));
|
|
19516
20720
|
hidden = input([], ...(ngDevMode ? [{ debugName: "hidden" }] : []));
|
|
19517
20721
|
interactive = input(true, ...(ngDevMode ? [{ debugName: "interactive", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
19518
20722
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
19519
20723
|
empty = input(false, ...(ngDevMode ? [{ debugName: "empty", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
19520
|
-
|
|
20724
|
+
/** Empty-state text; '' falls back to the configured labels. */
|
|
20725
|
+
emptyText = input(null, ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
19521
20726
|
height = input(300, ...(ngDevMode ? [{ debugName: "height" }] : []));
|
|
19522
20727
|
table = input({ columns: [], rows: [] }, ...(ngDevMode ? [{ debugName: "table" }] : []));
|
|
19523
20728
|
tableCaption = input('', ...(ngDevMode ? [{ debugName: "tableCaption" }] : []));
|
|
19524
20729
|
tableToggle = input(false, ...(ngDevMode ? [{ debugName: "tableToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
19525
|
-
|
|
19526
|
-
|
|
20730
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
20731
|
+
text = chartLabels();
|
|
19527
20732
|
toggle = output();
|
|
19528
20733
|
focusKey = output();
|
|
19529
20734
|
showTable = signal(false, ...(ngDevMode ? [{ debugName: "showTable" }] : []));
|
|
@@ -19540,7 +20745,7 @@ class SdsChartFrame {
|
|
|
19540
20745
|
this.toggle.emit(key);
|
|
19541
20746
|
}
|
|
19542
20747
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsChartFrame, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19543
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsChartFrame, isStandalone: true, selector: "sds-chart-frame", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null },
|
|
20748
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsChartFrame, isStandalone: true, selector: "sds-chart-frame", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, empty: { classPropertyName: "empty", publicName: "empty", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, table: { classPropertyName: "table", publicName: "table", isSignal: true, isRequired: false, transformFunction: null }, tableCaption: { classPropertyName: "tableCaption", publicName: "tableCaption", isSignal: true, isRequired: false, transformFunction: null }, tableToggle: { classPropertyName: "tableToggle", publicName: "tableToggle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggle: "toggle", focusKey: "focusKey" }, host: { classAttribute: "block @container" }, ngImport: i0, template: `
|
|
19544
20749
|
<figure class="m-0 flex flex-col gap-3" [attr.aria-busy]="loading() || null">
|
|
19545
20750
|
@if (heading() || subtitle() || tableToggle()) {
|
|
19546
20751
|
<figcaption class="flex items-start justify-between gap-3">
|
|
@@ -19559,7 +20764,7 @@ class SdsChartFrame {
|
|
|
19559
20764
|
(click)="showTable.set(!showTable())"
|
|
19560
20765
|
>
|
|
19561
20766
|
<sds-icon [name]="showTable() ? 'chart-column' : 'table'" [size]="14" />
|
|
19562
|
-
{{ showTable() ?
|
|
20767
|
+
{{ showTable() ? text().showChart : text().showTable }}
|
|
19563
20768
|
</button>
|
|
19564
20769
|
}
|
|
19565
20770
|
</figcaption>
|
|
@@ -19577,7 +20782,7 @@ class SdsChartFrame {
|
|
|
19577
20782
|
>
|
|
19578
20783
|
<div class="flex flex-col items-center gap-2 px-4 text-ink-faint">
|
|
19579
20784
|
<sds-icon name="bar-chart-3" [size]="22" />
|
|
19580
|
-
<p class="text-sm">{{ emptyText() }}</p>
|
|
20785
|
+
<p class="text-sm">{{ emptyText() || text().empty }}</p>
|
|
19581
20786
|
</div>
|
|
19582
20787
|
</div>
|
|
19583
20788
|
} @else if (showTable()) {
|
|
@@ -19608,7 +20813,7 @@ class SdsChartFrame {
|
|
|
19608
20813
|
class="flex flex-wrap gap-x-4 gap-y-1.5"
|
|
19609
20814
|
[class.@lg:flex-col]="legend() === 'right'"
|
|
19610
20815
|
[class.@lg:min-w-44]="legend() === 'right'"
|
|
19611
|
-
[attr.aria-label]="
|
|
20816
|
+
[attr.aria-label]="text().legend"
|
|
19612
20817
|
>
|
|
19613
20818
|
@for (item of items(); track item.key) {
|
|
19614
20819
|
<li>
|
|
@@ -19723,7 +20928,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
19723
20928
|
(click)="showTable.set(!showTable())"
|
|
19724
20929
|
>
|
|
19725
20930
|
<sds-icon [name]="showTable() ? 'chart-column' : 'table'" [size]="14" />
|
|
19726
|
-
{{ showTable() ?
|
|
20931
|
+
{{ showTable() ? text().showChart : text().showTable }}
|
|
19727
20932
|
</button>
|
|
19728
20933
|
}
|
|
19729
20934
|
</figcaption>
|
|
@@ -19741,7 +20946,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
19741
20946
|
>
|
|
19742
20947
|
<div class="flex flex-col items-center gap-2 px-4 text-ink-faint">
|
|
19743
20948
|
<sds-icon name="bar-chart-3" [size]="22" />
|
|
19744
|
-
<p class="text-sm">{{ emptyText() }}</p>
|
|
20949
|
+
<p class="text-sm">{{ emptyText() || text().empty }}</p>
|
|
19745
20950
|
</div>
|
|
19746
20951
|
</div>
|
|
19747
20952
|
} @else if (showTable()) {
|
|
@@ -19772,7 +20977,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
19772
20977
|
class="flex flex-wrap gap-x-4 gap-y-1.5"
|
|
19773
20978
|
[class.@lg:flex-col]="legend() === 'right'"
|
|
19774
20979
|
[class.@lg:min-w-44]="legend() === 'right'"
|
|
19775
|
-
[attr.aria-label]="
|
|
20980
|
+
[attr.aria-label]="text().legend"
|
|
19776
20981
|
>
|
|
19777
20982
|
@for (item of items(); track item.key) {
|
|
19778
20983
|
<li>
|
|
@@ -19865,7 +21070,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
19865
21070
|
</table>
|
|
19866
21071
|
</ng-template>
|
|
19867
21072
|
`, styles: [".sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
|
|
19868
|
-
}], propDecorators: { heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], legend: [{ type: i0.Input, args: [{ isSignal: true, alias: "legend", required: false }] }],
|
|
21073
|
+
}], propDecorators: { heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], legend: [{ type: i0.Input, args: [{ isSignal: true, alias: "legend", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], empty: [{ type: i0.Input, args: [{ isSignal: true, alias: "empty", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], table: [{ type: i0.Input, args: [{ isSignal: true, alias: "table", required: false }] }], tableCaption: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableCaption", required: false }] }], tableToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableToggle", required: false }] }], toggle: [{ type: i0.Output, args: ["toggle"] }], focusKey: [{ type: i0.Output, args: ["focusKey"] }] } });
|
|
19869
21074
|
/** The floating tooltip: default rows, or the consumer's `sdsChartTooltip` template. */
|
|
19870
21075
|
class SdsChartTooltipBox {
|
|
19871
21076
|
ctx = input(null, ...(ngDevMode ? [{ debugName: "ctx" }] : []));
|
|
@@ -20223,7 +21428,8 @@ class SdsLineChart {
|
|
|
20223
21428
|
animate = input(true, ...(ngDevMode ? [{ debugName: "animate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
20224
21429
|
/** Hold the current render at reduced opacity while new data loads (no skeleton flash). */
|
|
20225
21430
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
20226
|
-
|
|
21431
|
+
/** Empty-state text. Default (`null`): the configured `labels.empty` ("No data to display"). */
|
|
21432
|
+
emptyText = input(null, ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
20227
21433
|
/** Show a button that swaps the plot for its data table. */
|
|
20228
21434
|
tableToggle = input(false, ...(ngDevMode ? [{ debugName: "tableToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
20229
21435
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
@@ -20245,6 +21451,8 @@ class SdsLineChart {
|
|
|
20245
21451
|
pointerY = signal(0, ...(ngDevMode ? [{ debugName: "pointerY" }] : []));
|
|
20246
21452
|
width = hostWidth();
|
|
20247
21453
|
loc = chartLocale(() => this.locale());
|
|
21454
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
21455
|
+
text = chartLabels();
|
|
20248
21456
|
animates = chartAnimates(() => this.animate());
|
|
20249
21457
|
palette = chartPalette();
|
|
20250
21458
|
stacked = computed(() => this.stack() !== 'none', ...(ngDevMode ? [{ debugName: "stacked" }] : []));
|
|
@@ -20700,7 +21908,7 @@ class SdsLineChart {
|
|
|
20700
21908
|
return { key: s.key, label: s.label, value, raw, color: s.color, shape: 'line' };
|
|
20701
21909
|
});
|
|
20702
21910
|
const fmt = this.valueFormat();
|
|
20703
|
-
const footer = this.stacked() && vis.length > 1 ?
|
|
21911
|
+
const footer = this.stacked() && vis.length > 1 ? `${this.text().total} · ${valueFormatter(this.loc(), fmt)(total)}` : undefined;
|
|
20704
21912
|
return { title: this.fmtX()(p.x), rows, footer, data: [p.row], index: p.index };
|
|
20705
21913
|
}, ...(ngDevMode ? [{ debugName: "tooltipCtx" }] : []));
|
|
20706
21914
|
liveText = computed(() => {
|
|
@@ -20709,7 +21917,7 @@ class SdsLineChart {
|
|
|
20709
21917
|
const c = this.tooltipCtx();
|
|
20710
21918
|
if (!c)
|
|
20711
21919
|
return '';
|
|
20712
|
-
return `${c.title} — ${c.rows.map((r) =>
|
|
21920
|
+
return `${c.title} — ${c.rows.map((r) => this.text().labelValue(r.label, r.value)).join(', ')}${c.footer ? `, ${c.footer}` : ''}`;
|
|
20713
21921
|
}, ...(ngDevMode ? [{ debugName: "liveText" }] : []));
|
|
20714
21922
|
onPointer(event) {
|
|
20715
21923
|
const L = this.layout();
|
|
@@ -20832,7 +22040,7 @@ class SdsLineChart {
|
|
|
20832
22040
|
if (this.ariaLabel())
|
|
20833
22041
|
return this.ariaLabel();
|
|
20834
22042
|
const names = this.allSeries().map((s) => s.label).join(', ');
|
|
20835
|
-
return [this.heading() ||
|
|
22043
|
+
return [this.heading() || this.text().lineChart, names].filter(Boolean).join(' — ');
|
|
20836
22044
|
}, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
20837
22045
|
table = computed(() => {
|
|
20838
22046
|
const { pts } = this.model();
|
|
@@ -20840,7 +22048,7 @@ class SdsLineChart {
|
|
|
20840
22048
|
const values = this.values();
|
|
20841
22049
|
const fx = this.fmtX();
|
|
20842
22050
|
return {
|
|
20843
|
-
columns: [this.xLabel() || (this.model().kind === 'time' ?
|
|
22051
|
+
columns: [this.xLabel() || (this.model().kind === 'time' ? this.text().date : this.text().category), ...vis.map((s) => s.label)],
|
|
20844
22052
|
rows: pts.map((p, i) => [
|
|
20845
22053
|
fx(p.x),
|
|
20846
22054
|
...vis.map((s) => {
|
|
@@ -20873,7 +22081,7 @@ class SdsLineChart {
|
|
|
20873
22081
|
[style.height.px]="height()"
|
|
20874
22082
|
tabindex="0"
|
|
20875
22083
|
role="group"
|
|
20876
|
-
aria-roledescription="
|
|
22084
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
20877
22085
|
[attr.aria-label]="label()"
|
|
20878
22086
|
(keydown)="onKey($event)"
|
|
20879
22087
|
(blur)="onBlur()"
|
|
@@ -20995,7 +22203,7 @@ class SdsLineChart {
|
|
|
20995
22203
|
<div class="sr-only" aria-live="polite" aria-atomic="true">{{ liveText() }}</div>
|
|
20996
22204
|
</div>
|
|
20997
22205
|
</sds-chart-frame>
|
|
20998
|
-
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "
|
|
22206
|
+
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "hidden", "interactive", "loading", "empty", "emptyText", "height", "table", "tableCaption", "tableToggle"], outputs: ["toggle", "focusKey"] }, { kind: "component", type: SdsChartAxes, selector: "g[sdsChartAxes]", inputs: ["plot", "xTicks", "yTicks", "grid", "baselineY", "baselineX", "xTitle", "yTitle", "width"] }, { kind: "component", type: SdsChartAnnotations, selector: "g[sdsChartAnnotations]", inputs: ["items", "layer"] }, { kind: "component", type: SdsChartTooltipBox, selector: "sds-chart-tooltip-box", inputs: ["ctx", "template", "x", "y", "containerWidth", "containerHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
20999
22207
|
}
|
|
21000
22208
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsLineChart, decorators: [{
|
|
21001
22209
|
type: Component,
|
|
@@ -21021,7 +22229,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
21021
22229
|
[style.height.px]="height()"
|
|
21022
22230
|
tabindex="0"
|
|
21023
22231
|
role="group"
|
|
21024
|
-
aria-roledescription="
|
|
22232
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
21025
22233
|
[attr.aria-label]="label()"
|
|
21026
22234
|
(keydown)="onKey($event)"
|
|
21027
22235
|
(blur)="onBlur()"
|
|
@@ -21206,7 +22414,8 @@ class SdsBarChart {
|
|
|
21206
22414
|
tooltip = input(true, ...(ngDevMode ? [{ debugName: "tooltip", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
21207
22415
|
animate = input(true, ...(ngDevMode ? [{ debugName: "animate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
21208
22416
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
21209
|
-
|
|
22417
|
+
/** Empty-state text. Default (`null`): the configured `labels.empty` ("No data to display"). */
|
|
22418
|
+
emptyText = input(null, ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
21210
22419
|
tableToggle = input(false, ...(ngDevMode ? [{ debugName: "tableToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
21211
22420
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
21212
22421
|
hidden = model([], ...(ngDevMode ? [{ debugName: "hidden" }] : []));
|
|
@@ -21225,6 +22434,8 @@ class SdsBarChart {
|
|
|
21225
22434
|
pointer = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "pointer" }] : []));
|
|
21226
22435
|
width = hostWidth();
|
|
21227
22436
|
loc = chartLocale(() => this.locale());
|
|
22437
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
22438
|
+
text = chartLabels();
|
|
21228
22439
|
animates = chartAnimates(() => this.animate());
|
|
21229
22440
|
palette = chartPalette();
|
|
21230
22441
|
horizontal = computed(() => this.orientation() === 'horizontal', ...(ngDevMode ? [{ debugName: "horizontal" }] : []));
|
|
@@ -21781,14 +22992,14 @@ class SdsBarChart {
|
|
|
21781
22992
|
const m = this.meta().get(`${s.key}|${c.key}`);
|
|
21782
22993
|
return { key: s.key, label: s.label, value, raw, color: m?.color ?? s.color, shape: s.line ? 'line' : 'rect' };
|
|
21783
22994
|
});
|
|
21784
|
-
const footer = this.stacked() && bars.length > 1 ?
|
|
22995
|
+
const footer = this.stacked() && bars.length > 1 ? `${this.text().total} · ${valueFormatter(this.loc(), this.valueFormat())(total)}` : undefined;
|
|
21785
22996
|
return { title: this.fmtCat()(c.x), rows, footer, data: [c.row], index: c.index };
|
|
21786
22997
|
}, ...(ngDevMode ? [{ debugName: "tooltipCtx" }] : []));
|
|
21787
22998
|
liveText = computed(() => {
|
|
21788
22999
|
if (!this.keyboard())
|
|
21789
23000
|
return '';
|
|
21790
23001
|
const c = this.tooltipCtx();
|
|
21791
|
-
return c ? `${c.title} — ${c.rows.map((r) =>
|
|
23002
|
+
return c ? `${c.title} — ${c.rows.map((r) => this.text().labelValue(r.label, r.value)).join(', ')}${c.footer ? `, ${c.footer}` : ''}` : '';
|
|
21792
23003
|
}, ...(ngDevMode ? [{ debugName: "liveText" }] : []));
|
|
21793
23004
|
local(event) {
|
|
21794
23005
|
const L = this.layout();
|
|
@@ -21887,7 +23098,7 @@ class SdsBarChart {
|
|
|
21887
23098
|
if (this.ariaLabel())
|
|
21888
23099
|
return this.ariaLabel();
|
|
21889
23100
|
const names = this.allSeries().map((s) => s.label).join(', ');
|
|
21890
|
-
return [this.heading() ||
|
|
23101
|
+
return [this.heading() || this.text().barChart, names].filter(Boolean).join(' — ');
|
|
21891
23102
|
}, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
21892
23103
|
table = computed(() => {
|
|
21893
23104
|
const { cats } = this.raw();
|
|
@@ -21895,7 +23106,7 @@ class SdsBarChart {
|
|
|
21895
23106
|
const values = this.rawValues();
|
|
21896
23107
|
const fc = this.fmtCat();
|
|
21897
23108
|
return {
|
|
21898
|
-
columns: [this.xLabel() ||
|
|
23109
|
+
columns: [this.xLabel() || this.text().category, ...vis.map((s) => s.label)],
|
|
21899
23110
|
rows: this.order().map((i) => [
|
|
21900
23111
|
fc(cats[i].x),
|
|
21901
23112
|
...vis.map((s) => {
|
|
@@ -21928,7 +23139,7 @@ class SdsBarChart {
|
|
|
21928
23139
|
[style.height.px]="resolvedHeight()"
|
|
21929
23140
|
tabindex="0"
|
|
21930
23141
|
role="group"
|
|
21931
|
-
aria-roledescription="
|
|
23142
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
21932
23143
|
[attr.aria-label]="label()"
|
|
21933
23144
|
(keydown)="onKey($event)"
|
|
21934
23145
|
(blur)="onBlur()"
|
|
@@ -22008,7 +23219,7 @@ class SdsBarChart {
|
|
|
22008
23219
|
<div class="sr-only" aria-live="polite" aria-atomic="true">{{ liveText() }}</div>
|
|
22009
23220
|
</div>
|
|
22010
23221
|
</sds-chart-frame>
|
|
22011
|
-
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "
|
|
23222
|
+
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "hidden", "interactive", "loading", "empty", "emptyText", "height", "table", "tableCaption", "tableToggle"], outputs: ["toggle", "focusKey"] }, { kind: "component", type: SdsChartAxes, selector: "g[sdsChartAxes]", inputs: ["plot", "xTicks", "yTicks", "grid", "baselineY", "baselineX", "xTitle", "yTitle", "width"] }, { kind: "component", type: SdsChartAnnotations, selector: "g[sdsChartAnnotations]", inputs: ["items", "layer"] }, { kind: "component", type: SdsChartTooltipBox, selector: "sds-chart-tooltip-box", inputs: ["ctx", "template", "x", "y", "containerWidth", "containerHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
22012
23223
|
}
|
|
22013
23224
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsBarChart, decorators: [{
|
|
22014
23225
|
type: Component,
|
|
@@ -22034,7 +23245,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
22034
23245
|
[style.height.px]="resolvedHeight()"
|
|
22035
23246
|
tabindex="0"
|
|
22036
23247
|
role="group"
|
|
22037
|
-
aria-roledescription="
|
|
23248
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
22038
23249
|
[attr.aria-label]="label()"
|
|
22039
23250
|
(keydown)="onKey($event)"
|
|
22040
23251
|
(blur)="onBlur()"
|
|
@@ -22179,13 +23390,16 @@ class SdsScatterChart {
|
|
|
22179
23390
|
sizeFormat = input(null, ...(ngDevMode ? [{ debugName: "sizeFormat" }] : []));
|
|
22180
23391
|
xLabel = input('', ...(ngDevMode ? [{ debugName: "xLabel" }] : []));
|
|
22181
23392
|
yLabel = input('', ...(ngDevMode ? [{ debugName: "yLabel" }] : []));
|
|
22182
|
-
|
|
23393
|
+
/** Name of the bubble size (tooltip, table). Default (`null`): the configured `labels.size`. */
|
|
23394
|
+
sizeLabel = input(null, ...(ngDevMode ? [{ debugName: "sizeLabel" }] : []));
|
|
23395
|
+
sizeName = computed(() => this.sizeLabel() ?? this.text().size, ...(ngDevMode ? [{ debugName: "sizeName" }] : []));
|
|
22183
23396
|
locale = input(null, ...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
22184
23397
|
// --- Behaviour --------------------------------------------------------------------------------
|
|
22185
23398
|
tooltip = input(true, ...(ngDevMode ? [{ debugName: "tooltip", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
22186
23399
|
animate = input(true, ...(ngDevMode ? [{ debugName: "animate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
22187
23400
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
22188
|
-
|
|
23401
|
+
/** Empty-state text. Default (`null`): the configured `labels.empty` ("No data to display"). */
|
|
23402
|
+
emptyText = input(null, ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
22189
23403
|
tableToggle = input(false, ...(ngDevMode ? [{ debugName: "tableToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
22190
23404
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
22191
23405
|
/** Hidden group names (two-way bindable; the legend toggles them). */
|
|
@@ -22204,6 +23418,8 @@ class SdsScatterChart {
|
|
|
22204
23418
|
}
|
|
22205
23419
|
width = hostWidth();
|
|
22206
23420
|
loc = chartLocale(() => this.locale());
|
|
23421
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
23422
|
+
text = chartLabels();
|
|
22207
23423
|
animates = chartAnimates(() => this.animate());
|
|
22208
23424
|
palette = chartPalette();
|
|
22209
23425
|
bubbles = computed(() => this.size() !== null, ...(ngDevMode ? [{ debugName: "bubbles" }] : []));
|
|
@@ -22492,7 +23708,7 @@ class SdsScatterChart {
|
|
|
22492
23708
|
{ key: 'y', label: this.yLabel() || 'y', value: this.fmtY()(p.y), raw: p.y, color, shape: 'dot' },
|
|
22493
23709
|
];
|
|
22494
23710
|
if (this.bubbles() && p.size !== null)
|
|
22495
|
-
rows.push({ key: 'size', label: this.
|
|
23711
|
+
rows.push({ key: 'size', label: this.sizeName(), value: this.fmtSize()(p.size), raw: p.size, color, shape: 'dot' });
|
|
22496
23712
|
const title = [p.label, p.group].filter(Boolean).join(' · ');
|
|
22497
23713
|
return { title, rows, data: [p.row], index: p.index };
|
|
22498
23714
|
}, ...(ngDevMode ? [{ debugName: "tooltipCtx" }] : []));
|
|
@@ -22500,7 +23716,7 @@ class SdsScatterChart {
|
|
|
22500
23716
|
if (!this.keyboard())
|
|
22501
23717
|
return '';
|
|
22502
23718
|
const c = this.tooltipCtx();
|
|
22503
|
-
return c ? `${c.title} — ${c.rows.map((r) =>
|
|
23719
|
+
return c ? `${c.title} — ${c.rows.map((r) => this.text().labelValue(r.label, r.value)).join(', ')}` : '';
|
|
22504
23720
|
}, ...(ngDevMode ? [{ debugName: "liveText" }] : []));
|
|
22505
23721
|
onPointer(event) {
|
|
22506
23722
|
const L = this.layout();
|
|
@@ -22591,8 +23807,10 @@ class SdsScatterChart {
|
|
|
22591
23807
|
label = computed(() => {
|
|
22592
23808
|
if (this.ariaLabel())
|
|
22593
23809
|
return this.ariaLabel();
|
|
22594
|
-
const
|
|
22595
|
-
|
|
23810
|
+
const y = this.yLabel();
|
|
23811
|
+
const x = this.xLabel();
|
|
23812
|
+
const axes = y && x ? this.text().versus(y, x) : y || x;
|
|
23813
|
+
return [this.heading() || this.text().scatterChart, axes].filter(Boolean).join(' — ');
|
|
22596
23814
|
}, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
22597
23815
|
table = computed(() => {
|
|
22598
23816
|
const hasLabel = this.pointLabel() !== null;
|
|
@@ -22602,10 +23820,10 @@ class SdsScatterChart {
|
|
|
22602
23820
|
const fs = this.fmtSize();
|
|
22603
23821
|
const columns = [
|
|
22604
23822
|
hasLabel ? '' : '#',
|
|
22605
|
-
...(hasGroup ? [
|
|
23823
|
+
...(hasGroup ? [this.text().group] : []),
|
|
22606
23824
|
this.xLabel() || 'x',
|
|
22607
23825
|
this.yLabel() || 'y',
|
|
22608
|
-
...(this.bubbles() ? [this.
|
|
23826
|
+
...(this.bubbles() ? [this.sizeName()] : []),
|
|
22609
23827
|
];
|
|
22610
23828
|
return {
|
|
22611
23829
|
columns,
|
|
@@ -22641,7 +23859,7 @@ class SdsScatterChart {
|
|
|
22641
23859
|
[style.height.px]="height()"
|
|
22642
23860
|
tabindex="0"
|
|
22643
23861
|
role="group"
|
|
22644
|
-
aria-roledescription="
|
|
23862
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
22645
23863
|
[attr.aria-label]="label()"
|
|
22646
23864
|
(keydown)="onKey($event)"
|
|
22647
23865
|
(blur)="onBlur()"
|
|
@@ -22736,7 +23954,7 @@ class SdsScatterChart {
|
|
|
22736
23954
|
<div class="sr-only" aria-live="polite" aria-atomic="true">{{ liveText() }}</div>
|
|
22737
23955
|
</div>
|
|
22738
23956
|
</sds-chart-frame>
|
|
22739
|
-
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "
|
|
23957
|
+
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "hidden", "interactive", "loading", "empty", "emptyText", "height", "table", "tableCaption", "tableToggle"], outputs: ["toggle", "focusKey"] }, { kind: "component", type: SdsChartAxes, selector: "g[sdsChartAxes]", inputs: ["plot", "xTicks", "yTicks", "grid", "baselineY", "baselineX", "xTitle", "yTitle", "width"] }, { kind: "component", type: SdsChartAnnotations, selector: "g[sdsChartAnnotations]", inputs: ["items", "layer"] }, { kind: "component", type: SdsChartTooltipBox, selector: "sds-chart-tooltip-box", inputs: ["ctx", "template", "x", "y", "containerWidth", "containerHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
22740
23958
|
}
|
|
22741
23959
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsScatterChart, decorators: [{
|
|
22742
23960
|
type: Component,
|
|
@@ -22762,7 +23980,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
22762
23980
|
[style.height.px]="height()"
|
|
22763
23981
|
tabindex="0"
|
|
22764
23982
|
role="group"
|
|
22765
|
-
aria-roledescription="
|
|
23983
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
22766
23984
|
[attr.aria-label]="label()"
|
|
22767
23985
|
(keydown)="onKey($event)"
|
|
22768
23986
|
(blur)="onBlur()"
|
|
@@ -22860,11 +24078,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
22860
24078
|
`, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"] }]
|
|
22861
24079
|
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], x: [{ type: i0.Input, args: [{ isSignal: true, alias: "x", required: true }] }], y: [{ type: i0.Input, args: [{ isSignal: true, alias: "y", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], pointLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pointLabel", required: false }] }], groupOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupOrder", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], maxRadius: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRadius", required: false }] }], trendline: [{ type: i0.Input, args: [{ isSignal: true, alias: "trendline", required: false }] }], grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", required: false }] }], legend: [{ type: i0.Input, args: [{ isSignal: true, alias: "legend", required: false }] }], annotations: [{ type: i0.Input, args: [{ isSignal: true, alias: "annotations", required: false }] }], xScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "xScale", required: false }] }], yScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "yScale", required: false }] }], xMin: [{ type: i0.Input, args: [{ isSignal: true, alias: "xMin", required: false }] }], xMax: [{ type: i0.Input, args: [{ isSignal: true, alias: "xMax", required: false }] }], yMin: [{ type: i0.Input, args: [{ isSignal: true, alias: "yMin", required: false }] }], yMax: [{ type: i0.Input, args: [{ isSignal: true, alias: "yMax", required: false }] }], includeZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "includeZero", required: false }] }], xFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "xFormat", required: false }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], axisFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisFormat", required: false }] }], sizeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizeFormat", required: false }] }], xLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "xLabel", required: false }] }], yLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "yLabel", required: false }] }], sizeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizeLabel", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], animate: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], tableToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableToggle", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }, { type: i0.Output, args: ["hiddenChange"] }], pointClick: [{ type: i0.Output, args: ["pointClick"] }], customTooltip: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsChartTooltip), { isSignal: true }] }] } });
|
|
22862
24080
|
|
|
22863
|
-
/** Key of the folded "
|
|
24081
|
+
/** Key of the folded "Other" slice — in `hidden` and in `pointClick.key`. */
|
|
22864
24082
|
const SDS_DONUT_OTHER_KEY = '__sds_other__';
|
|
22865
24083
|
const OTHER_KEY = SDS_DONUT_OTHER_KEY;
|
|
22866
24084
|
/**
|
|
22867
|
-
* Donut, pie and half-donut for part-to-whole at a glance. Small tails fold into "
|
|
24085
|
+
* Donut, pie and half-donut for part-to-whole at a glance. Small tails fold into "Other" past
|
|
22868
24086
|
* `maxSlices` (a pie stops reading beyond ~6 parts), the legend doubles as direct labels with each
|
|
22869
24087
|
* share, the centre states the total and swaps to the hovered slice, slices separate with a
|
|
22870
24088
|
* constant 2 px gap, and the whole thing is keyboard-navigable with a data-table twin. Colour follows
|
|
@@ -22890,16 +24108,21 @@ class SdsDonutChart {
|
|
|
22890
24108
|
height = input(240, ...(ngDevMode ? [{ debugName: "height", transform: numberAttribute }] : [{ transform: numberAttribute }]));
|
|
22891
24109
|
/** Ring thickness in px. Defaults to ~26 % of the radius. */
|
|
22892
24110
|
thickness = input(null, ...(ngDevMode ? [{ debugName: "thickness", transform: numberOrNull }] : [{ transform: numberOrNull }]));
|
|
22893
|
-
/** Beyond this many slices the smallest fold into one "
|
|
24111
|
+
/** Beyond this many slices the smallest fold into one "Other" slice. */
|
|
22894
24112
|
maxSlices = input(6, ...(ngDevMode ? [{ debugName: "maxSlices", transform: numberAttribute }] : [{ transform: numberAttribute }]));
|
|
22895
|
-
|
|
24113
|
+
/** Name of the folded tail slice. Default (`null`): the configured `labels.other` ("Other"). */
|
|
24114
|
+
otherLabel = input(null, ...(ngDevMode ? [{ debugName: "otherLabel" }] : []));
|
|
22896
24115
|
/** `desc` (default) orders slices largest first; `none` keeps the data order. */
|
|
22897
24116
|
sort = input('desc', ...(ngDevMode ? [{ debugName: "sort" }] : []));
|
|
22898
24117
|
/** `auto` = right of the ring (below it on narrow containers). */
|
|
22899
24118
|
legend = input('auto', ...(ngDevMode ? [{ debugName: "legend" }] : []));
|
|
22900
24119
|
legendValue = input('percent', ...(ngDevMode ? [{ debugName: "legendValue" }] : []));
|
|
22901
|
-
/**
|
|
22902
|
-
|
|
24120
|
+
/**
|
|
24121
|
+
* Headline in the hole. Default (`null`): the configured `labels.total` ("Total"). An empty string
|
|
24122
|
+
* `''` hides the centre readout entirely (label and figure — what `null` did before 0.0.67), and the
|
|
24123
|
+
* hover tooltip takes over.
|
|
24124
|
+
*/
|
|
24125
|
+
centerLabel = input(null, ...(ngDevMode ? [{ debugName: "centerLabel" }] : []));
|
|
22903
24126
|
/** Override the centre figure (e.g. "72 %" for a completion donut). */
|
|
22904
24127
|
centerValue = input(null, ...(ngDevMode ? [{ debugName: "centerValue" }] : []));
|
|
22905
24128
|
valueFormat = input(null, ...(ngDevMode ? [{ debugName: "valueFormat" }] : []));
|
|
@@ -22907,10 +24130,11 @@ class SdsDonutChart {
|
|
|
22907
24130
|
tooltip = input(true, ...(ngDevMode ? [{ debugName: "tooltip", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
22908
24131
|
animate = input(true, ...(ngDevMode ? [{ debugName: "animate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
22909
24132
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
22910
|
-
|
|
24133
|
+
/** Empty-state text. Default (`null`): the configured `labels.empty` ("No data to display"). */
|
|
24134
|
+
emptyText = input(null, ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
22911
24135
|
tableToggle = input(false, ...(ngDevMode ? [{ debugName: "tableToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
22912
24136
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
22913
|
-
/** Hidden slice keys (category names, or the "
|
|
24137
|
+
/** Hidden slice keys (category names, or the "Other" slice). Two-way bindable. */
|
|
22914
24138
|
hidden = model([], ...(ngDevMode ? [{ debugName: "hidden" }] : []));
|
|
22915
24139
|
pointClick = output();
|
|
22916
24140
|
customTooltip = contentChild(SdsChartTooltip, ...(ngDevMode ? [{ debugName: "customTooltip" }] : []));
|
|
@@ -22926,11 +24150,13 @@ class SdsDonutChart {
|
|
|
22926
24150
|
pointer = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "pointer" }] : []));
|
|
22927
24151
|
width = hostWidth();
|
|
22928
24152
|
loc = chartLocale(() => this.locale());
|
|
24153
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
24154
|
+
text = chartLabels();
|
|
22929
24155
|
animates = chartAnimates(() => this.animate());
|
|
22930
24156
|
palette = chartPalette();
|
|
22931
24157
|
fmt = computed(() => valueFormatter(this.loc(), this.valueFormat()), ...(ngDevMode ? [{ debugName: "fmt" }] : []));
|
|
22932
24158
|
pct = computed(() => valueFormatter(this.loc(), PERCENT_VALUE), ...(ngDevMode ? [{ debugName: "pct" }] : []));
|
|
22933
|
-
/** Slices after grouping, sorting and folding the tail into "
|
|
24159
|
+
/** Slices after grouping, sorting and folding the tail into "Other". */
|
|
22934
24160
|
slices = computed(() => {
|
|
22935
24161
|
const data = this.data() ?? [];
|
|
22936
24162
|
const cAcc = this.category();
|
|
@@ -22954,7 +24180,7 @@ class SdsDonutChart {
|
|
|
22954
24180
|
let list = [...byKey.values()].filter((s) => s.value > 0);
|
|
22955
24181
|
const assign = (kept) => {
|
|
22956
24182
|
// Slot = position among the slices actually drawn, in DATA order (never by size) — so a slice
|
|
22957
|
-
// that appears 9th in the data still gets a hue, distinct from the gray "
|
|
24183
|
+
// that appears 9th in the data still gets a hue, distinct from the gray "Other".
|
|
22958
24184
|
let slot = 0;
|
|
22959
24185
|
for (const s of [...kept].sort((a, b) => a.index - b.index))
|
|
22960
24186
|
if (!s.color)
|
|
@@ -22974,7 +24200,7 @@ class SdsDonutChart {
|
|
|
22974
24200
|
assign(list);
|
|
22975
24201
|
list.push({
|
|
22976
24202
|
key: OTHER_KEY,
|
|
22977
|
-
label: `${this.otherLabel()} (${tail.length})`,
|
|
24203
|
+
label: `${this.otherLabel() ?? this.text().other} (${tail.length})`,
|
|
22978
24204
|
value: tail.reduce((sum, s) => sum + s.value, 0),
|
|
22979
24205
|
color: 'var(--color-ink-faint)',
|
|
22980
24206
|
rows: tail.flatMap((s) => s.rows),
|
|
@@ -22996,7 +24222,7 @@ class SdsDonutChart {
|
|
|
22996
24222
|
return Math.max(120, Math.min(this.height(), w));
|
|
22997
24223
|
}, ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
22998
24224
|
boxHeight = computed(() => (this.half() ? Math.round(this.size() / 2 + 18) : this.size()), ...(ngDevMode ? [{ debugName: "boxHeight" }] : []));
|
|
22999
|
-
showCenter = computed(() => this.variant() === 'donut' && this.centerLabel() !==
|
|
24225
|
+
showCenter = computed(() => this.variant() === 'donut' && this.centerLabel() !== '', ...(ngDevMode ? [{ debugName: "showCenter" }] : []));
|
|
23000
24226
|
showTooltip = computed(() => this.tooltip() && (!this.showCenter() || !!this.customTooltip()), ...(ngDevMode ? [{ debugName: "showTooltip" }] : []));
|
|
23001
24227
|
geo = computed(() => {
|
|
23002
24228
|
if (this.width() <= 0 || this.isEmpty())
|
|
@@ -23093,7 +24319,7 @@ class SdsDonutChart {
|
|
|
23093
24319
|
sub: total ? this.pct()(s.value / total) : '',
|
|
23094
24320
|
};
|
|
23095
24321
|
}
|
|
23096
|
-
return { label: this.centerLabel() ??
|
|
24322
|
+
return { label: this.centerLabel() ?? this.text().total, value: this.centerValue() ?? this.fmt()(total), sub: '' };
|
|
23097
24323
|
}, ...(ngDevMode ? [{ debugName: "center" }] : []));
|
|
23098
24324
|
tooltipCtx = computed(() => {
|
|
23099
24325
|
const key = this.active();
|
|
@@ -23116,7 +24342,7 @@ class SdsDonutChart {
|
|
|
23116
24342
|
if (!s)
|
|
23117
24343
|
return '';
|
|
23118
24344
|
const total = this.total();
|
|
23119
|
-
return `${s.label
|
|
24345
|
+
return `${this.text().labelValue(s.label, this.fmt()(s.value))}${total ? `, ${this.pct()(s.value / total)}` : ''}`;
|
|
23120
24346
|
}, ...(ngDevMode ? [{ debugName: "liveText" }] : []));
|
|
23121
24347
|
legendPosition = computed(() => (this.legend() === 'auto' ? 'right' : this.legend()), ...(ngDevMode ? [{ debugName: "legendPosition" }] : []));
|
|
23122
24348
|
hover(key, event) {
|
|
@@ -23205,12 +24431,12 @@ class SdsDonutChart {
|
|
|
23205
24431
|
label = computed(() => {
|
|
23206
24432
|
if (this.ariaLabel())
|
|
23207
24433
|
return this.ariaLabel();
|
|
23208
|
-
return [this.heading() ||
|
|
24434
|
+
return [this.heading() || this.text().donutChart, this.text().sliceCount(this.slices().length), this.text().totalOf(this.fmt()(this.total()))].join(' — ');
|
|
23209
24435
|
}, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
23210
24436
|
table = computed(() => {
|
|
23211
24437
|
const total = this.total();
|
|
23212
24438
|
return {
|
|
23213
|
-
columns: [
|
|
24439
|
+
columns: [this.text().category, this.text().value, this.text().share],
|
|
23214
24440
|
rows: this.visible().map((s) => [s.label, this.fmt()(s.value), total ? this.pct()(s.value / total) : '—']),
|
|
23215
24441
|
};
|
|
23216
24442
|
}, ...(ngDevMode ? [{ debugName: "table" }] : []));
|
|
@@ -23238,7 +24464,7 @@ class SdsDonutChart {
|
|
|
23238
24464
|
[style.height.px]="boxHeight()"
|
|
23239
24465
|
tabindex="0"
|
|
23240
24466
|
role="group"
|
|
23241
|
-
aria-roledescription="
|
|
24467
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
23242
24468
|
[attr.aria-label]="label()"
|
|
23243
24469
|
(keydown)="onKey($event)"
|
|
23244
24470
|
(blur)="onBlur()"
|
|
@@ -23282,7 +24508,7 @@ class SdsDonutChart {
|
|
|
23282
24508
|
<div class="sr-only" aria-live="polite" aria-atomic="true">{{ liveText() }}</div>
|
|
23283
24509
|
</div>
|
|
23284
24510
|
</sds-chart-frame>
|
|
23285
|
-
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "
|
|
24511
|
+
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "hidden", "interactive", "loading", "empty", "emptyText", "height", "table", "tableCaption", "tableToggle"], outputs: ["toggle", "focusKey"] }, { kind: "component", type: SdsChartTooltipBox, selector: "sds-chart-tooltip-box", inputs: ["ctx", "template", "x", "y", "containerWidth", "containerHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
23286
24512
|
}
|
|
23287
24513
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsDonutChart, decorators: [{
|
|
23288
24514
|
type: Component,
|
|
@@ -23309,7 +24535,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
23309
24535
|
[style.height.px]="boxHeight()"
|
|
23310
24536
|
tabindex="0"
|
|
23311
24537
|
role="group"
|
|
23312
|
-
aria-roledescription="
|
|
24538
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
23313
24539
|
[attr.aria-label]="label()"
|
|
23314
24540
|
(keydown)="onKey($event)"
|
|
23315
24541
|
(blur)="onBlur()"
|
|
@@ -23397,8 +24623,8 @@ class SdsHeatmap {
|
|
|
23397
24623
|
valueFormat = input(null, ...(ngDevMode ? [{ debugName: "valueFormat" }] : []));
|
|
23398
24624
|
/** Format of the column / row labels (a function; dates default to their day). */
|
|
23399
24625
|
xFormat = input(null, ...(ngDevMode ? [{ debugName: "xFormat" }] : []));
|
|
23400
|
-
/** Name of the measure in the tooltip (e.g. "
|
|
23401
|
-
valueLabel = input(
|
|
24626
|
+
/** Name of the measure in the tooltip (e.g. "Arrivals"). Default (`null`): `labels.value`. */
|
|
24627
|
+
valueLabel = input(null, ...(ngDevMode ? [{ debugName: "valueLabel" }] : []));
|
|
23402
24628
|
/** Column-axis title, drawn under the matrix. */
|
|
23403
24629
|
xLabel = input('', ...(ngDevMode ? [{ debugName: "xLabel" }] : []));
|
|
23404
24630
|
/** Row-axis title, drawn vertically on the left (and the table's first column header). */
|
|
@@ -23408,7 +24634,8 @@ class SdsHeatmap {
|
|
|
23408
24634
|
/** Cross-fade cell colours when the data changes. */
|
|
23409
24635
|
animate = input(true, ...(ngDevMode ? [{ debugName: "animate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23410
24636
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23411
|
-
|
|
24637
|
+
/** Empty-state text. Default (`null`): the configured `labels.empty` ("No data to display"). */
|
|
24638
|
+
emptyText = input(null, ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
23412
24639
|
tableToggle = input(false, ...(ngDevMode ? [{ debugName: "tableToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23413
24640
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
23414
24641
|
pointClick = output();
|
|
@@ -23423,6 +24650,8 @@ class SdsHeatmap {
|
|
|
23423
24650
|
}
|
|
23424
24651
|
width = hostWidth();
|
|
23425
24652
|
loc = chartLocale(() => this.locale());
|
|
24653
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
24654
|
+
text = chartLabels();
|
|
23426
24655
|
animates = chartAnimates(() => this.animate());
|
|
23427
24656
|
fmt = computed(() => valueFormatter(this.loc(), this.valueFormat()), ...(ngDevMode ? [{ debugName: "fmt" }] : []));
|
|
23428
24657
|
matrix = computed(() => {
|
|
@@ -23580,8 +24809,8 @@ class SdsHeatmap {
|
|
|
23580
24809
|
rows: [
|
|
23581
24810
|
{
|
|
23582
24811
|
key: 'value',
|
|
23583
|
-
label: this.valueLabel(),
|
|
23584
|
-
value: c.value === null ?
|
|
24812
|
+
label: this.valueLabel() ?? this.text().value,
|
|
24813
|
+
value: c.value === null ? this.text().noData : this.fmt()(c.value),
|
|
23585
24814
|
raw: c.value,
|
|
23586
24815
|
color: vis.fill,
|
|
23587
24816
|
shape: 'rect',
|
|
@@ -23595,7 +24824,7 @@ class SdsHeatmap {
|
|
|
23595
24824
|
if (!this.keyboard())
|
|
23596
24825
|
return '';
|
|
23597
24826
|
const c = this.tooltipCtx();
|
|
23598
|
-
return c ?
|
|
24827
|
+
return c ? this.text().labelValue(c.title ?? '', c.rows[0].value) : '';
|
|
23599
24828
|
}, ...(ngDevMode ? [{ debugName: "liveText" }] : []));
|
|
23600
24829
|
hover(i, _event) {
|
|
23601
24830
|
this.keyboard.set(false);
|
|
@@ -23661,7 +24890,7 @@ class SdsHeatmap {
|
|
|
23661
24890
|
if (this.ariaLabel())
|
|
23662
24891
|
return this.ariaLabel();
|
|
23663
24892
|
const { xs, ys } = this.matrix();
|
|
23664
|
-
return [this.heading() ||
|
|
24893
|
+
return [this.heading() || this.text().heatmap, this.text().gridSize(ys.length, xs.length)].join(' — ');
|
|
23665
24894
|
}, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
23666
24895
|
table = computed(() => {
|
|
23667
24896
|
const { xs, ys, cells } = this.matrix();
|
|
@@ -23697,7 +24926,7 @@ class SdsHeatmap {
|
|
|
23697
24926
|
[style.height.px]="resolvedHeight()"
|
|
23698
24927
|
tabindex="0"
|
|
23699
24928
|
role="group"
|
|
23700
|
-
aria-roledescription="
|
|
24929
|
+
[attr.aria-roledescription]="text().heatmapRole"
|
|
23701
24930
|
[attr.aria-label]="label()"
|
|
23702
24931
|
(keydown)="onKey($event)"
|
|
23703
24932
|
(blur)="onBlur()"
|
|
@@ -23780,7 +25009,7 @@ class SdsHeatmap {
|
|
|
23780
25009
|
</div>
|
|
23781
25010
|
}
|
|
23782
25011
|
</sds-chart-frame>
|
|
23783
|
-
`, isInline: true, styles: [".heat-cell{cursor:pointer}.heat-anim{transition:fill .3s ease}@media(prefers-reduced-motion:reduce){.heat-anim{transition:none}}.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "
|
|
25012
|
+
`, isInline: true, styles: [".heat-cell{cursor:pointer}.heat-anim{transition:fill .3s ease}@media(prefers-reduced-motion:reduce){.heat-anim{transition:none}}.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "hidden", "interactive", "loading", "empty", "emptyText", "height", "table", "tableCaption", "tableToggle"], outputs: ["toggle", "focusKey"] }, { kind: "component", type: SdsChartTooltipBox, selector: "sds-chart-tooltip-box", inputs: ["ctx", "template", "x", "y", "containerWidth", "containerHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
23784
25013
|
}
|
|
23785
25014
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsHeatmap, decorators: [{
|
|
23786
25015
|
type: Component,
|
|
@@ -23802,7 +25031,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
23802
25031
|
[style.height.px]="resolvedHeight()"
|
|
23803
25032
|
tabindex="0"
|
|
23804
25033
|
role="group"
|
|
23805
|
-
aria-roledescription="
|
|
25034
|
+
[attr.aria-roledescription]="text().heatmapRole"
|
|
23806
25035
|
[attr.aria-label]="label()"
|
|
23807
25036
|
(keydown)="onKey($event)"
|
|
23808
25037
|
(blur)="onBlur()"
|
|
@@ -23908,7 +25137,9 @@ class SdsTreemap {
|
|
|
23908
25137
|
/** Click a branch to zoom into it (with a breadcrumb back). */
|
|
23909
25138
|
drilldown = input(true, ...(ngDevMode ? [{ debugName: "drilldown", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23910
25139
|
/** Name of the top of the breadcrumb. */
|
|
23911
|
-
|
|
25140
|
+
/** Default (`null`): the configured `labels.all` ("All"). */
|
|
25141
|
+
rootLabel = input(null, ...(ngDevMode ? [{ debugName: "rootLabel" }] : []));
|
|
25142
|
+
rootName = computed(() => this.rootLabel() ?? this.text().all, ...(ngDevMode ? [{ debugName: "rootName" }] : []));
|
|
23912
25143
|
/** Print the value under the name inside tiles large enough. */
|
|
23913
25144
|
showValues = input(true, ...(ngDevMode ? [{ debugName: "showValues", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23914
25145
|
/** `auto` = the branch legend below the tiles when there are two or more branches. */
|
|
@@ -23917,7 +25148,8 @@ class SdsTreemap {
|
|
|
23917
25148
|
tooltip = input(true, ...(ngDevMode ? [{ debugName: "tooltip", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23918
25149
|
animate = input(true, ...(ngDevMode ? [{ debugName: "animate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23919
25150
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23920
|
-
|
|
25151
|
+
/** Empty-state text. Default (`null`): the configured `labels.empty` ("No data to display"). */
|
|
25152
|
+
emptyText = input(null, ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
23921
25153
|
tableToggle = input(false, ...(ngDevMode ? [{ debugName: "tableToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
23922
25154
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
23923
25155
|
/** A leaf tile was clicked (branches zoom instead while `drilldown` is on). `key` is the path "A › B". */
|
|
@@ -23931,6 +25163,8 @@ class SdsTreemap {
|
|
|
23931
25163
|
pointer = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "pointer" }] : []));
|
|
23932
25164
|
width = hostWidth();
|
|
23933
25165
|
loc = chartLocale(() => this.locale());
|
|
25166
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
25167
|
+
text = chartLabels();
|
|
23934
25168
|
animates = chartAnimates(() => this.animate());
|
|
23935
25169
|
palette = chartPalette();
|
|
23936
25170
|
fmt = computed(() => valueFormatter(this.loc(), this.valueFormat()), ...(ngDevMode ? [{ debugName: "fmt" }] : []));
|
|
@@ -23942,7 +25176,7 @@ class SdsTreemap {
|
|
|
23942
25176
|
this.keyboard.set(false);
|
|
23943
25177
|
}
|
|
23944
25178
|
/** Full hierarchy, summed once. */
|
|
23945
|
-
root = computed(() => this.build({ name: this.
|
|
25179
|
+
root = computed(() => this.build({ name: this.rootName(), children: this.data() ?? [] }), ...(ngDevMode ? [{ debugName: "root" }] : []));
|
|
23946
25180
|
build(data) {
|
|
23947
25181
|
return hierarchy(data, (d) => d.children)
|
|
23948
25182
|
.sum((d) => (d.children?.length ? 0 : Math.max(0, Number(d.value) || 0)))
|
|
@@ -23954,7 +25188,7 @@ class SdsTreemap {
|
|
|
23954
25188
|
* the first index that no longer names a branch — so new data can never leave a stale zoom behind.
|
|
23955
25189
|
*/
|
|
23956
25190
|
zoom = computed(() => {
|
|
23957
|
-
let node = { name: this.
|
|
25191
|
+
let node = { name: this.rootName(), children: this.data() ?? [] };
|
|
23958
25192
|
const indices = [];
|
|
23959
25193
|
const names = [];
|
|
23960
25194
|
for (const i of this.path()) {
|
|
@@ -24057,17 +25291,17 @@ class SdsTreemap {
|
|
|
24057
25291
|
const parent = t.node.parent;
|
|
24058
25292
|
const color = this.activeRect()?.color ?? slotColor(0);
|
|
24059
25293
|
const v = t.node.value ?? 0;
|
|
24060
|
-
const rows = [{ key: 'value', label:
|
|
25294
|
+
const rows = [{ key: 'value', label: this.text().value, value: this.fmt()(v), raw: v, color, shape: 'rect' }];
|
|
24061
25295
|
if (total)
|
|
24062
|
-
rows.push({ key: 'share', label:
|
|
25296
|
+
rows.push({ key: 'share', label: this.text().shareOfTotal, value: this.pct()(v / total), raw: v / total, color, shape: 'rect' });
|
|
24063
25297
|
if (parent && parent.depth > 0 && parent.value) {
|
|
24064
|
-
rows.push({ key: 'parent', label:
|
|
25298
|
+
rows.push({ key: 'parent', label: this.text().shareOf(parent.data.name), value: this.pct()(v / parent.value), raw: v / parent.value, color, shape: 'rect' });
|
|
24065
25299
|
}
|
|
24066
25300
|
return { title: t.path, rows, data: [t.node.data], index: 0 };
|
|
24067
25301
|
}, ...(ngDevMode ? [{ debugName: "tooltipCtx" }] : []));
|
|
24068
25302
|
liveText = computed(() => {
|
|
24069
25303
|
const c = this.keyboard() ? this.tooltipCtx() : null;
|
|
24070
|
-
return c ?
|
|
25304
|
+
return c ? this.text().labelValue(c.title ?? '', c.rows.map((r) => `${r.label} ${r.value}`).join(', ')) : this.announcement();
|
|
24071
25305
|
}, ...(ngDevMode ? [{ debugName: "liveText" }] : []));
|
|
24072
25306
|
hover(key, event) {
|
|
24073
25307
|
this.keyboard.set(false);
|
|
@@ -24089,7 +25323,8 @@ class SdsTreemap {
|
|
|
24089
25323
|
announceZoom() {
|
|
24090
25324
|
const z = this.zoom();
|
|
24091
25325
|
const count = this.layoutRoot()?.leaves().length ?? 0;
|
|
24092
|
-
|
|
25326
|
+
const t = this.text();
|
|
25327
|
+
this.announcement.set(`${z.names.length ? t.zoomedTo(z.names.join(PATH_SEP)) : this.rootName()} — ${t.itemCount(count)}`);
|
|
24093
25328
|
}
|
|
24094
25329
|
/** Zoom into the tile's branch — or, at the deepest level, report the leaf. */
|
|
24095
25330
|
activate(key) {
|
|
@@ -24181,14 +25416,14 @@ class SdsTreemap {
|
|
|
24181
25416
|
if (this.ariaLabel())
|
|
24182
25417
|
return this.ariaLabel();
|
|
24183
25418
|
const zoomed = this.zoom().names;
|
|
24184
|
-
return [this.heading() ||
|
|
25419
|
+
return [this.heading() || this.text().treemap, zoomed.length ? this.text().zoomedTo(zoomed.join(PATH_SEP)) : '', this.text().totalOf(this.fmt()(this.root().value ?? 0))]
|
|
24185
25420
|
.filter(Boolean)
|
|
24186
25421
|
.join(' — ');
|
|
24187
25422
|
}, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
24188
25423
|
table = computed(() => {
|
|
24189
25424
|
const total = this.root().value ?? 0;
|
|
24190
25425
|
return {
|
|
24191
|
-
columns: [
|
|
25426
|
+
columns: [this.text().item, this.text().value, this.text().share],
|
|
24192
25427
|
rows: this.root()
|
|
24193
25428
|
.leaves()
|
|
24194
25429
|
.map((l) => [
|
|
@@ -24215,9 +25450,9 @@ class SdsTreemap {
|
|
|
24215
25450
|
[tableToggle]="tableToggle()"
|
|
24216
25451
|
>
|
|
24217
25452
|
@if (drilldown() && zoom().names.length) {
|
|
24218
|
-
<nav class="mb-2 flex flex-wrap items-center gap-1 text-xs" aria-label="
|
|
25453
|
+
<nav class="mb-2 flex flex-wrap items-center gap-1 text-xs" [attr.aria-label]="text().breadcrumb">
|
|
24219
25454
|
<button type="button" class="rounded px-1.5 py-0.5 font-medium text-ink-soft underline-offset-2 hover:bg-muted hover:text-ink hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500" (click)="zoomTo(0)">
|
|
24220
|
-
{{
|
|
25455
|
+
{{ rootName() }}
|
|
24221
25456
|
</button>
|
|
24222
25457
|
@for (p of zoom().names; track $index) {
|
|
24223
25458
|
<sds-icon name="chevron-right" [size]="12" class="text-ink-faint" />
|
|
@@ -24234,7 +25469,7 @@ class SdsTreemap {
|
|
|
24234
25469
|
[style.height.px]="height()"
|
|
24235
25470
|
tabindex="0"
|
|
24236
25471
|
role="group"
|
|
24237
|
-
aria-roledescription="
|
|
25472
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
24238
25473
|
[attr.aria-label]="label()"
|
|
24239
25474
|
(keydown)="onKey($event)"
|
|
24240
25475
|
(blur)="onBlur()"
|
|
@@ -24285,7 +25520,7 @@ class SdsTreemap {
|
|
|
24285
25520
|
<div class="sr-only" aria-live="polite" aria-atomic="true">{{ liveText() }}</div>
|
|
24286
25521
|
</div>
|
|
24287
25522
|
</sds-chart-frame>
|
|
24288
|
-
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "
|
|
25523
|
+
`, isInline: true, styles: [".sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SdsChartFrame, selector: "sds-chart-frame", inputs: ["heading", "subtitle", "items", "legend", "hidden", "interactive", "loading", "empty", "emptyText", "height", "table", "tableCaption", "tableToggle"], outputs: ["toggle", "focusKey"] }, { kind: "component", type: SdsChartTooltipBox, selector: "sds-chart-tooltip-box", inputs: ["ctx", "template", "x", "y", "containerWidth", "containerHeight"] }, { kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth", "filled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
24289
25524
|
}
|
|
24290
25525
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsTreemap, decorators: [{
|
|
24291
25526
|
type: Component,
|
|
@@ -24305,9 +25540,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
24305
25540
|
[tableToggle]="tableToggle()"
|
|
24306
25541
|
>
|
|
24307
25542
|
@if (drilldown() && zoom().names.length) {
|
|
24308
|
-
<nav class="mb-2 flex flex-wrap items-center gap-1 text-xs" aria-label="
|
|
25543
|
+
<nav class="mb-2 flex flex-wrap items-center gap-1 text-xs" [attr.aria-label]="text().breadcrumb">
|
|
24309
25544
|
<button type="button" class="rounded px-1.5 py-0.5 font-medium text-ink-soft underline-offset-2 hover:bg-muted hover:text-ink hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500" (click)="zoomTo(0)">
|
|
24310
|
-
{{
|
|
25545
|
+
{{ rootName() }}
|
|
24311
25546
|
</button>
|
|
24312
25547
|
@for (p of zoom().names; track $index) {
|
|
24313
25548
|
<sds-icon name="chevron-right" [size]="12" class="text-ink-faint" />
|
|
@@ -24324,7 +25559,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
24324
25559
|
[style.height.px]="height()"
|
|
24325
25560
|
tabindex="0"
|
|
24326
25561
|
role="group"
|
|
24327
|
-
aria-roledescription="
|
|
25562
|
+
[attr.aria-roledescription]="text().chartRole"
|
|
24328
25563
|
[attr.aria-label]="label()"
|
|
24329
25564
|
(keydown)="onKey($event)"
|
|
24330
25565
|
(blur)="onBlur()"
|
|
@@ -24412,7 +25647,7 @@ class SdsSparkline {
|
|
|
24412
25647
|
valueFormat = input(null, ...(ngDevMode ? [{ debugName: "valueFormat" }] : []));
|
|
24413
25648
|
/** What the trend measures — prefixes the spoken summary. */
|
|
24414
25649
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
24415
|
-
/** Replace the generated summary ("
|
|
25650
|
+
/** Replace the generated summary ("Trend: from 12 to 24 — min…", `labels.sparklineSummary`) entirely. */
|
|
24416
25651
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
24417
25652
|
tooltip = input(true, ...(ngDevMode ? [{ debugName: "tooltip", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
24418
25653
|
animate = input(true, ...(ngDevMode ? [{ debugName: "animate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
@@ -24421,6 +25656,8 @@ class SdsSparkline {
|
|
|
24421
25656
|
active = signal(null, ...(ngDevMode ? [{ debugName: "active" }] : []));
|
|
24422
25657
|
measured = hostWidth();
|
|
24423
25658
|
loc = chartLocale(() => this.locale());
|
|
25659
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
25660
|
+
text = chartLabels();
|
|
24424
25661
|
animates = chartAnimates(() => this.animate());
|
|
24425
25662
|
fmt = computed(() => valueFormatter(this.loc(), this.valueFormat()), ...(ngDevMode ? [{ debugName: "fmt" }] : []));
|
|
24426
25663
|
palette = chartPalette();
|
|
@@ -24575,16 +25812,23 @@ class SdsSparkline {
|
|
|
24575
25812
|
index: i,
|
|
24576
25813
|
};
|
|
24577
25814
|
}, ...(ngDevMode ? [{ debugName: "tooltipCtx" }] : []));
|
|
24578
|
-
/** "Admissions
|
|
25815
|
+
/** "Admissions: from 12 to 24 — min 12, max 24, 7 points" (`labels.sparklineSummary`). */
|
|
24579
25816
|
summary = computed(() => {
|
|
24580
25817
|
if (this.ariaLabel())
|
|
24581
25818
|
return this.ariaLabel();
|
|
24582
25819
|
const vals = this.values().filter((v) => v !== null);
|
|
25820
|
+
const t = this.text();
|
|
24583
25821
|
if (!vals.length)
|
|
24584
|
-
return this.label() ||
|
|
25822
|
+
return this.label() || t.trend;
|
|
24585
25823
|
const f = this.fmt();
|
|
24586
|
-
|
|
24587
|
-
|
|
25824
|
+
return t.sparklineSummary({
|
|
25825
|
+
label: this.label() || t.trend,
|
|
25826
|
+
first: f(vals[0]),
|
|
25827
|
+
last: f(vals[vals.length - 1]),
|
|
25828
|
+
min: f(Math.min(...vals)),
|
|
25829
|
+
max: f(Math.max(...vals)),
|
|
25830
|
+
count: vals.length,
|
|
25831
|
+
});
|
|
24588
25832
|
}, ...(ngDevMode ? [{ debugName: "summary" }] : []));
|
|
24589
25833
|
onPointer(event) {
|
|
24590
25834
|
const G = this.geo();
|
|
@@ -24769,6 +26013,8 @@ class SdsKpi {
|
|
|
24769
26013
|
loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
24770
26014
|
locale = input(null, ...(ngDevMode ? [{ debugName: "locale" }] : []));
|
|
24771
26015
|
loc = chartLocale(() => this.locale());
|
|
26016
|
+
/** Built-in strings (provideSdsCharts labels over the English defaults). */
|
|
26017
|
+
text = chartLabels();
|
|
24772
26018
|
display = computed(() => {
|
|
24773
26019
|
const v = this.value();
|
|
24774
26020
|
if (v === null || v === undefined || !Number.isFinite(v))
|
|
@@ -24810,10 +26056,12 @@ class SdsKpi {
|
|
|
24810
26056
|
? 'var(--color-ink-soft)'
|
|
24811
26057
|
: `color-mix(in oklab, ${good ? 'var(--color-accent-green)' : 'var(--color-accent-red)'} 70%, var(--color-ink))`;
|
|
24812
26058
|
const icon = flat ? 'minus' : up ? 'trending-up' : 'trending-down';
|
|
24813
|
-
const
|
|
24814
|
-
|
|
24815
|
-
|
|
24816
|
-
|
|
26059
|
+
const spoken = this.text().kpiChange({
|
|
26060
|
+
direction: flat ? 'flat' : up ? 'up' : 'down',
|
|
26061
|
+
delta: flat ? '' : text.replace(/^[+−-]/, ''),
|
|
26062
|
+
period: this.deltaLabel(),
|
|
26063
|
+
good,
|
|
26064
|
+
});
|
|
24817
26065
|
return { text, tone, icon, spoken };
|
|
24818
26066
|
}, ...(ngDevMode ? [{ debugName: "deltaView" }] : []));
|
|
24819
26067
|
absoluteFormat() {
|
|
@@ -24967,5 +26215,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
24967
26215
|
* Generated bundle index. Do not edit.
|
|
24968
26216
|
*/
|
|
24969
26217
|
|
|
24970
|
-
export { SDS_ALLERGENS, SDS_ALLERGEN_ICONS, SDS_ALLERGEN_LABELS_EN, SDS_CHART_CONFIG, SDS_DONUT_OTHER_KEY, SDS_ICONS, SDS_PHONE_COUNTRIES, SDS_THEME_STORAGE_KEY, SDS_UI_PREF_LANG_PARAM, SDS_UI_PREF_THEME_PARAM, SdsAccordion, SdsAccordionContent, SdsAccordionHeader, SdsAccordionPanel, SdsAccordionStore, SdsAddressAutocomplete, SdsAddressExtra, SdsAllergenIcon, SdsAvatar, SdsBadge, SdsBarChart, SdsBulkBar, SdsButton, SdsCalendar, SdsCard, SdsChartTooltip, SdsCheckbox, SdsChecklistRow, SdsChip, SdsChipGroup, SdsDatePicker, SdsDonutChart, SdsEnvBanner, SdsFileDrop, SdsHeatmap, SdsIcon, SdsImageCropper, SdsInput, SdsInputNumber, SdsKpi, SdsLanguageSwitcher, SdsLineChart, SdsLocalizedInput, SdsMenu, SdsMenuItem, SdsMenuTrigger, SdsMultiSelect, SdsNavGroup, SdsNavItem, SdsOtpInput, SdsPaginator, SdsPhoneInput, SdsRadio, SdsScatterChart, SdsScore, SdsSearchCommand, SdsSegmented, SdsSelect, SdsSelectEmpty, SdsSelectFooter, SdsSelectOption, SdsShell, SdsSidebar, SdsSortableHandle, SdsSortableItem, SdsSortableList, SdsSparkline, SdsStatusTile, SdsTab, SdsTabList, SdsTabPanel, SdsTabPanels, SdsTable, SdsTableCell, SdsTableEmpty, SdsTableHeader, SdsTableRowExpansion, SdsTabs, SdsTabsStore, SdsTextarea, SdsThemeService, SdsThemeToggle, SdsTimeInput, SdsToastHost, SdsToastService, SdsToggleSwitch, SdsTopbar, SdsTreemap, SdsTriStateChip, SdsUserMenu, SidebarStore, addDays, addMonths, addMonthsKeepDay, appendUiPrefs, formatDdMmYyyy, formatHhMm, isOutOfRange, isSameDay, isSdsThemeMode, isoDay, pad2, provideSdsCharts, readUiPrefs, sdsFileMatchesAccept, sdsFormatBytes, sdsFormatNational, sdsMatchDialCode, sdsNormalizeSignificant, startOfDay, startOfMonth, stripUiPrefs };
|
|
26218
|
+
export { SDS_ALLERGENS, SDS_ALLERGEN_ICONS, SDS_ALLERGEN_LABELS_EN, SDS_CHART_CONFIG, SDS_CHART_LABELS_EN, SDS_DONUT_OTHER_KEY, SDS_ICONS, SDS_PHONE_COUNTRIES, SDS_THEME_STORAGE_KEY, SDS_UI_PREF_LANG_PARAM, SDS_UI_PREF_THEME_PARAM, SdsAccordion, SdsAccordionContent, SdsAccordionHeader, SdsAccordionPanel, SdsAccordionStore, SdsAddressAutocomplete, SdsAddressExtra, SdsAllergenIcon, SdsAvatar, SdsBadge, SdsBarChart, SdsBulkBar, SdsButton, SdsCalendar, SdsCard, SdsChartTooltip, SdsCheckbox, SdsChecklistRow, SdsChip, SdsChipGroup, SdsDatePicker, SdsDateRangePicker, SdsDonutChart, SdsEnvBanner, SdsFileDrop, SdsHeatmap, SdsIcon, SdsImageCropper, SdsInput, SdsInputNumber, SdsKpi, SdsLanguageSwitcher, SdsLineChart, SdsLocalizedInput, SdsMenu, SdsMenuItem, SdsMenuTrigger, SdsMultiSelect, SdsNavGroup, SdsNavItem, SdsOtpInput, SdsPaginator, SdsPhoneInput, SdsRadio, SdsRangeCalendar, SdsScatterChart, SdsScore, SdsSearchCommand, SdsSegmented, SdsSelect, SdsSelectEmpty, SdsSelectFooter, SdsSelectOption, SdsShell, SdsSidebar, SdsSortableHandle, SdsSortableItem, SdsSortableList, SdsSparkline, SdsStatusTile, SdsTab, SdsTabList, SdsTabPanel, SdsTabPanels, SdsTable, SdsTableCell, SdsTableEmpty, SdsTableHeader, SdsTableRowExpansion, SdsTabs, SdsTabsStore, SdsTextarea, SdsThemeService, SdsThemeToggle, SdsTimeInput, SdsToastHost, SdsToastService, SdsToggleSwitch, SdsTopbar, SdsTreemap, SdsTriStateChip, SdsUserMenu, SidebarStore, addDays, addMonths, addMonthsKeepDay, appendUiPrefs, diffInDays, formatDateRange, formatDdMmYyyy, formatHhMm, isOutOfRange, isSameDay, isSameRange, isSdsThemeMode, isoDay, pad2, provideSdsCharts, readUiPrefs, sdsFileMatchesAccept, sdsFormatBytes, sdsFormatNational, sdsLastDays, sdsLastMonths, sdsMatchDialCode, sdsNormalizeSignificant, startOfDay, startOfMonth, stripUiPrefs };
|
|
24971
26219
|
//# sourceMappingURL=besaitech-ng-design-system.mjs.map
|