@via-profit/ui-kit 0.2.6 → 0.4.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 (498) hide show
  1. package/Accordion/AccordionContainer.js +11 -11
  2. package/Accordion/AccordionContent.js +16 -7
  3. package/Accordion/AccordionHeader.d.ts +22 -0
  4. package/Accordion/AccordionHeader.js +35 -18
  5. package/Accordion/Chevron.js +3 -3
  6. package/Accordion/index.d.ts +12 -8
  7. package/Accordion/index.js +21 -6
  8. package/Autocomplete/AutocompleteContainer.d.ts +5 -9
  9. package/Autocomplete/AutocompleteContainer.js +125 -57
  10. package/Autocomplete/AutocompleteTagsInput.d.ts +15 -0
  11. package/Autocomplete/AutocompleteTagsInput.js +65 -0
  12. package/Autocomplete/context.d.ts +1 -0
  13. package/Autocomplete/context.js +5 -5
  14. package/Autocomplete/index.js +10 -7
  15. package/Avatar/AvatarBase.js +1 -1
  16. package/Avatar/AvatarContainer.js +6 -11
  17. package/Avatar/AvatarPicture.d.ts +9 -1
  18. package/Avatar/AvatarPicture.js +4 -3
  19. package/Avatar/index.js +10 -10
  20. package/Badge/BadgeBase.d.ts +9 -0
  21. package/Badge/BadgeBase.js +21 -3
  22. package/Badge/BadgeContainer.js +2 -1
  23. package/Badge/BadgeDeleteButton.d.ts +1 -1
  24. package/Badge/BadgeOutlined.d.ts +1 -1
  25. package/Badge/BadgeOutlined.js +5 -80
  26. package/Badge/BadgeStandard.d.ts +1 -1
  27. package/Badge/BadgeStandard.js +5 -91
  28. package/Badge/BadgeStyled.d.ts +5 -0
  29. package/Badge/BadgeStyled.js +125 -0
  30. package/Badge/index.d.ts +2 -2
  31. package/Badge/index.js +3 -20
  32. package/Button/ButtonBase.js +8 -4
  33. package/Button/ButtonContainer.js +2 -0
  34. package/Button/ButtonIconWrapper.d.ts +1 -1
  35. package/Button/ButtonOutlined.d.ts +1 -1
  36. package/Button/ButtonOutlined.js +5 -80
  37. package/Button/ButtonPlain.d.ts +1 -1
  38. package/Button/ButtonPlain.js +5 -85
  39. package/Button/ButtonStandard.d.ts +1 -1
  40. package/Button/ButtonStandard.js +5 -97
  41. package/Button/ButtonStyled.d.ts +10 -0
  42. package/Button/ButtonStyled.js +205 -0
  43. package/Button/index.d.ts +5 -5
  44. package/Button/index.js +3 -24
  45. package/ButtonGroup/ButtonGroupContext.d.ts +21 -0
  46. package/ButtonGroup/ButtonGroupContext.js +11 -0
  47. package/ButtonGroup/index.d.ts +76 -0
  48. package/ButtonGroup/index.js +132 -0
  49. package/CHANGELOG.md +160 -0
  50. package/Calendar/CalendarCell.js +11 -4
  51. package/Calendar/CalendarComponent.d.ts +15 -4
  52. package/Calendar/CalendarComponent.js +201 -103
  53. package/Calendar/CalendarDayBadge.d.ts +1 -1
  54. package/Calendar/CalendarMonthCell.js +1 -11
  55. package/Calendar/CalendarWeekDayLabel.js +3 -1
  56. package/Calendar/CalendarWeekDaysBar.js +6 -1
  57. package/Calendar/CalendarYearCell.js +1 -16
  58. package/Calendar/CalendarYearsSelector.d.ts +0 -1
  59. package/Calendar/CalendarYearsSelector.js +33 -35
  60. package/Calendar/use-calendar.d.ts +4 -3
  61. package/Calendar/use-calendar.js +31 -24
  62. package/Checkbox/CheckboxAsterisk.d.ts +13 -0
  63. package/{Autocomplete2/Autocomplete2TextField.js → Checkbox/CheckboxAsterisk.js} +24 -10
  64. package/Checkbox/CheckboxBox.d.ts +22 -0
  65. package/Checkbox/CheckboxBox.js +88 -0
  66. package/Checkbox/CheckboxContainer.d.ts +27 -0
  67. package/Checkbox/CheckboxContainer.js +38 -0
  68. package/Checkbox/CheckboxErrorText.d.ts +6 -0
  69. package/Checkbox/CheckboxErrorText.js +76 -0
  70. package/Checkbox/CheckboxIcon.d.ts +10 -0
  71. package/Checkbox/CheckboxIcon.js +57 -0
  72. package/Checkbox/CheckboxTextWrapper.d.ts +4 -0
  73. package/Checkbox/CheckboxTextWrapper.js +29 -0
  74. package/Checkbox/CheckboxWrapper.d.ts +4 -0
  75. package/Checkbox/CheckboxWrapper.js +29 -0
  76. package/Checkbox/index.d.ts +144 -0
  77. package/Checkbox/index.js +71 -0
  78. package/Checkbox/useCheckboxColor.d.ts +6 -0
  79. package/Checkbox/useCheckboxColor.js +33 -0
  80. package/ClickOutside/index.d.ts +6 -0
  81. package/ClickOutside/index.js +19 -3
  82. package/Color/Color.d.ts +4 -4
  83. package/Color/Color.js +9 -5
  84. package/Color/ColorGenerator.d.ts +5 -1
  85. package/Color/ColorParser.d.ts +9 -0
  86. package/Color/ColorParser.js +52 -12
  87. package/CountryFlags/AC.js +5 -1
  88. package/CountryFlags/AD.js +5 -1
  89. package/CountryFlags/AE.js +5 -1
  90. package/CountryFlags/AF.js +5 -1
  91. package/CountryFlags/AG.js +5 -1
  92. package/CountryFlags/AI.js +5 -1
  93. package/CountryFlags/AL.js +5 -1
  94. package/CountryFlags/AM.js +5 -1
  95. package/CountryFlags/AO.js +5 -1
  96. package/CountryFlags/AQ.js +5 -1
  97. package/CountryFlags/AR.js +5 -1
  98. package/CountryFlags/AS.js +5 -1
  99. package/CountryFlags/AT.js +5 -1
  100. package/CountryFlags/AU.js +5 -1
  101. package/CountryFlags/AW.js +5 -1
  102. package/CountryFlags/AX.js +5 -1
  103. package/CountryFlags/AZ.js +5 -1
  104. package/CountryFlags/BA.js +5 -1
  105. package/CountryFlags/BB.js +5 -1
  106. package/CountryFlags/BD.js +5 -1
  107. package/CountryFlags/BE.js +5 -1
  108. package/CountryFlags/BF.js +5 -1
  109. package/CountryFlags/BG.js +5 -1
  110. package/CountryFlags/BH.js +5 -1
  111. package/CountryFlags/BI.js +5 -1
  112. package/CountryFlags/BJ.js +5 -1
  113. package/CountryFlags/BL.js +5 -1
  114. package/CountryFlags/BM.js +5 -1
  115. package/CountryFlags/BN.js +5 -1
  116. package/CountryFlags/BO.js +5 -1
  117. package/CountryFlags/BQ.js +5 -1
  118. package/CountryFlags/BR.js +5 -1
  119. package/CountryFlags/BS.js +5 -1
  120. package/CountryFlags/BT.js +5 -1
  121. package/CountryFlags/BV.js +5 -1
  122. package/CountryFlags/BW.js +5 -1
  123. package/CountryFlags/BY.js +5 -1
  124. package/CountryFlags/BZ.js +5 -1
  125. package/CountryFlags/CA.js +5 -1
  126. package/CountryFlags/CC.js +5 -1
  127. package/CountryFlags/CD.js +5 -1
  128. package/CountryFlags/CF.js +5 -1
  129. package/CountryFlags/CG.js +5 -1
  130. package/CountryFlags/CH.js +5 -1
  131. package/CountryFlags/CI.js +5 -1
  132. package/CountryFlags/CK.js +5 -1
  133. package/CountryFlags/CL.js +5 -1
  134. package/CountryFlags/CM.js +5 -1
  135. package/CountryFlags/CN.js +5 -1
  136. package/CountryFlags/CO.js +5 -1
  137. package/CountryFlags/CR.js +5 -1
  138. package/CountryFlags/CU.js +5 -1
  139. package/CountryFlags/CV.js +5 -1
  140. package/CountryFlags/CW.js +5 -1
  141. package/CountryFlags/CX.js +5 -1
  142. package/CountryFlags/CY.js +5 -1
  143. package/CountryFlags/CZ.js +5 -1
  144. package/CountryFlags/DE.js +5 -1
  145. package/CountryFlags/DJ.js +5 -1
  146. package/CountryFlags/DK.js +5 -1
  147. package/CountryFlags/DM.js +5 -1
  148. package/CountryFlags/DO.js +5 -1
  149. package/CountryFlags/DZ.js +5 -1
  150. package/CountryFlags/EC.js +5 -1
  151. package/CountryFlags/EE.js +5 -1
  152. package/CountryFlags/EG.js +5 -1
  153. package/CountryFlags/EH.js +5 -1
  154. package/CountryFlags/ER.js +5 -1
  155. package/CountryFlags/ES.js +5 -1
  156. package/CountryFlags/ET.js +5 -1
  157. package/CountryFlags/EU.js +5 -1
  158. package/CountryFlags/FI.js +5 -1
  159. package/CountryFlags/FJ.js +5 -1
  160. package/CountryFlags/FK.js +5 -1
  161. package/CountryFlags/FM.js +5 -1
  162. package/CountryFlags/FO.js +5 -1
  163. package/CountryFlags/FR.js +5 -1
  164. package/CountryFlags/GA.js +5 -1
  165. package/CountryFlags/GB.js +5 -1
  166. package/CountryFlags/GD.js +5 -1
  167. package/CountryFlags/GE.js +5 -1
  168. package/CountryFlags/GEAB.js +5 -1
  169. package/CountryFlags/GEOS.js +5 -1
  170. package/CountryFlags/GF.js +5 -1
  171. package/CountryFlags/GG.js +5 -1
  172. package/CountryFlags/GH.js +5 -1
  173. package/CountryFlags/GI.js +5 -1
  174. package/CountryFlags/GL.js +5 -1
  175. package/CountryFlags/GM.js +5 -1
  176. package/CountryFlags/GN.js +5 -1
  177. package/CountryFlags/GP.js +5 -1
  178. package/CountryFlags/GQ.js +5 -1
  179. package/CountryFlags/GR.js +5 -1
  180. package/CountryFlags/GS.js +5 -1
  181. package/CountryFlags/GT.js +5 -1
  182. package/CountryFlags/GU.js +5 -1
  183. package/CountryFlags/GW.js +5 -1
  184. package/CountryFlags/GY.js +5 -1
  185. package/CountryFlags/HK.js +5 -1
  186. package/CountryFlags/HM.js +5 -1
  187. package/CountryFlags/HN.js +5 -1
  188. package/CountryFlags/HR.js +5 -1
  189. package/CountryFlags/HT.js +5 -1
  190. package/CountryFlags/HU.js +5 -1
  191. package/CountryFlags/IC.js +5 -1
  192. package/CountryFlags/ID.js +5 -1
  193. package/CountryFlags/IE.js +5 -1
  194. package/CountryFlags/IL.js +5 -1
  195. package/CountryFlags/IM.js +5 -1
  196. package/CountryFlags/IN.js +5 -1
  197. package/CountryFlags/IO.js +5 -1
  198. package/CountryFlags/IQ.js +5 -1
  199. package/CountryFlags/IR.js +5 -1
  200. package/CountryFlags/IS.js +5 -1
  201. package/CountryFlags/IT.js +5 -1
  202. package/CountryFlags/JE.js +5 -1
  203. package/CountryFlags/JM.js +5 -1
  204. package/CountryFlags/JO.js +5 -1
  205. package/CountryFlags/JP.js +5 -1
  206. package/CountryFlags/KE.js +5 -1
  207. package/CountryFlags/KG.js +5 -1
  208. package/CountryFlags/KH.js +5 -1
  209. package/CountryFlags/KI.js +5 -1
  210. package/CountryFlags/KM.js +5 -1
  211. package/CountryFlags/KN.js +5 -1
  212. package/CountryFlags/KP.js +5 -1
  213. package/CountryFlags/KR.js +5 -1
  214. package/CountryFlags/KW.js +5 -1
  215. package/CountryFlags/KY.js +5 -1
  216. package/CountryFlags/KZ.js +5 -1
  217. package/CountryFlags/LA.js +5 -1
  218. package/CountryFlags/LB.js +5 -1
  219. package/CountryFlags/LC.js +5 -1
  220. package/CountryFlags/LI.js +5 -1
  221. package/CountryFlags/LK.js +5 -1
  222. package/CountryFlags/LR.js +5 -1
  223. package/CountryFlags/LS.js +5 -1
  224. package/CountryFlags/LT.js +5 -1
  225. package/CountryFlags/LU.js +5 -1
  226. package/CountryFlags/LV.js +5 -1
  227. package/CountryFlags/LY.js +5 -1
  228. package/CountryFlags/MA.js +5 -1
  229. package/CountryFlags/MC.js +5 -1
  230. package/CountryFlags/MD.js +5 -1
  231. package/CountryFlags/ME.js +5 -1
  232. package/CountryFlags/MF.js +5 -1
  233. package/CountryFlags/MG.js +5 -1
  234. package/CountryFlags/MH.js +5 -1
  235. package/CountryFlags/MK.js +5 -1
  236. package/CountryFlags/ML.js +5 -1
  237. package/CountryFlags/MM.js +5 -1
  238. package/CountryFlags/MN.js +5 -1
  239. package/CountryFlags/MO.js +5 -1
  240. package/CountryFlags/MP.js +5 -1
  241. package/CountryFlags/MQ.js +5 -1
  242. package/CountryFlags/MR.js +5 -1
  243. package/CountryFlags/MS.js +5 -1
  244. package/CountryFlags/MT.js +5 -1
  245. package/CountryFlags/MU.js +5 -1
  246. package/CountryFlags/MV.js +5 -1
  247. package/CountryFlags/MW.js +5 -1
  248. package/CountryFlags/MX.js +5 -1
  249. package/CountryFlags/MY.js +5 -1
  250. package/CountryFlags/MZ.js +5 -1
  251. package/CountryFlags/NA.js +5 -1
  252. package/CountryFlags/NC.js +5 -1
  253. package/CountryFlags/NE.js +5 -1
  254. package/CountryFlags/NF.js +5 -1
  255. package/CountryFlags/NG.js +5 -1
  256. package/CountryFlags/NI.js +5 -1
  257. package/CountryFlags/NL.js +5 -1
  258. package/CountryFlags/NO.js +5 -1
  259. package/CountryFlags/NP.js +5 -1
  260. package/CountryFlags/NR.js +5 -1
  261. package/CountryFlags/NU.js +5 -1
  262. package/CountryFlags/NZ.js +5 -1
  263. package/CountryFlags/OM.js +5 -1
  264. package/CountryFlags/PA.js +5 -1
  265. package/CountryFlags/PE.js +5 -1
  266. package/CountryFlags/PF.js +5 -1
  267. package/CountryFlags/PG.js +5 -1
  268. package/CountryFlags/PH.js +5 -1
  269. package/CountryFlags/PK.js +5 -1
  270. package/CountryFlags/PL.js +5 -1
  271. package/CountryFlags/PM.js +5 -1
  272. package/CountryFlags/PN.js +5 -1
  273. package/CountryFlags/PR.js +5 -1
  274. package/CountryFlags/PS.js +5 -1
  275. package/CountryFlags/PT.js +5 -1
  276. package/CountryFlags/PW.js +5 -1
  277. package/CountryFlags/PY.js +5 -1
  278. package/CountryFlags/QA.js +5 -1
  279. package/CountryFlags/RE.js +5 -1
  280. package/CountryFlags/RO.js +5 -1
  281. package/CountryFlags/RS.js +5 -1
  282. package/CountryFlags/RU.js +5 -1
  283. package/CountryFlags/RW.js +5 -1
  284. package/CountryFlags/SA.js +5 -1
  285. package/CountryFlags/SB.js +5 -1
  286. package/CountryFlags/SC.js +5 -1
  287. package/CountryFlags/SD.js +5 -1
  288. package/CountryFlags/SE.js +5 -1
  289. package/CountryFlags/SG.js +5 -1
  290. package/CountryFlags/SH.js +5 -1
  291. package/CountryFlags/SI.js +5 -1
  292. package/CountryFlags/SJ.js +5 -1
  293. package/CountryFlags/SK.js +5 -1
  294. package/CountryFlags/SL.js +5 -1
  295. package/CountryFlags/SM.js +5 -1
  296. package/CountryFlags/SN.js +5 -1
  297. package/CountryFlags/SO.js +5 -1
  298. package/CountryFlags/SR.js +5 -1
  299. package/CountryFlags/SS.js +5 -1
  300. package/CountryFlags/ST.js +5 -1
  301. package/CountryFlags/SV.js +5 -1
  302. package/CountryFlags/SX.js +5 -1
  303. package/CountryFlags/SY.js +5 -1
  304. package/CountryFlags/SZ.js +5 -1
  305. package/CountryFlags/TA.js +5 -1
  306. package/CountryFlags/TC.js +5 -1
  307. package/CountryFlags/TD.js +5 -1
  308. package/CountryFlags/TF.js +5 -1
  309. package/CountryFlags/TG.js +5 -1
  310. package/CountryFlags/TH.js +5 -1
  311. package/CountryFlags/TJ.js +5 -1
  312. package/CountryFlags/TK.js +5 -1
  313. package/CountryFlags/TL.js +5 -1
  314. package/CountryFlags/TM.js +5 -1
  315. package/CountryFlags/TN.js +5 -1
  316. package/CountryFlags/TO.js +5 -1
  317. package/CountryFlags/TR.js +5 -1
  318. package/CountryFlags/TT.js +5 -1
  319. package/CountryFlags/TV.js +5 -1
  320. package/CountryFlags/TW.js +5 -1
  321. package/CountryFlags/TZ.js +5 -1
  322. package/CountryFlags/UA.js +5 -1
  323. package/CountryFlags/UG.js +5 -1
  324. package/CountryFlags/UM.js +5 -1
  325. package/CountryFlags/US.js +5 -1
  326. package/CountryFlags/UY.js +5 -1
  327. package/CountryFlags/UZ.js +5 -1
  328. package/CountryFlags/Uknown.d.ts +7 -3
  329. package/CountryFlags/Uknown.js +9 -31
  330. package/CountryFlags/Unknown.d.ts +3 -0
  331. package/CountryFlags/Unknown.js +42 -0
  332. package/CountryFlags/VA.js +5 -1
  333. package/CountryFlags/VC.js +5 -1
  334. package/CountryFlags/VE.js +5 -1
  335. package/CountryFlags/VG.js +5 -1
  336. package/CountryFlags/VI.js +5 -1
  337. package/CountryFlags/VN.js +5 -1
  338. package/CountryFlags/VU.js +5 -1
  339. package/CountryFlags/WF.js +5 -1
  340. package/CountryFlags/WS.js +5 -1
  341. package/CountryFlags/XK.js +5 -1
  342. package/CountryFlags/YE.js +5 -1
  343. package/CountryFlags/YT.js +5 -1
  344. package/CountryFlags/ZA.js +5 -1
  345. package/CountryFlags/ZM.js +5 -1
  346. package/CountryFlags/ZW.js +5 -1
  347. package/CountryFlags/index.d.ts +2 -1
  348. package/CountryFlags/index.js +3 -1
  349. package/CountryFlags/isLabelled.d.ts +6 -0
  350. package/CountryFlags/isLabelled.js +7 -0
  351. package/DatePicker/index.d.ts +23 -6
  352. package/DatePicker/index.js +84 -23
  353. package/DatePicker/useDatePickerFormat.js +20 -3
  354. package/Grid/index.d.ts +60 -0
  355. package/Grid/index.js +43 -0
  356. package/Highlighted/index.d.ts +1 -1
  357. package/Highlighted/index.js +14 -10
  358. package/LoadingIndicator/LoadingOverlay.d.ts +11 -0
  359. package/LoadingIndicator/LoadingOverlay.js +63 -0
  360. package/LoadingIndicator/Spinner.d.ts +34 -5
  361. package/LoadingIndicator/Spinner.js +48 -37
  362. package/LoadingIndicator/SpinnerCircle.d.ts +14 -0
  363. package/LoadingIndicator/SpinnerCircle.js +34 -0
  364. package/LoadingIndicator/index.d.ts +8 -3
  365. package/LoadingIndicator/index.js +9 -15
  366. package/MaskedField/index.d.ts +3 -2
  367. package/MaskedField/index.js +7 -2
  368. package/MaskedField/templates.js +2 -0
  369. package/MaskedField/useMasked.js +26 -12
  370. package/Menu/MenuContainer.d.ts +11 -3
  371. package/Menu/MenuContainer.js +127 -65
  372. package/Menu/MenuItem.js +1 -1
  373. package/Menu/VirtualizedList.js +1 -3
  374. package/Menu/context.js +5 -0
  375. package/Modal/BaseModal/ModalWrapper.js +65 -38
  376. package/Modal/BaseModal/context.js +6 -0
  377. package/Modal/BaseModal/index.js +0 -8
  378. package/Modal/BaseModal/useDialogID.d.ts +6 -0
  379. package/Modal/BaseModal/useDialogID.js +12 -0
  380. package/Modal/ConfirmBox/ConfirmBoxContainer.js +5 -1
  381. package/Modal/ConfirmBox/index.js +2 -1
  382. package/Modal/Dialog/DialogInner.js +1 -1
  383. package/Modal/Dialog/index.js +12 -7
  384. package/Modal/Drawer/DrawerHeader.d.ts +20 -0
  385. package/Modal/Drawer/DrawerHeader.js +3 -3
  386. package/Modal/Drawer/DrawerInner.js +9 -1
  387. package/Modal/Drawer/index.d.ts +7 -0
  388. package/Modal/Drawer/index.js +12 -10
  389. package/Modal/MessageBox/MessageBoxContainer.js +1 -1
  390. package/Modal/MessageBox/index.js +2 -1
  391. package/PhoneField/CountryFlagComponent.js +2 -2
  392. package/PhoneField/UnknownFlag.d.ts +6 -3
  393. package/PhoneField/UnknownFlag.js +8 -31
  394. package/PhoneField/index.js +45 -55
  395. package/PhoneField/templates.js +13 -14
  396. package/PhoneField/usePhoneUtils.d.ts +15 -0
  397. package/PhoneField/usePhoneUtils.js +30 -37
  398. package/Popper/Popper.d.ts +30 -10
  399. package/Popper/Popper.js +9 -7
  400. package/Popper/usePopper.d.ts +21 -31
  401. package/Popper/usePopper.js +79 -46
  402. package/README.md +27 -10
  403. package/Radio/RadioBox.d.ts +14 -0
  404. package/Radio/RadioBox.js +100 -0
  405. package/Radio/RadioContainer.d.ts +27 -0
  406. package/Radio/RadioContainer.js +38 -0
  407. package/Radio/RadioTextWrapper.d.ts +4 -0
  408. package/Radio/RadioTextWrapper.js +29 -0
  409. package/Radio/index.d.ts +64 -0
  410. package/Radio/index.js +49 -0
  411. package/Radio/useRadioColor.d.ts +6 -0
  412. package/Radio/useRadioColor.js +33 -0
  413. package/RadioGroup/RadioGroupAsterisk.d.ts +13 -0
  414. package/RadioGroup/RadioGroupAsterisk.js +53 -0
  415. package/RadioGroup/RadioGroupContainer.d.ts +4 -0
  416. package/RadioGroup/RadioGroupContainer.js +36 -0
  417. package/RadioGroup/RadioGroupContext.d.ts +20 -0
  418. package/RadioGroup/RadioGroupContext.js +11 -0
  419. package/RadioGroup/RadioGroupErrorText.d.ts +6 -0
  420. package/RadioGroup/RadioGroupErrorText.js +76 -0
  421. package/RadioGroup/RadioGroupItems.d.ts +9 -0
  422. package/RadioGroup/RadioGroupItems.js +30 -0
  423. package/RadioGroup/RadioGroupLegend.d.ts +4 -0
  424. package/RadioGroup/RadioGroupLegend.js +37 -0
  425. package/RadioGroup/index.d.ts +134 -0
  426. package/RadioGroup/index.js +62 -0
  427. package/Selectbox/SelectboxMenu.d.ts +1 -1
  428. package/Selectbox/index.d.ts +18 -2
  429. package/Selectbox/index.js +32 -32
  430. package/Stack/index.d.ts +62 -0
  431. package/Stack/index.js +38 -0
  432. package/Surface/SurfaceContainer.js +6 -0
  433. package/Surface/index.js +7 -3
  434. package/Swiper/Swiper.d.ts +28 -2
  435. package/Swiper/Swiper.js +246 -91
  436. package/Swiper/SwiperContainer.js +0 -2
  437. package/Swiper/SwiperSlidesRenderer.d.ts +8 -0
  438. package/Swiper/SwiperSlidesRenderer.js +17 -14
  439. package/Swiper/SwiperTrack.d.ts +8 -0
  440. package/Swiper/SwiperTrack.js +8 -3
  441. package/Swiper/SwiperWrapper.js +9 -1
  442. package/Switch/SwitchContainer.d.ts +1 -1
  443. package/Switch/SwitchContainer.js +5 -5
  444. package/Switch/SwitchDot.js +13 -53
  445. package/Switch/SwitchToggleWrapper.d.ts +1 -1
  446. package/Switch/SwitchToggleWrapper.js +5 -6
  447. package/Switch/SwitchTrack.js +5 -41
  448. package/Switch/index.d.ts +4 -4
  449. package/Switch/index.js +21 -11
  450. package/Switch/useSwitchColor.d.ts +7 -0
  451. package/Switch/useSwitchColor.js +33 -0
  452. package/Table/Table.d.ts +6 -0
  453. package/Table/Table.js +7 -62
  454. package/Table/TableBody.d.ts +1 -1
  455. package/Table/TableBody.js +4 -2
  456. package/Table/TableCaption.d.ts +2 -2
  457. package/Table/TableCaption.js +2 -3
  458. package/Table/TableCell.js +2 -5
  459. package/Table/TableFooter.js +8 -7
  460. package/Table/TableHeader.js +6 -2
  461. package/Table/TableHeaderCell.js +8 -9
  462. package/Table/TableRow.js +1 -5
  463. package/TextArea/TextAreaIconWrapper.d.ts +1 -1
  464. package/TextArea/TextAreaInput.js +2 -0
  465. package/TextArea/index.js +7 -15
  466. package/TextField/TextFieldInput.js +2 -0
  467. package/TextField/TextFieldInputWrapper.d.ts +2 -0
  468. package/TextField/TextFieldInputWrapper.js +12 -2
  469. package/TextField/index.js +7 -19
  470. package/ThemeProvider/createTheme.js +2 -3
  471. package/ThemeProvider/index.d.ts +19 -2
  472. package/Typography/Base.d.ts +1 -1
  473. package/Typography/Base.js +1 -1
  474. package/Typography/Blockquote.js +1 -1
  475. package/Typography/Del.js +2 -2
  476. package/Typography/H4.js +1 -1
  477. package/Typography/H5.js +2 -2
  478. package/Typography/H6.d.ts +4 -0
  479. package/Typography/H6.js +28 -0
  480. package/Typography/SectionDescription.js +0 -1
  481. package/Typography/SectionTitle.d.ts +4 -7
  482. package/Typography/SectionTitle.js +26 -8
  483. package/Typography/index.d.ts +27 -0
  484. package/Typography/index.js +35 -0
  485. package/package.json +2 -4
  486. package/utils/TabManager.d.ts +7 -1
  487. package/utils/TabManager.js +39 -45
  488. package/utils/spacing.d.ts +11 -0
  489. package/utils/spacing.js +14 -0
  490. package/Autocomplete/OverrideMenuList.d.ts +0 -4
  491. package/Autocomplete/OverrideMenuList.js +0 -39
  492. package/Autocomplete2/Autocomplete2.d.ts +0 -12
  493. package/Autocomplete2/Autocomplete2.js +0 -83
  494. package/Autocomplete2/Autocomplete2TextField.d.ts +0 -7
  495. package/Autocomplete2/index.d.ts +0 -2
  496. package/Autocomplete2/index.js +0 -7
  497. package/CountryFlags/SwiperOverview.d.ts +0 -257
  498. package/CountryFlags/SwiperOverview.js +0 -524
@@ -46,28 +46,35 @@ const isEqual = (a, b) => {
46
46
  return keysA.every(key => Object.prototype.hasOwnProperty.call(b, key) && a[key] === b[key]);
47
47
  };
48
48
  const MenuContainer = react_1.default.forwardRef((props, ref) => {
49
- const { items, value, anchorElement = null, overrides, children, closeOutsideClick = true, isOpen = false, anchorPos = 'bottom', alternativePlacements = ['bottom', 'top'], positionStrategy, autoFlip, viewportMargin, offset, multiple = false, autofocus = true, closeOnSelect = !multiple, onRequestClose = onRequestCloseDefault, onAnchorPosChanged, zIndex, onSelectItem, getOptionSelected, maxWidth, } = props;
50
- // const [actualPlacement, setActualPlacement] = React.useState(anchorPos);
51
- const [currentAnchorElement, setAnchorElement] = react_1.default.useState(anchorElement);
49
+ const { items, value, anchorElement = null, overrides, children, closeOutsideClick = true, closeOnAnchorClick = false, isOpen = false, anchorPos = 'bottom', alternativePlacements = ['bottom', 'top'], positionStrategy, autoFlip, viewportMargin, offset, multiple = false, autofocus = true, closeOnSelect = !multiple, onRequestClose = onRequestCloseDefault, onAnchorPosChanged, zIndex, onSelectItem, getOptionSelected, maxWidth, } = props;
52
50
  const overridesMap = react_1.default.useMemo(() => ({
53
51
  List: (overrides === null || overrides === void 0 ? void 0 : overrides.List) || MenuList_1.default,
54
52
  Popper: (overrides === null || overrides === void 0 ? void 0 : overrides.Popper) || Popper_1.default,
55
53
  }), [overrides === null || overrides === void 0 ? void 0 : overrides.List, overrides === null || overrides === void 0 ? void 0 : overrides.Popper]);
56
54
  const menuListRef = react_1.default.useRef(null);
57
55
  const menuPopperRef = react_1.default.useRef(null);
58
- const isOpenRef = react_1.default.useRef(isOpen);
56
+ // Starts as `false` so that a menu mounted in the open state is focused and scrolled too
57
+ const isOpenRef = react_1.default.useRef(false);
59
58
  const focusTimeoutRef = react_1.default.useRef();
59
+ // Whether the focus is inside the list: then it is returned to the anchor on close
60
+ const hasFocusRef = react_1.default.useRef(false);
61
+ // The parent often resets the anchor together with isOpen, so the last one is kept
62
+ const lastAnchorRef = react_1.default.useRef(anchorElement);
63
+ if (anchorElement) {
64
+ lastAnchorRef.current = anchorElement;
65
+ }
66
+ // Keyboard navigation scrolls the list under a still pointer, and the browser fires
67
+ // mouseenter on the item that appears under it. Such events must not move the highlight
68
+ const isKeyboardNavigationRef = react_1.default.useRef(false);
60
69
  const { dispatch, state: { selectedIndexes, markedIndex, hoveredIndex }, } = (0, context_1.default)();
61
70
  const selectedIndexesRef = react_1.default.useRef(selectedIndexes);
71
+ const compareFunc = react_1.default.useCallback((item, val) => getOptionSelected ? getOptionSelected({ item, value: val }) : isEqual(item, val), [getOptionSelected]);
62
72
  // Оптимизированная функция получения выбранных индексов
63
73
  const getSelectedIndexes = react_1.default.useCallback(() => {
64
74
  if (value === null || (multiple && value.length === 0)) {
65
75
  return [];
66
76
  }
67
77
  const indexes = [];
68
- const compareFunc = getOptionSelected
69
- ? (item, val) => getOptionSelected({ item, value: val })
70
- : (item, val) => isEqual(item, val);
71
78
  if (multiple) {
72
79
  const valueArray = value;
73
80
  items.forEach((item, index) => {
@@ -84,7 +91,7 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
84
91
  }
85
92
  }
86
93
  return indexes;
87
- }, [items, value, multiple, getOptionSelected]);
94
+ }, [items, value, multiple, compareFunc]);
88
95
  const scrollToIndex = react_1.default.useCallback((index) => {
89
96
  if (index === -1) {
90
97
  return;
@@ -94,40 +101,41 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
94
101
  if (container && option) {
95
102
  const containerRect = container.getBoundingClientRect();
96
103
  const optionRect = option.getBoundingClientRect();
97
- const scrollOffset = optionRect.top - containerRect.top + container.scrollTop;
98
- container.scrollTo({
99
- top: scrollOffset,
100
- behavior: 'instant'
101
- });
104
+ // Scroll only when the option is out of the visible area
105
+ if (optionRect.top < containerRect.top) {
106
+ container.scrollTop -= containerRect.top - optionRect.top;
107
+ }
108
+ else if (optionRect.bottom > containerRect.bottom) {
109
+ container.scrollTop += optionRect.bottom - containerRect.bottom;
110
+ }
102
111
  }
103
112
  }, []);
104
113
  const scrollToFirstSelected = react_1.default.useCallback(() => {
105
- if (selectedIndexes.length === 0)
114
+ // Computed from the props, the context state may not be updated yet
115
+ const indexes = getSelectedIndexes();
116
+ if (indexes.length === 0)
106
117
  return;
107
- const firstSelectedIndex = Math.min(...selectedIndexes);
118
+ const firstSelectedIndex = Math.min(...indexes);
108
119
  dispatch((0, context_1.actionSetmenuState)({ markedIndex: firstSelectedIndex }));
109
120
  scrollToIndex(firstSelectedIndex);
110
- }, [dispatch, selectedIndexes, scrollToIndex]);
121
+ }, [dispatch, getSelectedIndexes, scrollToIndex]);
111
122
  const selectItem = react_1.default.useCallback((index) => {
112
123
  if (index < 0 || index >= items.length)
113
124
  return;
114
125
  const item = items[index];
115
- if (!item)
126
+ // Falsy items such as 0 or an empty string are valid options
127
+ if (item === undefined)
116
128
  return;
117
129
  if (typeof onSelectItem === 'function') {
118
130
  if (multiple) {
119
131
  // Для multiple режима
120
- const selectedSet = new Set();
121
- if (value !== null) {
122
- value.forEach(v => selectedSet.add(v));
123
- }
124
- if (selectedIndexes.includes(index)) {
125
- selectedSet.delete(item);
126
- }
127
- else {
128
- selectedSet.add(item);
129
- }
130
- onSelectItem(Array.from(selectedSet));
132
+ // Value entries may be other instances than items, so compare them by compareFunc
133
+ const currentValue = value || [];
134
+ const isSelected = currentValue.some(v => compareFunc(item, v));
135
+ const newValue = isSelected
136
+ ? currentValue.filter(v => !compareFunc(item, v))
137
+ : [...currentValue, item];
138
+ onSelectItem(newValue);
131
139
  }
132
140
  else {
133
141
  // Для single режима
@@ -137,14 +145,16 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
137
145
  onRequestClose();
138
146
  }
139
147
  }
140
- }, [onSelectItem, onRequestClose, selectedIndexes, closeOnSelect, items, value, multiple]);
148
+ }, [onSelectItem, onRequestClose, compareFunc, closeOnSelect, items, value, multiple]);
141
149
  const highlightIndex = react_1.default.useCallback((index) => {
142
150
  const validIndex = Math.max(-1, Math.min(index, items.length - 1));
143
- if (validIndex !== markedIndex) {
144
- dispatch((0, context_1.actionSetmenuState)({ markedIndex: validIndex }));
145
- scrollToIndex(validIndex);
146
- }
147
- }, [dispatch, items.length, markedIndex, scrollToIndex]);
151
+ isKeyboardNavigationRef.current = true;
152
+ // Always dispatched: markedIndex of this closure can be outdated (e.g. the items effect
153
+ // has just reset it), the reducer skips the update when nothing changes.
154
+ // The mouse and the keyboard share one highlight
155
+ dispatch((0, context_1.actionSetmenuState)({ markedIndex: validIndex, hoveredIndex: -1 }));
156
+ scrollToIndex(validIndex);
157
+ }, [dispatch, items.length, scrollToIndex]);
148
158
  const highlightPrevItem = react_1.default.useCallback(() => {
149
159
  const newIndex = markedIndex - 1;
150
160
  highlightIndex(newIndex >= 0 ? newIndex : 0);
@@ -189,12 +199,6 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
189
199
  scrollToFirstSelected,
190
200
  selectItem,
191
201
  ]);
192
- // Обновление anchor элемента
193
- react_1.default.useEffect(() => {
194
- if (anchorElement !== currentAnchorElement) {
195
- setAnchorElement(anchorElement);
196
- }
197
- }, [anchorElement, currentAnchorElement]);
198
202
  // Обработчик клавиатуры
199
203
  const listKeydownEvent = react_1.default.useCallback((event) => {
200
204
  switch (event.code) {
@@ -225,6 +229,12 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
225
229
  event.preventDefault();
226
230
  onRequestClose(event);
227
231
  break;
232
+ case 'Tab':
233
+ // The list is rendered in a portal at the end of the page, so the next Tab stop
234
+ // would be lost: close the menu instead, the focus returns to the anchor
235
+ event.preventDefault();
236
+ onRequestClose(event);
237
+ break;
228
238
  default:
229
239
  break;
230
240
  }
@@ -240,27 +250,35 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
240
250
  ]);
241
251
  // Управление открытием/закрытием меню
242
252
  react_1.default.useEffect(() => {
253
+ var _a;
243
254
  if (isOpenRef.current === isOpen)
244
255
  return;
245
256
  isOpenRef.current = isOpen;
246
257
  if (!isOpen) {
247
- onRequestClose();
258
+ // The menu is already closed by the parent, so onRequestClose must not be called again
248
259
  dispatch((0, context_1.actionSetmenuState)({ markedIndex: -1, hoveredIndex: -1 }));
260
+ // Otherwise the focus is lost together with the unmounted list
261
+ if (hasFocusRef.current) {
262
+ hasFocusRef.current = false;
263
+ (_a = lastAnchorRef.current) === null || _a === void 0 ? void 0 : _a.focus();
264
+ }
249
265
  return;
250
266
  }
251
267
  // При открытии
252
268
  scrollToFirstSelected();
253
- if (autofocus) {
254
- // Очищаем предыдущий таймаут
255
- if (focusTimeoutRef.current) {
256
- clearTimeout(focusTimeoutRef.current);
257
- }
258
- focusTimeoutRef.current = setTimeout(() => {
259
- var _a;
260
- (_a = menuListRef.current) === null || _a === void 0 ? void 0 : _a.focus();
261
- }, 15);
269
+ if (focusTimeoutRef.current) {
270
+ clearTimeout(focusTimeoutRef.current);
262
271
  }
263
- }, [isOpen, autofocus, dispatch, onRequestClose, scrollToFirstSelected]);
272
+ // A menu mounted in the open state gets its list only after the portal is mounted,
273
+ // so the scroll is repeated when the list surely exists
274
+ focusTimeoutRef.current = setTimeout(() => {
275
+ var _a;
276
+ scrollToFirstSelected();
277
+ if (autofocus) {
278
+ (_a = menuListRef.current) === null || _a === void 0 ? void 0 : _a.focus();
279
+ }
280
+ }, 15);
281
+ }, [isOpen, autofocus, dispatch, scrollToFirstSelected]);
264
282
  // Обновление выбранных индексов
265
283
  react_1.default.useEffect(() => {
266
284
  const indexes = getSelectedIndexes();
@@ -275,23 +293,65 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
275
293
  });
276
294
  }
277
295
  }, [getSelectedIndexes, dispatch]);
296
+ // The highlight is an index, so when the items change it follows the same item
297
+ // or is removed. Otherwise a filtered list highlights a random item at the old index
298
+ const prevItemsRef = react_1.default.useRef(items);
299
+ const markedIndexRef = react_1.default.useRef(markedIndex);
300
+ markedIndexRef.current = markedIndex;
301
+ react_1.default.useEffect(() => {
302
+ const prevItems = prevItemsRef.current;
303
+ prevItemsRef.current = items;
304
+ // A new array with the same items (e.g. `items={list.filter(...)}`) is not a change
305
+ const isSameList = prevItems.length === items.length && prevItems.every((item, i) => item === items[i]);
306
+ if (isSameList) {
307
+ return;
308
+ }
309
+ const prevIndex = markedIndexRef.current;
310
+ const markedItem = prevIndex === -1 ? undefined : prevItems[prevIndex];
311
+ const newIndex = markedItem === undefined
312
+ ? -1
313
+ : items.findIndex(item => item === markedItem || compareFunc(item, markedItem));
314
+ if (newIndex !== prevIndex) {
315
+ dispatch((0, context_1.actionSetmenuState)({ markedIndex: newIndex, hoveredIndex: -1 }));
316
+ }
317
+ // The old scroll position means nothing for the new list
318
+ if (newIndex === -1) {
319
+ if (menuListRef.current) {
320
+ menuListRef.current.scrollTop = 0;
321
+ }
322
+ }
323
+ else {
324
+ scrollToIndex(newIndex);
325
+ }
326
+ }, [items, compareFunc, dispatch, scrollToIndex]);
278
327
  const itemClickHandler = react_1.default.useCallback((index) => () => selectItem(index), [selectItem]);
328
+ // The hovered item becomes the highlighted one, so the keyboard continues from it
329
+ // and Enter selects it
279
330
  const itemMouseEnterHandler = react_1.default.useCallback((index) => () => {
280
- if (index !== hoveredIndex) {
281
- dispatch((0, context_1.actionSetmenuState)({
282
- hoveredIndex: index,
283
- markedIndex: -1,
284
- }));
331
+ if (isKeyboardNavigationRef.current) {
332
+ return;
285
333
  }
286
- }, [dispatch, hoveredIndex]);
334
+ if (index !== markedIndex || index !== hoveredIndex) {
335
+ dispatch((0, context_1.actionSetmenuState)({ hoveredIndex: index, markedIndex: index }));
336
+ }
337
+ }, [dispatch, hoveredIndex, markedIndex]);
287
338
  const itemMouseLeaveHandler = react_1.default.useCallback((index) => () => {
288
339
  if (index === hoveredIndex) {
289
- dispatch((0, context_1.actionSetmenuState)({
290
- hoveredIndex: -1,
291
- markedIndex: -1,
292
- }));
340
+ dispatch((0, context_1.actionSetmenuState)({ hoveredIndex: -1 }));
293
341
  }
294
342
  }, [dispatch, hoveredIndex]);
343
+ // A real pointer movement ends the keyboard navigation
344
+ const listMouseMoveHandler = react_1.default.useCallback(() => {
345
+ isKeyboardNavigationRef.current = false;
346
+ }, []);
347
+ const listFocusHandler = react_1.default.useCallback(() => {
348
+ hasFocusRef.current = true;
349
+ }, []);
350
+ const listBlurHandler = react_1.default.useCallback((event) => {
351
+ if (!event.currentTarget.contains(event.relatedTarget)) {
352
+ hasFocusRef.current = false;
353
+ }
354
+ }, []);
295
355
  const onAnchorPosChangedMemo = react_1.default.useCallback((newPlacement) => {
296
356
  if (typeof onAnchorPosChanged === 'function') {
297
357
  onAnchorPosChanged(newPlacement);
@@ -300,15 +360,17 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
300
360
  const renderedChildren = react_1.default.useMemo(() => items.map((item, index) => children({ item, index }, {
301
361
  key: index,
302
362
  onMouseEnter: itemMouseEnterHandler(index),
363
+ // mouseenter is skipped during the keyboard navigation, so the item under a moving
364
+ // pointer is highlighted by mousemove
365
+ onMouseMove: itemMouseEnterHandler(index),
303
366
  onMouseLeave: itemMouseLeaveHandler(index),
304
367
  onClick: itemClickHandler(index),
305
368
  selected: selectedIndexes.includes(index),
306
- hovered: hoveredIndex === index || markedIndex === index,
369
+ hovered: markedIndex === index,
307
370
  })), [
308
371
  items,
309
372
  children,
310
373
  selectedIndexes,
311
- hoveredIndex,
312
374
  markedIndex,
313
375
  itemMouseEnterHandler,
314
376
  itemMouseLeaveHandler,
@@ -323,9 +385,9 @@ const MenuContainer = react_1.default.forwardRef((props, ref) => {
323
385
  // Мемоизация компонентов
324
386
  const PopperComponent = overridesMap.Popper;
325
387
  const ListComponent = overridesMap.List;
326
- return (react_1.default.createElement(ClickOutside_1.default, { onOutsideClick: onRequestClose, mouseEvent: isOpen && closeOutsideClick ? 'onMouseDown' : false },
388
+ return (react_1.default.createElement(ClickOutside_1.default, { onOutsideClick: onRequestClose, mouseEvent: isOpen && closeOutsideClick ? 'onMouseDown' : false, ignoreElements: closeOnAnchorClick ? undefined : [anchorElement] },
327
389
  react_1.default.createElement(PopperComponent, { isOpen: Boolean(isOpen), ref: menuPopperRef, zIndex: zIndex, anchorPos: anchorPos, alternativePlacements: alternativePlacements, anchorElement: anchorElement, onAnchorPosChanged: onAnchorPosChangedMemo, positionStrategy: positionStrategy, autoFlip: autoFlip, viewportMargin: viewportMargin, offset: offset },
328
- react_1.default.createElement(ListComponent, { anchorPos: anchorPos, isOpen: Boolean(isOpen), ref: menuListRef, maxWidth: maxWidth, onKeyDown: listKeydownEvent }, renderedChildren))));
390
+ react_1.default.createElement(ListComponent, { anchorPos: anchorPos, isOpen: Boolean(isOpen), ref: menuListRef, maxWidth: maxWidth, onKeyDown: listKeydownEvent, onMouseMoveCapture: listMouseMoveHandler, onFocus: listFocusHandler, onBlur: listBlurHandler, role: "listbox", "aria-multiselectable": multiple || undefined }, renderedChildren))));
329
391
  });
330
392
  MenuContainer.displayName = 'MenuContainer';
331
393
  exports.default = MenuContainer;
package/Menu/MenuItem.js CHANGED
@@ -62,7 +62,7 @@ exports.MenuItem = react_1.default.forwardRef((props, ref) => {
62
62
  }
63
63
  return react_1.default.createElement(ItemIconWrapper, null, startIcon);
64
64
  }, [startIcon]);
65
- return (react_1.default.createElement(StyledMenuItem, Object.assign({}, nativeProps, { ref: ref, onMouseLeave: onMouseLeave, onMouseEnter: onMouseEnter, onClick: onClick, selected: selected, hovered: hovered }),
65
+ return (react_1.default.createElement(StyledMenuItem, Object.assign({}, nativeProps, { ref: ref, onMouseLeave: onMouseLeave, onMouseEnter: onMouseEnter, onClick: onClick, role: "option", "aria-selected": selected, selected: selected, hovered: hovered }),
66
66
  renderStartIcon(),
67
67
  children));
68
68
  });
@@ -21,8 +21,6 @@ const react_1 = __importDefault(require("react"));
21
21
  const AutoHeightWrapper_1 = __importDefault(require("./AutoHeightWrapper"));
22
22
  const VirtualizedListComponent_1 = __importDefault(require("./VirtualizedListComponent"));
23
23
  __exportStar(require("./VirtualizedListComponent"), exports);
24
- const VirtualizedList = react_1.default.forwardRef((props, ref) => {
25
- return (react_1.default.createElement(AutoHeightWrapper_1.default, null, height => height > 0 && react_1.default.createElement(VirtualizedListComponent_1.default, Object.assign({}, props, { height: height, ref: ref }))));
26
- });
24
+ const VirtualizedList = react_1.default.forwardRef((props, ref) => (react_1.default.createElement(AutoHeightWrapper_1.default, null, height => height > 0 && react_1.default.createElement(VirtualizedListComponent_1.default, Object.assign({}, props, { height: height, ref: ref })))));
27
25
  VirtualizedList.displayName = 'VirtualizedList';
28
26
  exports.default = VirtualizedList;
package/Menu/context.js CHANGED
@@ -18,6 +18,11 @@ exports.defaultState = {
18
18
  const reducer = (state, action) => {
19
19
  switch (action.type) {
20
20
  case 'setMenuState': {
21
+ const keys = Object.keys(action.payload);
22
+ // Keep the state object when nothing changes, so the menu is not re-rendered
23
+ if (keys.every(key => state[key] === action.payload[key])) {
24
+ return state;
25
+ }
21
26
  return Object.assign(Object.assign({}, state), action.payload);
22
27
  }
23
28
  default:
@@ -7,12 +7,17 @@ const react_1 = __importDefault(require("react"));
7
7
  const react_2 = require("@emotion/react");
8
8
  const context_1 = require("./context");
9
9
  const TabManager_1 = __importDefault(require("../../utils/TabManager"));
10
+ /**
11
+ * Count of the modals which lock the body scroll
12
+ */
13
+ let bodyLocksCount = 0;
10
14
  const ModalWrapper = props => {
11
15
  const { children, isOpen: isOpenProp, autofocus = true } = props;
12
16
  const { state, dispatch } = (0, context_1.useContext)();
13
- const initialOpenStateRef = react_1.default.useRef(isOpenProp);
14
- const [alreadyMounted, setMountState] = react_1.default.useState(true);
15
17
  const { closeOnEscape, isMounted, isOpen, destroyTimeout, onRequestClose } = state;
18
+ const timerRef = react_1.default.useRef(null);
19
+ const bodyLockedRef = react_1.default.useRef(false);
20
+ const isFirstRunRef = react_1.default.useRef(true);
16
21
  const containerRef = react_1.default.useRef(null);
17
22
  const id = context_1.PORTAL_ID + react_1.default.useId();
18
23
  react_1.default.useEffect(() => {
@@ -53,13 +58,34 @@ const ModalWrapper = props => {
53
58
  (_a = outer.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(outer);
54
59
  return widthNoScroll - widthWithScroll;
55
60
  }, []);
61
+ const lockBody = react_1.default.useCallback(() => {
62
+ var _a;
63
+ if (!bodyLockedRef.current) {
64
+ bodyLockedRef.current = true;
65
+ bodyLocksCount += 1;
66
+ (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.classList.add('-modal-over');
67
+ }
68
+ }, []);
69
+ const unlockBody = react_1.default.useCallback(() => {
70
+ var _a;
71
+ if (bodyLockedRef.current) {
72
+ bodyLockedRef.current = false;
73
+ bodyLocksCount = Math.max(0, bodyLocksCount - 1);
74
+ if (bodyLocksCount === 0) {
75
+ (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.classList.remove('-modal-over');
76
+ }
77
+ }
78
+ }, []);
56
79
  /**
57
80
  * Component will unmount
58
- * Mark component as unmounted
81
+ * Clear pending timers and unlock the body scroll even if the modal is still open
59
82
  */
60
83
  react_1.default.useEffect(() => () => {
61
- setMountState(false);
62
- }, []);
84
+ if (timerRef.current) {
85
+ clearTimeout(timerRef.current);
86
+ }
87
+ unlockBody();
88
+ }, [unlockBody]);
63
89
  react_1.default.useEffect(() => {
64
90
  /**
65
91
  * The last dialog will be found and closed
@@ -101,40 +127,41 @@ const ModalWrapper = props => {
101
127
  * and sets visibility property to false otherwise
102
128
  */
103
129
  react_1.default.useEffect(() => {
104
- var _a;
105
- if (isOpen !== isOpenProp || initialOpenStateRef.current) {
106
- /**
107
- * Mark as mounted and wait minimum loop of event (15ms) then mark as open
108
- */
109
- if (isOpenProp) {
110
- dispatch((0, context_1.actionSetState)({ isMounted: true }));
111
- (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.classList.add('-modal-over');
112
- setTimeout(() => {
113
- if (alreadyMounted) {
114
- dispatch((0, context_1.actionSetState)({ isOpen: true }));
115
- }
116
- }, 120);
117
- return;
118
- }
119
- /**
120
- * Mark as closed and wait destroyTimeout then mark as unmounted
121
- */
122
- if (!isOpenProp) {
123
- dispatch((0, context_1.actionSetState)({ isOpen: false }));
124
- setTimeout(() => {
125
- var _a, _b;
126
- if (alreadyMounted) {
127
- const portal = window.document.querySelector(`#${context_1.PORTAL_ID}`);
128
- if (((_a = portal === null || portal === void 0 ? void 0 : portal.children) === null || _a === void 0 ? void 0 : _a.length) === 1) {
129
- (_b = window.document.body) === null || _b === void 0 ? void 0 : _b.classList.remove('-modal-over');
130
- }
131
- dispatch((0, context_1.actionSetState)({ isMounted: false }));
132
- }
133
- }, destroyTimeout);
134
- return;
135
- }
130
+ const isFirstRun = isFirstRunRef.current;
131
+ isFirstRunRef.current = false;
132
+ // Nothing to close on mount
133
+ if (isFirstRun && !isOpenProp) {
134
+ return;
136
135
  }
137
- }, [isOpenProp, isOpen, alreadyMounted, destroyTimeout, dispatch, getScrollWidth]);
136
+ // Previous transition (open or close) must not finish after the new one started
137
+ if (timerRef.current) {
138
+ clearTimeout(timerRef.current);
139
+ timerRef.current = null;
140
+ }
141
+ /**
142
+ * Mark as mounted and wait minimum loop of event then mark as open
143
+ */
144
+ if (isOpenProp) {
145
+ dispatch((0, context_1.actionSetState)({ isMounted: true }));
146
+ lockBody();
147
+ timerRef.current = setTimeout(() => {
148
+ timerRef.current = null;
149
+ dispatch((0, context_1.actionSetState)({ isOpen: true }));
150
+ }, 120);
151
+ return;
152
+ }
153
+ /**
154
+ * Mark as closed and wait destroyTimeout then mark as unmounted
155
+ */
156
+ dispatch((0, context_1.actionSetState)({ isOpen: false }));
157
+ timerRef.current = setTimeout(() => {
158
+ timerRef.current = null;
159
+ unlockBody();
160
+ dispatch((0, context_1.actionSetState)({ isMounted: false }));
161
+ }, destroyTimeout);
162
+ // destroyTimeout is read at the moment of closing
163
+ // eslint-disable-next-line react-hooks/exhaustive-deps
164
+ }, [isOpenProp, dispatch, lockBody, unlockBody]);
138
165
  return react_1.default.useMemo(() => isMounted ? (react_1.default.createElement("div", { ref: containerRef, tabIndex: -1, id: id },
139
166
  children,
140
167
  react_1.default.createElement(react_2.Global, { styles: (0, react_2.css) `
@@ -31,6 +31,12 @@ const context = react_1.default.createContext({ state: exports.defaultState, dis
31
31
  const ContextProvider = props => {
32
32
  const { children, initialState } = props;
33
33
  const [state, dispatch] = react_1.default.useReducer(reducer, Object.assign(Object.assign({}, exports.defaultState), initialState));
34
+ // Keep the props up to date (isOpen is managed by ModalWrapper itself),
35
+ // otherwise a stale onRequestClose callback would be called
36
+ const { onRequestClose, closeOnEscape, closeOnOverlayClick, destroyTimeout } = initialState;
37
+ react_1.default.useEffect(() => {
38
+ dispatch((0, exports.actionSetState)({ onRequestClose, closeOnEscape, closeOnOverlayClick, destroyTimeout }));
39
+ }, [onRequestClose, closeOnEscape, closeOnOverlayClick, destroyTimeout]);
34
40
  return react_1.default.createElement(context.Provider, { value: { state, dispatch } }, children);
35
41
  };
36
42
  exports.ContextProvider = ContextProvider;
@@ -14,7 +14,6 @@ const RenderModal_1 = __importDefault(require("./RenderModal"));
14
14
  const NoSSR_1 = __importDefault(require("../../NoSSR"));
15
15
  const BaseModal = props => {
16
16
  const { isOpen, children, overrides, autofocus = true, closeOnOverlayClick = context_1.defaultState.closeOnOverlayClick, closeOnEscape = context_1.defaultState.closeOnEscape, destroyTimeout = context_1.defaultState.destroyTimeout, onRequestClose, } = props;
17
- const destroyTimeoutRef = react_1.default.useRef(null);
18
17
  const [domLoaded, setDomLoaded] = react_1.default.useState(false);
19
18
  const overridesMap = react_1.default.useMemo(() => ({
20
19
  Overlay: (overrides === null || overrides === void 0 ? void 0 : overrides.Overlay) || ModalOverlay_1.default,
@@ -26,13 +25,6 @@ const BaseModal = props => {
26
25
  * Client render detection
27
26
  */
28
27
  setDomLoaded(true);
29
- const timeout = destroyTimeoutRef.current;
30
- // unload destroy timeout
31
- return () => {
32
- if (timeout) {
33
- clearTimeout(timeout);
34
- }
35
- };
36
28
  }, []);
37
29
  const portalEl = react_1.default.useMemo(() => {
38
30
  if (typeof window === 'undefined') {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Unique and SSR-stable id of a modal, used to link its title and content by aria attributes.
3
+ * The colons of React.useId are removed, so the id can be used in CSS selectors too
4
+ */
5
+ declare const useDialogID: (prefix: string) => string;
6
+ export default useDialogID;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ /**
8
+ * Unique and SSR-stable id of a modal, used to link its title and content by aria attributes.
9
+ * The colons of React.useId are removed, so the id can be used in CSS selectors too
10
+ */
11
+ const useDialogID = (prefix) => `${prefix}-${react_1.default.useId().replace(/:/g, '')}`;
12
+ exports.default = useDialogID;
@@ -23,6 +23,10 @@ const StyledConfirmBoxContainer = styled_1.default.div `
23
23
  `;
24
24
  const ConfirmBoxContainer = (props, ref) => {
25
25
  const { children, dialogID } = props, nativeProps = __rest(props, ["children", "dialogID"]);
26
- return (react_1.default.createElement(StyledConfirmBoxContainer, Object.assign({ role: "modal-confirmbox", "aria-labelledby": `${dialogID}-title`, "aria-describedby": `${dialogID}-description` }, nativeProps, { ref: ref }), children));
26
+ return (react_1.default.createElement(StyledConfirmBoxContainer
27
+ // A confirmation requires the user's response
28
+ , Object.assign({
29
+ // A confirmation requires the user's response
30
+ role: "alertdialog", "aria-modal": "true", "aria-labelledby": `${dialogID}-title`, "aria-describedby": `${dialogID}-description` }, nativeProps, { ref: ref }), children));
27
31
  };
28
32
  exports.default = react_1.default.forwardRef(ConfirmBoxContainer);
@@ -21,9 +21,10 @@ const ConfirmBoxContent_1 = __importDefault(require("./ConfirmBoxContent"));
21
21
  const ConfirmBoxFooter_1 = __importDefault(require("./ConfirmBoxFooter"));
22
22
  const ConfirmBoxHeader_1 = __importDefault(require("./ConfirmBoxHeader"));
23
23
  const ModalOverlay_1 = __importDefault(require("../BaseModal/ModalOverlay"));
24
+ const useDialogID_1 = __importDefault(require("../BaseModal/useDialogID"));
24
25
  const ConfirmBox = props => {
25
26
  const { header, children, onRequestYes, onRequestClose, overrides, isOpen, dismissButtonLabel, confirmButtonLabel } = props, otherProps = __rest(props, ["header", "children", "onRequestYes", "onRequestClose", "overrides", "isOpen", "dismissButtonLabel", "confirmButtonLabel"]);
26
- const dialogID = react_1.default.useMemo(() => `dialog-confirm-${new Date().getTime()}`, []);
27
+ const dialogID = (0, useDialogID_1.default)('dialog-confirm');
27
28
  const overridesMap = react_1.default.useMemo(() => ({
28
29
  Container: (overrides === null || overrides === void 0 ? void 0 : overrides.Container) || ConfirmBoxContainer_1.default,
29
30
  Content: (overrides === null || overrides === void 0 ? void 0 : overrides.Content) || ConfirmBoxContent_1.default,
@@ -22,6 +22,6 @@ const StyledDialogInner = (0, styled_1.default)(ModalInner_1.default) `
22
22
  `;
23
23
  const DialogInner = (props, ref) => {
24
24
  const { children, dialogID } = props, restProps = __rest(props, ["children", "dialogID"]);
25
- return (react_1.default.createElement(StyledDialogInner, Object.assign({ id: `${dialogID}-description` }, restProps, { ref: ref }), children));
25
+ return (react_1.default.createElement(StyledDialogInner, Object.assign({ role: "dialog", "aria-modal": "true", id: `${dialogID}-description` }, restProps, { ref: ref }), children));
26
26
  };
27
27
  exports.default = react_1.default.forwardRef(DialogInner);
@@ -40,14 +40,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
40
40
  const React = __importStar(require("react"));
41
41
  const BaseModal_1 = __importDefault(require("../BaseModal"));
42
42
  const DialogInner_1 = __importDefault(require("./DialogInner"));
43
+ const useDialogID_1 = __importDefault(require("../BaseModal/useDialogID"));
43
44
  const Dialog = props => {
44
- var _a;
45
45
  const { children, overrides } = props, restProps = __rest(props, ["children", "overrides"]);
46
- const dialogID = React.useMemo(() => `dialog-${new Date().getTime()}`, []);
47
- return (React.createElement(React.Fragment, null,
48
- React.createElement(BaseModal_1.default, Object.assign({}, restProps, { overrides: Object.assign(Object.assign({}, overrides), { Inner: (_a = overrides === null || overrides === void 0 ? void 0 : overrides.Inner) !== null && _a !== void 0 ? _a : React.forwardRef(function Inner(props, ref) {
49
- const { children } = props;
50
- return (React.createElement(DialogInner_1.default, Object.assign({ dialogID: dialogID, ref: ref }, props), children));
51
- }) }) }), children)));
46
+ const dialogID = (0, useDialogID_1.default)('dialog');
47
+ // Created once: a component created during the render is a new type on every render,
48
+ // so React would remount the whole dialog content (inputs lose the focus and the state)
49
+ const Inner = React.useMemo(() => {
50
+ var _a;
51
+ return (_a = overrides === null || overrides === void 0 ? void 0 : overrides.Inner) !== null && _a !== void 0 ? _a : React.forwardRef(function Inner(innerProps, ref) {
52
+ return React.createElement(DialogInner_1.default, Object.assign({ dialogID: dialogID, ref: ref }, innerProps));
53
+ });
54
+ }, [overrides === null || overrides === void 0 ? void 0 : overrides.Inner, dialogID]);
55
+ const modalOverrides = React.useMemo(() => (Object.assign(Object.assign({}, overrides), { Inner })), [overrides, Inner]);
56
+ return (React.createElement(BaseModal_1.default, Object.assign({}, restProps, { overrides: modalOverrides }), children));
52
57
  };
53
58
  exports.default = Dialog;
@@ -8,6 +8,16 @@ export type DrawerHeaderProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'titl
8
8
  * Display close button in the header
9
9
  */
10
10
  readonly showCloseButton?: boolean;
11
+ /**
12
+ * Accessible label of the close button\
13
+ * \
14
+ * **Default**: `'Close'`
15
+ */
16
+ readonly closeButtonLabel?: string;
17
+ /**
18
+ * Drawer unique ID, the title gets the `${dialogID}-title` id for `aria-labelledby`
19
+ */
20
+ readonly dialogID?: string;
11
21
  /**
12
22
  * On close request
13
23
  */
@@ -22,6 +32,16 @@ declare const _default: React.ForwardRefExoticComponent<Omit<React.HTMLAttribute
22
32
  * Display close button in the header
23
33
  */
24
34
  readonly showCloseButton?: boolean | undefined;
35
+ /**
36
+ * Accessible label of the close button\
37
+ * \
38
+ * **Default**: `'Close'`
39
+ */
40
+ readonly closeButtonLabel?: string | undefined;
41
+ /**
42
+ * Drawer unique ID, the title gets the `${dialogID}-title` id for `aria-labelledby`
43
+ */
44
+ readonly dialogID?: string | undefined;
25
45
  /**
26
46
  * On close request
27
47
  */