@etsoo/react 1.2.13 → 1.2.17

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.
@@ -1,4 +1,3 @@
1
- import Done from '@mui/icons-material/Done';
2
1
  import React from 'react';
3
2
  import ReactDOM from 'react-dom';
4
3
  import { act } from 'react-dom/test-utils';
@@ -102,7 +101,7 @@ test('Message tests', (done) => {
102
101
  // Callback
103
102
  const callback = jest.fn(() => done());
104
103
 
105
- let n: INotification<React.ReactNode> | undefined;
104
+ let n: INotification<React.ReactNode, any> | undefined;
106
105
  act(() => {
107
106
  // Add the notification
108
107
  n = notifier.message(
@@ -1,9 +1,9 @@
1
- /// <reference types="react" />
2
1
  import { NotificationReturn } from '@etsoo/notificationbase';
2
+ import { NotificationReactCallProps } from '../notifier/Notifier';
3
3
  /**
4
4
  * Input dialog props
5
5
  */
6
- export declare type InputDialogProps = {
6
+ export declare type InputDialogProps = NotificationReactCallProps & {
7
7
  /**
8
8
  * Title
9
9
  */
@@ -12,20 +12,8 @@ export declare type InputDialogProps = {
12
12
  * Message
13
13
  */
14
14
  message: string;
15
- /**
16
- * Inputs layout
17
- */
18
- inputs: React.ReactNode;
19
15
  /**
20
16
  * Callback
21
17
  */
22
18
  callback: NotificationReturn<HTMLFormElement>;
23
- /**
24
- * OK label
25
- */
26
- okLabel?: string;
27
- /**
28
- * Cancel label
29
- */
30
- cancelLabel?: string;
31
19
  };
@@ -1,6 +1,7 @@
1
1
  import { CoreApp, IAppSettings, ICoreApp, IUser, IUserData } from '@etsoo/appscript';
2
2
  import { DataTypes } from '@etsoo/shared';
3
3
  import React from 'react';
4
+ import { NotificationReactCallProps } from '../notifier/Notifier';
4
5
  import { CultureAction } from '../states/CultureState';
5
6
  import { IStateProps } from '../states/IState';
6
7
  import { IPageData, PageAction } from '../states/PageState';
@@ -18,16 +19,31 @@ export declare function ReactAppStateDetector(props: IStateProps): React.Functio
18
19
  /**
19
20
  * Core application interface
20
21
  */
21
- export interface IReactApp<S extends IAppSettings, D extends IUser, P extends IPageData> extends ICoreApp<S, React.ReactNode> {
22
+ export interface IReactApp<S extends IAppSettings, D extends IUser, P extends IPageData> extends ICoreApp<S, React.ReactNode, NotificationReactCallProps> {
22
23
  /**
23
24
  * User state
24
25
  */
25
26
  readonly userState: UserState<D>;
27
+ /**
28
+ * Set page data
29
+ * @param data Page data
30
+ */
31
+ setPageData(data: P): void;
32
+ /**
33
+ * Set page title and data
34
+ * @param key Page title resource key
35
+ */
36
+ setPageKey(key: string): void;
37
+ /**
38
+ * Set page title and data
39
+ * @param title Page title
40
+ */
41
+ setPageTitle(title: string): void;
26
42
  }
27
43
  /**
28
44
  * React application
29
45
  */
30
- export declare abstract class ReactApp<S extends IAppSettings, D extends IUser, P extends IPageData> extends CoreApp<S, React.ReactNode> implements IReactApp<S, D, P> {
46
+ export declare abstract class ReactApp<S extends IAppSettings, D extends IUser, P extends IPageData> extends CoreApp<S, React.ReactNode, NotificationReactCallProps> implements IReactApp<S, D, P> {
31
47
  /**
32
48
  * User state
33
49
  */
@@ -90,7 +106,7 @@ export declare abstract class ReactApp<S extends IAppSettings, D extends IUser,
90
106
  * Show input dialog
91
107
  * @param props Props
92
108
  */
93
- showInputDialog({ title, message, inputs, callback, cancelLabel, okLabel }: InputDialogProps): void;
109
+ showInputDialog({ title, message, callback, ...rest }: InputDialogProps): void;
94
110
  /**
95
111
  * User login extended
96
112
  * @param user New user
@@ -123,13 +123,8 @@ export class ReactApp extends CoreApp {
123
123
  * Show input dialog
124
124
  * @param props Props
125
125
  */
126
- showInputDialog({ title, message, inputs, callback, cancelLabel, okLabel }) {
127
- const props = {
128
- okLabel,
129
- cancelLabel,
130
- inputs
131
- };
132
- this.notifier.prompt(message, callback, title, props);
126
+ showInputDialog({ title, message, callback, ...rest }) {
127
+ this.notifier.prompt(message, callback, title, rest);
133
128
  }
134
129
  /**
135
130
  * User login extended
@@ -3,7 +3,7 @@ import { AutocompleteProps } from '@mui/material';
3
3
  /**
4
4
  * Autocomplete extended props
5
5
  */
6
- export interface AutocompleteExtendedProps<T extends Record<string, any>> extends Omit<AutocompleteProps<T, undefined, false, false>, 'renderInput'> {
6
+ export interface AutocompleteExtendedProps<T extends Record<string, any>> extends Omit<AutocompleteProps<T, undefined, false, false>, 'renderInput' | 'options'> {
7
7
  /**
8
8
  * Id field, default is id
9
9
  */
@@ -4,6 +4,14 @@ import { AutocompleteExtendedProps } from './AutocompleteExtendedProps';
4
4
  * ComboBox props
5
5
  */
6
6
  export interface ComboBoxProps<T extends Record<string, any>> extends AutocompleteExtendedProps<T> {
7
+ /**
8
+ * Load data callback
9
+ */
10
+ loadData?: () => PromiseLike<T[] | null | undefined>;
11
+ /**
12
+ * Array of options.
13
+ */
14
+ options?: ReadonlyArray<T>;
7
15
  }
8
16
  /**
9
17
  * ComboBox
@@ -10,12 +10,15 @@ import { SearchField } from './SearchField';
10
10
  */
11
11
  export function ComboBox(props) {
12
12
  // Destruct
13
- const { search = false, idField = 'id', idValue, inputMargin, inputRequired, inputVariant, defaultValue, label, name, options, readOnly = true, onChange, value, sx = { minWidth: '150px' }, ...rest } = props;
13
+ const { search = false, idField = 'id', idValue, inputMargin, inputRequired, inputVariant, defaultValue, label, loadData, name, options = [], readOnly = true, onChange, value, sx = { minWidth: '150px' }, ...rest } = props;
14
14
  // Value input ref
15
15
  const inputRef = React.createRef();
16
+ // Options state
17
+ const [localOptions, setOptions] = React.useState(options);
18
+ const isMounted = React.useRef(true);
16
19
  // Local default value
17
20
  const localValue = idValue != null
18
- ? options.find((o) => o[idField] === idValue)
21
+ ? localOptions.find((o) => o[idField] === idValue)
19
22
  : defaultValue !== null && defaultValue !== void 0 ? defaultValue : value;
20
23
  // Current id value
21
24
  const localIdValue = localValue == null ? undefined : localValue[idField];
@@ -31,6 +34,18 @@ export function ComboBox(props) {
31
34
  }
32
35
  return params;
33
36
  };
37
+ React.useEffect(() => {
38
+ if (loadData) {
39
+ loadData().then((result) => {
40
+ if (result == null || !isMounted.current)
41
+ return;
42
+ setOptions(result);
43
+ });
44
+ }
45
+ return () => {
46
+ isMounted.current = false;
47
+ };
48
+ }, []);
34
49
  // Layout
35
50
  return (React.createElement("div", null,
36
51
  React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: 'none' }, name: name, defaultValue: localIdValue }),
@@ -50,5 +65,5 @@ export function ComboBox(props) {
50
65
  // Custom
51
66
  if (onChange != null)
52
67
  onChange(event, value, reason, details);
53
- }, sx: sx, renderInput: (params) => search ? (React.createElement(SearchField, { ...addReadOnly(params), label: label, margin: inputMargin, variant: inputVariant, required: inputRequired })) : (React.createElement(InputField, { ...addReadOnly(params), label: label, margin: inputMargin, variant: inputVariant, required: inputRequired })), options: options, ...rest })));
68
+ }, sx: sx, renderInput: (params) => search ? (React.createElement(SearchField, { ...addReadOnly(params), label: label, margin: inputMargin, variant: inputVariant, required: inputRequired })) : (React.createElement(InputField, { ...addReadOnly(params), label: label, margin: inputMargin, variant: inputVariant, required: inputRequired })), options: localOptions, ...rest })));
54
69
  }
@@ -20,4 +20,4 @@ export declare type CountdownButtonProps = Omit<ButtonProps, 'endIcon' | 'disabl
20
20
  * @param props Props
21
21
  * @returns Button
22
22
  */
23
- export declare const CountdownButton: React.ForwardRefExoticComponent<Pick<CountdownButtonProps, "children" | "form" | "slot" | "title" | "value" | "name" | "type" | "onScroll" | "id" | "hidden" | "color" | "size" | keyof import("@mui/material/OverridableComponent").CommonProps | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "sx" | "TouchRippleProps" | "key" | "href" | "disableFocusRipple" | "variant" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "disableElevation" | "fullWidth" | "startIcon" | "onAction"> & React.RefAttributes<HTMLButtonElement>>;
23
+ export declare const CountdownButton: React.ForwardRefExoticComponent<Pick<CountdownButtonProps, "children" | "form" | "slot" | "title" | "value" | "name" | "type" | "fullWidth" | "onScroll" | "id" | "hidden" | "color" | "size" | keyof import("@mui/material/OverridableComponent").CommonProps | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "sx" | "TouchRippleProps" | "key" | "href" | "disableFocusRipple" | "variant" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "disableElevation" | "startIcon" | "onAction"> & React.RefAttributes<HTMLButtonElement>>;
@@ -1,6 +1,10 @@
1
1
  import { Breakpoint, ButtonProps } from '@mui/material';
2
2
  import React from 'react';
3
3
  export interface DialogButtonProps extends ButtonProps {
4
+ /**
5
+ * Button label
6
+ */
7
+ buttonLabel?: string;
4
8
  /**
5
9
  * Dialog content
6
10
  */
@@ -22,6 +26,17 @@ export interface DialogButtonProps extends ButtonProps {
22
26
  * Show fullscreen dialog
23
27
  */
24
28
  fullScreen?: boolean;
29
+ /**
30
+ * If `true`, the dialog stretches to `maxWidth`.
31
+ *
32
+ * Notice that the dialog width grow is limited by the default margin.
33
+ * @default false
34
+ */
35
+ fullWidth?: boolean;
36
+ /**
37
+ * Other layouts
38
+ */
39
+ inputs?: React.ReactNode;
25
40
  /**
26
41
  * Max width of the dialog
27
42
  */
@@ -1,21 +1,21 @@
1
- import { Button, Dialog, DialogContent, DialogContentText, DialogTitle, IconButton } from '@mui/material';
1
+ import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton } from '@mui/material';
2
2
  import React from 'react';
3
+ import { Labels } from '../app/Labels';
3
4
  /**
4
5
  * Dialog button
5
6
  * @param props Props
6
7
  * @returns Component
7
8
  */
8
9
  export function DialogButton(props) {
10
+ // Labels shared with NotificationMU
11
+ const labels = Labels.NotificationMU;
9
12
  // Destruct
10
- const { children, content, contentPre, dialogTitle, disableScrollLock, fullScreen, icon, maxWidth, onClick, ...rest } = props;
13
+ const { buttonLabel = labels.alertOK, children, content, contentPre, dialogTitle, disableScrollLock, fullScreen, fullWidth, icon, inputs, maxWidth, onClick, ...rest } = props;
11
14
  // Open state
12
15
  const [open, setOpen] = React.useState(false);
13
16
  const handleClickOpen = () => {
14
17
  setOpen(true);
15
18
  };
16
- const handleClose = () => {
17
- setOpen(false);
18
- };
19
19
  // Onclick handler
20
20
  const onClickLocal = (event) => {
21
21
  // Stop propagation
@@ -30,8 +30,15 @@ export function DialogButton(props) {
30
30
  // Layout
31
31
  return (React.createElement(React.Fragment, null,
32
32
  icon == null ? (React.createElement(Button, { ...rest, onClick: onClickLocal }, children)) : (React.createElement(IconButton, { ...rest, onClick: onClickLocal, title: children === null || children === void 0 ? void 0 : children.toString() }, icon)),
33
- React.createElement(Dialog, { disableScrollLock: disableScrollLock, fullScreen: fullScreen, maxWidth: maxWidth, open: open, onClose: handleClose },
33
+ React.createElement(Dialog, { disableScrollLock: disableScrollLock, fullScreen: fullScreen, fullWidth: fullWidth, maxWidth: maxWidth, open: open, onClose: () => setOpen(false), onClick: (event) => {
34
+ // The dialog will be embeded and the click event will bubble up
35
+ // Stop propatation but will also cancel onClose and onBackdropClick event
36
+ event.stopPropagation();
37
+ } },
34
38
  React.createElement(DialogTitle, null, dialogTitle ? dialogTitle : children),
35
39
  React.createElement(DialogContent, null,
36
- React.createElement(DialogContentText, { component: contentPre ? 'pre' : 'span' }, content)))));
40
+ React.createElement(DialogContentText, { component: contentPre ? 'pre' : 'span' }, content),
41
+ inputs),
42
+ React.createElement(DialogActions, null,
43
+ React.createElement(Button, { onClick: () => setOpen(false) }, buttonLabel)))));
37
44
  }
@@ -1,7 +1,6 @@
1
1
  import { INotificaseBase, NotificationAlign, NotificationRenderProps } from '@etsoo/notificationbase';
2
- import { ClassNameMap } from '@mui/material';
3
2
  import React from 'react';
4
- import { INotificationReact, NotificationReact, NotifierReact } from '../notifier/Notifier';
3
+ import { INotificationReact, NotificationReact, NotificationReactCallProps, NotifierReact } from '../notifier/Notifier';
5
4
  /**
6
5
  * MU notification
7
6
  */
@@ -19,7 +18,7 @@ export declare class NotificationMU extends NotificationReact {
19
18
  * @param className Style class name
20
19
  * @param classes Style classes
21
20
  */
22
- render(props: NotificationRenderProps, className: string, classes: ClassNameMap<string>): JSX.Element;
21
+ render(props: NotificationRenderProps, className: string): JSX.Element;
23
22
  }
24
23
  /**
25
24
  * Antd notifier
@@ -38,11 +37,11 @@ export declare class NotifierMU extends NotifierReact {
38
37
  * @param children Children
39
38
  * @param options Other options
40
39
  */
41
- protected createContainer: (align: NotificationAlign, children: React.ReactNode[], _options: ClassNameMap<string>) => JSX.Element;
40
+ protected createContainer: (align: NotificationAlign, children: React.ReactNode[]) => JSX.Element;
42
41
  /**
43
42
  * Add raw definition
44
43
  * @param data Notification data definition
45
44
  * @param modal Show as modal
46
45
  */
47
- protected addRaw(data: INotificaseBase, modal?: boolean): INotificationReact;
46
+ protected addRaw(data: INotificaseBase<NotificationReactCallProps>, modal?: boolean): INotificationReact;
48
47
  }
@@ -33,8 +33,10 @@ export class NotificationMU extends NotificationReact {
33
33
  this.dismiss();
34
34
  }
35
35
  // Create alert
36
- createAlert(_props, className, classes) {
36
+ createAlert(_props, className) {
37
+ var _a;
37
38
  const labels = Labels.NotificationMU;
39
+ const { inputs, fullScreen, fullWidth = true, maxWidth } = (_a = this.inputProps) !== null && _a !== void 0 ? _a : {};
38
40
  let title = this.title;
39
41
  let icon;
40
42
  if (this.type === NotificationMessageType.Success) {
@@ -53,28 +55,31 @@ export class NotificationMU extends NotificationReact {
53
55
  icon = React.createElement(Error, { color: "error" });
54
56
  title !== null && title !== void 0 ? title : (title = labels.alertTitle);
55
57
  }
56
- return (React.createElement(Dialog, { key: this.id, open: this.open, PaperComponent: DraggablePaperComponent, className: className },
57
- React.createElement(IconDialogTitle, { className: classes.iconTitle, id: "draggable-dialog-title" },
58
+ return (React.createElement(Dialog, { key: this.id, open: this.open, PaperComponent: DraggablePaperComponent, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen },
59
+ React.createElement(IconDialogTitle, { id: "draggable-dialog-title" },
58
60
  icon,
59
61
  React.createElement("span", { className: "dialogTitle" }, title)),
60
62
  React.createElement(DialogContent, null,
61
- React.createElement(DialogContentText, null, this.content)),
63
+ React.createElement(DialogContentText, null, this.content),
64
+ inputs),
62
65
  React.createElement(DialogActions, null,
63
66
  React.createElement(LoadingButton, { color: "primary", onClick: async () => await this.returnValue(undefined), autoFocus: true }, labels.alertOK))));
64
67
  }
65
68
  // Create confirm
66
- createConfirm(_props, className, classes) {
67
- var _a;
69
+ createConfirm(_props, className) {
70
+ var _a, _b;
68
71
  const labels = Labels.NotificationMU;
69
72
  const title = (_a = this.title) !== null && _a !== void 0 ? _a : labels.confirmTitle;
70
- const noLabel = labels.confirmNo;
71
- const yesLabel = labels.confirmYes;
72
- return (React.createElement(Dialog, { key: this.id, open: this.open, PaperComponent: DraggablePaperComponent, className: className },
73
- React.createElement(IconDialogTitle, { className: classes.iconTitle, id: "draggable-dialog-title" },
73
+ const { okLabel, cancelLabel, inputs, fullScreen, fullWidth = true, maxWidth } = (_b = this.inputProps) !== null && _b !== void 0 ? _b : {};
74
+ const noLabel = cancelLabel !== null && cancelLabel !== void 0 ? cancelLabel : labels.confirmNo;
75
+ const yesLabel = okLabel !== null && okLabel !== void 0 ? okLabel : labels.confirmYes;
76
+ return (React.createElement(Dialog, { key: this.id, open: this.open, PaperComponent: DraggablePaperComponent, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen },
77
+ React.createElement(IconDialogTitle, { id: "draggable-dialog-title" },
74
78
  React.createElement(Help, { color: "action" }),
75
79
  React.createElement("span", { className: "dialogTitle" }, title)),
76
80
  React.createElement(DialogContent, null,
77
- React.createElement(DialogContentText, null, this.content)),
81
+ React.createElement(DialogContentText, null, this.content),
82
+ inputs),
78
83
  React.createElement(DialogActions, null,
79
84
  React.createElement(LoadingButton, { color: "secondary", onClick: async () => await this.returnValue(false) }, noLabel),
80
85
  React.createElement(LoadingButton, { color: "primary", onClick: async () => await this.returnValue(true), autoFocus: true }, yesLabel))));
@@ -89,7 +94,7 @@ export class NotificationMU extends NotificationReact {
89
94
  return 'info';
90
95
  }
91
96
  // Create message
92
- createMessage(_props, className, _classes) {
97
+ createMessage(_props, className) {
93
98
  if (!this.open)
94
99
  return React.createElement(React.Fragment, { key: this.id });
95
100
  const setupProps = {
@@ -105,11 +110,11 @@ export class NotificationMU extends NotificationReact {
105
110
  this.content)));
106
111
  }
107
112
  // Create prompt
108
- createPrompt(_props, className, classes) {
109
- var _a;
113
+ createPrompt(_props, className) {
114
+ var _a, _b;
110
115
  const labels = Labels.NotificationMU;
111
116
  const title = (_a = this.title) !== null && _a !== void 0 ? _a : labels.promptTitle;
112
- const { cancelLabel = labels.promptCancel, okLabel = labels.promptOK, inputs, type, ...rest } = this.inputProps;
117
+ const { cancelLabel = labels.promptCancel, okLabel = labels.promptOK, inputs, type, fullScreen, fullWidth = true, maxWidth, ...rest } = (_b = this.inputProps) !== null && _b !== void 0 ? _b : {};
113
118
  const handleSubmit = async (event) => {
114
119
  // Result
115
120
  let result = undefined;
@@ -163,21 +168,21 @@ export class NotificationMU extends NotificationReact {
163
168
  let value = undefined;
164
169
  if (inputs == null) {
165
170
  if (type === 'switch') {
166
- localInputs = (React.createElement(Switch, { inputRef: inputRef, ...rest, value: "true", autoFocus: true }));
171
+ localInputs = (React.createElement(Switch, { inputRef: inputRef, ...rest, value: "true", autoFocus: true, required: true }));
167
172
  }
168
173
  else if (type === 'slider') {
169
174
  localInputs = React.createElement(Slider, { onChange: (_e, v) => (value = v) });
170
175
  }
171
176
  else {
172
- localInputs = (React.createElement(TextField, { inputRef: inputRef, autoFocus: true, fullWidth: true, type: type, ...rest }));
177
+ localInputs = (React.createElement(TextField, { inputRef: inputRef, autoFocus: true, fullWidth: true, type: type, required: true, ...rest }));
173
178
  }
174
179
  }
175
180
  else {
176
181
  localInputs = inputs;
177
182
  }
178
- return (React.createElement(Dialog, { key: this.id, open: this.open, PaperComponent: DraggablePaperComponent, className: className },
183
+ return (React.createElement(Dialog, { key: this.id, open: this.open, PaperComponent: DraggablePaperComponent, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen },
179
184
  React.createElement("form", null,
180
- React.createElement(IconDialogTitle, { className: classes.iconTitle, id: "draggable-dialog-title" },
185
+ React.createElement(IconDialogTitle, { id: "draggable-dialog-title" },
181
186
  React.createElement(Info, { color: "primary" }),
182
187
  React.createElement("span", { className: "dialogTitle" }, title)),
183
188
  React.createElement(DialogContent, null,
@@ -188,10 +193,13 @@ export class NotificationMU extends NotificationReact {
188
193
  React.createElement(LoadingButton, { color: "primary", autoFocus: true, onClick: handleSubmit }, okLabel)))));
189
194
  }
190
195
  // Create loading
191
- createLoading(_props, className, _classes) {
196
+ createLoading(_props, className) {
197
+ var _a;
192
198
  // Properties
193
199
  const setupProps = { color: 'primary' };
194
200
  const labels = Labels.NotificationMU;
201
+ // Input props
202
+ const { maxWidth = 'xs' } = (_a = this.inputProps) !== null && _a !== void 0 ? _a : {};
195
203
  // Content
196
204
  let content = this.content;
197
205
  if (content === '@')
@@ -209,7 +217,7 @@ export class NotificationMU extends NotificationReact {
209
217
  }
210
218
  } },
211
219
  React.createElement(CircularProgress, { ...setupProps }),
212
- content && React.createElement(Box, { maxWidth: 640 }, content))));
220
+ content && (React.createElement(Box, { maxWidth: maxWidth === false ? undefined : maxWidth }, content)))));
213
221
  }
214
222
  /**
215
223
  * Render method
@@ -217,24 +225,24 @@ export class NotificationMU extends NotificationReact {
217
225
  * @param className Style class name
218
226
  * @param classes Style classes
219
227
  */
220
- render(props, className, classes) {
228
+ render(props, className) {
221
229
  // Loading bar
222
230
  if (this.type === NotificationType.Loading) {
223
- return this.createLoading(props, className, classes);
231
+ return this.createLoading(props, className);
224
232
  }
225
233
  else if (this.type === NotificationType.Confirm) {
226
- return this.createConfirm(props, className, classes);
234
+ return this.createConfirm(props, className);
227
235
  }
228
236
  else if (this.type === NotificationType.Prompt) {
229
- return this.createPrompt(props, className, classes);
237
+ return this.createPrompt(props, className);
230
238
  }
231
239
  else if (this.type === NotificationType.Error ||
232
240
  (this.modal && this.type in NotificationMessageType)) {
233
241
  // Alert or modal message
234
- return this.createAlert(props, className, classes);
242
+ return this.createAlert(props, className);
235
243
  }
236
244
  else {
237
- return this.createMessage(props, className, classes);
245
+ return this.createMessage(props, className);
238
246
  }
239
247
  }
240
248
  }
@@ -250,7 +258,7 @@ export class NotifierMU extends NotifierReact {
250
258
  * @param children Children
251
259
  * @param options Other options
252
260
  */
253
- this.createContainer = (align, children, _options) => {
261
+ this.createContainer = (align, children) => {
254
262
  // Each align group, class equal to something similar to 'align-topleft'
255
263
  const alignText = NotificationAlign[align].toLowerCase();
256
264
  let className = `align-${alignText}`;
@@ -12,6 +12,10 @@ export interface SelectExProps<T = any> extends Omit<SelectProps, 'labelId' | 'i
12
12
  * Label field, default is label
13
13
  */
14
14
  labelField?: ((option: T) => string) | string;
15
+ /**
16
+ * Load data callback
17
+ */
18
+ loadData?: () => PromiseLike<T[] | null | undefined>;
15
19
  /**
16
20
  * Array of options.
17
21
  */
@@ -10,7 +10,10 @@ import { MUGlobal } from './MUGlobal';
10
10
  export function SelectEx(props) {
11
11
  var _a;
12
12
  // Destruct
13
- const { defaultValue, idField = 'id', label, labelField = 'label', multiple = false, name, options = [], search = false, value, ...rest } = props;
13
+ const { defaultValue, idField = 'id', label, labelField = 'label', loadData, multiple = false, name, options = [], search = false, value, ...rest } = props;
14
+ // Options state
15
+ const [localOptions, setOptions] = React.useState(options);
16
+ const isMounted = React.useRef(true);
14
17
  // Local value
15
18
  const valueSource = (_a = defaultValue !== null && defaultValue !== void 0 ? defaultValue : value) !== null && _a !== void 0 ? _a : '';
16
19
  let localValue;
@@ -23,7 +26,7 @@ export function SelectEx(props) {
23
26
  else {
24
27
  localValue = valueSource;
25
28
  }
26
- // State
29
+ // Value state
27
30
  const [valueState, setValueState] = React.useState(localValue);
28
31
  // Label id
29
32
  const labelId = `selectex-label-${name}`;
@@ -59,12 +62,23 @@ export function SelectEx(props) {
59
62
  React.useEffect(() => {
60
63
  var _a;
61
64
  const input = (_a = divRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('input');
62
- if (input)
63
- input.addEventListener('change', (event) => {
64
- // Reset case
65
- if (event.cancelable)
66
- setValueState(multiple ? [] : '');
65
+ const inputChange = (event) => {
66
+ // Reset case
67
+ if (event.cancelable)
68
+ setValueState(multiple ? [] : '');
69
+ };
70
+ input === null || input === void 0 ? void 0 : input.addEventListener('change', inputChange);
71
+ if (loadData) {
72
+ loadData().then((result) => {
73
+ if (result == null || !isMounted.current)
74
+ return;
75
+ setOptions(result);
67
76
  });
77
+ }
78
+ return () => {
79
+ isMounted.current = false;
80
+ input === null || input === void 0 ? void 0 : input.removeEventListener('change', inputChange);
81
+ };
68
82
  }, []);
69
83
  // Layout
70
84
  return (React.createElement(FormControl, { size: search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize },
@@ -73,13 +87,13 @@ export function SelectEx(props) {
73
87
  : MUGlobal.inputFieldShrink }, label),
74
88
  React.createElement(Select, { ref: divRef, value: valueState, input: React.createElement(OutlinedInput, { notched: true, label: label }), labelId: labelId, name: name, multiple: multiple, onChange: multiple ? handleChange : undefined, renderValue: (selected) => {
75
89
  // The text shows up
76
- return options
90
+ return localOptions
77
91
  .filter((option) => Array.isArray(selected)
78
92
  ? selected.indexOf(option.id) !== -1
79
93
  : selected === option.id)
80
94
  .map((option) => option.label)
81
95
  .join(', ');
82
- }, sx: { minWidth: '150px' }, ...rest }, options.map((option) => {
96
+ }, sx: { minWidth: '150px' }, ...rest }, localOptions.map((option) => {
83
97
  // Option id
84
98
  const id = option[idField];
85
99
  // Option label