ngx-kit 4.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.
- package/README.md +3 -2
- package/angle-selector/README.md +34 -0
- package/box-shadow/README.md +33 -0
- package/color-picker/README.md +52 -0
- package/data-table/README.md +120 -0
- package/date-picker/README.md +74 -0
- package/dialog/README.md +94 -169
- package/drawer-menu/README.md +76 -0
- package/dropzone/README.md +59 -0
- package/fesm2022/ngx-kit-angle-selector.mjs +2 -2
- package/fesm2022/ngx-kit-angle-selector.mjs.map +1 -1
- package/fesm2022/ngx-kit-box-shadow.mjs +28 -27
- package/fesm2022/ngx-kit-box-shadow.mjs.map +1 -1
- package/fesm2022/ngx-kit-color-picker.mjs +173 -43
- package/fesm2022/ngx-kit-color-picker.mjs.map +1 -1
- package/fesm2022/ngx-kit-data-table.mjs +446 -191
- package/fesm2022/ngx-kit-data-table.mjs.map +1 -1
- package/fesm2022/ngx-kit-date-picker.mjs +120 -86
- package/fesm2022/ngx-kit-date-picker.mjs.map +1 -1
- package/fesm2022/ngx-kit-dialog.mjs +38 -7
- package/fesm2022/ngx-kit-dialog.mjs.map +1 -1
- package/fesm2022/ngx-kit-drawer-menu.mjs +190 -0
- package/fesm2022/ngx-kit-drawer-menu.mjs.map +1 -0
- package/fesm2022/ngx-kit-dropzone.mjs +272 -0
- package/fesm2022/ngx-kit-dropzone.mjs.map +1 -0
- package/fesm2022/ngx-kit-form-field.mjs +87 -0
- package/fesm2022/ngx-kit-form-field.mjs.map +1 -0
- package/fesm2022/ngx-kit-gallery.mjs +419 -0
- package/fesm2022/ngx-kit-gallery.mjs.map +1 -0
- package/fesm2022/ngx-kit-gradient-picker.mjs +12 -4
- package/fesm2022/ngx-kit-gradient-picker.mjs.map +1 -1
- package/fesm2022/ngx-kit-image-editor.mjs +501 -0
- package/fesm2022/ngx-kit-image-editor.mjs.map +1 -0
- package/fesm2022/ngx-kit-menu.mjs +9 -4
- package/fesm2022/ngx-kit-menu.mjs.map +1 -1
- package/fesm2022/ngx-kit-message.mjs +58 -24
- package/fesm2022/ngx-kit-message.mjs.map +1 -1
- package/fesm2022/ngx-kit-notify.mjs +10 -4
- package/fesm2022/ngx-kit-notify.mjs.map +1 -1
- package/fesm2022/ngx-kit-shared.mjs +184 -88
- package/fesm2022/ngx-kit-shared.mjs.map +1 -1
- package/fesm2022/ngx-kit-time-picker.mjs +562 -0
- package/fesm2022/ngx-kit-time-picker.mjs.map +1 -0
- package/fesm2022/ngx-kit.mjs.map +1 -1
- package/gallery/README.md +71 -0
- package/gradient-picker/README.md +41 -0
- package/image-editor/README.md +44 -0
- package/menu/README.md +85 -0
- package/message/README.md +70 -0
- package/notify/README.md +56 -0
- package/package.json +25 -1
- package/shared/README.md +117 -0
- package/styles/all.css +27 -0
- package/styles/image-viewer.css +12 -0
- package/types/ngx-kit-box-shadow.d.ts +1 -2
- package/types/ngx-kit-data-table.d.ts +290 -147
- package/types/ngx-kit-date-picker.d.ts +1 -1
- package/types/ngx-kit-dialog.d.ts +1 -0
- package/types/ngx-kit-drawer-menu.d.ts +101 -0
- package/types/ngx-kit-dropzone.d.ts +84 -0
- package/types/ngx-kit-form-field.d.ts +31 -0
- package/types/ngx-kit-gallery.d.ts +168 -0
- package/types/ngx-kit-image-editor.d.ts +175 -0
- package/types/ngx-kit-menu.d.ts +1 -0
- package/types/ngx-kit-message.d.ts +14 -3
- package/types/ngx-kit-notify.d.ts +2 -1
- package/types/ngx-kit-shared.d.ts +70 -15
- package/types/ngx-kit-time-picker.d.ts +150 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* از 'start'/'end' منطقی استفاده میکنیم نه 'left'/'right' — یعنی توی
|
|
5
|
+
* RTL خودکار برعکس میشه (start یعنی راست در RTL، چپ در LTR)، دقیقاً هماهنگ
|
|
6
|
+
* با بقیهی کتابخونه که همهجا از پراپرتیهای منطقیِ CSS استفاده میکنه.
|
|
7
|
+
*/
|
|
8
|
+
type NgxDrawerSide = 'start' | 'end';
|
|
9
|
+
/**
|
|
10
|
+
* جلوهی بازوبستهشدنِ خودِ پنل:
|
|
11
|
+
* - slide: اسلاید سادهی کلاسیک
|
|
12
|
+
* - curtain: چند نوار عمودیِ همرنگِ پنل که با تأخیرِ پلکانی جمع میشن و
|
|
13
|
+
* محتوا رو نمایان میکنن — حسِ باز شدنِ یه پردهی چندلَته
|
|
14
|
+
* - jelly: بازشدن با افکتِ ژلهای/کشسان — چند نوسانِ فنری که رفتهرفته
|
|
15
|
+
* فروکش میکنه (الهام از https://dribbble.com/shots/2307371)
|
|
16
|
+
* - pull: یه کشیدگیِ لاستیکیِ تکضربهای — لبهی پنل از اندازهی نهایی رد
|
|
17
|
+
* میشه و برمیگرده سرجاش (rubber-band)
|
|
18
|
+
* - rotate3d: چرخشِ سهبعدیِ دور لولا (مثل باز شدنِ یه در)، با perspective
|
|
19
|
+
* - flip3d: پنل و محتوای صفحه با هم مثل ورقزدنِ یه کتاب میچرخن
|
|
20
|
+
* - scale: بزرگشدن از مرکز همراه با fade
|
|
21
|
+
*/
|
|
22
|
+
type NgxDrawerEffect = 'slide' | 'curtain' | 'jelly' | 'pull' | 'rotate3d' | 'flip3d' | 'scale';
|
|
23
|
+
/**
|
|
24
|
+
* رفتار محتوای اصلیِ صفحه وقتی درور باز میشه:
|
|
25
|
+
* - overlay: محتوا سرجاش میمونه، درور روش شناور میشه (با بکدراپ)
|
|
26
|
+
* - push: محتوا بهاندازهی عرضِ درور هل داده میشه (کنار میره)
|
|
27
|
+
* - reveal: محتوا کمی کوچیک/عقب میره، انگار درور از زیرش نمایان میشه
|
|
28
|
+
* (همون افکت معروف iOS)
|
|
29
|
+
*/
|
|
30
|
+
type NgxDrawerContentBehavior = 'overlay' | 'push' | 'reveal';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* درور منو (side drawer) با ۶ جلوهی بازوبستهشدنِ متفاوت (از ساده تا
|
|
34
|
+
* سهبعدی/ژلهای) و ۳ رفتار برای محتوای صفحه (overlay/push/reveal) —
|
|
35
|
+
* دقیقاً مدل کتابخونههای حرفهای مثل react-burger-menu یا Ionic Menu، ولی
|
|
36
|
+
* signal-based و بدون هیچ وابستگی خارجی.
|
|
37
|
+
*
|
|
38
|
+
* نکات معماری:
|
|
39
|
+
* - از 'start'/'end' منطقی استفاده میکنه، پس با CSS logical properties
|
|
40
|
+
* زیر RTL خودکار برعکس میشه؛ فقط ریاضیِ درگ (که برخلاف CSS جهت فیزیکیِ
|
|
41
|
+
* واقعی لازم داره) از DirectionService مشترک استفاده میکنه.
|
|
42
|
+
* - وضعیت باز/بسته با model() دوطرفهست، پس هم با [(open)] قابل کنترله و
|
|
43
|
+
* هم میتونه بهصورت خودکار و زنده با عرض صفحه هماهنگ بشه (respondToViewport)
|
|
44
|
+
* — یعنی رد شدن از breakpoint (نه فقط بار اول لود) میتونه خودکار باز/بستهش کنه.
|
|
45
|
+
* - افکتهای jelly/pull با keyframe سهمرحلهای (overshoot → نوسان → استقرار)
|
|
46
|
+
* پیاده شدن، نه فقط یه transition ساده.
|
|
47
|
+
*/
|
|
48
|
+
declare class NgxDrawerMenuComponent {
|
|
49
|
+
side: _angular_core.InputSignal<NgxDrawerSide>;
|
|
50
|
+
effect: _angular_core.InputSignal<NgxDrawerEffect>;
|
|
51
|
+
contentBehavior: _angular_core.InputSignal<NgxDrawerContentBehavior>;
|
|
52
|
+
width: _angular_core.InputSignal<number>;
|
|
53
|
+
swipeEdgeSize: _angular_core.InputSignal<number>;
|
|
54
|
+
curtainStrips: _angular_core.InputSignal<number>;
|
|
55
|
+
backdropClose: _angular_core.InputSignal<boolean>;
|
|
56
|
+
swipeEnabled: _angular_core.InputSignal<boolean>;
|
|
57
|
+
/** اگه true باشه، رد شدن از mobileBreakpoint بهصورت زنده open رو با openOnDesktop/openOnMobile هماهنگ میکنه */
|
|
58
|
+
respondToViewport: _angular_core.InputSignal<boolean>;
|
|
59
|
+
openOnDesktop: _angular_core.InputSignal<boolean>;
|
|
60
|
+
openOnMobile: _angular_core.InputSignal<boolean>;
|
|
61
|
+
mobileBreakpoint: _angular_core.InputSignal<number>;
|
|
62
|
+
/** state دوطرفهی باز/بسته؛ با [(open)] قابل bind هست */
|
|
63
|
+
open: _angular_core.ModelSignal<boolean>;
|
|
64
|
+
private readonly directionService;
|
|
65
|
+
private readonly doc;
|
|
66
|
+
private readonly destroyRef;
|
|
67
|
+
/** فقط حین یه درگِ واقعی مقدار داره؛ null یعنی از روی open() تصمیم بگیر */
|
|
68
|
+
protected readonly dragRatio: _angular_core.WritableSignal<number | null>;
|
|
69
|
+
protected readonly isDragging: _angular_core.Signal<boolean>;
|
|
70
|
+
protected readonly visualOpen: _angular_core.Signal<number>;
|
|
71
|
+
protected readonly strips: _angular_core.Signal<number[]>;
|
|
72
|
+
/**
|
|
73
|
+
* +۱ یعنی این پنل فیزیکاً روی لبهی چپِ صفحهست، -۱ یعنی لبهی راست —
|
|
74
|
+
* برای transform:translateX() محتوای اصلی (که برخلاف inset-inline، به
|
|
75
|
+
* dir=rtl خودکار واکنش نشون نمیده) لازمه. reactive هست چون هم به side()
|
|
76
|
+
* و هم به جهتِ زندهی صفحه (directionService.isRtl()) وابستهست.
|
|
77
|
+
*/
|
|
78
|
+
protected readonly pushDirSign: _angular_core.Signal<1 | -1>;
|
|
79
|
+
/** برای افکتهای keyframeمحور (jelly/pull) — فقط لحظهی رهاشدن (نه حین درگ زنده) پخش میشه */
|
|
80
|
+
protected readonly playEffectClass: _angular_core.WritableSignal<boolean>;
|
|
81
|
+
private stopDrag?;
|
|
82
|
+
private dragStartX;
|
|
83
|
+
private dragStartRatio;
|
|
84
|
+
private prevOpen;
|
|
85
|
+
constructor();
|
|
86
|
+
protected onEscape(): void;
|
|
87
|
+
protected closeFromBackdrop(): void;
|
|
88
|
+
toggle(): void;
|
|
89
|
+
/** true یعنی این پنل فیزیکاً روی لبهی چپِ صفحهست (صرفنظر از start/end منطقی) */
|
|
90
|
+
private isPhysicalLeftEdge;
|
|
91
|
+
protected stripDelay(index: number): string;
|
|
92
|
+
protected onEdgeDragStart(ev: MouseEvent | TouchEvent): void;
|
|
93
|
+
protected onPanelDragStart(ev: MouseEvent | TouchEvent): void;
|
|
94
|
+
private beginDrag;
|
|
95
|
+
private clientXOf;
|
|
96
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxDrawerMenuComponent, never>;
|
|
97
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgxDrawerMenuComponent, "ngx-drawer-menu", never, { "side": { "alias": "side"; "required": false; "isSignal": true; }; "effect": { "alias": "effect"; "required": false; "isSignal": true; }; "contentBehavior": { "alias": "contentBehavior"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "swipeEdgeSize": { "alias": "swipeEdgeSize"; "required": false; "isSignal": true; }; "curtainStrips": { "alias": "curtainStrips"; "required": false; "isSignal": true; }; "backdropClose": { "alias": "backdropClose"; "required": false; "isSignal": true; }; "swipeEnabled": { "alias": "swipeEnabled"; "required": false; "isSignal": true; }; "respondToViewport": { "alias": "respondToViewport"; "required": false; "isSignal": true; }; "openOnDesktop": { "alias": "openOnDesktop"; "required": false; "isSignal": true; }; "openOnMobile": { "alias": "openOnMobile"; "required": false; "isSignal": true; }; "mobileBreakpoint": { "alias": "mobileBreakpoint"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*", "[drawerContent]"], true, never>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export { NgxDrawerMenuComponent };
|
|
101
|
+
export type { NgxDrawerContentBehavior, NgxDrawerEffect, NgxDrawerSide };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { OnDestroy } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
interface NgxDropzoneFile {
|
|
5
|
+
/** شناسهی یکتا برای track کردن توی @for و امکان حذف تکی */
|
|
6
|
+
id: string;
|
|
7
|
+
file: File;
|
|
8
|
+
/** فقط برای فایلهای تصویری پر میشه (object URL) */
|
|
9
|
+
previewUrl?: string;
|
|
10
|
+
status: 'pending' | 'accepted' | 'rejected';
|
|
11
|
+
/** در صورت رد شدن، دلیلش */
|
|
12
|
+
rejectionReason?: NgxDropzoneRejectionReason;
|
|
13
|
+
}
|
|
14
|
+
type NgxDropzoneRejectionReason = 'type' | 'size' | 'count';
|
|
15
|
+
interface NgxDropzoneRejectedFile {
|
|
16
|
+
file: File;
|
|
17
|
+
reason: NgxDropzoneRejectionReason;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* ناحیهی درگانددراپِ فایل — کاملاً مستقل (بدون وابستگی به هیچ lib
|
|
22
|
+
* دیگهای، حتی shared)، signal-based و OnPush.
|
|
23
|
+
*
|
|
24
|
+
* ویژگیهای مهمی که معمولاً پیادهسازیهای سادهی dropzone ندارن:
|
|
25
|
+
* - شمارندهی dragenter/dragleave: چون dragleave برای فرزندهای داخل
|
|
26
|
+
* dropzone هم شلیک میشه، پیادهسازیهای ساده موقع درگکردن روی متن/آیکون
|
|
27
|
+
* داخل ناحیه، حالت "درگ" رو اشتباهی خاموش میکنن (چشمکزدن). اینجا با
|
|
28
|
+
* شمارنده حل شده.
|
|
29
|
+
* - پیمایش بازگشتیِ پوشهها (وقتی کاربر یه پوشه رو درگ کنه، نه فقط فایل).
|
|
30
|
+
* - قابلدسترسی با کیبورد (focusable + Enter/Space).
|
|
31
|
+
* - پاکسازی object URL پیشنمایشها روی حذف/destroy (وگرنه نشتی حافظهست).
|
|
32
|
+
*/
|
|
33
|
+
declare class NgxDropzoneComponent implements OnDestroy {
|
|
34
|
+
/** الگوی accept مثل input[type=file]: "image/*", ".pdf,.docx" و ... */
|
|
35
|
+
accept: _angular_core.InputSignal<string>;
|
|
36
|
+
multiple: _angular_core.InputSignal<boolean>;
|
|
37
|
+
/** حداکثر حجم هر فایل به بایت؛ undefined یعنی بدون محدودیت */
|
|
38
|
+
maxFileSize: _angular_core.InputSignal<number | undefined>;
|
|
39
|
+
/** حداکثر تعداد فایل مجاز؛ undefined یعنی بدون محدودیت */
|
|
40
|
+
maxFiles: _angular_core.InputSignal<number | undefined>;
|
|
41
|
+
disabled: _angular_core.InputSignal<boolean>;
|
|
42
|
+
/** نمایش لیست/پیشنمایش فایلهای انتخابشده داخل خودِ کامپوننت */
|
|
43
|
+
showFileList: _angular_core.InputSignal<boolean>;
|
|
44
|
+
filesAdded: _angular_core.OutputEmitterRef<File[]>;
|
|
45
|
+
filesRejected: _angular_core.OutputEmitterRef<NgxDropzoneRejectedFile[]>;
|
|
46
|
+
/** کل لیست فعلی (بعد از هر تغییر) — برای binding راحتتر */
|
|
47
|
+
filesChange: _angular_core.OutputEmitterRef<File[]>;
|
|
48
|
+
protected readonly files: _angular_core.WritableSignal<NgxDropzoneFile[]>;
|
|
49
|
+
protected readonly isDragging: _angular_core.WritableSignal<boolean>;
|
|
50
|
+
private dragCounter;
|
|
51
|
+
private readonly fileInput;
|
|
52
|
+
protected readonly hint: _angular_core.Signal<string>;
|
|
53
|
+
protected formatSize(bytes: number): string;
|
|
54
|
+
ngOnDestroy(): void;
|
|
55
|
+
protected onDragEnter(ev: DragEvent): void;
|
|
56
|
+
protected onDragOver(ev: DragEvent): void;
|
|
57
|
+
protected onDragLeave(ev: DragEvent): void;
|
|
58
|
+
protected onDrop(ev: DragEvent): Promise<void>;
|
|
59
|
+
protected onBrowseClick(): void;
|
|
60
|
+
protected onKeydown(ev: KeyboardEvent): void;
|
|
61
|
+
protected onFileInputChange(ev: Event): void;
|
|
62
|
+
protected removeFile(id: string): void;
|
|
63
|
+
private handleIncomingFiles;
|
|
64
|
+
private emitCurrentFiles;
|
|
65
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxDropzoneComponent, never>;
|
|
66
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgxDropzoneComponent, "ngx-dropzone", never, { "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "maxFileSize": { "alias": "maxFileSize"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "showFileList": { "alias": "showFileList"; "required": false; "isSignal": true; }; }, { "filesAdded": "filesAdded"; "filesRejected": "filesRejected"; "filesChange": "filesChange"; }, never, ["[dropzone-icon]", "*"], true, never>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* چک میکنه یه فایل با pattern رشتهای accept (مثل input[type=file])
|
|
71
|
+
* مطابقت داره یا نه. پشتیبانی میشه از:
|
|
72
|
+
* - MIME کامل: "image/png"
|
|
73
|
+
* - MIME با wildcard: "image/*"
|
|
74
|
+
* - پسوند فایل: ".png", ".jpg"
|
|
75
|
+
* - لیست کاما-جدا از موارد بالا: "image/*,.pdf,.docx"
|
|
76
|
+
*/
|
|
77
|
+
declare function matchesAccept(file: File, accept?: string): boolean;
|
|
78
|
+
/** تبدیل بایت به یه رشتهی خوانا (KB/MB/GB) */
|
|
79
|
+
declare function formatBytes(bytes: number): string;
|
|
80
|
+
/** استخراج فایلهای واقعی از یک DataTransfer، شامل پیمایش بازگشتیِ پوشهها (وقتی مرورگر پشتیبانی کنه) */
|
|
81
|
+
declare function extractFilesFromDataTransfer(dataTransfer: DataTransfer): Promise<File[]>;
|
|
82
|
+
|
|
83
|
+
export { NgxDropzoneComponent, extractFilesFromDataTransfer, formatBytes, matchesAccept };
|
|
84
|
+
export type { NgxDropzoneFile, NgxDropzoneRejectedFile, NgxDropzoneRejectionReason };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
|
|
3
|
+
type NgxFormFieldType = 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search' | 'textarea';
|
|
4
|
+
|
|
5
|
+
declare class NgxFormField {
|
|
6
|
+
readonly value: _angular_core.ModelSignal<string | number>;
|
|
7
|
+
readonly label: _angular_core.InputSignal<string>;
|
|
8
|
+
readonly type: _angular_core.InputSignal<NgxFormFieldType>;
|
|
9
|
+
readonly placeholder: _angular_core.InputSignal<string>;
|
|
10
|
+
readonly required: _angular_core.InputSignal<boolean>;
|
|
11
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
12
|
+
readonly readonly: _angular_core.InputSignal<boolean>;
|
|
13
|
+
readonly float: _angular_core.InputSignal<boolean>;
|
|
14
|
+
readonly name: _angular_core.InputSignal<string | null>;
|
|
15
|
+
readonly autocomplete: _angular_core.InputSignal<string | null>;
|
|
16
|
+
readonly rows: _angular_core.InputSignal<number>;
|
|
17
|
+
readonly hint: _angular_core.InputSignal<string>;
|
|
18
|
+
readonly errorMessages: _angular_core.InputSignal<string[]>;
|
|
19
|
+
readonly dir: _angular_core.InputSignal<"" | "ltr" | "rtl">;
|
|
20
|
+
readonly id: _angular_core.InputSignal<string>;
|
|
21
|
+
readonly focused: _angular_core.OutputEmitterRef<void>;
|
|
22
|
+
readonly blurred: _angular_core.OutputEmitterRef<void>;
|
|
23
|
+
readonly hasValue: _angular_core.Signal<boolean>;
|
|
24
|
+
onInput(event: Event): void;
|
|
25
|
+
onFocus(): void;
|
|
26
|
+
onBlur(): void;
|
|
27
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxFormField, never>;
|
|
28
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgxFormField, "ngx-form-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "float": { "alias": "float"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "errorMessages": { "alias": "errorMessages"; "required": false; "isSignal": true; }; "dir": { "alias": "dir"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "focused": "focused"; "blurred": "blurred"; }, never, never, true, never>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { NgxFormField };
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
|
|
3
|
+
interface NgxImageViewerItem {
|
|
4
|
+
src: string;
|
|
5
|
+
alt?: string;
|
|
6
|
+
caption?: string;
|
|
7
|
+
/** نام فایل هنگام دانلود؛ نبود یعنی از روی src حدس زده میشه */
|
|
8
|
+
downloadFileName?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* هر دکمهی نوار ابزار جدا فعال/غیرفعال میشه — دقیقاً طبق خواسته: «این
|
|
12
|
+
* دکمههای کانفیگی باشه که هر کدوم خواست فعال کنه».
|
|
13
|
+
*/
|
|
14
|
+
interface NgxImageViewerToolbarConfig {
|
|
15
|
+
prevNext?: boolean;
|
|
16
|
+
counter?: boolean;
|
|
17
|
+
zoomIn?: boolean;
|
|
18
|
+
zoomOut?: boolean;
|
|
19
|
+
resetZoom?: boolean;
|
|
20
|
+
rotateLeft?: boolean;
|
|
21
|
+
rotateRight?: boolean;
|
|
22
|
+
download?: boolean;
|
|
23
|
+
print?: boolean;
|
|
24
|
+
fullscreen?: boolean;
|
|
25
|
+
close?: boolean;
|
|
26
|
+
}
|
|
27
|
+
declare const NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR: Required<NgxImageViewerToolbarConfig>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* ویوئر حرفهایِ تصویر: یه لیست تصویر میگیره، اولی رو نشون میده، با
|
|
31
|
+
* دکمههای چپ/راست (مثل کاروسل) بینشون میره، و یه نوار ابزار کاملاً
|
|
32
|
+
* قابلتنظیم (هر دکمه جدا فعال/غیرفعال میشه) داره: زوم این/اوت/ریست،
|
|
33
|
+
* چرخش، دانلود، پرینت، تمامصفحه.
|
|
34
|
+
*
|
|
35
|
+
* تعاملها:
|
|
36
|
+
* - اسکرول موس روی تصویر = زوم (نسبت به همون نقطهی زیر cursor، نه مرکز)
|
|
37
|
+
* - دو انگشتی روی تاچ = پینچ زوم
|
|
38
|
+
* - وقتی زومشده، درگ با موس یا تکانگشتی = پن
|
|
39
|
+
* - کیبورد: ← → برای قبلی/بعدی، +/- برای زوم، Esc برای closed
|
|
40
|
+
*
|
|
41
|
+
* چون wheel/touchmove باید preventDefault بشن (وگرنه صفحه اسکرول/زوم
|
|
42
|
+
* میشه) و انگیولار این ایونتها رو بهصورت پیشفرض passive رجیستر میکنه
|
|
43
|
+
* (که توش preventDefault اثر نداره)، اینها با addEventListener دستی و
|
|
44
|
+
* {passive:false} وصل میشن، نه با بایندینگ تمپلیت.
|
|
45
|
+
*
|
|
46
|
+
* میتونه هم مستقیم توی صفحه جا بگیره، هم توسط مصرفکننده داخل
|
|
47
|
+
* ngx-kit/dialog (یا هر overlay دیگه) قرار بگیره — خودش به هیچکدوم وابسته
|
|
48
|
+
* نیست، فقط با closed خروجی به بیرون خبر میده که «ببندم».
|
|
49
|
+
*/
|
|
50
|
+
declare class NgxImageViewerComponent {
|
|
51
|
+
images: _angular_core.InputSignal<NgxImageViewerItem[]>;
|
|
52
|
+
startIndex: _angular_core.InputSignal<number>;
|
|
53
|
+
toolbar: _angular_core.InputSignal<NgxImageViewerToolbarConfig>;
|
|
54
|
+
minZoom: _angular_core.InputSignal<number>;
|
|
55
|
+
maxZoom: _angular_core.InputSignal<number>;
|
|
56
|
+
zoomStep: _angular_core.InputSignal<number>;
|
|
57
|
+
indexChange: _angular_core.OutputEmitterRef<number>;
|
|
58
|
+
closed: _angular_core.OutputEmitterRef<void>;
|
|
59
|
+
protected readonly activeIndex: _angular_core.WritableSignal<number>;
|
|
60
|
+
protected readonly zoom: _angular_core.WritableSignal<number>;
|
|
61
|
+
protected readonly panX: _angular_core.WritableSignal<number>;
|
|
62
|
+
protected readonly panY: _angular_core.WritableSignal<number>;
|
|
63
|
+
protected readonly rotation: _angular_core.WritableSignal<number>;
|
|
64
|
+
protected readonly activeImage: _angular_core.Signal<NgxImageViewerItem | undefined>;
|
|
65
|
+
protected readonly toolbarConfig: _angular_core.Signal<{
|
|
66
|
+
prevNext: boolean;
|
|
67
|
+
counter: boolean;
|
|
68
|
+
zoomIn: boolean;
|
|
69
|
+
zoomOut: boolean;
|
|
70
|
+
resetZoom: boolean;
|
|
71
|
+
rotateLeft: boolean;
|
|
72
|
+
rotateRight: boolean;
|
|
73
|
+
download: boolean;
|
|
74
|
+
print: boolean;
|
|
75
|
+
fullscreen: boolean;
|
|
76
|
+
close: boolean;
|
|
77
|
+
}>;
|
|
78
|
+
protected readonly isZoomed: _angular_core.Signal<boolean>;
|
|
79
|
+
protected readonly stageTransform: _angular_core.Signal<string>;
|
|
80
|
+
private readonly stageEl;
|
|
81
|
+
private readonly hostElRef;
|
|
82
|
+
private readonly destroyRef;
|
|
83
|
+
private pinchStartDistance;
|
|
84
|
+
private pinchStartZoom;
|
|
85
|
+
private stopPanDrag?;
|
|
86
|
+
constructor();
|
|
87
|
+
protected onKeydown(ev: KeyboardEvent): void;
|
|
88
|
+
protected next(): void;
|
|
89
|
+
protected prev(): void;
|
|
90
|
+
protected goTo(index: number): void;
|
|
91
|
+
protected zoomIn(): void;
|
|
92
|
+
protected zoomOut(): void;
|
|
93
|
+
protected resetView(): void;
|
|
94
|
+
protected rotateLeft(): void;
|
|
95
|
+
protected rotateRight(): void;
|
|
96
|
+
protected download(): Promise<void>;
|
|
97
|
+
protected print(): void;
|
|
98
|
+
protected toggleFullscreen(): void;
|
|
99
|
+
protected close(): void;
|
|
100
|
+
protected onPanPointerDown(ev: MouseEvent): void;
|
|
101
|
+
private beginPanDrag;
|
|
102
|
+
private setZoomAtCenter;
|
|
103
|
+
private applyZoomAt;
|
|
104
|
+
private clientXOf;
|
|
105
|
+
private clientYOf;
|
|
106
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxImageViewerComponent, never>;
|
|
107
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgxImageViewerComponent, "ngx-image-viewer", never, { "images": { "alias": "images"; "required": true; "isSignal": true; }; "startIndex": { "alias": "startIndex"; "required": false; "isSignal": true; }; "toolbar": { "alias": "toolbar"; "required": false; "isSignal": true; }; "minZoom": { "alias": "minZoom"; "required": false; "isSignal": true; }; "maxZoom": { "alias": "maxZoom"; "required": false; "isSignal": true; }; "zoomStep": { "alias": "zoomStep"; "required": false; "isSignal": true; }; }, { "indexChange": "indexChange"; "closed": "closed"; }, never, never, true, never>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface NgxImageViewerOpenOptions {
|
|
111
|
+
startIndex?: number;
|
|
112
|
+
toolbar?: NgxImageViewerToolbarConfig;
|
|
113
|
+
minZoom?: number;
|
|
114
|
+
maxZoom?: number;
|
|
115
|
+
zoomStep?: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* راه میانبر برای وقتی که کاربر میخواد ویوئر رو داخل یه دیالوگِ تمامصفحه
|
|
119
|
+
* باز کنه، بدون اینکه خودش دستی wire کنه. اگه کسی میخواد داخل دیالوگِ
|
|
120
|
+
* خودش (مثلاً ngx-kit/dialog) بذارتش، کافیه مستقیم از NgxImageViewerComponent
|
|
121
|
+
* استفاده کنه — این سرویس صرفاً یه میانبَره، وابستگی اجباری نیست.
|
|
122
|
+
*
|
|
123
|
+
* دقیقاً همون الگوی امنشدهی NgxMessageService: با Map<id, ComponentRef> و
|
|
124
|
+
* detachView قبل از destroy، تا اون نشتی حافظهای که قبلاً توی message
|
|
125
|
+
* service پیدا و رفع شد، اینجا از اول تکرار نشه.
|
|
126
|
+
*/
|
|
127
|
+
declare class NgxImageViewerService {
|
|
128
|
+
private readonly appRef;
|
|
129
|
+
private readonly envInjector;
|
|
130
|
+
private nextId;
|
|
131
|
+
private readonly openInstances;
|
|
132
|
+
open(images: NgxImageViewerItem[], options?: NgxImageViewerOpenOptions): {
|
|
133
|
+
close: () => void;
|
|
134
|
+
};
|
|
135
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxImageViewerService, never>;
|
|
136
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<NgxImageViewerService>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface PanZoomState {
|
|
140
|
+
zoom: number;
|
|
141
|
+
panX: number;
|
|
142
|
+
panY: number;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* با تغییر zoom، pan رو طوری تنظیم میکنه که نقطهی زیر cursor/انگشتها
|
|
146
|
+
* (نسبت به مرکز کانتینر) سرجاش بمونه — یعنی zoom-to-cursor بهجای
|
|
147
|
+
* zoom-to-center (که تجربهی خیلی بهتری داره، دقیقاً مثل هر ویوئر حرفهای).
|
|
148
|
+
*
|
|
149
|
+
* ریاضیِ پشتش: با transform="translate(panX,panY) scale(zoom)"، موقعیتِ
|
|
150
|
+
* صفحهایِ یه نقطهی محلیِ p (نسبت به مرکز) برابره با
|
|
151
|
+
* center + pan + p*zoom. اول p رو از روی وضعیت فعلی حساب میکنیم، بعد pan
|
|
152
|
+
* جدید رو طوری میسازیم که با zoom تازه، همون p به همون مختصات صفحه برسه.
|
|
153
|
+
*/
|
|
154
|
+
declare function zoomAroundPoint(current: PanZoomState, newZoom: number, cursorX: number, cursorY: number, containerWidth: number, containerHeight: number): PanZoomState;
|
|
155
|
+
declare function distanceBetweenTouches(a: Touch, b: Touch): number;
|
|
156
|
+
declare function midpointOfTouches(a: Touch, b: Touch): {
|
|
157
|
+
x: number;
|
|
158
|
+
y: number;
|
|
159
|
+
};
|
|
160
|
+
declare function clamp(value: number, min: number, max: number): number;
|
|
161
|
+
|
|
162
|
+
/** دانلود تصویر با fetch→blob (نامگذاریِ درست فایل رو تضمین میکنه)؛ اگه CORS اجازه نداد، در تب جدید باز میشه */
|
|
163
|
+
declare function downloadImage(src: string, filename?: string): Promise<void>;
|
|
164
|
+
/** یه پنجرهی جدید فقط با همون تصویر باز میکنه و بعد از لود، print میزنه؛ با DOM API (نه innerHTML) پس در برابر src مخرب امنه */
|
|
165
|
+
declare function printImage(src: string): void;
|
|
166
|
+
|
|
167
|
+
export { NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR, NgxImageViewerComponent, NgxImageViewerService, clamp, distanceBetweenTouches, downloadImage, midpointOfTouches, printImage, zoomAroundPoint };
|
|
168
|
+
export type { NgxImageViewerItem, NgxImageViewerOpenOptions, NgxImageViewerToolbarConfig, PanZoomState };
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
|
|
3
|
+
interface NgxCropRect {
|
|
4
|
+
/** همه به پیکسلهای واقعیِ تصویر مبدأ (نه پیکسل صفحه) */
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
}
|
|
10
|
+
type NgxImageFilterPreset = 'none' | 'grayscale' | 'sepia' | 'invert' | 'cartoon';
|
|
11
|
+
interface NgxImageEditorAdjustments {
|
|
12
|
+
/** همه ۱۰۰ یعنی بدون تغییر؛ بازهی معقول ۰ تا ۲۰۰ */
|
|
13
|
+
brightness: number;
|
|
14
|
+
contrast: number;
|
|
15
|
+
saturation: number;
|
|
16
|
+
/** درجه، ۹۰-درجهای یا آزاد */
|
|
17
|
+
rotation: number;
|
|
18
|
+
filter: NgxImageFilterPreset;
|
|
19
|
+
}
|
|
20
|
+
interface NgxImageEditorResult {
|
|
21
|
+
blob: Blob;
|
|
22
|
+
dataUrl: string;
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface NgxPointerDragDelta {
|
|
28
|
+
dx: number;
|
|
29
|
+
dy: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* درگ عمومی روی پایهی Pointer Events + setPointerCapture (دقیقاً همون
|
|
33
|
+
* تکنیکی که در ngx-kit/data-table برای ریسایز ستون استفاده شده) — نیازی به
|
|
34
|
+
* listener سطح document نداره چون بعد از setPointerCapture، رویدادهای
|
|
35
|
+
* pointermove/pointerup حتی بیرون از محدودهی المنت هم به خودش میرسن.
|
|
36
|
+
*
|
|
37
|
+
* dx/dy تجمعی از لحظهی pointerdown هستن (نه دلتای بین دو move متوالی)، چون
|
|
38
|
+
* معمولاً مصرفکننده میخواد «موقعیت شروع + دلتای کل» رو حساب کنه، نه جمع
|
|
39
|
+
* تدریجی گرد شوندهی دلتاهای ریز.
|
|
40
|
+
*/
|
|
41
|
+
declare class NgxPointerDragDirective {
|
|
42
|
+
dragStart: _angular_core.OutputEmitterRef<void>;
|
|
43
|
+
dragMove: _angular_core.OutputEmitterRef<NgxPointerDragDelta>;
|
|
44
|
+
dragEnd: _angular_core.OutputEmitterRef<void>;
|
|
45
|
+
private dragging;
|
|
46
|
+
private startX;
|
|
47
|
+
private startY;
|
|
48
|
+
onPointerDown(ev: PointerEvent): void;
|
|
49
|
+
onPointerMove(ev: PointerEvent): void;
|
|
50
|
+
onPointerUp(): void;
|
|
51
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxPointerDragDirective, never>;
|
|
52
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgxPointerDragDirective, "[ngxPointerDrag]", never, {}, { "dragStart": "dragStart"; "dragMove": "dragMove"; "dragEnd": "dragEnd"; }, never, never, true, never>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type Corner = 'nw' | 'ne' | 'sw' | 'se';
|
|
56
|
+
/**
|
|
57
|
+
* ویرایشگر تصویر: کراپ + چرخش + روشنایی/کنتراست/اشباع + فیلترهای آماده
|
|
58
|
+
* (سیاهوسفید، سپیا، معکوس، کارتونی) + فشردهسازی خروجی. کاملاً روی Canvas
|
|
59
|
+
* خام پیاده شده، بدون هیچ وابستگی خارجیای.
|
|
60
|
+
*
|
|
61
|
+
* نکتهی مهمِ معماری: تمام تعامل زنده (چرخوندن، جابهجا/ریسایز کراپباکس،
|
|
62
|
+
* پیشنمایش فیلترها حتی کارتونی) روی یه کپیِ کوچیکشده از تصویر انجام میشه
|
|
63
|
+
* (createWorkingCopy)، نه روی تصویر اصلی که ممکنه چند مگاپیکسل باشه — وگرنه
|
|
64
|
+
* درگکردن اسلایدرها/گوشههای کراپ رو کاربر حس تاخیر میکرد. فقط لحظهی
|
|
65
|
+
* save()، رندر نهایی از روی تصویر اصلیِ کامل انجام میشه.
|
|
66
|
+
*/
|
|
67
|
+
declare class NgxImageEditorComponent {
|
|
68
|
+
source: _angular_core.InputSignal<string | Blob | File | null>;
|
|
69
|
+
/** قفل نسبتِ کراپ (مثلاً ۱ برای آواتار مربعی)؛ undefined یعنی آزاد */
|
|
70
|
+
aspectRatio: _angular_core.InputSignal<number | undefined>;
|
|
71
|
+
outputMaxWidth: _angular_core.InputSignal<number | undefined>;
|
|
72
|
+
outputMaxHeight: _angular_core.InputSignal<number | undefined>;
|
|
73
|
+
outputType: _angular_core.InputSignal<"image/jpeg" | "image/png" | "image/webp">;
|
|
74
|
+
/** حداکثر عرض نمایشِ ناحیهی کراپ روی صفحه (پیکسل) */
|
|
75
|
+
displayMaxWidth: _angular_core.InputSignal<number>;
|
|
76
|
+
saved: _angular_core.OutputEmitterRef<NgxImageEditorResult>;
|
|
77
|
+
cancelled: _angular_core.OutputEmitterRef<void>;
|
|
78
|
+
protected readonly loading: _angular_core.WritableSignal<boolean>;
|
|
79
|
+
protected readonly saving: _angular_core.WritableSignal<boolean>;
|
|
80
|
+
protected readonly loadError: _angular_core.WritableSignal<string | null>;
|
|
81
|
+
private readonly originalImage;
|
|
82
|
+
private readonly workingCanvas;
|
|
83
|
+
protected readonly rotation: _angular_core.WritableSignal<number>;
|
|
84
|
+
protected readonly brightness: _angular_core.WritableSignal<number>;
|
|
85
|
+
protected readonly contrast: _angular_core.WritableSignal<number>;
|
|
86
|
+
protected readonly saturation: _angular_core.WritableSignal<number>;
|
|
87
|
+
protected readonly filterPreset: _angular_core.WritableSignal<NgxImageFilterPreset>;
|
|
88
|
+
protected readonly quality: _angular_core.WritableSignal<number>;
|
|
89
|
+
protected readonly crop: _angular_core.WritableSignal<NgxCropRect>;
|
|
90
|
+
protected readonly adjustments: _angular_core.Signal<NgxImageEditorAdjustments>;
|
|
91
|
+
/** تصویرِ (کوچیکشدهیِ) چرخیده — پایهی نمایش صحنهی کراپ */
|
|
92
|
+
protected readonly rotatedWorkingCanvas: _angular_core.Signal<HTMLCanvasElement | null>;
|
|
93
|
+
protected readonly displayScale: _angular_core.Signal<number>;
|
|
94
|
+
protected readonly stageImageUrl: _angular_core.Signal<string | null>;
|
|
95
|
+
protected readonly stageSize: _angular_core.Signal<{
|
|
96
|
+
width: number;
|
|
97
|
+
height: number;
|
|
98
|
+
}>;
|
|
99
|
+
protected readonly cropOverlayStyle: _angular_core.Signal<{
|
|
100
|
+
left: string;
|
|
101
|
+
top: string;
|
|
102
|
+
width: string;
|
|
103
|
+
height: string;
|
|
104
|
+
}>;
|
|
105
|
+
/** پیشنمایش نهایی (کوچیک، حداکثر ۴۸۰ پیکسل) — شامل همهچیز، حتی افکت کارتونی */
|
|
106
|
+
protected readonly previewUrl: _angular_core.Signal<string | null>;
|
|
107
|
+
private moveSnapshot;
|
|
108
|
+
private resizeSnapshot;
|
|
109
|
+
constructor();
|
|
110
|
+
private resetAdjustments;
|
|
111
|
+
protected rotateBy(delta: number): void;
|
|
112
|
+
protected setFilter(preset: NgxImageFilterPreset): void;
|
|
113
|
+
protected onMoveDragStart(): void;
|
|
114
|
+
protected onMoveDragMove(delta: NgxPointerDragDelta): void;
|
|
115
|
+
protected onResizeDragStart(): void;
|
|
116
|
+
protected onResizeDragMove(corner: Corner, delta: NgxPointerDragDelta): void;
|
|
117
|
+
protected cancel(): void;
|
|
118
|
+
save(): Promise<void>;
|
|
119
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxImageEditorComponent, never>;
|
|
120
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgxImageEditorComponent, "ngx-image-editor", never, { "source": { "alias": "source"; "required": false; "isSignal": true; }; "aspectRatio": { "alias": "aspectRatio"; "required": false; "isSignal": true; }; "outputMaxWidth": { "alias": "outputMaxWidth"; "required": false; "isSignal": true; }; "outputMaxHeight": { "alias": "outputMaxHeight"; "required": false; "isSignal": true; }; "outputType": { "alias": "outputType"; "required": false; "isSignal": true; }; "displayMaxWidth": { "alias": "displayMaxWidth"; "required": false; "isSignal": true; }; }, { "saved": "saved"; "cancelled": "cancelled"; }, never, never, true, never>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** یه File/Blob/data-URL/URL رو به یک HTMLImageElement بارگذاریشده تبدیل میکنه */
|
|
124
|
+
declare function loadImage(source: File | Blob | string): Promise<HTMLImageElement>;
|
|
125
|
+
/** canvas.toBlob بهصورت Promise، بههمراه fallback برای مرورگرهای قدیمیتر */
|
|
126
|
+
declare function canvasToBlob(canvas: HTMLCanvasElement, type?: string, quality?: number): Promise<Blob>;
|
|
127
|
+
/**
|
|
128
|
+
* یه کپیِ کوچیکشده از تصویر اصلی میسازه که کل UI ویرایشگر (چرخش، کراپ،
|
|
129
|
+
* پیشنمایش فیلترها/کارتونی) روی همین کار میکنه، نه روی تصویر اصلی که
|
|
130
|
+
* ممکنه چند مگاپیکسل باشه. این باعث میشه درگکردنِ اسلایدرها یا لبههای
|
|
131
|
+
* کراپ روون بمونه؛ خروجی نهایی (save) همیشه از روی تصویر اصلیِ کامل رندر
|
|
132
|
+
* میشه، نه از روی این کپی.
|
|
133
|
+
*/
|
|
134
|
+
declare function createWorkingCopy(img: HTMLImageElement, maxSize?: number): HTMLCanvasElement;
|
|
135
|
+
/** ابعاد جدید رو طوری حساب میکنه که از maxWidth/maxHeight بیشتر نشه، با حفظ نسبت تصویر */
|
|
136
|
+
declare function fitWithin(width: number, height: number, maxWidth?: number, maxHeight?: number): {
|
|
137
|
+
width: number;
|
|
138
|
+
height: number;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/** تصویر مبدأ رو با زاویهی دادهشده روی یه canvas جدید (به اندازهی bounding-box نتیجه) میچرخونه */
|
|
142
|
+
declare function renderRotated(source: CanvasImageSource, width: number, height: number, degrees: number): HTMLCanvasElement;
|
|
143
|
+
/**
|
|
144
|
+
* کراپ + فیلترها رو روی یه canvas خروجی میسازه. brightness/contrast/
|
|
145
|
+
* saturation/grayscale/sepia/invert همه با ctx.filter بومیِ Canvas 2D انجام
|
|
146
|
+
* میشن (شتابدهیشده توسط مرورگر، بدون حلقهی پیکسلی دستی)؛ فقط cartoon
|
|
147
|
+
* (که معادل بومی نداره) با پردازش پیکسلی جدا انجام میشه.
|
|
148
|
+
*
|
|
149
|
+
* maxWidth/maxHeight برای دو حالت استفاده میشه: پیشنمایش زنده (عدد کوچیک،
|
|
150
|
+
* برای واکنشگرا موندن حین کشیدن اسلایدرها) و خروجی نهایی (بدون محدودیت یا
|
|
151
|
+
* محدودیت دلخواه کاربر).
|
|
152
|
+
*/
|
|
153
|
+
declare function renderComposite(source: CanvasImageSource, sourceWidth: number, sourceHeight: number, crop: NgxCropRect, adjustments: NgxImageEditorAdjustments, maxWidth?: number, maxHeight?: number): HTMLCanvasElement;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* افکت «کارتونی»: چون ctx.filter استاندارد چیزی شبیه cartoon نداره (فقط
|
|
157
|
+
* brightness/contrast/saturate/grayscale/sepia/invert/blur/hue-rotate)، این
|
|
158
|
+
* یکی رو واقعاً با پردازش پیکسلی پیاده کردیم؛ دو مرحله:
|
|
159
|
+
*
|
|
160
|
+
* ۱) Posterize: هر کانال رنگ به تعداد محدودی سطح گرد میشه (پهنههای رنگیِ
|
|
161
|
+
* صاف و یکدست، حسِ کارتونی رنگ میده).
|
|
162
|
+
* ۲) لبهیابی Sobel روی نسخهی خاکستریِ تصویر: هرجا شدت لبه از حد آستانه
|
|
163
|
+
* بیشتر باشه، پیکسل تیره میشه (حسِ خط دور کارتونی).
|
|
164
|
+
*
|
|
165
|
+
* روی خودِ ImageData کار میکنه، پس هزینهش با اندازهی تصویر خطیست؛ برای
|
|
166
|
+
* تصاویر خیلی بزرگ (>~3000px) بهتره قبلش resize بشه (که در کامپوننت اصلی
|
|
167
|
+
* با fitWithin قبل از اعمال فیلتر انجام میشه).
|
|
168
|
+
*/
|
|
169
|
+
declare function applyCartoonEffect(ctx: CanvasRenderingContext2D, width: number, height: number, options?: {
|
|
170
|
+
levels?: number;
|
|
171
|
+
edgeThreshold?: number;
|
|
172
|
+
}): void;
|
|
173
|
+
|
|
174
|
+
export { NgxImageEditorComponent, NgxPointerDragDirective, applyCartoonEffect, canvasToBlob, createWorkingCopy, fitWithin, loadImage, renderComposite, renderRotated };
|
|
175
|
+
export type { NgxCropRect, NgxImageEditorAdjustments, NgxImageEditorResult, NgxImageFilterPreset, NgxPointerDragDelta };
|
package/types/ngx-kit-menu.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ declare class NgxContextMenu implements OnDestroy {
|
|
|
38
38
|
private overlayService;
|
|
39
39
|
ngxContextMenu: i0.InputSignal<NgxMenuPanel>;
|
|
40
40
|
private containerRef?;
|
|
41
|
+
private readonly boundOnClick;
|
|
41
42
|
constructor(el: ElementRef<HTMLElement>, appRef: ApplicationRef, overlayService: OverlayService);
|
|
42
43
|
ngOnDestroy(): void;
|
|
43
44
|
onClick(ev: PointerEvent): void;
|
|
@@ -173,8 +173,11 @@ declare class MSG {
|
|
|
173
173
|
static success(title: string, text?: string, options?: IMessageOptions): ngx_kit_message.MessageOutput<any>;
|
|
174
174
|
static warning(title: string, text?: string, options?: IMessageOptions): ngx_kit_message.MessageOutput<any>;
|
|
175
175
|
static error(title: string, text?: string, options?: IMessageOptions): ngx_kit_message.MessageOutput<any>;
|
|
176
|
+
static question(title: string, text?: string, options?: IMessageOptions): ngx_kit_message.MessageOutput<any>;
|
|
176
177
|
static loading(title: string, text?: string, options?: IMessageOptions): ngx_kit_message.MessageOutput<any>;
|
|
177
178
|
}
|
|
179
|
+
declare class Modal extends MSG {
|
|
180
|
+
}
|
|
178
181
|
|
|
179
182
|
type MessageOutput<T = any> = {
|
|
180
183
|
id: number;
|
|
@@ -216,6 +219,7 @@ declare class NgxMessageComponent implements OnInit, AfterViewInit {
|
|
|
216
219
|
index: number;
|
|
217
220
|
protected sanitizer: DomSanitizer;
|
|
218
221
|
protected doc: Document;
|
|
222
|
+
private readonly messageService;
|
|
219
223
|
private readonly _onClose;
|
|
220
224
|
onClose: rxjs.Observable<{
|
|
221
225
|
index: number;
|
|
@@ -223,6 +227,14 @@ declare class NgxMessageComponent implements OnInit, AfterViewInit {
|
|
|
223
227
|
}>;
|
|
224
228
|
ngOnInit(): void;
|
|
225
229
|
ngAfterViewInit(): void;
|
|
230
|
+
/**
|
|
231
|
+
* وقتی چند تا پیام همزمان باز باشن، هرکدوم listener خودشو روی document
|
|
232
|
+
* داشت — پس یه فشردن Escape/Enter، رویداد رو به *همهشون* همزمان میفرستاد،
|
|
233
|
+
* نه فقط آخرین پیامی که باز شده (رفتار طبیعیِ یه استکِ مودال باید این باشه
|
|
234
|
+
* که فقط بالاترین لایه به کیبورد واکنش نشون بده). این چک همون چیزیه که
|
|
235
|
+
* OverlayService با getLastDialog() برای اورلیها انجام میده.
|
|
236
|
+
*/
|
|
237
|
+
private isTopmost;
|
|
226
238
|
onScapeKey(event: Event): void;
|
|
227
239
|
onEnterKey(event: Event): void;
|
|
228
240
|
onConfirm(): void;
|
|
@@ -240,8 +252,7 @@ declare class NgxMessageService {
|
|
|
240
252
|
private injector;
|
|
241
253
|
private envInjector;
|
|
242
254
|
private _doc;
|
|
243
|
-
|
|
244
|
-
alerts: ComponentRef<NgxMessageComponent>[];
|
|
255
|
+
alerts: Map<number, ComponentRef<NgxMessageComponent>>;
|
|
245
256
|
insertedId: number;
|
|
246
257
|
constructor(appRef: ApplicationRef, injector: Injector, envInjector: EnvironmentInjector, _doc: Document);
|
|
247
258
|
show<T = any>(c?: IMessageOptions): MessageOutput<T>;
|
|
@@ -291,5 +302,5 @@ declare const NGX_MESSAGE_CONFIGS: InjectionToken<IMessageOptions>;
|
|
|
291
302
|
declare const NGX_MESSAGE_API: InjectionToken<NgxMessageService>;
|
|
292
303
|
declare const NGX_MESSAGE_DEFAULT_OPTIONS: MessageOptions;
|
|
293
304
|
|
|
294
|
-
export { DismissReason, MSG, MessageOptions, NGX_MESSAGE_API, NGX_MESSAGE_CONFIGS, NGX_MESSAGE_DEFAULT_OPTIONS, NgxMessageService, provideMessage };
|
|
305
|
+
export { DismissReason, MSG, MessageOptions, Modal, NGX_MESSAGE_API, NGX_MESSAGE_CONFIGS, NGX_MESSAGE_DEFAULT_OPTIONS, NgxMessageService, provideMessage };
|
|
295
306
|
export type { IMessageOptions, MessageOutput, MessageResult };
|