@transferwise/components 0.0.0-experimental-c1f5b0b → 0.0.0-experimental-fe160ab

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 (493) hide show
  1. package/build/Calendar/Calendar.constants.js +10 -0
  2. package/build/Calendar/Calendar.constants.js.map +1 -0
  3. package/build/Calendar/Calendar.constants.mjs +8 -0
  4. package/build/Calendar/Calendar.constants.mjs.map +1 -0
  5. package/build/Calendar/Calendar.js +116 -16
  6. package/build/Calendar/Calendar.js.map +1 -1
  7. package/build/Calendar/Calendar.messages.js +12 -0
  8. package/build/Calendar/Calendar.messages.js.map +1 -1
  9. package/build/Calendar/Calendar.messages.mjs +12 -0
  10. package/build/Calendar/Calendar.messages.mjs.map +1 -1
  11. package/build/Calendar/Calendar.mjs +117 -17
  12. package/build/Calendar/Calendar.mjs.map +1 -1
  13. package/build/Calendar/DateHeader/DateHeader.js +5 -1
  14. package/build/Calendar/DateHeader/DateHeader.js.map +1 -1
  15. package/build/Calendar/DateHeader/DateHeader.mjs +5 -1
  16. package/build/Calendar/DateHeader/DateHeader.mjs.map +1 -1
  17. package/build/Calendar/DayCalendar/DayCalendar.js +20 -2
  18. package/build/Calendar/DayCalendar/DayCalendar.js.map +1 -1
  19. package/build/Calendar/DayCalendar/DayCalendar.mjs +20 -2
  20. package/build/Calendar/DayCalendar/DayCalendar.mjs.map +1 -1
  21. package/build/Calendar/DayCalendar/Table/DayCalendarTable.js +60 -19
  22. package/build/Calendar/DayCalendar/Table/DayCalendarTable.js.map +1 -1
  23. package/build/Calendar/DayCalendar/Table/DayCalendarTable.mjs +60 -19
  24. package/build/Calendar/DayCalendar/Table/DayCalendarTable.mjs.map +1 -1
  25. package/build/Calendar/MonthCalendar/MonthCalendar.js +6 -0
  26. package/build/Calendar/MonthCalendar/MonthCalendar.js.map +1 -1
  27. package/build/Calendar/MonthCalendar/MonthCalendar.mjs +6 -0
  28. package/build/Calendar/MonthCalendar/MonthCalendar.mjs.map +1 -1
  29. package/build/Calendar/MonthCalendar/Table/MonthCalendarTable.js +8 -3
  30. package/build/Calendar/MonthCalendar/Table/MonthCalendarTable.js.map +1 -1
  31. package/build/Calendar/MonthCalendar/Table/MonthCalendarTable.mjs +8 -3
  32. package/build/Calendar/MonthCalendar/Table/MonthCalendarTable.mjs.map +1 -1
  33. package/build/Calendar/TableLink/TableLink.js +91 -0
  34. package/build/Calendar/TableLink/TableLink.js.map +1 -0
  35. package/build/Calendar/TableLink/TableLink.mjs +87 -0
  36. package/build/Calendar/TableLink/TableLink.mjs.map +1 -0
  37. package/build/Calendar/YearCalendar/Table/YearCalendarTable.js +8 -3
  38. package/build/Calendar/YearCalendar/Table/YearCalendarTable.js.map +1 -1
  39. package/build/Calendar/YearCalendar/Table/YearCalendarTable.mjs +8 -3
  40. package/build/Calendar/YearCalendar/Table/YearCalendarTable.mjs.map +1 -1
  41. package/build/Calendar/YearCalendar/YearCalendar.js +7 -0
  42. package/build/Calendar/YearCalendar/YearCalendar.js.map +1 -1
  43. package/build/Calendar/YearCalendar/YearCalendar.mjs +7 -0
  44. package/build/Calendar/YearCalendar/YearCalendar.mjs.map +1 -1
  45. package/build/Calendar/_helpers/hasDisabledDatesInMonth/hasDisabledDatesInMonth.js +33 -0
  46. package/build/Calendar/_helpers/hasDisabledDatesInMonth/hasDisabledDatesInMonth.js.map +1 -0
  47. package/build/Calendar/_helpers/hasDisabledDatesInMonth/hasDisabledDatesInMonth.mjs +31 -0
  48. package/build/Calendar/_helpers/hasDisabledDatesInMonth/hasDisabledDatesInMonth.mjs.map +1 -0
  49. package/build/Calendar/_helpers/isDateDisabled/isDateDisabled.js +40 -0
  50. package/build/Calendar/_helpers/isDateDisabled/isDateDisabled.js.map +1 -0
  51. package/build/Calendar/_helpers/isDateDisabled/isDateDisabled.mjs +38 -0
  52. package/build/Calendar/_helpers/isDateDisabled/isDateDisabled.mjs.map +1 -0
  53. package/build/DateLookup/DateLookup.js +20 -9
  54. package/build/DateLookup/DateLookup.js.map +1 -1
  55. package/build/DateLookup/DateLookup.mjs +20 -9
  56. package/build/DateLookup/DateLookup.mjs.map +1 -1
  57. package/build/i18n/en.json +4 -0
  58. package/build/i18n/en.json.js +4 -0
  59. package/build/i18n/en.json.js.map +1 -1
  60. package/build/i18n/en.json.mjs +4 -0
  61. package/build/i18n/en.json.mjs.map +1 -1
  62. package/build/index.js +2 -2
  63. package/build/index.mjs +1 -1
  64. package/build/main.css +8798 -4478
  65. package/build/styles/Accordion/Accordion.css +21 -23
  66. package/build/styles/AvatarLayout/AvatarLayout.css +11 -11
  67. package/build/styles/AvatarView/AvatarView.css +3 -3
  68. package/build/styles/AvatarView/Dot/Dot.css +3 -3
  69. package/build/styles/Button/Button.css +6 -6
  70. package/build/styles/Button/LegacyButton/LegacyButton.css +9 -3
  71. package/build/styles/Calendar/Calendar.css +119 -45
  72. package/build/styles/Calendar/TableLink/TableLink.css +115 -0
  73. package/build/styles/Carousel/Carousel.css +27 -28
  74. package/build/styles/CheckboxButton/CheckboxButton.css +15 -10
  75. package/build/styles/Chips/Chip/Chip.css +29 -26
  76. package/build/styles/Container/Container.css +5 -5
  77. package/build/styles/DateInput/DateInput.css +4 -4
  78. package/build/styles/DateLookup/DateLookup.css +1 -1
  79. package/build/styles/DateLookup/DateTrigger/DateTrigger.css +15 -9
  80. package/build/styles/DefinitionList/DefinitionList.css +83 -0
  81. package/build/styles/Dimmer/Dimmer.css +19 -9
  82. package/build/styles/Divider/Divider.css +7 -8
  83. package/build/styles/Drawer/Drawer.css +15 -16
  84. package/build/styles/DropFade/DropFade.css +2 -2
  85. package/build/styles/ExpressiveMoneyInput/AmountInput/AmountInput.css +4 -4
  86. package/build/styles/ExpressiveMoneyInput/Chevron/Chevron.css +5 -5
  87. package/build/styles/ExpressiveMoneyInput/ExpressiveMoneyInput.css +11 -11
  88. package/build/styles/Field/Field.css +12 -13
  89. package/build/styles/FlowNavigation/AnimatedLabel/AnimatedLabel.css +5 -5
  90. package/build/styles/FlowNavigation/FlowNavigation.css +46 -25
  91. package/build/styles/Header/Header.css +9 -11
  92. package/build/styles/Image/Image.css +7 -7
  93. package/build/styles/Info/Info.css +1 -1
  94. package/build/styles/Inputs/Input/Input.css +25 -24
  95. package/build/styles/Inputs/InputGroup/InputGroup.css +13 -13
  96. package/build/styles/Inputs/SelectInput/BottomSheet/SelectInputBottomSheet.css +10 -10
  97. package/build/styles/Inputs/SelectInput/ButtonInput/SelectInputButtonInput.css +7 -7
  98. package/build/styles/Inputs/SelectInput/ClearButton/SelectInputClearButton.css +6 -6
  99. package/build/styles/Inputs/SelectInput/ItemView/SelectInputItemView.css +4 -4
  100. package/build/styles/Inputs/SelectInput/Option/SelectInputOption.css +2 -4
  101. package/build/styles/Inputs/SelectInput/OptionContent/SelectInputOptionContent.css +4 -4
  102. package/build/styles/Inputs/SelectInput/Options/SelectInputOptions.css +12 -17
  103. package/build/styles/Inputs/SelectInput/Popover/SelectInputPopover.css +4 -4
  104. package/build/styles/Inputs/SelectInput/SelectInput.css +49 -56
  105. package/build/styles/Inputs/TextArea/TextArea.css +27 -26
  106. package/build/styles/InstructionsList/InstructionsList.css +5 -5
  107. package/build/styles/Link/Link.css +8 -2
  108. package/build/styles/ListItem/ListItem.css +35 -38
  109. package/build/styles/ListItem/ListItem.grid.css +7 -7
  110. package/build/styles/Loader/Loader.css +31 -31
  111. package/build/styles/Logo/Logo.css +2 -2
  112. package/build/styles/Modal/Modal.css +14 -15
  113. package/build/styles/MoneyInput/MoneyInput.css +20 -10
  114. package/build/styles/Nudge/Nudge.css +77 -49
  115. package/build/styles/PhoneNumberInput/PhoneNumberInput.css +9 -3
  116. package/build/styles/Popover/Popover.css +10 -13
  117. package/build/styles/Progress/Progress.css +3 -3
  118. package/build/styles/ProgressBar/ProgressBar.css +4 -4
  119. package/build/styles/PromoCard/PromoCard.css +42 -28
  120. package/build/styles/Prompt/ActionPrompt/ActionPrompt.css +9 -9
  121. package/build/styles/Prompt/CriticalBanner/CriticalBanner.css +23 -23
  122. package/build/styles/Prompt/InfoPrompt/InfoPrompt.css +15 -15
  123. package/build/styles/Prompt/InlinePrompt/InlinePrompt.css +6 -5
  124. package/build/styles/Prompt/PrimitivePrompt/PrimitivePrompt.css +8 -10
  125. package/build/styles/RadioGroup/RadioGroup.css +1 -1
  126. package/build/styles/Section/Section.css +6 -6
  127. package/build/styles/SegmentedControl/SegmentedControl.css +15 -18
  128. package/build/styles/SlidingPanel/SlidingPanel.css +40 -9
  129. package/build/styles/Snackbar/Snackbar.css +35 -21
  130. package/build/styles/Stepper/Stepper.css +15 -9
  131. package/build/styles/Sticky/Sticky.css +2 -2
  132. package/build/styles/Switch/Switch.css +7 -5
  133. package/build/styles/Table/Table.css +57 -60
  134. package/build/styles/Tabs/Tabs.css +14 -18
  135. package/build/styles/Tile/Tile.css +12 -12
  136. package/build/styles/Tooltip/Tooltip.css +2 -2
  137. package/build/styles/Typeahead/Typeahead.css +52 -40
  138. package/build/styles/Upload/Upload.css +10 -11
  139. package/build/styles/UploadInput/UploadButton/UploadButton.css +19 -20
  140. package/build/styles/UploadInput/UploadInput.css +4 -4
  141. package/build/styles/UploadInput/UploadItem/UploadItem.css +44 -45
  142. package/build/styles/_deprecated/ActionButton/ActionButton.css +6 -8
  143. package/build/styles/_deprecated/Alert/Alert.css +2 -2
  144. package/build/styles/_deprecated/Avatar/Avatar.css +65 -65
  145. package/build/styles/_deprecated/Badge/Badge.css +12 -8
  146. package/build/styles/_deprecated/Card/Card.css +18 -27
  147. package/build/styles/_deprecated/CriticalBanner/CriticalCommsBanner.css +7 -7
  148. package/build/styles/_deprecated/LegacyListItem/LegacyListItem.css +1 -1
  149. package/build/styles/_deprecated/NavigationOption/NavigationOption.css +19 -6
  150. package/build/styles/_deprecated/NavigationOptionsList/NavigationOptionsList.css +8 -3
  151. package/build/styles/_deprecated/OverlayHeader/OverlayHeader.css +6 -7
  152. package/build/styles/_deprecated/Select/Select.css +104 -57
  153. package/build/styles/_deprecated/Summary/Summary.css +30 -19
  154. package/build/styles/common/BaseCard/BaseCard.css +7 -3
  155. package/build/styles/common/BottomSheet/BottomSheet.css +18 -30
  156. package/build/styles/common/Circle/Circle.css +10 -10
  157. package/build/styles/common/CloseButton/CloseButton.css +36 -36
  158. package/build/styles/common/LiveRegion/LiveRegion.css +1 -1
  159. package/build/styles/common/Option/Option.css +44 -42
  160. package/build/styles/common/Panel/Panel.css +7 -7
  161. package/build/styles/css/accordion.css +52 -24
  162. package/build/styles/css/alerts.css +124 -56
  163. package/build/styles/css/badge.css +30 -20
  164. package/build/styles/css/breadcrumbs.css +4 -6
  165. package/build/styles/css/button-groups.css +258 -114
  166. package/build/styles/css/buttons.css +94 -49
  167. package/build/styles/css/chevron.css +6 -0
  168. package/build/styles/css/circles.css +76 -38
  169. package/build/styles/css/close.css +4 -1
  170. package/build/styles/css/column-layout.css +59 -37
  171. package/build/styles/css/currency-flags.css +17 -4
  172. package/build/styles/css/decision.css +12 -14
  173. package/build/styles/css/dropdowns.css +209 -58
  174. package/build/styles/css/droppable.css +38 -43
  175. package/build/styles/css/flex.css +136 -40
  176. package/build/styles/css/footer.css +14 -15
  177. package/build/styles/css/grid.css +1434 -381
  178. package/build/styles/css/input-groups.css +546 -252
  179. package/build/styles/css/link-callout.css +8 -2
  180. package/build/styles/css/list-group.css +92 -57
  181. package/build/styles/css/loaders.css +11 -11
  182. package/build/styles/css/media.css +34 -10
  183. package/build/styles/css/modals.css +59 -49
  184. package/build/styles/css/navbar.css +811 -371
  185. package/build/styles/css/navs.css +124 -59
  186. package/build/styles/css/neptune-social-media.css +44 -4
  187. package/build/styles/css/neptune.css +7118 -3155
  188. package/build/styles/css/panels.css +243 -143
  189. package/build/styles/css/popovers.css +295 -114
  190. package/build/styles/css/process.css +77 -64
  191. package/build/styles/css/progress-bars.css +21 -11
  192. package/build/styles/css/select.css +52 -20
  193. package/build/styles/css/sequences.css +219 -99
  194. package/build/styles/css/table.css +43 -48
  195. package/build/styles/css/tick.css +10 -10
  196. package/build/styles/css/tooltip.css +82 -49
  197. package/build/styles/css/utilities.css +40 -12
  198. package/build/styles/css/wells.css +16 -16
  199. package/build/styles/main.css +8798 -4478
  200. package/build/styles/styles/less/accordion.css +52 -24
  201. package/build/styles/styles/less/alerts.css +124 -56
  202. package/build/styles/styles/less/badge.css +30 -20
  203. package/build/styles/styles/less/breadcrumbs.css +4 -6
  204. package/build/styles/styles/less/button-groups.css +258 -114
  205. package/build/styles/styles/less/buttons.css +94 -49
  206. package/build/styles/styles/less/chevron.css +6 -0
  207. package/build/styles/styles/less/circles.css +76 -38
  208. package/build/styles/styles/less/close.css +4 -1
  209. package/build/styles/styles/less/column-layout.css +59 -37
  210. package/build/styles/styles/less/currency-flags.css +17 -4
  211. package/build/styles/styles/less/decision.css +12 -14
  212. package/build/styles/styles/less/dropdowns.css +209 -58
  213. package/build/styles/styles/less/droppable.css +38 -43
  214. package/build/styles/styles/less/flex.css +136 -40
  215. package/build/styles/styles/less/footer.css +14 -15
  216. package/build/styles/styles/less/forms/bootstrap-forms.css +348 -178
  217. package/build/styles/styles/less/forms/checkbox-radio.css +56 -29
  218. package/build/styles/styles/less/grid.css +1434 -381
  219. package/build/styles/styles/less/input-groups.css +546 -252
  220. package/build/styles/styles/less/link-callout.css +8 -2
  221. package/build/styles/styles/less/list-group.css +92 -57
  222. package/build/styles/styles/less/loaders.css +11 -11
  223. package/build/styles/styles/less/media.css +34 -10
  224. package/build/styles/styles/less/modals.css +59 -49
  225. package/build/styles/styles/less/navbar.css +811 -371
  226. package/build/styles/styles/less/navs.css +124 -59
  227. package/build/styles/styles/less/neptune-social-media.css +44 -4
  228. package/build/styles/styles/less/neptune.css +7118 -3155
  229. package/build/styles/styles/less/panels.css +243 -143
  230. package/build/styles/styles/less/popovers.css +295 -114
  231. package/build/styles/styles/less/process.css +77 -64
  232. package/build/styles/styles/less/progress-bars.css +21 -11
  233. package/build/styles/styles/less/select.css +52 -20
  234. package/build/styles/styles/less/sequences.css +219 -99
  235. package/build/styles/styles/less/table.css +43 -48
  236. package/build/styles/styles/less/tick.css +10 -10
  237. package/build/styles/styles/less/tooltip.css +82 -49
  238. package/build/styles/styles/less/utilities.css +40 -12
  239. package/build/styles/styles/less/wells.css +16 -16
  240. package/build/types/Calendar/Calendar.constants.d.ts +2 -0
  241. package/build/types/Calendar/Calendar.constants.d.ts.map +1 -0
  242. package/build/types/Calendar/Calendar.d.ts +16 -3
  243. package/build/types/Calendar/Calendar.d.ts.map +1 -1
  244. package/build/types/Calendar/Calendar.messages.d.ts +20 -0
  245. package/build/types/Calendar/Calendar.messages.d.ts.map +1 -1
  246. package/build/types/Calendar/Calendar.types.d.ts +32 -0
  247. package/build/types/Calendar/Calendar.types.d.ts.map +1 -0
  248. package/build/types/Calendar/DateHeader/DateHeader.d.ts +2 -0
  249. package/build/types/Calendar/DateHeader/DateHeader.d.ts.map +1 -1
  250. package/build/types/Calendar/DayCalendar/DayCalendar.d.ts +7 -1
  251. package/build/types/Calendar/DayCalendar/DayCalendar.d.ts.map +1 -1
  252. package/build/types/Calendar/DayCalendar/Table/DayCalendarTable.d.ts +6 -0
  253. package/build/types/Calendar/DayCalendar/Table/DayCalendarTable.d.ts.map +1 -1
  254. package/build/types/Calendar/MonthCalendar/MonthCalendar.d.ts +1 -0
  255. package/build/types/Calendar/MonthCalendar/MonthCalendar.d.ts.map +1 -1
  256. package/build/types/Calendar/MonthCalendar/Table/MonthCalendarTable.d.ts +2 -1
  257. package/build/types/Calendar/MonthCalendar/Table/MonthCalendarTable.d.ts.map +1 -1
  258. package/build/types/Calendar/{tableLink → TableLink}/TableLink.d.ts +5 -1
  259. package/build/types/Calendar/TableLink/TableLink.d.ts.map +1 -0
  260. package/build/types/Calendar/TableLink/index.d.ts.map +1 -0
  261. package/build/types/Calendar/YearCalendar/Table/YearCalendarTable.d.ts +2 -1
  262. package/build/types/Calendar/YearCalendar/Table/YearCalendarTable.d.ts.map +1 -1
  263. package/build/types/Calendar/YearCalendar/YearCalendar.d.ts +1 -0
  264. package/build/types/Calendar/YearCalendar/YearCalendar.d.ts.map +1 -1
  265. package/build/types/Calendar/_helpers/hasDisabledDatesInMonth/hasDisabledDatesInMonth.d.ts +3 -0
  266. package/build/types/Calendar/_helpers/hasDisabledDatesInMonth/hasDisabledDatesInMonth.d.ts.map +1 -0
  267. package/build/types/Calendar/_helpers/index.d.ts +3 -0
  268. package/build/types/Calendar/_helpers/index.d.ts.map +1 -0
  269. package/build/types/Calendar/_helpers/isDateDisabled/isDateDisabled.d.ts +3 -0
  270. package/build/types/Calendar/_helpers/isDateDisabled/isDateDisabled.d.ts.map +1 -0
  271. package/build/types/Calendar/index.d.ts +1 -0
  272. package/build/types/Calendar/index.d.ts.map +1 -1
  273. package/build/types/DateLookup/DateLookup.d.ts +24 -5
  274. package/build/types/DateLookup/DateLookup.d.ts.map +1 -1
  275. package/build/types/DateLookup/index.d.ts +1 -0
  276. package/build/types/DateLookup/index.d.ts.map +1 -1
  277. package/build/types/index.d.ts +3 -2
  278. package/build/types/index.d.ts.map +1 -1
  279. package/build/types/test-utils/index.d.ts +8 -0
  280. package/build/types/test-utils/index.d.ts.map +1 -1
  281. package/package.json +1 -1
  282. package/src/Accordion/Accordion.css +21 -23
  283. package/src/Accordion/Accordion.less +4 -3
  284. package/src/AvatarLayout/AvatarLayout.css +11 -11
  285. package/src/AvatarView/AvatarView.css +3 -3
  286. package/src/AvatarView/Dot/Dot.css +3 -3
  287. package/src/Button/Button.css +6 -6
  288. package/src/Button/LegacyButton/LegacyButton.css +9 -3
  289. package/src/Button/LegacyButton/LegacyButton.less +3 -1
  290. package/src/Calendar/Calendar.constants.ts +5 -0
  291. package/src/Calendar/Calendar.css +119 -45
  292. package/src/Calendar/Calendar.disabledDates.test.tsx +593 -0
  293. package/src/Calendar/Calendar.less +5 -35
  294. package/src/Calendar/Calendar.messages.ts +21 -0
  295. package/src/Calendar/Calendar.test.tsx +310 -28
  296. package/src/Calendar/Calendar.tsx +159 -18
  297. package/src/Calendar/Calendar.types.ts +35 -0
  298. package/src/Calendar/DateHeader/DateHeader.tsx +6 -0
  299. package/src/Calendar/DayCalendar/DayCalendar.tsx +39 -1
  300. package/src/Calendar/DayCalendar/Table/DayCalendarTable.tsx +67 -27
  301. package/src/Calendar/MonthCalendar/MonthCalendar.tsx +8 -0
  302. package/src/Calendar/MonthCalendar/Table/MonthCalendarTable.tsx +15 -3
  303. package/src/Calendar/TableLink/TableLink.css +115 -0
  304. package/src/Calendar/TableLink/TableLink.less +68 -0
  305. package/src/Calendar/TableLink/TableLink.tsx +112 -0
  306. package/src/Calendar/YearCalendar/Table/YearCalendarTable.tsx +15 -3
  307. package/src/Calendar/YearCalendar/YearCalendar.tsx +9 -0
  308. package/src/Calendar/_helpers/hasDisabledDatesInMonth/hasDisabledDatesInMonth.test.ts +98 -0
  309. package/src/Calendar/_helpers/hasDisabledDatesInMonth/hasDisabledDatesInMonth.ts +45 -0
  310. package/src/Calendar/_helpers/index.ts +2 -0
  311. package/src/Calendar/_helpers/isDateDisabled/isDateDisabled.test.ts +169 -0
  312. package/src/Calendar/_helpers/isDateDisabled/isDateDisabled.ts +59 -0
  313. package/src/Calendar/_stories/Calendar.accessibility.docs.mdx +118 -0
  314. package/src/Calendar/_stories/Calendar.story.tsx +138 -4
  315. package/src/Calendar/_stories/Calendar.test.story.tsx +114 -0
  316. package/src/Calendar/index.ts +7 -0
  317. package/src/Carousel/Carousel.css +27 -28
  318. package/src/CheckboxButton/CheckboxButton.css +15 -10
  319. package/src/CheckboxButton/CheckboxButton.less +4 -4
  320. package/src/Chips/Chip/Chip.css +29 -26
  321. package/src/Chips/Chip/Chip.less +3 -5
  322. package/src/Container/Container.css +5 -5
  323. package/src/DateInput/DateInput.css +4 -4
  324. package/src/DateLookup/DateLookup.css +1 -1
  325. package/src/DateLookup/DateLookup.disabledDates.test.tsx +293 -0
  326. package/src/DateLookup/DateLookup.test.tsx +34 -37
  327. package/src/DateLookup/DateLookup.tsx +37 -13
  328. package/src/DateLookup/DateTrigger/DateTrigger.css +15 -9
  329. package/src/DateLookup/DateTrigger/DateTrigger.less +2 -1
  330. package/src/DateLookup/_stories/DateLookup.accessibility.docs.mdx +108 -0
  331. package/src/DateLookup/_stories/DateLookup.story.tsx +124 -2
  332. package/src/DateLookup/index.ts +6 -0
  333. package/src/Decision/Decision.less +2 -0
  334. package/src/DefinitionList/DefinitionList.css +83 -0
  335. package/src/DefinitionList/DefinitionList.less +3 -1
  336. package/src/Dimmer/Dimmer.css +19 -9
  337. package/src/Dimmer/Dimmer.less +3 -2
  338. package/src/Divider/Divider.css +7 -8
  339. package/src/Drawer/Drawer.css +15 -16
  340. package/src/DropFade/DropFade.css +2 -2
  341. package/src/ExpressiveMoneyInput/AmountInput/AmountInput.css +4 -4
  342. package/src/ExpressiveMoneyInput/Chevron/Chevron.css +5 -5
  343. package/src/ExpressiveMoneyInput/ExpressiveMoneyInput.css +11 -11
  344. package/src/Field/Field.css +12 -13
  345. package/src/FlowNavigation/AnimatedLabel/AnimatedLabel.css +5 -5
  346. package/src/FlowNavigation/FlowNavigation.css +46 -25
  347. package/src/Header/Header.css +9 -11
  348. package/src/Image/Image.css +7 -7
  349. package/src/Info/Info.css +1 -1
  350. package/src/Inputs/Input/Input.css +25 -24
  351. package/src/Inputs/InputGroup/InputGroup.css +13 -13
  352. package/src/Inputs/SelectInput/BottomSheet/SelectInputBottomSheet.css +10 -10
  353. package/src/Inputs/SelectInput/ButtonInput/SelectInputButtonInput.css +7 -7
  354. package/src/Inputs/SelectInput/ClearButton/SelectInputClearButton.css +6 -6
  355. package/src/Inputs/SelectInput/ItemView/SelectInputItemView.css +4 -4
  356. package/src/Inputs/SelectInput/Option/SelectInputOption.css +2 -4
  357. package/src/Inputs/SelectInput/OptionContent/SelectInputOptionContent.css +4 -4
  358. package/src/Inputs/SelectInput/Options/SelectInputOptions.css +12 -17
  359. package/src/Inputs/SelectInput/Popover/SelectInputPopover.css +4 -4
  360. package/src/Inputs/SelectInput/SelectInput.css +49 -56
  361. package/src/Inputs/TextArea/TextArea.css +27 -26
  362. package/src/InstructionsList/InstructionsList.css +5 -5
  363. package/src/Link/Link.css +8 -2
  364. package/src/Link/Link.less +3 -3
  365. package/src/ListItem/ListItem.css +35 -38
  366. package/src/ListItem/ListItem.grid.css +7 -7
  367. package/src/Loader/Loader.css +31 -31
  368. package/src/Logo/Logo.css +2 -2
  369. package/src/Modal/Modal.css +14 -15
  370. package/src/MoneyInput/MoneyInput.css +20 -10
  371. package/src/MoneyInput/MoneyInput.less +3 -2
  372. package/src/Nudge/Nudge.css +77 -49
  373. package/src/Nudge/Nudge.less +8 -0
  374. package/src/PhoneNumberInput/PhoneNumberInput.css +9 -3
  375. package/src/PhoneNumberInput/PhoneNumberInput.less +3 -1
  376. package/src/Popover/Popover.css +10 -13
  377. package/src/Progress/Progress.css +3 -3
  378. package/src/ProgressBar/ProgressBar.css +4 -4
  379. package/src/PromoCard/PromoCard.css +42 -28
  380. package/src/PromoCard/PromoCard.less +32 -24
  381. package/src/Prompt/ActionPrompt/ActionPrompt.css +9 -9
  382. package/src/Prompt/CriticalBanner/CriticalBanner.css +23 -23
  383. package/src/Prompt/InfoPrompt/InfoPrompt.css +15 -15
  384. package/src/Prompt/InlinePrompt/InlinePrompt.css +6 -5
  385. package/src/Prompt/PrimitivePrompt/PrimitivePrompt.css +8 -10
  386. package/src/RadioGroup/RadioGroup.css +1 -1
  387. package/src/Section/Section.css +6 -6
  388. package/src/SegmentedControl/SegmentedControl.css +15 -18
  389. package/src/SlidingPanel/SlidingPanel.css +40 -9
  390. package/src/SlidingPanel/SlidingPanel.less +4 -4
  391. package/src/Snackbar/Snackbar.css +35 -21
  392. package/src/Snackbar/Snackbar.less +9 -3
  393. package/src/Stepper/Stepper.css +15 -9
  394. package/src/Stepper/Stepper.less +1 -1
  395. package/src/Sticky/Sticky.css +2 -2
  396. package/src/Sticky/Sticky.less +4 -1
  397. package/src/Switch/Switch.css +7 -5
  398. package/src/Table/Table.css +57 -60
  399. package/src/Tabs/Tabs.css +14 -18
  400. package/src/Tabs/Tabs.less +1 -0
  401. package/src/Tile/Tile.css +12 -12
  402. package/src/Tooltip/Tooltip.css +2 -2
  403. package/src/Typeahead/Typeahead.css +52 -40
  404. package/src/Typeahead/Typeahead.less +3 -2
  405. package/src/Upload/Upload.css +10 -11
  406. package/src/UploadInput/UploadButton/UploadButton.css +19 -20
  407. package/src/UploadInput/UploadInput.css +4 -4
  408. package/src/UploadInput/UploadItem/UploadItem.css +44 -45
  409. package/src/_deprecated/ActionButton/ActionButton.css +6 -8
  410. package/src/_deprecated/Alert/Alert.css +2 -2
  411. package/src/_deprecated/Avatar/Avatar.css +65 -65
  412. package/src/_deprecated/Avatar/Avatar.less +1 -0
  413. package/src/_deprecated/Badge/Badge.css +12 -8
  414. package/src/_deprecated/Badge/Badge.less +13 -13
  415. package/src/_deprecated/Card/Card.css +18 -27
  416. package/src/_deprecated/Card/Card.less +2 -1
  417. package/src/_deprecated/CriticalBanner/CriticalCommsBanner.css +7 -7
  418. package/src/_deprecated/LegacyListItem/LegacyListItem.css +1 -1
  419. package/src/_deprecated/NavigationOption/NavigationOption.css +19 -6
  420. package/src/_deprecated/NavigationOption/NavigationOption.less +4 -3
  421. package/src/_deprecated/NavigationOptionsList/NavigationOptionsList.css +8 -3
  422. package/src/_deprecated/NavigationOptionsList/NavigationOptionsList.less +3 -1
  423. package/src/_deprecated/OverlayHeader/OverlayHeader.css +6 -7
  424. package/src/_deprecated/Select/Select.css +104 -57
  425. package/src/_deprecated/Select/Select.less +11 -10
  426. package/src/_deprecated/Summary/Summary.css +30 -19
  427. package/src/_deprecated/Summary/Summary.less +8 -1
  428. package/src/common/BaseCard/BaseCard.css +7 -3
  429. package/src/common/BaseCard/BaseCard.less +5 -0
  430. package/src/common/BottomSheet/BottomSheet.css +18 -30
  431. package/src/common/Circle/Circle.css +10 -10
  432. package/src/common/CloseButton/CloseButton.css +36 -36
  433. package/src/common/LiveRegion/LiveRegion.css +1 -1
  434. package/src/common/Option/Option.css +44 -42
  435. package/src/common/Option/Option.less +10 -8
  436. package/src/common/Panel/Panel.css +7 -7
  437. package/src/i18n/en.json +4 -0
  438. package/src/index.ts +3 -2
  439. package/src/main.css +8798 -4478
  440. package/src/styles/less/accordion.css +52 -24
  441. package/src/styles/less/alerts.css +124 -56
  442. package/src/styles/less/badge.css +30 -20
  443. package/src/styles/less/breadcrumbs.css +4 -6
  444. package/src/styles/less/button-groups.css +258 -114
  445. package/src/styles/less/buttons.css +94 -49
  446. package/src/styles/less/buttons.less +10 -2
  447. package/src/styles/less/chevron.css +6 -0
  448. package/src/styles/less/circles.css +76 -38
  449. package/src/styles/less/close.css +4 -1
  450. package/src/styles/less/column-layout.css +59 -37
  451. package/src/styles/less/currency-flags.css +17 -4
  452. package/src/styles/less/decision.css +12 -14
  453. package/src/styles/less/dropdowns.css +209 -58
  454. package/src/styles/less/droppable.css +38 -43
  455. package/src/styles/less/flex.css +136 -40
  456. package/src/styles/less/footer.css +14 -15
  457. package/src/styles/less/forms/bootstrap-forms.css +348 -178
  458. package/src/styles/less/forms/checkbox-radio.css +56 -29
  459. package/src/styles/less/grid.css +1434 -381
  460. package/src/styles/less/input-groups.css +546 -252
  461. package/src/styles/less/link-callout.css +8 -2
  462. package/src/styles/less/list-group.css +92 -57
  463. package/src/styles/less/loaders.css +11 -11
  464. package/src/styles/less/media.css +34 -10
  465. package/src/styles/less/mixins/_logical-properties.less +2 -2
  466. package/src/styles/less/mixins/_physical-properties.less +5 -77
  467. package/src/styles/less/modals.css +59 -49
  468. package/src/styles/less/navbar.css +811 -371
  469. package/src/styles/less/navs.css +124 -59
  470. package/src/styles/less/neptune-social-media.css +44 -4
  471. package/src/styles/less/neptune-social-media.less +18 -4
  472. package/src/styles/less/neptune.css +7118 -3155
  473. package/src/styles/less/panels.css +243 -143
  474. package/src/styles/less/popovers.css +295 -114
  475. package/src/styles/less/process.css +77 -64
  476. package/src/styles/less/progress-bars.css +21 -11
  477. package/src/styles/less/progress-bars.less +6 -1
  478. package/src/styles/less/select.css +52 -20
  479. package/src/styles/less/sequences.css +219 -99
  480. package/src/styles/less/table.css +43 -48
  481. package/src/styles/less/tick.css +10 -10
  482. package/src/styles/less/tooltip.css +82 -49
  483. package/src/styles/less/utilities.css +40 -12
  484. package/src/styles/less/wells.css +16 -16
  485. package/build/Calendar/tableLink/TableLink.js +0 -61
  486. package/build/Calendar/tableLink/TableLink.js.map +0 -1
  487. package/build/Calendar/tableLink/TableLink.mjs +0 -57
  488. package/build/Calendar/tableLink/TableLink.mjs.map +0 -1
  489. package/build/types/Calendar/tableLink/TableLink.d.ts.map +0 -1
  490. package/build/types/Calendar/tableLink/index.d.ts.map +0 -1
  491. package/src/Calendar/tableLink/TableLink.tsx +0 -77
  492. /package/build/types/Calendar/{tableLink → TableLink}/index.d.ts +0 -0
  493. /package/src/Calendar/{tableLink → TableLink}/index.ts +0 -0
@@ -0,0 +1,169 @@
1
+ import { isDateDisabled } from './isDateDisabled';
2
+ import type { DisabledRules } from '../../Calendar.types';
3
+
4
+ describe('isDateDisabled', () => {
5
+ describe('when no rules provided', () => {
6
+ it('returns false when disabledRules is undefined', () => {
7
+ expect(isDateDisabled(new Date('2024-07-15'), undefined)).toBe(false);
8
+ });
9
+
10
+ it('returns false when disabledRules has only reason', () => {
11
+ const rules: DisabledRules = { reason: 'some reason' };
12
+ expect(isDateDisabled(new Date('2024-07-15'), rules)).toBe(false);
13
+ });
14
+ });
15
+
16
+ describe('weekdays', () => {
17
+ const rules: DisabledRules = {
18
+ weekdays: ['sat', 'sun'],
19
+ reason: 'Closed on weekends',
20
+ };
21
+
22
+ it('returns true for a Saturday', () => {
23
+ // 2024-07-13 is a Saturday
24
+ expect(isDateDisabled(new Date(2024, 6, 13), rules)).toBe(true);
25
+ });
26
+
27
+ it('returns true for a Sunday', () => {
28
+ // 2024-07-14 is a Sunday
29
+ expect(isDateDisabled(new Date(2024, 6, 14), rules)).toBe(true);
30
+ });
31
+
32
+ it('returns false for a Monday', () => {
33
+ // 2024-07-15 is a Monday
34
+ expect(isDateDisabled(new Date(2024, 6, 15), rules)).toBe(false);
35
+ });
36
+
37
+ it('returns false for a Friday', () => {
38
+ // 2024-07-12 is a Friday
39
+ expect(isDateDisabled(new Date(2024, 6, 12), rules)).toBe(false);
40
+ });
41
+
42
+ it('handles single weekday rule', () => {
43
+ const singleDay: DisabledRules = { weekdays: ['wed'], reason: 'Closed' };
44
+ // 2024-07-17 is a Wednesday
45
+ expect(isDateDisabled(new Date(2024, 6, 17), singleDay)).toBe(true);
46
+ // 2024-07-18 is a Thursday
47
+ expect(isDateDisabled(new Date(2024, 6, 18), singleDay)).toBe(false);
48
+ });
49
+ });
50
+
51
+ describe('specific dates', () => {
52
+ const rules: DisabledRules = {
53
+ dates: [new Date(2024, 6, 11), new Date(2025, 1, 12), new Date(2025, 4, 1)],
54
+ reason: 'Bank holidays',
55
+ };
56
+
57
+ it('returns true for a disabled date', () => {
58
+ expect(isDateDisabled(new Date(2024, 6, 11), rules)).toBe(true);
59
+ });
60
+
61
+ it('returns false for a non-disabled date', () => {
62
+ expect(isDateDisabled(new Date(2024, 6, 12), rules)).toBe(false);
63
+ });
64
+
65
+ it('compares date-only, ignoring time', () => {
66
+ const dateWithTime = new Date(2024, 6, 11, 14, 30, 0);
67
+ expect(isDateDisabled(dateWithTime, rules)).toBe(true);
68
+ });
69
+
70
+ it('handles disabled dates that have non-zero time components', () => {
71
+ const rulesWithTime: DisabledRules = {
72
+ dates: [new Date(2024, 6, 11, 23, 59, 59)],
73
+ reason: 'Holiday',
74
+ };
75
+ expect(isDateDisabled(new Date(2024, 6, 11), rulesWithTime)).toBe(true);
76
+ });
77
+ });
78
+
79
+ describe('ranges', () => {
80
+ const rules: DisabledRules = {
81
+ ranges: [
82
+ { start: new Date(2024, 2, 29), end: new Date(2024, 3, 3) },
83
+ { start: new Date(2024, 11, 24), end: new Date(2024, 11, 26) },
84
+ ],
85
+ reason: 'Scheduled maintenance',
86
+ };
87
+
88
+ it('returns true for start of range (inclusive)', () => {
89
+ expect(isDateDisabled(new Date(2024, 2, 29), rules)).toBe(true);
90
+ });
91
+
92
+ it('returns true for end of range (inclusive)', () => {
93
+ expect(isDateDisabled(new Date(2024, 3, 3), rules)).toBe(true);
94
+ });
95
+
96
+ it('returns true for date within range', () => {
97
+ expect(isDateDisabled(new Date(2024, 2, 31), rules)).toBe(true);
98
+ });
99
+
100
+ it('returns false for date before range', () => {
101
+ expect(isDateDisabled(new Date(2024, 2, 28), rules)).toBe(false);
102
+ });
103
+
104
+ it('returns false for date after range', () => {
105
+ expect(isDateDisabled(new Date(2024, 3, 4), rules)).toBe(false);
106
+ });
107
+
108
+ it('handles second range', () => {
109
+ expect(isDateDisabled(new Date(2024, 11, 25), rules)).toBe(true);
110
+ expect(isDateDisabled(new Date(2024, 11, 27), rules)).toBe(false);
111
+ });
112
+
113
+ it('correctly checks a date with non-midnight time against a range', () => {
114
+ const dateWithTime = new Date(2024, 2, 31, 14, 30, 0);
115
+ expect(isDateDisabled(dateWithTime, rules)).toBe(true);
116
+ });
117
+
118
+ it('correctly excludes a date with non-midnight time outside a range', () => {
119
+ const dateWithTime = new Date(2024, 2, 28, 23, 59, 59);
120
+ expect(isDateDisabled(dateWithTime, rules)).toBe(false);
121
+ });
122
+ });
123
+
124
+ describe('combined rules (additive)', () => {
125
+ const rules: DisabledRules = {
126
+ weekdays: ['sat', 'sun'],
127
+ dates: [new Date(2024, 6, 15)], // Monday
128
+ ranges: [{ start: new Date(2024, 6, 22), end: new Date(2024, 6, 24) }],
129
+ reason: 'Multiple rules',
130
+ };
131
+
132
+ it('disables by weekday', () => {
133
+ // 2024-07-13 is Saturday
134
+ expect(isDateDisabled(new Date(2024, 6, 13), rules)).toBe(true);
135
+ });
136
+
137
+ it('disables by specific date', () => {
138
+ // 2024-07-15 is Monday but explicitly disabled
139
+ expect(isDateDisabled(new Date(2024, 6, 15), rules)).toBe(true);
140
+ });
141
+
142
+ it('disables by range', () => {
143
+ // 2024-07-23 is Tuesday but in range
144
+ expect(isDateDisabled(new Date(2024, 6, 23), rules)).toBe(true);
145
+ });
146
+
147
+ it('allows date not matching any rule', () => {
148
+ // 2024-07-16 is Tuesday, not in dates or ranges
149
+ expect(isDateDisabled(new Date(2024, 6, 16), rules)).toBe(false);
150
+ });
151
+ });
152
+
153
+ describe('edge cases', () => {
154
+ it('handles empty weekdays array', () => {
155
+ const rules: DisabledRules = { weekdays: [], reason: 'Empty' };
156
+ expect(isDateDisabled(new Date(2024, 6, 13), rules)).toBe(false);
157
+ });
158
+
159
+ it('handles empty dates array', () => {
160
+ const rules: DisabledRules = { dates: [], reason: 'Empty' };
161
+ expect(isDateDisabled(new Date(2024, 6, 13), rules)).toBe(false);
162
+ });
163
+
164
+ it('handles empty ranges array', () => {
165
+ const rules: DisabledRules = { ranges: [], reason: 'Empty' };
166
+ expect(isDateDisabled(new Date(2024, 6, 13), rules)).toBe(false);
167
+ });
168
+ });
169
+ });
@@ -0,0 +1,59 @@
1
+ import type { DisabledRules, WeekDayType } from '../../Calendar.types';
2
+
3
+ const DAY_INDEX_TO_WEEKDAY: Record<number, WeekDayType> = {
4
+ 0: 'sun',
5
+ 1: 'mon',
6
+ 2: 'tue',
7
+ 3: 'wed',
8
+ 4: 'thu',
9
+ 5: 'fri',
10
+ 6: 'sat',
11
+ };
12
+
13
+ export function isDateDisabled(date: Date, disabledRules?: DisabledRules): boolean {
14
+ if (!disabledRules) return false;
15
+
16
+ if (disabledRules.weekdays?.length) {
17
+ const weekday = DAY_INDEX_TO_WEEKDAY[date.getDay()];
18
+ if (disabledRules.weekdays.includes(weekday)) return true;
19
+ }
20
+
21
+ if (disabledRules.dates?.length) {
22
+ const year = date.getFullYear();
23
+ const month = date.getMonth();
24
+ const day = date.getDate();
25
+ if (
26
+ disabledRules.dates.some(
27
+ (disabledDate) =>
28
+ disabledDate.getFullYear() === year &&
29
+ disabledDate.getMonth() === month &&
30
+ disabledDate.getDate() === day,
31
+ )
32
+ ) {
33
+ return true;
34
+ }
35
+ }
36
+
37
+ if (disabledRules.ranges?.length) {
38
+ const dateStart = date.getTime();
39
+ if (
40
+ disabledRules.ranges.some((range) => {
41
+ const rangeStart = new Date(
42
+ range.start.getFullYear(),
43
+ range.start.getMonth(),
44
+ range.start.getDate(),
45
+ ).getTime();
46
+ const rangeEnd = new Date(
47
+ range.end.getFullYear(),
48
+ range.end.getMonth(),
49
+ range.end.getDate(),
50
+ ).getTime();
51
+ return dateStart >= rangeStart && dateStart <= rangeEnd;
52
+ })
53
+ ) {
54
+ return true;
55
+ }
56
+ }
57
+
58
+ return false;
59
+ }
@@ -0,0 +1,118 @@
1
+ import { Meta } from '@storybook/addon-docs/blocks';
2
+
3
+ <Meta title="Forms/Calendar/Accessibility" />
4
+
5
+ # Accessibility
6
+
7
+ Calendar is a fully keyboard-accessible date picker grid. All dates — including disabled ones — are reachable via keyboard so that screen reader users can discover which dates are unavailable and why.
8
+
9
+ ## Keyboard Support
10
+
11
+ <table>
12
+ <thead>
13
+ <tr>
14
+ <th>Key</th>
15
+ <th>Action</th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <tr>
20
+ <td>
21
+ <code>ArrowLeft</code>
22
+ </td>
23
+ <td>Move focus to previous day / month / year</td>
24
+ </tr>
25
+ <tr>
26
+ <td>
27
+ <code>ArrowRight</code>
28
+ </td>
29
+ <td>Move focus to next day / month / year</td>
30
+ </tr>
31
+ <tr>
32
+ <td>
33
+ <code>ArrowUp</code>
34
+ </td>
35
+ <td>Move focus up by one week (7 days) / 4 months / 4 years</td>
36
+ </tr>
37
+ <tr>
38
+ <td>
39
+ <code>ArrowDown</code>
40
+ </td>
41
+ <td>Move focus down by one week (7 days) / 4 months / 4 years</td>
42
+ </tr>
43
+ <tr>
44
+ <td>
45
+ <code>Enter</code> / <code>Space</code>
46
+ </td>
47
+ <td>Select the focused date (if enabled)</td>
48
+ </tr>
49
+ </tbody>
50
+ </table>
51
+
52
+ <br /> Navigation **does not skip** disabled dates. Users can arrow through every date in the grid
53
+ regardless of its enabled state.
54
+
55
+ ## Screen Reader Announcements
56
+
57
+ Each date cell is a `<button>` with an `aria-label` in a human-readable long format (e.g. "6 July 2024") constructed via `Intl.DateTimeFormat` for full locale support.
58
+
59
+ ### Active (Selected) Date
60
+
61
+ The currently selected date includes "selected day" in its aria-label:
62
+
63
+ > "6 July 2024, selected day"
64
+
65
+ ### Disabled Dates (via `disabledRules`)
66
+
67
+ Dates disabled via `disabledRules` remain focusable and keyboard-navigable. They are announced with additional context:
68
+
69
+ - `aria-disabled="true"` signals the date is not selectable
70
+ - The aria-label appends "not available" (e.g. "6 July 2024, not available")
71
+ - `aria-describedby` links to the InlinePrompt element containing the reason text
72
+
73
+ This means a screen reader will announce something like:
74
+
75
+ > "6 July 2024, not available — We are closed on weekends. button, dimmed."
76
+
77
+ ### Disabled + Selected
78
+
79
+ If the focused date is both active and disabled:
80
+
81
+ > "6 July 2024, selected day, not available"
82
+
83
+ ### Out-of-Range Dates (via `min`/`max`)
84
+
85
+ Dates outside `min`/`max` boundaries use `aria-disabled="true"` (not the native HTML `disabled` attribute). They are rendered as interactive buttons in the grid: they can be clicked and the `aria-label` appends "not available". Arrow key navigation clamps at the boundary, so keyboard users cannot navigate into out-of-range cells — but they remain visible and clickable for pointer users.
86
+
87
+ This distinction is intentional: `min`/`max` defines a hard boundary (the calendar simply doesn't extend beyond it), while `disabledRules` marks dates that exist but are unavailable (users should be able to discover them and understand why).
88
+
89
+ ## InlinePrompt Behaviour
90
+
91
+ An `InlinePrompt` renders below the day grid when the current month contains disabled dates. It displays the `disabledRules.reason` text.
92
+
93
+ ### When It Appears
94
+
95
+ The prompt is visible when **all** of the following are true:
96
+
97
+ 1. The Calendar is in day view
98
+ 2. `disabledRules.reason` is provided
99
+ 3. The currently displayed month contains at least one disabled date
100
+
101
+ ### How It's Announced
102
+
103
+ The prompt is linked to disabled date cells via `aria-describedby`. This means the reason text is read as a description when a disabled cell receives focus — screen readers announce it after the label and role.
104
+
105
+ The prompt element has an `id` that matches the `aria-describedby` on each disabled cell. It is **not** a live region (`role="alert"` or `role="status"`) because:
106
+
107
+ - It does not change dynamically while focus is on a disabled cell
108
+ - Announcing it on every arrow key press would be disruptive
109
+ - The `aria-describedby` relationship already ensures it's read on focus
110
+
111
+ ### Sentiment
112
+
113
+ The prompt's visual sentiment changes based on the currently focused date:
114
+
115
+ - **Negative** (red) — when the focused date is disabled
116
+ - **Neutral** — when the focused date is enabled
117
+
118
+ This is a visual-only change and does not affect screen reader output.
@@ -1,22 +1,47 @@
1
1
  import { useState } from 'react';
2
2
  import { StoryObj } from '@storybook/react-webpack5';
3
- import { userEvent, within } from 'storybook/test';
3
+ import { fn, userEvent, within } from 'storybook/test';
4
4
  import {
5
5
  createSandboxStory,
6
6
  globalScope,
7
7
  } from '../../../.storybook/components/sandbox/SandboxEditor';
8
+ import { storySourceWithoutNoise } from '../../../.storybook/helpers';
8
9
  import Calendar, { type CalendarProps } from '../Calendar';
9
10
  import Modal from '../../Modal';
10
11
  import Button from '../../Button';
12
+ import { action } from 'storybook/actions';
11
13
 
12
- /** Inline calendar for selecting a single date, with optional min/max bounds. */
13
14
  export default {
14
15
  component: Calendar,
15
16
  title: 'Forms/Calendar',
17
+ args: {
18
+ value: undefined,
19
+ min: undefined,
20
+ max: undefined,
21
+ monthFormat: undefined,
22
+ placeholder: undefined,
23
+ disabledRules: undefined,
24
+ onChange: fn(),
25
+ onDateFocus: fn(),
26
+ },
16
27
  argTypes: {
17
28
  monthFormat: { control: 'select', options: ['long', 'short'] },
18
29
  min: { control: 'date' },
19
30
  max: { control: 'date' },
31
+ disabledRules: {
32
+ control: false,
33
+ table: {
34
+ type: {
35
+ summary: 'DisabledRules',
36
+ detail: `{
37
+ weekdays?: ('mon'|'tue'|'wed'|'thu'|'fri'|'sat'|'sun')[]
38
+ dates?: Date[]
39
+ ranges?: { start: Date; end: Date }[]
40
+ reason: string // required — shown in prompt, linked via aria-describedby
41
+ }`,
42
+ },
43
+ },
44
+ },
20
45
  },
21
46
  };
22
47
 
@@ -30,12 +55,17 @@ thePast.setUTCDate(epoch.getUTCDate() - 10);
30
55
 
31
56
  export const Sandbox = createSandboxStory({
32
57
  code: `const App = () => {
33
- const [value, setValue] = React.useState(new Date('2024-06-15'));
58
+ const [value, setValue] = React.useState(new Date(2024, 5, 18));
34
59
 
35
60
  return (
36
61
  <Calendar
37
62
  monthFormat="long"
38
63
  value={value}
64
+ disabledRules={{
65
+ weekdays: ['sat', 'sun'],
66
+ dates: [new Date(2024, 5, 19)],
67
+ reason: 'Weekends and holidays are unavailable.',
68
+ }}
39
69
  onChange={(date) => setValue(date)}
40
70
  />
41
71
  );
@@ -52,7 +82,13 @@ export const Basic: Story = {
52
82
  min={args.min ? new Date(args.min) : thePast}
53
83
  max={args.max ? new Date(args.max) : theFuture}
54
84
  value={value}
55
- onChange={(v) => setValue(v)}
85
+ onDateFocus={(date, options) => {
86
+ action('onDateFocus')(date, options);
87
+ }}
88
+ onChange={(date) => {
89
+ action('onChange')(date);
90
+ setValue(date);
91
+ }}
56
92
  />
57
93
  );
58
94
  },
@@ -102,3 +138,101 @@ export const InsideModal: Story = {
102
138
  await userEvent.click(canvas.getByRole('button', { name: 'Open modal' }));
103
139
  },
104
140
  };
141
+
142
+ /**
143
+ * Use `disabledRules` to disable specific weekdays, individual dates, or date ranges.
144
+ * Disabled dates remain focusable and keyboard-navigable — clicking or focusing one
145
+ * fires `onDateFocus` with `isEnabled: false` and shows a negative inline prompt with
146
+ * the `reason` text. `min`/`max` out-of-range dates show a built-in boundary prompt
147
+ * (e.g. "Please select a date between 4 December 2024 and 18 January 2025.").
148
+ *
149
+ * The `reason` field is **required for accessibility**: it renders as an InlinePrompt
150
+ * below the grid and is linked to every disabled cell via `aria-describedby`, so screen
151
+ * reader users understand why a date is unavailable. For per-date reason customisation
152
+ * see [DisabledDatesWithDynamicReason](#disabled-dates-with-dynamic-reason).
153
+ */
154
+ export const DisabledDates: Story = storySourceWithoutNoise({
155
+ render: function Render() {
156
+ const [value, setValue] = useState<Date | null>(new Date(2024, 11, 13));
157
+
158
+ return (
159
+ <Calendar
160
+ value={value}
161
+ min={new Date(2024, 11, 4)}
162
+ max={new Date(2025, 0, 18)}
163
+ disabledRules={{
164
+ weekdays: ['sat', 'sun'],
165
+ dates: [new Date(2024, 11, 10), new Date(2025, 0, 15)],
166
+ ranges: [{ start: new Date(2024, 11, 23), end: new Date(2024, 11, 27) }],
167
+ reason: 'Some dates are unavailable for this service.',
168
+ }}
169
+ onDateFocus={(date, { isEnabled }) => {
170
+ action('onDateFocus')(date, { isEnabled });
171
+ }}
172
+ onChange={(date) => {
173
+ action('onChange')(date);
174
+ setValue(date);
175
+ }}
176
+ />
177
+ );
178
+ },
179
+ });
180
+
181
+ /**
182
+ * When different disabled dates warrant different explanations, drive the `reason`
183
+ * dynamically from `onDateFocus`. The `isEnabled` flag tells you whether the focused
184
+ * date is selectable; from there you can look up the specific reason and update state.
185
+ *
186
+ * `min`/`max` out-of-range dates are handled automatically — the component shows a
187
+ * built-in prompt with the boundary dates, so `determineReason` only needs to cover
188
+ * rule-disabled dates.
189
+ */
190
+ export const DisabledDatesWithDynamicReason: Story = storySourceWithoutNoise({
191
+ render: function Render() {
192
+ const DEFAULT_REASON = 'Some dates are unavailable for this service.';
193
+ const min = new Date(2024, 11, 4);
194
+ const max = new Date(2025, 0, 18);
195
+ const maintenanceDays = [new Date(2024, 11, 10), new Date(2025, 0, 15)];
196
+ const [value, setValue] = useState<Date | null>(new Date(2024, 11, 13));
197
+ const [reason, setReason] = useState(DEFAULT_REASON);
198
+
199
+ function determineReason(date: Date, isEnabled: boolean): string {
200
+ if (isEnabled) return DEFAULT_REASON;
201
+ if (
202
+ maintenanceDays.some(
203
+ (maintenanceDay) => maintenanceDay.toDateString() === date.toDateString(),
204
+ )
205
+ ) {
206
+ return 'This date is a maintenance day.';
207
+ }
208
+ if (date.getDay() === 0 || date.getDay() === 6) {
209
+ return 'We do not operate on weekends.';
210
+ }
211
+ return 'This date is unavailable.';
212
+ }
213
+
214
+ return (
215
+ <Calendar
216
+ value={value}
217
+ min={min}
218
+ max={max}
219
+ disabledRules={{
220
+ weekdays: ['sat', 'sun'],
221
+ dates: maintenanceDays,
222
+ ranges: [{ start: new Date(2024, 11, 23), end: new Date(2024, 11, 27) }],
223
+ reason,
224
+ }}
225
+ onDateFocus={(date, { isEnabled }) => {
226
+ action('onDateFocus')(date, { isEnabled });
227
+ if (date) {
228
+ setReason(determineReason(date, isEnabled));
229
+ }
230
+ }}
231
+ onChange={(date) => {
232
+ action('onChange')(date);
233
+ setValue(date);
234
+ }}
235
+ />
236
+ );
237
+ },
238
+ });
@@ -0,0 +1,114 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { expect, waitFor, within, userEvent } from 'storybook/test';
3
+
4
+ import Calendar from '../Calendar';
5
+ import type { DisabledRules } from '../Calendar.types';
6
+
7
+ export default {
8
+ component: Calendar,
9
+ title: 'Forms/Calendar/Tests',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof Calendar>;
12
+
13
+ type Story = StoryObj<typeof Calendar>;
14
+
15
+ // min: March 2024, max: October 2024
16
+ const min = new Date(2024, 2, 1);
17
+ const max = new Date(2024, 9, 31);
18
+
19
+ /**
20
+ * Year view: years within min/max are enabled, years outside are disabled (aria-disabled),
21
+ * and both navigation arrows are disabled because min and max fall within the same 2020–2039 block.
22
+ */
23
+ export const YearViewBoundaries: Story = {
24
+ render: () => <Calendar value={new Date(2024, 5, 15)} min={min} max={max} />,
25
+ play: async ({ canvasElement }) => {
26
+ const canvas = within(canvasElement);
27
+
28
+ await userEvent.click(canvas.getByRole('button', { name: /year view/iu }));
29
+
30
+ // Selected year (within range) is enabled
31
+ await expect(
32
+ canvas.getByRole('button', { name: /2024.*selected year/iu }),
33
+ ).not.toHaveAttribute('aria-disabled');
34
+
35
+ // Adjacent years outside range are disabled
36
+ await expect(
37
+ canvas.getByRole('button', { name: /^2023.*not available/iu }),
38
+ ).toHaveAttribute('aria-disabled', 'true');
39
+ await expect(
40
+ canvas.getByRole('button', { name: /^2025.*not available/iu }),
41
+ ).toHaveAttribute('aria-disabled', 'true');
42
+
43
+ // Both nav arrows disabled — min and max are both in the 2020–2039 block
44
+ await expect(canvas.getByRole('button', { name: /previous 20 years/iu })).toBeDisabled();
45
+ await expect(canvas.getByRole('button', { name: /next 20 years/iu })).toBeDisabled();
46
+ },
47
+ };
48
+
49
+ /**
50
+ * Month view: months within min/max are enabled, months outside are disabled (aria-disabled),
51
+ * and both navigation arrows are disabled because min and max are both in 2024.
52
+ */
53
+ export const MonthViewBoundaries: Story = {
54
+ render: () => <Calendar value={new Date(2024, 5, 15)} min={min} max={max} />,
55
+ play: async ({ canvasElement }) => {
56
+ const canvas = within(canvasElement);
57
+
58
+ // Navigate: year view → click 2024 → month view
59
+ await userEvent.click(canvas.getByRole('button', { name: /year view/iu }));
60
+ await userEvent.click(canvas.getByRole('button', { name: /2024.*selected year/iu }));
61
+
62
+ // Selected month (within range) is enabled
63
+ await expect(
64
+ canvas.getByRole('button', { name: /^Jun.*selected month/iu }),
65
+ ).not.toHaveAttribute('aria-disabled');
66
+
67
+ // Boundary months (min=Mar, max=Oct) are enabled
68
+ await expect(
69
+ canvas.getByRole('button', { name: /^Mar(?!.*not available)/iu }),
70
+ ).not.toHaveAttribute('aria-disabled');
71
+ await expect(
72
+ canvas.getByRole('button', { name: /^Oct(?!.*not available)/iu }),
73
+ ).not.toHaveAttribute('aria-disabled');
74
+
75
+ // Months outside range are disabled
76
+ await expect(
77
+ canvas.getByRole('button', { name: /^Feb.*not available/iu }),
78
+ ).toHaveAttribute('aria-disabled', 'true');
79
+ await expect(
80
+ canvas.getByRole('button', { name: /^Nov.*not available/iu }),
81
+ ).toHaveAttribute('aria-disabled', 'true');
82
+
83
+ // Both nav arrows disabled — min and max are both in 2024
84
+ await expect(canvas.getByRole('button', { name: /previous year/iu })).toBeDisabled();
85
+ await expect(canvas.getByRole('button', { name: /next year/iu })).toBeDisabled();
86
+ },
87
+ };
88
+
89
+ const disabledRules: DisabledRules = {
90
+ weekdays: ['sat', 'sun'],
91
+ reason: 'We are closed on weekends.',
92
+ };
93
+
94
+ /**
95
+ * When a disabled cell receives direct DOM focus (e.g. screen reader virtual cursor),
96
+ * the inline prompt updates to negative sentiment showing the disabled reason.
97
+ */
98
+ export const DisabledDateFocusUpdatesPrompt: Story = {
99
+ render: () => <Calendar value={new Date(2024, 6, 5)} disabledRules={disabledRules} />,
100
+ play: async ({ canvasElement }) => {
101
+ const canvas = within(canvasElement);
102
+
103
+ // Initially prompt is neutral (focused date is enabled)
104
+ const prompt = canvasElement.querySelector('.wds-inline-prompt')!;
105
+ await expect(prompt).toHaveClass('wds-prompt--neutral');
106
+
107
+ // Simulate screen reader focus on a disabled Saturday (matches both "6 July 2024" and "July 6, 2024")
108
+ const saturday = canvas.getByLabelText(/(?:6 July|July 6).*2024/u);
109
+ saturday.focus();
110
+
111
+ // Prompt should switch to negative after React re-render
112
+ await waitFor(() => expect(prompt).toHaveClass('wds-prompt--negative'));
113
+ },
114
+ };
@@ -1,2 +1,9 @@
1
1
  export { default } from './Calendar';
2
2
  export type { CalendarProps } from './Calendar';
3
+ export type {
4
+ DateChangeMeta,
5
+ DisabledRules,
6
+ DisabledDateRange,
7
+ WeekDayType,
8
+ OnDateSelectParams,
9
+ } from './Calendar.types';