@cratis/components 2.6.2 → 2.7.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/dist/cjs/CommandDialog/CommandDialog.js +30 -4
- package/dist/cjs/CommandDialog/CommandDialog.js.map +1 -1
- package/dist/cjs/Dialogs/BusyIndicatorDialog.js +6 -2
- package/dist/cjs/Dialogs/BusyIndicatorDialog.js.map +1 -1
- package/dist/cjs/Dialogs/Dialog.js +61 -7
- package/dist/cjs/Dialogs/Dialog.js.map +1 -1
- package/dist/cjs/Dialogs/DialogInitialFocus.js +49 -0
- package/dist/cjs/Dialogs/DialogInitialFocus.js.map +1 -0
- package/dist/cjs/Dialogs/index.js +5 -0
- package/dist/cjs/Dialogs/index.js.map +1 -1
- package/dist/esm/CommandDialog/CommandDialog.d.ts.map +1 -1
- package/dist/esm/CommandDialog/CommandDialog.js +30 -4
- package/dist/esm/CommandDialog/CommandDialog.js.map +1 -1
- package/dist/esm/Dialogs/BusyIndicatorDialog.d.ts.map +1 -1
- package/dist/esm/Dialogs/BusyIndicatorDialog.js +6 -2
- package/dist/esm/Dialogs/BusyIndicatorDialog.js.map +1 -1
- package/dist/esm/Dialogs/Dialog.d.ts +3 -1
- package/dist/esm/Dialogs/Dialog.d.ts.map +1 -1
- package/dist/esm/Dialogs/Dialog.js +62 -8
- package/dist/esm/Dialogs/Dialog.js.map +1 -1
- package/dist/esm/Dialogs/DialogInitialFocus.d.ts +6 -0
- package/dist/esm/Dialogs/DialogInitialFocus.d.ts.map +1 -0
- package/dist/esm/Dialogs/DialogInitialFocus.js +49 -0
- package/dist/esm/Dialogs/DialogInitialFocus.js.map +1 -0
- package/dist/esm/Dialogs/index.d.ts +1 -0
- package/dist/esm/Dialogs/index.d.ts.map +1 -1
- package/dist/esm/Dialogs/index.js +1 -0
- package/dist/esm/Dialogs/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { Dialog as Dialog$1 } from 'primereact/dialog';
|
|
3
3
|
import { Button } from 'primereact/button';
|
|
4
|
-
import { useDialogContext,
|
|
4
|
+
import { useDialogContext, DialogButtons, DialogResult } from '@cratis/arc.react/dialogs';
|
|
5
|
+
import { useRef } from 'react';
|
|
6
|
+
import { DialogInitialFocus } from './DialogInitialFocus.js';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Cratis wrapper around PrimeReact's `Dialog` that adds the surface every Arc
|
|
@@ -23,6 +25,36 @@ import { useDialogContext, DialogResult, DialogButtons } from '@cratis/arc.react
|
|
|
23
25
|
* - **Validity gate** (`isValid`) that disables the confirm button without
|
|
24
26
|
* disabling the cancel button. Used by command-executing wrappers to
|
|
25
27
|
* block submission while form validation fails.
|
|
28
|
+
* - **Initial focus** (`initialFocus`) choosing which element inside the
|
|
29
|
+
* dialog the keyboard lands on when it opens.
|
|
30
|
+
*
|
|
31
|
+
* ## Initial focus
|
|
32
|
+
*
|
|
33
|
+
* By default the confirm button is focused when the dialog opens, so the
|
|
34
|
+
* common "read it, press Enter" flow costs one keystroke. That default also
|
|
35
|
+
* *arms* the confirm button: browsers fire `click` from the `keydown` of
|
|
36
|
+
* `Enter`, so the key still held down from opening the dialog — or the very
|
|
37
|
+
* ordinary habit of pressing `Enter` twice — confirms it immediately.
|
|
38
|
+
*
|
|
39
|
+
* A dialog whose confirm action is destructive **and** needs no input to
|
|
40
|
+
* become valid gets no protection from `isValid`, because there is nothing
|
|
41
|
+
* to fill in. Give those dialogs an explicit
|
|
42
|
+
* {@link DialogInitialFocus} instead:
|
|
43
|
+
*
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <Dialog title="Delete personal data?"
|
|
46
|
+
* buttons={DialogButtons.YesNo}
|
|
47
|
+
* initialFocus={DialogInitialFocus.Cancel}
|
|
48
|
+
* onConfirm={...} onCancel={...}>
|
|
49
|
+
* This permanently removes the person and every record about them.
|
|
50
|
+
* </Dialog>
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* `Cancel` focuses the dismissing button (`Cancel`, or `No` when the set has
|
|
54
|
+
* no `Cancel`); `Content` focuses the dialog's title so nothing at all is
|
|
55
|
+
* armed and screen readers announce the dialog from the top. Both keep the
|
|
56
|
+
* footer, the close (X), `Escape`, and every callback intact — unlike
|
|
57
|
+
* replacing `buttons` with a custom node.
|
|
26
58
|
*
|
|
27
59
|
* ## Arc dialog host integration
|
|
28
60
|
*
|
|
@@ -75,7 +107,7 @@ import { useDialogContext, DialogResult, DialogButtons } from '@cratis/arc.react
|
|
|
75
107
|
*
|
|
76
108
|
* @param props - {@link DialogProps}.
|
|
77
109
|
*/
|
|
78
|
-
const Dialog = ({ title, visible = true, onClose, onConfirm, onCancel, buttons = DialogButtons.OkCancel, children, width = '450px', style, contentStyle, resizable = false, isValid, isBusy = false, okLabel = 'Ok', cancelLabel = 'Cancel', yesLabel = 'Yes', noLabel = 'No', className, pt, ptOptions, unstyled }) => {
|
|
110
|
+
const Dialog = ({ title, visible = true, onClose, onConfirm, onCancel, buttons = DialogButtons.OkCancel, initialFocus = DialogInitialFocus.Confirm, children, width = '450px', style, contentStyle, resizable = false, isValid, isBusy = false, okLabel = 'Ok', cancelLabel = 'Cancel', yesLabel = 'Yes', noLabel = 'No', className, pt, ptOptions, unstyled }) => {
|
|
79
111
|
// useDialogContext() is called unconditionally on every render — the try/catch only suppresses
|
|
80
112
|
// the exception when Dialog is used standalone (outside a provider). React's Rules of Hooks
|
|
81
113
|
// are not violated because the hook is always called; the try/catch never skips the call.
|
|
@@ -88,7 +120,29 @@ const Dialog = ({ title, visible = true, onClose, onConfirm, onCancel, buttons =
|
|
|
88
120
|
contextCloseDialog = undefined;
|
|
89
121
|
}
|
|
90
122
|
const isDialogValid = isValid !== false;
|
|
91
|
-
|
|
123
|
+
// A dismissing button only exists for the predefined sets that have one — Cancel for
|
|
124
|
+
// OkCancel / YesNoCancel, No for YesNo. Asking for Cancel focus without one (DialogButtons.Ok,
|
|
125
|
+
// a custom footer node, or no footer) degrades to focusing the title rather than silently
|
|
126
|
+
// leaving focus on document.body outside the modal.
|
|
127
|
+
const hasDismissingButton = typeof buttons === 'number' && buttons !== DialogButtons.Ok;
|
|
128
|
+
const resolvedInitialFocus = (initialFocus === DialogInitialFocus.Cancel && !hasDismissingButton)
|
|
129
|
+
? DialogInitialFocus.Content
|
|
130
|
+
: initialFocus;
|
|
131
|
+
const focusesConfirmButton = resolvedInitialFocus === DialogInitialFocus.Confirm;
|
|
132
|
+
const focusesDismissingButton = resolvedInitialFocus === DialogInitialFocus.Cancel;
|
|
133
|
+
const focusesTitle = resolvedInitialFocus === DialogInitialFocus.Content;
|
|
134
|
+
// PrimeReact's focus trap parks focus on the first focusable element inside the dialog while
|
|
135
|
+
// it transitions in, and its own onShow focus only fires when nothing in the dialog has focus.
|
|
136
|
+
// Moving focus to the title from onShow therefore runs last and wins, without having to fight
|
|
137
|
+
// the trap or turn focusOnShow off (which would leave focus outside the modal for the duration
|
|
138
|
+
// of the transition).
|
|
139
|
+
const titleRef = useRef(null);
|
|
140
|
+
const handleShow = () => {
|
|
141
|
+
if (focusesTitle) {
|
|
142
|
+
titleRef.current?.focus({ preventScroll: true });
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
const headerElement = (jsx("div", { className: "inline-flex items-center justify-center gap-2", children: jsx("span", { ref: titleRef, tabIndex: focusesTitle ? -1 : undefined, className: "font-bold whitespace-nowrap", children: title }) }));
|
|
92
146
|
const handleClose = async (result) => {
|
|
93
147
|
let shouldCloseThroughContext = true;
|
|
94
148
|
if (result === DialogResult.Ok || result === DialogResult.Yes) {
|
|
@@ -115,10 +169,10 @@ const Dialog = ({ title, visible = true, onClose, onConfirm, onCancel, buttons =
|
|
|
115
169
|
contextCloseDialog?.(result);
|
|
116
170
|
}
|
|
117
171
|
};
|
|
118
|
-
const okFooter = (jsx(Fragment, { children: jsx(Button, { label: okLabel, icon: "pi pi-check", onClick: () => handleClose(DialogResult.Ok), disabled: !isDialogValid || isBusy, loading: isBusy, autoFocus:
|
|
119
|
-
const okCancelFooter = (jsxs(Fragment, { children: [jsx(Button, { label: okLabel, icon: "pi pi-check", onClick: () => handleClose(DialogResult.Ok), disabled: !isDialogValid || isBusy, loading: isBusy, autoFocus:
|
|
120
|
-
const yesNoFooter = (jsxs(Fragment, { children: [jsx(Button, { label: yesLabel, icon: "pi pi-check", onClick: () => handleClose(DialogResult.Yes), disabled: !isDialogValid || isBusy, loading: isBusy, autoFocus:
|
|
121
|
-
const yesNoCancelFooter = (jsxs(Fragment, { children: [jsx(Button, { label: yesLabel, icon: "pi pi-check", onClick: () => handleClose(DialogResult.Yes), disabled: !isDialogValid || isBusy, loading: isBusy, autoFocus:
|
|
172
|
+
const okFooter = (jsx(Fragment, { children: jsx(Button, { label: okLabel, icon: "pi pi-check", onClick: () => handleClose(DialogResult.Ok), disabled: !isDialogValid || isBusy, loading: isBusy, autoFocus: focusesConfirmButton }) }));
|
|
173
|
+
const okCancelFooter = (jsxs(Fragment, { children: [jsx(Button, { label: okLabel, icon: "pi pi-check", onClick: () => handleClose(DialogResult.Ok), disabled: !isDialogValid || isBusy, loading: isBusy, autoFocus: focusesConfirmButton }), jsx(Button, { label: cancelLabel, icon: "pi pi-times", outlined: true, onClick: () => handleClose(DialogResult.Cancelled), disabled: isBusy, autoFocus: focusesDismissingButton })] }));
|
|
174
|
+
const yesNoFooter = (jsxs(Fragment, { children: [jsx(Button, { label: yesLabel, icon: "pi pi-check", onClick: () => handleClose(DialogResult.Yes), disabled: !isDialogValid || isBusy, loading: isBusy, autoFocus: focusesConfirmButton }), jsx(Button, { label: noLabel, icon: "pi pi-times", outlined: true, onClick: () => handleClose(DialogResult.No), disabled: isBusy, autoFocus: focusesDismissingButton })] }));
|
|
175
|
+
const yesNoCancelFooter = (jsxs(Fragment, { children: [jsx(Button, { label: yesLabel, icon: "pi pi-check", onClick: () => handleClose(DialogResult.Yes), disabled: !isDialogValid || isBusy, loading: isBusy, autoFocus: focusesConfirmButton }), jsx(Button, { label: noLabel, icon: "pi pi-times", outlined: true, onClick: () => handleClose(DialogResult.No), disabled: isBusy }), jsx(Button, { label: cancelLabel, icon: "pi pi-times", outlined: true, onClick: () => handleClose(DialogResult.Cancelled), disabled: isBusy, autoFocus: focusesDismissingButton })] }));
|
|
122
176
|
const getFooterInterior = () => {
|
|
123
177
|
// If buttons is a ReactNode (custom buttons), use it directly
|
|
124
178
|
if (typeof buttons !== 'number') {
|
|
@@ -140,7 +194,7 @@ const Dialog = ({ title, visible = true, onClose, onConfirm, onCancel, buttons =
|
|
|
140
194
|
const footer = (jsx("div", { className: "flex flex-wrap justify-start gap-3", children: getFooterInterior() }));
|
|
141
195
|
return (jsx(Dialog$1, { header: headerElement, modal: true, footer: footer,
|
|
142
196
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
143
|
-
onHide: typeof buttons === 'number' ? () => handleClose(DialogResult.Cancelled) : () => { }, visible: visible, style: { width, ...style }, contentStyle: contentStyle, resizable: resizable, closable: typeof buttons === 'number', className: className, pt: pt, ptOptions: ptOptions, unstyled: unstyled, children: children }));
|
|
197
|
+
onHide: typeof buttons === 'number' ? () => handleClose(DialogResult.Cancelled) : () => { }, onShow: handleShow, visible: visible, style: { width, ...style }, contentStyle: contentStyle, resizable: resizable, closable: typeof buttons === 'number', className: className, pt: pt, ptOptions: ptOptions, unstyled: unstyled, children: children }));
|
|
144
198
|
};
|
|
145
199
|
|
|
146
200
|
export { Dialog };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.js","sources":["../../../Dialogs/Dialog.tsx"],"sourcesContent":[null],"names":["_jsx","
|
|
1
|
+
{"version":3,"file":"Dialog.js","sources":["../../../Dialogs/Dialog.tsx"],"sourcesContent":[null],"names":["_jsx","_Fragment","_jsxs","PrimeDialog"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogInitialFocus.d.ts","sourceRoot":"","sources":["../../../Dialogs/DialogInitialFocus.ts"],"names":[],"mappings":"AAYA,oBAAY,kBAAkB;IAY1B,OAAO,IAAI;IAYX,MAAM,IAAI;IAWV,OAAO,IAAI;CACd"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
/**
|
|
4
|
+
* Defines where keyboard focus lands when a dialog becomes visible.
|
|
5
|
+
*
|
|
6
|
+
* A modal must move focus into itself when it opens — leaving focus on
|
|
7
|
+
* `document.body` strands keyboard and screen-reader users outside the
|
|
8
|
+
* content they were just interrupted with. Every member of this enum
|
|
9
|
+
* therefore names a real element inside the dialog; there is deliberately
|
|
10
|
+
* no "focus nothing" member.
|
|
11
|
+
*/
|
|
12
|
+
var DialogInitialFocus;
|
|
13
|
+
(function (DialogInitialFocus) {
|
|
14
|
+
/**
|
|
15
|
+
* Focus the confirming button (`Ok` / `Yes`). This is the default and
|
|
16
|
+
* the fastest path for a dialog whose expected answer is "go ahead".
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ It also *arms* that button: a browser fires `click` on a native
|
|
19
|
+
* button from the `keydown` of `Enter` or `Space`, so a held key or a
|
|
20
|
+
* second press of the key that opened the dialog confirms it. For a
|
|
21
|
+
* destructive action that needs no input to become valid, prefer
|
|
22
|
+
* {@link DialogInitialFocus.Cancel} or {@link DialogInitialFocus.Content}.
|
|
23
|
+
*/
|
|
24
|
+
DialogInitialFocus[DialogInitialFocus["Confirm"] = 1] = "Confirm";
|
|
25
|
+
/**
|
|
26
|
+
* Focus the dismissing button — `Cancel` when the button set has one,
|
|
27
|
+
* otherwise `No`. This is the least destructive action, which is what
|
|
28
|
+
* the WAI-ARIA authoring practices recommend focusing for a dialog that
|
|
29
|
+
* confirms something irreversible.
|
|
30
|
+
*
|
|
31
|
+
* Falls back to {@link DialogInitialFocus.Content} when the button set
|
|
32
|
+
* has no dismissing button (`DialogButtons.Ok`), when the footer is a
|
|
33
|
+
* custom `ReactNode`, or when there is no footer at all.
|
|
34
|
+
*/
|
|
35
|
+
DialogInitialFocus[DialogInitialFocus["Cancel"] = 2] = "Cancel";
|
|
36
|
+
/**
|
|
37
|
+
* Focus the dialog's own title instead of any button, so nothing is
|
|
38
|
+
* armed. Screen readers announce the dialog and its title, and the
|
|
39
|
+
* first `Tab` walks the content from the top.
|
|
40
|
+
*
|
|
41
|
+
* This is the right choice for a dialog that should be *read* before it
|
|
42
|
+
* is answered, and the only sensible choice for a dialog with no footer
|
|
43
|
+
* buttons at all.
|
|
44
|
+
*/
|
|
45
|
+
DialogInitialFocus[DialogInitialFocus["Content"] = 3] = "Content";
|
|
46
|
+
})(DialogInitialFocus || (DialogInitialFocus = {}));
|
|
47
|
+
|
|
48
|
+
export { DialogInitialFocus };
|
|
49
|
+
//# sourceMappingURL=DialogInitialFocus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogInitialFocus.js","sources":["../../../Dialogs/DialogInitialFocus.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AAEA;;;;;;;;AAQG;IACS;AAAZ,CAAA,UAAY,kBAAkB,EAAA;AAE1B;;;;;;;;;AASG;AACH,IAAA,kBAAA,CAAA,kBAAA,CAAA,SAAA,CAAA,GAAA,CAAA,CAAA,GAAA,SAAW;AAEX;;;;;;;;;AASG;AACH,IAAA,kBAAA,CAAA,kBAAA,CAAA,QAAA,CAAA,GAAA,CAAA,CAAA,GAAA,QAAU;AAEV;;;;;;;;AAQG;AACH,IAAA,kBAAA,CAAA,kBAAA,CAAA,SAAA,CAAA,GAAA,CAAA,CAAA,GAAA,SAAW;AACf,CAAC,EApCW,kBAAkB,KAAlB,kBAAkB,GAAA,EAAA,CAAA,CAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../Dialogs/index.ts"],"names":[],"mappings":"AAGA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../Dialogs/index.ts"],"names":[],"mappings":"AAGA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,sBAAsB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { BusyIndicatorDialog } from './BusyIndicatorDialog.js';
|
|
2
2
|
export { ConfirmationDialog } from './ConfirmationDialog.js';
|
|
3
3
|
export { Dialog } from './Dialog.js';
|
|
4
|
+
export { DialogInitialFocus } from './DialogInitialFocus.js';
|
|
4
5
|
|
|
5
6
|
// Copyright (c) Cratis. All rights reserved.
|
|
6
7
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../Dialogs/index.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../Dialogs/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;AAAA;AACA"}
|