@marigold/components 0.0.3 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/CHANGELOG.md +174 -0
  2. package/dist/ActionGroup/ActionGroup.d.ts +8 -0
  3. package/dist/ActionGroup/ActionGroup.stories.d.ts +5 -0
  4. package/dist/ActionGroup/index.d.ts +1 -0
  5. package/dist/Alert/Alert.d.ts +22 -1
  6. package/dist/Alert/Alert.stories.d.ts +5 -0
  7. package/dist/Badge/Badge.d.ts +5 -0
  8. package/dist/Badge/Badge.stories.d.ts +5 -0
  9. package/dist/Box.d.ts +2 -0
  10. package/dist/Button/Button.d.ts +9 -6
  11. package/dist/Button/Button.stories.d.ts +5 -0
  12. package/dist/Card/Card.d.ts +14 -0
  13. package/dist/Card/Card.stories.d.ts +5 -0
  14. package/dist/Card/index.d.ts +1 -0
  15. package/dist/Checkbox/Checkbox.d.ts +15 -3
  16. package/dist/Checkbox/Checkbox.stories.d.ts +5 -0
  17. package/dist/Checkbox/CheckboxIcons.d.ts +9 -0
  18. package/dist/Column/Column.d.ts +3 -1
  19. package/dist/Column/Column.stories.d.ts +5 -0
  20. package/dist/Columns/Columns.d.ts +2 -2
  21. package/dist/Columns/Columns.stories.d.ts +5 -0
  22. package/dist/Container/Container.stories.d.ts +5 -0
  23. package/dist/Dialog/Dialog.d.ts +12 -2
  24. package/dist/Dialog/Dialog.stories.d.ts +5 -0
  25. package/dist/Dialog/ModalDialog.d.ts +8 -0
  26. package/dist/Divider/Divider.d.ts +5 -0
  27. package/dist/Divider/Divider.stories.d.ts +5 -0
  28. package/dist/Field/Field.d.ts +5 -1
  29. package/dist/Field/Field.stories.d.ts +5 -0
  30. package/dist/Image/Image.d.ts +5 -0
  31. package/dist/Image/Image.stories.d.ts +5 -0
  32. package/dist/Inline/Inline.d.ts +7 -0
  33. package/dist/Inline/Inline.stories.d.ts +5 -0
  34. package/dist/Inline/index.d.ts +1 -0
  35. package/dist/Input/Input.d.ts +5 -0
  36. package/dist/Input/Input.stories.d.ts +5 -0
  37. package/dist/Label/Label.d.ts +14 -2
  38. package/dist/Label/Label.stories.d.ts +5 -0
  39. package/dist/Link/Link.d.ts +10 -6
  40. package/dist/Link/Link.stories.d.ts +5 -0
  41. package/dist/Menu/Menu.d.ts +3 -0
  42. package/dist/Menu/Menu.stories.d.ts +5 -0
  43. package/dist/MenuItem/MenuItem.d.ts +5 -0
  44. package/dist/MenuItem/MenuItem.stories.d.ts +5 -0
  45. package/dist/Message/Message.d.ts +5 -0
  46. package/dist/Message/Message.stories.d.ts +5 -0
  47. package/dist/Provider/MarigoldProvider.d.ts +11 -0
  48. package/dist/Provider/index.d.ts +3 -0
  49. package/dist/Radio/Radio.d.ts +11 -4
  50. package/dist/Radio/Radio.stories.d.ts +5 -0
  51. package/dist/Radio/RadioIcon.d.ts +9 -0
  52. package/dist/Select/ListBox.d.ts +9 -0
  53. package/dist/Select/ListBoxSection.d.ts +9 -0
  54. package/dist/Select/Option.d.ts +9 -0
  55. package/dist/Select/Popover.d.ts +9 -0
  56. package/dist/Select/Select.d.ts +25 -4
  57. package/dist/Select/Select.stories.d.ts +5 -0
  58. package/dist/Slider/Slider.d.ts +5 -0
  59. package/dist/Slider/Slider.stories.d.ts +5 -0
  60. package/dist/Stack/Stack.d.ts +1 -3
  61. package/dist/Stack/Stack.stories.d.ts +5 -0
  62. package/dist/Text/Text.d.ts +17 -10
  63. package/dist/Text/Text.stories.d.ts +5 -0
  64. package/dist/Textarea/Textarea.d.ts +7 -1
  65. package/dist/Textarea/Textarea.stories.d.ts +5 -0
  66. package/dist/ValidationMessage/ValidationMessage.d.ts +5 -0
  67. package/dist/ValidationMessage/ValidationMessage.stories.d.ts +5 -0
  68. package/dist/VisuallyHidden/VisuallyHidden.d.ts +1 -0
  69. package/dist/VisuallyHidden/VisuallyHidden.stories.d.ts +5 -0
  70. package/dist/VisuallyHidden/index.d.ts +1 -0
  71. package/dist/components.cjs.development.js +1075 -562
  72. package/dist/components.cjs.development.js.map +1 -1
  73. package/dist/components.cjs.production.min.js +1 -1
  74. package/dist/components.cjs.production.min.js.map +1 -1
  75. package/dist/components.esm.js +1012 -542
  76. package/dist/components.esm.js.map +1 -1
  77. package/dist/index.d.ts +6 -2
  78. package/dist/theme.d.ts +23 -48
  79. package/package.json +21 -2
  80. package/src/ActionGroup/ActionGroup.stories.tsx +47 -0
  81. package/src/ActionGroup/ActionGroup.test.tsx +83 -0
  82. package/src/ActionGroup/ActionGroup.tsx +32 -0
  83. package/src/ActionGroup/index.ts +1 -0
  84. package/src/Alert/Alert.stories.tsx +32 -0
  85. package/src/Alert/Alert.test.tsx +5 -2
  86. package/src/Alert/Alert.tsx +27 -34
  87. package/src/Badge/Badge.stories.tsx +38 -0
  88. package/src/Badge/Badge.test.tsx +12 -16
  89. package/src/Badge/Badge.tsx +14 -3
  90. package/src/Box.ts +2 -0
  91. package/src/Button/Button.stories.tsx +57 -0
  92. package/src/Button/Button.test.tsx +76 -13
  93. package/src/Button/Button.tsx +61 -18
  94. package/src/Card/Card.stories.tsx +41 -0
  95. package/src/Card/Card.test.tsx +71 -0
  96. package/src/Card/Card.tsx +48 -0
  97. package/src/Card/index.ts +1 -0
  98. package/src/Checkbox/Checkbox.stories.tsx +78 -0
  99. package/src/Checkbox/Checkbox.test.tsx +138 -23
  100. package/src/Checkbox/Checkbox.tsx +81 -52
  101. package/src/Checkbox/CheckboxIcons.tsx +59 -0
  102. package/src/Column/Column.stories.tsx +33 -0
  103. package/src/Column/Column.test.tsx +8 -0
  104. package/src/Column/Column.tsx +12 -2
  105. package/src/Columns/Columns.stories.tsx +75 -0
  106. package/src/Columns/Columns.test.tsx +34 -23
  107. package/src/Columns/Columns.tsx +30 -30
  108. package/src/Container/Container.stories.tsx +14 -0
  109. package/src/Dialog/Dialog.stories.tsx +88 -0
  110. package/src/Dialog/Dialog.test.tsx +129 -18
  111. package/src/Dialog/Dialog.tsx +113 -15
  112. package/src/Dialog/ModalDialog.tsx +76 -0
  113. package/src/Divider/Divider.stories.tsx +30 -0
  114. package/src/Divider/Divider.test.tsx +13 -5
  115. package/src/Divider/Divider.tsx +12 -0
  116. package/src/Field/Field.stories.tsx +110 -0
  117. package/src/Field/Field.test.tsx +74 -33
  118. package/src/Field/Field.tsx +27 -20
  119. package/src/Image/Image.stories.tsx +34 -0
  120. package/src/Image/Image.test.tsx +4 -1
  121. package/src/Image/Image.tsx +13 -1
  122. package/src/Inline/Inline.stories.tsx +39 -0
  123. package/src/Inline/Inline.test.tsx +99 -0
  124. package/src/Inline/Inline.tsx +38 -0
  125. package/src/Inline/index.ts +1 -0
  126. package/src/Input/Input.stories.tsx +54 -0
  127. package/src/Input/Input.test.tsx +7 -3
  128. package/src/Input/Input.tsx +13 -1
  129. package/src/Label/Label.stories.tsx +41 -0
  130. package/src/Label/Label.test.tsx +40 -5
  131. package/src/Label/Label.tsx +54 -8
  132. package/src/Link/Link.stories.tsx +35 -0
  133. package/src/Link/Link.test.tsx +51 -21
  134. package/src/Link/Link.tsx +39 -13
  135. package/src/Menu/Menu.stories.tsx +62 -0
  136. package/src/Menu/Menu.test.tsx +11 -6
  137. package/src/Menu/Menu.tsx +22 -14
  138. package/src/MenuItem/MenuItem.stories.tsx +30 -0
  139. package/src/MenuItem/MenuItem.test.tsx +22 -13
  140. package/src/MenuItem/MenuItem.tsx +19 -10
  141. package/src/Message/Message.stories.tsx +30 -0
  142. package/src/Message/Message.test.tsx +4 -1
  143. package/src/Message/Message.tsx +18 -14
  144. package/src/Provider/MarigoldProvider.test.tsx +136 -0
  145. package/src/Provider/MarigoldProvider.tsx +47 -0
  146. package/src/Provider/index.ts +4 -0
  147. package/src/Radio/Radio.stories.tsx +78 -0
  148. package/src/Radio/Radio.test.tsx +129 -18
  149. package/src/Radio/Radio.tsx +62 -71
  150. package/src/Radio/RadioIcon.tsx +49 -0
  151. package/src/Select/ListBox.tsx +40 -0
  152. package/src/Select/ListBoxSection.tsx +40 -0
  153. package/src/Select/Option.tsx +48 -0
  154. package/src/Select/Popover.tsx +50 -0
  155. package/src/Select/Select.stories.tsx +81 -0
  156. package/src/Select/Select.test.tsx +317 -35
  157. package/src/Select/Select.tsx +162 -18
  158. package/src/Slider/Slider.stories.tsx +24 -0
  159. package/src/Slider/Slider.test.tsx +10 -6
  160. package/src/Slider/Slider.tsx +25 -13
  161. package/src/Stack/Stack.stories.tsx +57 -0
  162. package/src/Stack/Stack.test.tsx +93 -65
  163. package/src/Stack/Stack.tsx +27 -32
  164. package/src/Text/Text.stories.tsx +61 -0
  165. package/src/Text/Text.test.tsx +41 -36
  166. package/src/Text/Text.tsx +56 -31
  167. package/src/Textarea/Textarea.stories.tsx +64 -0
  168. package/src/Textarea/Textarea.test.tsx +11 -8
  169. package/src/Textarea/Textarea.tsx +41 -38
  170. package/src/ValidationMessage/ValidationMessage.stories.tsx +27 -0
  171. package/src/ValidationMessage/ValidationMessage.test.tsx +9 -4
  172. package/src/ValidationMessage/ValidationMessage.tsx +23 -12
  173. package/src/VisuallyHidden/VisuallyHidden.stories.tsx +19 -0
  174. package/src/VisuallyHidden/VisuallyHidden.test.tsx +10 -0
  175. package/src/VisuallyHidden/VisuallyHidden.tsx +1 -0
  176. package/src/VisuallyHidden/index.ts +1 -0
  177. package/src/index.ts +7 -2
  178. package/src/theme.ts +49 -48
  179. package/dist/Box/Box.d.ts +0 -45
  180. package/dist/Box/index.d.ts +0 -1
  181. package/dist/Heading/Heading.d.ts +0 -7
  182. package/dist/Heading/index.d.ts +0 -1
  183. package/dist/Hidden/Hidden.d.ts +0 -5
  184. package/dist/Hidden/index.d.ts +0 -1
  185. package/src/Alert/Alert.stories.mdx +0 -45
  186. package/src/Badge/Badge.stories.mdx +0 -43
  187. package/src/Box/Box.stories.mdx +0 -38
  188. package/src/Box/Box.test.tsx +0 -133
  189. package/src/Box/Box.tsx +0 -152
  190. package/src/Box/index.ts +0 -1
  191. package/src/Button/Button.stories.mdx +0 -176
  192. package/src/Checkbox/Checkbox.stories.mdx +0 -119
  193. package/src/Column/Column.stories.mdx +0 -74
  194. package/src/Columns/Columns.stories.mdx +0 -247
  195. package/src/Container/Container.stories.mdx +0 -36
  196. package/src/Dialog/Dialog.stories.mdx +0 -64
  197. package/src/Divider/Divider.stories.mdx +0 -43
  198. package/src/Field/Field.stories.mdx +0 -57
  199. package/src/Heading/Heading.stories.mdx +0 -91
  200. package/src/Heading/Heading.test.tsx +0 -77
  201. package/src/Heading/Heading.tsx +0 -19
  202. package/src/Heading/index.ts +0 -1
  203. package/src/Hidden/Hidden.stories.mdx +0 -64
  204. package/src/Hidden/Hidden.test.tsx +0 -24
  205. package/src/Hidden/Hidden.tsx +0 -16
  206. package/src/Hidden/index.ts +0 -1
  207. package/src/Image/Image.stories.mdx +0 -40
  208. package/src/Input/Input.stories.mdx +0 -45
  209. package/src/Label/Label.stories.mdx +0 -34
  210. package/src/Link/Link.stories.mdx +0 -38
  211. package/src/Menu/Menu.stories.mdx +0 -49
  212. package/src/MenuItem/MenuItem.stories.mdx +0 -32
  213. package/src/Message/Message.stories.mdx +0 -44
  214. package/src/Radio/Radio.stories.mdx +0 -100
  215. package/src/Select/Select.stories.mdx +0 -44
  216. package/src/Slider/Slider.stories.mdx +0 -58
  217. package/src/Stack/Stack.stories.mdx +0 -105
  218. package/src/Text/Text.stories.mdx +0 -60
  219. package/src/Textarea/Textarea.stories.mdx +0 -65
  220. package/src/ValidationMessage/ValidationMessage.stories.mdx +0 -36
@@ -0,0 +1,76 @@
1
+ import React, { RefObject } from 'react';
2
+ import {
3
+ useOverlay,
4
+ usePreventScroll,
5
+ useModal,
6
+ OverlayProps,
7
+ } from '@react-aria/overlays';
8
+ import { useDialog } from '@react-aria/dialog';
9
+ import { FocusScope } from '@react-aria/focus';
10
+ import { AriaDialogProps } from '@react-types/dialog';
11
+
12
+ import { Box } from '../Box';
13
+
14
+ // Props
15
+ // ---------------
16
+ export type ModalDialogProps = {
17
+ variant?: string;
18
+ backdropVariant?: string;
19
+ } & OverlayProps &
20
+ AriaDialogProps;
21
+
22
+ // Component
23
+ // ---------------
24
+ export const ModalDialog: React.FC<ModalDialogProps> = ({
25
+ variant,
26
+ backdropVariant = 'backdrop',
27
+ children,
28
+ ...props
29
+ }) => {
30
+ const { isDismissable, isOpen, onClose, ...restProps } = props;
31
+
32
+ // Handle interacting outside the dialog and pressing
33
+ // the Escape key to close the modal.
34
+ const ref = React.useRef<HTMLElement>() as RefObject<HTMLElement>;
35
+ const { overlayProps, underlayProps } = useOverlay(
36
+ { isDismissable, isOpen, onClose },
37
+ ref
38
+ );
39
+
40
+ // Prevent scrolling while the modal is open, and hide content
41
+ // outside the modal from screen readers.
42
+ usePreventScroll();
43
+
44
+ const { modalProps } = useModal();
45
+ const { dialogProps } = useDialog(props, ref);
46
+
47
+ return (
48
+ <Box
49
+ __baseCSS={{
50
+ display: 'grid',
51
+ placeItems: 'center',
52
+ position: 'fixed',
53
+ zIndex: 100,
54
+ top: 0,
55
+ left: 0,
56
+ bottom: 0,
57
+ right: 0,
58
+ }}
59
+ variant={`dialog.${backdropVariant}`}
60
+ {...underlayProps}
61
+ >
62
+ <FocusScope contain restoreFocus autoFocus>
63
+ <Box
64
+ {...overlayProps}
65
+ {...dialogProps}
66
+ {...modalProps}
67
+ ref={ref}
68
+ variant={variant ? `dialog.${variant}` : `dialog`}
69
+ {...restProps}
70
+ >
71
+ {children}
72
+ </Box>
73
+ </FocusScope>
74
+ </Box>
75
+ );
76
+ };
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import type { Meta, ComponentStory } from '@storybook/react';
3
+ import { Divider } from './Divider';
4
+ import { Text } from '../Text';
5
+
6
+ export default {
7
+ title: 'Components/Divider',
8
+ argTypes: {
9
+ variant: {
10
+ control: {
11
+ type: 'select',
12
+ },
13
+ options: ['regular', 'bold'],
14
+ description: 'Thick or thin line',
15
+ table: {
16
+ defaultValue: {
17
+ summary: 'regular',
18
+ },
19
+ },
20
+ },
21
+ },
22
+ } as Meta;
23
+
24
+ export const Basic: ComponentStory<typeof Divider> = args => (
25
+ <>
26
+ <Text>Above</Text>
27
+ <Divider {...args} />
28
+ <Text>Below</Text>
29
+ </>
30
+ );
@@ -4,16 +4,24 @@ import { ThemeProvider } from '@marigold/system';
4
4
  import { Divider } from './Divider';
5
5
 
6
6
  const theme = {
7
+ space: {
8
+ none: 0,
9
+ small: 2,
10
+ },
11
+ borders: {
12
+ none: 0,
13
+ regular: '1px solid',
14
+ },
7
15
  divider: {
8
16
  regular: {
9
- border: 0,
10
- borderBottom: '1px solid',
11
- margin: '2px',
17
+ border: 'none',
18
+ borderBottom: 'regular',
19
+ margin: 'small',
12
20
  },
13
21
  bold: {
14
- border: 0,
22
+ border: 'none',
15
23
  borderBottom: '2px solid',
16
- margin: '2px',
24
+ margin: 'small',
17
25
  },
18
26
  },
19
27
  };
@@ -1,12 +1,24 @@
1
1
  import React from 'react';
2
2
  import { Box } from '../Box';
3
3
 
4
+ // Theme Extension
5
+ // ---------------
6
+ export interface DividerThemeExtension<Value> {
7
+ divider?: {
8
+ [key: string]: Value;
9
+ };
10
+ }
11
+
12
+ // Props
13
+ // ---------------
4
14
  export type DividerProps = {
5
15
  className?: string;
6
16
  variant?: string;
7
17
  title?: string; // Should only be used for testing.
8
18
  };
9
19
 
20
+ // Component
21
+ // ---------------
10
22
  export const Divider: React.FC<DividerProps> = ({
11
23
  variant = 'regular',
12
24
  ...props
@@ -0,0 +1,110 @@
1
+ import React from 'react';
2
+ import type { Meta, ComponentStory } from '@storybook/react';
3
+ import { Field } from './Field';
4
+
5
+ export default {
6
+ title: 'Components/Field',
7
+ argTypes: {
8
+ variant: {
9
+ control: {
10
+ type: 'text',
11
+ },
12
+ description: 'Field variant',
13
+ table: {
14
+ defaultValue: {
15
+ summary: '__default',
16
+ },
17
+ },
18
+ },
19
+ labelVariant: {
20
+ control: {
21
+ type: 'text',
22
+ },
23
+ description: 'Field label variant',
24
+ table: {
25
+ defaultValue: {
26
+ summary: 'above',
27
+ },
28
+ },
29
+ },
30
+ htmlFor: {
31
+ control: {
32
+ type: 'text',
33
+ },
34
+ defaultValue: 'id',
35
+ },
36
+ label: {
37
+ control: {
38
+ type: 'text',
39
+ },
40
+ defaultValue: 'Label',
41
+ },
42
+ error: {
43
+ control: {
44
+ type: 'boolean',
45
+ },
46
+ description: 'Error',
47
+ table: {
48
+ defaultValue: {
49
+ summary: false,
50
+ },
51
+ },
52
+ },
53
+ errorMessage: {
54
+ control: {
55
+ type: 'text',
56
+ },
57
+ description: 'Error Message',
58
+ },
59
+ required: {
60
+ control: {
61
+ type: 'boolean',
62
+ },
63
+ options: [true, false],
64
+ table: {
65
+ defaultValue: {
66
+ summary: false,
67
+ },
68
+ },
69
+ },
70
+ disabled: {
71
+ control: {
72
+ type: 'boolean',
73
+ },
74
+ options: [true, false],
75
+ table: {
76
+ defaultValue: {
77
+ summary: false,
78
+ },
79
+ },
80
+ },
81
+ type: {
82
+ control: {
83
+ type: 'select',
84
+ },
85
+ options: [
86
+ 'date',
87
+ 'datetime-local',
88
+ 'email',
89
+ 'month',
90
+ 'number',
91
+ 'password',
92
+ 'search',
93
+ 'tel',
94
+ 'text',
95
+ 'time',
96
+ 'time',
97
+ 'url',
98
+ 'week',
99
+ ],
100
+ defaultValue: 'text',
101
+ table: {
102
+ defaultValue: {
103
+ summary: 'text',
104
+ },
105
+ },
106
+ },
107
+ },
108
+ } as Meta;
109
+
110
+ export const Basic: ComponentStory<typeof Field> = args => <Field {...args} />;
@@ -2,20 +2,29 @@ import React from 'react';
2
2
  import { render, screen } from '@testing-library/react';
3
3
  import { ThemeProvider } from '@marigold/system';
4
4
  import { Field } from './Field';
5
- import { useStyles } from '@marigold/system';
6
5
 
7
6
  const theme = {
8
- field: {
9
- default: {
10
- padding: '4px',
7
+ space: {
8
+ none: 0,
9
+ small: 4,
10
+ medium: 8,
11
+ },
12
+ label: {
13
+ above: {
14
+ fontSize: '14px',
15
+ },
16
+ },
17
+ input: {
18
+ __default: {
19
+ padding: 'small',
11
20
  },
12
- inputField: {
13
- padding: '8px',
21
+ error: {
22
+ padding: 'medium',
14
23
  },
15
24
  },
16
25
  };
17
26
 
18
- test('supports default variant and themeSection', () => {
27
+ test('renders correct HTML element', () => {
19
28
  render(
20
29
  <ThemeProvider theme={theme}>
21
30
  <Field htmlFor="myId" label="label" />
@@ -23,29 +32,47 @@ test('supports default variant and themeSection', () => {
23
32
  );
24
33
  const field = screen.getByText(/label/);
25
34
 
26
- expect(field).toHaveStyle(`padding: 4px`);
35
+ expect(field instanceof HTMLLabelElement).toBeTruthy();
27
36
  });
28
37
 
29
- test('accepts other variant than default', () => {
38
+ test('supports default variant', () => {
30
39
  render(
31
40
  <ThemeProvider theme={theme}>
32
- <Field htmlFor="myId" label="inputField" variant="inputField" />
41
+ <Field htmlFor="myId" label="Name" data-testid="field" />
33
42
  </ThemeProvider>
34
43
  );
35
- const inputField = screen.getByText(/inputField/);
44
+ const field = screen.getByTestId(/field/);
45
+ expect(field).toHaveStyle(`padding: 4px`);
46
+ });
36
47
 
37
- expect(inputField).toHaveStyle(`padding: 8px`);
48
+ test('supports other variant than default', () => {
49
+ render(
50
+ <ThemeProvider theme={theme}>
51
+ <Field htmlFor="myId" label="Name" variant="error" data-testid="field" />
52
+ </ThemeProvider>
53
+ );
54
+ const field = screen.getByTestId(/field/);
55
+ expect(field).toHaveStyle(`padding: 8px`);
38
56
  });
39
57
 
40
- test('renders correct HTML element', () => {
58
+ test('supports default variantLabel', () => {
41
59
  render(
42
60
  <ThemeProvider theme={theme}>
43
- <Field htmlFor="myId" label="label" />
61
+ <Field htmlFor="myId" label="Name" />
44
62
  </ThemeProvider>
45
63
  );
46
- const field = screen.getByText(/label/);
64
+ const label = screen.getByText(/Name/);
65
+ expect(label).toHaveStyle(`font-size: 14px`);
66
+ });
47
67
 
48
- expect(field instanceof HTMLLabelElement).toBeTruthy();
68
+ test('supports other variantLabel than default', () => {
69
+ render(
70
+ <ThemeProvider theme={theme}>
71
+ <Field htmlFor="myId" label="Name" />
72
+ </ThemeProvider>
73
+ );
74
+ const label = screen.getByText(/Name/);
75
+ expect(label).toHaveStyle(`font-size: 14px`);
49
76
  });
50
77
 
51
78
  test('supports label prop', () => {
@@ -56,34 +83,48 @@ test('supports label prop', () => {
56
83
  });
57
84
 
58
85
  test('supports htmlFor prop', () => {
59
- render(<Field htmlFor="myId" label="Name" error="Validation error" />);
86
+ render(<Field htmlFor="myId" label="Name" />);
60
87
  const field = screen.getByText(/Name/);
61
88
 
62
89
  expect(field).toHaveAttribute('for');
63
90
  });
64
91
 
65
- test('supports error prop', () => {
66
- render(<Field htmlFor="myId" label="label" error="Validation error" />);
67
- const field = screen.getByText(/Validation/);
92
+ test('supports required prop', () => {
93
+ render(<Field htmlFor="myId" label="label" required />);
94
+ const fieldLabel = screen.getByText(/label/);
68
95
 
69
- expect(field).toBeDefined();
96
+ expect(fieldLabel.nextSibling).toBeDefined();
97
+ expect(fieldLabel.nextSibling instanceof SVGElement).toBeTruthy();
98
+ });
99
+
100
+ test('supports error and errorMessage prop', () => {
101
+ render(
102
+ <Field htmlFor="myId" label="label" error errorMessage="Validation error" />
103
+ );
104
+
105
+ const errorMessage = screen.getByText(/Validation/);
106
+ expect(errorMessage).toBeDefined();
107
+ });
108
+
109
+ test('supports disabled prop', () => {
110
+ render(<Field htmlFor="myId" label="label" disabled />);
111
+ const fieldLabel = screen.getByText(/label/);
112
+ expect(fieldLabel.nextSibling).toHaveAttribute('disabled');
70
113
  });
71
114
 
72
115
  test('accepts custom styles prop className', () => {
73
- const TestComponent: React.FC = ({ children, ...props }) => {
74
- const classNames = useStyles({ css: { fontSize: '8px' } });
75
- return (
76
- <Field htmlFor="myId" label="label" className={classNames} {...props} />
77
- );
78
- };
79
-
80
- const { getByText } = render(
116
+ render(
81
117
  <ThemeProvider theme={theme}>
82
- <TestComponent />
118
+ <Field
119
+ htmlFor="myId"
120
+ label="label"
121
+ className="custom-class-name"
122
+ title="field"
123
+ data-testid="field"
124
+ />
83
125
  </ThemeProvider>
84
126
  );
85
- const testelem = getByText('label');
86
- const field = getComputedStyle(testelem);
127
+ const field = screen.getByTestId(/field/);
87
128
 
88
- expect(field.fontSize).toEqual('8px');
129
+ expect(field.className).toMatch('custom-class-name');
89
130
  });
@@ -1,49 +1,56 @@
1
1
  import React from 'react';
2
- import { useStyles } from '@marigold/system';
3
- import { Exclamation, Required } from '@marigold/icons';
2
+ import { Exclamation } from '@marigold/icons';
4
3
  import { ComponentProps } from '@marigold/types';
5
4
 
6
5
  import { Input } from '../Input';
7
6
  import { Label } from '../Label';
8
7
  import { ValidationMessage } from '../ValidationMessage';
9
8
 
9
+ // Props
10
+ // ---------------
10
11
  export type FieldProps = {
11
12
  variant?: string;
13
+ labelVariant?: string;
12
14
  htmlFor: string;
13
15
  label: string;
14
- error?: string;
16
+ required?: boolean;
17
+ error?: boolean;
18
+ errorMessage?: string;
19
+ disabled?: boolean;
15
20
  } & ComponentProps<'input'>;
16
21
 
22
+ // Component
23
+ // ---------------
17
24
  export const Field: React.FC<FieldProps> = ({
18
- variant = 'default',
19
25
  type = 'text',
20
- className = '',
26
+ variant = '',
27
+ labelVariant = 'above',
21
28
  htmlFor,
22
29
  label,
30
+ required,
23
31
  error,
32
+ errorMessage,
33
+ disabled,
24
34
  ...props
25
35
  }) => {
26
- const labelClassName = useStyles({
27
- variant: `field.${variant}`,
28
- className,
29
- });
30
- const errorClassName = useStyles({ css: { color: 'red60' } });
31
-
32
36
  return (
33
- <div>
34
- <Label className={labelClassName} htmlFor={htmlFor}>
37
+ <>
38
+ <Label variant={labelVariant} htmlFor={htmlFor} required={required}>
35
39
  {label}
36
- {error ? <Required size={16} className={errorClassName} /> : ''}
37
40
  </Label>
38
- <Input {...props} type={type} id={htmlFor} />
39
- {error ? (
41
+ <Input
42
+ {...props}
43
+ type={type}
44
+ id={htmlFor}
45
+ disabled={disabled}
46
+ variant={variant}
47
+ />
48
+ {error && errorMessage && (
40
49
  <ValidationMessage>
41
50
  <Exclamation size={16} />
42
- {error}
51
+ {errorMessage}
43
52
  </ValidationMessage>
44
- ) : (
45
- ''
46
53
  )}
47
- </div>
54
+ </>
48
55
  );
49
56
  };
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import type { Meta, ComponentStory } from '@storybook/react';
3
+ import { Image } from './Image';
4
+
5
+ export default {
6
+ title: 'Components/Image',
7
+ argTypes: {
8
+ variant: {
9
+ control: {
10
+ type: 'text',
11
+ },
12
+ description: 'there is only one variant',
13
+ table: {
14
+ defaultValue: {
15
+ summary: 'fullWidth',
16
+ },
17
+ },
18
+ },
19
+ alt: {
20
+ control: {
21
+ type: 'text',
22
+ },
23
+ description: 'Description text for screenreaders',
24
+ },
25
+ },
26
+ } as Meta;
27
+
28
+ export const Basic: ComponentStory<typeof Image> = args => (
29
+ <Image
30
+ src="https://www.reservix.net/_Resources/Persistent/0e8f5885125940fdb2bc2d54840f497782f56584/Reservix_Logo_dtp_web_rgb_font_black_180704.png"
31
+ alt="marigold_logo"
32
+ {...args}
33
+ />
34
+ );
@@ -4,7 +4,10 @@ import { ThemeProvider } from '@marigold/system';
4
4
  import { Image } from './Image';
5
5
 
6
6
  const theme = {
7
- images: {
7
+ colors: {
8
+ primary: 'hotpink',
9
+ },
10
+ image: {
8
11
  fullWidth: {
9
12
  alignItems: 'center',
10
13
  },
@@ -2,12 +2,24 @@ import React from 'react';
2
2
  import { ComponentProps } from '@marigold/types';
3
3
  import { Box } from '../Box';
4
4
 
5
+ // Theme Extension
6
+ // ---------------
7
+ export interface ImageThemeExtension<Value> {
8
+ image?: {
9
+ [key: string]: Value;
10
+ };
11
+ }
12
+
13
+ // Props
14
+ // ---------------
5
15
  export type ImageProps = {
6
16
  variant?: string;
7
17
  children?: never;
8
18
  } & ComponentProps<'img'>;
9
19
 
20
+ // Component
21
+ // ---------------
10
22
  export const Image: React.FC<ImageProps> = ({
11
23
  variant = 'fullWidth',
12
24
  ...props
13
- }) => <Box {...props} as="img" variant={`images.${variant}`} />;
25
+ }) => <Box {...props} as="img" variant={`image.${variant}`} />;
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import type { Meta, ComponentStory } from '@storybook/react';
3
+ import { Text } from '../Text';
4
+ import { Inline } from './Inline';
5
+ import { Check } from '@marigold/icons';
6
+
7
+ export default {
8
+ title: 'Components/Inline',
9
+ argTypes: {
10
+ space: {
11
+ control: {
12
+ type: 'select',
13
+ },
14
+ options: [
15
+ 'none',
16
+ 'xxsmall',
17
+ 'xsmall',
18
+ 'small',
19
+ 'medium',
20
+ 'large',
21
+ 'xlarge',
22
+ 'xxlarge',
23
+ ],
24
+ description: 'Responsive Style Value',
25
+ table: {
26
+ defaultValue: {
27
+ summary: 'none',
28
+ },
29
+ },
30
+ },
31
+ },
32
+ } as Meta;
33
+
34
+ export const Basic: ComponentStory<typeof Inline> = args => (
35
+ <Inline {...args}>
36
+ <Check />
37
+ <Text>Check</Text>
38
+ </Inline>
39
+ );