ngx-kit 5.0.0 → 6.0.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.
Files changed (68) hide show
  1. package/README.md +3 -2
  2. package/angle-selector/README.md +34 -0
  3. package/box-shadow/README.md +33 -0
  4. package/color-picker/README.md +52 -0
  5. package/data-table/README.md +120 -0
  6. package/date-picker/README.md +74 -0
  7. package/dialog/README.md +94 -169
  8. package/drawer-menu/README.md +76 -0
  9. package/dropzone/README.md +59 -0
  10. package/fesm2022/ngx-kit-angle-selector.mjs +2 -2
  11. package/fesm2022/ngx-kit-angle-selector.mjs.map +1 -1
  12. package/fesm2022/ngx-kit-box-shadow.mjs +28 -27
  13. package/fesm2022/ngx-kit-box-shadow.mjs.map +1 -1
  14. package/fesm2022/ngx-kit-color-picker.mjs +173 -43
  15. package/fesm2022/ngx-kit-color-picker.mjs.map +1 -1
  16. package/fesm2022/ngx-kit-data-table.mjs +9 -2
  17. package/fesm2022/ngx-kit-data-table.mjs.map +1 -1
  18. package/fesm2022/ngx-kit-date-picker.mjs +120 -86
  19. package/fesm2022/ngx-kit-date-picker.mjs.map +1 -1
  20. package/fesm2022/ngx-kit-dialog.mjs +38 -7
  21. package/fesm2022/ngx-kit-dialog.mjs.map +1 -1
  22. package/fesm2022/ngx-kit-drawer-menu.mjs +190 -0
  23. package/fesm2022/ngx-kit-drawer-menu.mjs.map +1 -0
  24. package/fesm2022/ngx-kit-dropzone.mjs +272 -0
  25. package/fesm2022/ngx-kit-dropzone.mjs.map +1 -0
  26. package/fesm2022/ngx-kit-form-field.mjs +87 -0
  27. package/fesm2022/ngx-kit-form-field.mjs.map +1 -0
  28. package/fesm2022/ngx-kit-gallery.mjs +419 -0
  29. package/fesm2022/ngx-kit-gallery.mjs.map +1 -0
  30. package/fesm2022/ngx-kit-gradient-picker.mjs +12 -4
  31. package/fesm2022/ngx-kit-gradient-picker.mjs.map +1 -1
  32. package/fesm2022/ngx-kit-image-editor.mjs +501 -0
  33. package/fesm2022/ngx-kit-image-editor.mjs.map +1 -0
  34. package/fesm2022/ngx-kit-menu.mjs +9 -4
  35. package/fesm2022/ngx-kit-menu.mjs.map +1 -1
  36. package/fesm2022/ngx-kit-message.mjs +50 -24
  37. package/fesm2022/ngx-kit-message.mjs.map +1 -1
  38. package/fesm2022/ngx-kit-notify.mjs +1 -4
  39. package/fesm2022/ngx-kit-notify.mjs.map +1 -1
  40. package/fesm2022/ngx-kit-shared.mjs +126 -83
  41. package/fesm2022/ngx-kit-shared.mjs.map +1 -1
  42. package/fesm2022/ngx-kit-time-picker.mjs +562 -0
  43. package/fesm2022/ngx-kit-time-picker.mjs.map +1 -0
  44. package/fesm2022/ngx-kit.mjs.map +1 -1
  45. package/gallery/README.md +71 -0
  46. package/gradient-picker/README.md +41 -0
  47. package/image-editor/README.md +44 -0
  48. package/menu/README.md +85 -0
  49. package/message/README.md +70 -0
  50. package/notify/README.md +56 -0
  51. package/package.json +25 -1
  52. package/shared/README.md +117 -0
  53. package/styles/all.css +27 -0
  54. package/styles/image-viewer.css +12 -0
  55. package/types/ngx-kit-box-shadow.d.ts +1 -2
  56. package/types/ngx-kit-data-table.d.ts +1 -0
  57. package/types/ngx-kit-date-picker.d.ts +1 -1
  58. package/types/ngx-kit-dialog.d.ts +1 -0
  59. package/types/ngx-kit-drawer-menu.d.ts +101 -0
  60. package/types/ngx-kit-dropzone.d.ts +84 -0
  61. package/types/ngx-kit-form-field.d.ts +31 -0
  62. package/types/ngx-kit-gallery.d.ts +168 -0
  63. package/types/ngx-kit-image-editor.d.ts +175 -0
  64. package/types/ngx-kit-menu.d.ts +1 -0
  65. package/types/ngx-kit-message.d.ts +13 -3
  66. package/types/ngx-kit-notify.d.ts +0 -1
  67. package/types/ngx-kit-shared.d.ts +44 -13
  68. package/types/ngx-kit-time-picker.d.ts +150 -0
@@ -1,7 +1,7 @@
1
1
  import * as i1 from '@angular/common';
2
2
  import { CommonModule, isPlatformBrowser, DOCUMENT } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { EventEmitter, forwardRef, HostListener, ViewChild, Output, Input, ChangeDetectionStrategy, Component, InjectionToken, PLATFORM_ID, Inject, Injectable, inject, DestroyRef, signal, computed } from '@angular/core';
4
+ import { EventEmitter, forwardRef, HostListener, ViewChild, Output, Input, ChangeDetectionStrategy, Component, inject, ChangeDetectorRef, InjectionToken, PLATFORM_ID, Inject, Injectable, DestroyRef, signal, computed } from '@angular/core';
5
5
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl, Validators } from '@angular/forms';
6
6
 
7
7
  function getOffsetPosition(evt, parent) {
@@ -24,6 +24,37 @@ function getOffsetPosition(evt, parent) {
24
24
  return position;
25
25
  }
26
26
 
27
+ /** با فراخوانی این تابع (مثلاً داخل dragStart) یک نشست‌ درگ شروع می‌شه. */
28
+ function startDragSession({ onMove, onEnd }) {
29
+ const handleMove = (ev) => {
30
+ if (ev.type === 'touchmove') {
31
+ // جلوگیری از اسکرول شدن صفحه هم‌زمان با درگ کردن روی موبایل/تاچ
32
+ ev.preventDefault();
33
+ }
34
+ onMove(ev);
35
+ };
36
+ const handleEnd = (ev) => {
37
+ stop();
38
+ onEnd?.(ev);
39
+ };
40
+ const stop = () => {
41
+ document.removeEventListener('mousemove', handleMove);
42
+ document.removeEventListener('touchmove', handleMove);
43
+ document.removeEventListener('mouseup', handleEnd);
44
+ document.removeEventListener('touchend', handleEnd);
45
+ document.removeEventListener('touchcancel', handleEnd);
46
+ };
47
+ document.addEventListener('mousemove', handleMove);
48
+ document.addEventListener('touchmove', handleMove, { passive: false });
49
+ document.addEventListener('mouseup', handleEnd);
50
+ document.addEventListener('touchend', handleEnd);
51
+ document.addEventListener('touchcancel', handleEnd);
52
+ // تابع stop برگردونده می‌شه تا هم بشه دستی صداش زد (مثلاً در ngOnDestroy،
53
+ // اگه کامپوننت درست وسط یه درگ نابود بشه) و هم به‌صورت خودکار روی
54
+ // mouseup/touchend صدا زده می‌شه.
55
+ return stop;
56
+ }
57
+
27
58
  class ValueModel {
28
59
  id;
29
60
  value;
@@ -75,10 +106,14 @@ class RangeSliderComponent {
75
106
  _validatorOnChange = () => { };
76
107
  sliderRect;
77
108
  thumbRect;
109
+ stopDrag;
78
110
  constructor(changeDetectorRef) {
79
111
  this.changeDetectorRef = changeDetectorRef;
80
112
  }
81
113
  ngOnInit() { }
114
+ ngOnDestroy() {
115
+ this.stopDrag?.();
116
+ }
82
117
  generateId() {
83
118
  let id = 'ngx-thumb-' + Math.random().toString(36).substring(2, 9);
84
119
  if (this.values.findIndex((x) => x.id == id) >= 0) {
@@ -132,11 +167,6 @@ class RangeSliderComponent {
132
167
  this.thumbRect = this.thumb.nativeElement.getBoundingClientRect();
133
168
  }
134
169
  }
135
- onDrag(ev) {
136
- if (!this.isDragging)
137
- return;
138
- this.updateThumbPosition(ev);
139
- }
140
170
  onResize() {
141
171
  this.writeValue(this.values);
142
172
  }
@@ -148,6 +178,15 @@ class RangeSliderComponent {
148
178
  this.updateRects();
149
179
  this.updateThumbPosition(ev);
150
180
  this.selectedIndexChange.emit(this.selectedIndex);
181
+ this.stopDrag?.();
182
+ this.stopDrag = startDragSession({
183
+ onMove: (moveEv) => this.updateThumbPosition(moveEv),
184
+ onEnd: () => {
185
+ this.isDragging = false;
186
+ this.stopDrag = undefined;
187
+ this.changeDetectorRef.markForCheck();
188
+ },
189
+ });
151
190
  }
152
191
  addnewRangeOnSliderClick(event) {
153
192
  if (!this.addNewRangeOnClick)
@@ -185,6 +224,7 @@ class RangeSliderComponent {
185
224
  thumb.x = position.x;
186
225
  }
187
226
  this.setValueByPosition(thumb, thumbRec, sliderRec);
227
+ this.changeDetectorRef.markForCheck();
188
228
  }
189
229
  updateAllThumbPositions() {
190
230
  // wait to add thumbs
@@ -193,7 +233,8 @@ class RangeSliderComponent {
193
233
  const sliderRec = this.sliderRect;
194
234
  const thumbRec = this.thumbRect;
195
235
  for (let item of this.values) {
196
- item.x = ((item.value - this.min) * (sliderRec.width - thumbRec.width)) / (this.max - this.min);
236
+ item.x =
237
+ ((item.value - this.min) * (sliderRec.width - thumbRec.width)) / (this.max - this.min);
197
238
  }
198
239
  this.changeDetectorRef.detectChanges();
199
240
  });
@@ -209,17 +250,13 @@ class RangeSliderComponent {
209
250
  this.valueChanged();
210
251
  }
211
252
  }
212
- onDragEnd(ev) {
213
- this.isDragging = false;
214
- // this.selectedIndex = undefined;
215
- }
216
253
  valueChanged() {
217
254
  const v = this.values; // this.values.map(({ x, thumb, ...rest }) => ({ ...rest }));
218
255
  this._onChange(v);
219
256
  this.change.emit(v);
220
257
  }
221
258
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: RangeSliderComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
222
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: RangeSliderComponent, isStandalone: true, selector: "range-slider", inputs: { step: "step", min: "min", max: "max", background: "background", isBgTransparent: "isBgTransparent", addNewRangeOnClick: "addNewRangeOnClick", selectedIndex: "selectedIndex" }, outputs: { change: "change", selectedIndexChange: "selectedIndexChange" }, host: { listeners: { "document:mousemove": "onDrag($event)", "document:touchmove": "onDrag($event)", "window:resize": "onResize()", "document:mouseup": "onDragEnd($event)", "document:touchend": "onDragEnd($event)" } }, providers: [
259
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: RangeSliderComponent, isStandalone: true, selector: "range-slider", inputs: { step: "step", min: "min", max: "max", background: "background", isBgTransparent: "isBgTransparent", addNewRangeOnClick: "addNewRangeOnClick", selectedIndex: "selectedIndex" }, outputs: { change: "change", selectedIndexChange: "selectedIndexChange" }, host: { listeners: { "window:resize": "onResize()" } }, providers: [
223
260
  {
224
261
  provide: NG_VALUE_ACCESSOR,
225
262
  useExisting: forwardRef(() => RangeSliderComponent),
@@ -230,7 +267,7 @@ class RangeSliderComponent {
230
267
  useExisting: forwardRef(() => RangeSliderComponent),
231
268
  multi: true,
232
269
  },
233
- ], viewQueries: [{ propertyName: "slider", first: true, predicate: ["slider"], descendants: true, static: true }, { propertyName: "thumb", first: true, predicate: ["thumb"], descendants: true }], ngImport: i0, template: "<div class=\"slider-container\">\r\n <ng-content></ng-content>\r\n <div\r\n #slider\r\n class=\"slider\"\r\n [class.add-range-cursor]=\"addNewRangeOnClick\"\r\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\r\n [class.bg-transparent]=\"isBgTransparent\"\r\n (mousedown)=\"addnewRangeOnSliderClick($event)\"\r\n (touchstart)=\"addnewRangeOnSliderClick($event)\">\r\n @for (item of values; track $index; let i = $index) {\r\n <div\r\n class=\"thumb\"\r\n [class.is-active]=\"selectedIndex == i\"\r\n #thumb\r\n [style.left.px]=\"item.x\"\r\n [style.background]=\"item.color\"\r\n [title]=\"item.value\"\r\n (mousedown)=\"dragStart($event, i)\"\r\n (touchstart)=\"dragStart($event, i)\"></div>\r\n }\r\n </div>\r\n</div>\r\n\r\n<!-- {{ selectedIndex }}\r\n<pre dir=\"ltr\" style=\"text-align: left\">{{ values | json }}</pre> -->\r\n\r\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .slider.add-range-cursor{cursor:copy}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}.slider-container .thumb.is-active{outline:1px rgb(89,0,255) solid}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
270
+ ], viewQueries: [{ propertyName: "slider", first: true, predicate: ["slider"], descendants: true, static: true }, { propertyName: "thumb", first: true, predicate: ["thumb"], descendants: true }], ngImport: i0, template: "<div class=\"slider-container\">\n <ng-content></ng-content>\n <div\n #slider\n class=\"slider\"\n [class.add-range-cursor]=\"addNewRangeOnClick\"\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\n [class.bg-transparent]=\"isBgTransparent\"\n (mousedown)=\"addnewRangeOnSliderClick($event)\"\n (touchstart)=\"addnewRangeOnSliderClick($event)\">\n @for (item of values; track $index; let i = $index) {\n <div\n class=\"thumb\"\n [class.is-active]=\"selectedIndex == i\"\n #thumb\n [style.left.px]=\"item.x\"\n [style.background]=\"item.color\"\n [title]=\"item.value\"\n (mousedown)=\"dragStart($event, i)\"\n (touchstart)=\"dragStart($event, i)\"></div>\n }\n </div>\n</div>\n\n<!-- {{ selectedIndex }}\n<pre dir=\"ltr\" style=\"text-align: left\">{{ values | json }}</pre> -->\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .slider.add-range-cursor{cursor:copy}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}.slider-container .thumb.is-active{outline:1px rgb(89,0,255) solid}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
234
271
  }
235
272
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: RangeSliderComponent, decorators: [{
236
273
  type: Component,
@@ -245,7 +282,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
245
282
  useExisting: forwardRef(() => RangeSliderComponent),
246
283
  multi: true,
247
284
  },
248
- ], template: "<div class=\"slider-container\">\r\n <ng-content></ng-content>\r\n <div\r\n #slider\r\n class=\"slider\"\r\n [class.add-range-cursor]=\"addNewRangeOnClick\"\r\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\r\n [class.bg-transparent]=\"isBgTransparent\"\r\n (mousedown)=\"addnewRangeOnSliderClick($event)\"\r\n (touchstart)=\"addnewRangeOnSliderClick($event)\">\r\n @for (item of values; track $index; let i = $index) {\r\n <div\r\n class=\"thumb\"\r\n [class.is-active]=\"selectedIndex == i\"\r\n #thumb\r\n [style.left.px]=\"item.x\"\r\n [style.background]=\"item.color\"\r\n [title]=\"item.value\"\r\n (mousedown)=\"dragStart($event, i)\"\r\n (touchstart)=\"dragStart($event, i)\"></div>\r\n }\r\n </div>\r\n</div>\r\n\r\n<!-- {{ selectedIndex }}\r\n<pre dir=\"ltr\" style=\"text-align: left\">{{ values | json }}</pre> -->\r\n\r\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .slider.add-range-cursor{cursor:copy}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}.slider-container .thumb.is-active{outline:1px rgb(89,0,255) solid}\n"] }]
285
+ ], template: "<div class=\"slider-container\">\n <ng-content></ng-content>\n <div\n #slider\n class=\"slider\"\n [class.add-range-cursor]=\"addNewRangeOnClick\"\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\n [class.bg-transparent]=\"isBgTransparent\"\n (mousedown)=\"addnewRangeOnSliderClick($event)\"\n (touchstart)=\"addnewRangeOnSliderClick($event)\">\n @for (item of values; track $index; let i = $index) {\n <div\n class=\"thumb\"\n [class.is-active]=\"selectedIndex == i\"\n #thumb\n [style.left.px]=\"item.x\"\n [style.background]=\"item.color\"\n [title]=\"item.value\"\n (mousedown)=\"dragStart($event, i)\"\n (touchstart)=\"dragStart($event, i)\"></div>\n }\n </div>\n</div>\n\n<!-- {{ selectedIndex }}\n<pre dir=\"ltr\" style=\"text-align: left\">{{ values | json }}</pre> -->\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .slider.add-range-cursor{cursor:copy}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}.slider-container .thumb.is-active{outline:1px rgb(89,0,255) solid}\n"] }]
249
286
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { step: [{
250
287
  type: Input
251
288
  }], min: [{
@@ -270,21 +307,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
270
307
  }], thumb: [{
271
308
  type: ViewChild,
272
309
  args: ['thumb', { static: false }]
273
- }], onDrag: [{
274
- type: HostListener,
275
- args: ['document:mousemove', ['$event']]
276
- }, {
277
- type: HostListener,
278
- args: ['document:touchmove', ['$event']]
279
310
  }], onResize: [{
280
311
  type: HostListener,
281
312
  args: ['window:resize']
282
- }], onDragEnd: [{
283
- type: HostListener,
284
- args: ['document:mouseup', ['$event']]
285
- }, {
286
- type: HostListener,
287
- args: ['document:touchend', ['$event']]
288
313
  }] } });
289
314
 
290
315
  class SaturationComponent {
@@ -307,7 +332,15 @@ class SaturationComponent {
307
332
  _validatorOnChange = () => { };
308
333
  saturationRect;
309
334
  thumbRect;
335
+ stopDrag;
310
336
  constructor() { }
337
+ ngOnDestroy() {
338
+ // اگه کامپوننت درست وسط یه درگ نابود بشه (مثلاً پیکر بسته بشه)، باید
339
+ // listenerهای document رو دستی پاک کنیم؛ برخلاف @HostListener که
340
+ // انگیولار خودش موقع destroy پاکش می‌کرد، این‌جا چون addEventListener
341
+ // دستیه، خودمون مسئول پاک‌سازی‌شیم.
342
+ this.stopDrag?.();
343
+ }
311
344
  updateRects() {
312
345
  this.saturationRect = this.saturation.nativeElement.getBoundingClientRect();
313
346
  this.thumbRect = this.thumb.nativeElement.getBoundingClientRect();
@@ -320,8 +353,12 @@ class SaturationComponent {
320
353
  this.updateRects();
321
354
  const saturationRec = this.saturationRect;
322
355
  const thumbRec = this.thumbRect;
323
- this.x = ((value.x - this.min.x) * (saturationRec.width - thumbRec.width / 2)) / (this.max.x - this.min.x);
324
- this.y = ((value.y - this.min.y) * (saturationRec.height - thumbRec.height / 2)) / (this.max.y - this.min.y);
356
+ this.x =
357
+ ((value.x - this.min.x) * (saturationRec.width - thumbRec.width / 2)) /
358
+ (this.max.x - this.min.x);
359
+ this.y =
360
+ ((value.y - this.min.y) * (saturationRec.height - thumbRec.height / 2)) /
361
+ (this.max.y - this.min.y);
325
362
  if (val !== value) {
326
363
  this.valueChanged(value);
327
364
  }
@@ -351,15 +388,18 @@ class SaturationComponent {
351
388
  this.isDragging = true;
352
389
  this.updateRects();
353
390
  this.updatePosition(ev);
391
+ this.stopDrag?.();
392
+ this.stopDrag = startDragSession({
393
+ onMove: (moveEv) => this.updatePosition(moveEv),
394
+ onEnd: () => {
395
+ this.isDragging = false;
396
+ this.stopDrag = undefined;
397
+ },
398
+ });
354
399
  }
355
400
  onResize() {
356
401
  this.writeValue(this.myControl.value);
357
402
  }
358
- onDrag(ev) {
359
- if (!this.isDragging)
360
- return;
361
- this.updatePosition(ev);
362
- }
363
403
  updatePosition(ev) {
364
404
  if (!this.isDragging)
365
405
  return;
@@ -390,9 +430,6 @@ class SaturationComponent {
390
430
  // this.y = this.y - thumbRec.height / 2;
391
431
  this.setValueByPosition(thumbRec, saturationRec);
392
432
  }
393
- onDragEnd(ev) {
394
- this.isDragging = false;
395
- }
396
433
  setValueByPosition(thumbRec, saturationRec) {
397
434
  const percentageX = this.x / (saturationRec.width - thumbRec.width);
398
435
  let newValueX = this.min.x + percentageX * (this.max.x - this.min.x);
@@ -404,7 +441,9 @@ class SaturationComponent {
404
441
  newValueY = Math.round(newValueY / this.step) * this.step;
405
442
  let valueY = Math.min(Math.max(newValueY, this.min.y), this.max.y);
406
443
  const newValue = { x: valueX, y: valueY };
407
- if (!this.myControl.value || this.myControl.value.x !== valueX || this.myControl.value.y !== valueY) {
444
+ if (!this.myControl.value ||
445
+ this.myControl.value.x !== valueX ||
446
+ this.myControl.value.y !== valueY) {
408
447
  this.valueChanged(newValue);
409
448
  }
410
449
  }
@@ -414,13 +453,13 @@ class SaturationComponent {
414
453
  this.change.emit(value);
415
454
  }
416
455
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SaturationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
417
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: SaturationComponent, isStandalone: true, selector: "saturation", inputs: { width: "width", height: "height", color: "color", step: "step", min: "min", max: "max" }, outputs: { change: "change" }, host: { listeners: { "window:resize": "onResize()", "document:mousemove": "onDrag($event)", "document:touchmove": "onDrag($event)", "document:mouseup": "onDragEnd($event)", "document:touchend": "onDragEnd($event)" } }, providers: [
456
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: SaturationComponent, isStandalone: true, selector: "saturation", inputs: { width: "width", height: "height", color: "color", step: "step", min: "min", max: "max" }, outputs: { change: "change" }, host: { listeners: { "window:resize": "onResize()" } }, providers: [
418
457
  {
419
458
  provide: NG_VALUE_ACCESSOR,
420
459
  useExisting: forwardRef(() => SaturationComponent),
421
460
  multi: true,
422
461
  },
423
- ], viewQueries: [{ propertyName: "saturation", first: true, predicate: ["saturation"], descendants: true, static: true }, { propertyName: "thumb", first: true, predicate: ["thumb"], descendants: true, static: true }], ngImport: i0, template: "<div\r\n class=\"saturation-container\"\r\n [style.width.px]=\"width\"\r\n [style.height.px]=\"height\"\r\n (mousedown)=\"dragStart($event)\"\r\n (touchstart)=\"dragStart($event)\">\r\n <div class=\"saturation\" #saturation>\r\n <div class=\"s-bg\" [style.background]=\"color\"></div>\r\n <div class=\"s-white\"></div>\r\n <div class=\"s-black\"></div>\r\n </div>\r\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [style.top.px]=\"y\"></div>\r\n</div>\r\n", styles: [".saturation-container{position:relative;width:100%;height:200px}.saturation-container .thumb{border:3px #000000 solid;box-shadow:inset 0 0 0 2px #fff;width:12px;height:12px;display:block;border-radius:10px;position:absolute;pointer-events:none;cursor:pointer}.saturation{position:absolute;inset:6px;border-radius:4px;overflow:hidden}.saturation .s-white,.saturation .s-black,.saturation .s-bg{position:absolute;inset:0}.saturation .s-white{background:linear-gradient(to right,#fff,#fff0)}.saturation .s-black{background:linear-gradient(to bottom,#0000,#000)}\n"] });
462
+ ], viewQueries: [{ propertyName: "saturation", first: true, predicate: ["saturation"], descendants: true, static: true }, { propertyName: "thumb", first: true, predicate: ["thumb"], descendants: true, static: true }], ngImport: i0, template: "<div\n class=\"saturation-container\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n (mousedown)=\"dragStart($event)\"\n (touchstart)=\"dragStart($event)\">\n <div class=\"saturation\" #saturation>\n <div class=\"s-bg\" [style.background]=\"color\"></div>\n <div class=\"s-white\"></div>\n <div class=\"s-black\"></div>\n </div>\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [style.top.px]=\"y\"></div>\n</div>\n", styles: [".saturation-container{position:relative;width:100%;height:200px}.saturation-container .thumb{border:3px #000000 solid;box-shadow:inset 0 0 0 2px #fff;width:12px;height:12px;display:block;border-radius:10px;position:absolute;pointer-events:none;cursor:pointer}.saturation{position:absolute;inset:6px;border-radius:4px;overflow:hidden}.saturation .s-white,.saturation .s-black,.saturation .s-bg{position:absolute;inset:0}.saturation .s-white{background:linear-gradient(to right,#fff,#fff0)}.saturation .s-black{background:linear-gradient(to bottom,#0000,#000)}\n"] });
424
463
  }
425
464
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SaturationComponent, decorators: [{
426
465
  type: Component,
@@ -430,7 +469,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
430
469
  useExisting: forwardRef(() => SaturationComponent),
431
470
  multi: true,
432
471
  },
433
- ], template: "<div\r\n class=\"saturation-container\"\r\n [style.width.px]=\"width\"\r\n [style.height.px]=\"height\"\r\n (mousedown)=\"dragStart($event)\"\r\n (touchstart)=\"dragStart($event)\">\r\n <div class=\"saturation\" #saturation>\r\n <div class=\"s-bg\" [style.background]=\"color\"></div>\r\n <div class=\"s-white\"></div>\r\n <div class=\"s-black\"></div>\r\n </div>\r\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [style.top.px]=\"y\"></div>\r\n</div>\r\n", styles: [".saturation-container{position:relative;width:100%;height:200px}.saturation-container .thumb{border:3px #000000 solid;box-shadow:inset 0 0 0 2px #fff;width:12px;height:12px;display:block;border-radius:10px;position:absolute;pointer-events:none;cursor:pointer}.saturation{position:absolute;inset:6px;border-radius:4px;overflow:hidden}.saturation .s-white,.saturation .s-black,.saturation .s-bg{position:absolute;inset:0}.saturation .s-white{background:linear-gradient(to right,#fff,#fff0)}.saturation .s-black{background:linear-gradient(to bottom,#0000,#000)}\n"] }]
472
+ ], template: "<div\n class=\"saturation-container\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n (mousedown)=\"dragStart($event)\"\n (touchstart)=\"dragStart($event)\">\n <div class=\"saturation\" #saturation>\n <div class=\"s-bg\" [style.background]=\"color\"></div>\n <div class=\"s-white\"></div>\n <div class=\"s-black\"></div>\n </div>\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [style.top.px]=\"y\"></div>\n</div>\n", styles: [".saturation-container{position:relative;width:100%;height:200px}.saturation-container .thumb{border:3px #000000 solid;box-shadow:inset 0 0 0 2px #fff;width:12px;height:12px;display:block;border-radius:10px;position:absolute;pointer-events:none;cursor:pointer}.saturation{position:absolute;inset:6px;border-radius:4px;overflow:hidden}.saturation .s-white,.saturation .s-black,.saturation .s-bg{position:absolute;inset:0}.saturation .s-white{background:linear-gradient(to right,#fff,#fff0)}.saturation .s-black{background:linear-gradient(to bottom,#0000,#000)}\n"] }]
434
473
  }], ctorParameters: () => [], propDecorators: { width: [{
435
474
  type: Input
436
475
  }], height: [{
@@ -454,18 +493,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
454
493
  }], onResize: [{
455
494
  type: HostListener,
456
495
  args: ['window:resize']
457
- }], onDrag: [{
458
- type: HostListener,
459
- args: ['document:mousemove', ['$event']]
460
- }, {
461
- type: HostListener,
462
- args: ['document:touchmove', ['$event']]
463
- }], onDragEnd: [{
464
- type: HostListener,
465
- args: ['document:mouseup', ['$event']]
466
- }, {
467
- type: HostListener,
468
- args: ['document:touchend', ['$event']]
469
496
  }] } });
470
497
 
471
498
  class SliderComponent {
@@ -486,10 +513,15 @@ class SliderComponent {
486
513
  _validatorOnChange = () => { };
487
514
  sliderRect;
488
515
  thumbRect;
516
+ stopDrag;
517
+ cd = inject(ChangeDetectorRef);
489
518
  constructor() { }
490
519
  ngOnInit() {
491
520
  this.myControl.setValidators([Validators.min(this.min), Validators.max(this.max)]);
492
521
  }
522
+ ngOnDestroy() {
523
+ this.stopDrag?.();
524
+ }
493
525
  updateRects() {
494
526
  this.sliderRect = this.slider.nativeElement.getBoundingClientRect();
495
527
  this.thumbRect = this.thumb.nativeElement.getBoundingClientRect();
@@ -538,11 +570,15 @@ class SliderComponent {
538
570
  this.isDragging = true;
539
571
  this.updateRects();
540
572
  this.updatePosition(ev);
541
- }
542
- onDrag(ev) {
543
- if (!this.isDragging)
544
- return;
545
- this.updatePosition(ev);
573
+ this.stopDrag?.();
574
+ this.stopDrag = startDragSession({
575
+ onMove: (moveEv) => this.updatePosition(moveEv),
576
+ onEnd: () => {
577
+ this.isDragging = false;
578
+ this.stopDrag = undefined;
579
+ this.cd.markForCheck();
580
+ },
581
+ });
546
582
  }
547
583
  onResize() {
548
584
  this.writeValue(this.myControl.value);
@@ -566,6 +602,9 @@ class SliderComponent {
566
602
  this.x = position.x;
567
603
  }
568
604
  this.setValueByPosition(thumbRec, sliderRec);
605
+ // OnPush + addEventListener دستی (به‌جای HostListener) یعنی خودمون باید
606
+ // view رو dirty کنیم، وگرنه thumb حین درگ روی صفحه آپدیت نمی‌شه.
607
+ this.cd.markForCheck();
569
608
  }
570
609
  setValueByPosition(thumbRec, sliderRec) {
571
610
  const percentage = this.x / (sliderRec.width - thumbRec.width);
@@ -577,16 +616,13 @@ class SliderComponent {
577
616
  this.valueChanged(value);
578
617
  }
579
618
  }
580
- onDragEnd(ev) {
581
- this.isDragging = false;
582
- }
583
619
  valueChanged(value) {
584
620
  this.myControl.setValue(value, { emitEvent: false });
585
621
  this._onChange(value);
586
622
  this.change.emit(value);
587
623
  }
588
624
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SliderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
589
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: SliderComponent, isStandalone: true, selector: "slider", inputs: { step: "step", min: "min", max: "max", background: "background", isBgTransparent: "isBgTransparent" }, outputs: { change: "change" }, host: { listeners: { "document:mousemove": "onDrag($event)", "document:touchmove": "onDrag($event)", "window:resize": "onResize()", "document:mouseup": "onDragEnd($event)", "document:touchend": "onDragEnd($event)" } }, providers: [
625
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: SliderComponent, isStandalone: true, selector: "slider", inputs: { step: "step", min: "min", max: "max", background: "background", isBgTransparent: "isBgTransparent" }, outputs: { change: "change" }, host: { listeners: { "window:resize": "onResize()" } }, providers: [
590
626
  {
591
627
  provide: NG_VALUE_ACCESSOR,
592
628
  useExisting: forwardRef(() => SliderComponent),
@@ -597,7 +633,7 @@ class SliderComponent {
597
633
  useExisting: forwardRef(() => SliderComponent),
598
634
  multi: true,
599
635
  },
600
- ], viewQueries: [{ propertyName: "slider", first: true, predicate: ["slider"], descendants: true, static: true }, { propertyName: "thumb", first: true, predicate: ["thumb"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"slider-container\">\r\n <ng-content></ng-content>\r\n <div\r\n #slider\r\n class=\"slider\"\r\n (mousedown)=\"dragStart($event)\"\r\n (touchstart)=\"dragStart($event)\"\r\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\r\n [class.bg-transparent]=\"isBgTransparent\">\r\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [title]=\"myControl.value\"></div>\r\n </div>\r\n</div>\r\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
636
+ ], viewQueries: [{ propertyName: "slider", first: true, predicate: ["slider"], descendants: true, static: true }, { propertyName: "thumb", first: true, predicate: ["thumb"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"slider-container\">\n <ng-content></ng-content>\n <div\n #slider\n class=\"slider\"\n (mousedown)=\"dragStart($event)\"\n (touchstart)=\"dragStart($event)\"\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\n [class.bg-transparent]=\"isBgTransparent\">\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [title]=\"myControl.value\"></div>\n </div>\n</div>\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
601
637
  }
602
638
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SliderComponent, decorators: [{
603
639
  type: Component,
@@ -612,7 +648,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
612
648
  useExisting: forwardRef(() => SliderComponent),
613
649
  multi: true,
614
650
  },
615
- ], template: "<div class=\"slider-container\">\r\n <ng-content></ng-content>\r\n <div\r\n #slider\r\n class=\"slider\"\r\n (mousedown)=\"dragStart($event)\"\r\n (touchstart)=\"dragStart($event)\"\r\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\r\n [class.bg-transparent]=\"isBgTransparent\">\r\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [title]=\"myControl.value\"></div>\r\n </div>\r\n</div>\r\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}\n"] }]
651
+ ], template: "<div class=\"slider-container\">\n <ng-content></ng-content>\n <div\n #slider\n class=\"slider\"\n (mousedown)=\"dragStart($event)\"\n (touchstart)=\"dragStart($event)\"\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\n [class.bg-transparent]=\"isBgTransparent\">\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [title]=\"myControl.value\"></div>\n </div>\n</div>\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}\n"] }]
616
652
  }], ctorParameters: () => [], propDecorators: { step: [{
617
653
  type: Input
618
654
  }], min: [{
@@ -631,21 +667,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
631
667
  }], thumb: [{
632
668
  type: ViewChild,
633
669
  args: ['thumb', { static: true }]
634
- }], onDrag: [{
635
- type: HostListener,
636
- args: ['document:mousemove', ['$event']]
637
- }, {
638
- type: HostListener,
639
- args: ['document:touchmove', ['$event']]
640
670
  }], onResize: [{
641
671
  type: HostListener,
642
672
  args: ['window:resize']
643
- }], onDragEnd: [{
644
- type: HostListener,
645
- args: ['document:mouseup', ['$event']]
646
- }, {
647
- type: HostListener,
648
- args: ['document:touchend', ['$event']]
649
673
  }] } });
650
674
 
651
675
  function isPlainObject(value) {
@@ -832,7 +856,6 @@ const FOCUSABLE_SELECTOR = 'button, [href], input, select, textarea, [tabindex]:
832
856
  const DIALOG_OVERLAY_CLASSNAME = 'ngx-ui-overlay';
833
857
  class OverlayService {
834
858
  overlayStacks = [];
835
- zIndexCounter = 1000;
836
859
  listenersAttached = false;
837
860
  resizeRafPending = false;
838
861
  doc = inject(DOCUMENT);
@@ -927,10 +950,6 @@ class OverlayService {
927
950
  style.maxHeight = '100vh';
928
951
  style.overflow = 'visible';
929
952
  style.visibility = 'hidden';
930
- // شمارنده‌ی صعودی مستقل از تعداد فعلی دیالوگ‌های باز؛ در نسخه‌ی قبلی
931
- // با استفاده از openDialogs.size محاسبه می‌شد که بعد از بستن دیالوگ‌ها
932
- // می‌تونست باعث تکرار zIndex بین دو دیالوگ بشه.
933
- style.zIndex = `${++this.zIndexCounter}`;
934
953
  this.doc.body.appendChild(element);
935
954
  return element;
936
955
  }
@@ -963,6 +982,21 @@ class OverlayService {
963
982
  instance.appRef.detachView(instance.embeddedView);
964
983
  instance.embeddedView.destroy();
965
984
  }
985
+ // قبل از remove()، دیالوگ رو با متد استاندارد close() می‌بندیم؛ این کار دو
986
+ // فایده داره که با remove() ساده به دست نمی‌اومدن:
987
+ // ۱) فوکوس به‌صورت خودکار به همون المنتی که قبل از باز شدن دیالوگ فوکوس
988
+ // داشت برمی‌گرده (رفتار استاندارد close() روی <dialog>) — با remove()
989
+ // ساده این اتفاق نمی‌افته و فوکوس معمولاً روی body گم می‌شه.
990
+ // ۲) رویداد 'close' استاندارد شلیک می‌شه، برای کدی که ممکنه به اون گوش بده.
991
+ // در try/catch گذاشتیمش چون در محیط تست (jsdom) این متدها mock هستن و ممکنه
992
+ // رفتار متفاوتی داشته باشن.
993
+ try {
994
+ if (instance.element.open)
995
+ instance.element.close();
996
+ }
997
+ catch {
998
+ /* noop */
999
+ }
966
1000
  instance.element.remove();
967
1001
  instance.onClosed?.();
968
1002
  }
@@ -1094,8 +1128,17 @@ class OverlayService {
1094
1128
  left = anchorRect.left;
1095
1129
  }
1096
1130
  }
1097
- else {
1098
- left = isRTL ? anchorRect.left : anchorRect.right; //- dialogRect.width;
1131
+ else if (alignment === 'end') {
1132
+ // انتهای دیالوگ باید با انتهای anchor یکی باشه؛ با استفاده از پراپرتی
1133
+ // CSS «right» (به‌جای کم‌کردن دستیِ عرض از «left») این کار درست و مستقل
1134
+ // از این‌که عرض دیالوگ چقدره انجام می‌شه (قبلاً این خط باگ داشت و دیالوگ
1135
+ // رو بعد از anchor می‌ذاشت، نه هم‌تراز با لبه‌ی انتهاییِ آن).
1136
+ if (isRTL) {
1137
+ left = anchorRect.left;
1138
+ }
1139
+ else {
1140
+ right = vw - anchorRect.right;
1141
+ }
1099
1142
  }
1100
1143
  if (left !== 'auto') {
1101
1144
  left = Math.min(Math.max(left, margin), vw - dialogRect.width - margin);
@@ -1127,5 +1170,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
1127
1170
  * Generated bundle index. Do not edit.
1128
1171
  */
1129
1172
 
1130
- export { BrowserService, DIALOG_OVERLAY_CLASSNAME, DirectionService, FOCUSABLE_SELECTOR, OverlayRef, OverlayService, RangeSliderComponent, SaturationComponent, SliderComponent, ValueModel, WINDOW, getOffsetPosition, makeConfetti, mergeConfig, randomStrnig };
1173
+ export { BrowserService, DIALOG_OVERLAY_CLASSNAME, DirectionService, FOCUSABLE_SELECTOR, OverlayRef, OverlayService, RangeSliderComponent, SaturationComponent, SliderComponent, ValueModel, WINDOW, getOffsetPosition, makeConfetti, mergeConfig, randomStrnig, startDragSession };
1131
1174
  //# sourceMappingURL=ngx-kit-shared.mjs.map