no-frills-ui 0.0.14-alpha.8 → 0.0.14-rc.1
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 +3 -3
- package/dist/index.js +847 -718
- package/dist/index.js.map +1 -1
- package/lib-esm/components/Accordion/Accordion.d.ts +9 -13
- package/lib-esm/components/Accordion/Accordion.js +13 -11
- package/lib-esm/components/Accordion/Accordion.js.map +1 -1
- package/lib-esm/components/Accordion/AccordionStep.d.ts +22 -22
- package/lib-esm/components/Accordion/AccordionStep.js +34 -29
- package/lib-esm/components/Accordion/AccordionStep.js.map +1 -1
- package/lib-esm/components/Badge/Badge.d.ts +13 -16
- package/lib-esm/components/Badge/Badge.js +10 -20
- package/lib-esm/components/Badge/Badge.js.map +1 -1
- package/lib-esm/components/Button/ActionButton.d.ts +9 -5
- package/lib-esm/components/Button/ActionButton.js +18 -3
- package/lib-esm/components/Button/ActionButton.js.map +1 -1
- package/lib-esm/components/Button/Button.d.ts +9 -5
- package/lib-esm/components/Button/Button.js +17 -5
- package/lib-esm/components/Button/Button.js.map +1 -1
- package/lib-esm/components/Button/IconButton.d.ts +9 -5
- package/lib-esm/components/Button/IconButton.js +18 -3
- package/lib-esm/components/Button/IconButton.js.map +1 -1
- package/lib-esm/components/Button/LinkButton.d.ts +9 -5
- package/lib-esm/components/Button/LinkButton.js +18 -3
- package/lib-esm/components/Button/LinkButton.js.map +1 -1
- package/lib-esm/components/Button/RaisedButton.d.ts +9 -5
- package/lib-esm/components/Button/RaisedButton.js +18 -3
- package/lib-esm/components/Button/RaisedButton.js.map +1 -1
- package/lib-esm/components/Card/Card.d.ts +4 -6
- package/lib-esm/components/Card/Card.js +16 -3
- package/lib-esm/components/Card/Card.js.map +1 -1
- package/lib-esm/components/Chip/Chip.d.ts +2 -2
- package/lib-esm/components/Chip/Chip.js +14 -8
- package/lib-esm/components/Chip/Chip.js.map +1 -1
- package/lib-esm/components/ChipInput/ChipInput.d.ts +28 -39
- package/lib-esm/components/ChipInput/ChipInput.js +37 -37
- package/lib-esm/components/ChipInput/ChipInput.js.map +1 -1
- package/lib-esm/components/Dialog/AlertDialog.d.ts +11 -12
- package/lib-esm/components/Dialog/AlertDialog.js +4 -11
- package/lib-esm/components/Dialog/AlertDialog.js.map +1 -1
- package/lib-esm/components/Dialog/ConfirmDialog.d.ts +13 -14
- package/lib-esm/components/Dialog/ConfirmDialog.js +4 -12
- package/lib-esm/components/Dialog/ConfirmDialog.js.map +1 -1
- package/lib-esm/components/Dialog/Dialog.d.ts +8 -14
- package/lib-esm/components/Dialog/Dialog.js +11 -9
- package/lib-esm/components/Dialog/Dialog.js.map +1 -1
- package/lib-esm/components/Dialog/PromptDialog.d.ts +18 -19
- package/lib-esm/components/Dialog/PromptDialog.js +10 -18
- package/lib-esm/components/Dialog/PromptDialog.js.map +1 -1
- package/lib-esm/components/DragAndDrop/DragAndDrop.d.ts +37 -59
- package/lib-esm/components/DragAndDrop/DragAndDrop.js +23 -26
- package/lib-esm/components/DragAndDrop/DragAndDrop.js.map +1 -1
- package/lib-esm/components/DragAndDrop/DragItem.d.ts +2 -2
- package/lib-esm/components/DragAndDrop/DragItem.js +40 -38
- package/lib-esm/components/DragAndDrop/DragItem.js.map +1 -1
- package/lib-esm/components/DragAndDrop/types.d.ts +3 -3
- package/lib-esm/components/DragAndDrop/types.js.map +1 -1
- package/lib-esm/components/Drawer/Drawer.d.ts +24 -31
- package/lib-esm/components/Drawer/Drawer.js +49 -45
- package/lib-esm/components/Drawer/Drawer.js.map +1 -1
- package/lib-esm/components/Groups/Group.d.ts +6 -8
- package/lib-esm/components/Groups/Group.js +12 -10
- package/lib-esm/components/Groups/Group.js.map +1 -1
- package/lib-esm/components/Input/Checkbox.d.ts +12 -15
- package/lib-esm/components/Input/Checkbox.js +30 -26
- package/lib-esm/components/Input/Checkbox.js.map +1 -1
- package/lib-esm/components/Input/Dropdown.d.ts +8 -18
- package/lib-esm/components/Input/Dropdown.js +42 -17
- package/lib-esm/components/Input/Dropdown.js.map +1 -1
- package/lib-esm/components/Input/Input.d.ts +8 -3
- package/lib-esm/components/Input/Input.js +20 -19
- package/lib-esm/components/Input/Input.js.map +1 -1
- package/lib-esm/components/Input/Radio.d.ts +4 -8
- package/lib-esm/components/Input/Radio.js +16 -13
- package/lib-esm/components/Input/Radio.js.map +1 -1
- package/lib-esm/components/Input/RadioButton.d.ts +4 -8
- package/lib-esm/components/Input/RadioButton.js +15 -12
- package/lib-esm/components/Input/RadioButton.js.map +1 -1
- package/lib-esm/components/Input/Select.d.ts +6 -13
- package/lib-esm/components/Input/Select.js +21 -18
- package/lib-esm/components/Input/Select.js.map +1 -1
- package/lib-esm/components/Input/TextArea.d.ts +6 -13
- package/lib-esm/components/Input/TextArea.js +29 -24
- package/lib-esm/components/Input/TextArea.js.map +1 -1
- package/lib-esm/components/Input/Toggle.d.ts +4 -9
- package/lib-esm/components/Input/Toggle.js +12 -10
- package/lib-esm/components/Input/Toggle.js.map +1 -1
- package/lib-esm/components/Menu/Menu.d.ts +4 -14
- package/lib-esm/components/Menu/Menu.js +24 -16
- package/lib-esm/components/Menu/Menu.js.map +1 -1
- package/lib-esm/components/Menu/MenuContext.d.ts +4 -4
- package/lib-esm/components/Menu/MenuContext.js +1 -0
- package/lib-esm/components/Menu/MenuContext.js.map +1 -1
- package/lib-esm/components/Menu/MenuItem.d.ts +10 -4
- package/lib-esm/components/Menu/MenuItem.js +19 -5
- package/lib-esm/components/Menu/MenuItem.js.map +1 -1
- package/lib-esm/components/Modal/Modal.d.ts +17 -23
- package/lib-esm/components/Modal/Modal.js +37 -34
- package/lib-esm/components/Modal/Modal.js.map +1 -1
- package/lib-esm/components/Notification/Notification.d.ts +39 -34
- package/lib-esm/components/Notification/Notification.js +16 -39
- package/lib-esm/components/Notification/Notification.js.map +1 -1
- package/lib-esm/components/Notification/NotificationManager.d.ts +4 -4
- package/lib-esm/components/Notification/NotificationManager.js +18 -14
- package/lib-esm/components/Notification/NotificationManager.js.map +1 -1
- package/lib-esm/components/Notification/index.d.ts +1 -0
- package/lib-esm/components/Notification/style.d.ts +2 -3
- package/lib-esm/components/Notification/style.js +11 -11
- package/lib-esm/components/Notification/style.js.map +1 -1
- package/lib-esm/components/Popover/Popover.d.ts +21 -20
- package/lib-esm/components/Popover/Popover.js +42 -44
- package/lib-esm/components/Popover/Popover.js.map +1 -1
- package/lib-esm/components/Spinner/Spinner.d.ts +14 -15
- package/lib-esm/components/Spinner/Spinner.js +12 -13
- package/lib-esm/components/Spinner/Spinner.js.map +1 -1
- package/lib-esm/components/Stepper/Step.d.ts +15 -12
- package/lib-esm/components/Stepper/Step.js +10 -8
- package/lib-esm/components/Stepper/Step.js.map +1 -1
- package/lib-esm/components/Stepper/Stepper.d.ts +11 -17
- package/lib-esm/components/Stepper/Stepper.js +25 -23
- package/lib-esm/components/Stepper/Stepper.js.map +1 -1
- package/lib-esm/components/Tabs/Tab.d.ts +10 -16
- package/lib-esm/components/Tabs/Tab.js +0 -8
- package/lib-esm/components/Tabs/Tab.js.map +1 -1
- package/lib-esm/components/Tabs/Tabs.d.ts +11 -22
- package/lib-esm/components/Tabs/Tabs.js +39 -31
- package/lib-esm/components/Tabs/Tabs.js.map +1 -1
- package/lib-esm/components/Toast/Toast.d.ts +7 -7
- package/lib-esm/components/Toast/Toast.js +13 -12
- package/lib-esm/components/Toast/Toast.js.map +1 -1
- package/lib-esm/components/Toast/ToastStory.d.ts +21 -24
- package/lib-esm/components/Tooltip/Tooltip.d.ts +11 -14
- package/lib-esm/components/Tooltip/Tooltip.js +11 -21
- package/lib-esm/components/Tooltip/Tooltip.js.map +1 -1
- package/lib-esm/icons/CheckCircle.js +2 -2
- package/lib-esm/icons/CheckCircle.js.map +1 -1
- package/lib-esm/icons/ErrorOutline.js +2 -2
- package/lib-esm/icons/ErrorOutline.js.map +1 -1
- package/lib-esm/icons/Info.js +2 -2
- package/lib-esm/icons/Info.js.map +1 -1
- package/lib-esm/icons/ReportProblem.js +2 -2
- package/lib-esm/icons/ReportProblem.js.map +1 -1
- package/lib-esm/index.js +43 -0
- package/lib-esm/shared/LayerManager.d.ts +5 -4
- package/lib-esm/shared/LayerManager.js +111 -111
- package/lib-esm/shared/LayerManager.js.map +1 -1
- package/lib-esm/shared/styles.d.ts +1 -1
- package/lib-esm/shared/styles.js +9 -9
- package/lib-esm/shared/styles.js.map +1 -1
- package/package.json +66 -31
- package/lib-esm/components/index.js +0 -43
- /package/lib-esm/{components/index.js.map → index.js.map} +0 -0
|
@@ -1,39 +1,10 @@
|
|
|
1
1
|
import { jsx } from '@emotion/react/jsx-runtime';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
2
|
import { flushSync } from 'react-dom';
|
|
5
3
|
import { createRoot } from 'react-dom/client';
|
|
6
4
|
import LayerManager, { LAYER_POSITION } from '../../shared/LayerManager.js';
|
|
7
5
|
import NotificationManager from './NotificationManager.js';
|
|
8
|
-
import { NOTIFICATION_POSITION
|
|
6
|
+
import { NOTIFICATION_POSITION } from './types.js';
|
|
9
7
|
|
|
10
|
-
/** This component is only used for storybook documentation */ class StoryProps extends React.Component {
|
|
11
|
-
render() {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
StoryProps.propTypes = {
|
|
16
|
-
/** Title of the notification */ title: PropTypes.string.isRequired,
|
|
17
|
-
/** Body of the notification */ description: PropTypes.string.isRequired,
|
|
18
|
-
/** Id for the notification, helps in de-duplication. */ id: PropTypes.string,
|
|
19
|
-
/** Duration for the notification in milliseconds */ duration: PropTypes.number,
|
|
20
|
-
/** Creates sticky notification */ sticky: PropTypes.bool,
|
|
21
|
-
/** Type of notification */ type: PropTypes.oneOf([
|
|
22
|
-
NOTIFICATION_TYPE.INFO,
|
|
23
|
-
NOTIFICATION_TYPE.SUCCESS,
|
|
24
|
-
NOTIFICATION_TYPE.WARNING,
|
|
25
|
-
NOTIFICATION_TYPE.DANGER
|
|
26
|
-
]),
|
|
27
|
-
/** Action button text */ buttonText: PropTypes.string,
|
|
28
|
-
/** Action button click callback */ buttonClick: PropTypes.func,
|
|
29
|
-
/** Notification close callback. */ onClose: PropTypes.func,
|
|
30
|
-
/** Aria label for the close button on the notification. Defaults to "Close notification" */ closeButtonAriaLabel: PropTypes.string
|
|
31
|
-
};
|
|
32
|
-
StoryProps.defaultProps = {
|
|
33
|
-
duration: 5000,
|
|
34
|
-
sticky: false,
|
|
35
|
-
type: NOTIFICATION_TYPE.INFO
|
|
36
|
-
};
|
|
37
8
|
/** Maps notification position to layer position */ const positionMap = {
|
|
38
9
|
[NOTIFICATION_POSITION.TOP_LEFT]: LAYER_POSITION.TOP_LEFT,
|
|
39
10
|
[NOTIFICATION_POSITION.TOP_RIGHT]: LAYER_POSITION.TOP_RIGHT,
|
|
@@ -43,6 +14,7 @@ StoryProps.defaultProps = {
|
|
|
43
14
|
/** Notification class */ class Notification {
|
|
44
15
|
constructor(){
|
|
45
16
|
/** Helps in maintaining single instance for different positions. */ this.containers = new Map();
|
|
17
|
+
/** Pending add requests waiting for manager to mount */ this.pending = new Map();
|
|
46
18
|
/**
|
|
47
19
|
* Adds a notification
|
|
48
20
|
*
|
|
@@ -57,6 +29,12 @@ StoryProps.defaultProps = {
|
|
|
57
29
|
if (container) {
|
|
58
30
|
container.manager = instance;
|
|
59
31
|
}
|
|
32
|
+
// Process pending requests
|
|
33
|
+
const queue = this.pending.get(position);
|
|
34
|
+
if (queue) {
|
|
35
|
+
queue.forEach((cb)=>cb(instance));
|
|
36
|
+
this.pending.delete(position);
|
|
37
|
+
}
|
|
60
38
|
}
|
|
61
39
|
};
|
|
62
40
|
const [Component] = LayerManager.renderLayer({
|
|
@@ -89,14 +67,13 @@ StoryProps.defaultProps = {
|
|
|
89
67
|
if (container && container.manager) {
|
|
90
68
|
return container.manager.add(options);
|
|
91
69
|
}
|
|
92
|
-
// If manager is not ready yet,
|
|
70
|
+
// If manager is not ready yet, add to pending queue
|
|
93
71
|
return new Promise((resolve)=>{
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}, 10);
|
|
72
|
+
const queue = this.pending.get(position) || [];
|
|
73
|
+
queue.push((manager)=>{
|
|
74
|
+
resolve(manager.add(options));
|
|
75
|
+
});
|
|
76
|
+
this.pending.set(position, queue);
|
|
100
77
|
});
|
|
101
78
|
};
|
|
102
79
|
/**
|
|
@@ -127,7 +104,7 @@ StoryProps.defaultProps = {
|
|
|
127
104
|
};
|
|
128
105
|
}
|
|
129
106
|
}
|
|
130
|
-
/** Export a singleton instance */ var
|
|
107
|
+
/** Export a singleton instance */ var Notification_default = new Notification();
|
|
131
108
|
|
|
132
|
-
export {
|
|
109
|
+
export { Notification_default as default };
|
|
133
110
|
//# sourceMappingURL=Notification.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Notification.js","sources":["../../../src/components/Notification/Notification.tsx"],"sourcesContent":["import React, { type RefCallback } from 'react';\nimport PropTypes from 'prop-types';\nimport { flushSync } from 'react-dom';\nimport { createRoot, type Root } from 'react-dom/client';\nimport LayerManager, { LAYER_POSITION } from '../../shared/LayerManager';\nimport NotificationManager from './NotificationManager';\nimport { NOTIFICATION_POSITION, NOTIFICATION_TYPE, NotificationOptions } from './types';\n\ntype NotificationProps = PropTypes.InferProps<typeof StoryProps.propTypes>;\n\n/** This component is only used for storybook documentation */\nexport class StoryProps extends React.Component<NotificationProps> {\n static propTypes = {\n /** Title of the notification */\n title: PropTypes.string.isRequired,\n /** Body of the notification */\n description: PropTypes.string.isRequired,\n /** Id for the notification, helps in de-duplication. */\n id: PropTypes.string,\n /** Duration for the notification in milliseconds */\n duration: PropTypes.number,\n /** Creates sticky notification */\n sticky: PropTypes.bool,\n /** Type of notification */\n type: PropTypes.oneOf([\n NOTIFICATION_TYPE.INFO,\n NOTIFICATION_TYPE.SUCCESS,\n NOTIFICATION_TYPE.WARNING,\n NOTIFICATION_TYPE.DANGER,\n ]),\n /** Action button text */\n buttonText: PropTypes.string,\n /** Action button click callback */\n buttonClick: PropTypes.func,\n /** Notification close callback. */\n onClose: PropTypes.func,\n /** Aria label for the close button on the notification. Defaults to \"Close notification\" */\n closeButtonAriaLabel: PropTypes.string,\n };\n\n static defaultProps = {\n duration: 5000,\n sticky: false,\n type: NOTIFICATION_TYPE.INFO,\n };\n\n render(): React.ReactNode {\n return null;\n }\n}\n\n/** Maps notification position to layer position */\nconst positionMap = {\n [NOTIFICATION_POSITION.TOP_LEFT]: LAYER_POSITION.TOP_LEFT,\n [NOTIFICATION_POSITION.TOP_RIGHT]: LAYER_POSITION.TOP_RIGHT,\n [NOTIFICATION_POSITION.BOTTOM_LEFT]: LAYER_POSITION.BOTTOM_LEFT,\n [NOTIFICATION_POSITION.BOTTOM_RIGHT]: LAYER_POSITION.BOTTOM_RIGHT,\n};\n\n/** Notification class */\nclass Notification {\n /** Helps in maintaining single instance for different positions. */\n private containers: Map<\n NOTIFICATION_POSITION,\n {\n manager: NotificationManager | null;\n root: Root;\n div: HTMLDivElement;\n }\n > = new Map();\n\n /**\n * Adds a notification\n *\n * @param position - The position where the notification should appear\n * @param options - Configuration options for the notification\n * @returns The notification ID or a promise that resolves to the notification ID\n */\n public add = (\n position: NOTIFICATION_POSITION,\n options: NotificationOptions,\n ariaLabel: string = 'Notifications',\n ) => {\n if (!this.containers.has(position)) {\n /** Callback ref to capture the NotificationManager instance when it mounts */\n const refCallback: RefCallback<NotificationManager> = (instance) => {\n if (instance) {\n const container = this.containers.get(position);\n if (container) {\n container.manager = instance;\n }\n }\n };\n\n const [Component] = LayerManager.renderLayer({\n closeOnEsc: false,\n closeOnOverlayClick: false,\n position: positionMap[position],\n alwaysOnTop: true,\n component: (\n <NotificationManager\n ref={refCallback}\n position={position}\n onEmpty={() => this.destroy(position)}\n ariaLabel={ariaLabel}\n />\n ),\n });\n\n // Create a div to mount the Component\n const div = document.createElement('div');\n document.body.appendChild(div);\n const root = createRoot(div);\n\n this.containers.set(position, {\n manager: null,\n root,\n div,\n });\n\n // Render the Component which will trigger the LayerManager's useEffect\n flushSync(() => {\n root.render(<Component />);\n });\n }\n\n const container = this.containers.get(position);\n if (container && container.manager) {\n return container.manager.add(options);\n }\n\n // If manager is not ready yet, wait a bit and retry\n return new Promise<string>((resolve) => {\n setTimeout(() => {\n const container = this.containers.get(position);\n if (container && container.manager) {\n resolve(container.manager.add(options));\n }\n }, 10);\n });\n };\n\n /**\n * Removes a notification\n *\n * @param position - The position of the notification container\n * @param id - The unique ID of the notification to remove\n */\n public remove = (position: NOTIFICATION_POSITION, id: string) => {\n const container = this.containers.get(position);\n if (container && container.manager) {\n container.manager.remove(id);\n }\n };\n\n /**\n * Destroys entire stack of notifications at a position.\n * Unmounts the React root and cleans up DOM elements.\n *\n * @param position - The position of the notification container to destroy\n */\n public destroy = (position: NOTIFICATION_POSITION) => {\n const container = this.containers.get(position);\n if (container) {\n container.root.unmount();\n if (document.body.contains(container.div)) {\n document.body.removeChild(container.div);\n }\n this.containers.delete(position);\n }\n };\n}\n\n/** Export a singleton instance */\nexport default new Notification();\n"],"names":["StoryProps","React","Component","render","propTypes","title","PropTypes","string","isRequired","description","id","duration","number","sticky","bool","type","oneOf","NOTIFICATION_TYPE","INFO","SUCCESS","WARNING","DANGER","buttonText","buttonClick","func","onClose","closeButtonAriaLabel","defaultProps","positionMap","NOTIFICATION_POSITION","TOP_LEFT","LAYER_POSITION","TOP_RIGHT","BOTTOM_LEFT","BOTTOM_RIGHT","Notification","containers","Map","add","position","options","ariaLabel","has","refCallback","instance","container","get","manager","LayerManager","renderLayer","closeOnEsc","closeOnOverlayClick","alwaysOnTop","component","_jsx","NotificationManager","ref","onEmpty","destroy","div","document","createElement","body","appendChild","root","createRoot","set","flushSync","Promise","resolve","setTimeout","remove","unmount","contains","removeChild","delete"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Notification.js","sources":["../../../src/components/Notification/Notification.tsx"],"sourcesContent":["import { type RefCallback } from 'react';\nimport { flushSync } from 'react-dom';\nimport { createRoot, type Root } from 'react-dom/client';\nimport LayerManager, { LAYER_POSITION } from '../../shared/LayerManager';\nimport NotificationManager from './NotificationManager';\nimport { NOTIFICATION_POSITION, NOTIFICATION_TYPE, NotificationOptions } from './types';\n\ntype NotificationProps = {\n /** Title of the notification */\n title: string;\n /** Body of the notification */\n description: string;\n /** Id for the notification, helps in de-duplication. */\n id?: string;\n /**\n * Duration for the notification in milliseconds\n * @default 5000\n */\n duration?: number;\n /**\n * Creates sticky notification\n * @default false\n */\n sticky?: boolean;\n /**\n * Type of notification\n * @default NOTIFICATION_TYPE.INFO\n */\n type?: NOTIFICATION_TYPE;\n /** Action button text */\n buttonText?: string;\n /** Action button click callback */\n buttonClick?: () => void;\n /** Notification close callback. */\n onClose?: () => void;\n /** Aria label for the close button on the notification. Defaults to \"Close notification\" */\n closeButtonAriaLabel?: string;\n};\n\n/**\n * This dummy component is used to extract props for documentation in Storybook.\n * @param props\n * @returns\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function StoryProps(props: NotificationProps) {\n return null;\n}\n\n/** Maps notification position to layer position */\nconst positionMap = {\n [NOTIFICATION_POSITION.TOP_LEFT]: LAYER_POSITION.TOP_LEFT,\n [NOTIFICATION_POSITION.TOP_RIGHT]: LAYER_POSITION.TOP_RIGHT,\n [NOTIFICATION_POSITION.BOTTOM_LEFT]: LAYER_POSITION.BOTTOM_LEFT,\n [NOTIFICATION_POSITION.BOTTOM_RIGHT]: LAYER_POSITION.BOTTOM_RIGHT,\n};\n\n/** Notification class */\nclass Notification {\n /** Helps in maintaining single instance for different positions. */\n private containers: Map<\n NOTIFICATION_POSITION,\n {\n manager: NotificationManager | null;\n root: Root;\n div: HTMLDivElement;\n }\n > = new Map();\n\n /** Pending add requests waiting for manager to mount */\n private pending: Map<NOTIFICATION_POSITION, Array<(manager: NotificationManager) => void>> =\n new Map();\n\n /**\n * Adds a notification\n *\n * @param position - The position where the notification should appear\n * @param options - Configuration options for the notification\n * @returns The notification ID or a promise that resolves to the notification ID\n */\n public add = (\n position: NOTIFICATION_POSITION,\n options: NotificationOptions,\n ariaLabel: string = 'Notifications',\n ) => {\n if (!this.containers.has(position)) {\n /** Callback ref to capture the NotificationManager instance when it mounts */\n const refCallback: RefCallback<NotificationManager> = (instance) => {\n if (instance) {\n const container = this.containers.get(position);\n if (container) {\n container.manager = instance;\n }\n\n // Process pending requests\n const queue = this.pending.get(position);\n if (queue) {\n queue.forEach((cb) => cb(instance));\n this.pending.delete(position);\n }\n }\n };\n\n const [Component] = LayerManager.renderLayer({\n closeOnEsc: false,\n closeOnOverlayClick: false,\n position: positionMap[position],\n alwaysOnTop: true,\n component: (\n <NotificationManager\n ref={refCallback}\n position={position}\n onEmpty={() => this.destroy(position)}\n ariaLabel={ariaLabel}\n />\n ),\n });\n\n // Create a div to mount the Component\n const div = document.createElement('div');\n document.body.appendChild(div);\n const root = createRoot(div);\n\n this.containers.set(position, {\n manager: null,\n root,\n div,\n });\n\n // Render the Component which will trigger the LayerManager's useEffect\n flushSync(() => {\n root.render(<Component />);\n });\n }\n\n const container = this.containers.get(position);\n if (container && container.manager) {\n return container.manager.add(options);\n }\n\n // If manager is not ready yet, add to pending queue\n return new Promise<string>((resolve) => {\n const queue = this.pending.get(position) || [];\n queue.push((manager) => {\n resolve(manager.add(options));\n });\n this.pending.set(position, queue);\n });\n };\n\n /**\n * Removes a notification\n *\n * @param position - The position of the notification container\n * @param id - The unique ID of the notification to remove\n */\n public remove = (position: NOTIFICATION_POSITION, id: string) => {\n const container = this.containers.get(position);\n if (container && container.manager) {\n container.manager.remove(id);\n }\n };\n\n /**\n * Destroys entire stack of notifications at a position.\n * Unmounts the React root and cleans up DOM elements.\n *\n * @param position - The position of the notification container to destroy\n */\n public destroy = (position: NOTIFICATION_POSITION) => {\n const container = this.containers.get(position);\n if (container) {\n container.root.unmount();\n if (document.body.contains(container.div)) {\n document.body.removeChild(container.div);\n }\n this.containers.delete(position);\n }\n };\n}\n\n/** Export a singleton instance */\nexport default new Notification();\n"],"names":["positionMap","NOTIFICATION_POSITION","TOP_LEFT","LAYER_POSITION","TOP_RIGHT","BOTTOM_LEFT","BOTTOM_RIGHT","Notification","containers","Map","pending","add","position","options","ariaLabel","has","refCallback","instance","container","get","manager","queue","forEach","cb","delete","Component","LayerManager","renderLayer","closeOnEsc","closeOnOverlayClick","alwaysOnTop","component","_jsx","NotificationManager","ref","onEmpty","destroy","div","document","createElement","body","appendChild","root","createRoot","set","flushSync","render","Promise","resolve","push","remove","id","unmount","contains","removeChild"],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@ declare class NotificationManager extends React.Component<NotificationManagerPro
|
|
|
25
25
|
*
|
|
26
26
|
* @param id
|
|
27
27
|
*/
|
|
28
|
-
remove: (id
|
|
28
|
+
remove: (id?: string) => void;
|
|
29
29
|
/**
|
|
30
30
|
* Adds a notification to stack.
|
|
31
31
|
*
|
|
@@ -44,19 +44,19 @@ declare class NotificationManager extends React.Component<NotificationManagerPro
|
|
|
44
44
|
*
|
|
45
45
|
* @param id
|
|
46
46
|
*/
|
|
47
|
-
closeClickHandler: (id
|
|
47
|
+
closeClickHandler: (id?: string) => () => void;
|
|
48
48
|
/**
|
|
49
49
|
* Pause notification when user is hovering over it.
|
|
50
50
|
*
|
|
51
51
|
* @param id
|
|
52
52
|
*/
|
|
53
|
-
pause: (id
|
|
53
|
+
pause: (id?: string) => () => void;
|
|
54
54
|
/**
|
|
55
55
|
* Restart the removal of notification.
|
|
56
56
|
*
|
|
57
57
|
* @param id
|
|
58
58
|
*/
|
|
59
|
-
resume: (id
|
|
59
|
+
resume: (id?: string) => () => void;
|
|
60
60
|
/**
|
|
61
61
|
* Clean up all pending timeouts when component unmounts
|
|
62
62
|
*/
|
|
@@ -9,7 +9,7 @@ import CheckCircle$3 from '../../icons/ErrorOutline.js';
|
|
|
9
9
|
import ActionButton from '../Button/ActionButton.js';
|
|
10
10
|
import Close from '../../icons/Close.js';
|
|
11
11
|
|
|
12
|
-
const DEFAULT_DURATION = 5000;
|
|
12
|
+
const DEFAULT_DURATION$1 = 5000;
|
|
13
13
|
/**
|
|
14
14
|
* Notification Manager class
|
|
15
15
|
*/ class NotificationManager extends React.Component {
|
|
@@ -106,6 +106,7 @@ const DEFAULT_DURATION = 5000;
|
|
|
106
106
|
*
|
|
107
107
|
* @param id
|
|
108
108
|
*/ this.remove = (id)=>{
|
|
109
|
+
if (!id) return;
|
|
109
110
|
// Trigger leaving animation.
|
|
110
111
|
this.setState({
|
|
111
112
|
notices: this.state.notices.map((notice)=>({
|
|
@@ -150,22 +151,22 @@ const DEFAULT_DURATION = 5000;
|
|
|
150
151
|
const type = notice.type || NOTIFICATION_TYPE.INFO;
|
|
151
152
|
const isUrgent = type === NOTIFICATION_TYPE.WARNING || type === NOTIFICATION_TYPE.DANGER;
|
|
152
153
|
// Add notice to the top of stack.
|
|
153
|
-
this.setState({
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
this.setState((prevState)=>({
|
|
155
|
+
notices: [
|
|
156
|
+
{
|
|
157
|
+
...notice,
|
|
158
|
+
id
|
|
159
|
+
},
|
|
160
|
+
...prevState.notices
|
|
161
|
+
]
|
|
162
|
+
}), ()=>{
|
|
162
163
|
// Update live region after state update
|
|
163
164
|
const announcement = `${notice.title} ${notice.description}`;
|
|
164
165
|
this.updateLiveRegion(announcement, isUrgent);
|
|
165
166
|
});
|
|
166
167
|
// set timeout for closing the notification.
|
|
167
168
|
if (!notice.sticky) {
|
|
168
|
-
this.timeouts[id] = setTimeout(()=>this.remove(id), notice.duration || DEFAULT_DURATION);
|
|
169
|
+
this.timeouts[id] = setTimeout(()=>this.remove(id), notice.duration || DEFAULT_DURATION$1);
|
|
169
170
|
}
|
|
170
171
|
// Add id to the set.
|
|
171
172
|
this.set.add(id);
|
|
@@ -197,15 +198,18 @@ const DEFAULT_DURATION = 5000;
|
|
|
197
198
|
*
|
|
198
199
|
* @param id
|
|
199
200
|
*/ this.pause = (id)=>()=>{
|
|
200
|
-
|
|
201
|
+
if (id && this.timeouts[id]) {
|
|
202
|
+
clearTimeout(this.timeouts[id]);
|
|
203
|
+
delete this.timeouts[id];
|
|
204
|
+
}
|
|
201
205
|
}, /**
|
|
202
206
|
* Restart the removal of notification.
|
|
203
207
|
*
|
|
204
208
|
* @param id
|
|
205
209
|
*/ this.resume = (id)=>()=>{
|
|
206
210
|
const notice = this.state.notices.find((notice)=>notice.id === id);
|
|
207
|
-
if (!notice.
|
|
208
|
-
this.timeouts[id] = setTimeout(()=>this.remove(id), DEFAULT_DURATION);
|
|
211
|
+
if (!notice?.sticky && id && !this.timeouts[id]) {
|
|
212
|
+
this.timeouts[id] = setTimeout(()=>this.remove(id), DEFAULT_DURATION$1);
|
|
209
213
|
}
|
|
210
214
|
};
|
|
211
215
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationManager.js","sources":["../../../src/components/Notification/NotificationManager.tsx"],"sourcesContent":["import React from 'react';\nimport { Close, Info, ReportProblem, ErrorOutline, CheckCircle } from '../../icons';\nimport { ActionButton } from '../Button';\nimport {\n Container,\n Notice,\n Title,\n IconContainer,\n FillParent,\n Body,\n CloseButton,\n Footer,\n VisuallyHidden,\n} from './style';\nimport { NOTIFICATION_POSITION, NOTIFICATION_TYPE, NotificationOptions } from './types';\n\ninterface NotificationManagerProps {\n // Notification Position\n position: NOTIFICATION_POSITION;\n // Callback for when stack is emptied\n onEmpty: () => void;\n // Aria label for the notification list\n ariaLabel?: string;\n}\n\n// Notice prop\ninterface NoticeProp extends NotificationOptions {\n leaving?: boolean;\n}\n\n// Manager state\ninterface NotificationManagerState {\n notices: NoticeProp[];\n}\n\ntype timeouts = {\n [id: string]: NodeJS.Timeout;\n};\n\nconst DEFAULT_DURATION = 5000;\n\n/**\n * Notification Manager class\n */\nclass NotificationManager extends React.Component<\n NotificationManagerProps,\n NotificationManagerState\n> {\n state: NotificationManagerState = {\n notices: [],\n };\n\n // bookkeeping for timeouts\n private timeouts: timeouts = {};\n\n // Set of notification ids\n private set = new Set<string>();\n\n // Refs for live regions to ensure they exist before updates\n private politeRegionRef = React.createRef<HTMLDivElement>();\n private assertiveRegionRef = React.createRef<HTMLDivElement>();\n\n /**\n * Removes a notification from stack if the notification with the given id is found.\n *\n * @param id\n */\n public remove = (id: string) => {\n // Trigger leaving animation.\n this.setState({\n notices: this.state.notices.map((notice) => ({\n ...notice,\n leaving: notice.id === id ? true : notice.leaving,\n })),\n });\n this.set.delete(id);\n\n // Remove notification on animation completion.\n setTimeout(() => {\n const notice = this.state.notices.find((notice) => notice.id === id);\n if (notice) {\n // call close callback, ignore any errors in callback.\n if (notice.onClose) {\n try {\n notice.onClose();\n } catch (e) {\n console.warn('Error in notification close callback', e.message);\n }\n }\n\n // Remove the notification\n this.setState(\n {\n notices: this.state.notices.filter((notice) => notice.id !== id),\n },\n () => {\n // Check if the stack is empty and then call the\n // empty callback function.\n if (this.state.notices.length === 0) {\n this.props.onEmpty();\n }\n },\n );\n }\n }, 550);\n };\n\n /**\n * Adds a notification to stack.\n *\n * @param notice\n */\n public add = async (notice: NotificationOptions) => {\n // Generate unique id if not provided.\n const id = notice.id || (Math.random() * 10 ** 7).toFixed(0);\n\n // De-dupe on id\n if (!this.set.has(id)) {\n const type = notice.type || NOTIFICATION_TYPE.INFO;\n const isUrgent =\n type === NOTIFICATION_TYPE.WARNING || type === NOTIFICATION_TYPE.DANGER;\n\n // Add notice to the top of stack.\n this.setState(\n {\n notices: [\n {\n ...notice,\n id,\n },\n ...this.state.notices,\n ],\n },\n () => {\n // Update live region after state update\n const announcement = `${notice.title} ${notice.description}`;\n this.updateLiveRegion(announcement, isUrgent);\n },\n );\n\n // set timeout for closing the notification.\n if (!notice.sticky) {\n this.timeouts[id] = setTimeout(\n () => this.remove(id),\n notice.duration || DEFAULT_DURATION,\n );\n }\n\n // Add id to the set.\n this.set.add(id);\n }\n\n return id;\n };\n\n /**\n * Update live region content with clear-then-set pattern for reliable VoiceOver announcements.\n *\n * @param content - The text content to announce\n * @param isAssertive - Whether to use assertive (alert) or polite (log) live region\n */\n private updateLiveRegion = (content: string, isAssertive: boolean) => {\n const region = isAssertive ? this.assertiveRegionRef.current : this.politeRegionRef.current;\n\n if (region) {\n // Add content after delay\n setTimeout(() => {\n if (region) {\n region.textContent = content;\n }\n }, 150);\n }\n };\n\n /**\n * Handler for close button click.\n *\n * @param id\n */\n public closeClickHandler = (id: string) => () => {\n this.remove(id);\n };\n\n /**\n * Pause notification when user is hovering over it.\n *\n * @param id\n */\n public pause = (id: string) => () => {\n clearTimeout(this.timeouts[id]);\n };\n\n /**\n * Restart the removal of notification.\n *\n * @param id\n */\n public resume = (id: string) => () => {\n const notice = this.state.notices.find((notice) => notice.id === id);\n if (!notice.sticky) {\n this.timeouts[id] = setTimeout(() => this.remove(id), DEFAULT_DURATION);\n }\n };\n\n /**\n * Clean up all pending timeouts when component unmounts\n */\n componentWillUnmount() {\n // Clear all pending timeouts\n Object.keys(this.timeouts).forEach((id) => {\n clearTimeout(this.timeouts[id]);\n });\n this.timeouts = {};\n this.set.clear();\n }\n\n render() {\n return (\n <Container position={this.props.position}>\n {/* Polite live region - uses role=\"log\" for better VoiceOver compatibility */}\n <VisuallyHidden\n ref={this.politeRegionRef}\n role=\"log\"\n aria-live=\"polite\"\n aria-atomic=\"false\"\n aria-relevant=\"additions text\"\n />\n\n {/* Assertive live region - pre-rendered and persistent */}\n <VisuallyHidden\n ref={this.assertiveRegionRef}\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n />\n\n {/* Visual notifications with list semantics */}\n <div role=\"list\" aria-label={this.props.ariaLabel}>\n {this.state.notices.map((notice) => {\n const {\n id,\n title,\n description,\n leaving,\n type = NOTIFICATION_TYPE.INFO,\n buttonText,\n buttonClick,\n closeButtonAriaLabel,\n } = notice;\n\n return (\n <Notice\n key={id}\n {...notice}\n position={this.props.position}\n className={leaving ? 'leave' : ''}\n onMouseEnter={this.pause(id)}\n onMouseLeave={this.resume(id)}\n role=\"listitem\"\n >\n <IconContainer type={type} aria-hidden=\"true\">\n {type === NOTIFICATION_TYPE.INFO && <Info />}\n {type === NOTIFICATION_TYPE.SUCCESS && <CheckCircle />}\n {type === NOTIFICATION_TYPE.WARNING && <ReportProblem />}\n {type === NOTIFICATION_TYPE.DANGER && <ErrorOutline />}\n </IconContainer>\n <FillParent>\n <Title type={type}>{title}</Title>\n <Body>{description}</Body>\n {buttonText && (\n <Footer>\n <ActionButton\n onClick={() => {\n buttonClick?.();\n }}\n >\n {buttonText}\n </ActionButton>\n </Footer>\n )}\n </FillParent>\n <CloseButton\n onClick={this.closeClickHandler(id)}\n aria-label={closeButtonAriaLabel || 'Close notification'}\n tabIndex={0}\n >\n <Close />\n </CloseButton>\n </Notice>\n );\n })}\n </div>\n </Container>\n );\n }\n}\n\nexport default NotificationManager;\n"],"names":["DEFAULT_DURATION","NotificationManager","React","Component","componentWillUnmount","Object","keys","timeouts","forEach","id","clearTimeout","set","clear","render","_jsxs","Container","position","props","_jsx","VisuallyHidden","ref","politeRegionRef","role","aria-live","aria-atomic","aria-relevant","assertiveRegionRef","div","aria-label","ariaLabel","state","notices","map","notice","title","description","leaving","type","NOTIFICATION_TYPE","INFO","buttonText","buttonClick","closeButtonAriaLabel","Notice","className","onMouseEnter","pause","onMouseLeave","resume","IconContainer","aria-hidden","Info","SUCCESS","CheckCircle","WARNING","ReportProblem","DANGER","ErrorOutline","FillParent","Title","Body","Footer","ActionButton","onClick","CloseButton","closeClickHandler","tabIndex","Close","Set","createRef","remove","setState","delete","setTimeout","find","onClose","e","console","warn","message","filter","length","onEmpty","add","Math","random","toFixed","has","isUrgent","announcement","updateLiveRegion","sticky","duration","content","isAssertive","region","current","textContent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NotificationManager.js","sources":["../../../src/components/Notification/NotificationManager.tsx"],"sourcesContent":["import React from 'react';\nimport { Close, Info, ReportProblem, ErrorOutline, CheckCircle } from '../../icons';\nimport { ActionButton } from '../Button';\nimport {\n Container,\n Notice,\n Title,\n IconContainer,\n FillParent,\n Body,\n CloseButton,\n Footer,\n VisuallyHidden,\n} from './style';\nimport { NOTIFICATION_POSITION, NOTIFICATION_TYPE, NotificationOptions } from './types';\n\ninterface NotificationManagerProps {\n // Notification Position\n position: NOTIFICATION_POSITION;\n // Callback for when stack is emptied\n onEmpty: () => void;\n // Aria label for the notification list\n ariaLabel?: string;\n}\n\n// Notice prop\ninterface NoticeProp extends NotificationOptions {\n leaving?: boolean;\n}\n\n// Manager state\ninterface NotificationManagerState {\n notices: NoticeProp[];\n}\n\ntype timeouts = {\n [id: string]: NodeJS.Timeout;\n};\n\nconst DEFAULT_DURATION = 5000;\n\n/**\n * Notification Manager class\n */\nclass NotificationManager extends React.Component<\n NotificationManagerProps,\n NotificationManagerState\n> {\n state: NotificationManagerState = {\n notices: [],\n };\n\n // bookkeeping for timeouts\n private timeouts: timeouts = {};\n\n // Set of notification ids\n private set = new Set<string>();\n\n // Refs for live regions to ensure they exist before updates\n private politeRegionRef = React.createRef<HTMLDivElement>();\n private assertiveRegionRef = React.createRef<HTMLDivElement>();\n\n /**\n * Removes a notification from stack if the notification with the given id is found.\n *\n * @param id\n */\n public remove = (id?: string) => {\n if (!id) return;\n\n // Trigger leaving animation.\n this.setState({\n notices: this.state.notices.map((notice) => ({\n ...notice,\n leaving: notice.id === id ? true : notice.leaving,\n })),\n });\n this.set.delete(id);\n\n // Remove notification on animation completion.\n setTimeout(() => {\n const notice = this.state.notices.find((notice) => notice.id === id);\n if (notice) {\n // call close callback, ignore any errors in callback.\n if (notice.onClose) {\n try {\n notice.onClose();\n } catch (e: unknown) {\n console.warn('Error in notification close callback', (e as Error).message);\n }\n }\n\n // Remove the notification\n this.setState(\n {\n notices: this.state.notices.filter((notice) => notice.id !== id),\n },\n () => {\n // Check if the stack is empty and then call the\n // empty callback function.\n if (this.state.notices.length === 0) {\n this.props.onEmpty();\n }\n },\n );\n }\n }, 550);\n };\n\n /**\n * Adds a notification to stack.\n *\n * @param notice\n */\n public add = async (notice: NotificationOptions) => {\n // Generate unique id if not provided.\n const id = notice.id || (Math.random() * 10 ** 7).toFixed(0);\n\n // De-dupe on id\n if (!this.set.has(id)) {\n const type = notice.type || NOTIFICATION_TYPE.INFO;\n const isUrgent =\n type === NOTIFICATION_TYPE.WARNING || type === NOTIFICATION_TYPE.DANGER;\n\n // Add notice to the top of stack.\n this.setState(\n (prevState) => ({\n notices: [\n {\n ...notice,\n id,\n },\n ...prevState.notices,\n ],\n }),\n () => {\n // Update live region after state update\n const announcement = `${notice.title} ${notice.description}`;\n this.updateLiveRegion(announcement, isUrgent);\n },\n );\n\n // set timeout for closing the notification.\n if (!notice.sticky) {\n this.timeouts[id] = setTimeout(\n () => this.remove(id),\n notice.duration || DEFAULT_DURATION,\n );\n }\n\n // Add id to the set.\n this.set.add(id);\n }\n\n return id;\n };\n\n /**\n * Update live region content with clear-then-set pattern for reliable VoiceOver announcements.\n *\n * @param content - The text content to announce\n * @param isAssertive - Whether to use assertive (alert) or polite (log) live region\n */\n private updateLiveRegion = (content: string, isAssertive: boolean) => {\n const region = isAssertive ? this.assertiveRegionRef.current : this.politeRegionRef.current;\n\n if (region) {\n // Add content after delay\n setTimeout(() => {\n if (region) {\n region.textContent = content;\n }\n }, 150);\n }\n };\n\n /**\n * Handler for close button click.\n *\n * @param id\n */\n public closeClickHandler = (id?: string) => () => {\n this.remove(id);\n };\n\n /**\n * Pause notification when user is hovering over it.\n *\n * @param id\n */\n public pause = (id?: string) => () => {\n if (id && this.timeouts[id]) {\n clearTimeout(this.timeouts[id]);\n delete this.timeouts[id];\n }\n };\n\n /**\n * Restart the removal of notification.\n *\n * @param id\n */\n public resume = (id?: string) => () => {\n const notice = this.state.notices.find((notice) => notice.id === id);\n if (!notice?.sticky && id && !this.timeouts[id]) {\n this.timeouts[id] = setTimeout(() => this.remove(id), DEFAULT_DURATION);\n }\n };\n\n /**\n * Clean up all pending timeouts when component unmounts\n */\n componentWillUnmount() {\n // Clear all pending timeouts\n Object.keys(this.timeouts).forEach((id) => {\n clearTimeout(this.timeouts[id]);\n });\n this.timeouts = {};\n this.set.clear();\n }\n\n render() {\n return (\n <Container position={this.props.position}>\n {/* Polite live region - uses role=\"log\" for better VoiceOver compatibility */}\n <VisuallyHidden\n ref={this.politeRegionRef}\n role=\"log\"\n aria-live=\"polite\"\n aria-atomic=\"false\"\n aria-relevant=\"additions text\"\n />\n\n {/* Assertive live region - pre-rendered and persistent */}\n <VisuallyHidden\n ref={this.assertiveRegionRef}\n role=\"alert\"\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n />\n\n {/* Visual notifications with list semantics */}\n <div role=\"list\" aria-label={this.props.ariaLabel}>\n {this.state.notices.map((notice) => {\n const {\n id,\n title,\n description,\n leaving,\n type = NOTIFICATION_TYPE.INFO,\n buttonText,\n buttonClick,\n closeButtonAriaLabel,\n } = notice;\n\n return (\n <Notice\n key={id}\n {...notice}\n position={this.props.position}\n className={leaving ? 'leave' : ''}\n onMouseEnter={this.pause(id)}\n onMouseLeave={this.resume(id)}\n role=\"listitem\"\n >\n <IconContainer type={type} aria-hidden=\"true\">\n {type === NOTIFICATION_TYPE.INFO && <Info />}\n {type === NOTIFICATION_TYPE.SUCCESS && <CheckCircle />}\n {type === NOTIFICATION_TYPE.WARNING && <ReportProblem />}\n {type === NOTIFICATION_TYPE.DANGER && <ErrorOutline />}\n </IconContainer>\n <FillParent>\n <Title type={type}>{title}</Title>\n <Body>{description}</Body>\n {buttonText && (\n <Footer>\n <ActionButton\n onClick={() => {\n buttonClick?.();\n }}\n >\n {buttonText}\n </ActionButton>\n </Footer>\n )}\n </FillParent>\n <CloseButton\n onClick={this.closeClickHandler(id)}\n aria-label={closeButtonAriaLabel || 'Close notification'}\n tabIndex={0}\n >\n <Close />\n </CloseButton>\n </Notice>\n );\n })}\n </div>\n </Container>\n );\n }\n}\n\nexport default NotificationManager;\n"],"names":["DEFAULT_DURATION","NotificationManager","React","Component","componentWillUnmount","Object","keys","timeouts","forEach","id","clearTimeout","set","clear","render","_jsxs","Container","position","props","_jsx","VisuallyHidden","ref","politeRegionRef","role","aria-live","aria-atomic","aria-relevant","assertiveRegionRef","div","aria-label","ariaLabel","state","notices","map","notice","title","description","leaving","type","NOTIFICATION_TYPE","INFO","buttonText","buttonClick","closeButtonAriaLabel","Notice","className","onMouseEnter","pause","onMouseLeave","resume","IconContainer","aria-hidden","Info","SUCCESS","CheckCircle","WARNING","ReportProblem","DANGER","ErrorOutline","FillParent","Title","Body","Footer","ActionButton","onClick","CloseButton","closeClickHandler","tabIndex","Close","Set","createRef","remove","setState","delete","setTimeout","find","onClose","e","console","warn","message","filter","length","onEmpty","add","Math","random","toFixed","has","isUrgent","prevState","announcement","updateLiveRegion","sticky","duration","content","isAssertive","region","current","textContent"],"mappings":"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"}
|
|
@@ -9,9 +9,8 @@ export declare const Container: import("@emotion/styled").StyledComponent<{
|
|
|
9
9
|
position: NOTIFICATION_POSITION;
|
|
10
10
|
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
11
11
|
export declare const Notice: import("@emotion/styled").StyledComponent<{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} & import("../Card/Card").CardExtraProps & import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
|
|
12
|
+
elevated?: boolean;
|
|
13
|
+
} & import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement> & {
|
|
15
14
|
theme?: import("@emotion/react").Theme;
|
|
16
15
|
} & NoticeProp, {}, {}>;
|
|
17
16
|
export declare const Title: import("@emotion/styled").StyledComponent<{
|
|
@@ -57,42 +57,42 @@ const getTypeStyle = (type)=>{
|
|
|
57
57
|
return `color: ${getThemeValue(THEME_NAME.WARNING)}`;
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
|
-
const Container = /*#__PURE__*/ styled("div", {
|
|
61
|
-
target: "
|
|
60
|
+
const Container$2 = /*#__PURE__*/ styled("div", {
|
|
61
|
+
target: "e10n1sw0",
|
|
62
62
|
label: "Container"
|
|
63
63
|
})("display:flex;flex-direction:", (props)=>props.position === NOTIFICATION_POSITION.TOP_LEFT || props.position === NOTIFICATION_POSITION.TOP_RIGHT ? 'column' : 'column-reverse', ";");
|
|
64
64
|
const Notice = /*#__PURE__*/ styled(Card, {
|
|
65
|
-
target: "
|
|
65
|
+
target: "e10n1sw1",
|
|
66
66
|
label: "Notice"
|
|
67
67
|
})("position:relative;border-radius:3px;border-left:4px solid ", (props)=>getBorderColor(props.type), ";width:300px;display:flex;padding:0 5px 5px 0;overflow:hidden;animation:", (props)=>getEntryAnimation(props.position), " 0.6s ease;& svg{fill:currentColor;vertical-align:middle;width:20px;height:20px;}&.leave{animation:", (props)=>getExitAnimation(props.position), " 0.6s;}@keyframes in-right{from{transform:translateX(100%);max-height:0;opacity:0;}to{transform:translateX(0%);max-height:150px;opacity:1;}}@keyframes out-right{to{transform:translateX(100%);max-height:0;opacity:0;}from{transform:translateX(0%);max-height:100px;opacity:1;}}@keyframes in-left{from{transform:translateX(-100%);max-height:0;opacity:0;}to{transform:translateX(0%);max-height:150px;opacity:1;}}@keyframes out-left{to{transform:translateX(-100%);max-height:0;opacity:0;}from{transform:translateX(0%);max-height:100px;opacity:1;}}");
|
|
68
68
|
const Title = /*#__PURE__*/ styled("div", {
|
|
69
|
-
target: "
|
|
69
|
+
target: "e10n1sw2",
|
|
70
70
|
label: "Title"
|
|
71
71
|
})("padding:5px 0;font-size:14px;color:", (props)=>getTitleColor(props.type), ";display:flex;align-items:center;");
|
|
72
72
|
const FillParent = /*#__PURE__*/ styled("div", {
|
|
73
|
-
target: "
|
|
73
|
+
target: "e10n1sw3",
|
|
74
74
|
label: "FillParent"
|
|
75
75
|
})("flex:1;");
|
|
76
76
|
const CloseButton = /*#__PURE__*/ styled("button", {
|
|
77
|
-
target: "
|
|
77
|
+
target: "e10n1sw4",
|
|
78
78
|
label: "CloseButton"
|
|
79
79
|
})("position:absolute;background-color:transparent;border:none;padding:0;top:4px;right:4px;cursor:pointer;color:", getThemeValue(THEME_NAME.TEXT_COLOR_DARK), ";&:focus{box-shadow:0 0 0 3px ", getThemeValue(THEME_NAME.PRIMARY_LIGHT), ";border-radius:3px;}");
|
|
80
80
|
const Body = /*#__PURE__*/ styled("div", {
|
|
81
|
-
target: "
|
|
81
|
+
target: "e10n1sw5",
|
|
82
82
|
label: "Body"
|
|
83
83
|
})("padding:5px 5px 5px 0;font-size:14px;");
|
|
84
84
|
const IconContainer = /*#__PURE__*/ styled("div", {
|
|
85
|
-
target: "
|
|
85
|
+
target: "e10n1sw6",
|
|
86
86
|
label: "IconContainer"
|
|
87
87
|
})("padding:6px 10px;", (props)=>getTypeStyle(props.type), ";");
|
|
88
88
|
const Footer = /*#__PURE__*/ styled("div", {
|
|
89
|
-
target: "
|
|
89
|
+
target: "e10n1sw7",
|
|
90
90
|
label: "Footer"
|
|
91
91
|
})("display:flex;justify-content:flex-end;padding:0 5px;");
|
|
92
92
|
const VisuallyHidden = /*#__PURE__*/ styled("span", {
|
|
93
|
-
target: "
|
|
93
|
+
target: "e10n1sw8",
|
|
94
94
|
label: "VisuallyHidden"
|
|
95
95
|
})("position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;");
|
|
96
96
|
|
|
97
|
-
export { Body, CloseButton, Container, FillParent, Footer, IconContainer, Notice, Title, VisuallyHidden };
|
|
97
|
+
export { Body, CloseButton, Container$2 as Container, FillParent, Footer, IconContainer, Notice, Title, VisuallyHidden };
|
|
98
98
|
//# sourceMappingURL=style.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","sources":["../../../src/components/Notification/style.ts"],"sourcesContent":["import styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\nimport { Card } from '../Card';\nimport { NOTIFICATION_POSITION, NOTIFICATION_TYPE, NotificationOptions } from './types';\n\nconst getEntryAnimation = (position: NOTIFICATION_POSITION) => {\n switch (position) {\n case NOTIFICATION_POSITION.TOP_LEFT:\n case NOTIFICATION_POSITION.BOTTOM_LEFT:\n return 'in-left';\n default:\n return 'in-right';\n }\n};\n\nconst getExitAnimation = (position: NOTIFICATION_POSITION) => {\n switch (position) {\n case NOTIFICATION_POSITION.TOP_LEFT:\n case NOTIFICATION_POSITION.BOTTOM_LEFT:\n return 'out-left';\n default:\n return 'out-right';\n }\n};\n\nconst getBorderColor = (type
|
|
1
|
+
{"version":3,"file":"style.js","sources":["../../../src/components/Notification/style.ts"],"sourcesContent":["import styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\nimport { Card } from '../Card';\nimport { NOTIFICATION_POSITION, NOTIFICATION_TYPE, NotificationOptions } from './types';\n\nconst getEntryAnimation = (position: NOTIFICATION_POSITION) => {\n switch (position) {\n case NOTIFICATION_POSITION.TOP_LEFT:\n case NOTIFICATION_POSITION.BOTTOM_LEFT:\n return 'in-left';\n default:\n return 'in-right';\n }\n};\n\nconst getExitAnimation = (position: NOTIFICATION_POSITION) => {\n switch (position) {\n case NOTIFICATION_POSITION.TOP_LEFT:\n case NOTIFICATION_POSITION.BOTTOM_LEFT:\n return 'out-left';\n default:\n return 'out-right';\n }\n};\n\nconst getBorderColor = (type?: NOTIFICATION_TYPE) => {\n switch (type) {\n case NOTIFICATION_TYPE.SUCCESS:\n return getThemeValue(THEME_NAME.SUCCESS_LIGHT);\n case NOTIFICATION_TYPE.DANGER:\n return getThemeValue(THEME_NAME.ERROR_LIGHT);\n case NOTIFICATION_TYPE.WARNING:\n return getThemeValue(THEME_NAME.WARNING_LIGHT);\n default:\n return getThemeValue(THEME_NAME.INFO_LIGHT);\n }\n};\n\nconst getTitleColor = (type: NOTIFICATION_TYPE) => {\n switch (type) {\n case NOTIFICATION_TYPE.SUCCESS:\n return getThemeValue(THEME_NAME.SUCCESS);\n case NOTIFICATION_TYPE.DANGER:\n return getThemeValue(THEME_NAME.ERROR);\n case NOTIFICATION_TYPE.WARNING:\n return getThemeValue(THEME_NAME.WARNING);\n case NOTIFICATION_TYPE.INFO:\n return getThemeValue(THEME_NAME.INFO);\n }\n};\n\nconst getTypeStyle = (type: NOTIFICATION_TYPE) => {\n switch (type) {\n case NOTIFICATION_TYPE.INFO:\n return `color: ${getThemeValue(THEME_NAME.INFO)}`;\n case NOTIFICATION_TYPE.SUCCESS:\n return `color: ${getThemeValue(THEME_NAME.SUCCESS)}`;\n case NOTIFICATION_TYPE.DANGER:\n return `color: ${getThemeValue(THEME_NAME.ERROR)}`;\n case NOTIFICATION_TYPE.WARNING:\n return `color: ${getThemeValue(THEME_NAME.WARNING)}`;\n }\n};\n\ninterface NoticeProp extends NotificationOptions {\n position: NOTIFICATION_POSITION;\n}\n\nexport const Container = styled.div<{ position: NOTIFICATION_POSITION }>`\n display: flex;\n flex-direction: ${(props) =>\n props.position === NOTIFICATION_POSITION.TOP_LEFT ||\n props.position === NOTIFICATION_POSITION.TOP_RIGHT\n ? 'column'\n : 'column-reverse'};\n`;\n\nexport const Notice = styled(Card)<NoticeProp>`\n position: relative;\n border-radius: 3px;\n border-left: 4px solid ${(props) => getBorderColor(props.type)};\n width: 300px;\n display: flex;\n padding: 0 5px 5px 0;\n overflow: hidden;\n animation: ${(props) => getEntryAnimation(props.position)} 0.6s ease;\n\n & svg {\n fill: currentColor;\n vertical-align: middle;\n width: 20px;\n height: 20px;\n }\n\n &.leave {\n animation: ${(props) => getExitAnimation(props.position)} 0.6s;\n }\n\n @keyframes in-right {\n from {\n transform: translateX(100%);\n max-height: 0;\n opacity: 0;\n }\n\n to {\n transform: translateX(0%);\n max-height: 150px;\n opacity: 1;\n }\n }\n\n @keyframes out-right {\n to {\n transform: translateX(100%);\n max-height: 0;\n opacity: 0;\n }\n\n from {\n transform: translateX(0%);\n max-height: 100px;\n opacity: 1;\n }\n }\n\n @keyframes in-left {\n from {\n transform: translateX(-100%);\n max-height: 0;\n opacity: 0;\n }\n\n to {\n transform: translateX(0%);\n max-height: 150px;\n opacity: 1;\n }\n }\n\n @keyframes out-left {\n to {\n transform: translateX(-100%);\n max-height: 0;\n opacity: 0;\n }\n\n from {\n transform: translateX(0%);\n max-height: 100px;\n opacity: 1;\n }\n }\n`;\n\nexport const Title = styled.div<{ type: NOTIFICATION_TYPE }>`\n padding: 5px 0;\n font-size: 14px;\n color: ${(props) => getTitleColor(props.type)};\n display: flex;\n align-items: center;\n`;\n\nexport const FillParent = styled.div`\n flex: 1;\n`;\n\nexport const CloseButton = styled.button`\n position: absolute;\n background-color: transparent;\n border: none;\n padding: 0;\n top: 4px;\n right: 4px;\n cursor: pointer;\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};\n\n &:focus {\n box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n border-radius: 3px;\n }\n`;\n\nexport const Body = styled.div`\n padding: 5px 5px 5px 0;\n font-size: 14px;\n`;\n\nexport const IconContainer = styled.div<{ type: NOTIFICATION_TYPE }>`\n padding: 6px 10px;\n ${(props) => getTypeStyle(props.type)};\n`;\n\nexport const Footer = styled.div`\n display: flex;\n justify-content: flex-end;\n padding: 0 5px;\n`;\n\nexport const VisuallyHidden = styled.span`\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n`;\n"],"names":["getEntryAnimation","position","NOTIFICATION_POSITION","TOP_LEFT","BOTTOM_LEFT","getExitAnimation","getBorderColor","type","NOTIFICATION_TYPE","SUCCESS","getThemeValue","THEME_NAME","SUCCESS_LIGHT","DANGER","ERROR_LIGHT","WARNING","WARNING_LIGHT","INFO_LIGHT","getTitleColor","ERROR","INFO","getTypeStyle","Container","styled","props","TOP_RIGHT","Notice","Card","Title","FillParent","CloseButton","TEXT_COLOR_DARK","PRIMARY_LIGHT","Body","IconContainer","Footer","VisuallyHidden"],"mappings":"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"}
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
export declare enum POPOVER_POSITION {
|
|
4
3
|
TOP_LEFT = "TOP_LEFT",
|
|
5
4
|
TOP_RIGHT = "TOP_RIGHT",
|
|
6
5
|
BOTTOM_LEFT = "BOTTOM_LEFT",
|
|
7
6
|
BOTTOM_RIGHT = "BOTTOM_RIGHT"
|
|
8
7
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
type PopoverProps = {
|
|
9
|
+
/** Opens the popover */
|
|
10
|
+
open: boolean;
|
|
11
|
+
/** Anchor element for the popover */
|
|
12
|
+
element: React.ElementType;
|
|
13
|
+
/**
|
|
14
|
+
* Position of the popover around anchor element
|
|
15
|
+
* @default POPOVER_POSITION.BOTTOM_LEFT
|
|
16
|
+
*/
|
|
17
|
+
position?: POPOVER_POSITION;
|
|
18
|
+
/**
|
|
19
|
+
* If the popover should close on `esc` key press
|
|
20
|
+
* @default true
|
|
21
|
+
*/
|
|
22
|
+
closeOnEsc?: boolean;
|
|
23
|
+
/** Popover close callback */
|
|
24
|
+
onClose?: () => void;
|
|
25
|
+
};
|
|
26
|
+
declare const Popover: React.ForwardRefExoticComponent<PopoverProps & {
|
|
27
|
+
children?: React.ReactNode | undefined;
|
|
28
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
28
29
|
export default Popover;
|