@ablogcms/dialog 3.2.28-beta.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 +22 -0
- package/dist/acms.d.ts +6 -0
- package/dist/acms.mjs +1 -0
- package/dist/acms.mjs.map +1 -0
- package/dist/dialog-container.d.ts +2 -0
- package/dist/dialog.d.ts +24 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +238 -0
- package/dist/index.mjs.map +1 -0
- package/dist/store/hook.d.ts +8 -0
- package/dist/store/index.d.ts +2 -0
- package/dist/store/store.d.ts +14 -0
- package/dist/types/index.d.ts +27 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @ablogcms/dialog
|
|
2
|
+
|
|
3
|
+
ブラウザ標準の `confirm` / `alert` / `prompt` を置き換える、Promise ベースの非同期ダイアログを
|
|
4
|
+
提供するパッケージ。
|
|
5
|
+
|
|
6
|
+
## 使い方
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import { dialog } from '@ablogcms/dialog';
|
|
10
|
+
|
|
11
|
+
const ok = await dialog.confirm('削除してよろしいですか?');
|
|
12
|
+
if (ok) {
|
|
13
|
+
await dialog.alert('削除しました');
|
|
14
|
+
}
|
|
15
|
+
const value = await dialog.prompt('タイトルを入力してください');
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- `dialog.confirm(message, options?)`: OK/キャンセルの確認ダイアログを開き、選択結果(`boolean`)を返す。
|
|
19
|
+
- `dialog.alert(message, options?)`: OK のみの警告ダイアログを開き、閉じられたら解決する。
|
|
20
|
+
- `dialog.prompt(message, options?)`: テキスト入力ダイアログを開き、入力値(`string | null`)を返す。
|
|
21
|
+
- `DialogContainer`: 実際にダイアログを DOM へレンダリングするコンポーネント。ページに 1 度だけ
|
|
22
|
+
マウントすれば、以降の `dialog.*` 呼び出しに反応して表示される。
|
package/dist/acms.d.ts
ADDED
package/dist/acms.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=acms.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/dialog.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ButtonProps, DialogStore, DialogStoreInterface } from './types/index.js';
|
|
2
|
+
export interface DialogOptionsInterface extends Pick<DialogStoreInterface, 'title' | 'dialogProps'> {
|
|
3
|
+
}
|
|
4
|
+
export interface ConfirmDialogOptions extends DialogOptionsInterface {
|
|
5
|
+
confirmButton: Partial<ButtonProps>;
|
|
6
|
+
cancelButton: Partial<ButtonProps>;
|
|
7
|
+
}
|
|
8
|
+
export interface AlertDialogOptions extends DialogOptionsInterface {
|
|
9
|
+
confirmButton: Partial<ButtonProps>;
|
|
10
|
+
}
|
|
11
|
+
export interface PromptDialogOptions extends DialogOptionsInterface {
|
|
12
|
+
defaultValue?: string;
|
|
13
|
+
confirmButton: Partial<ButtonProps>;
|
|
14
|
+
cancelButton: Partial<ButtonProps>;
|
|
15
|
+
}
|
|
16
|
+
declare function openConfirmDialog(message: DialogStore['message'], options?: Partial<ConfirmDialogOptions>): Promise<boolean>;
|
|
17
|
+
declare function openAlertDialog(message: DialogStore['message'], options?: Partial<AlertDialogOptions>): Promise<void>;
|
|
18
|
+
declare function openPromptDialog(message: DialogStore['message'], options?: Partial<PromptDialogOptions>): Promise<string | null>;
|
|
19
|
+
declare const dialog: {
|
|
20
|
+
confirm(message: import("react").ReactNode, options?: Partial<ConfirmDialogOptions> | undefined): Promise<boolean>;
|
|
21
|
+
alert(message: import("react").ReactNode, options?: Partial<AlertDialogOptions> | undefined): Promise<void>;
|
|
22
|
+
prompt(message: import("react").ReactNode, options?: Partial<PromptDialogOptions> | undefined): Promise<string | null>;
|
|
23
|
+
};
|
|
24
|
+
export default dialog;
|
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
// src/dialog.tsx
|
|
2
|
+
import { VStack } from "@ablogcms/components/stack";
|
|
3
|
+
|
|
4
|
+
// src/store/store.ts
|
|
5
|
+
var store = { isOpen: false, onClose: () => {
|
|
6
|
+
} };
|
|
7
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
8
|
+
function emitChange() {
|
|
9
|
+
for (const listener of listeners) {
|
|
10
|
+
listener();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function openDialog(dialog2) {
|
|
14
|
+
store = dialog2;
|
|
15
|
+
emitChange();
|
|
16
|
+
}
|
|
17
|
+
function closeDialog() {
|
|
18
|
+
if (store.isOpen) {
|
|
19
|
+
store = { isOpen: false, onClose: () => {
|
|
20
|
+
} };
|
|
21
|
+
emitChange();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function createDialogStore() {
|
|
25
|
+
return {
|
|
26
|
+
openDialog,
|
|
27
|
+
closeDialog,
|
|
28
|
+
subscribe(listener) {
|
|
29
|
+
listeners.add(listener);
|
|
30
|
+
return () => {
|
|
31
|
+
listeners.delete(listener);
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
getSnapshot() {
|
|
35
|
+
return store;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/dialog.tsx
|
|
41
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
42
|
+
function openConfirmDialog(message, options = {}) {
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
const handleConfirm = () => {
|
|
45
|
+
closeDialog();
|
|
46
|
+
resolve(true);
|
|
47
|
+
};
|
|
48
|
+
const handleClose = () => {
|
|
49
|
+
closeDialog();
|
|
50
|
+
resolve(false);
|
|
51
|
+
};
|
|
52
|
+
openDialog({
|
|
53
|
+
isOpen: true,
|
|
54
|
+
onClose: handleClose,
|
|
55
|
+
type: "confirm",
|
|
56
|
+
message,
|
|
57
|
+
buttons: [
|
|
58
|
+
{
|
|
59
|
+
id: "acms-dialog-cancel-button",
|
|
60
|
+
label: ACMS.i18n("dialog.cancel"),
|
|
61
|
+
onClick: handleClose,
|
|
62
|
+
...options.cancelButton,
|
|
63
|
+
type: "button"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "acms-dialog-ok-button",
|
|
67
|
+
label: ACMS.i18n("dialog.ok"),
|
|
68
|
+
onClick: handleConfirm,
|
|
69
|
+
className: "acms-admin-btn-primary",
|
|
70
|
+
...options.confirmButton,
|
|
71
|
+
type: "button"
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
title: ACMS.i18n("dialog.confirm_title"),
|
|
75
|
+
...options,
|
|
76
|
+
dialogProps: {
|
|
77
|
+
focusTrapOptions: {
|
|
78
|
+
initialFocus: "#acms-dialog-ok-button"
|
|
79
|
+
},
|
|
80
|
+
role: "alertdialog",
|
|
81
|
+
...options.dialogProps
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function openAlertDialog(message, options = {}) {
|
|
87
|
+
return new Promise((resolve) => {
|
|
88
|
+
const handleClose = () => {
|
|
89
|
+
closeDialog();
|
|
90
|
+
resolve();
|
|
91
|
+
};
|
|
92
|
+
openDialog({
|
|
93
|
+
isOpen: true,
|
|
94
|
+
onClose: handleClose,
|
|
95
|
+
type: "alert",
|
|
96
|
+
message,
|
|
97
|
+
buttons: [
|
|
98
|
+
{
|
|
99
|
+
id: "acms-dialog-ok-button",
|
|
100
|
+
label: ACMS.i18n("dialog.ok"),
|
|
101
|
+
onClick: handleClose,
|
|
102
|
+
className: "acms-admin-btn-primary",
|
|
103
|
+
...options.confirmButton,
|
|
104
|
+
type: "button"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
title: ACMS.i18n("dialog.warning_title"),
|
|
108
|
+
...options,
|
|
109
|
+
dialogProps: {
|
|
110
|
+
focusTrapOptions: {
|
|
111
|
+
initialFocus: "#acms-dialog-ok-button"
|
|
112
|
+
},
|
|
113
|
+
role: "alertdialog",
|
|
114
|
+
...options.dialogProps
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function openPromptDialog(message, options = {}) {
|
|
120
|
+
return new Promise((resolve) => {
|
|
121
|
+
const handleSubmit = (event) => {
|
|
122
|
+
if (!(event.target instanceof HTMLFormElement)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
const formData = new FormData(event.target);
|
|
127
|
+
const value = formData.get("prompt");
|
|
128
|
+
closeDialog();
|
|
129
|
+
resolve(value);
|
|
130
|
+
};
|
|
131
|
+
const handleClose = () => {
|
|
132
|
+
closeDialog();
|
|
133
|
+
resolve(null);
|
|
134
|
+
};
|
|
135
|
+
openDialog({
|
|
136
|
+
isOpen: true,
|
|
137
|
+
onClose: handleClose,
|
|
138
|
+
body(store2) {
|
|
139
|
+
return /* @__PURE__ */ jsx("form", { id: "acms-dialog-prompt-form", onSubmit: handleSubmit, className: "acms-admin-form", children: /* @__PURE__ */ jsx(VStack, { asChild: true, align: "start", children: /* @__PURE__ */ jsxs("label", { htmlFor: "input-text-dialog-prompt", children: [
|
|
140
|
+
/* @__PURE__ */ jsx("span", { id: "acms-dialog-description", children: store2.message }),
|
|
141
|
+
/* @__PURE__ */ jsx(
|
|
142
|
+
"input",
|
|
143
|
+
{
|
|
144
|
+
id: "input-text-dialog-prompt",
|
|
145
|
+
type: "text",
|
|
146
|
+
name: "prompt",
|
|
147
|
+
className: "acms-admin-form-width-full",
|
|
148
|
+
defaultValue: options.defaultValue
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
] }) }) });
|
|
152
|
+
},
|
|
153
|
+
type: "prompt",
|
|
154
|
+
message,
|
|
155
|
+
buttons: [
|
|
156
|
+
{
|
|
157
|
+
id: "acms-dialog-cancel-button",
|
|
158
|
+
label: ACMS.i18n("dialog.cancel"),
|
|
159
|
+
onClick: handleClose,
|
|
160
|
+
...options.cancelButton,
|
|
161
|
+
type: "button"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: "acms-dialog-ok-button",
|
|
165
|
+
label: ACMS.i18n("dialog.ok"),
|
|
166
|
+
className: "acms-admin-btn-primary",
|
|
167
|
+
...options.confirmButton,
|
|
168
|
+
type: "submit",
|
|
169
|
+
form: "acms-dialog-prompt-form"
|
|
170
|
+
}
|
|
171
|
+
],
|
|
172
|
+
title: ACMS.i18n("dialog.prompt_title"),
|
|
173
|
+
...options,
|
|
174
|
+
dialogProps: {
|
|
175
|
+
focusTrapOptions: {
|
|
176
|
+
initialFocus: "#input-text-dialog-prompt"
|
|
177
|
+
},
|
|
178
|
+
...options.dialogProps
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
var dialog = {
|
|
184
|
+
confirm(...args) {
|
|
185
|
+
return openConfirmDialog(...args);
|
|
186
|
+
},
|
|
187
|
+
alert(...args) {
|
|
188
|
+
return openAlertDialog(...args);
|
|
189
|
+
},
|
|
190
|
+
prompt(...args) {
|
|
191
|
+
return openPromptDialog(...args);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
var dialog_default = dialog;
|
|
195
|
+
|
|
196
|
+
// src/dialog-container.tsx
|
|
197
|
+
import classnames from "classnames";
|
|
198
|
+
import { HStack } from "@ablogcms/components/stack";
|
|
199
|
+
import Modal, { ModalBody, ModalFooter, ModalHeader } from "@ablogcms/components/modal";
|
|
200
|
+
|
|
201
|
+
// src/store/hook.ts
|
|
202
|
+
import { useRef, useSyncExternalStore } from "react";
|
|
203
|
+
function useDialogStore() {
|
|
204
|
+
const { subscribe, getSnapshot, openDialog: openDialog2, closeDialog: closeDialog2 } = useRef(createDialogStore()).current;
|
|
205
|
+
const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
206
|
+
return { snapshot, openDialog: openDialog2, closeDialog: closeDialog2 };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/dialog-container.tsx
|
|
210
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
211
|
+
function DialogContainer() {
|
|
212
|
+
const { snapshot } = useDialogStore();
|
|
213
|
+
return /* @__PURE__ */ jsx2(
|
|
214
|
+
Modal,
|
|
215
|
+
{
|
|
216
|
+
isOpen: snapshot.isOpen,
|
|
217
|
+
onClose: snapshot.onClose,
|
|
218
|
+
size: "small",
|
|
219
|
+
"aria-labelledby": "acms-dialog-title",
|
|
220
|
+
"aria-describedby": "acms-dialog-description",
|
|
221
|
+
...snapshot.isOpen ? snapshot.dialogProps : {},
|
|
222
|
+
children: snapshot.isOpen && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
223
|
+
/* @__PURE__ */ jsx2(ModalHeader, { children: snapshot.title }),
|
|
224
|
+
/* @__PURE__ */ jsx2(ModalBody, { children: typeof snapshot.body === "function" ? snapshot.body(snapshot) : /* @__PURE__ */ jsx2("p", { id: "acms-dialog-description", children: snapshot.message }) }),
|
|
225
|
+
snapshot.buttons && snapshot.buttons.length > 0 && /* @__PURE__ */ jsx2(ModalFooter, { children: /* @__PURE__ */ jsx2(HStack, { display: "inline-flex", children: snapshot.buttons.map(({ label, className, icon, ...props }, index) => /* @__PURE__ */ jsxs2("button", { className: classnames("acms-admin-btn", className), type: "button", ...props, children: [
|
|
226
|
+
icon,
|
|
227
|
+
label
|
|
228
|
+
] }, index)) }) })
|
|
229
|
+
] })
|
|
230
|
+
}
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
var dialog_container_default = DialogContainer;
|
|
234
|
+
export {
|
|
235
|
+
dialog_container_default as DialogContainer,
|
|
236
|
+
dialog_default as dialog
|
|
237
|
+
};
|
|
238
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/dialog.tsx","../src/store/store.ts","../src/dialog-container.tsx","../src/store/hook.ts"],"sourcesContent":["import { VStack } from '@ablogcms/components/stack';\nimport { openDialog, closeDialog } from './store/store';\nimport { ButtonProps, DialogStore, DialogStoreInterface } from './types';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface DialogOptionsInterface extends Pick<DialogStoreInterface, 'title' | 'dialogProps'> {}\n\nexport interface ConfirmDialogOptions extends DialogOptionsInterface {\n confirmButton: Partial<ButtonProps>;\n cancelButton: Partial<ButtonProps>;\n}\n\nexport interface AlertDialogOptions extends DialogOptionsInterface {\n confirmButton: Partial<ButtonProps>;\n}\n\nexport interface PromptDialogOptions extends DialogOptionsInterface {\n defaultValue?: string;\n confirmButton: Partial<ButtonProps>;\n cancelButton: Partial<ButtonProps>;\n}\n\nfunction openConfirmDialog(\n message: DialogStore['message'],\n options: Partial<ConfirmDialogOptions> = {}\n): Promise<boolean> {\n return new Promise((resolve) => {\n const handleConfirm = () => {\n closeDialog();\n resolve(true);\n };\n const handleClose = () => {\n closeDialog();\n resolve(false);\n };\n openDialog({\n isOpen: true,\n onClose: handleClose,\n type: 'confirm',\n message,\n buttons: [\n {\n id: 'acms-dialog-cancel-button',\n label: ACMS.i18n('dialog.cancel'),\n onClick: handleClose,\n ...options.cancelButton,\n type: 'button',\n },\n {\n id: 'acms-dialog-ok-button',\n label: ACMS.i18n('dialog.ok'),\n onClick: handleConfirm,\n className: 'acms-admin-btn-primary',\n ...options.confirmButton,\n type: 'button',\n },\n ],\n title: ACMS.i18n('dialog.confirm_title'),\n ...options,\n dialogProps: {\n focusTrapOptions: {\n initialFocus: '#acms-dialog-ok-button',\n },\n role: 'alertdialog',\n ...options.dialogProps,\n },\n });\n });\n}\n\nfunction openAlertDialog(message: DialogStore['message'], options: Partial<AlertDialogOptions> = {}): Promise<void> {\n return new Promise((resolve) => {\n const handleClose = () => {\n closeDialog();\n resolve();\n };\n openDialog({\n isOpen: true,\n onClose: handleClose,\n type: 'alert',\n message,\n buttons: [\n {\n id: 'acms-dialog-ok-button',\n label: ACMS.i18n('dialog.ok'),\n onClick: handleClose,\n className: 'acms-admin-btn-primary',\n ...options.confirmButton,\n type: 'button',\n },\n ],\n title: ACMS.i18n('dialog.warning_title'),\n ...options,\n dialogProps: {\n focusTrapOptions: {\n initialFocus: '#acms-dialog-ok-button',\n },\n role: 'alertdialog',\n ...options.dialogProps,\n },\n });\n });\n}\n\nfunction openPromptDialog(\n message: DialogStore['message'],\n options: Partial<PromptDialogOptions> = {}\n): Promise<string | null> {\n return new Promise((resolve) => {\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n if (!(event.target instanceof HTMLFormElement)) {\n return;\n }\n event.preventDefault();\n const formData = new FormData(event.target);\n const value = formData.get('prompt') as string | null;\n closeDialog();\n resolve(value);\n };\n const handleClose = () => {\n closeDialog();\n resolve(null);\n };\n openDialog({\n isOpen: true,\n onClose: handleClose,\n body(store) {\n return (\n <form id=\"acms-dialog-prompt-form\" onSubmit={handleSubmit} className=\"acms-admin-form\">\n <VStack asChild align=\"start\">\n <label htmlFor=\"input-text-dialog-prompt\">\n <span id=\"acms-dialog-description\">{store.message}</span>\n <input\n id=\"input-text-dialog-prompt\"\n type=\"text\"\n name=\"prompt\"\n className=\"acms-admin-form-width-full\"\n defaultValue={options.defaultValue}\n />\n </label>\n </VStack>\n </form>\n );\n },\n type: 'prompt',\n message,\n buttons: [\n {\n id: 'acms-dialog-cancel-button',\n label: ACMS.i18n('dialog.cancel'),\n onClick: handleClose,\n ...options.cancelButton,\n type: 'button',\n },\n {\n id: 'acms-dialog-ok-button',\n label: ACMS.i18n('dialog.ok'),\n className: 'acms-admin-btn-primary',\n ...options.confirmButton,\n type: 'submit',\n form: 'acms-dialog-prompt-form',\n },\n ],\n title: ACMS.i18n('dialog.prompt_title'),\n ...options,\n dialogProps: {\n focusTrapOptions: {\n initialFocus: '#input-text-dialog-prompt',\n },\n ...options.dialogProps,\n },\n });\n });\n}\n\nconst dialog = {\n confirm(...args: Parameters<typeof openConfirmDialog>) {\n return openConfirmDialog(...args);\n },\n alert(...args: Parameters<typeof openAlertDialog>) {\n return openAlertDialog(...args);\n },\n prompt(...args: Parameters<typeof openPromptDialog>) {\n return openPromptDialog(...args);\n },\n};\n\nexport default dialog;\n","import { DialogStore } from '../types';\n\nlet store: DialogStore | { isOpen: false; onClose: () => void } = { isOpen: false, onClose: () => {} };\ntype DialogListener = () => void;\nconst listeners = new Set<DialogListener>();\n\nfunction emitChange() {\n for (const listener of listeners) {\n listener();\n }\n}\n\nexport function openDialog(dialog: DialogStore) {\n store = dialog;\n emitChange();\n}\n\nexport function closeDialog() {\n if (store.isOpen) {\n store = { isOpen: false, onClose: () => {} };\n emitChange();\n }\n}\n\nexport function createDialogStore() {\n return {\n openDialog,\n closeDialog,\n subscribe(listener: DialogListener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot() {\n return store;\n },\n };\n}\n","import classnames from 'classnames';\nimport { HStack } from '@ablogcms/components/stack';\nimport Modal, { ModalBody, ModalFooter, ModalHeader } from '@ablogcms/components/modal';\nimport { useDialogStore } from './store';\n\nfunction DialogContainer() {\n const { snapshot } = useDialogStore();\n\n return (\n <Modal\n isOpen={snapshot.isOpen}\n onClose={snapshot.onClose}\n size=\"small\"\n aria-labelledby=\"acms-dialog-title\"\n aria-describedby=\"acms-dialog-description\"\n {...(snapshot.isOpen ? snapshot.dialogProps : {})}\n >\n {snapshot.isOpen && (\n <>\n <ModalHeader>{snapshot.title}</ModalHeader>\n <ModalBody>\n {typeof snapshot.body === 'function' ? (\n snapshot.body(snapshot)\n ) : (\n <p id=\"acms-dialog-description\">{snapshot.message}</p>\n )}\n </ModalBody>\n {snapshot.buttons && snapshot.buttons.length > 0 && (\n <ModalFooter>\n <HStack display=\"inline-flex\">\n {snapshot.buttons.map(({ label, className, icon, ...props }, index) => (\n <button key={index} className={classnames('acms-admin-btn', className)} type=\"button\" {...props}>\n {icon}\n {label}\n </button>\n ))}\n </HStack>\n </ModalFooter>\n )}\n </>\n )}\n </Modal>\n );\n}\n\nexport default DialogContainer;\n","import { useRef, useSyncExternalStore } from 'react';\n\nimport { createDialogStore } from './store';\n\nexport default function useDialogStore() {\n // 初期化 & 永続化\n const { subscribe, getSnapshot, openDialog, closeDialog } = useRef(createDialogStore()).current;\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return { snapshot, openDialog, closeDialog };\n}\n"],"mappings":"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","names":["dialog","store","openDialog","closeDialog","jsx","jsxs"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DialogStore } from '../types/index.js';
|
|
2
|
+
type DialogListener = () => void;
|
|
3
|
+
export declare function openDialog(dialog: DialogStore): void;
|
|
4
|
+
export declare function closeDialog(): void;
|
|
5
|
+
export declare function createDialogStore(): {
|
|
6
|
+
openDialog: typeof openDialog;
|
|
7
|
+
closeDialog: typeof closeDialog;
|
|
8
|
+
subscribe(listener: DialogListener): () => void;
|
|
9
|
+
getSnapshot(): DialogStore | {
|
|
10
|
+
isOpen: false;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Modal from '@ablogcms/components/modal';
|
|
2
|
+
export type DialogType = 'confirm' | 'alert' | 'prompt';
|
|
3
|
+
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
4
|
+
label: React.ReactNode;
|
|
5
|
+
icon?: React.ReactNode;
|
|
6
|
+
};
|
|
7
|
+
export interface DialogStoreInterface {
|
|
8
|
+
type: string;
|
|
9
|
+
isOpen: true;
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
title?: string;
|
|
12
|
+
message: React.ReactNode;
|
|
13
|
+
buttons?: ButtonProps[];
|
|
14
|
+
body?: (props: DialogStoreInterface) => React.ReactNode;
|
|
15
|
+
dialogProps?: DialogProps;
|
|
16
|
+
}
|
|
17
|
+
export interface ConfirmDialogStore extends DialogStoreInterface {
|
|
18
|
+
type: 'confirm';
|
|
19
|
+
}
|
|
20
|
+
export interface AlertDialogStore extends DialogStoreInterface {
|
|
21
|
+
type: 'alert';
|
|
22
|
+
}
|
|
23
|
+
export interface PromptDialogStore extends DialogStoreInterface {
|
|
24
|
+
type: 'prompt';
|
|
25
|
+
}
|
|
26
|
+
export type DialogProps = Omit<React.ComponentPropsWithoutRef<typeof Modal>, 'children' | 'onClose' | 'isOpen'>;
|
|
27
|
+
export type DialogStore = ConfirmDialogStore | AlertDialogStore | PromptDialogStore;
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ablogcms/dialog",
|
|
3
|
+
"version": "3.2.28-beta.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Promise ベースの非同期ダイアログ(confirm/alert/prompt 代替)",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://www.a-blogcms.jp",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+ssh://git@bitbucket.org:appleple/ablogcms.git",
|
|
11
|
+
"directory": "packages/frontend/dialog"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"classnames": "^2.5.1",
|
|
16
|
+
"@ablogcms/components": "3.2.28-beta.0",
|
|
17
|
+
"@ablogcms/types": "3.2.28-beta.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@testing-library/react": "^16.3.2",
|
|
21
|
+
"vitest": "^4.1.9"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"react": "^19",
|
|
25
|
+
"@types/react": "^19.2.17"
|
|
26
|
+
},
|
|
27
|
+
"peerDependenciesMeta": {
|
|
28
|
+
"@types/react": {
|
|
29
|
+
"optional": true
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"import": "./dist/index.mjs",
|
|
36
|
+
"default": "./dist/index.mjs"
|
|
37
|
+
},
|
|
38
|
+
"./acms": {
|
|
39
|
+
"types": "./dist/acms.d.ts",
|
|
40
|
+
"import": "./dist/acms.mjs",
|
|
41
|
+
"default": "./dist/acms.mjs"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist"
|
|
49
|
+
],
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "node ../../../tools/build-package.mjs"
|
|
52
|
+
}
|
|
53
|
+
}
|