@uxf/ui 11.104.0 → 11.105.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/modal/README.md +64 -22
- package/modal/index.d.ts +1 -1
- package/modal/index.js +2 -2
- package/modal/modal-service.d.ts +3 -3
- package/modal/modal-service.js +5 -10
- package/modal/modal.stories.js +5 -5
- package/package.json +1 -1
package/modal/README.md
CHANGED
|
@@ -50,7 +50,7 @@ function Component(props: AppProps) {
|
|
|
50
50
|
return (
|
|
51
51
|
<div>
|
|
52
52
|
<Button onClick={() => setIsOpen(true)}>Click to open modal</Button>
|
|
53
|
-
<Modal
|
|
53
|
+
<Modal onClose={() => setIsOpen(false)} isOpen={isOpen}>
|
|
54
54
|
<DialogPanel width="xs">Whatever content inside Modal</DialogPanel>
|
|
55
55
|
</Modal>
|
|
56
56
|
</div>
|
|
@@ -64,15 +64,13 @@ The modal system supports opening multiple modals simultaneously in different la
|
|
|
64
64
|
|
|
65
65
|
### Default Layer Configuration
|
|
66
66
|
|
|
67
|
-
By default,
|
|
67
|
+
By default, two layers are available:
|
|
68
68
|
|
|
69
69
|
```typescript
|
|
70
70
|
{
|
|
71
71
|
layers: {
|
|
72
|
-
main: { name: "main", zIndex:
|
|
73
|
-
|
|
74
|
-
alert: { name: "alert", zIndex: 1020 },
|
|
75
|
-
critical: { name: "critical", zIndex: 1030 },
|
|
72
|
+
main: { name: "main", zIndex: 100 },
|
|
73
|
+
confirm: { name: "confirm", zIndex: 1000 },
|
|
76
74
|
},
|
|
77
75
|
defaultLayer: "main"
|
|
78
76
|
}
|
|
@@ -81,7 +79,7 @@ By default, four layers are available:
|
|
|
81
79
|
### Basic Usage with Layers
|
|
82
80
|
|
|
83
81
|
```tsx
|
|
84
|
-
import { openModal, closeModal,
|
|
82
|
+
import { openModal, closeModal, closeModalLayer, closeAllModals } from "@uxf/ui/modal";
|
|
85
83
|
|
|
86
84
|
// Open modal in default "main" layer
|
|
87
85
|
openModal({
|
|
@@ -92,17 +90,14 @@ openModal({
|
|
|
92
90
|
openModal({
|
|
93
91
|
children: <DialogPanel>Confirmation dialog</DialogPanel>
|
|
94
92
|
}, {
|
|
95
|
-
layer: "
|
|
93
|
+
layer: "confirm" // TypeScript autocompletes: "main" | "confirm"
|
|
96
94
|
});
|
|
97
95
|
|
|
98
|
-
// Close topmost modal
|
|
96
|
+
// Close topmost modal (highest z-index)
|
|
99
97
|
closeModal();
|
|
100
98
|
|
|
101
|
-
// Close
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// Close all modals in a layer
|
|
105
|
-
closeModalsByLayer("alert");
|
|
99
|
+
// Close all modals in a specific layer
|
|
100
|
+
closeModalLayer("confirm");
|
|
106
101
|
|
|
107
102
|
// Close all modals across all layers
|
|
108
103
|
closeAllModals();
|
|
@@ -113,7 +108,58 @@ closeAllModals();
|
|
|
113
108
|
- Modals with higher z-index appear on top of modals with lower z-index
|
|
114
109
|
- Only the topmost modal (highest z-index) responds to backdrop clicks and ESC key
|
|
115
110
|
- Clicking inside a higher-layer modal will NOT close lower-layer modals
|
|
116
|
-
- Each layer can have one modal by default (use `
|
|
111
|
+
- Each layer can have one modal by default (use `shouldReplace: false` option to allow multiple)
|
|
112
|
+
|
|
113
|
+
## Closing Modals
|
|
114
|
+
|
|
115
|
+
### Service functions (for modals opened via `openModal`)
|
|
116
|
+
|
|
117
|
+
| Function | Description |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `closeModal()` | Closes the topmost modal (highest z-index across all layers) |
|
|
120
|
+
| `closeModalLayer(layer)` | Closes all modals in the specified layer |
|
|
121
|
+
| `closeAllModals()` | Closes all modals across all layers |
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { closeModal, closeModalLayer, closeAllModals } from "@uxf/ui/modal";
|
|
125
|
+
|
|
126
|
+
closeModal(); // closes topmost
|
|
127
|
+
closeModalLayer("confirm"); // closes all in "confirm" layer
|
|
128
|
+
closeAllModals(); // closes everything
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### `onClose` callback
|
|
132
|
+
|
|
133
|
+
When opening a modal via `openModal`, you can pass an `onClose` callback that fires whenever the modal is closed (by backdrop click, ESC key, or programmatic close):
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
openModal({
|
|
137
|
+
children: <DialogPanel>Content</DialogPanel>,
|
|
138
|
+
onClose: () => console.log("modal closed"),
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Disabling close triggers
|
|
143
|
+
|
|
144
|
+
You can prevent the modal from being closed by backdrop click or ESC key:
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
openModal({
|
|
148
|
+
children: <DialogPanel>Content</DialogPanel>,
|
|
149
|
+
isBackdropCloseDisabled: true, // backdrop click won't close
|
|
150
|
+
isEscapeKeyCloseDisabled: true, // ESC key won't close
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### `Modal` component (controlled)
|
|
155
|
+
|
|
156
|
+
When using the `Modal` component directly, pass `onClose` to handle close events:
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
<Modal onClose={() => setIsOpen(false)} isOpen={isOpen} isBackdropCloseDisabled={false}>
|
|
160
|
+
<DialogPanel>Content</DialogPanel>
|
|
161
|
+
</Modal>
|
|
162
|
+
```
|
|
117
163
|
|
|
118
164
|
## Custom Layer Configuration
|
|
119
165
|
|
|
@@ -180,10 +226,9 @@ You can extend the available layer names using TypeScript declaration merging:
|
|
|
180
226
|
// types/modal.d.ts (in your project)
|
|
181
227
|
import "@uxf/ui/modal";
|
|
182
228
|
|
|
183
|
-
declare module "@uxf/ui/modal" {
|
|
229
|
+
declare module "@uxf/ui/modal/theme" {
|
|
184
230
|
interface ModalLayers {
|
|
185
231
|
// Add your custom layer names
|
|
186
|
-
base: true;
|
|
187
232
|
form: true;
|
|
188
233
|
notification: true;
|
|
189
234
|
tooltip: true;
|
|
@@ -201,11 +246,8 @@ const customModalLayers = {
|
|
|
201
246
|
layers: {
|
|
202
247
|
// Default layers (keep or override)
|
|
203
248
|
main: { name: "main", zIndex: 1000 },
|
|
204
|
-
|
|
205
|
-
alert: { name: "alert", zIndex: 1020 },
|
|
206
|
-
critical: { name: "critical", zIndex: 1030 },
|
|
249
|
+
confirm: { name: "confirm", zIndex: 1010 },
|
|
207
250
|
// Your custom layers
|
|
208
|
-
base: { name: "base", zIndex: 900 },
|
|
209
251
|
form: { name: "form", zIndex: 1100 },
|
|
210
252
|
notification: { name: "notification", zIndex: 9000 },
|
|
211
253
|
tooltip: { name: "tooltip", zIndex: 9999 },
|
|
@@ -228,7 +270,7 @@ openModal({
|
|
|
228
270
|
children: <DialogPanel>Form content</DialogPanel>
|
|
229
271
|
}, {
|
|
230
272
|
layer: "form" // ✅ TypeScript autocompletes and validates!
|
|
231
|
-
// Available: "main" | "
|
|
273
|
+
// Available: "main" | "confirm" | "form" | "notification" | "tooltip"
|
|
232
274
|
});
|
|
233
275
|
```
|
|
234
276
|
|
package/modal/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { DEFAULT_MODAL_LAYERS } from "./constants";
|
|
|
2
2
|
export { Modal } from "./modal";
|
|
3
3
|
export { ModalLayerConfigProvider, useModalLayerConfig } from "./modal-layer-config";
|
|
4
4
|
export { ModalProvider } from "./modal-provider";
|
|
5
|
-
export { closeAllModals, closeModal,
|
|
5
|
+
export { closeAllModals, closeModal, closeModalLayer, getModalStackRef, openModal } from "./modal-service";
|
|
6
6
|
export type { ModalInstance, ModalLayerConfig, ModalLayerName, ModalLayersConfiguration, ModalProps, ModalProviderProps, ModalRef, ModalStackRef, ModalVariant, OpenModalOptions, } from "./types";
|
|
7
7
|
/** @deprecated use getModalStackRef */
|
|
8
8
|
export { getModalStackRef as getModalRef } from "./modal-service";
|
package/modal/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getModalRef = exports.openModal = exports.getModalStackRef = exports.
|
|
3
|
+
exports.getModalRef = exports.openModal = exports.getModalStackRef = exports.closeModalLayer = exports.closeModal = exports.closeAllModals = exports.ModalProvider = exports.useModalLayerConfig = exports.ModalLayerConfigProvider = exports.Modal = exports.DEFAULT_MODAL_LAYERS = void 0;
|
|
4
4
|
var constants_1 = require("./constants");
|
|
5
5
|
Object.defineProperty(exports, "DEFAULT_MODAL_LAYERS", { enumerable: true, get: function () { return constants_1.DEFAULT_MODAL_LAYERS; } });
|
|
6
6
|
var modal_1 = require("./modal");
|
|
@@ -13,7 +13,7 @@ Object.defineProperty(exports, "ModalProvider", { enumerable: true, get: functio
|
|
|
13
13
|
var modal_service_1 = require("./modal-service");
|
|
14
14
|
Object.defineProperty(exports, "closeAllModals", { enumerable: true, get: function () { return modal_service_1.closeAllModals; } });
|
|
15
15
|
Object.defineProperty(exports, "closeModal", { enumerable: true, get: function () { return modal_service_1.closeModal; } });
|
|
16
|
-
Object.defineProperty(exports, "
|
|
16
|
+
Object.defineProperty(exports, "closeModalLayer", { enumerable: true, get: function () { return modal_service_1.closeModalLayer; } });
|
|
17
17
|
Object.defineProperty(exports, "getModalStackRef", { enumerable: true, get: function () { return modal_service_1.getModalStackRef; } });
|
|
18
18
|
Object.defineProperty(exports, "openModal", { enumerable: true, get: function () { return modal_service_1.openModal; } });
|
|
19
19
|
// Backwards compatibility: getModalRef is now an alias for getModalStackRef
|
package/modal/modal-service.d.ts
CHANGED
|
@@ -6,13 +6,13 @@ export declare function getModalStackRef(): import("react").RefObject<ModalStack
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function openModal(modal: ModalProviderProps, options?: OpenModalOptions): string;
|
|
8
8
|
/**
|
|
9
|
-
* Closes the topmost modal
|
|
9
|
+
* Closes the topmost modal (highest z-index)
|
|
10
10
|
*/
|
|
11
|
-
export declare function closeModal(
|
|
11
|
+
export declare function closeModal(): void;
|
|
12
12
|
/**
|
|
13
13
|
* Closes all modals in a specific layer
|
|
14
14
|
*/
|
|
15
|
-
export declare function
|
|
15
|
+
export declare function closeModalLayer(layer: ModalLayerName): void;
|
|
16
16
|
/**
|
|
17
17
|
* Closes all modals across all layers
|
|
18
18
|
*/
|
package/modal/modal-service.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getModalStackRef = getModalStackRef;
|
|
4
4
|
exports.openModal = openModal;
|
|
5
5
|
exports.closeModal = closeModal;
|
|
6
|
-
exports.
|
|
6
|
+
exports.closeModalLayer = closeModalLayer;
|
|
7
7
|
exports.closeAllModals = closeAllModals;
|
|
8
8
|
const react_1 = require("react");
|
|
9
9
|
const modalStackRef = (0, react_1.createRef)();
|
|
@@ -23,23 +23,18 @@ function openModal(modal, options) {
|
|
|
23
23
|
return modalStackRef.current.openInLayer(modal, options);
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* Closes the topmost modal
|
|
26
|
+
* Closes the topmost modal (highest z-index)
|
|
27
27
|
*/
|
|
28
|
-
function closeModal(
|
|
28
|
+
function closeModal() {
|
|
29
29
|
if (!modalStackRef.current) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
modalStackRef.current.closeLayer(layer);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
modalStackRef.current.closeTopmost();
|
|
37
|
-
}
|
|
32
|
+
modalStackRef.current.closeTopmost();
|
|
38
33
|
}
|
|
39
34
|
/**
|
|
40
35
|
* Closes all modals in a specific layer
|
|
41
36
|
*/
|
|
42
|
-
function
|
|
37
|
+
function closeModalLayer(layer) {
|
|
43
38
|
if (!modalStackRef.current) {
|
|
44
39
|
return;
|
|
45
40
|
}
|
package/modal/modal.stories.js
CHANGED
|
@@ -129,13 +129,13 @@ function ModalProviderWithLayers() {
|
|
|
129
129
|
react_1.default.createElement("p", { className: "mb-2 text-lg font-bold" }, "Main Layer Modal"),
|
|
130
130
|
react_1.default.createElement("p", { className: "mb-4 text-sm text-gray-600" }, "This is in the \"main\" layer (default)"),
|
|
131
131
|
react_1.default.createElement("div", { className: "space-y-2" },
|
|
132
|
-
react_1.default.createElement(button_1.Button, { isFullWidth: true, onClick: () => (0, modal_service_1.
|
|
132
|
+
react_1.default.createElement(button_1.Button, { isFullWidth: true, onClick: () => (0, modal_service_1.closeModalLayer)("main") }, "Close Main Layer"),
|
|
133
133
|
react_1.default.createElement(button_1.Button, { isFullWidth: true, onClick: () => (0, modal_service_1.openModal)({
|
|
134
134
|
children: (react_1.default.createElement(dialog_1.DialogPanel, { width: "sm" },
|
|
135
135
|
react_1.default.createElement("div", { className: "p-4" },
|
|
136
136
|
react_1.default.createElement("p", { className: "mb-2 text-lg font-bold" }, "Confirmation Layer"),
|
|
137
137
|
react_1.default.createElement("p", { className: "mb-4 text-sm text-gray-600" }, "This is in the \"confirmation\" layer (above main)"),
|
|
138
|
-
react_1.default.createElement(button_1.Button, { isFullWidth: true, onClick: () => (0, modal_service_1.
|
|
138
|
+
react_1.default.createElement(button_1.Button, { isFullWidth: true, onClick: () => (0, modal_service_1.closeModalLayer)("confirm") }, "Close Confirmation")))),
|
|
139
139
|
}, { layer: "confirm" }) }, "Open Confirmation Layer"))))),
|
|
140
140
|
}, { layer: "main" }) }, "Open in Main Layer"),
|
|
141
141
|
react_1.default.createElement(button_1.Button, { onClick: () => {
|
|
@@ -144,13 +144,13 @@ function ModalProviderWithLayers() {
|
|
|
144
144
|
children: (react_1.default.createElement(dialog_1.DialogPanel, { width: "xl" },
|
|
145
145
|
react_1.default.createElement("div", { className: "p-4" },
|
|
146
146
|
react_1.default.createElement("p", { className: "mb-2 text-lg font-bold" }, "Main Layer"),
|
|
147
|
-
react_1.default.createElement("p", { className: "text-sm text-gray-600" }, "Layer
|
|
147
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600" }, "Layer: main - z-index: 100")))),
|
|
148
148
|
}, { layer: "main" });
|
|
149
149
|
(0, modal_service_1.openModal)({
|
|
150
150
|
children: (react_1.default.createElement(dialog_1.DialogPanel, { width: "default" },
|
|
151
151
|
react_1.default.createElement("div", { className: "p-4" },
|
|
152
152
|
react_1.default.createElement("p", { className: "mb-2 text-lg font-bold" }, "Confirmation Layer"),
|
|
153
|
-
react_1.default.createElement("p", { className: "text-sm text-gray-600" }, "Layer
|
|
153
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600" }, "Layer: confirm - z-index: 1000")))),
|
|
154
154
|
}, { layer: "confirm" });
|
|
155
155
|
}, variant: "secondary" }, "Open All 2 Layers")),
|
|
156
156
|
react_1.default.createElement("h3", { className: "uxf-typo-h5 mb-2" }, "Default Layer Configuration"),
|
|
@@ -160,5 +160,5 @@ function ModalProviderWithLayers() {
|
|
|
160
160
|
" z-index 100"),
|
|
161
161
|
react_1.default.createElement("li", null,
|
|
162
162
|
react_1.default.createElement("strong", null, "confirm:"),
|
|
163
|
-
" z-index
|
|
163
|
+
" z-index 1000")))));
|
|
164
164
|
}
|