@linzjs/windows 1.5.2 → 2.0.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/index.ts +1 -1
- package/dist/panel/PanelsContextProvider.tsx +1 -1
- package/package.json +48 -47
- package/dist/modal/Modal.tsx +0 -45
- package/dist/modal/ModalContext.scss +0 -11
- package/dist/modal/ModalContext.tsx +0 -27
- package/dist/modal/ModalContextProvider.tsx +0 -137
- package/dist/modal/ModalInstanceContext.ts +0 -16
- package/dist/modal/PrefabModal.scss +0 -21
- package/dist/modal/PrefabModal.tsx +0 -106
- package/dist/modal/index.ts +0 -6
- package/dist/modal/useShowModal.ts +0 -16
- package/dist/util/useInterval.ts +0 -18
package/dist/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./LuiModalAsync";
|
|
2
2
|
export * from "./panel";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useInterval } from "../util/useInterval";
|
|
2
1
|
import { PanelInstanceContextProvider } from "./PanelInstanceContextProvider";
|
|
3
2
|
import { PanelInstance, PanelPosition, PanelsContext } from "./PanelsContext";
|
|
4
3
|
import { castArray, maxBy, sortBy } from "lodash-es";
|
|
5
4
|
import React, { Fragment, PropsWithChildren, ReactElement, useCallback, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { useInterval } from "usehooks-ts";
|
|
6
6
|
|
|
7
7
|
export interface PanelsContextProviderProps {
|
|
8
8
|
baseZIndex?: number;
|
package/package.json
CHANGED
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"popout"
|
|
14
14
|
],
|
|
15
15
|
"main": "./dist/index.ts",
|
|
16
|
-
"version": "
|
|
16
|
+
"version": "2.0.0",
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"@linzjs/lui": "^
|
|
18
|
+
"@linzjs/lui": "^18",
|
|
19
19
|
"lodash-es": ">=4",
|
|
20
20
|
"react": ">=17",
|
|
21
21
|
"react-dom": ">=17"
|
|
@@ -49,71 +49,72 @@
|
|
|
49
49
|
"@emotion/cache": "^11.11.0",
|
|
50
50
|
"@emotion/react": "^11.11.1",
|
|
51
51
|
"@emotion/styled": "^11.11.0",
|
|
52
|
-
"@linzjs/lui": "^
|
|
52
|
+
"@linzjs/lui": "^20.0.3",
|
|
53
53
|
"lodash-es": ">=4",
|
|
54
|
-
"react": ">=
|
|
55
|
-
"react-dom": ">=
|
|
54
|
+
"react": ">=18",
|
|
55
|
+
"react-dom": ">=18",
|
|
56
56
|
"react-rnd": "^10.4.1",
|
|
57
|
-
"
|
|
57
|
+
"usehooks-ts": "^2.9.1",
|
|
58
|
+
"uuid": "^9.0.1"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
61
|
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
|
|
61
62
|
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
|
|
62
|
-
"@linzjs/step-ag-grid": "^
|
|
63
|
-
"@rollup/plugin-commonjs": "^25.0.
|
|
63
|
+
"@linzjs/step-ag-grid": "^17.6.1",
|
|
64
|
+
"@rollup/plugin-commonjs": "^25.0.4",
|
|
64
65
|
"@rollup/plugin-json": "^6.0.0",
|
|
65
|
-
"@rollup/plugin-node-resolve": "^15.1
|
|
66
|
-
"@storybook/addon-docs": "^7.
|
|
67
|
-
"@storybook/addon-essentials": "^7.
|
|
68
|
-
"@storybook/addon-interactions": "^7.
|
|
69
|
-
"@storybook/addon-links": "^7.
|
|
70
|
-
"@storybook/
|
|
71
|
-
"@storybook/
|
|
72
|
-
"@storybook/jest": "^0.
|
|
73
|
-
"@storybook/preset-create-react-app": "^7.
|
|
74
|
-
"@storybook/react": "^7.
|
|
75
|
-
"@storybook/react-vite": "^7.
|
|
76
|
-
"@storybook/test-runner": "^0.
|
|
77
|
-
"@storybook/testing-library": "^0.2.
|
|
78
|
-
"@testing-library/jest-dom": "^
|
|
66
|
+
"@rollup/plugin-node-resolve": "^15.2.1",
|
|
67
|
+
"@storybook/addon-docs": "^7.4.5",
|
|
68
|
+
"@storybook/addon-essentials": "^7.4.5",
|
|
69
|
+
"@storybook/addon-interactions": "^7.4.5",
|
|
70
|
+
"@storybook/addon-links": "^7.4.5",
|
|
71
|
+
"@storybook/addon-mdx-gfm": "^7.4.5",
|
|
72
|
+
"@storybook/blocks": "^7.4.5",
|
|
73
|
+
"@storybook/jest": "^0.2.2",
|
|
74
|
+
"@storybook/preset-create-react-app": "^7.4.5",
|
|
75
|
+
"@storybook/react": "^7.4.5",
|
|
76
|
+
"@storybook/react-vite": "^7.4.5",
|
|
77
|
+
"@storybook/test-runner": "^0.13.0",
|
|
78
|
+
"@storybook/testing-library": "^0.2.1",
|
|
79
|
+
"@testing-library/jest-dom": "^6.1.3",
|
|
79
80
|
"@testing-library/react": "^14.0.0",
|
|
80
|
-
"@testing-library/user-event": "^14.
|
|
81
|
-
"@trivago/prettier-plugin-sort-imports": "^4.
|
|
82
|
-
"@types/jest": "^29.5.
|
|
83
|
-
"@types/lodash-es": "^4.17.
|
|
84
|
-
"@types/node": "^20.
|
|
85
|
-
"@types/react": "^18.2.
|
|
86
|
-
"@types/react-dom": "^18.2.
|
|
87
|
-
"@types/uuid": "^9.0.
|
|
88
|
-
"ag-grid-community": "^
|
|
89
|
-
"ag-grid-react": "^
|
|
90
|
-
"eslint": "^8.
|
|
91
|
-
"eslint-config-prettier": "^8.
|
|
81
|
+
"@testing-library/user-event": "^14.5.1",
|
|
82
|
+
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
|
|
83
|
+
"@types/jest": "^29.5.5",
|
|
84
|
+
"@types/lodash-es": "^4.17.9",
|
|
85
|
+
"@types/node": "^20.7.1",
|
|
86
|
+
"@types/react": "^18.2.23",
|
|
87
|
+
"@types/react-dom": "^18.2.8",
|
|
88
|
+
"@types/uuid": "^9.0.4",
|
|
89
|
+
"ag-grid-community": "^29.3.5",
|
|
90
|
+
"ag-grid-react": "^29.3.5",
|
|
91
|
+
"eslint": "^8.50.0",
|
|
92
|
+
"eslint-config-prettier": "^8.10.0",
|
|
92
93
|
"eslint-config-react-app": "^7.0.1",
|
|
93
|
-
"eslint-plugin-deprecation": "^1.
|
|
94
|
-
"eslint-plugin-import": "^2.
|
|
95
|
-
"eslint-plugin-jest": "^27.
|
|
94
|
+
"eslint-plugin-deprecation": "^1.6.0",
|
|
95
|
+
"eslint-plugin-import": "^2.28.1",
|
|
96
|
+
"eslint-plugin-jest": "^27.4.0",
|
|
96
97
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
|
97
98
|
"eslint-plugin-prettier": "^4.2.1",
|
|
98
|
-
"eslint-plugin-react": "^7.
|
|
99
|
+
"eslint-plugin-react": "^7.33.2",
|
|
99
100
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
100
|
-
"eslint-plugin-storybook": "^0.6.
|
|
101
|
-
"eslint-plugin-testing-library": "^5.11.
|
|
102
|
-
"jest": "^29.
|
|
101
|
+
"eslint-plugin-storybook": "^0.6.14",
|
|
102
|
+
"eslint-plugin-testing-library": "^5.11.1",
|
|
103
|
+
"jest": "^29.7.0",
|
|
103
104
|
"jest-canvas-mock": "^2.5.2",
|
|
104
|
-
"jest-environment-jsdom": "^29.
|
|
105
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
105
106
|
"jest-expect-message": "^1.1.3",
|
|
106
107
|
"mkdirp": "^3.0.1",
|
|
107
108
|
"npm-run-all": "^4.1.5",
|
|
108
109
|
"prettier": "^2.8.8",
|
|
109
110
|
"prop-types": "^15.8.1",
|
|
110
111
|
"react-scripts": "5.0.1",
|
|
111
|
-
"rollup": "^3.
|
|
112
|
-
"rollup-plugin-copy": "^3.
|
|
113
|
-
"sass": "^1.
|
|
112
|
+
"rollup": "^3.29.3",
|
|
113
|
+
"rollup-plugin-copy": "^3.5.0",
|
|
114
|
+
"sass": "^1.68.0",
|
|
114
115
|
"sass-loader": "^13.3.2",
|
|
115
116
|
"semantic-release": "^19.0.5",
|
|
116
|
-
"storybook": "^7.
|
|
117
|
+
"storybook": "^7.4.5",
|
|
117
118
|
"style-loader": "^3.3.3",
|
|
118
119
|
"stylelint": "^14.16.1",
|
|
119
120
|
"stylelint-config-prettier": "^9.0.5",
|
|
@@ -122,7 +123,7 @@
|
|
|
122
123
|
"stylelint-prettier": "3.0.0",
|
|
123
124
|
"stylelint-scss": "5.0.1",
|
|
124
125
|
"typescript": "^4.9.5",
|
|
125
|
-
"vite": "^4.4.
|
|
126
|
+
"vite": "^4.4.9"
|
|
126
127
|
},
|
|
127
128
|
"eslintConfig": {
|
|
128
129
|
"extends": [
|
package/dist/modal/Modal.tsx
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { ModalInstanceContext } from "./ModalInstanceContext";
|
|
2
|
-
import clsx from "clsx";
|
|
3
|
-
import { delay } from "lodash-es";
|
|
4
|
-
import React, { PropsWithChildren, ReactElement, useContext, useEffect, useRef } from "react";
|
|
5
|
-
|
|
6
|
-
export interface ModalProps {
|
|
7
|
-
className?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const Modal = ({ className, children }: PropsWithChildren<ModalProps>): ReactElement => {
|
|
11
|
-
const dialogRef = useRef<HTMLDialogElement>(null);
|
|
12
|
-
|
|
13
|
-
const { close } = useContext(ModalInstanceContext);
|
|
14
|
-
|
|
15
|
-
// The only way to create a modal dialog is to call showModal, open attribute will not work
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
// Check if it's open already to support .vite hot deploys
|
|
18
|
-
if (!dialogRef.current?.open) {
|
|
19
|
-
dialogRef.current?.showModal();
|
|
20
|
-
}
|
|
21
|
-
}, []);
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
// Dialogs auto select the first focusable element, this is in case you don't want that
|
|
25
|
-
delay(() => {
|
|
26
|
-
const input = dialogRef.current?.querySelectorAll("[data-autofocus]") as any;
|
|
27
|
-
input[0]?.focus?.();
|
|
28
|
-
input?.select?.();
|
|
29
|
-
}, 100);
|
|
30
|
-
}, []);
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<dialog
|
|
34
|
-
className={clsx("linzjs-windows-dialog", className)}
|
|
35
|
-
ref={dialogRef}
|
|
36
|
-
onClick={(e) => e.target === e.currentTarget && close()}
|
|
37
|
-
onCancel={(e) => {
|
|
38
|
-
e.preventDefault();
|
|
39
|
-
close();
|
|
40
|
-
}}
|
|
41
|
-
>
|
|
42
|
-
{children}
|
|
43
|
-
</dialog>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ComponentProps, MutableRefObject, ReactElement, createContext } from "react";
|
|
2
|
-
|
|
3
|
-
export type ComponentType = (props: any) => ReactElement<any, any>;
|
|
4
|
-
|
|
5
|
-
export interface ModalCallback<R> {
|
|
6
|
-
resolve: (result: R | undefined) => void;
|
|
7
|
-
close: () => void;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface ModalContextType {
|
|
11
|
-
showModal: <
|
|
12
|
-
OR extends HTMLElement | null,
|
|
13
|
-
PROPS extends ModalCallback<any>,
|
|
14
|
-
CT extends (props: PROPS) => ReactElement<any, any>,
|
|
15
|
-
RT = Parameters<Parameters<CT>[0]["resolve"]>[0],
|
|
16
|
-
>(
|
|
17
|
-
ownerRef: MutableRefObject<OR>,
|
|
18
|
-
component: CT,
|
|
19
|
-
args: Omit<ComponentProps<CT>, "resolve" | "close">,
|
|
20
|
-
) => Promise<RT>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const ModalContext = createContext<ModalContextType>({
|
|
24
|
-
showModal: (async () => {
|
|
25
|
-
console.error("Missing ModalContext Provider");
|
|
26
|
-
}) as ModalContextType["showModal"],
|
|
27
|
-
});
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import "./ModalContext.scss";
|
|
2
|
-
|
|
3
|
-
import { useInterval } from "../util/useInterval";
|
|
4
|
-
import { ComponentType, ModalContext } from "./ModalContext";
|
|
5
|
-
import { ModalInstanceContext } from "./ModalInstanceContext";
|
|
6
|
-
import React, { Fragment, ReactNode } from "react";
|
|
7
|
-
import { MutableRefObject, ReactElement, useCallback, useState } from "react";
|
|
8
|
-
import { createPortal } from "react-dom";
|
|
9
|
-
import { v4 as makeUuid } from "uuid";
|
|
10
|
-
|
|
11
|
-
export interface ModalInstance {
|
|
12
|
-
uuid: string;
|
|
13
|
-
ownerElement: Element | undefined;
|
|
14
|
-
componentInstance: ReactElement;
|
|
15
|
-
resolve: (result: any) => void;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Provides the ability to show modals using react components without needing useState boilerplate and inline dialogs.
|
|
20
|
-
*
|
|
21
|
-
* To use:
|
|
22
|
-
* <ol>
|
|
23
|
-
* <li>Add this Provider somewhere in your standard providers
|
|
24
|
-
* <pre>
|
|
25
|
-
* <ModalContextProvider>
|
|
26
|
-
* ...children
|
|
27
|
-
* </ModalContextProvider>
|
|
28
|
-
* </pre>
|
|
29
|
-
* </li>
|
|
30
|
-
* <li>Add the modal return type to the element as below, and use the props resolve/close from ModalProps for results.
|
|
31
|
-
* <pre>
|
|
32
|
-
* export interface SomeModalProps extends ModalProps<number> {
|
|
33
|
-
* someProp?: number; // user props
|
|
34
|
-
* }
|
|
35
|
-
*
|
|
36
|
-
* export const SomeModal = ({initialState, resolve, close}: SomeModalProps): ReactElement => {
|
|
37
|
-
* return Modal(
|
|
38
|
-
* <div>
|
|
39
|
-
* Itsa me, I'm modal
|
|
40
|
-
* <button onClick={close}>Cancel</button>
|
|
41
|
-
* <button onClick={()=>resolve(someProp)}>Save</button>
|
|
42
|
-
* </div>
|
|
43
|
-
* )}
|
|
44
|
-
* }
|
|
45
|
-
* </pre>
|
|
46
|
-
* </li>
|
|
47
|
-
* <li> To show the dialog and get the result...
|
|
48
|
-
* <pre>
|
|
49
|
-
* // Note: modalOwnerRef is only required if you need to support popout windows
|
|
50
|
-
* const { showModal, modalOwnerRef } = useContext(ModalContext);
|
|
51
|
-
* ...
|
|
52
|
-
* const showModal = () => {
|
|
53
|
-
* const result = await showModal(SomeModal, { someProp: 1 });
|
|
54
|
-
* if (!result) return; // modal cancelled
|
|
55
|
-
* }
|
|
56
|
-
*
|
|
57
|
-
* return <button onClick={showModal} ref={modalOwnerRef}>Show Modal!</button>
|
|
58
|
-
* </pre>
|
|
59
|
-
* </li>
|
|
60
|
-
* </ol>
|
|
61
|
-
*/
|
|
62
|
-
export const ModalContextProvider = ({ children }: { children?: ReactNode | undefined }): ReactElement => {
|
|
63
|
-
const [modals, setModals] = useState<ModalInstance[]>([]);
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Inserts the modal into the page, and removes once modal has a result.
|
|
67
|
-
* Note: full generic types are provided by the interface. Function def has been simplified here.
|
|
68
|
-
*
|
|
69
|
-
* @param ownerRef Reference to div that opened this dialog such that it works for popout windows.
|
|
70
|
-
* @param Component React component.
|
|
71
|
-
* @param args Arguments for react component.
|
|
72
|
-
*/
|
|
73
|
-
const showModal = useCallback(
|
|
74
|
-
async (ownerRef: MutableRefObject<HTMLElement | null>, Component: ComponentType, args: any): Promise<any> => {
|
|
75
|
-
const uuid = makeUuid();
|
|
76
|
-
const promise = new Promise((resolve) => {
|
|
77
|
-
try {
|
|
78
|
-
// If there are any exceptions the modal won't show
|
|
79
|
-
setModals((modals) => [
|
|
80
|
-
...modals,
|
|
81
|
-
{
|
|
82
|
-
uuid,
|
|
83
|
-
ownerElement: ownerRef.current ?? document.body,
|
|
84
|
-
componentInstance: <Component {...args} resolve={resolve} close={() => resolve(undefined)} />,
|
|
85
|
-
resolve,
|
|
86
|
-
},
|
|
87
|
-
]);
|
|
88
|
-
} catch (e) {
|
|
89
|
-
console.error(e);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Wait for modal to complete
|
|
95
|
-
const result = await promise;
|
|
96
|
-
|
|
97
|
-
// Close modal
|
|
98
|
-
setModals((modals) => modals.filter((e) => e.uuid !== uuid));
|
|
99
|
-
|
|
100
|
-
return result;
|
|
101
|
-
},
|
|
102
|
-
[],
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
const modalHasView = useCallback(
|
|
106
|
-
(modalInstance: ModalInstance): boolean => !!modalInstance.ownerElement?.ownerDocument?.defaultView,
|
|
107
|
-
[],
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
// Tidy up modals that have closed because of an external window closing
|
|
111
|
-
useInterval(() => {
|
|
112
|
-
const newModals = modals.filter(modalHasView);
|
|
113
|
-
newModals.length !== modals.length && setModals(newModals);
|
|
114
|
-
}, 500);
|
|
115
|
-
|
|
116
|
-
return (
|
|
117
|
-
<ModalContext.Provider
|
|
118
|
-
value={{
|
|
119
|
-
showModal,
|
|
120
|
-
}}
|
|
121
|
-
>
|
|
122
|
-
<Fragment key={"modals"}>
|
|
123
|
-
{modals
|
|
124
|
-
.filter(modalHasView)
|
|
125
|
-
.map((modalInstance) =>
|
|
126
|
-
createPortal(
|
|
127
|
-
<ModalInstanceContext.Provider value={{ close: () => modalInstance.resolve(undefined) }}>
|
|
128
|
-
{modalInstance.componentInstance}
|
|
129
|
-
</ModalInstanceContext.Provider>,
|
|
130
|
-
(modalInstance.ownerElement?.ownerDocument ?? document).body,
|
|
131
|
-
),
|
|
132
|
-
)}
|
|
133
|
-
</Fragment>
|
|
134
|
-
<Fragment key={"children"}>{children}</Fragment>
|
|
135
|
-
</ModalContext.Provider>
|
|
136
|
-
);
|
|
137
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { createContext } from "react";
|
|
2
|
-
|
|
3
|
-
export interface ModalInstanceContextType {
|
|
4
|
-
close: () => void;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const NoContextError = () => {
|
|
8
|
-
console.error("Missing ModalInstanceContext Provider");
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Provides access to resolving/closing to modal elements.
|
|
13
|
-
*/
|
|
14
|
-
export const ModalInstanceContext = createContext<ModalInstanceContextType>({
|
|
15
|
-
close: NoContextError,
|
|
16
|
-
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
@use "node_modules/@linzjs/lui/dist/scss/Foundation/Variables/ColorVars.scss" as colours;
|
|
2
|
-
|
|
3
|
-
dialog.linzjs-windows-dialog {
|
|
4
|
-
display: flex;
|
|
5
|
-
flex-direction: column;
|
|
6
|
-
padding: 0;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
dialog.prefab-modal {
|
|
10
|
-
border-radius: 5px;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
dialog.prefab-modal .lui-modal {
|
|
14
|
-
margin: 0 !important;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
dialog.prefab-modal .lui-button:focus {
|
|
18
|
-
outline: 2px solid colours.$brand-primary;
|
|
19
|
-
// make sure the button sits above the others so the outline is not cut off on focus
|
|
20
|
-
position: relative;
|
|
21
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import "./PrefabModal.scss";
|
|
2
|
-
|
|
3
|
-
import { Modal } from "./Modal";
|
|
4
|
-
import { ModalCallback } from "./ModalContext";
|
|
5
|
-
import { useShowModal } from "./useShowModal";
|
|
6
|
-
import { isEmpty } from "lodash-es";
|
|
7
|
-
import React, { ReactElement } from "react";
|
|
8
|
-
|
|
9
|
-
import { LuiAlertModalButtons, LuiButton, LuiIcon } from "@linzjs/lui";
|
|
10
|
-
import { LuiButtonProps } from "@linzjs/lui/dist/components/LuiButton/LuiButton";
|
|
11
|
-
import { IconName } from "@linzjs/lui/dist/components/LuiIcon/LuiIcon";
|
|
12
|
-
|
|
13
|
-
export type WarningLevel = "success" | "info" | "warning" | "error";
|
|
14
|
-
|
|
15
|
-
export interface PrefabButton<RT> {
|
|
16
|
-
default?: boolean;
|
|
17
|
-
level?: LuiButtonProps["level"];
|
|
18
|
-
title: string;
|
|
19
|
-
value: RT;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface PrefabModalProps extends ModalCallback<string | null> {
|
|
23
|
-
level?: WarningLevel;
|
|
24
|
-
children: ReactElement;
|
|
25
|
-
buttons?: PrefabButton<any>[];
|
|
26
|
-
}
|
|
27
|
-
export const getIconForLevel = (level: "success" | "info" | "warning" | "error"): IconName => {
|
|
28
|
-
switch (level) {
|
|
29
|
-
case "success":
|
|
30
|
-
return "ic_check_circle";
|
|
31
|
-
case "info":
|
|
32
|
-
return "ic_info";
|
|
33
|
-
case "warning":
|
|
34
|
-
return "ic_warning";
|
|
35
|
-
case "error":
|
|
36
|
-
return "ic_error";
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const PrefabModal = ({ level = "warning", children, resolve, ...props }: PrefabModalProps) => {
|
|
41
|
-
const icon = getIconForLevel(level);
|
|
42
|
-
const buttons: PrefabButton<any>[] = props.buttons ?? [];
|
|
43
|
-
if (isEmpty(buttons)) {
|
|
44
|
-
if (level === "warning") {
|
|
45
|
-
buttons.push({
|
|
46
|
-
title: "Cancel",
|
|
47
|
-
value: null,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
buttons.push({
|
|
51
|
-
title: "Continue",
|
|
52
|
-
value: true,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
buttons.forEach((b, i) => {
|
|
57
|
-
if (!b.level) {
|
|
58
|
-
b.level = i === buttons.length - 1 ? "primary" : "secondary";
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<Modal className={"prefab-modal"}>
|
|
64
|
-
<div className={`lui-modal lui-box-shadow lui-modal-${level}`} style={{ minWidth: 400 }}>
|
|
65
|
-
<LuiIcon name={icon} alt={"warning"} size={"lg"} className={"lui-msg-status-icon"} />
|
|
66
|
-
{children}
|
|
67
|
-
<LuiAlertModalButtons>
|
|
68
|
-
{buttons.map((pf, i) => (
|
|
69
|
-
<LuiButton
|
|
70
|
-
key={i}
|
|
71
|
-
level={pf.level}
|
|
72
|
-
onClick={() => resolve(pf.value === undefined ? pf.title : pf.value)}
|
|
73
|
-
buttonProps={pf.default ? { "data-autofocus": true } : undefined}
|
|
74
|
-
>
|
|
75
|
-
{pf.title}
|
|
76
|
-
</LuiButton>
|
|
77
|
-
))}
|
|
78
|
-
</LuiAlertModalButtons>
|
|
79
|
-
</div>
|
|
80
|
-
</Modal>
|
|
81
|
-
);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const usePrefabModal = () => {
|
|
85
|
-
const { showModal, modalOwnerRef } = useShowModal();
|
|
86
|
-
return {
|
|
87
|
-
modalOwnerRef,
|
|
88
|
-
showPrefabModal: <RT extends any = boolean>(
|
|
89
|
-
level: WarningLevel,
|
|
90
|
-
title: ReactElement | string,
|
|
91
|
-
content: ReactElement | string,
|
|
92
|
-
buttons?: PrefabButton<RT>[],
|
|
93
|
-
) =>
|
|
94
|
-
showModal(PrefabModal, {
|
|
95
|
-
level,
|
|
96
|
-
|
|
97
|
-
children: (
|
|
98
|
-
<>
|
|
99
|
-
{typeof title === "string" ? <h2>{title}</h2> : title}
|
|
100
|
-
{typeof content === "string" ? <p>{content}</p> : content}
|
|
101
|
-
</>
|
|
102
|
-
),
|
|
103
|
-
buttons,
|
|
104
|
-
}) as Promise<RT>,
|
|
105
|
-
};
|
|
106
|
-
};
|
package/dist/modal/index.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ComponentType, ModalContext } from "./ModalContext";
|
|
2
|
-
import { ComponentProps, useContext, useRef } from "react";
|
|
3
|
-
|
|
4
|
-
export const useShowModal = () => {
|
|
5
|
-
const { showModal } = useContext(ModalContext);
|
|
6
|
-
|
|
7
|
-
const modalOwnerRef = useRef<any>(null);
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
showModal: <CT extends ComponentType>(
|
|
11
|
-
component: CT,
|
|
12
|
-
args: Omit<ComponentProps<CT>, "resolve" | "close">,
|
|
13
|
-
): Promise<Parameters<Parameters<CT>[0]["resolve"]>[0]> => showModal(modalOwnerRef, component, args),
|
|
14
|
-
modalOwnerRef,
|
|
15
|
-
};
|
|
16
|
-
};
|
package/dist/util/useInterval.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef } from "react";
|
|
2
|
-
|
|
3
|
-
type Callback = () => void | Promise<void>;
|
|
4
|
-
|
|
5
|
-
export const useInterval = (callback: Callback, timeoutMs: number | null) => {
|
|
6
|
-
const callbackRef = useRef(callback);
|
|
7
|
-
callbackRef.current = callback;
|
|
8
|
-
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
if (!timeoutMs) return;
|
|
11
|
-
const interval = setInterval(() => {
|
|
12
|
-
callbackRef.current && callbackRef.current();
|
|
13
|
-
}, timeoutMs);
|
|
14
|
-
return () => {
|
|
15
|
-
clearInterval(interval);
|
|
16
|
-
};
|
|
17
|
-
}, [timeoutMs]);
|
|
18
|
-
};
|