@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';
|
|
@@ -1172,15 +1172,23 @@ class LocalStorage extends BehaviorSubject {
|
|
|
1172
1172
|
}
|
|
1173
1173
|
|
|
1174
1174
|
class HelpComponent {
|
|
1175
|
+
constructor() {
|
|
1176
|
+
this.size = 16;
|
|
1177
|
+
}
|
|
1175
1178
|
}
|
|
1176
1179
|
HelpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HelpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1177
|
-
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]=\"
|
|
1180
|
+
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 });
|
|
1178
1181
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HelpComponent, decorators: [{
|
|
1179
1182
|
type: Component,
|
|
1180
|
-
args: [{ selector: 'riv-help', changeDetection: ChangeDetectionStrategy.OnPush, template: "<riv-icon [rivTooltip]=\"help\" [name]=\"'Info'\" [size]=\"
|
|
1183
|
+
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"] }]
|
|
1181
1184
|
}], propDecorators: { help: [{
|
|
1182
1185
|
type: Input
|
|
1186
|
+
}], size: [{
|
|
1187
|
+
type: Input
|
|
1183
1188
|
}] } });
|
|
1189
|
+
(function (HelpComponent) {
|
|
1190
|
+
HelpComponent.Sizes = [12, 16];
|
|
1191
|
+
})(HelpComponent || (HelpComponent = {}));
|
|
1184
1192
|
|
|
1185
1193
|
class LinkComponent {
|
|
1186
1194
|
constructor() {
|
|
@@ -1212,7 +1220,7 @@ class InputLabelComponent {
|
|
|
1212
1220
|
}
|
|
1213
1221
|
}
|
|
1214
1222
|
InputLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: InputLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1215
|
-
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 });
|
|
1223
|
+
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 });
|
|
1216
1224
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: InputLabelComponent, decorators: [{
|
|
1217
1225
|
type: Component,
|
|
1218
1226
|
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"] }]
|
|
@@ -1228,6 +1236,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1228
1236
|
type: Output
|
|
1229
1237
|
}] } });
|
|
1230
1238
|
|
|
1239
|
+
class FocusOnInitDirective {
|
|
1240
|
+
constructor(el) {
|
|
1241
|
+
this.el = el;
|
|
1242
|
+
this.shouldFocus = true;
|
|
1243
|
+
this.focusOnChange = false;
|
|
1244
|
+
}
|
|
1245
|
+
ngAfterViewInit() {
|
|
1246
|
+
if (this.shouldFocus) {
|
|
1247
|
+
this.focus();
|
|
1248
|
+
}
|
|
1249
|
+
else {
|
|
1250
|
+
this.focusOnChange = true;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
ngOnChanges() {
|
|
1254
|
+
if (this.focusOnChange && this.shouldFocus) {
|
|
1255
|
+
this.focusOnChange = false;
|
|
1256
|
+
this.focus();
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
focus() {
|
|
1260
|
+
if (this.el && this.el.nativeElement) {
|
|
1261
|
+
if (!this.el.nativeElement.hasAttribute('tabindex')) {
|
|
1262
|
+
this.el.nativeElement.tabIndex = 0;
|
|
1263
|
+
}
|
|
1264
|
+
this.el.nativeElement.focus();
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
FocusOnInitDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FocusOnInitDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1269
|
+
FocusOnInitDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: FocusOnInitDirective, selector: "[rivFocusOnInit]", inputs: { shouldFocus: ["rivFocusOnInit", "shouldFocus"] }, usesOnChanges: true, ngImport: i0 });
|
|
1270
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FocusOnInitDirective, decorators: [{
|
|
1271
|
+
type: Directive,
|
|
1272
|
+
args: [{
|
|
1273
|
+
selector: '[rivFocusOnInit]',
|
|
1274
|
+
}]
|
|
1275
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { shouldFocus: [{
|
|
1276
|
+
type: Input,
|
|
1277
|
+
args: ['rivFocusOnInit']
|
|
1278
|
+
}] } });
|
|
1279
|
+
|
|
1231
1280
|
function chunks(text, indices) {
|
|
1232
1281
|
let lastEnd = 0;
|
|
1233
1282
|
const chunks = [];
|
|
@@ -1297,6 +1346,7 @@ class SingleSelectComponent extends InputLabelComponent {
|
|
|
1297
1346
|
};
|
|
1298
1347
|
this.loading = false;
|
|
1299
1348
|
this.locked = false;
|
|
1349
|
+
this.maxCalloutHeight = '50vh';
|
|
1300
1350
|
this.noOptionsMessage = 'No available options';
|
|
1301
1351
|
this.placeholder = 'Select...';
|
|
1302
1352
|
this.disabled = false;
|
|
@@ -1324,6 +1374,15 @@ class SingleSelectComponent extends InputLabelComponent {
|
|
|
1324
1374
|
close() {
|
|
1325
1375
|
this.open = false;
|
|
1326
1376
|
}
|
|
1377
|
+
selectOption(newlySelectedOption) {
|
|
1378
|
+
this.selectedOptionChange.emit(newlySelectedOption);
|
|
1379
|
+
this.open = false;
|
|
1380
|
+
// Clear filter after an option is selected.
|
|
1381
|
+
if (this.filterabilityOptions.enabled) {
|
|
1382
|
+
this.filterQuery = '';
|
|
1383
|
+
this.filterQueryChange.emit(this.filterQuery);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1327
1386
|
trackByHeader(i, group) {
|
|
1328
1387
|
return `${i}${group.header}`;
|
|
1329
1388
|
}
|
|
@@ -1332,10 +1391,10 @@ class SingleSelectComponent extends InputLabelComponent {
|
|
|
1332
1391
|
}
|
|
1333
1392
|
}
|
|
1334
1393
|
SingleSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SingleSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1335
|
-
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)=\"
|
|
1394
|
+
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 });
|
|
1336
1395
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SingleSelectComponent, decorators: [{
|
|
1337
1396
|
type: Component,
|
|
1338
|
-
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)=\"
|
|
1397
|
+
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"] }]
|
|
1339
1398
|
}], propDecorators: { groups: [{
|
|
1340
1399
|
type: Input
|
|
1341
1400
|
}], selectedOption: [{
|
|
@@ -1346,6 +1405,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1346
1405
|
type: Input
|
|
1347
1406
|
}], locked: [{
|
|
1348
1407
|
type: Input
|
|
1408
|
+
}], maxCalloutHeight: [{
|
|
1409
|
+
type: Input
|
|
1349
1410
|
}], noOptionsMessage: [{
|
|
1350
1411
|
type: Input
|
|
1351
1412
|
}], nodeTemplate: [{
|
|
@@ -1401,42 +1462,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1401
1462
|
};
|
|
1402
1463
|
}
|
|
1403
1464
|
SingleSelectComponent.getFilterSync = getFilterSync;
|
|
1404
|
-
function getFilterAsync(query$, fetcher, debounceInput = 300) {
|
|
1405
|
-
return query$.pipe(debounceTime(debounceInput), switchMap(query => from(fetcher(query)).pipe(map(groups => {
|
|
1406
|
-
if (!query)
|
|
1407
|
-
return { loading: false, groups };
|
|
1408
|
-
const fuseOptions = {
|
|
1409
|
-
keys: ['title', 'subtitle'],
|
|
1410
|
-
includeMatches: true,
|
|
1411
|
-
shouldSort: true,
|
|
1412
|
-
threshold: 0.6,
|
|
1413
|
-
};
|
|
1414
|
-
const filteredGroups = groups
|
|
1415
|
-
.map(group => {
|
|
1416
|
-
const fuse = new Fuse(group.options, fuseOptions);
|
|
1417
|
-
const matches = fuse.search(query);
|
|
1418
|
-
return {
|
|
1419
|
-
...group,
|
|
1420
|
-
options: matches.map(match => ({
|
|
1421
|
-
...match.item,
|
|
1422
|
-
titleHighlightIndices: [
|
|
1423
|
-
...(match.matches?.find(result => result.key === 'title')
|
|
1424
|
-
?.indices || []),
|
|
1425
|
-
],
|
|
1426
|
-
subtitleHighlightIndices: [
|
|
1427
|
-
...(match.matches?.find(result => result.key === 'subtitle')?.indices || []),
|
|
1428
|
-
],
|
|
1429
|
-
})),
|
|
1430
|
-
};
|
|
1431
|
-
})
|
|
1432
|
-
.filter(group => group.options.length > 0); // Remove empty groups
|
|
1433
|
-
return { loading: false, groups: filteredGroups };
|
|
1434
|
-
}), startWith({ loading: true, groups: [] }))), pairwise(), map(([previous, next]) => ({
|
|
1435
|
-
loading: next.loading,
|
|
1436
|
-
groups: next.loading ? previous.groups : next.groups,
|
|
1437
|
-
})), startWith({ loading: false, groups: [] }));
|
|
1438
|
-
}
|
|
1439
|
-
SingleSelectComponent.getFilterAsync = getFilterAsync;
|
|
1440
1465
|
})(SingleSelectComponent || (SingleSelectComponent = {}));
|
|
1441
1466
|
|
|
1442
1467
|
const monthFormatter = timeFormat('%B');
|
|
@@ -1683,7 +1708,7 @@ class CalendarComponent {
|
|
|
1683
1708
|
}
|
|
1684
1709
|
}
|
|
1685
1710
|
CalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1686
|
-
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 });
|
|
1711
|
+
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 });
|
|
1687
1712
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CalendarComponent, decorators: [{
|
|
1688
1713
|
type: Component,
|
|
1689
1714
|
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"] }]
|
|
@@ -1842,7 +1867,7 @@ class DateRangeComponent extends InputLabelComponent {
|
|
|
1842
1867
|
}
|
|
1843
1868
|
}
|
|
1844
1869
|
DateRangeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DateRangeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1845
|
-
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 });
|
|
1870
|
+
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 });
|
|
1846
1871
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DateRangeComponent, decorators: [{
|
|
1847
1872
|
type: Component,
|
|
1848
1873
|
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"] }]
|
|
@@ -2165,6 +2190,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2165
2190
|
}]
|
|
2166
2191
|
}], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: CalloutService }, { type: i0.ChangeDetectorRef }]; } });
|
|
2167
2192
|
|
|
2193
|
+
class ContentService {
|
|
2194
|
+
constructor() {
|
|
2195
|
+
this.sizeChangesSource = new Subject();
|
|
2196
|
+
this.sizeChanges$ = this.sizeChangesSource.asObservable();
|
|
2197
|
+
this.resizeObserver = new ResizeObserver(entries => {
|
|
2198
|
+
for (const entry of entries) {
|
|
2199
|
+
this.sizeChangesSource.next({
|
|
2200
|
+
element: entry.target,
|
|
2201
|
+
width: entry.contentRect.width,
|
|
2202
|
+
height: entry.contentRect.height,
|
|
2203
|
+
});
|
|
2204
|
+
}
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
observe(element) {
|
|
2208
|
+
this.resizeObserver.observe(element);
|
|
2209
|
+
}
|
|
2210
|
+
unobserve(element) {
|
|
2211
|
+
this.resizeObserver.unobserve(element);
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
ContentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2215
|
+
ContentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentService, providedIn: 'root' });
|
|
2216
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentService, decorators: [{
|
|
2217
|
+
type: Injectable,
|
|
2218
|
+
args: [{ providedIn: 'root' }]
|
|
2219
|
+
}], ctorParameters: function () { return []; } });
|
|
2220
|
+
|
|
2221
|
+
class SizeDirective {
|
|
2222
|
+
constructor(elementRef, contentService, zone) {
|
|
2223
|
+
this.elementRef = elementRef;
|
|
2224
|
+
this.contentService = contentService;
|
|
2225
|
+
this.zone = zone;
|
|
2226
|
+
this.rivClientSize = new EventEmitter();
|
|
2227
|
+
}
|
|
2228
|
+
ngOnInit() {
|
|
2229
|
+
this.contentService.observe(this.elementRef.nativeElement);
|
|
2230
|
+
this.subscription = this.contentService.sizeChanges$
|
|
2231
|
+
.pipe(filter(change => change.element === this.elementRef.nativeElement), debounceTimeAfterFirst(10))
|
|
2232
|
+
.subscribe(change => {
|
|
2233
|
+
this.rivClientSize.emit(change);
|
|
2234
|
+
// TODO: Hopefully we can take this out once we switch to signals and zoneless Angular
|
|
2235
|
+
this.zone.run(() => { });
|
|
2236
|
+
});
|
|
2237
|
+
}
|
|
2238
|
+
ngOnDestroy() {
|
|
2239
|
+
this.contentService.unobserve(this.elementRef.nativeElement);
|
|
2240
|
+
this.subscription?.unsubscribe();
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
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 });
|
|
2244
|
+
SizeDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: SizeDirective, selector: "[rivClientSize]", outputs: { rivClientSize: "rivClientSize" }, ngImport: i0 });
|
|
2245
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SizeDirective, decorators: [{
|
|
2246
|
+
type: Directive,
|
|
2247
|
+
args: [{
|
|
2248
|
+
selector: '[rivClientSize]',
|
|
2249
|
+
}]
|
|
2250
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ContentService }, { type: i0.NgZone }]; }, propDecorators: { rivClientSize: [{
|
|
2251
|
+
type: Output
|
|
2252
|
+
}] } });
|
|
2253
|
+
function debounceTimeAfterFirst(delay) {
|
|
2254
|
+
return (source) => merge(source.pipe(take(1)), source.pipe(skip(1), debounceTime(delay)));
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2168
2257
|
class DataTableRowComponent {
|
|
2169
2258
|
constructor() {
|
|
2170
2259
|
this.subRow = false;
|
|
@@ -2607,17 +2696,7 @@ function getDateRange$1(stacks) {
|
|
|
2607
2696
|
function pointReducer(points) {
|
|
2608
2697
|
return points.reduce((total, { value }) => total + value, 0);
|
|
2609
2698
|
}
|
|
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
2699
|
|
|
2620
|
-
const MAX_COLUMNS = 72;
|
|
2621
2700
|
const DEFAULT_INTERVAL$1 = 'month';
|
|
2622
2701
|
// TODO: once we upgrade to Angular 16, this component can be cleaned up with
|
|
2623
2702
|
// signals instead of RxJS.
|
|
@@ -2625,16 +2704,30 @@ class StackedColumnComponent {
|
|
|
2625
2704
|
constructor() {
|
|
2626
2705
|
this.input$ = new BehaviorSubject([]);
|
|
2627
2706
|
this.width$ = new BehaviorSubject(960);
|
|
2628
|
-
this.
|
|
2707
|
+
this.HEIGHT = 300;
|
|
2629
2708
|
this.valueFormatter = v => v.toString();
|
|
2630
2709
|
this.interval$ = new BehaviorSubject(DEFAULT_INTERVAL$1);
|
|
2631
|
-
this.
|
|
2632
|
-
|
|
2710
|
+
this.COLUMN_WIDTHS = [8, 16, 40, 72];
|
|
2711
|
+
this.MIN_COLUMN_WIDTH = this.COLUMN_WIDTHS[0];
|
|
2712
|
+
this.numInvisibleColumns$ = this.input$.pipe(map(input => input.filter(stack => stack.filter(s => s.style == 'tooltipOnly').length > 0).length));
|
|
2713
|
+
this.numVisibleColumns$ = combineLatest([
|
|
2714
|
+
this.input$,
|
|
2715
|
+
this.numInvisibleColumns$,
|
|
2716
|
+
]).pipe(map(([input, numInvisibleColumns]) => input.length - numInvisibleColumns));
|
|
2717
|
+
this.maxColumns$ = this.width$.pipe(map(width => {
|
|
2718
|
+
const innerWidth = width - this.LEFT_OFFSET;
|
|
2719
|
+
const columnWidthWithPadding = this.MIN_COLUMN_WIDTH + this.COLUMN_PADDING * 2;
|
|
2720
|
+
return Math.floor(innerWidth / columnWidthWithPadding);
|
|
2721
|
+
}));
|
|
2722
|
+
this.allowedIntervals$ = combineLatest([
|
|
2723
|
+
this.input$,
|
|
2724
|
+
this.maxColumns$,
|
|
2725
|
+
this.numVisibleColumns$,
|
|
2726
|
+
]).pipe(map(([input, maxColumns, numVisibleColumns]) => {
|
|
2633
2727
|
const [minDate, maxDate] = getDateRange$1(input);
|
|
2634
2728
|
return intervals.filter(interval => {
|
|
2635
|
-
const
|
|
2636
|
-
|
|
2637
|
-
return numVisibleColumns * xStepsCount <= MAX_COLUMNS;
|
|
2729
|
+
const xStepsCount = this.getXStepsInRange(interval, minDate, maxDate);
|
|
2730
|
+
return numVisibleColumns * xStepsCount <= maxColumns;
|
|
2638
2731
|
});
|
|
2639
2732
|
}), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
2640
2733
|
this.intervalOptions$ = this.allowedIntervals$.pipe(map(intervals => intervals.map((interval) => ({
|
|
@@ -2659,6 +2752,26 @@ class StackedColumnComponent {
|
|
|
2659
2752
|
return options.find(o => o.id === interval) ?? null;
|
|
2660
2753
|
}), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
2661
2754
|
this.selectedInterval$ = this.selectedIntervalOption$.pipe(map(option => (option ? option.id : DEFAULT_INTERVAL$1)));
|
|
2755
|
+
this.columnWidth$ = combineLatest([
|
|
2756
|
+
this.input$,
|
|
2757
|
+
this.selectedInterval$,
|
|
2758
|
+
this.numVisibleColumns$,
|
|
2759
|
+
this.width$,
|
|
2760
|
+
]).pipe(map(([input, selectedInterval, numVisibleColumns, width]) => {
|
|
2761
|
+
const [minDate, maxDate] = getDateRange$1(input);
|
|
2762
|
+
const xStepCount = this.getXStepsInRange(selectedInterval, minDate, maxDate);
|
|
2763
|
+
const innerWidth = width - this.LEFT_OFFSET;
|
|
2764
|
+
const allowedColumnWidths = this.COLUMN_WIDTHS.filter(columnWidth => {
|
|
2765
|
+
const columnWidthWithPadding = columnWidth + this.COLUMN_PADDING * 2;
|
|
2766
|
+
return (innerWidth -
|
|
2767
|
+
numVisibleColumns * xStepCount * columnWidthWithPadding >=
|
|
2768
|
+
0);
|
|
2769
|
+
});
|
|
2770
|
+
const columnWidth = allowedColumnWidths.at(-1);
|
|
2771
|
+
if (!columnWidth)
|
|
2772
|
+
return 0;
|
|
2773
|
+
return columnWidth;
|
|
2774
|
+
}));
|
|
2662
2775
|
this.binnedData$ = combineLatest([
|
|
2663
2776
|
this.input$,
|
|
2664
2777
|
this.selectedInterval$,
|
|
@@ -2683,16 +2796,16 @@ class StackedColumnComponent {
|
|
|
2683
2796
|
});
|
|
2684
2797
|
})), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
2685
2798
|
this.LEFT_OFFSET = 48;
|
|
2799
|
+
this.COLUMN_PADDING = 4;
|
|
2686
2800
|
this.drawData$ = combineLatest([
|
|
2687
2801
|
this.binnedData$,
|
|
2688
2802
|
this.width$,
|
|
2689
|
-
this.height$,
|
|
2690
2803
|
this.selectedInterval$,
|
|
2691
|
-
|
|
2692
|
-
|
|
2804
|
+
this.numInvisibleColumns$,
|
|
2805
|
+
this.columnWidth$,
|
|
2806
|
+
]).pipe(map(([binnedData, width, interval, numInvisibleColumns, columnWidth]) => {
|
|
2807
|
+
const viewBox = `0 0 ${width} ${this.HEIGHT}`;
|
|
2693
2808
|
const padding = 16;
|
|
2694
|
-
const invisColumns = binnedData.filter(stack => stack.filter(s => s.style == 'tooltipOnly').length > 0).length;
|
|
2695
|
-
const visibleColumns = binnedData.length - invisColumns;
|
|
2696
2809
|
const [minDate, maxDate] = getDateRange$1(binnedData);
|
|
2697
2810
|
const hasMultipleYears = minDate.getFullYear() < maxDate.getFullYear();
|
|
2698
2811
|
const xMinorIntervalFormat = getMinorIntervalFormat(interval);
|
|
@@ -2706,11 +2819,9 @@ class StackedColumnComponent {
|
|
|
2706
2819
|
const xOuterScale = scaleBand()
|
|
2707
2820
|
.domain(xSteps.map(date => fullFormatter(date)))
|
|
2708
2821
|
.range([this.LEFT_OFFSET, width]);
|
|
2709
|
-
const columnWidth = getColumnWidth(xSteps.length * visibleColumns);
|
|
2710
|
-
const columnPadding = 4;
|
|
2711
2822
|
const outerPadding = (xOuterScale.bandwidth() -
|
|
2712
|
-
(
|
|
2713
|
-
columnWidth * (binnedData.length -
|
|
2823
|
+
(this.COLUMN_PADDING * (binnedData.length - 1 - numInvisibleColumns) +
|
|
2824
|
+
columnWidth * (binnedData.length - numInvisibleColumns))) /
|
|
2714
2825
|
2;
|
|
2715
2826
|
const renderInformation = binnedData.map(stackData => {
|
|
2716
2827
|
/*
|
|
@@ -2788,7 +2899,7 @@ class StackedColumnComponent {
|
|
|
2788
2899
|
domainMax = 1;
|
|
2789
2900
|
const yScale = scaleLinear()
|
|
2790
2901
|
.domain([0, domainMax])
|
|
2791
|
-
.range([
|
|
2902
|
+
.range([this.HEIGHT - padding * 2, padding]);
|
|
2792
2903
|
const rects = [];
|
|
2793
2904
|
let invisColumnsSoFar = 0;
|
|
2794
2905
|
// For each unique stack,
|
|
@@ -2808,7 +2919,7 @@ class StackedColumnComponent {
|
|
|
2808
2919
|
const x = (xOuterScale(fullFormatter(date)) ?? 0) +
|
|
2809
2920
|
outerPadding +
|
|
2810
2921
|
columnWidth * (index - invisColumnsSoFar) +
|
|
2811
|
-
|
|
2922
|
+
this.COLUMN_PADDING * (index - invisColumnsSoFar);
|
|
2812
2923
|
const y = yScale(baseline) - height;
|
|
2813
2924
|
let fill = '';
|
|
2814
2925
|
if (seriesPoint.series.style != 'tooltipOnly') {
|
|
@@ -2846,8 +2957,9 @@ class StackedColumnComponent {
|
|
|
2846
2957
|
.filter((tick, i, ticks) => i === 0 || tick.label !== ticks[i - 1].label)
|
|
2847
2958
|
: [];
|
|
2848
2959
|
const yTicks = yScale.ticks(5);
|
|
2849
|
-
const hoverBandWidth = (renderInformation.length -
|
|
2850
|
-
(renderInformation.length + 1 -
|
|
2960
|
+
const hoverBandWidth = (renderInformation.length - numInvisibleColumns) * columnWidth +
|
|
2961
|
+
(renderInformation.length + 1 - numInvisibleColumns) *
|
|
2962
|
+
this.COLUMN_PADDING;
|
|
2851
2963
|
const hoverBands = xSteps.map(date => ({
|
|
2852
2964
|
dateValue: date.valueOf(),
|
|
2853
2965
|
x: (xOuterScale(fullFormatter(date)) ?? 0) +
|
|
@@ -2894,36 +3006,27 @@ class StackedColumnComponent {
|
|
|
2894
3006
|
set width(v) {
|
|
2895
3007
|
this.width$.next(v);
|
|
2896
3008
|
}
|
|
2897
|
-
get width() {
|
|
2898
|
-
return this.width$.getValue();
|
|
2899
|
-
}
|
|
2900
|
-
set height(v) {
|
|
2901
|
-
this.height$.next(v);
|
|
2902
|
-
}
|
|
2903
|
-
get height() {
|
|
2904
|
-
return this.height$.getValue();
|
|
2905
|
-
}
|
|
2906
3009
|
set interval(v) {
|
|
2907
3010
|
this.interval$.next(v);
|
|
2908
3011
|
}
|
|
2909
3012
|
get interval() {
|
|
2910
3013
|
return this.interval$.getValue();
|
|
2911
3014
|
}
|
|
3015
|
+
getXStepsInRange(interval, minDate, maxDate) {
|
|
3016
|
+
const timeInterval = getTimeInterval(interval);
|
|
3017
|
+
return timeInterval.range(timeInterval.floor(minDate), timeInterval.floor(timeInterval.offset(maxDate, 1))).length;
|
|
3018
|
+
}
|
|
2912
3019
|
setIntervalOption(option) {
|
|
2913
3020
|
this.interval = option.id;
|
|
2914
3021
|
}
|
|
2915
3022
|
}
|
|
2916
3023
|
StackedColumnComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: StackedColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2917
|
-
StackedColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: StackedColumnComponent, selector: "riv-stacked-column", inputs: { input: "input",
|
|
3024
|
+
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 });
|
|
2918
3025
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: StackedColumnComponent, decorators: [{
|
|
2919
3026
|
type: Component,
|
|
2920
|
-
args: [{ selector: 'riv-stacked-column', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
3027
|
+
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"] }]
|
|
2921
3028
|
}], propDecorators: { input: [{
|
|
2922
3029
|
type: Input
|
|
2923
|
-
}], width: [{
|
|
2924
|
-
type: Input
|
|
2925
|
-
}], height: [{
|
|
2926
|
-
type: Input
|
|
2927
3030
|
}], valueFormatter: [{
|
|
2928
3031
|
type: Input
|
|
2929
3032
|
}], interval: [{
|
|
@@ -3012,18 +3115,42 @@ class StackedRowComponent {
|
|
|
3012
3115
|
// This is the list of rows we will display, in the order we will display them.
|
|
3013
3116
|
this.input$ = new BehaviorSubject([]);
|
|
3014
3117
|
// Width helps determine the size of the viewbox this graph is displaying in.
|
|
3015
|
-
this.width$ = new BehaviorSubject(
|
|
3016
|
-
// Height helps determine the size of the viewbox this graph is displaying in.
|
|
3017
|
-
this.height$ = new BehaviorSubject(null);
|
|
3118
|
+
this.width$ = new BehaviorSubject(0);
|
|
3018
3119
|
// ValueFormatter determines how we style the values in a metric and the x-axis
|
|
3019
3120
|
this.valueFormatter = v => v.toString();
|
|
3020
3121
|
this.zeroStateMessage$ = new BehaviorSubject('No data to display.');
|
|
3122
|
+
this.chartAndRowHeights$ = this.input$.pipe(map(input => {
|
|
3123
|
+
const heightWithoutRows = input.length * this.SECTION_PADDING.BETWEEN_ROW +
|
|
3124
|
+
this.SECTION_PADDING.OUTER_TOP_BOTTOM * 2 +
|
|
3125
|
+
this.SECTION_HEIGHTS.X_AXIS_LABEL;
|
|
3126
|
+
// The combined height of all rows at their min/max
|
|
3127
|
+
const minHeight = input.length * this.RECTANGLE_HEIGHTS.MIN_HEIGHT + heightWithoutRows;
|
|
3128
|
+
const maxHeight = input.length * this.RECTANGLE_HEIGHTS.MAX_HEIGHT + heightWithoutRows;
|
|
3129
|
+
// If the max-sized rows don't need the target size, shrink the chart
|
|
3130
|
+
if (maxHeight < this.TARGET_HEIGHT)
|
|
3131
|
+
return {
|
|
3132
|
+
chartHeight: maxHeight,
|
|
3133
|
+
rowHeight: this.RECTANGLE_HEIGHTS.MAX_HEIGHT,
|
|
3134
|
+
};
|
|
3135
|
+
// If the min-sized rows need more than the target size, grow the chart
|
|
3136
|
+
if (minHeight > this.TARGET_HEIGHT)
|
|
3137
|
+
return {
|
|
3138
|
+
chartHeight: minHeight,
|
|
3139
|
+
rowHeight: this.RECTANGLE_HEIGHTS.MIN_HEIGHT,
|
|
3140
|
+
};
|
|
3141
|
+
// Otherwise shrink the rows to fit the target size
|
|
3142
|
+
return {
|
|
3143
|
+
chartHeight: this.TARGET_HEIGHT,
|
|
3144
|
+
rowHeight: (this.TARGET_HEIGHT - heightWithoutRows) / input.length,
|
|
3145
|
+
};
|
|
3146
|
+
}));
|
|
3021
3147
|
/*
|
|
3022
3148
|
The layout we are shooting for is:
|
|
3023
3149
|
|
|
3024
3150
|
| X Axis Labels |
|
|
3025
3151
|
Row Name | Rectangles | Totals
|
|
3026
3152
|
*/
|
|
3153
|
+
this.TARGET_HEIGHT = 300;
|
|
3027
3154
|
this.RECTANGLE_HEIGHTS = {
|
|
3028
3155
|
MIN_HEIGHT: 12,
|
|
3029
3156
|
MAX_HEIGHT: 42, // Sets the largest size a row can expand to
|
|
@@ -3031,36 +3158,6 @@ class StackedRowComponent {
|
|
|
3031
3158
|
this.SECTION_HEIGHTS = {
|
|
3032
3159
|
// Space reserved for the x-axis labels
|
|
3033
3160
|
X_AXIS_LABEL: 14,
|
|
3034
|
-
// Height of each row
|
|
3035
|
-
PER_ROW: () => {
|
|
3036
|
-
//Only use height if specified
|
|
3037
|
-
if (this.input.length && this.height) {
|
|
3038
|
-
let rowHeight = (this.height -
|
|
3039
|
-
this.SECTION_HEIGHTS.X_AXIS_LABEL -
|
|
3040
|
-
this.SECTION_PADDING.OUTER_TOP_BOTTOM -
|
|
3041
|
-
this.SECTION_PADDING.RECTANGLE_TO_ROW) /
|
|
3042
|
-
this.input.length -
|
|
3043
|
-
this.SECTION_PADDING.BETWEEN_ROW; // calculate base row height
|
|
3044
|
-
// Clamping the row height between the min and max heights
|
|
3045
|
-
return Math.min(Math.max(rowHeight, this.RECTANGLE_HEIGHTS.MIN_HEIGHT), this.RECTANGLE_HEIGHTS.MAX_HEIGHT);
|
|
3046
|
-
}
|
|
3047
|
-
return this.RECTANGLE_HEIGHTS.MIN_HEIGHT; // Default if no input
|
|
3048
|
-
},
|
|
3049
|
-
// Max Height of each rectangle
|
|
3050
|
-
PER_RECTANGLE: () => {
|
|
3051
|
-
//Only use height if specified
|
|
3052
|
-
if (this.input.length && this.height) {
|
|
3053
|
-
let rectangleHeight = (this.height -
|
|
3054
|
-
this.SECTION_HEIGHTS.X_AXIS_LABEL -
|
|
3055
|
-
this.SECTION_PADDING.OUTER_TOP_BOTTOM -
|
|
3056
|
-
this.SECTION_PADDING.RECTANGLE_TO_ROW) /
|
|
3057
|
-
this.input.length -
|
|
3058
|
-
this.SECTION_PADDING.BETWEEN_ROW; // calculate base rectangle height
|
|
3059
|
-
// Clamping the rectangle height between the min and max heights
|
|
3060
|
-
return Math.min(Math.max(rectangleHeight, this.RECTANGLE_HEIGHTS.MIN_HEIGHT), this.RECTANGLE_HEIGHTS.MAX_HEIGHT);
|
|
3061
|
-
}
|
|
3062
|
-
return this.RECTANGLE_HEIGHTS.MIN_HEIGHT; // Default if no input
|
|
3063
|
-
},
|
|
3064
3161
|
};
|
|
3065
3162
|
this.SECTION_WIDTHS = {
|
|
3066
3163
|
// Space reserved for the name at the start of the row
|
|
@@ -3085,16 +3182,9 @@ class StackedRowComponent {
|
|
|
3085
3182
|
this.drawData$ = combineLatest([
|
|
3086
3183
|
this.input$,
|
|
3087
3184
|
this.width$,
|
|
3088
|
-
this.
|
|
3185
|
+
this.chartAndRowHeights$,
|
|
3089
3186
|
]).pipe(map(([input, width, height]) => {
|
|
3090
|
-
return this.getDrawnData(input, width, height
|
|
3091
|
-
? height
|
|
3092
|
-
: this.SECTION_HEIGHTS.X_AXIS_LABEL +
|
|
3093
|
-
this.SECTION_PADDING.OUTER_TOP_BOTTOM +
|
|
3094
|
-
this.SECTION_PADDING.RECTANGLE_TO_ROW +
|
|
3095
|
-
(this.SECTION_HEIGHTS.PER_ROW() +
|
|
3096
|
-
this.SECTION_PADDING.BETWEEN_ROW) *
|
|
3097
|
-
input.length);
|
|
3187
|
+
return this.getDrawnData(input, width, height.chartHeight, height.rowHeight);
|
|
3098
3188
|
}), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
3099
3189
|
// Lets us know whether to display the zero data state
|
|
3100
3190
|
this.empty$ = this.input$.pipe(map(input => input.every(stack => stack.data.length === 0)), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
@@ -3128,15 +3218,6 @@ class StackedRowComponent {
|
|
|
3128
3218
|
set width(v) {
|
|
3129
3219
|
this.width$.next(v);
|
|
3130
3220
|
}
|
|
3131
|
-
get width() {
|
|
3132
|
-
return this.width$.getValue();
|
|
3133
|
-
}
|
|
3134
|
-
set height(v) {
|
|
3135
|
-
this.height$.next(v);
|
|
3136
|
-
}
|
|
3137
|
-
get height() {
|
|
3138
|
-
return this.height$.getValue();
|
|
3139
|
-
}
|
|
3140
3221
|
set zeroStateMessage(v) {
|
|
3141
3222
|
this.zeroStateMessage$.next(v);
|
|
3142
3223
|
}
|
|
@@ -3158,19 +3239,19 @@ class StackedRowComponent {
|
|
|
3158
3239
|
return (this.SECTION_PADDING.OUTER_TOP_BOTTOM + this.SECTION_HEIGHTS.X_AXIS_LABEL);
|
|
3159
3240
|
}
|
|
3160
3241
|
// The y-index of the top of the current row
|
|
3161
|
-
getTopOfRow(rowIndex) {
|
|
3242
|
+
getTopOfRow(rowIndex, rowHeight) {
|
|
3162
3243
|
const spaceAboveRows = this.SECTION_PADDING.OUTER_TOP_BOTTOM + this.SECTION_HEIGHTS.X_AXIS_LABEL;
|
|
3163
|
-
const aboveRows = rowIndex *
|
|
3244
|
+
const aboveRows = rowIndex * rowHeight;
|
|
3164
3245
|
const aboveRowPaddings = rowIndex * this.SECTION_PADDING.BETWEEN_ROW;
|
|
3165
3246
|
const allAboveRows = aboveRows + aboveRowPaddings;
|
|
3166
3247
|
return spaceAboveRows + allAboveRows;
|
|
3167
3248
|
}
|
|
3168
3249
|
// Calculate all the values we need for displaying the graph on screen.
|
|
3169
|
-
getDrawnData(rowStacks, width,
|
|
3250
|
+
getDrawnData(rowStacks, width, chartHeight, rowHeight) {
|
|
3170
3251
|
if (rowStacks.length == 0) {
|
|
3171
3252
|
return null;
|
|
3172
3253
|
}
|
|
3173
|
-
const viewBox = `0 0 ${width} ${
|
|
3254
|
+
const viewBox = `0 0 ${width} ${chartHeight}`;
|
|
3174
3255
|
const keysInOrder = getKeyOrder(rowStacks);
|
|
3175
3256
|
const standardizedRows = standardizeRowStacks(rowStacks, keysInOrder);
|
|
3176
3257
|
const rowsForDisplay = standardizedRows.map(stackData => {
|
|
@@ -3188,13 +3269,13 @@ class StackedRowComponent {
|
|
|
3188
3269
|
.clamp(true); // Ensures the scale does not go beyond the defined range
|
|
3189
3270
|
const xtickCountAdjusted = Math.round(tickScale(width));
|
|
3190
3271
|
const xTicks = xScale.ticks(xtickCountAdjusted);
|
|
3191
|
-
const rects = this.createRectanglesFromRows(rowsForDisplay, xScale);
|
|
3192
|
-
const rowNamesToDraw = this.getRowNamesToDraw(rowsForDisplay);
|
|
3193
|
-
const rowTotalsToDraw = this.getRowTotalsToDraw(rowsForDisplay, width);
|
|
3272
|
+
const rects = this.createRectanglesFromRows(rowsForDisplay, xScale, rowHeight);
|
|
3273
|
+
const rowNamesToDraw = this.getRowNamesToDraw(rowsForDisplay, rowHeight);
|
|
3274
|
+
const rowTotalsToDraw = this.getRowTotalsToDraw(rowsForDisplay, width, rowHeight);
|
|
3194
3275
|
const legendItems = getLegendItems(rowsForDisplay, keysInOrder);
|
|
3195
3276
|
return {
|
|
3196
3277
|
legendItems: legendItems,
|
|
3197
|
-
rowHeight:
|
|
3278
|
+
rowHeight: rowHeight,
|
|
3198
3279
|
rects: rects,
|
|
3199
3280
|
rowNames: rowNamesToDraw,
|
|
3200
3281
|
rowTotals: rowTotalsToDraw,
|
|
@@ -3204,20 +3285,20 @@ class StackedRowComponent {
|
|
|
3204
3285
|
};
|
|
3205
3286
|
}
|
|
3206
3287
|
// Get data for all the rectangles for all the rows
|
|
3207
|
-
createRectanglesFromRows(displayRows, xScale) {
|
|
3288
|
+
createRectanglesFromRows(displayRows, xScale, rowHeight) {
|
|
3208
3289
|
const rectangles = [];
|
|
3209
3290
|
displayRows.forEach((currentRow, rowIndex) => {
|
|
3210
3291
|
currentRow.elementsButStacked.forEach((currentElement, _) => {
|
|
3211
|
-
const topOfRow = this.getTopOfRow(rowIndex);
|
|
3292
|
+
const topOfRow = this.getTopOfRow(rowIndex, rowHeight);
|
|
3212
3293
|
const rectangleWidth = xScale(currentElement.topline) - xScale(currentElement.baseline);
|
|
3213
|
-
const rectangleHeight =
|
|
3294
|
+
const rectangleHeight = rowHeight;
|
|
3214
3295
|
const rectangleX = xScale(currentElement.baseline);
|
|
3215
3296
|
const rectangleY = topOfRow + this.SECTION_PADDING.RECTANGLE_TO_ROW;
|
|
3216
3297
|
const fill = `var(${currentElement.colorToken})`;
|
|
3217
3298
|
rectangles.push({
|
|
3218
3299
|
x: rectangleX,
|
|
3219
3300
|
y: rectangleY,
|
|
3220
|
-
width: rectangleWidth,
|
|
3301
|
+
width: Math.max(rectangleWidth, 0),
|
|
3221
3302
|
height: rectangleHeight,
|
|
3222
3303
|
fill: fill,
|
|
3223
3304
|
striped: currentElement.style === 'striped',
|
|
@@ -3229,13 +3310,13 @@ class StackedRowComponent {
|
|
|
3229
3310
|
return rectangles;
|
|
3230
3311
|
}
|
|
3231
3312
|
// Get data on the row names we are drawing
|
|
3232
|
-
getRowNamesToDraw(displayRows) {
|
|
3313
|
+
getRowNamesToDraw(displayRows, rowHeight) {
|
|
3233
3314
|
return displayRows.map((row, rowIndex) => {
|
|
3234
3315
|
const rowLabelX = this.SECTION_PADDING.OUTER_LEFT_RIGHT;
|
|
3235
3316
|
// The row name looks right if its base is at the base of the associated rectangle
|
|
3236
|
-
const rowLabelY = this.getTopOfRow(rowIndex) +
|
|
3317
|
+
const rowLabelY = this.getTopOfRow(rowIndex, rowHeight) +
|
|
3237
3318
|
this.SECTION_PADDING.RECTANGLE_TO_ROW +
|
|
3238
|
-
|
|
3319
|
+
rowHeight / 2;
|
|
3239
3320
|
return {
|
|
3240
3321
|
label: row.rowName,
|
|
3241
3322
|
x: rowLabelX,
|
|
@@ -3244,13 +3325,13 @@ class StackedRowComponent {
|
|
|
3244
3325
|
});
|
|
3245
3326
|
}
|
|
3246
3327
|
// Get data on the row totals we are drawing
|
|
3247
|
-
getRowTotalsToDraw(displayRows, width) {
|
|
3328
|
+
getRowTotalsToDraw(displayRows, width, rowHeight) {
|
|
3248
3329
|
return displayRows.map((row, rowIndex) => {
|
|
3249
3330
|
const rowLabelX = width - this.SECTION_PADDING.OUTER_LEFT_RIGHT;
|
|
3250
3331
|
// The row totals looks right if its base is at the base of the associated rectangle
|
|
3251
|
-
const rowLabelY = this.getTopOfRow(rowIndex) +
|
|
3332
|
+
const rowLabelY = this.getTopOfRow(rowIndex, rowHeight) +
|
|
3252
3333
|
this.SECTION_PADDING.RECTANGLE_TO_ROW +
|
|
3253
|
-
|
|
3334
|
+
rowHeight / 2;
|
|
3254
3335
|
return {
|
|
3255
3336
|
label: this.valueFormatter(row.rowTotal),
|
|
3256
3337
|
x: rowLabelX,
|
|
@@ -3260,16 +3341,12 @@ class StackedRowComponent {
|
|
|
3260
3341
|
}
|
|
3261
3342
|
}
|
|
3262
3343
|
StackedRowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: StackedRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3263
|
-
StackedRowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: StackedRowComponent, selector: "riv-stacked-row", inputs: { input: "input",
|
|
3344
|
+
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 });
|
|
3264
3345
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: StackedRowComponent, decorators: [{
|
|
3265
3346
|
type: Component,
|
|
3266
|
-
args: [{ selector: 'riv-stacked-row', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
3347
|
+
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"] }]
|
|
3267
3348
|
}], propDecorators: { input: [{
|
|
3268
3349
|
type: Input
|
|
3269
|
-
}], width: [{
|
|
3270
|
-
type: Input
|
|
3271
|
-
}], height: [{
|
|
3272
|
-
type: Input
|
|
3273
3350
|
}], valueFormatter: [{
|
|
3274
3351
|
type: Input
|
|
3275
3352
|
}], zeroStateMessage: [{
|
|
@@ -3291,7 +3368,6 @@ function getDateRange(configs) {
|
|
|
3291
3368
|
return [new Date(min), new Date(max)];
|
|
3292
3369
|
}
|
|
3293
3370
|
|
|
3294
|
-
const MAX_POINTS = 90;
|
|
3295
3371
|
const DEFAULT_INTERVAL = 'day';
|
|
3296
3372
|
// TODO: once we upgrade to Angular 16, this component can be cleaned up with
|
|
3297
3373
|
// signals instead of RxJS. See commit e238c2d.
|
|
@@ -3304,8 +3380,8 @@ class TimeSeriesComponent {
|
|
|
3304
3380
|
series: [],
|
|
3305
3381
|
},
|
|
3306
3382
|
]);
|
|
3307
|
-
this.width$ = new BehaviorSubject(
|
|
3308
|
-
this.
|
|
3383
|
+
this.width$ = new BehaviorSubject(0);
|
|
3384
|
+
this.HEIGHT = 300;
|
|
3309
3385
|
this.zeroStateMessage$ = new BehaviorSubject('No data to display.');
|
|
3310
3386
|
this.BOTTOM_OFFSET = 24;
|
|
3311
3387
|
this.LEFT_OFFSET = 48;
|
|
@@ -3314,15 +3390,24 @@ class TimeSeriesComponent {
|
|
|
3314
3390
|
this.BOTTOM_PADDING = 8;
|
|
3315
3391
|
this.Y_TICK_COUNT = 5;
|
|
3316
3392
|
this.X_MINOR_TICK_LIMIT = 15;
|
|
3393
|
+
this.POINT_RADIUS = 3.5;
|
|
3317
3394
|
this.dateRange$ = this.input$.pipe(map(getDateRange), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
3318
3395
|
this.interval$ = new BehaviorSubject(DEFAULT_INTERVAL);
|
|
3319
3396
|
this.allowLegendToggle$ = new BehaviorSubject(false);
|
|
3320
|
-
this.
|
|
3397
|
+
this.maxPoints$ = this.width$.pipe(map(width => {
|
|
3398
|
+
const innerWidth = width - this.LEFT_OFFSET;
|
|
3399
|
+
const pointWithPadding = (this.POINT_RADIUS + 1) * 2;
|
|
3400
|
+
return Math.floor(innerWidth / pointWithPadding);
|
|
3401
|
+
}));
|
|
3402
|
+
this.allowedIntervals$ = combineLatest([
|
|
3403
|
+
this.input$,
|
|
3404
|
+
this.maxPoints$,
|
|
3405
|
+
]).pipe(map(([input, maxPoints]) => {
|
|
3321
3406
|
const [minDateValue, maxDateValue] = getDateRange(input);
|
|
3322
3407
|
return intervals.filter(interval => {
|
|
3323
3408
|
const timeInterval = getTimeInterval(interval);
|
|
3324
3409
|
const numSteps = timeInterval.range(timeInterval.floor(minDateValue), timeInterval.ceil(utcDay.offset(maxDateValue, 1))).length;
|
|
3325
|
-
return numSteps <=
|
|
3410
|
+
return numSteps <= maxPoints && numSteps > 1;
|
|
3326
3411
|
});
|
|
3327
3412
|
}), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
3328
3413
|
this.intervalOptions$ = this.allowedIntervals$.pipe(map(intervals => intervals.map((interval) => ({
|
|
@@ -3385,9 +3470,8 @@ class TimeSeriesComponent {
|
|
|
3385
3470
|
this.binnedDateRange$,
|
|
3386
3471
|
this.selectedInterval$,
|
|
3387
3472
|
this.width$,
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
const viewBox = `0 0 ${width} ${height}`;
|
|
3473
|
+
]).pipe(map(([binnedData, binnedDateRange, interval, width]) => {
|
|
3474
|
+
const viewBox = `0 0 ${width} ${this.HEIGHT}`;
|
|
3391
3475
|
const xScale = scaleLinear()
|
|
3392
3476
|
.domain(binnedDateRange)
|
|
3393
3477
|
.range([
|
|
@@ -3435,7 +3519,7 @@ class TimeSeriesComponent {
|
|
|
3435
3519
|
const yScale = scaleLinear()
|
|
3436
3520
|
.domain([yMin, yMax])
|
|
3437
3521
|
.range([
|
|
3438
|
-
|
|
3522
|
+
this.HEIGHT -
|
|
3439
3523
|
this.BOTTOM_OFFSET -
|
|
3440
3524
|
(this.BOTTOM_PADDING + this.TOP_PADDING),
|
|
3441
3525
|
this.TOP_PADDING,
|
|
@@ -3527,15 +3611,6 @@ class TimeSeriesComponent {
|
|
|
3527
3611
|
set width(v) {
|
|
3528
3612
|
this.width$.next(v);
|
|
3529
3613
|
}
|
|
3530
|
-
get width() {
|
|
3531
|
-
return this.width$.getValue();
|
|
3532
|
-
}
|
|
3533
|
-
set height(v) {
|
|
3534
|
-
this.height$.next(v);
|
|
3535
|
-
}
|
|
3536
|
-
get height() {
|
|
3537
|
-
return this.height$.getValue();
|
|
3538
|
-
}
|
|
3539
3614
|
set zeroStateMessage(v) {
|
|
3540
3615
|
this.zeroStateMessage$.next(v);
|
|
3541
3616
|
}
|
|
@@ -3559,16 +3634,12 @@ class TimeSeriesComponent {
|
|
|
3559
3634
|
}
|
|
3560
3635
|
}
|
|
3561
3636
|
TimeSeriesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TimeSeriesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3562
|
-
TimeSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TimeSeriesComponent, selector: "riv-time-series", inputs: { input: "input",
|
|
3637
|
+
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 });
|
|
3563
3638
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TimeSeriesComponent, decorators: [{
|
|
3564
3639
|
type: Component,
|
|
3565
|
-
args: [{ selector: 'riv-time-series', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
3640
|
+
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"] }]
|
|
3566
3641
|
}], propDecorators: { input: [{
|
|
3567
3642
|
type: Input
|
|
3568
|
-
}], width: [{
|
|
3569
|
-
type: Input
|
|
3570
|
-
}], height: [{
|
|
3571
|
-
type: Input
|
|
3572
3643
|
}], zeroStateMessage: [{
|
|
3573
3644
|
type: Input
|
|
3574
3645
|
}], interval: [{
|
|
@@ -3598,6 +3669,7 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
|
|
|
3598
3669
|
DaysPipe,
|
|
3599
3670
|
DollarsPipe,
|
|
3600
3671
|
DonutComponent,
|
|
3672
|
+
FocusOnInitDirective,
|
|
3601
3673
|
FunnelChartComponent,
|
|
3602
3674
|
HelpComponent,
|
|
3603
3675
|
HighlightComponent,
|
|
@@ -3614,6 +3686,7 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
|
|
|
3614
3686
|
OptionGroupPipe,
|
|
3615
3687
|
PercentagePipe,
|
|
3616
3688
|
SingleSelectComponent,
|
|
3689
|
+
SizeDirective,
|
|
3617
3690
|
SmallCurrencyPipe,
|
|
3618
3691
|
StackedColumnComponent,
|
|
3619
3692
|
StackedRowComponent,
|
|
@@ -3638,6 +3711,7 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
|
|
|
3638
3711
|
DaysPipe,
|
|
3639
3712
|
DollarsPipe,
|
|
3640
3713
|
DonutComponent,
|
|
3714
|
+
FocusOnInitDirective,
|
|
3641
3715
|
FunnelChartComponent,
|
|
3642
3716
|
HelpComponent,
|
|
3643
3717
|
HighlightComponent,
|
|
@@ -3653,6 +3727,7 @@ RivModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.
|
|
|
3653
3727
|
OptionGroupPipe,
|
|
3654
3728
|
PercentagePipe,
|
|
3655
3729
|
SingleSelectComponent,
|
|
3730
|
+
SizeDirective,
|
|
3656
3731
|
SmallCurrencyPipe,
|
|
3657
3732
|
StackedColumnComponent,
|
|
3658
3733
|
StackedRowComponent,
|
|
@@ -3684,6 +3759,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3684
3759
|
DaysPipe,
|
|
3685
3760
|
DollarsPipe,
|
|
3686
3761
|
DonutComponent,
|
|
3762
|
+
FocusOnInitDirective,
|
|
3687
3763
|
FunnelChartComponent,
|
|
3688
3764
|
HelpComponent,
|
|
3689
3765
|
HighlightComponent,
|
|
@@ -3700,6 +3776,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3700
3776
|
OptionGroupPipe,
|
|
3701
3777
|
PercentagePipe,
|
|
3702
3778
|
SingleSelectComponent,
|
|
3779
|
+
SizeDirective,
|
|
3703
3780
|
SmallCurrencyPipe,
|
|
3704
3781
|
StackedColumnComponent,
|
|
3705
3782
|
StackedRowComponent,
|
|
@@ -3727,6 +3804,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3727
3804
|
DaysPipe,
|
|
3728
3805
|
DollarsPipe,
|
|
3729
3806
|
DonutComponent,
|
|
3807
|
+
FocusOnInitDirective,
|
|
3730
3808
|
FunnelChartComponent,
|
|
3731
3809
|
HelpComponent,
|
|
3732
3810
|
HighlightComponent,
|
|
@@ -3742,6 +3820,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3742
3820
|
OptionGroupPipe,
|
|
3743
3821
|
PercentagePipe,
|
|
3744
3822
|
SingleSelectComponent,
|
|
3823
|
+
SizeDirective,
|
|
3745
3824
|
SmallCurrencyPipe,
|
|
3746
3825
|
StackedColumnComponent,
|
|
3747
3826
|
StackedRowComponent,
|
|
@@ -3762,5 +3841,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3762
3841
|
* Generated bundle index. Do not edit.
|
|
3763
3842
|
*/
|
|
3764
3843
|
|
|
3765
|
-
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 };
|
|
3844
|
+
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 };
|
|
3766
3845
|
//# sourceMappingURL=rivet-health-design-system.mjs.map
|