@edvisor/product-language 0.1.1 → 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 (230) hide show
  1. package/.babelrc +12 -0
  2. package/.eslintrc.json +139 -0
  3. package/.storybook/main.js +57 -0
  4. package/.storybook/manager.js +7 -0
  5. package/.storybook/preview-head.html +1 -0
  6. package/.storybook/preview.js +15 -0
  7. package/.storybook/tsconfig.json +30 -0
  8. package/jest.config.ts +15 -0
  9. package/jest.setup.ts +2 -0
  10. package/package.json +22 -10
  11. package/project.json +85 -0
  12. package/src/assets/svg/example_icon.svg +3 -0
  13. package/src/assets/svg/example_icon_white.svg +3 -0
  14. package/src/assets/svg/spinner.svg +3 -0
  15. package/src/assets/svg/spinner_white.svg +3 -0
  16. package/src/helpers/index.ts +3 -0
  17. package/src/helpers/talesOf.tsx +42 -0
  18. package/src/index.ts +2 -0
  19. package/src/lib/components/README.md +49 -0
  20. package/src/lib/components/alert-banner/alert-banner.tsx +34 -0
  21. package/src/lib/components/alert-banner/alert-level-flags.ts +77 -0
  22. package/src/lib/components/alert-banner/index.ts +1 -0
  23. package/src/lib/components/badge/badge-type-flags.ts +72 -0
  24. package/src/lib/components/badge/badge.stories.tsx +16 -0
  25. package/src/lib/components/badge/badge.test.tsx +29 -0
  26. package/src/lib/components/badge/badge.tsx +31 -0
  27. package/src/lib/components/badge/index.ts +1 -0
  28. package/{lib/components/card/atoms/card-frame.d.ts → src/lib/components/card/atoms/card-frame.tsx} +17 -7
  29. package/src/lib/components/card/atoms/index.ts +1 -0
  30. package/src/lib/components/card/card.test.tsx +163 -0
  31. package/src/lib/components/card/card.tsx +78 -0
  32. package/src/lib/components/card/components/card-alert-banner-slot.tsx +16 -0
  33. package/src/lib/components/card/components/card-controls-slot.tsx +19 -0
  34. package/src/lib/components/card/components/card-section-slot.tsx +51 -0
  35. package/src/lib/components/card/components/index.ts +3 -0
  36. package/src/lib/components/card/index.ts +2 -0
  37. package/src/lib/components/card/molecules/index.ts +1 -0
  38. package/src/lib/components/card/molecules/left-right-card.test.tsx +89 -0
  39. package/src/lib/components/card/molecules/left-right-card.tsx +63 -0
  40. package/src/lib/components/card/storybook/card.stories.mdx +100 -0
  41. package/src/lib/components/card/storybook/components.tsx +240 -0
  42. package/src/lib/components/checkbox/checkbox.test.tsx +39 -0
  43. package/src/lib/components/checkbox/checkbox.tsx +124 -0
  44. package/src/lib/components/checkbox/components/components.tsx +59 -0
  45. package/src/lib/components/checkbox/index.tsx +1 -0
  46. package/src/lib/components/checkbox/stories/checkbox.stories.mdx +54 -0
  47. package/src/lib/components/checkbox/stories/components.tsx +36 -0
  48. package/src/lib/components/checkbox/stories/index.tsx +1 -0
  49. package/src/lib/components/divider/divider-type-flags.tsx +37 -0
  50. package/src/lib/components/divider/divider.test.tsx +34 -0
  51. package/src/lib/components/divider/divider.tsx +37 -0
  52. package/src/lib/components/divider/index.tsx +1 -0
  53. package/src/lib/components/divider/stories/components.tsx +13 -0
  54. package/src/lib/components/divider/stories/divider.stories.mdx +50 -0
  55. package/src/lib/components/index.ts +14 -0
  56. package/src/lib/components/input-field/components/index.ts +2 -0
  57. package/src/lib/components/input-field/components/labeled-input.tsx +61 -0
  58. package/src/lib/components/input-field/components/stepper.tsx +59 -0
  59. package/src/lib/components/input-field/index.ts +6 -0
  60. package/src/lib/components/input-field/input-field.test.tsx +108 -0
  61. package/src/lib/components/input-field/input-field.tsx +126 -0
  62. package/src/lib/components/input-field/input-number.tsx +41 -0
  63. package/src/lib/components/input-field/input-text.tsx +30 -0
  64. package/src/lib/components/input-field/storybook/components.tsx +334 -0
  65. package/src/lib/components/input-field/storybook/input-field.stories.mdx +113 -0
  66. package/src/lib/components/layout/flex.tsx +22 -0
  67. package/src/lib/components/layout/grid-layout.tsx +40 -0
  68. package/src/lib/components/layout/index.ts +3 -0
  69. package/src/lib/components/layout/left-right-layout.tsx +67 -0
  70. package/src/lib/components/link/index.ts +1 -0
  71. package/src/lib/components/link/link.test.tsx +29 -0
  72. package/src/lib/components/link/link.tsx +56 -0
  73. package/src/lib/components/link/storybook/link.stories.mdx +51 -0
  74. package/src/lib/components/molecules/avatar/avatar-size-flags.tsx +55 -0
  75. package/src/lib/components/molecules/avatar/avatar.test.tsx +114 -0
  76. package/src/lib/components/molecules/avatar/avatar.tsx +80 -0
  77. package/src/lib/components/molecules/avatar/index.tsx +1 -0
  78. package/src/lib/components/molecules/avatar/stories/avatar.stories.mdx +55 -0
  79. package/src/lib/components/molecules/avatar/stories/components.tsx +36 -0
  80. package/src/lib/components/molecules/button/button-flags.tsx +235 -0
  81. package/src/lib/components/molecules/button/button.test.tsx +77 -0
  82. package/src/lib/components/molecules/button/button.tsx +231 -0
  83. package/src/lib/components/molecules/button/index.tsx +1 -0
  84. package/src/lib/components/molecules/button/stories/button.stories.mdx +104 -0
  85. package/src/lib/components/molecules/button/stories/components.tsx +86 -0
  86. package/src/lib/components/molecules/index.ts +3 -0
  87. package/src/lib/components/molecules/input-checkbox/index.tsx +1 -0
  88. package/src/lib/components/molecules/input-checkbox/input-checkbox.test.tsx +34 -0
  89. package/src/lib/components/molecules/input-checkbox/input-checkbox.tsx +50 -0
  90. package/src/lib/components/molecules/input-checkbox/stories/components.tsx +36 -0
  91. package/src/lib/components/molecules/input-checkbox/stories/index.tsx +1 -0
  92. package/src/lib/components/molecules/input-checkbox/stories/input-checkbox.stories.mdx +51 -0
  93. package/src/lib/components/organisms/index.ts +1 -0
  94. package/src/lib/components/organisms/multi-choice-list/index.tsx +1 -0
  95. package/src/lib/components/organisms/multi-choice-list/multi-choice-list.test.tsx +33 -0
  96. package/src/lib/components/organisms/multi-choice-list/multi-choice-list.tsx +53 -0
  97. package/src/lib/components/organisms/multi-choice-list/stories/components.tsx +126 -0
  98. package/src/lib/components/organisms/multi-choice-list/stories/index.tsx +1 -0
  99. package/src/lib/components/organisms/multi-choice-list/stories/multi-choice-list.stories.mdx +99 -0
  100. package/src/lib/components/spinner/index.tsx +1 -0
  101. package/src/lib/components/spinner/spinner-size-flags.tsx +39 -0
  102. package/src/lib/components/spinner/spinner.test.tsx +31 -0
  103. package/src/lib/components/spinner/spinner.tsx +67 -0
  104. package/src/lib/components/spinner/stories/components.tsx +8 -0
  105. package/src/lib/components/spinner/stories/spinner.stories.mdx +42 -0
  106. package/src/lib/components/thumbnail/index.tsx +1 -0
  107. package/src/lib/components/thumbnail/stories/thumbnail.stories.mdx +34 -0
  108. package/src/lib/components/thumbnail/thumbnail-size-flags.tsx +41 -0
  109. package/src/lib/components/thumbnail/thumbnail.test.tsx +51 -0
  110. package/src/lib/components/thumbnail/thumbnail.tsx +40 -0
  111. package/src/lib/components/typography/index.ts +1 -0
  112. package/src/lib/components/typography/storybook/components.tsx +256 -0
  113. package/src/lib/components/typography/storybook/typography.stories.mdx +88 -0
  114. package/src/lib/components/typography/typography.test.tsx +93 -0
  115. package/src/lib/components/typography/typography.tsx +57 -0
  116. package/src/lib/foundations/color-system/base-palette/base-palette.stories.tsx +123 -0
  117. package/src/lib/foundations/color-system/base-palette/base-palette.ts +94 -0
  118. package/src/lib/foundations/color-system/base-palette/index.ts +1 -0
  119. package/src/lib/foundations/color-system/color-guidelines/color-guidelines.stories.mdx +85 -0
  120. package/src/lib/foundations/color-system/color-guidelines/color-guidelines.stories.tsx +231 -0
  121. package/src/lib/foundations/color-system/color-guidelines/color-guidelines.ts +159 -0
  122. package/src/lib/foundations/color-system/color-guidelines/index.ts +1 -0
  123. package/src/lib/foundations/color-system/components/color-sample.tsx +99 -0
  124. package/src/lib/foundations/color-system/components/index.ts +1 -0
  125. package/src/lib/foundations/color-system/index.ts +1 -0
  126. package/src/lib/foundations/index.ts +4 -0
  127. package/src/lib/foundations/shadows/components.tsx +59 -0
  128. package/src/lib/foundations/shadows/index.ts +1 -0
  129. package/src/lib/foundations/shadows/shadows.stories.mdx +71 -0
  130. package/src/lib/foundations/shadows/shadows.tsx +47 -0
  131. package/src/lib/foundations/spacing/index.ts +1 -0
  132. package/src/lib/foundations/spacing/spacing-guidelines.ts +24 -0
  133. package/src/lib/foundations/spacing/spacing.stories.mdx +51 -0
  134. package/src/lib/foundations/spacing/spacing.ts +18 -0
  135. package/src/lib/foundations/typography/constants.ts +25 -0
  136. package/src/lib/foundations/typography/index.tsx +1 -0
  137. package/src/lib/foundations/typography/text-aspect-flags.ts +54 -0
  138. package/src/lib/foundations/typography/typography.tsx +97 -0
  139. package/src/lib/helpers/generic-types.ts +44 -0
  140. package/src/lib/helpers/index.ts +6 -0
  141. package/src/lib/helpers/nothing.tsx +18 -0
  142. package/{lib/helpers/numbers.d.ts → src/lib/helpers/numbers.ts} +53 -41
  143. package/src/lib/helpers/safe-navigation.ts +34 -0
  144. package/src/lib/helpers/slots.tsx +76 -0
  145. package/src/lib/helpers/strings.test.ts +47 -0
  146. package/src/lib/helpers/strings.ts +16 -0
  147. package/tsconfig.json +35 -0
  148. package/tsconfig.lib.json +28 -0
  149. package/tsconfig.spec.json +21 -0
  150. package/index.d.ts +0 -2
  151. package/index.js +0 -6078
  152. package/lib/components/alert-banner/alert-banner.d.ts +0 -11
  153. package/lib/components/alert-banner/alert-level-flags.d.ts +0 -13
  154. package/lib/components/alert-banner/index.d.ts +0 -1
  155. package/lib/components/badge/badge-type-flags.d.ts +0 -18
  156. package/lib/components/badge/badge.d.ts +0 -5
  157. package/lib/components/badge/index.d.ts +0 -1
  158. package/lib/components/card/atoms/index.d.ts +0 -1
  159. package/lib/components/card/card.d.ts +0 -14
  160. package/lib/components/card/components/card-alert-banner-slot.d.ts +0 -5
  161. package/lib/components/card/components/card-controls-slot.d.ts +0 -4
  162. package/lib/components/card/components/card-section-slot.d.ts +0 -11
  163. package/lib/components/card/components/index.d.ts +0 -3
  164. package/lib/components/card/index.d.ts +0 -2
  165. package/lib/components/card/molecules/index.d.ts +0 -1
  166. package/lib/components/card/molecules/left-right-card.d.ts +0 -16
  167. package/lib/components/checkbox/checkbox.d.ts +0 -11
  168. package/lib/components/checkbox/components/components.d.ts +0 -12
  169. package/lib/components/checkbox/index.d.ts +0 -1
  170. package/lib/components/divider/divider-type-flags.d.ts +0 -9
  171. package/lib/components/divider/divider.d.ts +0 -7
  172. package/lib/components/divider/index.d.ts +0 -1
  173. package/lib/components/index.d.ts +0 -12
  174. package/lib/components/input-field/components/index.d.ts +0 -2
  175. package/lib/components/input-field/components/labeled-input.d.ts +0 -11
  176. package/lib/components/input-field/components/stepper.d.ts +0 -7
  177. package/lib/components/input-field/index.d.ts +0 -3
  178. package/lib/components/input-field/input-field.d.ts +0 -25
  179. package/lib/components/input-field/input-number.d.ts +0 -18
  180. package/lib/components/input-field/input-text.d.ts +0 -14
  181. package/lib/components/layout/flex.d.ts +0 -16
  182. package/lib/components/layout/grid-layout.d.ts +0 -11
  183. package/lib/components/layout/index.d.ts +0 -3
  184. package/lib/components/layout/left-right-layout.d.ts +0 -70
  185. package/lib/components/link/index.d.ts +0 -1
  186. package/lib/components/link/link.d.ts +0 -14
  187. package/lib/components/molecules/avatar/avatar-size-flags.d.ts +0 -12
  188. package/lib/components/molecules/avatar/avatar.d.ts +0 -12
  189. package/lib/components/molecules/avatar/index.d.ts +0 -1
  190. package/lib/components/molecules/button/button-flags.d.ts +0 -39
  191. package/lib/components/molecules/button/button.d.ts +0 -24
  192. package/lib/components/molecules/button/index.d.ts +0 -1
  193. package/lib/components/molecules/index.d.ts +0 -3
  194. package/lib/components/molecules/input-checkbox/index.d.ts +0 -1
  195. package/lib/components/molecules/input-checkbox/input-checkbox.d.ts +0 -8
  196. package/lib/components/organisms/index.d.ts +0 -1
  197. package/lib/components/organisms/multi-choice-list/index.d.ts +0 -1
  198. package/lib/components/organisms/multi-choice-list/multi-choice-list.d.ts +0 -11
  199. package/lib/components/spinner/index.d.ts +0 -1
  200. package/lib/components/spinner/spinner-size-flags.d.ts +0 -10
  201. package/lib/components/spinner/spinner.d.ts +0 -9
  202. package/lib/components/thumbnail/index.d.ts +0 -1
  203. package/lib/components/thumbnail/thumbnail-size-flags.d.ts +0 -10
  204. package/lib/components/thumbnail/thumbnail.d.ts +0 -9
  205. package/lib/components/typography/index.d.ts +0 -1
  206. package/lib/components/typography/typography.d.ts +0 -23
  207. package/lib/foundations/color-system/base-palette/base-palette.d.ts +0 -77
  208. package/lib/foundations/color-system/base-palette/index.d.ts +0 -1
  209. package/lib/foundations/color-system/color-guidelines/color-guidelines.d.ts +0 -131
  210. package/lib/foundations/color-system/color-guidelines/index.d.ts +0 -1
  211. package/lib/foundations/color-system/components/color-sample.d.ts +0 -17
  212. package/lib/foundations/color-system/components/index.d.ts +0 -1
  213. package/lib/foundations/color-system/index.d.ts +0 -1
  214. package/lib/foundations/index.d.ts +0 -4
  215. package/lib/foundations/shadows/components.d.ts +0 -8
  216. package/lib/foundations/shadows/index.d.ts +0 -1
  217. package/lib/foundations/shadows/shadows.d.ts +0 -8
  218. package/lib/foundations/spacing/index.d.ts +0 -1
  219. package/lib/foundations/spacing/spacing-guidelines.d.ts +0 -22
  220. package/lib/foundations/spacing/spacing.d.ts +0 -18
  221. package/lib/foundations/typography/constants.d.ts +0 -22
  222. package/lib/foundations/typography/index.d.ts +0 -1
  223. package/lib/foundations/typography/text-aspect-flags.d.ts +0 -14
  224. package/lib/foundations/typography/typography.d.ts +0 -19
  225. package/lib/helpers/generic-types.d.ts +0 -21
  226. package/lib/helpers/index.d.ts +0 -6
  227. package/lib/helpers/nothing.d.ts +0 -8
  228. package/lib/helpers/safe-navigation.d.ts +0 -14
  229. package/lib/helpers/slots.d.ts +0 -8
  230. package/lib/helpers/strings.d.ts +0 -1
@@ -0,0 +1,33 @@
1
+ import { render, screen } from '@testing-library/react'
2
+ import { MultiChoiceList } from './multi-choice-list'
3
+
4
+ describe('MultiChoiceList Tests', () => {
5
+ it('should render the amount of checkbox matching with the options size', async () => {
6
+ render(
7
+ <MultiChoiceList options={[
8
+ {
9
+ label: 'My Awesome label',
10
+ id: 'My checkbox 1',
11
+ checked: true,
12
+ error: true,
13
+ helpfulMessage: 'Alternative text here',
14
+ },
15
+ {
16
+ label: 'My Awesome label',
17
+ id: 'My checkbox 2'
18
+ },
19
+ ]}
20
+ />
21
+ )
22
+
23
+ expect(screen.getByText('Alternative text here')).toBeInTheDocument()
24
+ expect(screen.getAllByRole('checkbox').length).toBe(2)
25
+ })
26
+ it('should not render anything if dont send valid options', async () => {
27
+ render(
28
+ <MultiChoiceList options={[]}
29
+ />
30
+ )
31
+ expect(screen.queryAllByRole('checkbox').length).toBe(0)
32
+ })
33
+ })
@@ -0,0 +1,53 @@
1
+ import styled from 'styled-components'
2
+ import { FC, isDefined, isEmpty, Nothing } from '@helpers'
3
+ import { Text , Margin } from '@foundations'
4
+ import { Flex } from 'components/layout'
5
+ import { Label1 } from 'components/typography'
6
+ import { InputCheckbox, IInputCheckbox } from '../../molecules/input-checkbox'
7
+
8
+ const HelpfulMessage = styled(Label1)`
9
+ margin-top: ${Margin.xxs};
10
+ margin-left: ${Margin.xl};
11
+ color: ${Text.Subdued};
12
+ user-select: none;
13
+ `
14
+ const Group = styled(Flex)`
15
+ width: 100%;
16
+ flex-direction: column;
17
+ gap: 18px;
18
+ `
19
+ interface IOption extends IInputCheckbox {
20
+ id: string
21
+ helpfulMessage?: string
22
+ }
23
+ interface IMultiChoiceList {
24
+ options: IOption[]
25
+ }
26
+
27
+ export const MultiChoiceList: FC<IMultiChoiceList> = (props: IMultiChoiceList) => {
28
+ const { options } = props
29
+
30
+ if (isEmpty(options)) {
31
+ return <Nothing />
32
+ }
33
+ return (
34
+ <Group role="group">
35
+ {options.map((option:IOption) => (
36
+ <div key={option.id}>
37
+ <InputCheckbox
38
+ aria-describedby={isDefined(option.helpfulMessage)
39
+ ? `${option.id}-id`
40
+ : ''
41
+ }
42
+ {...option}
43
+ />
44
+ {isDefined(option.helpfulMessage) && (
45
+ <HelpfulMessage id={`${option.id}-id`}>
46
+ {option.helpfulMessage}
47
+ </HelpfulMessage>
48
+ )}
49
+ </div>
50
+ ))}
51
+ </Group>
52
+ )
53
+ }
@@ -0,0 +1,126 @@
1
+ import { Body, Heading4 } from '@components'
2
+ import { Playground } from 'storybook-addon-jarle-monaco'
3
+ import { MultiChoiceList } from '../index'
4
+
5
+ export const PlainHTMLFormExample = () => (
6
+ <Playground
7
+ code={`
8
+ /* Edit this code sample! */
9
+ const [withError, setWithError] = useState(false);
10
+
11
+ <form onSubmit={(e) => {
12
+ e.preventDefault()
13
+ console.log('form submitted')
14
+ }}
15
+ >
16
+ <MultiChoiceList options={[
17
+ {
18
+ label: "My Awesome label",
19
+ id: 'My checkbox 1',
20
+ required: true,
21
+ error: withError,
22
+ helpfulMessage: 'Alternative text here',
23
+ onInvalid: function(e){
24
+ setWithError(true);
25
+ },
26
+ onChange: function(e){
27
+ console.log('at stories', e);
28
+ setWithError(false);
29
+ }
30
+ },
31
+ {
32
+ label: "My Awesome label",
33
+ id: 'My checkbox 2',
34
+ checked: true,
35
+ helpfulMessage: 'Alternative text here',
36
+ },
37
+ ]}
38
+ />
39
+ <input type="submit"/>
40
+ </form>
41
+ `}
42
+ providerProps={{
43
+ renderAsComponent: true,
44
+ scope: {
45
+ MultiChoiceList,
46
+ },
47
+ }}
48
+ />
49
+ )
50
+
51
+ export const ExampleWithStateManagement = () => (
52
+ <Playground
53
+ code={`
54
+ /* Edit this code sample! */
55
+ const Locations = [
56
+ {
57
+ label: "Vancouver, BC",
58
+ id: 1,
59
+ },
60
+ {
61
+ label: "Toronto, ON",
62
+ id: 2,
63
+ },
64
+ {
65
+ label: "Quebec, QC",
66
+ id: 3,
67
+ },
68
+ {
69
+ label: "Montreal, QC",
70
+ id: 4,
71
+ },
72
+ ];
73
+ const [locations, setLocations] = useState([]);
74
+ const [withError, setWithError] = useState(false);
75
+
76
+ const options = Locations.map((location) => {
77
+ return {
78
+ ...location,
79
+ checked: locations.find((l) => l.id === location.id),
80
+ onChange: (checked) => {
81
+ if (checked) {
82
+ setLocations([
83
+ ...locations,
84
+ location,
85
+ ])
86
+ } else {
87
+ const i = locations.findIndex((l) => l.id === location.id)
88
+ locations.splice(i, 1)
89
+ setLocations([
90
+ ...locations
91
+ ])
92
+ }
93
+ }
94
+ }
95
+ });
96
+
97
+ <>
98
+ <form onSubmit={(e) => {
99
+ e.preventDefault()
100
+ console.log('locations', locations)
101
+ }}
102
+ >
103
+ <MultiChoiceList options={options}
104
+ />
105
+ <input type="submit"/>
106
+ </form>
107
+ <div>
108
+ <Heading4>Your Selection</Heading4>
109
+ {locations.map((location) => {
110
+ return (
111
+ <Body key={location.id}>{location.label}</Body>
112
+ )
113
+ })}
114
+ </div>
115
+ </>
116
+ `}
117
+ providerProps={{
118
+ renderAsComponent: true,
119
+ scope: {
120
+ MultiChoiceList,
121
+ Heading4,
122
+ Body,
123
+ },
124
+ }}
125
+ />
126
+ )
@@ -0,0 +1 @@
1
+ export * from './components'
@@ -0,0 +1,99 @@
1
+ import { Canvas, Meta, Story } from '@storybook/addon-docs';
2
+ import { MultiChoiceList } from '../index'
3
+ import { PlainHTMLFormExample, ExampleWithStateManagement } from './index'
4
+
5
+ <Meta
6
+ title="Components/MultiChoiceList"
7
+ component={MultiChoiceList}
8
+ />
9
+
10
+ # MultiChoiceList
11
+
12
+ This is a organism, composed by checkbox molecule and some atoms.
13
+
14
+ For more details, check out the component page on [Figma](https://www.figma.com/file/ue1CurHfZ426o2T2l8Dk64/Edvisor-Product-Language?node-id=1097%3A2349)
15
+
16
+ ## How to use
17
+
18
+ ```javascript
19
+ // Import the component
20
+ import { MultiChoiceList } from './index'
21
+
22
+
23
+ // Render the component sending the required parameters
24
+ <MultiChoiceList options={[
25
+ {
26
+ label: 'My Awesome label',
27
+ checked: true,
28
+ id: '1',
29
+ }]
30
+ />
31
+ ```
32
+ ## Examples
33
+
34
+ <Canvas>
35
+ <MultiChoiceList options={[
36
+ {
37
+ label: "My Awesome label",
38
+ checked: true,
39
+ id: '1',
40
+ },
41
+ {
42
+ label: "My label",
43
+ id: '2',
44
+ },
45
+ {
46
+ label: "My label",
47
+ id: '3',
48
+ },
49
+ {
50
+ label: "My label",
51
+ id: '4',
52
+ },
53
+ ]}/>
54
+ </Canvas>
55
+
56
+ Also, you can send the altive text in order to helping user
57
+ <Canvas>
58
+ <MultiChoiceList options={[
59
+ {
60
+ label: "My Awesome label",
61
+ id: 'My checkbox 1',
62
+ checked: true,
63
+ error: true,
64
+ helpfulMessage: 'Alternative text here',
65
+ },
66
+ {
67
+ label: "My Awesome label",
68
+ id: 'My checkbox 2',
69
+ helpfulMessage: 'Alternative text here',
70
+ },
71
+ {
72
+ label: "My Awesome label",
73
+ id: 'My checkbox 3',
74
+ helpfulMessage: 'Alternative text here',
75
+ }
76
+ ]}/>
77
+ </Canvas>
78
+
79
+
80
+ ## API
81
+ This component receive a list (`options` parameter) from N amount of Checkbox if you'd like to render.
82
+ So all the possible values from Checkbox component can be passed here.
83
+ Also, you can sen this parameters:
84
+
85
+ | Name | Type | Description | Required (Y/N)|
86
+ | ---- | ----- | ------ | ----- |
87
+ | `id` | `string` | `The id from each checkbox in the list` | `Y` |
88
+ | `helpfulMessage` | `string` | `Message that will be render bellow each checkbox field` | `N` |
89
+
90
+ ## Playground
91
+
92
+ <PlainHTMLFormExample />
93
+
94
+ ### With State Management Example
95
+
96
+ <ExampleWithStateManagement />
97
+
98
+ ## Changelog
99
+ - Offer the "indeterminate" behavior to render this list nesting
@@ -0,0 +1 @@
1
+ export * from './spinner'
@@ -0,0 +1,39 @@
1
+ import { bitwiseOr, MappedEnum, RequireOnlyOne, PropsWithChildren } from '@helpers'
2
+
3
+ const enum SpinnerSize {
4
+ small = 1,
5
+ medium = 2,
6
+ large = 4,
7
+ }
8
+
9
+ type SpinnerSizes<T> = MappedEnum<typeof SpinnerSize, T>
10
+
11
+ function toSpinner(n: number): SpinnerSize {
12
+ switch (n) {
13
+ case SpinnerSize.small:
14
+ return SpinnerSize.small
15
+ case SpinnerSize.medium:
16
+ return SpinnerSize.medium
17
+ case SpinnerSize.large:
18
+ return SpinnerSize.large
19
+ default:
20
+ return SpinnerSize.medium
21
+ }
22
+ }
23
+
24
+ const SpinnerValues = {
25
+ [SpinnerSize.small]: '18px',
26
+ [SpinnerSize.medium]: '40px',
27
+ [SpinnerSize.large]: '60px',
28
+ }
29
+
30
+ export type SpinnerProps = Partial<RequireOnlyOne<SpinnerSizes<boolean>>> &
31
+ PropsWithChildren
32
+
33
+ export function getValuesBySize(props: SpinnerProps): string {
34
+ return SpinnerValues[
35
+ toSpinner(
36
+ bitwiseOr([props.small, props.medium, props.large])
37
+ )
38
+ ]
39
+ }
@@ -0,0 +1,31 @@
1
+ import { render, screen } from '@testing-library/react'
2
+ import { Spinner } from './index'
3
+
4
+ describe('Spinner Tests', () => {
5
+ describe('Spinner Tests', () => {
6
+ it('should render the Spinner with default size', async () => {
7
+ render(
8
+ <Spinner />
9
+ )
10
+
11
+ const spinner = screen.getByRole('progressbar')
12
+
13
+ expect(spinner).toBeInTheDocument()
14
+ expect(spinner).toHaveStyle('height: 40px')
15
+
16
+ })
17
+
18
+ it('should render the Spinner with small size', async () => {
19
+ render(
20
+ <Spinner small/>
21
+ )
22
+
23
+ const spinner = screen.getByRole('progressbar')
24
+
25
+ expect(spinner).toBeInTheDocument()
26
+ expect(spinner).toHaveStyle('height: 18px')
27
+
28
+ })
29
+
30
+ })
31
+ })
@@ -0,0 +1,67 @@
1
+ import { getValuesBySize, SpinnerProps } from './spinner-size-flags'
2
+ import { FC, is } from '@helpers'
3
+ import styled, { keyframes } from 'styled-components'
4
+ import { Icons } from '@foundations'
5
+
6
+ const spinAnimation = keyframes`
7
+ 0% {
8
+ transform: rotate(0deg);
9
+ stroke-dashoffset: 25;
10
+ }
11
+ 50% {
12
+ transform: rotate(720deg);
13
+ stroke-dashoffset: 125;
14
+ }
15
+ 100% {
16
+ transform: rotate(1080deg);
17
+ stroke-dashoffset: 25;
18
+ }
19
+ `
20
+
21
+ const Spin = styled.svg<{ size: string, onPrimary: boolean, onCritical: boolean }>`
22
+ width: ${({ size }) => size};
23
+ height: ${({ size }) => size};
24
+ fill: none;
25
+ path {
26
+ fill-rule: evenodd;
27
+ clip-rule: evenodd;
28
+ fill: ${({ onPrimary, onCritical }) => (onPrimary || onCritical) ? Icons.OnPrimary : Icons.Default};
29
+ stroke: ${({ onPrimary, onCritical }) => (onPrimary || onCritical) ? Icons.OnPrimary : Icons.Default};
30
+ -webkit-transform-origin: 20px 20 0;
31
+ -moz-transform-origin: 20px 20px 0;
32
+ -ms-transform-origin: 20px 20px 0;
33
+ -o-transform-origin: 20px 20px 0;
34
+ transform-origin: 20px 20px 0;
35
+ -webkit-animation: spinner 2s linear infinite;
36
+ -moz-animation: spinner 2s linear infinite;
37
+ -ms-animation: spinner 2s linear infinite;
38
+ -o-animation: spinner 2s linear infinite;
39
+ animation: spinner 2s linear infinite;
40
+ animation-name: ${spinAnimation};
41
+ }
42
+ `
43
+
44
+ type IProps = SpinnerProps & {
45
+ onPrimary?: boolean
46
+ onCritical?: boolean
47
+ className?: string
48
+ }
49
+
50
+ export const Spinner : FC<IProps> = (props) => {
51
+ const size = getValuesBySize(props)
52
+
53
+ return (
54
+ <Spin
55
+ onPrimary={is(props.onPrimary)}
56
+ onCritical={is(props.onCritical)}
57
+ className={props.className}
58
+ size={size}
59
+ role="progressbar"
60
+ viewBox="0 0 40 40"
61
+ xmlns="http://www.w3.org/2000/svg"
62
+ >
63
+ <path d="M20 3.5C10.8873 3.5 3.5 10.8873 3.5 20C3.5 29.1127 10.8873 36.5 20 36.5C20.2593 36.5 20.517 36.494 20.7732 36.4822C21.6007 36.4441 22.3578 37.0111 22.4704 37.8319C22.5831 38.6526 22.0089 39.4152 21.182 39.4647C20.7908 39.4881 20.3967 39.5 20 39.5C9.23045 39.5 0.5 30.7696 0.5 20C0.5 9.23045 9.23045 0.5 20 0.5C26.0299 0.5 31.4203 3.23815 34.9953 7.53374C35.5252 8.17049 35.3622 9.11117 34.6867 9.59078C34.0113 10.0704 33.0798 9.90641 32.5411 9.27701C29.5131 5.73882 25.018 3.5 20 3.5Z" />
64
+ </Spin>
65
+ )
66
+ }
67
+
@@ -0,0 +1,8 @@
1
+ import styled from 'styled-components'
2
+ import { Padding, Surface } from '@foundations'
3
+
4
+ export const WrapperStories = styled.div`
5
+ width: 100%;
6
+ padding: ${Padding.s};
7
+ background: ${Surface.Default.Default};
8
+ `
@@ -0,0 +1,42 @@
1
+ import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
2
+ import { StoryComponent, talesOf, StorybookFrame } from '@stories'
3
+ import { Spinner } from '../index'
4
+ import { ButtonPrimary, ButtonDestructive } from 'components/molecules/button'
5
+
6
+ import { WrapperStories } from './components'
7
+
8
+ <Meta title="Components/Spinner" />
9
+
10
+ # Spinner
11
+
12
+ Spinners are used to notify users that their action is being processed.
13
+
14
+ For more details, check out the guidelines on [Figma](https://www.figma.com/file/ue1CurHfZ426o2T2l8Dk64/Edvisor-Product-Language?node-id=734%3A7380)
15
+
16
+ ## How to Use
17
+
18
+ ```tsx
19
+ import { Spinner } from './index'
20
+
21
+ <Spinner />
22
+ ```
23
+
24
+ ### Size
25
+
26
+ <Canvas>
27
+ <Spinner small/>
28
+ <Spinner />
29
+ </Canvas>
30
+
31
+ ### On primary
32
+
33
+ When rendering the spinner on a primary or critical surface, use onPrimary or onCritical.
34
+
35
+ <Canvas>
36
+ <ButtonPrimary>
37
+ <Spinner onPrimary />
38
+ </ButtonPrimary>
39
+ <ButtonDestructive primary>
40
+ <Spinner onCritical />
41
+ </ButtonDestructive>
42
+ </Canvas>
@@ -0,0 +1 @@
1
+ export * from './thumbnail'
@@ -0,0 +1,34 @@
1
+ import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
2
+ import { Thumbnail } from '../index'
3
+ import { SpaceAround } from '../../layout'
4
+
5
+ <Meta
6
+ title="Components/Thumbnail"
7
+ component={Thumbnail}
8
+ />
9
+
10
+ # Thumbnail
11
+
12
+ For more details, check out the component page on [Figma](https://www.figma.com/file/ue1CurHfZ426o2T2l8Dk64/Edvisor-Product-Language?node-id=1545%3A4445)
13
+
14
+ ## How to use
15
+
16
+ ```javascript
17
+ // Import the component
18
+ import { Thumbnail } from './index'
19
+
20
+
21
+ // Render the component sending the required parameters
22
+ <Thumbnail imageUrl='https://blog.edvisor.io/hubfs/Edvisor%20Smi.png'/>
23
+ ```
24
+ ## Good Practices
25
+ - You can send the `imageLabel` propertie as an `alt` propertie in order to set and alternative text to image
26
+
27
+ ## Examples
28
+
29
+ <Canvas>
30
+ <Thumbnail large imageUrl='https://blog.edvisor.io/hubfs/Edvisor%20Smi.png'/>
31
+ <Thumbnail medium imageUrl='https://blog.edvisor.io/hubfs/Edvisor%20Smi.png'/>
32
+ <Thumbnail small imageUrl='https://blog.edvisor.io/hubfs/Edvisor%20Smi.png'/>
33
+ </Canvas>
34
+
@@ -0,0 +1,41 @@
1
+ // this file was generated, but it is safe to modify
2
+ import { bitwiseOr, MappedEnum, RequireOnlyOne, PropsWithChildren } from '@helpers'
3
+
4
+ const enum ThumbnailSize {
5
+ small = 1,
6
+ medium = 2,
7
+ large = 4,
8
+ }
9
+
10
+ type ThumbnailSizes<T> = MappedEnum<typeof ThumbnailSize, T>
11
+
12
+ function toThumbnailSize(n: number): ThumbnailSize {
13
+ switch (n) {
14
+ case ThumbnailSize.small:
15
+ return ThumbnailSize.small
16
+ case ThumbnailSize.medium:
17
+ return ThumbnailSize.medium
18
+ case ThumbnailSize.large:
19
+ return ThumbnailSize.large
20
+ default:
21
+ return ThumbnailSize.medium
22
+ }
23
+ }
24
+
25
+ const ThumbnailSizeValues = {
26
+ [ThumbnailSize.small]: '40px',
27
+ [ThumbnailSize.medium]: '60px',
28
+ [ThumbnailSize.large]: '80px',
29
+ }
30
+
31
+
32
+ export type ThumbnailSizeProps = Partial<RequireOnlyOne<ThumbnailSizes<boolean>>> &
33
+ PropsWithChildren
34
+
35
+ export function getValuesBySize(props: ThumbnailSizeProps): string {
36
+ return ThumbnailSizeValues[
37
+ toThumbnailSize(
38
+ bitwiseOr([props.small, props.medium, props.large])
39
+ )
40
+ ]
41
+ }
@@ -0,0 +1,51 @@
1
+ import {render, screen } from '@testing-library/react'
2
+ import { Thumbnail } from './index'
3
+
4
+ describe('Thumbnail Tests', () => {
5
+ describe('Thumbnail Tests', () => {
6
+ it('should render the Thumbnail with size small', () => {
7
+ render(
8
+ <Thumbnail
9
+ imageUrl='https://blog.edvisor.io/hubfs/Edvisor%20Smi.png'
10
+ small
11
+ />
12
+ )
13
+
14
+ expect(screen.getByRole('img')).toBeInTheDocument()
15
+ expect(screen.getByTestId('thumbnail-test')).toHaveStyle('height: 40px')
16
+ })
17
+
18
+ it('should render the Thumbnail with size medium', () => {
19
+ render(
20
+ <Thumbnail
21
+ imageUrl='https://blog.edvisor.io/hubfs/Edvisor%20Smi.png'
22
+ medium
23
+ />
24
+ )
25
+
26
+ expect(screen.getByRole('img')).toBeInTheDocument()
27
+ expect(screen.getByTestId('thumbnail-test')).toHaveStyle('height: 60px')
28
+ })
29
+
30
+ it('should render the Thumbnail with size large', () => {
31
+ render(
32
+ <Thumbnail
33
+ imageUrl='https://blog.edvisor.io/hubfs/Edvisor%20Smi.png'
34
+ large
35
+ />
36
+ )
37
+
38
+ expect(screen.getByRole('img')).toBeInTheDocument()
39
+ expect(screen.getByTestId('thumbnail-test')).toHaveStyle('height: 80px')
40
+ })
41
+
42
+ it('should not render the Thumbnail without imageUrl', () => {
43
+ render(
44
+ <Thumbnail />
45
+ )
46
+
47
+ const thumbnailElement = screen.queryByText('thumbnail-test')
48
+ expect(thumbnailElement).not.toBeInTheDocument()
49
+ })
50
+ })
51
+ })
@@ -0,0 +1,40 @@
1
+ import styled from 'styled-components'
2
+ import { FC, isNil, Nothing } from '@helpers'
3
+ import { Borders, Padding } from '@foundations'
4
+ import { SpaceAround } from '../layout/'
5
+ import { ThumbnailSizeProps, getValuesBySize } from './thumbnail-size-flags'
6
+
7
+ const Box = styled(SpaceAround)<{ size: string }>`
8
+ width: ${({ size }) => size};
9
+ height: ${({ size }) => size};
10
+ border-radius: 6px;
11
+ border: 1px solid ${Borders.Default};
12
+ padding: ${Padding.xs};
13
+ box-sizing: border-box;
14
+ `
15
+
16
+ const Image = styled.img`
17
+ width: 100%;
18
+ height: 100%;
19
+ `
20
+
21
+ interface IThumbnailProps {
22
+ imageUrl?: string;
23
+ imageLabel?: string;
24
+ }
25
+ type IProps = IThumbnailProps & ThumbnailSizeProps
26
+
27
+ export const Thumbnail: FC<IProps> = (props) => {
28
+ const { imageUrl, imageLabel = imageUrl } = props
29
+ const size = getValuesBySize(props)
30
+
31
+ if (isNil(imageUrl)) {
32
+ return <Nothing/>
33
+ }
34
+
35
+ return (
36
+ <Box size={size} data-testid="thumbnail-test">
37
+ <Image src={imageUrl} alt={imageLabel}/>
38
+ </Box>
39
+ )
40
+ }
@@ -0,0 +1 @@
1
+ export * from './typography'