box-ui-elements 15.0.0-beta.7 → 15.0.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 (508) hide show
  1. package/CONTRIBUTING.md +3 -1
  2. package/dist/explorer.css +1 -1
  3. package/dist/explorer.js +58 -26
  4. package/dist/openwith.css +1 -1
  5. package/dist/openwith.js +10 -17
  6. package/dist/picker.css +1 -1
  7. package/dist/picker.js +12 -19
  8. package/dist/preview.css +1 -1
  9. package/dist/preview.js +56 -24
  10. package/dist/sharing.css +1 -1
  11. package/dist/sharing.js +54 -22
  12. package/dist/sidebar.css +1 -1
  13. package/dist/sidebar.js +56 -24
  14. package/dist/uploader.css +1 -1
  15. package/dist/uploader.js +12 -19
  16. package/es/api/uploads/UploadsReachability.js.flow +2 -2
  17. package/es/api/uploads/UploadsReachability.js.map +1 -1
  18. package/es/common/messages.js +4 -0
  19. package/es/common/messages.js.flow +5 -0
  20. package/es/common/messages.js.map +1 -1
  21. package/es/common/types/core.js.flow +2 -0
  22. package/es/common/types/core.js.map +1 -1
  23. package/es/components/avatar/UnknownUserAvatar.js +6 -9
  24. package/es/components/avatar/UnknownUserAvatar.js.map +1 -1
  25. package/es/components/close-button/CloseButton.js +24 -0
  26. package/es/components/close-button/CloseButton.js.flow +26 -0
  27. package/es/components/close-button/CloseButton.js.map +1 -0
  28. package/es/components/close-button/CloseButton.scss +10 -0
  29. package/es/components/close-button/CloseButton.stories.js +14 -0
  30. package/es/components/close-button/CloseButton.stories.js.map +1 -0
  31. package/es/components/close-button/index.js +2 -0
  32. package/es/components/close-button/index.js.flow +2 -0
  33. package/es/components/close-button/index.js.map +1 -0
  34. package/es/components/date-picker/AccessiblePikaday.js +113 -0
  35. package/es/components/date-picker/AccessiblePikaday.js.map +1 -0
  36. package/es/components/date-picker/DatePicker.js +426 -106
  37. package/es/components/date-picker/DatePicker.js.map +1 -1
  38. package/es/components/date-picker/DatePicker.scss +32 -22
  39. package/es/components/date-picker/DatePicker.stories.js +10 -0
  40. package/es/components/date-picker/DatePicker.stories.js.map +1 -1
  41. package/es/components/date-picker/_pikaday.scss +8 -2
  42. package/es/components/flyout/Flyout.js +13 -3
  43. package/es/components/flyout/Flyout.js.flow +14 -3
  44. package/es/components/flyout/Flyout.js.map +1 -1
  45. package/es/components/flyout/Flyout.scss +40 -0
  46. package/es/components/flyout/FlyoutContext.js +6 -0
  47. package/es/components/flyout/FlyoutContext.js.flow +9 -0
  48. package/es/components/flyout/FlyoutContext.js.map +1 -0
  49. package/es/components/flyout/OverlayHeader.js +33 -0
  50. package/es/components/flyout/OverlayHeader.js.map +1 -0
  51. package/es/components/flyout/OverlayHeader.scss +9 -0
  52. package/es/components/flyout/_variables.scss +1 -0
  53. package/es/components/flyout/index.js +2 -0
  54. package/es/components/flyout/index.js.flow +2 -0
  55. package/es/components/flyout/index.js.map +1 -1
  56. package/es/components/image-tooltip/ImageTooltip.js +1 -2
  57. package/es/components/image-tooltip/ImageTooltip.js.map +1 -1
  58. package/es/components/media-query/constants.js +26 -0
  59. package/es/components/media-query/constants.js.flow +32 -0
  60. package/es/components/media-query/constants.js.map +1 -0
  61. package/es/components/media-query/index.js +3 -0
  62. package/es/components/media-query/index.js.flow +4 -0
  63. package/es/components/media-query/index.js.map +1 -0
  64. package/es/components/media-query/stories/MediaQuery.stories.js +37 -0
  65. package/es/components/media-query/stories/MediaQuery.stories.js.flow +80 -0
  66. package/es/components/media-query/stories/MediaQuery.stories.js.map +1 -0
  67. package/es/components/media-query/types.js +2 -0
  68. package/es/components/media-query/types.js.flow +29 -0
  69. package/es/components/media-query/types.js.map +1 -0
  70. package/es/components/media-query/useMediaQuery.js +91 -0
  71. package/es/components/media-query/useMediaQuery.js.flow +97 -0
  72. package/es/components/media-query/useMediaQuery.js.map +1 -0
  73. package/es/components/media-query/withMediaQuery.js +21 -0
  74. package/es/components/media-query/withMediaQuery.js.flow +23 -0
  75. package/es/components/media-query/withMediaQuery.js.map +1 -0
  76. package/es/components/modal/Modal.scss +27 -0
  77. package/es/components/preview/previewIcons.js +4 -0
  78. package/es/components/preview/previewIcons.js.map +1 -1
  79. package/es/components/search-form/SearchForm.scss +0 -5
  80. package/es/components/selector-dropdown/SelectorDropdown.js +5 -3
  81. package/es/components/selector-dropdown/SelectorDropdown.js.flow +3 -3
  82. package/es/components/selector-dropdown/SelectorDropdown.js.map +1 -1
  83. package/es/components/tab-view/Tabs.scss +0 -4
  84. package/es/components/tooltip/Tooltip.js +21 -4
  85. package/es/components/tooltip/Tooltip.js.map +1 -1
  86. package/es/constants.js +1 -0
  87. package/es/constants.js.flow +1 -0
  88. package/es/constants.js.map +1 -1
  89. package/es/elements/content-open-with/IconFileMap.js +0 -2
  90. package/es/elements/content-open-with/IconFileMap.js.flow +0 -2
  91. package/es/elements/content-open-with/IconFileMap.js.map +1 -1
  92. package/es/elements/content-sidebar/Sidebar.js +2 -1
  93. package/es/elements/content-sidebar/Sidebar.js.flow +1 -1
  94. package/es/elements/content-sidebar/Sidebar.js.map +1 -1
  95. package/es/elements/content-sidebar/activity-feed/common/delete-confirmation/DeleteConfirmation.scss +3 -3
  96. package/es/elements/content-sidebar/activity-feed/task-form/TaskForm.js +14 -4
  97. package/es/elements/content-sidebar/activity-feed/task-form/TaskForm.js.flow +18 -5
  98. package/es/elements/content-sidebar/activity-feed/task-form/TaskForm.js.map +1 -1
  99. package/es/elements/content-sidebar/versions/StaticVersionSidebar.js +78 -0
  100. package/es/elements/content-sidebar/versions/StaticVersionSidebar.js.flow +97 -0
  101. package/es/elements/content-sidebar/versions/StaticVersionSidebar.js.map +1 -0
  102. package/es/elements/content-sidebar/versions/StaticVersionsSidebar.scss +67 -0
  103. package/es/elements/content-sidebar/versions/VersionsSidebar.js +12 -4
  104. package/es/elements/content-sidebar/versions/VersionsSidebar.js.flow +16 -3
  105. package/es/elements/content-sidebar/versions/VersionsSidebar.js.map +1 -1
  106. package/es/elements/content-sidebar/versions/VersionsSidebar.scss +5 -0
  107. package/es/elements/content-sidebar/versions/VersionsSidebarContainer.js +42 -10
  108. package/es/elements/content-sidebar/versions/VersionsSidebarContainer.js.flow +42 -7
  109. package/es/elements/content-sidebar/versions/VersionsSidebarContainer.js.map +1 -1
  110. package/es/elements/content-sidebar/versions/flowTypes.js.flow +1 -0
  111. package/es/elements/content-sidebar/versions/messages.js +20 -0
  112. package/es/elements/content-sidebar/versions/messages.js.flow +28 -0
  113. package/es/elements/content-sidebar/versions/messages.js.map +1 -1
  114. package/es/features/classification/constants.js +2 -1
  115. package/es/features/classification/constants.js.flow +2 -0
  116. package/es/features/classification/constants.js.map +1 -1
  117. package/es/features/classification/flowTypes.js +1 -0
  118. package/es/features/classification/flowTypes.js.flow +7 -1
  119. package/es/features/classification/flowTypes.js.map +1 -1
  120. package/es/features/classification/security-controls/SecurityControls.js +3 -4
  121. package/es/features/classification/security-controls/SecurityControls.js.flow +3 -4
  122. package/es/features/classification/security-controls/SecurityControls.js.map +1 -1
  123. package/es/features/classification/security-controls/SecurityControlsItem.js +1 -1
  124. package/es/features/classification/security-controls/SecurityControlsItem.js.flow +20 -17
  125. package/es/features/classification/security-controls/SecurityControlsItem.js.map +1 -1
  126. package/es/features/classification/security-controls/SecurityControlsItem.scss +4 -0
  127. package/es/features/classification/security-controls/SecurityControlsModal.js +2 -2
  128. package/es/features/classification/security-controls/SecurityControlsModal.js.flow +2 -2
  129. package/es/features/classification/security-controls/SecurityControlsModal.js.map +1 -1
  130. package/es/features/classification/security-controls/messages.js +4 -0
  131. package/es/features/classification/security-controls/messages.js.flow +5 -0
  132. package/es/features/classification/security-controls/messages.js.map +1 -1
  133. package/es/features/classification/security-controls/utils.js +56 -35
  134. package/es/features/classification/security-controls/utils.js.flow +51 -27
  135. package/es/features/classification/security-controls/utils.js.map +1 -1
  136. package/es/features/collapsible-sidebar/CollapsibleSidebar.js +9 -3
  137. package/es/features/collapsible-sidebar/CollapsibleSidebar.js.flow +13 -5
  138. package/es/features/collapsible-sidebar/CollapsibleSidebar.js.map +1 -1
  139. package/es/features/collapsible-sidebar/CollapsibleSidebar.scss +35 -3
  140. package/es/features/content-explorer/content-explorer/ContentExplorer.scss +1 -1
  141. package/es/features/content-explorer/item-list/ItemList.js +1 -0
  142. package/es/features/content-explorer/item-list/ItemList.js.flow +1 -0
  143. package/es/features/content-explorer/item-list/ItemList.js.map +1 -1
  144. package/es/features/content-explorer/item-list/ItemListName.js +13 -2
  145. package/es/features/content-explorer/item-list/ItemListName.js.flow +3 -2
  146. package/es/features/content-explorer/item-list/ItemListName.js.map +1 -1
  147. package/es/features/header-flyout/HeaderFlyout.js +8 -10
  148. package/es/features/header-flyout/HeaderFlyout.js.flow +4 -8
  149. package/es/features/header-flyout/HeaderFlyout.js.map +1 -1
  150. package/es/features/header-flyout/styles/HeaderFlyout.scss +54 -15
  151. package/es/features/header-flyout/styles/_variables.scss +4 -0
  152. package/es/features/message-center/components/message-center-modal/MessageCenterModal.js +1 -0
  153. package/es/features/message-center/components/message-center-modal/MessageCenterModal.js.flow +1 -0
  154. package/es/features/message-center/components/message-center-modal/MessageCenterModal.js.map +1 -1
  155. package/es/features/presence/PresenceCollaborator.js +90 -0
  156. package/es/features/presence/PresenceCollaborator.js.flow +81 -0
  157. package/es/features/presence/PresenceCollaborator.js.map +1 -0
  158. package/es/features/presence/PresenceCollaborator.scss +28 -0
  159. package/es/features/presence/PresenceCollaboratorsList.js +9 -57
  160. package/es/features/presence/PresenceCollaboratorsList.js.flow +7 -58
  161. package/es/features/presence/PresenceCollaboratorsList.js.map +1 -1
  162. package/es/features/presence/PresenceCollaboratorsList.scss +8 -35
  163. package/es/features/quick-search/QuickSearch.js +4 -2
  164. package/es/features/quick-search/QuickSearch.js.flow +13 -1
  165. package/es/features/quick-search/QuickSearch.js.map +1 -1
  166. package/es/features/unified-share-modal/SharedLinkSection.js +9 -20
  167. package/es/features/unified-share-modal/SharedLinkSection.js.flow +6 -27
  168. package/es/features/unified-share-modal/SharedLinkSection.js.map +1 -1
  169. package/es/features/unified-share-modal/UnifiedShareForm.js +95 -53
  170. package/es/features/unified-share-modal/UnifiedShareForm.js.flow +70 -14
  171. package/es/features/unified-share-modal/UnifiedShareForm.js.map +1 -1
  172. package/es/features/unified-share-modal/UnifiedShareModal.scss +3 -0
  173. package/es/features/unified-share-modal/flowTypes.js.flow +6 -0
  174. package/es/features/unified-share-modal/flowTypes.js.map +1 -1
  175. package/es/features/unified-share-modal/messages.js +8 -0
  176. package/es/features/unified-share-modal/messages.js.flow +10 -0
  177. package/es/features/unified-share-modal/messages.js.map +1 -1
  178. package/es/features/unified-share-modal/utils/mergeContacts.js +13 -10
  179. package/es/features/unified-share-modal/utils/mergeContacts.js.flow +4 -2
  180. package/es/features/unified-share-modal/utils/mergeContacts.js.map +1 -1
  181. package/es/icon/content/FileXbd32.js +39 -0
  182. package/es/icon/content/FileXbd32.js.flow +38 -0
  183. package/es/icon/content/FileXbd32.js.map +1 -0
  184. package/es/icon/content/FileXbd32.stories.js +13 -0
  185. package/es/icon/content/FileXbd32.stories.js.map +1 -0
  186. package/es/icon/content/FileXdw32.js +39 -0
  187. package/es/icon/content/FileXdw32.js.flow +38 -0
  188. package/es/icon/content/FileXdw32.js.map +1 -0
  189. package/es/icon/content/FileXdw32.stories.js +13 -0
  190. package/es/icon/content/FileXdw32.stories.js.map +1 -0
  191. package/es/icon/content/RetentionPolicyModifiable32.js +36 -0
  192. package/es/icon/content/RetentionPolicyModifiable32.js.flow +31 -0
  193. package/es/icon/content/RetentionPolicyModifiable32.js.map +1 -0
  194. package/es/icon/content/RetentionPolicyModifiable32.stories.js +13 -0
  195. package/es/icon/content/RetentionPolicyModifiable32.stories.js.map +1 -0
  196. package/es/icon/content/RetentionPolicyNonModifiable32.js +36 -0
  197. package/es/icon/content/RetentionPolicyNonModifiable32.js.flow +31 -0
  198. package/es/icon/content/RetentionPolicyNonModifiable32.js.map +1 -0
  199. package/es/icon/content/RetentionPolicyNonModifiable32.stories.js +13 -0
  200. package/es/icon/content/RetentionPolicyNonModifiable32.stories.js.map +1 -0
  201. package/es/icons/avatars/UnknownUserAvatar.js +10 -34
  202. package/es/icons/avatars/UnknownUserAvatar.js.map +1 -1
  203. package/es/icons/file-icon/FileIcon.js +8 -2
  204. package/es/icons/file-icon/FileIcon.js.flow +2 -2
  205. package/es/icons/file-icon/FileIcon.js.map +1 -1
  206. package/es/icons/general/IconSearch.js +1 -1
  207. package/es/icons/general/IconSearch.js.flow +1 -1
  208. package/es/icons/general/IconSearch.js.map +1 -1
  209. package/es/icons/general/IconSearchJuicy.js +30 -0
  210. package/es/icons/general/IconSearchJuicy.js.flow +26 -0
  211. package/es/icons/general/IconSearchJuicy.js.map +1 -0
  212. package/es/icons/google-docs/IconGoogle.js +89 -0
  213. package/es/icons/google-docs/IconGoogle.js.flow +57 -0
  214. package/es/icons/google-docs/IconGoogle.js.map +1 -0
  215. package/es/icons/item-icon/ItemIcon.js +4 -0
  216. package/es/icons/item-icon/ItemIcon.js.map +1 -1
  217. package/es/icons/microsoft-office/IconOffice.js +80 -0
  218. package/es/icons/microsoft-office/IconOffice.js.flow +45 -0
  219. package/es/icons/microsoft-office/IconOffice.js.map +1 -0
  220. package/es/illustration/EmailVerification140.js +111 -0
  221. package/es/illustration/EmailVerification140.js.flow +102 -0
  222. package/es/illustration/EmailVerification140.js.map +1 -0
  223. package/es/illustration/EmailVerification140.stories.js +13 -0
  224. package/es/illustration/EmailVerification140.stories.js.map +1 -0
  225. package/es/src/components/close-button/CloseButton.d.ts +9 -0
  226. package/es/src/components/close-button/CloseButton.stories.d.ts +9 -0
  227. package/es/src/components/close-button/__tests__/CloseButton.stories.test.d.ts +0 -0
  228. package/es/src/components/close-button/__tests__/CloseButton.test.d.ts +1 -0
  229. package/es/src/components/close-button/index.d.ts +1 -0
  230. package/es/src/components/date-picker/AccessiblePikaday.d.ts +16 -0
  231. package/es/src/components/date-picker/DatePicker.d.ts +33 -6
  232. package/es/src/components/date-picker/DatePicker.stories.d.ts +2 -1
  233. package/es/src/components/flyout/OverlayHeader.d.ts +10 -0
  234. package/es/src/components/tooltip/Tooltip.d.ts +4 -3
  235. package/es/src/icon/content/FileXbd32.d.ts +13 -0
  236. package/es/src/icon/content/FileXbd32.stories.d.ts +9 -0
  237. package/es/src/icon/content/FileXdw32.d.ts +13 -0
  238. package/es/src/icon/content/FileXdw32.stories.d.ts +9 -0
  239. package/es/src/icon/content/RetentionPolicyModifiable32.d.ts +13 -0
  240. package/es/src/icon/content/RetentionPolicyModifiable32.stories.d.ts +9 -0
  241. package/es/src/icon/content/RetentionPolicyNonModifiable32.d.ts +13 -0
  242. package/es/src/icon/content/RetentionPolicyNonModifiable32.stories.d.ts +9 -0
  243. package/es/src/icons/avatars/UnknownUserAvatar.d.ts +0 -1
  244. package/es/src/icons/general/IconSearchJuicy.d.ts +3 -0
  245. package/es/src/icons/general/__tests__/IconSearchJuicy.test.d.ts +1 -0
  246. package/es/src/icons/google-docs/IconGoogle.d.ts +12 -0
  247. package/es/src/icons/google-docs/__tests__/IconGoogle.test.d.ts +1 -0
  248. package/es/src/icons/item-icon/ItemIcon.d.ts +2 -0
  249. package/es/src/icons/microsoft-office/IconOffice.d.ts +12 -0
  250. package/es/src/icons/microsoft-office/__tests__/IconOffice.test.d.ts +1 -0
  251. package/es/src/illustration/EmailVerification140.d.ts +13 -0
  252. package/es/src/illustration/EmailVerification140.stories.d.ts +9 -0
  253. package/es/src/styles/variables.d.ts +9 -0
  254. package/es/styles/_variables.scss +1 -0
  255. package/es/styles/common/_forms.scss +6 -0
  256. package/es/styles/constants/_layout.scss +3 -0
  257. package/es/styles/constants/_media-queries.scss +15 -0
  258. package/es/styles/variables.js +18 -0
  259. package/es/styles/variables.js.flow +10 -1
  260. package/es/styles/variables.js.map +1 -1
  261. package/es/utils/Browser.js +12 -0
  262. package/es/utils/Browser.js.flow +10 -0
  263. package/es/utils/Browser.js.map +1 -1
  264. package/es/utils/validators.js +26 -4
  265. package/es/utils/validators.js.flow +25 -3
  266. package/es/utils/validators.js.map +1 -1
  267. package/i18n/bn-IN.js +12 -0
  268. package/i18n/bn-IN.properties +24 -0
  269. package/i18n/da-DK.js +12 -0
  270. package/i18n/da-DK.properties +24 -0
  271. package/i18n/de-DE.js +12 -0
  272. package/i18n/de-DE.properties +24 -0
  273. package/i18n/en-AU.js +12 -0
  274. package/i18n/en-AU.properties +24 -0
  275. package/i18n/en-CA.js +12 -0
  276. package/i18n/en-CA.properties +24 -0
  277. package/i18n/en-GB.js +12 -0
  278. package/i18n/en-GB.properties +24 -0
  279. package/i18n/en-US.js +12 -0
  280. package/i18n/en-US.properties +24 -0
  281. package/i18n/en-x-pseudo.js +12 -0
  282. package/i18n/es-419.js +12 -0
  283. package/i18n/es-419.properties +24 -0
  284. package/i18n/es-ES.js +12 -0
  285. package/i18n/es-ES.properties +24 -0
  286. package/i18n/fi-FI.js +12 -0
  287. package/i18n/fi-FI.properties +24 -0
  288. package/i18n/fr-CA.js +12 -0
  289. package/i18n/fr-CA.properties +24 -0
  290. package/i18n/fr-FR.js +12 -0
  291. package/i18n/fr-FR.properties +24 -0
  292. package/i18n/hi-IN.js +12 -0
  293. package/i18n/hi-IN.properties +24 -0
  294. package/i18n/it-IT.js +12 -0
  295. package/i18n/it-IT.properties +24 -0
  296. package/i18n/ja-JP.js +25 -13
  297. package/i18n/ja-JP.properties +37 -13
  298. package/i18n/ko-KR.js +12 -0
  299. package/i18n/ko-KR.properties +24 -0
  300. package/i18n/nb-NO.js +12 -0
  301. package/i18n/nb-NO.properties +24 -0
  302. package/i18n/nl-NL.js +12 -0
  303. package/i18n/nl-NL.properties +24 -0
  304. package/i18n/pl-PL.js +12 -0
  305. package/i18n/pl-PL.properties +24 -0
  306. package/i18n/pt-BR.js +12 -0
  307. package/i18n/pt-BR.properties +24 -0
  308. package/i18n/ru-RU.js +12 -0
  309. package/i18n/ru-RU.properties +24 -0
  310. package/i18n/sv-SE.js +12 -0
  311. package/i18n/sv-SE.properties +24 -0
  312. package/i18n/tr-TR.js +12 -0
  313. package/i18n/tr-TR.properties +24 -0
  314. package/i18n/zh-CN.js +12 -0
  315. package/i18n/zh-CN.properties +24 -0
  316. package/i18n/zh-TW.js +12 -0
  317. package/i18n/zh-TW.properties +24 -0
  318. package/package.json +8 -5
  319. package/src/__mocks__/pikaday.js +1 -0
  320. package/src/api/__tests__/MockOpenWithData.json +2 -25
  321. package/src/api/uploads/UploadsReachability.js +2 -2
  322. package/src/common/messages.js +5 -0
  323. package/src/common/types/core.js +2 -0
  324. package/src/components/avatar/UnknownUserAvatar.tsx +5 -4
  325. package/src/components/close-button/CloseButton.js.flow +26 -0
  326. package/src/components/close-button/CloseButton.scss +10 -0
  327. package/src/components/close-button/CloseButton.stories.md +1 -0
  328. package/src/components/close-button/CloseButton.stories.tsx +14 -0
  329. package/src/components/close-button/CloseButton.tsx +30 -0
  330. package/src/components/close-button/__tests__/CloseButton.stories.test.tsx +6 -0
  331. package/src/components/close-button/__tests__/CloseButton.test.tsx +40 -0
  332. package/src/components/close-button/__tests__/__image_snapshots__/close-button-stories-test-tsx-components-close-button-close-button-looks-visually-correct-when-using-story-components-buttons-closebutton-regular-1-snap.png +0 -0
  333. package/src/components/close-button/index.js.flow +2 -0
  334. package/src/components/close-button/index.ts +1 -0
  335. package/src/components/date-picker/AccessiblePikaday.ts +79 -0
  336. package/src/components/date-picker/DatePicker.scss +32 -22
  337. package/src/components/date-picker/DatePicker.stories.tsx +6 -0
  338. package/src/components/date-picker/DatePicker.tsx +350 -64
  339. package/src/components/date-picker/__tests__/DatePicker.test.tsx +44 -2
  340. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-allows-editing-in-story-components-datepicker-manually-editable-1-snap.png +0 -0
  341. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-allows-keyboard-selection-in-components-datepicker-always-visible-with-custom-input-field-1-snap.png +0 -0
  342. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-closes-calendar-and-clears-date-for-components-datepicker-basic-1-snap.png +0 -0
  343. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-looks-visually-correct-when-using-story-components-datepicker-always-visible-with-custom-input-field-1-snap.png +0 -0
  344. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-looks-visually-correct-when-using-story-components-datepicker-basic-1-snap.png +0 -0
  345. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-looks-visually-correct-when-using-story-components-datepicker-custom-error-tooltip-position-1-snap.png +0 -0
  346. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-looks-visually-correct-when-using-story-components-datepicker-disabled-with-error-message-1-snap.png +0 -0
  347. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-looks-visually-correct-when-using-story-components-datepicker-manually-editable-1-snap.png +0 -0
  348. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-looks-visually-correct-when-using-story-components-datepicker-with-description-1-snap.png +0 -0
  349. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-looks-visually-correct-when-using-story-components-datepicker-with-limited-date-range-1-snap.png +0 -0
  350. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-looks-visually-correct-when-using-story-components-datepicker-with-range-1-snap.png +0 -0
  351. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-reflects-changes-in-components-datepicker-always-visible-with-custom-input-field-1-snap.png +0 -0
  352. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-shows-calendar-and-date-for-components-datepicker-basic-1-snap.png +0 -0
  353. package/src/components/date-picker/__tests__/__image_snapshots__/date-picker-stories-test-tsx-components-date-picker-date-picker-shows-limited-range-in-components-datepicker-with-limited-date-range-1-snap.png +0 -0
  354. package/src/components/date-picker/_pikaday.scss +8 -2
  355. package/src/components/flyout/Flyout.js +14 -3
  356. package/src/components/flyout/Flyout.scss +40 -0
  357. package/src/components/flyout/FlyoutContext.js +9 -0
  358. package/src/components/flyout/OverlayHeader.scss +9 -0
  359. package/src/components/flyout/OverlayHeader.tsx +38 -0
  360. package/src/components/flyout/__tests__/Flyout.test.js +15 -0
  361. package/src/components/flyout/__tests__/OverlayHeader.test.js +56 -0
  362. package/src/components/flyout/_variables.scss +1 -0
  363. package/src/components/flyout/index.js +2 -0
  364. package/src/components/image-tooltip/ImageTooltip.tsx +1 -2
  365. package/src/components/media-query/__tests__/useMediaQuery.test.js +48 -0
  366. package/src/components/media-query/__tests__/withMediaQuery.test.js +29 -0
  367. package/src/components/media-query/constants.js +32 -0
  368. package/src/components/media-query/index.js +4 -0
  369. package/src/components/media-query/stories/MediaQuery.stories.js +80 -0
  370. package/src/components/media-query/stories/MediaQuery.stories.md +29 -0
  371. package/src/components/media-query/types.js +29 -0
  372. package/src/components/media-query/useMediaQuery.js +97 -0
  373. package/src/components/media-query/withMediaQuery.js +23 -0
  374. package/src/components/modal/Modal.scss +27 -0
  375. package/src/components/modal/__tests__/Modal.stories.test.js +10 -0
  376. package/src/components/modal/__tests__/__image_snapshots__/modal-stories-test-js-components-modal-modal-looks-visually-correct-for-small-screens-when-button-is-clicked-in-story-components-modal-basic-1-snap.png +0 -0
  377. package/src/components/modal/__tests__/__image_snapshots__/modal-stories-test-js-components-modal-modal-looks-visually-correct-for-small-screens-when-button-is-clicked-in-story-components-modal-with-custom-backdrop-click-handler-1-snap.png +0 -0
  378. package/src/components/preview/previewIcons.ts +4 -0
  379. package/src/components/search-form/SearchForm.scss +0 -5
  380. package/src/components/selector-dropdown/SelectorDropdown.js +3 -3
  381. package/src/components/selector-dropdown/__tests__/SelectorDropdown.test.js +5 -1
  382. package/src/components/sidebar-toggle-button/__tests__/__snapshots__/SidebarToggleButton.test.js.snap +0 -8
  383. package/src/components/tab-view/Tabs.scss +0 -4
  384. package/src/components/tooltip/Tooltip.tsx +20 -5
  385. package/src/components/tooltip/__tests__/Tooltip.test.tsx +17 -4
  386. package/src/components/tooltip/__tests__/__snapshots__/Tooltip.test.tsx.snap +0 -2
  387. package/src/constants.js +1 -0
  388. package/src/elements/content-open-with/IconFileMap.js +0 -2
  389. package/src/elements/content-open-with/__tests__/ContentOpenWith.test.js +13 -13
  390. package/src/elements/content-open-with/__tests__/OpenWithButton.test.js +1 -1
  391. package/src/elements/content-open-with/__tests__/OpenWithDropdownMenu.test.js +1 -5
  392. package/src/elements/content-open-with/__tests__/OpenWithDropdownMenuItem.test.js +2 -2
  393. package/src/elements/content-open-with/__tests__/__snapshots__/ContentOpenWith.test.js.snap +5 -5
  394. package/src/elements/content-open-with/__tests__/__snapshots__/OpenWithButton.test.js.snap +1 -1
  395. package/src/elements/content-open-with/__tests__/__snapshots__/OpenWithDropdownMenu.test.js.snap +1 -11
  396. package/src/elements/content-open-with/__tests__/__snapshots__/OpenWithDropdownMenuItem.test.js.snap +4 -3
  397. package/src/elements/content-sidebar/Sidebar.js +1 -1
  398. package/src/elements/content-sidebar/__tests__/AddTaskButton.test.js +15 -0
  399. package/src/elements/content-sidebar/activity-feed/common/delete-confirmation/DeleteConfirmation.scss +3 -3
  400. package/src/elements/content-sidebar/activity-feed/task-form/TaskForm.js +18 -5
  401. package/src/elements/content-sidebar/versions/StaticVersionSidebar.js +97 -0
  402. package/src/elements/content-sidebar/versions/StaticVersionsSidebar.scss +67 -0
  403. package/src/elements/content-sidebar/versions/VersionsSidebar.js +16 -3
  404. package/src/elements/content-sidebar/versions/VersionsSidebar.scss +5 -0
  405. package/src/elements/content-sidebar/versions/VersionsSidebarContainer.js +42 -7
  406. package/src/elements/content-sidebar/versions/__tests__/VersionsSidebar.test.js +18 -1
  407. package/src/elements/content-sidebar/versions/__tests__/VersionsSidebarContainer.test.js +51 -2
  408. package/src/elements/content-sidebar/versions/__tests__/__snapshots__/VersionsSidebarContainer.test.js.snap +75 -0
  409. package/src/elements/content-sidebar/versions/flowTypes.js +1 -0
  410. package/src/elements/content-sidebar/versions/messages.js +28 -0
  411. package/src/features/classification/constants.js +2 -0
  412. package/src/features/classification/flowTypes.js +7 -1
  413. package/src/features/classification/security-controls/SecurityControls.js +3 -4
  414. package/src/features/classification/security-controls/SecurityControlsItem.js +20 -17
  415. package/src/features/classification/security-controls/SecurityControlsItem.scss +4 -0
  416. package/src/features/classification/security-controls/SecurityControlsModal.js +2 -2
  417. package/src/features/classification/security-controls/__tests__/SecurityControlsItem.test.js +10 -0
  418. package/src/features/classification/security-controls/__tests__/__snapshots__/SecurityControls.test.js.snap +6 -6
  419. package/src/features/classification/security-controls/__tests__/__snapshots__/SecurityControlsItem.test.js.snap +35 -0
  420. package/src/features/classification/security-controls/__tests__/__snapshots__/SecurityControlsModal.test.js.snap +2 -2
  421. package/src/features/classification/security-controls/__tests__/__snapshots__/utils.test.js.snap +20 -0
  422. package/src/features/classification/security-controls/__tests__/utils.test.js +38 -18
  423. package/src/features/classification/security-controls/messages.js +5 -0
  424. package/src/features/classification/security-controls/utils.js +51 -27
  425. package/src/features/collapsible-sidebar/CollapsibleSidebar.js +13 -5
  426. package/src/features/collapsible-sidebar/CollapsibleSidebar.scss +35 -3
  427. package/src/features/collapsible-sidebar/__tests__/CollapsibleSidebar.test.js +35 -0
  428. package/src/features/collapsible-sidebar/__tests__/__snapshots__/CollapsibleSidebar.test.js.snap +1 -0
  429. package/src/features/content-explorer/content-explorer/ContentExplorer.scss +1 -1
  430. package/src/features/content-explorer/item-list/ItemList.js +1 -0
  431. package/src/features/content-explorer/item-list/ItemListName.js +3 -2
  432. package/src/features/content-explorer/item-list/__tests__/ItemListName.test.js +16 -2
  433. package/src/features/header-flyout/HeaderFlyout.js +4 -8
  434. package/src/features/header-flyout/__tests__/__snapshots__/HeaderFlyout.test.js.snap +14 -11
  435. package/src/features/header-flyout/styles/HeaderFlyout.scss +54 -15
  436. package/src/features/header-flyout/styles/_variables.scss +4 -0
  437. package/src/features/message-center/components/message-center-modal/MessageCenterModal.js +1 -0
  438. package/src/features/metadata-instance-editor/__tests__/__snapshots__/TemplateDropdown.test.js.snap +7 -0
  439. package/src/features/pagination/__tests__/__snapshots__/MarkerBasedPagination.test.js.snap +0 -8
  440. package/src/features/pagination/__tests__/__snapshots__/OffsetBasedPagination.test.js.snap +0 -16
  441. package/src/features/presence/PresenceCollaborator.js +81 -0
  442. package/src/features/presence/PresenceCollaborator.scss +28 -0
  443. package/src/features/presence/PresenceCollaboratorsList.js +7 -58
  444. package/src/features/presence/PresenceCollaboratorsList.scss +8 -35
  445. package/src/features/presence/__tests__/PresenceCollaborator.test.js +36 -0
  446. package/src/features/presence/__tests__/PresenceCollaboratorsList.test.js +13 -57
  447. package/src/features/presence/__tests__/__snapshots__/Presence.test.js.snap +5 -0
  448. package/src/features/presence/__tests__/__snapshots__/PresenceLink.test.js.snap +3 -0
  449. package/src/features/query-bar/__tests__/__snapshots__/ColumnButton.test.js.snap +3 -0
  450. package/src/features/quick-search/QuickSearch.js +13 -1
  451. package/src/features/quick-search/__tests__/QuickSearch.test.js +17 -0
  452. package/src/features/unified-share-modal/SharedLinkSection.js +6 -27
  453. package/src/features/unified-share-modal/UnifiedShareForm.js +70 -14
  454. package/src/features/unified-share-modal/UnifiedShareModal.scss +3 -0
  455. package/src/features/unified-share-modal/__tests__/EmailForm.test.js +9 -0
  456. package/src/features/unified-share-modal/__tests__/SharedLinkSection.test.js +14 -4
  457. package/src/features/unified-share-modal/__tests__/UnifiedShareForm.test.js +53 -4
  458. package/src/features/unified-share-modal/__tests__/__snapshots__/SharedLinkSection.test.js.snap +9 -0
  459. package/src/features/unified-share-modal/__tests__/__snapshots__/UnifiedShareForm.test.js.snap +0 -159
  460. package/src/features/unified-share-modal/flowTypes.js +6 -0
  461. package/src/features/unified-share-modal/messages.js +10 -0
  462. package/src/features/unified-share-modal/utils/__tests__/mergeContacts.test.js +23 -0
  463. package/src/features/unified-share-modal/utils/mergeContacts.js +4 -2
  464. package/src/icon/content/FileXbd32.js.flow +38 -0
  465. package/src/icon/content/FileXbd32.stories.tsx +13 -0
  466. package/src/icon/content/FileXbd32.tsx +37 -0
  467. package/src/icon/content/FileXdw32.js.flow +38 -0
  468. package/src/icon/content/FileXdw32.stories.tsx +13 -0
  469. package/src/icon/content/FileXdw32.tsx +37 -0
  470. package/src/icon/content/RetentionPolicyModifiable32.js.flow +31 -0
  471. package/src/icon/content/RetentionPolicyModifiable32.stories.tsx +14 -0
  472. package/src/icon/content/RetentionPolicyModifiable32.tsx +29 -0
  473. package/src/icon/content/RetentionPolicyNonModifiable32.js.flow +31 -0
  474. package/src/icon/content/RetentionPolicyNonModifiable32.stories.tsx +14 -0
  475. package/src/icon/content/RetentionPolicyNonModifiable32.tsx +29 -0
  476. package/src/icons/adobe-sign/README.md +1 -1
  477. package/src/icons/avatars/UnknownUserAvatar.tsx +7 -15
  478. package/src/icons/file-icon/FileIcon.js.flow +2 -2
  479. package/src/icons/file-icon/FileIcon.tsx +8 -2
  480. package/src/icons/file-icon/__tests__/FileIcon.test.tsx +28 -69
  481. package/src/icons/file-icon/__tests__/__snapshots__/FileIcon.test.tsx.snap +48 -34
  482. package/src/icons/general/IconSearch.js.flow +1 -1
  483. package/src/icons/general/IconSearch.tsx +1 -1
  484. package/src/icons/general/IconSearchJuicy.js.flow +26 -0
  485. package/src/icons/general/IconSearchJuicy.tsx +25 -0
  486. package/src/icons/general/README.md +5 -0
  487. package/src/icons/general/__tests__/IconSearchJuicy.test.tsx +38 -0
  488. package/src/icons/google-docs/IconGoogle.js.flow +57 -0
  489. package/src/icons/google-docs/IconGoogle.tsx +50 -0
  490. package/src/icons/google-docs/__tests__/IconGoogle.test.tsx +44 -0
  491. package/src/icons/item-icon/ItemIcon.tsx +4 -0
  492. package/src/icons/item-icon/__tests__/ItemIcon.test.tsx +47 -115
  493. package/src/icons/item-icon/__tests__/__snapshots__/ItemIcon.test.tsx.snap +229 -229
  494. package/src/icons/microsoft-office/IconOffice.js.flow +45 -0
  495. package/src/icons/microsoft-office/IconOffice.tsx +38 -0
  496. package/src/icons/microsoft-office/__tests__/IconOffice.test.tsx +44 -0
  497. package/src/illustration/EmailVerification140.js.flow +102 -0
  498. package/src/illustration/EmailVerification140.stories.tsx +13 -0
  499. package/src/illustration/EmailVerification140.tsx +100 -0
  500. package/src/styles/_variables.scss +1 -0
  501. package/src/styles/common/_forms.scss +6 -0
  502. package/src/styles/constants/_layout.scss +3 -0
  503. package/src/styles/constants/_media-queries.scss +15 -0
  504. package/src/styles/variables.js +10 -1
  505. package/src/styles/variables.json +10 -1
  506. package/src/styles/variables.ts +9 -0
  507. package/src/utils/Browser.js +10 -0
  508. package/src/utils/validators.js +25 -3
@@ -2,17 +2,17 @@ import * as React from 'react';
2
2
  import { defineMessages, injectIntl, FormattedMessage, WrappedComponentProps } from 'react-intl';
3
3
 
4
4
  import classNames from 'classnames';
5
- import Pikaday from 'pikaday';
6
5
  import noop from 'lodash/noop';
7
6
  import range from 'lodash/range';
8
7
  import uniqueId from 'lodash/uniqueId';
9
8
 
10
9
  // @ts-ignore flow import
11
10
  import { RESIN_TAG_TARGET } from '../../common/variables';
12
- import IconAlert from '../../icons/general/IconAlert';
13
- import IconCalendar from '../../icons/general/IconCalendar';
14
- import IconClear from '../../icons/general/IconClear';
11
+ import Alert16 from '../../icon/fill/Alert16';
12
+ import Calendar16 from '../../icon/fill/Calendar16';
13
+ import ClearBadge16 from '../../icon/fill/ClearBadge16';
15
14
 
15
+ import AccessiblePikaday, { AccessiblePikadayOptions } from './AccessiblePikaday';
16
16
  import { ButtonType } from '../button';
17
17
  import Label from '../label';
18
18
  import PlainButton from '../plain-button';
@@ -49,6 +49,21 @@ const messages = defineMessages({
49
49
  description: 'Button for opening date picker',
50
50
  id: 'boxui.datePicker.chooseDate',
51
51
  },
52
+ dateInputRangeError: {
53
+ defaultMessage: 'Please enter a date between {minLocaleDate} and {maxLocaleDate}',
54
+ description: 'Error message when date is out of the minimum and maximum range',
55
+ id: 'boxui.datePicker.dateInputRangeError',
56
+ },
57
+ dateInputMaxError: {
58
+ defaultMessage: 'Please enter a date before {maxLocaleDate}',
59
+ description: 'Error message when date is later than the maximum date',
60
+ id: 'boxui.datePicker.dateInputMaxError',
61
+ },
62
+ dateInputMinError: {
63
+ defaultMessage: 'Please enter a date after {minLocaleDate}',
64
+ description: 'Error message when date is earlier than the minimum date',
65
+ id: 'boxui.datePicker.dateInputMinError',
66
+ },
52
67
  });
53
68
 
54
69
  const TOGGLE_DELAY_MS = 300;
@@ -56,8 +71,11 @@ const ENTER_KEY = 'Enter';
56
71
  const ESCAPE_KEY = 'Escape';
57
72
  const TAB_KEY = 'Tab';
58
73
 
74
+ const ISO_DATE_FORMAT_PATTERN = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
75
+
59
76
  export enum DateFormat {
60
77
  ISO_STRING_DATE_FORMAT = 'isoString',
78
+ LOCALE_DATE_STRING_DATE_FORMAT = 'localeDateString',
61
79
  UTC_TIME_DATE_FORMAT = 'utcTime',
62
80
  UNIX_TIME_DATE_FORMAT = 'unixTime',
63
81
  UTC_ISO_STRING_DATE_FORMAT = 'utcISOString',
@@ -87,6 +105,8 @@ function getFormattedDate(date: Date | null, format: DateFormat) {
87
105
  switch (format) {
88
106
  case DateFormat.ISO_STRING_DATE_FORMAT:
89
107
  return date.toISOString();
108
+ case DateFormat.LOCALE_DATE_STRING_DATE_FORMAT:
109
+ return date.toLocaleDateString();
90
110
  case DateFormat.UTC_TIME_DATE_FORMAT:
91
111
  return convertDateToUnixMidnightTime(date);
92
112
  case DateFormat.UTC_ISO_STRING_DATE_FORMAT:
@@ -108,8 +128,13 @@ export interface DatePickerProps extends WrappedComponentProps {
108
128
  dateFormat?: DateFormat;
109
129
  /** Some optional description */
110
130
  description?: React.ReactNode;
111
- /** The format of the date displayed in the input field */
112
- displayFormat?: Object;
131
+ /**
132
+ * The format of the date displayed in the input field
133
+ * @deprecated, will no longer be supported with accessible mode enabled (isAccessible = true)
134
+ */
135
+ displayFormat?: {
136
+ [key: string]: string;
137
+ };
113
138
  /** Error message */
114
139
  error?: React.ReactNode;
115
140
  /** Position of error message tooltip */
@@ -120,6 +145,8 @@ export interface DatePickerProps extends WrappedComponentProps {
120
145
  hideOptionalLabel?: boolean;
121
146
  /** Props that will be applied on the input element */
122
147
  inputProps?: Object;
148
+ /** Does the date input meet accessibility standards */
149
+ isAccessible?: boolean;
123
150
  /** Is the calendar always visible */
124
151
  isAlwaysVisible?: boolean;
125
152
  /** Is input clearable */
@@ -156,7 +183,14 @@ export interface DatePickerProps extends WrappedComponentProps {
156
183
  yearRange?: number | Array<number>;
157
184
  }
158
185
 
159
- class DatePicker extends React.Component<DatePickerProps> {
186
+ interface DatePickerState {
187
+ /** Is the date input invalid */
188
+ isDateInputInvalid: boolean;
189
+ /** Shows error message tooltip for invalid date input */
190
+ showDateInputError: boolean;
191
+ }
192
+
193
+ class DatePicker extends React.Component<DatePickerProps, DatePickerState> {
160
194
  static defaultProps = {
161
195
  className: '',
162
196
  dateFormat: DateFormat.UNIX_TIME_DATE_FORMAT,
@@ -170,6 +204,11 @@ class DatePicker extends React.Component<DatePickerProps> {
170
204
  yearRange: 10,
171
205
  };
172
206
 
207
+ state = {
208
+ isDateInputInvalid: false,
209
+ showDateInputError: false,
210
+ };
211
+
173
212
  errorMessageID = uniqueId('errorMessage');
174
213
 
175
214
  descriptionID = uniqueId('description');
@@ -178,37 +217,65 @@ class DatePicker extends React.Component<DatePickerProps> {
178
217
  const {
179
218
  customInput,
180
219
  dateFormat,
220
+ displayFormat,
181
221
  intl,
222
+ isAccessible,
182
223
  isAlwaysVisible,
183
224
  isTextInputAllowed,
184
225
  maxDate,
185
226
  minDate,
227
+ onChange,
186
228
  value,
187
229
  yearRange,
188
230
  } = this.props;
189
231
  const { formatDate, formatMessage } = intl;
190
232
  const { nextMonth, previousMonth } = messages;
191
233
  let defaultValue = value;
234
+
235
+ if (isAccessible && this.shouldUseAccessibleFallback()) {
236
+ this.canUseDateInputType = false;
237
+ }
238
+
192
239
  // When date format is utcTime, initial date needs to be converted from being relative to GMT to being
193
240
  // relative to browser timezone
194
241
  if (dateFormat === DateFormat.UTC_TIME_DATE_FORMAT && value) {
195
242
  defaultValue = convertUTCToLocal(value);
243
+
244
+ if (onChange) {
245
+ const formattedDate = this.formatValue(defaultValue);
246
+ onChange(defaultValue, formattedDate);
247
+ }
196
248
  }
197
249
  // Make sure the DST detection algorithm in browsers is up-to-date
198
250
  const year = new Date().getFullYear();
199
-
251
+ const { timeZone } = displayFormat || {};
200
252
  const i18n = {
201
253
  previousMonth: formatMessage(previousMonth),
202
254
  nextMonth: formatMessage(nextMonth),
203
- months: range(12).map(month => formatDate(new Date(year, month, 15), { month: 'long' })),
255
+ months: range(12).map(month =>
256
+ formatDate(new Date(year, month, 15), {
257
+ month: 'long',
258
+ timeZone,
259
+ }),
260
+ ),
204
261
  // weekdays must start with Sunday, so array of dates below is May 1st-8th, 2016
205
- weekdays: range(1, 8).map(date => formatDate(new Date(2016, 4, date), { weekday: 'long' })),
206
- weekdaysShort: range(1, 8).map(date => formatDate(new Date(2016, 4, date), { weekday: 'narrow' })),
262
+ weekdays: range(1, 8).map(date =>
263
+ formatDate(new Date(2016, 4, date), {
264
+ weekday: 'long',
265
+ timeZone,
266
+ }),
267
+ ),
268
+ weekdaysShort: range(1, 8).map(date =>
269
+ formatDate(new Date(2016, 4, date), {
270
+ weekday: 'narrow',
271
+ timeZone,
272
+ }),
273
+ ),
207
274
  };
208
275
 
209
276
  // If "bound" is true (default), the DatePicker will be appended at the end of the document, with absolute positioning
210
277
  // If "bound" is false, the DatePicker will be appended to the DOM right after the input, with relative positioning
211
- this.datePicker = new Pikaday({
278
+ const datePickerConfig: AccessiblePikadayOptions = {
212
279
  bound: !customInput,
213
280
  blurFieldOnSelect: false, // Available in pikaday > 1.5.1
214
281
  setDefaultDate: true,
@@ -223,7 +290,22 @@ class DatePicker extends React.Component<DatePickerProps> {
223
290
  onSelect: this.onSelectHandler,
224
291
  yearRange,
225
292
  toString: this.formatDisplay,
226
- });
293
+ };
294
+
295
+ if (isAccessible) {
296
+ if (this.canUseDateInputType) {
297
+ delete datePickerConfig.field;
298
+ datePickerConfig.trigger = this.dateInputEl;
299
+ datePickerConfig.accessibleFieldEl = this.dateInputEl;
300
+ datePickerConfig.datePickerButtonEl = this.datePickerButtonEl;
301
+ }
302
+
303
+ datePickerConfig.parse = this.parseDisplayDateType;
304
+ datePickerConfig.toString = this.formatDisplayDateType;
305
+ datePickerConfig.keyboardInput = false;
306
+ }
307
+
308
+ this.datePicker = new AccessiblePikaday(datePickerConfig);
227
309
 
228
310
  if (isTextInputAllowed) {
229
311
  this.updateDateInputValue(this.formatDisplay(defaultValue));
@@ -287,11 +369,29 @@ class DatePicker extends React.Component<DatePickerProps> {
287
369
  }
288
370
 
289
371
  onSelectHandler = (date: Date | null = null) => {
290
- const { onChange } = this.props;
372
+ const { onChange, isAccessible } = this.props;
373
+ const { isDateInputInvalid } = this.state;
374
+
291
375
  if (onChange) {
292
376
  const formattedDate = this.formatValue(date);
293
377
  onChange(date, formattedDate);
294
378
  }
379
+
380
+ if (isAccessible) {
381
+ if (this.dateInputEl && this.datePicker) {
382
+ // Required because Pikaday instance is unbound
383
+ // See https://github.com/Pikaday/Pikaday#usage
384
+ this.dateInputEl.value = this.datePicker.toString();
385
+ }
386
+ if (this.datePicker && this.datePicker.isVisible()) {
387
+ this.datePicker.hide();
388
+ this.focusDatePicker();
389
+ }
390
+ }
391
+
392
+ if (isDateInputInvalid) {
393
+ this.setState({ isDateInputInvalid: false, showDateInputError: false });
394
+ }
295
395
  };
296
396
 
297
397
  updateDateInputValue(value: string) {
@@ -304,31 +404,61 @@ class DatePicker extends React.Component<DatePickerProps> {
304
404
 
305
405
  datePicker: Pikaday | null = null;
306
406
 
307
- datePickerButtonEl: HTMLButtonElement | null | undefined;
407
+ datePickerButtonEl: HTMLButtonElement | HTMLDivElement | null | undefined;
408
+
409
+ // Used to detect when a fallback is necessary when isAccessible is enabled
410
+ canUseDateInputType = true;
308
411
 
309
412
  // Used to prevent bad sequences of hide/show when toggling the datepicker button
310
413
  shouldStayClosed = false;
311
414
 
312
415
  focusDatePicker = () => {
313
- // By default, this will open the datepicker too
416
+ // This also opens the date picker when isAccessible is disabled
314
417
  if (this.dateInputEl) {
315
418
  this.dateInputEl.focus();
316
419
  }
317
420
  };
318
421
 
422
+ getDateInputError = () => {
423
+ const { intl, maxDate = null, minDate = null } = this.props;
424
+ const { showDateInputError } = this.state;
425
+ const { formatMessage } = intl;
426
+
427
+ if (!showDateInputError) return '';
428
+
429
+ let dateInputError = '';
430
+ const maxLocaleDate = getFormattedDate(maxDate, DateFormat.LOCALE_DATE_STRING_DATE_FORMAT);
431
+ const minLocaleDate = getFormattedDate(minDate, DateFormat.LOCALE_DATE_STRING_DATE_FORMAT);
432
+
433
+ if (maxLocaleDate && minLocaleDate) {
434
+ dateInputError = formatMessage(messages.dateInputRangeError, { maxLocaleDate, minLocaleDate });
435
+ } else if (maxLocaleDate) {
436
+ dateInputError = formatMessage(messages.dateInputMaxError, { maxLocaleDate });
437
+ } else if (minLocaleDate) {
438
+ dateInputError = formatMessage(messages.dateInputMinError, { minLocaleDate });
439
+ }
440
+
441
+ return dateInputError;
442
+ };
443
+
319
444
  handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
320
- const { isKeyboardInputAllowed, isTextInputAllowed } = this.props;
445
+ const { isKeyboardInputAllowed, isTextInputAllowed, isAccessible } = this.props;
321
446
 
322
447
  if (!isKeyboardInputAllowed && this.datePicker && this.datePicker.isVisible()) {
323
448
  event.stopPropagation();
324
449
  }
325
450
 
326
451
  // Stops up/down arrow & spacebar from moving page scroll position since pikaday does not preventDefault correctly
327
- if (!isTextInputAllowed && event.key !== TAB_KEY) {
452
+ if (!(isTextInputAllowed || isAccessible) && event.key !== TAB_KEY) {
453
+ event.preventDefault();
454
+ }
455
+
456
+ if ((isTextInputAllowed || (isAccessible && !this.canUseDateInputType)) && event.key === ENTER_KEY) {
328
457
  event.preventDefault();
329
458
  }
330
459
 
331
- if (isTextInputAllowed && event.key === ENTER_KEY) {
460
+ // Stops enter & spacebar from opening up the browser's default date picker
461
+ if (isAccessible && (event.key === ENTER_KEY || event.key === ' ')) {
332
462
  event.preventDefault();
333
463
  }
334
464
 
@@ -340,9 +470,51 @@ class DatePicker extends React.Component<DatePickerProps> {
340
470
  }
341
471
  };
342
472
 
343
- handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {
344
- const { onBlur, isTextInputAllowed } = this.props;
473
+ handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
474
+ const { isAccessible, maxDate, minDate, onChange } = this.props;
475
+ const { isDateInputInvalid } = this.state;
476
+
477
+ if (!isAccessible || !this.canUseDateInputType) {
478
+ return;
479
+ }
480
+
481
+ if (this.datePicker && this.datePicker.isVisible()) {
482
+ event.stopPropagation();
483
+ }
484
+
485
+ const { value } = event.target;
486
+ if (this.datePicker && value) {
487
+ const parsedDate = this.parseDisplayDateType(value);
488
+
489
+ if (parsedDate) {
490
+ if ((minDate && parsedDate < minDate) || (maxDate && parsedDate > maxDate)) {
491
+ this.datePicker.setDate(null);
492
+ this.setState({ isDateInputInvalid: true });
493
+ return;
494
+ }
495
+ // Reset the error styling on valid date input
496
+ if (isDateInputInvalid) {
497
+ this.setState({ isDateInputInvalid: false, showDateInputError: false });
498
+ }
499
+ } else {
500
+ this.setState({ isDateInputInvalid: true });
501
+ }
502
+
503
+ // Set date so Pikaday date picker value stays in sync with input
504
+ this.datePicker.setDate(parsedDate, true);
505
+
506
+ if (onChange) {
507
+ const formattedDate = this.formatValue(parsedDate);
508
+ onChange(parsedDate, formattedDate);
509
+ }
510
+ } else if (isDateInputInvalid) {
511
+ this.setState({ isDateInputInvalid: false, showDateInputError: false });
512
+ }
513
+ };
345
514
 
515
+ handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {
516
+ const { isAccessible, isTextInputAllowed, onBlur } = this.props;
517
+ const { isDateInputInvalid } = this.state;
346
518
  const nextActiveElement = event.relatedTarget || document.activeElement;
347
519
 
348
520
  // This is mostly here to cancel out the pikaday hide() on blur
@@ -362,44 +534,142 @@ class DatePicker extends React.Component<DatePickerProps> {
362
534
  onBlur(event);
363
535
  }
364
536
 
365
- // Since we Fire parent onChange event if isTextInputAllowed
537
+ // Since we fire parent onChange event if isTextInputAllowed,
366
538
  // fire it on blur if the user typed a correct date format
367
539
  let inputDate: Date | null | undefined = null;
368
540
 
369
541
  if (this.dateInputEl) {
370
- inputDate = new Date(this.dateInputEl.value);
542
+ let dateInputElVal = null;
543
+ if (isAccessible && !this.canUseDateInputType) {
544
+ dateInputElVal = this.parseDisplayDateType(this.dateInputEl.value);
545
+ }
546
+ inputDate = new Date(dateInputElVal || this.dateInputEl.value);
371
547
  }
372
548
 
373
- if (isTextInputAllowed && inputDate && inputDate.getDate()) {
549
+ if ((isTextInputAllowed || (isAccessible && !this.canUseDateInputType)) && inputDate && inputDate.getDate()) {
374
550
  this.onSelectHandler(inputDate);
375
551
  }
552
+
553
+ if (isAccessible && isDateInputInvalid) this.setState({ showDateInputError: true });
376
554
  };
377
555
 
378
556
  handleButtonClick = (event: React.SyntheticEvent<HTMLButtonElement>) => {
379
557
  event.preventDefault();
380
558
  event.stopPropagation();
559
+ const { isAccessible, isDisabled } = this.props;
560
+
561
+ if (isAccessible) {
562
+ if (isDisabled || !this.datePicker) {
563
+ return;
564
+ }
565
+
566
+ if (this.datePicker.isVisible()) {
567
+ this.datePicker.hide();
568
+ this.focusDatePicker();
569
+ } else {
570
+ this.datePicker.show();
571
+ }
572
+ return;
573
+ }
381
574
 
382
575
  if (!this.shouldStayClosed) {
383
576
  this.focusDatePicker();
384
577
  }
385
578
  };
386
579
 
580
+ handleOnClick = (event: React.SyntheticEvent<HTMLInputElement>) => {
581
+ const { isAccessible } = this.props;
582
+
583
+ if (isAccessible) {
584
+ // Suppress Firefox default behavior: clicking on input type "date"
585
+ // opens the browser date picker.
586
+ event.preventDefault();
587
+ event.stopPropagation();
588
+ }
589
+ };
590
+
387
591
  formatDisplay = (date?: Date | null): string => {
388
592
  const { displayFormat, intl } = this.props;
389
593
  return date ? intl.formatDate(date, displayFormat) : '';
390
594
  };
391
595
 
596
+ formatDisplayDateType = (date?: Date | null): string => {
597
+ // Input type "date" only accepts the format YYYY-MM-DD
598
+ return date ? getFormattedDate(date, DateFormat.UTC_ISO_STRING_DATE_FORMAT).slice(0, 10) : '';
599
+ };
600
+
601
+ parseDisplayDateType = (dateString?: string | null): Date | null => {
602
+ if (dateString && ISO_DATE_FORMAT_PATTERN.test(dateString)) {
603
+ // Calling new Date('YYYY-MM-DD') without 'T00:00:00' yields undesired results:
604
+ // E.g. new Date('2017-06-01') => May 31 2017
605
+ // E.g. new Date('2017-06-01T00:00:00') => June 01 2017
606
+ // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#parameters
607
+ return new Date(`${dateString}T00:00:00`);
608
+ }
609
+ return null;
610
+ };
611
+
392
612
  formatValue = (date: Date | null): string | number => {
393
613
  const { dateFormat } = this.props;
394
614
  return dateFormat ? getFormattedDate(date, dateFormat) : '';
395
615
  };
396
616
 
397
617
  clearDate = (event: React.SyntheticEvent<HTMLButtonElement>) => {
398
- event.preventDefault(); // so datepicker doesn't open after clearing
618
+ // Prevents the date picker from opening after clearing
619
+ event.preventDefault();
620
+ const { isAccessible } = this.props;
621
+
399
622
  if (this.datePicker) {
400
623
  this.datePicker.setDate(null);
401
624
  }
402
625
  this.onSelectHandler(null);
626
+
627
+ if (isAccessible) {
628
+ this.focusDatePicker();
629
+ }
630
+ };
631
+
632
+ /** Determines whether a new date input falls back to a text input or not */
633
+ shouldUseAccessibleFallback = (): boolean => {
634
+ const test = document.createElement('input');
635
+
636
+ try {
637
+ test.type = 'date';
638
+ } catch (e) {
639
+ // no-op
640
+ }
641
+
642
+ // If date input falls back to text input, show the fallback
643
+ return test.type === 'text';
644
+ };
645
+
646
+ renderCalendarButton = () => {
647
+ const { intl, isAccessible, isAlwaysVisible, isDisabled } = this.props;
648
+ const { formatMessage } = intl;
649
+
650
+ if (isAlwaysVisible) {
651
+ return null;
652
+ }
653
+
654
+ // De-emphasizing the Pikaday date picker because it does not meet accessibility standards
655
+ // Screenreaders & navigating via keyboard will no longer pick up on this element
656
+ const accessibleAttrs = isAccessible ? { 'aria-hidden': true, tabIndex: -1 } : {};
657
+
658
+ return (
659
+ <PlainButton
660
+ aria-label={formatMessage(messages.chooseDate)}
661
+ className="date-picker-open-btn"
662
+ getDOMRef={ref => {
663
+ this.datePickerButtonEl = ref;
664
+ }}
665
+ isDisabled={isDisabled}
666
+ onClick={this.handleButtonClick}
667
+ type={ButtonType.BUTTON}
668
+ {...accessibleAttrs}
669
+ >
670
+ <Calendar16 />
671
+ </PlainButton>
672
+ );
403
673
  };
404
674
 
405
675
  render() {
@@ -413,27 +683,32 @@ class DatePicker extends React.Component<DatePickerProps> {
413
683
  hideOptionalLabel,
414
684
  inputProps,
415
685
  intl,
416
- isAlwaysVisible,
686
+ isAccessible,
417
687
  isClearable,
418
688
  isDisabled,
419
689
  isRequired,
420
690
  isTextInputAllowed,
421
691
  label,
692
+ maxDate,
693
+ minDate,
422
694
  name,
423
695
  onFocus,
424
696
  placeholder,
425
697
  resinTarget,
426
698
  value,
427
699
  } = this.props;
428
-
700
+ const { isDateInputInvalid } = this.state;
429
701
  const { formatMessage } = intl;
702
+
703
+ const errorMessage = error || this.getDateInputError();
704
+ const hasError = !!errorMessage || isDateInputInvalid;
705
+ const hasValue = !!value || isDateInputInvalid;
706
+
430
707
  const classes = classNames(className, 'date-picker-wrapper', {
431
- 'show-clear-btn': !!value,
432
- 'show-error': !!error,
708
+ 'show-clear-btn': isClearable && hasValue && !isDisabled,
709
+ 'show-error': hasError,
433
710
  });
434
711
 
435
- const hasError = !!error;
436
-
437
712
  const ariaAttrs = {
438
713
  'aria-invalid': hasError,
439
714
  'aria-required': isRequired,
@@ -443,16 +718,40 @@ class DatePicker extends React.Component<DatePickerProps> {
443
718
 
444
719
  const resinTargetAttr = resinTarget ? { [RESIN_TAG_TARGET]: resinTarget } : {};
445
720
 
446
- const valueAttr = isTextInputAllowed
447
- ? { defaultValue: this.formatDisplay(value) }
448
- : { value: this.formatDisplay(value) };
721
+ let valueAttr;
722
+ if (isAccessible) {
723
+ valueAttr = { defaultValue: this.formatDisplayDateType(value) };
724
+ } else if (isTextInputAllowed) {
725
+ valueAttr = { defaultValue: this.formatDisplay(value) };
726
+ } else {
727
+ valueAttr = { value: this.formatDisplay(value) };
728
+ }
449
729
 
450
- const onChangeAttr = isTextInputAllowed
451
- ? {}
452
- : {
453
- onChange: noop,
454
- };
455
- /* fixes proptype error about readonly field (not adding readonly so constraint validation works) */
730
+ let onChangeAttr;
731
+ if (isAccessible && this.canUseDateInputType) {
732
+ onChangeAttr = { onChange: this.handleOnChange };
733
+ } else if (isTextInputAllowed || (isAccessible && !this.canUseDateInputType)) {
734
+ onChangeAttr = {};
735
+ } else {
736
+ // Fixes prop type error about read-only field
737
+ // Not adding readOnly so constraint validation works
738
+ onChangeAttr = { onChange: noop };
739
+ }
740
+
741
+ let additionalAttrs;
742
+ if (isAccessible && this.canUseDateInputType) {
743
+ additionalAttrs = {
744
+ max: this.formatDisplayDateType(maxDate) || '9999-12-31',
745
+ min: this.formatDisplayDateType(minDate) || '0001-01-01',
746
+ };
747
+ } else if (isAccessible && !this.canUseDateInputType) {
748
+ // "name" prop is required for pattern validation to be surfaced on form submit. See components/form-elements/form/Form.js
749
+ // "title" prop is shown during constraint validation as a description of the pattern
750
+ // See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern#usability
751
+ additionalAttrs = { name, pattern: ISO_DATE_FORMAT_PATTERN.source, title: 'YYYY-MM-DD' };
752
+ } else {
753
+ additionalAttrs = {};
754
+ }
456
755
 
457
756
  return (
458
757
  <div className={classes}>
@@ -466,9 +765,9 @@ class DatePicker extends React.Component<DatePickerProps> {
466
765
  )}
467
766
  <Tooltip
468
767
  className="date-picker-error-tooltip"
469
- isShown={!!error}
768
+ isShown={!!errorMessage}
470
769
  position={errorTooltipPosition}
471
- text={error || ''}
770
+ text={errorMessage || ''}
472
771
  theme={TooltipTheme.ERROR}
473
772
  >
474
773
  {customInput ? (
@@ -489,9 +788,10 @@ class DatePicker extends React.Component<DatePickerProps> {
489
788
  className="date-picker-input"
490
789
  disabled={isDisabled}
491
790
  onBlur={this.handleInputBlur}
791
+ onClick={this.handleOnClick}
492
792
  placeholder={placeholder || formatMessage(messages.chooseDate)}
493
793
  required={isRequired}
494
- type="text"
794
+ type={isAccessible && this.canUseDateInputType ? 'date' : 'text'}
495
795
  {...onChangeAttr}
496
796
  onFocus={onFocus}
497
797
  onKeyDown={this.handleInputKeyDown}
@@ -499,46 +799,32 @@ class DatePicker extends React.Component<DatePickerProps> {
499
799
  {...ariaAttrs}
500
800
  {...inputProps}
501
801
  {...valueAttr}
802
+ {...additionalAttrs}
502
803
  />
503
804
  )}
504
805
  </Tooltip>
505
806
  <span id={this.errorMessageID} className="accessibility-hidden" role="alert">
506
- {error}
807
+ {errorMessage}
507
808
  </span>
508
809
  </>
509
810
  </Label>
510
- {isClearable && !!value && !isDisabled ? (
811
+ {isClearable && hasValue && !isDisabled ? (
511
812
  <PlainButton
512
813
  aria-label={formatMessage(messages.dateClearButton)}
513
814
  className="date-picker-clear-btn"
514
815
  onClick={this.clearDate}
515
816
  type={ButtonType.BUTTON}
516
817
  >
517
- <IconClear height={12} width={12} />
818
+ <ClearBadge16 />
518
819
  </PlainButton>
519
820
  ) : null}
520
- {error ? (
521
- <IconAlert
821
+ {hasError ? (
822
+ <Alert16
522
823
  className="date-picker-icon-alert"
523
- height={13}
524
824
  title={<FormattedMessage {...messages.iconAlertText} />}
525
- width={13}
526
825
  />
527
826
  ) : null}
528
- {!isAlwaysVisible && (
529
- <PlainButton
530
- aria-label={formatMessage(messages.chooseDate)}
531
- className="date-picker-open-btn"
532
- getDOMRef={ref => {
533
- this.datePickerButtonEl = ref;
534
- }}
535
- isDisabled={isDisabled}
536
- onClick={this.handleButtonClick}
537
- type={ButtonType.BUTTON}
538
- >
539
- <IconCalendar height={17} width={16} />
540
- </PlainButton>
541
- )}
827
+ {this.renderCalendarButton()}
542
828
  <input
543
829
  className="date-picker-unix-time-input"
544
830
  name={name}