@nuralyui/modal 0.0.2 → 0.0.4

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/index.d.ts CHANGED
@@ -1,2 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
1
6
  export * from './modal.component.js';
7
+ export * from './modal.types.js';
8
+ export * from './modal-manager.js';
9
+ export * from './controllers/index.js';
2
10
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,2 +1,10 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
1
6
  export * from './modal.component.js';
7
+ export * from './modal.types.js';
8
+ export * from './modal-manager.js';
9
+ export * from './controllers/index.js';
2
10
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/modal/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC","sourcesContent":["export * from './modal.component.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/modal/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nexport * from './modal.component.js';\nexport * from './modal.types.js';\nexport * from './modal-manager.js';\nexport * from './controllers/index.js';\n"]}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Modal stack item interface
8
+ */
9
+ export interface ModalStackItem {
10
+ modal: any;
11
+ previousFocus: Element | null;
12
+ zIndex: number;
13
+ id: string;
14
+ }
15
+ /**
16
+ * Modal Manager - Singleton class to handle nested modals
17
+ * Manages the modal stack, z-index allocation, and focus management
18
+ */
19
+ declare class ModalManagerClass {
20
+ private modalStack;
21
+ private baseZIndex;
22
+ private zIndexIncrement;
23
+ private bodyScrollDisabled;
24
+ private originalBodyOverflow;
25
+ /**
26
+ * Opens a modal and adds it to the stack
27
+ */
28
+ openModal(modal: any): number;
29
+ /**
30
+ * Closes a modal and removes it from the stack
31
+ */
32
+ closeModal(modal: any): void;
33
+ /**
34
+ * Gets the current z-index for a modal
35
+ */
36
+ getModalZIndex(modal: any): number;
37
+ /**
38
+ * Checks if a modal is the top modal in the stack
39
+ */
40
+ isTopModal(modal: any): boolean;
41
+ /**
42
+ * Gets the number of open modals
43
+ */
44
+ getStackDepth(): number;
45
+ /**
46
+ * Closes all modals
47
+ */
48
+ closeAllModals(): void;
49
+ /**
50
+ * Gets all open modal IDs
51
+ */
52
+ getOpenModalIds(): string[];
53
+ /**
54
+ * Checks if any modals are open
55
+ */
56
+ hasOpenModals(): boolean;
57
+ private generateModalId;
58
+ private updateModalZIndex;
59
+ private disableBodyScroll;
60
+ private restoreBodyScroll;
61
+ /**
62
+ * Handle Escape key for nested modals - only close the top modal
63
+ */
64
+ handleEscapeKey(): boolean;
65
+ /**
66
+ * Handle backdrop clicks - only close if it's the top modal
67
+ */
68
+ handleBackdropClick(modal: any): boolean;
69
+ }
70
+ export declare const ModalManager: ModalManagerClass;
71
+ export {};
72
+ //# sourceMappingURL=modal-manager.d.ts.map
@@ -0,0 +1,171 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Modal Manager - Singleton class to handle nested modals
8
+ * Manages the modal stack, z-index allocation, and focus management
9
+ */
10
+ class ModalManagerClass {
11
+ constructor() {
12
+ this.modalStack = [];
13
+ this.baseZIndex = 1000;
14
+ this.zIndexIncrement = 10;
15
+ this.bodyScrollDisabled = false;
16
+ this.originalBodyOverflow = '';
17
+ }
18
+ /**
19
+ * Opens a modal and adds it to the stack
20
+ */
21
+ openModal(modal) {
22
+ const id = this.generateModalId();
23
+ const zIndex = this.baseZIndex + (this.modalStack.length * this.zIndexIncrement);
24
+ // Store the currently focused element
25
+ const previousFocus = document.activeElement;
26
+ // Add to stack
27
+ const stackItem = {
28
+ modal,
29
+ previousFocus,
30
+ zIndex,
31
+ id
32
+ };
33
+ this.modalStack.push(stackItem);
34
+ // Disable body scroll for the first modal
35
+ if (this.modalStack.length === 1) {
36
+ this.disableBodyScroll();
37
+ }
38
+ // Update modal z-index
39
+ this.updateModalZIndex(modal, zIndex);
40
+ console.log(`Modal opened. Stack depth: ${this.modalStack.length}, Z-Index: ${zIndex}`);
41
+ return zIndex;
42
+ }
43
+ /**
44
+ * Closes a modal and removes it from the stack
45
+ */
46
+ closeModal(modal) {
47
+ const index = this.modalStack.findIndex(item => item.modal === modal);
48
+ if (index === -1) {
49
+ console.warn('Attempting to close a modal that is not in the stack');
50
+ return;
51
+ }
52
+ const stackItem = this.modalStack[index];
53
+ // If this is not the top modal, close all modals above it first
54
+ if (index < this.modalStack.length - 1) {
55
+ const modalsToClose = this.modalStack.slice(index + 1);
56
+ modalsToClose.forEach(item => {
57
+ if (item.modal && typeof item.modal.closeModal === 'function') {
58
+ item.modal.closeModal();
59
+ }
60
+ });
61
+ }
62
+ // Remove from stack
63
+ this.modalStack.splice(index);
64
+ // Restore focus to the previous element
65
+ if (stackItem.previousFocus instanceof HTMLElement) {
66
+ // Use setTimeout to ensure the modal DOM changes are complete
67
+ setTimeout(() => {
68
+ if (stackItem.previousFocus instanceof HTMLElement) {
69
+ stackItem.previousFocus.focus();
70
+ }
71
+ }, 100);
72
+ }
73
+ // If this was the last modal, restore body scroll
74
+ if (this.modalStack.length === 0) {
75
+ this.restoreBodyScroll();
76
+ }
77
+ console.log(`Modal closed. Stack depth: ${this.modalStack.length}`);
78
+ }
79
+ /**
80
+ * Gets the current z-index for a modal
81
+ */
82
+ getModalZIndex(modal) {
83
+ const stackItem = this.modalStack.find(item => item.modal === modal);
84
+ return stackItem ? stackItem.zIndex : this.baseZIndex;
85
+ }
86
+ /**
87
+ * Checks if a modal is the top modal in the stack
88
+ */
89
+ isTopModal(modal) {
90
+ if (this.modalStack.length === 0)
91
+ return false;
92
+ return this.modalStack[this.modalStack.length - 1].modal === modal;
93
+ }
94
+ /**
95
+ * Gets the number of open modals
96
+ */
97
+ getStackDepth() {
98
+ return this.modalStack.length;
99
+ }
100
+ /**
101
+ * Closes all modals
102
+ */
103
+ closeAllModals() {
104
+ // Close from top to bottom to maintain proper order
105
+ const modalsToClose = [...this.modalStack].reverse();
106
+ modalsToClose.forEach(item => {
107
+ if (item.modal && typeof item.modal.closeModal === 'function') {
108
+ item.modal.closeModal();
109
+ }
110
+ });
111
+ }
112
+ /**
113
+ * Gets all open modal IDs
114
+ */
115
+ getOpenModalIds() {
116
+ return this.modalStack.map(item => item.id);
117
+ }
118
+ /**
119
+ * Checks if any modals are open
120
+ */
121
+ hasOpenModals() {
122
+ return this.modalStack.length > 0;
123
+ }
124
+ generateModalId() {
125
+ return `modal-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
126
+ }
127
+ updateModalZIndex(modal, zIndex) {
128
+ if (modal && modal.style) {
129
+ modal.style.setProperty('--nuraly-z-modal-backdrop', zIndex.toString());
130
+ }
131
+ }
132
+ disableBodyScroll() {
133
+ if (!this.bodyScrollDisabled) {
134
+ this.originalBodyOverflow = document.body.style.overflow;
135
+ document.body.style.overflow = 'hidden';
136
+ this.bodyScrollDisabled = true;
137
+ }
138
+ }
139
+ restoreBodyScroll() {
140
+ if (this.bodyScrollDisabled) {
141
+ document.body.style.overflow = this.originalBodyOverflow;
142
+ this.bodyScrollDisabled = false;
143
+ }
144
+ }
145
+ /**
146
+ * Handle Escape key for nested modals - only close the top modal
147
+ */
148
+ handleEscapeKey() {
149
+ if (this.modalStack.length === 0)
150
+ return false;
151
+ const topModal = this.modalStack[this.modalStack.length - 1].modal;
152
+ if (topModal && typeof topModal.closeModal === 'function' && topModal.closable !== false) {
153
+ topModal.closeModal();
154
+ return true;
155
+ }
156
+ return false;
157
+ }
158
+ /**
159
+ * Handle backdrop clicks - only close if it's the top modal
160
+ */
161
+ handleBackdropClick(modal) {
162
+ return this.isTopModal(modal);
163
+ }
164
+ }
165
+ // Export singleton instance
166
+ export const ModalManager = new ModalManagerClass();
167
+ // Make it available globally for debugging
168
+ if (typeof window !== 'undefined') {
169
+ window.ModalManager = ModalManager;
170
+ }
171
+ //# sourceMappingURL=modal-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-manager.js","sourceRoot":"","sources":["../../../src/components/modal/modal-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\n/**\n * Modal stack item interface\n */\nexport interface ModalStackItem {\n modal: any; // The modal element\n previousFocus: Element | null; // The element that had focus before this modal\n zIndex: number; // The z-index for this modal\n id: string; // Unique identifier\n}\n\n/**\n * Modal Manager - Singleton class to handle nested modals\n * Manages the modal stack, z-index allocation, and focus management\n */\nclass ModalManagerClass {\n private modalStack: ModalStackItem[] = [];\n private baseZIndex = 1000;\n private zIndexIncrement = 10;\n private bodyScrollDisabled = false;\n private originalBodyOverflow = '';\n\n /**\n * Opens a modal and adds it to the stack\n */\n openModal(modal: any): number {\n const id = this.generateModalId();\n const zIndex = this.baseZIndex + (this.modalStack.length * this.zIndexIncrement);\n \n // Store the currently focused element\n const previousFocus = document.activeElement;\n \n // Add to stack\n const stackItem: ModalStackItem = {\n modal,\n previousFocus,\n zIndex,\n id\n };\n \n this.modalStack.push(stackItem);\n \n // Disable body scroll for the first modal\n if (this.modalStack.length === 1) {\n this.disableBodyScroll();\n }\n \n // Update modal z-index\n this.updateModalZIndex(modal, zIndex);\n \n console.log(`Modal opened. Stack depth: ${this.modalStack.length}, Z-Index: ${zIndex}`);\n \n return zIndex;\n }\n\n /**\n * Closes a modal and removes it from the stack\n */\n closeModal(modal: any): void {\n const index = this.modalStack.findIndex(item => item.modal === modal);\n \n if (index === -1) {\n console.warn('Attempting to close a modal that is not in the stack');\n return;\n }\n \n const stackItem = this.modalStack[index];\n \n // If this is not the top modal, close all modals above it first\n if (index < this.modalStack.length - 1) {\n const modalsToClose = this.modalStack.slice(index + 1);\n modalsToClose.forEach(item => {\n if (item.modal && typeof item.modal.closeModal === 'function') {\n item.modal.closeModal();\n }\n });\n }\n \n // Remove from stack\n this.modalStack.splice(index);\n \n // Restore focus to the previous element\n if (stackItem.previousFocus instanceof HTMLElement) {\n // Use setTimeout to ensure the modal DOM changes are complete\n setTimeout(() => {\n if (stackItem.previousFocus instanceof HTMLElement) {\n stackItem.previousFocus.focus();\n }\n }, 100);\n }\n \n // If this was the last modal, restore body scroll\n if (this.modalStack.length === 0) {\n this.restoreBodyScroll();\n }\n \n console.log(`Modal closed. Stack depth: ${this.modalStack.length}`);\n }\n\n /**\n * Gets the current z-index for a modal\n */\n getModalZIndex(modal: any): number {\n const stackItem = this.modalStack.find(item => item.modal === modal);\n return stackItem ? stackItem.zIndex : this.baseZIndex;\n }\n\n /**\n * Checks if a modal is the top modal in the stack\n */\n isTopModal(modal: any): boolean {\n if (this.modalStack.length === 0) return false;\n return this.modalStack[this.modalStack.length - 1].modal === modal;\n }\n\n /**\n * Gets the number of open modals\n */\n getStackDepth(): number {\n return this.modalStack.length;\n }\n\n /**\n * Closes all modals\n */\n closeAllModals(): void {\n // Close from top to bottom to maintain proper order\n const modalsToClose = [...this.modalStack].reverse();\n modalsToClose.forEach(item => {\n if (item.modal && typeof item.modal.closeModal === 'function') {\n item.modal.closeModal();\n }\n });\n }\n\n /**\n * Gets all open modal IDs\n */\n getOpenModalIds(): string[] {\n return this.modalStack.map(item => item.id);\n }\n\n /**\n * Checks if any modals are open\n */\n hasOpenModals(): boolean {\n return this.modalStack.length > 0;\n }\n\n private generateModalId(): string {\n return `modal-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private updateModalZIndex(modal: any, zIndex: number): void {\n if (modal && modal.style) {\n modal.style.setProperty('--nuraly-z-modal-backdrop', zIndex.toString());\n }\n }\n\n private disableBodyScroll(): void {\n if (!this.bodyScrollDisabled) {\n this.originalBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n this.bodyScrollDisabled = true;\n }\n }\n\n private restoreBodyScroll(): void {\n if (this.bodyScrollDisabled) {\n document.body.style.overflow = this.originalBodyOverflow;\n this.bodyScrollDisabled = false;\n }\n }\n\n /**\n * Handle Escape key for nested modals - only close the top modal\n */\n handleEscapeKey(): boolean {\n if (this.modalStack.length === 0) return false;\n \n const topModal = this.modalStack[this.modalStack.length - 1].modal;\n if (topModal && typeof topModal.closeModal === 'function' && topModal.closable !== false) {\n topModal.closeModal();\n return true;\n }\n \n return false;\n }\n\n /**\n * Handle backdrop clicks - only close if it's the top modal\n */\n handleBackdropClick(modal: any): boolean {\n return this.isTopModal(modal);\n }\n}\n\n// Export singleton instance\nexport const ModalManager = new ModalManagerClass();\n\n// Make it available globally for debugging\nif (typeof window !== 'undefined') {\n (window as any).ModalManager = ModalManager;\n}"]}
@@ -1,24 +1,123 @@
1
- import { LitElement } from 'lit';
2
- export declare class ModalComponent extends LitElement {
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { LitElement, nothing, PropertyValues } from 'lit';
7
+ import { ModalSize, ModalPosition, ModalAnimation, ModalBackdrop } from './modal.types.js';
8
+ import '../icon/icon.component.js';
9
+ import '../button/button.component.js';
10
+ import { ModalDragHost, ModalKeyboardHost } from './controllers/index.js';
11
+ declare const NrModalElement_base: (new (...args: any[]) => import("../../shared/dependency-mixin.js").DependencyAware) & (new (...args: any[]) => import("../../shared/theme-mixin.js").ThemeAware) & (new (...args: any[]) => import("../../shared/event-handler-mixin.js").EventHandlerCapable) & typeof LitElement;
12
+ /**
13
+ * Versatile modal component with multiple sizes, animations, and enhanced functionality.
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <!-- Simple usage -->
18
+ * <nr-modal open title="My Modal">
19
+ * <p>Modal content goes here</p>
20
+ * </nr-modal>
21
+ *
22
+ * <!-- With custom configuration -->
23
+ * <nr-modal
24
+ * open
25
+ * size="large"
26
+ * position="top"
27
+ * animation="zoom"
28
+ * backdrop="static"
29
+ * draggable>
30
+ * <div slot="header">
31
+ * <nr-icon name="info"></nr-icon>
32
+ * <span>Custom Header</span>
33
+ * </div>
34
+ * <p>Modal content</p>
35
+ * <div slot="footer">
36
+ * <nr-button type="secondary">Cancel</nr-button>
37
+ * <nr-button type="primary">OK</nr-button>
38
+ * </div>
39
+ * </nr-modal>
40
+ * ```
41
+ *
42
+ * @fires modal-open - Modal opened
43
+ * @fires modal-close - Modal closed
44
+ * @fires modal-before-close - Before modal closes (cancelable)
45
+ * @fires modal-after-open - After modal opens
46
+ * @fires modal-escape - Escape key pressed
47
+ *
48
+ * @slot default - Modal body content
49
+ * @slot header - Custom header content
50
+ * @slot footer - Custom footer content
51
+ */
52
+ export declare class NrModalElement extends NrModalElement_base implements ModalDragHost, ModalKeyboardHost {
3
53
  static styles: import("lit").CSSResult;
4
- isOpen: boolean;
5
- label: string;
6
- private offsetX;
7
- private offsetY;
8
- private isDragging;
9
- private initialX;
10
- private initialY;
54
+ /** Whether the modal is open */
55
+ open: boolean;
56
+ /** Modal size (small, medium, large, xl) */
57
+ size: ModalSize;
58
+ /** Modal position (center, top, bottom) */
59
+ position: ModalPosition;
60
+ /** Animation type */
61
+ animation: ModalAnimation;
62
+ /** Backdrop behavior */
63
+ backdrop: ModalBackdrop;
64
+ /** Whether the modal can be closed */
65
+ closable: boolean;
66
+ /** Whether the modal can be dragged */
67
+ modalDraggable: boolean;
68
+ /** Whether the modal is resizable */
69
+ resizable: boolean;
70
+ /** Whether the modal is fullscreen */
71
+ fullscreen: boolean;
72
+ /** Modal title */
73
+ modalTitle: string;
74
+ /** Show close button in header */
75
+ showCloseButton: boolean;
76
+ /** Header icon */
77
+ headerIcon: string;
78
+ /** Z-index for the modal */
79
+ zIndex: number;
80
+ /** Custom width */
81
+ width: string;
82
+ /** Custom height */
83
+ height: string;
84
+ /** Dragging state */
85
+ isDragging: boolean;
86
+ /** Current X offset for dragging */
87
+ offsetX: number;
88
+ /** Current Y offset for dragging */
89
+ offsetY: number;
90
+ /** Animation state */
91
+ private animationState;
92
+ /** Previous focus element */
93
+ private previousActiveElement;
94
+ requiredComponents: string[];
95
+ private dragController;
96
+ private keyboardController;
11
97
  connectedCallback(): void;
12
98
  disconnectedCallback(): void;
13
- private startDrag;
14
- private drag;
15
- private handleKeyDown;
16
- private handleOutsideClick;
17
- private isChildDialog;
99
+ willUpdate(changedProperties: PropertyValues): void;
100
+ private handleOpen;
101
+ private startOpenAnimation;
102
+ private getAnimationKeyframes;
103
+ private handleClose;
104
+ /**
105
+ * Opens the modal
106
+ */
107
+ openModal(): void;
108
+ /**
109
+ * Closes the modal
110
+ */
18
111
  closeModal(): void;
19
- private adjustDialogPosition;
20
- updated(changedProperties: Map<string | number | symbol, unknown>): void;
21
- private stopDrag;
22
- render(): import("lit").TemplateResult<1>;
112
+ private handleBackdropClick;
113
+ private getBackdropClasses;
114
+ private getModalClasses;
115
+ private getModalStyles;
116
+ private renderHeader;
117
+ private renderFooter;
118
+ updated(): void;
119
+ private updateDataTheme;
120
+ render(): import("lit").TemplateResult<1> | typeof nothing;
23
121
  }
122
+ export {};
24
123
  //# sourceMappingURL=modal.component.d.ts.map