@innovaccer/design-system 2.5.0-4 → 2.6.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 (264) hide show
  1. package/.all-contributorsrc +1 -1
  2. package/.eslintrc.json +53 -0
  3. package/.github/workflows/jira.yml +1 -2
  4. package/.github/workflows/main.yml +2 -2
  5. package/.github/workflows/pull_request.yml +1 -1
  6. package/.github/workflows/test.yml +1 -1
  7. package/.husky/commit-msg +4 -0
  8. package/.prettierrc +2 -2
  9. package/CHANGELOG.md +38 -88
  10. package/CONTRIBUTING.md +173 -97
  11. package/README.md +1 -1
  12. package/commitlint.config.js +1 -0
  13. package/core/accessibility/utils/index.ts +5 -0
  14. package/core/accessibility/utils/isEnterKey.ts +5 -0
  15. package/core/accessibility/utils/isSpaceKey.ts +5 -0
  16. package/core/accessibility/utils/useAccessibilityProps.ts +31 -0
  17. package/core/components/atoms/_chip/__tests__/__snapshots__/_chip.test.tsx.snap +8 -0
  18. package/core/components/atoms/_chip/index.tsx +2 -0
  19. package/core/components/atoms/button/__stories__/Alert.story.tsx +8 -1
  20. package/core/components/atoms/button/__stories__/Cancel.story.tsx +4 -1
  21. package/core/components/atoms/button/__stories__/IconButtonGroup.story.tsx +12 -3
  22. package/core/components/atoms/button/__stories__/IconButtonSecondary.story.tsx +6 -1
  23. package/core/components/atoms/button/__stories__/IconLeftSecondary.story.tsx +4 -1
  24. package/core/components/atoms/button/__stories__/IconRightSecondary.story.tsx +4 -1
  25. package/core/components/atoms/button/__stories__/IconTransparent.story.tsx +4 -1
  26. package/core/components/atoms/button/__stories__/LabelButtonGroup.story.tsx +14 -3
  27. package/core/components/atoms/button/__stories__/LargeIconExpanded.story.tsx +4 -1
  28. package/core/components/atoms/button/__stories__/LoadingPrimary.story.tsx +4 -1
  29. package/core/components/atoms/button/__stories__/Primary.story.tsx +5 -2
  30. package/core/components/atoms/button/__stories__/SplitButton.story.tsx +6 -1
  31. package/core/components/atoms/button/__stories__/Transparent.story.tsx +8 -1
  32. package/core/components/atoms/button/__stories__/index.story.tsx +11 -1
  33. package/core/components/atoms/button/__stories__/variants/Appearance.story.tsx +4 -0
  34. package/core/components/atoms/button/__stories__/variants/Expanded.story.tsx +4 -0
  35. package/core/components/atoms/button/__stories__/variants/Size.story.tsx +4 -0
  36. package/core/components/atoms/button/__stories__/variants/icon/Icon.story.tsx +15 -0
  37. package/core/components/atoms/button/__stories__/variants/icon/IconLeft.story.tsx +4 -0
  38. package/core/components/atoms/button/__stories__/variants/icon/IconRight.story.tsx +4 -0
  39. package/core/components/atoms/button/__stories__/variants/state/Alert.story.tsx +7 -17
  40. package/core/components/atoms/button/__stories__/variants/state/Basic.story.tsx +9 -17
  41. package/core/components/atoms/button/__stories__/variants/state/Primary.story.tsx +7 -17
  42. package/core/components/atoms/button/__stories__/variants/state/Success.story.tsx +7 -17
  43. package/core/components/atoms/button/__stories__/variants/state/Transparent.story.tsx +13 -17
  44. package/core/components/atoms/chipGroup/__tests__/__snapshots__/chipGroup.test.tsx.snap +6 -0
  45. package/core/components/atoms/collapsible/__stories__/index.story.tsx +2 -2
  46. package/core/components/atoms/collapsible/__tests__/__snapshots__/Collapsible.test.tsx.snap +8 -0
  47. package/core/components/atoms/divider/Divider.tsx +44 -0
  48. package/core/components/atoms/divider/__stories__/BasicDividerInCard.story.tsx +74 -0
  49. package/core/components/atoms/divider/__stories__/HeaderDividerInCard.story.tsx +35 -0
  50. package/core/components/atoms/divider/__stories__/IndentedDivider.story.tsx +49 -0
  51. package/core/components/atoms/divider/__stories__/Vertical.story.tsx +51 -0
  52. package/core/components/atoms/divider/__stories__/index.story.tsx +91 -0
  53. package/core/components/atoms/divider/__stories__/variants/HorizontalDivider.story.tsx +27 -0
  54. package/core/components/atoms/divider/__tests__/Divider.test.tsx +50 -0
  55. package/core/components/atoms/divider/__tests__/__snapshots__/Divider.test.tsx.snap +53 -0
  56. package/core/components/atoms/divider/index.tsx +2 -0
  57. package/core/components/atoms/dropdown/DropdownList.tsx +8 -2
  58. package/core/components/atoms/dropdown/__stories__/variants/controlledDropdown/MultiSelect.story.tsx +27 -17
  59. package/core/components/atoms/dropdown/option/DefaultOption.tsx +3 -0
  60. package/core/components/atoms/dropdown/option/IconOption.tsx +3 -0
  61. package/core/components/atoms/dropdown/option/IconWithMetaOption.tsx +3 -0
  62. package/core/components/atoms/dropdown/option/MetaOption.tsx +3 -0
  63. package/core/components/atoms/editable/Editable.tsx +3 -0
  64. package/core/components/atoms/icon/Icon.tsx +14 -3
  65. package/core/components/atoms/icon/__stories__/variants/Image.story.tsx +6 -1
  66. package/core/components/atoms/icon/__tests__/__snapshots__/Icon.test.tsx.snap +74 -0
  67. package/core/components/atoms/input/Input.tsx +14 -4
  68. package/core/components/atoms/input/__stories__/BasicInput.story.tsx +2 -1
  69. package/core/components/atoms/input/__stories__/InputWithCaption.story.tsx +29 -9
  70. package/core/components/atoms/input/__stories__/InputWithLabel.story.tsx +11 -3
  71. package/core/components/atoms/input/__stories__/LabelPosition.story.tsx +8 -4
  72. package/core/components/atoms/input/__stories__/RequiredVsOptional.story.tsx +12 -8
  73. package/core/components/atoms/input/__tests__/__snapshots__/Input.test.tsx.snap +19 -0
  74. package/core/components/atoms/legend/Legend.tsx +3 -0
  75. package/core/components/atoms/message/__stories__/CustomDescription.tsx +25 -0
  76. package/core/components/atoms/metricInput/MetricInput.tsx +12 -2
  77. package/core/components/atoms/metricInput/__stories__/DefaultMetric.story.tsx +8 -2
  78. package/core/components/atoms/metricInput/__stories__/WithPrefix.story.tsx +6 -2
  79. package/core/components/atoms/metricInput/__stories__/index.story.tsx +1 -0
  80. package/core/components/atoms/metricInput/__stories__/variants/Controlled.story.tsx +2 -0
  81. package/core/components/atoms/metricInput/__stories__/variants/Size.story.tsx +2 -2
  82. package/core/components/atoms/metricInput/__stories__/withSuffix.story.tsx +6 -2
  83. package/core/components/atoms/metricInput/__tests__/__snapshots__/MetricInput.test.tsx.snap +20 -4
  84. package/core/components/atoms/multiSlider/Handle.tsx +3 -0
  85. package/core/components/atoms/multiSlider/index.tsx +6 -0
  86. package/core/components/atoms/outsideClick/__stories__/index.story.tsx +1 -1
  87. package/core/components/atoms/statusHint/StatusHint.tsx +3 -0
  88. package/core/components/atoms/switchInput/Switch.tsx +10 -4
  89. package/core/components/atoms/switchInput/__stories__/DefaultSwitch.story.tsx +4 -1
  90. package/core/components/atoms/switchInput/__stories__/OffState.story.tsx +4 -1
  91. package/core/components/atoms/switchInput/__stories__/index.story.tsx +26 -3
  92. package/core/components/atoms/switchInput/__stories__/variants/Size.story.tsx +10 -1
  93. package/core/components/atoms/switchInput/__stories__/variants/State.story.tsx +9 -2
  94. package/core/components/atoms/textarea/__stories__/TextareaWithCaption.story.tsx +9 -3
  95. package/core/components/atoms/textarea/__stories__/defaultTextarea.story.tsx +10 -2
  96. package/core/components/atoms/textarea/__stories__/index.story.tsx +1 -0
  97. package/core/components/atoms/textarea/__stories__/variants/Disable.story.tsx +1 -0
  98. package/core/components/atoms/toast/__tests__/__snapshots__/Toast.test.tsx.snap +30 -0
  99. package/core/components/css-utilities/Align/Align.story.tsx +1 -1
  100. package/core/components/css-utilities/Background/Background.story.tsx +1 -1
  101. package/core/components/css-utilities/Border/Border.story.tsx +1 -1
  102. package/core/components/css-utilities/Display/Display.story.tsx +1 -1
  103. package/core/components/css-utilities/Flex/Flex.story.tsx +1 -1
  104. package/core/components/css-utilities/Miscellaneous/Miscellaneous.story.tsx +1 -1
  105. package/core/components/css-utilities/Overflow/Overflow.story.tsx +1 -1
  106. package/core/components/css-utilities/Position/Position.story.tsx +1 -1
  107. package/core/components/css-utilities/Sizing/Sizing.story.tsx +1 -1
  108. package/core/components/css-utilities/Spacing/Spacing.story.tsx +1 -1
  109. package/core/components/molecules/chatMessage/Box.tsx +3 -0
  110. package/core/components/molecules/chipInput/ChipInput.tsx +3 -0
  111. package/core/components/molecules/chipInput/__tests__/__snapshots__/ChipInput.test.tsx.snap +12 -0
  112. package/core/components/molecules/dropzone/Dropzone.tsx +3 -0
  113. package/core/components/molecules/dropzone/FileSelectorUtils.tsx +1 -1
  114. package/core/components/molecules/editableChipInput/EditableChipInput.tsx +9 -5
  115. package/core/components/molecules/editableChipInput/__stories__/Uncontrolled.story.tsx +1 -1
  116. package/core/components/molecules/editableChipInput/__tests__/__snapshots__/EditableChipInput.test.tsx.snap +8 -0
  117. package/core/components/molecules/editableDropdown/EditableDropdown.tsx +2 -2
  118. package/core/components/molecules/editableInput/EditableInput.tsx +13 -4
  119. package/core/components/molecules/emptyState/EmptyState.tsx +5 -1
  120. package/core/components/molecules/fileList/FileListItem.tsx +2 -0
  121. package/core/components/molecules/fileUploader/FileUploaderItem.tsx +2 -0
  122. package/core/components/molecules/fileUploader/__stories__/index.story.tsx +156 -21
  123. package/core/components/molecules/inputMask/InputMask.tsx +1 -1
  124. package/core/components/molecules/inputMask/__tests__/__snapshots__/InputMask.test.tsx.snap +1 -0
  125. package/core/components/molecules/pagination/__tests__/__snapshots__/Pagination.test.tsx.snap +5 -1
  126. package/core/components/molecules/stepper/Step.tsx +2 -0
  127. package/core/components/molecules/tabs/Tabs.tsx +2 -0
  128. package/core/components/molecules/tabs/TabsWrapper.tsx +2 -0
  129. package/core/components/molecules/tabs/__stories__/CustomLabels.story.tsx +1 -1
  130. package/core/components/molecules/verificationCodeInput/VerificationCodeInput.tsx +8 -4
  131. package/core/components/molecules/verificationCodeInput/__stories__/index.story.tsx +3 -1
  132. package/core/components/molecules/verificationCodeInput/__tests__/__snapshots__/VerificationCodeInput.test.tsx.snap +1 -0
  133. package/core/components/organisms/calendar/Calendar.tsx +130 -8
  134. package/core/components/organisms/calendar/__tests__/Calendar.test.tsx +27 -0
  135. package/core/components/organisms/choiceList/ChoiceList.tsx +1 -1
  136. package/core/components/organisms/datePicker/DatePicker.tsx +30 -15
  137. package/core/components/organisms/datePicker/__tests__/DatePicker.test.tsx +136 -46
  138. package/core/components/organisms/datePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap +4388 -1857
  139. package/core/components/organisms/dateRangePicker/__tests__/__snapshots__/DateRangePicker.test.tsx.snap +112 -40
  140. package/core/components/organisms/grid/Cell.tsx +4 -0
  141. package/core/components/organisms/grid/GridRow.tsx +4 -0
  142. package/core/components/organisms/grid/__stories__/_common_/fetchData.ts +2 -2
  143. package/core/components/organisms/horizontalNav/HorizontalNav.tsx +2 -0
  144. package/core/components/organisms/inlineMessage/InlineMessage.tsx +3 -5
  145. package/core/components/organisms/inlineMessage/__tests__/__snapshots__/InlineMessage.test.tsx.snap +30 -40
  146. package/core/components/organisms/navigation/VerticalNavigation.tsx +4 -0
  147. package/core/components/organisms/table/Table.tsx +1 -0
  148. package/core/components/organisms/table/__stories__/NestedTableWithNestedCard.story.tsx +4 -1
  149. package/core/components/organisms/table/__stories__/ResourceTable.story.tsx +3 -2
  150. package/core/components/organisms/table/__stories__/Selection.story.tsx +2 -2
  151. package/core/components/organisms/table/__stories__/TableAsDescriptionList.story.tsx +1 -1
  152. package/core/components/organisms/table/__stories__/TableAsOptionList.story.tsx +1 -1
  153. package/core/components/organisms/table/__stories__/syncTable.story.tsx +14 -6
  154. package/core/components/organisms/table/__stories__/variants/nestedRows.story.tsx +5 -2
  155. package/core/components/organisms/table/__stories__/variants/withHeader.story.tsx +0 -2
  156. package/core/components/organisms/timePicker/TimePicker.tsx +1 -1
  157. package/core/components/organisms/timePicker/__tests__/__snapshots__/TimePicker.test.tsx.snap +14 -2
  158. package/core/components/organisms/verticalNav/MenuItem.tsx +2 -0
  159. package/core/components/patterns/datePicker/datePickerWithPresets.story.tsx +126 -0
  160. package/core/components/patterns/dateRangePicker/withCustomPopover.story.tsx +8 -8
  161. package/core/components/patterns/forms/CreatePassword.story.tsx +1 -1
  162. package/core/components/patterns/forms/VerificationCodeInput.story.tsx +2 -2
  163. package/core/components/patterns/table/Table with Header/tableWithHeader.story.jsx +7 -7
  164. package/core/index.tsx +1 -0
  165. package/core/index.type.tsx +1 -0
  166. package/core/utils/Keys.ts +4 -0
  167. package/core/utils/__tests__/__snapshots__/TS.test.tsx.snap +544 -536
  168. package/core/utils/docPage/index.tsx +22 -17
  169. package/core/utils/testHelper.ts +1 -1
  170. package/core/utils/validators.ts +37 -34
  171. package/css/dist/index.css +1523 -1402
  172. package/css/dist/index.css.map +1 -1
  173. package/css/src/components/Legend.css +7 -7
  174. package/css/src/components/ProgressBar.css +1 -1
  175. package/css/src/components/avatarGroup.css +1 -1
  176. package/css/src/components/backdrop.css +12 -6
  177. package/css/src/components/badge.css +52 -52
  178. package/css/src/components/button.css +99 -94
  179. package/css/src/components/calendar.css +137 -126
  180. package/css/src/components/card.css +0 -1
  181. package/css/src/components/cardSubdued.css +3 -5
  182. package/css/src/components/chat.css +1 -1
  183. package/css/src/components/checkbox.css +71 -70
  184. package/css/src/components/chip.css +14 -13
  185. package/css/src/components/chipGroup.css +5 -5
  186. package/css/src/components/chipInput.css +1 -1
  187. package/css/src/components/choiceList.css +4 -4
  188. package/css/src/components/dateRangePicker.css +13 -13
  189. package/css/src/components/divider.css +20 -0
  190. package/css/src/components/dropdown.css +61 -61
  191. package/css/src/components/dropdownButton.css +36 -36
  192. package/css/src/components/dropzone.css +16 -20
  193. package/css/src/components/editableChipInput.css +10 -9
  194. package/css/src/components/editableDropdown.css +1 -1
  195. package/css/src/components/editableInput.css +1 -1
  196. package/css/src/components/emptyState.css +15 -15
  197. package/css/src/components/fileList.css +44 -45
  198. package/css/src/components/grid.css +217 -199
  199. package/css/src/components/horizontalNav.css +0 -1
  200. package/css/src/components/icon.css +1 -7
  201. package/css/src/components/inlineMessage.css +2 -1
  202. package/css/src/components/input.css +62 -62
  203. package/css/src/components/link.css +1 -1
  204. package/css/src/components/list.css +10 -10
  205. package/css/src/components/message.css +69 -70
  206. package/css/src/components/metaList.css +26 -26
  207. package/css/src/components/metricInput.css +3 -4
  208. package/css/src/components/modal.css +1 -1
  209. package/css/src/components/navigation.css +3 -3
  210. package/css/src/components/pageHeader.css +1 -2
  211. package/css/src/components/pagination.css +36 -36
  212. package/css/src/components/pills.css +19 -19
  213. package/css/src/components/placeholder.css +10 -5
  214. package/css/src/components/popover.css +2 -2
  215. package/css/src/components/progressRing.css +1 -1
  216. package/css/src/components/radio.css +74 -74
  217. package/css/src/components/slider.css +5 -5
  218. package/css/src/components/statusHints.css +15 -15
  219. package/css/src/components/switch.css +45 -41
  220. package/css/src/components/table.css +15 -15
  221. package/css/src/components/tabs.css +53 -53
  222. package/css/src/components/textarea.css +1 -1
  223. package/css/src/components/toast.css +53 -53
  224. package/css/src/components/verificationCodeInput.css +5 -6
  225. package/css/src/components/verticalNav.css +1 -2
  226. package/css/src/core/base.css +3 -0
  227. package/css/src/core/typography.css +1 -1
  228. package/css/src/core/utilities.css +1 -1
  229. package/css/src/tokens/index.css +63 -63
  230. package/css/src/utils/align.css +1 -1
  231. package/css/src/utils/background.css +1 -1
  232. package/css/src/utils/cursor.css +1 -1
  233. package/css/src/utils/display.css +1 -1
  234. package/css/src/utils/flex.css +1 -1
  235. package/css/src/utils/grid.css +1 -1
  236. package/css/src/utils/overflow.css +1 -1
  237. package/css/src/utils/position.css +1 -1
  238. package/css/src/utils/spacing.css +1 -1
  239. package/css/src/utils/utility.css +13 -13
  240. package/css/src/variables/index.css +1 -1
  241. package/dist/core/accessibility/utils/index.d.ts +4 -0
  242. package/dist/core/accessibility/utils/isEnterKey.d.ts +3 -0
  243. package/dist/core/accessibility/utils/isSpaceKey.d.ts +3 -0
  244. package/dist/core/accessibility/utils/useAccessibilityProps.d.ts +15 -0
  245. package/dist/core/components/atoms/divider/Divider.d.ts +15 -0
  246. package/dist/core/components/atoms/divider/index.d.ts +2 -0
  247. package/dist/core/components/atoms/icon/Icon.d.ts +3 -1
  248. package/dist/core/components/atoms/input/Input.d.ts +1 -1
  249. package/dist/core/components/atoms/popperWrapper/PopperWrapper.d.ts +50 -49
  250. package/dist/core/components/atoms/switchInput/Switch.d.ts +2 -1
  251. package/dist/core/components/organisms/calendar/Calendar.d.ts +31 -0
  252. package/dist/core/components/organisms/datePicker/DatePicker.d.ts +2 -0
  253. package/dist/core/components/patterns/datePicker/datePickerWithPresets.story.d.ts +15 -0
  254. package/dist/core/index.d.ts +1 -0
  255. package/dist/core/index.type.d.ts +1 -0
  256. package/dist/index.esm.js +829 -495
  257. package/dist/index.js +313 -144
  258. package/dist/index.js.map +1 -1
  259. package/dist/index.umd.js +1 -1
  260. package/dist/index.umd.js.br +0 -0
  261. package/dist/index.umd.js.gz +0 -0
  262. package/package.json +17 -14
  263. package/.husky/prepare-commit-msg +0 -6
  264. package/tslint.json +0 -30
@@ -16,6 +16,31 @@ import {
16
16
  convertToDate,
17
17
  } from './utility';
18
18
 
19
+ type OnHover = React.MouseEvent<HTMLSpanElement> | React.MouseEvent<HTMLDivElement>;
20
+ interface hoveredDateProps {
21
+ value: number;
22
+ isToday: boolean;
23
+ isDisabled: boolean;
24
+ todayDate?: Date;
25
+ fullDate: Date;
26
+ date: number;
27
+ month: string;
28
+ year: number;
29
+ dayName: string;
30
+ }
31
+ interface hoveredMonthProps {
32
+ value: string;
33
+ month: string;
34
+ year?: number;
35
+ isCurrentMonth: boolean;
36
+ isDisabled: boolean;
37
+ }
38
+ interface hoveredYearProps {
39
+ value: number;
40
+ year: number;
41
+ isCurrentYear: boolean;
42
+ isDisabled: boolean;
43
+ }
19
44
  export interface SharedProps extends BaseProps {
20
45
  /**
21
46
  * Size of `Calendar`
@@ -73,6 +98,18 @@ export type CalendarProps = {
73
98
  * Callback function called when range is changed
74
99
  */
75
100
  onRangeChange?: (startDate: Date | undefined, endDate: Date | undefined) => void;
101
+ /**
102
+ * Callback function called when a date is hovered
103
+ */
104
+ onDateHover?: (dateData: hoveredDateProps, evnt: OnHover) => void;
105
+ /**
106
+ * Callback function called when a month is hovered
107
+ */
108
+ onMonthHover?: (monthData: hoveredMonthProps, evnt: OnHover) => void;
109
+ /**
110
+ * Callback function called when a year is hovered
111
+ */
112
+ onYearHover?: (yearData: hoveredYearProps, evnt: OnHover) => void;
76
113
  /**
77
114
  * Selected date
78
115
  */
@@ -351,6 +388,22 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
351
388
  });
352
389
  };
353
390
 
391
+ yearMouseOverHandler = (
392
+ year: number,
393
+ isCurrentYear: boolean,
394
+ isDisabled: boolean,
395
+ ev: React.MouseEvent<HTMLDivElement>
396
+ ) => {
397
+ const { onYearHover } = this.props;
398
+ const yearData = {
399
+ value: year,
400
+ year: year,
401
+ isCurrentYear: isCurrentYear,
402
+ isDisabled: isDisabled,
403
+ };
404
+ if (onYearHover) onYearHover(yearData, ev);
405
+ };
406
+
354
407
  selectMonth = (month: number) => () => {
355
408
  this.updateState(this.state.yearNav, month);
356
409
  this.setState({
@@ -358,7 +411,38 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
358
411
  });
359
412
  };
360
413
 
414
+ monthMouseOverHandler = (
415
+ month: number,
416
+ isCurrentMonth: boolean,
417
+ isDisabled: boolean,
418
+ ev: React.MouseEvent<HTMLDivElement>
419
+ ) => {
420
+ const { months } = config;
421
+ const { onMonthHover } = this.props;
422
+ const monthData = {
423
+ value: months[month],
424
+ month: months[month],
425
+ year: this.state.year,
426
+ isCurrentMonth: isCurrentMonth,
427
+ isDisabled: isDisabled,
428
+ };
429
+ if (onMonthHover) onMonthHover(monthData, ev);
430
+ };
431
+
361
432
  selectDate = (index: number, date: number, prevMonthDayRange: number, dayRange: number) => {
433
+ const d = this.calculateDate(index, date, prevMonthDayRange, dayRange, false);
434
+ this.setState({
435
+ currDate: d,
436
+ });
437
+ };
438
+
439
+ calculateDate = (
440
+ index: number,
441
+ date: number,
442
+ prevMonthDayRange: number,
443
+ dayRange: number,
444
+ isDateHovered: boolean
445
+ ) => {
362
446
  let neighbouringMonthIndex;
363
447
  let neighbouringMonthDate;
364
448
  let type = '';
@@ -375,12 +459,12 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
375
459
  neighbouringMonthDate = date;
376
460
  }
377
461
  const { year, month } = this.getNavDateInfo(neighbouringMonthIndex);
378
- this.updateState(year, month, neighbouringMonthDate);
379
- this.onNavIconClickHandler(type)();
462
+ if (isDateHovered === false) {
463
+ this.updateState(year, month, neighbouringMonthDate);
464
+ this.onNavIconClickHandler(type)();
465
+ }
380
466
  const d = this.getDateValue(year, month, neighbouringMonthDate);
381
- this.setState({
382
- currDate: d,
383
- });
467
+ return d;
384
468
  };
385
469
 
386
470
  onNavIconClickHandler = (type: string) => () => {
@@ -525,6 +609,8 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
525
609
  return (
526
610
  <div className={headerContentClass}>
527
611
  {view !== 'date' && (
612
+ // TODO(a11y)
613
+ // eslint-disable-next-line
528
614
  <div
529
615
  className="d-flex justify-content-center align-items-center"
530
616
  onClick={this.onNavHeadingClickHandler(view)}
@@ -532,14 +618,19 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
532
618
  {renderHeading(headerContent)}
533
619
  </div>
534
620
  )}
621
+
535
622
  {view === 'date' && (
536
623
  <>
624
+ {/* TODO(a11y) */}
625
+ {/* eslint-disable-next-line */}
537
626
  <div
538
627
  onClick={this.onNavHeadingClickHandler(view)}
539
628
  className="d-flex justify-content-center align-items-center"
540
629
  >
541
630
  {renderHeading(months[monthNavVal])}
542
631
  </div>
632
+ {/* TODO(a11y) */}
633
+ {/* eslint-disable-next-line */}
543
634
  <div
544
635
  className="ml-4 d-flex justify-content-center align-items-center"
545
636
  onClick={this.onNavHeadingClickHandler('month')}
@@ -584,11 +675,14 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
584
675
  });
585
676
 
586
677
  return (
678
+ // TODO(a11y)
679
+ // eslint-disable-next-line
587
680
  <div
588
681
  key={`${row}-${col}`}
589
682
  data-test="DesignSystem-Calendar--yearValue"
590
683
  className={valueClass}
591
684
  onClick={this.selectYear(year)}
685
+ onMouseOver={this.yearMouseOverHandler.bind(this, year, isCurrentYear(), disabled)}
592
686
  >
593
687
  <Text
594
688
  size={size === 'small' ? 'small' : 'regular'}
@@ -632,11 +726,14 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
632
726
  });
633
727
 
634
728
  return (
729
+ //TODO(a11y)
730
+ //eslint-disable-next-line
635
731
  <div
636
732
  key={`${row}-${col}`}
637
733
  data-test="DesignSystem-Calendar--monthValue"
638
734
  className={valueClass}
639
735
  onClick={this.selectMonth(month)}
736
+ onMouseOver={this.monthMouseOverHandler.bind(this, month, isCurrentMonth(), disabled)}
640
737
  >
641
738
  <Text
642
739
  size={size === 'small' ? 'small' : 'regular'}
@@ -703,7 +800,7 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
703
800
  renderDateValues = (index: number) => {
704
801
  const { daysInRow, monthBlock } = config;
705
802
 
706
- const { size, rangePicker, firstDayOfWeek, disabledBefore, disabledAfter, monthsInView } = this.props;
803
+ const { size, rangePicker, firstDayOfWeek, disabledBefore, disabledAfter, monthsInView, onDateHover } = this.props;
707
804
 
708
805
  const {
709
806
  startDate,
@@ -727,10 +824,10 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
727
824
  const dayDiff = getFirstDayOfMonth(yearNavVal, monthNavVal) - getIndexOfDay(firstDayOfWeek);
728
825
  const dummyDays = Math.abs(dayDiff);
729
826
  let noOfRows = Math.ceil((dayRange + dummyDays) / daysInRow);
827
+ // TODO: @veekays
828
+ // if(noOfRows !== 6 && monthsInView <= 1) ?
730
829
  if (noOfRows === 6) {
731
- noOfRows = noOfRows;
732
830
  } else if (monthsInView > 1) {
733
- noOfRows = noOfRows;
734
831
  } else {
735
832
  noOfRows = noOfRows + 1;
736
833
  }
@@ -761,6 +858,29 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
761
858
  }
762
859
  };
763
860
 
861
+ const onMouseEnterHandler = (
862
+ date: number,
863
+ isToday: boolean,
864
+ isDisabled: boolean,
865
+ ev: React.MouseEvent<HTMLSpanElement>
866
+ ) => {
867
+ const d = this.calculateDate(index, date, prevMonthDayRange, dayRange, true) || new Date();
868
+ const { months, days } = config;
869
+ const dayName = days.large[d.getDay()];
870
+ const dateData = {
871
+ value: d.getDate(),
872
+ isToday: isToday,
873
+ isDisabled: isDisabled,
874
+ todayDate: this.state.currDate,
875
+ fullDate: d,
876
+ date: d.getDate(),
877
+ month: months[d.getMonth()],
878
+ year: d.getFullYear(),
879
+ dayName: dayName,
880
+ };
881
+ if (onDateHover) onDateHover(dateData, ev);
882
+ };
883
+
764
884
  return Array.from({ length: noOfRows }, (_y, row) => {
765
885
  return (
766
886
  <div key={row} className="Calendar-valueRow">
@@ -876,6 +996,7 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
876
996
  className={valueClass}
877
997
  onClick={onClickHandler(date)}
878
998
  onMouseOver={onMouseOverHandler(date)}
999
+ onMouseEnter={onMouseEnterHandler.bind(this, date, today(), disabled)}
879
1000
  >
880
1001
  {date}
881
1002
  </Text>
@@ -891,6 +1012,7 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
891
1012
  className={valueClass}
892
1013
  onClick={onClickHandler(date)}
893
1014
  onMouseOver={onMouseOverHandler(date)}
1015
+ onMouseEnter={onMouseEnterHandler.bind(this, date, today(), disabled)}
894
1016
  >
895
1017
  {date <= 0 ? prevMonthDayRange + date : date - dayRange}
896
1018
  </Text>
@@ -214,4 +214,31 @@ describe('Calendar compoennt', () => {
214
214
  fireEvent.click(month);
215
215
  expect(FunctionValue).toHaveBeenCalled();
216
216
  });
217
+
218
+ it('calls onMouseOver handler when date value is hovered', () => {
219
+ const { getAllByTestId } = render(
220
+ <Calendar date={new Date(2020, 2, 15)} rangePicker={false} onDateHover={FunctionValue} view="date" />
221
+ );
222
+ const date = getAllByTestId('DesignSystem-Calendar--dateValue')[0];
223
+ fireEvent.mouseOver(date);
224
+ expect(FunctionValue).toHaveBeenCalled();
225
+ });
226
+
227
+ it('calls onMouseOver handler when month value is hovered', () => {
228
+ const { getAllByTestId } = render(
229
+ <Calendar date={new Date(2020, 2, 15)} rangePicker={false} onMonthHover={FunctionValue} view="month" />
230
+ );
231
+ const month = getAllByTestId('DesignSystem-Calendar--monthValue')[0];
232
+ fireEvent.mouseOver(month);
233
+ expect(FunctionValue).toHaveBeenCalled();
234
+ });
235
+
236
+ it('calls onMouseOver handler when year value is hovered', () => {
237
+ const { getAllByTestId } = render(
238
+ <Calendar date={new Date(2020, 2, 15)} rangePicker={false} onYearHover={FunctionValue} view="year" />
239
+ );
240
+ const year = getAllByTestId('DesignSystem-Calendar--yearValue')[0];
241
+ fireEvent.mouseOver(year);
242
+ expect(FunctionValue).toHaveBeenCalled();
243
+ });
217
244
  });
@@ -187,7 +187,7 @@ export const ChoiceList = (props: ChoiceListProps) => {
187
187
  <>
188
188
  <fieldset className={ChoiceListClass} data-test="DesignSystem-ChoiceList-Wrapper">
189
189
  {title && title.trim() && <Label>{title.trim()}</Label>}
190
- {!!allowMultiple ? (
190
+ {allowMultiple ? (
191
191
  <div className={`${alignment === 'horizontal' ? ChoiceHorizontalClass : ChoiceListVerticalClass}`}>
192
192
  {renderCheckbox(choices, handleOnChange, disabled, size, alignment, selected)}
193
193
  </div>
@@ -58,6 +58,14 @@ export type DatePickerProps = SharedProps & {
58
58
  * Close Popover on date selection
59
59
  */
60
60
  closeOnSelect: boolean;
61
+ /**
62
+ * Add or remove the select today's date chip from DatePicker Footer
63
+ */
64
+ showTodayDate?: boolean;
65
+ /**
66
+ * Element to be rendered inside Popover
67
+ */
68
+ children: React.ReactNode;
61
69
  };
62
70
 
63
71
  export interface DatePickerState {
@@ -182,6 +190,8 @@ export class DatePicker extends React.Component<DatePickerProps, DatePickerState
182
190
  onDateChange,
183
191
  closeOnSelect,
184
192
  size,
193
+ showTodayDate = true,
194
+ children = <></>,
185
195
  ...rest
186
196
  } = this.props;
187
197
 
@@ -205,23 +215,28 @@ export class DatePicker extends React.Component<DatePickerProps, DatePickerState
205
215
  };
206
216
  return (
207
217
  <div>
208
- <Calendar
209
- {...rest}
210
- size={size}
211
- date={currDate}
212
- disabledBefore={dateDisabledBefore}
213
- disabledAfter={dateDisabledAfter}
214
- onDateChange={this.onDateChangeHandler}
215
- />
216
- <div className="d-flex justify-content-center pb-6" data-test="DesignSystem-Select--TodaysDate-wrapper">
217
- <Chip
218
- label={`Today, ${todayMonthAndDate}`}
219
- name="chip"
220
- type="action"
221
- disabled={isTodayDisabled()}
222
- onClick={() => this.onDateChangeHandler(new Date())}
218
+ <div className="d-flex">
219
+ {children}
220
+ <Calendar
221
+ {...rest}
222
+ size={size}
223
+ date={currDate}
224
+ disabledBefore={dateDisabledBefore}
225
+ disabledAfter={dateDisabledAfter}
226
+ onDateChange={this.onDateChangeHandler}
223
227
  />
224
228
  </div>
229
+ {showTodayDate && (
230
+ <div className="d-flex justify-content-center pb-6" data-test="DesignSystem-Select--TodaysDate-wrapper">
231
+ <Chip
232
+ label={`Today, ${todayMonthAndDate}`}
233
+ name="chip"
234
+ type="action"
235
+ disabled={isTodayDisabled()}
236
+ onClick={() => this.onDateChangeHandler(new Date())}
237
+ />
238
+ </div>
239
+ )}
225
240
  </div>
226
241
  );
227
242
  }
@@ -19,68 +19,158 @@ afterAll(() => {
19
19
  const view = ['year', 'month', 'date'];
20
20
  const booleanValue = [true, false];
21
21
  const FunctionValue = jest.fn();
22
+ const newDate = new Date(2020, 2, 1);
22
23
 
23
- describe('DatePicker component', () => {
24
- const mapper: Record<string, any> = {
25
- view: valueHelper(view, { required: true, iterate: true }),
26
- };
24
+ const testFunc = (props: Record<string, any>): void => {
25
+ const attr = filterUndefined(props) as Props;
27
26
 
28
- const testFunc = (props: Record<string, any>): void => {
29
- const attr = filterUndefined(props) as Props;
30
-
31
- it(testMessageHelper(attr), () => {
32
- const { baseElement } = render(<DatePicker date={new Date(2020, 2, 1)} {...attr} />);
33
- expect(baseElement).toMatchSnapshot();
34
- });
35
- };
36
-
37
- testHelper(mapper, testFunc);
38
- });
39
-
40
- describe('DatePicker component', () => {
41
- const mapper: Record<string, any> = {
42
- withInput: valueHelper(booleanValue, { required: true, iterate: true }),
43
- };
44
-
45
- const testFunc = (props: Record<string, any>): void => {
46
- const attr = filterUndefined(props) as Props;
47
-
48
- it(testMessageHelper(attr), () => {
49
- const { baseElement } = render(<DatePicker date={new Date(2020, 2, 1)} {...attr} />);
50
- expect(baseElement).toMatchSnapshot();
51
- });
52
- };
27
+ it(testMessageHelper(attr), () => {
28
+ const { baseElement } = render(<DatePicker date={newDate} {...attr} />);
29
+ expect(baseElement).toMatchSnapshot();
30
+ });
31
+ };
32
+
33
+ describe('DatePicker component snapshots', () => {
34
+ describe('renders snapshot for prop:view', () => {
35
+ const mapper: Record<string, any> = {
36
+ view: valueHelper(view, { required: true, iterate: true }),
37
+ };
38
+ testHelper(mapper, testFunc);
39
+ });
53
40
 
54
- testHelper(mapper, testFunc);
55
- });
41
+ describe('renders snapshot for prop:withInput', () => {
42
+ const mapper: Record<string, any> = {
43
+ withInput: valueHelper(booleanValue, { required: true, iterate: true }),
44
+ };
45
+ testHelper(mapper, testFunc);
46
+ });
56
47
 
57
- describe('DatePicker component', () => {
58
- const mapper: Record<string, any> = {
59
- open: valueHelper(booleanValue, { required: true, iterate: true }),
60
- };
48
+ describe('renders snapshot for prop:open', () => {
49
+ const mapper: Record<string, any> = {
50
+ open: valueHelper(booleanValue, { required: true, iterate: true }),
51
+ };
52
+ testHelper(mapper, testFunc);
53
+ });
61
54
 
62
- const testFunc = (props: Record<string, any>): void => {
63
- const attr = filterUndefined(props) as Props;
55
+ describe('renders snapshot for prop:disabledBefore, prop:disabledAfter', () => {
56
+ const mapper: Record<string, any> = {
57
+ disabledBefore: valueHelper('10/10/2020', { required: true }),
58
+ disabledAfter: valueHelper('10/10/2021', { required: true }),
59
+ };
60
+ testHelper(mapper, testFunc);
61
+ });
64
62
 
65
- it(testMessageHelper(attr), () => {
66
- const { baseElement } = render(<DatePicker date={new Date(2020, 2, 1)} withInput={true} {...attr} />);
67
- expect(baseElement).toMatchSnapshot();
68
- });
69
- };
63
+ describe('renders snapshot for prop:disabledBefore', () => {
64
+ const mapper: Record<string, any> = {
65
+ disabledBefore: valueHelper('10/10/2020', { required: true }),
66
+ };
67
+ testHelper(mapper, testFunc);
68
+ });
70
69
 
71
- testHelper(mapper, testFunc);
70
+ describe('renders snapshot for prop:disabledAfter', () => {
71
+ const mapper: Record<string, any> = {
72
+ disabledAfter: valueHelper('10/10/2021', { required: true }),
73
+ };
74
+ testHelper(mapper, testFunc);
75
+ });
72
76
  });
73
77
 
74
- describe('DatePicker component', () => {
78
+ describe('DatePicker component today date chip', () => {
75
79
  it('renders component with today date chip', () => {
76
- const { getByTestId } = render(<DatePicker date={new Date(2021, 9, 8)} />);
80
+ const { getByTestId } = render(<DatePicker date={newDate} />);
77
81
  expect(getByTestId('DesignSystem-Select--TodaysDate-wrapper')).toBeInTheDocument();
78
82
  });
79
83
 
80
84
  it('calls click handler', () => {
81
- const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} date={new Date(2021, 9, 25)} />);
85
+ const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} date={newDate} />);
82
86
  const chip = getByTestId('DesignSystem-Chip--GenericChip');
83
87
  fireEvent.click(chip);
84
88
  expect(FunctionValue).toHaveBeenCalled();
85
89
  });
86
90
  });
91
+
92
+ describe('renders DatePicker component Event Handlers ', () => {
93
+ it('checks for trigger popover on input field click', () => {
94
+ const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} withInput={true} />);
95
+ const input = getByTestId('DesignSystem-InputWrapper');
96
+ fireEvent.click(input);
97
+ expect(getByTestId('DesignSystem-Popover')).toBeInTheDocument();
98
+ });
99
+
100
+ it('checks for input field onChange event', () => {
101
+ const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} withInput={true} />);
102
+ const input = getByTestId('DesignSystem-Input');
103
+ fireEvent.change(input, { target: { value: newDate } });
104
+ expect(FunctionValue).toHaveBeenCalled();
105
+ });
106
+
107
+ it('checks onCancel Event', () => {
108
+ const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} withInput={true} date={newDate} />);
109
+ const closeIcon = getByTestId('DesignSystem-Input--closeIcon');
110
+ expect(closeIcon).toBeInTheDocument();
111
+ fireEvent.click(closeIcon);
112
+ expect(getByTestId('DesignSystem-Popover')).toBeInTheDocument();
113
+ });
114
+
115
+ it('checks onCancel Event in case of required:true', () => {
116
+ const { getByTestId, getAllByTestId } = render(
117
+ <DatePicker
118
+ onDateChange={FunctionValue}
119
+ withInput={true}
120
+ date={newDate}
121
+ inputOptions={{
122
+ required: true,
123
+ }}
124
+ />
125
+ );
126
+ const closeIcon = getByTestId('DesignSystem-Input--closeIcon');
127
+ expect(closeIcon).toBeInTheDocument();
128
+ fireEvent.click(closeIcon);
129
+ expect(getByTestId('DesignSystem-Caption')).toBeInTheDocument();
130
+ expect(getAllByTestId('DesignSystem-Text')[0]).toHaveTextContent('Invalid value');
131
+ });
132
+
133
+ it('checks for custom caption onCancel Event', () => {
134
+ const { getByTestId, getAllByTestId } = render(
135
+ <DatePicker
136
+ onDateChange={FunctionValue}
137
+ withInput={true}
138
+ date={newDate}
139
+ inputOptions={{
140
+ required: true,
141
+ caption: 'Invalid Date Entered',
142
+ }}
143
+ />
144
+ );
145
+ const closeIcon = getByTestId('DesignSystem-Input--closeIcon');
146
+ fireEvent.click(closeIcon);
147
+ expect(getByTestId('DesignSystem-Caption')).toBeInTheDocument();
148
+ expect(getAllByTestId('DesignSystem-Text')[0]).toHaveTextContent('Invalid Date Entered');
149
+ });
150
+
151
+ it('checks for custom placeholderChar option onClose Event', () => {
152
+ const { getByTestId } = render(
153
+ <DatePicker
154
+ onDateChange={FunctionValue}
155
+ withInput={true}
156
+ date={newDate}
157
+ inputOptions={{
158
+ required: true,
159
+ placeholderChar: '*',
160
+ }}
161
+ />
162
+ );
163
+ const closeIcon = getByTestId('DesignSystem-Input--closeIcon');
164
+ fireEvent.click(closeIcon);
165
+ expect(getByTestId('DesignSystem-Input')).toHaveValue('**/**/****');
166
+ });
167
+
168
+ it('checks onBlur Event', () => {
169
+ const { getByTestId } = render(<DatePicker onDateChange={FunctionValue} withInput={true} date={newDate} />);
170
+ const closeIcon = getByTestId('DesignSystem-Input--closeIcon');
171
+ const input = getByTestId('DesignSystem-Input');
172
+ fireEvent.click(closeIcon);
173
+ fireEvent.blur(input);
174
+ expect(input).toHaveValue('__/__/____');
175
+ });
176
+ });