@marigold/components 0.0.1 → 0.2.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 (194) hide show
  1. package/dist/ActionGroup/ActionGroup.d.ts +9 -0
  2. package/dist/ActionGroup/index.d.ts +1 -0
  3. package/dist/Alert/Alert.d.ts +20 -2
  4. package/dist/Badge/Badge.d.ts +8 -0
  5. package/dist/Badge/index.d.ts +1 -0
  6. package/dist/Box/Box.d.ts +47 -0
  7. package/dist/Box/index.d.ts +1 -0
  8. package/dist/Button/Button.d.ts +4 -3
  9. package/dist/Card/Card.d.ts +9 -0
  10. package/dist/Card/index.d.ts +1 -0
  11. package/dist/Checkbox/Checkbox.d.ts +14 -2
  12. package/dist/Checkbox/CheckboxIcons.d.ts +9 -0
  13. package/dist/Column/Column.d.ts +8 -0
  14. package/dist/Column/index.d.ts +1 -0
  15. package/dist/Columns/Columns.d.ts +10 -0
  16. package/dist/Columns/index.d.ts +1 -0
  17. package/dist/Container/Container.d.ts +6 -0
  18. package/dist/Container/index.d.ts +1 -0
  19. package/dist/Dialog/Dialog.d.ts +14 -0
  20. package/dist/Dialog/ModalDialog.d.ts +5 -0
  21. package/dist/Dialog/index.d.ts +1 -0
  22. package/dist/Divider/Divider.d.ts +7 -0
  23. package/dist/Divider/index.d.ts +1 -0
  24. package/dist/Field/Field.d.ts +11 -0
  25. package/dist/Field/index.d.ts +1 -0
  26. package/dist/Heading/Heading.d.ts +7 -5
  27. package/dist/Hidden/Hidden.d.ts +5 -0
  28. package/dist/Hidden/index.d.ts +1 -0
  29. package/dist/Image/Image.d.ts +7 -0
  30. package/dist/Image/index.d.ts +1 -0
  31. package/dist/Input/Input.d.ts +6 -0
  32. package/dist/Input/index.d.ts +1 -0
  33. package/dist/Label/Label.d.ts +8 -5
  34. package/dist/Link/Link.d.ts +7 -3
  35. package/dist/Menu/Menu.d.ts +12 -0
  36. package/dist/Menu/index.d.ts +1 -0
  37. package/dist/MenuItem/MenuItem.d.ts +7 -0
  38. package/dist/MenuItem/index.d.ts +1 -0
  39. package/dist/Message/Message.d.ts +7 -0
  40. package/dist/Message/index.d.ts +1 -0
  41. package/dist/Provider/MarigoldProvider.d.ts +3 -0
  42. package/dist/Provider/index.d.ts +3 -0
  43. package/dist/Radio/Radio.d.ts +14 -2
  44. package/dist/Radio/RadioIcons.d.ts +9 -0
  45. package/dist/Select/ListBox.d.ts +8 -0
  46. package/dist/Select/ListBoxSection.d.ts +8 -0
  47. package/dist/Select/Option.d.ts +8 -0
  48. package/dist/Select/Popover.d.ts +9 -0
  49. package/dist/Select/Select.d.ts +13 -3
  50. package/dist/Slider/Slider.d.ts +6 -3
  51. package/dist/Stack/Stack.d.ts +7 -0
  52. package/dist/Stack/index.d.ts +1 -0
  53. package/dist/Text/Text.d.ts +12 -3
  54. package/dist/Textarea/Textarea.d.ts +11 -3
  55. package/dist/ValidationMessage/ValidationMessage.d.ts +6 -0
  56. package/dist/ValidationMessage/index.d.ts +1 -0
  57. package/dist/components.cjs.development.js +1308 -195
  58. package/dist/components.cjs.development.js.map +1 -1
  59. package/dist/components.cjs.production.min.js +1 -1
  60. package/dist/components.cjs.production.min.js.map +1 -1
  61. package/dist/components.esm.js +1267 -185
  62. package/dist/components.esm.js.map +1 -1
  63. package/dist/index.d.ts +21 -4
  64. package/dist/theme.d.ts +24 -4
  65. package/package.json +24 -4
  66. package/src/ActionGroup/ActionGroup.stories.mdx +62 -0
  67. package/src/ActionGroup/ActionGroup.test.tsx +83 -0
  68. package/src/ActionGroup/ActionGroup.tsx +43 -0
  69. package/src/ActionGroup/index.ts +1 -0
  70. package/src/Alert/Alert.stories.mdx +30 -42
  71. package/src/Alert/Alert.test.tsx +37 -22
  72. package/src/Alert/Alert.tsx +31 -21
  73. package/src/Badge/Badge.stories.mdx +57 -0
  74. package/src/Badge/Badge.test.tsx +61 -0
  75. package/src/Badge/Badge.tsx +25 -0
  76. package/src/Badge/index.ts +1 -0
  77. package/src/Box/Box.stories.mdx +334 -0
  78. package/src/Box/Box.test.tsx +133 -0
  79. package/src/Box/Box.tsx +165 -0
  80. package/src/Box/index.ts +1 -0
  81. package/src/Button/Button.stories.mdx +58 -134
  82. package/src/Button/Button.test.tsx +65 -23
  83. package/src/Button/Button.tsx +48 -14
  84. package/src/Card/Card.stories.mdx +49 -0
  85. package/src/Card/Card.test.tsx +66 -0
  86. package/src/Card/Card.tsx +36 -0
  87. package/src/Card/index.ts +1 -0
  88. package/src/Checkbox/Checkbox.stories.mdx +79 -101
  89. package/src/Checkbox/Checkbox.test.tsx +73 -32
  90. package/src/Checkbox/Checkbox.tsx +114 -35
  91. package/src/Checkbox/CheckboxIcons.tsx +49 -0
  92. package/src/Column/Column.stories.mdx +49 -0
  93. package/src/Column/Column.test.tsx +32 -0
  94. package/src/Column/Column.tsx +27 -0
  95. package/src/Column/index.ts +1 -0
  96. package/src/Columns/Columns.stories.mdx +65 -0
  97. package/src/Columns/Columns.test.tsx +102 -0
  98. package/src/Columns/Columns.tsx +69 -0
  99. package/src/Columns/index.ts +1 -0
  100. package/src/Container/Container.stories.mdx +19 -0
  101. package/src/Container/Container.test.tsx +26 -0
  102. package/src/Container/Container.tsx +13 -0
  103. package/src/Container/index.ts +1 -0
  104. package/src/Dialog/Dialog.stories.mdx +73 -0
  105. package/src/Dialog/Dialog.test.tsx +87 -0
  106. package/src/Dialog/Dialog.tsx +84 -0
  107. package/src/Dialog/ModalDialog.tsx +47 -0
  108. package/src/Dialog/index.ts +1 -0
  109. package/src/Divider/Divider.stories.mdx +37 -0
  110. package/src/Divider/Divider.test.tsx +63 -0
  111. package/src/Divider/Divider.tsx +13 -0
  112. package/src/Divider/index.ts +1 -0
  113. package/src/Field/Field.stories.mdx +97 -0
  114. package/src/Field/Field.test.tsx +80 -0
  115. package/src/Field/Field.tsx +54 -0
  116. package/src/Field/index.ts +1 -0
  117. package/src/Heading/Heading.stories.mdx +36 -76
  118. package/src/Heading/Heading.test.tsx +31 -17
  119. package/src/Heading/Heading.tsx +15 -12
  120. package/src/Hidden/Hidden.stories.mdx +39 -0
  121. package/src/Hidden/Hidden.test.tsx +24 -0
  122. package/src/Hidden/Hidden.tsx +16 -0
  123. package/src/Hidden/index.ts +1 -0
  124. package/src/Image/Image.stories.mdx +36 -0
  125. package/src/Image/Image.test.tsx +70 -0
  126. package/src/Image/Image.tsx +13 -0
  127. package/src/Image/index.ts +1 -0
  128. package/src/Input/Input.stories.mdx +61 -0
  129. package/src/Input/Input.test.tsx +70 -0
  130. package/src/Input/Input.tsx +13 -0
  131. package/src/Input/index.ts +1 -0
  132. package/src/Label/Label.stories.mdx +50 -34
  133. package/src/Label/Label.test.tsx +45 -16
  134. package/src/Label/Label.tsx +26 -17
  135. package/src/Link/Link.stories.mdx +40 -31
  136. package/src/Link/Link.test.tsx +53 -28
  137. package/src/Link/Link.tsx +32 -14
  138. package/src/Menu/Menu.stories.mdx +81 -0
  139. package/src/Menu/Menu.test.tsx +79 -0
  140. package/src/Menu/Menu.tsx +41 -0
  141. package/src/Menu/index.ts +1 -0
  142. package/src/MenuItem/MenuItem.stories.mdx +37 -0
  143. package/src/MenuItem/MenuItem.test.tsx +63 -0
  144. package/src/MenuItem/MenuItem.tsx +23 -0
  145. package/src/MenuItem/index.ts +1 -0
  146. package/src/Message/Message.stories.mdx +44 -0
  147. package/src/Message/Message.test.tsx +87 -0
  148. package/src/Message/Message.tsx +43 -0
  149. package/src/Message/index.ts +1 -0
  150. package/src/Provider/MarigoldProvider.test.tsx +126 -0
  151. package/src/Provider/MarigoldProvider.tsx +29 -0
  152. package/src/Provider/index.ts +3 -0
  153. package/src/Radio/Radio.stories.mdx +80 -83
  154. package/src/Radio/Radio.test.tsx +63 -22
  155. package/src/Radio/Radio.tsx +110 -35
  156. package/src/Radio/RadioIcons.tsx +39 -0
  157. package/src/Select/ListBox.tsx +39 -0
  158. package/src/Select/ListBoxSection.tsx +40 -0
  159. package/src/Select/Option.tsx +48 -0
  160. package/src/Select/Popover.tsx +50 -0
  161. package/src/Select/Select.stories.mdx +72 -37
  162. package/src/Select/Select.test.tsx +271 -28
  163. package/src/Select/Select.tsx +158 -23
  164. package/src/Slider/Slider.stories.mdx +26 -54
  165. package/src/Slider/Slider.test.tsx +13 -13
  166. package/src/Slider/Slider.tsx +20 -18
  167. package/src/Stack/Stack.stories.mdx +51 -0
  168. package/src/Stack/Stack.test.tsx +129 -0
  169. package/src/Stack/Stack.tsx +39 -0
  170. package/src/Stack/index.ts +1 -0
  171. package/src/Text/Text.stories.mdx +53 -47
  172. package/src/Text/Text.test.tsx +55 -15
  173. package/src/Text/Text.tsx +44 -10
  174. package/src/Textarea/Textarea.stories.mdx +68 -21
  175. package/src/Textarea/Textarea.test.tsx +47 -16
  176. package/src/Textarea/Textarea.tsx +46 -14
  177. package/src/ValidationMessage/ValidationMessage.stories.mdx +36 -0
  178. package/src/ValidationMessage/ValidationMessage.test.tsx +63 -0
  179. package/src/ValidationMessage/ValidationMessage.tsx +28 -0
  180. package/src/ValidationMessage/index.ts +1 -0
  181. package/src/index.ts +22 -4
  182. package/src/theme.ts +24 -4
  183. package/dist/Svg/Svg.d.ts +0 -5
  184. package/dist/Svg/index.d.ts +0 -1
  185. package/dist/TextInput/TextInput.d.ts +0 -3
  186. package/dist/TextInput/index.d.ts +0 -1
  187. package/src/Svg/Svg.stories.mdx +0 -47
  188. package/src/Svg/Svg.test.tsx +0 -58
  189. package/src/Svg/Svg.tsx +0 -25
  190. package/src/Svg/index.ts +0 -1
  191. package/src/TextInput/TextInput.stories.mdx +0 -37
  192. package/src/TextInput/TextInput.test.tsx +0 -71
  193. package/src/TextInput/TextInput.tsx +0 -21
  194. package/src/TextInput/index.ts +0 -1
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import { SVG } from '@marigold/icons';
3
+
4
+ import { Box } from '../Box';
5
+
6
+ export const CheckboxChecked = ({ disabled = false, ...props }) => (
7
+ <SVG width="16" height="32" viewBox="0 0 16 32" fill="none" {...props}>
8
+ <Box
9
+ as="rect"
10
+ x="0.5"
11
+ y="8.5"
12
+ width="15px"
13
+ height="15px"
14
+ rx="1.5"
15
+ variant={disabled ? 'checkbox.checked.disabled' : 'checkbox.checked'}
16
+ />
17
+ <Box
18
+ as="path"
19
+ fillRule="evenodd"
20
+ clipRule="evenodd"
21
+ d="M13.9571 12.8338L12.4085 11.2852L6.08699 17.6007L3.59887 15.1126L2.04163 16.6588L6.08682 20.704L13.9571 12.8338Z"
22
+ variant="checkbox.checked.icon"
23
+ />
24
+ </SVG>
25
+ );
26
+
27
+ export const CheckboxUnchecked = ({
28
+ disabled = false,
29
+ error = false,
30
+ ...props
31
+ }) => (
32
+ <SVG width="16" height="32" viewBox="0 0 16 32" fill="none" {...props}>
33
+ <Box
34
+ as="rect"
35
+ x="0.5"
36
+ y="8.5"
37
+ width="15px"
38
+ height="15px"
39
+ rx="1.5"
40
+ variant={
41
+ disabled
42
+ ? 'checkbox.unchecked.disabled'
43
+ : error
44
+ ? 'checkbox.unchecked.error'
45
+ : 'checkbox.unchecked'
46
+ }
47
+ />
48
+ </SVG>
49
+ );
@@ -0,0 +1,49 @@
1
+ import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
2
+ import { Column } from './Column';
3
+ import { Text } from '../Text';
4
+ import { useStyles } from '@marigold/system';
5
+
6
+ <Meta
7
+ title="Components/Column"
8
+ argTypes={{
9
+ width: {
10
+ control: {
11
+ type: 'range',
12
+ min: 0,
13
+ max: 12,
14
+ step: 1,
15
+ },
16
+ description: 'Absolute width in 12 grid',
17
+ table: {
18
+ defaultValue: {
19
+ summary: 12,
20
+ },
21
+ },
22
+ },
23
+ }}
24
+ />
25
+
26
+ # Column
27
+
28
+ export const Template = args => (
29
+ <Column
30
+ className={useStyles({
31
+ css: {
32
+ textAlign: 'center',
33
+ border: '1px solid red',
34
+ padding: 2,
35
+ margin: 2,
36
+ },
37
+ })}
38
+ width={12}
39
+ {...args}
40
+ >
41
+ <Text>full width</Text>
42
+ </Column>
43
+ );
44
+
45
+ <Canvas>
46
+ <Story name="Default">{Template.bind({})}</Story>
47
+ </Canvas>
48
+
49
+ <ArgsTable story="Default" />
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { Column } from './Column';
4
+
5
+ test('supports width prop', () => {
6
+ render(<Column width={6}>column</Column>);
7
+ const column = screen.getByText('column');
8
+
9
+ expect(column).toHaveStyle(`width: 50%`);
10
+ });
11
+
12
+ test('renders correct HTML element', () => {
13
+ render(<Column>column</Column>);
14
+ const column = screen.getByText('column');
15
+
16
+ expect(column instanceof HTMLDivElement).toBeTruthy();
17
+ });
18
+
19
+ test('accepts custom styles prop className', () => {
20
+ render(<Column className="custom-class-name">column</Column>);
21
+ const column = screen.getByText('column');
22
+
23
+ expect(column.className).toMatch('custom-class-name');
24
+ });
25
+
26
+ test('accepts responsive values', () => {
27
+ render(<Column width={[12, 6]}>column</Column>);
28
+ const column = screen.getByText('column');
29
+
30
+ // Note: as of November 2021 jest-dom does not support media queries...
31
+ expect(column).toHaveStyle('width: 100%');
32
+ });
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { Box } from '../Box';
3
+
4
+ type WidthValues = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
5
+
6
+ export type ColumnProps = {
7
+ className?: string;
8
+ width?: WidthValues | WidthValues[];
9
+ };
10
+
11
+ const transform = (width: WidthValues | WidthValues[]) => {
12
+ if (Array.isArray(width)) {
13
+ return width.map(v => `${(v / 12) * 100}%`);
14
+ }
15
+
16
+ return `${(width / 12) * 100}%`;
17
+ };
18
+
19
+ export const Column: React.FC<ColumnProps> = ({
20
+ width = 12,
21
+ children,
22
+ ...props
23
+ }) => (
24
+ <Box {...props} width={transform(width)}>
25
+ {children}
26
+ </Box>
27
+ );
@@ -0,0 +1 @@
1
+ export * from './Column';
@@ -0,0 +1,65 @@
1
+ import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
2
+ import { Column, Columns, Text } from '@marigold/components';
3
+
4
+ <Meta
5
+ title="Components/Columns"
6
+ argTypes={{
7
+ space: {
8
+ control: {
9
+ type: 'range',
10
+ min: 0,
11
+ max: 96,
12
+ step: 2,
13
+ },
14
+ description: 'Absolute space value',
15
+ table: {
16
+ defaultValue: {
17
+ summary: 0,
18
+ },
19
+ },
20
+ },
21
+ horizontalAlign: {
22
+ control: {
23
+ type: 'select',
24
+ },
25
+ options: ['left', 'right', 'center'],
26
+ description: 'where to place',
27
+ table: {
28
+ defaultValue: {
29
+ summary: 'left',
30
+ },
31
+ },
32
+ },
33
+ verticalAlign: {
34
+ control: {
35
+ type: 'select',
36
+ },
37
+ options: ['top', 'bottom', 'center'],
38
+ description: 'where to place',
39
+ table: {
40
+ defaultValue: {
41
+ summary: 'top',
42
+ },
43
+ },
44
+ },
45
+ }}
46
+ />
47
+
48
+ # Columns
49
+
50
+ export const Template = args => (
51
+ <Columns {...args}>
52
+ <Column width={6}>
53
+ <Text>First column</Text>
54
+ </Column>
55
+ <Column width={6}>
56
+ <Text>Second column</Text>
57
+ </Column>
58
+ </Columns>
59
+ );
60
+
61
+ <Canvas>
62
+ <Story name="Default">{Template.bind({})}</Story>
63
+ </Canvas>
64
+
65
+ <ArgsTable story="Default" />
@@ -0,0 +1,102 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { Column, Columns } from '@marigold/components';
4
+
5
+ test('supports default space prop', () => {
6
+ render(
7
+ <Columns title="column">
8
+ <Column>column</Column>
9
+ </Columns>
10
+ );
11
+ const column = screen.getByTitle(/column/);
12
+
13
+ expect(column).toHaveStyle(`margin: 0px`);
14
+ });
15
+
16
+ test('supports custom space prop', () => {
17
+ render(
18
+ <Columns space={24} title="column">
19
+ <Column>column</Column>
20
+ </Columns>
21
+ );
22
+ const column = screen.getByTitle(/column/);
23
+
24
+ expect(column).toHaveStyle(`margin: -12px`);
25
+ });
26
+
27
+ test('supports default horizontalAlign prop: left', () => {
28
+ render(
29
+ <Columns title="column">
30
+ <Column>column</Column>
31
+ </Columns>
32
+ );
33
+ const column = screen.getByTitle(/column/);
34
+
35
+ expect(column).toHaveStyle(`justify-content: flex-start`);
36
+ });
37
+
38
+ test('supports custom horizontalAlign prop: center', () => {
39
+ render(
40
+ <Columns horizontalAlign="center" title="column">
41
+ <Column>column</Column>
42
+ </Columns>
43
+ );
44
+ const column = screen.getByTitle(/column/);
45
+
46
+ expect(column).toHaveStyle(`justify-content: center`);
47
+ });
48
+
49
+ test('supports custom horizontalAlign prop: right', () => {
50
+ render(
51
+ <Columns horizontalAlign="right" title="column">
52
+ <Column>column</Column>
53
+ </Columns>
54
+ );
55
+ const column = screen.getByTitle(/column/);
56
+
57
+ expect(column).toHaveStyle(`justify-content: flex-end`);
58
+ });
59
+
60
+ test('supports default verticalAlign prop: top', () => {
61
+ render(
62
+ <Columns title="column">
63
+ <Column>column</Column>
64
+ </Columns>
65
+ );
66
+ const column = screen.getByTitle(/column/);
67
+
68
+ expect(column).toHaveStyle(`align-items: flex-start`);
69
+ });
70
+
71
+ test('supports custom verticalAlign prop: center', () => {
72
+ render(
73
+ <Columns verticalAlign="center" title="column">
74
+ <Column>column</Column>
75
+ </Columns>
76
+ );
77
+ const column = screen.getByTitle(/column/);
78
+
79
+ expect(column).toHaveStyle(`align-items: center`);
80
+ });
81
+
82
+ test('supports custom verticalAlign prop: bottom', () => {
83
+ render(
84
+ <Columns verticalAlign="bottom" title="column">
85
+ <Column>column</Column>
86
+ </Columns>
87
+ );
88
+ const column = screen.getByTitle(/column/);
89
+
90
+ expect(column).toHaveStyle(`align-items: flex-end`);
91
+ });
92
+
93
+ test('renders correct HTML element', () => {
94
+ render(
95
+ <Columns title="column">
96
+ <Column>column</Column>
97
+ </Columns>
98
+ );
99
+ const column = screen.getByTitle(/column/);
100
+
101
+ expect(column instanceof HTMLDivElement).toBeTruthy();
102
+ });
@@ -0,0 +1,69 @@
1
+ import React, { Children } from 'react';
2
+ import { useStyles } from '@marigold/system';
3
+ import { Box } from '../Box';
4
+ import flattenChildren from 'react-keyed-flatten-children';
5
+
6
+ type ColumnsProps = {
7
+ className?: string;
8
+ space?: number;
9
+ horizontalAlign?: 'left' | 'right' | 'center';
10
+ verticalAlign?: 'top' | 'bottom' | 'center';
11
+ title?: string; // Should only be used for testing.
12
+ };
13
+
14
+ export const Columns: React.FC<ColumnsProps> = ({
15
+ space = 0,
16
+ horizontalAlign = 'left',
17
+ verticalAlign = 'top',
18
+ className,
19
+ children,
20
+ ...props
21
+ }) => {
22
+ let columnItems = flattenChildren(children);
23
+ let childClassNames = useStyles({ css: { p: `${space / 2}px` } });
24
+
25
+ // horizontal Alignment
26
+ let justify = 'flex-start';
27
+ if (horizontalAlign === 'right') {
28
+ justify = 'flex-end';
29
+ } else if (horizontalAlign === 'center') {
30
+ justify = 'center';
31
+ }
32
+
33
+ // vertical Alignment
34
+ let alignItems = 'flex-start';
35
+ if (verticalAlign === 'bottom') {
36
+ alignItems = 'flex-end';
37
+ } else if (verticalAlign === 'center') {
38
+ alignItems = 'center';
39
+ }
40
+
41
+ return (
42
+ <Box p={`${space}px`} display="flex" className={className}>
43
+ <Box
44
+ width={`calc(100% + ${space}px)`}
45
+ m={`${-space / 2}px`}
46
+ display="flex"
47
+ flexWrap="wrap"
48
+ alignItems={alignItems}
49
+ justifyContent={justify}
50
+ {...props}
51
+ >
52
+ {Children.map(
53
+ columnItems as unknown as React.ReactElement,
54
+ (child: React.ReactElement) => {
55
+ return React.cloneElement(
56
+ child,
57
+ {
58
+ className: childClassNames,
59
+ },
60
+ <Box className={child && child.props.className}>
61
+ {child.props.children}
62
+ </Box>
63
+ );
64
+ }
65
+ )}
66
+ </Box>
67
+ </Box>
68
+ );
69
+ };
@@ -0,0 +1 @@
1
+ export * from './Columns';
@@ -0,0 +1,19 @@
1
+ import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
2
+ import { Container } from './Container';
3
+ import { Text } from '../Text';
4
+
5
+ <Meta title="Components/Container" />
6
+
7
+ # Container
8
+
9
+ export const Template = args => (
10
+ <Container {...args}>
11
+ <Text>Container with width=100%</Text>
12
+ </Container>
13
+ );
14
+
15
+ <Canvas>
16
+ <Story name="Default">{Template.bind({})}</Story>
17
+ </Canvas>
18
+
19
+ <ArgsTable story="Default" />
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { Container } from './Container';
4
+ import { Text } from '../Text';
5
+
6
+ test('renders correct HTML element', () => {
7
+ render(
8
+ <Container title="container">
9
+ <Text>sdf</Text>
10
+ </Container>
11
+ );
12
+ const container = screen.getByTitle(/container/);
13
+
14
+ expect(container instanceof HTMLDivElement).toBeTruthy();
15
+ });
16
+
17
+ test('accepts custom styles prop className', () => {
18
+ render(
19
+ <Container className="custom-class-name" title="container">
20
+ <Text>text</Text>
21
+ </Container>
22
+ );
23
+ const container = screen.getByTitle(/container/);
24
+
25
+ expect(container.className).toMatch('custom-class-name');
26
+ });
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { Box } from '../Box';
3
+
4
+ export type ContainerProps = {
5
+ className?: string;
6
+ title?: string; // Used for testing.
7
+ };
8
+
9
+ export const Container: React.FC<ContainerProps> = ({ children, ...props }) => (
10
+ <Box {...props} width="100%">
11
+ {children}
12
+ </Box>
13
+ );
@@ -0,0 +1 @@
1
+ export * from './Container';
@@ -0,0 +1,73 @@
1
+ import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
2
+ import { Dialog, useDialogButtonProps } from './Dialog';
3
+ import { Button } from '../Button';
4
+ import { Text } from '../Text';
5
+
6
+ <Meta
7
+ title="Components/Dialog"
8
+ parameters={{
9
+ actions: {
10
+ handles: ['click'],
11
+ },
12
+ }}
13
+ argTypes={{
14
+ isOpen: {
15
+ control: {
16
+ type: 'boolean',
17
+ },
18
+ description: 'handled by state from useDialogButtonProps',
19
+ options: [true, false],
20
+ table: {
21
+ defaultValue: {
22
+ summary: false,
23
+ },
24
+ },
25
+ },
26
+ title: {
27
+ control: {
28
+ type: 'text',
29
+ },
30
+ description: 'set dialog title',
31
+ },
32
+ close: {
33
+ control: {
34
+ type: 'text',
35
+ },
36
+ description: 'handled by state from useDialogButtonProps',
37
+ },
38
+ }}
39
+ />
40
+
41
+ # Dialog
42
+
43
+ export const Template = ({ ...args }) => {
44
+ const { state, openButtonProps, openButtonRef } = useDialogButtonProps();
45
+ return (
46
+ <>
47
+ <Button
48
+ variant="secondary"
49
+ size="small"
50
+ {...openButtonProps}
51
+ ref={openButtonRef}
52
+ >
53
+ Open Dialog
54
+ </Button>
55
+ {state.isOpen && (
56
+ <Dialog
57
+ title="Dialog Title"
58
+ isOpen={state.isOpen}
59
+ close={state.close}
60
+ {...args}
61
+ >
62
+ <Text>Dialog content</Text>
63
+ </Dialog>
64
+ )}
65
+ </>
66
+ );
67
+ };
68
+
69
+ <Canvas>
70
+ <Story name="Default">{Template.bind({})}</Story>
71
+ </Canvas>
72
+
73
+ <ArgsTable story="Default" />
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { ThemeProvider } from '@marigold/system';
5
+ import { Dialog, useDialogButtonProps } from './Dialog';
6
+ import { Button } from '../Button';
7
+
8
+ const theme = {
9
+ dialog: {
10
+ wrapper: {
11
+ p: '8px',
12
+ },
13
+ body: {
14
+ p: '4px',
15
+ },
16
+ onClose: {
17
+ p: '0px',
18
+ },
19
+ },
20
+ };
21
+
22
+ const DialogComponent: React.FC = props => {
23
+ const { state, openButtonProps, openButtonRef } = useDialogButtonProps();
24
+ return (
25
+ <>
26
+ <Button {...openButtonProps} ref={openButtonRef}>
27
+ Open
28
+ </Button>
29
+ {state.isOpen && (
30
+ <Dialog
31
+ title="Title"
32
+ isOpen={state.isOpen}
33
+ close={state.close}
34
+ {...props}
35
+ >
36
+ Content
37
+ </Dialog>
38
+ )}
39
+ </>
40
+ );
41
+ };
42
+
43
+ test('dialog can be opened by button', () => {
44
+ render(<DialogComponent />);
45
+ const button = screen.getByText(/Open/);
46
+ fireEvent.click(button);
47
+ const dialog = screen.getByText(/Content/);
48
+ expect(dialog).toBeDefined();
49
+ });
50
+
51
+ test('supports theme variants', () => {
52
+ render(
53
+ <ThemeProvider theme={theme}>
54
+ <DialogComponent data-testid="Dialog" />
55
+ </ThemeProvider>
56
+ );
57
+ const button = screen.getByText(/Open/);
58
+ fireEvent.click(button);
59
+
60
+ const dialogBody = screen.getByTestId(/Dialog/);
61
+ expect(dialogBody).toHaveStyle(`padding: 8px`);
62
+ const dialogTitle = screen.getByText(/Title/);
63
+ expect(dialogTitle.parentElement).toHaveStyle(`padding: 4px`);
64
+ });
65
+
66
+ test('close Dialog by escape key', () => {
67
+ render(<DialogComponent />);
68
+ const button = screen.getByText(/Open/);
69
+ fireEvent.click(button);
70
+
71
+ const dialog = screen.getByText(/Content/);
72
+ userEvent.type(dialog, '{esc}');
73
+ expect(dialog).not.toBeVisible();
74
+ });
75
+
76
+ test('close Dialog by close button', () => {
77
+ render(<DialogComponent data-testid="Dialog" />);
78
+ const button = screen.getByText(/Open/);
79
+ fireEvent.click(button);
80
+
81
+ const dialog = screen.getByTestId(/Dialog/);
82
+ expect(dialog).toBeVisible();
83
+ const buttonDiv = dialog.lastChild;
84
+ const onClose = buttonDiv && buttonDiv.firstChild;
85
+ onClose && fireEvent.click(onClose);
86
+ expect(dialog).not.toBeVisible();
87
+ });