@jetbrains/ring-ui 4.1.0-beta.9 → 4.1.4

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 (438) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +22 -16
  3. package/babel.config.js +3 -2
  4. package/components/alert/alert.js +9 -3
  5. package/components/alert/container.css +1 -1
  6. package/components/alert-service/alert-service.examples.css +18 -0
  7. package/components/alert-service/alert-service.examples.js +21 -0
  8. package/components/alert-service/alert-service.js +10 -3
  9. package/components/analytics/analytics__fus-plugin.js +1 -1
  10. package/components/auth/auth.test.js +14 -7
  11. package/components/auth/auth__core.js +64 -33
  12. package/components/auth-dialog/auth-dialog.js +1 -0
  13. package/components/avatar/avatar.css +4 -1
  14. package/components/avatar/avatar.examples.js +3 -2
  15. package/components/avatar/avatar.js +31 -6
  16. package/components/avatar/fallback-avatar.js +136 -0
  17. package/components/avatar-editor-ng/avatar-editor-ng.css +2 -2
  18. package/components/avatar-editor-ng/avatar-editor-ng.js +2 -1
  19. package/components/avatar-editor-ng/{avatar-editor-ng.html → avatar-editor-ng__template.js} +2 -2
  20. package/components/button/button.css +2 -2
  21. package/components/button/button.js +4 -1
  22. package/components/button-group/button-group.js +1 -1
  23. package/components/button-group/caption.js +1 -1
  24. package/components/button-ng/button-ng.js +1 -1
  25. package/components/button-set-ng/button-set-ng.js +3 -1
  26. package/components/checkbox/checkbox.css +1 -1
  27. package/components/code/code.js +1 -1
  28. package/components/confirm/confirm.js +1 -0
  29. package/components/confirm-service/confirm-service.js +5 -5
  30. package/components/content-layout/content-layout.css +1 -1
  31. package/components/data-list/data-list.css +1 -1
  32. package/components/date-picker/date-input.js +5 -4
  33. package/components/date-picker/date-picker.css +34 -22
  34. package/components/date-picker/date-picker.examples.js +1 -1
  35. package/components/date-picker/date-picker.js +16 -14
  36. package/components/date-picker/date-popup.js +22 -7
  37. package/components/date-picker/month-names.js +8 -5
  38. package/components/date-picker/month.js +6 -2
  39. package/components/date-picker/weekdays.js +10 -2
  40. package/components/dialog/dialog.examples.js +3 -1
  41. package/components/dialog/dialog.js +5 -2
  42. package/components/dialog/dialog.test.js +1 -1
  43. package/components/dialog/dialog__body-scroll-preventer.js +2 -2
  44. package/components/dialog-ng/dialog-ng.js +7 -8
  45. package/components/dialog-ng/{dialog-ng.html → dialog-ng__template.js} +2 -2
  46. package/components/dropdown/anchor.js +1 -0
  47. package/components/dropdown/dropdown.examples.js +36 -1
  48. package/components/dropdown-menu/dropdown-menu.examples.js +47 -0
  49. package/components/dropdown-menu/dropdown-menu.js +117 -0
  50. package/components/dropdown-menu/dropdown-menu.test.js +76 -0
  51. package/components/error-bubble/error-bubble-legacy.css +1 -1
  52. package/components/error-bubble/error-bubble.css +1 -1
  53. package/components/error-bubble/error-bubble.examples.js +1 -1
  54. package/components/error-page/error-page.css +2 -2
  55. package/components/footer-ng/footer-ng.js +13 -3
  56. package/components/form/form.css +2 -2
  57. package/components/form-ng/form-ng.js +3 -1
  58. package/components/global/global.css +1 -1
  59. package/components/global/theme.js +1 -1
  60. package/components/global/variables.css +8 -1
  61. package/components/grid/grid.css +10 -9
  62. package/components/header/header.css +1 -1
  63. package/components/header/header.examples.js +7 -8
  64. package/components/header/profile.js +10 -11
  65. package/components/http/http.js +1 -1
  66. package/components/icon/icon.css +5 -4
  67. package/components/island/island.css +4 -3
  68. package/components/island-legacy/island-legacy.css +3 -1
  69. package/components/list/list.js +6 -1
  70. package/components/list/list__custom.js +9 -3
  71. package/components/list/list__item.js +8 -2
  72. package/components/list/list__link.js +2 -1
  73. package/components/loader-inline/loader-inline.css +1 -1
  74. package/components/loader-screen/loader-screen.css +1 -1
  75. package/components/message/message.css +1 -1
  76. package/components/message/message.examples.js +8 -5
  77. package/components/pager/pager.js +5 -3
  78. package/components/permissions/permissions.js +1 -1
  79. package/components/progress-bar/progress-bar.css +1 -1
  80. package/components/progress-bar/progress-bar.examples.js +3 -3
  81. package/components/progress-bar/progress-bar.js +5 -2
  82. package/components/progress-bar/progress-bar.test.js +12 -13
  83. package/components/progress-bar-ng/progress-bar-ng.examples.js +3 -3
  84. package/components/query-assist/query-assist.css +13 -3
  85. package/components/query-assist/query-assist.examples.js +3 -1
  86. package/components/query-assist/query-assist.js +56 -12
  87. package/components/query-assist/query-assist.test.js +37 -5
  88. package/components/save-field-ng/save-field-ng.css +0 -3
  89. package/components/save-field-ng/save-field-ng.js +3 -1
  90. package/components/save-field-ng/{save-field-ng.html → save-field-ng__template.js} +2 -2
  91. package/components/select/select.css +12 -7
  92. package/components/select/select.examples.js +13 -0
  93. package/components/select/select.js +30 -43
  94. package/components/select/select.test.js +4 -5
  95. package/components/shortcuts-hint-ng/shortcuts-hint-ng.css +1 -1
  96. package/components/shortcuts-hint-ng/shortcuts-hint-ng.js +1 -1
  97. package/components/shortcuts-hint-ng/{shortcuts-hint-ng.html → shortcuts-hint-ng__template.js} +2 -2
  98. package/components/sidebar/sidebar.css +1 -0
  99. package/components/sidebar-ng/sidebar-ng.js +6 -2
  100. package/components/sidebar-ng/{sidebar-ng__button.html → sidebar-ng__button-template.js} +2 -2
  101. package/components/sidebar-ng/{sidebar-ng.html → sidebar-ng__template.js} +2 -2
  102. package/components/table/row.js +2 -1
  103. package/components/table/table.css +2 -1
  104. package/components/table-legacy/table-legacy.css +2 -2
  105. package/components/table-legacy/table-legacy__toolbar.css +2 -2
  106. package/components/table-legacy-ng/table-legacy-ng.js +38 -5
  107. package/components/table-legacy-ng/table-legacy-ng__pager.js +7 -1
  108. package/components/tabs/collapsible-tab.js +2 -2
  109. package/components/tabs/collapsible-tabs.js +4 -8
  110. package/components/tabs/dumb-tabs.js +1 -0
  111. package/components/tabs/tab-link.js +4 -2
  112. package/components/tabs/tabs.css +27 -0
  113. package/components/tabs-ng/tabs-ng.js +4 -2
  114. package/components/tabs-ng/{tabs-ng.html → tabs-ng__template.js} +6 -2
  115. package/components/tag/tag.css +5 -2
  116. package/components/tag/tag.examples.js +3 -0
  117. package/components/tag/tag.js +19 -16
  118. package/components/tags-input/tag-input.examples.js +1 -1
  119. package/components/tags-input/tags-input.js +5 -2
  120. package/components/template-ng/template-ng.js +1 -1
  121. package/components/tooltip/tooltip.js +7 -2
  122. package/components/user-agreement/user-agreement.css +1 -1
  123. package/components/user-agreement/user-agreement.examples.js +7 -4
  124. package/components/user-agreement/user-agreement.js +1 -0
  125. package/dist/_helpers/_rollupPluginBabelHelpers.js +1 -94
  126. package/dist/_helpers/anchor.js +6 -6
  127. package/dist/_helpers/badge.js +1 -1
  128. package/dist/_helpers/button-group.js +3 -0
  129. package/dist/_helpers/button-set.js +3 -0
  130. package/dist/_helpers/button-toolbar.js +3 -0
  131. package/dist/_helpers/button__classes.js +1 -1
  132. package/dist/_helpers/card.js +6 -8
  133. package/dist/_helpers/checkbox.js +3 -0
  134. package/dist/_helpers/date-picker.js +1 -1
  135. package/dist/_helpers/dialog__body-scroll-preventer.js +3 -2
  136. package/dist/_helpers/error-message.js +3 -0
  137. package/dist/_helpers/footer.js +121 -0
  138. package/dist/_helpers/grid.js +1 -1
  139. package/dist/_helpers/group.js +3 -0
  140. package/dist/_helpers/header.js +1 -1
  141. package/dist/_helpers/icon.js +3 -0
  142. package/dist/_helpers/inject-styles.js +1 -1
  143. package/dist/_helpers/input.js +3 -0
  144. package/dist/_helpers/island.js +1 -1
  145. package/dist/_helpers/link.js +3 -0
  146. package/dist/_helpers/list.js +1 -1
  147. package/dist/_helpers/loader-screen.js +3 -0
  148. package/dist/_helpers/panel.js +3 -0
  149. package/dist/_helpers/query-assist__suggestions.js +1 -1
  150. package/dist/_helpers/radio.js +3 -0
  151. package/dist/_helpers/select__filter.js +6 -8
  152. package/dist/_helpers/services-link.js +6 -8
  153. package/dist/_helpers/sidebar.js +6 -8
  154. package/dist/_helpers/table.js +1 -1
  155. package/dist/_helpers/tabs.js +1 -1
  156. package/dist/_helpers/title.js +1 -1
  157. package/dist/alert/alert.js +15 -9
  158. package/dist/alert/container.js +7 -9
  159. package/dist/alert-service/alert-service.js +24 -13
  160. package/dist/analytics/analytics.js +2 -2
  161. package/dist/analytics/analytics__custom-plugin.js +1 -1
  162. package/dist/analytics/analytics__fus-plugin.js +2 -2
  163. package/dist/analytics/analytics__ga-plugin.js +1 -1
  164. package/dist/analytics/analytics__plugin-utils.js +1 -1
  165. package/dist/analytics-ng/analytics-ng.js +94 -0
  166. package/dist/auth/auth.js +7 -4
  167. package/dist/auth/auth__core.js +86 -48
  168. package/dist/auth/background-flow.js +1 -2
  169. package/dist/auth/down-notification.js +6 -3
  170. package/dist/auth/iframe-flow.js +5 -2
  171. package/dist/auth/landing-entry.js +1 -1
  172. package/dist/auth/landing.js +5 -2
  173. package/dist/auth/request-builder.js +1 -1
  174. package/dist/auth/response-parser.js +1 -1
  175. package/dist/auth/storage.js +3 -2
  176. package/dist/auth/token-validator.js +1 -1
  177. package/dist/auth/window-flow.js +1 -1
  178. package/dist/auth-dialog/auth-dialog.js +5 -3
  179. package/dist/auth-dialog-service/auth-dialog-service.js +6 -5
  180. package/dist/auth-ng/auth-ng.js +203 -0
  181. package/dist/auth-ng/auth-ng.mock.js +33 -0
  182. package/dist/autofocus-ng/autofocus-ng.js +50 -0
  183. package/dist/avatar/avatar.js +36 -30
  184. package/dist/avatar/fallback-avatar.js +141 -0
  185. package/dist/avatar-editor-ng/avatar-editor-ng.js +164 -0
  186. package/dist/avatar-editor-ng/avatar-editor-ng__template.js +30 -0
  187. package/dist/avatar-ng/avatar-ng.js +18 -0
  188. package/dist/badge/badge.js +6 -8
  189. package/dist/badge-ng/badge-ng.js +16 -0
  190. package/dist/breadcrumb-ng/breadcrumb-ng.js +61 -0
  191. package/dist/button/button.js +16 -10
  192. package/dist/button-group/button-group.js +4 -4
  193. package/dist/button-group/caption.js +24 -5
  194. package/dist/button-group-ng/button-group-ng.js +38 -0
  195. package/dist/button-ng/button-ng.js +223 -0
  196. package/dist/button-set/button-set.js +3 -4
  197. package/dist/button-set-ng/button-set-ng.js +19 -0
  198. package/dist/button-toolbar/button-toolbar.js +3 -4
  199. package/dist/button-toolbar-ng/button-toolbar-ng.js +23 -0
  200. package/dist/caret/caret.js +1 -1
  201. package/dist/checkbox/checkbox.js +9 -11
  202. package/dist/checkbox-ng/checkbox-ng.js +55 -0
  203. package/dist/code/code.js +136 -0
  204. package/dist/compiler-ng/compiler-ng.js +53 -0
  205. package/dist/confirm/confirm.js +6 -3
  206. package/dist/confirm-ng/confirm-ng.js +66 -0
  207. package/dist/confirm-service/confirm-service.js +12 -10
  208. package/dist/content-layout/content-layout.js +6 -8
  209. package/dist/contenteditable/contenteditable.js +13 -16
  210. package/dist/data-list/data-list.js +10 -7
  211. package/dist/data-list/data-list.mock.js +2 -2
  212. package/dist/data-list/item.js +5 -3
  213. package/dist/data-list/selection.js +1 -1
  214. package/dist/data-list/title.js +3 -1
  215. package/dist/data-list-ng/data-list-ng.js +59 -0
  216. package/dist/date-picker/consts.js +1 -2
  217. package/dist/date-picker/date-input.js +10 -6
  218. package/dist/date-picker/date-picker.js +38 -29
  219. package/dist/date-picker/date-popup.js +51 -28
  220. package/dist/date-picker/day.js +2 -2
  221. package/dist/date-picker/formats.js +1 -1
  222. package/dist/date-picker/month-names.js +16 -9
  223. package/dist/date-picker/month-slider.js +2 -2
  224. package/dist/date-picker/month.js +13 -7
  225. package/dist/date-picker/months.js +3 -3
  226. package/dist/date-picker/weekdays.js +12 -4
  227. package/dist/date-picker/years.js +2 -2
  228. package/dist/dialog/dialog.js +13 -10
  229. package/dist/dialog/dialog__body-scroll-preventer.js +1 -1
  230. package/dist/dialog-ng/dialog-ng.js +601 -0
  231. package/dist/dialog-ng/dialog-ng__template.js +71 -0
  232. package/dist/docked-panel-ng/docked-panel-ng.js +170 -0
  233. package/dist/dropdown/anchor.js +2 -1
  234. package/dist/dropdown/dropdown.js +8 -10
  235. package/dist/dropdown-menu/dropdown-menu.js +175 -0
  236. package/dist/error-bubble/error-bubble.js +7 -9
  237. package/dist/error-message/error-message.js +4 -4
  238. package/dist/error-message-ng/error-message-ng.js +53 -0
  239. package/dist/footer/footer.js +6 -122
  240. package/dist/footer-ng/footer-ng.js +75 -0
  241. package/dist/form-ng/form-ng.js +169 -0
  242. package/dist/global/angular-component-factory.js +1 -2
  243. package/dist/global/compose.js +1 -1
  244. package/dist/global/composeRefs.js +1 -1
  245. package/dist/global/conic-gradient.js +3 -5
  246. package/dist/global/create-stateful-context.js +1 -1
  247. package/dist/global/data-tests.js +1 -1
  248. package/dist/global/focus-sensor-hoc.js +9 -11
  249. package/dist/global/fuzzy-highlight.js +1 -1
  250. package/dist/global/get-event-key.js +1 -1
  251. package/dist/global/get-uid.js +1 -1
  252. package/dist/global/linear-function.js +1 -2
  253. package/dist/global/listeners.js +1 -1
  254. package/dist/global/memoize.js +1 -1
  255. package/dist/global/normalize-indent.js +1 -1
  256. package/dist/global/promise-with-timeout.js +1 -1
  257. package/dist/global/radial-gradient-mask.js +1 -1
  258. package/dist/global/react-dom-renderer.js +1 -1
  259. package/dist/global/rerender-hoc.js +3 -5
  260. package/dist/global/ring-angular-component.js +1 -1
  261. package/dist/global/schedule-raf.js +1 -1
  262. package/dist/global/sniffer.js +1 -1
  263. package/dist/global/supports-css.js +1 -1
  264. package/dist/global/theme.js +6 -8
  265. package/dist/global/trivial-template-tag.js +1 -1
  266. package/dist/global/variables_dark.js +1 -1
  267. package/dist/grid/col.js +6 -8
  268. package/dist/grid/grid.js +5 -7
  269. package/dist/grid/row.js +6 -8
  270. package/dist/group/group.js +7 -10
  271. package/dist/group-ng/group-ng.js +11 -0
  272. package/dist/header/header.js +29 -26
  273. package/dist/header/logo.js +8 -9
  274. package/dist/header/profile.js +37 -32
  275. package/dist/header/services-link.js +1 -0
  276. package/dist/header/services.js +10 -9
  277. package/dist/header/smart-profile.js +27 -24
  278. package/dist/header/smart-services.js +10 -9
  279. package/dist/header/tray-icon.js +12 -12
  280. package/dist/header/tray.js +6 -8
  281. package/dist/heading/heading.js +9 -12
  282. package/dist/http/http.js +37 -37
  283. package/dist/http/http.mock.js +4 -4
  284. package/dist/hub-source/hub-source.js +1 -1
  285. package/dist/hub-source/hub-source__users-groups.js +1 -1
  286. package/dist/icon/icon.js +8 -8
  287. package/dist/icon/icon__svg.js +81 -6
  288. package/dist/icon/index.js +2 -1
  289. package/dist/icon-ng/icon-ng.js +89 -0
  290. package/dist/input/input.js +9 -12
  291. package/dist/input-ng/input-ng.js +166 -0
  292. package/dist/island/adaptive-island-hoc.js +1 -2
  293. package/dist/island/content.js +6 -8
  294. package/dist/island/header.js +6 -8
  295. package/dist/island/island.js +6 -9
  296. package/dist/island-legacy/content-legacy.js +6 -8
  297. package/dist/island-legacy/header-legacy.js +6 -8
  298. package/dist/island-legacy/island-legacy.js +6 -8
  299. package/dist/island-ng/island-content-ng.js +56 -0
  300. package/dist/island-ng/island-header-ng.js +32 -0
  301. package/dist/island-ng/island-ng-class-fixer.js +9 -0
  302. package/dist/island-ng/island-ng.js +31 -0
  303. package/dist/link/clickableLink.js +6 -8
  304. package/dist/link/link.js +7 -11
  305. package/dist/link-ng/link-ng.js +25 -0
  306. package/dist/list/list.js +25 -13
  307. package/dist/list/list__custom.js +13 -10
  308. package/dist/list/list__hint.js +1 -1
  309. package/dist/list/list__item.js +20 -13
  310. package/dist/list/list__link.js +11 -12
  311. package/dist/list/list__separator.js +1 -1
  312. package/dist/list/list__title.js +1 -1
  313. package/dist/list/list__users-groups-source.js +11 -7
  314. package/dist/loader/loader.js +6 -8
  315. package/dist/loader/loader__core.js +2 -2
  316. package/dist/loader-inline/inject-styles.js +1 -1
  317. package/dist/loader-inline/loader-inline.js +6 -8
  318. package/dist/loader-inline-ng/loader-inline-ng.js +42 -0
  319. package/dist/loader-ng/loader-ng.js +43 -0
  320. package/dist/loader-screen/loader-screen.js +7 -10
  321. package/dist/loader-screen-ng/loader-screen-ng.js +99 -0
  322. package/dist/login-dialog/login-dialog.js +5 -3
  323. package/dist/login-dialog/service.js +7 -5
  324. package/dist/markdown/code.js +30 -0
  325. package/dist/markdown/heading.js +23 -0
  326. package/dist/markdown/link.js +30 -0
  327. package/dist/markdown/markdown.js +73 -0
  328. package/dist/message/message.js +5 -4
  329. package/dist/message-bundle-ng/message-bundle-ng.js +111 -0
  330. package/dist/old-browsers-message/old-browsers-message.js +0 -1
  331. package/dist/old-browsers-message/old-browsers-message__stop.js +0 -1
  332. package/dist/old-browsers-message/white-list.js +4 -5
  333. package/dist/pager/pager.js +18 -9
  334. package/dist/pager-ng/pager-ng.js +96 -0
  335. package/dist/panel/panel.js +7 -10
  336. package/dist/panel-ng/panel-ng.js +16 -0
  337. package/dist/permissions/permissions.js +1 -1
  338. package/dist/permissions/permissions__cache.js +1 -1
  339. package/dist/permissions-ng/permissions-ng.js +274 -0
  340. package/dist/place-under-ng/place-under-ng.js +157 -0
  341. package/dist/popup/popup.js +8 -8
  342. package/dist/popup/popup.target.js +4 -5
  343. package/dist/popup/position.js +1 -2
  344. package/dist/popup-menu/popup-menu.js +21 -14
  345. package/dist/progress-bar/progress-bar.js +12 -10
  346. package/dist/progress-bar-ng/progress-bar-ng.js +15 -0
  347. package/dist/promised-click-ng/promised-click-ng.js +126 -0
  348. package/dist/proxy-attrs/proxy-attrs.js +1 -1
  349. package/dist/query-assist/query-assist.js +97 -28
  350. package/dist/query-assist/query-assist__suggestions.js +5 -1
  351. package/dist/query-assist-ng/query-assist-ng.js +82 -0
  352. package/dist/radio/radio.js +7 -5
  353. package/dist/radio/radio__item.js +10 -15
  354. package/dist/radio-ng/radio-ng.js +63 -0
  355. package/dist/save-field-ng/save-field-ng.js +335 -0
  356. package/dist/save-field-ng/save-field-ng__template.js +34 -0
  357. package/dist/select/select.js +50 -49
  358. package/dist/select/select__filter.js +6 -1
  359. package/dist/select/select__popup.js +8 -3
  360. package/dist/select-ng/select-ng.js +621 -0
  361. package/dist/select-ng/select-ng__lazy.js +150 -0
  362. package/dist/select-ng/select-ng__options.js +145 -0
  363. package/dist/shortcuts/core.js +2 -2
  364. package/dist/shortcuts/shortcuts-hoc.js +6 -8
  365. package/dist/shortcuts/shortcuts.js +6 -6
  366. package/dist/shortcuts-hint-ng/shortcuts-hint-ng.js +120 -0
  367. package/dist/shortcuts-hint-ng/shortcuts-hint-ng__template.js +50 -0
  368. package/dist/shortcuts-ng/shortcuts-ng.js +261 -0
  369. package/dist/sidebar-ng/sidebar-ng.js +111 -0
  370. package/dist/sidebar-ng/sidebar-ng__button-template.js +20 -0
  371. package/dist/sidebar-ng/sidebar-ng__template.js +12 -0
  372. package/dist/storage/storage.js +3 -2
  373. package/dist/storage/storage__fallback.js +1 -1
  374. package/dist/storage/storage__local.js +3 -2
  375. package/dist/style.css +1 -1
  376. package/dist/tab-trap/tab-trap.js +7 -9
  377. package/dist/table/cell.js +2 -2
  378. package/dist/table/disable-hover-hoc.js +2 -2
  379. package/dist/table/header-cell.js +8 -9
  380. package/dist/table/header.js +5 -3
  381. package/dist/table/multitable.js +1 -1
  382. package/dist/table/row-with-focus-sensor.js +5 -3
  383. package/dist/table/row.js +11 -10
  384. package/dist/table/selection-adapter.js +1 -1
  385. package/dist/table/selection-shortcuts-hoc.js +8 -6
  386. package/dist/table/selection.js +1 -1
  387. package/dist/table/smart-table.js +14 -8
  388. package/dist/table/table.js +10 -11
  389. package/dist/table-legacy-ng/table-legacy-ng.js +501 -0
  390. package/dist/table-legacy-ng/table-legacy-ng__pager.js +122 -0
  391. package/dist/table-legacy-ng/table-legacy-ng__selection-navigate-actions.js +123 -0
  392. package/dist/table-legacy-ng/table-legacy-ng__selection.js +179 -0
  393. package/dist/table-legacy-ng/table-legacy-ng__toolbar.js +56 -0
  394. package/dist/table-ng/smart-table-ng.js +65 -0
  395. package/dist/table-ng/table-ng.js +64 -0
  396. package/dist/tabs/collapsible-more.js +9 -6
  397. package/dist/tabs/collapsible-tab.js +7 -7
  398. package/dist/tabs/collapsible-tabs.js +18 -19
  399. package/dist/tabs/dumb-tabs.js +12 -9
  400. package/dist/tabs/smart-tabs.js +11 -9
  401. package/dist/tabs/tab-link.js +13 -7
  402. package/dist/tabs/tab.js +1 -1
  403. package/dist/tabs/tabs.js +5 -1
  404. package/dist/tabs-ng/tabs-ng.js +193 -0
  405. package/dist/tabs-ng/tabs-ng__template.js +40 -0
  406. package/dist/tag/tag.js +20 -14
  407. package/dist/tags-input/tags-input.js +14 -10
  408. package/dist/tags-input-ng/tags-input-ng.js +89 -0
  409. package/dist/tags-list/tags-list.js +8 -9
  410. package/dist/template-ng/template-ng.js +70 -0
  411. package/dist/text/text.js +7 -9
  412. package/dist/theme-ng/theme-ng.js +44 -0
  413. package/dist/title-ng/title-ng.js +114 -0
  414. package/dist/toggle/toggle.js +8 -11
  415. package/dist/toggle-ng/toggle-ng.js +16 -0
  416. package/dist/tooltip/tooltip.js +14 -12
  417. package/dist/tooltip-ng/tooltip-ng.js +98 -0
  418. package/dist/user-agreement/service.js +409 -0
  419. package/dist/user-agreement/toolbox.eula.js +162 -0
  420. package/dist/user-agreement/user-agreement.js +167 -0
  421. package/dist/user-card/card.js +3 -0
  422. package/dist/user-card/smart-user-card-tooltip.js +14 -14
  423. package/dist/user-card/tooltip.js +9 -7
  424. package/dist/user-card/user-card.js +5 -2
  425. package/dist/user-card-ng/user-card-ng.js +59 -0
  426. package/package.json +81 -79
  427. package/webpack.config.js +14 -10
  428. package/components/button-set-ng/button-set-ng.html +0 -1
  429. package/components/footer-ng/footer-ng.html +0 -13
  430. package/components/form-ng/form-ng__error-bubble.html +0 -3
  431. package/components/table-legacy-ng/table-legacy-ng.html +0 -4
  432. package/components/table-legacy-ng/table-legacy-ng__column.html +0 -12
  433. package/components/table-legacy-ng/table-legacy-ng__header.html +0 -4
  434. package/components/table-legacy-ng/table-legacy-ng__pager.html +0 -7
  435. package/components/table-legacy-ng/table-legacy-ng__row.html +0 -12
  436. package/components/table-legacy-ng/table-legacy-ng__title.html +0 -9
  437. package/dist/_helpers/caption.js +0 -25
  438. package/dist/_helpers/icon__svg.js +0 -83
@@ -90,7 +90,8 @@ export default class DatePicker extends PureComponent {
90
90
  disabled: PropTypes.bool,
91
91
  minDate: dateType,
92
92
  maxDate: dateType,
93
- translations: PropTypes.object
93
+ translations: PropTypes.object,
94
+ locale: PropTypes.object
94
95
  };
95
96
 
96
97
  static defaultProps = {
@@ -101,10 +102,10 @@ export default class DatePicker extends PureComponent {
101
102
  from: null,
102
103
  to: null,
103
104
  clear: false,
104
- displayFormat: date => (date ? formatDate(date, 'd MMM yyyy') : ''),
105
- displayMonthFormat: date => (date ? formatDate(date, 'd MMM') : ''),
106
- displayDayFormat: date => (date ? formatDate(date, 'd') : ''),
107
- displayTimeFormat: date => (date ? formatDate(date, 'HH:mm') : ''),
105
+ displayFormat: (date, locale) => (date ? formatDate(date, 'd MMM yyyy', {locale}) : ''),
106
+ displayMonthFormat: (date, locale) => (date ? formatDate(date, 'd MMM', {locale}) : ''),
107
+ displayDayFormat: (date, locale) => (date ? formatDate(date, 'd', {locale}) : ''),
108
+ displayTimeFormat: (date, locale) => (date ? formatDate(date, 'HH:mm', {locale}) : ''),
108
109
  datePlaceholder: 'Set a date',
109
110
  dateTimePlaceholder: 'Set date and time',
110
111
  rangePlaceholder: 'Set a period',
@@ -194,7 +195,8 @@ export default class DatePicker extends PureComponent {
194
195
  displayFormat,
195
196
  displayMonthFormat,
196
197
  displayDayFormat,
197
- translations
198
+ translations,
199
+ locale
198
200
  } = this.props;
199
201
 
200
202
  const date = this.parse(this.props.date);
@@ -204,27 +206,27 @@ export default class DatePicker extends PureComponent {
204
206
 
205
207
  let text;
206
208
  if (!range && !withTime) {
207
- text = date ? displayFormat(date) : datePlaceholder || translations.setDate;
209
+ text = date ? displayFormat(date, locale) : datePlaceholder || translations.setDate;
208
210
  } else if (!range && withTime) {
209
211
  if (!date && !time) {
210
212
  text = dateTimePlaceholder || translations.setDateTime;
211
213
  } else {
212
- text = `${date && displayFormat(date) || '—'}, ${time || '—'}`;
214
+ text = `${date && displayFormat(date, locale) || '—'}, ${time || '—'}`;
213
215
  }
214
216
  } else if (!from && !to) {
215
217
  text = rangePlaceholder || translations.setPeriod;
216
218
  } else if (!to) {
217
- text = `${displayFormat(from)} —`;
219
+ text = `${displayFormat(from, locale)} —`;
218
220
  } else if (!from) {
219
- text = `— ${displayFormat(to)}`;
221
+ text = `— ${displayFormat(to, locale)}`;
220
222
  } else if (!isSameYear(from, to)) {
221
- text = `${displayFormat(from)} — ${displayFormat(to)}`;
223
+ text = `${displayFormat(from, locale)} — ${displayFormat(to, locale)}`;
222
224
  } else if (!isSameMonth(from, to)) {
223
- text = `${displayMonthFormat(from)} — ${displayFormat(to)}`;
225
+ text = `${displayMonthFormat(from, locale)} — ${displayFormat(to, locale)}`;
224
226
  } else if (!isSameDay(from, to)) {
225
- text = `${displayDayFormat(from)} — ${displayFormat(to)}`;
227
+ text = `${displayDayFormat(from, locale)} — ${displayFormat(to, locale)}`;
226
228
  } else {
227
- text = `${displayFormat(to)}`;
229
+ text = `${displayFormat(to, locale)}`;
228
230
  }
229
231
 
230
232
  return text;
@@ -47,7 +47,8 @@ export default class DatePopup extends Component {
47
47
  hidden: PropTypes.bool,
48
48
  fromPlaceholder: PropTypes.string,
49
49
  toPlaceholder: PropTypes.string,
50
- timePlaceholder: PropTypes.string
50
+ timePlaceholder: PropTypes.string,
51
+ locale: PropTypes.object
51
52
  };
52
53
 
53
54
  static defaultProps = {
@@ -77,7 +78,7 @@ export default class DatePopup extends Component {
77
78
 
78
79
  componentDidMount() {
79
80
  if (this.componentRef.current) {
80
- this.componentRef.current.addEventListener('wheel', this.handleWheel);
81
+ this.componentRef.current.addEventListener('wheel', this.handleWheel, {passive: true});
81
82
  }
82
83
  }
83
84
 
@@ -278,15 +279,26 @@ export default class DatePopup extends Component {
278
279
  handleScroll = scrollDate => this.setState({scrollDate});
279
280
 
280
281
  onClear = e => {
281
- this.setState({
282
- active: undefined
283
- });
282
+ let changes;
283
+
284
+ if (this.props.range) {
285
+ changes = {
286
+ from: null,
287
+ to: null
288
+ };
289
+
290
+ } else {
291
+ changes = {
292
+ date: null
293
+ };
294
+ }
284
295
 
296
+ this.select(changes);
285
297
  this.props.onClear(e);
286
298
  };
287
299
 
288
300
  render() {
289
- const {range, hidden, withTime, time} = this.props;
301
+ const {range, hidden, withTime, time, locale} = this.props;
290
302
  const parsedDate = this.parse(this.props.date, 'date');
291
303
  const parsedTo = this.parse(this.props.to, 'to');
292
304
 
@@ -380,6 +392,7 @@ export default class DatePopup extends Component {
380
392
  onInput={this.handleInput}
381
393
  onConfirm={this.handleConfirm(name)}
382
394
  onClear={onClear}
395
+ locale={locale}
383
396
  />
384
397
  );
385
398
  })}
@@ -402,12 +415,13 @@ export default class DatePopup extends Component {
402
415
  onInput={this.handleInput}
403
416
  onConfirm={this.handleConfirm('time')}
404
417
  onClear={clearable && this.onClear || undefined}
418
+ locale={locale}
405
419
  />
406
420
  )
407
421
  : ('')
408
422
  }
409
423
  </div>
410
- <Weekdays/>
424
+ <Weekdays locale={locale}/>
411
425
  <div
412
426
  className={styles.calendar}
413
427
  >
@@ -415,6 +429,7 @@ export default class DatePopup extends Component {
415
429
  {...calendarProps}
416
430
  onHover={this.hoverHandler}
417
431
  onSelect={this.selectHandler}
432
+ locale={locale}
418
433
  />
419
434
  <Years {...calendarProps}/>
420
435
  </div>
@@ -21,7 +21,7 @@ class MonthName extends PureComponent {
21
21
  };
22
22
 
23
23
  render() {
24
- const {month} = this.props;
24
+ const {month, locale} = this.props;
25
25
 
26
26
  return (
27
27
  <button
@@ -34,7 +34,7 @@ class MonthName extends PureComponent {
34
34
  )}
35
35
  onClick={this.handleClick}
36
36
  >
37
- {format(month, 'MMM')}
37
+ {format(month, 'LLL', {locale})}
38
38
  </button>
39
39
  );
40
40
  }
@@ -42,11 +42,12 @@ class MonthName extends PureComponent {
42
42
 
43
43
  MonthName.propTypes = {
44
44
  month: dateType,
45
- onScrollChange: PropTypes.func
45
+ onScrollChange: PropTypes.func,
46
+ locale: PropTypes.string
46
47
  };
47
48
 
48
49
  export default function MonthNames(props) {
49
- const {scrollDate} = props;
50
+ const {scrollDate, locale} = props;
50
51
  const months = [];
51
52
  for (let i = 0; i < YEAR; i++) {
52
53
  const middleDay = set(scrollDate, {month: i, date: MIDDLE_DAY});
@@ -73,6 +74,7 @@ export default function MonthNames(props) {
73
74
  key={+month}
74
75
  month={month}
75
76
  onScrollChange={props.onScrollChange}
77
+ locale={locale}
76
78
  />
77
79
  ))}
78
80
  {props.currentRange &&
@@ -97,5 +99,6 @@ export default function MonthNames(props) {
97
99
  MonthNames.propTypes = {
98
100
  scrollDate: dateType,
99
101
  onScrollChange: PropTypes.func,
100
- currentRange: PropTypes.arrayOf(dateType)
102
+ currentRange: PropTypes.arrayOf(dateType),
103
+ locale: PropTypes.string
101
104
  };
@@ -5,6 +5,8 @@ import format from 'date-fns/format';
5
5
  import getDay from 'date-fns/getDay';
6
6
  import setDay from 'date-fns/setDay';
7
7
 
8
+ import PropTypes from 'prop-types';
9
+
8
10
  import Day from './day';
9
11
  import {dateType, WEEK, weekdays} from './consts';
10
12
  import styles from './date-picker.css';
@@ -12,6 +14,7 @@ import styles from './date-picker.css';
12
14
  export default function Month(props) {
13
15
  const start = props.month;
14
16
  const end = endOfMonth(start);
17
+ const {locale} = props;
15
18
 
16
19
  // pad with empty cells starting from last friday
17
20
  const weekday = getDay(start);
@@ -25,7 +28,7 @@ export default function Month(props) {
25
28
  return (
26
29
  <div className={styles.month}>
27
30
  <span className={styles.monthTitle}>
28
- {format(props.month, 'MMMM')}
31
+ {format(props.month, 'LLLL', {locale})}
29
32
  </span>
30
33
  {days.map(date => (
31
34
  <Day
@@ -40,5 +43,6 @@ export default function Month(props) {
40
43
  }
41
44
 
42
45
  Month.propTypes = {
43
- month: dateType
46
+ month: dateType,
47
+ locale: PropTypes.string
44
48
  };
@@ -5,13 +5,17 @@ import format from 'date-fns/format';
5
5
  import setDay from 'date-fns/setDay';
6
6
  import startOfDay from 'date-fns/startOfDay';
7
7
 
8
+ import PropTypes from 'prop-types';
9
+
8
10
  import {weekdays} from './consts';
9
11
  import styles from './date-picker.css';
10
12
 
11
- export default function Weekdays() {
13
+ export default function Weekdays(props) {
12
14
  const days = Object.keys(weekdays).
13
15
  map(key => startOfDay(setDay(new Date(), weekdays[key])));
14
16
 
17
+ const {locale} = props;
18
+
15
19
  return (
16
20
  <div className={styles.weekdays}>
17
21
  {days.map(day => (
@@ -24,9 +28,13 @@ export default function Weekdays() {
24
28
  )}
25
29
  key={+day}
26
30
  >
27
- {format(day, 'EEEEEE')}
31
+ {format(day, 'EEEEEE', {locale})}
28
32
  </span>
29
33
  ))}
30
34
  </div>
31
35
  );
32
36
  }
37
+
38
+ Weekdays.propTypes = {
39
+ locale: PropTypes.string
40
+ };
@@ -55,6 +55,7 @@ export const basic = ({onAction}) => {
55
55
  </Group>
56
56
 
57
57
  <Dialog
58
+ label="Dialog"
58
59
  show={show}
59
60
  onCloseAttempt={this.cancelDialog}
60
61
  trapFocus
@@ -124,6 +125,7 @@ export const withScroll = ({onAction}) => {
124
125
  </div>
125
126
 
126
127
  <Dialog
128
+ label="Dialog"
127
129
  show={this.state.show}
128
130
  onCloseAttempt={this.cancelDialog}
129
131
  trapFocus
@@ -167,7 +169,7 @@ export const WithOverflowScrollOnHtml = () => {
167
169
  <div className="container">
168
170
  <div>Scroll down</div>
169
171
  <Button className="button" onClick={() => setOpen(true)}>Show dialog</Button>
170
- <Dialog show={open} onCloseAttempt={() => setOpen(false)}>
172
+ <Dialog label="Dialog" show={open} onCloseAttempt={() => setOpen(false)}>
171
173
  <Header>Dialog title</Header>
172
174
  </Dialog>
173
175
  </div>
@@ -13,7 +13,7 @@ import Button from '../button/button';
13
13
 
14
14
  import {PopupTarget} from '../popup/popup.target';
15
15
 
16
- import scrollPreventerFactory from './dialog__body-scroll-preventer';
16
+ import {preventerFactory as scrollPreventerFactory} from './dialog__body-scroll-preventer';
17
17
  import styles from './dialog.css';
18
18
 
19
19
  /**
@@ -24,6 +24,7 @@ function noop() {}
24
24
 
25
25
  export default class Dialog extends PureComponent {
26
26
  static propTypes = {
27
+ label: PropTypes.string,
27
28
  className: PropTypes.string,
28
29
  contentClassName: PropTypes.string,
29
30
  children: PropTypes.oneOfType([
@@ -47,6 +48,7 @@ export default class Dialog extends PureComponent {
47
48
  };
48
49
 
49
50
  static defaultProps = {
51
+ label: 'Dialog',
50
52
  onOverlayClick: noop,
51
53
  onEscPress: noop,
52
54
  onCloseClick: noop,
@@ -117,7 +119,7 @@ export default class Dialog extends PureComponent {
117
119
  render() {
118
120
  const {show, showCloseButton, onOverlayClick, onCloseAttempt, onEscPress, onCloseClick,
119
121
  children, className, contentClassName, trapFocus, 'data-test': dataTest, closeButtonInside,
120
- portalTarget, ...restProps} = this.props;
122
+ portalTarget, label, ...restProps} = this.props;
121
123
  const classes = classNames(styles.container, className);
122
124
  const shortcutsMap = this.getShortcutsMap();
123
125
 
@@ -150,6 +152,7 @@ export default class Dialog extends PureComponent {
150
152
  className={classNames(styles.content, contentClassName)}
151
153
  data-test="ring-dialog"
152
154
  role="dialog"
155
+ aria-label={label}
153
156
  >
154
157
  {children}
155
158
  {showCloseButton &&
@@ -6,7 +6,7 @@ import styles from './dialog.css';
6
6
 
7
7
  describe('Dialog', () => {
8
8
  const children = <div/>;
9
- const mountDialog = props => mount(<Dialog {...props} trapFocus={false}/>);
9
+ const mountDialog = props => mount(<Dialog label="Dialog" {...props} trapFocus={false}/>);
10
10
 
11
11
  it('should create component', () => {
12
12
  mountDialog({show: true, children}).should.have.type(Dialog);
@@ -47,7 +47,7 @@ const reset = key => {
47
47
  }
48
48
  };
49
49
 
50
- const preventerFactory = key => {
50
+ export const preventerFactory = key => {
51
51
  const preventerKey = key || Math.random();
52
52
 
53
53
  return {
@@ -56,4 +56,4 @@ const preventerFactory = key => {
56
56
  };
57
57
  };
58
58
 
59
- export default preventerFactory;
59
+ export default preventerFactory('default-preventer');
@@ -1,7 +1,5 @@
1
1
  import angular from 'angular';
2
2
 
3
- import angularSanitize from 'angular-sanitize';
4
-
5
3
  import {createFocusTrap} from 'focus-trap';
6
4
 
7
5
  import {getRect, getStyles} from '../global/dom';
@@ -10,12 +8,13 @@ import shortcuts from '../shortcuts/core';
10
8
  import RingButton from '../button-ng/button-ng';
11
9
  import PromisedClickNg from '../promised-click-ng/promised-click-ng';
12
10
  import rgCompilerModuleName from '../compiler-ng/compiler-ng';
13
- import scrollPreventerFactory from '../dialog/dialog__body-scroll-preventer';
11
+ import {preventerFactory as scrollPreventerFactory} from '../dialog/dialog__body-scroll-preventer';
14
12
  import '../form/form.css';
15
13
  import dialogStyles from '../dialog/dialog.css';
16
14
  import islandStyles from '../island/island.css';
17
15
 
18
16
  import styles from './dialog-ng.css';
17
+ import dialogTemplate from './dialog-ng__template';
19
18
 
20
19
  /**
21
20
  * @name Dialog Ng
@@ -23,12 +22,12 @@ import styles from './dialog-ng.css';
23
22
 
24
23
  const angularModule = angular.module(
25
24
  'Ring.dialog',
26
- [angularSanitize, RingButton, PromisedClickNg, rgCompilerModuleName]
25
+ [RingButton, PromisedClickNg, rgCompilerModuleName]
27
26
  );
28
27
 
29
28
  class DialogController extends RingAngularComponent {
30
29
  static $inject = ['$scope', '$q', 'dialog', '$element', 'dialogInSidebar', '$compile',
31
- '$injector', '$controller', 'rgCompiler'];
30
+ '$injector', '$controller', 'rgCompiler', '$sce'];
32
31
 
33
32
  constructor(...args) {
34
33
  super(...args);
@@ -273,7 +272,7 @@ class DialogController extends RingAngularComponent {
273
272
  }];
274
273
  this.serverErrorFields.push(errorField);
275
274
  } else {
276
- this.error = this.getErrorMessage(errorResponse);
275
+ this.error = this.$inject.$sce.trustAsHtml(this.getErrorMessage(errorResponse));
277
276
  }
278
277
  };
279
278
 
@@ -365,7 +364,7 @@ class DialogService extends RingAngularComponent {
365
364
 
366
365
  unregister = () => {
367
366
  Reflect.deleteProperty(this, 'ctrl');
368
- }
367
+ };
369
368
  }
370
369
 
371
370
  class DialogInSidebarService extends DialogService {
@@ -491,7 +490,7 @@ function rgDialogDirective($timeout) {
491
490
  active: '=?'
492
491
  },
493
492
  replace: true,
494
- template: require('./dialog-ng.html'),
493
+ template: dialogTemplate,
495
494
  controllerAs: 'dialog',
496
495
  link
497
496
  };
@@ -1,4 +1,4 @@
1
- <div
1
+ export default `<div
2
2
  ng-show="dialog.active"
3
3
  ng-class="[!dialog.inSidebar && dialog.dialogStyles.container]"
4
4
  ng-click="dialog.handleClick($event)"
@@ -66,4 +66,4 @@
66
66
  <div tabindex="-1" ng-show="false" data-anchor="focus-trap-fallback"></div>
67
67
  </div>
68
68
  </div>
69
- </div>
69
+ </div>`;
@@ -11,6 +11,7 @@ import styles from './dropdown.css';
11
11
 
12
12
  const Anchor = ({children, className, ...restProps}) => (
13
13
  <Button
14
+ data-test-ring-dropdown-anchor
14
15
  text
15
16
  className={classNames(styles.anchor, className)}
16
17
  {...restProps}
@@ -3,12 +3,14 @@ import chevronDownIcon from '@jetbrains/icons/chevron-down';
3
3
 
4
4
  import reactDecorator from '../../.storybook/react-decorator';
5
5
 
6
+ import {ActiveItemContext} from '../list/list';
7
+
6
8
  import Popup from '@jetbrains/ring-ui/components/popup/popup';
7
9
  import PopupMenu from '@jetbrains/ring-ui/components/popup-menu/popup-menu';
8
10
  import Button from '@jetbrains/ring-ui/components/button/button';
9
11
  import Link from '@jetbrains/ring-ui/components/link/link';
10
12
  import {Input} from '@jetbrains/ring-ui/components/input/input';
11
-
13
+ import getUID from '@jetbrains/ring-ui/components/global/get-uid';
12
14
  import Dropdown from '@jetbrains/ring-ui/components/dropdown/dropdown';
13
15
 
14
16
  export default {
@@ -45,6 +47,39 @@ export const withCustomAnchorAndPopup = () => (
45
47
  </Dropdown>
46
48
  );
47
49
 
50
+ export const withCustomAnchorAndPopupAndContentAccessibilityHandling = () => {
51
+ const listId = getUID('popup-menu-list-id');
52
+
53
+ return (
54
+ <ActiveItemContext.Provider>
55
+ <Dropdown anchor={({active}) => (
56
+ <ActiveItemContext.ValueContext.Consumer>
57
+ {activeItemId => {
58
+ const anchorAriaProps = active && activeItemId
59
+ ? {'aria-owns': listId, 'aria-activedescendant': activeItemId}
60
+ : {};
61
+ return (
62
+ <Button
63
+ {...anchorAriaProps}
64
+ delayed
65
+ >Edit</Button>
66
+ );
67
+ }}
68
+ </ActiveItemContext.ValueContext.Consumer>
69
+ )}
70
+ >
71
+ <PopupMenu
72
+ id={listId}
73
+ ariaLabel="My options menu"
74
+ closeOnSelect
75
+ activateFirstItem
76
+ data={['Cut', 'Copy', 'Paste'].map(label => ({label, key: label.toLowerCase()}))}
77
+ />
78
+ </Dropdown>
79
+ </ActiveItemContext.Provider>
80
+ );
81
+ };
82
+
48
83
  withCustomAnchorAndPopup.storyName = 'with custom anchor and popup';
49
84
 
50
85
  export const withActiveClassName = () => (
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+
3
+ import reactDecorator from '../../.storybook/react-decorator';
4
+
5
+ import DropdownMenu from '@jetbrains/ring-ui/components/dropdown-menu/dropdown-menu';
6
+
7
+ export default {
8
+ title: 'Components/DropdownMenu',
9
+ decorators: [reactDecorator()],
10
+
11
+ parameters: {
12
+ notes: 'Displays a menu in a dropdown.',
13
+ hermione: {
14
+ actions: [
15
+ {type: 'click', selector: '[data-test~=ring-dropdown]'},
16
+ {
17
+ type: 'capture',
18
+ name: 'dropdown',
19
+ selector: ['[data-test~=ring-dropdown]', '[data-test~=ring-popup]']
20
+ }
21
+ ]
22
+ },
23
+ a11y: {element: '*[data-test~=ring-dropdown]'}
24
+ }
25
+ };
26
+
27
+ export const basic = () => {
28
+ const data = [
29
+ {label: 'Item'},
30
+ {label: 'Link to jetbrains.com', href: 'http://www.jetbrains.com'},
31
+ {rgItemType: DropdownMenu.ListProps.Type.SEPARATOR},
32
+ {rgItemType: DropdownMenu.ListProps.Type.LINK, label: 'Link Item'},
33
+ {
34
+ rgItemType: DropdownMenu.ListProps.Type.LINK,
35
+ label: 'Link Item With Additional Class',
36
+ className: 'test'
37
+ },
38
+ {rgItemType: DropdownMenu.ListProps.Type.SEPARATOR, description: 'Separator With Description'},
39
+ {rgItemType: DropdownMenu.ListProps.Type.TITLE, label: 'Title'},
40
+ {rgItemType: DropdownMenu.ListProps.Type.ITEM, label: '1 Element in group'},
41
+ {rgItemType: DropdownMenu.ListProps.Type.ITEM, label: '2 Element in group'}
42
+ ];
43
+
44
+ return <DropdownMenu data={data} anchor={'Click me!'}/>;
45
+ };
46
+
47
+ basic.storyName = 'DropdownMenu';
@@ -0,0 +1,117 @@
1
+ import React, {useMemo, cloneElement} from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import List, {ActiveItemContext} from '../list/list';
5
+ import Dropdown from '../dropdown/dropdown';
6
+ import PopupMenu from '../popup-menu/popup-menu';
7
+ import getUID from '../global/get-uid';
8
+ import Anchor from '../dropdown/anchor';
9
+
10
+ const {children, ...dropdownPropTypes} = Dropdown.propTypes || {};
11
+ const {
12
+ id: idPropType,
13
+ data: dataPropType,
14
+ ariaLabel: ariaLabelPropType,
15
+ onSelect: onSelectPropType
16
+ } = PopupMenu.propTypes || {};
17
+
18
+ const defaultAriaLabel = 'Dropdown menu';
19
+
20
+ function DropdownAnchorWrapper({anchor, pinned, active, activeListItemId, listId, ...restProps}) {
21
+ const anchorAriaProps = useMemo(() => ({
22
+ ...(listId ? {'aria-haspopup': 'true'} : {}),
23
+ ...(activeListItemId ? {'aria-activedescendant': activeListItemId, 'aria-owns': listId} : {}),
24
+ ...(active ? {'aria-expanded': 'true'} : {})
25
+ }), [active, activeListItemId, listId]);
26
+
27
+ const anchorProps = useMemo(
28
+ () => ({active, pinned, ...restProps, ...anchorAriaProps}),
29
+ [pinned, active, restProps, anchorAriaProps]
30
+ );
31
+
32
+ const anchorComponentProps = useMemo(
33
+ () => ({...anchorProps, pinned: `${anchorProps.pinned}`}),
34
+ [anchorProps]
35
+ );
36
+
37
+ if (typeof anchor === 'string') {
38
+ return (
39
+ <Anchor
40
+ {...anchorComponentProps}
41
+ >{anchor}</Anchor>
42
+ );
43
+ }
44
+ if (typeof anchor === 'function') {
45
+ return anchor(({active, pinned, ...restProps}), anchorAriaProps);
46
+ }
47
+ if (!Array.isArray(anchor)) {
48
+ return cloneElement(
49
+ anchor,
50
+ typeof anchor.type === 'string' ? anchorAriaProps : anchorComponentProps
51
+ );
52
+ }
53
+ return (
54
+ <div {...anchorAriaProps}>{anchor}</div>
55
+ );
56
+ }
57
+
58
+ DropdownAnchorWrapper.propTypes = {
59
+ anchor: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.func]).isRequired,
60
+ pinned: PropTypes.bool,
61
+ active: PropTypes.bool,
62
+ activeListItemId: PropTypes.string,
63
+ listId: PropTypes.string
64
+ };
65
+
66
+ const DropdownMenu = React.forwardRef(function DropdownMenu(
67
+ {id, anchor, ariaLabel, data, onSelect, menuProps, ...restDropdownProps},
68
+ forwardedRef
69
+ ) {
70
+ const listId = useMemo(() => id || getUID('dropdown-menu-list'), [id]);
71
+
72
+ return (
73
+ <ActiveItemContext.Provider>
74
+ <Dropdown
75
+ anchor={({pinned, active, ...restAnchorProps}) => (
76
+ <ActiveItemContext.ValueContext.Consumer>
77
+ {activeItemId => (
78
+ <DropdownAnchorWrapper
79
+ anchor={anchor}
80
+ pinned={pinned}
81
+ active={active}
82
+ activeListItemId={activeItemId}
83
+ listId={listId}
84
+ {...restAnchorProps}
85
+ />
86
+ )}
87
+ </ActiveItemContext.ValueContext.Consumer>
88
+ )}
89
+ {...restDropdownProps}
90
+ >
91
+ <PopupMenu
92
+ ref={forwardedRef}
93
+ id={listId}
94
+ ariaLabel={ariaLabel || defaultAriaLabel}
95
+ closeOnSelect
96
+ activateFirstItem
97
+ data={data}
98
+ onSelect={onSelect}
99
+ {...menuProps}
100
+ />
101
+ </Dropdown>
102
+ </ActiveItemContext.Provider>
103
+ );
104
+ });
105
+
106
+ DropdownMenu.propTypes = {
107
+ id: idPropType,
108
+ data: dataPropType,
109
+ ariaLabel: ariaLabelPropType,
110
+ onSelect: onSelectPropType,
111
+ menuProps: PropTypes.object,
112
+ ...dropdownPropTypes
113
+ };
114
+
115
+ DropdownMenu.ListProps = List.ListProps;
116
+
117
+ export default DropdownMenu;