@smwb/ui-react 2.8.0 → 2.9.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 (239) hide show
  1. package/AI_LESS_OVERRIDES.md +84 -21
  2. package/AI_THEMING.md +72 -28
  3. package/README.md +654 -0
  4. package/dist/assets/styles/less/components/appBar/appBar.entry.css +1 -1
  5. package/dist/assets/styles/less/components/button/button.entry.css +1 -1
  6. package/dist/assets/styles/less/components/checkbox/checkbox.entry.css +1 -1
  7. package/dist/assets/styles/less/components/chip/chip.entry.css +1 -1
  8. package/dist/assets/styles/less/components/commandPalette/commandPalette.entry.css +1 -0
  9. package/dist/assets/styles/less/components/composer/composer.entry.css +1 -0
  10. package/dist/assets/styles/less/components/dagView/dagView.entry.css +1 -0
  11. package/dist/assets/styles/less/components/diffStat/diffStat.entry.css +1 -0
  12. package/dist/assets/styles/less/components/kbd/kbd.entry.css +1 -0
  13. package/dist/assets/styles/less/components/list/list.entry.css +1 -1
  14. package/dist/assets/styles/less/components/qrCode/qrCode.entry.css +1 -0
  15. package/dist/assets/styles/less/components/radioButton/radioButton.entry.css +1 -1
  16. package/dist/assets/styles/less/components/selectField/selectField.entry.css +1 -1
  17. package/dist/assets/styles/less/components/sidebar/sidebar.entry.css +1 -1
  18. package/dist/assets/styles/less/components/statusDot/statusDot.entry.css +1 -0
  19. package/dist/assets/styles/less/components/swimlanes/swimlanes.entry.css +1 -0
  20. package/dist/assets/styles/less/components/tabGroups/tabGroups.entry.css +1 -0
  21. package/dist/assets/styles/less/components/tabs/tab/tab.entry.css +1 -1
  22. package/dist/assets/styles/less/components/tabs/tabPanel/tabPanel.entry.css +1 -0
  23. package/dist/assets/styles/less/components/tabs/tabs.entry.css +1 -1
  24. package/dist/assets/styles/less/components/textField/textField.entry.css +1 -1
  25. package/dist/assets/styles/less/components/toggle/toggle.entry.css +1 -1
  26. package/dist/assets/styles/less/components/treeView/treeView.entry.css +1 -1
  27. package/dist/assets/styles/less/tokens.entry.css +1 -1
  28. package/dist/components/dataDisplay/chat/chat.d.ts +43 -1
  29. package/dist/components/dataDisplay/chat/chat.js +179 -150
  30. package/dist/components/dataDisplay/chat/chat.js.map +1 -1
  31. package/dist/components/dataDisplay/chat/chatComposer.d.ts +17 -0
  32. package/dist/components/dataDisplay/chat/chatComposer.js +31 -29
  33. package/dist/components/dataDisplay/chat/chatComposer.js.map +1 -1
  34. package/dist/components/dataDisplay/chat/index.d.ts +1 -1
  35. package/dist/components/dataDisplay/chat/utils.d.ts +14 -0
  36. package/dist/components/dataDisplay/chat/utils.js.map +1 -1
  37. package/dist/components/dataDisplay/dagView/dagLayout.d.ts +74 -0
  38. package/dist/components/dataDisplay/dagView/dagLayout.js +289 -0
  39. package/dist/components/dataDisplay/dagView/dagLayout.js.map +1 -0
  40. package/dist/components/dataDisplay/dagView/dagView.d.ts +157 -0
  41. package/dist/components/dataDisplay/dagView/dagView.js +543 -0
  42. package/dist/components/dataDisplay/dagView/dagView.js.map +1 -0
  43. package/dist/components/dataDisplay/dagView/index.d.ts +4 -0
  44. package/dist/components/dataDisplay/dagView/panZoom.d.ts +75 -0
  45. package/dist/components/dataDisplay/dagView/panZoom.js +171 -0
  46. package/dist/components/dataDisplay/dagView/panZoom.js.map +1 -0
  47. package/dist/components/dataDisplay/diffStat/diffStat.d.ts +54 -0
  48. package/dist/components/dataDisplay/diffStat/diffStat.js +63 -0
  49. package/dist/components/dataDisplay/diffStat/diffStat.js.map +1 -0
  50. package/dist/components/dataDisplay/diffStat/index.d.ts +2 -0
  51. package/dist/components/dataDisplay/kbd/index.d.ts +4 -0
  52. package/dist/components/dataDisplay/kbd/kbd.d.ts +40 -0
  53. package/dist/components/dataDisplay/kbd/kbd.js +27 -0
  54. package/dist/components/dataDisplay/kbd/kbd.js.map +1 -0
  55. package/dist/components/dataDisplay/kbd/kbdKeys.d.ts +18 -0
  56. package/dist/components/dataDisplay/kbd/kbdKeys.js +72 -0
  57. package/dist/components/dataDisplay/kbd/kbdKeys.js.map +1 -0
  58. package/dist/components/dataDisplay/list/listItem.d.ts +34 -0
  59. package/dist/components/dataDisplay/list/listItem.js +47 -24
  60. package/dist/components/dataDisplay/list/listItem.js.map +1 -1
  61. package/dist/components/dataDisplay/qrCode/index.d.ts +2 -0
  62. package/dist/components/dataDisplay/qrCode/qrCode.d.ts +28 -0
  63. package/dist/components/dataDisplay/qrCode/qrCode.js +78 -0
  64. package/dist/components/dataDisplay/qrCode/qrCode.js.map +1 -0
  65. package/dist/components/dataDisplay/qrCode/qrCodePath.d.ts +7 -0
  66. package/dist/components/dataDisplay/qrCode/qrCodePath.js +20 -0
  67. package/dist/components/dataDisplay/qrCode/qrCodePath.js.map +1 -0
  68. package/dist/components/dataDisplay/statusDot/index.d.ts +2 -0
  69. package/dist/components/dataDisplay/statusDot/statusDot.d.ts +35 -0
  70. package/dist/components/dataDisplay/statusDot/statusDot.js +30 -0
  71. package/dist/components/dataDisplay/statusDot/statusDot.js.map +1 -0
  72. package/dist/components/dataDisplay/swimlanes/index.d.ts +2 -0
  73. package/dist/components/dataDisplay/swimlanes/swimlanes.d.ts +53 -0
  74. package/dist/components/dataDisplay/swimlanes/swimlanes.js +357 -0
  75. package/dist/components/dataDisplay/swimlanes/swimlanes.js.map +1 -0
  76. package/dist/components/dataDisplay/treeView/treeView.d.ts +17 -1
  77. package/dist/components/dataDisplay/treeView/treeView.js +113 -92
  78. package/dist/components/dataDisplay/treeView/treeView.js.map +1 -1
  79. package/dist/components/feedBack/modal/modal.js +84 -63
  80. package/dist/components/feedBack/modal/modal.js.map +1 -1
  81. package/dist/components/inputs/button/button.d.ts +13 -1
  82. package/dist/components/inputs/button/button.js +57 -51
  83. package/dist/components/inputs/button/button.js.map +1 -1
  84. package/dist/components/inputs/composer/composer.d.ts +149 -0
  85. package/dist/components/inputs/composer/composer.js +219 -0
  86. package/dist/components/inputs/composer/composer.js.map +1 -0
  87. package/dist/components/inputs/composer/composerFiles.d.ts +26 -0
  88. package/dist/components/inputs/composer/composerFiles.js +19 -0
  89. package/dist/components/inputs/composer/composerFiles.js.map +1 -0
  90. package/dist/components/inputs/composer/composerKeys.d.ts +29 -0
  91. package/dist/components/inputs/composer/composerKeys.js +7 -0
  92. package/dist/components/inputs/composer/composerKeys.js.map +1 -0
  93. package/dist/components/inputs/composer/index.d.ts +3 -0
  94. package/dist/components/layout/sheet/sheet.d.ts +12 -0
  95. package/dist/components/layout/sheet/sheet.js +152 -137
  96. package/dist/components/layout/sheet/sheet.js.map +1 -1
  97. package/dist/components/layout/tabGroups/index.d.ts +4 -0
  98. package/dist/components/layout/tabGroups/tabGroups.d.ts +94 -0
  99. package/dist/components/layout/tabGroups/tabGroups.js +783 -0
  100. package/dist/components/layout/tabGroups/tabGroups.js.map +1 -0
  101. package/dist/components/layout/tabGroups/tabGroupsFocus.d.ts +55 -0
  102. package/dist/components/layout/tabGroups/tabGroupsFocus.js +199 -0
  103. package/dist/components/layout/tabGroups/tabGroupsFocus.js.map +1 -0
  104. package/dist/components/layout/tabGroups/tabGroupsLayout.d.ts +250 -0
  105. package/dist/components/layout/tabGroups/tabGroupsLayout.js +497 -0
  106. package/dist/components/layout/tabGroups/tabGroupsLayout.js.map +1 -0
  107. package/dist/components/navigation/appBar/appBar.d.ts +22 -0
  108. package/dist/components/navigation/appBar/appBar.js +31 -26
  109. package/dist/components/navigation/appBar/appBar.js.map +1 -1
  110. package/dist/components/navigation/commandPalette/commandPalette.d.ts +111 -0
  111. package/dist/components/navigation/commandPalette/commandPalette.js +337 -0
  112. package/dist/components/navigation/commandPalette/commandPalette.js.map +1 -0
  113. package/dist/components/navigation/commandPalette/commandPaletteFilter.d.ts +11 -0
  114. package/dist/components/navigation/commandPalette/commandPaletteFilter.js +16 -0
  115. package/dist/components/navigation/commandPalette/commandPaletteFilter.js.map +1 -0
  116. package/dist/components/navigation/commandPalette/commandPaletteNavigation.d.ts +13 -0
  117. package/dist/components/navigation/commandPalette/commandPaletteNavigation.js +38 -0
  118. package/dist/components/navigation/commandPalette/commandPaletteNavigation.js.map +1 -0
  119. package/dist/components/navigation/commandPalette/commandPaletteTypes.d.ts +39 -0
  120. package/dist/components/navigation/commandPalette/index.d.ts +4 -0
  121. package/dist/components/navigation/sidebar/sidebar.d.ts +10 -0
  122. package/dist/components/navigation/sidebar/sidebar.js +61 -59
  123. package/dist/components/navigation/sidebar/sidebar.js.map +1 -1
  124. package/dist/components/navigation/tabs/index.d.ts +3 -1
  125. package/dist/components/navigation/tabs/tab/tab.d.ts +88 -1
  126. package/dist/components/navigation/tabs/tab/tab.js +121 -42
  127. package/dist/components/navigation/tabs/tab/tab.js.map +1 -1
  128. package/dist/components/navigation/tabs/tabPanel/tabPanel.d.ts +19 -0
  129. package/dist/components/navigation/tabs/tabPanel/tabPanel.js +27 -0
  130. package/dist/components/navigation/tabs/tabPanel/tabPanel.js.map +1 -0
  131. package/dist/components/navigation/tabs/tabs.d.ts +75 -5
  132. package/dist/components/navigation/tabs/tabs.js +369 -145
  133. package/dist/components/navigation/tabs/tabs.js.map +1 -1
  134. package/dist/components/navigation/tabs/tabs.utils.d.ts +20 -0
  135. package/dist/components/navigation/tabs/tabs.utils.js +11 -0
  136. package/dist/components/navigation/tabs/tabs.utils.js.map +1 -0
  137. package/dist/components/navigation/tabs/tabsContext.d.ts +11 -0
  138. package/dist/components/navigation/tabs/tabsContext.js +6 -0
  139. package/dist/components/navigation/tabs/tabsContext.js.map +1 -0
  140. package/dist/headless/components/dataDisplay/chat/chat.js +179 -150
  141. package/dist/headless/components/dataDisplay/chat/chat.js.map +1 -1
  142. package/dist/headless/components/dataDisplay/chat/chatComposer.js +31 -29
  143. package/dist/headless/components/dataDisplay/chat/chatComposer.js.map +1 -1
  144. package/dist/headless/components/dataDisplay/chat/utils.js.map +1 -1
  145. package/dist/headless/components/dataDisplay/dagView/dagLayout.js +289 -0
  146. package/dist/headless/components/dataDisplay/dagView/dagLayout.js.map +1 -0
  147. package/dist/headless/components/dataDisplay/dagView/dagView.js +541 -0
  148. package/dist/headless/components/dataDisplay/dagView/dagView.js.map +1 -0
  149. package/dist/headless/components/dataDisplay/dagView/panZoom.js +171 -0
  150. package/dist/headless/components/dataDisplay/dagView/panZoom.js.map +1 -0
  151. package/dist/headless/components/dataDisplay/diffStat/diffStat.js +61 -0
  152. package/dist/headless/components/dataDisplay/diffStat/diffStat.js.map +1 -0
  153. package/dist/headless/components/dataDisplay/kbd/kbd.js +25 -0
  154. package/dist/headless/components/dataDisplay/kbd/kbd.js.map +1 -0
  155. package/dist/headless/components/dataDisplay/kbd/kbdKeys.js +72 -0
  156. package/dist/headless/components/dataDisplay/kbd/kbdKeys.js.map +1 -0
  157. package/dist/headless/components/dataDisplay/list/listItem.js +47 -24
  158. package/dist/headless/components/dataDisplay/list/listItem.js.map +1 -1
  159. package/dist/headless/components/dataDisplay/qrCode/qrCode.js +76 -0
  160. package/dist/headless/components/dataDisplay/qrCode/qrCode.js.map +1 -0
  161. package/dist/headless/components/dataDisplay/qrCode/qrCodePath.js +20 -0
  162. package/dist/headless/components/dataDisplay/qrCode/qrCodePath.js.map +1 -0
  163. package/dist/headless/components/dataDisplay/statusDot/statusDot.js +28 -0
  164. package/dist/headless/components/dataDisplay/statusDot/statusDot.js.map +1 -0
  165. package/dist/headless/components/dataDisplay/swimlanes/swimlanes.js +355 -0
  166. package/dist/headless/components/dataDisplay/swimlanes/swimlanes.js.map +1 -0
  167. package/dist/headless/components/dataDisplay/treeView/treeView.js +113 -92
  168. package/dist/headless/components/dataDisplay/treeView/treeView.js.map +1 -1
  169. package/dist/headless/components/feedBack/modal/modal.js +85 -64
  170. package/dist/headless/components/feedBack/modal/modal.js.map +1 -1
  171. package/dist/headless/components/inputs/button/button.js +56 -50
  172. package/dist/headless/components/inputs/button/button.js.map +1 -1
  173. package/dist/headless/components/inputs/composer/composer.js +217 -0
  174. package/dist/headless/components/inputs/composer/composer.js.map +1 -0
  175. package/dist/headless/components/inputs/composer/composerFiles.js +19 -0
  176. package/dist/headless/components/inputs/composer/composerFiles.js.map +1 -0
  177. package/dist/headless/components/inputs/composer/composerKeys.js +7 -0
  178. package/dist/headless/components/inputs/composer/composerKeys.js.map +1 -0
  179. package/dist/headless/components/layout/sheet/sheet.js +160 -145
  180. package/dist/headless/components/layout/sheet/sheet.js.map +1 -1
  181. package/dist/headless/components/layout/tabGroups/tabGroups.js +781 -0
  182. package/dist/headless/components/layout/tabGroups/tabGroups.js.map +1 -0
  183. package/dist/headless/components/layout/tabGroups/tabGroupsFocus.js +199 -0
  184. package/dist/headless/components/layout/tabGroups/tabGroupsFocus.js.map +1 -0
  185. package/dist/headless/components/layout/tabGroups/tabGroupsLayout.js +497 -0
  186. package/dist/headless/components/layout/tabGroups/tabGroupsLayout.js.map +1 -0
  187. package/dist/headless/components/navigation/appBar/appBar.js +35 -30
  188. package/dist/headless/components/navigation/appBar/appBar.js.map +1 -1
  189. package/dist/headless/components/navigation/commandPalette/commandPalette.js +335 -0
  190. package/dist/headless/components/navigation/commandPalette/commandPalette.js.map +1 -0
  191. package/dist/headless/components/navigation/commandPalette/commandPaletteFilter.js +16 -0
  192. package/dist/headless/components/navigation/commandPalette/commandPaletteFilter.js.map +1 -0
  193. package/dist/headless/components/navigation/commandPalette/commandPaletteNavigation.js +38 -0
  194. package/dist/headless/components/navigation/commandPalette/commandPaletteNavigation.js.map +1 -0
  195. package/dist/headless/components/navigation/sidebar/sidebar.js +56 -54
  196. package/dist/headless/components/navigation/sidebar/sidebar.js.map +1 -1
  197. package/dist/headless/components/navigation/tabs/tab/tab.js +121 -42
  198. package/dist/headless/components/navigation/tabs/tab/tab.js.map +1 -1
  199. package/dist/headless/components/navigation/tabs/tabPanel/tabPanel.js +25 -0
  200. package/dist/headless/components/navigation/tabs/tabPanel/tabPanel.js.map +1 -0
  201. package/dist/headless/components/navigation/tabs/tabs.js +369 -145
  202. package/dist/headless/components/navigation/tabs/tabs.js.map +1 -1
  203. package/dist/headless/components/navigation/tabs/tabs.utils.js +11 -0
  204. package/dist/headless/components/navigation/tabs/tabs.utils.js.map +1 -0
  205. package/dist/headless/components/navigation/tabs/tabsContext.js +6 -0
  206. package/dist/headless/components/navigation/tabs/tabsContext.js.map +1 -0
  207. package/dist/headless/hooks/useFocusTrap.js +24 -21
  208. package/dist/headless/hooks/useFocusTrap.js.map +1 -1
  209. package/dist/headless/hooks/useKeyboardShortcut.js +19 -0
  210. package/dist/headless/hooks/useKeyboardShortcut.js.map +1 -0
  211. package/dist/headless/index.js +360 -316
  212. package/dist/headless/index.js.map +1 -1
  213. package/dist/headless/utils/keyboardShortcut.js +49 -0
  214. package/dist/headless/utils/keyboardShortcut.js.map +1 -0
  215. package/dist/headless/utils/linkAttrs.js +13 -0
  216. package/dist/headless/utils/linkAttrs.js.map +1 -0
  217. package/dist/headless/utils/restoreFocus.js +10 -0
  218. package/dist/headless/utils/restoreFocus.js.map +1 -0
  219. package/dist/hooks/useFocusTrap.d.ts +6 -1
  220. package/dist/hooks/useFocusTrap.js +24 -21
  221. package/dist/hooks/useFocusTrap.js.map +1 -1
  222. package/dist/hooks/useKeyboardShortcut.d.ts +30 -0
  223. package/dist/hooks/useKeyboardShortcut.js +19 -0
  224. package/dist/hooks/useKeyboardShortcut.js.map +1 -0
  225. package/dist/index.cjs +3 -2
  226. package/dist/index.cjs.map +1 -1
  227. package/dist/index.d.ts +24 -3
  228. package/dist/index.js +360 -316
  229. package/dist/index.js.map +1 -1
  230. package/dist/utils/keyboardShortcut.d.ts +12 -0
  231. package/dist/utils/keyboardShortcut.js +49 -0
  232. package/dist/utils/keyboardShortcut.js.map +1 -0
  233. package/dist/utils/linkAttrs.d.ts +13 -0
  234. package/dist/utils/linkAttrs.js +13 -0
  235. package/dist/utils/linkAttrs.js.map +1 -0
  236. package/dist/utils/restoreFocus.d.ts +8 -0
  237. package/dist/utils/restoreFocus.js +10 -0
  238. package/dist/utils/restoreFocus.js.map +1 -0
  239. package/package.json +5 -3
@@ -1,121 +1,142 @@
1
- import { jsx as a, jsxs as b } from "react/jsx-runtime";
1
+ import { jsx as r, jsxs as y } from "react/jsx-runtime";
2
2
  import '../../../assets/styles/less/components/treeView/treeView.entry.css';import '../../../assets/styles/less/tokens.entry.css';/* empty css */
3
3
  /* empty css */
4
- import { forwardRef as I, useState as D, useRef as ee, useMemo as se } from "react";
5
- import O from "clsx";
6
- import { Icon as N } from "../../base/icon/icon.js";
7
- import { useControllableState as K } from "../../../hooks/useControllableState.js";
8
- const de = I(function({
9
- className: M,
4
+ import { forwardRef as le, useState as q, useRef as ne, useMemo as ie } from "react";
5
+ import A from "clsx";
6
+ import { Icon as u } from "../../base/icon/icon.js";
7
+ import { useControllableState as B } from "../../../hooks/useControllableState.js";
8
+ import { useId as oe } from "../../../hooks/useId.js";
9
+ import { isOwnClick as de } from "../../../utils/ownClick.js";
10
+ const Ne = le(function({
11
+ className: F,
10
12
  listIcon: k = "draft",
11
- nodeIcon: n = { closed: "folder", opened: "folder_open" },
13
+ nodeIcon: o = { closed: "folder", opened: "folder_open" },
12
14
  data: x = [],
13
- expanded: P,
14
- defaultExpanded: S = [],
15
- onExpandedChange: q,
16
- selected: B,
17
- defaultSelected: F = [],
18
- onSelectedChange: d,
19
- selectable: f = !1,
20
- checkboxes: u = !1,
21
- renderLabel: m,
22
- loadChildren: _,
23
- "data-testid": G = "tree-view",
24
- ...H
25
- }, J) {
26
- const [o, Q] = D({}), [y, L] = D([]), [z, C] = K({
15
+ expanded: G,
16
+ defaultExpanded: H = [],
17
+ onExpandedChange: J,
18
+ selected: P,
19
+ defaultSelected: Q = [],
20
+ onSelectedChange: _,
21
+ selectable: c = !1,
22
+ checkboxes: m = !1,
23
+ toggleOnRowClick: $ = !c,
24
+ renderLabel: h,
25
+ renderActions: p,
26
+ loadingText: z = "Loading…",
27
+ loadChildren: w,
28
+ "data-testid": U = "tree-view",
29
+ ...W
30
+ }, X) {
31
+ const [f, Y] = q({}), [L, R] = q([]), V = oe(), [C, E] = B({
32
+ value: G,
33
+ defaultValue: H,
34
+ onChange: J
35
+ }), g = ne(), [b, Z] = B({
27
36
  value: P,
28
- defaultValue: S,
29
- onChange: q
30
- }), p = ee(), [h, U] = K({
31
- value: B,
32
- defaultValue: F,
33
- onChange: (e) => {
34
- const t = p.current;
35
- p.current = void 0, d == null || d(e, t);
37
+ defaultValue: Q,
38
+ onChange: (s) => {
39
+ const t = g.current;
40
+ g.current = void 0, _ == null || _(s, t);
36
41
  }
37
- }), W = (e) => {
38
- C((t) => t.includes(e) ? t.filter((s) => s !== e) : [...t, e]);
39
- }, R = (e, t) => {
40
- C((s) => {
41
- const l = s.includes(e);
42
- return t && !l ? [...s, e] : !t && l ? s.filter((w) => w !== e) : s;
42
+ }), I = (s) => {
43
+ E((t) => t.includes(s) ? t.filter((e) => e !== s) : [...t, s]);
44
+ }, T = (s, t) => {
45
+ E((e) => {
46
+ const l = e.includes(s);
47
+ return t && !l ? [...e, s] : !t && l ? e.filter((i) => i !== s) : e;
43
48
  });
44
- }, V = (e) => {
45
- p.current = { id: e, selected: !h.includes(e) }, U((t) => t.includes(e) ? t.filter((s) => s !== e) : [...t, e]);
46
- }, E = (e, t) => {
47
- !_ || o[t] || e.children && e.children.length > 0 || (L((s) => s.includes(t) ? s : [...s, t]), _(e, t).then((s) => {
48
- Q((l) => ({ ...l, [t]: s }));
49
+ }, j = (s) => {
50
+ g.current = { id: s, selected: !b.includes(s) }, Z((t) => t.includes(s) ? t.filter((e) => e !== s) : [...t, s]);
51
+ }, D = (s, t) => {
52
+ !w || f[t] || s.children && s.children.length > 0 || (R((e) => e.includes(t) ? e : [...e, t]), w(s, t).then((e) => {
53
+ Y((l) => ({ ...l, [t]: e }));
49
54
  }).finally(() => {
50
- L((s) => s.filter((l) => l !== t));
55
+ R((e) => e.filter((l) => l !== t));
51
56
  }));
52
- }, T = (e, t) => {
53
- var j, A;
54
- const s = (j = e.id) != null ? j : t, l = (A = e.children) != null ? A : o[s], w = !!_ && (e.hasChildren || !!o[s]), i = !!l && l.length > 0 || w, c = z.includes(s), g = h.includes(s), Y = y.includes(s), $ = () => {
55
- i && (c || E(e, s), W(s)), f && V(s);
56
- }, Z = (r) => {
57
- r.key === "Enter" || r.key === " " ? (r.preventDefault(), $()) : r.key === "ArrowRight" && i ? (E(e, s), R(s, !0)) : r.key === "ArrowLeft" && i && R(s, !1);
57
+ }, O = (s, t) => {
58
+ var M, S;
59
+ const e = (M = s.id) != null ? M : t, l = `${V}-${e}`, i = (S = s.children) != null ? S : f[e], se = !!w && (s.hasChildren || !!f[e]), n = !!i && i.length > 0 || se, d = C.includes(e), N = b.includes(e), te = L.includes(e), v = () => {
60
+ d || D(s, e), I(e);
61
+ }, K = () => {
62
+ $ && n && v(), c && j(e);
63
+ }, re = (a) => {
64
+ a.target === a.currentTarget && (a.key === "Enter" || a.key === " " ? (a.preventDefault(), K()) : a.key === "ArrowRight" && n ? (D(s, e), T(e, !0)) : a.key === "ArrowLeft" && n && T(e, !1));
58
65
  };
59
- return /* @__PURE__ */ b(
66
+ return /* @__PURE__ */ y(
60
67
  "div",
61
68
  {
62
- className: O("smwb-tree__node", { "smwb-tree__node_selected": g }),
69
+ className: A("smwb-tree__node", { "smwb-tree__node_selected": N }),
63
70
  role: "treeitem",
64
- "aria-expanded": i ? c : void 0,
65
- "aria-selected": f || u ? g : void 0,
71
+ "aria-labelledby": l,
72
+ "aria-expanded": n ? d : void 0,
73
+ "aria-selected": c || m ? N : void 0,
66
74
  children: [
67
- /* @__PURE__ */ b(
68
- "span",
69
- {
70
- className: "smwb-tree__node__content",
71
- onClick: $,
72
- onKeyDown: Z,
73
- tabIndex: 0,
74
- role: "button",
75
- children: [
76
- u && /* @__PURE__ */ a(
77
- "input",
78
- {
79
- type: "checkbox",
80
- className: "smwb-tree__node__checkbox",
81
- checked: g,
82
- onClick: (r) => r.stopPropagation(),
83
- onChange: () => V(s),
84
- "aria-label": e.label
85
- }
86
- ),
87
- /* @__PURE__ */ b("span", { className: "smwb-tree__node__label", children: [
88
- i && c ? /* @__PURE__ */ a(N, { name: n == null ? void 0 : n.opened, fill: 1, size: 20 }) : i ? /* @__PURE__ */ a(N, { name: n == null ? void 0 : n.closed, fill: 1, size: 20 }) : /* @__PURE__ */ a(N, { name: k, size: 20 }),
89
- m ? m(e, s) : e.label
75
+ /* @__PURE__ */ y("div", { className: "smwb-tree__node__row", children: [
76
+ /* @__PURE__ */ r("span", { className: "smwb-tree__node__toggle", "aria-hidden": "true", onClick: n ? v : void 0, children: n && /* @__PURE__ */ r(u, { name: d ? "expand_more" : "chevron_right", size: 20 }) }),
77
+ m && /* @__PURE__ */ r(
78
+ "input",
79
+ {
80
+ type: "checkbox",
81
+ className: "smwb-tree__node__checkbox",
82
+ checked: N,
83
+ onChange: () => j(e),
84
+ "aria-label": s.label
85
+ }
86
+ ),
87
+ /* @__PURE__ */ r(
88
+ "span",
89
+ {
90
+ className: "smwb-tree__node__content",
91
+ onClick: (a) => {
92
+ de(a) && K();
93
+ },
94
+ onKeyDown: re,
95
+ tabIndex: 0,
96
+ role: "button",
97
+ children: /* @__PURE__ */ y("span", { className: "smwb-tree__node__label", id: l, children: [
98
+ n && d ? /* @__PURE__ */ r(u, { name: o == null ? void 0 : o.opened, fill: 1, size: 20 }) : n ? /* @__PURE__ */ r(u, { name: o == null ? void 0 : o.closed, fill: 1, size: 20 }) : /* @__PURE__ */ r(u, { name: k, size: 20 }),
99
+ h ? h(s, e) : s.label
90
100
  ] })
91
- ]
92
- }
93
- ),
94
- i && c && /* @__PURE__ */ a("div", { role: "group", children: Y && !l ? /* @__PURE__ */ a("div", { className: "smwb-tree__node__loading", role: "status", children: "Загрузка…" }) : l == null ? void 0 : l.map((r, v) => T(r, `${t}.${v}`)) })
101
+ }
102
+ ),
103
+ p && /* @__PURE__ */ r("span", { className: "smwb-tree__node__actions", children: p(s, e) })
104
+ ] }),
105
+ n && d && /* @__PURE__ */ r("div", { role: "group", children: te && !i ? /* @__PURE__ */ r("div", { className: "smwb-tree__node__loading", role: "status", children: z }) : i == null ? void 0 : i.map((a, ae) => O(a, `${t}.${ae}`)) })
95
106
  ]
96
107
  },
97
- s
108
+ e
98
109
  );
99
- }, X = se(
100
- () => x.map((e, t) => T(e, `${t}`)),
110
+ }, ee = ie(
111
+ () => x.map((s, t) => {
112
+ var e;
113
+ return (
114
+ // Keyed by node id, not position: a node that moves or gains a sibling keeps its DOM and focus.
115
+ /* @__PURE__ */ r("div", { className: "smwb-tree__wrapper", role: "presentation", children: O(s, `${t}`) }, (e = s.id) != null ? e : `${t}`)
116
+ );
117
+ }),
101
118
  // eslint-disable-next-line react-hooks/exhaustive-deps
102
119
  [
103
120
  x,
104
- z,
105
- h,
106
- f,
107
- u,
108
- k,
109
- n,
121
+ V,
122
+ C,
123
+ b,
124
+ c,
110
125
  m,
126
+ $,
127
+ k,
111
128
  o,
112
- y
129
+ h,
130
+ p,
131
+ z,
132
+ f,
133
+ L
113
134
  ]
114
135
  );
115
- return /* @__PURE__ */ a("div", { "data-testid": G, ...H, ref: J, role: "tree", className: O("smwb-tree", M), children: X.map((e, t) => /* @__PURE__ */ a("div", { className: "smwb-tree__wrapper", role: "presentation", children: e }, t)) });
136
+ return /* @__PURE__ */ r("div", { "data-testid": U, ...W, ref: X, role: "tree", className: A("smwb-tree", F), children: ee });
116
137
  });
117
138
  export {
118
- de as TreeView,
119
- de as default
139
+ Ne as TreeView,
140
+ Ne as default
120
141
  };
121
142
  //# sourceMappingURL=treeView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"treeView.js","sources":["../../../../src/components/dataDisplay/treeView/treeView.tsx"],"sourcesContent":["import React, { forwardRef, KeyboardEvent, ReactNode, useMemo, useRef, useState } from \"react\";\nimport cn from \"clsx\";\nimport Icon from \"../../base/icon/icon\";\nimport { useControllableState } from \"../../../hooks/useControllableState\";\n\nexport interface ITreeNodeItem {\n /** Stable identifier. Falls back to the positional path when omitted. */\n id?: string;\n label: string;\n children?: ITreeNodeItem[];\n /** Hint that the node is expandable even before its children are loaded. */\n hasChildren?: boolean;\n}\n\nexport interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n nodeIcon?: {\n opened?: string;\n closed?: string;\n };\n listIcon?: string;\n data: ITreeNodeItem[];\n /** Controlled list of expanded node ids. */\n expanded?: string[];\n /** Initially expanded node ids (uncontrolled). */\n defaultExpanded?: string[];\n /** Called with the next expanded ids. */\n onExpandedChange?: (expanded: string[]) => void;\n /** Controlled list of selected node ids. */\n selected?: string[];\n /** Initially selected node ids (uncontrolled). */\n defaultSelected?: string[];\n /** Called with the next selected ids plus, for user toggles, the node that just changed. */\n onSelectedChange?: (selected: string[], changed?: { id: string; selected: boolean }) => void;\n /** Enables label click selection. */\n selectable?: boolean;\n /** Renders a checkbox per node bound to selection. */\n checkboxes?: boolean;\n /** Custom node renderer. */\n renderLabel?: (item: ITreeNodeItem, nodeId: string) => ReactNode;\n /** Lazily resolves children the first time a node is expanded. */\n loadChildren?: (item: ITreeNodeItem, nodeId: string) => Promise<ITreeNodeItem[]>;\n /** Test id of the root `<div>`; `tree-view` unless given. */\n \"data-testid\"?: string;\n}\n\nexport const TreeView = forwardRef<HTMLDivElement, TreeViewProps>(function TreeView(\n {\n className,\n listIcon = \"draft\",\n nodeIcon = { closed: \"folder\", opened: \"folder_open\" },\n data = [],\n expanded,\n defaultExpanded = [],\n onExpandedChange,\n selected,\n defaultSelected = [],\n onSelectedChange,\n selectable = false,\n checkboxes = false,\n renderLabel,\n loadChildren,\n \"data-testid\": dataTestId = \"tree-view\",\n ...props\n },\n ref\n) {\n const [loadedChildren, setLoadedChildren] = useState<Record<string, ITreeNodeItem[]>>({});\n const [loadingIds, setLoadingIds] = useState<string[]>([]);\n const [expandedIds, setExpandedIds] = useControllableState<string[]>({\n value: expanded,\n defaultValue: defaultExpanded,\n onChange: onExpandedChange,\n });\n const lastToggledRef = useRef<{ id: string; selected: boolean }>();\n const [selectedIds, setSelectedIds] = useControllableState<string[]>({\n value: selected,\n defaultValue: defaultSelected,\n onChange: (next) => {\n // useControllableState calls onChange synchronously from the setter,\n // so lastToggledRef still refers to the toggle that caused this change.\n const changed = lastToggledRef.current;\n lastToggledRef.current = undefined;\n onSelectedChange?.(next, changed);\n },\n });\n\n const toggleExpanded = (id: string) => {\n setExpandedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const setOpen = (id: string, open: boolean) => {\n setExpandedIds((prev) => {\n const has = prev.includes(id);\n if (open && !has) return [...prev, id];\n if (!open && has) return prev.filter((x) => x !== id);\n return prev;\n });\n };\n\n const toggleSelected = (id: string) => {\n lastToggledRef.current = { id, selected: !selectedIds.includes(id) };\n setSelectedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const ensureLoaded = (item: ITreeNodeItem, nodeId: string) => {\n if (!loadChildren || loadedChildren[nodeId] || (item.children && item.children.length > 0)) {\n return;\n }\n setLoadingIds((prev) => (prev.includes(nodeId) ? prev : [...prev, nodeId]));\n void loadChildren(item, nodeId)\n .then((children) => {\n setLoadedChildren((prev) => ({ ...prev, [nodeId]: children }));\n })\n .finally(() => {\n setLoadingIds((prev) => prev.filter((x) => x !== nodeId));\n });\n };\n\n const renderNode = (item: ITreeNodeItem, path: string): ReactNode => {\n const nodeId = item.id ?? path;\n const resolvedChildren = item.children ?? loadedChildren[nodeId];\n const isLazy = !!loadChildren && (item.hasChildren || !!loadedChildren[nodeId]);\n const hasChildNodes = (!!resolvedChildren && resolvedChildren.length > 0) || isLazy;\n const isOpen = expandedIds.includes(nodeId);\n const isSelected = selectedIds.includes(nodeId);\n const isLoading = loadingIds.includes(nodeId);\n\n const onLabelClick = () => {\n if (hasChildNodes) {\n if (!isOpen) {\n ensureLoaded(item, nodeId);\n }\n toggleExpanded(nodeId);\n }\n if (selectable) {\n toggleSelected(nodeId);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLSpanElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onLabelClick();\n } else if (event.key === \"ArrowRight\" && hasChildNodes) {\n ensureLoaded(item, nodeId);\n setOpen(nodeId, true);\n } else if (event.key === \"ArrowLeft\" && hasChildNodes) {\n setOpen(nodeId, false);\n }\n };\n\n return (\n <div\n className={cn(\"smwb-tree__node\", { \"smwb-tree__node_selected\": isSelected })}\n role=\"treeitem\"\n aria-expanded={hasChildNodes ? isOpen : undefined}\n aria-selected={selectable || checkboxes ? isSelected : undefined}\n key={nodeId}\n >\n <span\n className=\"smwb-tree__node__content\"\n onClick={onLabelClick}\n onKeyDown={onKeyDown}\n tabIndex={0}\n role=\"button\"\n >\n {checkboxes && (\n <input\n type=\"checkbox\"\n className=\"smwb-tree__node__checkbox\"\n checked={isSelected}\n onClick={(e) => e.stopPropagation()}\n onChange={() => toggleSelected(nodeId)}\n aria-label={item.label}\n />\n )}\n <span className=\"smwb-tree__node__label\">\n {hasChildNodes && isOpen ? (\n <Icon name={nodeIcon?.opened as string} fill={1} size={20} />\n ) : hasChildNodes ? (\n <Icon name={nodeIcon?.closed as string} fill={1} size={20} />\n ) : (\n <Icon name={listIcon} size={20} />\n )}\n {renderLabel ? renderLabel(item, nodeId) : item.label}\n </span>\n </span>\n {hasChildNodes && isOpen && (\n <div role=\"group\">\n {isLoading && !resolvedChildren ? (\n <div className=\"smwb-tree__node__loading\" role=\"status\">\n Загрузка…\n </div>\n ) : (\n resolvedChildren?.map((c, idx) => renderNode(c, `${path}.${idx}`))\n )}\n </div>\n )}\n </div>\n );\n };\n\n const tree = useMemo(\n () => data.map((d, idx) => renderNode(d, `${idx}`)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n data,\n expandedIds,\n selectedIds,\n selectable,\n checkboxes,\n listIcon,\n nodeIcon,\n renderLabel,\n loadedChildren,\n loadingIds,\n ]\n );\n\n return (\n <div data-testid={dataTestId} {...props} ref={ref} role=\"tree\" className={cn(\"smwb-tree\", className)}>\n {tree.map((node, idx) => (\n <div className=\"smwb-tree__wrapper\" key={idx} role=\"presentation\">\n {node}\n </div>\n ))}\n </div>\n );\n});\n\nexport default TreeView;\n"],"names":["TreeView","forwardRef","className","listIcon","nodeIcon","data","expanded","defaultExpanded","onExpandedChange","selected","defaultSelected","onSelectedChange","selectable","checkboxes","renderLabel","loadChildren","dataTestId","props","ref","loadedChildren","setLoadedChildren","useState","loadingIds","setLoadingIds","expandedIds","setExpandedIds","useControllableState","lastToggledRef","useRef","selectedIds","setSelectedIds","next","changed","toggleExpanded","id","prev","x","setOpen","open","has","toggleSelected","ensureLoaded","item","nodeId","children","renderNode","path","_a","resolvedChildren","_b","isLazy","hasChildNodes","isOpen","isSelected","isLoading","onLabelClick","onKeyDown","event","jsxs","cn","jsx","e","Icon","c","idx","tree","useMemo","d","node"],"mappings":"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"}
1
+ {"version":3,"file":"treeView.js","sources":["../../../../src/components/dataDisplay/treeView/treeView.tsx"],"sourcesContent":["import React, { forwardRef, KeyboardEvent, ReactNode, useMemo, useRef, useState } from \"react\";\nimport cn from \"clsx\";\nimport Icon from \"../../base/icon/icon\";\nimport { useControllableState } from \"../../../hooks/useControllableState\";\nimport { useId } from \"../../../hooks/useId\";\nimport { isOwnClick } from \"../../../utils/ownClick\";\n\nexport interface ITreeNodeItem {\n /** Stable identifier. Falls back to the positional path when omitted. */\n id?: string;\n label: string;\n children?: ITreeNodeItem[];\n /** Hint that the node is expandable even before its children are loaded. */\n hasChildren?: boolean;\n}\n\nexport interface TreeViewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n nodeIcon?: {\n opened?: string;\n closed?: string;\n };\n listIcon?: string;\n data: ITreeNodeItem[];\n /** Controlled list of expanded node ids. */\n expanded?: string[];\n /** Initially expanded node ids (uncontrolled). */\n defaultExpanded?: string[];\n /** Called with the next expanded ids. */\n onExpandedChange?: (expanded: string[]) => void;\n /** Controlled list of selected node ids. */\n selected?: string[];\n /** Initially selected node ids (uncontrolled). */\n defaultSelected?: string[];\n /** Called with the next selected ids plus, for user toggles, the node that just changed. */\n onSelectedChange?: (selected: string[], changed?: { id: string; selected: boolean }) => void;\n /**\n * Enables row selection: a click, Enter or Space on a row toggles its selection. The chevron and the\n * Left/Right keys never change it.\n */\n selectable?: boolean;\n /** Renders a checkbox per node bound to selection. */\n checkboxes?: boolean;\n /**\n * Whether a click, Enter or Space on a row also expands or collapses its children. The chevron and the\n * Right/Left keys always do. Defaults to `true` while the tree is not `selectable` (a row has nothing else to\n * do) and to `false` otherwise, so that selecting a row leaves it open or closed.\n */\n toggleOnRowClick?: boolean;\n /** Custom node renderer. */\n renderLabel?: (item: ITreeNodeItem, nodeId: string) => ReactNode;\n /**\n * Per-node actions (buttons, a menu trigger), drawn at the end of the row. They sit beside the row's\n * button, not inside it, so they take their own clicks, Enter and Space, focus and accessible names.\n */\n renderActions?: (item: ITreeNodeItem, nodeId: string) => ReactNode;\n /** Text shown while `loadChildren` is pending; \"Loading…\" unless given. */\n loadingText?: string;\n /** Lazily resolves children the first time a node is expanded. */\n loadChildren?: (item: ITreeNodeItem, nodeId: string) => Promise<ITreeNodeItem[]>;\n /** Test id of the root `<div>`; `tree-view` unless given. */\n \"data-testid\"?: string;\n}\n\nexport const TreeView = forwardRef<HTMLDivElement, TreeViewProps>(function TreeView(\n {\n className,\n listIcon = \"draft\",\n nodeIcon = { closed: \"folder\", opened: \"folder_open\" },\n data = [],\n expanded,\n defaultExpanded = [],\n onExpandedChange,\n selected,\n defaultSelected = [],\n onSelectedChange,\n selectable = false,\n checkboxes = false,\n toggleOnRowClick = !selectable,\n renderLabel,\n renderActions,\n loadingText = \"Loading…\",\n loadChildren,\n \"data-testid\": dataTestId = \"tree-view\",\n ...props\n },\n ref\n) {\n const [loadedChildren, setLoadedChildren] = useState<Record<string, ITreeNodeItem[]>>({});\n const [loadingIds, setLoadingIds] = useState<string[]>([]);\n // Base of every node's label id: one tree on a page must not collide with another.\n const uid = useId();\n const [expandedIds, setExpandedIds] = useControllableState<string[]>({\n value: expanded,\n defaultValue: defaultExpanded,\n onChange: onExpandedChange,\n });\n const lastToggledRef = useRef<{ id: string; selected: boolean }>();\n const [selectedIds, setSelectedIds] = useControllableState<string[]>({\n value: selected,\n defaultValue: defaultSelected,\n onChange: (next) => {\n // useControllableState calls onChange synchronously from the setter,\n // so lastToggledRef still refers to the toggle that caused this change.\n const changed = lastToggledRef.current;\n lastToggledRef.current = undefined;\n onSelectedChange?.(next, changed);\n },\n });\n\n const toggleExpanded = (id: string) => {\n setExpandedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const setOpen = (id: string, open: boolean) => {\n setExpandedIds((prev) => {\n const has = prev.includes(id);\n if (open && !has) return [...prev, id];\n if (!open && has) return prev.filter((x) => x !== id);\n return prev;\n });\n };\n\n const toggleSelected = (id: string) => {\n lastToggledRef.current = { id, selected: !selectedIds.includes(id) };\n setSelectedIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));\n };\n\n const ensureLoaded = (item: ITreeNodeItem, nodeId: string) => {\n if (!loadChildren || loadedChildren[nodeId] || (item.children && item.children.length > 0)) {\n return;\n }\n setLoadingIds((prev) => (prev.includes(nodeId) ? prev : [...prev, nodeId]));\n void loadChildren(item, nodeId)\n .then((children) => {\n setLoadedChildren((prev) => ({ ...prev, [nodeId]: children }));\n })\n .finally(() => {\n setLoadingIds((prev) => prev.filter((x) => x !== nodeId));\n });\n };\n\n const renderNode = (item: ITreeNodeItem, path: string): ReactNode => {\n const nodeId = item.id ?? path;\n // Names the treeitem: its own content would drag the actions and the checkbox into the node's name.\n const labelId = `${uid}-${nodeId}`;\n const resolvedChildren = item.children ?? loadedChildren[nodeId];\n const isLazy = !!loadChildren && (item.hasChildren || !!loadedChildren[nodeId]);\n const hasChildNodes = (!!resolvedChildren && resolvedChildren.length > 0) || isLazy;\n const isOpen = expandedIds.includes(nodeId);\n const isSelected = selectedIds.includes(nodeId);\n const isLoading = loadingIds.includes(nodeId);\n\n const toggleNode = () => {\n if (!isOpen) {\n ensureLoaded(item, nodeId);\n }\n toggleExpanded(nodeId);\n };\n\n const activateRow = () => {\n if (toggleOnRowClick && hasChildNodes) {\n toggleNode();\n }\n if (selectable) {\n toggleSelected(nodeId);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLSpanElement>) => {\n // Keys from controls a custom label draws are theirs.\n if (event.target !== event.currentTarget) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n activateRow();\n } else if (event.key === \"ArrowRight\" && hasChildNodes) {\n ensureLoaded(item, nodeId);\n setOpen(nodeId, true);\n } else if (event.key === \"ArrowLeft\" && hasChildNodes) {\n setOpen(nodeId, false);\n }\n };\n\n return (\n <div\n className={cn(\"smwb-tree__node\", { \"smwb-tree__node_selected\": isSelected })}\n role=\"treeitem\"\n aria-labelledby={labelId}\n aria-expanded={hasChildNodes ? isOpen : undefined}\n aria-selected={selectable || checkboxes ? isSelected : undefined}\n key={nodeId}\n >\n <div className=\"smwb-tree__node__row\">\n {/*\n A pointer shortcut: the keyboard expands with ArrowRight/ArrowLeft on the row, so the chevron is\n decorative, unnamed and no Tab stop. If it ever becomes a real <button>, `aria-hidden` must go with\n it (a focusable element inside `aria-hidden` is an ARIA violation) and it then needs a name plus\n `aria-expanded`.\n */}\n <span className=\"smwb-tree__node__toggle\" aria-hidden=\"true\" onClick={hasChildNodes ? toggleNode : undefined}>\n {hasChildNodes && <Icon name={isOpen ? \"expand_more\" : \"chevron_right\"} size={20} />}\n </span>\n {checkboxes && (\n <input\n type=\"checkbox\"\n className=\"smwb-tree__node__checkbox\"\n checked={isSelected}\n onChange={() => toggleSelected(nodeId)}\n aria-label={item.label}\n />\n )}\n <span\n className=\"smwb-tree__node__content\"\n onClick={(event) => {\n if (isOwnClick(event)) activateRow();\n }}\n onKeyDown={onKeyDown}\n tabIndex={0}\n role=\"button\"\n >\n <span className=\"smwb-tree__node__label\" id={labelId}>\n {hasChildNodes && isOpen ? (\n <Icon name={nodeIcon?.opened as string} fill={1} size={20} />\n ) : hasChildNodes ? (\n <Icon name={nodeIcon?.closed as string} fill={1} size={20} />\n ) : (\n <Icon name={listIcon} size={20} />\n )}\n {renderLabel ? renderLabel(item, nodeId) : item.label}\n </span>\n </span>\n {renderActions && <span className=\"smwb-tree__node__actions\">{renderActions(item, nodeId)}</span>}\n </div>\n {hasChildNodes && isOpen && (\n <div role=\"group\">\n {isLoading && !resolvedChildren ? (\n <div className=\"smwb-tree__node__loading\" role=\"status\">\n {loadingText}\n </div>\n ) : (\n resolvedChildren?.map((c, idx) => renderNode(c, `${path}.${idx}`))\n )}\n </div>\n )}\n </div>\n );\n };\n\n const tree = useMemo(\n () =>\n data.map((d, idx) => (\n // Keyed by node id, not position: a node that moves or gains a sibling keeps its DOM and focus.\n <div className=\"smwb-tree__wrapper\" key={d.id ?? `${idx}`} role=\"presentation\">\n {renderNode(d, `${idx}`)}\n </div>\n )),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n data,\n uid,\n expandedIds,\n selectedIds,\n selectable,\n checkboxes,\n toggleOnRowClick,\n listIcon,\n nodeIcon,\n renderLabel,\n renderActions,\n loadingText,\n loadedChildren,\n loadingIds,\n ]\n );\n\n return (\n <div data-testid={dataTestId} {...props} ref={ref} role=\"tree\" className={cn(\"smwb-tree\", className)}>\n {tree}\n </div>\n );\n});\n\nexport default TreeView;\n"],"names":["TreeView","forwardRef","className","listIcon","nodeIcon","data","expanded","defaultExpanded","onExpandedChange","selected","defaultSelected","onSelectedChange","selectable","checkboxes","toggleOnRowClick","renderLabel","renderActions","loadingText","loadChildren","dataTestId","props","ref","loadedChildren","setLoadedChildren","useState","loadingIds","setLoadingIds","uid","useId","expandedIds","setExpandedIds","useControllableState","lastToggledRef","useRef","selectedIds","setSelectedIds","next","changed","toggleExpanded","id","prev","x","setOpen","open","has","toggleSelected","ensureLoaded","item","nodeId","children","renderNode","path","_a","labelId","resolvedChildren","_b","isLazy","hasChildNodes","isOpen","isSelected","isLoading","toggleNode","activateRow","onKeyDown","event","jsxs","cn","jsx","Icon","isOwnClick","c","idx","tree","useMemo","d"],"mappings":"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"}
@@ -1,51 +1,71 @@
1
- import { jsx as t, Fragment as D } from "react/jsx-runtime";
1
+ import { jsx as n, Fragment as D } from "react/jsx-runtime";
2
2
  import '../../../assets/styles/less/components/modal/modal.entry.css';import '../../../assets/styles/less/tokens.entry.css';/* empty css */
3
3
  /* empty css */
4
- import { forwardRef as L, useState as S, useRef as f, useEffect as $ } from "react";
5
- import { CSSTransition as h } from "react-transition-group";
6
- import { createPortal as A } from "react-dom";
7
- import a from "clsx";
8
- import { useSafeLayoutEffect as F } from "../../../hooks/useSafeLayoutEffect.js";
9
- import { useForkRef as M } from "../../../hooks/useForkRef.js";
10
- import { isTopOverlayLayer as O } from "../../../utils/overlayLayer.js";
11
- const P = L(function({
4
+ import { forwardRef as L, useState as v, useRef as c, useInsertionEffect as M, useEffect as _, useCallback as $ } from "react";
5
+ import { CSSTransition as O } from "react-transition-group";
6
+ import { createPortal as P } from "react-dom";
7
+ import m from "clsx";
8
+ import { useFocusTrap as j } from "../../../hooks/useFocusTrap.js";
9
+ import { useSafeLayoutEffect as I } from "../../../hooks/useSafeLayoutEffect.js";
10
+ import { useForkRef as q } from "../../../hooks/useForkRef.js";
11
+ import { isTopOverlayLayer as B } from "../../../utils/overlayLayer.js";
12
+ import { restoreFocus as H } from "../../../utils/restoreFocus.js";
13
+ function K(t) {
14
+ if (!t || typeof document == "undefined") return !0;
15
+ const e = document.querySelectorAll(".smwb-modal__overlay:not(.smwb-modal__overlay-exit)");
16
+ return e[e.length - 1] === t;
17
+ }
18
+ const G = L(function({
12
19
  children: e,
13
- onClose: r,
14
- open: m,
15
- className: u,
16
- animation: p = "fade",
17
- backdrop: v = "dark",
20
+ onClose: a,
21
+ open: o,
22
+ className: b,
23
+ animation: w = "fade",
24
+ backdrop: y = "dark",
18
25
  size: i = "large",
19
- closeOnOutsideClick: _ = !0,
20
- asForm: w = !1,
21
- disableAppearAnimation: b = !1,
22
- role: y = "dialog",
23
- closeOnEsc: d = !0,
24
- ...k
25
- }, x) {
26
- const [l, R] = S(), s = f(null), E = f(null), N = M(x, E);
27
- if (F(() => {
28
- R(document.body);
29
- }, []), $(() => {
30
- if (!m || !d || !r)
26
+ closeOnOutsideClick: E = !0,
27
+ asForm: x = !1,
28
+ disableAppearAnimation: k = !1,
29
+ role: R = "dialog",
30
+ closeOnEsc: u = !0,
31
+ ...g
32
+ }, F) {
33
+ const [d, N] = v(), s = c(null), l = c(null), [S, T] = v(null), h = q(F, l, T);
34
+ I(() => {
35
+ N(document.body);
36
+ }, []);
37
+ const f = c(null);
38
+ M(() => {
39
+ var r;
40
+ o && (f.current = (r = l.current) != null && r.contains(document.activeElement) ? null : document.activeElement);
41
+ }, [o]), _(() => {
42
+ if (!o) return;
43
+ const r = f.current;
44
+ return () => {
45
+ H(r, l.current);
46
+ };
47
+ }, [o]);
48
+ const A = $(() => K(s.current), []);
49
+ if (j(l, { active: o && S !== null, restoreFocus: !1, isTopmost: A }), _(() => {
50
+ if (!o || !u || !a)
31
51
  return;
32
- const n = (c) => {
33
- c.key === "Escape" && !c.defaultPrevented && O(s.current) && r();
52
+ const r = (p) => {
53
+ p.key === "Escape" && !p.defaultPrevented && B(s.current) && a();
34
54
  };
35
- return document.addEventListener("keydown", n), () => document.removeEventListener("keydown", n);
36
- }, [m, d, r]), !l)
37
- return /* @__PURE__ */ t(D, {});
38
- const g = w ? "form" : "div";
39
- return A(
40
- /* @__PURE__ */ t(
41
- h,
55
+ return document.addEventListener("keydown", r), () => document.removeEventListener("keydown", r);
56
+ }, [o, u, a]), !d)
57
+ return /* @__PURE__ */ n(D, {});
58
+ const C = x ? "form" : "div";
59
+ return P(
60
+ /* @__PURE__ */ n(
61
+ O,
42
62
  {
43
63
  timeout: {
44
64
  appear: 225,
45
65
  enter: 225,
46
66
  exit: 150
47
67
  },
48
- in: m,
68
+ in: o,
49
69
  classNames: {
50
70
  appear: "smwb-modal__overlay-appear",
51
71
  appearActive: "smwb-modal__overlay-appear-active",
@@ -56,26 +76,27 @@ const P = L(function({
56
76
  exit: "smwb-modal__overlay-exit",
57
77
  exitActive: "smwb-modal__overlay-exit-active"
58
78
  },
59
- appear: !b,
79
+ appear: !k,
60
80
  mountOnEnter: !0,
61
81
  unmountOnExit: !0,
62
82
  nodeRef: s,
63
- children: /* @__PURE__ */ t(
83
+ children: /* @__PURE__ */ n(
64
84
  "div",
65
85
  {
66
86
  ref: s,
67
87
  "data-smwb-overlay-layer": "",
68
- className: a("smwb-modal__overlay", `smwb-${v}`, `smwb-${i}`),
69
- onClick: _ && r ? r : void 0,
70
- children: /* @__PURE__ */ t(
71
- g,
88
+ className: m("smwb-modal__overlay", `smwb-${y}`, `smwb-${i}`),
89
+ onClick: E && a ? a : void 0,
90
+ children: /* @__PURE__ */ n(
91
+ C,
72
92
  {
73
- ref: N,
74
- className: a("smwb-modal", `smwb-${i}`, `smwb-${p}`, u),
75
- onClick: (n) => n.stopPropagation(),
76
- role: y,
93
+ ref: h,
94
+ className: m("smwb-modal", `smwb-${i}`, `smwb-${w}`, b),
95
+ onClick: (r) => r.stopPropagation(),
96
+ tabIndex: -1,
97
+ role: R,
77
98
  "aria-modal": "true",
78
- ...k,
99
+ ...g,
79
100
  children: e
80
101
  }
81
102
  )
@@ -83,28 +104,28 @@ const P = L(function({
83
104
  )
84
105
  }
85
106
  ),
86
- l
107
+ d
87
108
  );
88
109
  });
89
- function j({ className: o, children: e }) {
90
- return /* @__PURE__ */ t("div", { className: a("smwb-modal__header", o), children: e });
110
+ function J({ className: t, children: e }) {
111
+ return /* @__PURE__ */ n("div", { className: m("smwb-modal__header", t), children: e });
91
112
  }
92
- function C({ className: o, children: e }) {
93
- return /* @__PURE__ */ t("div", { className: a("smwb-modal__content", o), children: e });
113
+ function Q({ className: t, children: e }) {
114
+ return /* @__PURE__ */ n("div", { className: m("smwb-modal__content", t), children: e });
94
115
  }
95
- function T({ className: o, children: e }) {
96
- return /* @__PURE__ */ t("div", { className: a("smwb-modal__footer", o), children: e });
116
+ function U({ className: t, children: e }) {
117
+ return /* @__PURE__ */ n("div", { className: m("smwb-modal__footer", t), children: e });
97
118
  }
98
- const W = Object.assign(P, {
99
- Footer: T,
100
- Header: j,
101
- Content: C
119
+ const me = Object.assign(G, {
120
+ Footer: U,
121
+ Header: J,
122
+ Content: Q
102
123
  });
103
124
  export {
104
- C as Content,
105
- T as Footer,
106
- j as Header,
107
- W as Modal,
108
- W as default
125
+ Q as Content,
126
+ U as Footer,
127
+ J as Header,
128
+ me as Modal,
129
+ me as default
109
130
  };
110
131
  //# sourceMappingURL=modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"modal.js","sources":["../../../../src/components/feedBack/modal/modal.tsx"],"sourcesContent":["import React, { forwardRef, PropsWithChildren, useEffect, useRef, useState } from \"react\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { createPortal } from \"react-dom\";\nimport cn from \"clsx\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport { isTopOverlayLayer } from \"../../../utils/overlayLayer\";\n\nexport interface ModalProps {\n size?: \"small\" | \"medium\" | \"large\" | \"fullscreen\";\n closeOnOutsideClick?: boolean;\n onClose?: () => void;\n open: boolean;\n animation?: \"fade\" | \"scale\" | \"drop\";\n className?: string;\n backdrop?: \"blured\" | \"dark\" | \"transparent\" | \"darkBlured\";\n asForm?: boolean;\n disableAppearAnimation?: boolean;\n /** ARIA role of the dialog. */\n role?: \"dialog\" | \"alertdialog\";\n /** Close the modal when Escape is pressed. */\n closeOnEsc?: boolean;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n}\n\nconst ModalBase = forwardRef<HTMLDivElement, PropsWithChildren<ModalProps>>(function Modal(\n {\n children,\n onClose,\n open,\n className,\n animation = \"fade\",\n backdrop = \"dark\",\n size = \"large\",\n closeOnOutsideClick = true,\n asForm = false,\n disableAppearAnimation = false,\n role = \"dialog\",\n closeOnEsc = true,\n ...rest\n },\n ref\n) {\n const [domRoot, setDomRoot] = useState<HTMLElement>();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const forkedContentRef = useForkRef<HTMLDivElement>(ref, contentRef);\n\n useSafeLayoutEffect(() => {\n setDomRoot(document.body);\n }, []);\n\n useEffect(() => {\n if (!open || !closeOnEsc || !onClose) {\n return;\n }\n const onKeyDown = (event: KeyboardEvent) => {\n // Only the topmost overlay layer reacts to Escape, and not to one handled inside\n // it, e.g. by a menu closing on it.\n if (event.key === \"Escape\" && !event.defaultPrevented && isTopOverlayLayer(nodeRef.current)) {\n onClose();\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [open, closeOnEsc, onClose]);\n\n if (!domRoot) {\n return <></>;\n }\n\n const Component = (asForm ? \"form\" : \"div\") as \"div\";\n\n return createPortal(\n <CSSTransition\n timeout={{\n appear: 225,\n enter: 225,\n exit: 150,\n }}\n in={open}\n classNames={{\n appear: \"smwb-modal__overlay-appear\",\n appearActive: \"smwb-modal__overlay-appear-active\",\n appearDone: \"smwb-modal__overlay-appear-done\",\n enter: \"smwb-modal__overlay-enter\",\n enterActive: \"smwb-modal__overlay-enter-active\",\n enterDone: \"smwb-modal__overlay-enter-done\",\n exit: \"smwb-modal__overlay-exit\",\n exitActive: \"smwb-modal__overlay-exit-active\",\n }}\n appear={!disableAppearAnimation}\n mountOnEnter\n unmountOnExit\n nodeRef={nodeRef}\n >\n <div\n ref={nodeRef}\n data-smwb-overlay-layer=\"\"\n className={cn(\"smwb-modal__overlay\", `smwb-${backdrop}`, `smwb-${size}`)}\n onClick={closeOnOutsideClick && onClose ? onClose : undefined}\n >\n <Component\n ref={forkedContentRef}\n className={cn(\"smwb-modal\", `smwb-${size}`, `smwb-${animation}`, className)}\n onClick={(e) => e.stopPropagation()}\n role={role}\n aria-modal=\"true\"\n {...rest}\n >\n {children}\n </Component>\n </div>\n </CSSTransition>,\n domRoot\n );\n});\n\nexport interface HeaderProps {\n className?: string;\n}\n\nexport function Header({ className, children }: PropsWithChildren<HeaderProps>) {\n return <div className={cn(\"smwb-modal__header\", className)}>{children}</div>;\n}\n\nexport interface ContentProps {\n className?: string;\n}\n\nexport function Content({ className, children }: PropsWithChildren<ContentProps>) {\n return <div className={cn(\"smwb-modal__content\", className)}>{children}</div>;\n}\n\nexport interface FooterProps {\n className?: string;\n}\n\nexport function Footer({ className, children }: PropsWithChildren<FooterProps>) {\n return <div className={cn(\"smwb-modal__footer\", className)}>{children}</div>;\n}\n\nexport const Modal = Object.assign(ModalBase, {\n Footer,\n Header,\n Content,\n});\n\nexport default Modal;\n"],"names":["ModalBase","forwardRef","children","onClose","open","className","animation","backdrop","size","closeOnOutsideClick","asForm","disableAppearAnimation","role","closeOnEsc","rest","ref","domRoot","setDomRoot","useState","nodeRef","useRef","contentRef","forkedContentRef","useForkRef","useSafeLayoutEffect","useEffect","onKeyDown","event","isTopOverlayLayer","jsx","Fragment","Component","createPortal","CSSTransition","cn","e","Header","Content","Footer","Modal"],"mappings":"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"}
1
+ {"version":3,"file":"modal.js","sources":["../../../../src/components/feedBack/modal/modal.tsx"],"sourcesContent":["import React, {\n forwardRef,\n PropsWithChildren,\n useCallback,\n useEffect,\n useInsertionEffect,\n useRef,\n useState,\n} from \"react\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { createPortal } from \"react-dom\";\nimport cn from \"clsx\";\nimport { useFocusTrap } from \"../../../hooks/useFocusTrap\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport { isTopOverlayLayer } from \"../../../utils/overlayLayer\";\nimport { restoreFocus } from \"../../../utils/restoreFocus\";\n\nexport interface ModalProps {\n size?: \"small\" | \"medium\" | \"large\" | \"fullscreen\";\n closeOnOutsideClick?: boolean;\n onClose?: () => void;\n open: boolean;\n animation?: \"fade\" | \"scale\" | \"drop\";\n className?: string;\n backdrop?: \"blured\" | \"dark\" | \"transparent\" | \"darkBlured\";\n asForm?: boolean;\n disableAppearAnimation?: boolean;\n /** ARIA role of the dialog. */\n role?: \"dialog\" | \"alertdialog\";\n /** Close the modal when Escape is pressed. */\n closeOnEsc?: boolean;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n}\n\n/**\n * Whether `overlay` is the last open Modal overlay; a dialog stacked above it owns Tab. Fading-out\n * ones do not count. Not `isTopOverlayLayer`: menus, select dropdowns and pickers are overlay\n * layers too, and a select dropdown open inside a Modal must not switch the Modal's trap off.\n */\nfunction isTopModal(overlay: Element | null | undefined): boolean {\n if (!overlay || typeof document === \"undefined\") return true;\n const open = document.querySelectorAll(\".smwb-modal__overlay:not(.smwb-modal__overlay-exit)\");\n return open[open.length - 1] === overlay;\n}\n\n/**\n * A modal dialog: portaled to `<body>`, animated, closed by Escape or a backdrop click.\n *\n * While open it traps Tab/Shift+Tab inside the dialog and moves the focus into it (the first tab\n * stop, else the dialog itself), unless a child has already focused itself. On close, and on\n * unmount while open, the focus goes back to the element that had it when the dialog opened —\n * unless the app has moved the focus elsewhere by then.\n * Of stacked dialogs only the topmost one handles Tab.\n */\nconst ModalBase = forwardRef<HTMLDivElement, PropsWithChildren<ModalProps>>(function Modal(\n {\n children,\n onClose,\n open,\n className,\n animation = \"fade\",\n backdrop = \"dark\",\n size = \"large\",\n closeOnOutsideClick = true,\n asForm = false,\n disableAppearAnimation = false,\n role = \"dialog\",\n closeOnEsc = true,\n ...rest\n },\n ref\n) {\n const [domRoot, setDomRoot] = useState<HTMLElement>();\n\n const nodeRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n // The dialog element as state too: the content is portaled and appears a commit after `open`, and\n // the trap only re-runs when `active` changes, so a plain ref that fills in later would never arm it.\n const [contentEl, setContentEl] = useState<HTMLDivElement | null>(null);\n const forkedContentRef = useForkRef<HTMLDivElement>(ref, contentRef, setContentEl);\n\n useSafeLayoutEffect(() => {\n setDomRoot(document.body);\n }, []);\n\n // The opener is captured in an insertion effect, which runs in the mutation phase of the open\n // commit: before React focuses an `autoFocus` child (that happens in the layout phase, ahead of\n // any layout effect of this component), before the children's passive effects (a CommandPalette\n // focusing its input) and before the trap moves the focus into the dialog.\n const openerRef = useRef<Element | null>(null);\n useInsertionEffect(() => {\n if (!open) return;\n openerRef.current = contentRef.current?.contains(document.activeElement) ? null : document.activeElement;\n }, [open]);\n\n // The element focused when the dialog opens gets focus back when it closes or unmounts while open,\n // unless the app has moved focus out of the dialog by then (see restoreFocus). The return runs in a\n // passive cleanup, not in a layout one: React gives the focus back to whatever was focused when the\n // commit started (resetAfterCommit -> restoreSelection), and a closing dialog is still in the\n // document during its fade-out, so restoring inside that commit is undone. The palette relied on a\n // setTimeout(0) for the same reason.\n useEffect(() => {\n if (!open) return;\n const opener = openerRef.current;\n return () => {\n // The dialog is read here, not captured above: mounted with `open` it appears only a commit\n // after this effect runs, so a capture would hold null and skip the return. On unmount the ref\n // is already null, which is the \"root is gone\" case restoreFocus handles.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n restoreFocus(opener, contentRef.current);\n };\n }, [open]);\n\n const isTopmost = useCallback(() => isTopModal(nodeRef.current), []);\n useFocusTrap(contentRef, { active: open && contentEl !== null, restoreFocus: false, isTopmost });\n\n useEffect(() => {\n if (!open || !closeOnEsc || !onClose) {\n return;\n }\n const onKeyDown = (event: KeyboardEvent) => {\n // Only the topmost overlay layer reacts to Escape, and not to one handled inside\n // it, e.g. by a menu closing on it.\n if (event.key === \"Escape\" && !event.defaultPrevented && isTopOverlayLayer(nodeRef.current)) {\n onClose();\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [open, closeOnEsc, onClose]);\n\n if (!domRoot) {\n return <></>;\n }\n\n const Component = (asForm ? \"form\" : \"div\") as \"div\";\n\n return createPortal(\n <CSSTransition\n timeout={{\n appear: 225,\n enter: 225,\n exit: 150,\n }}\n in={open}\n classNames={{\n appear: \"smwb-modal__overlay-appear\",\n appearActive: \"smwb-modal__overlay-appear-active\",\n appearDone: \"smwb-modal__overlay-appear-done\",\n enter: \"smwb-modal__overlay-enter\",\n enterActive: \"smwb-modal__overlay-enter-active\",\n enterDone: \"smwb-modal__overlay-enter-done\",\n exit: \"smwb-modal__overlay-exit\",\n exitActive: \"smwb-modal__overlay-exit-active\",\n }}\n appear={!disableAppearAnimation}\n mountOnEnter\n unmountOnExit\n nodeRef={nodeRef}\n >\n <div\n ref={nodeRef}\n data-smwb-overlay-layer=\"\"\n className={cn(\"smwb-modal__overlay\", `smwb-${backdrop}`, `smwb-${size}`)}\n onClick={closeOnOutsideClick && onClose ? onClose : undefined}\n >\n <Component\n ref={forkedContentRef}\n className={cn(\"smwb-modal\", `smwb-${size}`, `smwb-${animation}`, className)}\n onClick={(e) => e.stopPropagation()}\n tabIndex={-1}\n role={role}\n aria-modal=\"true\"\n {...rest}\n >\n {children}\n </Component>\n </div>\n </CSSTransition>,\n domRoot\n );\n});\n\nexport interface HeaderProps {\n className?: string;\n}\n\nexport function Header({ className, children }: PropsWithChildren<HeaderProps>) {\n return <div className={cn(\"smwb-modal__header\", className)}>{children}</div>;\n}\n\nexport interface ContentProps {\n className?: string;\n}\n\nexport function Content({ className, children }: PropsWithChildren<ContentProps>) {\n return <div className={cn(\"smwb-modal__content\", className)}>{children}</div>;\n}\n\nexport interface FooterProps {\n className?: string;\n}\n\nexport function Footer({ className, children }: PropsWithChildren<FooterProps>) {\n return <div className={cn(\"smwb-modal__footer\", className)}>{children}</div>;\n}\n\nexport const Modal = Object.assign(ModalBase, {\n Footer,\n Header,\n Content,\n});\n\nexport default Modal;\n"],"names":["isTopModal","overlay","open","ModalBase","forwardRef","children","onClose","className","animation","backdrop","size","closeOnOutsideClick","asForm","disableAppearAnimation","role","closeOnEsc","rest","ref","domRoot","setDomRoot","useState","nodeRef","useRef","contentRef","contentEl","setContentEl","forkedContentRef","useForkRef","useSafeLayoutEffect","openerRef","useInsertionEffect","_a","useEffect","opener","restoreFocus","isTopmost","useCallback","useFocusTrap","onKeyDown","event","isTopOverlayLayer","jsx","Fragment","Component","createPortal","CSSTransition","cn","e","Header","Content","Footer","Modal"],"mappings":";;;;;;;;;;;;AA4CA,SAASA,EAAWC,GAA8C;AAChE,MAAI,CAACA,KAAW,OAAO,YAAa,YAAa,QAAO;AACxD,QAAMC,IAAO,SAAS,iBAAiB,qDAAqD;AAC5F,SAAOA,EAAKA,EAAK,SAAS,CAAC,MAAMD;AACnC;AAWA,MAAME,IAAYC,EAA0D,SAC1E;AAAA,EACE,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAJ;AAAA,EACA,WAAAK;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,UAAAC,IAAW;AAAA,EACX,MAAAC,IAAO;AAAA,EACP,qBAAAC,IAAsB;AAAA,EACtB,QAAAC,IAAS;AAAA,EACT,wBAAAC,IAAyB;AAAA,EACzB,MAAAC,IAAO;AAAA,EACP,YAAAC,IAAa;AAAA,EACb,GAAGC;AACL,GACAC,GACA;AACA,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAA,GAExBC,IAAUC,EAAuB,IAAI,GACrCC,IAAaD,EAAuB,IAAI,GAGxC,CAACE,GAAWC,CAAY,IAAIL,EAAgC,IAAI,GAChEM,IAAmBC,EAA2BV,GAAKM,GAAYE,CAAY;AAEjF,EAAAG,EAAoB,MAAM;AACxB,IAAAT,EAAW,SAAS,IAAI;AAAA,EAC1B,GAAG,CAAA,CAAE;AAML,QAAMU,IAAYP,EAAuB,IAAI;AAC7C,EAAAQ,EAAmB,MAAM;;AACvB,IAAK5B,MACL2B,EAAU,WAAUE,IAAAR,EAAW,YAAX,QAAAQ,EAAoB,SAAS,SAAS,iBAAiB,OAAO,SAAS;AAAA,EAC7F,GAAG,CAAC7B,CAAI,CAAC,GAQT8B,EAAU,MAAM;AACd,QAAI,CAAC9B,EAAM;AACX,UAAM+B,IAASJ,EAAU;AACzB,WAAO,MAAM;AAKX,MAAAK,EAAaD,GAAQV,EAAW,OAAO;AAAA,IACzC;AAAA,EACF,GAAG,CAACrB,CAAI,CAAC;AAET,QAAMiC,IAAYC,EAAY,MAAMpC,EAAWqB,EAAQ,OAAO,GAAG,EAAE;AAmBnE,MAlBAgB,EAAad,GAAY,EAAE,QAAQrB,KAAQsB,MAAc,MAAM,cAAc,IAAO,WAAAW,GAAW,GAE/FH,EAAU,MAAM;AACd,QAAI,CAAC9B,KAAQ,CAACa,KAAc,CAACT;AAC3B;AAEF,UAAMgC,IAAY,CAACC,MAAyB;AAG1C,MAAIA,EAAM,QAAQ,YAAY,CAACA,EAAM,oBAAoBC,EAAkBnB,EAAQ,OAAO,KACxFf,EAAA;AAAA,IAEJ;AACA,oBAAS,iBAAiB,WAAWgC,CAAS,GAEvC,MAAM,SAAS,oBAAoB,WAAWA,CAAS;AAAA,EAChE,GAAG,CAACpC,GAAMa,GAAYT,CAAO,CAAC,GAE1B,CAACY;AACH,WAAO,gBAAAuB,EAAAC,GAAA,EAAE;AAGX,QAAMC,IAAa/B,IAAS,SAAS;AAErC,SAAOgC;AAAA,IACL,gBAAAH;AAAA,MAACI;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,MAAM;AAAA,QAAA;AAAA,QAER,IAAI3C;AAAA,QACJ,YAAY;AAAA,UACV,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,aAAa;AAAA,UACb,WAAW;AAAA,UACX,MAAM;AAAA,UACN,YAAY;AAAA,QAAA;AAAA,QAEd,QAAQ,CAACW;AAAA,QACT,cAAY;AAAA,QACZ,eAAa;AAAA,QACb,SAAAQ;AAAA,QAEA,UAAA,gBAAAoB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAKpB;AAAA,YACL,2BAAwB;AAAA,YACxB,WAAWyB,EAAG,uBAAuB,QAAQrC,CAAQ,IAAI,QAAQC,CAAI,EAAE;AAAA,YACvE,SAASC,KAAuBL,IAAUA,IAAU;AAAA,YAEpD,UAAA,gBAAAmC;AAAA,cAACE;AAAA,cAAA;AAAA,gBACC,KAAKjB;AAAA,gBACL,WAAWoB,EAAG,cAAc,QAAQpC,CAAI,IAAI,QAAQF,CAAS,IAAID,CAAS;AAAA,gBAC1E,SAAS,CAACwC,MAAMA,EAAE,gBAAA;AAAA,gBAClB,UAAU;AAAA,gBACV,MAAAjC;AAAA,gBACA,cAAW;AAAA,gBACV,GAAGE;AAAA,gBAEH,UAAAX;AAAA,cAAA;AAAA,YAAA;AAAA,UACH;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,IAEFa;AAAA,EAAA;AAEJ,CAAC;AAMM,SAAS8B,EAAO,EAAE,WAAAzC,GAAW,UAAAF,KAA4C;AAC9E,2BAAQ,OAAA,EAAI,WAAWyC,EAAG,sBAAsBvC,CAAS,GAAI,UAAAF,GAAS;AACxE;AAMO,SAAS4C,EAAQ,EAAE,WAAA1C,GAAW,UAAAF,KAA6C;AAChF,2BAAQ,OAAA,EAAI,WAAWyC,EAAG,uBAAuBvC,CAAS,GAAI,UAAAF,GAAS;AACzE;AAMO,SAAS6C,EAAO,EAAE,WAAA3C,GAAW,UAAAF,KAA4C;AAC9E,2BAAQ,OAAA,EAAI,WAAWyC,EAAG,sBAAsBvC,CAAS,GAAI,UAAAF,GAAS;AACxE;AAEO,MAAM8C,KAAQ,OAAO,OAAOhD,GAAW;AAAA,EAC5C,QAAA+C;AAAA,EACA,QAAAF;AAAA,EACA,SAAAC;AACF,CAAC;"}
@@ -30,9 +30,21 @@ export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement | HT
30
30
  */
31
31
  color?: "primary" | "secondary" | "error" | "success" | "warning" | "info";
32
32
  /**
33
- * Ссылка. Если задана, компонент может рендериться как <a>.
33
+ * Ссылка. Если задана, компонент рендерится как <a>.
34
34
  */
35
35
  href?: string;
36
+ /**
37
+ * Where a link (with `href`) opens. By default `"_blank"`: a new tab. `null` leaves the `target`
38
+ * attribute out, so the link opens in place, like an internal one; an empty string does the same, and
39
+ * any other string is used as is.
40
+ */
41
+ target?: string | null;
42
+ /**
43
+ * The `rel` of a link (with `href`). By default `"noreferrer"` for a link that opens another tab or
44
+ * window, and none for one that opens in place. Your own value replaces the default, so add `noreferrer` yourself
45
+ * if you still want it; an empty string drops the attribute.
46
+ */
47
+ rel?: string;
36
48
  /**
37
49
  * Отключённое состояние.
38
50
  */