@livechat/design-system-react-components 1.0.0-alpha.4 → 1.0.0-alpha.7

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 (233) hide show
  1. package/dist/dsrc.cjs.js +1 -0
  2. package/dist/dsrc.es.js +2213 -0
  3. package/dist/dsrc.umd.js +1 -0
  4. package/dist/src/components/Alert/Alert.d.ts +19 -0
  5. package/{src/components/Alert/index.ts → dist/src/components/Alert/index.d.ts} +0 -0
  6. package/dist/src/components/Badge/Badge.d.ts +5 -0
  7. package/{src/components/Badge/index.ts → dist/src/components/Badge/index.d.ts} +0 -0
  8. package/dist/src/components/Button/Button.d.ts +13 -0
  9. package/{src/components/Button/index.ts → dist/src/components/Button/index.d.ts} +0 -0
  10. package/dist/src/components/ButtonGroup/ButtonGroup.d.ts +11 -0
  11. package/{src/components/ButtonGroup/index.ts → dist/src/components/ButtonGroup/index.d.ts} +0 -0
  12. package/dist/src/components/Card/Card.d.ts +6 -0
  13. package/{src/components/Card/index.ts → dist/src/components/Card/index.d.ts} +0 -0
  14. package/dist/src/components/Checkbox/Checkbox.d.ts +7 -0
  15. package/dist/src/components/Checkbox/CheckboxField.d.ts +7 -0
  16. package/{src/components/Checkbox/index.ts → dist/src/components/Checkbox/index.d.ts} +0 -0
  17. package/dist/src/components/FieldDescription/FieldDescription.d.ts +3 -0
  18. package/{src/components/FieldDescription/index.ts → dist/src/components/FieldDescription/index.d.ts} +0 -0
  19. package/dist/src/components/FieldError/FieldError.d.ts +3 -0
  20. package/{src/components/FieldError/index.ts → dist/src/components/FieldError/index.d.ts} +0 -0
  21. package/dist/src/components/FieldGroup/FieldGroup.d.ts +8 -0
  22. package/{src/components/FieldGroup/index.ts → dist/src/components/FieldGroup/index.d.ts} +0 -0
  23. package/dist/src/components/Form/Form.d.ts +7 -0
  24. package/{src/components/Form/index.ts → dist/src/components/Form/index.d.ts} +0 -0
  25. package/dist/src/components/FormGroup/FormGroup.d.ts +7 -0
  26. package/{src/components/FormGroup/index.ts → dist/src/components/FormGroup/index.d.ts} +0 -0
  27. package/dist/src/components/Icon/Icon.d.ts +70 -0
  28. package/{src/components/Icon/index.ts → dist/src/components/Icon/index.d.ts} +0 -0
  29. package/dist/src/components/InputField/InputField.d.ts +15 -0
  30. package/{src/components/InputField/index.ts → dist/src/components/InputField/index.d.ts} +0 -0
  31. package/{src/components/Link/Link.tsx → dist/src/components/Link/Link.d.ts} +3 -26
  32. package/{src/components/Link/index.ts → dist/src/components/Link/index.d.ts} +0 -0
  33. package/dist/src/components/Loader/Loader.d.ts +10 -0
  34. package/{src/components/Loader/index.ts → dist/src/components/Loader/index.d.ts} +0 -0
  35. package/dist/src/components/Modal/ActionModal.d.ts +8 -0
  36. package/dist/src/components/Modal/Modal.d.ts +7 -0
  37. package/dist/src/components/Modal/ModalBase.d.ts +6 -0
  38. package/dist/src/components/Modal/ModalCloseButton.d.ts +3 -0
  39. package/dist/src/components/Modal/ModalPortal.d.ts +7 -0
  40. package/{src/components/Modal/index.ts → dist/src/components/Modal/index.d.ts} +0 -1
  41. package/dist/src/components/NumericInput/NumericInput.d.ts +14 -0
  42. package/dist/src/components/NumericInput/NumericInputField.d.ts +19 -0
  43. package/{src/components/NumericInput/index.ts → dist/src/components/NumericInput/index.d.ts} +0 -0
  44. package/dist/src/components/Popover/Popover.d.ts +15 -0
  45. package/{src/components/Popover/index.ts → dist/src/components/Popover/index.d.ts} +0 -0
  46. package/dist/src/components/Progress/ProgressCircle.d.ts +9 -0
  47. package/dist/src/components/Progress/constants.d.ts +12 -0
  48. package/dist/src/components/Progress/helpers.d.ts +3 -0
  49. package/{src/components/Progress/index.ts → dist/src/components/Progress/index.d.ts} +0 -0
  50. package/dist/src/components/PromoBanner/PromoBanner.d.ts +19 -0
  51. package/{src/components/PromoBanner/index.ts → dist/src/components/PromoBanner/index.d.ts} +0 -0
  52. package/dist/src/components/RadioButton/RadioButton.d.ts +7 -0
  53. package/{src/components/RadioButton/index.ts → dist/src/components/RadioButton/index.d.ts} +0 -0
  54. package/dist/src/components/Switch/Switch.d.ts +20 -0
  55. package/{src/components/Switch/index.ts → dist/src/components/Switch/index.d.ts} +0 -0
  56. package/dist/src/components/Tab/Tab.d.ts +12 -0
  57. package/dist/src/components/Tab/TabsWrapper.d.ts +3 -0
  58. package/{src/components/Tab/index.ts → dist/src/components/Tab/index.d.ts} +0 -0
  59. package/dist/src/components/Tag/Tag.d.ts +12 -0
  60. package/{src/components/Tag/index.ts → dist/src/components/Tag/index.d.ts} +0 -0
  61. package/dist/src/components/TagInput/EditableTag.d.ts +11 -0
  62. package/dist/src/components/TagInput/EditableTagContent.d.ts +11 -0
  63. package/dist/src/components/TagInput/EmailTagInput.d.ts +5 -0
  64. package/dist/src/components/TagInput/TagInput.d.ts +12 -0
  65. package/{src/components/TagInput/index.ts → dist/src/components/TagInput/index.d.ts} +0 -0
  66. package/dist/src/components/TextField/TextField.d.ts +13 -0
  67. package/{src/components/TextField/index.ts → dist/src/components/TextField/index.d.ts} +0 -0
  68. package/dist/src/components/Toast/Toast.d.ts +22 -0
  69. package/dist/src/components/Toast/ToastWrapper.d.ts +27 -0
  70. package/{src/components/Toast/index.ts → dist/src/components/Toast/index.d.ts} +0 -0
  71. package/dist/src/components/Typography/Heading.d.ts +11 -0
  72. package/dist/src/components/Typography/Text.d.ts +15 -0
  73. package/{src/components/Typography/index.ts → dist/src/components/Typography/index.d.ts} +0 -0
  74. package/{src/index.ts → dist/src/index.d.ts} +0 -3
  75. package/dist/src/themes/designTokens.d.ts +126 -0
  76. package/dist/src/utils/keyCodes.d.ts +12 -0
  77. package/dist/src/utils/noop.d.ts +1 -0
  78. package/{src → dist/src}/vite-env.d.ts +0 -0
  79. package/dist/style.css +1 -0
  80. package/{src/themes/dark.scss → dist/themes/dark.css} +2 -0
  81. package/dist/themes/dark.css.map +1 -0
  82. package/{src/themes/legacy.scss → dist/themes/legacy.css} +2 -0
  83. package/dist/themes/legacy.css.map +1 -0
  84. package/{src/themes/light.scss → dist/themes/light.css} +2 -0
  85. package/dist/themes/light.css.map +1 -0
  86. package/package.json +8 -5
  87. package/.eslintrc +0 -9
  88. package/.storybook/main.js +0 -20
  89. package/.storybook/preview-head.html +0 -31
  90. package/.storybook/preview.js +0 -21
  91. package/src/components/Alert/Alert.module.scss +0 -88
  92. package/src/components/Alert/Alert.spec.tsx +0 -78
  93. package/src/components/Alert/Alert.stories.tsx +0 -73
  94. package/src/components/Alert/Alert.tsx +0 -94
  95. package/src/components/Badge/Badge.module.scss +0 -23
  96. package/src/components/Badge/Badge.spec.tsx +0 -12
  97. package/src/components/Badge/Badge.stories.tsx +0 -24
  98. package/src/components/Badge/Badge.tsx +0 -24
  99. package/src/components/Button/Button.module.scss +0 -257
  100. package/src/components/Button/Button.spec.tsx +0 -110
  101. package/src/components/Button/Button.stories.tsx +0 -152
  102. package/src/components/Button/Button.tsx +0 -88
  103. package/src/components/ButtonGroup/ButtonGroup.module.scss +0 -31
  104. package/src/components/ButtonGroup/ButtonGroup.spec.tsx +0 -61
  105. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -53
  106. package/src/components/ButtonGroup/ButtonGroup.tsx +0 -75
  107. package/src/components/Card/Card.module.scss +0 -31
  108. package/src/components/Card/Card.spec.tsx +0 -38
  109. package/src/components/Card/Card.stories.tsx +0 -30
  110. package/src/components/Card/Card.tsx +0 -34
  111. package/src/components/Checkbox/Checkbox.module.scss +0 -99
  112. package/src/components/Checkbox/Checkbox.tsx +0 -39
  113. package/src/components/Checkbox/CheckboxField.spec.tsx +0 -58
  114. package/src/components/Checkbox/CheckboxField.stories.tsx +0 -30
  115. package/src/components/Checkbox/CheckboxField.tsx +0 -46
  116. package/src/components/FieldDescription/FieldDescription.module.scss +0 -5
  117. package/src/components/FieldDescription/FieldDescription.tsx +0 -23
  118. package/src/components/FieldError/FieldError.module.scss +0 -5
  119. package/src/components/FieldError/FieldError.tsx +0 -23
  120. package/src/components/FieldGroup/FieldGroup.module.scss +0 -25
  121. package/src/components/FieldGroup/FieldGroup.spec.tsx +0 -42
  122. package/src/components/FieldGroup/FieldGroup.stories.tsx +0 -34
  123. package/src/components/FieldGroup/FieldGroup.tsx +0 -38
  124. package/src/components/Form/Form.module.scss +0 -22
  125. package/src/components/Form/Form.spec.tsx +0 -38
  126. package/src/components/Form/Form.stories.tsx +0 -42
  127. package/src/components/Form/Form.tsx +0 -46
  128. package/src/components/FormGroup/FormGroup.module.scss +0 -20
  129. package/src/components/FormGroup/FormGroup.spec.tsx +0 -34
  130. package/src/components/FormGroup/FormGroup.stories.tsx +0 -30
  131. package/src/components/FormGroup/FormGroup.tsx +0 -44
  132. package/src/components/Icon/Icon.module.scss +0 -70
  133. package/src/components/Icon/Icon.stories.tsx +0 -53
  134. package/src/components/Icon/Icon.tsx +0 -118
  135. package/src/components/InputField/InputField.module.scss +0 -37
  136. package/src/components/InputField/InputField.spec.tsx +0 -53
  137. package/src/components/InputField/InputField.stories.tsx +0 -73
  138. package/src/components/InputField/InputField.tsx +0 -72
  139. package/src/components/Link/Link.module.scss +0 -18
  140. package/src/components/Link/Link.stories.tsx +0 -17
  141. package/src/components/Loader/Loader.module.scss +0 -66
  142. package/src/components/Loader/Loader.spec.tsx +0 -64
  143. package/src/components/Loader/Loader.stories.tsx +0 -25
  144. package/src/components/Loader/Loader.tsx +0 -48
  145. package/src/components/Modal/ActionModal.tsx +0 -37
  146. package/src/components/Modal/Modal.module.scss +0 -131
  147. package/src/components/Modal/Modal.stories.tsx +0 -85
  148. package/src/components/Modal/Modal.tsx +0 -41
  149. package/src/components/Modal/ModalBase.spec.tsx +0 -58
  150. package/src/components/Modal/ModalBase.tsx +0 -66
  151. package/src/components/Modal/ModalCloseButton.tsx +0 -20
  152. package/src/components/Modal/ModalPortal.tsx +0 -35
  153. package/src/components/NumericInput/NumericInput.module.scss +0 -110
  154. package/src/components/NumericInput/NumericInput.spec.tsx +0 -129
  155. package/src/components/NumericInput/NumericInput.stories.tsx +0 -56
  156. package/src/components/NumericInput/NumericInput.tsx +0 -161
  157. package/src/components/NumericInput/NumericInputField.stories.tsx +0 -58
  158. package/src/components/NumericInput/NumericInputField.tsx +0 -57
  159. package/src/components/Popover/Popover.module.scss +0 -16
  160. package/src/components/Popover/Popover.spec.tsx +0 -39
  161. package/src/components/Popover/Popover.stories.css +0 -23
  162. package/src/components/Popover/Popover.stories.tsx +0 -164
  163. package/src/components/Popover/Popover.tsx +0 -124
  164. package/src/components/Progress/ProgressBar.module.scss +0 -48
  165. package/src/components/Progress/ProgressBar.spec.tsx +0 -33
  166. package/src/components/Progress/ProgressBar.stories.tsx +0 -23
  167. package/src/components/Progress/ProgressBar.tsx +0 -62
  168. package/src/components/Progress/ProgressCircle.module.scss +0 -64
  169. package/src/components/Progress/ProgressCircle.spec.tsx +0 -34
  170. package/src/components/Progress/ProgressCircle.stories.tsx +0 -28
  171. package/src/components/Progress/ProgressCircle.tsx +0 -104
  172. package/src/components/Progress/constants.ts +0 -23
  173. package/src/components/Progress/helpers.ts +0 -23
  174. package/src/components/PromoBanner/PromoBanner.module.scss +0 -121
  175. package/src/components/PromoBanner/PromoBanner.spec.tsx +0 -119
  176. package/src/components/PromoBanner/PromoBanner.stories.tsx +0 -125
  177. package/src/components/PromoBanner/PromoBanner.tsx +0 -99
  178. package/src/components/RadioButton/RadioButton.module.scss +0 -100
  179. package/src/components/RadioButton/RadioButton.spec.tsx +0 -70
  180. package/src/components/RadioButton/RadioButton.stories.tsx +0 -34
  181. package/src/components/RadioButton/RadioButton.tsx +0 -54
  182. package/src/components/Switch/Switch.module.scss +0 -126
  183. package/src/components/Switch/Switch.spec.tsx +0 -40
  184. package/src/components/Switch/Switch.stories.tsx +0 -23
  185. package/src/components/Switch/Switch.tsx +0 -100
  186. package/src/components/Tab/Tab.module.scss +0 -56
  187. package/src/components/Tab/Tab.spec.tsx +0 -34
  188. package/src/components/Tab/Tab.stories.tsx +0 -20
  189. package/src/components/Tab/Tab.tsx +0 -49
  190. package/src/components/Tab/TabsWrapper.module.scss +0 -11
  191. package/src/components/Tab/TabsWrapper.spec.tsx +0 -19
  192. package/src/components/Tab/TabsWrapper.stories.tsx +0 -46
  193. package/src/components/Tab/TabsWrapper.tsx +0 -24
  194. package/src/components/Tag/Tag.module.scss +0 -131
  195. package/src/components/Tag/Tag.spec.tsx +0 -93
  196. package/src/components/Tag/Tag.stories.tsx +0 -151
  197. package/src/components/Tag/Tag.tsx +0 -129
  198. package/src/components/TagInput/EditableTag.tsx +0 -54
  199. package/src/components/TagInput/EditableTagContent.tsx +0 -81
  200. package/src/components/TagInput/EmailTagInput.tsx +0 -31
  201. package/src/components/TagInput/TagInput.module.scss +0 -81
  202. package/src/components/TagInput/TagInput.spec.tsx +0 -58
  203. package/src/components/TagInput/TagInput.stories.tsx +0 -49
  204. package/src/components/TagInput/TagInput.tsx +0 -133
  205. package/src/components/TextField/TextField.module.scss +0 -90
  206. package/src/components/TextField/TextField.spec.tsx +0 -40
  207. package/src/components/TextField/TextField.stories.tsx +0 -60
  208. package/src/components/TextField/TextField.tsx +0 -100
  209. package/src/components/Toast/Toast.module.scss +0 -218
  210. package/src/components/Toast/Toast.spec.tsx +0 -96
  211. package/src/components/Toast/Toast.stories.tsx +0 -64
  212. package/src/components/Toast/Toast.tsx +0 -121
  213. package/src/components/Toast/ToastWrapper.spec.tsx +0 -13
  214. package/src/components/Toast/ToastWrapper.stories.tsx +0 -55
  215. package/src/components/Toast/ToastWrapper.tsx +0 -87
  216. package/src/components/Typography/Heading.tsx +0 -36
  217. package/src/components/Typography/Text.tsx +0 -49
  218. package/src/components/Typography/Typography.module.scss +0 -132
  219. package/src/index.scss +0 -9
  220. package/src/stories/ColorTokens.stories.mdx +0 -10
  221. package/src/stories/Icons.stories.mdx +0 -12
  222. package/src/stories/Typography.stories.mdx +0 -65
  223. package/src/stories/components/ColorTokens.tsx +0 -99
  224. package/src/stories/components/IconsShowcase.tsx +0 -25
  225. package/src/stories/components/iconsShowcase.css +0 -13
  226. package/src/test/setup.ts +0 -1
  227. package/src/test/utils.ts +0 -3
  228. package/src/themes/designTokens.ts +0 -126
  229. package/src/utils/keyCodes.ts +0 -12
  230. package/src/utils/noop.ts +0 -2
  231. package/tsconfig.json +0 -25
  232. package/tsconfig.node.json +0 -8
  233. package/vite.config.ts +0 -44
@@ -1,64 +0,0 @@
1
- import * as React from 'react';
2
- import { render } from 'test-utils';
3
-
4
- import { Loader } from './Loader';
5
- import styles from './Loader.module.scss';
6
-
7
- describe('<Loader> component', () => {
8
- function renderLoader(props = {}) {
9
- const result = render(<Loader {...props} />);
10
- return {
11
- ...result,
12
- loaderEl: result.container.firstChild,
13
- spinnerEl: result.container.querySelector(
14
- `.${styles['loader__spinner']}`
15
- ),
16
- circleEl: result.container.querySelector(
17
- `.${styles['loader__spinner-circle']}`
18
- ),
19
- labelEl: result.container.querySelector(`.${styles['loader__label']}`),
20
- };
21
- }
22
-
23
- it('should have default set of classNames', () => {
24
- const { loaderEl, spinnerEl, circleEl } = renderLoader();
25
-
26
- expect(loaderEl).toHaveClass(styles['loader']);
27
- expect(spinnerEl).toBeVisible();
28
- expect(spinnerEl).toHaveClass(styles['loader__spinner--medium']);
29
- expect(circleEl).toBeVisible();
30
- });
31
-
32
- it('should allow for custom className', () => {
33
- const { loaderEl } = renderLoader({ className: 'my-loader-class' });
34
-
35
- expect(loaderEl).toHaveClass('my-loader-class');
36
- });
37
-
38
- it('should not display "label" by default', () => {
39
- const { labelEl } = renderLoader();
40
-
41
- expect(labelEl).not.toBeInTheDocument();
42
- });
43
-
44
- it('should display label passed via "label" prop', () => {
45
- const { labelEl } = renderLoader({ label: 'my custom label' });
46
-
47
- expect(labelEl).toBeVisible();
48
- expect(labelEl).toHaveTextContent('my custom label');
49
- });
50
-
51
- it('should allow for change colors of loader', () => {
52
- const { circleEl } = renderLoader({
53
- primaryColor: 'red',
54
- secondaryColor: 'blue',
55
- });
56
-
57
- const { borderColor, borderTopColor } = getComputedStyle(
58
- circleEl as HTMLElement
59
- );
60
-
61
- expect(borderColor).toBe('blue');
62
- expect(borderTopColor).toBe('red');
63
- });
64
- });
@@ -1,25 +0,0 @@
1
- import * as React from 'react';
2
- import { ComponentMeta } from '@storybook/react';
3
-
4
- import { Loader, LoaderProps } from './Loader';
5
-
6
- export default {
7
- title: 'Components/Loader',
8
- component: Loader,
9
- } as ComponentMeta<typeof Loader>;
10
-
11
- export const sizes = (): React.ReactElement => (
12
- <div className="spacer">
13
- <Loader size="small" />
14
- <Loader size="medium" />
15
- <Loader size="large"></Loader>
16
- </div>
17
- );
18
-
19
- export const labeled = (args: LoaderProps): React.ReactElement => (
20
- <Loader size="small" label="Loading..." {...args} />
21
- );
22
-
23
- export const customColors = (args: LoaderProps): React.ReactElement => (
24
- <Loader primaryColor="#d64646" secondaryColor="#eec4c5" {...args} />
25
- );
@@ -1,48 +0,0 @@
1
- import * as React from 'react';
2
- import cx from 'clsx';
3
-
4
- import { Text } from '../Typography';
5
-
6
- import styles from './Loader.module.scss';
7
-
8
- const baseClass = 'loader';
9
- const spinnerClass = `${baseClass}__spinner`;
10
-
11
- export interface LoaderProps extends React.HTMLAttributes<HTMLDivElement> {
12
- size?: 'small' | 'medium' | 'large';
13
- label?: string;
14
- /** Fragment circle color */
15
- primaryColor?: string;
16
- /** Main circle color */
17
- secondaryColor?: string;
18
- }
19
-
20
- export const Loader: React.FC<LoaderProps> = ({
21
- primaryColor,
22
- secondaryColor,
23
- label,
24
- className,
25
- size = 'medium',
26
- }) => {
27
- return (
28
- <div className={cx(styles[baseClass], className)}>
29
- <div
30
- className={cx(styles[spinnerClass], styles[`${spinnerClass}--${size}`])}
31
- >
32
- <div
33
- className={styles['loader__spinner-circle']}
34
- style={{
35
- /* stylelint-disable */
36
- borderColor: secondaryColor,
37
- borderTopColor: primaryColor,
38
- }}
39
- />
40
- </div>
41
- {label && (
42
- <Text as="div" size="md" className={styles['loader__label']}>
43
- {label}
44
- </Text>
45
- )}
46
- </div>
47
- );
48
- };
@@ -1,37 +0,0 @@
1
- import * as React from 'react';
2
- import cx from 'clsx';
3
- import { ModalBaseProps, ModalBase } from './ModalBase';
4
-
5
- import styles from './Modal.module.scss';
6
-
7
- export interface ActionModalProps extends ModalBaseProps {
8
- icon?: React.ReactNode;
9
- heading?: React.ReactNode;
10
- actions?: React.ReactNode;
11
- }
12
-
13
- const baseClass = 'action-modal';
14
-
15
- export const ActionModal: React.FC<ActionModalProps> = ({
16
- children,
17
- className = '',
18
- icon,
19
- heading,
20
- actions,
21
- ...props
22
- }) => {
23
- const mergedClassNames = cx(styles[baseClass], className);
24
-
25
- return (
26
- <ModalBase className={mergedClassNames} {...props}>
27
- {icon && <div className={styles[`${baseClass}__icon`]}>{icon}</div>}
28
- {heading && (
29
- <div className={styles[`${baseClass}__heading`]}>{heading}</div>
30
- )}
31
- <div className={styles[`${baseClass}__content`]}>{children}</div>
32
- {actions && (
33
- <div className={styles[`${baseClass}__actions`]}>{actions}</div>
34
- )}
35
- </ModalBase>
36
- );
37
- };
@@ -1,131 +0,0 @@
1
- .modal-base {
2
- background-color: var(--surface-basic-default);
3
- border-radius: 4px;
4
- box-shadow: 0 20px 60px 0 rgba(0, 0, 0, 0.3);
5
- color: var(--content-default);
6
- display: flex;
7
- flex-direction: column;
8
- margin: 10px;
9
- max-width: 800px;
10
- min-width: 400px;
11
- overflow: hidden;
12
- position: relative;
13
-
14
- &__overlay {
15
- align-items: center;
16
- background-color: var(--surface-overlay);
17
- display: none;
18
- height: 100%;
19
- justify-content: center;
20
- left: 0;
21
- position: fixed;
22
- top: 0;
23
- width: 100%;
24
- z-index: 13000;
25
-
26
- &--visible {
27
- display: flex;
28
- }
29
- }
30
-
31
- &__close {
32
- align-items: center;
33
- background-color: transparent;
34
- border-style: none;
35
- box-shadow: none;
36
- color: var(--content-subtle);
37
- cursor: pointer;
38
- display: flex;
39
- height: 24px;
40
- justify-content: center;
41
- outline: none;
42
- padding: 0;
43
- position: absolute;
44
- right: 18px;
45
- top: 18px;
46
- width: 24px;
47
- z-index: 1;
48
-
49
- &:hover {
50
- color: var(--content-default);
51
- }
52
- }
53
- }
54
-
55
- .modal {
56
- &__header {
57
- background-color: var(--surface-basic-default);
58
- box-shadow: inset 0 -1px 0 var(--border-subtle);
59
- box-sizing: border-box;
60
- color: var(--content-default);
61
- padding: 20px;
62
- width: 100%;
63
- }
64
-
65
- &__heading {
66
- color: var(--content-default);
67
- margin: 0;
68
- max-width: calc(100% - 32px);
69
- padding: 0;
70
- text-align: left;
71
- }
72
-
73
- &__body {
74
- background-color: var(--surface-basic-default);
75
- box-sizing: border-box;
76
- color: var(--content-default);
77
- display: flex;
78
- flex-direction: column;
79
- flex-grow: 1;
80
- padding: 20px;
81
- position: relative;
82
- width: 100%;
83
- }
84
-
85
- &__footer {
86
- box-shadow: inset 0 1px 0 var(--border-subtle);
87
- box-sizing: border-box;
88
- display: flex;
89
- flex-shrink: 0;
90
- justify-content: flex-end;
91
- padding: 20px;
92
- width: 100%;
93
- }
94
- }
95
-
96
- .action-modal {
97
- align-items: center;
98
- box-sizing: border-box;
99
- justify-content: center;
100
- padding: 52px 20px;
101
-
102
- &__heading {
103
- color: var(--content-default);
104
- font-size: 24px;
105
- font-weight: 600;
106
- line-height: 1.33;
107
- margin: 0 0 20px;
108
- text-align: center;
109
- width: 100%;
110
- }
111
-
112
- &__content {
113
- color: var(--content-default);
114
- font-size: 15px;
115
- line-height: 1.33;
116
- text-align: center;
117
- width: 100%;
118
- }
119
-
120
- &__actions {
121
- box-sizing: border-box;
122
- display: flex;
123
- justify-content: center;
124
- margin-top: 32px;
125
- width: 100%;
126
- }
127
-
128
- &__icon {
129
- margin-bottom: 20px;
130
- }
131
- }
@@ -1,85 +0,0 @@
1
- import * as React from 'react';
2
- import { ComponentMeta } from '@storybook/react';
3
- import { Error } from '@livechat/design-system-icons/react/material';
4
-
5
- import {
6
- Modal as ModalComponent,
7
- ModalProps,
8
- ActionModal as ActionModalComponent,
9
- ActionModalProps,
10
- ModalPortal as ModalPortalComponent,
11
- ModalPortalProps,
12
- ModalBase,
13
- } from './index';
14
- import { Button } from '../Button';
15
- import { Icon, IconSizeName } from '../Icon';
16
-
17
- export default {
18
- title: 'Components/Modal',
19
- component: ModalComponent,
20
- } as ComponentMeta<typeof ModalComponent>;
21
-
22
- export const Modal = ({
23
- children,
24
- ...args
25
- }: ModalProps): React.ReactElement => (
26
- <ModalComponent {...args}>{children}</ModalComponent>
27
- );
28
-
29
- Modal.args = {
30
- heading: 'Modal',
31
- children: 'Modal content',
32
- closeOnEscPress: true,
33
- style: { width: '600px', height: '400px' },
34
- footer: (
35
- <React.Fragment>
36
- <Button size="medium" kind="secondary" style={{ marginRight: '8px' }}>
37
- Secondary
38
- </Button>
39
- <Button kind="primary" size="medium">
40
- Primary
41
- </Button>
42
- </React.Fragment>
43
- ),
44
- } as ModalProps;
45
-
46
- export const ActionModal = ({
47
- children,
48
- ...args
49
- }: ActionModalProps): React.ReactElement => (
50
- <ActionModalComponent {...args}>{children}</ActionModalComponent>
51
- );
52
-
53
- ActionModal.args = {
54
- heading: 'Danger! Danger!',
55
- style: { width: '410px' },
56
- closeOnEscPress: true,
57
- children:
58
- 'You’re about to do something that cannot be undone. Are you sure you want to continue?',
59
- actions: (
60
- <React.Fragment>
61
- <Button size="medium" kind="secondary" style={{ marginRight: '8px' }}>
62
- Wait, go back
63
- </Button>
64
- <Button kind="destructive" size="medium">
65
- Yes, delete
66
- </Button>
67
- </React.Fragment>
68
- ),
69
- icon: <Icon source={Error} size={IconSizeName.XLarge} />,
70
- } as ActionModalProps;
71
-
72
- export const ModalPortal = ({
73
- children,
74
- ...args
75
- }: ModalPortalProps): React.ReactElement => (
76
- <ModalPortalComponent {...args}>{children}</ModalPortalComponent>
77
- );
78
-
79
- ModalPortal.args = {
80
- children: (
81
- <ModalBase onClose={() => ({})} style={{ width: '600px', height: '400px' }}>
82
- <div style={{ margin: 'auto' }}>Modal Portal content</div>
83
- </ModalBase>
84
- ),
85
- } as ModalPortalProps;
@@ -1,41 +0,0 @@
1
- import * as React from 'react';
2
- import cx from 'clsx';
3
- import { ModalBaseProps, ModalBase } from './ModalBase';
4
- import { Heading } from '../Typography';
5
-
6
- import styles from './Modal.module.scss';
7
-
8
- export interface ModalProps extends ModalBaseProps {
9
- heading?: React.ReactNode;
10
- footer?: React.ReactNode;
11
- }
12
-
13
- const baseClass = 'modal';
14
-
15
- export const Modal: React.FC<ModalProps> = ({
16
- children,
17
- className = '',
18
- heading,
19
- footer,
20
- ...props
21
- }) => {
22
- const mergedClassNames = cx(styles[baseClass], className);
23
-
24
- return (
25
- <ModalBase className={mergedClassNames} {...props}>
26
- {heading && (
27
- <div className={styles[`${baseClass}__header`]}>
28
- <Heading
29
- size="sm"
30
- as="div"
31
- className={styles[`${baseClass}__heading`]}
32
- >
33
- {heading}
34
- </Heading>
35
- </div>
36
- )}
37
- <div className={styles[`${baseClass}__body`]}>{children}</div>
38
- {footer && <div className={styles[`${baseClass}__footer`]}>{footer}</div>}
39
- </ModalBase>
40
- );
41
- };
@@ -1,58 +0,0 @@
1
- import * as React from 'react';
2
- import userEvent from '@testing-library/user-event';
3
- import { render, vi } from 'test-utils';
4
- import { ModalBase } from './ModalBase';
5
-
6
- describe('<ModalBase /> component', () => {
7
- it('should allow for custom class', () => {
8
- const onClose = vi.fn();
9
- const { container } = render(
10
- <ModalBase onClose={onClose} className="my-css-class">
11
- test
12
- </ModalBase>
13
- );
14
- expect(container.firstChild?.firstChild).toHaveClass('my-css-class');
15
- });
16
-
17
- it('should call onClose method on overlay click', () => {
18
- const onClose = vi.fn();
19
- const { queryByTestId } = render(
20
- <ModalBase onClose={onClose}>test</ModalBase>
21
- );
22
-
23
- const overlay = queryByTestId('lc-modal-overlay');
24
-
25
- if (overlay) {
26
- userEvent.click(overlay);
27
- }
28
- expect(onClose).toBeCalledTimes(1);
29
- });
30
-
31
- it('should call onClose method on close modal button press', () => {
32
- const onClose = vi.fn();
33
- const { getByRole } = render(<ModalBase onClose={onClose}>test</ModalBase>);
34
-
35
- userEvent.click(getByRole('button'));
36
- expect(onClose).toBeCalledTimes(1);
37
- });
38
-
39
- it('should call onClose on escape button pressed by default', () => {
40
- const onClose = vi.fn();
41
- render(<ModalBase onClose={onClose}>test</ModalBase>);
42
-
43
- userEvent.keyboard('[Escape]');
44
- expect(onClose).toBeCalledTimes(1);
45
- });
46
-
47
- it('should not call onClose on escape button pressed when closeOnEscPress is disabled', () => {
48
- const onClose = vi.fn();
49
- render(
50
- <ModalBase onClose={onClose} closeOnEscPress={false}>
51
- test
52
- </ModalBase>
53
- );
54
-
55
- userEvent.keyboard('[Escape]');
56
- expect(onClose).not.toBeCalled();
57
- });
58
- });
@@ -1,66 +0,0 @@
1
- import * as React from 'react';
2
- import cx from 'clsx';
3
- import { ModalCloseButton } from './ModalCloseButton';
4
- import { KeyCodes } from '../../utils/keyCodes';
5
-
6
- import styles from './Modal.module.scss';
7
-
8
- export interface ModalBaseProps extends React.HTMLAttributes<HTMLDivElement> {
9
- onClose(): void;
10
- closeOnEscPress?: boolean;
11
- }
12
-
13
- const baseClass = 'modal-base';
14
-
15
- export const ModalBase: React.FC<ModalBaseProps> = ({
16
- children,
17
- className = '',
18
- onClose,
19
- closeOnEscPress = true,
20
- ...props
21
- }) => {
22
- const mergedClassNames = cx(styles[baseClass], className);
23
-
24
- React.useEffect(() => {
25
- if (!closeOnEscPress) {
26
- return;
27
- }
28
-
29
- const onKeyUp = (event: KeyboardEvent) => {
30
- if (event.key === KeyCodes.esc) {
31
- onClose();
32
- }
33
- };
34
-
35
- document.addEventListener('keyup', onKeyUp, true);
36
- return () => document.removeEventListener('keyup', onKeyUp, true);
37
- }, [closeOnEscPress]);
38
-
39
- const onOverlayClick = (event: React.MouseEvent<HTMLDivElement>) => {
40
- if (event.target === event.currentTarget) {
41
- onClose();
42
- }
43
- };
44
-
45
- const onCloseButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
46
- event.preventDefault();
47
- event.stopPropagation();
48
- onClose();
49
- };
50
-
51
- return (
52
- <div
53
- data-testid="lc-modal-overlay"
54
- onMouseDown={onOverlayClick}
55
- className={cx(
56
- styles[`${baseClass}__overlay`],
57
- styles[`${baseClass}__overlay--visible`]
58
- )}
59
- >
60
- <div className={mergedClassNames} {...props}>
61
- <ModalCloseButton onClick={onCloseButtonClick} />
62
- {children}
63
- </div>
64
- </div>
65
- );
66
- };
@@ -1,20 +0,0 @@
1
- import * as React from 'react';
2
- import { Close } from '@livechat/design-system-icons/react/material';
3
- import { Icon, IconSizeName } from '../Icon';
4
-
5
- import styles from './Modal.module.scss';
6
-
7
- export type ModalCloseButtonProps = React.HTMLAttributes<HTMLButtonElement>;
8
-
9
- export const ModalCloseButton: React.FC<ModalCloseButtonProps> = ({
10
- onClick,
11
- }) => (
12
- <button
13
- title="Close modal"
14
- className={styles['modal-base__close']}
15
- onClick={onClick}
16
- type="button"
17
- >
18
- <Icon source={Close} size={IconSizeName.Large} />
19
- </button>
20
- );
@@ -1,35 +0,0 @@
1
- import * as React from 'react';
2
- import * as ReactDOM from 'react-dom';
3
-
4
- export interface ModalPortalProps extends React.HTMLAttributes<HTMLDivElement> {
5
- children: React.ReactNode;
6
- zIndex: number;
7
- parentElementName: string;
8
- }
9
-
10
- export const ModalPortal: React.FC<ModalPortalProps> = ({
11
- children,
12
- className = '',
13
- parentElementName = 'body',
14
- zIndex,
15
- }) => {
16
- const [container] = React.useState(() => document.createElement('div'));
17
-
18
- if (className) {
19
- container.classList.add(className);
20
- }
21
-
22
- if (zIndex) {
23
- container.style.zIndex = zIndex.toString();
24
- }
25
-
26
- React.useEffect(() => {
27
- document.querySelector(parentElementName)?.appendChild(container);
28
- return () => {
29
- document.querySelector(parentElementName)?.removeChild(container);
30
- };
31
- }, []);
32
-
33
- // Fragment added to fix TS complaining about createPortal any type
34
- return <>{ReactDOM.createPortal(children, container)}</>;
35
- };