@marigold/components 0.2.0 → 0.3.3

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 (201) hide show
  1. package/CHANGELOG.md +180 -0
  2. package/dist/ActionGroup/ActionGroup.d.ts +1 -2
  3. package/dist/ActionGroup/ActionGroup.stories.d.ts +5 -0
  4. package/dist/Alert/Alert.d.ts +7 -1
  5. package/dist/Alert/Alert.stories.d.ts +5 -0
  6. package/dist/Badge/Badge.d.ts +5 -0
  7. package/dist/Badge/Badge.stories.d.ts +5 -0
  8. package/dist/Box.d.ts +2 -0
  9. package/dist/Button/Button.d.ts +5 -0
  10. package/dist/Button/Button.stories.d.ts +5 -0
  11. package/dist/Card/Card.d.ts +5 -0
  12. package/dist/Card/Card.stories.d.ts +5 -0
  13. package/dist/Checkbox/Checkbox.d.ts +10 -5
  14. package/dist/Checkbox/Checkbox.stories.d.ts +5 -0
  15. package/dist/Checkbox/CheckboxIcons.d.ts +9 -9
  16. package/dist/Column/Column.stories.d.ts +5 -0
  17. package/dist/Columns/Columns.d.ts +2 -2
  18. package/dist/Columns/Columns.stories.d.ts +5 -0
  19. package/dist/Container/Container.stories.d.ts +5 -0
  20. package/dist/Dialog/Dialog.d.ts +5 -2
  21. package/dist/Dialog/Dialog.stories.d.ts +5 -0
  22. package/dist/Dialog/ModalDialog.d.ts +4 -1
  23. package/dist/Divider/Divider.d.ts +7 -3
  24. package/dist/Divider/Divider.stories.d.ts +5 -0
  25. package/dist/Field/Field.d.ts +2 -0
  26. package/dist/Field/Field.stories.d.ts +5 -0
  27. package/dist/Image/Image.d.ts +5 -0
  28. package/dist/Image/Image.stories.d.ts +5 -0
  29. package/dist/Inline/Inline.d.ts +7 -0
  30. package/dist/Inline/Inline.stories.d.ts +5 -0
  31. package/dist/Inline/index.d.ts +1 -0
  32. package/dist/Input/Input.d.ts +5 -0
  33. package/dist/Input/Input.stories.d.ts +5 -0
  34. package/dist/Label/Label.d.ts +12 -1
  35. package/dist/Label/Label.stories.d.ts +5 -0
  36. package/dist/Link/Link.d.ts +3 -0
  37. package/dist/Link/Link.stories.d.ts +5 -0
  38. package/dist/Menu/Menu.d.ts +3 -0
  39. package/dist/Menu/Menu.stories.d.ts +5 -0
  40. package/dist/MenuItem/MenuItem.d.ts +5 -0
  41. package/dist/MenuItem/MenuItem.stories.d.ts +5 -0
  42. package/dist/Message/Message.d.ts +5 -0
  43. package/dist/Message/Message.stories.d.ts +5 -0
  44. package/dist/Provider/MarigoldProvider.d.ts +11 -3
  45. package/dist/Provider/index.d.ts +1 -1
  46. package/dist/Radio/Radio.d.ts +9 -5
  47. package/dist/Radio/Radio.stories.d.ts +5 -0
  48. package/dist/Radio/RadioIcon.d.ts +9 -0
  49. package/dist/Select/ListBox.d.ts +1 -0
  50. package/dist/Select/ListBoxSection.d.ts +1 -0
  51. package/dist/Select/Option.d.ts +1 -0
  52. package/dist/Select/Select.d.ts +15 -1
  53. package/dist/Select/Select.stories.d.ts +5 -0
  54. package/dist/Slider/Slider.d.ts +5 -0
  55. package/dist/Slider/Slider.stories.d.ts +5 -0
  56. package/dist/Stack/Stack.stories.d.ts +5 -0
  57. package/dist/Text/Text.d.ts +5 -0
  58. package/dist/Text/Text.stories.d.ts +5 -0
  59. package/dist/Textarea/Textarea.d.ts +5 -0
  60. package/dist/Textarea/Textarea.stories.d.ts +5 -0
  61. package/dist/ValidationMessage/ValidationMessage.d.ts +5 -0
  62. package/dist/ValidationMessage/ValidationMessage.stories.d.ts +5 -0
  63. package/dist/VisuallyHidden/VisuallyHidden.d.ts +1 -0
  64. package/dist/VisuallyHidden/VisuallyHidden.stories.d.ts +5 -0
  65. package/dist/VisuallyHidden/index.d.ts +1 -0
  66. package/dist/components.cjs.development.js +536 -580
  67. package/dist/components.cjs.development.js.map +1 -1
  68. package/dist/components.cjs.production.min.js +1 -1
  69. package/dist/components.cjs.production.min.js.map +1 -1
  70. package/dist/components.esm.js +481 -535
  71. package/dist/components.esm.js.map +1 -1
  72. package/dist/index.d.ts +2 -2
  73. package/dist/theme.d.ts +23 -48
  74. package/package.json +8 -4
  75. package/src/ActionGroup/ActionGroup.stories.tsx +47 -0
  76. package/src/ActionGroup/ActionGroup.test.tsx +36 -36
  77. package/src/ActionGroup/ActionGroup.tsx +17 -28
  78. package/src/Alert/Alert.stories.tsx +32 -0
  79. package/src/Alert/Alert.test.tsx +4 -1
  80. package/src/Alert/Alert.tsx +18 -3
  81. package/src/Badge/Badge.stories.tsx +38 -0
  82. package/src/Badge/Badge.test.tsx +5 -1
  83. package/src/Badge/Badge.tsx +13 -1
  84. package/src/Box.ts +2 -0
  85. package/src/Button/{Button.stories.mdx → Button.stories.tsx} +10 -17
  86. package/src/Button/Button.test.tsx +34 -11
  87. package/src/Button/Button.tsx +17 -3
  88. package/src/Card/{Card.stories.mdx → Card.stories.tsx} +9 -17
  89. package/src/Card/Card.test.tsx +8 -3
  90. package/src/Card/Card.tsx +13 -1
  91. package/src/Checkbox/{Checkbox.stories.mdx → Checkbox.stories.tsx} +31 -39
  92. package/src/Checkbox/Checkbox.test.tsx +77 -8
  93. package/src/Checkbox/Checkbox.tsx +70 -90
  94. package/src/Checkbox/CheckboxIcons.tsx +51 -41
  95. package/src/Column/Column.stories.tsx +33 -0
  96. package/src/Column/Column.tsx +0 -0
  97. package/src/Columns/Columns.stories.tsx +75 -0
  98. package/src/Columns/Columns.test.tsx +34 -23
  99. package/src/Columns/Columns.tsx +30 -30
  100. package/src/Container/Container.stories.tsx +14 -0
  101. package/src/Container/Container.tsx +0 -0
  102. package/src/Dialog/{Dialog.stories.mdx → Dialog.stories.tsx} +33 -18
  103. package/src/Dialog/Dialog.test.tsx +91 -20
  104. package/src/Dialog/Dialog.tsx +63 -17
  105. package/src/Dialog/ModalDialog.tsx +33 -4
  106. package/src/Divider/Divider.stories.tsx +30 -0
  107. package/src/Divider/Divider.test.tsx +32 -23
  108. package/src/Divider/Divider.tsx +27 -7
  109. package/src/Field/{Field.stories.mdx → Field.stories.tsx} +33 -20
  110. package/src/Field/Field.test.tsx +55 -5
  111. package/src/Field/Field.tsx +10 -8
  112. package/src/Image/Image.stories.tsx +34 -0
  113. package/src/Image/Image.test.tsx +4 -1
  114. package/src/Image/Image.tsx +13 -1
  115. package/src/Inline/Inline.stories.tsx +39 -0
  116. package/src/Inline/Inline.test.tsx +99 -0
  117. package/src/Inline/Inline.tsx +38 -0
  118. package/src/Inline/index.ts +1 -0
  119. package/src/Input/{Input.stories.mdx → Input.stories.tsx} +10 -17
  120. package/src/Input/Input.test.tsx +7 -3
  121. package/src/Input/Input.tsx +13 -1
  122. package/src/Label/{Label.stories.mdx → Label.stories.tsx} +10 -21
  123. package/src/Label/Label.test.tsx +25 -4
  124. package/src/Label/Label.tsx +42 -9
  125. package/src/Link/Link.stories.tsx +35 -0
  126. package/src/Link/Link.test.tsx +6 -2
  127. package/src/Link/Link.tsx +12 -1
  128. package/src/Menu/{Menu.stories.mdx → Menu.stories.tsx} +13 -32
  129. package/src/Menu/Menu.test.tsx +7 -2
  130. package/src/Menu/Menu.tsx +10 -0
  131. package/src/MenuItem/MenuItem.stories.tsx +30 -0
  132. package/src/MenuItem/MenuItem.test.tsx +7 -2
  133. package/src/MenuItem/MenuItem.tsx +12 -0
  134. package/src/Message/Message.stories.tsx +30 -0
  135. package/src/Message/Message.test.tsx +4 -1
  136. package/src/Message/Message.tsx +17 -5
  137. package/src/Provider/MarigoldProvider.test.tsx +65 -55
  138. package/src/Provider/MarigoldProvider.tsx +37 -19
  139. package/src/Provider/index.ts +2 -1
  140. package/src/Radio/{Radio.stories.mdx → Radio.stories.tsx} +31 -39
  141. package/src/Radio/Radio.test.tsx +78 -9
  142. package/src/Radio/Radio.tsx +58 -87
  143. package/src/Radio/RadioIcon.tsx +49 -0
  144. package/src/Select/ListBox.tsx +1 -0
  145. package/src/Select/{Select.stories.mdx → Select.stories.tsx} +23 -20
  146. package/src/Select/Select.test.tsx +39 -1
  147. package/src/Select/Select.tsx +24 -13
  148. package/src/Slider/Slider.stories.tsx +24 -0
  149. package/src/Slider/Slider.test.tsx +10 -6
  150. package/src/Slider/Slider.tsx +25 -13
  151. package/src/Stack/Stack.stories.tsx +57 -0
  152. package/src/Stack/Stack.test.tsx +16 -7
  153. package/src/Stack/Stack.tsx +0 -0
  154. package/src/Text/{Text.stories.mdx → Text.stories.tsx} +20 -19
  155. package/src/Text/Text.test.tsx +2 -2
  156. package/src/Text/Text.tsx +12 -0
  157. package/src/Textarea/{Textarea.stories.mdx → Textarea.stories.tsx} +14 -24
  158. package/src/Textarea/Textarea.test.tsx +7 -3
  159. package/src/Textarea/Textarea.tsx +13 -1
  160. package/src/ValidationMessage/{ValidationMessage.stories.mdx → ValidationMessage.stories.tsx} +8 -17
  161. package/src/ValidationMessage/ValidationMessage.test.tsx +7 -2
  162. package/src/ValidationMessage/ValidationMessage.tsx +12 -0
  163. package/src/VisuallyHidden/VisuallyHidden.stories.tsx +19 -0
  164. package/src/VisuallyHidden/VisuallyHidden.test.tsx +10 -0
  165. package/src/VisuallyHidden/VisuallyHidden.tsx +1 -0
  166. package/src/VisuallyHidden/index.ts +1 -0
  167. package/src/index.ts +2 -2
  168. package/src/theme.ts +49 -48
  169. package/dist/Box/Box.d.ts +0 -47
  170. package/dist/Box/index.d.ts +0 -1
  171. package/dist/Heading/Heading.d.ts +0 -7
  172. package/dist/Heading/index.d.ts +0 -1
  173. package/dist/Hidden/Hidden.d.ts +0 -5
  174. package/dist/Hidden/index.d.ts +0 -1
  175. package/dist/Radio/RadioIcons.d.ts +0 -9
  176. package/src/ActionGroup/ActionGroup.stories.mdx +0 -62
  177. package/src/Alert/Alert.stories.mdx +0 -35
  178. package/src/Badge/Badge.stories.mdx +0 -57
  179. package/src/Box/Box.stories.mdx +0 -334
  180. package/src/Box/Box.test.tsx +0 -133
  181. package/src/Box/Box.tsx +0 -165
  182. package/src/Box/index.ts +0 -1
  183. package/src/Column/Column.stories.mdx +0 -49
  184. package/src/Columns/Columns.stories.mdx +0 -65
  185. package/src/Container/Container.stories.mdx +0 -19
  186. package/src/Divider/Divider.stories.mdx +0 -37
  187. package/src/Heading/Heading.stories.mdx +0 -39
  188. package/src/Heading/Heading.test.tsx +0 -77
  189. package/src/Heading/Heading.tsx +0 -19
  190. package/src/Heading/index.ts +0 -1
  191. package/src/Hidden/Hidden.stories.mdx +0 -39
  192. package/src/Hidden/Hidden.test.tsx +0 -24
  193. package/src/Hidden/Hidden.tsx +0 -16
  194. package/src/Hidden/index.ts +0 -1
  195. package/src/Image/Image.stories.mdx +0 -36
  196. package/src/Link/Link.stories.mdx +0 -45
  197. package/src/MenuItem/MenuItem.stories.mdx +0 -37
  198. package/src/Message/Message.stories.mdx +0 -44
  199. package/src/Radio/RadioIcons.tsx +0 -39
  200. package/src/Slider/Slider.stories.mdx +0 -31
  201. package/src/Stack/Stack.stories.mdx +0 -51
@@ -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: ['__default', 'bold'],
14
+ description: 'Thick or thin line',
15
+ table: {
16
+ defaultValue: {
17
+ summary: '__default',
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,60 +4,69 @@ 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
+ medium: 4,
11
+ },
12
+ colors: {
13
+ text: 'hotpink',
14
+ },
7
15
  divider: {
8
- regular: {
9
- border: 0,
10
- borderBottom: '1px solid',
11
- margin: '2px',
16
+ __default: {
17
+ margin: 'small',
12
18
  },
13
19
  bold: {
14
- border: 0,
15
- borderBottom: '2px solid',
16
- margin: '2px',
20
+ margin: 'medium',
17
21
  },
18
22
  },
19
23
  };
20
24
 
21
- test('supports default variant and themeSection', () => {
25
+ test('has base styles', () => {
22
26
  render(
23
27
  <ThemeProvider theme={theme}>
24
- <Divider title="divider" />
28
+ <Divider data-testid="divider" />
25
29
  </ThemeProvider>
26
30
  );
27
- const divider = screen.getByTitle(/divider/);
31
+ const divider = screen.getByTestId(/divider/);
28
32
 
29
- expect(divider).toHaveStyle(`borderBottom: 1px solid`);
33
+ // __baseCSS
34
+ expect(divider).toHaveStyle(`background: hotpink`);
35
+ expect(divider).toHaveStyle(`width: 100%`);
36
+ expect(divider).toHaveStyle(`height: 1px`);
37
+ // margin from default variant
38
+ expect(divider).toHaveStyle(`margin: 2px`);
30
39
  });
31
40
 
32
- test('accepts other variant than default', () => {
41
+ test('supports default variant', () => {
33
42
  render(
34
43
  <ThemeProvider theme={theme}>
35
- <Divider variant="bold" title="divider" />
44
+ <Divider data-testid="divider" />
36
45
  </ThemeProvider>
37
46
  );
38
- const divider = screen.getByTitle(/divider/);
47
+ const divider = screen.getByTestId(/divider/);
39
48
 
40
- expect(divider).toHaveStyle(`borderBottom: 2px solid`);
49
+ expect(divider).toHaveStyle(`margin: 2px`);
41
50
  });
42
51
 
43
- test('renders correct HTML element', () => {
52
+ test('accepts other variant than default', () => {
44
53
  render(
45
54
  <ThemeProvider theme={theme}>
46
- <Divider title="divider" />
55
+ <Divider variant="bold" data-testid="divider" />
47
56
  </ThemeProvider>
48
57
  );
49
- const divider = screen.getByTitle(/divider/);
58
+ const divider = screen.getByTestId(/divider/);
50
59
 
51
- expect(divider instanceof HTMLHRElement).toBeTruthy();
60
+ expect(divider).toHaveStyle(`margin: 4px`);
52
61
  });
53
62
 
54
- test('accepts custom styles prop className', () => {
63
+ test('renders correct HTML element', () => {
55
64
  render(
56
65
  <ThemeProvider theme={theme}>
57
- <Divider className="custom-class-name" title="divider" />
66
+ <Divider data-testid="divider" />
58
67
  </ThemeProvider>
59
68
  );
60
- const divider = screen.getByTitle(/divider/);
69
+ const divider = screen.getByTestId(/divider/);
61
70
 
62
- expect(divider.className).toMatch('custom-class-name');
71
+ expect(divider instanceof HTMLDivElement).toBeTruthy();
63
72
  });
@@ -1,13 +1,33 @@
1
1
  import React from 'react';
2
+ import { SeparatorProps, useSeparator } from '@react-aria/separator';
3
+
2
4
  import { Box } from '../Box';
3
5
 
6
+ // Theme Extension
7
+ // ---------------
8
+ export interface DividerThemeExtension<Value> {
9
+ divider?: {
10
+ [key: string]: Value;
11
+ };
12
+ }
13
+
14
+ // Props
15
+ // ---------------
4
16
  export type DividerProps = {
5
- className?: string;
6
17
  variant?: string;
7
- title?: string; // Should only be used for testing.
8
- };
18
+ } & SeparatorProps;
9
19
 
10
- export const Divider: React.FC<DividerProps> = ({
11
- variant = 'regular',
12
- ...props
13
- }) => <Box {...props} as="hr" variant={`divider.${variant}`} />;
20
+ // Component
21
+ // ---------------
22
+ export const Divider: React.FC<DividerProps> = ({ variant = '', ...props }) => {
23
+ const { separatorProps } = useSeparator(props);
24
+
25
+ return (
26
+ <Box
27
+ __baseCSS={{ width: '100%', height: '1px', m: 'none', bg: 'text' }}
28
+ variant={`divider.${variant}`}
29
+ {...props}
30
+ {...separatorProps}
31
+ />
32
+ );
33
+ };
@@ -1,20 +1,43 @@
1
- import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
1
+ import React from 'react';
2
+ import type { Meta, ComponentStory } from '@storybook/react';
2
3
  import { Field } from './Field';
3
4
 
4
- <Meta
5
- title="Components/Field"
6
- argTypes={{
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
+ },
7
30
  htmlFor: {
8
31
  control: {
9
32
  type: 'text',
10
33
  },
11
- type: { required: true },
34
+ defaultValue: 'id',
12
35
  },
13
36
  label: {
14
37
  control: {
15
38
  type: 'text',
16
39
  },
17
- type: { required: true },
40
+ defaultValue: 'Label',
18
41
  },
19
42
  error: {
20
43
  control: {
@@ -74,24 +97,14 @@ import { Field } from './Field';
74
97
  'url',
75
98
  'week',
76
99
  ],
77
- type: { required: true },
100
+ defaultValue: 'text',
78
101
  table: {
79
102
  defaultValue: {
80
103
  summary: 'text',
81
104
  },
82
105
  },
83
106
  },
84
- }}
85
- />
86
-
87
- # Field
88
-
89
- export const Template = args => (
90
- <Field htmlFor="id" label="A label" type="text" {...args} />
91
- );
92
-
93
- <Canvas>
94
- <Story name="Default">{Template.bind({})}</Story>
95
- </Canvas>
107
+ },
108
+ } as Meta;
96
109
 
97
- <ArgsTable story="Default" />
110
+ export const Basic: ComponentStory<typeof Field> = args => <Field {...args} />;
@@ -4,12 +4,22 @@ import { ThemeProvider } from '@marigold/system';
4
4
  import { Field } from './Field';
5
5
 
6
6
  const theme = {
7
- field: {
8
- default: {
9
- 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',
10
20
  },
11
- inputField: {
12
- padding: '8px',
21
+ error: {
22
+ padding: 'medium',
13
23
  },
14
24
  },
15
25
  };
@@ -25,6 +35,46 @@ test('renders correct HTML element', () => {
25
35
  expect(field instanceof HTMLLabelElement).toBeTruthy();
26
36
  });
27
37
 
38
+ test('supports default variant', () => {
39
+ render(
40
+ <ThemeProvider theme={theme}>
41
+ <Field htmlFor="myId" label="Name" data-testid="field" />
42
+ </ThemeProvider>
43
+ );
44
+ const field = screen.getByTestId(/field/);
45
+ expect(field).toHaveStyle(`padding: 4px`);
46
+ });
47
+
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`);
56
+ });
57
+
58
+ test('supports default variantLabel', () => {
59
+ render(
60
+ <ThemeProvider theme={theme}>
61
+ <Field htmlFor="myId" label="Name" />
62
+ </ThemeProvider>
63
+ );
64
+ const label = screen.getByText(/Name/);
65
+ expect(label).toHaveStyle(`font-size: 14px`);
66
+ });
67
+
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`);
76
+ });
77
+
28
78
  test('supports label prop', () => {
29
79
  render(<Field htmlFor="myId" label="Name" />);
30
80
  const field = screen.getByText(/Name/);
@@ -6,7 +6,11 @@ import { Input } from '../Input';
6
6
  import { Label } from '../Label';
7
7
  import { ValidationMessage } from '../ValidationMessage';
8
8
 
9
+ // Props
10
+ // ---------------
9
11
  export type FieldProps = {
12
+ variant?: string;
13
+ labelVariant?: string;
10
14
  htmlFor: string;
11
15
  label: string;
12
16
  required?: boolean;
@@ -15,9 +19,12 @@ export type FieldProps = {
15
19
  disabled?: boolean;
16
20
  } & ComponentProps<'input'>;
17
21
 
22
+ // Component
23
+ // ---------------
18
24
  export const Field: React.FC<FieldProps> = ({
19
25
  type = 'text',
20
- className,
26
+ variant = '',
27
+ labelVariant = 'above',
21
28
  htmlFor,
22
29
  label,
23
30
  required,
@@ -28,11 +35,7 @@ export const Field: React.FC<FieldProps> = ({
28
35
  }) => {
29
36
  return (
30
37
  <>
31
- <Label
32
- variant={disabled ? 'disabled' : 'above'}
33
- htmlFor={htmlFor}
34
- required={required}
35
- >
38
+ <Label variant={labelVariant} htmlFor={htmlFor} required={required}>
36
39
  {label}
37
40
  </Label>
38
41
  <Input
@@ -40,8 +43,7 @@ export const Field: React.FC<FieldProps> = ({
40
43
  type={type}
41
44
  id={htmlFor}
42
45
  disabled={disabled}
43
- variant={error ? 'error' : 'default'}
44
- className={className}
46
+ variant={variant}
45
47
  />
46
48
  {error && errorMessage && (
47
49
  <ValidationMessage>
@@ -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
+ );
@@ -0,0 +1,99 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { ThemeProvider } from '@marigold/system';
4
+
5
+ import { Inline } from './Inline';
6
+ import { Text } from '../Text';
7
+
8
+ // Setup
9
+ // ---------------
10
+ const theme = {
11
+ space: {
12
+ none: 0,
13
+ small: 2,
14
+ medium: 4,
15
+ large: 8,
16
+ },
17
+ };
18
+
19
+ const getLeftPadding = (element: HTMLElement) =>
20
+ getComputedStyle(element).getPropertyValue('padding-left');
21
+
22
+ test('default space is "none"', () => {
23
+ render(
24
+ <ThemeProvider theme={theme}>
25
+ <Inline>
26
+ <Text>first</Text>
27
+ <Text>second</Text>
28
+ </Inline>
29
+ </ThemeProvider>
30
+ );
31
+ const first = screen.getByText(/first/).parentElement!;
32
+ const second = screen.getByText(/second/).parentElement!;
33
+
34
+ expect(getLeftPadding(first)).toEqual('');
35
+ expect(second).toHaveStyle(`padding-left: 0px`);
36
+ });
37
+
38
+ test('accepts and uses spacing from theme', () => {
39
+ render(
40
+ <ThemeProvider theme={theme}>
41
+ <Inline space="small">
42
+ <Text>first</Text>
43
+ <Text>second</Text>
44
+ </Inline>
45
+ </ThemeProvider>
46
+ );
47
+ const first = screen.getByText(/first/);
48
+ const second = screen.getByText(/second/);
49
+
50
+ expect(getLeftPadding(first)).toEqual('');
51
+ expect(second.parentElement).toHaveStyle(`padding-left: 2px`);
52
+ });
53
+
54
+ test('supports nesting', () => {
55
+ render(
56
+ <ThemeProvider theme={theme}>
57
+ <Inline space="large">
58
+ <Inline space="small" data-testid="leftInline">
59
+ <Text>first</Text>
60
+ <Text>second</Text>
61
+ </Inline>
62
+ <Inline space="small" data-testid="rightInline">
63
+ <Text>third</Text>
64
+ <Text>fourth</Text>
65
+ </Inline>
66
+ </Inline>
67
+ </ThemeProvider>
68
+ );
69
+ const first = screen.getByText(/first/);
70
+ const second = screen.getByText(/second/);
71
+ const leftInline = screen.getByTestId('leftInline');
72
+
73
+ const third = screen.getByText(/third/);
74
+ const fourth = screen.getByText(/fourth/);
75
+ const rightInline = screen.getByTestId('rightInline');
76
+
77
+ expect(getLeftPadding(leftInline.parentElement!)).toEqual('');
78
+ expect(rightInline.parentElement).toHaveStyle(`padding-left: 8px`);
79
+
80
+ expect(getLeftPadding(first.parentElement!)).toEqual('');
81
+ expect(second.parentElement).toHaveStyle(`padding-left: 2px`);
82
+
83
+ expect(getLeftPadding(third.parentElement!)).toEqual('');
84
+ expect(fourth.parentElement).toHaveStyle(`padding-left: 2px`);
85
+ });
86
+
87
+ test('renders div per default', () => {
88
+ render(
89
+ <ThemeProvider theme={theme}>
90
+ <Inline data-testid="inline">
91
+ <Text>first</Text>
92
+ <Text>second</Text>
93
+ </Inline>
94
+ </ThemeProvider>
95
+ );
96
+
97
+ const inline = screen.getByTestId('inline');
98
+ expect(inline instanceof HTMLDivElement).toBeTruthy();
99
+ });
@@ -0,0 +1,38 @@
1
+ import React, { Children } from 'react';
2
+ import flattenChildren from 'react-keyed-flatten-children';
3
+
4
+ import { ResponsiveStyleValue } from '@marigold/system';
5
+
6
+ import { Box } from '../Box';
7
+
8
+ export type InlineProps = {
9
+ space?: ResponsiveStyleValue<string>;
10
+ align?: 'top' | 'center' | 'bottom';
11
+ };
12
+
13
+ const ALIGNMENT = {
14
+ top: 'flex-start',
15
+ center: 'center',
16
+ bottom: 'flex-end',
17
+ };
18
+
19
+ export const Inline: React.FC<InlineProps> = ({
20
+ space = 'none',
21
+ align = 'center',
22
+ children,
23
+ ...props
24
+ }) => (
25
+ <Box
26
+ display="inline-flex"
27
+ css={{ '> * + *': { pl: space } }}
28
+ alignItems={ALIGNMENT[align]}
29
+ {...props}
30
+ >
31
+ {Children.map(
32
+ flattenChildren(children) as unknown as React.ReactElement,
33
+ (child: React.ReactElement) => (
34
+ <Box>{React.cloneElement(child, {}, child.props.children)}</Box>
35
+ )
36
+ )}
37
+ </Box>
38
+ );
@@ -0,0 +1 @@
1
+ export * from './Inline';
@@ -1,10 +1,11 @@
1
- import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
1
+ import React from 'react';
2
+ import type { Meta, ComponentStory } from '@storybook/react';
2
3
  import { Input } from './Input';
3
4
  import { Label } from '../Label';
4
5
 
5
- <Meta
6
- title="Components/Input"
7
- argTypes={{
6
+ export default {
7
+ title: 'Components/Input',
8
+ argTypes: {
8
9
  variant: {
9
10
  control: {
10
11
  type: 'text',
@@ -12,7 +13,7 @@ import { Label } from '../Label';
12
13
  description: '?',
13
14
  table: {
14
15
  defaultValue: {
15
- summary: 'default',
16
+ summary: '__default',
16
17
  },
17
18
  },
18
19
  },
@@ -35,27 +36,19 @@ import { Label } from '../Label';
35
36
  'url',
36
37
  'week',
37
38
  ],
38
- type: { required: true },
39
+ defaultValue: 'text',
39
40
  table: {
40
41
  defaultValue: {
41
42
  summary: 'text',
42
43
  },
43
44
  },
44
45
  },
45
- }}
46
- />
46
+ },
47
+ } as Meta;
47
48
 
48
- # Input
49
-
50
- export const Template = args => (
49
+ export const Basic: ComponentStory<typeof Input> = args => (
51
50
  <Label htmlFor="input">
52
51
  Label
53
52
  <Input id="input" placeholder="Placeholder..." {...args} />
54
53
  </Label>
55
54
  );
56
-
57
- <Canvas>
58
- <Story name="Default">{Template.bind({})}</Story>
59
- </Canvas>
60
-
61
- <ArgsTable story="Default" />