imbric-theme 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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