imbric-theme 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. package/.babelrc.json +3 -0
  2. package/.commitlintrc.json +3 -0
  3. package/.editorconfig +13 -0
  4. package/.eslintcache +1 -0
  5. package/.eslintrc.json +36 -0
  6. package/.huskyrc.json +6 -0
  7. package/.lintstagedrc.json +5 -0
  8. package/.nvmrc +1 -0
  9. package/.prettierrc.json +4 -0
  10. package/.releaserc.json +13 -0
  11. package/.storybook/main.js +9 -0
  12. package/.storybook/preview-head.html +2 -0
  13. package/.storybook/preview.js +32 -0
  14. package/.stylelintrc.json +14 -0
  15. package/.vscode/launch.json +15 -0
  16. package/CHANGELOG.md +0 -0
  17. package/README.md +69 -0
  18. package/atoms/Avatar/Avatar.js +36 -0
  19. package/atoms/Avatar/Avatar.module.css +3 -0
  20. package/atoms/Avatar/Avatar.stories.js +29 -0
  21. package/atoms/Avatar/__snapshots__/Avatar.stories.js.snap +105 -0
  22. package/atoms/Avatar/constants.js +3 -0
  23. package/atoms/Avatar/helpers.js +7 -0
  24. package/atoms/Avatar/index.js +3 -0
  25. package/atoms/Button/Button.js +68 -0
  26. package/atoms/Button/Button.module.css +63 -0
  27. package/atoms/Button/Button.stories.js +47 -0
  28. package/atoms/Button/Button.test.js +60 -0
  29. package/atoms/Button/__snapshots__/Button.stories.js.snap +191 -0
  30. package/atoms/Button/constants.js +3 -0
  31. package/atoms/Button/index.js +3 -0
  32. package/atoms/Card/Card.js +48 -0
  33. package/atoms/Card/Card.module.css +52 -0
  34. package/atoms/Card/Card.stories.js +41 -0
  35. package/atoms/Card/__snapshots__/Card.stories.js.snap +136 -0
  36. package/atoms/Card/constants.js +4 -0
  37. package/atoms/Card/index.js +3 -0
  38. package/atoms/Check/Check.js +26 -0
  39. package/atoms/Check/Check.module.css +11 -0
  40. package/atoms/Check/Check.stories.js +15 -0
  41. package/atoms/Check/__snapshots__/Check.stories.js.snap +67 -0
  42. package/atoms/Check/index.js +2 -0
  43. package/atoms/Divider/Divider.js +19 -0
  44. package/atoms/Divider/Divider.module.css +5 -0
  45. package/atoms/Divider/Divider.stories.js +12 -0
  46. package/atoms/Divider/__snapshots__/Divider.stories.js.snap +22 -0
  47. package/atoms/Divider/index.js +2 -0
  48. package/atoms/Heading/Heading.js +37 -0
  49. package/atoms/Heading/Heading.module.css +66 -0
  50. package/atoms/Heading/Heading.stories.js +46 -0
  51. package/atoms/Heading/__snapshots__/Heading.stories.js.snap +189 -0
  52. package/atoms/Heading/constants.js +5 -0
  53. package/atoms/Heading/index.js +3 -0
  54. package/atoms/Icon/Icon.js +66 -0
  55. package/atoms/Icon/Icon.module.css +112 -0
  56. package/atoms/Icon/Icon.stories.js +48 -0
  57. package/atoms/Icon/__snapshots__/Icon.stories.js.snap +1311 -0
  58. package/atoms/Icon/constants.js +486 -0
  59. package/atoms/Icon/helpers.js +9 -0
  60. package/atoms/Icon/index.js +3 -0
  61. package/atoms/Input/Input.js +49 -0
  62. package/atoms/Input/Input.module.css +27 -0
  63. package/atoms/Input/Input.stories.js +32 -0
  64. package/atoms/Input/__snapshots__/Input.stories.js.snap +101 -0
  65. package/atoms/Input/constants.js +3 -0
  66. package/atoms/Input/index.js +3 -0
  67. package/atoms/Link/Link.js +33 -0
  68. package/atoms/Link/Link.module.css +14 -0
  69. package/atoms/Link/Link.stories.js +30 -0
  70. package/atoms/Link/__snapshots__/Link.stories.js.snap +118 -0
  71. package/atoms/Link/constants.js +5 -0
  72. package/atoms/Link/index.js +3 -0
  73. package/atoms/Loading/Loading.js +30 -0
  74. package/atoms/Loading/Loading.module.css +51 -0
  75. package/atoms/Loading/Loading.stories.js +17 -0
  76. package/atoms/Loading/__snapshots__/Loading.stories.js.snap +26 -0
  77. package/atoms/Loading/index.js +2 -0
  78. package/atoms/Modal/Modal.js +98 -0
  79. package/atoms/Modal/Modal.module.css +85 -0
  80. package/atoms/Modal/Modal.stories.js +43 -0
  81. package/atoms/Modal/__snapshots__/Modal.stories.js.snap +239 -0
  82. package/atoms/Modal/constants.js +1 -0
  83. package/atoms/Modal/index.js +3 -0
  84. package/atoms/Paragraph/Paragraph.js +56 -0
  85. package/atoms/Paragraph/Paragraph.module.css +68 -0
  86. package/atoms/Paragraph/Paragraph.stories.js +52 -0
  87. package/atoms/Paragraph/__snapshots__/Paragraph.stories.js.snap +230 -0
  88. package/atoms/Paragraph/constants.js +5 -0
  89. package/atoms/Paragraph/index.js +3 -0
  90. package/atoms/Picture/Picture.js +40 -0
  91. package/atoms/Picture/Picture.module.css +16 -0
  92. package/atoms/Picture/Picture.stories.js +32 -0
  93. package/atoms/Picture/__snapshots__/Picture.stories.js.snap +156 -0
  94. package/atoms/Picture/index.js +2 -0
  95. package/atoms/Textarea/Textarea.js +46 -0
  96. package/atoms/Textarea/Textarea.module.css +25 -0
  97. package/atoms/Textarea/Textarea.stories.js +16 -0
  98. package/atoms/Textarea/__snapshots__/Textarea.stories.js.snap +25 -0
  99. package/atoms/Textarea/index.js +2 -0
  100. package/codecov.yml +2 -0
  101. package/helpers/storybook.js +29 -0
  102. package/helpers/storybook.test.js +40 -0
  103. package/helpers/styles.js +37 -0
  104. package/helpers/styles.test.js +222 -0
  105. package/hocs/withStyles.js +17 -0
  106. package/hook/useMedia.js +22 -0
  107. package/index.js +31 -0
  108. package/jest.config.js +23 -0
  109. package/jest.setup.js +13 -0
  110. package/layout/CenteredContent/CenteredContent.js +30 -0
  111. package/layout/CenteredContent/CenteredContent.module.css +12 -0
  112. package/layout/CenteredContent/CenteredContent.stories.js +22 -0
  113. package/layout/CenteredContent/__snapshots__/CenteredContent.stories.js.snap +27 -0
  114. package/layout/CenteredContent/index.js +2 -0
  115. package/layout/Container/Container.js +29 -0
  116. package/layout/Container/Container.module.css +14 -0
  117. package/layout/Container/Container.stories.js +22 -0
  118. package/layout/Container/__snapshots__/Container.stories.js.snap +27 -0
  119. package/layout/Container/index.js +2 -0
  120. package/layout/FullHeightContent/FullHeightContent.js +40 -0
  121. package/layout/FullHeightContent/FullHeightContent.module.css +21 -0
  122. package/layout/FullHeightContent/FullHeightContent.stories.js +22 -0
  123. package/layout/FullHeightContent/__snapshots__/FullHeightContent.stories.js.snap +41 -0
  124. package/layout/FullHeightContent/index.js +2 -0
  125. package/layout/Spacer/Spacer.js +40 -0
  126. package/layout/Spacer/Spacer.module.css +12 -0
  127. package/layout/Spacer/Spacer.stories.js +25 -0
  128. package/layout/Spacer/__snapshots__/Spacer.stories.js.snap +97 -0
  129. package/layout/Spacer/components/Horizontal/Horizontal.js +43 -0
  130. package/layout/Spacer/components/Horizontal/Horizontal.stories.js +32 -0
  131. package/layout/Spacer/components/Horizontal/__snapshots__/Horizontal.stories.js.snap +97 -0
  132. package/layout/Spacer/components/Horizontal/index.js +1 -0
  133. package/layout/Spacer/components/Vertical/Vertical.js +31 -0
  134. package/layout/Spacer/components/Vertical/Vertical.stories.js +25 -0
  135. package/layout/Spacer/components/Vertical/__snapshots__/Vertical.stories.js.snap +85 -0
  136. package/layout/Spacer/components/Vertical/index.js +1 -0
  137. package/layout/Spacer/components/index.js +2 -0
  138. package/layout/Spacer/constants.js +5 -0
  139. package/layout/Spacer/helpers.js +3 -0
  140. package/layout/Spacer/index.js +3 -0
  141. package/molecules/Accordion/Accordion.js +70 -0
  142. package/molecules/Accordion/Accordion.module.css +12 -0
  143. package/molecules/Accordion/Accordion.stories.js +31 -0
  144. package/molecules/Accordion/__snapshots__/Accordion.stories.js.snap +228 -0
  145. package/molecules/Accordion/index.js +2 -0
  146. package/molecules/AddButton/AddButton.js +137 -0
  147. package/molecules/AddButton/AddButton.module.css +128 -0
  148. package/molecules/AddButton/AddButton.stories.js +47 -0
  149. package/molecules/AddButton/__snapshots__/AddButton.stories.js.snap +326 -0
  150. package/molecules/AddButton/constants.js +6 -0
  151. package/molecules/AddButton/handlers.js +58 -0
  152. package/molecules/AddButton/handlers.test.js +19 -0
  153. package/molecules/AddButton/helpers.js +6 -0
  154. package/molecules/AddButton/helpers.test.js +41 -0
  155. package/molecules/AddButton/hooks.js +14 -0
  156. package/molecules/AddButton/index.js +3 -0
  157. package/molecules/ButtonIcon/ButtonIcon.js +41 -0
  158. package/molecules/ButtonIcon/ButtonIcon.stories.js +27 -0
  159. package/molecules/ButtonIcon/__snapshots__/ButtonIcon.stories.js.snap +178 -0
  160. package/molecules/ButtonIcon/constants.js +6 -0
  161. package/molecules/ButtonIcon/index.js +2 -0
  162. package/molecules/Dropdown/Dropdown.js +59 -0
  163. package/molecules/Dropdown/Dropdown.module.css +34 -0
  164. package/molecules/Dropdown/Dropdown.stories.js +41 -0
  165. package/molecules/Dropdown/__snapshots__/Dropdown.stories.js.snap +181 -0
  166. package/molecules/Dropdown/index.js +2 -0
  167. package/molecules/Error/Error.js +35 -0
  168. package/molecules/Error/Error.module.css +11 -0
  169. package/molecules/Error/Error.stories.js +18 -0
  170. package/molecules/Error/__snapshots__/Error.stories.js.snap +134 -0
  171. package/molecules/Error/index.js +2 -0
  172. package/molecules/IconLabel/IconLabel.js +83 -0
  173. package/molecules/IconLabel/IconLabel.module.css +16 -0
  174. package/molecules/IconLabel/IconLabel.stories.js +25 -0
  175. package/molecules/IconLabel/__snapshots__/IconLabel.stories.js.snap +211 -0
  176. package/molecules/IconLabel/constants.js +6 -0
  177. package/molecules/IconLabel/index.js +3 -0
  178. package/molecules/LoadingError/LoadingError.js +31 -0
  179. package/molecules/LoadingError/LoadingError.stories.js +24 -0
  180. package/molecules/LoadingError/__snapshots__/LoadingError.stories.js.snap +109 -0
  181. package/molecules/LoadingError/index.js +1 -0
  182. package/molecules/Score/Score.js +61 -0
  183. package/molecules/Score/Score.module.css +11 -0
  184. package/molecules/Score/Score.stories.js +13 -0
  185. package/molecules/Score/__snapshots__/Score.stories.js.snap +100 -0
  186. package/molecules/Score/faces/happy.svg +7 -0
  187. package/molecules/Score/faces/normal.svg +6 -0
  188. package/molecules/Score/faces/sad.svg +6 -0
  189. package/molecules/Score/index.js +2 -0
  190. package/molecules/Task/Task.js +114 -0
  191. package/molecules/Task/Task.module.css +47 -0
  192. package/molecules/Task/Task.stories.js +47 -0
  193. package/molecules/Task/__snapshots__/Task.stories.js.snap +953 -0
  194. package/molecules/Task/constants.js +1 -0
  195. package/molecules/Task/index.js +3 -0
  196. package/molecules/TaskCounter/TaskCounter.js +74 -0
  197. package/molecules/TaskCounter/TaskCounter.module.css +11 -0
  198. package/molecules/TaskCounter/TaskCounter.stories.js +26 -0
  199. package/molecules/TaskCounter/__snapshots__/TaskCounter.stories.js.snap +177 -0
  200. package/molecules/TaskCounter/index.js +2 -0
  201. package/package.json +102 -0
  202. package/scripts/build-tokens.js +40 -0
  203. package/scripts/create-component.js +127 -0
  204. package/storybook.test.js +13 -0
  205. package/styles/globals.css +10 -0
  206. package/styles/tokens.css +390 -0
  207. package/templates/component/Component.js +22 -0
  208. package/templates/component/Component.module.css +3 -0
  209. package/templates/component/Component.stories.js +23 -0
  210. package/templates/component/constants.js +1 -0
  211. package/templates/component/index.js +3 -0
  212. package/tokens/Token/Helper.js +30 -0
  213. package/tokens/Token/Token.js +13 -0
  214. package/tokens/Token/Token.module.css +64 -0
  215. package/tokens/Token/components/Color.js +21 -0
  216. package/tokens/Token/components/Color.stories.js +126 -0
  217. package/tokens/Token/components/FontFamily.js +24 -0
  218. package/tokens/Token/components/FontFamily.stories.js +32 -0
  219. package/tokens/Token/components/FontSize.js +24 -0
  220. package/tokens/Token/components/FontSize.stories.js +31 -0
  221. package/tokens/Token/components/FontWeight.js +24 -0
  222. package/tokens/Token/components/FontWeight.stories.js +31 -0
  223. package/tokens/Token/components/Spacing.js +24 -0
  224. package/tokens/Token/components/Spacing.stories.js +29 -0
  225. package/tokens/Token/components/__snapshots__/Color.stories.js.snap +7169 -0
  226. package/tokens/Token/components/__snapshots__/FontFamily.stories.js.snap +133 -0
  227. package/tokens/Token/components/__snapshots__/FontSize.stories.js.snap +261 -0
  228. package/tokens/Token/components/__snapshots__/FontWeight.stories.js.snap +317 -0
  229. package/tokens/Token/components/__snapshots__/Spacing.stories.js.snap +229 -0
  230. package/tokens/Token/components/index.js +5 -0
  231. package/tokens/Token/helpers.js +17 -0
  232. package/tokens/Token/index.js +1 -0
  233. package/tokens/index.js +471 -0
  234. package/utils/isEmpty.js +28 -0
  235. package/utils/isEmpty.test.js +125 -0
  236. package/utils/isObject.js +4 -0
  237. package/utils/keyboardCodes.js +6 -0
  238. package/utils/testUtils/matchMediaMock.js +14 -0
  239. package/utils/testUtils/svgrMock.js +2 -0
  240. package/utils/toCapitalize.js +4 -0
  241. package/utils/toKebabCase.js +8 -0
  242. package/utils/toPascalCase.js +20 -0
  243. package/webpack/cssModules.js +30 -0
  244. package/webpack/loadConfigs.js +6 -0
  245. package/webpack/reactInlineSvg.js +22 -0
@@ -0,0 +1,16 @@
1
+ .picture {
2
+ user-select: none;
3
+ }
4
+
5
+ .picture img {
6
+ display: block;
7
+ width: 100%;
8
+ }
9
+
10
+ .is-rounded img {
11
+ border-radius: var(--border-radius-full);
12
+ }
13
+
14
+ .with-border img {
15
+ border: var(--picture-border);
16
+ }
@@ -0,0 +1,32 @@
1
+ import { Picture, styles } from '.'
2
+
3
+ import { getTemplate } from '../../helpers/storybook'
4
+
5
+ const Template = getTemplate(Picture, styles)
6
+
7
+ export default {
8
+ title: 'Atoms/Picture',
9
+ component: Picture,
10
+ args: {
11
+ src: 'https://picsum.photos/id/1033/400/400',
12
+ width: 200,
13
+ },
14
+ argTypes: {
15
+ width: { control: 'number' },
16
+ height: { control: 'number' },
17
+ },
18
+ }
19
+
20
+ export const Default = Template.bind({})
21
+
22
+ export const Rounded = Template.bind({})
23
+ Rounded.args = { isRounded: true }
24
+
25
+ export const Border = Template.bind({})
26
+ Border.args = { withBorder: true }
27
+
28
+ export const Height = Template.bind({})
29
+ Height.args = { src: 'https://picsum.photos/id/1033/400/800', height: 400 }
30
+
31
+ export const Width = Template.bind({})
32
+ Width.args = { src: 'https://picsum.photos/id/1033/800/400', width: 400 }
@@ -0,0 +1,156 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Storyshots Atoms/Picture Border 1`] = `
4
+ <div
5
+ style={
6
+ Object {
7
+ "alignContent": "flex-start",
8
+ "display": "flex",
9
+ "flexDirection": "column",
10
+ "flexWrap": "wrap",
11
+ "gap": "10px 30px",
12
+ "height": "100%",
13
+ "justifyContent": "flex-start",
14
+ "maxHeight": "auto",
15
+ }
16
+ }
17
+ >
18
+ <picture
19
+ className="picture with-border"
20
+ >
21
+ <img
22
+ src="https://picsum.photos/id/1033/400/400"
23
+ style={
24
+ Object {
25
+ "height": "auto",
26
+ "maxWidth": 200,
27
+ }
28
+ }
29
+ />
30
+ </picture>
31
+ </div>
32
+ `;
33
+
34
+ exports[`Storyshots Atoms/Picture Default 1`] = `
35
+ <div
36
+ style={
37
+ Object {
38
+ "alignContent": "flex-start",
39
+ "display": "flex",
40
+ "flexDirection": "column",
41
+ "flexWrap": "wrap",
42
+ "gap": "10px 30px",
43
+ "height": "100%",
44
+ "justifyContent": "flex-start",
45
+ "maxHeight": "auto",
46
+ }
47
+ }
48
+ >
49
+ <picture
50
+ className="picture"
51
+ >
52
+ <img
53
+ src="https://picsum.photos/id/1033/400/400"
54
+ style={
55
+ Object {
56
+ "height": "auto",
57
+ "maxWidth": 200,
58
+ }
59
+ }
60
+ />
61
+ </picture>
62
+ </div>
63
+ `;
64
+
65
+ exports[`Storyshots Atoms/Picture Height 1`] = `
66
+ <div
67
+ style={
68
+ Object {
69
+ "alignContent": "flex-start",
70
+ "display": "flex",
71
+ "flexDirection": "column",
72
+ "flexWrap": "wrap",
73
+ "gap": "10px 30px",
74
+ "height": "100%",
75
+ "justifyContent": "flex-start",
76
+ "maxHeight": "auto",
77
+ }
78
+ }
79
+ >
80
+ <picture
81
+ className="picture"
82
+ >
83
+ <img
84
+ src="https://picsum.photos/id/1033/400/800"
85
+ style={
86
+ Object {
87
+ "height": 400,
88
+ "maxWidth": 200,
89
+ }
90
+ }
91
+ />
92
+ </picture>
93
+ </div>
94
+ `;
95
+
96
+ exports[`Storyshots Atoms/Picture Rounded 1`] = `
97
+ <div
98
+ style={
99
+ Object {
100
+ "alignContent": "flex-start",
101
+ "display": "flex",
102
+ "flexDirection": "column",
103
+ "flexWrap": "wrap",
104
+ "gap": "10px 30px",
105
+ "height": "100%",
106
+ "justifyContent": "flex-start",
107
+ "maxHeight": "auto",
108
+ }
109
+ }
110
+ >
111
+ <picture
112
+ className="picture is-rounded"
113
+ >
114
+ <img
115
+ src="https://picsum.photos/id/1033/400/400"
116
+ style={
117
+ Object {
118
+ "height": "auto",
119
+ "maxWidth": 200,
120
+ }
121
+ }
122
+ />
123
+ </picture>
124
+ </div>
125
+ `;
126
+
127
+ exports[`Storyshots Atoms/Picture Width 1`] = `
128
+ <div
129
+ style={
130
+ Object {
131
+ "alignContent": "flex-start",
132
+ "display": "flex",
133
+ "flexDirection": "column",
134
+ "flexWrap": "wrap",
135
+ "gap": "10px 30px",
136
+ "height": "100%",
137
+ "justifyContent": "flex-start",
138
+ "maxHeight": "auto",
139
+ }
140
+ }
141
+ >
142
+ <picture
143
+ className="picture"
144
+ >
145
+ <img
146
+ src="https://picsum.photos/id/1033/800/400"
147
+ style={
148
+ Object {
149
+ "height": "auto",
150
+ "maxWidth": 400,
151
+ }
152
+ }
153
+ />
154
+ </picture>
155
+ </div>
156
+ `;
@@ -0,0 +1,2 @@
1
+ export { default, Picture } from './Picture'
2
+ export { default as styles } from './Picture.module.css'
@@ -0,0 +1,46 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+
4
+ import styles from './Textarea.module.css'
5
+ import withStyles from '../../hocs/withStyles'
6
+
7
+ const DEFAULT_TEXTAREA_ROWS = 5
8
+
9
+ const handleChange = ({ onChange }) => () => {
10
+ onChange()
11
+ }
12
+
13
+ export const Textarea = ({
14
+ children,
15
+ rows,
16
+ placeholder,
17
+ onChange,
18
+ getStyles,
19
+ }) => {
20
+ return (
21
+ <textarea
22
+ className={getStyles('textarea')}
23
+ rows={rows}
24
+ placeholder={placeholder}
25
+ onChange={handleChange({ onChange })}
26
+ >
27
+ {children}
28
+ </textarea>
29
+ )
30
+ }
31
+
32
+ Textarea.propTypes = {
33
+ children: PropTypes.node,
34
+ getStyles: PropTypes.func.isRequired,
35
+ onChange: PropTypes.func.isRequired,
36
+ rows: PropTypes.number,
37
+ placeholder: PropTypes.string,
38
+ }
39
+
40
+ Textarea.defaultProps = {
41
+ getStyles: () => {},
42
+ onChange: () => {},
43
+ rows: DEFAULT_TEXTAREA_ROWS,
44
+ }
45
+
46
+ export default withStyles(styles)(Textarea)
@@ -0,0 +1,25 @@
1
+ .textarea {
2
+ display: flex;
3
+ width: 100%;
4
+ min-height: 100px;
5
+ padding: 20px;
6
+ border: var(--border-width-thin) solid var(--color-cool-gray-200);
7
+ background: var(--input-background);
8
+ border-radius: var(--textarea-border-radius);
9
+ box-shadow: var(--box-shadow-sm);
10
+ color: var(--color-font-base);
11
+ font-family: var(--font-family-sans);
12
+ font-size: var(--input-font-size);
13
+ font-weight: var(--font-weight-medium);
14
+ line-height: var(--line-height-tight);
15
+ resize: vertical;
16
+ }
17
+
18
+ .textarea::placeholder {
19
+ color: var(--color-font-highlight);
20
+ }
21
+
22
+ .textarea:focus {
23
+ box-shadow: 0 0 0 1px var(--color-primary), 0 0 10px 0 var(--color-primary);
24
+ outline: none;
25
+ }
@@ -0,0 +1,16 @@
1
+ import { Textarea, styles } from '.'
2
+
3
+ import { getTemplate } from '../../helpers/storybook'
4
+
5
+ const Template = getTemplate(Textarea, styles)
6
+
7
+ export default {
8
+ title: 'Atoms/Textarea',
9
+ component: Textarea,
10
+ args: {
11
+ placeholder:
12
+ 'Country speed seat newfound ah stained Gundabad stinking runt.',
13
+ },
14
+ }
15
+
16
+ export const Default = Template.bind({})
@@ -0,0 +1,25 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Storyshots Atoms/Textarea Default 1`] = `
4
+ <div
5
+ style={
6
+ Object {
7
+ "alignContent": "flex-start",
8
+ "display": "flex",
9
+ "flexDirection": "column",
10
+ "flexWrap": "wrap",
11
+ "gap": "10px 30px",
12
+ "height": "100%",
13
+ "justifyContent": "flex-start",
14
+ "maxHeight": "auto",
15
+ }
16
+ }
17
+ >
18
+ <textarea
19
+ className="textarea"
20
+ onChange={[Function]}
21
+ placeholder="Country speed seat newfound ah stained Gundabad stinking runt."
22
+ rows={5}
23
+ />
24
+ </div>
25
+ `;
@@ -0,0 +1,2 @@
1
+ export { default, Textarea } from './Textarea'
2
+ export { default as styles } from './Textarea.module.css'
package/codecov.yml ADDED
@@ -0,0 +1,2 @@
1
+ github_checks:
2
+ annotations: false
@@ -0,0 +1,29 @@
1
+ /* eslint-disable react/display-name, react/jsx-key */
2
+ import React from 'react'
3
+ import { getClasses } from './styles'
4
+
5
+ export const getTemplate = (Component, styles) => (args) => {
6
+ const allProps = { ...Component.defaultProps, ...args }
7
+ return <Component {...args} getStyles={getClasses(styles)(allProps)} />
8
+ }
9
+
10
+ export const getListTemplate = (Component, styles) => ({ items, ...args }) =>
11
+ items.map((item, index) => {
12
+ const allProps = { ...Component.defaultProps, ...args, ...item }
13
+ return (
14
+ <Component
15
+ key={index}
16
+ {...args}
17
+ {...item}
18
+ getStyles={getClasses(styles)(allProps)}
19
+ />
20
+ )
21
+ })
22
+
23
+ export const getOptionsArgTypes = (options) => ({
24
+ description: '**options:**',
25
+ table: {
26
+ type: { summary: options.map((option) => `'${option}'`).join('|') },
27
+ },
28
+ control: { type: 'select', options },
29
+ })
@@ -0,0 +1,40 @@
1
+ import { getTemplate } from './storybook'
2
+
3
+ jest.mock('./styles', () => ({
4
+ getClasses: (a) => (b) => ({ ...a, ...b }),
5
+ }))
6
+
7
+ describe('[ helpers / storybook ]', () => {
8
+ describe('#getTemplate', () => {
9
+ describe('when `Component`, `styles`, and `args` are provided', () => {
10
+ it('should return a `Component` with `defaultProps`, `styles` and `args`', () => {
11
+ // given
12
+ const Component = (props) => ({ props })
13
+ Component.defaultProps = { defaultProps: 'defaultProps', foo: 'bar' }
14
+
15
+ const styles = { styles: 'styles' }
16
+ const args = { args: 'args', foo: 'foo' }
17
+
18
+ // when
19
+ const result = getTemplate(Component, styles)(args)
20
+
21
+ // then
22
+ expect(result).toMatchInlineSnapshot(`
23
+ <Component
24
+ args="args"
25
+ defaultProps="defaultProps"
26
+ foo="foo"
27
+ getStyles={
28
+ Object {
29
+ "args": "args",
30
+ "defaultProps": "defaultProps",
31
+ "foo": "foo",
32
+ "styles": "styles",
33
+ }
34
+ }
35
+ />
36
+ `)
37
+ })
38
+ })
39
+ })
40
+ })
@@ -0,0 +1,37 @@
1
+ import classNames from 'classnames'
2
+
3
+ export const getDynamicClasses = (cssModule = {}, props = {}, classes) => {
4
+ return classes.reduce((classesObject, classKey) => {
5
+ const propValue = props[classKey]
6
+ const className = cssModule[`${classKey}-${propValue}`]
7
+
8
+ return className && propValue
9
+ ? { ...classesObject, [className]: propValue }
10
+ : classesObject
11
+ }, {})
12
+ }
13
+
14
+ export const getModuleClasses = (cssModule, classKey) => {
15
+ return (cssModule && cssModule[classKey]) || classKey
16
+ }
17
+
18
+ export const getObjectClasses = (cssModule, object) => {
19
+ return Object.keys(object).reduce((classes, classKey) => {
20
+ const className = cssModule[classKey]
21
+ return className ? { ...classes, [className]: object[classKey] } : classes
22
+ }, {})
23
+ }
24
+
25
+ export const getClasses = (cssModule = {}) => (props) => (...args) => {
26
+ return classNames(
27
+ args.map((arg) => {
28
+ if (Array.isArray(arg)) {
29
+ return getDynamicClasses(cssModule, props, arg)
30
+ } else if (typeof arg === 'string') {
31
+ return getModuleClasses(cssModule, arg)
32
+ } else if (typeof arg === 'object') {
33
+ return getObjectClasses(cssModule, arg)
34
+ }
35
+ })
36
+ )
37
+ }
@@ -0,0 +1,222 @@
1
+ import {
2
+ getDynamicClasses,
3
+ getModuleClasses,
4
+ getObjectClasses,
5
+ getClasses,
6
+ } from './styles'
7
+
8
+ const cssModuleMock = {
9
+ ['size-sm']: '.xyz_size_sm',
10
+ ['color-red']: '.xyz_color_red',
11
+ ['is-editable']: '.xyz_is_editable',
12
+ ['is-inverted']: '.xyz_is_inverted',
13
+ }
14
+
15
+ const propsMock = { size: 'sm', color: 'red' }
16
+
17
+ jest.mock('classnames', () => (value) => value)
18
+
19
+ describe('[ helpers / styles ]', () => {
20
+ describe('#getDynamicClasses', () => {
21
+ describe('when all `props` match the `classes` array', () => {
22
+ it('should return the dynamic classes', () => {
23
+ // given
24
+ const args = ['size', 'color']
25
+ // when
26
+ const result = getDynamicClasses(cssModuleMock, propsMock, args)
27
+ // then
28
+ const expected = { '.xyz_size_sm': 'sm', '.xyz_color_red': 'red' }
29
+
30
+ expect(result).toStrictEqual(expected)
31
+ })
32
+ })
33
+
34
+ describe("when all `props` doesn't match the `classes` array", () => {
35
+ it('should return an empty object', () => {
36
+ // given
37
+ const args = ['type', 'width']
38
+ // when
39
+ const result = getDynamicClasses(cssModuleMock, propsMock, args)
40
+ // then
41
+ const expected = {}
42
+
43
+ expect(result).toStrictEqual(expected)
44
+ })
45
+ })
46
+
47
+ describe('when some `props` match the `array` classes', () => {
48
+ it('should return the dynamic classes', () => {
49
+ // given
50
+ const args = ['type', 'color']
51
+
52
+ // when
53
+ const result = getDynamicClasses(cssModuleMock, propsMock, args)
54
+ // then
55
+ const expected = { '.xyz_color_red': 'red' }
56
+
57
+ expect(result).toStrictEqual(expected)
58
+ })
59
+ })
60
+ })
61
+
62
+ describe('#getModuleClasses', () => {
63
+ describe('when `cssModule` contains the `classKey`', () => {
64
+ it('should return the module class', () => {
65
+ // given
66
+ const args = 'size-sm'
67
+ // when
68
+ const result = getModuleClasses(cssModuleMock, args)
69
+ // then
70
+ const expected = '.xyz_size_sm'
71
+
72
+ expect(result).toBe(expected)
73
+ })
74
+ })
75
+ describe("when `cssModule` doesn't contain the `classKey`", () => {
76
+ it('should return the `classKey`', () => {
77
+ // given
78
+ const args = 'type-primary'
79
+ // when
80
+ const result = getModuleClasses(cssModuleMock, args)
81
+ // then
82
+ const expected = 'type-primary'
83
+
84
+ expect(result).toBe(expected)
85
+ })
86
+ })
87
+
88
+ describe('when `cssModule` is undefined', () => {
89
+ it('should return the `classKey`', () => {
90
+ // given
91
+ const args = 'size-sm'
92
+ // when
93
+ const result = getModuleClasses(undefined, args)
94
+ // then
95
+ const expected = 'size-sm'
96
+
97
+ expect(result).toBe(expected)
98
+ })
99
+ })
100
+
101
+ describe('when `cssModule` is null', () => {
102
+ it('should return the `classKey`', () => {
103
+ // given
104
+ const args = 'size-sm'
105
+ // when
106
+ const result = getModuleClasses(null, args)
107
+ // then
108
+ const expected = 'size-sm'
109
+
110
+ expect(result).toBe(expected)
111
+ })
112
+ })
113
+ })
114
+
115
+ describe('#getObjectClasses', () => {
116
+ describe('when `cssModule` and `object` is provided', () => {
117
+ it('should return the object class', () => {
118
+ // given
119
+ const args = { 'is-editable': true, 'is-inverted': false }
120
+ // when
121
+ const result = getObjectClasses(cssModuleMock, args)
122
+ // then
123
+ const expected = { '.xyz_is_editable': true, '.xyz_is_inverted': false }
124
+
125
+ expect(result).toStrictEqual(expected)
126
+ })
127
+ })
128
+
129
+ describe("when the `object` doesn't match any `cssModule` class", () => {
130
+ it('should return an empty object', () => {
131
+ // given
132
+ const args = { 'is-block': true, 'is-inline': false }
133
+ // when
134
+ const result = getObjectClasses(cssModuleMock, args)
135
+ // then
136
+ const expected = {}
137
+
138
+ expect(result).toStrictEqual(expected)
139
+ })
140
+ })
141
+
142
+ describe('when the `object` match some `cssModule` class', () => {
143
+ it('should return an empty object', () => {
144
+ // given
145
+ const args = { 'is-editable': true, 'is-inline': false }
146
+ // when
147
+ const result = getObjectClasses(cssModuleMock, args)
148
+ // then
149
+ const expected = { '.xyz_is_editable': true }
150
+
151
+ expect(result).toStrictEqual(expected)
152
+ })
153
+ })
154
+
155
+ describe('when `object` is empty', () => {
156
+ it('should return an empty object', () => {
157
+ // given
158
+ const args = {}
159
+ // when
160
+ const result = getObjectClasses(cssModuleMock, args)
161
+ // then
162
+ const expected = {}
163
+
164
+ expect(result).toStrictEqual(expected)
165
+ })
166
+ })
167
+ })
168
+
169
+ describe('#getClasses', () => {
170
+ describe('when `arg` is an array', () => {
171
+ it('should return the classnames', () => {
172
+ // given
173
+ const args = ['size', 'color']
174
+ // when
175
+ const result = getClasses(cssModuleMock)(propsMock)(args)
176
+ // then
177
+ const expected = [{ '.xyz_size_sm': 'sm', '.xyz_color_red': 'red' }]
178
+
179
+ expect(result).toStrictEqual(expected)
180
+ })
181
+ })
182
+
183
+ describe('when `arg` is an string and `cssModule` contains the `classKey`', () => {
184
+ it('should return the classnames', () => {
185
+ // given
186
+ const args = 'size-sm'
187
+ // when
188
+ const result = getClasses(cssModuleMock)(propsMock)(args)
189
+ // then
190
+ const expected = ['.xyz_size_sm']
191
+
192
+ expect(result).toStrictEqual(expected)
193
+ })
194
+ })
195
+
196
+ describe("when `arg` is an string and `cssModule` doesn't contain the `classKey`", () => {
197
+ it('should return the classnames', () => {
198
+ // given
199
+ const args = 'width-full'
200
+ // when
201
+ const result = getClasses(cssModuleMock)(propsMock)(args)
202
+ // then
203
+ const expected = ['width-full']
204
+
205
+ expect(result).toStrictEqual(expected)
206
+ })
207
+ })
208
+
209
+ describe('when `arg` is an object', () => {
210
+ it('should return the classnames', () => {
211
+ // given
212
+ const args = { 'is-editable': true, 'is-block': true }
213
+ // when
214
+ const result = getClasses(cssModuleMock)(propsMock)(args)
215
+ // then
216
+ const expected = [{ '.xyz_is_editable': true }]
217
+
218
+ expect(result).toStrictEqual(expected)
219
+ })
220
+ })
221
+ })
222
+ })
@@ -0,0 +1,17 @@
1
+ import React from 'react'
2
+ import { getClasses } from '../helpers/styles'
3
+
4
+ const withStyles = (styles) => (WrappedComponent) => {
5
+ const WithStylesComponent = (props) => {
6
+ const allProps = { ...WrappedComponent.defaultProps, ...props }
7
+ return (
8
+ <WrappedComponent getStyles={getClasses(styles)(allProps)} {...props} />
9
+ )
10
+ }
11
+
12
+ WithStylesComponent.displayName = WrappedComponent.displayName
13
+
14
+ return WithStylesComponent
15
+ }
16
+
17
+ export default withStyles