@rivet-health/design-system 5.2.2 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/input/calendar/calendar.component.mjs +1 -1
- package/esm2020/lib/input/date-range/date-range.component.mjs +1 -1
- package/esm2020/lib/input/input-label/input-label.component.mjs +1 -1
- package/esm2020/lib/input/single-select/single-select.component.mjs +20 -44
- package/esm2020/lib/interaction/focus-on-init.directive.mjs +43 -0
- package/esm2020/lib/modal/help/help.component.mjs +11 -3
- package/esm2020/lib/riv.module.mjs +11 -1
- package/esm2020/lib/size/content.service.mjs +31 -0
- package/esm2020/lib/size/size.directive.mjs +40 -0
- package/esm2020/lib/visualization/stacked-column/stacked-column.component.mjs +63 -39
- package/esm2020/lib/visualization/stacked-column/stacked-column.helpers.mjs +1 -10
- package/esm2020/lib/visualization/stacked-row/stacked-row.component.mjs +53 -78
- package/esm2020/lib/visualization/time-series/time-series.component.mjs +22 -27
- package/esm2020/public-api.mjs +3 -1
- package/fesm2015/rivet-health-design-system.mjs +268 -183
- package/fesm2015/rivet-health-design-system.mjs.map +1 -1
- package/fesm2020/rivet-health-design-system.mjs +267 -188
- package/fesm2020/rivet-health-design-system.mjs.map +1 -1
- package/lib/input/single-select/single-select.component.d.ts +3 -6
- package/lib/interaction/focus-on-init.directive.d.ts +13 -0
- package/lib/modal/help/help.component.d.ts +6 -1
- package/lib/riv.module.d.ts +31 -29
- package/lib/size/content.service.d.ts +16 -0
- package/lib/size/size.directive.d.ts +20 -0
- package/lib/visualization/stacked-column/stacked-column.component.d.ts +11 -6
- package/lib/visualization/stacked-column/stacked-column.helpers.d.ts +0 -1
- package/lib/visualization/stacked-row/stacked-row.component.d.ts +9 -13
- package/lib/visualization/time-series/time-series.component.d.ts +5 -6
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
- package/styles/tokens/typography.css +1 -1
|
@@ -3,7 +3,7 @@ import { Component, ChangeDetectionStrategy, Input, HostBinding, Pipe, Injectabl
|
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { DatePipe as DatePipe$1, DecimalPipe, CurrencyPipe, PercentPipe, CommonModule } from '@angular/common';
|
|
5
5
|
import { timeYears, timeYear, timeMonths, timeMonth, timeDays, timeDay, timeSunday, timeWeek, utcYear, utcMonth, utcWeek, utcDay } from 'd3-time';
|
|
6
|
-
import { BehaviorSubject,
|
|
6
|
+
import { BehaviorSubject, combineLatest, map, shareReplay, Subject, merge, scan, startWith, filter, distinctUntilChanged, take, skip, debounceTime } from 'rxjs';
|
|
7
7
|
import { timeFormat, utcFormat } from 'd3-time-format';
|
|
8
8
|
import Fuse from 'fuse.js';
|
|
9
9
|
import { pie, arc, area, stack, line } from 'd3-shape';
|
|
@@ -1181,15 +1181,23 @@ class LocalStorage extends BehaviorSubject {
|
|
|
1181
1181
|
}
|
|
1182
1182
|
|
|
1183
1183
|
class HelpComponent {
|
|
1184
|
+
constructor() {
|
|
1185
|
+
this.size = 16;
|
|
1186
|
+
}
|
|
1184
1187
|
}
|
|
1185
1188
|
HelpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HelpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1186
|
-
HelpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: HelpComponent, selector: "riv-help", inputs: { help: "help" }, ngImport: i0, template: "<riv-icon [rivTooltip]=\"help\" [name]=\"'Info'\" [size]=\"
|
|
1189
|
+
HelpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: HelpComponent, selector: "riv-help", inputs: { help: "help", size: "size" }, ngImport: i0, template: "<riv-icon [rivTooltip]=\"help\" [name]=\"'Info'\" [size]=\"size\"></riv-icon>\n", styles: ["riv-icon{line-height:0}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "riv-icon", inputs: ["name", "size", "customSize", "strokeWidth"] }, { kind: "directive", type: TooltipDirective, selector: "[rivTooltip]", inputs: ["rivTooltip", "rivTooltipTheme", "rivTooltipMaxWidth", "rivTooltipPreferredPosition", "rivTooltipCloseDelay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1187
1190
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HelpComponent, decorators: [{
|
|
1188
1191
|
type: Component,
|
|
1189
|
-
args: [{ selector: 'riv-help', changeDetection: ChangeDetectionStrategy.OnPush, template: "<riv-icon [rivTooltip]=\"help\" [name]=\"'Info'\" [size]=\"
|
|
1192
|
+
args: [{ selector: 'riv-help', changeDetection: ChangeDetectionStrategy.OnPush, template: "<riv-icon [rivTooltip]=\"help\" [name]=\"'Info'\" [size]=\"size\"></riv-icon>\n", styles: ["riv-icon{line-height:0}\n"] }]
|
|
1190
1193
|
}], propDecorators: { help: [{
|
|
1191
1194
|
type: Input
|
|
1195
|
+
}], size: [{
|
|
1196
|
+
type: Input
|
|
1192
1197
|
}] } });
|
|
1198
|
+
(function (HelpComponent) {
|
|
1199
|
+
HelpComponent.Sizes = [12, 16];
|
|
1200
|
+
})(HelpComponent || (HelpComponent = {}));
|
|
1193
1201
|
|
|
1194
1202
|
class LinkComponent {
|
|
1195
1203
|
constructor() {
|
|
@@ -1221,7 +1229,7 @@ class InputLabelComponent {
|
|
|
1221
1229
|
}
|
|
1222
1230
|
}
|
|
1223
1231
|
InputLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: InputLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1224
|
-
InputLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: InputLabelComponent, selector: "riv-input-label", inputs: { label: "label", help: "help", required: "required", labelActionText: "labelActionText" }, outputs: { labelAction: "labelAction" }, ngImport: i0, template: "<label *ngIf=\"label\">\n <span class=\"title\">\n {{ label }}\n <span *ngIf=\"required\" class=\"required\">*</span>\n </span>\n <button\n *ngIf=\"labelActionText\"\n rivLink\n type=\"button\"\n (click)=\"labelAction.emit()\"\n type=\"button\"\n >\n {{ labelActionText }}\n </button>\n <riv-help *ngIf=\"help\" [help]=\"help\"></riv-help>\n</label>\n<div class=\"content\"><ng-content></ng-content></div>\n", styles: [":host{max-width:100%;display:flex;flex-direction:column}label{display:flex;justify-content:space-between;align-items:center;gap:var(--size-small);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-1);font-weight:var(--font-weight-heavy);color:var(--type-light-high-contrast);margin-bottom:var(--base-grid-size)}label .title{flex-grow:1}label .required{color:var(--type-light-danger)}label .action{margin:0 var(--size-xxsmall)}label riv-icon{color:var(--type-light-low-contrast)}riv-help{margin-left:var(--size-xsmall)}.content{display:flex;flex-direction:column;flex:1;justify-content:center}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: HelpComponent, selector: "riv-help", inputs: ["help"] }, { kind: "component", type: LinkComponent, selector: "[rivLink]", inputs: ["disabled", "locked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1232
|
+
InputLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: InputLabelComponent, selector: "riv-input-label", inputs: { label: "label", help: "help", required: "required", labelActionText: "labelActionText" }, outputs: { labelAction: "labelAction" }, ngImport: i0, template: "<label *ngIf=\"label\">\n <span class=\"title\">\n {{ label }}\n <span *ngIf=\"required\" class=\"required\">*</span>\n </span>\n <button\n *ngIf=\"labelActionText\"\n rivLink\n type=\"button\"\n (click)=\"labelAction.emit()\"\n type=\"button\"\n >\n {{ labelActionText }}\n </button>\n <riv-help *ngIf=\"help\" [help]=\"help\"></riv-help>\n</label>\n<div class=\"content\"><ng-content></ng-content></div>\n", styles: [":host{max-width:100%;display:flex;flex-direction:column}label{display:flex;justify-content:space-between;align-items:center;gap:var(--size-small);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-1);font-weight:var(--font-weight-heavy);color:var(--type-light-high-contrast);margin-bottom:var(--base-grid-size)}label .title{flex-grow:1}label .required{color:var(--type-light-danger)}label .action{margin:0 var(--size-xxsmall)}label riv-icon{color:var(--type-light-low-contrast)}riv-help{margin-left:var(--size-xsmall)}.content{display:flex;flex-direction:column;flex:1;justify-content:center}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: HelpComponent, selector: "riv-help", inputs: ["help", "size"] }, { kind: "component", type: LinkComponent, selector: "[rivLink]", inputs: ["disabled", "locked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1225
1233
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: InputLabelComponent, decorators: [{
|
|
1226
1234
|
type: Component,
|
|
1227
1235
|
args: [{ selector: 'riv-input-label', changeDetection: ChangeDetectionStrategy.OnPush, template: "<label *ngIf=\"label\">\n <span class=\"title\">\n {{ label }}\n <span *ngIf=\"required\" class=\"required\">*</span>\n </span>\n <button\n *ngIf=\"labelActionText\"\n rivLink\n type=\"button\"\n (click)=\"labelAction.emit()\"\n type=\"button\"\n >\n {{ labelActionText }}\n </button>\n <riv-help *ngIf=\"help\" [help]=\"help\"></riv-help>\n</label>\n<div class=\"content\"><ng-content></ng-content></div>\n", styles: [":host{max-width:100%;display:flex;flex-direction:column}label{display:flex;justify-content:space-between;align-items:center;gap:var(--size-small);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-1);font-weight:var(--font-weight-heavy);color:var(--type-light-high-contrast);margin-bottom:var(--base-grid-size)}label .title{flex-grow:1}label .required{color:var(--type-light-danger)}label .action{margin:0 var(--size-xxsmall)}label riv-icon{color:var(--type-light-low-contrast)}riv-help{margin-left:var(--size-xsmall)}.content{display:flex;flex-direction:column;flex:1;justify-content:center}\n"] }]
|
|
@@ -1237,6 +1245,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1237
1245
|
type: Output
|
|
1238
1246
|
}] } });
|
|
1239
1247
|
|
|
1248
|
+
class FocusOnInitDirective {
|
|
1249
|
+
constructor(el) {
|
|
1250
|
+
this.el = el;
|
|
1251
|
+
this.shouldFocus = true;
|
|
1252
|
+
this.focusOnChange = false;
|
|
1253
|
+
}
|
|
1254
|
+
ngAfterViewInit() {
|
|
1255
|
+
if (this.shouldFocus) {
|
|
1256
|
+
this.focus();
|
|
1257
|
+
}
|
|
1258
|
+
else {
|
|
1259
|
+
this.focusOnChange = true;
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
ngOnChanges() {
|
|
1263
|
+
if (this.focusOnChange && this.shouldFocus) {
|
|
1264
|
+
this.focusOnChange = false;
|
|
1265
|
+
this.focus();
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
focus() {
|
|
1269
|
+
if (this.el && this.el.nativeElement) {
|
|
1270
|
+
if (!this.el.nativeElement.hasAttribute('tabindex')) {
|
|
1271
|
+
this.el.nativeElement.tabIndex = 0;
|
|
1272
|
+
}
|
|
1273
|
+
this.el.nativeElement.focus();
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
FocusOnInitDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FocusOnInitDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1278
|
+
FocusOnInitDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: FocusOnInitDirective, selector: "[rivFocusOnInit]", inputs: { shouldFocus: ["rivFocusOnInit", "shouldFocus"] }, usesOnChanges: true, ngImport: i0 });
|
|
1279
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FocusOnInitDirective, decorators: [{
|
|
1280
|
+
type: Directive,
|
|
1281
|
+
args: [{
|
|
1282
|
+
selector: '[rivFocusOnInit]',
|
|
1283
|
+
}]
|
|
1284
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { shouldFocus: [{
|
|
1285
|
+
type: Input,
|
|
1286
|
+
args: ['rivFocusOnInit']
|
|
1287
|
+
}] } });
|
|
1288
|
+
|
|
1240
1289
|
function chunks(text, indices) {
|
|
1241
1290
|
let lastEnd = 0;
|
|
1242
1291
|
const chunks = [];
|
|
@@ -1306,6 +1355,7 @@ class SingleSelectComponent extends InputLabelComponent {
|
|
|
1306
1355
|
};
|
|
1307
1356
|
this.loading = false;
|
|
1308
1357
|
this.locked = false;
|
|
1358
|
+
this.maxCalloutHeight = '50vh';
|
|
1309
1359
|
this.noOptionsMessage = 'No available options';
|
|
1310
1360
|
this.placeholder = 'Select...';
|
|
1311
1361
|
this.disabled = false;
|
|
@@ -1333,6 +1383,15 @@ class SingleSelectComponent extends InputLabelComponent {
|
|
|
1333
1383
|
close() {
|
|
1334
1384
|
this.open = false;
|
|
1335
1385
|
}
|
|
1386
|
+
selectOption(newlySelectedOption) {
|
|
1387
|
+
this.selectedOptionChange.emit(newlySelectedOption);
|
|
1388
|
+
this.open = false;
|
|
1389
|
+
// Clear filter after an option is selected.
|
|
1390
|
+
if (this.filterabilityOptions.enabled) {
|
|
1391
|
+
this.filterQuery = '';
|
|
1392
|
+
this.filterQueryChange.emit(this.filterQuery);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1336
1395
|
trackByHeader(i, group) {
|
|
1337
1396
|
return `${i}${group.header}`;
|
|
1338
1397
|
}
|
|
@@ -1341,10 +1400,10 @@ class SingleSelectComponent extends InputLabelComponent {
|
|
|
1341
1400
|
}
|
|
1342
1401
|
}
|
|
1343
1402
|
SingleSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SingleSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1344
|
-
SingleSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: SingleSelectComponent, selector: "riv-single-select", inputs: { groups: "groups", selectedOption: "selectedOption", filterabilityOptions: "filterabilityOptions", loading: "loading", locked: "locked", noOptionsMessage: "noOptionsMessage", nodeTemplate: "nodeTemplate", triggerTemplate: "triggerTemplate", placeholder: "placeholder", disabled: "disabled" }, outputs: { filterQueryChange: "filterQueryChange", selectedOptionChange: "selectedOptionChange" }, viewQueries: [{ propertyName: "customTriggerButton", first: true, predicate: ["customTriggerButton"], descendants: true }, { propertyName: "standardTriggerButton", first: true, predicate: ["standardTriggerButton"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"triggerTemplate; else standardTrigger\">\n <button\n #customTriggerButton\n (click)=\"allowedOpen()\"\n [disabled]=\"disabled || locked\"\n type=\"button\"\n >\n <ng-container\n [ngTemplateOutlet]=\"triggerTemplate\"\n [ngTemplateOutletContext]=\"{ selectedOption }\"\n ></ng-container>\n </button>\n</ng-container>\n<ng-template #standardTrigger>\n <riv-input-label\n [label]=\"label\"\n [help]=\"help\"\n [required]=\"required\"\n [labelActionText]=\"labelActionText\"\n (labelAction)=\"labelAction.emit($event)\"\n >\n <button\n #standardTriggerButton\n class=\"trigger\"\n (click)=\"allowedOpen()\"\n [disabled]=\"disabled || locked\"\n type=\"button\"\n >\n <ng-container *ngIf=\"selectedOption; else placeholderValue\">\n <span class=\"value\">{{ selectedOption.title }}</span>\n </ng-container>\n <ng-template #placeholderValue>\n <span class=\"value placeholder\">{{ placeholder }}</span>\n </ng-template>\n <span class=\"chevron\">\n <riv-icon *ngIf=\"!locked\" [name]=\"'ChevronDown'\" [size]=\"16\"></riv-icon>\n <riv-icon *ngIf=\"locked\" [name]=\"'Lock'\" [size]=\"16\"></riv-icon>\n </span>\n </button>\n </riv-input-label>\n</ng-template>\n\n<riv-callout\n *ngIf=\"open\"\n [anchor]=\"getTrigger()\"\n [theme]=\"'light'\"\n [showCaret]=\"false\"\n [allowedPositions]=\"[\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-right',\n 'bottom-center',\n 'bottom-left'\n ]\"\n (close)=\"open = false\"\n>\n <input\n *ngIf=\"filterabilityOptions.enabled\"\n #filter\n class=\"filter\"\n [placeholder]=\"getFilterPlaceholder()\"\n [value]=\"filterQuery\"\n (input)=\"filterQuery = filter.value; filterQueryChange.emit(filterQuery)\"\n />\n <div class=\"options\">\n <riv-loading-cover [loading]=\"loading\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackByHeader\">\n <ng-container *ngIf=\"group.header\">\n <span class=\"group-header\">\n {{ group.header }}\n </span>\n </ng-container>\n <ng-container *ngIf=\"group.options; let nodes\">\n <ng-container *ngIf=\"nodes.length > 0; else empty\">\n <ng-container *ngFor=\"let node of nodes; trackBy: trackByOption\">\n <ng-container *ngIf=\"nodeTemplate; else standardTemplate\">\n <button\n class=\"custom-single-select-node\"\n [disabled]=\"node.disabled\"\n (click)=\"
|
|
1403
|
+
SingleSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: SingleSelectComponent, selector: "riv-single-select", inputs: { groups: "groups", selectedOption: "selectedOption", filterabilityOptions: "filterabilityOptions", loading: "loading", locked: "locked", maxCalloutHeight: "maxCalloutHeight", noOptionsMessage: "noOptionsMessage", nodeTemplate: "nodeTemplate", triggerTemplate: "triggerTemplate", placeholder: "placeholder", disabled: "disabled" }, outputs: { filterQueryChange: "filterQueryChange", selectedOptionChange: "selectedOptionChange" }, viewQueries: [{ propertyName: "customTriggerButton", first: true, predicate: ["customTriggerButton"], descendants: true }, { propertyName: "standardTriggerButton", first: true, predicate: ["standardTriggerButton"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"triggerTemplate; else standardTrigger\">\n <button\n #customTriggerButton\n (click)=\"allowedOpen()\"\n [disabled]=\"disabled || locked\"\n type=\"button\"\n >\n <ng-container\n [ngTemplateOutlet]=\"triggerTemplate\"\n [ngTemplateOutletContext]=\"{ selectedOption }\"\n ></ng-container>\n </button>\n</ng-container>\n<ng-template #standardTrigger>\n <riv-input-label\n [label]=\"label\"\n [help]=\"help\"\n [required]=\"required\"\n [labelActionText]=\"labelActionText\"\n (labelAction)=\"labelAction.emit($event)\"\n >\n <button\n #standardTriggerButton\n class=\"trigger\"\n (click)=\"allowedOpen()\"\n [disabled]=\"disabled || locked\"\n type=\"button\"\n >\n <ng-container *ngIf=\"selectedOption; else placeholderValue\">\n <span class=\"value\">{{ selectedOption.title }}</span>\n </ng-container>\n <ng-template #placeholderValue>\n <span class=\"value placeholder\">{{ placeholder }}</span>\n </ng-template>\n <span class=\"chevron\">\n <riv-icon *ngIf=\"!locked\" [name]=\"'ChevronDown'\" [size]=\"16\"></riv-icon>\n <riv-icon *ngIf=\"locked\" [name]=\"'Lock'\" [size]=\"16\"></riv-icon>\n </span>\n </button>\n </riv-input-label>\n</ng-template>\n\n<riv-callout\n *ngIf=\"open\"\n [anchor]=\"getTrigger()\"\n [theme]=\"'light'\"\n [showCaret]=\"false\"\n [allowedPositions]=\"[\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-right',\n 'bottom-center',\n 'bottom-left'\n ]\"\n (close)=\"open = false\"\n>\n <input\n *ngIf=\"filterabilityOptions.enabled\"\n #filter\n class=\"filter\"\n [placeholder]=\"getFilterPlaceholder()\"\n [value]=\"filterQuery\"\n (input)=\"filterQuery = filter.value; filterQueryChange.emit(filterQuery)\"\n [rivFocusOnInit]=\"true\"\n />\n <div class=\"options\" [style.max-height]=\"maxCalloutHeight\">\n <riv-loading-cover [loading]=\"loading\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackByHeader\">\n <ng-container *ngIf=\"group.header\">\n <span class=\"group-header\">\n {{ group.header }}\n </span>\n </ng-container>\n <ng-container *ngIf=\"group.options; let nodes\">\n <ng-container *ngIf=\"nodes.length > 0; else empty\">\n <ng-container *ngFor=\"let node of nodes; trackBy: trackByOption\">\n <ng-container *ngIf=\"nodeTemplate; else standardTemplate\">\n <button\n class=\"custom-single-select-node\"\n [disabled]=\"node.disabled\"\n (click)=\"selectOption(node)\"\n type=\"button\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ node }\"\n ></ng-container>\n </button>\n </ng-container>\n <ng-template #standardTemplate>\n <button\n class=\"single-select-node\"\n [class.selected]=\"node?.id === selectedOption?.id\"\n [class.disabled]=\"node?.disabled\"\n [disabled]=\"node?.disabled\"\n (click)=\"selectOption(node)\"\n type=\"button\"\n >\n <riv-icon\n [name]=\"'Check'\"\n *ngIf=\"node?.id === selectedOption?.id\"\n [size]=\"16\"\n ></riv-icon>\n <span class=\"label\">\n <span class=\"label-title\">\n <riv-highlight\n [text]=\"node?.title || ''\"\n [indices]=\"node?.titleHighlightIndices || []\"\n ></riv-highlight>\n </span>\n <span *ngIf=\"node?.subtitle\" class=\"label-subtitle\">\n <riv-highlight\n [text]=\"node?.subtitle || ''\"\n [indices]=\"node?.subtitleHighlightIndices || []\"\n ></riv-highlight>\n </span>\n </span>\n </button>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #empty>\n <div class=\"empty\">\n {{ noOptionsMessage }}\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n </riv-loading-cover>\n </div>\n <div class=\"footer\">\n <ng-content select=\"[footer]\"> </ng-content>\n </div>\n</riv-callout>\n", styles: [".trigger{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);display:flex;gap:var(--size-small);background-color:var(--surface-light-0)}.trigger:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.trigger:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.value{font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);color:var(--type-light-high-contrast);padding:var(--size-small);flex-grow:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:pre}.value.placeholder{color:var(--type-light-disabled)}.chevron{display:flex;justify-content:center;align-items:center;padding:var(--size-small);background-color:var(--surface-light-2);border-left:var(--border-width) solid var(--border-light)}.filter{width:100%;outline:none;border:none;border-bottom:var(--border-width) solid var(--border-light);font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);color:var(--type-light-high-contrast);padding:var(--size-small)}.filter::placeholder{color:var(--type-light-disabled)}.options{max-width:calc(var(--base-grid-size) * 150);overflow-y:auto}.single-select-node{display:flex;align-items:center;overflow:hidden;flex-grow:1;text-align:left;padding:var(--size-xsmall) var(--size-xsmall) var(--size-xsmall) calc(var(--base-grid-size) * 6);width:100%}.single-select-node.selected{padding-left:var(--size-small)}.single-select-node:hover{background-color:var(--surface-light-2)}.single-select-node.disabled{cursor:default;background-color:var(--surface-light-0)}.single-select-node.disabled .label,.single-select-node.disabled .label-subtitle{color:var(--type-light-disabled)}.single-select-node riv-icon{flex-shrink:0}.single-select-node .label{font-size:calc(var(--base-grid-size) * 4);line-height:calc(var(--base-grid-size) * 6);overflow:hidden;text-overflow:ellipsis;white-space:pre;flex-grow:1;padding:0 calc(var(--base-grid-size) * 2);min-width:calc(var(--base-grid-size) * 16)}.single-select-node .label-subtitle{padding-left:var(--base-grid-size);color:var(--type-light-low-contrast)}.custom-single-select-node{display:block;width:100%;text-align:left}.empty{padding:var(--size-medium);text-align:center;color:var(--type-light-disabled)}.footer{border-top:var(--border-width) solid var(--border-light-blend);background-color:var(--surface-light-1);border-bottom-left-radius:var(--border-radius-medium);border-bottom-right-radius:var(--border-radius-medium)}.group-header{display:flex;padding:8px 8px 4px;align-items:flex-start;gap:10px;align-self:stretch;font:var(--title-01)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }, { kind: "directive", type: FocusOnInitDirective, selector: "[rivFocusOnInit]", inputs: ["rivFocusOnInit"] }, { kind: "component", type: HighlightComponent, selector: "riv-highlight", inputs: ["text", "indices"] }, { kind: "component", type: IconComponent, selector: "riv-icon", inputs: ["name", "size", "customSize", "strokeWidth"] }, { kind: "component", type: InputLabelComponent, selector: "riv-input-label", inputs: ["label", "help", "required", "labelActionText"], outputs: ["labelAction"] }, { kind: "component", type: LoadingCoverComponent, selector: "riv-loading-cover", inputs: ["loading", "loadingSize", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1345
1404
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SingleSelectComponent, decorators: [{
|
|
1346
1405
|
type: Component,
|
|
1347
|
-
args: [{ selector: 'riv-single-select', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"triggerTemplate; else standardTrigger\">\n <button\n #customTriggerButton\n (click)=\"allowedOpen()\"\n [disabled]=\"disabled || locked\"\n type=\"button\"\n >\n <ng-container\n [ngTemplateOutlet]=\"triggerTemplate\"\n [ngTemplateOutletContext]=\"{ selectedOption }\"\n ></ng-container>\n </button>\n</ng-container>\n<ng-template #standardTrigger>\n <riv-input-label\n [label]=\"label\"\n [help]=\"help\"\n [required]=\"required\"\n [labelActionText]=\"labelActionText\"\n (labelAction)=\"labelAction.emit($event)\"\n >\n <button\n #standardTriggerButton\n class=\"trigger\"\n (click)=\"allowedOpen()\"\n [disabled]=\"disabled || locked\"\n type=\"button\"\n >\n <ng-container *ngIf=\"selectedOption; else placeholderValue\">\n <span class=\"value\">{{ selectedOption.title }}</span>\n </ng-container>\n <ng-template #placeholderValue>\n <span class=\"value placeholder\">{{ placeholder }}</span>\n </ng-template>\n <span class=\"chevron\">\n <riv-icon *ngIf=\"!locked\" [name]=\"'ChevronDown'\" [size]=\"16\"></riv-icon>\n <riv-icon *ngIf=\"locked\" [name]=\"'Lock'\" [size]=\"16\"></riv-icon>\n </span>\n </button>\n </riv-input-label>\n</ng-template>\n\n<riv-callout\n *ngIf=\"open\"\n [anchor]=\"getTrigger()\"\n [theme]=\"'light'\"\n [showCaret]=\"false\"\n [allowedPositions]=\"[\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-right',\n 'bottom-center',\n 'bottom-left'\n ]\"\n (close)=\"open = false\"\n>\n <input\n *ngIf=\"filterabilityOptions.enabled\"\n #filter\n class=\"filter\"\n [placeholder]=\"getFilterPlaceholder()\"\n [value]=\"filterQuery\"\n (input)=\"filterQuery = filter.value; filterQueryChange.emit(filterQuery)\"\n />\n <div class=\"options\">\n <riv-loading-cover [loading]=\"loading\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackByHeader\">\n <ng-container *ngIf=\"group.header\">\n <span class=\"group-header\">\n {{ group.header }}\n </span>\n </ng-container>\n <ng-container *ngIf=\"group.options; let nodes\">\n <ng-container *ngIf=\"nodes.length > 0; else empty\">\n <ng-container *ngFor=\"let node of nodes; trackBy: trackByOption\">\n <ng-container *ngIf=\"nodeTemplate; else standardTemplate\">\n <button\n class=\"custom-single-select-node\"\n [disabled]=\"node.disabled\"\n (click)=\"
|
|
1406
|
+
args: [{ selector: 'riv-single-select', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"triggerTemplate; else standardTrigger\">\n <button\n #customTriggerButton\n (click)=\"allowedOpen()\"\n [disabled]=\"disabled || locked\"\n type=\"button\"\n >\n <ng-container\n [ngTemplateOutlet]=\"triggerTemplate\"\n [ngTemplateOutletContext]=\"{ selectedOption }\"\n ></ng-container>\n </button>\n</ng-container>\n<ng-template #standardTrigger>\n <riv-input-label\n [label]=\"label\"\n [help]=\"help\"\n [required]=\"required\"\n [labelActionText]=\"labelActionText\"\n (labelAction)=\"labelAction.emit($event)\"\n >\n <button\n #standardTriggerButton\n class=\"trigger\"\n (click)=\"allowedOpen()\"\n [disabled]=\"disabled || locked\"\n type=\"button\"\n >\n <ng-container *ngIf=\"selectedOption; else placeholderValue\">\n <span class=\"value\">{{ selectedOption.title }}</span>\n </ng-container>\n <ng-template #placeholderValue>\n <span class=\"value placeholder\">{{ placeholder }}</span>\n </ng-template>\n <span class=\"chevron\">\n <riv-icon *ngIf=\"!locked\" [name]=\"'ChevronDown'\" [size]=\"16\"></riv-icon>\n <riv-icon *ngIf=\"locked\" [name]=\"'Lock'\" [size]=\"16\"></riv-icon>\n </span>\n </button>\n </riv-input-label>\n</ng-template>\n\n<riv-callout\n *ngIf=\"open\"\n [anchor]=\"getTrigger()\"\n [theme]=\"'light'\"\n [showCaret]=\"false\"\n [allowedPositions]=\"[\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-right',\n 'bottom-center',\n 'bottom-left'\n ]\"\n (close)=\"open = false\"\n>\n <input\n *ngIf=\"filterabilityOptions.enabled\"\n #filter\n class=\"filter\"\n [placeholder]=\"getFilterPlaceholder()\"\n [value]=\"filterQuery\"\n (input)=\"filterQuery = filter.value; filterQueryChange.emit(filterQuery)\"\n [rivFocusOnInit]=\"true\"\n />\n <div class=\"options\" [style.max-height]=\"maxCalloutHeight\">\n <riv-loading-cover [loading]=\"loading\">\n <ng-container *ngFor=\"let group of groups; trackBy: trackByHeader\">\n <ng-container *ngIf=\"group.header\">\n <span class=\"group-header\">\n {{ group.header }}\n </span>\n </ng-container>\n <ng-container *ngIf=\"group.options; let nodes\">\n <ng-container *ngIf=\"nodes.length > 0; else empty\">\n <ng-container *ngFor=\"let node of nodes; trackBy: trackByOption\">\n <ng-container *ngIf=\"nodeTemplate; else standardTemplate\">\n <button\n class=\"custom-single-select-node\"\n [disabled]=\"node.disabled\"\n (click)=\"selectOption(node)\"\n type=\"button\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ node }\"\n ></ng-container>\n </button>\n </ng-container>\n <ng-template #standardTemplate>\n <button\n class=\"single-select-node\"\n [class.selected]=\"node?.id === selectedOption?.id\"\n [class.disabled]=\"node?.disabled\"\n [disabled]=\"node?.disabled\"\n (click)=\"selectOption(node)\"\n type=\"button\"\n >\n <riv-icon\n [name]=\"'Check'\"\n *ngIf=\"node?.id === selectedOption?.id\"\n [size]=\"16\"\n ></riv-icon>\n <span class=\"label\">\n <span class=\"label-title\">\n <riv-highlight\n [text]=\"node?.title || ''\"\n [indices]=\"node?.titleHighlightIndices || []\"\n ></riv-highlight>\n </span>\n <span *ngIf=\"node?.subtitle\" class=\"label-subtitle\">\n <riv-highlight\n [text]=\"node?.subtitle || ''\"\n [indices]=\"node?.subtitleHighlightIndices || []\"\n ></riv-highlight>\n </span>\n </span>\n </button>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #empty>\n <div class=\"empty\">\n {{ noOptionsMessage }}\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n </riv-loading-cover>\n </div>\n <div class=\"footer\">\n <ng-content select=\"[footer]\"> </ng-content>\n </div>\n</riv-callout>\n", styles: [".trigger{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);display:flex;gap:var(--size-small);background-color:var(--surface-light-0)}.trigger:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.trigger:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.value{font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);color:var(--type-light-high-contrast);padding:var(--size-small);flex-grow:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:pre}.value.placeholder{color:var(--type-light-disabled)}.chevron{display:flex;justify-content:center;align-items:center;padding:var(--size-small);background-color:var(--surface-light-2);border-left:var(--border-width) solid var(--border-light)}.filter{width:100%;outline:none;border:none;border-bottom:var(--border-width) solid var(--border-light);font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);color:var(--type-light-high-contrast);padding:var(--size-small)}.filter::placeholder{color:var(--type-light-disabled)}.options{max-width:calc(var(--base-grid-size) * 150);overflow-y:auto}.single-select-node{display:flex;align-items:center;overflow:hidden;flex-grow:1;text-align:left;padding:var(--size-xsmall) var(--size-xsmall) var(--size-xsmall) calc(var(--base-grid-size) * 6);width:100%}.single-select-node.selected{padding-left:var(--size-small)}.single-select-node:hover{background-color:var(--surface-light-2)}.single-select-node.disabled{cursor:default;background-color:var(--surface-light-0)}.single-select-node.disabled .label,.single-select-node.disabled .label-subtitle{color:var(--type-light-disabled)}.single-select-node riv-icon{flex-shrink:0}.single-select-node .label{font-size:calc(var(--base-grid-size) * 4);line-height:calc(var(--base-grid-size) * 6);overflow:hidden;text-overflow:ellipsis;white-space:pre;flex-grow:1;padding:0 calc(var(--base-grid-size) * 2);min-width:calc(var(--base-grid-size) * 16)}.single-select-node .label-subtitle{padding-left:var(--base-grid-size);color:var(--type-light-low-contrast)}.custom-single-select-node{display:block;width:100%;text-align:left}.empty{padding:var(--size-medium);text-align:center;color:var(--type-light-disabled)}.footer{border-top:var(--border-width) solid var(--border-light-blend);background-color:var(--surface-light-1);border-bottom-left-radius:var(--border-radius-medium);border-bottom-right-radius:var(--border-radius-medium)}.group-header{display:flex;padding:8px 8px 4px;align-items:flex-start;gap:10px;align-self:stretch;font:var(--title-01)}\n"] }]
|
|
1348
1407
|
}], propDecorators: { groups: [{
|
|
1349
1408
|
type: Input
|
|
1350
1409
|
}], selectedOption: [{
|
|
@@ -1355,6 +1414,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1355
1414
|
type: Input
|
|
1356
1415
|
}], locked: [{
|
|
1357
1416
|
type: Input
|
|
1417
|
+
}], maxCalloutHeight: [{
|
|
1418
|
+
type: Input
|
|
1358
1419
|
}], noOptionsMessage: [{
|
|
1359
1420
|
type: Input
|
|
1360
1421
|
}], nodeTemplate: [{
|
|
@@ -1404,37 +1465,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1404
1465
|
};
|
|
1405
1466
|
}
|
|
1406
1467
|
SingleSelectComponent.getFilterSync = getFilterSync;
|
|
1407
|
-
function getFilterAsync(query$, fetcher, debounceInput = 300) {
|
|
1408
|
-
return query$.pipe(debounceTime(debounceInput), switchMap(query => from(fetcher(query)).pipe(map(groups => {
|
|
1409
|
-
if (!query)
|
|
1410
|
-
return { loading: false, groups };
|
|
1411
|
-
const fuseOptions = {
|
|
1412
|
-
keys: ['title', 'subtitle'],
|
|
1413
|
-
includeMatches: true,
|
|
1414
|
-
shouldSort: true,
|
|
1415
|
-
threshold: 0.6,
|
|
1416
|
-
};
|
|
1417
|
-
const filteredGroups = groups
|
|
1418
|
-
.map(group => {
|
|
1419
|
-
const fuse = new Fuse(group.options, fuseOptions);
|
|
1420
|
-
const matches = fuse.search(query);
|
|
1421
|
-
return Object.assign(Object.assign({}, group), { options: matches.map(match => {
|
|
1422
|
-
var _a, _b, _c, _d;
|
|
1423
|
-
return (Object.assign(Object.assign({}, match.item), { titleHighlightIndices: [
|
|
1424
|
-
...(((_b = (_a = match.matches) === null || _a === void 0 ? void 0 : _a.find(result => result.key === 'title')) === null || _b === void 0 ? void 0 : _b.indices) || []),
|
|
1425
|
-
], subtitleHighlightIndices: [
|
|
1426
|
-
...(((_d = (_c = match.matches) === null || _c === void 0 ? void 0 : _c.find(result => result.key === 'subtitle')) === null || _d === void 0 ? void 0 : _d.indices) || []),
|
|
1427
|
-
] }));
|
|
1428
|
-
}) });
|
|
1429
|
-
})
|
|
1430
|
-
.filter(group => group.options.length > 0); // Remove empty groups
|
|
1431
|
-
return { loading: false, groups: filteredGroups };
|
|
1432
|
-
}), startWith({ loading: true, groups: [] }))), pairwise(), map(([previous, next]) => ({
|
|
1433
|
-
loading: next.loading,
|
|
1434
|
-
groups: next.loading ? previous.groups : next.groups,
|
|
1435
|
-
})), startWith({ loading: false, groups: [] }));
|
|
1436
|
-
}
|
|
1437
|
-
SingleSelectComponent.getFilterAsync = getFilterAsync;
|
|
1438
1468
|
})(SingleSelectComponent || (SingleSelectComponent = {}));
|
|
1439
1469
|
|
|
1440
1470
|
const monthFormatter = timeFormat('%B');
|
|
@@ -1682,7 +1712,7 @@ class CalendarComponent {
|
|
|
1682
1712
|
}
|
|
1683
1713
|
}
|
|
1684
1714
|
CalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1685
|
-
CalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CalendarComponent, selector: "riv-calendar", inputs: { activeYearMonth: "activeYearMonth", displayMin: "displayMin", displayMax: "displayMax", selectableMin: "selectableMin", selectableMax: "selectableMax", omitRange: "omitRange", selectedValue: "selectedValue" }, outputs: { activeYearMonthChange: "activeYearMonthChange", dateSelect: "dateSelect" }, ngImport: i0, template: "<div class=\"controls\">\n <div>\n <ng-template #selectTrigger let-selectedOption=\"selectedOption\">\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ChevronDown'\"\n [iconPosition]=\"'last'\"\n type=\"button\"\n >\n {{ selectedOption.title || '...' }}\n </button>\n </ng-template>\n <riv-single-select\n placeholder=\"Month...\"\n [groups]=\"monthOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedMonthOption$ | async\"\n (selectedOptionChange)=\"activeYearMonthChange.emit($event.date)\"\n [triggerTemplate]=\"selectTrigger\"\n ></riv-single-select>\n <riv-single-select\n placeholder=\"Year...\"\n [groups]=\"yearOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedYearOption$ | async\"\n (selectedOptionChange)=\"activeYearMonthChange.emit($event.date)\"\n [triggerTemplate]=\"selectTrigger\"\n ></riv-single-select>\n </div>\n <div\n *ngIf=\"{ prev: previousMonth$ | async, next: nextMonth$ | async }; let vm\"\n >\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ArrowLeft'\"\n [disabled]=\"!vm.prev\"\n (click)=\"vm.prev ? activeYearMonthChange.emit(vm.prev) : null\"\n type=\"button\"\n ></button>\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ArrowRight'\"\n [disabled]=\"!vm.next\"\n (click)=\"vm.next ? activeYearMonthChange.emit(vm.next) : null\"\n type=\"button\"\n ></button>\n </div>\n</div>\n<div class=\"calendar\">\n <span class=\"label\">Su</span>\n <span class=\"label\">Mo</span>\n <span class=\"label\">Tu</span>\n <span class=\"label\">We</span>\n <span class=\"label\">Th</span>\n <span class=\"label\">Fr</span>\n <span class=\"label\">Sa</span>\n <button\n *ngFor=\"let day of dates$ | async\"\n class=\"day\"\n [disabled]=\"day.hidden\"\n [class.bleed]=\"!day.inCurrentMonth\"\n [class.fade-in]=\"day.fadeIn\"\n [class.fade-out]=\"day.fadeOut\"\n [class.in-range]=\"day.inRange\"\n [class.rounded-ne]=\"day.roundedNe\"\n [class.rounded-nw]=\"day.roundedNw\"\n [class.rounded-se]=\"day.roundedSe\"\n [class.rounded-sw]=\"day.roundedSw\"\n (click)=\"selectDay(day)\"\n type=\"button\"\n >\n <span\n class=\"day-wrapper\"\n [class.selected]=\"day.selected\"\n [class.today]=\"day.today\"\n [class.hidden]=\"day.hidden\"\n >\n {{ day.display }}\n </span>\n </button>\n</div>\n", styles: [".controls{display:flex;align-items:center;justify-content:space-between}.calendar{display:grid;grid-template-columns:repeat(7,calc(var(--base-grid-size) * 10));grid-auto-rows:calc(var(--base-grid-size) * 6)}.label{display:flex;justify-content:center;align-items:center;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);font-weight:var(--font-weight-heavy)}.day{display:flex;align-items:stretch}.day:hover{background-color:var(--surface-light-1)}.day.in-range{background-color:var(--purp-10)}.day.fade-out{background-image:linear-gradient(to right,var(--purp-10),var(--white-100))}.day.fade-in{background-image:linear-gradient(to right,var(--white-100),var(--purp-10))}.day.bleed{color:var(--type-light-disabled)}.day.rounded-ne{border-top-right-radius:var(--border-radius-medium)}.day.rounded-nw{border-top-left-radius:var(--border-radius-medium)}.day.rounded-sw{border-bottom-left-radius:var(--border-radius-medium)}.day.rounded-se{border-bottom-right-radius:var(--border-radius-medium)}.day-wrapper{flex-grow:1;display:flex;justify-content:center;align-items:center;border-radius:var(--border-radius-medium)}.day-wrapper.selected{background-color:var(--purp-60);color:var(--type-dark-high-contrast)}.day-wrapper.today{border-radius:calc(var(--base-grid-size) * 8);border:var(--border-width) solid var(--border-light);font-weight:var(--font-weight-heavy)}.day-wrapper.hidden{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "[rivButton]", inputs: ["locked", "disabled", "loading", "full", "size", "variant", "icon", "iconPosition"] }, { kind: "component", type: SingleSelectComponent, selector: "riv-single-select", inputs: ["groups", "selectedOption", "filterabilityOptions", "loading", "locked", "noOptionsMessage", "nodeTemplate", "triggerTemplate", "placeholder", "disabled"], outputs: ["filterQueryChange", "selectedOptionChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: OptionGroupPipe, name: "rivOptionGroup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1715
|
+
CalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CalendarComponent, selector: "riv-calendar", inputs: { activeYearMonth: "activeYearMonth", displayMin: "displayMin", displayMax: "displayMax", selectableMin: "selectableMin", selectableMax: "selectableMax", omitRange: "omitRange", selectedValue: "selectedValue" }, outputs: { activeYearMonthChange: "activeYearMonthChange", dateSelect: "dateSelect" }, ngImport: i0, template: "<div class=\"controls\">\n <div>\n <ng-template #selectTrigger let-selectedOption=\"selectedOption\">\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ChevronDown'\"\n [iconPosition]=\"'last'\"\n type=\"button\"\n >\n {{ selectedOption.title || '...' }}\n </button>\n </ng-template>\n <riv-single-select\n placeholder=\"Month...\"\n [groups]=\"monthOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedMonthOption$ | async\"\n (selectedOptionChange)=\"activeYearMonthChange.emit($event.date)\"\n [triggerTemplate]=\"selectTrigger\"\n ></riv-single-select>\n <riv-single-select\n placeholder=\"Year...\"\n [groups]=\"yearOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedYearOption$ | async\"\n (selectedOptionChange)=\"activeYearMonthChange.emit($event.date)\"\n [triggerTemplate]=\"selectTrigger\"\n ></riv-single-select>\n </div>\n <div\n *ngIf=\"{ prev: previousMonth$ | async, next: nextMonth$ | async }; let vm\"\n >\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ArrowLeft'\"\n [disabled]=\"!vm.prev\"\n (click)=\"vm.prev ? activeYearMonthChange.emit(vm.prev) : null\"\n type=\"button\"\n ></button>\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ArrowRight'\"\n [disabled]=\"!vm.next\"\n (click)=\"vm.next ? activeYearMonthChange.emit(vm.next) : null\"\n type=\"button\"\n ></button>\n </div>\n</div>\n<div class=\"calendar\">\n <span class=\"label\">Su</span>\n <span class=\"label\">Mo</span>\n <span class=\"label\">Tu</span>\n <span class=\"label\">We</span>\n <span class=\"label\">Th</span>\n <span class=\"label\">Fr</span>\n <span class=\"label\">Sa</span>\n <button\n *ngFor=\"let day of dates$ | async\"\n class=\"day\"\n [disabled]=\"day.hidden\"\n [class.bleed]=\"!day.inCurrentMonth\"\n [class.fade-in]=\"day.fadeIn\"\n [class.fade-out]=\"day.fadeOut\"\n [class.in-range]=\"day.inRange\"\n [class.rounded-ne]=\"day.roundedNe\"\n [class.rounded-nw]=\"day.roundedNw\"\n [class.rounded-se]=\"day.roundedSe\"\n [class.rounded-sw]=\"day.roundedSw\"\n (click)=\"selectDay(day)\"\n type=\"button\"\n >\n <span\n class=\"day-wrapper\"\n [class.selected]=\"day.selected\"\n [class.today]=\"day.today\"\n [class.hidden]=\"day.hidden\"\n >\n {{ day.display }}\n </span>\n </button>\n</div>\n", styles: [".controls{display:flex;align-items:center;justify-content:space-between}.calendar{display:grid;grid-template-columns:repeat(7,calc(var(--base-grid-size) * 10));grid-auto-rows:calc(var(--base-grid-size) * 6)}.label{display:flex;justify-content:center;align-items:center;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);font-weight:var(--font-weight-heavy)}.day{display:flex;align-items:stretch}.day:hover{background-color:var(--surface-light-1)}.day.in-range{background-color:var(--purp-10)}.day.fade-out{background-image:linear-gradient(to right,var(--purp-10),var(--white-100))}.day.fade-in{background-image:linear-gradient(to right,var(--white-100),var(--purp-10))}.day.bleed{color:var(--type-light-disabled)}.day.rounded-ne{border-top-right-radius:var(--border-radius-medium)}.day.rounded-nw{border-top-left-radius:var(--border-radius-medium)}.day.rounded-sw{border-bottom-left-radius:var(--border-radius-medium)}.day.rounded-se{border-bottom-right-radius:var(--border-radius-medium)}.day-wrapper{flex-grow:1;display:flex;justify-content:center;align-items:center;border-radius:var(--border-radius-medium)}.day-wrapper.selected{background-color:var(--purp-60);color:var(--type-dark-high-contrast)}.day-wrapper.today{border-radius:calc(var(--base-grid-size) * 8);border:var(--border-width) solid var(--border-light);font-weight:var(--font-weight-heavy)}.day-wrapper.hidden{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "[rivButton]", inputs: ["locked", "disabled", "loading", "full", "size", "variant", "icon", "iconPosition"] }, { kind: "component", type: SingleSelectComponent, selector: "riv-single-select", inputs: ["groups", "selectedOption", "filterabilityOptions", "loading", "locked", "maxCalloutHeight", "noOptionsMessage", "nodeTemplate", "triggerTemplate", "placeholder", "disabled"], outputs: ["filterQueryChange", "selectedOptionChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: OptionGroupPipe, name: "rivOptionGroup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1686
1716
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CalendarComponent, decorators: [{
|
|
1687
1717
|
type: Component,
|
|
1688
1718
|
args: [{ selector: 'riv-calendar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"controls\">\n <div>\n <ng-template #selectTrigger let-selectedOption=\"selectedOption\">\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ChevronDown'\"\n [iconPosition]=\"'last'\"\n type=\"button\"\n >\n {{ selectedOption.title || '...' }}\n </button>\n </ng-template>\n <riv-single-select\n placeholder=\"Month...\"\n [groups]=\"monthOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedMonthOption$ | async\"\n (selectedOptionChange)=\"activeYearMonthChange.emit($event.date)\"\n [triggerTemplate]=\"selectTrigger\"\n ></riv-single-select>\n <riv-single-select\n placeholder=\"Year...\"\n [groups]=\"yearOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedYearOption$ | async\"\n (selectedOptionChange)=\"activeYearMonthChange.emit($event.date)\"\n [triggerTemplate]=\"selectTrigger\"\n ></riv-single-select>\n </div>\n <div\n *ngIf=\"{ prev: previousMonth$ | async, next: nextMonth$ | async }; let vm\"\n >\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ArrowLeft'\"\n [disabled]=\"!vm.prev\"\n (click)=\"vm.prev ? activeYearMonthChange.emit(vm.prev) : null\"\n type=\"button\"\n ></button>\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n [icon]=\"'ArrowRight'\"\n [disabled]=\"!vm.next\"\n (click)=\"vm.next ? activeYearMonthChange.emit(vm.next) : null\"\n type=\"button\"\n ></button>\n </div>\n</div>\n<div class=\"calendar\">\n <span class=\"label\">Su</span>\n <span class=\"label\">Mo</span>\n <span class=\"label\">Tu</span>\n <span class=\"label\">We</span>\n <span class=\"label\">Th</span>\n <span class=\"label\">Fr</span>\n <span class=\"label\">Sa</span>\n <button\n *ngFor=\"let day of dates$ | async\"\n class=\"day\"\n [disabled]=\"day.hidden\"\n [class.bleed]=\"!day.inCurrentMonth\"\n [class.fade-in]=\"day.fadeIn\"\n [class.fade-out]=\"day.fadeOut\"\n [class.in-range]=\"day.inRange\"\n [class.rounded-ne]=\"day.roundedNe\"\n [class.rounded-nw]=\"day.roundedNw\"\n [class.rounded-se]=\"day.roundedSe\"\n [class.rounded-sw]=\"day.roundedSw\"\n (click)=\"selectDay(day)\"\n type=\"button\"\n >\n <span\n class=\"day-wrapper\"\n [class.selected]=\"day.selected\"\n [class.today]=\"day.today\"\n [class.hidden]=\"day.hidden\"\n >\n {{ day.display }}\n </span>\n </button>\n</div>\n", styles: [".controls{display:flex;align-items:center;justify-content:space-between}.calendar{display:grid;grid-template-columns:repeat(7,calc(var(--base-grid-size) * 10));grid-auto-rows:calc(var(--base-grid-size) * 6)}.label{display:flex;justify-content:center;align-items:center;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);font-weight:var(--font-weight-heavy)}.day{display:flex;align-items:stretch}.day:hover{background-color:var(--surface-light-1)}.day.in-range{background-color:var(--purp-10)}.day.fade-out{background-image:linear-gradient(to right,var(--purp-10),var(--white-100))}.day.fade-in{background-image:linear-gradient(to right,var(--white-100),var(--purp-10))}.day.bleed{color:var(--type-light-disabled)}.day.rounded-ne{border-top-right-radius:var(--border-radius-medium)}.day.rounded-nw{border-top-left-radius:var(--border-radius-medium)}.day.rounded-sw{border-bottom-left-radius:var(--border-radius-medium)}.day.rounded-se{border-bottom-right-radius:var(--border-radius-medium)}.day-wrapper{flex-grow:1;display:flex;justify-content:center;align-items:center;border-radius:var(--border-radius-medium)}.day-wrapper.selected{background-color:var(--purp-60);color:var(--type-dark-high-contrast)}.day-wrapper.today{border-radius:calc(var(--base-grid-size) * 8);border:var(--border-width) solid var(--border-light);font-weight:var(--font-weight-heavy)}.day-wrapper.hidden{display:none}\n"] }]
|
|
@@ -1841,7 +1871,7 @@ class DateRangeComponent extends InputLabelComponent {
|
|
|
1841
1871
|
}
|
|
1842
1872
|
}
|
|
1843
1873
|
DateRangeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DateRangeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1844
|
-
DateRangeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DateRangeComponent, selector: "riv-date-range", inputs: { showPresets: "showPresets", min: "min", max: "max", value: "value", placeholder: "placeholder", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<riv-input-label\n [label]=\"label\"\n [help]=\"help\"\n [required]=\"required\"\n [labelActionText]=\"labelActionText\"\n (labelAction)=\"labelAction.emit($event)\"\n>\n <button\n #trigger\n class=\"trigger\"\n (click)=\"open$.next(true)\"\n [disabled]=\"disabled$ | async\"\n type=\"button\"\n >\n <ng-container\n *ngIf=\"displayValue$ | async; else placeholderValue; let display\"\n >\n <span class=\"value\">{{ display }}</span>\n </ng-container>\n <ng-template #placeholderValue>\n <span class=\"value placeholder\">{{ placeholder$ | async }}</span>\n </ng-template>\n <span class=\"chevron\">\n <riv-icon [name]=\"'Calendar'\" [size]=\"16\"></riv-icon>\n </span>\n </button>\n</riv-input-label>\n\n<ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-inputValue\n [ngTemplateOutletContext]=\"{ $implicit: (value$ | async) }\"\n>\n <riv-callout\n *ngIf=\"open$ | async\"\n [anchor]=\"trigger\"\n [showCaret]=\"false\"\n [theme]=\"'light'\"\n [allowedPositions]=\"[\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-right',\n 'bottom-center',\n 'bottom-left'\n ]\"\n [preferredPosition]=\"'bottom-right'\"\n (close)=\"open$.next(false); userSelectedDate$.next(inputValue)\"\n >\n <div class=\"content\">\n <div *ngIf=\"showPresets\" class=\"presets\">\n <ng-template #presetTpl let-node=\"node\">\n <ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-isFavorite\n [ngTemplateOutletContext]=\"{\n $implicit: (favoritePresetIds$ | async)?.includes(node.id)\n }\"\n >\n <div class=\"preset\" [class.favorite]=\"isFavorite\">\n <div class=\"description\">\n <riv-highlight\n class=\"title\"\n [text]=\"node.title\"\n [indices]=\"node.titleHighlightIndices || []\"\n ></riv-highlight>\n <riv-highlight\n class=\"subtitle\"\n [text]=\"node.subtitle\"\n [indices]=\"node.subtitleHighlightIndices || []\"\n ></riv-highlight>\n </div>\n <button\n (click)=\"\n setFavorite(node, !isFavorite); $event.stopPropagation()\n \"\n type=\"button\"\n >\n <riv-icon\n [name]=\"isFavorite ? 'HeartActive' : 'Heart'\"\n [size]=\"16\"\n [rivTooltip]=\"'Mark as favorite'\"\n ></riv-icon>\n </button>\n </div>\n </ng-template>\n </ng-template>\n <riv-single-select\n [label]=\"'Date presets'\"\n [filterabilityOptions]=\"{ enabled: true, placeholder: 'Search...' }\"\n (filterQueryChange)=\"presetFilterQuery$.next($event)\"\n [groups]=\"(filteredPresetOptions$ | async) ?? []\"\n [selectedOption]=\"selectedPreset$ | async\"\n (selectedOptionChange)=\"userSelectedPreset$.next($event)\"\n [nodeTemplate]=\"presetTpl\"\n ></riv-single-select>\n <ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-favorites\n [ngTemplateOutletContext]=\"{ $implicit: favoritePresets$ | async }\"\n >\n <riv-input-label *ngIf=\"favorites.length\" [label]=\"'Favorites'\">\n <div class=\"shortcuts\">\n <button\n *ngFor=\"let favorite of favorites\"\n class=\"shortcut\"\n [class.active]=\"(selectedPreset$ | async)?.id === favorite.id\"\n (click)=\"userSelectedPreset$.next(favorite)\"\n type=\"button\"\n >\n <span class=\"title\">{{ favorite.title }}</span>\n <button\n (click)=\"setFavorite(favorite, false)\"\n [rivTooltip]=\"'Remove favorite'\"\n type=\"button\"\n >\n <riv-icon [name]=\"'HeartActive'\" [size]=\"16\"></riv-icon>\n </button>\n </button>\n </div>\n </riv-input-label>\n </ng-template>\n </div>\n\n <div class=\"calendars\">\n <riv-calendar\n class=\"left\"\n [activeYearMonth]=\"(leftActiveYearMonth$ | async) || TODAY\"\n (activeYearMonthChange)=\"userLeftActiveYearMonth$.next($event)\"\n [displayMin]=\"(min$ | async) || TODAY\"\n [displayMax]=\"(max$ | async) || TODAY\"\n [selectableMin]=\"(leftMin$ | async) || TODAY\"\n [selectableMax]=\"(leftMax$ | async) || TODAY\"\n [omitRange]=\"(leftOmitRange$ | async) || [TODAY, TODAY]\"\n [selectedValue]=\"(selectedValue$ | async) || TODAY\"\n (dateSelect)=\"userSelectedDate$.next($event)\"\n ></riv-calendar>\n <riv-calendar\n class=\"right\"\n [activeYearMonth]=\"(rightActiveYearMonth$ | async) || TODAY\"\n (activeYearMonthChange)=\"userRightActiveYearMonth$.next($event)\"\n [displayMin]=\"(min$ | async) || TODAY\"\n [displayMax]=\"(max$ | async) || TODAY\"\n [selectableMin]=\"(rightMin$ | async) || TODAY\"\n [selectableMax]=\"(rightMax$ | async) || TODAY\"\n [selectedValue]=\"(selectedValue$ | async) || TODAY\"\n (dateSelect)=\"userSelectedDate$.next($event)\"\n ></riv-calendar>\n </div>\n\n <footer class=\"buttons\">\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n (click)=\"userSelectedDate$.next(undefined)\"\n type=\"button\"\n >\n Clear\n </button>\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'primary'\"\n (click)=\"open$.next(false)\"\n type=\"button\"\n >\n Done\n </button>\n </footer>\n </div>\n </riv-callout>\n</ng-template>\n", styles: [".trigger{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);display:flex;gap:var(--size-small)}.trigger:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.trigger:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.value{font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);color:var(--type-light-high-contrast);padding:var(--size-small);flex-grow:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:pre}.value.placeholder{color:var(--type-light-disabled)}.chevron{display:flex;justify-content:center;align-items:center;padding:var(--size-small);background-color:var(--surface-light-2);border-left:var(--border-width) solid var(--border-light)}.content{display:inline-grid;grid-template-rows:1fr auto;grid-template-columns:calc(var(--base-grid-size) * 50) 1fr 1fr}.presets{grid-area:1 / 1 / 3 / 2;background-color:var(--surface-light-1);padding:var(--size-xlarge) var(--size-large);border-right:var(--border-width) solid var(--border-light);display:flex;flex-direction:column;gap:var(--size-medium)}.preset{display:flex;transition:background-color var(--short-transition)}.preset:hover{background-color:var(--surface-light-2)}.preset button{color:transparent;transition:color var(--short-transition);padding:var(--size-medium) var(--size-large) var(--size-medium) var(--size-small)}.preset:hover button{color:var(--type-light-low-contrast)}.preset button:hover{color:var(--type-light-high-contrast)}.preset.favorite button{color:var(--type-light-link)}.preset .description{flex-grow:1;padding:var(--size-medium) var(--size-small) var(--size-medium) var(--size-medium)}.preset .title{display:block;font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-1)}.preset .subtitle{display:block;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-1);color:var(--type-light-low-contrast)}.shortcuts{display:flex;flex-direction:column;gap:var(--size-xsmall);overflow-y:auto}.shortcut{display:flex;align-items:center;padding:var(--size-small) var(--size-small) var(--size-small) var(--size-medium);gap:var(--size-small);border-radius:var(--border-radius-small);transition:background-color var(--short-transition)}.shortcut:hover{background-color:var(--black-20)}.shortcut.active{background-color:var(--baloo-05)}.shortcut .title{flex-grow:1;text-align:left;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-2)}.shortcut button{color:transparent;transition:color var(--short-transition)}.shortcut:hover button{color:var(--type-light-link)}.calendars{grid-column:2 / 4;display:grid;grid-template-columns:subgrid;grid-template-rows:subgrid;padding:var(--size-large)}.left{grid-area:1 / 1 / 2 / 2;padding-right:var(--size-large);border-right:var(--border-width) solid var(--border-light)}.right{padding-left:var(--size-large);grid-area:1 / 2 / 2 / 3}.buttons{grid-area:2 / 2 / 3 / 4;padding:var(--size-small);display:flex;justify-content:space-between}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "[rivButton]", inputs: ["locked", "disabled", "loading", "full", "size", "variant", "icon", "iconPosition"] }, { kind: "component", type: CalendarComponent, selector: "riv-calendar", inputs: ["activeYearMonth", "displayMin", "displayMax", "selectableMin", "selectableMax", "omitRange", "selectedValue"], outputs: ["activeYearMonthChange", "dateSelect"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }, { kind: "component", type: HighlightComponent, selector: "riv-highlight", inputs: ["text", "indices"] }, { kind: "component", type: IconComponent, selector: "riv-icon", inputs: ["name", "size", "customSize", "strokeWidth"] }, { kind: "component", type: InputLabelComponent, selector: "riv-input-label", inputs: ["label", "help", "required", "labelActionText"], outputs: ["labelAction"] }, { kind: "component", type: SingleSelectComponent, selector: "riv-single-select", inputs: ["groups", "selectedOption", "filterabilityOptions", "loading", "locked", "noOptionsMessage", "nodeTemplate", "triggerTemplate", "placeholder", "disabled"], outputs: ["filterQueryChange", "selectedOptionChange"] }, { kind: "directive", type: TooltipDirective, selector: "[rivTooltip]", inputs: ["rivTooltip", "rivTooltipTheme", "rivTooltipMaxWidth", "rivTooltipPreferredPosition", "rivTooltipCloseDelay"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1874
|
+
DateRangeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DateRangeComponent, selector: "riv-date-range", inputs: { showPresets: "showPresets", min: "min", max: "max", value: "value", placeholder: "placeholder", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<riv-input-label\n [label]=\"label\"\n [help]=\"help\"\n [required]=\"required\"\n [labelActionText]=\"labelActionText\"\n (labelAction)=\"labelAction.emit($event)\"\n>\n <button\n #trigger\n class=\"trigger\"\n (click)=\"open$.next(true)\"\n [disabled]=\"disabled$ | async\"\n type=\"button\"\n >\n <ng-container\n *ngIf=\"displayValue$ | async; else placeholderValue; let display\"\n >\n <span class=\"value\">{{ display }}</span>\n </ng-container>\n <ng-template #placeholderValue>\n <span class=\"value placeholder\">{{ placeholder$ | async }}</span>\n </ng-template>\n <span class=\"chevron\">\n <riv-icon [name]=\"'Calendar'\" [size]=\"16\"></riv-icon>\n </span>\n </button>\n</riv-input-label>\n\n<ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-inputValue\n [ngTemplateOutletContext]=\"{ $implicit: (value$ | async) }\"\n>\n <riv-callout\n *ngIf=\"open$ | async\"\n [anchor]=\"trigger\"\n [showCaret]=\"false\"\n [theme]=\"'light'\"\n [allowedPositions]=\"[\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-right',\n 'bottom-center',\n 'bottom-left'\n ]\"\n [preferredPosition]=\"'bottom-right'\"\n (close)=\"open$.next(false); userSelectedDate$.next(inputValue)\"\n >\n <div class=\"content\">\n <div *ngIf=\"showPresets\" class=\"presets\">\n <ng-template #presetTpl let-node=\"node\">\n <ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-isFavorite\n [ngTemplateOutletContext]=\"{\n $implicit: (favoritePresetIds$ | async)?.includes(node.id)\n }\"\n >\n <div class=\"preset\" [class.favorite]=\"isFavorite\">\n <div class=\"description\">\n <riv-highlight\n class=\"title\"\n [text]=\"node.title\"\n [indices]=\"node.titleHighlightIndices || []\"\n ></riv-highlight>\n <riv-highlight\n class=\"subtitle\"\n [text]=\"node.subtitle\"\n [indices]=\"node.subtitleHighlightIndices || []\"\n ></riv-highlight>\n </div>\n <button\n (click)=\"\n setFavorite(node, !isFavorite); $event.stopPropagation()\n \"\n type=\"button\"\n >\n <riv-icon\n [name]=\"isFavorite ? 'HeartActive' : 'Heart'\"\n [size]=\"16\"\n [rivTooltip]=\"'Mark as favorite'\"\n ></riv-icon>\n </button>\n </div>\n </ng-template>\n </ng-template>\n <riv-single-select\n [label]=\"'Date presets'\"\n [filterabilityOptions]=\"{ enabled: true, placeholder: 'Search...' }\"\n (filterQueryChange)=\"presetFilterQuery$.next($event)\"\n [groups]=\"(filteredPresetOptions$ | async) ?? []\"\n [selectedOption]=\"selectedPreset$ | async\"\n (selectedOptionChange)=\"userSelectedPreset$.next($event)\"\n [nodeTemplate]=\"presetTpl\"\n ></riv-single-select>\n <ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-favorites\n [ngTemplateOutletContext]=\"{ $implicit: favoritePresets$ | async }\"\n >\n <riv-input-label *ngIf=\"favorites.length\" [label]=\"'Favorites'\">\n <div class=\"shortcuts\">\n <button\n *ngFor=\"let favorite of favorites\"\n class=\"shortcut\"\n [class.active]=\"(selectedPreset$ | async)?.id === favorite.id\"\n (click)=\"userSelectedPreset$.next(favorite)\"\n type=\"button\"\n >\n <span class=\"title\">{{ favorite.title }}</span>\n <button\n (click)=\"setFavorite(favorite, false)\"\n [rivTooltip]=\"'Remove favorite'\"\n type=\"button\"\n >\n <riv-icon [name]=\"'HeartActive'\" [size]=\"16\"></riv-icon>\n </button>\n </button>\n </div>\n </riv-input-label>\n </ng-template>\n </div>\n\n <div class=\"calendars\">\n <riv-calendar\n class=\"left\"\n [activeYearMonth]=\"(leftActiveYearMonth$ | async) || TODAY\"\n (activeYearMonthChange)=\"userLeftActiveYearMonth$.next($event)\"\n [displayMin]=\"(min$ | async) || TODAY\"\n [displayMax]=\"(max$ | async) || TODAY\"\n [selectableMin]=\"(leftMin$ | async) || TODAY\"\n [selectableMax]=\"(leftMax$ | async) || TODAY\"\n [omitRange]=\"(leftOmitRange$ | async) || [TODAY, TODAY]\"\n [selectedValue]=\"(selectedValue$ | async) || TODAY\"\n (dateSelect)=\"userSelectedDate$.next($event)\"\n ></riv-calendar>\n <riv-calendar\n class=\"right\"\n [activeYearMonth]=\"(rightActiveYearMonth$ | async) || TODAY\"\n (activeYearMonthChange)=\"userRightActiveYearMonth$.next($event)\"\n [displayMin]=\"(min$ | async) || TODAY\"\n [displayMax]=\"(max$ | async) || TODAY\"\n [selectableMin]=\"(rightMin$ | async) || TODAY\"\n [selectableMax]=\"(rightMax$ | async) || TODAY\"\n [selectedValue]=\"(selectedValue$ | async) || TODAY\"\n (dateSelect)=\"userSelectedDate$.next($event)\"\n ></riv-calendar>\n </div>\n\n <footer class=\"buttons\">\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n (click)=\"userSelectedDate$.next(undefined)\"\n type=\"button\"\n >\n Clear\n </button>\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'primary'\"\n (click)=\"open$.next(false)\"\n type=\"button\"\n >\n Done\n </button>\n </footer>\n </div>\n </riv-callout>\n</ng-template>\n", styles: [".trigger{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);display:flex;gap:var(--size-small)}.trigger:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.trigger:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.value{font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);color:var(--type-light-high-contrast);padding:var(--size-small);flex-grow:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:pre}.value.placeholder{color:var(--type-light-disabled)}.chevron{display:flex;justify-content:center;align-items:center;padding:var(--size-small);background-color:var(--surface-light-2);border-left:var(--border-width) solid var(--border-light)}.content{display:inline-grid;grid-template-rows:1fr auto;grid-template-columns:calc(var(--base-grid-size) * 50) 1fr 1fr}.presets{grid-area:1 / 1 / 3 / 2;background-color:var(--surface-light-1);padding:var(--size-xlarge) var(--size-large);border-right:var(--border-width) solid var(--border-light);display:flex;flex-direction:column;gap:var(--size-medium)}.preset{display:flex;transition:background-color var(--short-transition)}.preset:hover{background-color:var(--surface-light-2)}.preset button{color:transparent;transition:color var(--short-transition);padding:var(--size-medium) var(--size-large) var(--size-medium) var(--size-small)}.preset:hover button{color:var(--type-light-low-contrast)}.preset button:hover{color:var(--type-light-high-contrast)}.preset.favorite button{color:var(--type-light-link)}.preset .description{flex-grow:1;padding:var(--size-medium) var(--size-small) var(--size-medium) var(--size-medium)}.preset .title{display:block;font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-1)}.preset .subtitle{display:block;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-1);color:var(--type-light-low-contrast)}.shortcuts{display:flex;flex-direction:column;gap:var(--size-xsmall);overflow-y:auto}.shortcut{display:flex;align-items:center;padding:var(--size-small) var(--size-small) var(--size-small) var(--size-medium);gap:var(--size-small);border-radius:var(--border-radius-small);transition:background-color var(--short-transition)}.shortcut:hover{background-color:var(--black-20)}.shortcut.active{background-color:var(--baloo-05)}.shortcut .title{flex-grow:1;text-align:left;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-2)}.shortcut button{color:transparent;transition:color var(--short-transition)}.shortcut:hover button{color:var(--type-light-link)}.calendars{grid-column:2 / 4;display:grid;grid-template-columns:subgrid;grid-template-rows:subgrid;padding:var(--size-large)}.left{grid-area:1 / 1 / 2 / 2;padding-right:var(--size-large);border-right:var(--border-width) solid var(--border-light)}.right{padding-left:var(--size-large);grid-area:1 / 2 / 2 / 3}.buttons{grid-area:2 / 2 / 3 / 4;padding:var(--size-small);display:flex;justify-content:space-between}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "[rivButton]", inputs: ["locked", "disabled", "loading", "full", "size", "variant", "icon", "iconPosition"] }, { kind: "component", type: CalendarComponent, selector: "riv-calendar", inputs: ["activeYearMonth", "displayMin", "displayMax", "selectableMin", "selectableMax", "omitRange", "selectedValue"], outputs: ["activeYearMonthChange", "dateSelect"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }, { kind: "component", type: HighlightComponent, selector: "riv-highlight", inputs: ["text", "indices"] }, { kind: "component", type: IconComponent, selector: "riv-icon", inputs: ["name", "size", "customSize", "strokeWidth"] }, { kind: "component", type: InputLabelComponent, selector: "riv-input-label", inputs: ["label", "help", "required", "labelActionText"], outputs: ["labelAction"] }, { kind: "component", type: SingleSelectComponent, selector: "riv-single-select", inputs: ["groups", "selectedOption", "filterabilityOptions", "loading", "locked", "maxCalloutHeight", "noOptionsMessage", "nodeTemplate", "triggerTemplate", "placeholder", "disabled"], outputs: ["filterQueryChange", "selectedOptionChange"] }, { kind: "directive", type: TooltipDirective, selector: "[rivTooltip]", inputs: ["rivTooltip", "rivTooltipTheme", "rivTooltipMaxWidth", "rivTooltipPreferredPosition", "rivTooltipCloseDelay"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1845
1875
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DateRangeComponent, decorators: [{
|
|
1846
1876
|
type: Component,
|
|
1847
1877
|
args: [{ selector: 'riv-date-range', changeDetection: ChangeDetectionStrategy.OnPush, template: "<riv-input-label\n [label]=\"label\"\n [help]=\"help\"\n [required]=\"required\"\n [labelActionText]=\"labelActionText\"\n (labelAction)=\"labelAction.emit($event)\"\n>\n <button\n #trigger\n class=\"trigger\"\n (click)=\"open$.next(true)\"\n [disabled]=\"disabled$ | async\"\n type=\"button\"\n >\n <ng-container\n *ngIf=\"displayValue$ | async; else placeholderValue; let display\"\n >\n <span class=\"value\">{{ display }}</span>\n </ng-container>\n <ng-template #placeholderValue>\n <span class=\"value placeholder\">{{ placeholder$ | async }}</span>\n </ng-template>\n <span class=\"chevron\">\n <riv-icon [name]=\"'Calendar'\" [size]=\"16\"></riv-icon>\n </span>\n </button>\n</riv-input-label>\n\n<ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-inputValue\n [ngTemplateOutletContext]=\"{ $implicit: (value$ | async) }\"\n>\n <riv-callout\n *ngIf=\"open$ | async\"\n [anchor]=\"trigger\"\n [showCaret]=\"false\"\n [theme]=\"'light'\"\n [allowedPositions]=\"[\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-right',\n 'bottom-center',\n 'bottom-left'\n ]\"\n [preferredPosition]=\"'bottom-right'\"\n (close)=\"open$.next(false); userSelectedDate$.next(inputValue)\"\n >\n <div class=\"content\">\n <div *ngIf=\"showPresets\" class=\"presets\">\n <ng-template #presetTpl let-node=\"node\">\n <ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-isFavorite\n [ngTemplateOutletContext]=\"{\n $implicit: (favoritePresetIds$ | async)?.includes(node.id)\n }\"\n >\n <div class=\"preset\" [class.favorite]=\"isFavorite\">\n <div class=\"description\">\n <riv-highlight\n class=\"title\"\n [text]=\"node.title\"\n [indices]=\"node.titleHighlightIndices || []\"\n ></riv-highlight>\n <riv-highlight\n class=\"subtitle\"\n [text]=\"node.subtitle\"\n [indices]=\"node.subtitleHighlightIndices || []\"\n ></riv-highlight>\n </div>\n <button\n (click)=\"\n setFavorite(node, !isFavorite); $event.stopPropagation()\n \"\n type=\"button\"\n >\n <riv-icon\n [name]=\"isFavorite ? 'HeartActive' : 'Heart'\"\n [size]=\"16\"\n [rivTooltip]=\"'Mark as favorite'\"\n ></riv-icon>\n </button>\n </div>\n </ng-template>\n </ng-template>\n <riv-single-select\n [label]=\"'Date presets'\"\n [filterabilityOptions]=\"{ enabled: true, placeholder: 'Search...' }\"\n (filterQueryChange)=\"presetFilterQuery$.next($event)\"\n [groups]=\"(filteredPresetOptions$ | async) ?? []\"\n [selectedOption]=\"selectedPreset$ | async\"\n (selectedOptionChange)=\"userSelectedPreset$.next($event)\"\n [nodeTemplate]=\"presetTpl\"\n ></riv-single-select>\n <ng-template\n #self\n [ngTemplateOutlet]=\"self\"\n let-favorites\n [ngTemplateOutletContext]=\"{ $implicit: favoritePresets$ | async }\"\n >\n <riv-input-label *ngIf=\"favorites.length\" [label]=\"'Favorites'\">\n <div class=\"shortcuts\">\n <button\n *ngFor=\"let favorite of favorites\"\n class=\"shortcut\"\n [class.active]=\"(selectedPreset$ | async)?.id === favorite.id\"\n (click)=\"userSelectedPreset$.next(favorite)\"\n type=\"button\"\n >\n <span class=\"title\">{{ favorite.title }}</span>\n <button\n (click)=\"setFavorite(favorite, false)\"\n [rivTooltip]=\"'Remove favorite'\"\n type=\"button\"\n >\n <riv-icon [name]=\"'HeartActive'\" [size]=\"16\"></riv-icon>\n </button>\n </button>\n </div>\n </riv-input-label>\n </ng-template>\n </div>\n\n <div class=\"calendars\">\n <riv-calendar\n class=\"left\"\n [activeYearMonth]=\"(leftActiveYearMonth$ | async) || TODAY\"\n (activeYearMonthChange)=\"userLeftActiveYearMonth$.next($event)\"\n [displayMin]=\"(min$ | async) || TODAY\"\n [displayMax]=\"(max$ | async) || TODAY\"\n [selectableMin]=\"(leftMin$ | async) || TODAY\"\n [selectableMax]=\"(leftMax$ | async) || TODAY\"\n [omitRange]=\"(leftOmitRange$ | async) || [TODAY, TODAY]\"\n [selectedValue]=\"(selectedValue$ | async) || TODAY\"\n (dateSelect)=\"userSelectedDate$.next($event)\"\n ></riv-calendar>\n <riv-calendar\n class=\"right\"\n [activeYearMonth]=\"(rightActiveYearMonth$ | async) || TODAY\"\n (activeYearMonthChange)=\"userRightActiveYearMonth$.next($event)\"\n [displayMin]=\"(min$ | async) || TODAY\"\n [displayMax]=\"(max$ | async) || TODAY\"\n [selectableMin]=\"(rightMin$ | async) || TODAY\"\n [selectableMax]=\"(rightMax$ | async) || TODAY\"\n [selectedValue]=\"(selectedValue$ | async) || TODAY\"\n (dateSelect)=\"userSelectedDate$.next($event)\"\n ></riv-calendar>\n </div>\n\n <footer class=\"buttons\">\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'ghost'\"\n (click)=\"userSelectedDate$.next(undefined)\"\n type=\"button\"\n >\n Clear\n </button>\n <button\n rivButton\n [size]=\"'small'\"\n [variant]=\"'primary'\"\n (click)=\"open$.next(false)\"\n type=\"button\"\n >\n Done\n </button>\n </footer>\n </div>\n </riv-callout>\n</ng-template>\n", styles: [".trigger{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);display:flex;gap:var(--size-small)}.trigger:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.trigger:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.value{font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);color:var(--type-light-high-contrast);padding:var(--size-small);flex-grow:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:pre}.value.placeholder{color:var(--type-light-disabled)}.chevron{display:flex;justify-content:center;align-items:center;padding:var(--size-small);background-color:var(--surface-light-2);border-left:var(--border-width) solid var(--border-light)}.content{display:inline-grid;grid-template-rows:1fr auto;grid-template-columns:calc(var(--base-grid-size) * 50) 1fr 1fr}.presets{grid-area:1 / 1 / 3 / 2;background-color:var(--surface-light-1);padding:var(--size-xlarge) var(--size-large);border-right:var(--border-width) solid var(--border-light);display:flex;flex-direction:column;gap:var(--size-medium)}.preset{display:flex;transition:background-color var(--short-transition)}.preset:hover{background-color:var(--surface-light-2)}.preset button{color:transparent;transition:color var(--short-transition);padding:var(--size-medium) var(--size-large) var(--size-medium) var(--size-small)}.preset:hover button{color:var(--type-light-low-contrast)}.preset button:hover{color:var(--type-light-high-contrast)}.preset.favorite button{color:var(--type-light-link)}.preset .description{flex-grow:1;padding:var(--size-medium) var(--size-small) var(--size-medium) var(--size-medium)}.preset .title{display:block;font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-1)}.preset .subtitle{display:block;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-1);color:var(--type-light-low-contrast)}.shortcuts{display:flex;flex-direction:column;gap:var(--size-xsmall);overflow-y:auto}.shortcut{display:flex;align-items:center;padding:var(--size-small) var(--size-small) var(--size-small) var(--size-medium);gap:var(--size-small);border-radius:var(--border-radius-small);transition:background-color var(--short-transition)}.shortcut:hover{background-color:var(--black-20)}.shortcut.active{background-color:var(--baloo-05)}.shortcut .title{flex-grow:1;text-align:left;font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-2)}.shortcut button{color:transparent;transition:color var(--short-transition)}.shortcut:hover button{color:var(--type-light-link)}.calendars{grid-column:2 / 4;display:grid;grid-template-columns:subgrid;grid-template-rows:subgrid;padding:var(--size-large)}.left{grid-area:1 / 1 / 2 / 2;padding-right:var(--size-large);border-right:var(--border-width) solid var(--border-light)}.right{padding-left:var(--size-large);grid-area:1 / 2 / 2 / 3}.buttons{grid-area:2 / 2 / 3 / 4;padding:var(--size-small);display:flex;justify-content:space-between}\n"] }]
|
|
@@ -2164,6 +2194,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2164
2194
|
}]
|
|
2165
2195
|
}], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: CalloutService }, { type: i0.ChangeDetectorRef }]; } });
|
|
2166
2196
|
|
|
2197
|
+
class ContentService {
|
|
2198
|
+
constructor() {
|
|
2199
|
+
this.sizeChangesSource = new Subject();
|
|
2200
|
+
this.sizeChanges$ = this.sizeChangesSource.asObservable();
|
|
2201
|
+
this.resizeObserver = new ResizeObserver(entries => {
|
|
2202
|
+
for (const entry of entries) {
|
|
2203
|
+
this.sizeChangesSource.next({
|
|
2204
|
+
element: entry.target,
|
|
2205
|
+
width: entry.contentRect.width,
|
|
2206
|
+
height: entry.contentRect.height,
|
|
2207
|
+
});
|
|
2208
|
+
}
|
|
2209
|
+
});
|
|
2210
|
+
}
|
|
2211
|
+
observe(element) {
|
|
2212
|
+
this.resizeObserver.observe(element);
|
|
2213
|
+
}
|
|
2214
|
+
unobserve(element) {
|
|
2215
|
+
this.resizeObserver.unobserve(element);
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
ContentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2219
|
+
ContentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentService, providedIn: 'root' });
|
|
2220
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentService, decorators: [{
|
|
2221
|
+
type: Injectable,
|
|
2222
|
+
args: [{ providedIn: 'root' }]
|
|
2223
|
+
}], ctorParameters: function () { return []; } });
|
|
2224
|
+
|
|
2225
|
+
class SizeDirective {
|
|
2226
|
+
constructor(elementRef, contentService, zone) {
|
|
2227
|
+
this.elementRef = elementRef;
|
|
2228
|
+
this.contentService = contentService;
|
|
2229
|
+
this.zone = zone;
|
|
2230
|
+
this.rivClientSize = new EventEmitter();
|
|
2231
|
+
}
|
|
2232
|
+
ngOnInit() {
|
|
2233
|
+
this.contentService.observe(this.elementRef.nativeElement);
|
|
2234
|
+
this.subscription = this.contentService.sizeChanges$
|
|
2235
|
+
.pipe(filter(change => change.element === this.elementRef.nativeElement), debounceTimeAfterFirst(10))
|
|
2236
|
+
.subscribe(change => {
|
|
2237
|
+
this.rivClientSize.emit(change);
|
|
2238
|
+
// TODO: Hopefully we can take this out once we switch to signals and zoneless Angular
|
|
2239
|
+
this.zone.run(() => { });
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
ngOnDestroy() {
|
|
2243
|
+
var _a;
|
|
2244
|
+
this.contentService.unobserve(this.elementRef.nativeElement);
|
|
2245
|
+
(_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
SizeDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SizeDirective, deps: [{ token: i0.ElementRef }, { token: ContentService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2249
|
+
SizeDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: SizeDirective, selector: "[rivClientSize]", outputs: { rivClientSize: "rivClientSize" }, ngImport: i0 });
|
|
2250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SizeDirective, decorators: [{
|
|
2251
|
+
type: Directive,
|
|
2252
|
+
args: [{
|
|
2253
|
+
selector: '[rivClientSize]',
|
|
2254
|
+
}]
|
|
2255
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ContentService }, { type: i0.NgZone }]; }, propDecorators: { rivClientSize: [{
|
|
2256
|
+
type: Output
|
|
2257
|
+
}] } });
|
|
2258
|
+
function debounceTimeAfterFirst(delay) {
|
|
2259
|
+
return (source) => merge(source.pipe(take(1)), source.pipe(skip(1), debounceTime(delay)));
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2167
2262
|
class DataTableRowComponent {
|
|
2168
2263
|
constructor() {
|
|
2169
2264
|
this.subRow = false;
|
|
@@ -2607,17 +2702,7 @@ function getDateRange$1(stacks) {
|
|
|
2607
2702
|
function pointReducer(points) {
|
|
2608
2703
|
return points.reduce((total, { value }) => total + value, 0);
|
|
2609
2704
|
}
|
|
2610
|
-
function getColumnWidth(numColumns) {
|
|
2611
|
-
if (numColumns <= 6)
|
|
2612
|
-
return 72;
|
|
2613
|
-
if (numColumns <= 18)
|
|
2614
|
-
return 40;
|
|
2615
|
-
if (numColumns <= 40)
|
|
2616
|
-
return 16;
|
|
2617
|
-
return 8;
|
|
2618
|
-
}
|
|
2619
2705
|
|
|
2620
|
-
const MAX_COLUMNS = 72;
|
|
2621
2706
|
const DEFAULT_INTERVAL$1 = 'month';
|
|
2622
2707
|
// TODO: once we upgrade to Angular 16, this component can be cleaned up with
|
|
2623
2708
|
// signals instead of RxJS.
|
|
@@ -2625,16 +2710,30 @@ class StackedColumnComponent {
|
|
|
2625
2710
|
constructor() {
|
|
2626
2711
|
this.input$ = new BehaviorSubject([]);
|
|
2627
2712
|
this.width$ = new BehaviorSubject(960);
|
|
2628
|
-
this.
|
|
2713
|
+
this.HEIGHT = 300;
|
|
2629
2714
|
this.valueFormatter = v => v.toString();
|
|
2630
2715
|
this.interval$ = new BehaviorSubject(DEFAULT_INTERVAL$1);
|
|
2631
|
-
this.
|
|
2632
|
-
|
|
2716
|
+
this.COLUMN_WIDTHS = [8, 16, 40, 72];
|
|
2717
|
+
this.MIN_COLUMN_WIDTH = this.COLUMN_WIDTHS[0];
|
|
2718
|
+
this.numInvisibleColumns$ = this.input$.pipe(map(input => input.filter(stack => stack.filter(s => s.style == 'tooltipOnly').length > 0).length));
|
|
2719
|
+
this.numVisibleColumns$ = combineLatest([
|
|
2720
|
+
this.input$,
|
|
2721
|
+
this.numInvisibleColumns$,
|
|
2722
|
+
]).pipe(map(([input, numInvisibleColumns]) => input.length - numInvisibleColumns));
|
|
2723
|
+
this.maxColumns$ = this.width$.pipe(map(width => {
|
|
2724
|
+
const innerWidth = width - this.LEFT_OFFSET;
|
|
2725
|
+
const columnWidthWithPadding = this.MIN_COLUMN_WIDTH + this.COLUMN_PADDING * 2;
|
|
2726
|
+
return Math.floor(innerWidth / columnWidthWithPadding);
|
|
2727
|
+
}));
|
|
2728
|
+
this.allowedIntervals$ = combineLatest([
|
|
2729
|
+
this.input$,
|
|
2730
|
+
this.maxColumns$,
|
|
2731
|
+
this.numVisibleColumns$,
|
|
2732
|
+
]).pipe(map(([input, maxColumns, numVisibleColumns]) => {
|
|
2633
2733
|
const [minDate, maxDate] = getDateRange$1(input);
|
|
2634
2734
|
return intervals.filter(interval => {
|
|
2635
|
-
const
|
|
2636
|
-
|
|
2637
|
-
return numVisibleColumns * xStepsCount <= MAX_COLUMNS;
|
|
2735
|
+
const xStepsCount = this.getXStepsInRange(interval, minDate, maxDate);
|
|
2736
|
+
return numVisibleColumns * xStepsCount <= maxColumns;
|
|
2638
2737
|
});
|
|
2639
2738
|
}), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
2640
2739
|
this.intervalOptions$ = this.allowedIntervals$.pipe(map(intervals => intervals.map((interval) => ({
|
|
@@ -2660,6 +2759,26 @@ class StackedColumnComponent {
|
|
|
2660
2759
|
return (_a = options.find(o => o.id === interval)) !== null && _a !== void 0 ? _a : null;
|
|
2661
2760
|
}), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
2662
2761
|
this.selectedInterval$ = this.selectedIntervalOption$.pipe(map(option => (option ? option.id : DEFAULT_INTERVAL$1)));
|
|
2762
|
+
this.columnWidth$ = combineLatest([
|
|
2763
|
+
this.input$,
|
|
2764
|
+
this.selectedInterval$,
|
|
2765
|
+
this.numVisibleColumns$,
|
|
2766
|
+
this.width$,
|
|
2767
|
+
]).pipe(map(([input, selectedInterval, numVisibleColumns, width]) => {
|
|
2768
|
+
const [minDate, maxDate] = getDateRange$1(input);
|
|
2769
|
+
const xStepCount = this.getXStepsInRange(selectedInterval, minDate, maxDate);
|
|
2770
|
+
const innerWidth = width - this.LEFT_OFFSET;
|
|
2771
|
+
const allowedColumnWidths = this.COLUMN_WIDTHS.filter(columnWidth => {
|
|
2772
|
+
const columnWidthWithPadding = columnWidth + this.COLUMN_PADDING * 2;
|
|
2773
|
+
return (innerWidth -
|
|
2774
|
+
numVisibleColumns * xStepCount * columnWidthWithPadding >=
|
|
2775
|
+
0);
|
|
2776
|
+
});
|
|
2777
|
+
const columnWidth = allowedColumnWidths.at(-1);
|
|
2778
|
+
if (!columnWidth)
|
|
2779
|
+
return 0;
|
|
2780
|
+
return columnWidth;
|
|
2781
|
+
}));
|
|
2663
2782
|
this.binnedData$ = combineLatest([
|
|
2664
2783
|
this.input$,
|
|
2665
2784
|
this.selectedInterval$,
|
|
@@ -2681,16 +2800,16 @@ class StackedColumnComponent {
|
|
|
2681
2800
|
});
|
|
2682
2801
|
})), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
2683
2802
|
this.LEFT_OFFSET = 48;
|
|
2803
|
+
this.COLUMN_PADDING = 4;
|
|
2684
2804
|
this.drawData$ = combineLatest([
|
|
2685
2805
|
this.binnedData$,
|
|
2686
2806
|
this.width$,
|
|
2687
|
-
this.height$,
|
|
2688
2807
|
this.selectedInterval$,
|
|
2689
|
-
|
|
2690
|
-
|
|
2808
|
+
this.numInvisibleColumns$,
|
|
2809
|
+
this.columnWidth$,
|
|
2810
|
+
]).pipe(map(([binnedData, width, interval, numInvisibleColumns, columnWidth]) => {
|
|
2811
|
+
const viewBox = `0 0 ${width} ${this.HEIGHT}`;
|
|
2691
2812
|
const padding = 16;
|
|
2692
|
-
const invisColumns = binnedData.filter(stack => stack.filter(s => s.style == 'tooltipOnly').length > 0).length;
|
|
2693
|
-
const visibleColumns = binnedData.length - invisColumns;
|
|
2694
2813
|
const [minDate, maxDate] = getDateRange$1(binnedData);
|
|
2695
2814
|
const hasMultipleYears = minDate.getFullYear() < maxDate.getFullYear();
|
|
2696
2815
|
const xMinorIntervalFormat = getMinorIntervalFormat(interval);
|
|
@@ -2704,11 +2823,9 @@ class StackedColumnComponent {
|
|
|
2704
2823
|
const xOuterScale = scaleBand()
|
|
2705
2824
|
.domain(xSteps.map(date => fullFormatter(date)))
|
|
2706
2825
|
.range([this.LEFT_OFFSET, width]);
|
|
2707
|
-
const columnWidth = getColumnWidth(xSteps.length * visibleColumns);
|
|
2708
|
-
const columnPadding = 4;
|
|
2709
2826
|
const outerPadding = (xOuterScale.bandwidth() -
|
|
2710
|
-
(
|
|
2711
|
-
columnWidth * (binnedData.length -
|
|
2827
|
+
(this.COLUMN_PADDING * (binnedData.length - 1 - numInvisibleColumns) +
|
|
2828
|
+
columnWidth * (binnedData.length - numInvisibleColumns))) /
|
|
2712
2829
|
2;
|
|
2713
2830
|
const renderInformation = binnedData.map(stackData => {
|
|
2714
2831
|
/*
|
|
@@ -2783,7 +2900,7 @@ class StackedColumnComponent {
|
|
|
2783
2900
|
domainMax = 1;
|
|
2784
2901
|
const yScale = scaleLinear()
|
|
2785
2902
|
.domain([0, domainMax])
|
|
2786
|
-
.range([
|
|
2903
|
+
.range([this.HEIGHT - padding * 2, padding]);
|
|
2787
2904
|
const rects = [];
|
|
2788
2905
|
let invisColumnsSoFar = 0;
|
|
2789
2906
|
// For each unique stack,
|
|
@@ -2804,7 +2921,7 @@ class StackedColumnComponent {
|
|
|
2804
2921
|
const x = ((_a = xOuterScale(fullFormatter(date))) !== null && _a !== void 0 ? _a : 0) +
|
|
2805
2922
|
outerPadding +
|
|
2806
2923
|
columnWidth * (index - invisColumnsSoFar) +
|
|
2807
|
-
|
|
2924
|
+
this.COLUMN_PADDING * (index - invisColumnsSoFar);
|
|
2808
2925
|
const y = yScale(baseline) - height;
|
|
2809
2926
|
let fill = '';
|
|
2810
2927
|
if (seriesPoint.series.style != 'tooltipOnly') {
|
|
@@ -2848,8 +2965,9 @@ class StackedColumnComponent {
|
|
|
2848
2965
|
.filter((tick, i, ticks) => i === 0 || tick.label !== ticks[i - 1].label)
|
|
2849
2966
|
: [];
|
|
2850
2967
|
const yTicks = yScale.ticks(5);
|
|
2851
|
-
const hoverBandWidth = (renderInformation.length -
|
|
2852
|
-
(renderInformation.length + 1 -
|
|
2968
|
+
const hoverBandWidth = (renderInformation.length - numInvisibleColumns) * columnWidth +
|
|
2969
|
+
(renderInformation.length + 1 - numInvisibleColumns) *
|
|
2970
|
+
this.COLUMN_PADDING;
|
|
2853
2971
|
const hoverBands = xSteps.map(date => {
|
|
2854
2972
|
var _a;
|
|
2855
2973
|
return ({
|
|
@@ -2899,36 +3017,27 @@ class StackedColumnComponent {
|
|
|
2899
3017
|
set width(v) {
|
|
2900
3018
|
this.width$.next(v);
|
|
2901
3019
|
}
|
|
2902
|
-
get width() {
|
|
2903
|
-
return this.width$.getValue();
|
|
2904
|
-
}
|
|
2905
|
-
set height(v) {
|
|
2906
|
-
this.height$.next(v);
|
|
2907
|
-
}
|
|
2908
|
-
get height() {
|
|
2909
|
-
return this.height$.getValue();
|
|
2910
|
-
}
|
|
2911
3020
|
set interval(v) {
|
|
2912
3021
|
this.interval$.next(v);
|
|
2913
3022
|
}
|
|
2914
3023
|
get interval() {
|
|
2915
3024
|
return this.interval$.getValue();
|
|
2916
3025
|
}
|
|
3026
|
+
getXStepsInRange(interval, minDate, maxDate) {
|
|
3027
|
+
const timeInterval = getTimeInterval(interval);
|
|
3028
|
+
return timeInterval.range(timeInterval.floor(minDate), timeInterval.floor(timeInterval.offset(maxDate, 1))).length;
|
|
3029
|
+
}
|
|
2917
3030
|
setIntervalOption(option) {
|
|
2918
3031
|
this.interval = option.id;
|
|
2919
3032
|
}
|
|
2920
3033
|
}
|
|
2921
3034
|
StackedColumnComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: StackedColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2922
|
-
StackedColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: StackedColumnComponent, selector: "riv-stacked-column", inputs: { input: "input",
|
|
3035
|
+
StackedColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: StackedColumnComponent, selector: "riv-stacked-column", inputs: { input: "input", valueFormatter: "valueFormatter", interval: "interval" }, viewQueries: [{ propertyName: "controls", first: true, predicate: ["controls"], descendants: true }], ngImport: i0, template: "<div\n *ngIf=\"!(empty$ | async); else zeroState\"\n class=\"container\"\n (rivClientSize)=\"width = $event.width\"\n>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let d\"\n [attr.viewBox]=\"d.viewBox\"\n >\n <defs>\n <pattern\n id=\"stripes\"\n x=\"0\"\n y=\"0\"\n [attr.width]=\"d.columnWidth\"\n [attr.height]=\"d.columnWidth\"\n patternUnits=\"userSpaceOnUse\"\n >\n <line\n x1=\"0\"\n [attr.y1]=\"d.columnWidth\"\n [attr.x2]=\"d.columnWidth\"\n y2=\"0\"\n stroke=\"var(--white-100)\"\n stroke-width=\"1\"\n ></line>\n </pattern>\n </defs>\n <g *ngFor=\"let tick of d.xMinorTicks\">\n <rect\n class=\"tick-background\"\n [class.focused]=\"(hoveredBand$ | async)?.dateValue === tick.dateValue\"\n [attr.x]=\"tick.x - 20\"\n [attr.y]=\"d.yScale(0) + 3\"\n width=\"40\"\n height=\"12\"\n rx=\"2\"\n ></rect>\n <text\n class=\"tick-label\"\n [attr.x]=\"tick.x\"\n [attr.y]=\"d.yScale(0) + 12\"\n text-anchor=\"middle\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.xMajorTicks\">\n <text\n class=\"tick-label\"\n [attr.x]=\"tick.x\"\n [attr.y]=\"d.yScale(0) + 24\"\n text-anchor=\"middle\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.yTicks\">\n <rect\n class=\"tick\"\n x=\"0\"\n [attr.y]=\"d.yScale(tick)\"\n width=\"100%\"\n height=\"1\"\n ></rect>\n <text class=\"tick-label\" x=\"0\" [attr.y]=\"d.yScale(tick)\" dy=\"-4\">\n {{ valueFormatter(tick) }}\n </text>\n </g>\n <g *ngFor=\"let rect of d.rects\">\n <rect\n class=\"column\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n [attr.fill]=\"rect.fill\"\n [class.blurred]=\"\n (hoveredBand$ | async) !== null &&\n (hoveredBand$ | async)?.dateValue !== rect.dateValue\n \"\n ></rect>\n <rect\n *ngIf=\"rect.striped\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n fill=\"url(#stripes)\"\n ></rect>\n </g>\n <rect\n *ngFor=\"let rect of d.hoverBands\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n fill=\"transparent\"\n (mouseenter)=\"\n hoveredBand$.next({ dateValue: rect.dateValue, event: $event })\n \"\n (mouseleave)=\"hoveredBand$.next(null)\"\n ></rect>\n </svg>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'center-right'\"\n [allowedPositions]=\"[\n 'center-right',\n 'center-left',\n 'top-center',\n 'bottom-center'\n ]\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n\n<ng-template #controls>\n <riv-single-select\n [groups]=\"intervalOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedIntervalOption$ | async\"\n (selectedOptionChange)=\"setIntervalOption($event)\"\n ></riv-single-select>\n</ng-template>\n", styles: [".tick{fill:var(--gray-20)}.tick-label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);fill:var(--type-light-low-contrast)}.tick-background{transition:fill var(--short-transition);fill:transparent}.tick-background.focused{fill:var(--baloo-10)}.column{transition:opacity var(--short-transition)}.column.blurred{opacity:.4}.callout-content{padding:var(--size-large);display:grid;gap:var(--size-medium);grid-template-columns:1fr 1fr}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }, { kind: "directive", type: CalloutDirective, selector: "[riv-callout]" }, { kind: "component", type: SingleSelectComponent, selector: "riv-single-select", inputs: ["groups", "selectedOption", "filterabilityOptions", "loading", "locked", "maxCalloutHeight", "noOptionsMessage", "nodeTemplate", "triggerTemplate", "placeholder", "disabled"], outputs: ["filterQueryChange", "selectedOptionChange"] }, { kind: "directive", type: SizeDirective, selector: "[rivClientSize]", outputs: ["rivClientSize"] }, { kind: "component", type: ZeroStateComponent, selector: "riv-zero-state", inputs: ["message"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: OptionGroupPipe, name: "rivOptionGroup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2923
3036
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: StackedColumnComponent, decorators: [{
|
|
2924
3037
|
type: Component,
|
|
2925
|
-
args: [{ selector: 'riv-stacked-column', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
3038
|
+
args: [{ selector: 'riv-stacked-column', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n *ngIf=\"!(empty$ | async); else zeroState\"\n class=\"container\"\n (rivClientSize)=\"width = $event.width\"\n>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let d\"\n [attr.viewBox]=\"d.viewBox\"\n >\n <defs>\n <pattern\n id=\"stripes\"\n x=\"0\"\n y=\"0\"\n [attr.width]=\"d.columnWidth\"\n [attr.height]=\"d.columnWidth\"\n patternUnits=\"userSpaceOnUse\"\n >\n <line\n x1=\"0\"\n [attr.y1]=\"d.columnWidth\"\n [attr.x2]=\"d.columnWidth\"\n y2=\"0\"\n stroke=\"var(--white-100)\"\n stroke-width=\"1\"\n ></line>\n </pattern>\n </defs>\n <g *ngFor=\"let tick of d.xMinorTicks\">\n <rect\n class=\"tick-background\"\n [class.focused]=\"(hoveredBand$ | async)?.dateValue === tick.dateValue\"\n [attr.x]=\"tick.x - 20\"\n [attr.y]=\"d.yScale(0) + 3\"\n width=\"40\"\n height=\"12\"\n rx=\"2\"\n ></rect>\n <text\n class=\"tick-label\"\n [attr.x]=\"tick.x\"\n [attr.y]=\"d.yScale(0) + 12\"\n text-anchor=\"middle\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.xMajorTicks\">\n <text\n class=\"tick-label\"\n [attr.x]=\"tick.x\"\n [attr.y]=\"d.yScale(0) + 24\"\n text-anchor=\"middle\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.yTicks\">\n <rect\n class=\"tick\"\n x=\"0\"\n [attr.y]=\"d.yScale(tick)\"\n width=\"100%\"\n height=\"1\"\n ></rect>\n <text class=\"tick-label\" x=\"0\" [attr.y]=\"d.yScale(tick)\" dy=\"-4\">\n {{ valueFormatter(tick) }}\n </text>\n </g>\n <g *ngFor=\"let rect of d.rects\">\n <rect\n class=\"column\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n [attr.fill]=\"rect.fill\"\n [class.blurred]=\"\n (hoveredBand$ | async) !== null &&\n (hoveredBand$ | async)?.dateValue !== rect.dateValue\n \"\n ></rect>\n <rect\n *ngIf=\"rect.striped\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n fill=\"url(#stripes)\"\n ></rect>\n </g>\n <rect\n *ngFor=\"let rect of d.hoverBands\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n fill=\"transparent\"\n (mouseenter)=\"\n hoveredBand$.next({ dateValue: rect.dateValue, event: $event })\n \"\n (mouseleave)=\"hoveredBand$.next(null)\"\n ></rect>\n </svg>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'center-right'\"\n [allowedPositions]=\"[\n 'center-right',\n 'center-left',\n 'top-center',\n 'bottom-center'\n ]\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state></riv-zero-state>\n</ng-template>\n\n<ng-template #controls>\n <riv-single-select\n [groups]=\"intervalOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedIntervalOption$ | async\"\n (selectedOptionChange)=\"setIntervalOption($event)\"\n ></riv-single-select>\n</ng-template>\n", styles: [".tick{fill:var(--gray-20)}.tick-label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);fill:var(--type-light-low-contrast)}.tick-background{transition:fill var(--short-transition);fill:transparent}.tick-background.focused{fill:var(--baloo-10)}.column{transition:opacity var(--short-transition)}.column.blurred{opacity:.4}.callout-content{padding:var(--size-large);display:grid;gap:var(--size-medium);grid-template-columns:1fr 1fr}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"] }]
|
|
2926
3039
|
}], propDecorators: { input: [{
|
|
2927
3040
|
type: Input
|
|
2928
|
-
}], width: [{
|
|
2929
|
-
type: Input
|
|
2930
|
-
}], height: [{
|
|
2931
|
-
type: Input
|
|
2932
3041
|
}], valueFormatter: [{
|
|
2933
3042
|
type: Input
|
|
2934
3043
|
}], interval: [{
|
|
@@ -3011,18 +3120,42 @@ class StackedRowComponent {
|
|
|
3011
3120
|
// This is the list of rows we will display, in the order we will display them.
|
|
3012
3121
|
this.input$ = new BehaviorSubject([]);
|
|
3013
3122
|
// Width helps determine the size of the viewbox this graph is displaying in.
|
|
3014
|
-
this.width$ = new BehaviorSubject(
|
|
3015
|
-
// Height helps determine the size of the viewbox this graph is displaying in.
|
|
3016
|
-
this.height$ = new BehaviorSubject(null);
|
|
3123
|
+
this.width$ = new BehaviorSubject(0);
|
|
3017
3124
|
// ValueFormatter determines how we style the values in a metric and the x-axis
|
|
3018
3125
|
this.valueFormatter = v => v.toString();
|
|
3019
3126
|
this.zeroStateMessage$ = new BehaviorSubject('No data to display.');
|
|
3127
|
+
this.chartAndRowHeights$ = this.input$.pipe(map(input => {
|
|
3128
|
+
const heightWithoutRows = input.length * this.SECTION_PADDING.BETWEEN_ROW +
|
|
3129
|
+
this.SECTION_PADDING.OUTER_TOP_BOTTOM * 2 +
|
|
3130
|
+
this.SECTION_HEIGHTS.X_AXIS_LABEL;
|
|
3131
|
+
// The combined height of all rows at their min/max
|
|
3132
|
+
const minHeight = input.length * this.RECTANGLE_HEIGHTS.MIN_HEIGHT + heightWithoutRows;
|
|
3133
|
+
const maxHeight = input.length * this.RECTANGLE_HEIGHTS.MAX_HEIGHT + heightWithoutRows;
|
|
3134
|
+
// If the max-sized rows don't need the target size, shrink the chart
|
|
3135
|
+
if (maxHeight < this.TARGET_HEIGHT)
|
|
3136
|
+
return {
|
|
3137
|
+
chartHeight: maxHeight,
|
|
3138
|
+
rowHeight: this.RECTANGLE_HEIGHTS.MAX_HEIGHT,
|
|
3139
|
+
};
|
|
3140
|
+
// If the min-sized rows need more than the target size, grow the chart
|
|
3141
|
+
if (minHeight > this.TARGET_HEIGHT)
|
|
3142
|
+
return {
|
|
3143
|
+
chartHeight: minHeight,
|
|
3144
|
+
rowHeight: this.RECTANGLE_HEIGHTS.MIN_HEIGHT,
|
|
3145
|
+
};
|
|
3146
|
+
// Otherwise shrink the rows to fit the target size
|
|
3147
|
+
return {
|
|
3148
|
+
chartHeight: this.TARGET_HEIGHT,
|
|
3149
|
+
rowHeight: (this.TARGET_HEIGHT - heightWithoutRows) / input.length,
|
|
3150
|
+
};
|
|
3151
|
+
}));
|
|
3020
3152
|
/*
|
|
3021
3153
|
The layout we are shooting for is:
|
|
3022
3154
|
|
|
3023
3155
|
| X Axis Labels |
|
|
3024
3156
|
Row Name | Rectangles | Totals
|
|
3025
3157
|
*/
|
|
3158
|
+
this.TARGET_HEIGHT = 300;
|
|
3026
3159
|
this.RECTANGLE_HEIGHTS = {
|
|
3027
3160
|
MIN_HEIGHT: 12,
|
|
3028
3161
|
MAX_HEIGHT: 42, // Sets the largest size a row can expand to
|
|
@@ -3030,36 +3163,6 @@ class StackedRowComponent {
|
|
|
3030
3163
|
this.SECTION_HEIGHTS = {
|
|
3031
3164
|
// Space reserved for the x-axis labels
|
|
3032
3165
|
X_AXIS_LABEL: 14,
|
|
3033
|
-
// Height of each row
|
|
3034
|
-
PER_ROW: () => {
|
|
3035
|
-
//Only use height if specified
|
|
3036
|
-
if (this.input.length && this.height) {
|
|
3037
|
-
let rowHeight = (this.height -
|
|
3038
|
-
this.SECTION_HEIGHTS.X_AXIS_LABEL -
|
|
3039
|
-
this.SECTION_PADDING.OUTER_TOP_BOTTOM -
|
|
3040
|
-
this.SECTION_PADDING.RECTANGLE_TO_ROW) /
|
|
3041
|
-
this.input.length -
|
|
3042
|
-
this.SECTION_PADDING.BETWEEN_ROW; // calculate base row height
|
|
3043
|
-
// Clamping the row height between the min and max heights
|
|
3044
|
-
return Math.min(Math.max(rowHeight, this.RECTANGLE_HEIGHTS.MIN_HEIGHT), this.RECTANGLE_HEIGHTS.MAX_HEIGHT);
|
|
3045
|
-
}
|
|
3046
|
-
return this.RECTANGLE_HEIGHTS.MIN_HEIGHT; // Default if no input
|
|
3047
|
-
},
|
|
3048
|
-
// Max Height of each rectangle
|
|
3049
|
-
PER_RECTANGLE: () => {
|
|
3050
|
-
//Only use height if specified
|
|
3051
|
-
if (this.input.length && this.height) {
|
|
3052
|
-
let rectangleHeight = (this.height -
|
|
3053
|
-
this.SECTION_HEIGHTS.X_AXIS_LABEL -
|
|
3054
|
-
this.SECTION_PADDING.OUTER_TOP_BOTTOM -
|
|
3055
|
-
this.SECTION_PADDING.RECTANGLE_TO_ROW) /
|
|
3056
|
-
this.input.length -
|
|
3057
|
-
this.SECTION_PADDING.BETWEEN_ROW; // calculate base rectangle height
|
|
3058
|
-
// Clamping the rectangle height between the min and max heights
|
|
3059
|
-
return Math.min(Math.max(rectangleHeight, this.RECTANGLE_HEIGHTS.MIN_HEIGHT), this.RECTANGLE_HEIGHTS.MAX_HEIGHT);
|
|
3060
|
-
}
|
|
3061
|
-
return this.RECTANGLE_HEIGHTS.MIN_HEIGHT; // Default if no input
|
|
3062
|
-
},
|
|
3063
3166
|
};
|
|
3064
3167
|
this.SECTION_WIDTHS = {
|
|
3065
3168
|
// Space reserved for the name at the start of the row
|
|
@@ -3084,16 +3187,9 @@ class StackedRowComponent {
|
|
|
3084
3187
|
this.drawData$ = combineLatest([
|
|
3085
3188
|
this.input$,
|
|
3086
3189
|
this.width$,
|
|
3087
|
-
this.
|
|
3190
|
+
this.chartAndRowHeights$,
|
|
3088
3191
|
]).pipe(map(([input, width, height]) => {
|
|
3089
|
-
return this.getDrawnData(input, width, height
|
|
3090
|
-
? height
|
|
3091
|
-
: this.SECTION_HEIGHTS.X_AXIS_LABEL +
|
|
3092
|
-
this.SECTION_PADDING.OUTER_TOP_BOTTOM +
|
|
3093
|
-
this.SECTION_PADDING.RECTANGLE_TO_ROW +
|
|
3094
|
-
(this.SECTION_HEIGHTS.PER_ROW() +
|
|
3095
|
-
this.SECTION_PADDING.BETWEEN_ROW) *
|
|
3096
|
-
input.length);
|
|
3192
|
+
return this.getDrawnData(input, width, height.chartHeight, height.rowHeight);
|
|
3097
3193
|
}), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
3098
3194
|
// Lets us know whether to display the zero data state
|
|
3099
3195
|
this.empty$ = this.input$.pipe(map(input => input.every(stack => stack.data.length === 0)), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
@@ -3127,15 +3223,6 @@ class StackedRowComponent {
|
|
|
3127
3223
|
set width(v) {
|
|
3128
3224
|
this.width$.next(v);
|
|
3129
3225
|
}
|
|
3130
|
-
get width() {
|
|
3131
|
-
return this.width$.getValue();
|
|
3132
|
-
}
|
|
3133
|
-
set height(v) {
|
|
3134
|
-
this.height$.next(v);
|
|
3135
|
-
}
|
|
3136
|
-
get height() {
|
|
3137
|
-
return this.height$.getValue();
|
|
3138
|
-
}
|
|
3139
3226
|
set zeroStateMessage(v) {
|
|
3140
3227
|
this.zeroStateMessage$.next(v);
|
|
3141
3228
|
}
|
|
@@ -3157,19 +3244,19 @@ class StackedRowComponent {
|
|
|
3157
3244
|
return (this.SECTION_PADDING.OUTER_TOP_BOTTOM + this.SECTION_HEIGHTS.X_AXIS_LABEL);
|
|
3158
3245
|
}
|
|
3159
3246
|
// The y-index of the top of the current row
|
|
3160
|
-
getTopOfRow(rowIndex) {
|
|
3247
|
+
getTopOfRow(rowIndex, rowHeight) {
|
|
3161
3248
|
const spaceAboveRows = this.SECTION_PADDING.OUTER_TOP_BOTTOM + this.SECTION_HEIGHTS.X_AXIS_LABEL;
|
|
3162
|
-
const aboveRows = rowIndex *
|
|
3249
|
+
const aboveRows = rowIndex * rowHeight;
|
|
3163
3250
|
const aboveRowPaddings = rowIndex * this.SECTION_PADDING.BETWEEN_ROW;
|
|
3164
3251
|
const allAboveRows = aboveRows + aboveRowPaddings;
|
|
3165
3252
|
return spaceAboveRows + allAboveRows;
|
|
3166
3253
|
}
|
|
3167
3254
|
// Calculate all the values we need for displaying the graph on screen.
|
|
3168
|
-
getDrawnData(rowStacks, width,
|
|
3255
|
+
getDrawnData(rowStacks, width, chartHeight, rowHeight) {
|
|
3169
3256
|
if (rowStacks.length == 0) {
|
|
3170
3257
|
return null;
|
|
3171
3258
|
}
|
|
3172
|
-
const viewBox = `0 0 ${width} ${
|
|
3259
|
+
const viewBox = `0 0 ${width} ${chartHeight}`;
|
|
3173
3260
|
const keysInOrder = getKeyOrder(rowStacks);
|
|
3174
3261
|
const standardizedRows = standardizeRowStacks(rowStacks, keysInOrder);
|
|
3175
3262
|
const rowsForDisplay = standardizedRows.map(stackData => {
|
|
@@ -3187,13 +3274,13 @@ class StackedRowComponent {
|
|
|
3187
3274
|
.clamp(true); // Ensures the scale does not go beyond the defined range
|
|
3188
3275
|
const xtickCountAdjusted = Math.round(tickScale(width));
|
|
3189
3276
|
const xTicks = xScale.ticks(xtickCountAdjusted);
|
|
3190
|
-
const rects = this.createRectanglesFromRows(rowsForDisplay, xScale);
|
|
3191
|
-
const rowNamesToDraw = this.getRowNamesToDraw(rowsForDisplay);
|
|
3192
|
-
const rowTotalsToDraw = this.getRowTotalsToDraw(rowsForDisplay, width);
|
|
3277
|
+
const rects = this.createRectanglesFromRows(rowsForDisplay, xScale, rowHeight);
|
|
3278
|
+
const rowNamesToDraw = this.getRowNamesToDraw(rowsForDisplay, rowHeight);
|
|
3279
|
+
const rowTotalsToDraw = this.getRowTotalsToDraw(rowsForDisplay, width, rowHeight);
|
|
3193
3280
|
const legendItems = getLegendItems(rowsForDisplay, keysInOrder);
|
|
3194
3281
|
return {
|
|
3195
3282
|
legendItems: legendItems,
|
|
3196
|
-
rowHeight:
|
|
3283
|
+
rowHeight: rowHeight,
|
|
3197
3284
|
rects: rects,
|
|
3198
3285
|
rowNames: rowNamesToDraw,
|
|
3199
3286
|
rowTotals: rowTotalsToDraw,
|
|
@@ -3203,20 +3290,20 @@ class StackedRowComponent {
|
|
|
3203
3290
|
};
|
|
3204
3291
|
}
|
|
3205
3292
|
// Get data for all the rectangles for all the rows
|
|
3206
|
-
createRectanglesFromRows(displayRows, xScale) {
|
|
3293
|
+
createRectanglesFromRows(displayRows, xScale, rowHeight) {
|
|
3207
3294
|
const rectangles = [];
|
|
3208
3295
|
displayRows.forEach((currentRow, rowIndex) => {
|
|
3209
3296
|
currentRow.elementsButStacked.forEach((currentElement, _) => {
|
|
3210
|
-
const topOfRow = this.getTopOfRow(rowIndex);
|
|
3297
|
+
const topOfRow = this.getTopOfRow(rowIndex, rowHeight);
|
|
3211
3298
|
const rectangleWidth = xScale(currentElement.topline) - xScale(currentElement.baseline);
|
|
3212
|
-
const rectangleHeight =
|
|
3299
|
+
const rectangleHeight = rowHeight;
|
|
3213
3300
|
const rectangleX = xScale(currentElement.baseline);
|
|
3214
3301
|
const rectangleY = topOfRow + this.SECTION_PADDING.RECTANGLE_TO_ROW;
|
|
3215
3302
|
const fill = `var(${currentElement.colorToken})`;
|
|
3216
3303
|
rectangles.push({
|
|
3217
3304
|
x: rectangleX,
|
|
3218
3305
|
y: rectangleY,
|
|
3219
|
-
width: rectangleWidth,
|
|
3306
|
+
width: Math.max(rectangleWidth, 0),
|
|
3220
3307
|
height: rectangleHeight,
|
|
3221
3308
|
fill: fill,
|
|
3222
3309
|
striped: currentElement.style === 'striped',
|
|
@@ -3228,13 +3315,13 @@ class StackedRowComponent {
|
|
|
3228
3315
|
return rectangles;
|
|
3229
3316
|
}
|
|
3230
3317
|
// Get data on the row names we are drawing
|
|
3231
|
-
getRowNamesToDraw(displayRows) {
|
|
3318
|
+
getRowNamesToDraw(displayRows, rowHeight) {
|
|
3232
3319
|
return displayRows.map((row, rowIndex) => {
|
|
3233
3320
|
const rowLabelX = this.SECTION_PADDING.OUTER_LEFT_RIGHT;
|
|
3234
3321
|
// The row name looks right if its base is at the base of the associated rectangle
|
|
3235
|
-
const rowLabelY = this.getTopOfRow(rowIndex) +
|
|
3322
|
+
const rowLabelY = this.getTopOfRow(rowIndex, rowHeight) +
|
|
3236
3323
|
this.SECTION_PADDING.RECTANGLE_TO_ROW +
|
|
3237
|
-
|
|
3324
|
+
rowHeight / 2;
|
|
3238
3325
|
return {
|
|
3239
3326
|
label: row.rowName,
|
|
3240
3327
|
x: rowLabelX,
|
|
@@ -3243,13 +3330,13 @@ class StackedRowComponent {
|
|
|
3243
3330
|
});
|
|
3244
3331
|
}
|
|
3245
3332
|
// Get data on the row totals we are drawing
|
|
3246
|
-
getRowTotalsToDraw(displayRows, width) {
|
|
3333
|
+
getRowTotalsToDraw(displayRows, width, rowHeight) {
|
|
3247
3334
|
return displayRows.map((row, rowIndex) => {
|
|
3248
3335
|
const rowLabelX = width - this.SECTION_PADDING.OUTER_LEFT_RIGHT;
|
|
3249
3336
|
// The row totals looks right if its base is at the base of the associated rectangle
|
|
3250
|
-
const rowLabelY = this.getTopOfRow(rowIndex) +
|
|
3337
|
+
const rowLabelY = this.getTopOfRow(rowIndex, rowHeight) +
|
|
3251
3338
|
this.SECTION_PADDING.RECTANGLE_TO_ROW +
|
|
3252
|
-
|
|
3339
|
+
rowHeight / 2;
|
|
3253
3340
|
return {
|
|
3254
3341
|
label: this.valueFormatter(row.rowTotal),
|
|
3255
3342
|
x: rowLabelX,
|
|
@@ -3259,16 +3346,12 @@ class StackedRowComponent {
|
|
|
3259
3346
|
}
|
|
3260
3347
|
}
|
|
3261
3348
|
StackedRowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: StackedRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3262
|
-
StackedRowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: StackedRowComponent, selector: "riv-stacked-row", inputs: { input: "input",
|
|
3349
|
+
StackedRowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: StackedRowComponent, selector: "riv-stacked-row", inputs: { input: "input", valueFormatter: "valueFormatter", zeroStateMessage: "zeroStateMessage" }, ngImport: i0, template: "<div\n *ngIf=\"!(empty$ | async); else zeroState\"\n class=\"container\"\n (rivClientSize)=\"width = $event.width\"\n>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let draw\"\n [attr.viewBox]=\"draw.viewBox\"\n >\n <defs>\n <pattern\n id=\"stripes\"\n x=\"0\"\n y=\"0\"\n [attr.width]=\"draw.rowHeight\"\n [attr.height]=\"draw.rowHeight\"\n patternUnits=\"userSpaceOnUse\"\n >\n <line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"draw.rowHeight\"\n [attr.y2]=\"draw.rowHeight\"\n stroke=\"var(--white-100)\"\n stroke-width=\"1\"\n ></line>\n </pattern>\n </defs>\n <g *ngFor=\"let rowNameToDraw of draw.rowNames\">\n <text\n rivSVGTextTruncate\n [text]=\"rowNameToDraw.label\"\n [width]=\"SECTION_WIDTHS.ROW_NAME\"\n class=\"row-title\"\n [attr.x]=\"rowNameToDraw.x\"\n [attr.y]=\"rowNameToDraw.y\"\n ></text>\n </g>\n <g *ngFor=\"let tick of draw.xTicks\">\n <rect\n class=\"tick\"\n [attr.x]=\"draw.xScale(tick)\"\n y=\"0\"\n width=\"1\"\n height=\"100%\"\n ></rect>\n <text\n class=\"tick-label\"\n [attr.x]=\"draw.xScale(tick)\"\n [attr.y]=\"locationOfXAxisTick()\"\n dx=\"4\"\n dy=\"-4\"\n >\n {{ valueFormatter(tick) }}\n </text>\n </g>\n <g\n *ngFor=\"let rect of draw.rects\"\n (mouseenter)=\"hoveredBand$.next({ rowName: rect.rowName, event: $event })\"\n (mouseleave)=\"hoveredBand$.next(null)\"\n >\n <rect\n class=\"row\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n [attr.fill]=\"rect.fill\"\n [class.blurred]=\"\n (hoveredBand$ | async) !== null &&\n (hoveredBand$ | async)?.rowName !== rect.rowName\n \"\n ></rect>\n <rect\n *ngIf=\"rect.striped\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n fill=\"url(#stripes)\"\n ></rect>\n </g>\n <g *ngFor=\"let rowTotalToDraw of draw.rowTotals\">\n <text\n class=\"row-total\"\n [attr.x]=\"rowTotalToDraw.x\"\n [attr.y]=\"rowTotalToDraw.y\"\n text-anchor=\"end\"\n >\n {{ rowTotalToDraw.label }}\n </text>\n </g>\n </svg>\n <legend *ngIf=\"drawData$ | async; let draw\">\n <riv-legend-item\n *ngFor=\"let item of draw.legendItems\"\n [label]=\"item.label\"\n [colorToken]=\"item.colorToken\"\n [style]=\"item.style ? item.style : 'solid'\"\n ></riv-legend-item>\n </legend>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'bottom-center'\"\n [allowedPositions]=\"[\n 'center-right',\n 'center-left',\n 'top-center',\n 'bottom-center'\n ]\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state [message]=\"zeroStateMessage\"></riv-zero-state>\n</ng-template>\n", styles: [".tick{fill:var(--gray-20)}.tick-label{font-size:var(--type-0-font-size);line-height:var(--type-0-line-height-0);fill:var(--type-light-low-contrast)}.row-title{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-2)}.row-total{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-2);fill:var(--type-light-low-contrast)}.row{transition:opacity var(--short-transition)}.row.blurred{opacity:.4}legend{display:flex;flex-wrap:wrap;gap:var(--size-large);justify-content:flex-start;align-items:baseline}.callout-content{padding:var(--size-large);display:grid;gap:var(--size-medium);grid-template-columns:1fr 1fr}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }, { kind: "directive", type: CalloutDirective, selector: "[riv-callout]" }, { kind: "component", type: LegendItemComponent, selector: "riv-legend-item", inputs: ["label", "colorToken", "style", "visibility", "iconTooltip", "clickable", "showCheckWhenClickable"], outputs: ["itemClick"] }, { kind: "directive", type: SizeDirective, selector: "[rivClientSize]", outputs: ["rivClientSize"] }, { kind: "directive", type: SVGTextTruncateDirective, selector: "svg text[rivSVGTextTruncate]", inputs: ["text", "width"] }, { kind: "component", type: ZeroStateComponent, selector: "riv-zero-state", inputs: ["message"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3263
3350
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: StackedRowComponent, decorators: [{
|
|
3264
3351
|
type: Component,
|
|
3265
|
-
args: [{ selector: 'riv-stacked-row', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
3352
|
+
args: [{ selector: 'riv-stacked-row', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n *ngIf=\"!(empty$ | async); else zeroState\"\n class=\"container\"\n (rivClientSize)=\"width = $event.width\"\n>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let draw\"\n [attr.viewBox]=\"draw.viewBox\"\n >\n <defs>\n <pattern\n id=\"stripes\"\n x=\"0\"\n y=\"0\"\n [attr.width]=\"draw.rowHeight\"\n [attr.height]=\"draw.rowHeight\"\n patternUnits=\"userSpaceOnUse\"\n >\n <line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"draw.rowHeight\"\n [attr.y2]=\"draw.rowHeight\"\n stroke=\"var(--white-100)\"\n stroke-width=\"1\"\n ></line>\n </pattern>\n </defs>\n <g *ngFor=\"let rowNameToDraw of draw.rowNames\">\n <text\n rivSVGTextTruncate\n [text]=\"rowNameToDraw.label\"\n [width]=\"SECTION_WIDTHS.ROW_NAME\"\n class=\"row-title\"\n [attr.x]=\"rowNameToDraw.x\"\n [attr.y]=\"rowNameToDraw.y\"\n ></text>\n </g>\n <g *ngFor=\"let tick of draw.xTicks\">\n <rect\n class=\"tick\"\n [attr.x]=\"draw.xScale(tick)\"\n y=\"0\"\n width=\"1\"\n height=\"100%\"\n ></rect>\n <text\n class=\"tick-label\"\n [attr.x]=\"draw.xScale(tick)\"\n [attr.y]=\"locationOfXAxisTick()\"\n dx=\"4\"\n dy=\"-4\"\n >\n {{ valueFormatter(tick) }}\n </text>\n </g>\n <g\n *ngFor=\"let rect of draw.rects\"\n (mouseenter)=\"hoveredBand$.next({ rowName: rect.rowName, event: $event })\"\n (mouseleave)=\"hoveredBand$.next(null)\"\n >\n <rect\n class=\"row\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n [attr.fill]=\"rect.fill\"\n [class.blurred]=\"\n (hoveredBand$ | async) !== null &&\n (hoveredBand$ | async)?.rowName !== rect.rowName\n \"\n ></rect>\n <rect\n *ngIf=\"rect.striped\"\n [attr.x]=\"rect.x\"\n [attr.y]=\"rect.y\"\n [attr.width]=\"rect.width\"\n [attr.height]=\"rect.height\"\n fill=\"url(#stripes)\"\n ></rect>\n </g>\n <g *ngFor=\"let rowTotalToDraw of draw.rowTotals\">\n <text\n class=\"row-total\"\n [attr.x]=\"rowTotalToDraw.x\"\n [attr.y]=\"rowTotalToDraw.y\"\n text-anchor=\"end\"\n >\n {{ rowTotalToDraw.label }}\n </text>\n </g>\n </svg>\n <legend *ngIf=\"drawData$ | async; let draw\">\n <riv-legend-item\n *ngFor=\"let item of draw.legendItems\"\n [label]=\"item.label\"\n [colorToken]=\"item.colorToken\"\n [style]=\"item.style ? item.style : 'solid'\"\n ></riv-legend-item>\n </legend>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'bottom-center'\"\n [allowedPositions]=\"[\n 'center-right',\n 'center-left',\n 'top-center',\n 'bottom-center'\n ]\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state [message]=\"zeroStateMessage\"></riv-zero-state>\n</ng-template>\n", styles: [".tick{fill:var(--gray-20)}.tick-label{font-size:var(--type-0-font-size);line-height:var(--type-0-line-height-0);fill:var(--type-light-low-contrast)}.row-title{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-2)}.row-total{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-2);fill:var(--type-light-low-contrast)}.row{transition:opacity var(--short-transition)}.row.blurred{opacity:.4}legend{display:flex;flex-wrap:wrap;gap:var(--size-large);justify-content:flex-start;align-items:baseline}.callout-content{padding:var(--size-large);display:grid;gap:var(--size-medium);grid-template-columns:1fr 1fr}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"] }]
|
|
3266
3353
|
}], propDecorators: { input: [{
|
|
3267
3354
|
type: Input
|
|
3268
|
-
}], width: [{
|
|
3269
|
-
type: Input
|
|
3270
|
-
}], height: [{
|
|
3271
|
-
type: Input
|
|
3272
3355
|
}], valueFormatter: [{
|
|
3273
3356
|
type: Input
|
|
3274
3357
|
}], zeroStateMessage: [{
|
|
@@ -3290,7 +3373,6 @@ function getDateRange(configs) {
|
|
|
3290
3373
|
return [new Date(min), new Date(max)];
|
|
3291
3374
|
}
|
|
3292
3375
|
|
|
3293
|
-
const MAX_POINTS = 90;
|
|
3294
3376
|
const DEFAULT_INTERVAL = 'day';
|
|
3295
3377
|
// TODO: once we upgrade to Angular 16, this component can be cleaned up with
|
|
3296
3378
|
// signals instead of RxJS. See commit e238c2d.
|
|
@@ -3303,8 +3385,8 @@ class TimeSeriesComponent {
|
|
|
3303
3385
|
series: [],
|
|
3304
3386
|
},
|
|
3305
3387
|
]);
|
|
3306
|
-
this.width$ = new BehaviorSubject(
|
|
3307
|
-
this.
|
|
3388
|
+
this.width$ = new BehaviorSubject(0);
|
|
3389
|
+
this.HEIGHT = 300;
|
|
3308
3390
|
this.zeroStateMessage$ = new BehaviorSubject('No data to display.');
|
|
3309
3391
|
this.BOTTOM_OFFSET = 24;
|
|
3310
3392
|
this.LEFT_OFFSET = 48;
|
|
@@ -3313,15 +3395,24 @@ class TimeSeriesComponent {
|
|
|
3313
3395
|
this.BOTTOM_PADDING = 8;
|
|
3314
3396
|
this.Y_TICK_COUNT = 5;
|
|
3315
3397
|
this.X_MINOR_TICK_LIMIT = 15;
|
|
3398
|
+
this.POINT_RADIUS = 3.5;
|
|
3316
3399
|
this.dateRange$ = this.input$.pipe(map(getDateRange), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
3317
3400
|
this.interval$ = new BehaviorSubject(DEFAULT_INTERVAL);
|
|
3318
3401
|
this.allowLegendToggle$ = new BehaviorSubject(false);
|
|
3319
|
-
this.
|
|
3402
|
+
this.maxPoints$ = this.width$.pipe(map(width => {
|
|
3403
|
+
const innerWidth = width - this.LEFT_OFFSET;
|
|
3404
|
+
const pointWithPadding = (this.POINT_RADIUS + 1) * 2;
|
|
3405
|
+
return Math.floor(innerWidth / pointWithPadding);
|
|
3406
|
+
}));
|
|
3407
|
+
this.allowedIntervals$ = combineLatest([
|
|
3408
|
+
this.input$,
|
|
3409
|
+
this.maxPoints$,
|
|
3410
|
+
]).pipe(map(([input, maxPoints]) => {
|
|
3320
3411
|
const [minDateValue, maxDateValue] = getDateRange(input);
|
|
3321
3412
|
return intervals.filter(interval => {
|
|
3322
3413
|
const timeInterval = getTimeInterval(interval);
|
|
3323
3414
|
const numSteps = timeInterval.range(timeInterval.floor(minDateValue), timeInterval.ceil(utcDay.offset(maxDateValue, 1))).length;
|
|
3324
|
-
return numSteps <=
|
|
3415
|
+
return numSteps <= maxPoints && numSteps > 1;
|
|
3325
3416
|
});
|
|
3326
3417
|
}), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
3327
3418
|
this.intervalOptions$ = this.allowedIntervals$.pipe(map(intervals => intervals.map((interval) => ({
|
|
@@ -3379,9 +3470,8 @@ class TimeSeriesComponent {
|
|
|
3379
3470
|
this.binnedDateRange$,
|
|
3380
3471
|
this.selectedInterval$,
|
|
3381
3472
|
this.width$,
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
const viewBox = `0 0 ${width} ${height}`;
|
|
3473
|
+
]).pipe(map(([binnedData, binnedDateRange, interval, width]) => {
|
|
3474
|
+
const viewBox = `0 0 ${width} ${this.HEIGHT}`;
|
|
3385
3475
|
const xScale = scaleLinear()
|
|
3386
3476
|
.domain(binnedDateRange)
|
|
3387
3477
|
.range([
|
|
@@ -3430,7 +3520,7 @@ class TimeSeriesComponent {
|
|
|
3430
3520
|
const yScale = scaleLinear()
|
|
3431
3521
|
.domain([yMin, yMax])
|
|
3432
3522
|
.range([
|
|
3433
|
-
|
|
3523
|
+
this.HEIGHT -
|
|
3434
3524
|
this.BOTTOM_OFFSET -
|
|
3435
3525
|
(this.BOTTOM_PADDING + this.TOP_PADDING),
|
|
3436
3526
|
this.TOP_PADDING,
|
|
@@ -3513,15 +3603,6 @@ class TimeSeriesComponent {
|
|
|
3513
3603
|
set width(v) {
|
|
3514
3604
|
this.width$.next(v);
|
|
3515
3605
|
}
|
|
3516
|
-
get width() {
|
|
3517
|
-
return this.width$.getValue();
|
|
3518
|
-
}
|
|
3519
|
-
set height(v) {
|
|
3520
|
-
this.height$.next(v);
|
|
3521
|
-
}
|
|
3522
|
-
get height() {
|
|
3523
|
-
return this.height$.getValue();
|
|
3524
|
-
}
|
|
3525
3606
|
set zeroStateMessage(v) {
|
|
3526
3607
|
this.zeroStateMessage$.next(v);
|
|
3527
3608
|
}
|
|
@@ -3545,16 +3626,12 @@ class TimeSeriesComponent {
|
|
|
3545
3626
|
}
|
|
3546
3627
|
}
|
|
3547
3628
|
TimeSeriesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TimeSeriesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3548
|
-
TimeSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TimeSeriesComponent, selector: "riv-time-series", inputs: { input: "input",
|
|
3629
|
+
TimeSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TimeSeriesComponent, selector: "riv-time-series", inputs: { input: "input", zeroStateMessage: "zeroStateMessage", interval: "interval", allowLegendToggle: "allowLegendToggle" }, viewQueries: [{ propertyName: "controls", first: true, predicate: ["controls"], descendants: true }], ngImport: i0, template: "<div\n *ngIf=\"!(empty$ | async); else zeroState\"\n class=\"container\"\n (rivClientSize)=\"width = $event.width\"\n>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let d\"\n [attr.viewBox]=\"d.viewBox\"\n >\n <g *ngFor=\"let tick of d.x.xMajorTicks\">\n <rect\n class=\"tick\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n y=\"0\"\n width=\"1\"\n [attr.height]=\"d.y1.yScale(d.y1.yMin)\"\n ></rect>\n <text\n *ngIf=\"d.x.xScale(tick.value) >= 0\"\n class=\"x-major-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n dx=\"4\"\n dy=\"-4\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.x.xMinorTicks\">\n <text\n class=\"x-minor-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n text-anchor=\"middle\"\n dominant-baseline=\"hanging\"\n dy=\"8\"\n >\n {{ tick.label }}\n <title>{{ tick.value | date }}</title>\n </text>\n </g>\n <g *ngFor=\"let tick of d.y1.yTicks\">\n <rect\n class=\"tick\"\n x=\"0\"\n [attr.y]=\"d.y1.yScale(tick)\"\n width=\"100%\"\n height=\"1\"\n ></rect>\n <text class=\"y-tick-label\" x=\"0\" [attr.y]=\"d.y1.yScale(tick)\" dy=\"-4\">\n {{ d.y1.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngFor=\"let tick of d.y2?.yTicks\">\n <text\n class=\"y-tick-label\"\n [attr.x]=\"d.x.xScale(d.x.xMax)\"\n [attr.y]=\"d.y2?.yScale(tick)\"\n text-anchor=\"end\"\n dy=\"-4\"\n >\n {{ d.y2?.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngIf=\"hoveredMarker$ | async; let hoveredMarker\">\n <line\n class=\"hover-rule\"\n [attr.x1]=\"hoveredMarker.marker.x\"\n [attr.y1]=\"d.y1.yScale(d.y1.yMin)\"\n [attr.x2]=\"hoveredMarker.marker.x\"\n [attr.y2]=\"d.y1.yScale(d.y1.yMax)\"\n stroke-width=\"2\"\n stroke-dasharray=\"4\"\n />\n </g>\n\n <ng-template #seriesTpl let-series=\"series\">\n <path\n *ngIf=\"series.visibility != 'hidden'\"\n class=\"data path\"\n [class.marker-hovered]=\"!!(hoveredMarker$ | async)\"\n [attr.d]=\"series.path\"\n fill=\"none\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n [attr.stroke-dasharray]=\"series.style === 'dashed' ? '4' : null\"\n ></path>\n <ng-container *ngFor=\"let marker of series.markers\">\n <circle\n *ngIf=\"series.visibility != 'hidden'\"\n class=\"data marker\"\n [class.focused]=\"(hoveredMarker$ | async)?.marker?.x === marker.x\"\n [class.blurred]=\"\n (hoveredMarker$ | async) !== null &&\n (hoveredMarker$ | async)?.marker?.x !== marker.x\n \"\n [attr.cx]=\"marker.x\"\n [attr.cy]=\"marker.y\"\n [attr.r]=\"POINT_RADIUS\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n (mouseover)=\"hoveredMarker$.next({ event: $event, marker: marker })\"\n (mouseleave)=\"hoveredMarker$.next(null)\"\n ></circle>\n </ng-container>\n </ng-template>\n <g *ngFor=\"let series of d.y1.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n <g *ngFor=\"let series of d.y2?.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n </svg>\n <legend>\n <riv-legend-item\n *ngFor=\"let item of legend$ | async\"\n [label]=\"item.label\"\n [colorToken]=\"item.colorToken\"\n [visibility]=\"item.visibility\"\n [clickable]=\"allowLegendToggle\"\n (itemClick)=\"\n allowLegendToggle\n ? toggleVisibility$.next({\n label: item.label,\n visibility: item.visibility == 'hidden' ? 'visible' : 'hidden'\n })\n : null\n \"\n ></riv-legend-item>\n </legend>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'top-center'\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state [message]=\"zeroStateMessage\"></riv-zero-state>\n</ng-template>\n\n<ng-template #controls>\n <riv-single-select\n [groups]=\"intervalOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedIntervalOption$ | async\"\n (selectedOptionChange)=\"setIntervalOption($event)\"\n ></riv-single-select>\n</ng-template>\n", styles: [".container{display:flex;flex-direction:column;gap:var(--size-xlarge)}.y-tick-label,.x-major-tick-label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);fill:var(--type-light-low-contrast)}.x-minor-tick-label{font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);fill:var(--type-light-low-contrast);text-anchor:middle}.tick{fill:var(--gray-20)}.data.path{transition:stroke-opacity var(--short-transition)}.data.path.marker-hovered{stroke-opacity:.4}.data.marker{fill:var(--surface-light-0);transition:stroke-opacity var(--short-transition)}.data.marker.focused{stroke-opacity:1;filter:drop-shadow(0 1px 1px rgba(10,2,22,.15))}.data.marker.blurred{stroke-opacity:.4}.hover-rule{stroke:var(--gray-20)}legend{display:flex;flex-wrap:wrap;gap:var(--size-large);justify-content:flex-start;align-items:baseline}.callout-content{padding:var(--size-large);display:flex;gap:var(--size-medium)}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }, { kind: "directive", type: CalloutDirective, selector: "[riv-callout]" }, { kind: "component", type: LegendItemComponent, selector: "riv-legend-item", inputs: ["label", "colorToken", "style", "visibility", "iconTooltip", "clickable", "showCheckWhenClickable"], outputs: ["itemClick"] }, { kind: "component", type: SingleSelectComponent, selector: "riv-single-select", inputs: ["groups", "selectedOption", "filterabilityOptions", "loading", "locked", "maxCalloutHeight", "noOptionsMessage", "nodeTemplate", "triggerTemplate", "placeholder", "disabled"], outputs: ["filterQueryChange", "selectedOptionChange"] }, { kind: "directive", type: SizeDirective, selector: "[rivClientSize]", outputs: ["rivClientSize"] }, { kind: "component", type: ZeroStateComponent, selector: "riv-zero-state", inputs: ["message"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "pipe", type: OptionGroupPipe, name: "rivOptionGroup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3549
3630
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TimeSeriesComponent, decorators: [{
|
|
3550
3631
|
type: Component,
|
|
3551
|
-
args: [{ selector: 'riv-time-series', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
3632
|
+
args: [{ selector: 'riv-time-series', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n *ngIf=\"!(empty$ | async); else zeroState\"\n class=\"container\"\n (rivClientSize)=\"width = $event.width\"\n>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n *ngIf=\"drawData$ | async; let d\"\n [attr.viewBox]=\"d.viewBox\"\n >\n <g *ngFor=\"let tick of d.x.xMajorTicks\">\n <rect\n class=\"tick\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n y=\"0\"\n width=\"1\"\n [attr.height]=\"d.y1.yScale(d.y1.yMin)\"\n ></rect>\n <text\n *ngIf=\"d.x.xScale(tick.value) >= 0\"\n class=\"x-major-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n dx=\"4\"\n dy=\"-4\"\n >\n {{ tick.label }}\n </text>\n </g>\n <g *ngFor=\"let tick of d.x.xMinorTicks\">\n <text\n class=\"x-minor-tick-label\"\n [attr.x]=\"d.x.xScale(tick.value)\"\n [attr.y]=\"d.y1.yScale(d.y1.yMin)\"\n text-anchor=\"middle\"\n dominant-baseline=\"hanging\"\n dy=\"8\"\n >\n {{ tick.label }}\n <title>{{ tick.value | date }}</title>\n </text>\n </g>\n <g *ngFor=\"let tick of d.y1.yTicks\">\n <rect\n class=\"tick\"\n x=\"0\"\n [attr.y]=\"d.y1.yScale(tick)\"\n width=\"100%\"\n height=\"1\"\n ></rect>\n <text class=\"y-tick-label\" x=\"0\" [attr.y]=\"d.y1.yScale(tick)\" dy=\"-4\">\n {{ d.y1.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngFor=\"let tick of d.y2?.yTicks\">\n <text\n class=\"y-tick-label\"\n [attr.x]=\"d.x.xScale(d.x.xMax)\"\n [attr.y]=\"d.y2?.yScale(tick)\"\n text-anchor=\"end\"\n dy=\"-4\"\n >\n {{ d.y2?.valueFormatter(tick) }}\n </text>\n </g>\n\n <g *ngIf=\"hoveredMarker$ | async; let hoveredMarker\">\n <line\n class=\"hover-rule\"\n [attr.x1]=\"hoveredMarker.marker.x\"\n [attr.y1]=\"d.y1.yScale(d.y1.yMin)\"\n [attr.x2]=\"hoveredMarker.marker.x\"\n [attr.y2]=\"d.y1.yScale(d.y1.yMax)\"\n stroke-width=\"2\"\n stroke-dasharray=\"4\"\n />\n </g>\n\n <ng-template #seriesTpl let-series=\"series\">\n <path\n *ngIf=\"series.visibility != 'hidden'\"\n class=\"data path\"\n [class.marker-hovered]=\"!!(hoveredMarker$ | async)\"\n [attr.d]=\"series.path\"\n fill=\"none\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n [attr.stroke-dasharray]=\"series.style === 'dashed' ? '4' : null\"\n ></path>\n <ng-container *ngFor=\"let marker of series.markers\">\n <circle\n *ngIf=\"series.visibility != 'hidden'\"\n class=\"data marker\"\n [class.focused]=\"(hoveredMarker$ | async)?.marker?.x === marker.x\"\n [class.blurred]=\"\n (hoveredMarker$ | async) !== null &&\n (hoveredMarker$ | async)?.marker?.x !== marker.x\n \"\n [attr.cx]=\"marker.x\"\n [attr.cy]=\"marker.y\"\n [attr.r]=\"POINT_RADIUS\"\n stroke-width=\"2\"\n [attr.stroke]=\"series.stroke\"\n (mouseover)=\"hoveredMarker$.next({ event: $event, marker: marker })\"\n (mouseleave)=\"hoveredMarker$.next(null)\"\n ></circle>\n </ng-container>\n </ng-template>\n <g *ngFor=\"let series of d.y1.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n <g *ngFor=\"let series of d.y2?.series\">\n <ng-container\n *ngTemplateOutlet=\"seriesTpl; context: { series: series }\"\n ></ng-container>\n </g>\n </svg>\n <legend>\n <riv-legend-item\n *ngFor=\"let item of legend$ | async\"\n [label]=\"item.label\"\n [colorToken]=\"item.colorToken\"\n [visibility]=\"item.visibility\"\n [clickable]=\"allowLegendToggle\"\n (itemClick)=\"\n allowLegendToggle\n ? toggleVisibility$.next({\n label: item.label,\n visibility: item.visibility == 'hidden' ? 'visible' : 'hidden'\n })\n : null\n \"\n ></riv-legend-item>\n </legend>\n</div>\n\n<ng-container *ngIf=\"callout$ | async; let callout\">\n <riv-callout\n *riv-callout\n [anchor]=\"callout.anchor\"\n [isModal]=\"false\"\n [preferredPosition]=\"'top-center'\"\n >\n <div class=\"callout-content\">\n <div class=\"callout-metric\" *ngFor=\"let metric of callout.metrics\">\n <div>{{ metric.label }}</div>\n <div class=\"callout-metric-value\">{{ metric.value }}</div>\n </div>\n </div>\n </riv-callout>\n</ng-container>\n\n<ng-template #zeroState>\n <riv-zero-state [message]=\"zeroStateMessage\"></riv-zero-state>\n</ng-template>\n\n<ng-template #controls>\n <riv-single-select\n [groups]=\"intervalOptions$ | async | rivOptionGroup\"\n [selectedOption]=\"selectedIntervalOption$ | async\"\n (selectedOptionChange)=\"setIntervalOption($event)\"\n ></riv-single-select>\n</ng-template>\n", styles: [".container{display:flex;flex-direction:column;gap:var(--size-xlarge)}.y-tick-label,.x-major-tick-label{font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0);fill:var(--type-light-low-contrast)}.x-minor-tick-label{font-size:var(--type-2-font-size);line-height:var(--type-2-line-height-0);fill:var(--type-light-low-contrast);text-anchor:middle}.tick{fill:var(--gray-20)}.data.path{transition:stroke-opacity var(--short-transition)}.data.path.marker-hovered{stroke-opacity:.4}.data.marker{fill:var(--surface-light-0);transition:stroke-opacity var(--short-transition)}.data.marker.focused{stroke-opacity:1;filter:drop-shadow(0 1px 1px rgba(10,2,22,.15))}.data.marker.blurred{stroke-opacity:.4}.hover-rule{stroke:var(--gray-20)}legend{display:flex;flex-wrap:wrap;gap:var(--size-large);justify-content:flex-start;align-items:baseline}.callout-content{padding:var(--size-large);display:flex;gap:var(--size-medium)}.callout-metric{display:flex;flex-direction:column;gap:var(--size-xsmall);font-size:var(--type-1-font-size);line-height:var(--type-1-line-height-0)}.callout-metric-value{font-weight:var(--font-weight-heavy)}\n"] }]
|
|
3552
3633
|
}], propDecorators: { input: [{
|
|
3553
3634
|
type: Input
|
|
3554
|
-
}], width: [{
|
|
3555
|
-
type: Input
|
|
3556
|
-
}], height: [{
|
|
3557
|
-
type: Input
|
|
3558
3635
|
}], zeroStateMessage: [{
|
|
3559
3636
|
type: Input
|
|
3560
3637
|
}], interval: [{
|
|
@@ -3584,6 +3661,7 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
|
|
|
3584
3661
|
DaysPipe,
|
|
3585
3662
|
DollarsPipe,
|
|
3586
3663
|
DonutComponent,
|
|
3664
|
+
FocusOnInitDirective,
|
|
3587
3665
|
FunnelChartComponent,
|
|
3588
3666
|
HelpComponent,
|
|
3589
3667
|
HighlightComponent,
|
|
@@ -3600,6 +3678,7 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
|
|
|
3600
3678
|
OptionGroupPipe,
|
|
3601
3679
|
PercentagePipe,
|
|
3602
3680
|
SingleSelectComponent,
|
|
3681
|
+
SizeDirective,
|
|
3603
3682
|
SmallCurrencyPipe,
|
|
3604
3683
|
StackedColumnComponent,
|
|
3605
3684
|
StackedRowComponent,
|
|
@@ -3624,6 +3703,7 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
|
|
|
3624
3703
|
DaysPipe,
|
|
3625
3704
|
DollarsPipe,
|
|
3626
3705
|
DonutComponent,
|
|
3706
|
+
FocusOnInitDirective,
|
|
3627
3707
|
FunnelChartComponent,
|
|
3628
3708
|
HelpComponent,
|
|
3629
3709
|
HighlightComponent,
|
|
@@ -3639,6 +3719,7 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
|
|
|
3639
3719
|
OptionGroupPipe,
|
|
3640
3720
|
PercentagePipe,
|
|
3641
3721
|
SingleSelectComponent,
|
|
3722
|
+
SizeDirective,
|
|
3642
3723
|
SmallCurrencyPipe,
|
|
3643
3724
|
StackedColumnComponent,
|
|
3644
3725
|
StackedRowComponent,
|
|
@@ -3670,6 +3751,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3670
3751
|
DaysPipe,
|
|
3671
3752
|
DollarsPipe,
|
|
3672
3753
|
DonutComponent,
|
|
3754
|
+
FocusOnInitDirective,
|
|
3673
3755
|
FunnelChartComponent,
|
|
3674
3756
|
HelpComponent,
|
|
3675
3757
|
HighlightComponent,
|
|
@@ -3686,6 +3768,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3686
3768
|
OptionGroupPipe,
|
|
3687
3769
|
PercentagePipe,
|
|
3688
3770
|
SingleSelectComponent,
|
|
3771
|
+
SizeDirective,
|
|
3689
3772
|
SmallCurrencyPipe,
|
|
3690
3773
|
StackedColumnComponent,
|
|
3691
3774
|
StackedRowComponent,
|
|
@@ -3713,6 +3796,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3713
3796
|
DaysPipe,
|
|
3714
3797
|
DollarsPipe,
|
|
3715
3798
|
DonutComponent,
|
|
3799
|
+
FocusOnInitDirective,
|
|
3716
3800
|
FunnelChartComponent,
|
|
3717
3801
|
HelpComponent,
|
|
3718
3802
|
HighlightComponent,
|
|
@@ -3728,6 +3812,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3728
3812
|
OptionGroupPipe,
|
|
3729
3813
|
PercentagePipe,
|
|
3730
3814
|
SingleSelectComponent,
|
|
3815
|
+
SizeDirective,
|
|
3731
3816
|
SmallCurrencyPipe,
|
|
3732
3817
|
StackedColumnComponent,
|
|
3733
3818
|
StackedRowComponent,
|
|
@@ -3748,5 +3833,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3748
3833
|
* Generated bundle index. Do not edit.
|
|
3749
3834
|
*/
|
|
3750
3835
|
|
|
3751
|
-
export { ButtonComponent, CalloutComponent, CalloutDirective, CalloutOutletComponent, DataTableCellComponent, DataTableComponent, DataTableHeaderCellComponent, DataTableRowComponent, DateComponent, DatePipe, DateRangeComponent, DaysPipe, DollarsPipe, DonutComponent, FunnelChartComponent, HelpComponent, HighlightComponent, IconComponent, InputLabelComponent, IssueComponent, LegendItemComponent, LinkComponent, LoadingComponent, LoadingCoverComponent, MetricComponent, NumberPipe, OptionGroupPipe, PercentagePipe, RivModule, SVGTextTruncateDirective, SingleSelectComponent, SmallCurrencyPipe, StackedColumnComponent, StackedRowComponent, TextToggleComponent, TimeSeriesComponent, TooltipComponent, TooltipDirective, TrendComponent, TruncateComponent, ZeroStateComponent };
|
|
3836
|
+
export { ButtonComponent, CalloutComponent, CalloutDirective, CalloutOutletComponent, DataTableCellComponent, DataTableComponent, DataTableHeaderCellComponent, DataTableRowComponent, DateComponent, DatePipe, DateRangeComponent, DaysPipe, DollarsPipe, DonutComponent, FocusOnInitDirective, FunnelChartComponent, HelpComponent, HighlightComponent, IconComponent, InputLabelComponent, IssueComponent, LegendItemComponent, LinkComponent, LoadingComponent, LoadingCoverComponent, MetricComponent, NumberPipe, OptionGroupPipe, PercentagePipe, RivModule, SVGTextTruncateDirective, SingleSelectComponent, SizeDirective, SmallCurrencyPipe, StackedColumnComponent, StackedRowComponent, TextToggleComponent, TimeSeriesComponent, TooltipComponent, TooltipDirective, TrendComponent, TruncateComponent, ZeroStateComponent };
|
|
3752
3837
|
//# sourceMappingURL=rivet-health-design-system.mjs.map
|