@popsure/dirty-swan 0.26.9 → 0.26.12

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 (241) hide show
  1. package/dist/index.css +63 -1
  2. package/dist/index.css.map +1 -1
  3. package/dist/lib/scss/private/base/_border_radius.scss +15 -0
  4. package/dist/lib/scss/private/base/_grid.scss +8 -0
  5. package/dist/lib/scss/private/base/_index.scss +1 -0
  6. package/dist/lib/scss/private/base/style.module.scss +10 -0
  7. package/dist/lib/scss/private/components/_buttons.scss +1 -1
  8. package/dist/lib/scss/public/colors/default.scss +2 -0
  9. package/dist/lib/scss/public/demo.tsx +13 -1
  10. package/package.json +2 -1
  11. package/src/App.tsx +50 -0
  12. package/src/bin/index.ts +71 -0
  13. package/src/bin/tsconfig.json +13 -0
  14. package/src/bin/util/index.test.ts +85 -0
  15. package/src/bin/util/index.ts +132 -0
  16. package/src/bin/util/test/data.json +13 -0
  17. package/src/colors.scss +1 -0
  18. package/src/font-weight.scss +1 -0
  19. package/src/grid.scss +1 -0
  20. package/src/index.tsx +37 -0
  21. package/src/intro.stories.mdx +41 -0
  22. package/src/lib/components/autocompleteAddress/demo.tsx +38 -0
  23. package/src/lib/components/autocompleteAddress/index.stories.mdx +44 -0
  24. package/src/lib/components/autocompleteAddress/index.tsx +316 -0
  25. package/src/lib/components/autocompleteAddress/mapStyle.ts +187 -0
  26. package/src/lib/components/autocompleteAddress/style.module.scss +82 -0
  27. package/src/lib/components/autocompleteAddress/util/index.test.ts +51 -0
  28. package/src/lib/components/autocompleteAddress/util/index.ts +55 -0
  29. package/src/lib/components/button/icons/index.ts +14 -0
  30. package/src/lib/components/button/icons/send-purple.svg +4 -0
  31. package/src/lib/components/button/icons/send-white.svg +4 -0
  32. package/src/lib/components/button/index.stories.mdx +121 -0
  33. package/src/lib/components/button/index.tsx +64 -0
  34. package/src/lib/components/button/styles.module.scss +5 -0
  35. package/src/lib/components/cards/a.stories.mdx +44 -0
  36. package/src/lib/components/cards/cardButton/index.stories.mdx +47 -0
  37. package/src/lib/components/cards/cardButton/index.tsx +61 -0
  38. package/src/lib/components/cards/cardButton/style.module.scss +33 -0
  39. package/src/lib/components/cards/cardWithLeftIcon/index.stories.mdx +103 -0
  40. package/src/lib/components/cards/cardWithLeftIcon/index.tsx +87 -0
  41. package/src/lib/components/cards/cardWithLeftIcon/style.module.scss +23 -0
  42. package/src/lib/components/cards/cardWithTopIcon/index.stories.mdx +105 -0
  43. package/src/lib/components/cards/cardWithTopIcon/index.tsx +60 -0
  44. package/src/lib/components/cards/cardWithTopIcon/style.module.scss +10 -0
  45. package/src/lib/components/cards/cardWithTopLeftIcon/index.stories.mdx +101 -0
  46. package/src/lib/components/cards/cardWithTopLeftIcon/index.tsx +72 -0
  47. package/src/lib/components/cards/cardWithTopLeftIcon/style.module.scss +21 -0
  48. package/src/lib/components/cards/icons/arrow-right.svg +4 -0
  49. package/src/lib/components/cards/icons/chevron-right.svg +3 -0
  50. package/src/lib/components/cards/icons/feather-logo.svg +10 -0
  51. package/src/lib/components/cards/icons/index.ts +36 -0
  52. package/src/lib/components/cards/icons/info.svg +12 -0
  53. package/src/lib/components/cards/index.test.ts +37 -0
  54. package/src/lib/components/cards/index.tsx +57 -0
  55. package/src/lib/components/cards/infoCard/index.stories.mdx +61 -0
  56. package/src/lib/components/cards/infoCard/index.tsx +47 -0
  57. package/src/lib/components/cards/infoCard/style.module.scss +53 -0
  58. package/src/lib/components/chip/icons/remove-button-highlighted.svg +4 -0
  59. package/src/lib/components/chip/icons/remove-button.svg +4 -0
  60. package/src/lib/components/chip/index.stories.mdx +101 -0
  61. package/src/lib/components/chip/index.tsx +38 -0
  62. package/src/lib/components/chip/style.module.scss +54 -0
  63. package/src/lib/components/comparisonTable/components/Chevron.tsx +19 -0
  64. package/src/lib/components/comparisonTable/components/Row/index.tsx +68 -0
  65. package/src/lib/components/comparisonTable/components/Row/style.module.scss +114 -0
  66. package/src/lib/components/comparisonTable/components/TableArrows/Arrow.tsx +19 -0
  67. package/src/lib/components/comparisonTable/components/TableArrows/index.tsx +52 -0
  68. package/src/lib/components/comparisonTable/components/TableArrows/style.module.scss +53 -0
  69. package/src/lib/components/comparisonTable/components/TableInfoButton/index.tsx +37 -0
  70. package/src/lib/components/comparisonTable/components/TableInfoButton/style.module.scss +30 -0
  71. package/src/lib/components/comparisonTable/components/TableRating/StarIcon.tsx +13 -0
  72. package/src/lib/components/comparisonTable/components/TableRating/ZapIcon.tsx +17 -0
  73. package/src/lib/components/comparisonTable/components/TableRating/index.tsx +45 -0
  74. package/src/lib/components/comparisonTable/components/TableRating/style.module.scss +13 -0
  75. package/src/lib/components/comparisonTable/components/TableRowHeader/index.tsx +35 -0
  76. package/src/lib/components/comparisonTable/components/TableRowHeader/style.module.scss +3 -0
  77. package/src/lib/components/comparisonTable/components/TableTrueFalse.tsx +40 -0
  78. package/src/lib/components/comparisonTable/hooks/useActiveTableArrows.ts +63 -0
  79. package/src/lib/components/comparisonTable/index.stories.mdx +254 -0
  80. package/src/lib/components/comparisonTable/index.tsx +211 -0
  81. package/src/lib/components/comparisonTable/style.module.scss +104 -0
  82. package/src/lib/components/dateSelector/datepicker.scss +406 -0
  83. package/src/lib/components/dateSelector/icons/calendar.svg +6 -0
  84. package/src/lib/components/dateSelector/icons/chevron-left.svg +3 -0
  85. package/src/lib/components/dateSelector/icons/chevron-right.svg +3 -0
  86. package/src/lib/components/dateSelector/index.stories.mdx +62 -0
  87. package/src/lib/components/dateSelector/index.test.ts +33 -0
  88. package/src/lib/components/dateSelector/index.tsx +247 -0
  89. package/src/lib/components/dateSelector/style.module.scss +77 -0
  90. package/src/lib/components/downloadButton/icons/check.svg +3 -0
  91. package/src/lib/components/downloadButton/icons/download.svg +5 -0
  92. package/src/lib/components/downloadButton/index.stories.mdx +59 -0
  93. package/src/lib/components/downloadButton/index.tsx +67 -0
  94. package/src/lib/components/downloadButton/style.module.scss +19 -0
  95. package/src/lib/components/downloadRing/icons/check-outside-circle.tsx +26 -0
  96. package/src/lib/components/downloadRing/icons/download-cloud.tsx +18 -0
  97. package/src/lib/components/downloadRing/icons/style.module.scss +7 -0
  98. package/src/lib/components/downloadRing/index.stories.mdx +35 -0
  99. package/src/lib/components/downloadRing/index.tsx +79 -0
  100. package/src/lib/components/downloadRing/style.module.scss +66 -0
  101. package/src/lib/components/dropzone/images/error.tsx +18 -0
  102. package/src/lib/components/dropzone/images/file.tsx +26 -0
  103. package/src/lib/components/dropzone/images/style.module.scss +7 -0
  104. package/src/lib/components/dropzone/images/upload-complete.tsx +24 -0
  105. package/src/lib/components/dropzone/images/upload.tsx +18 -0
  106. package/src/lib/components/dropzone/index.stories.mdx +44 -0
  107. package/src/lib/components/dropzone/index.tsx +152 -0
  108. package/src/lib/components/dropzone/style.module.scss +90 -0
  109. package/src/lib/components/input/a.stories.mdx +28 -0
  110. package/src/lib/components/input/autoSuggestInput/index.stories.mdx +137 -0
  111. package/src/lib/components/input/autoSuggestInput/index.tsx +81 -0
  112. package/src/lib/components/input/autoSuggestInput/style.module.scss +71 -0
  113. package/src/lib/components/input/autoSuggestMultiSelect/index.stories.mdx +115 -0
  114. package/src/lib/components/input/autoSuggestMultiSelect/index.tsx +75 -0
  115. package/src/lib/components/input/autoSuggestMultiSelect/style.module.scss +4 -0
  116. package/src/lib/components/input/currency/format/index.test.ts +49 -0
  117. package/src/lib/components/input/currency/format/index.ts +15 -0
  118. package/src/lib/components/input/currency/index.stories.mdx +25 -0
  119. package/src/lib/components/input/currency/index.test.tsx +56 -0
  120. package/src/lib/components/input/currency/index.tsx +53 -0
  121. package/src/lib/components/input/iban/formatIban/index.test.ts +11 -0
  122. package/src/lib/components/input/iban/formatIban/index.ts +22 -0
  123. package/src/lib/components/input/iban/index.stories.mdx +21 -0
  124. package/src/lib/components/input/iban/index.tsx +20 -0
  125. package/src/lib/components/input/index.stories.mdx +62 -0
  126. package/src/lib/components/input/index.tsx +51 -0
  127. package/src/lib/components/input/style.module.scss +94 -0
  128. package/src/lib/components/modal/bottomModal/img/close.svg +4 -0
  129. package/src/lib/components/modal/bottomModal/index.tsx +68 -0
  130. package/src/lib/components/modal/bottomModal/style.module.scss +104 -0
  131. package/src/lib/components/modal/bottomOrRegularModal/index.tsx +43 -0
  132. package/src/lib/components/modal/bottomOrRegularModal/style.module.scss +16 -0
  133. package/src/lib/components/modal/hooks/useOnClose.ts +51 -0
  134. package/src/lib/components/modal/index.stories.mdx +316 -0
  135. package/src/lib/components/modal/index.ts +14 -0
  136. package/src/lib/components/modal/regularModal/img/close.svg +4 -0
  137. package/src/lib/components/modal/regularModal/index.tsx +55 -0
  138. package/src/lib/components/modal/regularModal/style.module.scss +106 -0
  139. package/src/lib/components/multiDropzone/UploadFileCell/index.tsx +138 -0
  140. package/src/lib/components/multiDropzone/UploadFileCell/style.module.scss +101 -0
  141. package/src/lib/components/multiDropzone/icons/bmp-complete.svg +10 -0
  142. package/src/lib/components/multiDropzone/icons/bmp.svg +10 -0
  143. package/src/lib/components/multiDropzone/icons/doc-complete.svg +11 -0
  144. package/src/lib/components/multiDropzone/icons/doc.svg +11 -0
  145. package/src/lib/components/multiDropzone/icons/docx-complete.svg +12 -0
  146. package/src/lib/components/multiDropzone/icons/docx.svg +12 -0
  147. package/src/lib/components/multiDropzone/icons/eye.svg +4 -0
  148. package/src/lib/components/multiDropzone/icons/generic-complete.svg +4 -0
  149. package/src/lib/components/multiDropzone/icons/generic-error.svg +7 -0
  150. package/src/lib/components/multiDropzone/icons/generic.svg +4 -0
  151. package/src/lib/components/multiDropzone/icons/heic-complete.svg +11 -0
  152. package/src/lib/components/multiDropzone/icons/heic.svg +11 -0
  153. package/src/lib/components/multiDropzone/icons/index.ts +51 -0
  154. package/src/lib/components/multiDropzone/icons/jpeg-complete.svg +11 -0
  155. package/src/lib/components/multiDropzone/icons/jpeg.svg +11 -0
  156. package/src/lib/components/multiDropzone/icons/jpg-complete.svg +10 -0
  157. package/src/lib/components/multiDropzone/icons/jpg.svg +10 -0
  158. package/src/lib/components/multiDropzone/icons/pdf-complete.svg +8 -0
  159. package/src/lib/components/multiDropzone/icons/pdf.svg +8 -0
  160. package/src/lib/components/multiDropzone/icons/png-complete.svg +10 -0
  161. package/src/lib/components/multiDropzone/icons/png.svg +10 -0
  162. package/src/lib/components/multiDropzone/icons/trash.svg +6 -0
  163. package/src/lib/components/multiDropzone/icons/upload.svg +5 -0
  164. package/src/lib/components/multiDropzone/index.stories.mdx +91 -0
  165. package/src/lib/components/multiDropzone/index.tsx +99 -0
  166. package/src/lib/components/multiDropzone/style.module.scss +32 -0
  167. package/src/lib/components/segmentedControl/index.stories.mdx +47 -0
  168. package/src/lib/components/segmentedControl/index.tsx +105 -0
  169. package/src/lib/components/segmentedControl/style.module.scss +36 -0
  170. package/src/lib/components/signaturePad/img/reset.svg +4 -0
  171. package/src/lib/components/signaturePad/img/sign.svg +3 -0
  172. package/src/lib/components/signaturePad/index.stories.mdx +17 -0
  173. package/src/lib/components/signaturePad/index.tsx +96 -0
  174. package/src/lib/components/signaturePad/style.module.scss +90 -0
  175. package/src/lib/index.tsx +71 -0
  176. package/src/lib/models/autoSuggestInput/index.ts +4 -0
  177. package/src/lib/models/download.ts +1 -0
  178. package/src/lib/models/downloadRing/index.ts +6 -0
  179. package/src/lib/scss/index.scss +22 -0
  180. package/src/lib/scss/private/_reset.scss +149 -0
  181. package/src/lib/scss/private/base/_border_radius.scss +15 -0
  182. package/src/lib/scss/private/base/_colors.scss +19 -0
  183. package/src/lib/scss/private/base/_cursors.scss +31 -0
  184. package/src/lib/scss/private/base/_display.scss +35 -0
  185. package/src/lib/scss/private/base/_grid.scss +60 -0
  186. package/src/lib/scss/private/base/_index.scss +10 -0
  187. package/src/lib/scss/private/base/_shadows.scss +2 -0
  188. package/src/lib/scss/private/base/_spacing.scss +89 -0
  189. package/src/lib/scss/private/base/_typography.scss +128 -0
  190. package/src/lib/scss/private/base/_width_and_height.scss +25 -0
  191. package/src/lib/scss/private/base/border_radius.stories.mdx +43 -0
  192. package/src/lib/scss/private/base/cursors.stories.mdx +18 -0
  193. package/src/lib/scss/private/base/demo.tsx +119 -0
  194. package/src/lib/scss/private/base/display.stories.mdx +19 -0
  195. package/src/lib/scss/private/base/flex/_flex.scss +63 -0
  196. package/src/lib/scss/private/base/flex/flex.stories.mdx +139 -0
  197. package/src/lib/scss/private/base/flex/style.module.scss +24 -0
  198. package/src/lib/scss/private/base/spacing.stories.mdx +185 -0
  199. package/src/lib/scss/private/base/style.module.scss +52 -0
  200. package/src/lib/scss/private/base/typography.stories.mdx +71 -0
  201. package/src/lib/scss/private/base/width_and_height.stories.mdx +172 -0
  202. package/src/lib/scss/private/components/_badge.scss +41 -0
  203. package/src/lib/scss/private/components/_buttons.scss +193 -0
  204. package/src/lib/scss/private/components/_cards.scss +32 -0
  205. package/src/lib/scss/private/components/_index.scss +6 -0
  206. package/src/lib/scss/private/components/_input.scss +241 -0
  207. package/src/lib/scss/private/components/_notices.scss +39 -0
  208. package/src/lib/scss/private/components/_spinner.scss +60 -0
  209. package/src/lib/scss/private/components/assets/checkmark.svg +3 -0
  210. package/src/lib/scss/private/components/assets/icon-form-dropdown.svg +3 -0
  211. package/src/lib/scss/private/components/badge.stories.mdx +37 -0
  212. package/src/lib/scss/private/components/button.stories.mdx +107 -0
  213. package/src/lib/scss/private/components/cards.stories.mdx +35 -0
  214. package/src/lib/scss/private/components/checkbox.stories.mdx +47 -0
  215. package/src/lib/scss/private/components/input.stories.mdx +33 -0
  216. package/src/lib/scss/private/components/notices.stories.mdx +37 -0
  217. package/src/lib/scss/private/components/radio.stories.mdx +47 -0
  218. package/src/lib/scss/private/components/select.stories.mdx +17 -0
  219. package/src/lib/scss/private/components/spinner.stories.mdx +25 -0
  220. package/src/lib/scss/public/colors/_index.scss +2 -0
  221. package/src/lib/scss/public/colors/default.scss +127 -0
  222. package/src/lib/scss/public/colors/overrides.scss +0 -0
  223. package/src/lib/scss/public/colors.stories.mdx +27 -0
  224. package/src/lib/scss/public/demo.tsx +297 -0
  225. package/src/lib/scss/public/font/_index.scss +2 -0
  226. package/src/lib/scss/public/font/default.scss +3 -0
  227. package/src/lib/scss/public/font/overrides.scss +0 -0
  228. package/src/lib/scss/public/font-weight.scss +9 -0
  229. package/src/lib/scss/public/font-weight.stories.mdx +32 -0
  230. package/src/lib/scss/public/grid.scss +21 -0
  231. package/src/lib/scss/public/grid.stories.mdx +41 -0
  232. package/src/lib/scss/third-party/_google_places.scss +62 -0
  233. package/src/lib/scss/third-party/_index.scss +1 -0
  234. package/src/lib/scss/utils/_index.scss +3 -0
  235. package/src/lib/util/calendarDate/index.test.ts +32 -0
  236. package/src/lib/util/calendarDate/index.ts +30 -0
  237. package/src/lib/util/zeroFill.test.ts +15 -0
  238. package/src/lib/util/zeroFill.ts +7 -0
  239. package/src/react-app-env.d.ts +1 -0
  240. package/src/setupTests.js +8 -0
  241. package/src/theme.stories.mdx +54 -0
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M15 18.1406L9 12.1406L15 6.14062" stroke="#26262E" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M9.04504 18.1406L15.045 12.1406L9.04504 6.14062" stroke="#26262E" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
3
+ </svg>
@@ -0,0 +1,62 @@
1
+ import { useState } from 'react';
2
+ import { Meta, Preview } from '@storybook/addon-docs/blocks';
3
+
4
+ import DateSelector from '.';
5
+
6
+ <Meta title="JSX/Date selector" component={DateSelector} />
7
+
8
+ # Date selector
9
+
10
+ Date selector are user interface elements which allow user to select a date in the `YYYY-MM-DD` format.
11
+
12
+ <Preview>
13
+ <iframe
14
+ width="100%"
15
+ height="450"
16
+ src="https://www.figma.com/embed?embed_host=share&url=https%3A%2F%2Fwww.figma.com%2Ffile%2FMKs4cbojdVOBKUxv7okb93%2FDirty-Swan-Design-System%3Fnode-id%3D293%253A169"
17
+ allowFullScreen
18
+ ></iframe>
19
+ </Preview>
20
+
21
+ ## Default example
22
+
23
+ ### Without calendar
24
+
25
+ export const DateSelectorWithoutCalendarStory = () => {
26
+ const [date, setDate] = useState('');
27
+ return (
28
+ <>
29
+ <DateSelector
30
+ value={date}
31
+ className="mt24"
32
+ yearBoundaries={{ min: 2020, max: 2022 }}
33
+ onChange={(date) => {
34
+ setDate(date);
35
+ }}
36
+ />
37
+ </>
38
+ );
39
+ };
40
+
41
+ <DateSelectorWithoutCalendarStory />
42
+
43
+ ### With calendar
44
+
45
+ export const DateSelectorWithCalendarStory = () => {
46
+ const [date, setDate] = useState('');
47
+ return (
48
+ <div style={{ paddingBottom: '120px' }}>
49
+ <DateSelector
50
+ value={date}
51
+ className="mt24"
52
+ yearBoundaries={{ min: 2020, max: 2022 }}
53
+ onChange={(date) => {
54
+ setDate(date);
55
+ }}
56
+ displayCalendar={true}
57
+ />
58
+ </div>
59
+ );
60
+ };
61
+
62
+ <DateSelectorWithCalendarStory />
@@ -0,0 +1,33 @@
1
+ import { fillArray, daysInMonthOfYear } from '.';
2
+
3
+ describe('fillArray tests', () => {
4
+ it('Should fill array from 1 to 10 ascending', () => {
5
+ const expectedOutput = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
6
+
7
+ expect(fillArray(1, 10)).toEqual(expectedOutput);
8
+ });
9
+
10
+ it('Should fill array from 10 to 5 descending', () => {
11
+ const expectedOutput = [10, 9, 8, 7, 6, 5];
12
+
13
+ expect(fillArray(10, 5)).toEqual(expectedOutput);
14
+ });
15
+ });
16
+
17
+ describe('Days for month in year', () => {
18
+ it('Should return 28 for February 2019', () => {
19
+ expect(daysInMonthOfYear({ month: 2, year: 2019 })).toEqual(28);
20
+ });
21
+
22
+ it('Should return 31 for January 2019', () => {
23
+ expect(daysInMonthOfYear({ month: 1, year: 2019 })).toEqual(31);
24
+ });
25
+
26
+ it('Should return 29 for February 2016', () => {
27
+ expect(daysInMonthOfYear({ month: 2, year: 2016 })).toEqual(29);
28
+ });
29
+
30
+ it('Should return 31 for October 2016', () => {
31
+ expect(daysInMonthOfYear({ month: 10, year: 2016 })).toEqual(31);
32
+ });
33
+ });
@@ -0,0 +1,247 @@
1
+ import { useState, useEffect } from 'react';
2
+ import dayjs from 'dayjs';
3
+ import localeData from 'dayjs/plugin/localeData';
4
+ import { CalendarDate } from '@popsure/public-models';
5
+ import DayPicker from 'react-day-picker';
6
+
7
+ import {
8
+ calendarDateToISODate,
9
+ isoStringtoCalendarDate,
10
+ } from '../../util/calendarDate';
11
+ import styles from './style.module.scss';
12
+ import './datepicker.scss';
13
+ import calendarIcon from './icons/calendar.svg';
14
+
15
+ dayjs.extend(localeData);
16
+
17
+ const COLLECTABLE_DATE_FORMAT = 'YYYY-MM-DD';
18
+
19
+ /*
20
+ Fill an array with an increment from a number to another number.
21
+ i.e. fillArray from 1 to 4 will return the following: [1, 2, 3, 4]
22
+
23
+ You can fill descending by flipping the to value
24
+ i.e. fillArray from 4 to 1 will return the following: [4, 3, 2, 1]
25
+ */
26
+ export const fillArray = (from: number, to: number): number[] => {
27
+ const ascending = from > to;
28
+ const arraySize = Math.abs(from - to) + 1;
29
+ const toReturn = new Array(arraySize).fill(0).map((_, index) => {
30
+ return ascending ? to + index : from + index;
31
+ });
32
+
33
+ if (ascending) {
34
+ return toReturn.reverse();
35
+ }
36
+
37
+ return toReturn;
38
+ };
39
+
40
+ /*
41
+ Return the maximum number of days given a month and a year.
42
+ */
43
+ export const daysInMonthOfYear = ({
44
+ month,
45
+ year,
46
+ }: {
47
+ month: number;
48
+ year: number;
49
+ }) => {
50
+ return dayjs(`${year}-${month}`).daysInMonth();
51
+ };
52
+
53
+ const DateSelector = ({
54
+ value,
55
+ onChange,
56
+ yearBoundaries,
57
+ displayCalendar,
58
+ }: {
59
+ value?: string;
60
+ onChange: (date: string) => void;
61
+ yearBoundaries: { min: number; max: number };
62
+ displayCalendar?: boolean;
63
+ }) => {
64
+ const calendarDateValue = value ? isoStringtoCalendarDate(value) : undefined;
65
+ const daysInSelectedDate = calendarDateValue
66
+ ? daysInMonthOfYear({
67
+ month: calendarDateValue.month,
68
+ year: calendarDateValue.year,
69
+ })
70
+ : 31;
71
+ const availableDays = fillArray(1, daysInSelectedDate);
72
+ const availableYears = fillArray(yearBoundaries.max, yearBoundaries.min);
73
+ const availableMonths = dayjs.monthsShort();
74
+
75
+ const [date, setDate] = useState<Partial<CalendarDate>>(
76
+ calendarDateValue ?? {}
77
+ );
78
+ const [openCalendar, setOpenCalendar] = useState(false);
79
+
80
+ const calendarDefaultDate =
81
+ dayjs().year() >= yearBoundaries.min && dayjs().year() <= yearBoundaries.max
82
+ ? dayjs().toDate()
83
+ : dayjs().set('year', yearBoundaries.max).toDate();
84
+ const selectedDateInDateType = value
85
+ ? dayjs(value).toDate()
86
+ : calendarDefaultDate;
87
+ const dateCalendarFromMonth = dayjs(String(yearBoundaries.min))
88
+ .startOf('year')
89
+ .toDate();
90
+ const dateCalendarToMonth = dayjs(String(yearBoundaries.max))
91
+ .endOf('year')
92
+ .toDate();
93
+
94
+ useEffect(() => {
95
+ if (calendarDateValue) {
96
+ setDate(calendarDateValue);
97
+ }
98
+ }, [value]); //eslint-disable-line react-hooks/exhaustive-deps
99
+
100
+ useEffect(() => {
101
+ if (
102
+ date.year !== undefined &&
103
+ date.month !== undefined &&
104
+ date.day !== undefined
105
+ ) {
106
+ if (
107
+ calendarDateValue === undefined ||
108
+ date.day !== calendarDateValue.day ||
109
+ date.month !== calendarDateValue.month ||
110
+ date.year !== calendarDateValue.year
111
+ ) {
112
+ onChange(
113
+ calendarDateToISODate({
114
+ day: date.day,
115
+ month: date.month,
116
+ year: date.year,
117
+ })
118
+ );
119
+ }
120
+ }
121
+ }, [date]); //eslint-disable-line react-hooks/exhaustive-deps
122
+
123
+ const handleOnChange = (key: keyof CalendarDate, v: number) => {
124
+ const newValue = { ...date, [key]: v };
125
+ if (
126
+ key !== 'day' &&
127
+ newValue.month !== undefined &&
128
+ newValue.year !== undefined &&
129
+ newValue.day !== undefined
130
+ ) {
131
+ const cappedDays = Math.min(
132
+ daysInMonthOfYear({ month: newValue.month, year: newValue.year }),
133
+ newValue.day
134
+ );
135
+ setDate({ ...newValue, day: cappedDays });
136
+ } else {
137
+ setDate(newValue);
138
+ }
139
+ };
140
+
141
+ return (
142
+ <div className={styles.container}>
143
+ <div className={styles['date-selector-container']}>
144
+ <div className={styles['row-container']}>
145
+ <select
146
+ data-cy="date-selector-day"
147
+ className={`p-select ${styles['day-select']}`}
148
+ id="day"
149
+ name="day"
150
+ required={true}
151
+ value={date.day ?? ''}
152
+ onChange={(e) => {
153
+ handleOnChange('day', parseInt(e.target.value, 10));
154
+ }}
155
+ >
156
+ <option value="" disabled={true}>
157
+ Day
158
+ </option>
159
+ {availableDays.map((day) => (
160
+ <option key={day} value={day}>
161
+ {day}
162
+ </option>
163
+ ))}
164
+ </select>
165
+ <select
166
+ data-cy="date-selector-month"
167
+ className={`p-select ${styles['month-select']}`}
168
+ id="month"
169
+ name="month"
170
+ required={true}
171
+ value={date.month ?? ''}
172
+ onChange={(e) => {
173
+ handleOnChange('month', parseInt(e.target.value, 10));
174
+ }}
175
+ >
176
+ <option value="" disabled={true}>
177
+ Month
178
+ </option>
179
+ {availableMonths.map((month, i) => (
180
+ <option key={month} value={i + 1}>
181
+ {month}
182
+ </option>
183
+ ))}
184
+ </select>
185
+ </div>
186
+ <select
187
+ data-cy="date-selector-year"
188
+ className={`p-select ${styles['year-select']}`}
189
+ id="year"
190
+ name="year"
191
+ required={true}
192
+ value={date.year ?? ''}
193
+ onChange={(e) => {
194
+ handleOnChange('year', parseInt(e.target.value, 10));
195
+ }}
196
+ >
197
+ <option value="" disabled={true}>
198
+ Year
199
+ </option>
200
+ {availableYears.map((year) => (
201
+ <option key={year} value={year}>
202
+ {year}
203
+ </option>
204
+ ))}
205
+ </select>
206
+ </div>
207
+ {displayCalendar && (
208
+ <div className={styles['date-calendar-container']}>
209
+ <img
210
+ className="c-pointer"
211
+ src={calendarIcon}
212
+ alt="calendar"
213
+ onClick={() => setOpenCalendar(!openCalendar)}
214
+ />
215
+ {openCalendar && (
216
+ <DayPicker
217
+ month={selectedDateInDateType}
218
+ showOutsideDays={true}
219
+ fromMonth={dateCalendarFromMonth}
220
+ toMonth={dateCalendarToMonth}
221
+ selectedDays={selectedDateInDateType}
222
+ onDayClick={(date: Date) => {
223
+ if (
224
+ dayjs(date).isAfter(dateCalendarFromMonth) ||
225
+ dayjs(date).isBefore(dateCalendarToMonth)
226
+ ) {
227
+ const selectedDate = dayjs(date).format(
228
+ COLLECTABLE_DATE_FORMAT
229
+ );
230
+ onChange(selectedDate);
231
+ setOpenCalendar(false);
232
+ }
233
+ }}
234
+ pagedNavigation={true}
235
+ disabledDays={{
236
+ before: dateCalendarFromMonth,
237
+ after: dateCalendarToMonth,
238
+ }}
239
+ />
240
+ )}
241
+ </div>
242
+ )}
243
+ </div>
244
+ );
245
+ };
246
+
247
+ export default DateSelector;
@@ -0,0 +1,77 @@
1
+ @use '../../scss/public/grid' as *;
2
+
3
+ .container {
4
+ display: flex;
5
+ align-items: center;
6
+ }
7
+
8
+ .date-selector-container {
9
+ margin-left: -8px;
10
+
11
+ display: flex;
12
+
13
+ > select {
14
+ margin-left: 8px;
15
+
16
+ @include p-size-mobile {
17
+ margin-left: 0;
18
+ }
19
+ }
20
+
21
+ @include p-size-mobile {
22
+ margin-left: 0;
23
+ display: unset;
24
+ }
25
+ }
26
+
27
+ .row-container {
28
+ > select {
29
+ margin-left: 8px;
30
+
31
+ @include p-size-mobile {
32
+ margin-left: 0;
33
+ }
34
+ }
35
+
36
+ @include p-size-mobile {
37
+ display: flex;
38
+ justify-content: space-between;
39
+ }
40
+ }
41
+
42
+ .day-select {
43
+ width: 88px;
44
+
45
+ @include p-size-mobile {
46
+ flex: 1;
47
+ margin-right: 8px;
48
+ }
49
+ }
50
+
51
+ .month-select {
52
+ width: 104px;
53
+
54
+ @include p-size-mobile {
55
+ flex: 1;
56
+ }
57
+ }
58
+
59
+ .year-select {
60
+ width: 104px;
61
+
62
+ @include p-size-mobile {
63
+ display: block;
64
+
65
+ margin-top: 8px;
66
+ width: 100%;
67
+ }
68
+ }
69
+
70
+ .date-calendar-container {
71
+ position: relative;
72
+ margin-left: 24px;
73
+
74
+ @include p-size-mobile {
75
+ margin-left: 16px;
76
+ }
77
+ }
@@ -0,0 +1,3 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M16.6666 5.83203L7.49992 14.9987L3.33325 10.832" stroke="#B4B4BA" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M18 12.5V15.8333C18 16.2754 17.8244 16.6993 17.5118 17.0118C17.1993 17.3244 16.7754 17.5 16.3333 17.5H4.66667C4.22464 17.5 3.80072 17.3244 3.48816 17.0118C3.17559 16.6993 3 16.2754 3 15.8333V12.5" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
3
+ <path d="M6.33325 8.33301L10.4999 12.4997L14.6666 8.33301" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
4
+ <path d="M10.5 12.5V2.5" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
5
+ </svg>
@@ -0,0 +1,59 @@
1
+ import { Meta, Preview } from '@storybook/addon-docs/blocks';
2
+
3
+ import DownloadButton from '.';
4
+
5
+ <Meta title="JSX/DownloadButton" component={DownloadButton} />
6
+
7
+ # DownloadButton
8
+
9
+ DownloadButton component displays progress and status of downloading files.
10
+
11
+ ## Examples
12
+
13
+ ### Idle state
14
+
15
+ <Preview>
16
+ <DownloadButton downloadStatus="INITIAL" onDownload={() => {}} />
17
+ </Preview>
18
+
19
+ ### Generating state
20
+
21
+ <Preview>
22
+ <DownloadButton downloadStatus="GENERATING" onDownload={() => {}} />
23
+ </Preview>
24
+
25
+ ### Download complete state
26
+
27
+ <Preview>
28
+ <DownloadButton downloadStatus="COMPLETED" onDownload={() => {}} />
29
+ </Preview>
30
+
31
+ ### Error state
32
+
33
+ <Preview>
34
+ <DownloadButton downloadStatus="FAILED" onDownload={() => {}} />
35
+ </Preview>
36
+
37
+ ### Custom Error state
38
+
39
+ <Preview>
40
+ <DownloadButton
41
+ customFail={
42
+ <>
43
+ An error occured while generating your documents. Please try again or{' '}
44
+ <a
45
+ className='tc-primary-500'
46
+ href={`mailto:help@yourcompany.com`}
47
+ target="_blank"
48
+ rel="noopener noreferrer"
49
+ >
50
+ contact us
51
+ </a>
52
+ .
53
+ </>
54
+ }
55
+ downloadStatus="FAILED"
56
+ onDownload={() => {}}
57
+ />
58
+ </Preview>
59
+
@@ -0,0 +1,67 @@
1
+ import Button from '../button';
2
+ import { DownloadStatus } from '../../models/download';
3
+
4
+ import checkIcon from './icons/check.svg';
5
+ import downloadIcon from './icons/download.svg';
6
+ import styles from './style.module.scss';
7
+
8
+ interface Props {
9
+ downloadStatus: DownloadStatus;
10
+ onDownload: () => void;
11
+ className?: string;
12
+ customFail?: React.ReactNode;
13
+ }
14
+
15
+ const InitialButton = ({ onDownload }: { onDownload: () => void }) => (
16
+ <Button
17
+ className={`w100 ${styles.button}`}
18
+ buttonTitle="Download"
19
+ leftIcon={{ src: downloadIcon, alt: 'download arrow icon' }}
20
+ onClick={onDownload}
21
+ data-cy="download-documents-button"
22
+ />
23
+ );
24
+
25
+ // TODO: Allow setting loading to true to display text
26
+ const GeneratingButton = () => (
27
+ <Button
28
+ className={`w100 ${styles.button}`}
29
+ buttonTitle="Generating"
30
+ loading={true}
31
+ />
32
+ );
33
+
34
+ const CompletedChip = () => (
35
+ <div className={styles['chip-complete']}>
36
+ <img src={checkIcon} alt="grey check" />
37
+ <div className="p-h4 tc-grey-500 ml8">Download complete</div>
38
+ </div>
39
+ );
40
+
41
+ const DownloadButton = ({
42
+ downloadStatus,
43
+ onDownload,
44
+ className = '',
45
+ customFail,
46
+ }: Props) => {
47
+ const mapDownloadButton: { [K in DownloadStatus]: React.ReactNode } = {
48
+ INITIAL: <InitialButton onDownload={onDownload} />,
49
+ GENERATING: <GeneratingButton />,
50
+ COMPLETED: <CompletedChip />,
51
+ FAILED: <InitialButton onDownload={onDownload} />,
52
+ };
53
+
54
+ return (
55
+ <div className={`d-flex fd-column ai-center ${className}`}>
56
+ <div className="ws4">{mapDownloadButton[downloadStatus]}</div>
57
+ {downloadStatus === 'FAILED' && (
58
+ <div className="p-notice p-notice--danger p-p mt40 wmx5">
59
+ {customFail ??
60
+ 'An error occured when generating documents. Please try again or contact us.'}
61
+ </div>
62
+ )}
63
+ </div>
64
+ );
65
+ };
66
+
67
+ export default DownloadButton;
@@ -0,0 +1,19 @@
1
+ @use "../../scss/public/colors" as *;
2
+
3
+ .button {
4
+ height: 48px;
5
+ }
6
+
7
+ .chip-complete {
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+
12
+ background-color: white;
13
+
14
+ border-radius: 8px;
15
+
16
+ padding: 8px 16px;
17
+
18
+ height: 48px;
19
+ }
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+
3
+ export default () => (
4
+ <svg
5
+ width="63"
6
+ height="63"
7
+ viewBox="0 0 63 63"
8
+ fill="none"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ >
11
+ <path
12
+ d="M57.75 29.0849V31.4999C57.7468 37.1605 55.9138 42.6684 52.5245 47.2022C49.1352 51.7359 44.3711 55.0526 38.9428 56.6576C33.5145 58.2626 27.7128 58.0699 22.403 56.1082C17.0932 54.1465 12.5597 50.5209 9.47877 45.7722C6.39782 41.0235 4.93445 35.4061 5.3069 29.7577C5.67935 24.1094 7.86767 18.7327 11.5455 14.4297C15.2233 10.1267 20.1936 7.12777 25.715 5.88027C31.2364 4.63278 37.0132 5.20352 42.1838 7.50739"
13
+ stroke="#90DF9B"
14
+ strokeWidth="5"
15
+ strokeLinecap="round"
16
+ strokeLinejoin="round"
17
+ />
18
+ <path
19
+ d="M57.75 10.5L31.5 36.7762L23.625 28.9012"
20
+ stroke="#90DF9B"
21
+ strokeWidth="5"
22
+ strokeLinecap="round"
23
+ strokeLinejoin="round"
24
+ />
25
+ </svg>
26
+ );
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+
3
+ import styles from './style.module.scss';
4
+
5
+ export default () => (
6
+ <svg
7
+ width="81"
8
+ height="60"
9
+ viewBox="0 0 81 60"
10
+ fill="none"
11
+ xmlns="http://www.w3.org/2000/svg"
12
+ >
13
+ <path
14
+ className={styles['fill-primary-500']}
15
+ d="M40.5003 0.52832C34.2609 0.52832 27.9875 2.90796 23.2303 7.66515C19.6924 11.203 17.5477 15.5917 16.6382 20.1682C7.40644 21.9591 0.40332 30.0216 0.40332 39.7537C0.40332 50.7951 9.41033 59.8022 20.4518 59.8022H51.4253C51.7718 59.8071 52.1159 59.7431 52.4374 59.6139C52.759 59.4846 53.0517 59.2928 53.2985 59.0495C53.5452 58.8062 53.7412 58.5163 53.8749 58.1965C54.0087 57.8768 54.0776 57.5337 54.0776 57.1872C54.0776 56.8406 54.0087 56.4975 53.8749 56.1778C53.7412 55.8581 53.5452 55.5682 53.2985 55.3249C53.0517 55.0816 52.759 54.8897 52.4374 54.7605C52.1159 54.6313 51.7718 54.5673 51.4253 54.5722H20.4518C12.237 54.5722 5.63336 47.9686 5.63336 39.7537C5.63336 31.9959 11.5333 25.6757 19.0898 24.9897C19.6825 24.9319 20.2376 24.6737 20.6636 24.2577C21.0895 23.8416 21.3608 23.2926 21.4325 22.7015C21.9136 18.5566 23.7477 14.5297 26.9349 11.3425C30.688 7.58956 35.5857 5.75836 40.5003 5.75836C45.415 5.75836 50.2818 7.58568 54.0385 11.3425C58.3797 15.6837 60.2168 21.5819 59.541 27.2233C59.4947 27.5909 59.5271 27.964 59.6359 28.3181C59.7447 28.6722 59.9274 28.9991 60.1721 29.2773C60.4168 29.5554 60.7177 29.7784 61.055 29.9315C61.3923 30.0845 61.7583 30.1642 62.1287 30.1652H63.1639C69.9698 30.1652 75.3673 35.5627 75.3673 42.3687C75.3673 49.1747 69.9698 54.5722 63.1639 54.5722H50.9604C50.6139 54.5673 50.2699 54.6313 49.9483 54.7605C49.6267 54.8897 49.334 55.0816 49.0873 55.3249C48.8405 55.5682 48.6445 55.8581 48.5108 56.1778C48.377 56.4975 48.3081 56.8406 48.3081 57.1872C48.3081 57.5337 48.377 57.8768 48.5108 58.1965C48.6445 58.5163 48.8405 58.8062 49.0873 59.0495C49.334 59.2928 49.6267 59.4846 49.9483 59.6139C50.2699 59.7431 50.6139 59.8071 50.9604 59.8022H63.1639C72.7768 59.8022 80.5973 51.9816 80.5973 42.3687C80.5973 33.2962 73.6081 25.9105 64.7438 25.0986C64.7847 18.7886 62.5435 12.4655 57.7431 7.66515C52.99 2.91184 46.7398 0.52832 40.5003 0.52832ZM40.5003 48.1024C39.6285 48.1024 39.1674 47.8218 38.7298 47.4214L29.1414 38.7047C28.0342 37.6771 28.0536 36.0095 28.9778 35C29.9022 33.9906 31.6684 33.9175 32.6825 34.8366L37.8853 39.5763V22.0877C37.8853 20.6435 39.0559 19.4727 40.5003 19.4727C41.9449 19.4727 43.1153 20.6435 43.1153 22.0877V39.5763L48.3182 34.8366C49.3324 33.9175 51.0451 34.0421 52.0228 35C53.053 36.0095 52.8643 37.7756 51.8593 38.7047L42.2709 47.4214C41.7528 47.8957 41.3722 48.1024 40.5003 48.1024Z"
16
+ />
17
+ </svg>
18
+ );
@@ -0,0 +1,7 @@
1
+ .stroke-primary-500 {
2
+ stroke: var(--ds-primary-500);
3
+ }
4
+
5
+ .fill-primary-500 {
6
+ fill: var(--ds-primary-500);
7
+ }
@@ -0,0 +1,35 @@
1
+ import { Meta, Preview } from '@storybook/addon-docs/blocks';
2
+
3
+ import DownloadRing from '.';
4
+
5
+ <Meta title="JSX/DownloadRing" component={DownloadRing} />
6
+
7
+ # DownloadRing
8
+
9
+ DownloadRing component displays progress and status of downloading files.
10
+
11
+ ## Examples
12
+
13
+ ### Idle state
14
+
15
+ <Preview>
16
+ <DownloadRing progress={0} status="INITIAL" handleClick={() => {}} />
17
+ </Preview>
18
+
19
+ ### Downloading state
20
+
21
+ <Preview>
22
+ <DownloadRing progress={74} status="DOWNLOADING" handleClick={() => {}} />
23
+ </Preview>
24
+
25
+ ### Download complete state
26
+
27
+ <Preview>
28
+ <DownloadRing progress={100} status="COMPLETED" handleClick={() => {}} />
29
+ </Preview>
30
+
31
+ ### Error state
32
+
33
+ <Preview>
34
+ <DownloadRing progress={100} status="FAILED" handleClick={() => {}} />
35
+ </Preview>