@mintplayer/ng-bootstrap 21.29.0 → 21.30.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.
@@ -0,0 +1,693 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, forwardRef, Directive, input, model, output, viewChild, computed, effect, ChangeDetectionStrategy, CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
3
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
4
+ import { html, unsafeCSS, LitElement, nothing } from 'lit';
5
+
6
+ class BsMultiRangeValueAccessor {
7
+ constructor() {
8
+ this.host = inject(BsMultiRangeComponent);
9
+ }
10
+ onInputEvent(ev) {
11
+ if (!this.onValueChange)
12
+ return;
13
+ const detail = ev.detail;
14
+ if (detail)
15
+ this.onValueChange([...detail]);
16
+ }
17
+ onTouchEvent() {
18
+ if (this.onTouched)
19
+ this.onTouched();
20
+ }
21
+ registerOnChange(fn) {
22
+ this.onValueChange = fn;
23
+ }
24
+ registerOnTouched(fn) {
25
+ this.onTouched = fn;
26
+ }
27
+ writeValue(value) {
28
+ const ref = this.host.elementRef();
29
+ if (!ref)
30
+ return;
31
+ ref.nativeElement.value = value ?? [];
32
+ }
33
+ setDisabledState(isDisabled) {
34
+ const ref = this.host.elementRef();
35
+ if (!ref)
36
+ return;
37
+ if (isDisabled) {
38
+ ref.nativeElement.setAttribute('disabled', '');
39
+ }
40
+ else {
41
+ ref.nativeElement.removeAttribute('disabled');
42
+ }
43
+ }
44
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsMultiRangeValueAccessor, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
45
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.11", type: BsMultiRangeValueAccessor, isStandalone: true, selector: "bs-multi-range", host: { listeners: { "value-input": "onInputEvent($event)", "value-change": "onTouchEvent()" } }, providers: [{
46
+ provide: NG_VALUE_ACCESSOR,
47
+ useExisting: forwardRef(() => BsMultiRangeValueAccessor),
48
+ multi: true,
49
+ }], ngImport: i0 }); }
50
+ }
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsMultiRangeValueAccessor, decorators: [{
52
+ type: Directive,
53
+ args: [{
54
+ selector: 'bs-multi-range',
55
+ providers: [{
56
+ provide: NG_VALUE_ACCESSOR,
57
+ useExisting: forwardRef(() => BsMultiRangeValueAccessor),
58
+ multi: true,
59
+ }],
60
+ host: {
61
+ '(value-input)': 'onInputEvent($event)',
62
+ '(value-change)': 'onTouchEvent()',
63
+ },
64
+ }]
65
+ }] });
66
+
67
+ class BsMultiRangeComponent {
68
+ constructor() {
69
+ this.min = input(0, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
70
+ this.max = input(100, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
71
+ this.step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
72
+ this.minDistance = input(0, ...(ngDevMode ? [{ debugName: "minDistance" }] : /* istanbul ignore next */ []));
73
+ this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
74
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
75
+ this.formatValue = input(null, ...(ngDevMode ? [{ debugName: "formatValue" }] : /* istanbul ignore next */ []));
76
+ this.label = input(null, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
77
+ // Default is `undefined` so the effect doesn't clobber a writeValue() from a
78
+ // form-control binding that hasn't fired yet. Once the model is set (either
79
+ // by [(value)] binding or by user interaction), the effect drives the WC.
80
+ this.value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
81
+ this.valueChange = output();
82
+ this.valueInput = output();
83
+ this.elementRef = viewChild.required('el');
84
+ this.disabledAttr = computed(() => (this.disabled() ? '' : null), ...(ngDevMode ? [{ debugName: "disabledAttr" }] : /* istanbul ignore next */ []));
85
+ effect(() => {
86
+ const ref = this.elementRef();
87
+ if (!ref)
88
+ return;
89
+ const v = this.value();
90
+ if (v === undefined)
91
+ return;
92
+ ref.nativeElement.value = v;
93
+ });
94
+ effect(() => {
95
+ const ref = this.elementRef();
96
+ if (!ref)
97
+ return;
98
+ ref.nativeElement.formatValue = this.formatValue();
99
+ });
100
+ }
101
+ onValueInput(event) {
102
+ const detail = event.detail;
103
+ if (!detail)
104
+ return;
105
+ this.value.set(detail);
106
+ this.valueInput.emit(detail);
107
+ }
108
+ onValueChange(event) {
109
+ const detail = event.detail;
110
+ if (!detail)
111
+ return;
112
+ this.value.set(detail);
113
+ this.valueChange.emit(detail);
114
+ }
115
+ /** Imperatively read the currently-rendered values from the WC. */
116
+ getValues() {
117
+ const ref = this.elementRef();
118
+ return ref ? ref.nativeElement.getValues() : [];
119
+ }
120
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsMultiRangeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
121
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.11", type: BsMultiRangeComponent, isStandalone: true, selector: "bs-multi-range", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, minDistance: { classPropertyName: "minDistance", publicName: "minDistance", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, formatValue: { classPropertyName: "formatValue", publicName: "formatValue", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChange: "valueChange", valueInput: "valueInput" }, host: { properties: { "attr.orientation": "orientation()" } }, viewQueries: [{ propertyName: "elementRef", first: true, predicate: ["el"], descendants: true, isSignal: true }], hostDirectives: [{ directive: BsMultiRangeValueAccessor }], ngImport: i0, template: `
122
+ <mp-multi-range
123
+ #el
124
+ class="bs-multi-range"
125
+ [attr.min]="min()"
126
+ [attr.max]="max()"
127
+ [attr.step]="step()"
128
+ [attr.min-distance]="minDistance()"
129
+ [attr.orientation]="orientation()"
130
+ [attr.disabled]="disabledAttr()"
131
+ [attr.aria-label]="label()"
132
+ (value-input)="onValueInput($event)"
133
+ (value-change)="onValueChange($event)"
134
+ ></mp-multi-range>
135
+ `, isInline: true, styles: [":host{display:block;width:100%}.bs-multi-range{display:block;width:100%;height:100%}:host([orientation=\"vertical\"]){width:auto;height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
136
+ }
137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsMultiRangeComponent, decorators: [{
138
+ type: Component,
139
+ args: [{ selector: 'bs-multi-range', template: `
140
+ <mp-multi-range
141
+ #el
142
+ class="bs-multi-range"
143
+ [attr.min]="min()"
144
+ [attr.max]="max()"
145
+ [attr.step]="step()"
146
+ [attr.min-distance]="minDistance()"
147
+ [attr.orientation]="orientation()"
148
+ [attr.disabled]="disabledAttr()"
149
+ [attr.aria-label]="label()"
150
+ (value-input)="onValueInput($event)"
151
+ (value-change)="onValueChange($event)"
152
+ ></mp-multi-range>
153
+ `, host: {
154
+ '[attr.orientation]': 'orientation()',
155
+ }, schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [BsMultiRangeValueAccessor], styles: [":host{display:block;width:100%}.bs-multi-range{display:block;width:100%;height:100%}:host([orientation=\"vertical\"]){width:auto;height:100%}\n"] }]
156
+ }], ctorParameters: () => [], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], minDistance: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDistance", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], formatValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatValue", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], valueInput: [{ type: i0.Output, args: ["valueInput"] }], elementRef: [{ type: i0.ViewChild, args: ['el', { isSignal: true }] }] } });
157
+
158
+ // AUTO-GENERATED — do not edit by hand.
159
+ // Source: mint-multi-range.element.html + mint-multi-range.element.scss
160
+ // Regenerate with the codegen-wc Nx target.
161
+ const template = html `<!-- Track + thumbs are rendered dynamically by render(). This file exists so the
162
+ codegen-wc target produces a \`styles\` export from the sibling .scss; the
163
+ \`template\` export it generates here is intentionally unused. -->`;
164
+ const styles = unsafeCSS(`:host {
165
+ display: block;
166
+ position: relative;
167
+ box-sizing: border-box;
168
+ width: 100%;
169
+ --bs-multi-range-track-bg: var(--bs-tertiary-bg, #e9ecef);
170
+ --bs-multi-range-track-radius: 1rem;
171
+ --bs-multi-range-track-thickness: 0.5rem;
172
+ --bs-multi-range-thumb-bg: var(--bs-primary, #0d6efd);
173
+ --bs-multi-range-thumb-bg-disabled: var(--bs-secondary, #6c757d);
174
+ --bs-multi-range-thumb-size: 1rem;
175
+ --bs-multi-range-thumb-shadow: 0 0.1rem 0.25rem rgba(0, 0, 0, 0.1);
176
+ --bs-multi-range-fill-bg: var(--bs-primary, #0d6efd);
177
+ --bs-multi-range-fill-bg-disabled: var(--bs-secondary, #6c757d);
178
+ --bs-multi-range-tooltip-bg: var(--bs-dark, #212529);
179
+ --bs-multi-range-tooltip-color: var(--bs-light, #f8f9fa);
180
+ }
181
+
182
+ :host([orientation=vertical]) {
183
+ width: auto;
184
+ height: 100%;
185
+ min-height: 8rem;
186
+ }
187
+
188
+ :host([disabled]) {
189
+ cursor: not-allowed;
190
+ }
191
+
192
+ .track {
193
+ position: relative;
194
+ background: var(--bs-multi-range-track-bg);
195
+ border-radius: var(--bs-multi-range-track-radius);
196
+ touch-action: none;
197
+ }
198
+
199
+ :host([orientation=horizontal]) .track {
200
+ width: 100%;
201
+ height: var(--bs-multi-range-track-thickness);
202
+ margin: calc(var(--bs-multi-range-thumb-size) / 2) 0;
203
+ }
204
+
205
+ :host([orientation=vertical]) .track {
206
+ width: var(--bs-multi-range-track-thickness);
207
+ height: 100%;
208
+ margin: 0 calc(var(--bs-multi-range-thumb-size) / 2);
209
+ }
210
+
211
+ .fill {
212
+ position: absolute;
213
+ background: var(--bs-multi-range-fill-bg);
214
+ border-radius: var(--bs-multi-range-track-radius);
215
+ }
216
+
217
+ :host([orientation=horizontal]) .fill {
218
+ top: 0;
219
+ bottom: 0;
220
+ }
221
+
222
+ :host([orientation=vertical]) .fill {
223
+ left: 0;
224
+ right: 0;
225
+ }
226
+
227
+ :host([disabled]) .fill {
228
+ background: var(--bs-multi-range-fill-bg-disabled);
229
+ }
230
+
231
+ .thumb {
232
+ position: absolute;
233
+ width: var(--bs-multi-range-thumb-size);
234
+ height: var(--bs-multi-range-thumb-size);
235
+ background: var(--bs-multi-range-thumb-bg);
236
+ border: 0;
237
+ border-radius: 50%;
238
+ box-shadow: var(--bs-multi-range-thumb-shadow);
239
+ cursor: grab;
240
+ touch-action: none;
241
+ padding: 0;
242
+ outline: none;
243
+ transition: transform 100ms ease-out;
244
+ }
245
+
246
+ .thumb:active {
247
+ cursor: grabbing;
248
+ transform: scale(1.1);
249
+ }
250
+
251
+ :host([orientation=horizontal]) .thumb {
252
+ top: 50%;
253
+ transform: translate(-50%, -50%);
254
+ }
255
+
256
+ :host([orientation=horizontal]) .thumb:active {
257
+ transform: translate(-50%, -50%) scale(1.1);
258
+ }
259
+
260
+ :host([orientation=horizontal]:dir(rtl)) .thumb {
261
+ transform: translate(50%, -50%);
262
+ }
263
+
264
+ :host([orientation=horizontal]:dir(rtl)) .thumb:active {
265
+ transform: translate(50%, -50%) scale(1.1);
266
+ }
267
+
268
+ :host([orientation=vertical]) .thumb {
269
+ left: 50%;
270
+ transform: translate(-50%, 50%);
271
+ }
272
+
273
+ :host([orientation=vertical]) .thumb:active {
274
+ transform: translate(-50%, 50%) scale(1.1);
275
+ }
276
+
277
+ :host([disabled]) .thumb {
278
+ background: var(--bs-multi-range-thumb-bg-disabled);
279
+ cursor: not-allowed;
280
+ }
281
+
282
+ .thumb:focus-visible {
283
+ box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.35), var(--bs-multi-range-thumb-shadow);
284
+ }
285
+
286
+ .tooltip {
287
+ position: absolute;
288
+ background: var(--bs-multi-range-tooltip-bg);
289
+ color: var(--bs-multi-range-tooltip-color);
290
+ font-size: 0.75rem;
291
+ font-weight: 500;
292
+ line-height: 1;
293
+ padding: 0.25rem 0.5rem;
294
+ border-radius: 0.25rem;
295
+ pointer-events: none;
296
+ white-space: nowrap;
297
+ opacity: 0;
298
+ transition: opacity 120ms ease-out;
299
+ z-index: 2;
300
+ }
301
+
302
+ :host([orientation=horizontal]) .tooltip {
303
+ bottom: calc(100% + 0.5rem);
304
+ left: 50%;
305
+ transform: translateX(-50%);
306
+ }
307
+
308
+ :host([orientation=vertical]) .tooltip {
309
+ left: calc(100% + 0.5rem);
310
+ top: 50%;
311
+ transform: translateY(-50%);
312
+ }
313
+
314
+ .thumb:hover .tooltip,
315
+ .thumb:focus-visible .tooltip,
316
+ .thumb:active .tooltip,
317
+ .thumb[data-dragging=true] .tooltip {
318
+ opacity: 1;
319
+ }
320
+
321
+ :host([disabled]) .tooltip {
322
+ display: none;
323
+ }
324
+
325
+ @media (prefers-reduced-motion: reduce) {
326
+ .thumb,
327
+ .tooltip {
328
+ transition: none;
329
+ }
330
+ }`);
331
+
332
+ /**
333
+ * Bootstrap-flavoured multi-thumb range slider.
334
+ *
335
+ * Block-crossing: thumbs cannot pass their neighbours. Identity is by index —
336
+ * value[0] is always the lowest thumb. The value setter normalises input by
337
+ * sorting ascending and clamping each entry to [min, max]; minDistance is
338
+ * enforced only at user-interaction entry points (pointer + keyboard), not on
339
+ * programmatic writes — callers' arrays are preserved verbatim within bounds.
340
+ *
341
+ * Events:
342
+ * - `value-input` fires continuously during drag and on every keyboard step.
343
+ * - `value-change` fires on commit (pointerup) and after every keyboard step.
344
+ *
345
+ * Both bubble and compose so the Angular wrapper's host listeners pick them up.
346
+ */
347
+ class MintMultiRangeElement extends LitElement {
348
+ constructor() {
349
+ super(...arguments);
350
+ this.min = 0;
351
+ this.max = 100;
352
+ this.step = 1;
353
+ this.minDistance = 0;
354
+ this.orientation = 'horizontal';
355
+ this.disabled = false;
356
+ this.formatValue = null;
357
+ this._value = null;
358
+ this.dragState = null;
359
+ // Cached references / state to keep the per-pointermove path off the hot path
360
+ // for getComputedStyle and querySelector. Track ref is set in firstUpdated()
361
+ // and is stable across renders. RTL is captured at gesture start so a single
362
+ // drag stream sees a coherent direction even if the host's `dir` changes mid-air.
363
+ this.trackEl = null;
364
+ this.rtlDuringGesture = null;
365
+ this.onThumbPointerDown = (thumbIndex, ev) => {
366
+ if (this.disabled)
367
+ return;
368
+ this.startDrag(thumbIndex, ev.pointerId, ev.currentTarget);
369
+ };
370
+ this.onTrackPointerDown = (ev) => {
371
+ if (this.disabled)
372
+ return;
373
+ // Ignore clicks that originated on a thumb — those are handled by the thumb's own pointerdown.
374
+ const path = ev.composedPath();
375
+ if (path.some(node => node instanceof HTMLElement && node.classList?.contains('thumb')))
376
+ return;
377
+ // Capture direction up-front so the first valueFromPointer / nearest-thumb
378
+ // calculation in this gesture sees a consistent value.
379
+ this.rtlDuringGesture = getComputedStyle(this).direction === 'rtl';
380
+ const targetValue = this.valueFromPointer(ev.clientX, ev.clientY);
381
+ const values = this.value;
382
+ const nearestIndex = this.nearestThumbIndex(values, targetValue);
383
+ if (this.moveThumb(nearestIndex, targetValue))
384
+ this.dispatchValueChange();
385
+ // Transfer drag to the nearest thumb so a continued press-and-drag keeps moving it.
386
+ const thumbEl = this.renderRoot.querySelector(`.thumb[data-thumb-index="${nearestIndex}"]`);
387
+ if (thumbEl)
388
+ this.startDrag(nearestIndex, ev.pointerId, thumbEl);
389
+ };
390
+ this.onPointerMove = (ev) => {
391
+ if (!this.dragState || ev.pointerId !== this.dragState.pointerId)
392
+ return;
393
+ const candidate = this.valueFromPointer(ev.clientX, ev.clientY);
394
+ this.moveThumb(this.dragState.thumbIndex, candidate);
395
+ };
396
+ this.onPointerUp = (ev) => {
397
+ if (!this.dragState || ev.pointerId !== this.dragState.pointerId)
398
+ return;
399
+ const target = ev.target;
400
+ if (target?.releasePointerCapture && target.hasPointerCapture(ev.pointerId)) {
401
+ target.releasePointerCapture(ev.pointerId);
402
+ }
403
+ this.dragState = null;
404
+ this.rtlDuringGesture = null;
405
+ this.requestUpdate();
406
+ this.dispatchValueChange();
407
+ };
408
+ this.onThumbKeyDown = (thumbIndex, ev) => {
409
+ if (this.disabled)
410
+ return;
411
+ const target = this.keyboardTarget(thumbIndex, ev.key);
412
+ if (target === null)
413
+ return;
414
+ ev.preventDefault();
415
+ if (this.moveThumb(thumbIndex, target))
416
+ this.dispatchValueChange();
417
+ };
418
+ }
419
+ static { this.styles = [styles]; }
420
+ static get observedAttributes() {
421
+ return [
422
+ ...(super.observedAttributes ?? []),
423
+ 'min',
424
+ 'max',
425
+ 'step',
426
+ 'min-distance',
427
+ 'orientation',
428
+ 'disabled',
429
+ ];
430
+ }
431
+ static { this.properties = {
432
+ value: { attribute: false },
433
+ min: { attribute: 'min', type: Number, reflect: true },
434
+ max: { attribute: 'max', type: Number, reflect: true },
435
+ step: { attribute: 'step', type: Number, reflect: true },
436
+ minDistance: { attribute: 'min-distance', type: Number },
437
+ orientation: { attribute: 'orientation', type: String, reflect: true },
438
+ disabled: { attribute: 'disabled', type: Boolean, reflect: true },
439
+ formatValue: { attribute: false },
440
+ }; }
441
+ connectedCallback() {
442
+ super.connectedCallback();
443
+ if (!this.hasAttribute('role'))
444
+ this.setAttribute('role', 'group');
445
+ }
446
+ firstUpdated() {
447
+ this.trackEl = this.renderRoot.querySelector('.track');
448
+ }
449
+ get value() {
450
+ return this._value ?? [this.min, this.max];
451
+ }
452
+ set value(next) {
453
+ const old = this._value;
454
+ const normalised = this.normalise(next);
455
+ // Skip the update entirely when the incoming array is shallow-equal to the
456
+ // current state — the wrapper's effect re-pushes the value on every
457
+ // value-input event during a drag, so without this we'd queue a redundant
458
+ // Lit update for every pointermove.
459
+ if (this.arraysEqual(old, normalised))
460
+ return;
461
+ this._value = normalised;
462
+ this.requestUpdate('value', old);
463
+ }
464
+ arraysEqual(a, b) {
465
+ if (a === b)
466
+ return true;
467
+ if (a === null || b === null)
468
+ return false;
469
+ if (a.length !== b.length)
470
+ return false;
471
+ return a.every((v, i) => v === b[i]);
472
+ }
473
+ normalise(input) {
474
+ if (!input || input.length === 0)
475
+ return null;
476
+ const clamped = input.map(v => this.clampToBounds(v));
477
+ return [...clamped].sort((a, b) => a - b);
478
+ }
479
+ clampToBounds(v) {
480
+ return Math.min(this.max, Math.max(this.min, v));
481
+ }
482
+ snapToStep(v) {
483
+ if (!this.step || this.step <= 0)
484
+ return this.clampToBounds(v);
485
+ const snapped = this.min + Math.round((v - this.min) / this.step) * this.step;
486
+ return this.clampToBounds(snapped);
487
+ }
488
+ percent(value) {
489
+ const range = this.max - this.min;
490
+ if (range <= 0)
491
+ return 0;
492
+ return ((value - this.min) / range) * 100;
493
+ }
494
+ formatThumb(value) {
495
+ if (this.formatValue) {
496
+ try {
497
+ return this.formatValue(value);
498
+ }
499
+ catch {
500
+ return String(value);
501
+ }
502
+ }
503
+ return String(value);
504
+ }
505
+ isVertical() {
506
+ return this.orientation === 'vertical';
507
+ }
508
+ /**
509
+ * Returns whether the host renders in RTL. Uses the cached value if a gesture
510
+ * is active (set in startDrag / onTrackPointerDown), otherwise reads
511
+ * getComputedStyle fresh — direction can come from any ancestor's `dir`,
512
+ * so document.dir or our own attribute aren't sufficient.
513
+ */
514
+ isRtl() {
515
+ if (this.rtlDuringGesture !== null)
516
+ return this.rtlDuringGesture;
517
+ return getComputedStyle(this).direction === 'rtl';
518
+ }
519
+ /**
520
+ * Apply the Block + minDistance constraint to a candidate value for thumb i.
521
+ * Returns the candidate clamped between its (already-respected) neighbours.
522
+ */
523
+ constrainThumb(values, i, candidate) {
524
+ const lower = i > 0 ? values[i - 1] + this.minDistance : this.min;
525
+ const upper = i < values.length - 1 ? values[i + 1] - this.minDistance : this.max;
526
+ return Math.min(Math.max(candidate, lower), upper);
527
+ }
528
+ /** Map a pointer coordinate inside the track rect to a value in [min, max]. */
529
+ valueFromPointer(clientX, clientY) {
530
+ const track = this.trackEl ?? this.renderRoot.querySelector('.track');
531
+ if (!track)
532
+ return this.min;
533
+ const rect = track.getBoundingClientRect();
534
+ let pct;
535
+ if (this.isVertical()) {
536
+ pct = (rect.bottom - clientY) / rect.height;
537
+ }
538
+ else if (this.isRtl()) {
539
+ pct = (rect.right - clientX) / rect.width;
540
+ }
541
+ else {
542
+ pct = (clientX - rect.left) / rect.width;
543
+ }
544
+ pct = Math.min(1, Math.max(0, pct));
545
+ const raw = this.min + pct * (this.max - this.min);
546
+ return this.snapToStep(raw);
547
+ }
548
+ /** Update one thumb in-place; emit `value-input`. Returns true if value changed. */
549
+ moveThumb(thumbIndex, candidate) {
550
+ const current = [...this.value];
551
+ const constrained = this.constrainThumb(current, thumbIndex, this.snapToStep(candidate));
552
+ if (constrained === current[thumbIndex])
553
+ return false;
554
+ current[thumbIndex] = constrained;
555
+ this._value = current;
556
+ this.requestUpdate('value');
557
+ this.dispatchEvent(new CustomEvent('value-input', {
558
+ detail: [...current],
559
+ bubbles: true,
560
+ composed: true,
561
+ }));
562
+ return true;
563
+ }
564
+ dispatchValueChange() {
565
+ this.dispatchEvent(new CustomEvent('value-change', {
566
+ detail: [...this.value],
567
+ bubbles: true,
568
+ composed: true,
569
+ }));
570
+ }
571
+ startDrag(thumbIndex, pointerId, target) {
572
+ if (this.disabled)
573
+ return;
574
+ if (this.rtlDuringGesture === null) {
575
+ this.rtlDuringGesture = getComputedStyle(this).direction === 'rtl';
576
+ }
577
+ target.setPointerCapture(pointerId);
578
+ target.focus();
579
+ this.dragState = { thumbIndex, pointerId };
580
+ this.requestUpdate();
581
+ }
582
+ /**
583
+ * Returns the index of the thumb closest to `target`. Ties (multiple thumbs
584
+ * stacked at the same value) are broken by direction: clicks to the right of
585
+ * the stack pick the highest-index thumb, clicks to the left pick the
586
+ * lowest. Without this, a stack would always select the lowest-index thumb,
587
+ * which is blocked by its higher-indexed neighbours and can't move toward
588
+ * the click — the user would see no response.
589
+ */
590
+ nearestThumbIndex(values, target) {
591
+ return values.reduce((best, v, i) => {
592
+ const dBest = Math.abs(values[best] - target);
593
+ const dCur = Math.abs(v - target);
594
+ if (dCur < dBest)
595
+ return i;
596
+ if (dCur > dBest)
597
+ return best;
598
+ // Tie. Prefer the thumb on the side of the target so it can move toward it.
599
+ return target > v ? i : best;
600
+ }, 0);
601
+ }
602
+ /** Return the target value for a key press, or null if the key isn't bound. */
603
+ keyboardTarget(thumbIndex, key) {
604
+ const step = this.step || 1;
605
+ const big = step * 10;
606
+ const current = this.value[thumbIndex];
607
+ const rtl = !this.isVertical() && this.isRtl();
608
+ switch (key) {
609
+ case 'ArrowRight': return current + (rtl ? -step : step);
610
+ case 'ArrowLeft': return current + (rtl ? step : -step);
611
+ case 'ArrowUp': return current + step;
612
+ case 'ArrowDown': return current - step;
613
+ case 'PageUp': return current + big;
614
+ case 'PageDown': return current - big;
615
+ case 'Home': return this.min;
616
+ case 'End': return this.max;
617
+ default: return null;
618
+ }
619
+ }
620
+ render() {
621
+ const values = this.value;
622
+ const vertical = this.isVertical();
623
+ const fills = values.slice(0, -1).map((v, i) => ({
624
+ from: this.percent(v),
625
+ to: this.percent(values[i + 1]),
626
+ }));
627
+ return html `
628
+ <div
629
+ class="track"
630
+ part="track"
631
+ @pointerdown=${this.onTrackPointerDown}
632
+ @pointermove=${this.onPointerMove}
633
+ @pointerup=${this.onPointerUp}
634
+ @pointercancel=${this.onPointerUp}
635
+ >
636
+ ${fills.map(f => this.renderFill(f, vertical))}
637
+ ${values.map((v, i) => this.renderThumb(v, i, vertical))}
638
+ </div>
639
+ `;
640
+ }
641
+ renderFill(segment, vertical) {
642
+ // Use logical `inset-inline-start` so the fill flips correctly in RTL;
643
+ // works as `left` in LTR and `right` in RTL.
644
+ const style = vertical
645
+ ? `bottom: ${segment.from}%; height: ${segment.to - segment.from}%;`
646
+ : `inset-inline-start: ${segment.from}%; width: ${segment.to - segment.from}%;`;
647
+ return html `<div class="fill" part="fill" style=${style}></div>`;
648
+ }
649
+ renderThumb(value, index, vertical) {
650
+ const pct = this.percent(value);
651
+ // Logical `inset-inline-start` so the thumb position flips in RTL.
652
+ const style = vertical ? `bottom: ${pct}%;` : `inset-inline-start: ${pct}%;`;
653
+ const formatted = this.formatThumb(value);
654
+ const isDragging = this.dragState?.thumbIndex === index;
655
+ // aria-valuetext only when formatValue is provided — otherwise aria-valuenow alone is read out.
656
+ const valueText = this.formatValue ? formatted : null;
657
+ return html `
658
+ <button
659
+ class="thumb"
660
+ part="thumb"
661
+ type="button"
662
+ role="slider"
663
+ data-thumb-index=${index}
664
+ data-dragging=${isDragging ? 'true' : 'false'}
665
+ aria-valuemin=${this.min}
666
+ aria-valuemax=${this.max}
667
+ aria-valuenow=${value}
668
+ aria-orientation=${this.orientation}
669
+ aria-valuetext=${valueText ?? nothing}
670
+ ?disabled=${this.disabled}
671
+ style=${style}
672
+ @pointerdown=${(ev) => this.onThumbPointerDown(index, ev)}
673
+ @keydown=${(ev) => this.onThumbKeyDown(index, ev)}
674
+ >
675
+ <span class="tooltip" part="tooltip">${formatted}</span>
676
+ </button>
677
+ `;
678
+ }
679
+ /** Returns a copy of the current values. */
680
+ getValues() {
681
+ return [...this.value];
682
+ }
683
+ }
684
+ if (typeof customElements !== 'undefined' && !customElements.get('mp-multi-range')) {
685
+ customElements.define('mp-multi-range', MintMultiRangeElement);
686
+ }
687
+
688
+ /**
689
+ * Generated bundle index. Do not edit.
690
+ */
691
+
692
+ export { BsMultiRangeComponent, BsMultiRangeValueAccessor, MintMultiRangeElement };
693
+ //# sourceMappingURL=mintplayer-ng-bootstrap-multi-range.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mintplayer-ng-bootstrap-multi-range.mjs","sources":["../../../../libs/mintplayer-ng-bootstrap/multi-range/src/lib/value-accessor/multi-range-value-accessor.ts","../../../../libs/mintplayer-ng-bootstrap/multi-range/src/lib/components/multi-range.component.ts","../../../../libs/mintplayer-ng-bootstrap/multi-range/src/lib/web-components/mint-multi-range.element.template.ts","../../../../libs/mintplayer-ng-bootstrap/multi-range/src/lib/web-components/mint-multi-range.element.ts","../../../../libs/mintplayer-ng-bootstrap/multi-range/mintplayer-ng-bootstrap-multi-range.ts"],"sourcesContent":["import { Directive, forwardRef, inject } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { BsMultiRangeComponent } from '../components/multi-range.component';\n\n@Directive({\n selector: 'bs-multi-range',\n providers: [{\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => BsMultiRangeValueAccessor),\n multi: true,\n }],\n host: {\n '(value-input)': 'onInputEvent($event)',\n '(value-change)': 'onTouchEvent()',\n },\n})\nexport class BsMultiRangeValueAccessor implements ControlValueAccessor {\n private host = inject(BsMultiRangeComponent);\n\n private onValueChange?: (value: number[]) => void;\n private onTouched?: () => void;\n\n protected onInputEvent(ev: Event) {\n if (!this.onValueChange) return;\n const detail = (ev as CustomEvent<number[]>).detail;\n if (detail) this.onValueChange([...detail]);\n }\n\n protected onTouchEvent() {\n if (this.onTouched) this.onTouched();\n }\n\n registerOnChange(fn: (value: number[]) => void) {\n this.onValueChange = fn;\n }\n\n registerOnTouched(fn: () => void) {\n this.onTouched = fn;\n }\n\n writeValue(value: number[] | null | undefined) {\n const ref = this.host.elementRef();\n if (!ref) return;\n ref.nativeElement.value = value ?? [];\n }\n\n setDisabledState(isDisabled: boolean) {\n const ref = this.host.elementRef();\n if (!ref) return;\n if (isDisabled) {\n ref.nativeElement.setAttribute('disabled', '');\n } else {\n ref.nativeElement.removeAttribute('disabled');\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n CUSTOM_ELEMENTS_SCHEMA,\n ElementRef,\n computed,\n effect,\n input,\n model,\n output,\n viewChild,\n} from '@angular/core';\nimport { MintMultiRangeElement } from '../web-components/mint-multi-range.element';\nimport { BsMultiRangeValueAccessor } from '../value-accessor/multi-range-value-accessor';\nimport { MultiRangeOrientation } from '../types/multi-range-orientation';\n\n@Component({\n selector: 'bs-multi-range',\n template: `\n <mp-multi-range\n #el\n class=\"bs-multi-range\"\n [attr.min]=\"min()\"\n [attr.max]=\"max()\"\n [attr.step]=\"step()\"\n [attr.min-distance]=\"minDistance()\"\n [attr.orientation]=\"orientation()\"\n [attr.disabled]=\"disabledAttr()\"\n [attr.aria-label]=\"label()\"\n (value-input)=\"onValueInput($event)\"\n (value-change)=\"onValueChange($event)\"\n ></mp-multi-range>\n `,\n styles: [`\n :host { display: block; width: 100%; }\n .bs-multi-range { display: block; width: 100%; height: 100%; }\n :host([orientation='vertical']) { width: auto; height: 100%; }\n `],\n host: {\n '[attr.orientation]': 'orientation()',\n },\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n changeDetection: ChangeDetectionStrategy.OnPush,\n hostDirectives: [BsMultiRangeValueAccessor],\n})\nexport class BsMultiRangeComponent {\n readonly min = input(0);\n readonly max = input(100);\n readonly step = input(1);\n readonly minDistance = input(0);\n readonly orientation = input<MultiRangeOrientation>('horizontal');\n readonly disabled = input(false);\n readonly formatValue = input<((value: number) => string) | null>(null);\n readonly label = input<string | null>(null);\n\n // Default is `undefined` so the effect doesn't clobber a writeValue() from a\n // form-control binding that hasn't fired yet. Once the model is set (either\n // by [(value)] binding or by user interaction), the effect drives the WC.\n readonly value = model<number[] | undefined>(undefined);\n\n readonly valueChange = output<number[]>();\n readonly valueInput = output<number[]>();\n\n readonly elementRef = viewChild.required<ElementRef<MintMultiRangeElement>>('el');\n\n protected readonly disabledAttr = computed(() => (this.disabled() ? '' : null));\n\n constructor() {\n effect(() => {\n const ref = this.elementRef();\n if (!ref) return;\n const v = this.value();\n if (v === undefined) return;\n ref.nativeElement.value = v;\n });\n effect(() => {\n const ref = this.elementRef();\n if (!ref) return;\n ref.nativeElement.formatValue = this.formatValue();\n });\n }\n\n protected onValueInput(event: Event): void {\n const detail = (event as CustomEvent<number[]>).detail;\n if (!detail) return;\n this.value.set(detail);\n this.valueInput.emit(detail);\n }\n\n protected onValueChange(event: Event): void {\n const detail = (event as CustomEvent<number[]>).detail;\n if (!detail) return;\n this.value.set(detail);\n this.valueChange.emit(detail);\n }\n\n /** Imperatively read the currently-rendered values from the WC. */\n getValues(): number[] {\n const ref = this.elementRef();\n return ref ? ref.nativeElement.getValues() : [];\n }\n}\n","// AUTO-GENERATED — do not edit by hand.\n// Source: mint-multi-range.element.html + mint-multi-range.element.scss\n// Regenerate with the codegen-wc Nx target.\n\nimport { html, unsafeCSS } from 'lit';\n\nexport const template = html`<!-- Track + thumbs are rendered dynamically by render(). This file exists so the\n codegen-wc target produces a \\`styles\\` export from the sibling .scss; the\n \\`template\\` export it generates here is intentionally unused. -->`;\nexport const styles = unsafeCSS(`:host {\n display: block;\n position: relative;\n box-sizing: border-box;\n width: 100%;\n --bs-multi-range-track-bg: var(--bs-tertiary-bg, #e9ecef);\n --bs-multi-range-track-radius: 1rem;\n --bs-multi-range-track-thickness: 0.5rem;\n --bs-multi-range-thumb-bg: var(--bs-primary, #0d6efd);\n --bs-multi-range-thumb-bg-disabled: var(--bs-secondary, #6c757d);\n --bs-multi-range-thumb-size: 1rem;\n --bs-multi-range-thumb-shadow: 0 0.1rem 0.25rem rgba(0, 0, 0, 0.1);\n --bs-multi-range-fill-bg: var(--bs-primary, #0d6efd);\n --bs-multi-range-fill-bg-disabled: var(--bs-secondary, #6c757d);\n --bs-multi-range-tooltip-bg: var(--bs-dark, #212529);\n --bs-multi-range-tooltip-color: var(--bs-light, #f8f9fa);\n}\n\n:host([orientation=vertical]) {\n width: auto;\n height: 100%;\n min-height: 8rem;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.track {\n position: relative;\n background: var(--bs-multi-range-track-bg);\n border-radius: var(--bs-multi-range-track-radius);\n touch-action: none;\n}\n\n:host([orientation=horizontal]) .track {\n width: 100%;\n height: var(--bs-multi-range-track-thickness);\n margin: calc(var(--bs-multi-range-thumb-size) / 2) 0;\n}\n\n:host([orientation=vertical]) .track {\n width: var(--bs-multi-range-track-thickness);\n height: 100%;\n margin: 0 calc(var(--bs-multi-range-thumb-size) / 2);\n}\n\n.fill {\n position: absolute;\n background: var(--bs-multi-range-fill-bg);\n border-radius: var(--bs-multi-range-track-radius);\n}\n\n:host([orientation=horizontal]) .fill {\n top: 0;\n bottom: 0;\n}\n\n:host([orientation=vertical]) .fill {\n left: 0;\n right: 0;\n}\n\n:host([disabled]) .fill {\n background: var(--bs-multi-range-fill-bg-disabled);\n}\n\n.thumb {\n position: absolute;\n width: var(--bs-multi-range-thumb-size);\n height: var(--bs-multi-range-thumb-size);\n background: var(--bs-multi-range-thumb-bg);\n border: 0;\n border-radius: 50%;\n box-shadow: var(--bs-multi-range-thumb-shadow);\n cursor: grab;\n touch-action: none;\n padding: 0;\n outline: none;\n transition: transform 100ms ease-out;\n}\n\n.thumb:active {\n cursor: grabbing;\n transform: scale(1.1);\n}\n\n:host([orientation=horizontal]) .thumb {\n top: 50%;\n transform: translate(-50%, -50%);\n}\n\n:host([orientation=horizontal]) .thumb:active {\n transform: translate(-50%, -50%) scale(1.1);\n}\n\n:host([orientation=horizontal]:dir(rtl)) .thumb {\n transform: translate(50%, -50%);\n}\n\n:host([orientation=horizontal]:dir(rtl)) .thumb:active {\n transform: translate(50%, -50%) scale(1.1);\n}\n\n:host([orientation=vertical]) .thumb {\n left: 50%;\n transform: translate(-50%, 50%);\n}\n\n:host([orientation=vertical]) .thumb:active {\n transform: translate(-50%, 50%) scale(1.1);\n}\n\n:host([disabled]) .thumb {\n background: var(--bs-multi-range-thumb-bg-disabled);\n cursor: not-allowed;\n}\n\n.thumb:focus-visible {\n box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.35), var(--bs-multi-range-thumb-shadow);\n}\n\n.tooltip {\n position: absolute;\n background: var(--bs-multi-range-tooltip-bg);\n color: var(--bs-multi-range-tooltip-color);\n font-size: 0.75rem;\n font-weight: 500;\n line-height: 1;\n padding: 0.25rem 0.5rem;\n border-radius: 0.25rem;\n pointer-events: none;\n white-space: nowrap;\n opacity: 0;\n transition: opacity 120ms ease-out;\n z-index: 2;\n}\n\n:host([orientation=horizontal]) .tooltip {\n bottom: calc(100% + 0.5rem);\n left: 50%;\n transform: translateX(-50%);\n}\n\n:host([orientation=vertical]) .tooltip {\n left: calc(100% + 0.5rem);\n top: 50%;\n transform: translateY(-50%);\n}\n\n.thumb:hover .tooltip,\n.thumb:focus-visible .tooltip,\n.thumb:active .tooltip,\n.thumb[data-dragging=true] .tooltip {\n opacity: 1;\n}\n\n:host([disabled]) .tooltip {\n display: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .thumb,\n .tooltip {\n transition: none;\n }\n}`);\n","import { LitElement, html, nothing, type TemplateResult } from 'lit';\nimport { styles } from './mint-multi-range.element.template';\nimport { MultiRangeOrientation } from '../types/multi-range-orientation';\n\n/**\n * Bootstrap-flavoured multi-thumb range slider.\n *\n * Block-crossing: thumbs cannot pass their neighbours. Identity is by index —\n * value[0] is always the lowest thumb. The value setter normalises input by\n * sorting ascending and clamping each entry to [min, max]; minDistance is\n * enforced only at user-interaction entry points (pointer + keyboard), not on\n * programmatic writes — callers' arrays are preserved verbatim within bounds.\n *\n * Events:\n * - `value-input` fires continuously during drag and on every keyboard step.\n * - `value-change` fires on commit (pointerup) and after every keyboard step.\n *\n * Both bubble and compose so the Angular wrapper's host listeners pick them up.\n */\nexport class MintMultiRangeElement extends LitElement {\n static override styles = [styles];\n\n static override get observedAttributes(): string[] {\n return [\n ...(super.observedAttributes ?? []),\n 'min',\n 'max',\n 'step',\n 'min-distance',\n 'orientation',\n 'disabled',\n ];\n }\n\n static override properties = {\n value: { attribute: false },\n min: { attribute: 'min', type: Number, reflect: true },\n max: { attribute: 'max', type: Number, reflect: true },\n step: { attribute: 'step', type: Number, reflect: true },\n minDistance: { attribute: 'min-distance', type: Number },\n orientation: { attribute: 'orientation', type: String, reflect: true },\n disabled: { attribute: 'disabled', type: Boolean, reflect: true },\n formatValue: { attribute: false },\n };\n\n min = 0;\n max = 100;\n step = 1;\n minDistance = 0;\n orientation: MultiRangeOrientation = 'horizontal';\n disabled = false;\n formatValue: ((value: number) => string) | null = null;\n\n private _value: number[] | null = null;\n private dragState: { thumbIndex: number; pointerId: number } | null = null;\n\n // Cached references / state to keep the per-pointermove path off the hot path\n // for getComputedStyle and querySelector. Track ref is set in firstUpdated()\n // and is stable across renders. RTL is captured at gesture start so a single\n // drag stream sees a coherent direction even if the host's `dir` changes mid-air.\n private trackEl: HTMLElement | null = null;\n private rtlDuringGesture: boolean | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) this.setAttribute('role', 'group');\n }\n\n protected override firstUpdated(): void {\n this.trackEl = this.renderRoot.querySelector<HTMLElement>('.track');\n }\n\n get value(): number[] {\n return this._value ?? [this.min, this.max];\n }\n\n set value(next: number[] | null | undefined) {\n const old = this._value;\n const normalised = this.normalise(next);\n // Skip the update entirely when the incoming array is shallow-equal to the\n // current state — the wrapper's effect re-pushes the value on every\n // value-input event during a drag, so without this we'd queue a redundant\n // Lit update for every pointermove.\n if (this.arraysEqual(old, normalised)) return;\n this._value = normalised;\n this.requestUpdate('value', old);\n }\n\n private arraysEqual(a: number[] | null, b: number[] | null): boolean {\n if (a === b) return true;\n if (a === null || b === null) return false;\n if (a.length !== b.length) return false;\n return a.every((v, i) => v === b[i]);\n }\n\n private normalise(input: number[] | null | undefined): number[] | null {\n if (!input || input.length === 0) return null;\n const clamped = input.map(v => this.clampToBounds(v));\n return [...clamped].sort((a, b) => a - b);\n }\n\n private clampToBounds(v: number): number {\n return Math.min(this.max, Math.max(this.min, v));\n }\n\n private snapToStep(v: number): number {\n if (!this.step || this.step <= 0) return this.clampToBounds(v);\n const snapped = this.min + Math.round((v - this.min) / this.step) * this.step;\n return this.clampToBounds(snapped);\n }\n\n private percent(value: number): number {\n const range = this.max - this.min;\n if (range <= 0) return 0;\n return ((value - this.min) / range) * 100;\n }\n\n private formatThumb(value: number): string {\n if (this.formatValue) {\n try { return this.formatValue(value); } catch { return String(value); }\n }\n return String(value);\n }\n\n private isVertical(): boolean {\n return this.orientation === 'vertical';\n }\n\n /**\n * Returns whether the host renders in RTL. Uses the cached value if a gesture\n * is active (set in startDrag / onTrackPointerDown), otherwise reads\n * getComputedStyle fresh — direction can come from any ancestor's `dir`,\n * so document.dir or our own attribute aren't sufficient.\n */\n private isRtl(): boolean {\n if (this.rtlDuringGesture !== null) return this.rtlDuringGesture;\n return getComputedStyle(this).direction === 'rtl';\n }\n\n /**\n * Apply the Block + minDistance constraint to a candidate value for thumb i.\n * Returns the candidate clamped between its (already-respected) neighbours.\n */\n private constrainThumb(values: number[], i: number, candidate: number): number {\n const lower = i > 0 ? values[i - 1] + this.minDistance : this.min;\n const upper = i < values.length - 1 ? values[i + 1] - this.minDistance : this.max;\n return Math.min(Math.max(candidate, lower), upper);\n }\n\n /** Map a pointer coordinate inside the track rect to a value in [min, max]. */\n private valueFromPointer(clientX: number, clientY: number): number {\n const track = this.trackEl ?? this.renderRoot.querySelector<HTMLElement>('.track');\n if (!track) return this.min;\n const rect = track.getBoundingClientRect();\n let pct: number;\n if (this.isVertical()) {\n pct = (rect.bottom - clientY) / rect.height;\n } else if (this.isRtl()) {\n pct = (rect.right - clientX) / rect.width;\n } else {\n pct = (clientX - rect.left) / rect.width;\n }\n pct = Math.min(1, Math.max(0, pct));\n const raw = this.min + pct * (this.max - this.min);\n return this.snapToStep(raw);\n }\n\n /** Update one thumb in-place; emit `value-input`. Returns true if value changed. */\n private moveThumb(thumbIndex: number, candidate: number): boolean {\n const current = [...this.value];\n const constrained = this.constrainThumb(current, thumbIndex, this.snapToStep(candidate));\n if (constrained === current[thumbIndex]) return false;\n current[thumbIndex] = constrained;\n this._value = current;\n this.requestUpdate('value');\n this.dispatchEvent(new CustomEvent<number[]>('value-input', {\n detail: [...current],\n bubbles: true,\n composed: true,\n }));\n return true;\n }\n\n private dispatchValueChange(): void {\n this.dispatchEvent(new CustomEvent<number[]>('value-change', {\n detail: [...this.value],\n bubbles: true,\n composed: true,\n }));\n }\n\n private startDrag(thumbIndex: number, pointerId: number, target: HTMLElement): void {\n if (this.disabled) return;\n if (this.rtlDuringGesture === null) {\n this.rtlDuringGesture = getComputedStyle(this).direction === 'rtl';\n }\n target.setPointerCapture(pointerId);\n target.focus();\n this.dragState = { thumbIndex, pointerId };\n this.requestUpdate();\n }\n\n private onThumbPointerDown = (thumbIndex: number, ev: PointerEvent): void => {\n if (this.disabled) return;\n this.startDrag(thumbIndex, ev.pointerId, ev.currentTarget as HTMLElement);\n };\n\n private onTrackPointerDown = (ev: PointerEvent): void => {\n if (this.disabled) return;\n // Ignore clicks that originated on a thumb — those are handled by the thumb's own pointerdown.\n const path = ev.composedPath();\n if (path.some(node => node instanceof HTMLElement && node.classList?.contains('thumb'))) return;\n // Capture direction up-front so the first valueFromPointer / nearest-thumb\n // calculation in this gesture sees a consistent value.\n this.rtlDuringGesture = getComputedStyle(this).direction === 'rtl';\n const targetValue = this.valueFromPointer(ev.clientX, ev.clientY);\n const values = this.value;\n const nearestIndex = this.nearestThumbIndex(values, targetValue);\n if (this.moveThumb(nearestIndex, targetValue)) this.dispatchValueChange();\n // Transfer drag to the nearest thumb so a continued press-and-drag keeps moving it.\n const thumbEl = this.renderRoot.querySelector<HTMLElement>(\n `.thumb[data-thumb-index=\"${nearestIndex}\"]`,\n );\n if (thumbEl) this.startDrag(nearestIndex, ev.pointerId, thumbEl);\n };\n\n /**\n * Returns the index of the thumb closest to `target`. Ties (multiple thumbs\n * stacked at the same value) are broken by direction: clicks to the right of\n * the stack pick the highest-index thumb, clicks to the left pick the\n * lowest. Without this, a stack would always select the lowest-index thumb,\n * which is blocked by its higher-indexed neighbours and can't move toward\n * the click — the user would see no response.\n */\n private nearestThumbIndex(values: number[], target: number): number {\n return values.reduce((best, v, i) => {\n const dBest = Math.abs(values[best] - target);\n const dCur = Math.abs(v - target);\n if (dCur < dBest) return i;\n if (dCur > dBest) return best;\n // Tie. Prefer the thumb on the side of the target so it can move toward it.\n return target > v ? i : best;\n }, 0);\n }\n\n private onPointerMove = (ev: PointerEvent): void => {\n if (!this.dragState || ev.pointerId !== this.dragState.pointerId) return;\n const candidate = this.valueFromPointer(ev.clientX, ev.clientY);\n this.moveThumb(this.dragState.thumbIndex, candidate);\n };\n\n private onPointerUp = (ev: PointerEvent): void => {\n if (!this.dragState || ev.pointerId !== this.dragState.pointerId) return;\n const target = ev.target as HTMLElement | null;\n if (target?.releasePointerCapture && target.hasPointerCapture(ev.pointerId)) {\n target.releasePointerCapture(ev.pointerId);\n }\n this.dragState = null;\n this.rtlDuringGesture = null;\n this.requestUpdate();\n this.dispatchValueChange();\n };\n\n private onThumbKeyDown = (thumbIndex: number, ev: KeyboardEvent): void => {\n if (this.disabled) return;\n const target = this.keyboardTarget(thumbIndex, ev.key);\n if (target === null) return;\n ev.preventDefault();\n if (this.moveThumb(thumbIndex, target)) this.dispatchValueChange();\n };\n\n /** Return the target value for a key press, or null if the key isn't bound. */\n private keyboardTarget(thumbIndex: number, key: string): number | null {\n const step = this.step || 1;\n const big = step * 10;\n const current = this.value[thumbIndex];\n const rtl = !this.isVertical() && this.isRtl();\n switch (key) {\n case 'ArrowRight': return current + (rtl ? -step : step);\n case 'ArrowLeft': return current + (rtl ? step : -step);\n case 'ArrowUp': return current + step;\n case 'ArrowDown': return current - step;\n case 'PageUp': return current + big;\n case 'PageDown': return current - big;\n case 'Home': return this.min;\n case 'End': return this.max;\n default: return null;\n }\n }\n\n protected override render(): TemplateResult {\n const values = this.value;\n const vertical = this.isVertical();\n const fills = values.slice(0, -1).map((v, i) => ({\n from: this.percent(v),\n to: this.percent(values[i + 1]),\n }));\n\n return html`\n <div\n class=\"track\"\n part=\"track\"\n @pointerdown=${this.onTrackPointerDown}\n @pointermove=${this.onPointerMove}\n @pointerup=${this.onPointerUp}\n @pointercancel=${this.onPointerUp}\n >\n ${fills.map(f => this.renderFill(f, vertical))}\n ${values.map((v, i) => this.renderThumb(v, i, vertical))}\n </div>\n `;\n }\n\n private renderFill(\n segment: { from: number; to: number },\n vertical: boolean,\n ): TemplateResult {\n // Use logical `inset-inline-start` so the fill flips correctly in RTL;\n // works as `left` in LTR and `right` in RTL.\n const style = vertical\n ? `bottom: ${segment.from}%; height: ${segment.to - segment.from}%;`\n : `inset-inline-start: ${segment.from}%; width: ${segment.to - segment.from}%;`;\n return html`<div class=\"fill\" part=\"fill\" style=${style}></div>`;\n }\n\n private renderThumb(value: number, index: number, vertical: boolean): TemplateResult {\n const pct = this.percent(value);\n // Logical `inset-inline-start` so the thumb position flips in RTL.\n const style = vertical ? `bottom: ${pct}%;` : `inset-inline-start: ${pct}%;`;\n const formatted = this.formatThumb(value);\n const isDragging = this.dragState?.thumbIndex === index;\n // aria-valuetext only when formatValue is provided — otherwise aria-valuenow alone is read out.\n const valueText = this.formatValue ? formatted : null;\n return html`\n <button\n class=\"thumb\"\n part=\"thumb\"\n type=\"button\"\n role=\"slider\"\n data-thumb-index=${index}\n data-dragging=${isDragging ? 'true' : 'false'}\n aria-valuemin=${this.min}\n aria-valuemax=${this.max}\n aria-valuenow=${value}\n aria-orientation=${this.orientation}\n aria-valuetext=${valueText ?? nothing}\n ?disabled=${this.disabled}\n style=${style}\n @pointerdown=${(ev: PointerEvent) => this.onThumbPointerDown(index, ev)}\n @keydown=${(ev: KeyboardEvent) => this.onThumbKeyDown(index, ev)}\n >\n <span class=\"tooltip\" part=\"tooltip\">${formatted}</span>\n </button>\n `;\n }\n\n /** Returns a copy of the current values. */\n getValues(): number[] {\n return [...this.value];\n }\n}\n\nif (typeof customElements !== 'undefined' && !customElements.get('mp-multi-range')) {\n customElements.define('mp-multi-range', MintMultiRangeElement);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mp-multi-range': MintMultiRangeElement;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.BsMultiRangeValueAccessor"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mintplayer/ng-bootstrap",
3
3
  "private": false,
4
- "version": "21.29.0",
4
+ "version": "21.30.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/MintPlayer/mintplayer-ng-bootstrap",
@@ -184,6 +184,10 @@
184
184
  "types": "./types/mintplayer-ng-bootstrap-modal.d.ts",
185
185
  "default": "./fesm2022/mintplayer-ng-bootstrap-modal.mjs"
186
186
  },
187
+ "./multi-range": {
188
+ "types": "./types/mintplayer-ng-bootstrap-multi-range.d.ts",
189
+ "default": "./fesm2022/mintplayer-ng-bootstrap-multi-range.mjs"
190
+ },
187
191
  "./multiselect": {
188
192
  "types": "./types/mintplayer-ng-bootstrap-multiselect.d.ts",
189
193
  "default": "./fesm2022/mintplayer-ng-bootstrap-multiselect.mjs"
@@ -0,0 +1,170 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { ElementRef } from '@angular/core';
3
+ import * as lit from 'lit';
4
+ import { LitElement, TemplateResult } from 'lit';
5
+ import { ControlValueAccessor } from '@angular/forms';
6
+
7
+ type MultiRangeOrientation = 'horizontal' | 'vertical';
8
+
9
+ /**
10
+ * Bootstrap-flavoured multi-thumb range slider.
11
+ *
12
+ * Block-crossing: thumbs cannot pass their neighbours. Identity is by index —
13
+ * value[0] is always the lowest thumb. The value setter normalises input by
14
+ * sorting ascending and clamping each entry to [min, max]; minDistance is
15
+ * enforced only at user-interaction entry points (pointer + keyboard), not on
16
+ * programmatic writes — callers' arrays are preserved verbatim within bounds.
17
+ *
18
+ * Events:
19
+ * - `value-input` fires continuously during drag and on every keyboard step.
20
+ * - `value-change` fires on commit (pointerup) and after every keyboard step.
21
+ *
22
+ * Both bubble and compose so the Angular wrapper's host listeners pick them up.
23
+ */
24
+ declare class MintMultiRangeElement extends LitElement {
25
+ static styles: lit.CSSResult[];
26
+ static get observedAttributes(): string[];
27
+ static properties: {
28
+ value: {
29
+ attribute: boolean;
30
+ };
31
+ min: {
32
+ attribute: string;
33
+ type: NumberConstructor;
34
+ reflect: boolean;
35
+ };
36
+ max: {
37
+ attribute: string;
38
+ type: NumberConstructor;
39
+ reflect: boolean;
40
+ };
41
+ step: {
42
+ attribute: string;
43
+ type: NumberConstructor;
44
+ reflect: boolean;
45
+ };
46
+ minDistance: {
47
+ attribute: string;
48
+ type: NumberConstructor;
49
+ };
50
+ orientation: {
51
+ attribute: string;
52
+ type: StringConstructor;
53
+ reflect: boolean;
54
+ };
55
+ disabled: {
56
+ attribute: string;
57
+ type: BooleanConstructor;
58
+ reflect: boolean;
59
+ };
60
+ formatValue: {
61
+ attribute: boolean;
62
+ };
63
+ };
64
+ min: number;
65
+ max: number;
66
+ step: number;
67
+ minDistance: number;
68
+ orientation: MultiRangeOrientation;
69
+ disabled: boolean;
70
+ formatValue: ((value: number) => string) | null;
71
+ private _value;
72
+ private dragState;
73
+ private trackEl;
74
+ private rtlDuringGesture;
75
+ connectedCallback(): void;
76
+ protected firstUpdated(): void;
77
+ get value(): number[];
78
+ set value(next: number[] | null | undefined);
79
+ private arraysEqual;
80
+ private normalise;
81
+ private clampToBounds;
82
+ private snapToStep;
83
+ private percent;
84
+ private formatThumb;
85
+ private isVertical;
86
+ /**
87
+ * Returns whether the host renders in RTL. Uses the cached value if a gesture
88
+ * is active (set in startDrag / onTrackPointerDown), otherwise reads
89
+ * getComputedStyle fresh — direction can come from any ancestor's `dir`,
90
+ * so document.dir or our own attribute aren't sufficient.
91
+ */
92
+ private isRtl;
93
+ /**
94
+ * Apply the Block + minDistance constraint to a candidate value for thumb i.
95
+ * Returns the candidate clamped between its (already-respected) neighbours.
96
+ */
97
+ private constrainThumb;
98
+ /** Map a pointer coordinate inside the track rect to a value in [min, max]. */
99
+ private valueFromPointer;
100
+ /** Update one thumb in-place; emit `value-input`. Returns true if value changed. */
101
+ private moveThumb;
102
+ private dispatchValueChange;
103
+ private startDrag;
104
+ private onThumbPointerDown;
105
+ private onTrackPointerDown;
106
+ /**
107
+ * Returns the index of the thumb closest to `target`. Ties (multiple thumbs
108
+ * stacked at the same value) are broken by direction: clicks to the right of
109
+ * the stack pick the highest-index thumb, clicks to the left pick the
110
+ * lowest. Without this, a stack would always select the lowest-index thumb,
111
+ * which is blocked by its higher-indexed neighbours and can't move toward
112
+ * the click — the user would see no response.
113
+ */
114
+ private nearestThumbIndex;
115
+ private onPointerMove;
116
+ private onPointerUp;
117
+ private onThumbKeyDown;
118
+ /** Return the target value for a key press, or null if the key isn't bound. */
119
+ private keyboardTarget;
120
+ protected render(): TemplateResult;
121
+ private renderFill;
122
+ private renderThumb;
123
+ /** Returns a copy of the current values. */
124
+ getValues(): number[];
125
+ }
126
+ declare global {
127
+ interface HTMLElementTagNameMap {
128
+ 'mp-multi-range': MintMultiRangeElement;
129
+ }
130
+ }
131
+
132
+ declare class BsMultiRangeValueAccessor implements ControlValueAccessor {
133
+ private host;
134
+ private onValueChange?;
135
+ private onTouched?;
136
+ protected onInputEvent(ev: Event): void;
137
+ protected onTouchEvent(): void;
138
+ registerOnChange(fn: (value: number[]) => void): void;
139
+ registerOnTouched(fn: () => void): void;
140
+ writeValue(value: number[] | null | undefined): void;
141
+ setDisabledState(isDisabled: boolean): void;
142
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<BsMultiRangeValueAccessor, never>;
143
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BsMultiRangeValueAccessor, "bs-multi-range", never, {}, {}, never, never, true, never>;
144
+ }
145
+
146
+ declare class BsMultiRangeComponent {
147
+ readonly min: _angular_core.InputSignal<number>;
148
+ readonly max: _angular_core.InputSignal<number>;
149
+ readonly step: _angular_core.InputSignal<number>;
150
+ readonly minDistance: _angular_core.InputSignal<number>;
151
+ readonly orientation: _angular_core.InputSignal<MultiRangeOrientation>;
152
+ readonly disabled: _angular_core.InputSignal<boolean>;
153
+ readonly formatValue: _angular_core.InputSignal<((value: number) => string) | null>;
154
+ readonly label: _angular_core.InputSignal<string | null>;
155
+ readonly value: _angular_core.ModelSignal<number[] | undefined>;
156
+ readonly valueChange: _angular_core.OutputEmitterRef<number[]>;
157
+ readonly valueInput: _angular_core.OutputEmitterRef<number[]>;
158
+ readonly elementRef: _angular_core.Signal<ElementRef<MintMultiRangeElement>>;
159
+ protected readonly disabledAttr: _angular_core.Signal<"" | null>;
160
+ constructor();
161
+ protected onValueInput(event: Event): void;
162
+ protected onValueChange(event: Event): void;
163
+ /** Imperatively read the currently-rendered values from the WC. */
164
+ getValues(): number[];
165
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<BsMultiRangeComponent, never>;
166
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<BsMultiRangeComponent, "bs-multi-range", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "minDistance": { "alias": "minDistance"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "formatValue": { "alias": "formatValue"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "valueChange": "valueChange"; "valueInput": "valueInput"; }, never, never, true, [{ directive: typeof BsMultiRangeValueAccessor; inputs: {}; outputs: {}; }]>;
167
+ }
168
+
169
+ export { BsMultiRangeComponent, BsMultiRangeValueAccessor, MintMultiRangeElement };
170
+ export type { MultiRangeOrientation };