@ruc-lib/knob 2.0.0 → 3.1.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.
@@ -1,622 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { EventEmitter, forwardRef, Component, ViewChild, Output, Input, HostListener, NgModule } from '@angular/core';
3
- import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import { NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
6
- import * as i2 from '@angular/material/button';
7
- import { MatButtonModule } from '@angular/material/button';
8
- import * as i3 from '@angular/material/icon';
9
- import { MatIconModule } from '@angular/material/icon';
10
-
11
- const DefaultKnobConfig = {
12
- min: 0,
13
- max: 100,
14
- step: 1,
15
- size: 150,
16
- valueColor: '',
17
- strokeBackground: 'lightblue',
18
- progressBackground: 'blue',
19
- strokeWidth: 15,
20
- valueSize: 20,
21
- valueWeight: 'normal',
22
- showHandle: true,
23
- handleBackground: 'lightblue',
24
- handleBorderColor: 'blue',
25
- handleBorderWidth: 4,
26
- roundedCorner: true,
27
- valuePrefix: '',
28
- valueSuffix: '',
29
- readOnly: false,
30
- disabled: false,
31
- enableTooltip: false,
32
- animateOnHover: false,
33
- isRangeMode: false,
34
- rangeStartValue: 25,
35
- rangeEndValue: 75,
36
- showButtons: false,
37
- knobType: 'arc' // 'horizontal' | 'vertical' | 'arc'
38
- };
39
- const DEFAULT_LABELS = {
40
- incrementButton: 'Increment Value',
41
- decrementButton: 'Decrement Value'
42
- };
43
-
44
- class RuclibKnobComponent {
45
- constructor(cdr) {
46
- this.cdr = cdr;
47
- this.rucEvent = new EventEmitter();
48
- this.customTheme = '';
49
- this.activeHandle = '';
50
- this.value = 0;
51
- this.dragging = false;
52
- this.centerX = 0;
53
- this.centerY = 0;
54
- this.radius = 0;
55
- this.startAngle = 210;
56
- this.endAngle = 510;
57
- this.arcLength = 300;
58
- this.changeColorAfter = 0;
59
- this.tooltipX = 0;
60
- this.tooltipY = 0;
61
- this.showTooltip = false;
62
- this.hovering = false;
63
- this.config = DefaultKnobConfig;
64
- this.onTouched = () => { };
65
- this.onChange = (value) => { };
66
- }
67
- /**
68
- * handling form control binding to write value
69
- * @param val
70
- */
71
- writeValue(val) {
72
- this.value = val;
73
- }
74
- /**
75
- * registering onChange method to use as form control
76
- * @param fn
77
- */
78
- registerOnChange(fn) {
79
- this.onChange = fn;
80
- }
81
- /**
82
- * registering onTouch method to use as form control
83
- * @param fn
84
- */
85
- registerOnTouched(fn) {
86
- this.onTouched = fn;
87
- }
88
- /**
89
- * registering disabled state
90
- * @param isDisabled
91
- */
92
- setDisabledState(isDisabled) {
93
- this.config.disabled = isDisabled;
94
- }
95
- /**
96
- * handling input data changes
97
- * updating default config with user provided config
98
- * @param changes
99
- */
100
- ngOnChanges(changes) {
101
- if (changes && changes['rucInputData'] && changes['rucInputData'].currentValue) {
102
- this.config = Object.assign(Object.assign({}, this.config), changes['rucInputData'].currentValue);
103
- }
104
- }
105
- /**
106
- * handling change on component initilization
107
- */
108
- ngOnInit() {
109
- this.adjustDefaultValue();
110
- if (this.config.knobType != 'arc') {
111
- this.config.isRangeMode = false;
112
- this.config.enableTooltip = false;
113
- }
114
- if (Array.isArray(this.config.progressBackground)) {
115
- this.changeColorAfter = Math.round(100 / this.config.progressBackground.length);
116
- }
117
- }
118
- /**
119
- * handling change after view initilization
120
- */
121
- ngAfterViewInit() {
122
- var _a;
123
- this.centerX = this.config.size / 2;
124
- this.centerY = this.config.size / 2;
125
- this.radius = this.config.size / 2 - 20;
126
- (_a = this.bgArcRef) === null || _a === void 0 ? void 0 : _a.nativeElement.setAttribute('d', this.describeArc(this.centerX, this.centerY, this.radius, this.startAngle, this.endAngle));
127
- this.updateArc();
128
- this.cdr.detectChanges();
129
- }
130
- /**
131
- * handling change when dragin on svg
132
- * @returns
133
- */
134
- startDrag() {
135
- if (this.config.disabled || this.config.readOnly)
136
- return;
137
- this.dragging = true;
138
- this.showTooltip = true;
139
- this.rucEvent.emit({ eventName: 'dragStart', eventOutput: { value: this.getEventOutput() } });
140
- }
141
- /**
142
- * rounding value to increment or decrement based on provide config value for step
143
- * @param value
144
- * @returns
145
- */
146
- roundToStep(value) {
147
- const stepped = Math.round((value - this.config.min) / this.config.step) * this.config.step + this.config.min;
148
- return this.clamp(stepped, this.config.min, this.config.max);
149
- }
150
- /**
151
- * adjusting default value within min & max value when its provide out of range
152
- */
153
- adjustDefaultValue() {
154
- if (this.value < this.config.min) {
155
- this.value = this.config.min;
156
- }
157
- if (this.value > this.config.max) {
158
- this.value = this.config.max;
159
- }
160
- if (this.config.isRangeMode) {
161
- if (this.config.rangeStartValue < this.config.min || this.config.rangeStartValue > this.config.max) {
162
- this.config.rangeStartValue = this.config.min;
163
- }
164
- if (this.config.rangeEndValue > this.config.max || this.config.rangeEndValue < this.config.min) {
165
- this.config.rangeEndValue = this.config.max;
166
- }
167
- }
168
- this.updateArc();
169
- }
170
- /**
171
- * handle changes on mouseUp and touchEnd event
172
- */
173
- stopDrag() {
174
- this.dragging = false;
175
- this.showTooltip = false;
176
- this.rucEvent.emit({ eventName: 'dragEnd', eventOutput: { value: this.getEventOutput() } });
177
- }
178
- /**
179
- * handle changes on mouseMove and touch event
180
- * @param event
181
- * @returns
182
- */
183
- onMove(event) {
184
- if (this.config.disabled || this.config.readOnly || !this.dragging)
185
- return;
186
- event.preventDefault();
187
- this.setProgressFromEvent(event);
188
- }
189
- /**
190
- * handling change on main svg click
191
- * @param event
192
- * @returns
193
- */
194
- onSvgClick(event) {
195
- if (this.config.disabled || this.config.readOnly || this.config.isRangeMode)
196
- return;
197
- this.setProgressFromEvent(event);
198
- }
199
- /**
200
- * get ref of active svg element for different type of knobs
201
- * @returns
202
- */
203
- getTargetSvg() {
204
- if (this.config.knobType === 'horizontal') {
205
- return this.horizontalLineRef.nativeElement.closest('svg');
206
- }
207
- else if (this.config.knobType === 'vertical') {
208
- return this.verticalLineRef.nativeElement.closest('svg');
209
- }
210
- return this.bgArcRef.nativeElement.closest('svg');
211
- }
212
- /**
213
- * updating progrees value while dragging the handle on stroke bar
214
- * @param e
215
- * @returns
216
- */
217
- setProgressFromEvent(e) {
218
- const svg = this.getTargetSvg();
219
- if (!svg) {
220
- return;
221
- }
222
- const rect = svg.getBoundingClientRect();
223
- const clientX = (e instanceof TouchEvent) ? e.touches[0].clientX : e.clientX;
224
- const clientY = (e instanceof TouchEvent) ? e.touches[0].clientY : e.clientY;
225
- const x = clientX - rect.left;
226
- const y = clientY - rect.top;
227
- let rawPercent;
228
- if (this.config.knobType === 'horizontal') {
229
- const usableWidth = this.config.size - 2 * this.config.strokeWidth;
230
- rawPercent = ((x - this.config.strokeWidth) / usableWidth) * 100;
231
- }
232
- else if (this.config.knobType === 'vertical') {
233
- const usableHeight = this.config.size - 2 * this.config.strokeWidth;
234
- rawPercent = (1 - (y - this.config.strokeWidth) / usableHeight) * 100;
235
- }
236
- else {
237
- const angle = this.getAngleFromPoint(x, y);
238
- if (angle === null)
239
- return;
240
- rawPercent = ((angle - this.startAngle) / this.arcLength) * 100;
241
- }
242
- const clampedPercent = this.clamp(rawPercent, 0, 100);
243
- let absolutePercent = this.config.min + (clampedPercent / 100) * (this.config.max - this.config.min);
244
- absolutePercent = this.roundToStep(absolutePercent);
245
- if (this.config.isRangeMode) {
246
- if (this.activeHandle === 'start') {
247
- if (absolutePercent > this.config.rangeEndValue) {
248
- absolutePercent = this.config.rangeEndValue;
249
- }
250
- this.config.rangeStartValue = absolutePercent;
251
- }
252
- else {
253
- if (absolutePercent < this.config.rangeStartValue) {
254
- absolutePercent = this.config.rangeStartValue;
255
- }
256
- this.config.rangeEndValue = absolutePercent;
257
- }
258
- this.rucEvent.emit({ eventName: 'valueChange', eventOutput: { start: this.config.rangeStartValue, end: this.config.rangeEndValue } });
259
- }
260
- else {
261
- this.value = absolutePercent;
262
- this.rucEvent.emit({ eventName: 'valueChange', eventOutput: this.value });
263
- }
264
- this.updateArc();
265
- this.onChange(this.value);
266
- this.onTouched();
267
- }
268
- /**
269
- * updating svg progress based on value changes
270
- * @returns
271
- */
272
- updateArc() {
273
- var _a, _b, _c;
274
- if (this.config.knobType !== 'arc') {
275
- return;
276
- }
277
- const scaled = (this.value - this.config.min) / (this.config.max - this.config.min);
278
- const angle = this.startAngle + scaled * this.arcLength;
279
- const path = this.describeArc(this.centerX, this.centerY, this.radius, this.startAngle, angle);
280
- (_a = this.progressArcRef) === null || _a === void 0 ? void 0 : _a.nativeElement.setAttribute('d', path);
281
- const pos = this.polarToCartesian(this.centerX, this.centerY, this.radius, angle);
282
- (_b = this.handleRef) === null || _b === void 0 ? void 0 : _b.nativeElement.setAttribute('cx', pos.x.toString());
283
- (_c = this.handleRef) === null || _c === void 0 ? void 0 : _c.nativeElement.setAttribute('cy', pos.y.toString());
284
- // for tooltip
285
- const angleRad = (angle - 90) * Math.PI / 180;
286
- const tooltipRadius = this.radius + this.config.strokeWidth / 2 + 10;
287
- this.tooltipX = this.centerX + tooltipRadius * Math.cos(angleRad);
288
- this.tooltipY = this.centerY + tooltipRadius * Math.sin(angleRad);
289
- }
290
- /**
291
- * return maximum value out of min & max range
292
- * @param val
293
- * @param min
294
- * @param max
295
- * @returns
296
- */
297
- clamp(val, min, max) {
298
- return Math.max(min, Math.min(max, val));
299
- }
300
- /**
301
- * getting calulated point from polar coordinates to cartesian coordinates
302
- * @param cx
303
- * @param cy
304
- * @param r
305
- * @param angleDeg
306
- * @returns
307
- */
308
- polarToCartesian(cx, cy, r, angleDeg) {
309
- const angleRad = (angleDeg - 90) * Math.PI / 180;
310
- return {
311
- x: cx + r * Math.cos(angleRad),
312
- y: cy + r * Math.sin(angleRad)
313
- };
314
- }
315
- /**
316
- * getting radius for arc handle based on stroke width
317
- * @returns
318
- */
319
- getRadius() {
320
- var _a;
321
- return this.config.strokeWidth ? (this.config.strokeWidth / 2) - (((_a = this.config.handleBorderWidth) !== null && _a !== void 0 ? _a : 0) / 2) : 4;
322
- }
323
- /**
324
- * getting svg box size based on different knob shapes
325
- * @returns
326
- */
327
- getSvgViewBoxSize() {
328
- let width = this.config.size, height = this.config.size;
329
- if (this.config.knobType === 'horizontal') {
330
- height = this.config.strokeWidth + 40;
331
- }
332
- if (this.config.knobType === 'vertical') {
333
- height = this.config.size / 4 + 5;
334
- width = this.config.strokeWidth + 40;
335
- }
336
- return '0 0 ' + width + ' ' + height;
337
- }
338
- /**
339
- * geeting dynamic bg color for progress stroke based on provide config for "progressBackground"
340
- */
341
- get progressColor() {
342
- var _a;
343
- if (typeof this.config.progressBackground === 'string') {
344
- return this.config.progressBackground;
345
- }
346
- else if (((_a = this.config.progressBackground) === null || _a === void 0 ? void 0 : _a.length) == 1) {
347
- return this.config.progressBackground[0];
348
- }
349
- else if (this.config.progressBackground.length > 1) {
350
- return this.config.progressBackground[Math.ceil(this.value / this.changeColorAfter) - 1];
351
- }
352
- else {
353
- return 'green';
354
- }
355
- }
356
- /**
357
- * getting coordinates for arc based on provided inputs
358
- * @param cx
359
- * @param cy
360
- * @param r
361
- * @param start
362
- * @param end
363
- * @returns
364
- */
365
- describeArc(cx, cy, r, start, end) {
366
- const startPos = this.polarToCartesian(cx, cy, r, end);
367
- const endPos = this.polarToCartesian(cx, cy, r, start);
368
- const largeArc = end - start <= 180 ? 0 : 1;
369
- return [
370
- "M", startPos.x, startPos.y,
371
- "A", r, r, 0, largeArc, 0, endPos.x, endPos.y
372
- ].join(" ");
373
- }
374
- /**
375
- * getting calculated angle for arc progress based on provided input
376
- * @param x
377
- * @param y
378
- * @returns
379
- */
380
- getAngleFromPoint(x, y) {
381
- const dx = x - this.centerX;
382
- if (dx === 0) {
383
- return null;
384
- }
385
- const dy = y - this.centerY;
386
- let angle = Math.atan2(dy, dx) * 180 / Math.PI + 90;
387
- if (angle < 0)
388
- angle += 360;
389
- const normalizedStart = this.startAngle % 360;
390
- let delta = angle - normalizedStart;
391
- if (delta < 0)
392
- delta += 360;
393
- if (delta > this.arcLength)
394
- return null;
395
- return this.startAngle + delta;
396
- }
397
- /**
398
- * increment value on click on button
399
- * @returns
400
- */
401
- increment() {
402
- if (this.config.disabled || this.config.readOnly)
403
- return;
404
- this.value = this.clamp((this.value + this.config.step), this.config.min, this.config.max);
405
- this.updateArc();
406
- this.onChange(this.value);
407
- this.onTouched();
408
- }
409
- /**
410
- * decrement value on click on button
411
- * @returns
412
- */
413
- decrement() {
414
- if (this.config.disabled || this.config.readOnly)
415
- return;
416
- this.value = this.clamp((this.value - this.config.step), this.config.min, this.config.max);
417
- this.updateArc();
418
- this.onChange(this.value);
419
- this.onTouched();
420
- }
421
- /**
422
- * change value using arrow keys for accessibility
423
- * @param event
424
- * @returns
425
- */
426
- onKeyDown(event) {
427
- if (this.config.readOnly || this.config.disabled)
428
- return;
429
- if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {
430
- this.increment();
431
- event.preventDefault();
432
- }
433
- else if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {
434
- this.decrement();
435
- event.preventDefault();
436
- }
437
- }
438
- /**
439
- * geeting arc coordinated for range selection mode
440
- * @returns
441
- */
442
- getRangeArcPath() {
443
- const startAngle = this.startAngle + (this.config.rangeStartValue / (this.config.max - this.config.min)) * (this.endAngle - this.startAngle);
444
- const endAngle = this.startAngle + (this.config.rangeEndValue / (this.config.max - this.config.min)) * (this.endAngle - this.startAngle);
445
- return this.describeArc(this.centerX, this.centerY, this.radius, startAngle, endAngle);
446
- }
447
- /**
448
- * handling mousedown when range mode is enabled
449
- * @param event
450
- * @param handleType
451
- * @returns
452
- */
453
- onHandleMouseDown(event, handleType) {
454
- if (this.config.disabled || this.config.readOnly)
455
- return;
456
- this.activeHandle = handleType;
457
- this.startDrag();
458
- }
459
- /**
460
- * getting x & y to update handle position when dragging
461
- * @param value
462
- * @returns
463
- */
464
- getHandlePosition(value) {
465
- const scaled = (value - this.config.min) / (this.config.max - this.config.min);
466
- const angle = this.startAngle + scaled * this.arcLength;
467
- const pos = this.polarToCartesian(this.centerX, this.centerY, this.radius, angle);
468
- return pos;
469
- }
470
- /**
471
- * geeting handle position for horizontal line
472
- * @param value
473
- * @returns
474
- */
475
- getHorizontalHandleX(value) {
476
- const usableWidth = this.config.size - 2 * this.config.strokeWidth;
477
- const ratio = (value - this.config.min) / (this.config.max - this.config.min);
478
- return this.config.strokeWidth + usableWidth * ratio;
479
- }
480
- /**
481
- * geeting start position for horizontal line
482
- * @param value
483
- * @returns
484
- */
485
- getHorizontalLineStartX() {
486
- return this.getHorizontalHandleX(this.config.isRangeMode ? this.config.rangeStartValue : this.config.min);
487
- }
488
- /**
489
- * geeting end position for horizontal line
490
- * @param value
491
- * @returns
492
- */
493
- getHorizontalLineEndX() {
494
- return this.getHorizontalHandleX(this.config.isRangeMode ? this.config.rangeEndValue : this.value);
495
- }
496
- /**
497
- * geeting handle position for vertical line
498
- * @param value
499
- * @returns
500
- */
501
- getVerticalHandleY(value) {
502
- const usableHeight = this.config.size - 2 * this.config.strokeWidth;
503
- const ratio = 1 - (value - this.config.min) / (this.config.max - this.config.min);
504
- return this.config.strokeWidth + usableHeight * ratio;
505
- }
506
- /**
507
- * geeting start position for vertical line
508
- * @param value
509
- * @returns
510
- */
511
- getVerticalLineStartY() {
512
- return this.getVerticalHandleY(this.config.isRangeMode ? this.config.rangeEndValue : this.value);
513
- }
514
- /**
515
- * get output to be emitted based on range mode
516
- * @returns
517
- */
518
- getEventOutput() {
519
- if (this.config.isRangeMode) {
520
- return { start: this.config.rangeStartValue, end: this.config.rangeEndValue };
521
- }
522
- return this.value;
523
- }
524
- /**
525
- * get correct page label from object
526
- * @param labelName
527
- * @returns string
528
- */
529
- getLabel(labelName) {
530
- return DEFAULT_LABELS[labelName] || '';
531
- }
532
- }
533
- RuclibKnobComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibKnobComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
534
- RuclibKnobComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RuclibKnobComponent, selector: "uxp-ruclib-knob", inputs: { customTheme: "customTheme", rucInputData: "rucInputData" }, outputs: { rucEvent: "rucEvent" }, host: { listeners: { "window:mouseup": "stopDrag()", "window:touchend": "stopDrag()", "window:mousemove": "onMove($event)", "window:touchmove": "onMove($event)" } }, providers: [
535
- {
536
- provide: NG_VALUE_ACCESSOR,
537
- useExisting: forwardRef(() => RuclibKnobComponent),
538
- multi: true
539
- }
540
- ], viewQueries: [{ propertyName: "bgArcRef", first: true, predicate: ["bgArc"], descendants: true }, { propertyName: "progressArcRef", first: true, predicate: ["progressArc"], descendants: true }, { propertyName: "handleRef", first: true, predicate: ["handle"], descendants: true }, { propertyName: "horizontalLineRef", first: true, predicate: ["horizontalLine"], descendants: true }, { propertyName: "verticalLineRef", first: true, predicate: ["verticalLine"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"knob-container {{customTheme}}\" [style.width.px]=\"config.size\">\r\n <svg [ngClass]=\"{ 'hover-animate': config.animateOnHover }\" [attr.viewBox]=\"getSvgViewBoxSize()\"\r\n (click)=\"onSvgClick($event)\" [style.cursor]=\"(config.readOnly || config.disabled) ? 'not-allowed' : 'pointer'\"\r\n [class.disabled]=\"config.disabled\" [class.read-only]=\"config.readOnly\"\r\n (mouseenter)=\"showTooltip = true; hovering=true; rucEvent.emit({eventName: 'hover'})\"\r\n (mouseleave)=\"showTooltip = false; hovering=false\" (focus)=\"rucEvent.emit({eventName: 'focus'})\"\r\n (blur)=\"rucEvent.emit({eventName: 'blur'})\" (keydown)=\"onKeyDown($event)\" [attr.role]=\"'slider'\"\r\n [attr.aria-valuemin]=\"config.min\" [attr.aria-valuemax]=\"config.max\" [attr.aria-valuenow]=\"value\"\r\n [attr.aria-disabled]=\"config.disabled\" [ngSwitch]=\"config.knobType\">\r\n\r\n <!-- arc knob -->\r\n <ng-container *ngSwitchCase=\"'arc'\">\r\n\r\n <!-- glow effect -->\r\n <defs>\r\n <filter id=\"glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\r\n <feDropShadow dx=\"0\" dy=\"0\" stdDeviation=\"4\" [attr.flood-color]=\"config.strokeBackground\"\r\n flood-opacity=\"0.75\" />\r\n </filter>\r\n </defs>\r\n\r\n <!-- arc main stroke -->\r\n <path #bgArc fill=\"none\" class=\"main-path\" [attr.stroke]=\"config.strokeBackground\"\r\n [attr.stroke-width]=\"config.strokeWidth\" [attr.stroke-linecap]=\"config.roundedCorner ? 'round' : ''\" />\r\n\r\n <!-- arc progress stroke - single handle -->\r\n <path *ngIf=\"!config.isRangeMode\" #progressArc fill=\"none\" class=\"progress-path\" [attr.stroke]=\"progressColor\"\r\n [attr.stroke-width]=\"config.strokeWidth\" [attr.stroke-linecap]=\"config.roundedCorner ? 'round' : ''\" />\r\n\r\n <!-- arc - single handle -->\r\n <circle *ngIf=\"!config.isRangeMode\" #handle class=\"handle\" [attr.r]=\"getRadius()\"\r\n [attr.fill]=\"config.showHandle ? config.handleBackground : 'transparent'\"\r\n [attr.stroke-width]=\"config.showHandle ? config.handleBorderWidth : 0\"\r\n [attr.stroke]=\"config.showHandle ? config.handleBorderColor : 'transparent'\" (mousedown)=\"startDrag()\"\r\n (touchstart)=\"startDrag()\" />\r\n\r\n <!-- arc progress stroke - dual handle for range -->\r\n <path *ngIf=\"config.isRangeMode\" [attr.d]=\"getRangeArcPath()\" [attr.stroke]=\"progressColor\"\r\n [attr.stroke-width]=\"config.strokeWidth\" fill=\"none\" stroke-linecap=\"round\" />\r\n\r\n <!-- arc dual handle - start -->\r\n <circle *ngIf=\"config.isRangeMode\" [attr.cx]=\"getHandlePosition(config.rangeStartValue).x\"\r\n [attr.cy]=\"getHandlePosition(config.rangeStartValue).y\" [attr.r]=\"getRadius()\"\r\n [attr.fill]=\"config.handleBackground\" [attr.stroke-width]=\"config.handleBorderWidth\"\r\n [attr.stroke]=\"config.handleBorderColor\" (mousedown)=\"onHandleMouseDown($event, 'start')\" />\r\n\r\n <!-- arc dual handle - end -->\r\n <circle *ngIf=\"config.isRangeMode\" [attr.cx]=\"getHandlePosition(config.rangeEndValue).x\"\r\n [attr.cy]=\"getHandlePosition(config.rangeEndValue).y\" [attr.r]=\"getRadius()\"\r\n [attr.fill]=\"config.handleBackground\" [attr.stroke-width]=\"config.handleBorderWidth\"\r\n [attr.stroke]=\"config.handleBorderColor\" (mousedown)=\"onHandleMouseDown($event, 'end')\" />\r\n </ng-container>\r\n\r\n <!-- horizontal line -->\r\n <ng-container *ngSwitchCase=\"'horizontal'\">\r\n <line #horizontalLine [attr.x1]=\"config.strokeWidth\" [attr.x2]=\"config.size\" [attr.y1]=\"config.strokeWidth + 10\"\r\n [attr.y2]=\"config.strokeWidth + 10\" [attr.stroke]=\"config.strokeBackground\"\r\n [attr.stroke-width]=\"config.strokeWidth\" [attr.line-cap]=\"config.roundedCorner ? 'round' : ''\" />\r\n\r\n <!-- progress for horizontal line -->\r\n <line [attr.x1]=\"getHorizontalLineStartX()\" [attr.x2]=\"getHorizontalLineEndX()\"\r\n [attr.y1]=\"config.strokeWidth + 10\" [attr.y2]=\"config.strokeWidth + 10\" [attr.stroke]=\"progressColor\"\r\n [attr.stroke-width]=\"config.strokeWidth\" />\r\n\r\n <!-- handle for horizontal line -->\r\n <rect *ngIf=\"!config.isRangeMode\" [attr.x]=\"getHorizontalHandleX(value)\"\r\n [attr.y]=\"config.strokeWidth + 10 - getRadius()-1\" [attr.width]=\"config.strokeWidth\"\r\n [attr.height]=\"config.strokeWidth\"\r\n [attr.fill]=\"config.handleBackground ? config.handleBackground : progressColor\" (mousedown)=\"startDrag()\"\r\n (touchstart)=\"startDrag()\" />\r\n </ng-container>\r\n\r\n <!-- vertical line -->\r\n <ng-container *ngSwitchCase=\"'vertical'\">\r\n <line #verticalLine [attr.y1]=\"config.strokeWidth/4\" [attr.y2]=\"config.size/4\" [attr.x1]=\"config.strokeWidth + 10\"\r\n [attr.x2]=\"config.strokeWidth + 10\" [attr.stroke]=\"config.strokeBackground\"\r\n [attr.stroke-width]=\"config.strokeWidth/4\" [attr.line-cap]=\"config.roundedCorner ? 'round' : ''\" />\r\n\r\n <!-- progress for vertical line -->\r\n <line [attr.y1]=\"getVerticalLineStartY()/4\" [attr.y2]=\"config.size/4\" [attr.x1]=\"config.strokeWidth + 10\"\r\n [attr.x2]=\"config.strokeWidth + 10\" [attr.stroke]=\"progressColor\" [attr.stroke-width]=\"config.strokeWidth/4\" />\r\n\r\n <!-- Handle for vertical line -->\r\n <rect *ngIf=\"!config.isRangeMode\" [attr.y]=\"getVerticalHandleY(value)/4\" [attr.x]=\"config.strokeWidth + 7.5\"\r\n [attr.width]=\"config.strokeWidth/4\" [attr.height]=\"config.strokeWidth/4\"\r\n [attr.fill]=\"config.handleBackground ? config.handleBackground : progressColor\" (mousedown)=\"startDrag()\"\r\n (touchstart)=\"startDrag()\" />\r\n </ng-container>\r\n </svg>\r\n\r\n <!-- tooltip -->\r\n <div class=\"tooltip\" *ngIf=\"config.enableTooltip && !config.isRangeMode\" [class.show]=\"showTooltip\"\r\n [style.left.px]=\"tooltipX\" [style.top.px]=\"tooltipY\">\r\n {{ value}}\r\n </div>\r\n\r\n <!-- progress value -->\r\n <div class=\"progress-value {{config.knobType}}\" [style.maxWidth.px]=\"config.size * 2 - 50\"\r\n [style.color]=\"config.valueColor\" [style.fontSize.px]=\"config.valueSize\" [style.fontWeight]=\"config.valueWeight\"\r\n [style.cursor]=\"(config.readOnly || config.disabled) ? 'not-allowed' : ''\" [class.disabled]=\"config.disabled\"\r\n [class.read-only]=\"config.readOnly\" title=\"{{config.valuePrefix +''+value+''+config.valueSuffix}}\">\r\n <ng-container *ngIf=\"!config.isRangeMode\">\r\n <span class=\"value-prefix\">{{config.valuePrefix}}</span>\r\n <span class=\"value\">{{ value }}</span>\r\n <span class=\"value-suffix\">{{config.valueSuffix}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"config.isRangeMode\">\r\n <span class=\"value\">{{config.rangeStartValue}} : {{config.rangeEndValue}}</span>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- increment-decrement button -->\r\n <div class=\"arc-buttons\" *ngIf=\"!config.isRangeMode && config.showButtons\">\r\n <button mat-mini-fab color=\"secondary\" (click)=\"decrement()\" [disabled]=\"config.disabled || config.readOnly\" (keydown)=\"onKeyDown($event)\"\r\n [attr.aria-label]=\"getLabel('decrementButton')\">\r\n <mat-icon>remove</mat-icon>\r\n </button>\r\n \r\n <button mat-mini-fab color=\"secondary\" (click)=\"increment()\" [disabled]=\"config.disabled || config.readOnly\" (keydown)=\"onKeyDown($event)\"\r\n [attr.aria-label]=\"getLabel('incrementButton')\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n \r\n </div>\r\n</div>", styles: [".knob-container{position:relative;padding-bottom:10px}svg{width:100%;height:100%;outline:none}.progress-value{left:50%;font-size:24px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;transform:translate(-50%,-50%);-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%)}.progress-value.arc{position:absolute;top:45%}.progress-value.horizontal,.progress-value.vertical{position:relative;display:flex;justify-content:center;align-items:center;padding-top:20px}.handle{cursor:pointer}.disabled{opacity:.6;pointer-events:none}.read-only{opacity:.8}.arc-buttons{display:flex;justify-content:center;gap:1rem;margin-top:-10px}.arc-buttons button{padding:6px;width:35px;height:35px;font-size:1rem;cursor:pointer;border:none;border-radius:4px;transition:background .2s ease;box-shadow:0 0 1px 1px #ddd!important}::ng-deep .mat-mdc-mini-fab:not(.mdc-fab--extended) .mdc-fab__ripple{border-radius:0!important;-webkit-border-radius:0!important;-moz-border-radius:0!important;-ms-border-radius:0!important;-o-border-radius:0!important}.arc-buttons button:disabled{opacity:.6;cursor:not-allowed}.tooltip{position:absolute;background:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;pointer-events:none;white-space:nowrap;transform:translate(-50%,-100%);opacity:0;transition:opacity .3s ease}.tooltip.show{opacity:1}.main-path{transition:all 1s ease;-webkit-transition:all 1s ease;-moz-transition:all 1s ease;-ms-transition:all 1s ease;-o-transition:all 1s ease}.hover-animate:hover .main-path{filter:url(#glow);-webkit-filter:url(#glow)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
541
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibKnobComponent, decorators: [{
542
- type: Component,
543
- args: [{ selector: 'uxp-ruclib-knob', providers: [
544
- {
545
- provide: NG_VALUE_ACCESSOR,
546
- useExisting: forwardRef(() => RuclibKnobComponent),
547
- multi: true
548
- }
549
- ], template: "<div class=\"knob-container {{customTheme}}\" [style.width.px]=\"config.size\">\r\n <svg [ngClass]=\"{ 'hover-animate': config.animateOnHover }\" [attr.viewBox]=\"getSvgViewBoxSize()\"\r\n (click)=\"onSvgClick($event)\" [style.cursor]=\"(config.readOnly || config.disabled) ? 'not-allowed' : 'pointer'\"\r\n [class.disabled]=\"config.disabled\" [class.read-only]=\"config.readOnly\"\r\n (mouseenter)=\"showTooltip = true; hovering=true; rucEvent.emit({eventName: 'hover'})\"\r\n (mouseleave)=\"showTooltip = false; hovering=false\" (focus)=\"rucEvent.emit({eventName: 'focus'})\"\r\n (blur)=\"rucEvent.emit({eventName: 'blur'})\" (keydown)=\"onKeyDown($event)\" [attr.role]=\"'slider'\"\r\n [attr.aria-valuemin]=\"config.min\" [attr.aria-valuemax]=\"config.max\" [attr.aria-valuenow]=\"value\"\r\n [attr.aria-disabled]=\"config.disabled\" [ngSwitch]=\"config.knobType\">\r\n\r\n <!-- arc knob -->\r\n <ng-container *ngSwitchCase=\"'arc'\">\r\n\r\n <!-- glow effect -->\r\n <defs>\r\n <filter id=\"glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\r\n <feDropShadow dx=\"0\" dy=\"0\" stdDeviation=\"4\" [attr.flood-color]=\"config.strokeBackground\"\r\n flood-opacity=\"0.75\" />\r\n </filter>\r\n </defs>\r\n\r\n <!-- arc main stroke -->\r\n <path #bgArc fill=\"none\" class=\"main-path\" [attr.stroke]=\"config.strokeBackground\"\r\n [attr.stroke-width]=\"config.strokeWidth\" [attr.stroke-linecap]=\"config.roundedCorner ? 'round' : ''\" />\r\n\r\n <!-- arc progress stroke - single handle -->\r\n <path *ngIf=\"!config.isRangeMode\" #progressArc fill=\"none\" class=\"progress-path\" [attr.stroke]=\"progressColor\"\r\n [attr.stroke-width]=\"config.strokeWidth\" [attr.stroke-linecap]=\"config.roundedCorner ? 'round' : ''\" />\r\n\r\n <!-- arc - single handle -->\r\n <circle *ngIf=\"!config.isRangeMode\" #handle class=\"handle\" [attr.r]=\"getRadius()\"\r\n [attr.fill]=\"config.showHandle ? config.handleBackground : 'transparent'\"\r\n [attr.stroke-width]=\"config.showHandle ? config.handleBorderWidth : 0\"\r\n [attr.stroke]=\"config.showHandle ? config.handleBorderColor : 'transparent'\" (mousedown)=\"startDrag()\"\r\n (touchstart)=\"startDrag()\" />\r\n\r\n <!-- arc progress stroke - dual handle for range -->\r\n <path *ngIf=\"config.isRangeMode\" [attr.d]=\"getRangeArcPath()\" [attr.stroke]=\"progressColor\"\r\n [attr.stroke-width]=\"config.strokeWidth\" fill=\"none\" stroke-linecap=\"round\" />\r\n\r\n <!-- arc dual handle - start -->\r\n <circle *ngIf=\"config.isRangeMode\" [attr.cx]=\"getHandlePosition(config.rangeStartValue).x\"\r\n [attr.cy]=\"getHandlePosition(config.rangeStartValue).y\" [attr.r]=\"getRadius()\"\r\n [attr.fill]=\"config.handleBackground\" [attr.stroke-width]=\"config.handleBorderWidth\"\r\n [attr.stroke]=\"config.handleBorderColor\" (mousedown)=\"onHandleMouseDown($event, 'start')\" />\r\n\r\n <!-- arc dual handle - end -->\r\n <circle *ngIf=\"config.isRangeMode\" [attr.cx]=\"getHandlePosition(config.rangeEndValue).x\"\r\n [attr.cy]=\"getHandlePosition(config.rangeEndValue).y\" [attr.r]=\"getRadius()\"\r\n [attr.fill]=\"config.handleBackground\" [attr.stroke-width]=\"config.handleBorderWidth\"\r\n [attr.stroke]=\"config.handleBorderColor\" (mousedown)=\"onHandleMouseDown($event, 'end')\" />\r\n </ng-container>\r\n\r\n <!-- horizontal line -->\r\n <ng-container *ngSwitchCase=\"'horizontal'\">\r\n <line #horizontalLine [attr.x1]=\"config.strokeWidth\" [attr.x2]=\"config.size\" [attr.y1]=\"config.strokeWidth + 10\"\r\n [attr.y2]=\"config.strokeWidth + 10\" [attr.stroke]=\"config.strokeBackground\"\r\n [attr.stroke-width]=\"config.strokeWidth\" [attr.line-cap]=\"config.roundedCorner ? 'round' : ''\" />\r\n\r\n <!-- progress for horizontal line -->\r\n <line [attr.x1]=\"getHorizontalLineStartX()\" [attr.x2]=\"getHorizontalLineEndX()\"\r\n [attr.y1]=\"config.strokeWidth + 10\" [attr.y2]=\"config.strokeWidth + 10\" [attr.stroke]=\"progressColor\"\r\n [attr.stroke-width]=\"config.strokeWidth\" />\r\n\r\n <!-- handle for horizontal line -->\r\n <rect *ngIf=\"!config.isRangeMode\" [attr.x]=\"getHorizontalHandleX(value)\"\r\n [attr.y]=\"config.strokeWidth + 10 - getRadius()-1\" [attr.width]=\"config.strokeWidth\"\r\n [attr.height]=\"config.strokeWidth\"\r\n [attr.fill]=\"config.handleBackground ? config.handleBackground : progressColor\" (mousedown)=\"startDrag()\"\r\n (touchstart)=\"startDrag()\" />\r\n </ng-container>\r\n\r\n <!-- vertical line -->\r\n <ng-container *ngSwitchCase=\"'vertical'\">\r\n <line #verticalLine [attr.y1]=\"config.strokeWidth/4\" [attr.y2]=\"config.size/4\" [attr.x1]=\"config.strokeWidth + 10\"\r\n [attr.x2]=\"config.strokeWidth + 10\" [attr.stroke]=\"config.strokeBackground\"\r\n [attr.stroke-width]=\"config.strokeWidth/4\" [attr.line-cap]=\"config.roundedCorner ? 'round' : ''\" />\r\n\r\n <!-- progress for vertical line -->\r\n <line [attr.y1]=\"getVerticalLineStartY()/4\" [attr.y2]=\"config.size/4\" [attr.x1]=\"config.strokeWidth + 10\"\r\n [attr.x2]=\"config.strokeWidth + 10\" [attr.stroke]=\"progressColor\" [attr.stroke-width]=\"config.strokeWidth/4\" />\r\n\r\n <!-- Handle for vertical line -->\r\n <rect *ngIf=\"!config.isRangeMode\" [attr.y]=\"getVerticalHandleY(value)/4\" [attr.x]=\"config.strokeWidth + 7.5\"\r\n [attr.width]=\"config.strokeWidth/4\" [attr.height]=\"config.strokeWidth/4\"\r\n [attr.fill]=\"config.handleBackground ? config.handleBackground : progressColor\" (mousedown)=\"startDrag()\"\r\n (touchstart)=\"startDrag()\" />\r\n </ng-container>\r\n </svg>\r\n\r\n <!-- tooltip -->\r\n <div class=\"tooltip\" *ngIf=\"config.enableTooltip && !config.isRangeMode\" [class.show]=\"showTooltip\"\r\n [style.left.px]=\"tooltipX\" [style.top.px]=\"tooltipY\">\r\n {{ value}}\r\n </div>\r\n\r\n <!-- progress value -->\r\n <div class=\"progress-value {{config.knobType}}\" [style.maxWidth.px]=\"config.size * 2 - 50\"\r\n [style.color]=\"config.valueColor\" [style.fontSize.px]=\"config.valueSize\" [style.fontWeight]=\"config.valueWeight\"\r\n [style.cursor]=\"(config.readOnly || config.disabled) ? 'not-allowed' : ''\" [class.disabled]=\"config.disabled\"\r\n [class.read-only]=\"config.readOnly\" title=\"{{config.valuePrefix +''+value+''+config.valueSuffix}}\">\r\n <ng-container *ngIf=\"!config.isRangeMode\">\r\n <span class=\"value-prefix\">{{config.valuePrefix}}</span>\r\n <span class=\"value\">{{ value }}</span>\r\n <span class=\"value-suffix\">{{config.valueSuffix}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"config.isRangeMode\">\r\n <span class=\"value\">{{config.rangeStartValue}} : {{config.rangeEndValue}}</span>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- increment-decrement button -->\r\n <div class=\"arc-buttons\" *ngIf=\"!config.isRangeMode && config.showButtons\">\r\n <button mat-mini-fab color=\"secondary\" (click)=\"decrement()\" [disabled]=\"config.disabled || config.readOnly\" (keydown)=\"onKeyDown($event)\"\r\n [attr.aria-label]=\"getLabel('decrementButton')\">\r\n <mat-icon>remove</mat-icon>\r\n </button>\r\n \r\n <button mat-mini-fab color=\"secondary\" (click)=\"increment()\" [disabled]=\"config.disabled || config.readOnly\" (keydown)=\"onKeyDown($event)\"\r\n [attr.aria-label]=\"getLabel('incrementButton')\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n \r\n </div>\r\n</div>", styles: [".knob-container{position:relative;padding-bottom:10px}svg{width:100%;height:100%;outline:none}.progress-value{left:50%;font-size:24px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;transform:translate(-50%,-50%);-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%)}.progress-value.arc{position:absolute;top:45%}.progress-value.horizontal,.progress-value.vertical{position:relative;display:flex;justify-content:center;align-items:center;padding-top:20px}.handle{cursor:pointer}.disabled{opacity:.6;pointer-events:none}.read-only{opacity:.8}.arc-buttons{display:flex;justify-content:center;gap:1rem;margin-top:-10px}.arc-buttons button{padding:6px;width:35px;height:35px;font-size:1rem;cursor:pointer;border:none;border-radius:4px;transition:background .2s ease;box-shadow:0 0 1px 1px #ddd!important}::ng-deep .mat-mdc-mini-fab:not(.mdc-fab--extended) .mdc-fab__ripple{border-radius:0!important;-webkit-border-radius:0!important;-moz-border-radius:0!important;-ms-border-radius:0!important;-o-border-radius:0!important}.arc-buttons button:disabled{opacity:.6;cursor:not-allowed}.tooltip{position:absolute;background:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;pointer-events:none;white-space:nowrap;transform:translate(-50%,-100%);opacity:0;transition:opacity .3s ease}.tooltip.show{opacity:1}.main-path{transition:all 1s ease;-webkit-transition:all 1s ease;-moz-transition:all 1s ease;-ms-transition:all 1s ease;-o-transition:all 1s ease}.hover-animate:hover .main-path{filter:url(#glow);-webkit-filter:url(#glow)}\n"] }]
550
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { bgArcRef: [{
551
- type: ViewChild,
552
- args: ['bgArc']
553
- }], progressArcRef: [{
554
- type: ViewChild,
555
- args: ['progressArc']
556
- }], handleRef: [{
557
- type: ViewChild,
558
- args: ['handle']
559
- }], horizontalLineRef: [{
560
- type: ViewChild,
561
- args: ['horizontalLine']
562
- }], verticalLineRef: [{
563
- type: ViewChild,
564
- args: ['verticalLine']
565
- }], rucEvent: [{
566
- type: Output
567
- }], customTheme: [{
568
- type: Input
569
- }], rucInputData: [{
570
- type: Input
571
- }], stopDrag: [{
572
- type: HostListener,
573
- args: ['window:mouseup']
574
- }, {
575
- type: HostListener,
576
- args: ['window:touchend']
577
- }], onMove: [{
578
- type: HostListener,
579
- args: ['window:mousemove', ['$event']]
580
- }, {
581
- type: HostListener,
582
- args: ['window:touchmove', ['$event']]
583
- }] } });
584
-
585
- class RuclibKnobModule {
586
- }
587
- RuclibKnobModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibKnobModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
588
- RuclibKnobModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: RuclibKnobModule, declarations: [RuclibKnobComponent], imports: [CommonModule,
589
- FormsModule,
590
- ReactiveFormsModule,
591
- MatButtonModule,
592
- MatIconModule], exports: [RuclibKnobComponent] });
593
- RuclibKnobModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibKnobModule, imports: [CommonModule,
594
- FormsModule,
595
- ReactiveFormsModule,
596
- MatButtonModule,
597
- MatIconModule] });
598
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibKnobModule, decorators: [{
599
- type: NgModule,
600
- args: [{
601
- imports: [
602
- CommonModule,
603
- FormsModule,
604
- ReactiveFormsModule,
605
- MatButtonModule,
606
- MatIconModule
607
- ],
608
- declarations: [
609
- RuclibKnobComponent
610
- ],
611
- exports: [RuclibKnobComponent],
612
- }]
613
- }] });
614
-
615
- ;
616
-
617
- /**
618
- * Generated bundle index. Do not edit.
619
- */
620
-
621
- export { RuclibKnobComponent, RuclibKnobModule };
622
- //# sourceMappingURL=ruc-lib-knob.mjs.map