@spaced-out/ui-design-system 0.0.1-alpha.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.
Files changed (259) hide show
  1. package/.commitlintrc.json +3 -0
  2. package/.cspell/custom-words.txt +22 -0
  3. package/.editorconfig +9 -0
  4. package/.eslintignore +1 -0
  5. package/.eslintrc.yml +122 -0
  6. package/.flowconfig +45 -0
  7. package/.github/workflows/pages.yml +52 -0
  8. package/.prettierrc +11 -0
  9. package/.storybook/SenseTheme.js +12 -0
  10. package/.storybook/main.js +73 -0
  11. package/.storybook/manager-head.html +41 -0
  12. package/.storybook/manager.js +14 -0
  13. package/.storybook/preview-head.html +130 -0
  14. package/.storybook/preview.js +128 -0
  15. package/.storybook/public/favicon.ico +0 -0
  16. package/.storybook/public/favicon.svg +6 -0
  17. package/.storybook/public/fonts/CentraNo2-Book.woff +0 -0
  18. package/.storybook/public/fonts/CentraNo2-Book.woff2 +0 -0
  19. package/.storybook/public/fonts/CentraNo2-BookItalic.woff +0 -0
  20. package/.storybook/public/fonts/CentraNo2-BookItalic.woff2 +0 -0
  21. package/.storybook/public/fonts/CentraNo2-Medium.woff +0 -0
  22. package/.storybook/public/fonts/CentraNo2-Medium.woff2 +0 -0
  23. package/.vscode/extensions.json +3 -0
  24. package/CHANGELOG.md +73 -0
  25. package/README.md +178 -0
  26. package/babel.config.js +24 -0
  27. package/config.js +58 -0
  28. package/cspell.json +26 -0
  29. package/design-tokens/border/app-border.json +41 -0
  30. package/design-tokens/border/base-border.json +41 -0
  31. package/design-tokens/color/app-color.json +226 -0
  32. package/design-tokens/color/base-color.json +265 -0
  33. package/design-tokens/elevation/app-elevation.json +22 -0
  34. package/design-tokens/elevation/base-elevation.json +19 -0
  35. package/design-tokens/font/base-font.json +98 -0
  36. package/design-tokens/index.js +5 -0
  37. package/design-tokens/motion/app.motion.json +24 -0
  38. package/design-tokens/motion/base-motion.json +40 -0
  39. package/design-tokens/opacity/base-opacity.json +49 -0
  40. package/design-tokens/shadow/base-shadow.json +86 -0
  41. package/design-tokens/size/base-size.json +94 -0
  42. package/design-tokens/space/app-space.json +40 -0
  43. package/design-tokens/space/base-space.json +40 -0
  44. package/flow-typed/npm/lodash_v4.x.x.js +6407 -0
  45. package/git-conventional-commits.json +43 -0
  46. package/gulpfile.js +48 -0
  47. package/jest.config.js +9 -0
  48. package/lib/assets/fontawesome/LICENSE.txt +18 -0
  49. package/lib/assets/fontawesome/css/all.min.css +27184 -0
  50. package/lib/assets/fontawesome/webfonts/fa-brands-400.ttf +0 -0
  51. package/lib/assets/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
  52. package/lib/assets/fontawesome/webfonts/fa-duotone-900.ttf +0 -0
  53. package/lib/assets/fontawesome/webfonts/fa-duotone-900.woff2 +0 -0
  54. package/lib/assets/fontawesome/webfonts/fa-light-300.ttf +0 -0
  55. package/lib/assets/fontawesome/webfonts/fa-light-300.woff2 +0 -0
  56. package/lib/assets/fontawesome/webfonts/fa-regular-400.ttf +0 -0
  57. package/lib/assets/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
  58. package/lib/assets/fontawesome/webfonts/fa-solid-900.ttf +0 -0
  59. package/lib/assets/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
  60. package/lib/assets/fontawesome/webfonts/fa-thin-100.ttf +0 -0
  61. package/lib/assets/fontawesome/webfonts/fa-thin-100.woff2 +0 -0
  62. package/lib/assets/fontawesome/webfonts/fa-v4compatibility.ttf +0 -0
  63. package/lib/assets/fontawesome/webfonts/fa-v4compatibility.woff2 +0 -0
  64. package/lib/components/Button/Button.js +120 -0
  65. package/lib/components/Button/Button.js.flow +166 -0
  66. package/lib/components/Button/Button.module.css +226 -0
  67. package/lib/components/Button/index.js +24 -0
  68. package/lib/components/Button/index.js.flow +4 -0
  69. package/lib/components/ButtonDropdown/ButtonDropdown.js +89 -0
  70. package/lib/components/ButtonDropdown/ButtonDropdown.js.flow +119 -0
  71. package/lib/components/ButtonDropdown/ButtonDropdown.module.css +4 -0
  72. package/lib/components/ButtonDropdown/index.js +12 -0
  73. package/lib/components/ButtonDropdown/index.js.flow +4 -0
  74. package/lib/components/Checkbox/Checkbox.js +99 -0
  75. package/lib/components/Checkbox/Checkbox.js.flow +133 -0
  76. package/lib/components/Checkbox/Checkbox.module.css +160 -0
  77. package/lib/components/Checkbox/CheckboxGroup.js +85 -0
  78. package/lib/components/Checkbox/CheckboxGroup.js.flow +105 -0
  79. package/lib/components/Checkbox/CheckboxGroup.module.css +47 -0
  80. package/lib/components/Checkbox/index.js +19 -0
  81. package/lib/components/Checkbox/index.js.flow +3 -0
  82. package/lib/components/CircularLoader/CircularLoader.js +44 -0
  83. package/lib/components/CircularLoader/CircularLoader.js.flow +44 -0
  84. package/lib/components/CircularLoader/CircularLoader.module.css +81 -0
  85. package/lib/components/CircularLoader/index.js +12 -0
  86. package/lib/components/CircularLoader/index.js.flow +3 -0
  87. package/lib/components/CodeBlock.js +26 -0
  88. package/lib/components/CodeBlock.js.flow +19 -0
  89. package/lib/components/Dialog/Dialog.js +148 -0
  90. package/lib/components/Dialog/Dialog.js.flow +165 -0
  91. package/lib/components/Dialog/Dialog.module.css +87 -0
  92. package/lib/components/Dialog/index.js +36 -0
  93. package/lib/components/Dialog/index.js.flow +14 -0
  94. package/lib/components/Dropdown/Dropdown.js +108 -0
  95. package/lib/components/Dropdown/Dropdown.js.flow +129 -0
  96. package/lib/components/Dropdown/Dropdown.module.css +14 -0
  97. package/lib/components/Dropdown/index.js +18 -0
  98. package/lib/components/Dropdown/index.js.flow +4 -0
  99. package/lib/components/Grid/Grid.js +82 -0
  100. package/lib/components/Grid/Grid.js.flow +88 -0
  101. package/lib/components/Grid/Grid.module.css +30 -0
  102. package/lib/components/Grid/index.js +16 -0
  103. package/lib/components/Grid/index.js.flow +3 -0
  104. package/lib/components/Icon/ClickableIcon.js +51 -0
  105. package/lib/components/Icon/ClickableIcon.js.flow +51 -0
  106. package/lib/components/Icon/ClickableIcon.module.css +50 -0
  107. package/lib/components/Icon/FontAwesomeLibrary.js +3 -0
  108. package/lib/components/Icon/FontAwesomeLibrary.js.flow +3 -0
  109. package/lib/components/Icon/Icon.js +38 -0
  110. package/lib/components/Icon/Icon.js.flow +51 -0
  111. package/lib/components/Icon/index.js +25 -0
  112. package/lib/components/Icon/index.js.flow +6 -0
  113. package/lib/components/InContextAlert/InContextAlert.js +121 -0
  114. package/lib/components/InContextAlert/InContextAlert.js.flow +173 -0
  115. package/lib/components/InContextAlert/InContextAlert.module.css +54 -0
  116. package/lib/components/InContextAlert/index.js +18 -0
  117. package/lib/components/InContextAlert/index.js.flow +3 -0
  118. package/lib/components/Input/Input.js +172 -0
  119. package/lib/components/Input/Input.js.flow +246 -0
  120. package/lib/components/Input/Input.module.css +122 -0
  121. package/lib/components/Input/index.js +12 -0
  122. package/lib/components/Input/index.js.flow +4 -0
  123. package/lib/components/LinearLoader/LinearLoader.js +35 -0
  124. package/lib/components/LinearLoader/LinearLoader.js.flow +34 -0
  125. package/lib/components/LinearLoader/LinearLoader.module.css +43 -0
  126. package/lib/components/LinearLoader/index.js +12 -0
  127. package/lib/components/LinearLoader/index.js.flow +3 -0
  128. package/lib/components/Menu/Menu.js +76 -0
  129. package/lib/components/Menu/Menu.js.flow +85 -0
  130. package/lib/components/Menu/Menu.module.css +124 -0
  131. package/lib/components/Menu/index.js +12 -0
  132. package/lib/components/Menu/index.js.flow +4 -0
  133. package/lib/components/Modal/Modal.js +121 -0
  134. package/lib/components/Modal/Modal.js.flow +157 -0
  135. package/lib/components/Modal/Modal.module.css +62 -0
  136. package/lib/components/Modal/index.js +12 -0
  137. package/lib/components/Modal/index.js.flow +3 -0
  138. package/lib/components/Notification/Notification.js +89 -0
  139. package/lib/components/Notification/Notification.js.flow +136 -0
  140. package/lib/components/Notification/Notification.module.css +54 -0
  141. package/lib/components/Notification/index.js +18 -0
  142. package/lib/components/Notification/index.js.flow +3 -0
  143. package/lib/components/Panel/Panel.js +96 -0
  144. package/lib/components/Panel/Panel.js.flow +109 -0
  145. package/lib/components/Panel/Panel.module.css +77 -0
  146. package/lib/components/Panel/index.js +30 -0
  147. package/lib/components/Panel/index.js.flow +10 -0
  148. package/lib/components/RadioButton/RadioButton.js +76 -0
  149. package/lib/components/RadioButton/RadioButton.js.flow +102 -0
  150. package/lib/components/RadioButton/RadioButton.module.css +122 -0
  151. package/lib/components/RadioButton/RadioGroup.js +60 -0
  152. package/lib/components/RadioButton/RadioGroup.js.flow +85 -0
  153. package/lib/components/RadioButton/RadioGroup.module.css +47 -0
  154. package/lib/components/RadioButton/index.js +19 -0
  155. package/lib/components/RadioButton/index.js.flow +3 -0
  156. package/lib/components/SearchInput/SearchInput.js +47 -0
  157. package/lib/components/SearchInput/SearchInput.js.flow +73 -0
  158. package/lib/components/SearchInput/SearchInput.module.css +11 -0
  159. package/lib/components/SearchInput/index.js +12 -0
  160. package/lib/components/SearchInput/index.js.flow +4 -0
  161. package/lib/components/Text/Text.js +195 -0
  162. package/lib/components/Text/Text.js.flow +160 -0
  163. package/lib/components/Text/index.js +103 -0
  164. package/lib/components/Text/index.js.flow +21 -0
  165. package/lib/components/Textarea/Textarea.js +95 -0
  166. package/lib/components/Textarea/Textarea.js.flow +133 -0
  167. package/lib/components/Textarea/Textarea.module.css +110 -0
  168. package/lib/components/Textarea/index.js +12 -0
  169. package/lib/components/Textarea/index.js.flow +4 -0
  170. package/lib/components/Toast/Toast.js +187 -0
  171. package/lib/components/Toast/Toast.js.flow +210 -0
  172. package/lib/components/Toast/Toast.module.css +52 -0
  173. package/lib/components/Toast/ToastContainer.js +129 -0
  174. package/lib/components/Toast/ToastContainer.js.flow +125 -0
  175. package/lib/components/Toast/ToastContainer.module.css +41 -0
  176. package/lib/components/Toast/ToastManager.js +62 -0
  177. package/lib/components/Toast/ToastManager.js.flow +67 -0
  178. package/lib/components/Toast/index.js +56 -0
  179. package/lib/components/Toast/index.js.flow +12 -0
  180. package/lib/components/Toggle/Toggle.js +69 -0
  181. package/lib/components/Toggle/Toggle.js.flow +94 -0
  182. package/lib/components/Toggle/Toggle.module.css +144 -0
  183. package/lib/components/Toggle/index.js +12 -0
  184. package/lib/components/Toggle/index.js.flow +2 -0
  185. package/lib/components/Tooltip/Tooltip.js +81 -0
  186. package/lib/components/Tooltip/Tooltip.js.flow +110 -0
  187. package/lib/components/Tooltip/Tooltip.module.css +16 -0
  188. package/lib/components/Tooltip/index.js +12 -0
  189. package/lib/components/Tooltip/index.js.flow +4 -0
  190. package/lib/components/Truncate/Truncate.js +28 -0
  191. package/lib/components/Truncate/Truncate.js.flow +22 -0
  192. package/lib/components/Truncate/Truncate.module.css +6 -0
  193. package/lib/components/Truncate/index.js +12 -0
  194. package/lib/components/Truncate/index.js.flow +4 -0
  195. package/lib/components/Typeahead/Typeahead.js +124 -0
  196. package/lib/components/Typeahead/Typeahead.js.flow +153 -0
  197. package/lib/components/Typeahead/Typeahead.module.css +10 -0
  198. package/lib/components/Typeahead/index.js +12 -0
  199. package/lib/components/Typeahead/index.js.flow +4 -0
  200. package/lib/hooks/index.js +27 -0
  201. package/lib/hooks/index.js.flow +4 -0
  202. package/lib/hooks/useMountTransition.js +25 -0
  203. package/lib/hooks/useMountTransition.js.flow +27 -0
  204. package/lib/hooks/useToastPortal.js +32 -0
  205. package/lib/hooks/useToastPortal.js.flow +30 -0
  206. package/lib/styles/animation.module.css +9 -0
  207. package/lib/styles/border.module.css +27 -0
  208. package/lib/styles/shadow.module.css +42 -0
  209. package/lib/styles/typography.module.css +227 -0
  210. package/lib/styles/variables/_border.css +21 -0
  211. package/lib/styles/variables/_border.js +29 -0
  212. package/lib/styles/variables/_border.js.flow +23 -0
  213. package/lib/styles/variables/_color.css +131 -0
  214. package/lib/styles/variables/_color.js +139 -0
  215. package/lib/styles/variables/_color.js.flow +133 -0
  216. package/lib/styles/variables/_elevation.css +11 -0
  217. package/lib/styles/variables/_elevation.js +19 -0
  218. package/lib/styles/variables/_elevation.js.flow +13 -0
  219. package/lib/styles/variables/_font.css +51 -0
  220. package/lib/styles/variables/_font.js +59 -0
  221. package/lib/styles/variables/_font.js.flow +53 -0
  222. package/lib/styles/variables/_motion.css +11 -0
  223. package/lib/styles/variables/_motion.js +19 -0
  224. package/lib/styles/variables/_motion.js.flow +13 -0
  225. package/lib/styles/variables/_opacity.css +29 -0
  226. package/lib/styles/variables/_opacity.js +37 -0
  227. package/lib/styles/variables/_opacity.js.flow +31 -0
  228. package/lib/styles/variables/_shadow.css +47 -0
  229. package/lib/styles/variables/_shadow.js +55 -0
  230. package/lib/styles/variables/_shadow.js.flow +49 -0
  231. package/lib/styles/variables/_size.css +59 -0
  232. package/lib/styles/variables/_size.js +67 -0
  233. package/lib/styles/variables/_size.js.flow +61 -0
  234. package/lib/styles/variables/_space.css +23 -0
  235. package/lib/styles/variables/_space.js +31 -0
  236. package/lib/styles/variables/_space.js.flow +25 -0
  237. package/lib/types/common.js +1 -0
  238. package/lib/types/common.js.flow +3 -0
  239. package/lib/types/toast.js +24 -0
  240. package/lib/types/toast.js.flow +41 -0
  241. package/lib/types/typography.js +22 -0
  242. package/lib/types/typography.js.flow +18 -0
  243. package/lib/utils/classify.js +33 -0
  244. package/lib/utils/classify.js.flow +29 -0
  245. package/lib/utils/click-away.js +110 -0
  246. package/lib/utils/click-away.js.flow +134 -0
  247. package/lib/utils/dom.js +202 -0
  248. package/lib/utils/dom.js.flow +238 -0
  249. package/lib/utils/helpers.js +16 -0
  250. package/lib/utils/helpers.js.flow +11 -0
  251. package/lib/utils/makeClassNameComponent.js +58 -0
  252. package/lib/utils/makeClassNameComponent.js.flow +71 -0
  253. package/lib/utils/merge-refs.js +17 -0
  254. package/lib/utils/merge-refs.js.flow +14 -0
  255. package/lint-staged.config.js +5 -0
  256. package/package.json +114 -0
  257. package/postcss.config.js +3 -0
  258. package/pull_request_template.md +48 -0
  259. package/settings.json +3 -0
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Modal = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _reactDom = require("react-dom");
9
+ var _reactDomInteractions = require("@floating-ui/react-dom-interactions");
10
+ var _useMountTransition = _interopRequireDefault(require("../../hooks/useMountTransition"));
11
+ var _motion = require("../../styles/variables/_motion");
12
+ var _classify = _interopRequireDefault(require("../../utils/classify"));
13
+ var _ModalModule = _interopRequireDefault(require("./Modal.module.css"));
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
18
+
19
+ // $FlowFixMe[untyped-import]
20
+
21
+ const createPortalRoot = () => {
22
+ const modalRoot = document.createElement('div');
23
+ modalRoot.setAttribute('id', 'modal-root');
24
+ return modalRoot;
25
+ };
26
+ const Modal = _ref => {
27
+ let {
28
+ classNames,
29
+ children,
30
+ isOpen = false,
31
+ onClose,
32
+ showBackdrop = false,
33
+ removeWhenClosed = true,
34
+ tapOutsideToClose = true,
35
+ initialFocus = -1
36
+ } = _ref;
37
+ const {
38
+ floating,
39
+ context
40
+ } = (0, _reactDomInteractions.useFloating)();
41
+ const bodyRef = React.useRef(document.querySelector('body'));
42
+ const portalRootRef = React.useRef(document.getElementById('modal-root') || createPortalRoot());
43
+ const isTransitioning = (0, _useMountTransition.default)(isOpen, parseInt(_motion.motionDurationNormal));
44
+
45
+ // Append portal root on mount
46
+ React.useEffect(() => {
47
+ bodyRef.current?.appendChild(portalRootRef.current);
48
+ const portal = portalRootRef.current;
49
+ const bodyEl = bodyRef.current;
50
+ return () => {
51
+ // Clean up the portal when modal component unmounts
52
+ portal.remove();
53
+ // Ensure scroll overflow is removed
54
+ if (bodyEl) {
55
+ bodyEl.style.overflow = '';
56
+ }
57
+ };
58
+ }, []);
59
+
60
+ // Prevent page scrolling when the modal is open
61
+ React.useEffect(() => {
62
+ const updatePageScroll = () => {
63
+ if (isOpen) {
64
+ if (bodyRef.current) {
65
+ bodyRef.current.style.overflow = 'hidden';
66
+ }
67
+ } else {
68
+ if (bodyRef.current) {
69
+ bodyRef.current.style.overflow = '';
70
+ }
71
+ }
72
+ };
73
+ updatePageScroll();
74
+ }, [isOpen]);
75
+
76
+ // Allow Escape key to dismiss the modal
77
+ React.useEffect(() => {
78
+ const onKeyPress = e => {
79
+ if (e.key === 'Escape') {
80
+ tapOutsideToClose && onClose && onClose(e);
81
+ }
82
+ };
83
+ if (isOpen) {
84
+ window.addEventListener('keyup', onKeyPress);
85
+ }
86
+ return () => {
87
+ window.removeEventListener('keyup', onKeyPress);
88
+ };
89
+ }, [isOpen, onClose]);
90
+ if (!isTransitioning && removeWhenClosed && !isOpen) {
91
+ return null;
92
+ }
93
+ const onBackdropClick = e => {
94
+ if (tapOutsideToClose && onClose) {
95
+ onClose(e);
96
+ }
97
+ };
98
+ return /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/(0, _jsxRuntime.js)(_reactDomInteractions.FloatingFocusManager, {
99
+ context: context,
100
+ initialFocus: initialFocus,
101
+ children: /*#__PURE__*/(0, _jsxRuntime.jss)("div", {
102
+ ref: floating,
103
+ "aria-hidden": isOpen ? 'false' : 'true',
104
+ className: (0, _classify.default)(_ModalModule.default.modalContainer, {
105
+ [_ModalModule.default.in]: isTransitioning,
106
+ [_ModalModule.default.open]: isOpen
107
+ }, classNames?.container),
108
+ children: [/*#__PURE__*/(0, _jsxRuntime.js)("div", {
109
+ className: (0, _classify.default)(_ModalModule.default.backdrop, {
110
+ [_ModalModule.default.darkBackdrop]: showBackdrop
111
+ }, classNames?.backdrop),
112
+ onClick: onBackdropClick
113
+ }), /*#__PURE__*/(0, _jsxRuntime.js)("div", {
114
+ className: (0, _classify.default)(_ModalModule.default.modal, classNames?.content),
115
+ role: "dialog",
116
+ children: children
117
+ })]
118
+ })
119
+ }), portalRootRef.current);
120
+ };
121
+ exports.Modal = Modal;
@@ -0,0 +1,157 @@
1
+ // @flow strict
2
+
3
+ import * as React from 'react';
4
+ // $FlowFixMe[untyped-import]
5
+ import {createPortal} from 'react-dom';
6
+ import {
7
+ // $FlowFixMe[untyped-import]
8
+ FloatingFocusManager,
9
+ // $FlowFixMe[untyped-import]
10
+ useFloating,
11
+ } from '@floating-ui/react-dom-interactions';
12
+
13
+ import useMountTransition from '../../hooks/useMountTransition';
14
+ import {motionDurationNormal} from '../../styles/variables/_motion';
15
+ import classify from '../../utils/classify';
16
+
17
+ import css from './Modal.module.css';
18
+
19
+
20
+ type ClassNames = $ReadOnly<{
21
+ container?: string,
22
+ content?: string,
23
+ backdrop?: string,
24
+ }>;
25
+
26
+ export type ModalProps = {
27
+ classNames?: ClassNames,
28
+ children?: React.Node,
29
+ isOpen?: boolean,
30
+ onClose?: ?(SyntheticEvent<HTMLElement>) => mixed,
31
+ showBackdrop?: boolean,
32
+ removeWhenClosed?: boolean,
33
+ tapOutsideToClose?: boolean,
34
+ initialFocus?: number,
35
+ };
36
+
37
+ const createPortalRoot = () => {
38
+ const modalRoot = document.createElement('div');
39
+ modalRoot.setAttribute('id', 'modal-root');
40
+
41
+ return modalRoot;
42
+ };
43
+
44
+ export const Modal = ({
45
+ classNames,
46
+ children,
47
+ isOpen = false,
48
+ onClose,
49
+ showBackdrop = false,
50
+ removeWhenClosed = true,
51
+ tapOutsideToClose = true,
52
+ initialFocus = -1,
53
+ }: ModalProps): React.Node => {
54
+ const {floating, context} = useFloating();
55
+
56
+ const bodyRef = React.useRef(document.querySelector('body'));
57
+ const portalRootRef = React.useRef(
58
+ document.getElementById('modal-root') || createPortalRoot(),
59
+ );
60
+
61
+ const isTransitioning = useMountTransition(
62
+ isOpen,
63
+ parseInt(motionDurationNormal),
64
+ );
65
+
66
+ // Append portal root on mount
67
+ React.useEffect(() => {
68
+ bodyRef.current?.appendChild(portalRootRef.current);
69
+ const portal = portalRootRef.current;
70
+ const bodyEl = bodyRef.current;
71
+
72
+ return () => {
73
+ // Clean up the portal when modal component unmounts
74
+ portal.remove();
75
+ // Ensure scroll overflow is removed
76
+ if (bodyEl) {
77
+ bodyEl.style.overflow = '';
78
+ }
79
+ };
80
+ }, []);
81
+
82
+ // Prevent page scrolling when the modal is open
83
+ React.useEffect(() => {
84
+ const updatePageScroll = () => {
85
+ if (isOpen) {
86
+ if (bodyRef.current) {
87
+ bodyRef.current.style.overflow = 'hidden';
88
+ }
89
+ } else {
90
+ if (bodyRef.current) {
91
+ bodyRef.current.style.overflow = '';
92
+ }
93
+ }
94
+ };
95
+
96
+ updatePageScroll();
97
+ }, [isOpen]);
98
+
99
+ // Allow Escape key to dismiss the modal
100
+ React.useEffect(() => {
101
+ const onKeyPress = (e) => {
102
+ if (e.key === 'Escape') {
103
+ tapOutsideToClose && onClose && onClose(e);
104
+ }
105
+ };
106
+
107
+ if (isOpen) {
108
+ window.addEventListener('keyup', onKeyPress);
109
+ }
110
+
111
+ return () => {
112
+ window.removeEventListener('keyup', onKeyPress);
113
+ };
114
+ }, [isOpen, onClose]);
115
+
116
+ if (!isTransitioning && removeWhenClosed && !isOpen) {
117
+ return null;
118
+ }
119
+
120
+ const onBackdropClick = (e: SyntheticEvent<HTMLElement>) => {
121
+ if (tapOutsideToClose && onClose) {
122
+ onClose(e);
123
+ }
124
+ };
125
+
126
+ return createPortal(
127
+ <FloatingFocusManager context={context} initialFocus={initialFocus}>
128
+ <div
129
+ ref={floating}
130
+ aria-hidden={isOpen ? 'false' : 'true'}
131
+ className={classify(
132
+ css.modalContainer,
133
+ {
134
+ [css.in]: isTransitioning,
135
+ [css.open]: isOpen,
136
+ },
137
+ classNames?.container,
138
+ )}
139
+ >
140
+ <div
141
+ className={classify(
142
+ css.backdrop,
143
+ {
144
+ [css.darkBackdrop]: showBackdrop,
145
+ },
146
+ classNames?.backdrop,
147
+ )}
148
+ onClick={onBackdropClick}
149
+ />
150
+ <div className={classify(css.modal, classNames?.content)} role="dialog">
151
+ {children}
152
+ </div>
153
+ </div>
154
+ </FloatingFocusManager>,
155
+ portalRootRef.current,
156
+ );
157
+ };
@@ -0,0 +1,62 @@
1
+ @value (colorBackgroundTertiary, colorBackdropFill) from '../../styles/variables/_color.css';
2
+ @value (spaceNone, spaceXXSmall, spaceHalfFluid, spaceNegHalfFluid) from '../../styles/variables/_space.css';
3
+ @value (sizeFluid) from '../../styles/variables/_size.css';
4
+ @value (elevationNone, elevationModal, elevationBackdrop) from '../../styles/variables/_elevation.css';
5
+ @value (opacity100, opacity0) from '../../styles/variables/_opacity.css';
6
+ @value (motionDurationNormal, motionEaseInEaseOut) from '../../styles/variables/_motion.css';
7
+
8
+ .modalContainer {
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: center;
12
+ }
13
+
14
+ .modal {
15
+ position: fixed;
16
+ top: spaceHalfFluid;
17
+ transform: translateY(spaceNegHalfFluid) scale(0.95);
18
+ opacity: opacity0;
19
+ composes: boxShadow4 from '../../styles/shadow.module.css';
20
+ display: flex;
21
+ max-height: sizeFluid;
22
+ flex-flow: column;
23
+ background: colorBackgroundTertiary;
24
+ overflow: auto;
25
+ z-index: elevationModal;
26
+ transition: opacity motionDurationNormal, transform motionDurationNormal;
27
+ }
28
+
29
+ .modalContainer.open.in .modal {
30
+ opacity: opacity100;
31
+ transform: translateY(spaceNegHalfFluid) scale(1);
32
+ }
33
+
34
+ .backdrop {
35
+ display: flex;
36
+ flex-flow: column;
37
+ visibility: hidden;
38
+ opacity: opacity0;
39
+ background-color: transparent;
40
+ backdrop-filter: blur(spaceNone);
41
+ width: sizeFluid;
42
+ height: sizeFluid;
43
+ top: spaceNone;
44
+ left: spaceNone;
45
+ position: fixed;
46
+ pointer-events: none;
47
+ z-index: elevationNone;
48
+ transition: visibility motionDurationNormal,
49
+ backdrop-filter motionDurationNormal;
50
+ }
51
+
52
+ .modalContainer.open.in .backdrop {
53
+ visibility: visible;
54
+ opacity: opacity100;
55
+ pointer-events: auto;
56
+ z-index: elevationBackdrop;
57
+ }
58
+
59
+ .modalContainer.open.in .darkBackdrop {
60
+ backdrop-filter: blur(spaceXXSmall);
61
+ background-color: colorBackdropFill;
62
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "Modal", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _Modal.Modal;
10
+ }
11
+ });
12
+ var _Modal = require("./Modal.js");
@@ -0,0 +1,3 @@
1
+ //@flow strict
2
+ export type {ModalProps} from './Modal.js';
3
+ export {Modal} from './Modal.js';
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Notification = exports.NOTIFICATION_SEMANTIC = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _typography = require("../../types/typography");
9
+ var _classify = require("../../utils/classify");
10
+ var _Icon = require("../Icon");
11
+ var _Text = require("../Text");
12
+ var _NotificationModule = _interopRequireDefault(require("./Notification.module.css"));
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
16
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
+
18
+ const NOTIFICATION_SEMANTIC = Object.freeze({
19
+ success: 'success',
20
+ information: 'information',
21
+ danger: 'danger'
22
+ });
23
+ exports.NOTIFICATION_SEMANTIC = NOTIFICATION_SEMANTIC;
24
+ // Base Notification will not have any state.
25
+
26
+ const BaseNotification = props => {
27
+ const {
28
+ classNames,
29
+ semantic = NOTIFICATION_SEMANTIC.success,
30
+ iconLeftName,
31
+ iconLeftType = 'regular',
32
+ dismissable,
33
+ children,
34
+ onCloseClick
35
+ } = props;
36
+ return /*#__PURE__*/(0, _jsxRuntime.jss)("div", {
37
+ className: (0, _classify.classify)(_NotificationModule.default.baseContainer, {
38
+ [_NotificationModule.default.success]: semantic === NOTIFICATION_SEMANTIC.success,
39
+ [_NotificationModule.default.information]: semantic === NOTIFICATION_SEMANTIC.information,
40
+ [_NotificationModule.default.danger]: semantic === NOTIFICATION_SEMANTIC.danger
41
+ }, classNames?.wrapper),
42
+ children: [iconLeftName ? /*#__PURE__*/(0, _jsxRuntime.js)(_Icon.Icon, {
43
+ name: iconLeftName,
44
+ color: _typography.TEXT_COLORS.inversePrimary,
45
+ size: "small",
46
+ type: iconLeftType
47
+ }) : null, /*#__PURE__*/(0, _jsxRuntime.js)(_Text.SubTitleSmall, {
48
+ className: (0, _classify.classify)(classNames?.text),
49
+ color: _typography.TEXT_COLORS.inversePrimary,
50
+ children: children
51
+ }), dismissable && /*#__PURE__*/(0, _jsxRuntime.js)(_Icon.Icon, {
52
+ color: _typography.TEXT_COLORS.inversePrimary,
53
+ name: "close",
54
+ size: "small",
55
+ type: "regular",
56
+ onClick: onCloseClick,
57
+ className: _NotificationModule.default.closeIcon
58
+ })]
59
+ });
60
+ };
61
+ const Notification = props => {
62
+ const {
63
+ classNames,
64
+ semantic = NOTIFICATION_SEMANTIC.success,
65
+ iconLeftName,
66
+ iconLeftType,
67
+ dismissable,
68
+ children,
69
+ selfDismiss = false,
70
+ onCloseClick
71
+ } = props;
72
+ const [dismissed, setDismissed] = React.useState(false);
73
+ const closeClickHandler = e => {
74
+ onCloseClick && onCloseClick(e);
75
+ selfDismiss && setDismissed(true);
76
+ };
77
+ return /*#__PURE__*/(0, _jsxRuntime.js)(_jsxRuntime.Fragment, {
78
+ children: !dismissed && /*#__PURE__*/(0, _jsxRuntime.js)(BaseNotification, {
79
+ classNames: classNames,
80
+ iconLeftName: iconLeftName,
81
+ iconLeftType: iconLeftType,
82
+ semantic: semantic,
83
+ dismissable: dismissable,
84
+ onCloseClick: closeClickHandler,
85
+ children: children
86
+ })
87
+ });
88
+ };
89
+ exports.Notification = Notification;
@@ -0,0 +1,136 @@
1
+ // @flow strict
2
+
3
+ import * as React from 'react';
4
+
5
+ import {TEXT_COLORS} from '../../types/typography';
6
+ import {classify} from '../../utils/classify';
7
+ import type {IconType} from '../Icon';
8
+ import {Icon} from '../Icon';
9
+ import {SubTitleSmall} from '../Text';
10
+
11
+ import css from './Notification.module.css';
12
+
13
+
14
+ export const NOTIFICATION_SEMANTIC = Object.freeze({
15
+ success: 'success',
16
+ information: 'information',
17
+ danger: 'danger',
18
+ });
19
+
20
+ type ClassNames = $ReadOnly<{wrapper?: string, text?: string}>;
21
+
22
+ export type NotificationSemanticType = $Values<typeof NOTIFICATION_SEMANTIC>;
23
+
24
+ type BaseNotificationProps = {
25
+ classNames?: ClassNames,
26
+ semantic: NotificationSemanticType,
27
+ iconLeftName?: string,
28
+ iconLeftType?: IconType,
29
+ dismissable?: boolean,
30
+ children?: string,
31
+ onCloseClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
32
+ };
33
+
34
+ // Base Notification will not have any state.
35
+
36
+ const BaseNotification = (props: BaseNotificationProps): React.Node => {
37
+ const {
38
+ classNames,
39
+ semantic = NOTIFICATION_SEMANTIC.success,
40
+ iconLeftName,
41
+ iconLeftType = 'regular',
42
+ dismissable,
43
+ children,
44
+ onCloseClick,
45
+ } = props;
46
+ return (
47
+ <div
48
+ className={classify(
49
+ css.baseContainer,
50
+ {
51
+ [css.success]: semantic === NOTIFICATION_SEMANTIC.success,
52
+ [css.information]: semantic === NOTIFICATION_SEMANTIC.information,
53
+ [css.danger]: semantic === NOTIFICATION_SEMANTIC.danger,
54
+ },
55
+ classNames?.wrapper,
56
+ )}
57
+ >
58
+ {iconLeftName ? (
59
+ <Icon
60
+ name={iconLeftName}
61
+ color={TEXT_COLORS.inversePrimary}
62
+ size="small"
63
+ type={iconLeftType}
64
+ />
65
+ ) : null}
66
+ <SubTitleSmall
67
+ className={classify(classNames?.text)}
68
+ color={TEXT_COLORS.inversePrimary}
69
+ >
70
+ {children}
71
+ </SubTitleSmall>
72
+ {dismissable && (
73
+ <Icon
74
+ color={TEXT_COLORS.inversePrimary}
75
+ name="close"
76
+ size="small"
77
+ type="regular"
78
+ onClick={onCloseClick}
79
+ className={css.closeIcon}
80
+ />
81
+ )}
82
+ </div>
83
+ );
84
+ };
85
+
86
+ type NotificationBaseProps = {
87
+ ...BaseNotificationProps,
88
+ classNames?: ClassNames,
89
+ ...
90
+ | {
91
+ dismissable: true,
92
+ onCloseClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
93
+ selfDismiss?: boolean,
94
+ }
95
+ | {dismissable?: false},
96
+ };
97
+
98
+ export type NotificationProps = {
99
+ ...NotificationBaseProps,
100
+ semantic: NotificationSemanticType,
101
+ };
102
+
103
+ export const Notification = (props: NotificationProps): React.Node => {
104
+ const {
105
+ classNames,
106
+ semantic = NOTIFICATION_SEMANTIC.success,
107
+ iconLeftName,
108
+ iconLeftType,
109
+ dismissable,
110
+ children,
111
+ selfDismiss = false,
112
+ onCloseClick,
113
+ } = props;
114
+ const [dismissed, setDismissed] = React.useState(false);
115
+ const closeClickHandler = (e) => {
116
+ onCloseClick && onCloseClick(e);
117
+ selfDismiss && setDismissed(true);
118
+ };
119
+
120
+ return (
121
+ <>
122
+ {!dismissed && (
123
+ <BaseNotification
124
+ classNames={classNames}
125
+ iconLeftName={iconLeftName}
126
+ iconLeftType={iconLeftType}
127
+ semantic={semantic}
128
+ dismissable={dismissable}
129
+ onCloseClick={closeClickHandler}
130
+ >
131
+ {children}
132
+ </BaseNotification>
133
+ )}
134
+ </>
135
+ );
136
+ };
@@ -0,0 +1,54 @@
1
+ @value (borderRadiusXSmall) from '../../styles/variables/_border.css';
2
+ @value (colorFillPrimary,
3
+ colorTextPrimary,
4
+ colorSuccess,
5
+ colorInformation,
6
+ colorDanger
7
+ ) from '../../styles/variables/_color.css';
8
+
9
+ @value (
10
+ spaceXSmall,
11
+ spaceSmall,
12
+ spaceLarge
13
+ ) from '../../styles/variables/_space.css';
14
+
15
+ @value (
16
+ size34,
17
+ sizeFluid
18
+ ) from '../../styles/variables/_size.css';
19
+
20
+ .baseContainer {
21
+ display: flex;
22
+ flex-direction: row;
23
+ align-items: center;
24
+ justify-content: center;
25
+ gap: spaceXSmall;
26
+ width: sizeFluid;
27
+ min-height: size34;
28
+ position: relative;
29
+ padding: spaceXSmall spaceLarge spaceXSmall spaceSmall;
30
+ word-break: normal;
31
+ overflow-wrap: anywhere;
32
+ }
33
+
34
+ .content {
35
+ display: flex;
36
+ }
37
+
38
+ .success {
39
+ background-color: colorSuccess;
40
+ }
41
+
42
+ .information {
43
+ background-color: colorInformation;
44
+ }
45
+
46
+ .danger {
47
+ background-color: colorDanger;
48
+ }
49
+
50
+ .closeIcon {
51
+ cursor: pointer;
52
+ position: absolute;
53
+ right: spaceSmall;
54
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "NOTIFICATION_SEMANTIC", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _Notification.NOTIFICATION_SEMANTIC;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "Notification", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _Notification.Notification;
16
+ }
17
+ });
18
+ var _Notification = require("./Notification");
@@ -0,0 +1,3 @@
1
+ // @flow strict
2
+
3
+ export {Notification, NOTIFICATION_SEMANTIC} from './Notification';