@rokku-x/react-hook-dialog 1.1.0 → 1.2.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 +77 -41
- package/dist/README.md +77 -41
- package/dist/components/BaseDialogRenderer.cjs.js +1 -0
- package/dist/components/BaseDialogRenderer.d.ts +13 -0
- package/dist/components/BaseDialogRenderer.esm.js +1 -0
- package/dist/components/ModalWindow.cjs.js +1 -1
- package/dist/components/ModalWindow.esm.js +6 -6
- package/dist/hooks/useHookDialog.cjs.js +1 -1
- package/dist/hooks/useHookDialog.d.ts +7 -2
- package/dist/hooks/useHookDialog.esm.js +1 -1
- package/dist/index.cjs.js +3 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.esm.js +3 -1
- package/dist/react-hook-dialog.css +1 -0
- package/dist/store/dialog.cjs.js +1 -0
- package/dist/store/{dialogStore.d.ts → dialog.d.ts} +7 -3
- package/dist/store/dialog.esm.js +1 -0
- package/package.json +10 -4
- package/dist/store/dialogStore.cjs.js +0 -1
- package/dist/store/dialogStore.esm.js +0 -1
package/README.md
CHANGED
|
@@ -1,38 +1,46 @@
|
|
|
1
1
|
# react-hook-dialog
|
|
2
2
|
|
|
3
|
-
[](https://github.com/rokku-x/react-hook-dialog/actions/workflows/ci.yml)
|
|
3
|
+
[](https://github.com/rokku-x/react-hook-dialog/actions/workflows/ci.yml) [](https://www.npmjs.com/package/@rokku-x/react-hook-dialog) [](https://www.npmjs.com/package/@rokku-x/react-hook-dialog) [](https://www.npmjs.com/package/@rokku-x/react-hook-dialog) 
|
|
4
4
|
|
|
5
|
-
A powerful and flexible React dialog hook library for confirmation dialogs, alerts, and modals. Built on top of `@rokku-x/react-hook-modal` with a focus on dialog-specific features like action buttons, variants, and customizable styling.
|
|
5
|
+
A lightweight, powerful, and flexible React dialog hook library for confirmation dialogs, alerts, and modals. Built on top of `@rokku-x/react-hook-modal` with a focus on dialog-specific features like action buttons, variants, and customizable styling.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
+
- ♿ **Accessibility Focused** - Keyboard navigation and ARIA support
|
|
10
|
+
- 🔄 **Asynchronous** - Async/await friendly dialog results
|
|
9
11
|
- 🎯 **Hook-based API** - Simple and intuitive `useHookDialog()` hook
|
|
10
12
|
- 🎨 **Rich Variants** - 7 button variants (primary, secondary, danger, success, warning, info, neutral)
|
|
11
|
-
- 🧩 **Modular Components** - Composed from reusable Backdrop and DialogWindow components
|
|
12
13
|
- 📝 **Dialog Actions** - Flexible action button system with left/right positioning
|
|
13
14
|
- 💅 **Full Customization** - Injectable className and styles at every level
|
|
14
15
|
- ⌨️ **Rich Configuration** - Default configs with per-call overrides
|
|
15
|
-
- 🎁 **Zero Dependencies** - Only requires React, Zustand, and @rokku-x/react-hook-modal
|
|
16
16
|
- 📱 **TypeScript Support** - Full type safety out of the box
|
|
17
|
-
-
|
|
17
|
+
- 🧑🤝🧑 **Multiple Dialogs** - Support for multiple simultaneous dialogs
|
|
18
|
+
- 🛠️ **Programmatic Control** - Force actions and cancellations via dialog context
|
|
19
|
+
- 🖼️ **Rich Content Support** - Accepts React nodes for titles and content
|
|
20
|
+
- 📦 **Lightweight** - Minimal bundle size for fast load times
|
|
18
21
|
|
|
19
22
|
## Installation
|
|
20
23
|
|
|
21
24
|
```bash
|
|
22
25
|
npm install @rokku-x/react-hook-dialog
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
or
|
|
26
|
-
|
|
27
|
-
```bash
|
|
26
|
+
# or
|
|
27
|
+
bun add @rokku-x/react-hook-dialog
|
|
28
|
+
# or
|
|
28
29
|
yarn add @rokku-x/react-hook-dialog
|
|
30
|
+
# or
|
|
31
|
+
pnpm add @rokku-x/react-hook-dialog
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
## Quick Start
|
|
32
35
|
|
|
33
|
-
### 1. Setup BaseModalRenderer
|
|
36
|
+
### 1. Setup BaseModalRenderer or BaseDialogRenderer
|
|
37
|
+
|
|
38
|
+
You can either use the upstream `BaseModalRenderer` directly (from `@rokku-x/react-hook-modal`) or use the convenience wrapper `BaseDialogRenderer` provided by this package.
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
- `BaseModalRenderer` (upstream): mount this at the root to render modal instances.
|
|
41
|
+
- `BaseDialogRenderer` (this package): a thin wrapper around `BaseModalRenderer` that lets you pass a `defaultConfig` prop to set default dialog options for all dialogs created by `useHookDialog()`.
|
|
42
|
+
|
|
43
|
+
Use `BaseModalRenderer` directly:
|
|
36
44
|
|
|
37
45
|
```tsx
|
|
38
46
|
import { BaseModalRenderer } from '@rokku-x/react-hook-modal';
|
|
@@ -47,6 +55,23 @@ function App() {
|
|
|
47
55
|
}
|
|
48
56
|
```
|
|
49
57
|
|
|
58
|
+
Or use the wrapper `BaseDialogRenderer` from this package to set defaults:
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { BaseDialogRenderer } from '@rokku-x/react-hook-dialog';
|
|
62
|
+
|
|
63
|
+
function App() {
|
|
64
|
+
return (
|
|
65
|
+
<>
|
|
66
|
+
<YourComponents />
|
|
67
|
+
<BaseDialogRenderer defaultConfig={{ showCloseButton: false, backdropCancel: false }} />
|
|
68
|
+
</>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Either component is fine — `BaseDialogRenderer` simply sets the dialog defaults for you so consumers of `useHookDialog()` don't have to provide them on each call.
|
|
74
|
+
|
|
50
75
|
### 2. Use useHookDialog Hook
|
|
51
76
|
|
|
52
77
|
```tsx
|
|
@@ -91,63 +116,62 @@ useHookDialog(defaultConfig?: UseHookDialogConfig)
|
|
|
91
116
|
#### Returns
|
|
92
117
|
|
|
93
118
|
```typescript
|
|
94
|
-
[requestDialog]
|
|
119
|
+
[requestDialog, getContext]
|
|
95
120
|
```
|
|
96
121
|
|
|
97
122
|
| Return Value | Type | Description |
|
|
98
123
|
|---|---|---|
|
|
99
|
-
| `requestDialog` | `(config: ConfirmConfig) => RequestDialogReturnType<ValidValue>` |
|
|
124
|
+
| `requestDialog` | `(config: ConfirmConfig) => RequestDialogReturnType<ValidValue>` | Open a dialog and receive a result. The return value is an **augmented Promise** (see `RequestDialogReturnType<T>`). |
|
|
125
|
+
| `getContext` | `(id: string) => DialogInstanceContext` | Retrieve the runtime context for an open dialog by its `id` (useful if you only have the `id`). |
|
|
100
126
|
|
|
101
127
|
```typescript
|
|
102
|
-
//
|
|
128
|
+
// Augmented promise returned by `requestDialog`
|
|
103
129
|
type RequestDialogReturnType<T> = Promise<T> & { id: string; context: DialogInstanceContext };
|
|
104
130
|
```
|
|
105
131
|
|
|
132
|
+
> Important: awaiting the returned Promise resolves with the dialog result (`T`). The `id` and `context` properties are available immediately after calling `requestDialog(...)`, allowing programmatic control while the dialog is open.
|
|
133
|
+
|
|
106
134
|
### Dialog Context & Force Functions ✅
|
|
107
135
|
|
|
108
|
-
The Promise
|
|
136
|
+
The augmented Promise exposes two helpers:
|
|
109
137
|
|
|
110
138
|
- `id: string` — unique identifier for the dialog instance
|
|
111
|
-
- `context: DialogInstanceContext` —
|
|
139
|
+
- `context: DialogInstanceContext` — runtime control helpers
|
|
112
140
|
|
|
113
|
-
|
|
141
|
+
`DialogInstanceContext` methods:
|
|
114
142
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
143
|
+
| Method | Signature | Description |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| `forceCancel` | `forceCancel(forceReject?: boolean = true): void` | Close the dialog as a cancellation. **Default:** `forceReject = true` (the promise will be rejected by default). If set to `false`, the dialog follows the dialog's `rejectOnCancel` setting. |
|
|
146
|
+
| `forceAction` | `forceAction(action: ModalAction): void` | Programmatically trigger the specified action (resolves/rejects according to the action and dialog config). |
|
|
147
|
+
| `forceDefault` | `forceDefault(): void` | Trigger the dialog's default action (first action marked with `isFocused`). Throws if no default is defined. |
|
|
120
148
|
|
|
121
|
-
|
|
149
|
+
Quick example:
|
|
122
150
|
|
|
123
151
|
```tsx
|
|
124
152
|
const [requestDialog, getContext] = useHookDialog();
|
|
125
153
|
|
|
126
|
-
|
|
154
|
+
const actions: ModalAction[][] = [[ { title: 'Cancel', isCancel: true }, { title: 'OK', value: true, isFocused: true } ]];
|
|
155
|
+
|
|
127
156
|
const p = requestDialog({
|
|
128
157
|
title: 'Confirm',
|
|
129
158
|
content: 'Proceed?',
|
|
130
|
-
actions
|
|
131
|
-
{ title: 'Cancel', isCancel: true },
|
|
132
|
-
{ title: 'OK', value: true, isFocused: true }
|
|
133
|
-
]]
|
|
159
|
+
actions
|
|
134
160
|
});
|
|
135
161
|
|
|
162
|
+
// id available immediately
|
|
136
163
|
console.log('dialog id:', p.id);
|
|
137
164
|
|
|
138
|
-
//
|
|
139
|
-
p.context.forceDefault();
|
|
140
|
-
|
|
141
|
-
// or cancel programmatically (forces reject by default)
|
|
165
|
+
// cancel programmatically (rejects by default)
|
|
142
166
|
p.context.forceCancel();
|
|
143
167
|
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
168
|
+
// trigger a specific action by referencing the action in the array
|
|
169
|
+
getContext(p.id).forceAction(actions[0][1]); // triggers `okAction`
|
|
170
|
+
// or
|
|
171
|
+
p.context.forceAction(actions[0][0]); // triggers `cancelAction`
|
|
147
172
|
```
|
|
148
173
|
|
|
149
|
-
>
|
|
150
|
-
|
|
174
|
+
> Tip: use `forceAction(...)` when you want to trigger a specific action object. Use `forceDefault()` to trigger the focused/default action (if defined). The returned Promise still resolves with the action's `value` (or rejects when cancelled).
|
|
151
175
|
#### Default Config Options
|
|
152
176
|
|
|
153
177
|
| Property | Type | Default | Description |
|
|
@@ -263,6 +287,18 @@ Customize inline styles for all elements:
|
|
|
263
287
|
|
|
264
288
|
## Components
|
|
265
289
|
|
|
290
|
+
### BaseDialogRenderer 🔧
|
|
291
|
+
|
|
292
|
+
A convenience wrapper around the upstream `BaseModalRenderer` that accepts a `defaultConfig` prop allowing you to specify default `UseHookDialogConfig` for all dialogs created by `useHookDialog()`.
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
import { BaseDialogRenderer } from '@rokku-x/react-hook-dialog';
|
|
296
|
+
|
|
297
|
+
<BaseDialogRenderer defaultConfig={{ showCloseButton: false, backdropCancel: false }} />
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
> Note: `BaseModalRenderer` from `@rokku-x/react-hook-modal` can still be used directly if you prefer — this wrapper only adds `defaultConfig` convenience.
|
|
301
|
+
|
|
266
302
|
### Backdrop
|
|
267
303
|
|
|
268
304
|
Overlay component that wraps dialog windows.
|
|
@@ -776,10 +812,10 @@ Custom styles for each variant type.
|
|
|
776
812
|
|
|
777
813
|
## Bundle Size
|
|
778
814
|
|
|
779
|
-
- ESM: ~
|
|
780
|
-
- CJS: ~
|
|
815
|
+
- ESM : ~6.69 kB gzipped (13.10 kB raw)
|
|
816
|
+
- CJS : ~7.35 kB gzipped (14.14 kB raw)
|
|
781
817
|
|
|
782
|
-
Measured with Vite build for
|
|
818
|
+
Measured with Vite build for the current branch.
|
|
783
819
|
|
|
784
820
|
## License
|
|
785
821
|
|
package/dist/README.md
CHANGED
|
@@ -1,38 +1,46 @@
|
|
|
1
1
|
# react-hook-dialog
|
|
2
2
|
|
|
3
|
-
[](https://github.com/rokku-x/react-hook-dialog/actions/workflows/ci.yml)
|
|
3
|
+
[](https://github.com/rokku-x/react-hook-dialog/actions/workflows/ci.yml) [](https://www.npmjs.com/package/@rokku-x/react-hook-dialog) [](https://www.npmjs.com/package/@rokku-x/react-hook-dialog) [](https://www.npmjs.com/package/@rokku-x/react-hook-dialog) 
|
|
4
4
|
|
|
5
|
-
A powerful and flexible React dialog hook library for confirmation dialogs, alerts, and modals. Built on top of `@rokku-x/react-hook-modal` with a focus on dialog-specific features like action buttons, variants, and customizable styling.
|
|
5
|
+
A lightweight, powerful, and flexible React dialog hook library for confirmation dialogs, alerts, and modals. Built on top of `@rokku-x/react-hook-modal` with a focus on dialog-specific features like action buttons, variants, and customizable styling.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
+
- ♿ **Accessibility Focused** - Keyboard navigation and ARIA support
|
|
10
|
+
- 🔄 **Asynchronous** - Async/await friendly dialog results
|
|
9
11
|
- 🎯 **Hook-based API** - Simple and intuitive `useHookDialog()` hook
|
|
10
12
|
- 🎨 **Rich Variants** - 7 button variants (primary, secondary, danger, success, warning, info, neutral)
|
|
11
|
-
- 🧩 **Modular Components** - Composed from reusable Backdrop and DialogWindow components
|
|
12
13
|
- 📝 **Dialog Actions** - Flexible action button system with left/right positioning
|
|
13
14
|
- 💅 **Full Customization** - Injectable className and styles at every level
|
|
14
15
|
- ⌨️ **Rich Configuration** - Default configs with per-call overrides
|
|
15
|
-
- 🎁 **Zero Dependencies** - Only requires React, Zustand, and @rokku-x/react-hook-modal
|
|
16
16
|
- 📱 **TypeScript Support** - Full type safety out of the box
|
|
17
|
-
-
|
|
17
|
+
- 🧑🤝🧑 **Multiple Dialogs** - Support for multiple simultaneous dialogs
|
|
18
|
+
- 🛠️ **Programmatic Control** - Force actions and cancellations via dialog context
|
|
19
|
+
- 🖼️ **Rich Content Support** - Accepts React nodes for titles and content
|
|
20
|
+
- 📦 **Lightweight** - Minimal bundle size for fast load times
|
|
18
21
|
|
|
19
22
|
## Installation
|
|
20
23
|
|
|
21
24
|
```bash
|
|
22
25
|
npm install @rokku-x/react-hook-dialog
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
or
|
|
26
|
-
|
|
27
|
-
```bash
|
|
26
|
+
# or
|
|
27
|
+
bun add @rokku-x/react-hook-dialog
|
|
28
|
+
# or
|
|
28
29
|
yarn add @rokku-x/react-hook-dialog
|
|
30
|
+
# or
|
|
31
|
+
pnpm add @rokku-x/react-hook-dialog
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
## Quick Start
|
|
32
35
|
|
|
33
|
-
### 1. Setup BaseModalRenderer
|
|
36
|
+
### 1. Setup BaseModalRenderer or BaseDialogRenderer
|
|
37
|
+
|
|
38
|
+
You can either use the upstream `BaseModalRenderer` directly (from `@rokku-x/react-hook-modal`) or use the convenience wrapper `BaseDialogRenderer` provided by this package.
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
- `BaseModalRenderer` (upstream): mount this at the root to render modal instances.
|
|
41
|
+
- `BaseDialogRenderer` (this package): a thin wrapper around `BaseModalRenderer` that lets you pass a `defaultConfig` prop to set default dialog options for all dialogs created by `useHookDialog()`.
|
|
42
|
+
|
|
43
|
+
Use `BaseModalRenderer` directly:
|
|
36
44
|
|
|
37
45
|
```tsx
|
|
38
46
|
import { BaseModalRenderer } from '@rokku-x/react-hook-modal';
|
|
@@ -47,6 +55,23 @@ function App() {
|
|
|
47
55
|
}
|
|
48
56
|
```
|
|
49
57
|
|
|
58
|
+
Or use the wrapper `BaseDialogRenderer` from this package to set defaults:
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { BaseDialogRenderer } from '@rokku-x/react-hook-dialog';
|
|
62
|
+
|
|
63
|
+
function App() {
|
|
64
|
+
return (
|
|
65
|
+
<>
|
|
66
|
+
<YourComponents />
|
|
67
|
+
<BaseDialogRenderer defaultConfig={{ showCloseButton: false, backdropCancel: false }} />
|
|
68
|
+
</>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Either component is fine — `BaseDialogRenderer` simply sets the dialog defaults for you so consumers of `useHookDialog()` don't have to provide them on each call.
|
|
74
|
+
|
|
50
75
|
### 2. Use useHookDialog Hook
|
|
51
76
|
|
|
52
77
|
```tsx
|
|
@@ -91,63 +116,62 @@ useHookDialog(defaultConfig?: UseHookDialogConfig)
|
|
|
91
116
|
#### Returns
|
|
92
117
|
|
|
93
118
|
```typescript
|
|
94
|
-
[requestDialog]
|
|
119
|
+
[requestDialog, getContext]
|
|
95
120
|
```
|
|
96
121
|
|
|
97
122
|
| Return Value | Type | Description |
|
|
98
123
|
|---|---|---|
|
|
99
|
-
| `requestDialog` | `(config: ConfirmConfig) => RequestDialogReturnType<ValidValue>` |
|
|
124
|
+
| `requestDialog` | `(config: ConfirmConfig) => RequestDialogReturnType<ValidValue>` | Open a dialog and receive a result. The return value is an **augmented Promise** (see `RequestDialogReturnType<T>`). |
|
|
125
|
+
| `getContext` | `(id: string) => DialogInstanceContext` | Retrieve the runtime context for an open dialog by its `id` (useful if you only have the `id`). |
|
|
100
126
|
|
|
101
127
|
```typescript
|
|
102
|
-
//
|
|
128
|
+
// Augmented promise returned by `requestDialog`
|
|
103
129
|
type RequestDialogReturnType<T> = Promise<T> & { id: string; context: DialogInstanceContext };
|
|
104
130
|
```
|
|
105
131
|
|
|
132
|
+
> Important: awaiting the returned Promise resolves with the dialog result (`T`). The `id` and `context` properties are available immediately after calling `requestDialog(...)`, allowing programmatic control while the dialog is open.
|
|
133
|
+
|
|
106
134
|
### Dialog Context & Force Functions ✅
|
|
107
135
|
|
|
108
|
-
The Promise
|
|
136
|
+
The augmented Promise exposes two helpers:
|
|
109
137
|
|
|
110
138
|
- `id: string` — unique identifier for the dialog instance
|
|
111
|
-
- `context: DialogInstanceContext` —
|
|
139
|
+
- `context: DialogInstanceContext` — runtime control helpers
|
|
112
140
|
|
|
113
|
-
|
|
141
|
+
`DialogInstanceContext` methods:
|
|
114
142
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
143
|
+
| Method | Signature | Description |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| `forceCancel` | `forceCancel(forceReject?: boolean = true): void` | Close the dialog as a cancellation. **Default:** `forceReject = true` (the promise will be rejected by default). If set to `false`, the dialog follows the dialog's `rejectOnCancel` setting. |
|
|
146
|
+
| `forceAction` | `forceAction(action: ModalAction): void` | Programmatically trigger the specified action (resolves/rejects according to the action and dialog config). |
|
|
147
|
+
| `forceDefault` | `forceDefault(): void` | Trigger the dialog's default action (first action marked with `isFocused`). Throws if no default is defined. |
|
|
120
148
|
|
|
121
|
-
|
|
149
|
+
Quick example:
|
|
122
150
|
|
|
123
151
|
```tsx
|
|
124
152
|
const [requestDialog, getContext] = useHookDialog();
|
|
125
153
|
|
|
126
|
-
|
|
154
|
+
const actions: ModalAction[][] = [[ { title: 'Cancel', isCancel: true }, { title: 'OK', value: true, isFocused: true } ]];
|
|
155
|
+
|
|
127
156
|
const p = requestDialog({
|
|
128
157
|
title: 'Confirm',
|
|
129
158
|
content: 'Proceed?',
|
|
130
|
-
actions
|
|
131
|
-
{ title: 'Cancel', isCancel: true },
|
|
132
|
-
{ title: 'OK', value: true, isFocused: true }
|
|
133
|
-
]]
|
|
159
|
+
actions
|
|
134
160
|
});
|
|
135
161
|
|
|
162
|
+
// id available immediately
|
|
136
163
|
console.log('dialog id:', p.id);
|
|
137
164
|
|
|
138
|
-
//
|
|
139
|
-
p.context.forceDefault();
|
|
140
|
-
|
|
141
|
-
// or cancel programmatically (forces reject by default)
|
|
165
|
+
// cancel programmatically (rejects by default)
|
|
142
166
|
p.context.forceCancel();
|
|
143
167
|
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
168
|
+
// trigger a specific action by referencing the action in the array
|
|
169
|
+
getContext(p.id).forceAction(actions[0][1]); // triggers `okAction`
|
|
170
|
+
// or
|
|
171
|
+
p.context.forceAction(actions[0][0]); // triggers `cancelAction`
|
|
147
172
|
```
|
|
148
173
|
|
|
149
|
-
>
|
|
150
|
-
|
|
174
|
+
> Tip: use `forceAction(...)` when you want to trigger a specific action object. Use `forceDefault()` to trigger the focused/default action (if defined). The returned Promise still resolves with the action's `value` (or rejects when cancelled).
|
|
151
175
|
#### Default Config Options
|
|
152
176
|
|
|
153
177
|
| Property | Type | Default | Description |
|
|
@@ -263,6 +287,18 @@ Customize inline styles for all elements:
|
|
|
263
287
|
|
|
264
288
|
## Components
|
|
265
289
|
|
|
290
|
+
### BaseDialogRenderer 🔧
|
|
291
|
+
|
|
292
|
+
A convenience wrapper around the upstream `BaseModalRenderer` that accepts a `defaultConfig` prop allowing you to specify default `UseHookDialogConfig` for all dialogs created by `useHookDialog()`.
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
import { BaseDialogRenderer } from '@rokku-x/react-hook-dialog';
|
|
296
|
+
|
|
297
|
+
<BaseDialogRenderer defaultConfig={{ showCloseButton: false, backdropCancel: false }} />
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
> Note: `BaseModalRenderer` from `@rokku-x/react-hook-modal` can still be used directly if you prefer — this wrapper only adds `defaultConfig` convenience.
|
|
301
|
+
|
|
266
302
|
### Backdrop
|
|
267
303
|
|
|
268
304
|
Overlay component that wraps dialog windows.
|
|
@@ -776,10 +812,10 @@ Custom styles for each variant type.
|
|
|
776
812
|
|
|
777
813
|
## Bundle Size
|
|
778
814
|
|
|
779
|
-
- ESM: ~
|
|
780
|
-
- CJS: ~
|
|
815
|
+
- ESM : ~6.69 kB gzipped (13.10 kB raw)
|
|
816
|
+
- CJS : ~7.35 kB gzipped (14.14 kB raw)
|
|
781
817
|
|
|
782
|
-
Measured with Vite build for
|
|
818
|
+
Measured with Vite build for the current branch.
|
|
783
819
|
|
|
784
820
|
## License
|
|
785
821
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),r=require("../store/dialog.cjs.js"),t=require("@rokku-x/react-hook-modal"),o=require("react");exports.default=function({defaultConfig:u,...s}){const{setDefaultConfig:a}=r.default();return o.useEffect(()=>{a(u||{})},[u]),e.jsx(t.BaseModalRenderer,{...s})};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { UseHookDialogConfig } from '../types';
|
|
2
|
+
import { ModalWindowProps } from '@rokku-x/react-hook-modal';
|
|
3
|
+
/**
|
|
4
|
+
* Wrapper component around the BaseModalRenderer to set default dialog configuration.
|
|
5
|
+
* @param props - Component props
|
|
6
|
+
* @param props.defaultConfig - Default configuration applied to all dialogs rendered by this component
|
|
7
|
+
* @param rest - Other props passed to BaseModalRenderer
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export default function BaseDialogRenderer({ defaultConfig, ...rest }: ModalWindowProps & {
|
|
12
|
+
defaultConfig?: UseHookDialogConfig;
|
|
13
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as o}from"react/jsx-runtime";import r from"../store/dialog.esm.js";import{BaseModalRenderer as t}from"@rokku-x/react-hook-modal";import{useEffect as e}from"react";function m({defaultConfig:m,...f}){const{setDefaultConfig:a}=r();return e(()=>{a(m||{})},[m]),/* @__PURE__ */o(t,{...f})}export{m as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),t=require("../constants/theme.cjs.js"),o=require("../utils/utils.cjs.js"),n=require("@rokku-x/react-hook-modal"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),t=require("../constants/theme.cjs.js"),o=require("../utils/utils.cjs.js"),n=require("@rokku-x/react-hook-modal"),s=require("react");;/* empty css */const a=n.ModalWindow;exports.default=function({modalWindowId:i,handleAction:l,handleClose:r,config:c}){const{actions:u=[],title:d,backdropCancel:f,showCloseButton:m,classNames:h={},styles:b={},variantStyles:y={}}=c;let{content:k}=c;const v=(u.length?u:[[{title:"OK",variant:"primary"}]]).filter(e=>e&&e.length),g={...t.baseVariantStyles,...y},p=s.useRef(null),x=s.useRef(null),j=s.useRef(null);return s.useEffect(()=>{const e=p.current;if(!e)return;const t=document.activeElement;if(x.current)x.current.focus();else{const t=e.querySelector("button, [href], input, select, textarea, [tabindex]:not([tabindex='-1'])");t?t.focus():(e.setAttribute("tabindex","-1"),e.focus())}const o=t=>{if("Escape"===t.key)t.stopPropagation(),r(i);else if("Tab"===t.key){const o=Array.from(e.querySelectorAll("button, [href], input, select, textarea, [tabindex]:not([tabindex='-1'])")).filter(Boolean);if(0===o.length)return void t.preventDefault();const n=o[0],s=o[o.length-1];t.shiftKey?document.activeElement===n&&(t.preventDefault(),s.focus()):document.activeElement===s&&(t.preventDefault(),n.focus())}};return e.addEventListener("keydown",o),()=>{e.removeEventListener("keydown",o),t&&t.focus&&t.focus()}},[r,i]),o.IsForm(k)&&(k=s.cloneElement(k,{ref:j})),e.jsx(n.ModalBackdrop,{onClick:()=>f&&r(i),className:h.backdrop||"",style:b.backdrop,children:e.jsxs(a,{ref:p,role:"dialog","aria-modal":"true","aria-labelledby":d?`${i}-title`:void 0,className:h.dialog||"",style:b.dialog,children:[m&&e.jsx("button",{type:"button",className:`hook-dialog-close-button ${h.closeButton||""}`,"aria-label":"Close",onClick:()=>r(i),style:b.closeButton,children:"×"}),d&&e.jsx("h3",{id:`${i}-title`,className:`hook-dialog-title ${h.title||""}`,style:b.title,children:d}),k&&e.jsx("div",{className:`hook-dialog-content ${h.content||""}`,style:b.content,children:k}),e.jsx("div",{className:`hook-dialog-actions ${h.actions||""}`,style:b.actions,children:v.map((t,n)=>{const s=t.filter(e=>e.isOnLeft),a=t.filter(e=>!e.isOnLeft),r=(t,n)=>{const s=g[t.variant||"secondary"]||g.secondary;return e.jsx("button",{ref:e=>{t.isFocused&&e&&(x.current=e)},"data-action-focused":t.isFocused?"true":void 0,className:`hook-dialog-action-button hook-dialog-action-${t.variant||"secondary"} ${h.actionButton||""} ${t.className||""}`,onClick:e=>{try{t.onClick?.(e,t)}catch{}return t.isSubmit&&c.isReturnSubmit&&j.current?l(i,t,o.FormDataToObject(new FormData(j.current))):(t.isSubmit&&j.current?.requestSubmit(),t.noActionReturn?e.stopPropagation():void l(i,t))},style:{...s,...b.actionButton,...t.style||{}},children:t.title},`${t.title}-${n}`)};return e.jsxs("div",{className:`hook-dialog-actions-row ${h.actionsRow||""}`,style:b.actionsRow,children:[e.jsx("div",{className:"hook-dialog-actions-left",children:s.map((e,t)=>r(e,t))}),e.jsx("div",{className:"hook-dialog-actions-right",children:a.map((e,t)=>r(e,t))})]},n)})})]})})};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e}from"react/jsx-runtime";import{baseVariantStyles as o}from"../constants/theme.esm.js";import{IsForm as n,FormDataToObject as
|
|
2
|
-
/* @__PURE__ */t("div",{className:`hook-dialog-actions ${
|
|
3
|
-
return t("button",{ref:t=>{e.isFocused&&t&&(
|
|
4
|
-
return e("div",{className:`hook-dialog-actions-row ${
|
|
5
|
-
/* @__PURE__ */t("div",{className:"hook-dialog-actions-left",
|
|
6
|
-
/* @__PURE__ */t("div",{className:"hook-dialog-actions-right",
|
|
1
|
+
import{jsx as t,jsxs as e}from"react/jsx-runtime";import{baseVariantStyles as o}from"../constants/theme.esm.js";import{IsForm as n,FormDataToObject as a}from"../utils/utils.esm.js";import{ModalBackdrop as i,ModalWindow as l}from"@rokku-x/react-hook-modal";import s,{useRef as r,useEffect as c}from"react";/* empty css */const d=l;function u({modalWindowId:l,handleAction:u,handleClose:m,config:f}){const{actions:h=[],title:y,backdropCancel:p,showCloseButton:b,classNames:k={},styles:v={},variantStyles:g={}}=f;let{content:N}=f;const $=(h.length?h:[[{title:"OK",variant:"primary"}]]).filter(t=>t&&t.length),w={...o,...g},x=r(null),C=r(null),E=r(null);return c(()=>{const t=x.current;if(!t)return;const e=document.activeElement;if(C.current)C.current.focus();else{const e=t.querySelector("button, [href], input, select, textarea, [tabindex]:not([tabindex='-1'])");e?e.focus():(t.setAttribute("tabindex","-1"),t.focus())}const o=e=>{if("Escape"===e.key)e.stopPropagation(),m(l);else if("Tab"===e.key){const o=Array.from(t.querySelectorAll("button, [href], input, select, textarea, [tabindex]:not([tabindex='-1'])")).filter(Boolean);if(0===o.length)return void e.preventDefault();const n=o[0],a=o[o.length-1];e.shiftKey?document.activeElement===n&&(e.preventDefault(),a.focus()):document.activeElement===a&&(e.preventDefault(),n.focus())}};return t.addEventListener("keydown",o),()=>{t.removeEventListener("keydown",o),e&&e.focus&&e.focus()}},[m,l]),n(N)&&(N=s.cloneElement(N,{ref:E})),/* @__PURE__ */t(i,{onClick:()=>p&&m(l),className:k.backdrop||"",style:v.backdrop,children:/* @__PURE__ */e(d,{ref:x,role:"dialog","aria-modal":"true","aria-labelledby":y?`${l}-title`:void 0,className:k.dialog||"",style:v.dialog,children:[b&&/* @__PURE__ */t("button",{type:"button",className:`hook-dialog-close-button ${k.closeButton||""}`,"aria-label":"Close",onClick:()=>m(l),style:v.closeButton,children:"×"}),y&&/* @__PURE__ */t("h3",{id:`${l}-title`,className:`hook-dialog-title ${k.title||""}`,style:v.title,children:y}),N&&/* @__PURE__ */t("div",{className:`hook-dialog-content ${k.content||""}`,style:v.content,children:N}),
|
|
2
|
+
/* @__PURE__ */t("div",{className:`hook-dialog-actions ${k.actions||""}`,style:v.actions,children:$.map((o,n)=>{const i=o.filter(t=>t.isOnLeft),s=o.filter(t=>!t.isOnLeft),r=(e,o)=>{const n=w[e.variant||"secondary"]||w.secondary;/* @__PURE__ */
|
|
3
|
+
return t("button",{ref:t=>{e.isFocused&&t&&(C.current=t)},"data-action-focused":e.isFocused?"true":void 0,className:`hook-dialog-action-button hook-dialog-action-${e.variant||"secondary"} ${k.actionButton||""} ${e.className||""}`,onClick:t=>{try{e.onClick?.(t,e)}catch{}return e.isSubmit&&f.isReturnSubmit&&E.current?u(l,e,a(new FormData(E.current))):(e.isSubmit&&E.current?.requestSubmit(),e.noActionReturn?t.stopPropagation():void u(l,e))},style:{...n,...v.actionButton,...e.style||{}},children:e.title},`${e.title}-${o}`)};/* @__PURE__ */
|
|
4
|
+
return e("div",{className:`hook-dialog-actions-row ${k.actionsRow||""}`,style:v.actionsRow,children:[
|
|
5
|
+
/* @__PURE__ */t("div",{className:"hook-dialog-actions-left",children:i.map((t,e)=>r(t,e))}),
|
|
6
|
+
/* @__PURE__ */t("div",{className:"hook-dialog-actions-right",children:s.map((t,e)=>r(t,e))})]},n)})})]})})}export{u as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("@rokku-x/react-hook-modal"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react"),s=require("@rokku-x/react-hook-modal"),t=require("../components/ModalWindow.cjs.js"),a=require("../store/dialog.cjs.js");exports.default=function(o){const n=s.useBaseModal(),{addInstance:r,handleAction:l,handleClose:i,rendererDefaultConfig:d}=a.default();return[function(s){return new Promise((a,c)=>{const u=Math.random().toString(36).substring(2,6),m={...d,...o,...s,classNames:{...d?.classNames,...o?.classNames,...s.classNames},styles:{...d?.styles,...o?.styles,...s.styles},variantStyles:{...d?.variantStyles,...o?.variantStyles,...s.variantStyles}},f={id:u,config:m,resolve:a,reject:c};r(f),f.id=n.pushModal(u,e.createElement(t.default,{config:m,modalWindowId:u,handleClose:i,handleAction:l}))})}]};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { UseHookDialogConfig, ValidValue
|
|
1
|
+
import { FormDataObject, ConfirmConfig, UseHookDialogConfig, ValidValue } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Hook for displaying confirmation dialogs and alerts.
|
|
4
4
|
*
|
|
@@ -34,4 +34,9 @@ import { UseHookDialogConfig, ValidValue, UseHookDialogReturnType } from '../typ
|
|
|
34
34
|
* });
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
|
-
export default function useHookDialog<T = ValidValue>(defaultConfig?: UseHookDialogConfig):
|
|
37
|
+
export default function useHookDialog<T = ValidValue>(defaultConfig?: UseHookDialogConfig): {
|
|
38
|
+
<U = FormDataObject>(config: ConfirmConfig & {
|
|
39
|
+
isReturnSubmit: true;
|
|
40
|
+
}): Promise<U>;
|
|
41
|
+
<U = T>(config: ConfirmConfig): Promise<U>;
|
|
42
|
+
}[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useBaseModal as
|
|
1
|
+
import e from"react";import{useBaseModal as s}from"@rokku-x/react-hook-modal";import t from"../components/ModalWindow.esm.js";import o from"../store/dialog.esm.js";function a(a){const n=s(),{addInstance:r,handleAction:l,handleClose:i,rendererDefaultConfig:m}=o();return[function(s){return new Promise((o,d)=>{const c=Math.random().toString(36).substring(2,6),f={...m,...a,...s,classNames:{...m?.classNames,...a?.classNames,...s.classNames},styles:{...m?.styles,...a?.styles,...s.styles},variantStyles:{...m?.variantStyles,...a?.variantStyles,...s.variantStyles}},u={id:c,config:f,resolve:o,reject:d};r(u),u.id=n.pushModal(c,e.createElement(t,{config:f,modalWindowId:c,handleClose:i,handleAction:l}))})}]}export{a as default};
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@rokku-x/react-hook-modal"),o=require("./hooks/useHookDialog.cjs.js");Object.defineProperty(exports,"BaseModalRenderer",{enumerable:!0,get:()=>e.BaseModalRenderer}),exports.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@rokku-x/react-hook-modal"),o=require("./components/BaseDialogRenderer.cjs.js"),r=require("./hooks/useHookDialog.cjs.js");Object.defineProperty(exports,"BaseModalRenderer",{enumerable:!0,get:()=>e.BaseModalRenderer}),exports.BaseDialogRenderer=o.default,exports.useHookDialog=r.default;
|
|
2
|
+
|
|
3
|
+
if (typeof document !== 'undefined') { const style = document.createElement('style'); style.textContent = ".hook-dialog-close-button{position:absolute;top:0;right:0;transform:translate(75%,-75%);width:32px;height:32px;background:none;border:none;font-size:21px;cursor:pointer;line-height:1;color:#555}.hook-dialog-title{margin:0 0 15px;font-size:20px}.hook-dialog-content{margin-bottom:15px;color:#555}.hook-dialog-actions{display:flex;flex-direction:column;gap:10px;padding-top:15px}.hook-dialog-actions-row{display:flex;gap:8px;justify-content:space-between}.hook-dialog-actions-left,.hook-dialog-actions-right{display:flex;gap:8px}.hook-dialog-action-button{border:none;border-radius:15px;padding:10px 18px;font-size:14px;font-weight:800;cursor:pointer}\n"; document.head.appendChild(style); }
|
package/dist/index.d.ts
CHANGED
|
@@ -36,12 +36,16 @@
|
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
/**
|
|
39
|
-
* Re-
|
|
40
|
-
*
|
|
39
|
+
* Re-exports of renderer components.
|
|
40
|
+
* - `BaseModalRenderer` is the upstream renderer from `@rokku-x/react-hook-modal`.
|
|
41
|
+
* - `BaseDialogRenderer` is a small wrapper provided by this package that allows setting a `defaultConfig` prop.
|
|
42
|
+
* Both should be mounted at the root of your application for dialogs to render.
|
|
41
43
|
*/
|
|
42
44
|
export { BaseModalRenderer } from '@rokku-x/react-hook-modal';
|
|
45
|
+
export { default as BaseDialogRenderer } from './components/BaseDialogRenderer';
|
|
43
46
|
/**
|
|
44
47
|
* Main hook for displaying confirmation dialogs and alerts.
|
|
45
48
|
* @see {@link useHookDialog}
|
|
46
49
|
*/
|
|
47
50
|
export { default as useHookDialog } from './hooks/useHookDialog';
|
|
51
|
+
export type { UseHookDialogConfig, ConfirmConfig, ModalAction, RequestDialogReturnType, DialogInstanceContext, RequestDialog, UseHookDialogReturnType } from './types';
|
package/dist/index.esm.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{BaseModalRenderer as o}from"@rokku-x/react-hook-modal";import{default as a}from"./hooks/useHookDialog.esm.js";export{o as BaseModalRenderer,a as useHookDialog};
|
|
1
|
+
import{BaseModalRenderer as o}from"@rokku-x/react-hook-modal";import{default as e}from"./components/BaseDialogRenderer.esm.js";import{default as a}from"./hooks/useHookDialog.esm.js";export{e as BaseDialogRenderer,o as BaseModalRenderer,a as useHookDialog};
|
|
2
|
+
|
|
3
|
+
if (typeof document !== 'undefined') { const style = document.createElement('style'); style.textContent = ".hook-dialog-close-button{position:absolute;top:0;right:0;transform:translate(75%,-75%);width:32px;height:32px;background:none;border:none;font-size:21px;cursor:pointer;line-height:1;color:#555}.hook-dialog-title{margin:0 0 15px;font-size:20px}.hook-dialog-content{margin-bottom:15px;color:#555}.hook-dialog-actions{display:flex;flex-direction:column;gap:10px;padding-top:15px}.hook-dialog-actions-row{display:flex;gap:8px;justify-content:space-between}.hook-dialog-actions-left,.hook-dialog-actions-right{display:flex;gap:8px}.hook-dialog-action-button{border:none;border-radius:15px;padding:10px 18px;font-size:14px;font-weight:800;cursor:pointer}\n"; document.head.appendChild(style); }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.hook-dialog-close-button{position:absolute;top:0;right:0;transform:translate(75%,-75%);width:32px;height:32px;background:none;border:none;font-size:21px;cursor:pointer;line-height:1;color:#555}.hook-dialog-title{margin:0 0 15px;font-size:20px}.hook-dialog-content{margin-bottom:15px;color:#555}.hook-dialog-actions{display:flex;flex-direction:column;gap:10px;padding-top:15px}.hook-dialog-actions-row{display:flex;gap:8px;justify-content:space-between}.hook-dialog-actions-left,.hook-dialog-actions-right{display:flex;gap:8px}.hook-dialog-action-button{border:none;border-radius:15px;padding:10px 18px;font-size:14px;font-weight:800;cursor:pointer}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("../components/ModalWindow.cjs.js"),n=require("@rokku-x/react-hook-modal"),t=require("react"),o=require("zustand").create((o,a)=>({instances:[],rendererDefaultConfig:{},setDefaultConfig:e=>{o(()=>({rendererDefaultConfig:e}))},addInstance:c=>{o(e=>({instances:[...e.instances,c]})),c.id=n.storeBaseModal.getState().actions.pushModal(c.id,t.createElement(e.default,{config:c.config,modalWindowId:c.id,handleClose:a().handleClose,handleAction:a().handleAction}))},removeInstance:e=>o(n=>({instances:n.instances.filter(n=>n.id!==e)})),handleClose:(e,t=!1)=>{const o=a().getInstance(e);o&&(n.storeBaseModal.getState().actions.popModal(e),!1!==o.config.rejectOnCancel||t?o.reject(o.config.defaultCancelValue):o.resolve(o.config.defaultCancelValue),a().removeInstance(e))},handleAction:(e,t)=>{const o=a().getInstance(e);o&&(n.storeBaseModal.getState().actions.popModal(e),t.isCancel&&!1!==o.config.rejectOnCancel?o.reject(t.value):o.resolve(t.value),a().removeInstance(e))},getContext:e=>{const n=a().getInstance(e);if(!n)throw new Error(`Dialog instance with id "${e}" not found.`);return{id:n.id,config:n.config,forceCancel:(n=!0)=>a().handleClose(e,n),forceAction:n=>{a().handleAction(e,n)},forceDefault:()=>{const t=n.config.actions?.flat().find(e=>e.isFocused);if(!t)throw new Error(`No default action (isFocused) defined for dialog instance with id "${e}".`);a().handleAction(e,t)}}},getInstance:e=>a().instances.find(n=>n.id===e)}));exports.default=o;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConfirmInstance, ModalAction, ValidValue } from '../types';
|
|
1
|
+
import { ConfirmInstance, ModalAction, UseHookDialogConfig, ValidValue } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Zustand store interface for managing dialog instances.
|
|
4
4
|
* Maintains a centralized list of active dialog instances.
|
|
@@ -7,6 +7,10 @@ import { ConfirmInstance, ModalAction, ValidValue } from '../types';
|
|
|
7
7
|
interface DialogStore<T = ValidValue> {
|
|
8
8
|
/** Array of currently active dialog instances */
|
|
9
9
|
instances: ConfirmInstance<T>[];
|
|
10
|
+
/** Default configuration applied to all dialogs */
|
|
11
|
+
rendererDefaultConfig: UseHookDialogConfig;
|
|
12
|
+
/** Set the default configuration for dialogs */
|
|
13
|
+
setDefaultConfig: (config: UseHookDialogConfig) => void;
|
|
10
14
|
/** Add a new dialog instance to the store */
|
|
11
15
|
addInstance: (instance: ConfirmInstance<T>) => void;
|
|
12
16
|
/** Remove a dialog instance from the store by ID */
|
|
@@ -34,5 +38,5 @@ interface DialogStore<T = ValidValue> {
|
|
|
34
38
|
* const { addInstance, removeInstance, getInstance } = useDialogStore();
|
|
35
39
|
* ```
|
|
36
40
|
*/
|
|
37
|
-
|
|
38
|
-
export
|
|
41
|
+
declare const storeDialog: import('zustand').UseBoundStore<import('zustand').StoreApi<DialogStore<any>>>;
|
|
42
|
+
export default storeDialog;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"../components/ModalWindow.esm.js";import{storeBaseModal as n}from"@rokku-x/react-hook-modal";import t from"react";import{create as o}from"zustand";const a=o((o,a)=>({instances:[],rendererDefaultConfig:{},setDefaultConfig:e=>{o(()=>({rendererDefaultConfig:e}))},addInstance:c=>{o(e=>({instances:[...e.instances,c]})),c.id=n.getState().actions.pushModal(c.id,t.createElement(e,{config:c.config,modalWindowId:c.id,handleClose:a().handleClose,handleAction:a().handleAction}))},removeInstance:e=>o(n=>({instances:n.instances.filter(n=>n.id!==e)})),handleClose:(e,t=!1)=>{const o=a().getInstance(e);o&&(n.getState().actions.popModal(e),!1!==o.config.rejectOnCancel||t?o.reject(o.config.defaultCancelValue):o.resolve(o.config.defaultCancelValue),a().removeInstance(e))},handleAction:(e,t)=>{const o=a().getInstance(e);o&&(n.getState().actions.popModal(e),t.isCancel&&!1!==o.config.rejectOnCancel?o.reject(t.value):o.resolve(t.value),a().removeInstance(e))},getContext:e=>{const n=a().getInstance(e);if(!n)throw new Error(`Dialog instance with id "${e}" not found.`);return{id:n.id,config:n.config,forceCancel:(n=!0)=>a().handleClose(e,n),forceAction:n=>{a().handleAction(e,n)},forceDefault:()=>{const t=n.config.actions?.flat().find(e=>e.isFocused);if(!t)throw new Error(`No default action (isFocused) defined for dialog instance with id "${e}".`);a().handleAction(e,t)}}},getInstance:e=>a().instances.find(n=>n.id===e)}));export{a as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rokku-x/react-hook-dialog",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"author": "rokku-x",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"main": "dist/index.cjs.js",
|
|
10
10
|
"module": "dist/index.esm.js",
|
|
11
11
|
"peerDependencies": {
|
|
12
|
-
"@rokku-x/react-hook-modal": "^0.9.0",
|
|
13
12
|
"react": "^18.0.0",
|
|
14
13
|
"react-dom": "^18.0.0",
|
|
15
|
-
"zustand": "^5.0.10"
|
|
14
|
+
"zustand": "^5.0.10",
|
|
15
|
+
"@rokku-x/react-hook-modal": "^0.9.4"
|
|
16
16
|
},
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
"import": "./dist/index.esm.js",
|
|
21
21
|
"require": "./dist/index.cjs.js"
|
|
22
22
|
},
|
|
23
|
+
"./react-hook-dialog.css": "./dist/react-hook-dialog.css",
|
|
24
|
+
"./dist/react-hook-dialog.css": "./dist/react-hook-dialog.css",
|
|
23
25
|
"./package.json": "./package.json"
|
|
24
26
|
},
|
|
25
27
|
"bugs": {
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
"confirmation",
|
|
40
42
|
"alert",
|
|
41
43
|
"prompt",
|
|
44
|
+
"confirm",
|
|
42
45
|
"hook",
|
|
43
46
|
"typescript",
|
|
44
47
|
"zustand",
|
|
@@ -50,7 +53,10 @@
|
|
|
50
53
|
"react-modal"
|
|
51
54
|
],
|
|
52
55
|
"license": "MIT",
|
|
53
|
-
"sideEffects":
|
|
56
|
+
"sideEffects": [
|
|
57
|
+
"*.css",
|
|
58
|
+
"*.scss"
|
|
59
|
+
],
|
|
54
60
|
"types": "dist/index.d.ts",
|
|
55
61
|
"typesVersions": {
|
|
56
62
|
"*": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../components/ModalWindow.cjs.js"),n=require("@rokku-x/react-hook-modal"),o=require("react"),t=require("zustand"),a=n.useBaseModal(),c=t.create((n,t)=>({instances:[],addInstance:c=>{n(e=>({instances:[...e.instances,c]})),c.id=a.pushModal(c.id,o.createElement(e.default,{config:c.config,modalWindowId:c.id,handleClose:t().handleClose,handleAction:t().handleAction}))},removeInstance:e=>n(n=>({instances:n.instances.filter(n=>n.id!==e)})),handleClose:(e,n=!1)=>{const o=t().getInstance(e);o&&(a.popModal(e),!1!==o.config.rejectOnCancel||n?o.reject(o.config.defaultCancelValue):o.resolve(o.config.defaultCancelValue),t().removeInstance(e))},handleAction:(e,n)=>{const o=t().getInstance(e);o&&(a.popModal(e),n.isCancel&&!1!==o.config.rejectOnCancel?o.reject(n.value):o.resolve(n.value),t().removeInstance(e))},getContext:e=>{const n=t().getInstance(e);if(!n)throw new Error(`Dialog instance with id "${e}" not found.`);return{id:n.id,config:n.config,forceCancel:(n=!0)=>t().handleClose(e,n),forceAction:n=>{t().handleAction(e,n)},forceDefault:()=>{const o=n.config.actions?.flat().find(e=>e.isFocused);if(!o)throw new Error(`No default action (isFocused) defined for dialog instance with id "${e}".`);t().handleAction(e,o)}}},getInstance:e=>t().instances.find(n=>n.id===e)}));exports.useDialogStore=c;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e from"../components/ModalWindow.esm.js";import{useBaseModal as n}from"@rokku-x/react-hook-modal";import o from"react";import{create as t}from"zustand";const c=n(),a=t((n,t)=>({instances:[],addInstance:a=>{n(e=>({instances:[...e.instances,a]})),a.id=c.pushModal(a.id,o.createElement(e,{config:a.config,modalWindowId:a.id,handleClose:t().handleClose,handleAction:t().handleAction}))},removeInstance:e=>n(n=>({instances:n.instances.filter(n=>n.id!==e)})),handleClose:(e,n=!1)=>{const o=t().getInstance(e);o&&(c.popModal(e),!1!==o.config.rejectOnCancel||n?o.reject(o.config.defaultCancelValue):o.resolve(o.config.defaultCancelValue),t().removeInstance(e))},handleAction:(e,n)=>{const o=t().getInstance(e);o&&(c.popModal(e),n.isCancel&&!1!==o.config.rejectOnCancel?o.reject(n.value):o.resolve(n.value),t().removeInstance(e))},getContext:e=>{const n=t().getInstance(e);if(!n)throw new Error(`Dialog instance with id "${e}" not found.`);return{id:n.id,config:n.config,forceCancel:(n=!0)=>t().handleClose(e,n),forceAction:n=>{t().handleAction(e,n)},forceDefault:()=>{const o=n.config.actions?.flat().find(e=>e.isFocused);if(!o)throw new Error(`No default action (isFocused) defined for dialog instance with id "${e}".`);t().handleAction(e,o)}}},getInstance:e=>t().instances.find(n=>n.id===e)}));export{a as useDialogStore};
|