@marigold/components 0.1.0 → 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 (112) 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 +16 -1
  4. package/dist/Box/Box.d.ts +2 -1
  5. package/dist/Button/Button.d.ts +4 -6
  6. package/dist/Card/Card.d.ts +9 -0
  7. package/dist/Card/index.d.ts +1 -0
  8. package/dist/Checkbox/Checkbox.d.ts +3 -0
  9. package/dist/Checkbox/CheckboxIcons.d.ts +9 -0
  10. package/dist/Column/Column.d.ts +3 -1
  11. package/dist/Dialog/Dialog.d.ts +8 -1
  12. package/dist/Dialog/ModalDialog.d.ts +5 -0
  13. package/dist/Field/Field.d.ts +4 -2
  14. package/dist/Label/Label.d.ts +2 -1
  15. package/dist/Provider/MarigoldProvider.d.ts +3 -0
  16. package/dist/Provider/index.d.ts +3 -0
  17. package/dist/Radio/Radio.d.ts +3 -0
  18. package/dist/Radio/RadioIcons.d.ts +9 -0
  19. package/dist/Select/ListBox.d.ts +8 -0
  20. package/dist/Select/ListBoxSection.d.ts +8 -0
  21. package/dist/Select/Option.d.ts +8 -0
  22. package/dist/Select/Popover.d.ts +9 -0
  23. package/dist/Select/Select.d.ts +11 -4
  24. package/dist/Stack/Stack.d.ts +1 -3
  25. package/dist/Textarea/Textarea.d.ts +2 -1
  26. package/dist/components.cjs.development.js +868 -357
  27. package/dist/components.cjs.development.js.map +1 -1
  28. package/dist/components.cjs.production.min.js +1 -1
  29. package/dist/components.cjs.production.min.js.map +1 -1
  30. package/dist/components.esm.js +837 -359
  31. package/dist/components.esm.js.map +1 -1
  32. package/dist/index.d.ts +4 -0
  33. package/package.json +18 -3
  34. package/src/ActionGroup/ActionGroup.stories.mdx +62 -0
  35. package/src/ActionGroup/ActionGroup.test.tsx +83 -0
  36. package/src/ActionGroup/ActionGroup.tsx +43 -0
  37. package/src/ActionGroup/index.ts +1 -0
  38. package/src/Alert/Alert.stories.mdx +28 -38
  39. package/src/Alert/Alert.test.tsx +1 -1
  40. package/src/Alert/Alert.tsx +11 -33
  41. package/src/Badge/Badge.stories.mdx +48 -34
  42. package/src/Badge/Badge.test.tsx +7 -15
  43. package/src/Badge/Badge.tsx +1 -2
  44. package/src/Box/Box.stories.mdx +322 -26
  45. package/src/Box/Box.tsx +58 -50
  46. package/src/Button/Button.stories.mdx +54 -166
  47. package/src/Button/Button.test.tsx +48 -8
  48. package/src/Button/Button.tsx +47 -18
  49. package/src/Card/Card.stories.mdx +49 -0
  50. package/src/Card/Card.test.tsx +66 -0
  51. package/src/Card/Card.tsx +36 -0
  52. package/src/Card/index.ts +1 -0
  53. package/src/Checkbox/Checkbox.stories.mdx +76 -71
  54. package/src/Checkbox/Checkbox.test.tsx +70 -24
  55. package/src/Checkbox/Checkbox.tsx +68 -49
  56. package/src/Checkbox/CheckboxIcons.tsx +49 -0
  57. package/src/Column/Column.stories.mdx +39 -64
  58. package/src/Column/Column.test.tsx +8 -0
  59. package/src/Column/Column.tsx +12 -2
  60. package/src/Columns/Columns.stories.mdx +58 -240
  61. package/src/Container/Container.stories.mdx +8 -25
  62. package/src/Dialog/Dialog.stories.mdx +65 -56
  63. package/src/Dialog/Dialog.test.tsx +64 -24
  64. package/src/Dialog/Dialog.tsx +64 -12
  65. package/src/Dialog/ModalDialog.tsx +47 -0
  66. package/src/Divider/Divider.stories.mdx +28 -34
  67. package/src/Field/Field.stories.mdx +88 -48
  68. package/src/Field/Field.test.tsx +31 -40
  69. package/src/Field/Field.tsx +26 -21
  70. package/src/Heading/Heading.stories.mdx +30 -82
  71. package/src/Hidden/Hidden.stories.mdx +29 -54
  72. package/src/Image/Image.stories.mdx +26 -30
  73. package/src/Input/Input.stories.mdx +52 -36
  74. package/src/Label/Label.stories.mdx +47 -29
  75. package/src/Label/Label.test.tsx +15 -1
  76. package/src/Label/Label.tsx +20 -7
  77. package/src/Link/Link.stories.mdx +36 -29
  78. package/src/Menu/Menu.stories.mdx +71 -39
  79. package/src/Menu/Menu.test.tsx +4 -4
  80. package/src/Menu/Menu.tsx +12 -14
  81. package/src/MenuItem/MenuItem.stories.mdx +32 -27
  82. package/src/MenuItem/MenuItem.test.tsx +15 -11
  83. package/src/MenuItem/MenuItem.tsx +7 -10
  84. package/src/Message/Message.stories.mdx +35 -35
  85. package/src/Message/Message.tsx +2 -10
  86. package/src/Provider/MarigoldProvider.test.tsx +126 -0
  87. package/src/Provider/MarigoldProvider.tsx +29 -0
  88. package/src/Provider/index.ts +3 -0
  89. package/src/Radio/Radio.stories.mdx +78 -92
  90. package/src/Radio/Radio.test.tsx +57 -15
  91. package/src/Radio/Radio.tsx +71 -51
  92. package/src/Radio/RadioIcons.tsx +39 -0
  93. package/src/Select/ListBox.tsx +39 -0
  94. package/src/Select/ListBoxSection.tsx +40 -0
  95. package/src/Select/Option.tsx +48 -0
  96. package/src/Select/Popover.tsx +50 -0
  97. package/src/Select/Select.stories.mdx +70 -36
  98. package/src/Select/Select.test.tsx +279 -35
  99. package/src/Select/Select.tsx +151 -18
  100. package/src/Slider/Slider.stories.mdx +22 -49
  101. package/src/Stack/Stack.stories.mdx +40 -94
  102. package/src/Stack/Stack.test.tsx +84 -65
  103. package/src/Stack/Stack.tsx +25 -41
  104. package/src/Text/Text.stories.mdx +52 -52
  105. package/src/Text/Text.tsx +13 -14
  106. package/src/Textarea/Textarea.stories.mdx +65 -56
  107. package/src/Textarea/Textarea.test.tsx +4 -5
  108. package/src/Textarea/Textarea.tsx +28 -37
  109. package/src/ValidationMessage/ValidationMessage.stories.mdx +26 -26
  110. package/src/ValidationMessage/ValidationMessage.test.tsx +4 -4
  111. package/src/ValidationMessage/ValidationMessage.tsx +11 -12
  112. package/src/index.ts +5 -0
@@ -1,81 +1,86 @@
1
- import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks';
1
+ import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
2
2
  import { Checkbox } from './Checkbox';
3
3
  import { useState } from 'react';
4
- import { useStyles } from '@marigold/system';
5
4
 
6
- <Meta title="Components/Checkbox" />
5
+ <Meta
6
+ title="Components/Checkbox"
7
+ parameters={{
8
+ actions: {
9
+ handles: ['click'],
10
+ },
11
+ }}
12
+ argTypes={{
13
+ id: {
14
+ control: {
15
+ type: 'text',
16
+ },
17
+ type: { required: true },
18
+ description: 'Unique ID',
19
+ },
20
+ variant: {
21
+ control: {
22
+ type: 'text',
23
+ },
24
+ description: 'Checkbox variant',
25
+ table: {
26
+ defaultValue: {
27
+ summary: 'default',
28
+ },
29
+ },
30
+ },
31
+ label: {
32
+ control: {
33
+ type: 'text',
34
+ },
35
+ description: 'Label',
36
+ },
37
+ required: {
38
+ control: {
39
+ type: 'boolean',
40
+ },
41
+ description: 'Require',
42
+ table: {
43
+ defaultValue: {
44
+ summary: false,
45
+ },
46
+ },
47
+ },
48
+ error: {
49
+ control: {
50
+ type: 'boolean',
51
+ },
52
+ description: 'Error',
53
+ table: {
54
+ defaultValue: {
55
+ summary: false,
56
+ },
57
+ },
58
+ },
59
+ errorMessage: {
60
+ control: {
61
+ type: 'text',
62
+ },
63
+ description: 'Error Message',
64
+ },
65
+ }}
66
+ />
7
67
 
8
68
  # Checkbox
9
69
 
10
- ## Description
11
-
12
- With the Checkbox component you can add a HTML `<input>` element with `type="checkbox"` to your form.
13
- The element uses always the themeSection with the name: `checkbox` in your given theme. The variant in your section can be added with the variant prop. The default variant is `default`.
14
-
15
- ## Properties
16
-
17
- | Property | Type | Default |
18
- | :-------------------- | :-------- | :-------- |
19
- | `id` | `string` | |
20
- | `variant` (optional) | `string` | `default` |
21
- | `label` (optional) | `string` | |
22
- | `required` (optional) | `boolean` | |
23
-
24
- ## Import
25
-
26
- ```tsx
27
- import { Checkbox } from '@marigold/components';
28
- ```
29
-
30
- ## Usage
31
-
32
- ### Checkbox standard labeled
70
+ export const Template = ({ onChange, checked, ...args }) => {
71
+ const [isChecked, setChecked] = useState(false);
72
+ return (
73
+ <Checkbox
74
+ onChange={() => setChecked(!isChecked)}
75
+ checked={isChecked}
76
+ label="Checkbox Label"
77
+ {...args}
78
+ />
79
+ );
80
+ };
33
81
 
34
82
  <Canvas>
35
- <Story name="CheckboxOne">
36
- {() => {
37
- const [isChecked, setChecked] = React.useState(false);
38
- const onChange = () => {
39
- setChecked(!isChecked);
40
- };
41
- return (
42
- <Checkbox
43
- id="myCheckbox"
44
- name="myCheckbox"
45
- onChange={onChange}
46
- checked={isChecked}
47
- value="Checkbox"
48
- label="check if you like Marigold"
49
- />
50
- );
51
- }}
52
- </Story>
83
+ <Story name="Default">{Template.bind({})}</Story>
53
84
  </Canvas>
54
85
 
55
- ### Checkbox checked, disabled and custom styled
56
-
57
- <Canvas>
58
- <Story name="CheckboxTwo">
59
- <>
60
- <Checkbox id="checkboxOne" checked />
61
- <Checkbox id="checkboxTwo" disabled />
62
- <Checkbox id="checkboxThree" checked disabled />
63
- </>
64
- </Story>
65
- </Canvas>
66
-
67
- ### Checkbox with required label
68
-
69
- <Canvas>
70
- <Story name="CheckboxThree">
71
- <div>
72
- <Checkbox
73
- checked
74
- id="required"
75
- value="required"
76
- required
77
- label="This label is required"
78
- />
79
- </div>
80
- </Story>
81
- </Canvas>
86
+ <ArgsTable story="Default" />
@@ -1,51 +1,97 @@
1
1
  import React from 'react';
2
- import { render, screen, fireEvent } from '@testing-library/react';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import { Checkbox } from './Checkbox';
4
+ import { ThemeProvider } from '@marigold/system';
5
+
6
+ const theme = {
7
+ checkbox: {
8
+ default: {
9
+ m: '2px',
10
+ },
11
+ },
12
+ };
4
13
 
5
14
  test('supports label prop', () => {
6
15
  render(<Checkbox label="Test" id="test" title="checkbox" />);
7
- const checkbox = screen.getByText(/Test/);
8
16
 
9
- expect(checkbox).toBeDefined();
17
+ const checkboxLabel = screen.getByText(/Test/);
18
+ expect(checkboxLabel).toBeDefined();
10
19
  });
11
20
 
12
- test('supports required prop an renders required icon', () => {
21
+ test('supports required prop and renders required icon', () => {
13
22
  render(<Checkbox label="Test" id="test" required title="checkbox" />);
14
- const checkbox = screen.getByText(/Test/);
15
23
 
16
- expect(checkbox).toContainHTML('path d="M10.8');
24
+ const label = screen.getByText(/Test/);
25
+ expect(label.nextSibling).toContainHTML('path d="M10.8');
17
26
  });
18
27
 
19
28
  test('supports default type', () => {
20
- render(<Checkbox id="test" title="checkbox" />);
21
- const checkbox = screen.getByTitle(/checkbox/);
29
+ render(<Checkbox id="checkbox" title="checkbox" />);
22
30
 
31
+ const checkbox = screen.getByTitle(/checkbox/);
23
32
  expect(checkbox.getAttribute('type')).toEqual('checkbox');
24
33
  });
25
34
 
26
35
  test('renders <input> element', () => {
27
- render(<Checkbox id="test" title="checkbox" />);
28
- const checkbox = screen.getByTitle(/checkbox/);
36
+ render(<Checkbox id="checkbox" title="checkbox" />);
29
37
 
38
+ const checkbox = screen.getByTitle(/checkbox/);
30
39
  expect(checkbox instanceof HTMLInputElement).toBeTruthy();
31
40
  });
32
41
 
33
- test('renders <SVG> SquareUnchecked element', () => {
34
- render(<Checkbox id="checkbox" label="Test" />);
35
- const checkbox = screen.getByText(/Test/);
36
- expect(checkbox).toContainHTML('path d="M19.2917');
42
+ test('supports disabled prop', () => {
43
+ render(
44
+ <ThemeProvider theme={theme}>
45
+ <Checkbox id="test" title="checkbox" label="label" disabled />
46
+ </ThemeProvider>
47
+ );
48
+
49
+ const checkbox = screen.getByTitle(/checkbox/);
50
+ expect(checkbox).toHaveAttribute('disabled');
37
51
  });
38
52
 
39
- test('renders <SVG> SquareChecked element', () => {
40
- render(<Checkbox id="checkbox" label="Test" checked onChange={() => {}} />);
41
- const checkbox = screen.getByText(/Test/);
42
- expect(checkbox).toContainHTML('path d="M19.2917 2.62');
53
+ test('supports error and errorMessage prop', () => {
54
+ render(
55
+ <ThemeProvider theme={theme}>
56
+ <Checkbox
57
+ id="test"
58
+ title="checkbox"
59
+ label="test"
60
+ error
61
+ errorMessage="error"
62
+ />
63
+ </ThemeProvider>
64
+ );
65
+
66
+ const errorMessage = screen.getByText(/error/);
67
+ expect(errorMessage).toBeDefined();
43
68
  });
44
69
 
45
- test('change state onClick', () => {
46
- render(<Checkbox id="checkbox" label="Test" />);
47
- const checkbox = screen.getByText(/Test/);
48
- expect(checkbox).toContainHTML('path d="M19.2917');
49
- fireEvent.click(checkbox);
50
- expect(checkbox).toContainHTML('path d="M19.2917');
70
+ test('supports checked checkbox', () => {
71
+ render(
72
+ <ThemeProvider theme={theme}>
73
+ <Checkbox id="test" title="checkbox" onChange={() => {}} checked />
74
+ </ThemeProvider>
75
+ );
76
+
77
+ const checkbox = screen.getByTitle(/checkbox/);
78
+ expect(checkbox).toBeDefined();
79
+ });
80
+
81
+ test('supports checked and disabled checkbox', () => {
82
+ render(
83
+ <ThemeProvider theme={theme}>
84
+ <Checkbox
85
+ id="test"
86
+ title="checkbox"
87
+ onChange={() => {}}
88
+ checked
89
+ disabled
90
+ />
91
+ </ThemeProvider>
92
+ );
93
+
94
+ const checkbox = screen.getByTitle(/checkbox/);
95
+ expect(checkbox).toBeDefined();
96
+ expect(checkbox).toHaveAttribute('disabled');
51
97
  });
@@ -1,79 +1,83 @@
1
1
  import React from 'react';
2
- import { Required, SquareUnchecked, SquareChecked } from '@marigold/icons';
3
- import { useStyles } from '@marigold/system';
4
2
  import { ComponentProps } from '@marigold/types';
3
+ import { Exclamation } from '@marigold/icons';
4
+
5
+ import { CheckboxChecked, CheckboxUnchecked } from './CheckboxIcons';
5
6
 
6
7
  import { Box } from '../Box';
7
8
  import { Label } from '../Label';
9
+ import { ValidationMessage } from '../ValidationMessage';
8
10
 
9
11
  // Checkbox Icon
10
12
  // ---------------
11
13
  type CheckboxIconProps = {
12
- className?: string;
13
14
  variant?: string;
14
15
  checked?: boolean;
16
+ disabled?: boolean;
15
17
  children?: never;
18
+ error?: boolean;
16
19
  };
17
20
 
18
21
  const CheckboxIcon: React.FC<CheckboxIconProps> = ({
19
- className,
20
22
  variant,
21
23
  checked,
24
+ disabled,
25
+ error,
22
26
  }) => {
23
- const checkboxIconStyle = useStyles({
24
- variant: variant,
25
- css: {
26
- ariaHidden: 'true',
27
- mr: 2,
28
- verticalAlign: 'middle',
29
- ':hover': { cursor: 'pointer' },
30
- 'input:disabled ~ &': {
31
- color: 'disabled',
32
- cursor: 'not-allowed',
33
- },
34
- },
35
- className,
36
- });
37
-
38
27
  if (checked) {
39
- return <SquareChecked className={checkboxIconStyle} />;
28
+ return (
29
+ <Box
30
+ as={CheckboxChecked}
31
+ variant={`checkbox.${variant}`}
32
+ disabled={disabled}
33
+ />
34
+ );
40
35
  }
41
- return <SquareUnchecked className={checkboxIconStyle} />;
36
+ return (
37
+ <Box
38
+ as={CheckboxUnchecked}
39
+ variant={`checkbox.${variant}`}
40
+ disabled={disabled}
41
+ error={error}
42
+ />
43
+ );
42
44
  };
43
45
 
44
46
  // Checkbox Input
45
47
  // ---------------
46
48
  type CheckboxInputProps = {
47
49
  variant?: string;
50
+ error?: boolean;
48
51
  } & ComponentProps<'input'>;
49
52
 
50
53
  const CheckboxInput: React.FC<CheckboxInputProps> = ({
51
54
  className,
52
55
  variant = 'default',
56
+ error,
53
57
  ...props
54
- }) => {
55
- const checkboxStyle = useStyles({
56
- css: {
57
- position: 'absolute',
58
- opacity: 0,
59
- zIndex: -1,
60
- width: 1,
61
- height: 1,
62
- overflow: 'hidden',
63
- },
64
- });
65
-
66
- return (
67
- <Box display="inline-block">
68
- <input type="checkbox" className={checkboxStyle} {...props} />
69
- <CheckboxIcon
70
- checked={props.checked}
71
- className={className}
72
- variant={variant}
73
- />
74
- </Box>
75
- );
76
- };
58
+ }) => (
59
+ <Box display="inline-block" className={className}>
60
+ <Box
61
+ as="input"
62
+ type="checkbox"
63
+ css={{
64
+ position: 'absolute',
65
+ opacity: 0,
66
+ zIndex: -1,
67
+ width: 1,
68
+ height: 1,
69
+ overflow: 'hidden',
70
+ }}
71
+ {...props}
72
+ />
73
+ <CheckboxIcon
74
+ checked={props.checked}
75
+ variant={variant}
76
+ disabled={props.disabled}
77
+ error={error}
78
+ />
79
+ </Box>
80
+ );
77
81
 
78
82
  // Checkbox
79
83
  // ---------------
@@ -81,20 +85,35 @@ export type CheckboxProps = {
81
85
  id: string;
82
86
  label?: string;
83
87
  required?: boolean;
88
+ error?: boolean;
89
+ errorMessage?: string;
84
90
  } & CheckboxInputProps;
85
91
 
86
92
  export const Checkbox: React.FC<CheckboxProps> = ({
87
93
  label,
88
94
  required,
95
+ error,
96
+ errorMessage,
89
97
  ...props
90
98
  }) => {
91
99
  if (label) {
92
100
  return (
93
- <Label htmlFor={props.id}>
94
- <CheckboxInput {...props} />
95
- {label}
96
- {required && <Required size={16} />}
97
- </Label>
101
+ <>
102
+ <Label
103
+ htmlFor={props.id}
104
+ required={required}
105
+ variant={props.disabled ? 'disabled' : 'inline'}
106
+ >
107
+ <Box as={CheckboxInput} pr="8px" error={error} {...props} />
108
+ {label}
109
+ </Label>
110
+ {error && errorMessage && (
111
+ <ValidationMessage>
112
+ <Exclamation size={16} />
113
+ {errorMessage}
114
+ </ValidationMessage>
115
+ )}
116
+ </>
98
117
  );
99
118
  }
100
119
 
@@ -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
+ );
@@ -1,74 +1,49 @@
1
- import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks';
1
+ import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
2
2
  import { Column } from './Column';
3
- import { useState } from 'react';
3
+ import { Text } from '../Text';
4
4
  import { useStyles } from '@marigold/system';
5
5
 
6
- <Meta title="Components/Column" />
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
+ />
7
25
 
8
26
  # Column
9
27
 
10
- ## Description
11
-
12
- With the Column component you can add a column with a width in percent of the full content.
13
-
14
- ## Properties
15
-
16
- | Property | Type | Default |
17
- | :----------------- | :-------------------------------------- | :------ |
18
- | `width` (optional) | `1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12` | `12` |
19
-
20
- ## Import
21
-
22
- ```tsx
23
- import { Column } from '@marigold/components';
24
- ```
25
-
26
- ## Usage
27
-
28
- <Canvas>
29
- <Story name="Column">
30
- <Column
31
- className={useStyles({
32
- textAlign: 'center',
33
- border: '1px solid',
34
- padding: 2,
35
- margin: 2,
36
- })}
37
- >
38
- width=12
39
- </Column>
40
- <Column
41
- width={6}
42
- className={useStyles({
43
- textAlign: 'center',
44
- border: '1px solid',
45
- padding: 2,
46
- margin: 2,
47
- })}
48
- >
49
- width=6
50
- </Column>
51
- <Column
52
- width={3}
53
- className={useStyles({
54
- textAlign: 'center',
55
- border: '1px solid',
56
- padding: 2,
57
- margin: 2,
58
- })}
59
- >
60
- width=3
61
- </Column>
62
- <Column
63
- width={2}
64
- className={useStyles({
28
+ export const Template = args => (
29
+ <Column
30
+ className={useStyles({
31
+ css: {
65
32
  textAlign: 'center',
66
- border: '1px solid',
33
+ border: '1px solid red',
67
34
  padding: 2,
68
35
  margin: 2,
69
- })}
70
- >
71
- width=2
72
- </Column>
73
- </Story>
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>
74
47
  </Canvas>
48
+
49
+ <ArgsTable story="Default" />
@@ -22,3 +22,11 @@ test('accepts custom styles prop className', () => {
22
22
 
23
23
  expect(column.className).toMatch('custom-class-name');
24
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
+ });
@@ -1,9 +1,19 @@
1
1
  import React from 'react';
2
2
  import { Box } from '../Box';
3
3
 
4
+ type WidthValues = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
5
+
4
6
  export type ColumnProps = {
5
7
  className?: string;
6
- width?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
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}%`;
7
17
  };
8
18
 
9
19
  export const Column: React.FC<ColumnProps> = ({
@@ -11,7 +21,7 @@ export const Column: React.FC<ColumnProps> = ({
11
21
  children,
12
22
  ...props
13
23
  }) => (
14
- <Box {...props} width={`${(width / 12) * 100}%`}>
24
+ <Box {...props} width={transform(width)}>
15
25
  {children}
16
26
  </Box>
17
27
  );