@libs-ui/components-inputs-range-slider 0.2.356-41 → 0.2.356-43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,27 +1,39 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @libs-ui/components-inputs-range-slider
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Component thanh trượt (range slider) cho phép người dùng chọn một giá trị số trong khoảng Min/Max bằng cách kéo, hỗ trợ hai chế độ hiển thị và nhãn giá trị động thông minh.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Giới thiệu
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- 🏷️ **Nhãn giá trị động**: Tự động hiển thị giá trị hiện tại theo vị trí con trỏ chuột.
|
|
9
|
-
- 👁️ **Thông minh**: Tự động ẩn nhãn Min/Max khi nhãn giá trị hiện tại bị chồng lấp để đảm bảo tính thẩm mỹ.
|
|
10
|
-
- 🔢 **Định dạng số**: Hỗ trợ định dạng số theo ngôn ngữ thông qua thuộc tính `formatNumber`.
|
|
11
|
-
- 🛠️ **Tùy biến cao**: Cho phép cấu hình `min`, `max`, `step` và đơn vị đo (`unit`).
|
|
12
|
-
- 🎨 **Hiệu ứng mượt mà**: Sử dụng CSS variables để xử lý tiến độ (progress) và các hiệu ứng hover/focus.
|
|
7
|
+
`@libs-ui/components-inputs-range-slider` là một Angular Standalone Component cung cấp thanh trượt (range input) đầy đủ tính năng. Component tự động hiển thị nhãn giá trị hiện tại theo vị trí con trỏ kéo và thông minh ẩn/hiện nhãn Min/Max khi bị chồng lấp. Tiến trình (progress) được điều khiển qua CSS Variables giúp hiệu năng rendering cao và dễ tuỳ chỉnh giao diện.
|
|
13
8
|
|
|
14
|
-
##
|
|
9
|
+
## Tính năng
|
|
10
|
+
|
|
11
|
+
- ✅ Hai chế độ: `slider` (có nhãn Min/Max/Value) và `audio` (tối giản, dùng cho media player)
|
|
12
|
+
- ✅ Nhãn giá trị hiện tại di chuyển theo vị trí kéo, luôn nằm đúng giữa thumb
|
|
13
|
+
- ✅ Tự động ẩn nhãn Min/Max khi bị chồng lấp bởi nhãn giá trị hiện tại
|
|
14
|
+
- ✅ Two-way binding qua `model()` signal với cú pháp `[(value)]`
|
|
15
|
+
- ✅ Output `outChange` được debounce 250ms, tránh phát quá nhiều sự kiện khi đang kéo
|
|
16
|
+
- ✅ Hỗ trợ bước nhảy `step` tuỳ chỉnh
|
|
17
|
+
- ✅ Hỗ trợ đơn vị đo `unit` hiển thị sau giá trị (%, px, đ, ...)
|
|
18
|
+
- ✅ Định dạng số theo ngôn ngữ qua `formatNumber`
|
|
19
|
+
- ✅ Trạng thái `disable` — ngăn thay đổi giá trị và giữ nguyên giá trị cũ
|
|
20
|
+
- ✅ Class bổ sung qua `classInclude` không ghi đè class gốc container
|
|
21
|
+
|
|
22
|
+
## Khi nào sử dụng
|
|
15
23
|
|
|
16
|
-
|
|
24
|
+
- Điều chỉnh âm lượng, độ sáng hoặc các thông số kỹ thuật dạng số
|
|
25
|
+
- Chọn khoảng giá trong bộ lọc tìm kiếm (price range)
|
|
26
|
+
- Thiết lập cấu hình có giới hạn Min/Max rõ ràng
|
|
27
|
+
- Cần interface trực quan, tốn ít diện tích hơn dạng Number Input
|
|
28
|
+
- Điều khiển tiến trình phát nhạc/video (dùng mode `audio`)
|
|
29
|
+
|
|
30
|
+
## Cài đặt
|
|
17
31
|
|
|
18
32
|
```bash
|
|
19
33
|
npm install @libs-ui/components-inputs-range-slider
|
|
20
34
|
```
|
|
21
35
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
### Import Module
|
|
36
|
+
## Import
|
|
25
37
|
|
|
26
38
|
```typescript
|
|
27
39
|
import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
|
|
@@ -34,56 +46,233 @@ import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-
|
|
|
34
46
|
export class YourComponent {}
|
|
35
47
|
```
|
|
36
48
|
|
|
37
|
-
|
|
49
|
+
## Ví dụ sử dụng
|
|
50
|
+
|
|
51
|
+
### Cơ bản — slider có nhãn đơn vị
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// component.ts
|
|
55
|
+
import { Component, signal } from '@angular/core';
|
|
56
|
+
import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
|
|
57
|
+
|
|
58
|
+
@Component({
|
|
59
|
+
standalone: true,
|
|
60
|
+
imports: [LibsUiComponentsInputsRangeSliderComponent],
|
|
61
|
+
templateUrl: './volume.component.html',
|
|
62
|
+
})
|
|
63
|
+
export class VolumeComponent {
|
|
64
|
+
protected volume = signal<number>(50);
|
|
65
|
+
|
|
66
|
+
protected handlerVolumeChange(value: number): void {
|
|
67
|
+
// outChange đã được debounce 250ms
|
|
68
|
+
console.log('Volume changed:', value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
38
72
|
|
|
39
73
|
```html
|
|
74
|
+
<!-- volume.component.html -->
|
|
40
75
|
<libs_ui-components-inputs-range_slider
|
|
41
76
|
[(value)]="volume"
|
|
42
77
|
[min]="0"
|
|
43
78
|
[max]="100"
|
|
44
|
-
[unit]="'%'"
|
|
79
|
+
[unit]="'%'"
|
|
80
|
+
(outChange)="handlerVolumeChange($event)">
|
|
81
|
+
</libs_ui-components-inputs-range_slider>
|
|
82
|
+
<p>Âm lượng: {{ volume() }}%</p>
|
|
45
83
|
```
|
|
46
84
|
|
|
47
|
-
### Chế độ
|
|
85
|
+
### Chế độ audio — tối giản cho media player
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// audio-player.component.ts
|
|
89
|
+
import { Component, signal } from '@angular/core';
|
|
90
|
+
import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
|
|
91
|
+
|
|
92
|
+
@Component({
|
|
93
|
+
standalone: true,
|
|
94
|
+
imports: [LibsUiComponentsInputsRangeSliderComponent],
|
|
95
|
+
templateUrl: './audio-player.component.html',
|
|
96
|
+
})
|
|
97
|
+
export class AudioPlayerComponent {
|
|
98
|
+
protected currentTime = signal<number>(0);
|
|
99
|
+
protected duration = 180; // giây
|
|
100
|
+
|
|
101
|
+
protected handlerSeek(value: number): void {
|
|
102
|
+
// Seek đến vị trí mới trong audio
|
|
103
|
+
this.audioService.seekTo(value);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
48
107
|
|
|
49
108
|
```html
|
|
109
|
+
<!-- audio-player.component.html -->
|
|
50
110
|
<libs_ui-components-inputs-range_slider
|
|
51
|
-
[(value)]="
|
|
111
|
+
[(value)]="currentTime"
|
|
52
112
|
[mode]="'audio'"
|
|
53
113
|
[min]="0"
|
|
54
|
-
[max]="
|
|
55
|
-
[step]="
|
|
114
|
+
[max]="duration"
|
|
115
|
+
[step]="1"
|
|
116
|
+
(outChange)="handlerSeek($event)">
|
|
117
|
+
</libs_ui-components-inputs-range_slider>
|
|
56
118
|
```
|
|
57
119
|
|
|
58
|
-
|
|
120
|
+
### Bước nhảy (Step) — chỉ cho phép giá trị rời rạc
|
|
59
121
|
|
|
60
|
-
|
|
122
|
+
```typescript
|
|
123
|
+
// config-panel.component.ts
|
|
124
|
+
import { Component, signal } from '@angular/core';
|
|
125
|
+
import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
|
|
61
126
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
| `unit` | `string` | `undefined` | Đơn vị hiển thị sau giá trị (vd: %, px, $). |
|
|
70
|
-
| `disable` | `boolean` | `false` | Vô hiệu hóa tương tác. |
|
|
71
|
-
| `formatNumber` | `boolean` | `false` | Nếu `true`, định dạng số theo ngữ cảnh ngôn ngữ. |
|
|
72
|
-
| `hideProgressingValue` | `boolean` | `false` | Ẩn nhãn giá trị động phía trên thanh trượt. |
|
|
73
|
-
| `classInclude` | `string` | `undefined` | Class CSS bổ sung cho container. |
|
|
127
|
+
@Component({
|
|
128
|
+
standalone: true,
|
|
129
|
+
imports: [LibsUiComponentsInputsRangeSliderComponent],
|
|
130
|
+
templateUrl: './config-panel.component.html',
|
|
131
|
+
})
|
|
132
|
+
export class ConfigPanelComponent {
|
|
133
|
+
protected pageSize = signal<number>(20);
|
|
74
134
|
|
|
75
|
-
|
|
135
|
+
protected handlerPageSizeChange(value: number): void {
|
|
136
|
+
this.loadData(value);
|
|
137
|
+
}
|
|
76
138
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
139
|
+
private loadData(size: number): void {
|
|
140
|
+
// reload với pageSize mới
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
80
144
|
|
|
81
|
-
|
|
145
|
+
```html
|
|
146
|
+
<!-- config-panel.component.html -->
|
|
147
|
+
<libs_ui-components-inputs-range_slider
|
|
148
|
+
[(value)]="pageSize"
|
|
149
|
+
[min]="10"
|
|
150
|
+
[max]="100"
|
|
151
|
+
[step]="10"
|
|
152
|
+
[unit]="'rows'"
|
|
153
|
+
(outChange)="handlerPageSizeChange($event)">
|
|
154
|
+
</libs_ui-components-inputs-range_slider>
|
|
155
|
+
<p>Hiển thị {{ pageSize() }} hàng mỗi trang</p>
|
|
156
|
+
```
|
|
82
157
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
158
|
+
### Định dạng số — hiển thị số lớn dễ đọc
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
// price-filter.component.ts
|
|
162
|
+
import { Component, signal } from '@angular/core';
|
|
163
|
+
import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
|
|
164
|
+
|
|
165
|
+
@Component({
|
|
166
|
+
standalone: true,
|
|
167
|
+
imports: [LibsUiComponentsInputsRangeSliderComponent],
|
|
168
|
+
templateUrl: './price-filter.component.html',
|
|
169
|
+
})
|
|
170
|
+
export class PriceFilterComponent {
|
|
171
|
+
protected budget = signal<number>(5000000);
|
|
86
172
|
|
|
87
|
-
|
|
173
|
+
protected handlerBudgetChange(value: number): void {
|
|
174
|
+
this.filterProducts(value);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private filterProducts(maxPrice: number): void {
|
|
178
|
+
// filter sản phẩm theo giá
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```html
|
|
184
|
+
<!-- price-filter.component.html -->
|
|
185
|
+
<libs_ui-components-inputs-range_slider
|
|
186
|
+
[(value)]="budget"
|
|
187
|
+
[min]="0"
|
|
188
|
+
[max]="10000000"
|
|
189
|
+
[formatNumber]="true"
|
|
190
|
+
[unit]="'đ'"
|
|
191
|
+
(outChange)="handlerBudgetChange($event)">
|
|
192
|
+
</libs_ui-components-inputs-range_slider>
|
|
193
|
+
<!-- maxDisplay hiển thị "10,0" thay vì 10000000 -->
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Ẩn nhãn giá trị — chỉ thanh kéo đơn thuần
|
|
197
|
+
|
|
198
|
+
```html
|
|
199
|
+
<libs_ui-components-inputs-range_slider
|
|
200
|
+
[(value)]="brightness"
|
|
201
|
+
[min]="0"
|
|
202
|
+
[max]="100"
|
|
203
|
+
[hideProgressingValue]="true"
|
|
204
|
+
[unit]="'%'">
|
|
205
|
+
</libs_ui-components-inputs-range_slider>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Disabled — vô hiệu hoá tương tác
|
|
209
|
+
|
|
210
|
+
```html
|
|
211
|
+
<libs_ui-components-inputs-range_slider
|
|
212
|
+
[(value)]="readonlyValue"
|
|
213
|
+
[min]="0"
|
|
214
|
+
[max]="100"
|
|
215
|
+
[disable]="true">
|
|
216
|
+
</libs_ui-components-inputs-range_slider>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## @Input()
|
|
220
|
+
|
|
221
|
+
| Input | Type | Default | Mô tả | Ví dụ |
|
|
222
|
+
|---|---|---|---|---|
|
|
223
|
+
| `value` | `number` (model) | `0` | Giá trị hiện tại — dùng two-way binding `[(value)]`. Là Angular `model()` signal. | `[(value)]="volume"` |
|
|
224
|
+
| `mode` | `'audio' \| 'slider'` | `'slider'` | Chế độ hiển thị: `slider` có thanh nhãn Min/Value/Max; `audio` chỉ hiển thị thanh kéo tối giản (không nhãn, không padding top). | `[mode]="'audio'"` |
|
|
225
|
+
| `min` | `number` | `1` | Giá trị tối thiểu của khoảng. | `[min]="0"` |
|
|
226
|
+
| `max` | `number` | `100` | Giá trị tối đa của khoảng. | `[max]="200"` |
|
|
227
|
+
| `step` | `number` | `0` | Bước nhảy khi kéo. `0` là kéo liên tục mượt mà. | `[step]="10"` |
|
|
228
|
+
| `unit` | `string` | `undefined` | Đơn vị đo hiển thị sau mỗi nhãn giá trị (Min, Value, Max). | `[unit]="'%'"` |
|
|
229
|
+
| `disable` | `boolean` | `false` | Vô hiệu hoá tương tác. Khi bằng `true`, người dùng không kéo được; giá trị được giữ nguyên dù có thao tác chuột. | `[disable]="true"` |
|
|
230
|
+
| `formatNumber` | `boolean` | `false` | Bật định dạng số cho nhãn Max (`maxDisplay`). Ví dụ: `10000` → `10,0`. Sử dụng `viewDataNumberByLanguage` từ `@libs-ui/utils`. | `[formatNumber]="true"` |
|
|
231
|
+
| `hideProgressingValue` | `boolean` | `undefined` | Ẩn nhãn giá trị hiện tại di chuyển theo thumb. Chỉ còn nhãn Min và Max cố định. | `[hideProgressingValue]="true"` |
|
|
232
|
+
| `classInclude` | `string` | `undefined` | Class CSS bổ sung cho div container ngoài cùng. Class `libs-ui-range-slider-container` luôn được giữ nguyên, giá trị truyền vào được nối thêm sau. | `[classInclude]="'mt-4 w-64'"` |
|
|
233
|
+
|
|
234
|
+
## @Output()
|
|
235
|
+
|
|
236
|
+
| Output | Type | Mô tả | Handler TS | Binding HTML |
|
|
237
|
+
|---|---|---|---|---|
|
|
238
|
+
| `(outChange)` | `number` | Phát ra giá trị mới sau khi người dùng kéo. Được debounce 250ms — không phát liên tục khi đang kéo. Với mode `audio`, sự kiện bị skip lần emit đầu tiên (khi khởi tạo). | `handlerChange(value: number): void { value; }` | `(outChange)="handlerChange($event)"` |
|
|
239
|
+
|
|
240
|
+
## Logic ngầm quan trọng
|
|
241
|
+
|
|
242
|
+
### Tính toán vị trí nhãn giá trị (Tooltip Position)
|
|
243
|
+
|
|
244
|
+
Nhãn giá trị hiện tại được định vị tuyệt đối bên dưới thanh kéo. Vị trí (left) được tính dựa trên tỷ lệ % của giá trị trong khoảng `[min, max]`, nhân với chiều rộng container, rồi trừ đi nửa chiều rộng của chính nhãn để căn giữa. Có xử lý thêm để nhãn không tràn ra ngoài phạm vi container.
|
|
245
|
+
|
|
246
|
+
### Xử lý chồng lấp nhãn (Overlap Detection)
|
|
247
|
+
|
|
248
|
+
Sử dụng `getBoundingClientRect()` để so sánh vị trí thực tế của nhãn giá trị hiện tại với nhãn Min và Max. Khi nhãn giá trị chạm đến vùng Min hoặc Max, nhãn tương ứng sẽ bị ẩn đi (qua signal `visibilityMin` / `visibilityMax`). Khi `value = 0`, nhãn Min tự động ẩn.
|
|
249
|
+
|
|
250
|
+
### CSS Variables Progress
|
|
251
|
+
|
|
252
|
+
Phần màu tiến trình (màu xanh đã kéo) không dùng JavaScript để cập nhật DOM trực tiếp mà thông qua CSS custom property `--libs-ui-slider-value` được set theo phần trăm. Hiệu ứng hover/focus đổi màu thanh trượt nhạt hơn thông qua `--libs-ui-slider-border-box-shadow`.
|
|
253
|
+
|
|
254
|
+
### Debounce Output
|
|
255
|
+
|
|
256
|
+
`outChange` được pipe qua `debounceTime(250)`. Khi người dùng kéo liên tục, chỉ sau khi dừng kéo 250ms thì giá trị mới được emit, tránh gọi API hoặc tính toán nặng liên tục trong khi kéo. Với mode `audio`, skip 1 lần emit đầu (khi component init) để tránh trigger seek không cần thiết.
|
|
257
|
+
|
|
258
|
+
## Lưu ý quan trọng
|
|
259
|
+
|
|
260
|
+
⚠️ **Two-way binding bắt buộc**: `value` là Angular `model()` signal — phải dùng `[(value)]` để đọc giá trị từ bên ngoài và nhận cập nhật ngược lại từ component. Nếu chỉ dùng `[value]` (một chiều), giá trị trong template ngoài sẽ không tự cập nhật.
|
|
261
|
+
|
|
262
|
+
⚠️ **Debounce 250ms**: `outChange` không phát theo thời gian thực khi đang kéo. Nếu cần phản hồi tức thì (ví dụ: preview màu sắc), hãy đọc trực tiếp signal `[(value)]` thay vì lắng nghe `outChange`.
|
|
263
|
+
|
|
264
|
+
⚠️ **mode audio không có nhãn**: Khi `mode="audio"`, component không render phần nhãn Min/Value/Max và có chiều cao nhỏ hơn (22px thay vì 44px với padding top). Các input `unit`, `hideProgressingValue`, `formatNumber` không có tác dụng trực quan trong mode này.
|
|
265
|
+
|
|
266
|
+
⚠️ **min mặc định là 1**: Giá trị mặc định của `min` là `1`, không phải `0`. Nếu cần khoảng bắt đầu từ `0`, phải truyền rõ `[min]="0"`.
|
|
267
|
+
|
|
268
|
+
⚠️ **disable giữ nguyên giá trị**: Khi `disable=true`, component chủ động override giá trị input về giá trị cũ ngay trong handler — người dùng không thể thay đổi bằng cách kéo dù DOM input không bị `disabled` attribute.
|
|
269
|
+
|
|
270
|
+
⚠️ **classInclude không ghi đè**: Class `libs-ui-range-slider-container` luôn được giữ lại trên container dù `classInclude` được truyền vào hay không. Các class truyền vào được nối thêm sau.
|
|
271
|
+
|
|
272
|
+
## Demo
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
npx nx serve core-ui
|
|
276
|
+
```
|
|
88
277
|
|
|
89
|
-
|
|
278
|
+
Truy cập: http://localhost:4500/components/inputs/range-slider
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, computed, input, model, output, viewChild, effect, untracked,
|
|
2
|
+
import { signal, computed, input, model, output, viewChild, effect, untracked, Component, ChangeDetectionStrategy } from '@angular/core';
|
|
3
3
|
import { viewDataNumberByLanguage } from '@libs-ui/utils';
|
|
4
4
|
import { Subject, fromEvent } from 'rxjs';
|
|
5
5
|
import { tap, takeUntil, skip, debounceTime } from 'rxjs/operators';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs-ui-components-inputs-range-slider.mjs","sources":["../../../../../../libs-ui/components/inputs/range-slider/src/inputs-range-slider.component.ts","../../../../../../libs-ui/components/inputs/range-slider/src/inputs-range-slider.component.html","../../../../../../libs-ui/components/inputs/range-slider/src/libs-ui-components-inputs-range-slider.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, OnDestroy, computed, effect, input, model, output, signal, untracked, viewChild } from '@angular/core';\nimport { IEvent } from '@libs-ui/interfaces-types';\nimport { viewDataNumberByLanguage } from '@libs-ui/utils';\nimport { Observable, Subject, fromEvent } from 'rxjs';\nimport { debounceTime, skip, takeUntil, tap } from 'rxjs/operators';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-inputs-range_slider',\n templateUrl: 'inputs-range-slider.component.html',\n styleUrl: 'inputs-range-slider.component.scss',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsInputsRangeSliderComponent implements AfterViewInit, OnDestroy {\n // #region PROPERTY\n protected visibilityMin = signal<boolean>(true);\n protected visibilityMax = signal<boolean>(true);\n protected position = signal<number>(0);\n protected focus = signal<boolean>(false);\n protected maxDisplay = computed(this.maxComputed.bind(this));\n\n private readonly onChange = new Subject<number>();\n private readonly onDestroy = new Subject<void>();\n\n // #region INPUT\n readonly mode = input<'audio' | 'slider'>('slider');\n readonly min = input<number>(1);\n readonly max = input<number>(100);\n readonly value = model<number>(0);\n readonly classInclude = input<string, string | undefined>('libs-ui-range-slider-container', { transform: (value) => (value ? `libs-ui-range-slider-container ${value}` : 'libs-ui-range-slider-container') });\n readonly disable = input<boolean>(false);\n readonly unit = input<string>();\n readonly step = input<number>(0);\n readonly hideProgressingValue = input<boolean>();\n readonly formatNumber = input<boolean>();\n\n // #region OUTPUT\n readonly outChange = output<number>();\n\n /* VIEW CHILD */\n private readonly containerEl = viewChild<ElementRef>('containerEl');\n private readonly rangeEl = viewChild<ElementRef>('rangeEl');\n private readonly valueEl = viewChild<ElementRef>('valueEl');\n private readonly maxValueEl = viewChild<ElementRef>('maxValueEl');\n private readonly minValueEl = viewChild<ElementRef>('minValueEl');\n\n constructor() {\n effect(() => {\n this.onChange.next(this.value());\n untracked(() => {\n this.setVariableCss();\n this.calculatePosition();\n });\n });\n }\n\n /* FUNCTIONS */\n ngAfterViewInit(): void {\n this.initEvent(window as unknown as HTMLElement, 'mouseup').pipe(tap(() => this.focus.set(false)));\n this.initEvent(this.rangeEl()?.nativeElement, 'mousedown').pipe(tap(() => this.focus.set(true)));\n const inputChange = this.initEvent(this.rangeEl()?.nativeElement, 'input');\n\n inputChange.pipe(takeUntil(this.onDestroy)).subscribe(this.handlerChange.bind(this));\n this.onChange.pipe(skip(this.mode() === 'audio' ? 1 : 0), debounceTime(250), takeUntil(this.onDestroy)).subscribe((value: number) => this.outChange.emit(value));\n this.calculatePosition();\n }\n\n private initEvent(element: HTMLElement, name: string): Observable<IEvent> {\n return fromEvent<IEvent>(element, name).pipe(\n tap((e: IEvent) => e.stopPropagation()),\n takeUntil(this.onDestroy)\n );\n }\n\n private async handlerChange(event: IEvent) {\n if (this.disable()) {\n event.preventDefault();\n event.stopPropagation();\n event.target.value = this.value();\n\n return;\n }\n this.value.set(+event.target.value);\n this.onChange.next(this.value());\n }\n\n private async calculatePosition() {\n if (!this.containerEl() || !this.valueEl()) {\n return;\n }\n const sliderContainer = this.containerEl()?.nativeElement.getBoundingClientRect();\n const progressing = this.max() ? (this.value() - this.min()) / (this.max() - this.min()) : 0;\n\n if (this.hideProgressingValue()) {\n return;\n }\n const rectValue = this.valueEl()?.nativeElement.getBoundingClientRect();\n const rectMax = this.containerEl()?.nativeElement.getBoundingClientRect();\n\n this.position.set(sliderContainer.width * progressing - rectValue.width / 2 + ((progressing < 0.5 ? 1 : 0.5) - progressing) * 8);\n const grandWidthValue = this.position() + rectValue.width - rectMax.width;\n\n if (grandWidthValue > 0) {\n this.position.update((value) => value - grandWidthValue);\n }\n setTimeout(() => {\n this.setVisibility();\n });\n }\n\n private async setVisibility() {\n const rectMax = this.maxValueEl()?.nativeElement.getBoundingClientRect();\n const rectValue = this.valueEl()?.nativeElement.getBoundingClientRect();\n const rectMin = this.minValueEl()?.nativeElement.getBoundingClientRect();\n\n this.visibilityMin.set(true);\n this.visibilityMax.set(true);\n if (!this.value()) {\n this.visibilityMin.set(false);\n\n return;\n }\n if (rectValue.left + rectValue.width >= rectMax.left) {\n this.visibilityMax.set(false);\n }\n if (rectValue.left <= rectMin.width + rectMin.left) {\n this.visibilityMin.set(false);\n }\n }\n\n private async setVariableCss() {\n const element = this.containerEl()?.nativeElement;\n\n if (!element) {\n return;\n }\n const colorHover = getComputedStyle(element).getPropertyValue('--libs-ui-color-light-1');\n\n element.style.setProperty('--libs-ui-slider-border-box-shadow', `${colorHover}30`);\n const percent = (100 * (this.value() - this.min())) / (this.max() - this.min());\n element.style.setProperty('--libs-ui-slider-value', `${percent}%`);\n }\n\n protected maxComputed() {\n if (this.formatNumber()) {\n return viewDataNumberByLanguage(this.max(), true, 1, false, true);\n }\n\n return this.max();\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n}\n","<div\n [class]=\"classInclude()\"\n [style.height.px]=\"mode() === 'slider' ? 44 : 22\"\n [class.pt-[4px]]=\"mode() === 'slider'\"\n #containerEl>\n <div\n [class.hidden]=\"!focus()\"\n class=\"libs-ui-range-slider-icon-active\"></div>\n <input\n #rangeEl\n class=\"libs-ui-range-slider\"\n [attr.mode]=\"mode()\"\n [attr.focus]=\"focus()\"\n [attr.disable]=\"disable()\"\n [value]=\"value()\"\n [type]=\"'range'\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\" />\n @if (mode() === 'slider') {\n <div class=\"flex justify-between relative mt-[8px]\">\n <div\n #minValueEl\n class=\"libs-ui-font-h7r text-[#9ca2ad] flex\"\n [class.invisible]=\"!visibilityMin()\">\n {{ min() }}\n @if (unit()) {\n <span class=\"libs-ui-font-h7r text-[#9ca2ad]\">{{ unit() }}</span>\n }\n </div>\n <div\n #valueEl\n class=\"libs-ui-font-h7r text-[#9ca2ad] absolute bottom-0 flex\"\n [style.left.px]=\"position()\">\n @if (!hideProgressingValue()) {\n {{ value() }}\n @if (unit()) {\n <span class=\"libs-ui-font-h7r text-[#9ca2ad]\">{{ unit() }}</span>\n }\n }\n </div>\n <div\n #maxValueEl\n class=\"libs-ui-font-h7r text-[#9ca2ad] flex\"\n [class.invisible]=\"!visibilityMax()\">\n {{ maxComputed() }}\n @if (unit()) {\n <span class=\"libs-ui-font-h7r text-[#9ca2ad]\">{{ unit() }}</span>\n }\n </div>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"libs-ui-components-inputs-range-slider.mjs","sources":["../../../../../../libs-ui/components/inputs/range-slider/src/inputs-range-slider.component.ts","../../../../../../libs-ui/components/inputs/range-slider/src/inputs-range-slider.component.html","../../../../../../libs-ui/components/inputs/range-slider/src/libs-ui-components-inputs-range-slider.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, OnDestroy, computed, effect, input, model, output, signal, untracked, viewChild } from '@angular/core';\nimport { IEvent } from '@libs-ui/interfaces-types';\nimport { viewDataNumberByLanguage } from '@libs-ui/utils';\nimport { Observable, Subject, fromEvent } from 'rxjs';\nimport { debounceTime, skip, takeUntil, tap } from 'rxjs/operators';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-inputs-range_slider',\n templateUrl: 'inputs-range-slider.component.html',\n styleUrl: 'inputs-range-slider.component.scss',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiComponentsInputsRangeSliderComponent implements AfterViewInit, OnDestroy {\n // #region PROPERTY\n protected visibilityMin = signal<boolean>(true);\n protected visibilityMax = signal<boolean>(true);\n protected position = signal<number>(0);\n protected focus = signal<boolean>(false);\n protected maxDisplay = computed(this.maxComputed.bind(this));\n\n private readonly onChange = new Subject<number>();\n private readonly onDestroy = new Subject<void>();\n\n // #region INPUT\n readonly mode = input<'audio' | 'slider'>('slider');\n readonly min = input<number>(1);\n readonly max = input<number>(100);\n readonly value = model<number>(0);\n readonly classInclude = input<string, string | undefined>('libs-ui-range-slider-container', { transform: (value) => (value ? `libs-ui-range-slider-container ${value}` : 'libs-ui-range-slider-container') });\n readonly disable = input<boolean>(false);\n readonly unit = input<string>();\n readonly step = input<number>(0);\n readonly hideProgressingValue = input<boolean>();\n readonly formatNumber = input<boolean>();\n\n // #region OUTPUT\n readonly outChange = output<number>();\n\n /* VIEW CHILD */\n private readonly containerEl = viewChild<ElementRef>('containerEl');\n private readonly rangeEl = viewChild<ElementRef>('rangeEl');\n private readonly valueEl = viewChild<ElementRef>('valueEl');\n private readonly maxValueEl = viewChild<ElementRef>('maxValueEl');\n private readonly minValueEl = viewChild<ElementRef>('minValueEl');\n\n constructor() {\n effect(() => {\n this.onChange.next(this.value());\n untracked(() => {\n this.setVariableCss();\n this.calculatePosition();\n });\n });\n }\n\n /* FUNCTIONS */\n ngAfterViewInit(): void {\n this.initEvent(window as unknown as HTMLElement, 'mouseup').pipe(tap(() => this.focus.set(false)));\n this.initEvent(this.rangeEl()?.nativeElement, 'mousedown').pipe(tap(() => this.focus.set(true)));\n const inputChange = this.initEvent(this.rangeEl()?.nativeElement, 'input');\n\n inputChange.pipe(takeUntil(this.onDestroy)).subscribe(this.handlerChange.bind(this));\n this.onChange.pipe(skip(this.mode() === 'audio' ? 1 : 0), debounceTime(250), takeUntil(this.onDestroy)).subscribe((value: number) => this.outChange.emit(value));\n this.calculatePosition();\n }\n\n private initEvent(element: HTMLElement, name: string): Observable<IEvent> {\n return fromEvent<IEvent>(element, name).pipe(\n tap((e: IEvent) => e.stopPropagation()),\n takeUntil(this.onDestroy)\n );\n }\n\n private async handlerChange(event: IEvent) {\n if (this.disable()) {\n event.preventDefault();\n event.stopPropagation();\n event.target.value = this.value();\n\n return;\n }\n this.value.set(+event.target.value);\n this.onChange.next(this.value());\n }\n\n private async calculatePosition() {\n if (!this.containerEl() || !this.valueEl()) {\n return;\n }\n const sliderContainer = this.containerEl()?.nativeElement.getBoundingClientRect();\n const progressing = this.max() ? (this.value() - this.min()) / (this.max() - this.min()) : 0;\n\n if (this.hideProgressingValue()) {\n return;\n }\n const rectValue = this.valueEl()?.nativeElement.getBoundingClientRect();\n const rectMax = this.containerEl()?.nativeElement.getBoundingClientRect();\n\n this.position.set(sliderContainer.width * progressing - rectValue.width / 2 + ((progressing < 0.5 ? 1 : 0.5) - progressing) * 8);\n const grandWidthValue = this.position() + rectValue.width - rectMax.width;\n\n if (grandWidthValue > 0) {\n this.position.update((value) => value - grandWidthValue);\n }\n setTimeout(() => {\n this.setVisibility();\n });\n }\n\n private async setVisibility() {\n const rectMax = this.maxValueEl()?.nativeElement.getBoundingClientRect();\n const rectValue = this.valueEl()?.nativeElement.getBoundingClientRect();\n const rectMin = this.minValueEl()?.nativeElement.getBoundingClientRect();\n\n this.visibilityMin.set(true);\n this.visibilityMax.set(true);\n if (!this.value()) {\n this.visibilityMin.set(false);\n\n return;\n }\n if (rectValue.left + rectValue.width >= rectMax.left) {\n this.visibilityMax.set(false);\n }\n if (rectValue.left <= rectMin.width + rectMin.left) {\n this.visibilityMin.set(false);\n }\n }\n\n private async setVariableCss() {\n const element = this.containerEl()?.nativeElement;\n\n if (!element) {\n return;\n }\n const colorHover = getComputedStyle(element).getPropertyValue('--libs-ui-color-light-1');\n\n element.style.setProperty('--libs-ui-slider-border-box-shadow', `${colorHover}30`);\n const percent = (100 * (this.value() - this.min())) / (this.max() - this.min());\n element.style.setProperty('--libs-ui-slider-value', `${percent}%`);\n }\n\n protected maxComputed() {\n if (this.formatNumber()) {\n return viewDataNumberByLanguage(this.max(), true, 1, false, true);\n }\n\n return this.max();\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n}\n","<div\n [class]=\"classInclude()\"\n [style.height.px]=\"mode() === 'slider' ? 44 : 22\"\n [class.pt-[4px]]=\"mode() === 'slider'\"\n #containerEl>\n <div\n [class.hidden]=\"!focus()\"\n class=\"libs-ui-range-slider-icon-active\"></div>\n <input\n #rangeEl\n class=\"libs-ui-range-slider\"\n [attr.mode]=\"mode()\"\n [attr.focus]=\"focus()\"\n [attr.disable]=\"disable()\"\n [value]=\"value()\"\n [type]=\"'range'\"\n [min]=\"min()\"\n [max]=\"max()\"\n [step]=\"step()\" />\n @if (mode() === 'slider') {\n <div class=\"flex justify-between relative mt-[8px]\">\n <div\n #minValueEl\n class=\"libs-ui-font-h7r text-[#9ca2ad] flex\"\n [class.invisible]=\"!visibilityMin()\">\n {{ min() }}\n @if (unit()) {\n <span class=\"libs-ui-font-h7r text-[#9ca2ad]\">{{ unit() }}</span>\n }\n </div>\n <div\n #valueEl\n class=\"libs-ui-font-h7r text-[#9ca2ad] absolute bottom-0 flex\"\n [style.left.px]=\"position()\">\n @if (!hideProgressingValue()) {\n {{ value() }}\n @if (unit()) {\n <span class=\"libs-ui-font-h7r text-[#9ca2ad]\">{{ unit() }}</span>\n }\n }\n </div>\n <div\n #maxValueEl\n class=\"libs-ui-font-h7r text-[#9ca2ad] flex\"\n [class.invisible]=\"!visibilityMax()\">\n {{ maxComputed() }}\n @if (unit()) {\n <span class=\"libs-ui-font-h7r text-[#9ca2ad]\">{{ unit() }}</span>\n }\n </div>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;MAca,0CAA0C,CAAA;;AAE3C,IAAA,aAAa,GAAG,MAAM,CAAU,IAAI,CAAC,CAAC;AACtC,IAAA,aAAa,GAAG,MAAM,CAAU,IAAI,CAAC,CAAC;AACtC,IAAA,QAAQ,GAAG,MAAM,CAAS,CAAC,CAAC,CAAC;AAC7B,IAAA,KAAK,GAAG,MAAM,CAAU,KAAK,CAAC,CAAC;AAC/B,IAAA,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAE5C,IAAA,QAAQ,GAAG,IAAI,OAAO,EAAU,CAAC;AACjC,IAAA,SAAS,GAAG,IAAI,OAAO,EAAQ,CAAC;;AAGxC,IAAA,IAAI,GAAG,KAAK,CAAqB,QAAQ,CAAC,CAAC;AAC3C,IAAA,GAAG,GAAG,KAAK,CAAS,CAAC,CAAC,CAAC;AACvB,IAAA,GAAG,GAAG,KAAK,CAAS,GAAG,CAAC,CAAC;AACzB,IAAA,KAAK,GAAG,KAAK,CAAS,CAAC,CAAC,CAAC;AACzB,IAAA,YAAY,GAAG,KAAK,CAA6B,gCAAgC,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,MAAM,KAAK,GAAG,CAAkC,+BAAA,EAAA,KAAK,CAAE,CAAA,GAAG,gCAAgC,CAAC,EAAE,CAAC,CAAC;AACrM,IAAA,OAAO,GAAG,KAAK,CAAU,KAAK,CAAC,CAAC;IAChC,IAAI,GAAG,KAAK,EAAU,CAAC;AACvB,IAAA,IAAI,GAAG,KAAK,CAAS,CAAC,CAAC,CAAC;IACxB,oBAAoB,GAAG,KAAK,EAAW,CAAC;IACxC,YAAY,GAAG,KAAK,EAAW,CAAC;;IAGhC,SAAS,GAAG,MAAM,EAAU,CAAC;;AAGrB,IAAA,WAAW,GAAG,SAAS,CAAa,aAAa,CAAC,CAAC;AACnD,IAAA,OAAO,GAAG,SAAS,CAAa,SAAS,CAAC,CAAC;AAC3C,IAAA,OAAO,GAAG,SAAS,CAAa,SAAS,CAAC,CAAC;AAC3C,IAAA,UAAU,GAAG,SAAS,CAAa,YAAY,CAAC,CAAC;AACjD,IAAA,UAAU,GAAG,SAAS,CAAa,YAAY,CAAC,CAAC;AAElE,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACjC,SAAS,CAAC,MAAK;gBACb,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,IAAI,CAAC,iBAAiB,EAAE,CAAC;AAC3B,aAAC,CAAC,CAAC;AACL,SAAC,CAAC,CAAC;KACJ;;IAGD,eAAe,GAAA;QACb,IAAI,CAAC,SAAS,CAAC,MAAgC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnG,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjG,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;QAE3E,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAa,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACjK,IAAI,CAAC,iBAAiB,EAAE,CAAC;KAC1B;IAEO,SAAS,CAAC,OAAoB,EAAE,IAAY,EAAA;AAClD,QAAA,OAAO,SAAS,CAAS,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,CAC1C,GAAG,CAAC,CAAC,CAAS,KAAK,CAAC,CAAC,eAAe,EAAE,CAAC,EACvC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAC1B,CAAC;KACH;IAEO,MAAM,aAAa,CAAC,KAAa,EAAA;AACvC,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YAClB,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAElC,OAAO;SACR;AACD,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;KAClC;AAEO,IAAA,MAAM,iBAAiB,GAAA;AAC7B,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE;YAC1C,OAAO;SACR;QACD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC,qBAAqB,EAAE,CAAC;AAClF,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;AAE7F,QAAA,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE;YAC/B,OAAO;SACR;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,qBAAqB,EAAE,CAAC;QACxE,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC,qBAAqB,EAAE,CAAC;AAE1E,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,GAAG,WAAW,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,WAAW,IAAI,CAAC,CAAC,CAAC;AACjI,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;AAE1E,QAAA,IAAI,eAAe,GAAG,CAAC,EAAE;AACvB,YAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,GAAG,eAAe,CAAC,CAAC;SAC1D;QACD,UAAU,CAAC,MAAK;YACd,IAAI,CAAC,aAAa,EAAE,CAAC;AACvB,SAAC,CAAC,CAAC;KACJ;AAEO,IAAA,MAAM,aAAa,GAAA;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,qBAAqB,EAAE,CAAC;QACzE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,qBAAqB,EAAE,CAAC;QACxE,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,qBAAqB,EAAE,CAAC;AAEzE,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE;AACjB,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAE9B,OAAO;SACR;AACD,QAAA,IAAI,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE;AACpD,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAC/B;AACD,QAAA,IAAI,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE;AAClD,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAC/B;KACF;AAEO,IAAA,MAAM,cAAc,GAAA;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC;QAElD,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO;SACR;QACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;QAEzF,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,oCAAoC,EAAE,CAAG,EAAA,UAAU,CAAI,EAAA,CAAA,CAAC,CAAC;AACnF,QAAA,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAChF,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,wBAAwB,EAAE,CAAG,EAAA,OAAO,CAAG,CAAA,CAAA,CAAC,CAAC;KACpE;IAES,WAAW,GAAA;AACnB,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE;AACvB,YAAA,OAAO,wBAAwB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;SACnE;AAED,QAAA,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;KACnB;IAED,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;KAC3B;wGA7IU,0CAA0C,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA1C,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,0CAA0C,67DCdvD,qiDAqDA,EAAA,MAAA,EAAA,CAAA,0yFAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FDvCa,0CAA0C,EAAA,UAAA,EAAA,CAAA;kBARtD,SAAS;AAEE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wCAAwC,EAGtC,UAAA,EAAA,IAAI,EACC,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,qiDAAA,EAAA,MAAA,EAAA,CAAA,0yFAAA,CAAA,EAAA,CAAA;;;AEZjD;;AAEG;;;;"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libs-ui/components-inputs-range-slider",
|
|
3
|
-
"version": "0.2.356-
|
|
3
|
+
"version": "0.2.356-43",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/core": ">=18.0.0",
|
|
6
|
-
"@libs-ui/interfaces-types": "0.2.356-
|
|
7
|
-
"@libs-ui/utils": "0.2.356-
|
|
6
|
+
"@libs-ui/interfaces-types": "0.2.356-43",
|
|
7
|
+
"@libs-ui/utils": "0.2.356-43",
|
|
8
8
|
"rxjs": "~7.8.0"
|
|
9
9
|
},
|
|
10
10
|
"sideEffects": false,
|