@kerusiweb/angular 2.2.0 → 2.3.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/README.md +225 -4
- package/fesm2022/kerusiweb-angular.mjs +104 -135
- package/fesm2022/kerusiweb-angular.mjs.map +1 -1
- package/package.json +2 -2
- package/types/kerusiweb-angular.d.ts +88 -59
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NgTemplateOutlet } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, output, computed, ChangeDetectionStrategy, Component, inject, ElementRef, model, signal, viewChild, effect, untracked } from '@angular/core';
|
|
4
|
-
import { DEFAULT_KERUSI_COLORS,
|
|
3
|
+
import { input, output, computed, ChangeDetectionStrategy, Component, inject, TemplateRef, Directive, ElementRef, model, contentChild, signal, viewChild, effect, untracked } from '@angular/core';
|
|
4
|
+
import { DEFAULT_KERUSI_COLORS, resolveSeatStyle, resolveSeatGlyph, cssVar, elementStyle, elementFill, elementTextFill, screenPath, legendSwatchFill, legendSwatchPath, legendSwatchText, seatBodyPath, seatSelectedFrame, seatOccupantPath, seatOccupantStroke, seatWashFill, occupantFillFor, occupantStrokeFor, seatCoreFill, formatMoney, DEFAULT_SEAT_ARIA_STRINGS, DEFAULT_MAX_ZOOM, FIT_VIEWPORT, IDLE_GESTURE, errorsOf, KerusiValidationError, viewportsEqual, validateDocumentSet, expireHolds, buildRenderModel, resolveMapLocale, isRtlLocale, resolveColors, zoomLimits, resolveControlStrings, controlStyle, viewportTransform, viewportTouchAction, computeSectionLayout, buildNavigationGraph, seatAriaLabel, summarizeSelection, toggleSeatSelection, disallowedAnnouncement, fitViewport, stepViewport, clampViewport, revealRect, reduceGesture, wheelZoomFactor, zoomViewportBy, zoomViewportTo, isTextEntryTarget, keyboardViewport, DEFAULT_SEQUENCE_READER, heldSeats, applyStateDeltaOrdered } from '@kerusiweb/core';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Draws one Kerusi `Section` as a single `<svg>`.
|
|
@@ -33,6 +33,15 @@ class KerusiSectionComponent {
|
|
|
33
33
|
/** Whether an available seat may take its `SeatType.color` (§4.7). */
|
|
34
34
|
typeColors = input(true, /* @ts-ignore */
|
|
35
35
|
...(ngDevMode ? [{ debugName: "typeColors" }] : /* istanbul ignore next */ []));
|
|
36
|
+
/** Styles for every seat of a type, keyed by `SeatType.id`. */
|
|
37
|
+
seatTypeStyles = input(undefined, /* @ts-ignore */
|
|
38
|
+
...(ngDevMode ? [{ debugName: "seatTypeStyles" }] : /* istanbul ignore next */ []));
|
|
39
|
+
/** A style for one seat, laid over its type's. */
|
|
40
|
+
seatStyle = input(undefined, /* @ts-ignore */
|
|
41
|
+
...(ngDevMode ? [{ debugName: "seatStyle" }] : /* istanbul ignore next */ []));
|
|
42
|
+
/** Draws the inside of each seat in place of the stock glyph. */
|
|
43
|
+
seatTemplate = input(undefined, /* @ts-ignore */
|
|
44
|
+
...(ngDevMode ? [{ debugName: "seatTemplate" }] : /* istanbul ignore next */ []));
|
|
36
45
|
/** When false, seats render but do not respond to pointer or keyboard. */
|
|
37
46
|
interactive = input(true, /* @ts-ignore */
|
|
38
47
|
...(ngDevMode ? [{ debugName: "interactive" }] : /* istanbul ignore next */ []));
|
|
@@ -55,114 +64,29 @@ class KerusiSectionComponent {
|
|
|
55
64
|
/** The section's natural width in CSS pixels; it never draws wider. */
|
|
56
65
|
naturalWidth = computed(() => this.layout().width * this.unitScale(), /* @ts-ignore */
|
|
57
66
|
...(ngDevMode ? [{ debugName: "naturalWidth" }] : /* istanbul ignore next */ []));
|
|
58
|
-
isSelected(placed) {
|
|
59
|
-
return this.selection().has(placed.seat.id);
|
|
60
|
-
}
|
|
61
|
-
fill(placed) {
|
|
62
|
-
return seatFill(placed.seat, this.isSelected(placed), this.colors(), this.typeColors());
|
|
63
|
-
}
|
|
64
|
-
textFill(placed) {
|
|
65
|
-
return seatTextFill(placed.seat, this.isSelected(placed), this.colors(), this.typeColors());
|
|
66
|
-
}
|
|
67
|
-
backdrop() {
|
|
68
|
-
return cssVar('backdrop', this.colors().backdrop);
|
|
69
|
-
}
|
|
70
|
-
// --- the seat glyph -------------------------------------------------------
|
|
71
|
-
/** The seat's outline: square-ish front, tapered back — shape carries facing. */
|
|
72
|
-
bodyPath(placed) {
|
|
73
|
-
return seatBodyPath(placed.x, placed.y, placed.width, placed.height);
|
|
74
|
-
}
|
|
75
|
-
/** `null` for an available or blocked seat — nothing to mark. */
|
|
76
|
-
occupantVariant(placed) {
|
|
77
|
-
return seatOccupantVariant(placed.seat, this.isSelected(placed));
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* The box a seat's decorative marks are drawn to: the seat's own, or — when
|
|
81
|
-
* it is selected — the core plate's, which is inset by the frame width.
|
|
82
|
-
*
|
|
83
|
-
* Everything over a selected seat sits on the core, so it all has to be
|
|
84
|
-
* measured from the core. Drawing to the seat's box instead leaves the
|
|
85
|
-
* occupant's hips crossing the frame, where a figure tinted `selectedBg`
|
|
86
|
-
* lands on a frame filled `selectedBg` and reads as a hard nub. Since the
|
|
87
|
-
* core is an exact scaled copy of the body (see {@link seatSelectedFrame}),
|
|
88
|
-
* routing through here reproduces every clearance the mark had against the
|
|
89
|
-
* body, scaled — so the frame width stays free to change.
|
|
90
|
-
*/
|
|
91
|
-
markBox(placed) {
|
|
92
|
-
if (!this.isSelected(placed)) {
|
|
93
|
-
return placed;
|
|
94
|
-
}
|
|
95
|
-
const frame = seatSelectedFrame(placed.width, placed.height);
|
|
96
|
-
return {
|
|
97
|
-
x: placed.x + frame,
|
|
98
|
-
y: placed.y + frame,
|
|
99
|
-
width: placed.width - frame * 2,
|
|
100
|
-
height: placed.height - frame * 2,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
/** The bright plate inside a selected seat's frame. */
|
|
104
|
-
corePath(placed) {
|
|
105
|
-
const box = this.markBox(placed);
|
|
106
|
-
return seatBodyPath(box.x, box.y, box.width, box.height);
|
|
107
|
-
}
|
|
108
|
-
coreFill() {
|
|
109
|
-
return seatCoreFill(this.colors());
|
|
110
|
-
}
|
|
111
|
-
/** The dimming wash over a held or booked seat's type colour. */
|
|
112
|
-
washFill(placed) {
|
|
113
|
-
// Only called for held/booked seats — see the template's @if.
|
|
114
|
-
return seatWashFill(placed.seat.status, this.colors());
|
|
115
|
-
}
|
|
116
|
-
/** The occupant figure for a marked seat, sized to whatever it sits on. */
|
|
117
|
-
occupantPath(placed) {
|
|
118
|
-
const box = this.markBox(placed);
|
|
119
|
-
return seatOccupantPath(box.x, box.y, box.width, box.height);
|
|
120
|
-
}
|
|
121
|
-
occupantStroke(placed) {
|
|
122
|
-
const box = this.markBox(placed);
|
|
123
|
-
return seatOccupantStroke(box.width, box.height);
|
|
124
|
-
}
|
|
125
|
-
// The wheelchair marker keeps the same relative corner it always had; only
|
|
126
|
-
// the box it is relative to changes, so a selected seat's dot stays whole
|
|
127
|
-
// instead of being bitten off by the frame.
|
|
128
|
-
wheelchairCx(placed) {
|
|
129
|
-
const box = this.markBox(placed);
|
|
130
|
-
return box.x + box.width * 0.82;
|
|
131
|
-
}
|
|
132
|
-
wheelchairCy(placed) {
|
|
133
|
-
const box = this.markBox(placed);
|
|
134
|
-
return box.y + box.height * 0.18;
|
|
135
|
-
}
|
|
136
|
-
wheelchairRadius(placed) {
|
|
137
|
-
return this.markBox(placed).width * 0.13;
|
|
138
|
-
}
|
|
139
67
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* The label is centred on the occupant's shoulder line, so without this it is
|
|
144
|
-
* `selectedBg` over a `selectedBg` silhouette — the figure, not the plate, is
|
|
145
|
-
* what it actually has to contrast against. The halo also rescues a label too
|
|
146
|
-
* long for the core, which would otherwise run onto the frame and vanish into
|
|
147
|
-
* it.
|
|
148
|
-
*
|
|
149
|
-
* Bound here rather than in the stylesheet on purpose: a CSS
|
|
150
|
-
* `var(--kerusi-selected-fg, …)` rule would carry the library default as its
|
|
151
|
-
* fallback and silently skip the `[colors]` input tier, which only the
|
|
152
|
-
* TypeScript side can resolve.
|
|
68
|
+
* Every seat with its glyph resolved, once per change of layout, selection or
|
|
69
|
+
* theme rather than once per binding per change detection.
|
|
153
70
|
*/
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
71
|
+
seats = computed(() => {
|
|
72
|
+
const selection = this.selection();
|
|
73
|
+
const colors = this.colors();
|
|
74
|
+
const typeColors = this.typeColors();
|
|
75
|
+
const typeStyles = this.seatTypeStyles();
|
|
76
|
+
const seatStyle = this.seatStyle();
|
|
77
|
+
return this.layout().seats.map((placed) => {
|
|
78
|
+
const selected = selection.has(placed.seat.id);
|
|
79
|
+
const style = resolveSeatStyle(placed.seat, selected, typeStyles, seatStyle);
|
|
80
|
+
return {
|
|
81
|
+
placed,
|
|
82
|
+
selected,
|
|
83
|
+
glyph: resolveSeatGlyph(placed, selected, colors, typeColors, style),
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
}, /* @ts-ignore */
|
|
87
|
+
...(ngDevMode ? [{ debugName: "seats" }] : /* istanbul ignore next */ []));
|
|
88
|
+
backdrop() {
|
|
89
|
+
return cssVar('backdrop', this.colors().backdrop);
|
|
166
90
|
}
|
|
167
91
|
/** The section's single tab stop; every other seat is reachable by arrow key. */
|
|
168
92
|
tabIndex(placed) {
|
|
@@ -174,19 +98,6 @@ class KerusiSectionComponent {
|
|
|
174
98
|
ariaLabel(placed) {
|
|
175
99
|
return this.ariaLabels().get(placed.seat.id) ?? placed.seat.label;
|
|
176
100
|
}
|
|
177
|
-
seatClasses(placed) {
|
|
178
|
-
const seat = placed.seat;
|
|
179
|
-
return [
|
|
180
|
-
'kerusi-seat',
|
|
181
|
-
`kerusi-seat--${seat.status}`,
|
|
182
|
-
this.isSelected(placed) ? 'kerusi-seat--selected' : '',
|
|
183
|
-
seat.selectable ? '' : 'kerusi-seat--unselectable',
|
|
184
|
-
seat.accessibility?.wheelchairAccessible ? 'kerusi-seat--wheelchair' : '',
|
|
185
|
-
seat.companions.length > 0 ? 'kerusi-seat--companion' : '',
|
|
186
|
-
]
|
|
187
|
-
.filter(Boolean)
|
|
188
|
-
.join(' ');
|
|
189
|
-
}
|
|
190
101
|
/** SVG rotate() about the item's center; null when it does not rotate. */
|
|
191
102
|
transform(item) {
|
|
192
103
|
return item.rotation ? `rotate(${item.rotation} ${item.centerX} ${item.centerY})` : null;
|
|
@@ -238,12 +149,12 @@ class KerusiSectionComponent {
|
|
|
238
149
|
}
|
|
239
150
|
}
|
|
240
151
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KerusiSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
241
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: KerusiSectionComponent, isStandalone: true, selector: "kerusi-section", inputs: { section: { classPropertyName: "section", publicName: "section", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, focusedSeatId: { classPropertyName: "focusedSeatId", publicName: "focusedSeatId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabels: { classPropertyName: "ariaLabels", publicName: "ariaLabels", isSignal: true, isRequired: false, transformFunction: null }, colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, typeColors: { classPropertyName: "typeColors", publicName: "typeColors", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, unitScale: { classPropertyName: "unitScale", publicName: "unitScale", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { seatActivate: "seatActivate", seatFocused: "seatFocused", seatKeydown: "seatKeydown" }, ngImport: i0, template: "<svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"kerusi-section-svg\"\r\n role=\"presentation\"\r\n focusable=\"false\"\r\n [style.--kerusi-focus-ring-input]=\"colors().focusRing\"\r\n [attr.viewBox]=\"viewBox()\"\r\n [style.max-width.px]=\"naturalWidth()\"\r\n preserveAspectRatio=\"xMidYMid meet\"\r\n>\r\n <rect\r\n x=\"0\"\r\n y=\"0\"\r\n [attr.width]=\"layout().width\"\r\n [attr.height]=\"layout().height\"\r\n [style.fill]=\"backdrop()\"\r\n />\r\n\r\n <!-- Elements first, so a screen or stage sits behind the seats it faces. -->\r\n @for (placed of layout().elements; track placed.element.id) {\r\n @if (drawsElement(placed)) {\r\n <g\r\n class=\"kerusi-element kerusi-element--{{ placed.element.kind }}\"\r\n [attr.transform]=\"transform(placed)\"\r\n >\r\n @switch (style(placed).shape) {\r\n @case ('screen') {\r\n <path [attr.d]=\"screenPathOf(placed)\" [style.fill]=\"elementFillOf(placed)\" />\r\n }\r\n @case ('text') {}\r\n @case ('void') {\r\n <rect\r\n class=\"kerusi-element__void\"\r\n [attr.x]=\"placed.x\"\r\n [attr.y]=\"placed.y\"\r\n [attr.width]=\"placed.width\"\r\n [attr.height]=\"placed.height\"\r\n [style.stroke]=\"elementTextFillOf(placed)\"\r\n fill=\"none\"\r\n />\r\n }\r\n @default {\r\n <rect\r\n [attr.x]=\"placed.x\"\r\n [attr.y]=\"placed.y\"\r\n [attr.width]=\"placed.width\"\r\n [attr.height]=\"placed.height\"\r\n [attr.rx]=\"radiusOf(placed)\"\r\n [style.fill]=\"elementFillOf(placed)\"\r\n />\r\n }\r\n }\r\n @if (placed.element.label && style(placed).showLabel) {\r\n <text\r\n class=\"kerusi-element__label\"\r\n text-anchor=\"middle\"\r\n dominant-baseline=\"central\"\r\n [attr.x]=\"placed.centerX\"\r\n [attr.y]=\"placed.centerY\"\r\n [attr.font-size]=\"placed.fontSize\"\r\n [style.fill]=\"elementTextFillOf(placed)\"\r\n [attr.transform]=\"labelTransform(placed)\"\r\n >\r\n {{ placed.element.label }}\r\n </text>\r\n }\r\n </g>\r\n }\r\n }\r\n\r\n @for (placed of layout().seats; track placed.seat.id) {\r\n <g\r\n [class]=\"seatClasses(placed)\"\r\n role=\"button\"\r\n [attr.tabindex]=\"tabIndex(placed)\"\r\n [attr.aria-label]=\"ariaLabel(placed)\"\r\n [attr.aria-pressed]=\"isSelected(placed)\"\r\n [attr.aria-disabled]=\"!placed.seat.selectable\"\r\n [attr.data-seat-id]=\"placed.seat.id\"\r\n [attr.transform]=\"transform(placed)\"\r\n (click)=\"onSeatClick(placed)\"\r\n (focus)=\"onSeatFocus(placed)\"\r\n (keydown)=\"onKeydown($event)\"\r\n >\r\n @let variant = occupantVariant(placed);\r\n <!-- Tapered toward the back, square at the front, so which way the seat\r\n faces is legible from the outline alone. -->\r\n <path class=\"kerusi-seat__box\" [attr.d]=\"bodyPath(placed)\" [style.fill]=\"fill(placed)\" />\r\n @if (variant === 'held' || variant === 'booked') {\r\n <!-- Colour stays the seat type's; a taken seat recedes under a wash\r\n instead, so the type colour still reads on a busy map. -->\r\n <path\r\n class=\"kerusi-seat__wash\"\r\n [attr.d]=\"bodyPath(placed)\"\r\n [style.fill]=\"washFill(placed)\"\r\n />\r\n }\r\n @if (variant === 'selected') {\r\n <!-- Selection is the one state drawn from two tones: the body above is\r\n the frame, this is the bright core inside it. Whichever way the\r\n host page is themed, one of the two separates from it \u2014 which is\r\n why nothing here has to know about the page. -->\r\n <path class=\"kerusi-seat__core\" [attr.d]=\"corePath(placed)\" [style.fill]=\"coreFill()\" />\r\n }\r\n @if (variant) {\r\n <!-- Deliberately not counter-rotated: the occupant leans with the\r\n seat. Solid = settled (yours, or sold); hollow = a hold still in\r\n progress. -->\r\n <path\r\n class=\"kerusi-seat__occupant kerusi-seat__occupant--{{ variant }}\"\r\n [attr.d]=\"occupantPath(placed)\"\r\n [attr.stroke-width]=\"occupantStroke(placed)\"\r\n [style.fill]=\"occupantFill(variant)\"\r\n [style.stroke]=\"occupantStrokeColor(variant)\"\r\n />\r\n }\r\n <text\r\n class=\"kerusi-seat__label\"\r\n text-anchor=\"middle\"\r\n dominant-baseline=\"central\"\r\n [attr.x]=\"placed.centerX\"\r\n [attr.y]=\"placed.centerY\"\r\n [attr.font-size]=\"placed.fontSize\"\r\n [style.fill]=\"textFill(placed)\"\r\n [style.stroke]=\"labelHalo(placed)\"\r\n [attr.stroke-width]=\"labelHaloWidth(placed)\"\r\n [attr.transform]=\"counterRotate(placed)\"\r\n >\r\n {{ placed.seat.label }}\r\n </text>\r\n @if (placed.seat.accessibility?.wheelchairAccessible) {\r\n <!-- A corner marker, not a different fill: availability owns the fill. -->\r\n <circle\r\n class=\"kerusi-seat__wheelchair\"\r\n [attr.cx]=\"wheelchairCx(placed)\"\r\n [attr.cy]=\"wheelchairCy(placed)\"\r\n [attr.r]=\"wheelchairRadius(placed)\"\r\n [style.fill]=\"textFill(placed)\"\r\n />\r\n }\r\n </g>\r\n }\r\n</svg>\r\n", styles: [":host{display:block}.kerusi-section-svg{display:block;width:100%;height:auto;max-width:100%}.kerusi-seat{cursor:pointer;outline:none}.kerusi-seat--unselectable{cursor:not-allowed}.kerusi-seat__label,.kerusi-element__label{pointer-events:none;-webkit-user-select:none;user-select:none;font-family:inherit}.kerusi-seat__label{paint-order:stroke;stroke-linejoin:round}.kerusi-seat__wash{pointer-events:none;opacity:.5}.kerusi-seat__core,.kerusi-seat__occupant{pointer-events:none}.kerusi-seat__occupant--selected{opacity:.2}.kerusi-seat__occupant--booked{opacity:.55}.kerusi-seat__occupant--held{opacity:.75;stroke-linecap:round;stroke-linejoin:round}.kerusi-seat--selected .kerusi-seat__label{font-weight:600}.kerusi-seat:focus-visible .kerusi-seat__box{stroke:var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));stroke-width:2.5;paint-order:stroke}.kerusi-element__void{stroke-width:1;stroke-dasharray:4 3;opacity:.7}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
152
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: KerusiSectionComponent, isStandalone: true, selector: "kerusi-section", inputs: { section: { classPropertyName: "section", publicName: "section", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, focusedSeatId: { classPropertyName: "focusedSeatId", publicName: "focusedSeatId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabels: { classPropertyName: "ariaLabels", publicName: "ariaLabels", isSignal: true, isRequired: false, transformFunction: null }, colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, typeColors: { classPropertyName: "typeColors", publicName: "typeColors", isSignal: true, isRequired: false, transformFunction: null }, seatTypeStyles: { classPropertyName: "seatTypeStyles", publicName: "seatTypeStyles", isSignal: true, isRequired: false, transformFunction: null }, seatStyle: { classPropertyName: "seatStyle", publicName: "seatStyle", isSignal: true, isRequired: false, transformFunction: null }, seatTemplate: { classPropertyName: "seatTemplate", publicName: "seatTemplate", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, unitScale: { classPropertyName: "unitScale", publicName: "unitScale", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { seatActivate: "seatActivate", seatFocused: "seatFocused", seatKeydown: "seatKeydown" }, ngImport: i0, template: "<svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"kerusi-section-svg\"\r\n role=\"presentation\"\r\n focusable=\"false\"\r\n [style.--kerusi-focus-ring-input]=\"colors().focusRing\"\r\n [attr.viewBox]=\"viewBox()\"\r\n [style.max-width.px]=\"naturalWidth()\"\r\n preserveAspectRatio=\"xMidYMid meet\"\r\n>\r\n <rect\r\n x=\"0\"\r\n y=\"0\"\r\n [attr.width]=\"layout().width\"\r\n [attr.height]=\"layout().height\"\r\n [style.fill]=\"backdrop()\"\r\n />\r\n\r\n <!-- Elements first, so a screen or stage sits behind the seats it faces. -->\r\n @for (placed of layout().elements; track placed.element.id) {\r\n @if (drawsElement(placed)) {\r\n <g\r\n class=\"kerusi-element kerusi-element--{{ placed.element.kind }}\"\r\n [attr.transform]=\"transform(placed)\"\r\n >\r\n @switch (style(placed).shape) {\r\n @case ('screen') {\r\n <path [attr.d]=\"screenPathOf(placed)\" [style.fill]=\"elementFillOf(placed)\" />\r\n }\r\n @case ('text') {}\r\n @case ('void') {\r\n <rect\r\n class=\"kerusi-element__void\"\r\n [attr.x]=\"placed.x\"\r\n [attr.y]=\"placed.y\"\r\n [attr.width]=\"placed.width\"\r\n [attr.height]=\"placed.height\"\r\n [style.stroke]=\"elementTextFillOf(placed)\"\r\n fill=\"none\"\r\n />\r\n }\r\n @default {\r\n <rect\r\n [attr.x]=\"placed.x\"\r\n [attr.y]=\"placed.y\"\r\n [attr.width]=\"placed.width\"\r\n [attr.height]=\"placed.height\"\r\n [attr.rx]=\"radiusOf(placed)\"\r\n [style.fill]=\"elementFillOf(placed)\"\r\n />\r\n }\r\n }\r\n @if (placed.element.label && style(placed).showLabel) {\r\n <text\r\n class=\"kerusi-element__label\"\r\n text-anchor=\"middle\"\r\n dominant-baseline=\"central\"\r\n [attr.x]=\"placed.centerX\"\r\n [attr.y]=\"placed.centerY\"\r\n [attr.font-size]=\"placed.fontSize\"\r\n [style.fill]=\"elementTextFillOf(placed)\"\r\n [attr.transform]=\"labelTransform(placed)\"\r\n >\r\n {{ placed.element.label }}\r\n </text>\r\n }\r\n </g>\r\n }\r\n }\r\n\r\n <!-- The stock seat drawing. A template rather than inline markup so that a\r\n custom seat template can render it too, as `defaultContent`. Declared\r\n inside the <svg>, so its elements are created in the SVG namespace. -->\r\n <ng-template #stockSeat let-seat>\r\n @let glyph = seat.glyph;\r\n <!-- Tapered toward the back, square at the front, so which way the seat\r\n faces is legible from the outline alone. -->\r\n <path class=\"kerusi-seat__box\" [attr.d]=\"glyph.body.d\" [style.fill]=\"glyph.body.fill\" />\r\n @if (glyph.wash; as wash) {\r\n <!-- Colour stays the seat type's; a taken seat recedes under a wash\r\n instead, so the type colour still reads on a busy map. -->\r\n <path class=\"kerusi-seat__wash\" [attr.d]=\"wash.d\" [style.fill]=\"wash.fill\" />\r\n }\r\n @if (glyph.core; as core) {\r\n <!-- Selection is the one state drawn from two tones: the body above is\r\n the frame, this is the bright core inside it. Whichever way the\r\n host page is themed, one of the two separates from it \u2014 which is\r\n why nothing here has to know about the page. -->\r\n <path class=\"kerusi-seat__core\" [attr.d]=\"core.d\" [style.fill]=\"core.fill\" />\r\n }\r\n @if (glyph.occupant; as occupant) {\r\n <!-- Deliberately not counter-rotated: the occupant leans with the\r\n seat. Solid = settled (yours, or sold); hollow = a hold still in\r\n progress. -->\r\n <path\r\n class=\"kerusi-seat__occupant kerusi-seat__occupant--{{ occupant.variant }}\"\r\n [attr.d]=\"occupant.d\"\r\n [attr.stroke-width]=\"occupant.strokeWidth\"\r\n [style.fill]=\"occupant.fill\"\r\n [style.stroke]=\"occupant.stroke\"\r\n />\r\n }\r\n <!-- The halo colour and width are bound here rather than in the\r\n stylesheet: a CSS `var(--kerusi-selected-fg, \u2026)` rule would carry\r\n the library default as its fallback and skip the [colors] tier. -->\r\n <text\r\n class=\"kerusi-seat__label\"\r\n text-anchor=\"middle\"\r\n dominant-baseline=\"central\"\r\n [attr.x]=\"glyph.label.x\"\r\n [attr.y]=\"glyph.label.y\"\r\n [attr.font-size]=\"glyph.label.fontSize\"\r\n [style.fill]=\"glyph.label.fill\"\r\n [style.stroke]=\"glyph.label.halo\"\r\n [attr.stroke-width]=\"glyph.label.haloWidth\"\r\n [attr.transform]=\"glyph.label.transform\"\r\n >\r\n {{ glyph.label.text }}\r\n </text>\r\n @if (glyph.wheelchair; as wheelchair) {\r\n <!-- A corner marker, not a different fill: availability owns the fill. -->\r\n <circle\r\n class=\"kerusi-seat__wheelchair\"\r\n [attr.cx]=\"wheelchair.cx\"\r\n [attr.cy]=\"wheelchair.cy\"\r\n [attr.r]=\"wheelchair.r\"\r\n [style.fill]=\"wheelchair.fill\"\r\n />\r\n }\r\n </ng-template>\r\n\r\n @for (entry of seats(); track entry.placed.seat.id) {\r\n @let placed = entry.placed;\r\n @let glyph = entry.glyph;\r\n @let ctx =\r\n {\r\n placed: placed,\r\n seat: placed.seat,\r\n selected: entry.selected,\r\n glyph: glyph,\r\n defaultContent: stockSeat,\r\n };\r\n <g\r\n [class]=\"glyph.className\"\r\n role=\"button\"\r\n [attr.tabindex]=\"tabIndex(placed)\"\r\n [attr.aria-label]=\"ariaLabel(placed)\"\r\n [attr.aria-pressed]=\"entry.selected\"\r\n [attr.aria-disabled]=\"!placed.seat.selectable\"\r\n [attr.data-seat-id]=\"placed.seat.id\"\r\n [attr.data-seat-type]=\"glyph.data.type\"\r\n [attr.data-seat-status]=\"glyph.data.status\"\r\n [attr.data-section-id]=\"glyph.data.section\"\r\n [attr.data-seat-row]=\"glyph.data.row\"\r\n [attr.data-seat-attributes]=\"glyph.data.attributes\"\r\n [attr.transform]=\"transform(placed)\"\r\n (click)=\"onSeatClick(placed)\"\r\n (focus)=\"onSeatFocus(placed)\"\r\n (keydown)=\"onKeydown($event)\"\r\n >\r\n @if (seatTemplate(); as custom) {\r\n <ng-container *ngTemplateOutlet=\"custom; context: { $implicit: ctx }\" />\r\n <!-- Drawn over the custom content, because that content may have no\r\n .kerusi-seat__box for the stock focus ring to stroke. Only visible\r\n on :focus-visible. -->\r\n <path class=\"kerusi-seat__focus\" [attr.d]=\"glyph.body.d\" />\r\n } @else {\r\n <ng-container *ngTemplateOutlet=\"stockSeat; context: { $implicit: ctx }\" />\r\n }\r\n </g>\r\n }\r\n</svg>\r\n", styles: [":host{display:block}.kerusi-section-svg{display:block;width:100%;height:auto;max-width:100%}.kerusi-seat{cursor:pointer;outline:none}.kerusi-seat--unselectable{cursor:not-allowed}.kerusi-seat__label,.kerusi-element__label{pointer-events:none;-webkit-user-select:none;user-select:none;font-family:inherit}.kerusi-seat__label{paint-order:stroke;stroke-linejoin:round}.kerusi-seat__wash{pointer-events:none;opacity:.5}.kerusi-seat__core,.kerusi-seat__occupant{pointer-events:none}.kerusi-seat__occupant--selected{opacity:.2}.kerusi-seat__occupant--booked{opacity:.55}.kerusi-seat__occupant--held{opacity:.75;stroke-linecap:round;stroke-linejoin:round}.kerusi-seat--selected .kerusi-seat__label{font-weight:600}.kerusi-seat:focus-visible .kerusi-seat__box{stroke:var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));stroke-width:2.5;paint-order:stroke}.kerusi-seat__focus{fill:none;stroke:none;pointer-events:none}.kerusi-seat:focus-visible .kerusi-seat__focus{stroke:var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));stroke-width:2.5}.kerusi-element__void{stroke-width:1;stroke-dasharray:4 3;opacity:.7}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
242
153
|
}
|
|
243
154
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KerusiSectionComponent, decorators: [{
|
|
244
155
|
type: Component,
|
|
245
|
-
args: [{ selector: 'kerusi-section', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"kerusi-section-svg\"\r\n role=\"presentation\"\r\n focusable=\"false\"\r\n [style.--kerusi-focus-ring-input]=\"colors().focusRing\"\r\n [attr.viewBox]=\"viewBox()\"\r\n [style.max-width.px]=\"naturalWidth()\"\r\n preserveAspectRatio=\"xMidYMid meet\"\r\n>\r\n <rect\r\n x=\"0\"\r\n y=\"0\"\r\n [attr.width]=\"layout().width\"\r\n [attr.height]=\"layout().height\"\r\n [style.fill]=\"backdrop()\"\r\n />\r\n\r\n <!-- Elements first, so a screen or stage sits behind the seats it faces. -->\r\n @for (placed of layout().elements; track placed.element.id) {\r\n @if (drawsElement(placed)) {\r\n <g\r\n class=\"kerusi-element kerusi-element--{{ placed.element.kind }}\"\r\n [attr.transform]=\"transform(placed)\"\r\n >\r\n @switch (style(placed).shape) {\r\n @case ('screen') {\r\n <path [attr.d]=\"screenPathOf(placed)\" [style.fill]=\"elementFillOf(placed)\" />\r\n }\r\n @case ('text') {}\r\n @case ('void') {\r\n <rect\r\n class=\"kerusi-element__void\"\r\n [attr.x]=\"placed.x\"\r\n [attr.y]=\"placed.y\"\r\n [attr.width]=\"placed.width\"\r\n [attr.height]=\"placed.height\"\r\n [style.stroke]=\"elementTextFillOf(placed)\"\r\n fill=\"none\"\r\n />\r\n }\r\n @default {\r\n <rect\r\n [attr.x]=\"placed.x\"\r\n [attr.y]=\"placed.y\"\r\n [attr.width]=\"placed.width\"\r\n [attr.height]=\"placed.height\"\r\n [attr.rx]=\"radiusOf(placed)\"\r\n [style.fill]=\"elementFillOf(placed)\"\r\n />\r\n }\r\n }\r\n @if (placed.element.label && style(placed).showLabel) {\r\n <text\r\n class=\"kerusi-element__label\"\r\n text-anchor=\"middle\"\r\n dominant-baseline=\"central\"\r\n [attr.x]=\"placed.centerX\"\r\n [attr.y]=\"placed.centerY\"\r\n [attr.font-size]=\"placed.fontSize\"\r\n [style.fill]=\"elementTextFillOf(placed)\"\r\n [attr.transform]=\"labelTransform(placed)\"\r\n >\r\n {{ placed.element.label }}\r\n </text>\r\n }\r\n </g>\r\n }\r\n }\r\n\r\n
|
|
246
|
-
}], propDecorators: { section: [{ type: i0.Input, args: [{ isSignal: true, alias: "section", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], focusedSeatId: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusedSeatId", required: false }] }], ariaLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabels", required: false }] }], colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], typeColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeColors", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], unitScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "unitScale", required: false }] }], seatActivate: [{ type: i0.Output, args: ["seatActivate"] }], seatFocused: [{ type: i0.Output, args: ["seatFocused"] }], seatKeydown: [{ type: i0.Output, args: ["seatKeydown"] }] } });
|
|
156
|
+
args: [{ selector: 'kerusi-section', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], template: "<svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"kerusi-section-svg\"\r\n role=\"presentation\"\r\n focusable=\"false\"\r\n [style.--kerusi-focus-ring-input]=\"colors().focusRing\"\r\n [attr.viewBox]=\"viewBox()\"\r\n [style.max-width.px]=\"naturalWidth()\"\r\n preserveAspectRatio=\"xMidYMid meet\"\r\n>\r\n <rect\r\n x=\"0\"\r\n y=\"0\"\r\n [attr.width]=\"layout().width\"\r\n [attr.height]=\"layout().height\"\r\n [style.fill]=\"backdrop()\"\r\n />\r\n\r\n <!-- Elements first, so a screen or stage sits behind the seats it faces. -->\r\n @for (placed of layout().elements; track placed.element.id) {\r\n @if (drawsElement(placed)) {\r\n <g\r\n class=\"kerusi-element kerusi-element--{{ placed.element.kind }}\"\r\n [attr.transform]=\"transform(placed)\"\r\n >\r\n @switch (style(placed).shape) {\r\n @case ('screen') {\r\n <path [attr.d]=\"screenPathOf(placed)\" [style.fill]=\"elementFillOf(placed)\" />\r\n }\r\n @case ('text') {}\r\n @case ('void') {\r\n <rect\r\n class=\"kerusi-element__void\"\r\n [attr.x]=\"placed.x\"\r\n [attr.y]=\"placed.y\"\r\n [attr.width]=\"placed.width\"\r\n [attr.height]=\"placed.height\"\r\n [style.stroke]=\"elementTextFillOf(placed)\"\r\n fill=\"none\"\r\n />\r\n }\r\n @default {\r\n <rect\r\n [attr.x]=\"placed.x\"\r\n [attr.y]=\"placed.y\"\r\n [attr.width]=\"placed.width\"\r\n [attr.height]=\"placed.height\"\r\n [attr.rx]=\"radiusOf(placed)\"\r\n [style.fill]=\"elementFillOf(placed)\"\r\n />\r\n }\r\n }\r\n @if (placed.element.label && style(placed).showLabel) {\r\n <text\r\n class=\"kerusi-element__label\"\r\n text-anchor=\"middle\"\r\n dominant-baseline=\"central\"\r\n [attr.x]=\"placed.centerX\"\r\n [attr.y]=\"placed.centerY\"\r\n [attr.font-size]=\"placed.fontSize\"\r\n [style.fill]=\"elementTextFillOf(placed)\"\r\n [attr.transform]=\"labelTransform(placed)\"\r\n >\r\n {{ placed.element.label }}\r\n </text>\r\n }\r\n </g>\r\n }\r\n }\r\n\r\n <!-- The stock seat drawing. A template rather than inline markup so that a\r\n custom seat template can render it too, as `defaultContent`. Declared\r\n inside the <svg>, so its elements are created in the SVG namespace. -->\r\n <ng-template #stockSeat let-seat>\r\n @let glyph = seat.glyph;\r\n <!-- Tapered toward the back, square at the front, so which way the seat\r\n faces is legible from the outline alone. -->\r\n <path class=\"kerusi-seat__box\" [attr.d]=\"glyph.body.d\" [style.fill]=\"glyph.body.fill\" />\r\n @if (glyph.wash; as wash) {\r\n <!-- Colour stays the seat type's; a taken seat recedes under a wash\r\n instead, so the type colour still reads on a busy map. -->\r\n <path class=\"kerusi-seat__wash\" [attr.d]=\"wash.d\" [style.fill]=\"wash.fill\" />\r\n }\r\n @if (glyph.core; as core) {\r\n <!-- Selection is the one state drawn from two tones: the body above is\r\n the frame, this is the bright core inside it. Whichever way the\r\n host page is themed, one of the two separates from it \u2014 which is\r\n why nothing here has to know about the page. -->\r\n <path class=\"kerusi-seat__core\" [attr.d]=\"core.d\" [style.fill]=\"core.fill\" />\r\n }\r\n @if (glyph.occupant; as occupant) {\r\n <!-- Deliberately not counter-rotated: the occupant leans with the\r\n seat. Solid = settled (yours, or sold); hollow = a hold still in\r\n progress. -->\r\n <path\r\n class=\"kerusi-seat__occupant kerusi-seat__occupant--{{ occupant.variant }}\"\r\n [attr.d]=\"occupant.d\"\r\n [attr.stroke-width]=\"occupant.strokeWidth\"\r\n [style.fill]=\"occupant.fill\"\r\n [style.stroke]=\"occupant.stroke\"\r\n />\r\n }\r\n <!-- The halo colour and width are bound here rather than in the\r\n stylesheet: a CSS `var(--kerusi-selected-fg, \u2026)` rule would carry\r\n the library default as its fallback and skip the [colors] tier. -->\r\n <text\r\n class=\"kerusi-seat__label\"\r\n text-anchor=\"middle\"\r\n dominant-baseline=\"central\"\r\n [attr.x]=\"glyph.label.x\"\r\n [attr.y]=\"glyph.label.y\"\r\n [attr.font-size]=\"glyph.label.fontSize\"\r\n [style.fill]=\"glyph.label.fill\"\r\n [style.stroke]=\"glyph.label.halo\"\r\n [attr.stroke-width]=\"glyph.label.haloWidth\"\r\n [attr.transform]=\"glyph.label.transform\"\r\n >\r\n {{ glyph.label.text }}\r\n </text>\r\n @if (glyph.wheelchair; as wheelchair) {\r\n <!-- A corner marker, not a different fill: availability owns the fill. -->\r\n <circle\r\n class=\"kerusi-seat__wheelchair\"\r\n [attr.cx]=\"wheelchair.cx\"\r\n [attr.cy]=\"wheelchair.cy\"\r\n [attr.r]=\"wheelchair.r\"\r\n [style.fill]=\"wheelchair.fill\"\r\n />\r\n }\r\n </ng-template>\r\n\r\n @for (entry of seats(); track entry.placed.seat.id) {\r\n @let placed = entry.placed;\r\n @let glyph = entry.glyph;\r\n @let ctx =\r\n {\r\n placed: placed,\r\n seat: placed.seat,\r\n selected: entry.selected,\r\n glyph: glyph,\r\n defaultContent: stockSeat,\r\n };\r\n <g\r\n [class]=\"glyph.className\"\r\n role=\"button\"\r\n [attr.tabindex]=\"tabIndex(placed)\"\r\n [attr.aria-label]=\"ariaLabel(placed)\"\r\n [attr.aria-pressed]=\"entry.selected\"\r\n [attr.aria-disabled]=\"!placed.seat.selectable\"\r\n [attr.data-seat-id]=\"placed.seat.id\"\r\n [attr.data-seat-type]=\"glyph.data.type\"\r\n [attr.data-seat-status]=\"glyph.data.status\"\r\n [attr.data-section-id]=\"glyph.data.section\"\r\n [attr.data-seat-row]=\"glyph.data.row\"\r\n [attr.data-seat-attributes]=\"glyph.data.attributes\"\r\n [attr.transform]=\"transform(placed)\"\r\n (click)=\"onSeatClick(placed)\"\r\n (focus)=\"onSeatFocus(placed)\"\r\n (keydown)=\"onKeydown($event)\"\r\n >\r\n @if (seatTemplate(); as custom) {\r\n <ng-container *ngTemplateOutlet=\"custom; context: { $implicit: ctx }\" />\r\n <!-- Drawn over the custom content, because that content may have no\r\n .kerusi-seat__box for the stock focus ring to stroke. Only visible\r\n on :focus-visible. -->\r\n <path class=\"kerusi-seat__focus\" [attr.d]=\"glyph.body.d\" />\r\n } @else {\r\n <ng-container *ngTemplateOutlet=\"stockSeat; context: { $implicit: ctx }\" />\r\n }\r\n </g>\r\n }\r\n</svg>\r\n", styles: [":host{display:block}.kerusi-section-svg{display:block;width:100%;height:auto;max-width:100%}.kerusi-seat{cursor:pointer;outline:none}.kerusi-seat--unselectable{cursor:not-allowed}.kerusi-seat__label,.kerusi-element__label{pointer-events:none;-webkit-user-select:none;user-select:none;font-family:inherit}.kerusi-seat__label{paint-order:stroke;stroke-linejoin:round}.kerusi-seat__wash{pointer-events:none;opacity:.5}.kerusi-seat__core,.kerusi-seat__occupant{pointer-events:none}.kerusi-seat__occupant--selected{opacity:.2}.kerusi-seat__occupant--booked{opacity:.55}.kerusi-seat__occupant--held{opacity:.75;stroke-linecap:round;stroke-linejoin:round}.kerusi-seat--selected .kerusi-seat__label{font-weight:600}.kerusi-seat:focus-visible .kerusi-seat__box{stroke:var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));stroke-width:2.5;paint-order:stroke}.kerusi-seat__focus{fill:none;stroke:none;pointer-events:none}.kerusi-seat:focus-visible .kerusi-seat__focus{stroke:var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));stroke-width:2.5}.kerusi-element__void{stroke-width:1;stroke-dasharray:4 3;opacity:.7}\n"] }]
|
|
157
|
+
}], propDecorators: { section: [{ type: i0.Input, args: [{ isSignal: true, alias: "section", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], focusedSeatId: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusedSeatId", required: false }] }], ariaLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabels", required: false }] }], colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], typeColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeColors", required: false }] }], seatTypeStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatTypeStyles", required: false }] }], seatStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatStyle", required: false }] }], seatTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatTemplate", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], unitScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "unitScale", required: false }] }], seatActivate: [{ type: i0.Output, args: ["seatActivate"] }], seatFocused: [{ type: i0.Output, args: ["seatFocused"] }], seatKeydown: [{ type: i0.Output, args: ["seatKeydown"] }] } });
|
|
247
158
|
|
|
248
159
|
/**
|
|
249
160
|
* A key for a seat map: its seat types on one side, its availability states on
|
|
@@ -269,6 +180,9 @@ class KerusiLegendComponent {
|
|
|
269
180
|
/** Whether an available seat takes its type color — mirrors the seatmap input. */
|
|
270
181
|
typeColors = input(true, /* @ts-ignore */
|
|
271
182
|
...(ngDevMode ? [{ debugName: "typeColors" }] : /* istanbul ignore next */ []));
|
|
183
|
+
/** Mirrors the seatmap input: a type's style is what its swatch shows. */
|
|
184
|
+
seatTypeStyles = input(undefined, /* @ts-ignore */
|
|
185
|
+
...(ngDevMode ? [{ debugName: "seatTypeStyles" }] : /* istanbul ignore next */ []));
|
|
272
186
|
showPrices = input(true, /* @ts-ignore */
|
|
273
187
|
...(ngDevMode ? [{ debugName: "showPrices" }] : /* istanbul ignore next */ []));
|
|
274
188
|
/** Hide types no seat in the rendered map actually uses. */
|
|
@@ -302,13 +216,17 @@ class KerusiLegendComponent {
|
|
|
302
216
|
];
|
|
303
217
|
}, /* @ts-ignore */
|
|
304
218
|
...(ngDevMode ? [{ debugName: "statuses" }] : /* istanbul ignore next */ []));
|
|
219
|
+
// Same token and fallback as an available seat of the type, so a rule that
|
|
220
|
+
// sets `--kerusi-seat-fill` on the seats and the legend items keeps them in step.
|
|
305
221
|
swatch(entry) {
|
|
306
|
-
return (this.
|
|
222
|
+
return legendSwatchFill(entry, this.colors(), this.typeColors(), this.seatTypeStyles()?.[entry.id]);
|
|
223
|
+
}
|
|
224
|
+
/** The swatch outline for a type styled with its own shape; `undefined` keeps the square. */
|
|
225
|
+
typeShape(entry) {
|
|
226
|
+
return legendSwatchPath(this.seatTypeStyles()?.[entry.id], this.glyphSize);
|
|
307
227
|
}
|
|
308
228
|
swatchText(entry) {
|
|
309
|
-
|
|
310
|
-
// Mirrors `seatTextFill`: only a document-supplied color needs guessing at.
|
|
311
|
-
return typeColor ? readableOn(typeColor) : cssVar('availableFg', this.colors().availableFg);
|
|
229
|
+
return legendSwatchText(entry, this.colors(), this.typeColors(), this.seatTypeStyles()?.[entry.id]);
|
|
312
230
|
}
|
|
313
231
|
// --- status swatches -------------------------------------------------------
|
|
314
232
|
//
|
|
@@ -356,12 +274,44 @@ class KerusiLegendComponent {
|
|
|
356
274
|
return entry.price ? formatMoney(entry.price, this.locale()) : '';
|
|
357
275
|
}
|
|
358
276
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KerusiLegendComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
359
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: KerusiLegendComponent, isStandalone: true, selector: "kerusi-legend", inputs: { legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, typeColors: { classPropertyName: "typeColors", publicName: "typeColors", isSignal: true, isRequired: false, transformFunction: null }, showPrices: { classPropertyName: "showPrices", publicName: "showPrices", isSignal: true, isRequired: false, transformFunction: null }, hideUnusedTypes: { classPropertyName: "hideUnusedTypes", publicName: "hideUnusedTypes", isSignal: true, isRequired: false, transformFunction: null }, headingSeatTypes: { classPropertyName: "headingSeatTypes", publicName: "headingSeatTypes", isSignal: true, isRequired: false, transformFunction: null }, headingAvailability: { classPropertyName: "headingAvailability", publicName: "headingAvailability", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"kerusi-legend\">\r\n @if (types().length) {\r\n <div class=\"kerusi-legend__block\">\r\n <h4 class=\"kerusi-legend__heading\">{{ headingSeatTypes() }}</h4>\r\n <ul class=\"kerusi-legend__list\">\r\n @for (entry of types(); track entry.id) {\r\n <li class=\"kerusi-legend__item\">\r\n <
|
|
277
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: KerusiLegendComponent, isStandalone: true, selector: "kerusi-legend", inputs: { legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: true, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, typeColors: { classPropertyName: "typeColors", publicName: "typeColors", isSignal: true, isRequired: false, transformFunction: null }, seatTypeStyles: { classPropertyName: "seatTypeStyles", publicName: "seatTypeStyles", isSignal: true, isRequired: false, transformFunction: null }, showPrices: { classPropertyName: "showPrices", publicName: "showPrices", isSignal: true, isRequired: false, transformFunction: null }, hideUnusedTypes: { classPropertyName: "hideUnusedTypes", publicName: "hideUnusedTypes", isSignal: true, isRequired: false, transformFunction: null }, headingSeatTypes: { classPropertyName: "headingSeatTypes", publicName: "headingSeatTypes", isSignal: true, isRequired: false, transformFunction: null }, headingAvailability: { classPropertyName: "headingAvailability", publicName: "headingAvailability", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"kerusi-legend\">\r\n @if (types().length) {\r\n <div class=\"kerusi-legend__block\">\r\n <h4 class=\"kerusi-legend__heading\">{{ headingSeatTypes() }}</h4>\r\n <ul class=\"kerusi-legend__list\">\r\n @for (entry of types(); track entry.id) {\r\n <li class=\"kerusi-legend__item\" [attr.data-seat-type]=\"entry.id\">\r\n @if (typeShape(entry); as d) {\r\n <!-- A type styled with its own shape keys that shape, not a square. -->\r\n <svg\r\n class=\"kerusi-legend__swatch kerusi-legend__swatch--glyph\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n [attr.viewBox]=\"'0 0 ' + glyphSize + ' ' + glyphSize\"\r\n >\r\n <path [attr.d]=\"d\" [style.fill]=\"swatch(entry)\" />\r\n </svg>\r\n } @else {\r\n <span\r\n class=\"kerusi-legend__swatch\"\r\n aria-hidden=\"true\"\r\n [style.background]=\"swatch(entry)\"\r\n [style.color]=\"swatchText(entry)\"\r\n ></span>\r\n }\r\n <span class=\"kerusi-legend__label\">{{ entry.label }}</span>\r\n @if (showPrices() && price(entry)) {\r\n <span class=\"kerusi-legend__price\">{{ price(entry) }}</span>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <div class=\"kerusi-legend__block\">\r\n <h4 class=\"kerusi-legend__heading\">{{ headingAvailability() }}</h4>\r\n <ul class=\"kerusi-legend__list\">\r\n @for (status of statuses(); track status.key) {\r\n <li class=\"kerusi-legend__item\">\r\n <!-- Shape carries status now, so every swatch draws the seat glyph\r\n rather than a flat colour \u2014 a flat swatch would teach a cue the\r\n map itself no longer uses. -->\r\n <svg\r\n class=\"kerusi-legend__swatch kerusi-legend__swatch--glyph\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n [attr.viewBox]=\"'0 0 ' + glyphSize + ' ' + glyphSize\"\r\n >\r\n <path [attr.d]=\"glyphBody\" [style.fill]=\"status.fill\" />\r\n @if (hasWash(status.kind)) {\r\n <path [attr.d]=\"glyphBody\" [style.fill]=\"washFillOf(status.kind)\" opacity=\"0.5\" />\r\n }\r\n @if (status.kind === 'selected') {\r\n <!-- Two tones, same as the map: the body above is the frame, this\r\n is the core inside it. -->\r\n <path [attr.d]=\"glyphCore\" [style.fill]=\"coreFill()\" />\r\n }\r\n @if (hasOccupant(status.kind)) {\r\n <path\r\n [attr.d]=\"occupantPathOf(status.kind)\"\r\n class=\"kerusi-legend__occupant kerusi-legend__occupant--{{ status.kind }}\"\r\n [attr.stroke-width]=\"occupantStrokeWidthOf(status.kind)\"\r\n [style.fill]=\"occupantFillOf(status.kind)\"\r\n [style.stroke]=\"occupantStrokeOf(status.kind)\"\r\n />\r\n }\r\n </svg>\r\n <span class=\"kerusi-legend__label\">{{ status.label }}</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}.kerusi-legend{display:flex;flex-wrap:wrap;gap:1.5rem;font-size:.85rem}.kerusi-legend__block{display:flex;flex-direction:column;gap:.4rem;min-width:0}.kerusi-legend__heading{margin:0;font-size:.72rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;opacity:.65}.kerusi-legend__list{display:flex;flex-wrap:wrap;gap:.35rem .9rem;margin:0;padding:0;list-style:none}.kerusi-legend__item{display:inline-flex;align-items:center;gap:.4rem}.kerusi-legend__swatch{display:inline-block;flex:none;width:.85rem;height:.85rem;border-radius:3px}.kerusi-legend__swatch--glyph{border-radius:0;overflow:visible}.kerusi-legend__occupant--selected{opacity:.2}.kerusi-legend__occupant--booked{opacity:.55}.kerusi-legend__occupant--held{opacity:.75;stroke-linecap:round;stroke-linejoin:round}.kerusi-legend__price{opacity:.7;font-variant-numeric:tabular-nums}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
360
278
|
}
|
|
361
279
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KerusiLegendComponent, decorators: [{
|
|
362
280
|
type: Component,
|
|
363
|
-
args: [{ selector: 'kerusi-legend', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"kerusi-legend\">\r\n @if (types().length) {\r\n <div class=\"kerusi-legend__block\">\r\n <h4 class=\"kerusi-legend__heading\">{{ headingSeatTypes() }}</h4>\r\n <ul class=\"kerusi-legend__list\">\r\n @for (entry of types(); track entry.id) {\r\n <li class=\"kerusi-legend__item\">\r\n <
|
|
364
|
-
}], propDecorators: { legend: [{ type: i0.Input, args: [{ isSignal: true, alias: "legend", required: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], typeColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeColors", required: false }] }], showPrices: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPrices", required: false }] }], hideUnusedTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideUnusedTypes", required: false }] }], headingSeatTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingSeatTypes", required: false }] }], headingAvailability: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingAvailability", required: false }] }] } });
|
|
281
|
+
args: [{ selector: 'kerusi-legend', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"kerusi-legend\">\r\n @if (types().length) {\r\n <div class=\"kerusi-legend__block\">\r\n <h4 class=\"kerusi-legend__heading\">{{ headingSeatTypes() }}</h4>\r\n <ul class=\"kerusi-legend__list\">\r\n @for (entry of types(); track entry.id) {\r\n <li class=\"kerusi-legend__item\" [attr.data-seat-type]=\"entry.id\">\r\n @if (typeShape(entry); as d) {\r\n <!-- A type styled with its own shape keys that shape, not a square. -->\r\n <svg\r\n class=\"kerusi-legend__swatch kerusi-legend__swatch--glyph\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n [attr.viewBox]=\"'0 0 ' + glyphSize + ' ' + glyphSize\"\r\n >\r\n <path [attr.d]=\"d\" [style.fill]=\"swatch(entry)\" />\r\n </svg>\r\n } @else {\r\n <span\r\n class=\"kerusi-legend__swatch\"\r\n aria-hidden=\"true\"\r\n [style.background]=\"swatch(entry)\"\r\n [style.color]=\"swatchText(entry)\"\r\n ></span>\r\n }\r\n <span class=\"kerusi-legend__label\">{{ entry.label }}</span>\r\n @if (showPrices() && price(entry)) {\r\n <span class=\"kerusi-legend__price\">{{ price(entry) }}</span>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n <div class=\"kerusi-legend__block\">\r\n <h4 class=\"kerusi-legend__heading\">{{ headingAvailability() }}</h4>\r\n <ul class=\"kerusi-legend__list\">\r\n @for (status of statuses(); track status.key) {\r\n <li class=\"kerusi-legend__item\">\r\n <!-- Shape carries status now, so every swatch draws the seat glyph\r\n rather than a flat colour \u2014 a flat swatch would teach a cue the\r\n map itself no longer uses. -->\r\n <svg\r\n class=\"kerusi-legend__swatch kerusi-legend__swatch--glyph\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n [attr.viewBox]=\"'0 0 ' + glyphSize + ' ' + glyphSize\"\r\n >\r\n <path [attr.d]=\"glyphBody\" [style.fill]=\"status.fill\" />\r\n @if (hasWash(status.kind)) {\r\n <path [attr.d]=\"glyphBody\" [style.fill]=\"washFillOf(status.kind)\" opacity=\"0.5\" />\r\n }\r\n @if (status.kind === 'selected') {\r\n <!-- Two tones, same as the map: the body above is the frame, this\r\n is the core inside it. -->\r\n <path [attr.d]=\"glyphCore\" [style.fill]=\"coreFill()\" />\r\n }\r\n @if (hasOccupant(status.kind)) {\r\n <path\r\n [attr.d]=\"occupantPathOf(status.kind)\"\r\n class=\"kerusi-legend__occupant kerusi-legend__occupant--{{ status.kind }}\"\r\n [attr.stroke-width]=\"occupantStrokeWidthOf(status.kind)\"\r\n [style.fill]=\"occupantFillOf(status.kind)\"\r\n [style.stroke]=\"occupantStrokeOf(status.kind)\"\r\n />\r\n }\r\n </svg>\r\n <span class=\"kerusi-legend__label\">{{ status.label }}</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}.kerusi-legend{display:flex;flex-wrap:wrap;gap:1.5rem;font-size:.85rem}.kerusi-legend__block{display:flex;flex-direction:column;gap:.4rem;min-width:0}.kerusi-legend__heading{margin:0;font-size:.72rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;opacity:.65}.kerusi-legend__list{display:flex;flex-wrap:wrap;gap:.35rem .9rem;margin:0;padding:0;list-style:none}.kerusi-legend__item{display:inline-flex;align-items:center;gap:.4rem}.kerusi-legend__swatch{display:inline-block;flex:none;width:.85rem;height:.85rem;border-radius:3px}.kerusi-legend__swatch--glyph{border-radius:0;overflow:visible}.kerusi-legend__occupant--selected{opacity:.2}.kerusi-legend__occupant--booked{opacity:.55}.kerusi-legend__occupant--held{opacity:.75;stroke-linecap:round;stroke-linejoin:round}.kerusi-legend__price{opacity:.7;font-variant-numeric:tabular-nums}\n"] }]
|
|
282
|
+
}], propDecorators: { legend: [{ type: i0.Input, args: [{ isSignal: true, alias: "legend", required: true }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], typeColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeColors", required: false }] }], seatTypeStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatTypeStyles", required: false }] }], showPrices: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPrices", required: false }] }], hideUnusedTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideUnusedTypes", required: false }] }], headingSeatTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingSeatTypes", required: false }] }], headingAvailability: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingAvailability", required: false }] }] } });
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Marks an `<ng-template>` inside `<kerusi-seatmap>` as the drawing for every
|
|
286
|
+
* seat. The library keeps each seat's `<g>`, with its role, ARIA state, tab
|
|
287
|
+
* stop, rotation and event handlers, and stamps this template inside it.
|
|
288
|
+
*
|
|
289
|
+
* The template is declared outside any `<svg>`, so Angular cannot tell its
|
|
290
|
+
* elements are SVG: prefix each one with `svg:` (`<svg:path>`, `<svg:image>`),
|
|
291
|
+
* or it is created as an unknown HTML element and draws nothing.
|
|
292
|
+
*
|
|
293
|
+
* ```html
|
|
294
|
+
* <kerusi-seatmap [map]="map">
|
|
295
|
+
* <ng-template kerusiSeat let-seat>
|
|
296
|
+
* <ng-container *ngTemplateOutlet="seat.defaultContent; context: { $implicit: seat }" />
|
|
297
|
+
* <svg:circle [attr.cx]="seat.glyph.box.x" [attr.cy]="seat.glyph.box.y" r="3" />
|
|
298
|
+
* </ng-template>
|
|
299
|
+
* </kerusi-seatmap>
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
class KerusiSeatTemplateDirective {
|
|
303
|
+
template = inject(TemplateRef);
|
|
304
|
+
/** Types `let-seat` as a {@link SeatTemplateContext}. */
|
|
305
|
+
static ngTemplateContextGuard(_dir, ctx) {
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KerusiSeatTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
309
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: KerusiSeatTemplateDirective, isStandalone: true, selector: "ng-template[kerusiSeat]", ngImport: i0 });
|
|
310
|
+
}
|
|
311
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KerusiSeatTemplateDirective, decorators: [{
|
|
312
|
+
type: Directive,
|
|
313
|
+
args: [{ selector: 'ng-template[kerusiSeat]' }]
|
|
314
|
+
}] });
|
|
365
315
|
|
|
366
316
|
/**
|
|
367
317
|
* Renders a Kerusi seat map.
|
|
@@ -412,6 +362,25 @@ class KerusiSeatmapComponent {
|
|
|
412
362
|
/** Let an available seat take its `SeatType.color` (§4.7). */
|
|
413
363
|
typeColors = input(true, /* @ts-ignore */
|
|
414
364
|
...(ngDevMode ? [{ debugName: "typeColors" }] : /* istanbul ignore next */ []));
|
|
365
|
+
/**
|
|
366
|
+
* Styles for every seat of a type, keyed by `SeatType.id`: fill, label colour
|
|
367
|
+
* and classes. Never changes a selected or blocked seat's fill. Also shown in
|
|
368
|
+
* the legend.
|
|
369
|
+
*/
|
|
370
|
+
seatTypeStyles = input(undefined, /* @ts-ignore */
|
|
371
|
+
...(ngDevMode ? [{ debugName: "seatTypeStyles" }] : /* istanbul ignore next */ []));
|
|
372
|
+
/**
|
|
373
|
+
* A style for one seat, laid over its `seatTypeStyles` entry; return nothing
|
|
374
|
+
* to leave a seat be. Never changes a selected or blocked seat's fill.
|
|
375
|
+
*/
|
|
376
|
+
seatStyle = input(undefined, /* @ts-ignore */
|
|
377
|
+
...(ngDevMode ? [{ debugName: "seatStyle" }] : /* istanbul ignore next */ []));
|
|
378
|
+
/**
|
|
379
|
+
* A `<ng-template kerusiSeat let-seat>` placed inside the map draws the inside
|
|
380
|
+
* of every seat in place of the stock glyph. See {@link KerusiSeatTemplateDirective}.
|
|
381
|
+
*/
|
|
382
|
+
seatTemplate = contentChild(KerusiSeatTemplateDirective, /* @ts-ignore */
|
|
383
|
+
...(ngDevMode ? [{ debugName: "seatTemplate" }] : /* istanbul ignore next */ []));
|
|
415
384
|
/** Grid cell edge, in viewBox units. */
|
|
416
385
|
seatSize = input(28, /* @ts-ignore */
|
|
417
386
|
...(ngDevMode ? [{ debugName: "seatSize" }] : /* istanbul ignore next */ []));
|
|
@@ -1142,12 +1111,12 @@ class KerusiSeatmapComponent {
|
|
|
1142
1111
|
return (this.map().sections ?? []).map((s) => s.id).filter((id) => !hidden.includes(id));
|
|
1143
1112
|
}
|
|
1144
1113
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KerusiSeatmapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1145
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: KerusiSeatmapComponent, isStandalone: true, selector: "kerusi-seatmap", inputs: { map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: true, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, session: { classPropertyName: "session", publicName: "session", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, rtl: { classPropertyName: "rtl", publicName: "rtl", isSignal: true, isRequired: false, transformFunction: null }, ariaStrings: { classPropertyName: "ariaStrings", publicName: "ariaStrings", isSignal: true, isRequired: false, transformFunction: null }, colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, typeColors: { classPropertyName: "typeColors", publicName: "typeColors", isSignal: true, isRequired: false, transformFunction: null }, seatSize: { classPropertyName: "seatSize", publicName: "seatSize", isSignal: true, isRequired: false, transformFunction: null }, seatGap: { classPropertyName: "seatGap", publicName: "seatGap", isSignal: true, isRequired: false, transformFunction: null }, freeformBasis: { classPropertyName: "freeformBasis", publicName: "freeformBasis", isSignal: true, isRequired: false, transformFunction: null }, unitScale: { classPropertyName: "unitScale", publicName: "unitScale", isSignal: true, isRequired: false, transformFunction: null }, showSectionLabels: { classPropertyName: "showSectionLabels", publicName: "showSectionLabels", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, showLegendPrices: { classPropertyName: "showLegendPrices", publicName: "showLegendPrices", isSignal: true, isRequired: false, transformFunction: null }, sectionIds: { classPropertyName: "sectionIds", publicName: "sectionIds", isSignal: true, isRequired: false, transformFunction: null }, sectionOverrides: { classPropertyName: "sectionOverrides", publicName: "sectionOverrides", isSignal: true, isRequired: false, transformFunction: null }, selectableStatuses: { classPropertyName: "selectableStatuses", publicName: "selectableStatuses", isSignal: true, isRequired: false, transformFunction: null }, companionMode: { classPropertyName: "companionMode", publicName: "companionMode", isSignal: true, isRequired: false, transformFunction: null }, maxSelection: { classPropertyName: "maxSelection", publicName: "maxSelection", isSignal: true, isRequired: false, transformFunction: null }, seatSelectable: { classPropertyName: "seatSelectable", publicName: "seatSelectable", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, expireHolds: { classPropertyName: "expireHolds", publicName: "expireHolds", isSignal: true, isRequired: false, transformFunction: null }, expiryIntervalMs: { classPropertyName: "expiryIntervalMs", publicName: "expiryIntervalMs", isSignal: true, isRequired: false, transformFunction: null }, zoomable: { classPropertyName: "zoomable", publicName: "zoomable", isSignal: true, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: true, isRequired: false, transformFunction: null }, showZoomControls: { classPropertyName: "showZoomControls", publicName: "showZoomControls", isSignal: true, isRequired: false, transformFunction: null }, maximizable: { classPropertyName: "maximizable", publicName: "maximizable", isSignal: true, isRequired: false, transformFunction: null }, controlStrings: { classPropertyName: "controlStrings", publicName: "controlStrings", isSignal: true, isRequired: false, transformFunction: null }, validate: { classPropertyName: "validate", publicName: "validate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange", seatSelect: "seatSelect", seatDeselect: "seatDeselect", seatDisallowed: "seatDisallowed", seatFocus: "seatFocus", validationIssues: "validationIssues", viewportChange: "viewportChange", maximizedChange: "maximizedChange" }, viewQueries: [{ propertyName: "viewportEl", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "contentEl", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\r\n class=\"kerusi-seatmap\"\r\n [class.kerusi-seatmap--maximized]=\"maximized()\"\r\n role=\"group\"\r\n [attr.aria-label]=\"mapLabel()\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : null\"\r\n [attr.lang]=\"resolvedLocale()\"\r\n [style.background]=\"maximized() ? controlColors().maximizedBackground : null\"\r\n [style.color]=\"maximized() ? controlColors().maximizedColor : null\"\r\n (keydown)=\"onRootKeydown($event)\"\r\n>\r\n @if (zoomable() || maximizable()) {\r\n <!-- Only when a zoom or maximize feature is on, so a plain map's markup is\r\n exactly what it was before they existed. -->\r\n <div class=\"kerusi-seatmap__stage\">\r\n @if (showToolbar()) {\r\n <div\r\n class=\"kerusi-toolbar\"\r\n role=\"toolbar\"\r\n [attr.aria-label]=\"strings().toolbar\"\r\n [style.--kerusi-focus-ring-input]=\"resolvedColors().focusRing\"\r\n >\r\n @if (zoomable() && showZoomControls()) {\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-in\"\r\n [attr.aria-label]=\"strings().zoomIn\"\r\n [attr.aria-disabled]=\"atMaxZoom()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"zoomIn()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M12 5v14M5 12h14\" />\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-out\"\r\n [attr.aria-label]=\"strings().zoomOut\"\r\n [attr.aria-disabled]=\"atFit()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"zoomOut()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M5 12h14\" />\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-reset\"\r\n [attr.aria-label]=\"strings().zoomReset\"\r\n [attr.aria-disabled]=\"atFit()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"resetZoom()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M3 12a9 9 0 1 0 3-6.7M3 4v5h5\" />\r\n </svg>\r\n </button>\r\n }\r\n @if (maximizable()) {\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--maximize\"\r\n [attr.aria-label]=\"maximized() ? strings().restore : strings().maximize\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"toggleMaximized()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n @if (maximized()) {\r\n <path d=\"M9 4v5H4M15 4v5h5M15 20v-5h5M9 20v-5H4\" />\r\n } @else {\r\n <path d=\"M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5\" />\r\n }\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (zoomable()) {\r\n <div\r\n #viewport\r\n class=\"kerusi-viewport\"\r\n role=\"group\"\r\n tabindex=\"0\"\r\n [attr.aria-label]=\"strings().viewport\"\r\n [style.touch-action]=\"touchAction()\"\r\n [style.--kerusi-focus-ring-input]=\"resolvedColors().focusRing\"\r\n >\r\n <div\r\n #content\r\n class=\"kerusi-viewport__content\"\r\n [class.kerusi-viewport__content--animated]=\"animated()\"\r\n [style.transform]=\"transform()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n </div>\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n }\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n }\r\n\r\n @if (showLegend()) {\r\n <kerusi-legend\r\n [legend]=\"renderMap().legend\"\r\n [locale]=\"resolvedLocale()\"\r\n [colors]=\"resolvedColors()\"\r\n [typeColors]=\"typeColors()\"\r\n [showPrices]=\"showLegendPrices()\"\r\n />\r\n }\r\n\r\n <p class=\"kerusi-sr-only\" aria-live=\"polite\" aria-atomic=\"true\">{{ liveMessage() }}</p>\r\n</div>\r\n\r\n<ng-template #sections>\r\n @for (section of renderMap().sections; track section.id) {\r\n <section\r\n class=\"kerusi-seatmap__section kerusi-seatmap__section--{{ section.layoutMode }}\"\r\n role=\"group\"\r\n [attr.aria-labelledby]=\"labelFor(section) ? labelId(section) : null\"\r\n [attr.aria-label]=\"labelFor(section) ? null : section.id\"\r\n >\r\n @if (showSectionLabels() && labelFor(section)) {\r\n <h3 class=\"kerusi-section-label\" [id]=\"labelId(section)\">{{ labelFor(section) }}</h3>\r\n }\r\n\r\n <kerusi-section\r\n [section]=\"section\"\r\n [layout]=\"layoutFor(section)\"\r\n [selection]=\"selectionSet()\"\r\n [focusedSeatId]=\"focusedSeatIn(section)\"\r\n [ariaLabels]=\"ariaLabels()\"\r\n [colors]=\"resolvedColors()\"\r\n [typeColors]=\"typeColors()\"\r\n [unitScale]=\"unitScale()\"\r\n [interactive]=\"interactive()\"\r\n (seatActivate)=\"onSeatActivate($event)\"\r\n (seatFocused)=\"onSeatFocused($event)\"\r\n (seatKeydown)=\"onKeydown(section, $event)\"\r\n />\r\n </section>\r\n }\r\n</ng-template>\r\n", styles: [":host{display:block}.kerusi-seatmap{display:flex;flex-direction:column;gap:1.25rem}.kerusi-seatmap__section{display:flex;flex-direction:column;gap:.4rem}.kerusi-section-label{margin:0;font-size:.85rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;opacity:.75}.kerusi-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}.kerusi-seatmap__stage{display:flex;flex-direction:column;gap:1.25rem}.kerusi-toolbar{display:flex;gap:.35rem;align-self:flex-end;flex:none}.kerusi-control{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:2.75rem;height:2.75rem;padding:0;border:1px solid;border-radius:.4rem;font:inherit;cursor:pointer}.kerusi-control[aria-disabled=true]{opacity:.45;cursor:default}.kerusi-control svg{width:1.4rem;height:1.4rem;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}.kerusi-control:focus-visible,.kerusi-viewport:focus-visible{outline:2px solid var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));outline-offset:2px}.kerusi-viewport{position:relative;overflow:hidden;overflow:clip;user-select:none;-webkit-user-select:none}.kerusi-viewport__content{display:flex;flex-direction:column;gap:1.25rem;transform-origin:0 0}.kerusi-viewport__content--animated{transition:transform .16s ease-out}@media(prefers-reduced-motion:reduce){.kerusi-viewport__content--animated{transition:none}}.kerusi-seatmap--maximized{position:fixed;inset:0;z-index:var(--kerusi-maximized-z-index, 1000);box-sizing:border-box;padding:.75rem;gap:.5rem;overflow:hidden;overscroll-behavior:contain}.kerusi-seatmap--maximized .kerusi-seatmap__stage{flex:1 1 auto;min-height:0;gap:.5rem;overflow:auto}.kerusi-seatmap--maximized .kerusi-viewport{flex:1 1 auto;min-height:0}\n"], dependencies: [{ kind: "component", type: KerusiSectionComponent, selector: "kerusi-section", inputs: ["section", "layout", "selection", "focusedSeatId", "ariaLabels", "colors", "typeColors", "interactive", "unitScale"], outputs: ["seatActivate", "seatFocused", "seatKeydown"] }, { kind: "component", type: KerusiLegendComponent, selector: "kerusi-legend", inputs: ["legend", "locale", "colors", "typeColors", "showPrices", "hideUnusedTypes", "headingSeatTypes", "headingAvailability"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1114
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: KerusiSeatmapComponent, isStandalone: true, selector: "kerusi-seatmap", inputs: { map: { classPropertyName: "map", publicName: "map", isSignal: true, isRequired: true, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, session: { classPropertyName: "session", publicName: "session", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, rtl: { classPropertyName: "rtl", publicName: "rtl", isSignal: true, isRequired: false, transformFunction: null }, ariaStrings: { classPropertyName: "ariaStrings", publicName: "ariaStrings", isSignal: true, isRequired: false, transformFunction: null }, colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, typeColors: { classPropertyName: "typeColors", publicName: "typeColors", isSignal: true, isRequired: false, transformFunction: null }, seatTypeStyles: { classPropertyName: "seatTypeStyles", publicName: "seatTypeStyles", isSignal: true, isRequired: false, transformFunction: null }, seatStyle: { classPropertyName: "seatStyle", publicName: "seatStyle", isSignal: true, isRequired: false, transformFunction: null }, seatSize: { classPropertyName: "seatSize", publicName: "seatSize", isSignal: true, isRequired: false, transformFunction: null }, seatGap: { classPropertyName: "seatGap", publicName: "seatGap", isSignal: true, isRequired: false, transformFunction: null }, freeformBasis: { classPropertyName: "freeformBasis", publicName: "freeformBasis", isSignal: true, isRequired: false, transformFunction: null }, unitScale: { classPropertyName: "unitScale", publicName: "unitScale", isSignal: true, isRequired: false, transformFunction: null }, showSectionLabels: { classPropertyName: "showSectionLabels", publicName: "showSectionLabels", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, showLegendPrices: { classPropertyName: "showLegendPrices", publicName: "showLegendPrices", isSignal: true, isRequired: false, transformFunction: null }, sectionIds: { classPropertyName: "sectionIds", publicName: "sectionIds", isSignal: true, isRequired: false, transformFunction: null }, sectionOverrides: { classPropertyName: "sectionOverrides", publicName: "sectionOverrides", isSignal: true, isRequired: false, transformFunction: null }, selectableStatuses: { classPropertyName: "selectableStatuses", publicName: "selectableStatuses", isSignal: true, isRequired: false, transformFunction: null }, companionMode: { classPropertyName: "companionMode", publicName: "companionMode", isSignal: true, isRequired: false, transformFunction: null }, maxSelection: { classPropertyName: "maxSelection", publicName: "maxSelection", isSignal: true, isRequired: false, transformFunction: null }, seatSelectable: { classPropertyName: "seatSelectable", publicName: "seatSelectable", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, expireHolds: { classPropertyName: "expireHolds", publicName: "expireHolds", isSignal: true, isRequired: false, transformFunction: null }, expiryIntervalMs: { classPropertyName: "expiryIntervalMs", publicName: "expiryIntervalMs", isSignal: true, isRequired: false, transformFunction: null }, zoomable: { classPropertyName: "zoomable", publicName: "zoomable", isSignal: true, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: true, isRequired: false, transformFunction: null }, showZoomControls: { classPropertyName: "showZoomControls", publicName: "showZoomControls", isSignal: true, isRequired: false, transformFunction: null }, maximizable: { classPropertyName: "maximizable", publicName: "maximizable", isSignal: true, isRequired: false, transformFunction: null }, controlStrings: { classPropertyName: "controlStrings", publicName: "controlStrings", isSignal: true, isRequired: false, transformFunction: null }, validate: { classPropertyName: "validate", publicName: "validate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange", seatSelect: "seatSelect", seatDeselect: "seatDeselect", seatDisallowed: "seatDisallowed", seatFocus: "seatFocus", validationIssues: "validationIssues", viewportChange: "viewportChange", maximizedChange: "maximizedChange" }, queries: [{ propertyName: "seatTemplate", first: true, predicate: KerusiSeatTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "viewportEl", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "contentEl", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\r\n class=\"kerusi-seatmap\"\r\n [class.kerusi-seatmap--maximized]=\"maximized()\"\r\n role=\"group\"\r\n [attr.aria-label]=\"mapLabel()\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : null\"\r\n [attr.lang]=\"resolvedLocale()\"\r\n [style.background]=\"maximized() ? controlColors().maximizedBackground : null\"\r\n [style.color]=\"maximized() ? controlColors().maximizedColor : null\"\r\n (keydown)=\"onRootKeydown($event)\"\r\n>\r\n @if (zoomable() || maximizable()) {\r\n <!-- Only when a zoom or maximize feature is on, so a plain map's markup is\r\n exactly what it was before they existed. -->\r\n <div class=\"kerusi-seatmap__stage\">\r\n @if (showToolbar()) {\r\n <div\r\n class=\"kerusi-toolbar\"\r\n role=\"toolbar\"\r\n [attr.aria-label]=\"strings().toolbar\"\r\n [style.--kerusi-focus-ring-input]=\"resolvedColors().focusRing\"\r\n >\r\n @if (zoomable() && showZoomControls()) {\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-in\"\r\n [attr.aria-label]=\"strings().zoomIn\"\r\n [attr.aria-disabled]=\"atMaxZoom()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"zoomIn()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M12 5v14M5 12h14\" />\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-out\"\r\n [attr.aria-label]=\"strings().zoomOut\"\r\n [attr.aria-disabled]=\"atFit()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"zoomOut()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M5 12h14\" />\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-reset\"\r\n [attr.aria-label]=\"strings().zoomReset\"\r\n [attr.aria-disabled]=\"atFit()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"resetZoom()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M3 12a9 9 0 1 0 3-6.7M3 4v5h5\" />\r\n </svg>\r\n </button>\r\n }\r\n @if (maximizable()) {\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--maximize\"\r\n [attr.aria-label]=\"maximized() ? strings().restore : strings().maximize\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"toggleMaximized()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n @if (maximized()) {\r\n <path d=\"M9 4v5H4M15 4v5h5M15 20v-5h5M9 20v-5H4\" />\r\n } @else {\r\n <path d=\"M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5\" />\r\n }\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (zoomable()) {\r\n <div\r\n #viewport\r\n class=\"kerusi-viewport\"\r\n role=\"group\"\r\n tabindex=\"0\"\r\n [attr.aria-label]=\"strings().viewport\"\r\n [style.touch-action]=\"touchAction()\"\r\n [style.--kerusi-focus-ring-input]=\"resolvedColors().focusRing\"\r\n >\r\n <div\r\n #content\r\n class=\"kerusi-viewport__content\"\r\n [class.kerusi-viewport__content--animated]=\"animated()\"\r\n [style.transform]=\"transform()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n </div>\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n }\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n }\r\n\r\n @if (showLegend()) {\r\n <kerusi-legend\r\n [legend]=\"renderMap().legend\"\r\n [locale]=\"resolvedLocale()\"\r\n [colors]=\"resolvedColors()\"\r\n [typeColors]=\"typeColors()\"\r\n [seatTypeStyles]=\"seatTypeStyles()\"\r\n [showPrices]=\"showLegendPrices()\"\r\n />\r\n }\r\n\r\n <p class=\"kerusi-sr-only\" aria-live=\"polite\" aria-atomic=\"true\">{{ liveMessage() }}</p>\r\n</div>\r\n\r\n<ng-template #sections>\r\n @for (section of renderMap().sections; track section.id) {\r\n <section\r\n class=\"kerusi-seatmap__section kerusi-seatmap__section--{{ section.layoutMode }}\"\r\n role=\"group\"\r\n [attr.aria-labelledby]=\"labelFor(section) ? labelId(section) : null\"\r\n [attr.aria-label]=\"labelFor(section) ? null : section.id\"\r\n >\r\n @if (showSectionLabels() && labelFor(section)) {\r\n <h3 class=\"kerusi-section-label\" [id]=\"labelId(section)\">{{ labelFor(section) }}</h3>\r\n }\r\n\r\n <kerusi-section\r\n [section]=\"section\"\r\n [layout]=\"layoutFor(section)\"\r\n [selection]=\"selectionSet()\"\r\n [focusedSeatId]=\"focusedSeatIn(section)\"\r\n [ariaLabels]=\"ariaLabels()\"\r\n [colors]=\"resolvedColors()\"\r\n [typeColors]=\"typeColors()\"\r\n [seatTemplate]=\"seatTemplate()?.template\"\r\n [seatStyle]=\"seatStyle()\"\r\n [seatTypeStyles]=\"seatTypeStyles()\"\r\n [unitScale]=\"unitScale()\"\r\n [interactive]=\"interactive()\"\r\n (seatActivate)=\"onSeatActivate($event)\"\r\n (seatFocused)=\"onSeatFocused($event)\"\r\n (seatKeydown)=\"onKeydown(section, $event)\"\r\n />\r\n </section>\r\n }\r\n</ng-template>\r\n", styles: [":host{display:block}.kerusi-seatmap{display:flex;flex-direction:column;gap:1.25rem}.kerusi-seatmap__section{display:flex;flex-direction:column;gap:.4rem}.kerusi-section-label{margin:0;font-size:.85rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;opacity:.75}.kerusi-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}.kerusi-seatmap__stage{display:flex;flex-direction:column;gap:1.25rem}.kerusi-toolbar{display:flex;gap:.35rem;align-self:flex-end;flex:none}.kerusi-control{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:2.75rem;height:2.75rem;padding:0;border:1px solid;border-radius:.4rem;font:inherit;cursor:pointer}.kerusi-control[aria-disabled=true]{opacity:.45;cursor:default}.kerusi-control svg{width:1.4rem;height:1.4rem;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}.kerusi-control:focus-visible,.kerusi-viewport:focus-visible{outline:2px solid var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));outline-offset:2px}.kerusi-viewport{position:relative;overflow:hidden;overflow:clip;user-select:none;-webkit-user-select:none}.kerusi-viewport__content{display:flex;flex-direction:column;gap:1.25rem;transform-origin:0 0}.kerusi-viewport__content--animated{transition:transform .16s ease-out}@media(prefers-reduced-motion:reduce){.kerusi-viewport__content--animated{transition:none}}.kerusi-seatmap--maximized{position:fixed;inset:0;z-index:var(--kerusi-maximized-z-index, 1000);box-sizing:border-box;padding:.75rem;gap:.5rem;overflow:hidden;overscroll-behavior:contain}.kerusi-seatmap--maximized .kerusi-seatmap__stage{flex:1 1 auto;min-height:0;gap:.5rem;overflow:auto}.kerusi-seatmap--maximized .kerusi-viewport{flex:1 1 auto;min-height:0}\n"], dependencies: [{ kind: "component", type: KerusiSectionComponent, selector: "kerusi-section", inputs: ["section", "layout", "selection", "focusedSeatId", "ariaLabels", "colors", "typeColors", "seatTypeStyles", "seatStyle", "seatTemplate", "interactive", "unitScale"], outputs: ["seatActivate", "seatFocused", "seatKeydown"] }, { kind: "component", type: KerusiLegendComponent, selector: "kerusi-legend", inputs: ["legend", "locale", "colors", "typeColors", "seatTypeStyles", "showPrices", "hideUnusedTypes", "headingSeatTypes", "headingAvailability"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1146
1115
|
}
|
|
1147
1116
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KerusiSeatmapComponent, decorators: [{
|
|
1148
1117
|
type: Component,
|
|
1149
|
-
args: [{ selector: 'kerusi-seatmap', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KerusiSectionComponent, KerusiLegendComponent, NgTemplateOutlet], template: "<div\r\n class=\"kerusi-seatmap\"\r\n [class.kerusi-seatmap--maximized]=\"maximized()\"\r\n role=\"group\"\r\n [attr.aria-label]=\"mapLabel()\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : null\"\r\n [attr.lang]=\"resolvedLocale()\"\r\n [style.background]=\"maximized() ? controlColors().maximizedBackground : null\"\r\n [style.color]=\"maximized() ? controlColors().maximizedColor : null\"\r\n (keydown)=\"onRootKeydown($event)\"\r\n>\r\n @if (zoomable() || maximizable()) {\r\n <!-- Only when a zoom or maximize feature is on, so a plain map's markup is\r\n exactly what it was before they existed. -->\r\n <div class=\"kerusi-seatmap__stage\">\r\n @if (showToolbar()) {\r\n <div\r\n class=\"kerusi-toolbar\"\r\n role=\"toolbar\"\r\n [attr.aria-label]=\"strings().toolbar\"\r\n [style.--kerusi-focus-ring-input]=\"resolvedColors().focusRing\"\r\n >\r\n @if (zoomable() && showZoomControls()) {\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-in\"\r\n [attr.aria-label]=\"strings().zoomIn\"\r\n [attr.aria-disabled]=\"atMaxZoom()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"zoomIn()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M12 5v14M5 12h14\" />\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-out\"\r\n [attr.aria-label]=\"strings().zoomOut\"\r\n [attr.aria-disabled]=\"atFit()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"zoomOut()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M5 12h14\" />\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-reset\"\r\n [attr.aria-label]=\"strings().zoomReset\"\r\n [attr.aria-disabled]=\"atFit()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"resetZoom()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M3 12a9 9 0 1 0 3-6.7M3 4v5h5\" />\r\n </svg>\r\n </button>\r\n }\r\n @if (maximizable()) {\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--maximize\"\r\n [attr.aria-label]=\"maximized() ? strings().restore : strings().maximize\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"toggleMaximized()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n @if (maximized()) {\r\n <path d=\"M9 4v5H4M15 4v5h5M15 20v-5h5M9 20v-5H4\" />\r\n } @else {\r\n <path d=\"M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5\" />\r\n }\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (zoomable()) {\r\n <div\r\n #viewport\r\n class=\"kerusi-viewport\"\r\n role=\"group\"\r\n tabindex=\"0\"\r\n [attr.aria-label]=\"strings().viewport\"\r\n [style.touch-action]=\"touchAction()\"\r\n [style.--kerusi-focus-ring-input]=\"resolvedColors().focusRing\"\r\n >\r\n <div\r\n #content\r\n class=\"kerusi-viewport__content\"\r\n [class.kerusi-viewport__content--animated]=\"animated()\"\r\n [style.transform]=\"transform()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n </div>\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n }\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n }\r\n\r\n @if (showLegend()) {\r\n <kerusi-legend\r\n [legend]=\"renderMap().legend\"\r\n [locale]=\"resolvedLocale()\"\r\n [colors]=\"resolvedColors()\"\r\n [typeColors]=\"typeColors()\"\r\n [showPrices]=\"showLegendPrices()\"\r\n />\r\n }\r\n\r\n <p class=\"kerusi-sr-only\" aria-live=\"polite\" aria-atomic=\"true\">{{ liveMessage() }}</p>\r\n</div>\r\n\r\n<ng-template #sections>\r\n @for (section of renderMap().sections; track section.id) {\r\n <section\r\n class=\"kerusi-seatmap__section kerusi-seatmap__section--{{ section.layoutMode }}\"\r\n role=\"group\"\r\n [attr.aria-labelledby]=\"labelFor(section) ? labelId(section) : null\"\r\n [attr.aria-label]=\"labelFor(section) ? null : section.id\"\r\n >\r\n @if (showSectionLabels() && labelFor(section)) {\r\n <h3 class=\"kerusi-section-label\" [id]=\"labelId(section)\">{{ labelFor(section) }}</h3>\r\n }\r\n\r\n <kerusi-section\r\n [section]=\"section\"\r\n [layout]=\"layoutFor(section)\"\r\n [selection]=\"selectionSet()\"\r\n [focusedSeatId]=\"focusedSeatIn(section)\"\r\n [ariaLabels]=\"ariaLabels()\"\r\n [colors]=\"resolvedColors()\"\r\n [typeColors]=\"typeColors()\"\r\n [unitScale]=\"unitScale()\"\r\n [interactive]=\"interactive()\"\r\n (seatActivate)=\"onSeatActivate($event)\"\r\n (seatFocused)=\"onSeatFocused($event)\"\r\n (seatKeydown)=\"onKeydown(section, $event)\"\r\n />\r\n </section>\r\n }\r\n</ng-template>\r\n", styles: [":host{display:block}.kerusi-seatmap{display:flex;flex-direction:column;gap:1.25rem}.kerusi-seatmap__section{display:flex;flex-direction:column;gap:.4rem}.kerusi-section-label{margin:0;font-size:.85rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;opacity:.75}.kerusi-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}.kerusi-seatmap__stage{display:flex;flex-direction:column;gap:1.25rem}.kerusi-toolbar{display:flex;gap:.35rem;align-self:flex-end;flex:none}.kerusi-control{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:2.75rem;height:2.75rem;padding:0;border:1px solid;border-radius:.4rem;font:inherit;cursor:pointer}.kerusi-control[aria-disabled=true]{opacity:.45;cursor:default}.kerusi-control svg{width:1.4rem;height:1.4rem;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}.kerusi-control:focus-visible,.kerusi-viewport:focus-visible{outline:2px solid var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));outline-offset:2px}.kerusi-viewport{position:relative;overflow:hidden;overflow:clip;user-select:none;-webkit-user-select:none}.kerusi-viewport__content{display:flex;flex-direction:column;gap:1.25rem;transform-origin:0 0}.kerusi-viewport__content--animated{transition:transform .16s ease-out}@media(prefers-reduced-motion:reduce){.kerusi-viewport__content--animated{transition:none}}.kerusi-seatmap--maximized{position:fixed;inset:0;z-index:var(--kerusi-maximized-z-index, 1000);box-sizing:border-box;padding:.75rem;gap:.5rem;overflow:hidden;overscroll-behavior:contain}.kerusi-seatmap--maximized .kerusi-seatmap__stage{flex:1 1 auto;min-height:0;gap:.5rem;overflow:auto}.kerusi-seatmap--maximized .kerusi-viewport{flex:1 1 auto;min-height:0}\n"] }]
|
|
1150
|
-
}], ctorParameters: () => [], propDecorators: { map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: true }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], session: [{ type: i0.Input, args: [{ isSignal: true, alias: "session", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], rtl: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtl", required: false }] }], ariaStrings: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaStrings", required: false }] }], colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], typeColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeColors", required: false }] }], seatSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatSize", required: false }] }], seatGap: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatGap", required: false }] }], freeformBasis: [{ type: i0.Input, args: [{ isSignal: true, alias: "freeformBasis", required: false }] }], unitScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "unitScale", required: false }] }], showSectionLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSectionLabels", required: false }] }], showLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegend", required: false }] }], showLegendPrices: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegendPrices", required: false }] }], sectionIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionIds", required: false }] }], sectionOverrides: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionOverrides", required: false }] }], selectableStatuses: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectableStatuses", required: false }] }], companionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "companionMode", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], seatSelectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatSelectable", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], expireHolds: [{ type: i0.Input, args: [{ isSignal: true, alias: "expireHolds", required: false }] }], expiryIntervalMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "expiryIntervalMs", required: false }] }], zoomable: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomable", required: false }] }], maxZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxZoom", required: false }] }], showZoomControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZoomControls", required: false }] }], maximizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "maximizable", required: false }] }], controlStrings: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlStrings", required: false }] }], validate: [{ type: i0.Input, args: [{ isSignal: true, alias: "validate", required: false }] }], seatSelect: [{ type: i0.Output, args: ["seatSelect"] }], seatDeselect: [{ type: i0.Output, args: ["seatDeselect"] }], seatDisallowed: [{ type: i0.Output, args: ["seatDisallowed"] }], seatFocus: [{ type: i0.Output, args: ["seatFocus"] }], validationIssues: [{ type: i0.Output, args: ["validationIssues"] }], viewportChange: [{ type: i0.Output, args: ["viewportChange"] }], maximizedChange: [{ type: i0.Output, args: ["maximizedChange"] }], viewportEl: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], contentEl: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }] } });
|
|
1118
|
+
args: [{ selector: 'kerusi-seatmap', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KerusiSectionComponent, KerusiLegendComponent, NgTemplateOutlet], template: "<div\r\n class=\"kerusi-seatmap\"\r\n [class.kerusi-seatmap--maximized]=\"maximized()\"\r\n role=\"group\"\r\n [attr.aria-label]=\"mapLabel()\"\r\n [attr.dir]=\"isRtl() ? 'rtl' : null\"\r\n [attr.lang]=\"resolvedLocale()\"\r\n [style.background]=\"maximized() ? controlColors().maximizedBackground : null\"\r\n [style.color]=\"maximized() ? controlColors().maximizedColor : null\"\r\n (keydown)=\"onRootKeydown($event)\"\r\n>\r\n @if (zoomable() || maximizable()) {\r\n <!-- Only when a zoom or maximize feature is on, so a plain map's markup is\r\n exactly what it was before they existed. -->\r\n <div class=\"kerusi-seatmap__stage\">\r\n @if (showToolbar()) {\r\n <div\r\n class=\"kerusi-toolbar\"\r\n role=\"toolbar\"\r\n [attr.aria-label]=\"strings().toolbar\"\r\n [style.--kerusi-focus-ring-input]=\"resolvedColors().focusRing\"\r\n >\r\n @if (zoomable() && showZoomControls()) {\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-in\"\r\n [attr.aria-label]=\"strings().zoomIn\"\r\n [attr.aria-disabled]=\"atMaxZoom()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"zoomIn()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M12 5v14M5 12h14\" />\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-out\"\r\n [attr.aria-label]=\"strings().zoomOut\"\r\n [attr.aria-disabled]=\"atFit()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"zoomOut()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M5 12h14\" />\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--zoom-reset\"\r\n [attr.aria-label]=\"strings().zoomReset\"\r\n [attr.aria-disabled]=\"atFit()\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"resetZoom()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n <path d=\"M3 12a9 9 0 1 0 3-6.7M3 4v5h5\" />\r\n </svg>\r\n </button>\r\n }\r\n @if (maximizable()) {\r\n <button\r\n type=\"button\"\r\n class=\"kerusi-control kerusi-control--maximize\"\r\n [attr.aria-label]=\"maximized() ? strings().restore : strings().maximize\"\r\n [style.background]=\"controlColors().buttonBackground\"\r\n [style.color]=\"controlColors().buttonColor\"\r\n [style.border-color]=\"controlColors().buttonBorder\"\r\n (click)=\"toggleMaximized()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\r\n @if (maximized()) {\r\n <path d=\"M9 4v5H4M15 4v5h5M15 20v-5h5M9 20v-5H4\" />\r\n } @else {\r\n <path d=\"M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5\" />\r\n }\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (zoomable()) {\r\n <div\r\n #viewport\r\n class=\"kerusi-viewport\"\r\n role=\"group\"\r\n tabindex=\"0\"\r\n [attr.aria-label]=\"strings().viewport\"\r\n [style.touch-action]=\"touchAction()\"\r\n [style.--kerusi-focus-ring-input]=\"resolvedColors().focusRing\"\r\n >\r\n <div\r\n #content\r\n class=\"kerusi-viewport__content\"\r\n [class.kerusi-viewport__content--animated]=\"animated()\"\r\n [style.transform]=\"transform()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n </div>\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n }\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"sections\" />\r\n }\r\n\r\n @if (showLegend()) {\r\n <kerusi-legend\r\n [legend]=\"renderMap().legend\"\r\n [locale]=\"resolvedLocale()\"\r\n [colors]=\"resolvedColors()\"\r\n [typeColors]=\"typeColors()\"\r\n [seatTypeStyles]=\"seatTypeStyles()\"\r\n [showPrices]=\"showLegendPrices()\"\r\n />\r\n }\r\n\r\n <p class=\"kerusi-sr-only\" aria-live=\"polite\" aria-atomic=\"true\">{{ liveMessage() }}</p>\r\n</div>\r\n\r\n<ng-template #sections>\r\n @for (section of renderMap().sections; track section.id) {\r\n <section\r\n class=\"kerusi-seatmap__section kerusi-seatmap__section--{{ section.layoutMode }}\"\r\n role=\"group\"\r\n [attr.aria-labelledby]=\"labelFor(section) ? labelId(section) : null\"\r\n [attr.aria-label]=\"labelFor(section) ? null : section.id\"\r\n >\r\n @if (showSectionLabels() && labelFor(section)) {\r\n <h3 class=\"kerusi-section-label\" [id]=\"labelId(section)\">{{ labelFor(section) }}</h3>\r\n }\r\n\r\n <kerusi-section\r\n [section]=\"section\"\r\n [layout]=\"layoutFor(section)\"\r\n [selection]=\"selectionSet()\"\r\n [focusedSeatId]=\"focusedSeatIn(section)\"\r\n [ariaLabels]=\"ariaLabels()\"\r\n [colors]=\"resolvedColors()\"\r\n [typeColors]=\"typeColors()\"\r\n [seatTemplate]=\"seatTemplate()?.template\"\r\n [seatStyle]=\"seatStyle()\"\r\n [seatTypeStyles]=\"seatTypeStyles()\"\r\n [unitScale]=\"unitScale()\"\r\n [interactive]=\"interactive()\"\r\n (seatActivate)=\"onSeatActivate($event)\"\r\n (seatFocused)=\"onSeatFocused($event)\"\r\n (seatKeydown)=\"onKeydown(section, $event)\"\r\n />\r\n </section>\r\n }\r\n</ng-template>\r\n", styles: [":host{display:block}.kerusi-seatmap{display:flex;flex-direction:column;gap:1.25rem}.kerusi-seatmap__section{display:flex;flex-direction:column;gap:.4rem}.kerusi-section-label{margin:0;font-size:.85rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;opacity:.75}.kerusi-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}.kerusi-seatmap__stage{display:flex;flex-direction:column;gap:1.25rem}.kerusi-toolbar{display:flex;gap:.35rem;align-self:flex-end;flex:none}.kerusi-control{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:2.75rem;height:2.75rem;padding:0;border:1px solid;border-radius:.4rem;font:inherit;cursor:pointer}.kerusi-control[aria-disabled=true]{opacity:.45;cursor:default}.kerusi-control svg{width:1.4rem;height:1.4rem;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}.kerusi-control:focus-visible,.kerusi-viewport:focus-visible{outline:2px solid var(--kerusi-focus-ring, var(--kerusi-focus-ring-input, currentColor));outline-offset:2px}.kerusi-viewport{position:relative;overflow:hidden;overflow:clip;user-select:none;-webkit-user-select:none}.kerusi-viewport__content{display:flex;flex-direction:column;gap:1.25rem;transform-origin:0 0}.kerusi-viewport__content--animated{transition:transform .16s ease-out}@media(prefers-reduced-motion:reduce){.kerusi-viewport__content--animated{transition:none}}.kerusi-seatmap--maximized{position:fixed;inset:0;z-index:var(--kerusi-maximized-z-index, 1000);box-sizing:border-box;padding:.75rem;gap:.5rem;overflow:hidden;overscroll-behavior:contain}.kerusi-seatmap--maximized .kerusi-seatmap__stage{flex:1 1 auto;min-height:0;gap:.5rem;overflow:auto}.kerusi-seatmap--maximized .kerusi-viewport{flex:1 1 auto;min-height:0}\n"] }]
|
|
1119
|
+
}], ctorParameters: () => [], propDecorators: { map: [{ type: i0.Input, args: [{ isSignal: true, alias: "map", required: true }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], session: [{ type: i0.Input, args: [{ isSignal: true, alias: "session", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], rtl: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtl", required: false }] }], ariaStrings: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaStrings", required: false }] }], colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], typeColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeColors", required: false }] }], seatTypeStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatTypeStyles", required: false }] }], seatStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatStyle", required: false }] }], seatTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KerusiSeatTemplateDirective), { isSignal: true }] }], seatSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatSize", required: false }] }], seatGap: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatGap", required: false }] }], freeformBasis: [{ type: i0.Input, args: [{ isSignal: true, alias: "freeformBasis", required: false }] }], unitScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "unitScale", required: false }] }], showSectionLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSectionLabels", required: false }] }], showLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegend", required: false }] }], showLegendPrices: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegendPrices", required: false }] }], sectionIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionIds", required: false }] }], sectionOverrides: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionOverrides", required: false }] }], selectableStatuses: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectableStatuses", required: false }] }], companionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "companionMode", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], seatSelectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "seatSelectable", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], expireHolds: [{ type: i0.Input, args: [{ isSignal: true, alias: "expireHolds", required: false }] }], expiryIntervalMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "expiryIntervalMs", required: false }] }], zoomable: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomable", required: false }] }], maxZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxZoom", required: false }] }], showZoomControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZoomControls", required: false }] }], maximizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "maximizable", required: false }] }], controlStrings: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlStrings", required: false }] }], validate: [{ type: i0.Input, args: [{ isSignal: true, alias: "validate", required: false }] }], seatSelect: [{ type: i0.Output, args: ["seatSelect"] }], seatDeselect: [{ type: i0.Output, args: ["seatDeselect"] }], seatDisallowed: [{ type: i0.Output, args: ["seatDisallowed"] }], seatFocus: [{ type: i0.Output, args: ["seatFocus"] }], validationIssues: [{ type: i0.Output, args: ["validationIssues"] }], viewportChange: [{ type: i0.Output, args: ["viewportChange"] }], maximizedChange: [{ type: i0.Output, args: ["maximizedChange"] }], viewportEl: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], contentEl: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }] } });
|
|
1151
1120
|
function formatTotal(total, locale) {
|
|
1152
1121
|
return total ? formatMoney(total, locale) : '';
|
|
1153
1122
|
}
|
|
@@ -1269,5 +1238,5 @@ class KerusiStateStore {
|
|
|
1269
1238
|
* Generated bundle index. Do not edit.
|
|
1270
1239
|
*/
|
|
1271
1240
|
|
|
1272
|
-
export { KerusiLegendComponent, KerusiSeatmapComponent, KerusiSectionComponent, KerusiStateStore };
|
|
1241
|
+
export { KerusiLegendComponent, KerusiSeatTemplateDirective, KerusiSeatmapComponent, KerusiSectionComponent, KerusiStateStore };
|
|
1273
1242
|
//# sourceMappingURL=kerusiweb-angular.mjs.map
|