@marigold/components 0.2.0 → 0.3.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 (195) hide show
  1. package/CHANGELOG.md +294 -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 +10 -13
  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 +5 -0
  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 +4 -1
  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 +6 -0
  47. package/dist/Radio/RadioIcons.d.ts +1 -0
  48. package/dist/Select/ListBox.d.ts +1 -0
  49. package/dist/Select/ListBoxSection.d.ts +1 -0
  50. package/dist/Select/Option.d.ts +1 -0
  51. package/dist/Select/Select.d.ts +15 -1
  52. package/dist/Select/Select.stories.d.ts +5 -0
  53. package/dist/Slider/Slider.d.ts +5 -0
  54. package/dist/Slider/Slider.stories.d.ts +5 -0
  55. package/dist/Stack/Stack.stories.d.ts +5 -0
  56. package/dist/Text/Text.d.ts +5 -0
  57. package/dist/Text/Text.stories.d.ts +5 -0
  58. package/dist/Textarea/Textarea.d.ts +5 -0
  59. package/dist/Textarea/Textarea.stories.d.ts +5 -0
  60. package/dist/ValidationMessage/ValidationMessage.d.ts +5 -0
  61. package/dist/ValidationMessage/ValidationMessage.stories.d.ts +5 -0
  62. package/dist/VisuallyHidden/VisuallyHidden.d.ts +1 -0
  63. package/dist/VisuallyHidden/VisuallyHidden.stories.d.ts +5 -0
  64. package/dist/VisuallyHidden/index.d.ts +1 -0
  65. package/dist/components.cjs.development.js +480 -496
  66. package/dist/components.cjs.development.js.map +1 -1
  67. package/dist/components.cjs.production.min.js +1 -1
  68. package/dist/components.cjs.production.min.js.map +1 -1
  69. package/dist/components.esm.js +415 -441
  70. package/dist/components.esm.js.map +1 -1
  71. package/dist/index.d.ts +2 -2
  72. package/dist/theme.d.ts +23 -48
  73. package/package.json +4 -1
  74. package/src/ActionGroup/ActionGroup.stories.tsx +47 -0
  75. package/src/ActionGroup/ActionGroup.test.tsx +36 -36
  76. package/src/ActionGroup/ActionGroup.tsx +17 -28
  77. package/src/Alert/Alert.stories.tsx +32 -0
  78. package/src/Alert/Alert.test.tsx +4 -1
  79. package/src/Alert/Alert.tsx +18 -3
  80. package/src/Badge/Badge.stories.tsx +38 -0
  81. package/src/Badge/Badge.test.tsx +5 -1
  82. package/src/Badge/Badge.tsx +13 -1
  83. package/src/Box.ts +2 -0
  84. package/src/Button/{Button.stories.mdx → Button.stories.tsx} +10 -17
  85. package/src/Button/Button.test.tsx +34 -11
  86. package/src/Button/Button.tsx +17 -3
  87. package/src/Card/{Card.stories.mdx → Card.stories.tsx} +9 -17
  88. package/src/Card/Card.test.tsx +8 -3
  89. package/src/Card/Card.tsx +13 -1
  90. package/src/Checkbox/Checkbox.stories.mdx +11 -0
  91. package/src/Checkbox/Checkbox.stories.tsx +78 -0
  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/Columns/Columns.stories.tsx +75 -0
  97. package/src/Columns/Columns.test.tsx +34 -23
  98. package/src/Columns/Columns.tsx +30 -30
  99. package/src/Container/Container.stories.tsx +14 -0
  100. package/src/Dialog/{Dialog.stories.mdx → Dialog.stories.tsx} +33 -18
  101. package/src/Dialog/Dialog.test.tsx +91 -20
  102. package/src/Dialog/Dialog.tsx +63 -17
  103. package/src/Dialog/ModalDialog.tsx +33 -4
  104. package/src/Divider/{Divider.stories.mdx → Divider.stories.tsx} +10 -17
  105. package/src/Divider/Divider.test.tsx +13 -5
  106. package/src/Divider/Divider.tsx +12 -0
  107. package/src/Field/{Field.stories.mdx → Field.stories.tsx} +33 -20
  108. package/src/Field/Field.test.tsx +55 -5
  109. package/src/Field/Field.tsx +10 -8
  110. package/src/Image/Image.stories.tsx +34 -0
  111. package/src/Image/Image.test.tsx +4 -1
  112. package/src/Image/Image.tsx +13 -1
  113. package/src/Inline/Inline.stories.tsx +39 -0
  114. package/src/Inline/Inline.test.tsx +99 -0
  115. package/src/Inline/Inline.tsx +38 -0
  116. package/src/Inline/index.ts +1 -0
  117. package/src/Input/{Input.stories.mdx → Input.stories.tsx} +10 -17
  118. package/src/Input/Input.test.tsx +7 -3
  119. package/src/Input/Input.tsx +13 -1
  120. package/src/Label/{Label.stories.mdx → Label.stories.tsx} +10 -21
  121. package/src/Label/Label.test.tsx +25 -4
  122. package/src/Label/Label.tsx +42 -9
  123. package/src/Link/Link.stories.tsx +35 -0
  124. package/src/Link/Link.test.tsx +6 -2
  125. package/src/Link/Link.tsx +10 -0
  126. package/src/Menu/{Menu.stories.mdx → Menu.stories.tsx} +13 -32
  127. package/src/Menu/Menu.test.tsx +7 -2
  128. package/src/Menu/Menu.tsx +10 -0
  129. package/src/MenuItem/MenuItem.stories.tsx +30 -0
  130. package/src/MenuItem/MenuItem.test.tsx +7 -2
  131. package/src/MenuItem/MenuItem.tsx +12 -0
  132. package/src/Message/Message.stories.tsx +30 -0
  133. package/src/Message/Message.test.tsx +4 -1
  134. package/src/Message/Message.tsx +17 -5
  135. package/src/Provider/MarigoldProvider.test.tsx +65 -55
  136. package/src/Provider/MarigoldProvider.tsx +37 -19
  137. package/src/Provider/index.ts +2 -1
  138. package/src/Radio/Radio.stories.mdx +11 -0
  139. package/src/Radio/Radio.test.tsx +36 -2
  140. package/src/Radio/Radio.tsx +13 -2
  141. package/src/Radio/RadioIcons.tsx +1 -1
  142. package/src/Select/ListBox.tsx +1 -0
  143. package/src/Select/{Select.stories.mdx → Select.stories.tsx} +23 -20
  144. package/src/Select/Select.test.tsx +39 -1
  145. package/src/Select/Select.tsx +24 -13
  146. package/src/Slider/Slider.stories.tsx +24 -0
  147. package/src/Slider/Slider.test.tsx +10 -6
  148. package/src/Slider/Slider.tsx +25 -13
  149. package/src/Stack/Stack.stories.tsx +57 -0
  150. package/src/Stack/Stack.test.tsx +16 -7
  151. package/src/Text/{Text.stories.mdx → Text.stories.tsx} +20 -19
  152. package/src/Text/Text.test.tsx +2 -2
  153. package/src/Text/Text.tsx +12 -0
  154. package/src/Textarea/{Textarea.stories.mdx → Textarea.stories.tsx} +14 -24
  155. package/src/Textarea/Textarea.test.tsx +7 -3
  156. package/src/Textarea/Textarea.tsx +13 -1
  157. package/src/ValidationMessage/{ValidationMessage.stories.mdx → ValidationMessage.stories.tsx} +8 -17
  158. package/src/ValidationMessage/ValidationMessage.test.tsx +7 -2
  159. package/src/ValidationMessage/ValidationMessage.tsx +12 -0
  160. package/src/VisuallyHidden/VisuallyHidden.stories.tsx +19 -0
  161. package/src/VisuallyHidden/VisuallyHidden.test.tsx +10 -0
  162. package/src/VisuallyHidden/VisuallyHidden.tsx +1 -0
  163. package/src/VisuallyHidden/index.ts +1 -0
  164. package/src/index.ts +2 -2
  165. package/src/theme.ts +49 -48
  166. package/dist/Box/Box.d.ts +0 -47
  167. package/dist/Box/index.d.ts +0 -1
  168. package/dist/Heading/Heading.d.ts +0 -7
  169. package/dist/Heading/index.d.ts +0 -1
  170. package/dist/Hidden/Hidden.d.ts +0 -5
  171. package/dist/Hidden/index.d.ts +0 -1
  172. package/src/ActionGroup/ActionGroup.stories.mdx +0 -62
  173. package/src/Alert/Alert.stories.mdx +0 -35
  174. package/src/Badge/Badge.stories.mdx +0 -57
  175. package/src/Box/Box.stories.mdx +0 -334
  176. package/src/Box/Box.test.tsx +0 -133
  177. package/src/Box/Box.tsx +0 -165
  178. package/src/Box/index.ts +0 -1
  179. package/src/Column/Column.stories.mdx +0 -49
  180. package/src/Columns/Columns.stories.mdx +0 -65
  181. package/src/Container/Container.stories.mdx +0 -19
  182. package/src/Heading/Heading.stories.mdx +0 -39
  183. package/src/Heading/Heading.test.tsx +0 -77
  184. package/src/Heading/Heading.tsx +0 -19
  185. package/src/Heading/index.ts +0 -1
  186. package/src/Hidden/Hidden.stories.mdx +0 -39
  187. package/src/Hidden/Hidden.test.tsx +0 -24
  188. package/src/Hidden/Hidden.tsx +0 -16
  189. package/src/Hidden/index.ts +0 -1
  190. package/src/Image/Image.stories.mdx +0 -36
  191. package/src/Link/Link.stories.mdx +0 -45
  192. package/src/MenuItem/MenuItem.stories.mdx +0 -37
  193. package/src/Message/Message.stories.mdx +0 -44
  194. package/src/Slider/Slider.stories.mdx +0 -31
  195. package/src/Stack/Stack.stories.mdx +0 -51
@@ -1,16 +1,22 @@
1
1
  import React from 'react';
2
2
  import { useTheme } from '@marigold/system';
3
3
  import { render, screen } from '@testing-library/react';
4
- import { useModal } from '@react-aria/overlays';
5
4
 
6
5
  import { MarigoldProvider } from './MarigoldProvider';
7
6
 
8
7
  // Setup
9
8
  // ---------------
10
9
  const theme = {
10
+ colors: {
11
+ black: '#000',
12
+ },
13
+ fontSizes: {
14
+ body: 16,
15
+ heading: 32,
16
+ },
11
17
  text: {
12
18
  body: {
13
- fontSize: 1,
19
+ fontSize: 'body',
14
20
  color: 'black',
15
21
  },
16
22
  },
@@ -64,63 +70,67 @@ test('themes can be cascaded', () => {
64
70
  `);
65
71
  });
66
72
 
67
- // if theres no OverlayProvider you got an error with text: Modal is not contained within a provider
68
- test('OverlayProvider is present and supports useModal hook', () => {
69
- const ChildComponent: React.FC = ({ children }) => {
70
- const { modalProps } = useModal();
71
- return <div {...modalProps}>{children}</div>;
72
- };
73
+ test('OverlayProvider is added', () => {
74
+ const { container } = render(
75
+ <MarigoldProvider theme={theme}>Test</MarigoldProvider>
76
+ );
73
77
 
74
- render(
78
+ expect(
79
+ container.querySelector(`div[data-overlay-container="true"]`)
80
+ ).toBeDefined();
81
+ });
82
+
83
+ test('OverlayProvider is added only once', () => {
84
+ const innerTheme = { colors: { primary: 'red' } };
85
+ const { container } = render(
75
86
  <MarigoldProvider theme={theme}>
76
- <ChildComponent>Test</ChildComponent>
87
+ <MarigoldProvider theme={innerTheme}>Test</MarigoldProvider>
77
88
  </MarigoldProvider>
78
89
  );
79
90
 
80
- const childComp = screen.getByText('Test');
81
- expect(childComp).toBeDefined();
91
+ expect(
92
+ container.querySelectorAll(`div[data-overlay-container="true"]`).length
93
+ ).toEqual(1);
82
94
  });
83
95
 
84
- // test('renders global styles for body and html based on root in theme', () => {
85
- // const root = render(
86
- // <MarigoldProvider
87
- // theme={{
88
- // fonts: {
89
- // body: 'Inter',
90
- // html: 'Roboto',
91
- // },
92
- // lineHeights: {
93
- // body: 1.5,
94
- // html: 1,
95
- // },
96
- // fontWeights: {
97
- // body: 500,
98
- // html: 700,
99
- // },
100
- // root: {
101
- // body: {
102
- // fontFamily: 'body',
103
- // lineHeight: 'body',
104
- // fontWeight: 'body',
105
- // },
106
- // html: {
107
- // fontFamily: 'html',
108
- // lineHeight: 'html',
109
- // fontWeight: 'html',
110
- // }
111
- // },
112
- // }}
113
- // >
114
- // <h1 title="h1">Hello</h1>
115
- // </MarigoldProvider>
116
- // );
117
-
118
- // const html = window.getComputedStyle(root.baseElement.parentElement!);
119
- // expect(html.fontFamily).toBe('Roboto');
120
- // expect(html.fontWeight).toBe('700');
121
- // expect(html.lineHeight).toBe('1');
122
- // const body = window.getComputedStyle(root.baseElement);
123
- // expect(body.fontFamily).toBe('Inter');
124
- // expect(body.fontWeight).toBe('500');
125
- // expect(body.lineHeight).toBe('1.5');
126
- // });
96
+ test('applies global styles for body and html based on `theme.root`', () => {
97
+ const theme = {
98
+ fonts: {
99
+ body: 'Inter',
100
+ html: 'Roboto',
101
+ },
102
+ lineHeights: {
103
+ body: 2.5,
104
+ },
105
+ fontWeights: {
106
+ body: 500,
107
+ html: 700,
108
+ },
109
+ root: {
110
+ body: {
111
+ fontFamily: 'body',
112
+ lineHeight: 'body',
113
+ fontWeight: 'body',
114
+ },
115
+ html: {
116
+ fontFamily: 'html',
117
+ fontWeight: 'html',
118
+ },
119
+ },
120
+ };
121
+
122
+ const root = render(
123
+ <MarigoldProvider theme={theme}>
124
+ <h1>Hello</h1>
125
+ </MarigoldProvider>
126
+ );
127
+
128
+ const html = root.baseElement.parentElement;
129
+ expect(html).toHaveStyle(`font-family: ${theme.fonts.html}`);
130
+ expect(html).toHaveStyle(`font-weight: ${theme.fontWeights.html}`);
131
+
132
+ const body = root.baseElement;
133
+ expect(body).toHaveStyle(`font-family: ${theme.fonts.body}`);
134
+ expect(body).toHaveStyle(`font-weight: ${theme.fontWeights.body}`);
135
+ expect(body).toHaveStyle(`line-height: ${theme.lineHeights.body}`);
136
+ });
@@ -1,29 +1,47 @@
1
1
  import React from 'react';
2
2
  import { OverlayProvider } from '@react-aria/overlays';
3
- import { ThemeProvider, ThemeProviderProps } from '@marigold/system';
4
- // import { Global } from '@emotion/react';
5
- // import { css } from '@theme-ui/css';
3
+ import {
4
+ Theme,
5
+ Global,
6
+ ThemeProvider,
7
+ ThemeProviderProps,
8
+ useTheme,
9
+ __defaultTheme,
10
+ } from '@marigold/system';
6
11
 
7
- // const GlobalStyles = () => {
8
- // const theme = useTheme();
9
- // const styles = css({
10
- // body: { variant: 'root.body' },
11
- // html: { variant: 'root.html' },
12
- // })(theme);
12
+ // Theme Extension
13
+ // ---------------
14
+ export interface RootThemeExtension<Value> {
15
+ root?: {
16
+ body?: Value;
17
+ html?: Value;
18
+ };
19
+ }
13
20
 
14
- // return <Global styles={styles} />;
15
- // };
16
- // a merge of the ThemeProvider and the react-aria OverlayProvider
17
- export const MarigoldProvider: React.FC<ThemeProviderProps> = ({
21
+ // Props
22
+ // ---------------
23
+ export interface MarigoldProviderProps<T extends Theme>
24
+ extends ThemeProviderProps<T> {}
25
+
26
+ // Provider
27
+ // ---------------
28
+ export function MarigoldProvider<T extends Theme>({
18
29
  theme,
19
30
  children,
20
- }) => {
31
+ }: MarigoldProviderProps<T>) {
32
+ const outer = useTheme();
33
+ const isTopLevel = outer.theme === __defaultTheme;
34
+
21
35
  return (
22
36
  <ThemeProvider theme={theme}>
23
- <OverlayProvider>
24
- {/* <GlobalStyles /> */}
25
- {children}
26
- </OverlayProvider>
37
+ {isTopLevel ? (
38
+ <>
39
+ <Global />
40
+ <OverlayProvider>{children}</OverlayProvider>
41
+ </>
42
+ ) : (
43
+ children
44
+ )}
27
45
  </ThemeProvider>
28
46
  );
29
- };
47
+ }
@@ -1,3 +1,4 @@
1
1
  export { useTheme, ThemeProvider } from '@marigold/system';
2
- export * from './MarigoldProvider';
3
2
  export { SSRProvider } from '@react-aria/ssr';
3
+
4
+ export * from './MarigoldProvider';
@@ -28,6 +28,17 @@ import { useState } from 'react';
28
28
  },
29
29
  },
30
30
  },
31
+ labelVariant: {
32
+ control: {
33
+ type: 'text',
34
+ },
35
+ description: 'Radio label variant',
36
+ table: {
37
+ defaultValue: {
38
+ summary: 'inline',
39
+ },
40
+ },
41
+ },
31
42
  label: {
32
43
  control: {
33
44
  type: 'text',
@@ -4,13 +4,47 @@ import { Radio } from './Radio';
4
4
  import { ThemeProvider } from '@marigold/system';
5
5
 
6
6
  const theme = {
7
+ space: {
8
+ none: 0,
9
+ small: 2,
10
+ },
7
11
  radio: {
8
- default: {
9
- m: '2px',
12
+ __default: {
13
+ m: 'small',
14
+ },
15
+ },
16
+ label: {
17
+ above: {
18
+ fontSize: '8px',
19
+ },
20
+ inline: {
21
+ fontSize: '14px',
10
22
  },
11
23
  },
12
24
  };
13
25
 
26
+ test('supports default labelVariant', () => {
27
+ render(
28
+ <ThemeProvider theme={theme}>
29
+ <Radio id="test" title="checkbox" label="label" />
30
+ </ThemeProvider>
31
+ );
32
+
33
+ const label = screen.getByText(/label/);
34
+ expect(label).toHaveStyle(`font-size: 14px`);
35
+ });
36
+
37
+ test('supports other labelVariant than default', () => {
38
+ render(
39
+ <ThemeProvider theme={theme}>
40
+ <Radio id="test" title="checkbox" label="label" labelVariant="above" />
41
+ </ThemeProvider>
42
+ );
43
+
44
+ const label = screen.getByText(/label/);
45
+ expect(label).toHaveStyle(`font-size: 8px`);
46
+ });
47
+
14
48
  test('supports label prop', () => {
15
49
  render(<Radio label="Test" id="test" title="radio" />);
16
50
 
@@ -8,6 +8,14 @@ import { ValidationMessage } from '../ValidationMessage';
8
8
 
9
9
  import { RadioChecked, RadioUnchecked } from './RadioIcons';
10
10
 
11
+ // Theme Extension
12
+ // ---------------
13
+ export interface RadioThemeExtension<Value> {
14
+ radio?: {
15
+ [key: string]: Value;
16
+ };
17
+ }
18
+
11
19
  // Radio Icon
12
20
  // ---------------
13
21
  type RadioIconProps = {
@@ -48,7 +56,7 @@ type RadioInputProps = {
48
56
 
49
57
  const RadioInput: React.FC<RadioInputProps> = ({
50
58
  className,
51
- variant = 'default',
59
+ variant = '',
52
60
  error,
53
61
  ...props
54
62
  }) => (
@@ -81,6 +89,7 @@ export type RadioProps = {
81
89
  id: string;
82
90
  label?: string;
83
91
  required?: boolean;
92
+ labelVariant?: string;
84
93
  error?: boolean;
85
94
  errorMessage?: string;
86
95
  } & RadioInputProps;
@@ -88,6 +97,7 @@ export type RadioProps = {
88
97
  export const Radio: React.FC<RadioProps> = ({
89
98
  label,
90
99
  required,
100
+ labelVariant = 'inline',
91
101
  error,
92
102
  errorMessage,
93
103
  ...props
@@ -98,7 +108,8 @@ export const Radio: React.FC<RadioProps> = ({
98
108
  <Label
99
109
  htmlFor={props.id}
100
110
  required={required}
101
- variant={props.disabled ? 'disabled' : 'inline'}
111
+ variant={labelVariant}
112
+ color={props.disabled ? 'disabled' : 'text'}
102
113
  >
103
114
  <Box as={RadioInput} pr="8px" error={error} {...props} />
104
115
  {label}
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { SVG } from '@marigold/icons';
2
+ import { SVG } from '@marigold/system';
3
3
 
4
4
  import { Box } from '../Box';
5
5
 
@@ -20,6 +20,7 @@ export const ListBox = (props: ListBoxProps) => {
20
20
  return (
21
21
  <Box
22
22
  as="ul"
23
+ p="none"
23
24
  css={{
24
25
  listStyle: 'none',
25
26
  }}
@@ -1,10 +1,22 @@
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 { Select } from './Select';
3
4
  import { Item } from '@marigold/components';
4
5
 
5
- <Meta
6
- title="Components/Select"
7
- argTypes={{
6
+ export default {
7
+ title: 'Components/Select',
8
+ argTypes: {
9
+ label: {
10
+ control: {
11
+ type: 'text',
12
+ },
13
+ table: {
14
+ defaultValue: {
15
+ summary: 'Select label',
16
+ },
17
+ },
18
+ defaultValue: 'Favorite Color',
19
+ },
8
20
  placeholder: {
9
21
  control: {
10
22
  type: 'text',
@@ -57,22 +69,13 @@ import { Item } from '@marigold/components';
57
69
  width: {
58
70
  control: 'number',
59
71
  },
60
- }}
61
- />
62
-
63
- # Select
72
+ },
73
+ } as Meta;
64
74
 
65
- export const Template = args => (
66
- <Select label="Favorite Color" htmlFor="id" {...args}>
67
- {/* Storybook crashes with imported <Item> component
68
- <Item>Red</Item>
69
- <Item>Orange</Item>
70
- <Item>Yellow</Item> */}
75
+ export const Basic: ComponentStory<typeof Select> = args => (
76
+ <Select {...args}>
77
+ <Item>Red</Item>
78
+ <Item>Orange</Item>
79
+ <Item>Yellow</Item>
71
80
  </Select>
72
81
  );
73
-
74
- <Canvas>
75
- <Story name="Default">{Template.bind({})}</Story>
76
- </Canvas>
77
-
78
- <ArgsTable story="Default" />
@@ -6,14 +6,28 @@ import { Item, MarigoldProvider, Section } from '..';
6
6
  import { Select } from './Select';
7
7
 
8
8
  const theme = {
9
+ colors: {
10
+ red: 'red',
11
+ },
12
+ fonts: {
13
+ body: 'Inter',
14
+ },
9
15
  button: {
10
16
  select: {
11
- fontFamily: 'Inter',
17
+ fontFamily: 'body',
12
18
  errorOpened: {
13
19
  color: 'red',
14
20
  },
15
21
  },
16
22
  },
23
+ label: {
24
+ above: {
25
+ fontSize: '8px',
26
+ },
27
+ inline: {
28
+ fontSize: '14px',
29
+ },
30
+ },
17
31
  };
18
32
 
19
33
  test('supports button select variant', () => {
@@ -29,6 +43,30 @@ test('supports button select variant', () => {
29
43
  expect(select).toHaveStyle(`font-family: Inter`);
30
44
  });
31
45
 
46
+ test('supports default labelVariant', () => {
47
+ render(
48
+ <MarigoldProvider theme={theme}>
49
+ <Select label="MyLabel" data-testid="selectId">
50
+ <Item>1</Item>
51
+ </Select>
52
+ </MarigoldProvider>
53
+ );
54
+ const label = screen.getAllByText('MyLabel');
55
+ expect(label[0]).toHaveStyle(`font-size: 8px`);
56
+ });
57
+
58
+ test('supports other labelVariant than default', () => {
59
+ render(
60
+ <MarigoldProvider theme={theme}>
61
+ <Select label="MyLabel" data-testid="selectId" labelVariant="inline">
62
+ <Item>1</Item>
63
+ </Select>
64
+ </MarigoldProvider>
65
+ );
66
+ const label = screen.getAllByText('MyLabel');
67
+ expect(label[0]).toHaveStyle(`font-size: 14px`);
68
+ });
69
+
32
70
  test('accepts custom styles prop className', () => {
33
71
  render(
34
72
  <MarigoldProvider theme={theme}>
@@ -19,7 +19,25 @@ import { ValidationMessage } from '../ValidationMessage';
19
19
  import { ListBox } from './ListBox';
20
20
  import { Popover } from './Popover';
21
21
 
22
+ // Theme Extension
23
+ // ---------------
24
+ export interface SelectThemeExtension<Value> {
25
+ select?: {
26
+ __default: Value;
27
+ disabled?: Value;
28
+ listbox?: {
29
+ __default: Value;
30
+ error?: Value;
31
+ };
32
+ section?: Value;
33
+ option?: Value;
34
+ };
35
+ }
36
+
37
+ // Props
38
+ // ---------------
22
39
  export type SelectProps = {
40
+ labelVariant?: string;
23
41
  placeholder?: string;
24
42
  disabled?: boolean;
25
43
  required?: boolean;
@@ -30,7 +48,10 @@ export type SelectProps = {
30
48
  AriaSelectProps<object> &
31
49
  SingleSelection;
32
50
 
51
+ // Component
52
+ // ---------------
33
53
  export const Select = ({
54
+ labelVariant = 'above',
34
55
  placeholder = 'Select an option',
35
56
  disabled,
36
57
  required,
@@ -75,11 +96,7 @@ export const Select = ({
75
96
  <Box position="relative" display="inline-block" width={width && width}>
76
97
  {props.label && (
77
98
  <Box>
78
- <Label
79
- {...labelProps}
80
- htmlFor={labelProps.id}
81
- variant={disabled ? 'disabled' : 'above'}
82
- >
99
+ <Label {...labelProps} htmlFor={labelProps.id} variant={labelVariant}>
83
100
  {required ? (
84
101
  <Box as="span" display="inline-flex" alignItems="center">
85
102
  {props.label}
@@ -122,11 +139,7 @@ export const Select = ({
122
139
  {state.selectedItem ? state.selectedItem.rendered : placeholder}
123
140
  </Box>
124
141
  {state.isOpen && !disabled ? (
125
- <Box
126
- as={ArrowUp}
127
- size={16}
128
- css={{ fill: disabled ? 'disabled' : 'text' }}
129
- />
142
+ <Box as={ArrowUp} size={16} css={{ fill: 'text' }} />
130
143
  ) : (
131
144
  <Box
132
145
  as={ArrowDown}
@@ -141,9 +154,7 @@ export const Select = ({
141
154
  {...overlayProps}
142
155
  {...positionProps}
143
156
  css={{
144
- width: width
145
- ? width
146
- : triggerRef.current && triggerRef.current.offsetWidth + 'px',
157
+ width: triggerRef.current && triggerRef.current.offsetWidth + 'px',
147
158
  }}
148
159
  ref={overlayRef as Ref<HTMLDivElement>}
149
160
  isOpen={state.isOpen}
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import type { Meta, ComponentStory } from '@storybook/react';
3
+ import { Slider } from './Slider';
4
+
5
+ export default {
6
+ title: 'Components/Slider',
7
+ argTypes: {
8
+ variant: {
9
+ control: {
10
+ type: 'text',
11
+ },
12
+ description: 'Style',
13
+ table: {
14
+ defaultValue: {
15
+ summary: '__default',
16
+ },
17
+ },
18
+ },
19
+ },
20
+ } as Meta;
21
+
22
+ export const Basic: ComponentStory<typeof Slider> = args => (
23
+ <Slider name="vol" min="0" max="50" {...args} />
24
+ );
@@ -4,12 +4,16 @@ import { ThemeProvider } from '@marigold/system';
4
4
  import { Slider } from './Slider';
5
5
 
6
6
  const theme = {
7
- form: {
8
- slider: {
9
- fontFamily: 'Oswald Regular',
7
+ fonts: {
8
+ regular: 'Oswald Regular',
9
+ body: 'Inter',
10
+ },
11
+ slider: {
12
+ __default: {
13
+ fontFamily: 'regular',
10
14
  },
11
- range: {
12
- fontFamily: 'Inter',
15
+ special: {
16
+ fontFamily: 'body',
13
17
  },
14
18
  },
15
19
  };
@@ -28,7 +32,7 @@ test('supports default variant and themeSection', () => {
28
32
  test('accepts other variant than default', () => {
29
33
  render(
30
34
  <ThemeProvider theme={theme}>
31
- <Slider variant="range" title="slider" />
35
+ <Slider variant="special" title="slider" />
32
36
  </ThemeProvider>
33
37
  );
34
38
  const slider = screen.getByTitle(/slider/);
@@ -1,23 +1,35 @@
1
1
  import React from 'react';
2
- import { useStyles } from '@marigold/system';
3
2
  import { ComponentProps } from '@marigold/types';
4
3
 
4
+ import { Box } from '../Box';
5
+
6
+ // Theme Extension
7
+ // ---------------
8
+ export interface SliderThemeExtension<Value> {
9
+ slider?: {
10
+ [key: string]: Value;
11
+ };
12
+ }
13
+
14
+ // Props
15
+ // ---------------
5
16
  export type SliderProps = {
6
17
  variant?: string;
7
18
  } & ComponentProps<'input'>;
8
19
 
20
+ // Component
21
+ // ---------------
9
22
  export const Slider: React.FC<SliderProps> = ({
10
- variant = 'slider',
23
+ variant = '',
11
24
  className,
12
25
  ...props
13
- }) => {
14
- const classNames = useStyles({
15
- variant: `form.${variant}`,
16
- css: {
17
- verticalAlign: 'middle',
18
- },
19
- className,
20
- });
21
-
22
- return <input type="range" className={classNames} {...props} />;
23
- };
26
+ }) => (
27
+ <Box
28
+ as="input"
29
+ type="range"
30
+ css={{ verticalAlign: 'middle' }}
31
+ variant={`slider.${variant}`}
32
+ className={className}
33
+ {...props}
34
+ />
35
+ );