@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,57 +1,136 @@
1
- import { jsxs as p, jsx as o } from "react/jsx-runtime";
1
+ import { jsxs as C, jsx as i } from "react/jsx-runtime";
2
2
  import '../../../../assets/styles/less/components/tabs/tab/tab.entry.css';import '../../../../assets/styles/less/tokens.entry.css';/* empty css */
3
3
  /* empty css */
4
- import f from "react";
5
- import j from "clsx";
6
- import { Ripple as k } from "../../../base/ripple/ripple.js";
7
- const y = f.forwardRef(function(w, u) {
4
+ import r from "react";
5
+ import v from "clsx";
6
+ import { Ripple as X } from "../../../base/ripple/ripple.js";
7
+ import { Icon as Y } from "../../../base/icon/icon.js";
8
+ import { useSafeLayoutEffect as Z } from "../../../../hooks/useSafeLayoutEffect.js";
9
+ const $ = (e) => e.ctrlKey || e.metaKey || e.altKey || e.shiftKey, g = 'button:not(:disabled), a[href], [role="button"]:not([aria-disabled="true"]), [tabindex]', tt = '[role^="menuitem"]:not([aria-disabled="true"])', et = (e) => {
10
+ var u, f, d;
11
+ for (const c of (f = (u = e == null ? void 0 : e.getAttribute("aria-controls")) == null ? void 0 : u.split(/\s+/)) != null ? f : []) {
12
+ const s = c ? (d = e == null ? void 0 : e.ownerDocument.getElementById(c)) == null ? void 0 : d.querySelector(tt) : null;
13
+ if (s) {
14
+ s.focus({ preventScroll: !0 });
15
+ return;
16
+ }
17
+ }
18
+ }, ut = r.forwardRef(function(u, f) {
8
19
  const {
9
- className: R,
10
- label: i,
11
- isActive: e = !1,
12
- contentRef: _,
13
- icon: l,
14
- stacked: h = !1,
15
- tag: s,
16
- disabled: t,
17
- onMouseDown: n,
20
+ className: d,
21
+ label: c,
22
+ isActive: s = !1,
23
+ contentRef: G,
24
+ icon: N,
25
+ stacked: L = !1,
26
+ tag: y,
27
+ href: T,
28
+ tabStop: w,
29
+ disabled: o,
30
+ // `Tabs` passes this when the row is reorderable. It belongs to the item, so it is taken out of
31
+ // the spread below and placed on the wrapper (or on the bare tab when there is no wrapper).
32
+ draggable: I,
33
+ closable: n,
34
+ onClose: k,
35
+ closeLabel: O = "Close tab",
36
+ actions: b,
37
+ onClick: R,
38
+ onKeyDown: _,
39
+ onMouseDown: D,
18
40
  // The tab sets this on its root too; its own handler calls the caller's first.
19
- onPointerDown: c,
20
- ...b
21
- } = w, r = f.useRef(null), x = (a) => {
22
- n == null || n(a);
23
- }, N = (a) => {
24
- var m;
25
- c == null || c(a), (m = r.current) == null || m.onRipple(a);
26
- }, d = s != null ? s : s || "button", T = j("smwb-tab", R, {
27
- "smwb-tab--active": e,
28
- "smwb-tab--stacked": h,
29
- "smwb-tab--disabled": t
30
- });
31
- return /* @__PURE__ */ p(
32
- d,
41
+ onPointerDown: M,
42
+ ...S
43
+ } = u, K = r.useRef(null), q = r.useRef(null), A = r.useRef(null), [B, W] = r.useState(0), m = y != null ? y : T !== void 0 ? "a" : "button", E = !!o && m !== "button", z = (t) => {
44
+ if (E) {
45
+ t.preventDefault();
46
+ return;
47
+ }
48
+ R == null || R(t);
49
+ }, p = (t, a) => k == null ? void 0 : k(t, a), h = typeof b == "function" ? b({ close: (t) => p(t, "actions") }) : b, x = h != null && h !== !1;
50
+ Z(() => {
51
+ B > 0 && et(A.current);
52
+ }, [B]);
53
+ const U = (t) => {
54
+ var a;
55
+ if (_ == null || _(t), !(o || t.defaultPrevented || t.target !== t.currentTarget)) {
56
+ if (m !== "button" && t.key === " ")
57
+ t.preventDefault(), t.currentTarget.click();
58
+ else if (n && (t.key === "Delete" || t.key === "Backspace") && !$(t))
59
+ t.preventDefault(), p(t, "key");
60
+ else if (x && (t.key === "ContextMenu" || t.key === "F10" && t.shiftKey)) {
61
+ const l = (a = q.current) == null ? void 0 : a.querySelector(g);
62
+ l && (t.preventDefault(), l.focus(), l.getAttribute("aria-expanded") !== "true" && l.click(), A.current = l, W((V) => V + 1));
63
+ }
64
+ }
65
+ }, H = (t) => {
66
+ D == null || D(t), t.button === 1 && n && !o && (t.preventDefault(), p(t, "middleClick"));
67
+ }, J = (t) => {
68
+ var a;
69
+ M == null || M(t), (a = K.current) == null || a.onRipple(t);
70
+ }, P = [
71
+ S["aria-keyshortcuts"],
72
+ !o && n ? "Delete Backspace" : void 0,
73
+ !o && x ? "Shift+F10 ContextMenu" : void 0,
74
+ !o && n ? "Meta+W Control+W" : void 0,
75
+ o ? void 0 : "Meta+Shift+[ Control+Shift+[ Meta+Shift+] Control+Shift+]"
76
+ ].filter(Boolean).join(" ") || void 0, Q = v("smwb-tab", d, {
77
+ "smwb-tab--active": s,
78
+ "smwb-tab--stacked": L,
79
+ "smwb-tab--disabled": o
80
+ }), F = n !== void 0 || b !== void 0, j = /* @__PURE__ */ C(
81
+ m,
33
82
  {
34
- ...b,
35
- ref: u,
36
- className: T,
37
- onMouseDown: x,
38
- onPointerDown: N,
83
+ ...S,
84
+ ref: f,
85
+ className: Q,
86
+ draggable: F ? void 0 : I,
87
+ href: E ? void 0 : T,
88
+ target: void 0,
89
+ onClick: z,
90
+ onKeyDown: U,
91
+ onMouseDown: H,
92
+ onPointerDown: J,
39
93
  role: "tab",
40
- "aria-selected": e,
41
- "aria-disabled": t || b["aria-disabled"],
42
- tabIndex: e ? 0 : -1,
43
- disabled: d === "button" ? t : void 0,
94
+ "aria-selected": s,
95
+ "aria-disabled": o || S["aria-disabled"],
96
+ "aria-keyshortcuts": P,
97
+ tabIndex: (w != null ? w : s) ? 0 : -1,
98
+ disabled: m === "button" ? o : void 0,
44
99
  children: [
45
- /* @__PURE__ */ p("span", { className: "smwb-tab__content", ref: _, children: [
46
- l && /* @__PURE__ */ o("span", { className: "smwb-tab__icon", children: l }),
47
- i && /* @__PURE__ */ o("span", { className: "smwb-tab__text-label", children: i })
100
+ /* @__PURE__ */ C("span", { className: "smwb-tab__content", ref: G, children: [
101
+ N && /* @__PURE__ */ i("span", { className: "smwb-tab__icon", "aria-hidden": "true", children: N }),
102
+ c && /* @__PURE__ */ i("span", { className: "smwb-tab__text-label", children: c })
48
103
  ] }),
49
- /* @__PURE__ */ o(k, { actionRef: r, classes: { child: "tab__ripple-child" } })
104
+ /* @__PURE__ */ i(X, { actionRef: K, classes: { child: "tab__ripple-child" } })
50
105
  ]
51
106
  }
52
107
  );
108
+ return F ? /* @__PURE__ */ C(
109
+ "div",
110
+ {
111
+ className: v("smwb-tab-item", { "smwb-tab-item--active": s, "smwb-tab-item--disabled": o }),
112
+ draggable: I,
113
+ children: [
114
+ j,
115
+ x && /* @__PURE__ */ i("span", { className: "smwb-tab__actions", ref: q, children: h }),
116
+ n && /* @__PURE__ */ i(
117
+ "button",
118
+ {
119
+ type: "button",
120
+ className: "smwb-tab__close",
121
+ tabIndex: -1,
122
+ "aria-label": O,
123
+ disabled: o,
124
+ onMouseDown: (t) => t.preventDefault(),
125
+ onClick: (t) => p(t, "button"),
126
+ children: /* @__PURE__ */ i(Y, { name: "close", size: 16 })
127
+ }
128
+ )
129
+ ]
130
+ }
131
+ ) : j;
53
132
  });
54
133
  export {
55
- y as Tab
134
+ ut as Tab
56
135
  };
57
136
  //# sourceMappingURL=tab.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tab.js","sources":["../../../../../src/components/navigation/tabs/tab/tab.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"clsx\";\nimport { Ripple, RippleActionsRef } from \"../../../base/ripple/ripple\";\n\nexport interface TabProps extends React.HTMLAttributes<HTMLButtonElement | HTMLAnchorElement> {\n label?: string | React.ReactNode;\n isActive?: boolean;\n contentRef?: React.Ref<unknown>;\n icon?: React.ReactNode;\n stacked?: boolean;\n tag?: React.ElementType;\n /** With `tag=\"a\"`: where the link goes, so the tab stays a real link. */\n href?: string;\n disabled?: boolean;\n}\n\nexport const Tab = React.forwardRef<HTMLButtonElement | HTMLAnchorElement, TabProps>(function Tab(props, ref) {\n const {\n className,\n label,\n isActive = false,\n contentRef,\n icon,\n stacked = false,\n tag,\n disabled,\n onMouseDown: onMouseDownProp,\n // The tab sets this on its root too; its own handler calls the caller's first.\n onPointerDown: onPointerDownProp,\n ...rest\n } = props;\n const rippleRef = React.useRef<RippleActionsRef>(null);\n\n const onMouseDown = (event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {\n onMouseDownProp?.(event);\n };\n\n // Ripple on pointerdown so it fires for touch and pen, not just mouse.\n const onPointerDown = (event: React.PointerEvent<HTMLButtonElement | HTMLAnchorElement>) => {\n onPointerDownProp?.(event);\n rippleRef.current?.onRipple(event);\n };\n\n const Tag = tag ?? (tag || \"button\");\n const classes = cn(\"smwb-tab\", className, {\n \"smwb-tab--active\": isActive,\n \"smwb-tab--stacked\": stacked,\n \"smwb-tab--disabled\": disabled,\n });\n\n return (\n <Tag\n {...rest}\n ref={ref}\n className={classes}\n onMouseDown={onMouseDown}\n onPointerDown={onPointerDown}\n // The role, the selection and the roving tabIndex belong to the tab list:\n // they win over the caller's. A tab that is not disabled keeps the\n // caller's aria-disabled.\n role={\"tab\"}\n aria-selected={isActive}\n aria-disabled={disabled || rest[\"aria-disabled\"]}\n tabIndex={isActive ? 0 : -1}\n disabled={Tag === \"button\" ? disabled : undefined}\n >\n <span className=\"smwb-tab__content\" ref={contentRef as React.Ref<HTMLSpanElement>}>\n {icon && <span className=\"smwb-tab__icon\">{icon}</span>}\n {label && <span className=\"smwb-tab__text-label\">{label}</span>}\n </span>\n <Ripple actionRef={rippleRef} classes={{ child: \"tab__ripple-child\" }} />\n </Tag>\n );\n});\n"],"names":["Tab","React","props","ref","className","label","isActive","contentRef","icon","stacked","tag","disabled","onMouseDownProp","onPointerDownProp","rest","rippleRef","onMouseDown","event","onPointerDown","_a","Tag","classes","cn","jsxs","jsx","Ripple"],"mappings":";;;;;;AAkBO,MAAMA,IAAMC,EAAM,WAA4D,SAAaC,GAAOC,GAAK;AAC5G,QAAM;AAAA,IACJ,WAAAC;AAAA,IACA,OAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,YAAAC;AAAA,IACA,MAAAC;AAAA,IACA,SAAAC,IAAU;AAAA,IACV,KAAAC;AAAA,IACA,UAAAC;AAAA,IACA,aAAaC;AAAA;AAAA,IAEb,eAAeC;AAAA,IACf,GAAGC;AAAA,EAAA,IACDZ,GACEa,IAAYd,EAAM,OAAyB,IAAI,GAE/Ce,IAAc,CAACC,MAAmE;AACtF,IAAAL,KAAA,QAAAA,EAAkBK;AAAA,EACpB,GAGMC,IAAgB,CAACD,MAAqE;;AAC1F,IAAAJ,KAAA,QAAAA,EAAoBI,KACpBE,IAAAJ,EAAU,YAAV,QAAAI,EAAmB,SAASF;AAAA,EAC9B,GAEMG,IAAMV,KAAA,OAAAA,IAAQA,KAAO,UACrBW,IAAUC,EAAG,YAAYlB,GAAW;AAAA,IACxC,oBAAoBE;AAAA,IACpB,qBAAqBG;AAAA,IACrB,sBAAsBE;AAAA,EAAA,CACvB;AAED,SACE,gBAAAY;AAAA,IAACH;AAAA,IAAA;AAAA,MACE,GAAGN;AAAA,MACJ,KAAAX;AAAA,MACA,WAAWkB;AAAA,MACX,aAAAL;AAAA,MACA,eAAAE;AAAA,MAIA,MAAM;AAAA,MACN,iBAAeZ;AAAA,MACf,iBAAeK,KAAYG,EAAK,eAAe;AAAA,MAC/C,UAAUR,IAAW,IAAI;AAAA,MACzB,UAAUc,MAAQ,WAAWT,IAAW;AAAA,MAExC,UAAA;AAAA,QAAA,gBAAAY,EAAC,QAAA,EAAK,WAAU,qBAAoB,KAAKhB,GACtC,UAAA;AAAA,UAAAC,KAAQ,gBAAAgB,EAAC,QAAA,EAAK,WAAU,kBAAkB,UAAAhB,GAAK;AAAA,UAC/CH,KAAS,gBAAAmB,EAAC,QAAA,EAAK,WAAU,wBAAwB,UAAAnB,EAAA,CAAM;AAAA,QAAA,GAC1D;AAAA,QACA,gBAAAmB,EAACC,KAAO,WAAWV,GAAW,SAAS,EAAE,OAAO,sBAAoB,CAAG;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG7E,CAAC;"}
1
+ {"version":3,"file":"tab.js","sources":["../../../../../src/components/navigation/tabs/tab/tab.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"clsx\";\nimport { Ripple, RippleActionsRef } from \"../../../base/ripple/ripple\";\nimport Icon from \"../../../base/icon/icon\";\nimport { useSafeLayoutEffect } from \"../../../../hooks/useSafeLayoutEffect\";\n\n/**\n * What asked for a tab to close: its close button, Delete or Backspace or a middle click on it, or\n * its `actions`.\n */\nexport type TabCloseReason = \"button\" | \"key\" | \"middleClick\" | \"actions\";\n\n/** What a function given as `actions` receives. */\nexport interface TabActionsApi {\n /**\n * Ask for the tab to close, as its close button does: `onClose` is called with this event and the\n * reason \"actions\", and `Tabs` moves focus on to the neighbour once the tab goes, even though focus\n * is in a menu drawn outside the row. Call it from the item that closes the tab (\"Terminate\"), with\n * that item's event. It works on a tab that is not `closable`.\n */\n close: (event: React.SyntheticEvent<HTMLElement>) => void;\n}\n\nexport interface TabProps extends React.HTMLAttributes<HTMLButtonElement | HTMLAnchorElement> {\n label?: string | React.ReactNode;\n isActive?: boolean;\n /**\n * Whether the tab is the one in the page's Tab order (`tabIndex` 0, the others -1). `Tabs` sets\n * it: the focused tab while focus is in the row, the selected one otherwise. On its own a tab\n * is the stop while `isActive`.\n */\n tabStop?: boolean;\n contentRef?: React.Ref<unknown>;\n /**\n * Content before the label: a status marker (running, done, failed). The slot is decorative, so\n * the tab's accessible name stays the label alone and nothing is read out twice. An icon that has\n * to be announced belongs in `label`, where you can give it words.\n */\n icon?: React.ReactNode;\n stacked?: boolean;\n /** The element to render. A tab with an `href` is an `a` unless you say otherwise. */\n tag?: React.ElementType;\n /**\n * Navigation mode: where the tab goes. The tab is then a real link (`<a href role=\"tab\">`, with\n * no `target`: a tab never opens another window), so it opens in place and middle click, copy\n * link and the like work. A router takes over the plain click in `onClick` with\n * `event.preventDefault()`; `Tabs` still calls `onChange` for it. A modified or non-primary click\n * (Ctrl, Meta, Shift or Alt held, or a button other than the main one) is the browser's, as\n * \"open in a new tab\": the router must let it through, and `Tabs` does not call `onChange`.\n * The one exception is a middle press on a `closable` tab: it closes the tab instead, as in an\n * editor, and its default is prevented so nothing opens.\n */\n href?: string;\n disabled?: boolean;\n /**\n * Draw a close button after the tab, and let Delete or Backspace on the focused tab close it too\n * (Backspace because a Mac has no Delete key); the tab lists them in `aria-keyshortcuts`. A middle\n * press on the tab asks for the same thing (`reason` \"middleClick\") without selecting it. The tab\n * does not close itself: `onClose` asks for it and the owner removes the `Tab`. The button is a\n * sibling of the tab, not inside its `role=\"tab\"`, so the tab's accessible name is its label alone.\n * It is out of the Tab order (`tabIndex` -1), so the row keeps one tab stop, and a press on it takes\n * no focus and never selects the tab. When the tab that has focus closes, `Tabs` moves focus to the\n * tab that takes its place (the previous one if it was last), skipping disabled tabs. A disabled tab\n * has a disabled button.\n *\n * The button stays in the accessibility tree, named by `closeLabel`: it is how a screen reader user\n * who cannot press Delete, as on a touch screen, closes the tab. It sits in the tab list beside its\n * tab, though, and ARIA 1.2 lets a `tablist` own only `tab`s: a linter that applies that strictly\n * (axe `aria-required-children`) can flag the button, and whatever `actions` holds.\n *\n * To switch it off on a tab, pass `false` rather than leaving it out: a tab given `closable` or\n * `actions` is wrapped in an item with them, a tab given neither is not, and moving between the two\n * recreates the tab and drops its focus.\n */\n closable?: boolean;\n /**\n * Asks for the tab to close, and receives what asked for it: the close button's click (`reason`\n * \"button\"), the key press of Delete or Backspace on the tab (`reason` \"key\", its default is\n * prevented), the middle press on the tab (`reason` \"middleClick\", its default is prevented too),\n * or the event passed to `close` by the tab's `actions` (`reason` \"actions\"). The owner removes\n * the `Tab`.\n */\n onClose?: (event: React.SyntheticEvent<HTMLElement>, reason: TabCloseReason) => void;\n /** Accessible label of the close button. English by default; set it to localise, or to name the tab (\"Close Terminal 1\"). */\n closeLabel?: string;\n /**\n * Content after the tab, before the close button: a trigger with a `Menu` (\"Rename\", \"Terminate\"),\n * or any control. Give a function to get `{ close }` (see `TabActionsApi`). Like the close button\n * the content is a sibling of the tab, so it is not part of the tab's name; the tab's own `ref`,\n * `className` and handlers stay on the `role=\"tab\"` element. It stays in the accessibility tree as\n * written, inside the tab list (see `closable`).\n *\n * The row has one tab stop, so give the trigger `tabIndex={-1}`. Shift+F10 or the Menu key on the\n * focused tab, which the tab lists in `aria-keyshortcuts`, focuses the first control in `actions`\n * and clicks it, unless that control says `aria-expanded=\"true\"` (it is already open). If the\n * control names its popup in `aria-controls`, the first enabled `menuitem` in that element then\n * takes focus, as the WAI-ARIA menu button pattern asks: ArrowDown moves on, Enter chooses, and\n * Escape hands focus back to the trigger. Without `aria-controls` focus stays on the trigger.\n *\n * The row clips what overflows it: draw the menu in a portal, anchored to the trigger and with the\n * `id` the trigger names. A choice that removes the tab (\"Terminate\") should call `close` with its\n * event, so that `onClose` removes the tab and `Tabs` moves focus on to the neighbour; a tab removed\n * some other way leaves focus on the page.\n */\n actions?: React.ReactNode | ((api: TabActionsApi) => React.ReactNode);\n}\n\nconst hasModifier = (event: React.KeyboardEvent): boolean =>\n event.ctrlKey || event.metaKey || event.altKey || event.shiftKey;\n\n/** What the Menu key and Shift+F10 stand for: the actions' trigger. */\nconst ACTIONS_TRIGGER = 'button:not(:disabled), a[href], [role=\"button\"]:not([aria-disabled=\"true\"]), [tabindex]';\n\n/** The item of an opened menu that takes focus first. */\nconst FIRST_MENU_ITEM = '[role^=\"menuitem\"]:not([aria-disabled=\"true\"])';\n\n/** Focus the first item of the popup `trigger` names in `aria-controls`, if it is there. */\nconst focusPopupOf = (trigger: HTMLElement | null): void => {\n for (const id of trigger?.getAttribute(\"aria-controls\")?.split(/\\s+/) ?? []) {\n const item = id ? trigger?.ownerDocument.getElementById(id)?.querySelector<HTMLElement>(FIRST_MENU_ITEM) : null;\n if (item) {\n // The menu may not be placed yet: a scroll to it would jump to the corner it starts in.\n item.focus({ preventScroll: true });\n return;\n }\n }\n};\n\nexport const Tab = React.forwardRef<HTMLButtonElement | HTMLAnchorElement, TabProps>(function Tab(props, ref) {\n const {\n className,\n label,\n isActive = false,\n contentRef,\n icon,\n stacked = false,\n tag,\n href,\n tabStop,\n disabled,\n // `Tabs` passes this when the row is reorderable. It belongs to the item, so it is taken out of\n // the spread below and placed on the wrapper (or on the bare tab when there is no wrapper).\n draggable,\n closable,\n onClose,\n closeLabel = \"Close tab\",\n actions: actionsProp,\n onClick: onClickProp,\n onKeyDown: onKeyDownProp,\n onMouseDown: onMouseDownProp,\n // The tab sets this on its root too; its own handler calls the caller's first.\n onPointerDown: onPointerDownProp,\n ...rest\n } = props;\n const rippleRef = React.useRef<RippleActionsRef>(null);\n const actionsRef = React.useRef<HTMLSpanElement>(null);\n // The trigger the Menu key opened, and how many times it asked for focus to move into its popup.\n const menuTriggerRef = React.useRef<HTMLElement | null>(null);\n const [menuFocusRequest, setMenuFocusRequest] = React.useState(0);\n\n const Tag = tag ?? (href !== undefined ? \"a\" : \"button\");\n // Anything but a button is not disabled by the attribute: its clicks are swallowed here.\n const inert = Boolean(disabled) && Tag !== \"button\";\n\n const onClick = (event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {\n if (inert) {\n event.preventDefault();\n return;\n }\n onClickProp?.(event);\n };\n\n const requestClose = (event: React.SyntheticEvent<HTMLElement>, reason: TabCloseReason) => onClose?.(event, reason);\n const actions =\n typeof actionsProp === \"function\" ? actionsProp({ close: (event) => requestClose(event, \"actions\") }) : actionsProp;\n const hasActions = actions !== undefined && actions !== null && actions !== false;\n\n // The popup opens in the commit that follows the key press, and focus moves into it once it is there.\n useSafeLayoutEffect(() => {\n if (menuFocusRequest > 0) {\n focusPopupOf(menuTriggerRef.current);\n }\n }, [menuFocusRequest]);\n\n // A button clicks on Enter and Space by itself, a link on Enter only: Space does it here.\n const onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement | HTMLAnchorElement>) => {\n onKeyDownProp?.(event);\n if (disabled || event.defaultPrevented || event.target !== event.currentTarget) {\n return;\n }\n if (Tag !== \"button\" && event.key === \" \") {\n event.preventDefault();\n event.currentTarget.click();\n } else if (closable && (event.key === \"Delete\" || event.key === \"Backspace\") && !hasModifier(event)) {\n event.preventDefault();\n requestClose(event, \"key\");\n } else if (hasActions && (event.key === \"ContextMenu\" || (event.key === \"F10\" && event.shiftKey))) {\n // The Menu key, or Shift+F10: the keyboard's right click. The trigger takes focus first, so\n // the menu it opens hands focus back to it on Escape.\n const trigger = actionsRef.current?.querySelector<HTMLElement>(ACTIONS_TRIGGER);\n if (trigger) {\n event.preventDefault();\n trigger.focus();\n // The keys mean \"open\": a menu that already is open is not toggled shut.\n if (trigger.getAttribute(\"aria-expanded\") !== \"true\") {\n trigger.click();\n }\n menuTriggerRef.current = trigger;\n setMenuFocusRequest((count) => count + 1);\n }\n }\n };\n\n // Middle press on a closable tab closes it, as in an editor: never a selection, and its default is\n // prevented so neither the autoscroll nor, on a link tab, the browser's \"open in a new tab\" answers.\n // A caller's `onMouseDown` cannot take the press away — it runs first, then the close is requested\n // whatever it did to the event. Same in Solid; only `closable` and not `disabled` gate it.\n const onMouseDown = (event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {\n onMouseDownProp?.(event);\n if (event.button === 1 && closable && !disabled) {\n event.preventDefault();\n requestClose(event, \"middleClick\");\n }\n };\n\n // Ripple on pointerdown so it fires for touch and pen, not just mouse.\n const onPointerDown = (event: React.PointerEvent<HTMLButtonElement | HTMLAnchorElement>) => {\n onPointerDownProp?.(event);\n rippleRef.current?.onRipple(event);\n };\n\n // What the tab answers to, for assistive technology; the caller's own list is kept.\n // The chords are best-effort: browsers reserve Mod+W and Mod+Shift+[/] in a page of\n // their own tabs, and they bite only in an embedded webview.\n const keyshortcuts =\n [\n rest[\"aria-keyshortcuts\"],\n !disabled && closable ? \"Delete Backspace\" : undefined,\n !disabled && hasActions ? \"Shift+F10 ContextMenu\" : undefined,\n !disabled && closable ? \"Meta+W Control+W\" : undefined,\n !disabled ? \"Meta+Shift+[ Control+Shift+[ Meta+Shift+] Control+Shift+]\" : undefined,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const classes = cn(\"smwb-tab\", className, {\n \"smwb-tab--active\": isActive,\n \"smwb-tab--stacked\": stacked,\n \"smwb-tab--disabled\": disabled,\n });\n\n // The item is the wrapper when the tab has a close button or actions beside it, and the tab itself\n // when it has neither. It, not the `role=\"tab\"` element, is the drag surface of a reorderable row.\n const wrapped = closable !== undefined || actionsProp !== undefined;\n\n const tab = (\n <Tag\n {...rest}\n ref={ref}\n className={classes}\n draggable={wrapped ? undefined : draggable}\n // A disabled link has no href, so it is no link to follow or to focus.\n href={inert ? undefined : href}\n // A tab opens in place, whatever the caller passed.\n target={undefined}\n onClick={onClick}\n onKeyDown={onKeyDown}\n onMouseDown={onMouseDown}\n onPointerDown={onPointerDown}\n // The role, the selection and the roving tabIndex belong to the tab list:\n // they win over the caller's. A tab that is not disabled keeps the\n // caller's aria-disabled.\n role={\"tab\"}\n aria-selected={isActive}\n aria-disabled={disabled || rest[\"aria-disabled\"]}\n aria-keyshortcuts={keyshortcuts}\n tabIndex={(tabStop ?? isActive) ? 0 : -1}\n disabled={Tag === \"button\" ? disabled : undefined}\n >\n <span className=\"smwb-tab__content\" ref={contentRef as React.Ref<HTMLSpanElement>}>\n {icon && (\n <span className=\"smwb-tab__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n {label && <span className=\"smwb-tab__text-label\">{label}</span>}\n </span>\n <Ripple actionRef={rippleRef} classes={{ child: \"tab__ripple-child\" }} />\n </Tag>\n );\n\n // A tab given neither `closable` nor `actions` is the bare element, as it always was.\n if (!wrapped) {\n return tab;\n }\n\n return (\n <div\n className={cn(\"smwb-tab-item\", { \"smwb-tab-item--active\": isActive, \"smwb-tab-item--disabled\": disabled })}\n draggable={draggable}\n >\n {tab}\n {hasActions && (\n <span className=\"smwb-tab__actions\" ref={actionsRef}>\n {actions}\n </span>\n )}\n {closable && (\n <button\n type=\"button\"\n className=\"smwb-tab__close\"\n // Out of the Tab order, so the row keeps its one tab stop; Delete on the tab closes it.\n tabIndex={-1}\n aria-label={closeLabel}\n disabled={disabled}\n // A press does not take focus from where it is: from the tab being closed, or the page.\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => requestClose(event, \"button\")}\n >\n <Icon name=\"close\" size={16} />\n </button>\n )}\n </div>\n );\n});\n"],"names":["hasModifier","event","ACTIONS_TRIGGER","FIRST_MENU_ITEM","focusPopupOf","trigger","id","_b","_a","item","_c","Tab","React","props","ref","className","label","isActive","contentRef","icon","stacked","tag","href","tabStop","disabled","draggable","closable","onClose","closeLabel","actionsProp","onClickProp","onKeyDownProp","onMouseDownProp","onPointerDownProp","rest","rippleRef","actionsRef","menuTriggerRef","menuFocusRequest","setMenuFocusRequest","Tag","inert","onClick","requestClose","reason","actions","hasActions","useSafeLayoutEffect","onKeyDown","count","onMouseDown","onPointerDown","keyshortcuts","classes","cn","wrapped","tab","jsxs","jsx","Ripple","Icon"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ export interface TabPanelProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ /**
4
+ * The tab this panel belongs to: its index, counted as for the `value` of `Tabs`. The panel
5
+ * shows while that tab is selected and is hidden otherwise.
6
+ */
7
+ index: number;
8
+ /** Extra class on the panel. */
9
+ className?: string;
10
+ /** The panel's content. It stays in the document while the panel is hidden. */
11
+ children?: React.ReactNode;
12
+ }
13
+ /**
14
+ * The content of one tab. Give it to the `panels` of `Tabs`, which links it to its tab: the panel
15
+ * is `aria-labelledby` the tab and the tab `aria-controls` the panel. A panel is `role="tabpanel"`
16
+ * and a tab stop of its own (`tabIndex={0}`), so Tab moves from the tab list to the panel. A panel
17
+ * placed anywhere else is not linked to any tabs and is always shown (its `hidden` is yours).
18
+ */
19
+ export declare const TabPanel: React.ForwardRefExoticComponent<TabPanelProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,27 @@
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import '../../../../assets/styles/less/components/tabs/tabPanel/tabPanel.entry.css';import '../../../../assets/styles/less/tokens.entry.css';/* empty css */
3
+ /* empty css */
4
+ import o from "react";
5
+ import m from "clsx";
6
+ import { TabsContext as p } from "../tabsContext.js";
7
+ const I = o.forwardRef(function(r, t) {
8
+ const { index: a, className: i, children: d, ...n } = r, e = o.useContext(p);
9
+ return /* @__PURE__ */ l(
10
+ "div",
11
+ {
12
+ id: e == null ? void 0 : e.panelId(a),
13
+ "aria-labelledby": e == null ? void 0 : e.tabId(a),
14
+ tabIndex: 0,
15
+ ...n,
16
+ ref: t,
17
+ className: m("smwb-tab-panel", i),
18
+ role: "tabpanel",
19
+ hidden: e ? e.value !== a : n.hidden,
20
+ children: d
21
+ }
22
+ );
23
+ });
24
+ export {
25
+ I as TabPanel
26
+ };
27
+ //# sourceMappingURL=tabPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabPanel.js","sources":["../../../../../src/components/navigation/tabs/tabPanel/tabPanel.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"clsx\";\nimport { TabsContext } from \"../tabsContext\";\n\nexport interface TabPanelProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The tab this panel belongs to: its index, counted as for the `value` of `Tabs`. The panel\n * shows while that tab is selected and is hidden otherwise.\n */\n index: number;\n /** Extra class on the panel. */\n className?: string;\n /** The panel's content. It stays in the document while the panel is hidden. */\n children?: React.ReactNode;\n}\n\n/**\n * The content of one tab. Give it to the `panels` of `Tabs`, which links it to its tab: the panel\n * is `aria-labelledby` the tab and the tab `aria-controls` the panel. A panel is `role=\"tabpanel\"`\n * and a tab stop of its own (`tabIndex={0}`), so Tab moves from the tab list to the panel. A panel\n * placed anywhere else is not linked to any tabs and is always shown (its `hidden` is yours).\n */\nexport const TabPanel = React.forwardRef<HTMLDivElement, TabPanelProps>(function TabPanel(props, ref) {\n const { index, className, children, ...rest } = props;\n const tabs = React.useContext(TabsContext);\n\n return (\n <div\n // Yours win: a TabPanel outside Tabs `panels` has no ids to give, and a caller's\n // `id`, `aria-labelledby` or `tabIndex` replaces the linked ones.\n id={tabs?.panelId(index)}\n aria-labelledby={tabs?.tabId(index)}\n tabIndex={0}\n {...rest}\n ref={ref}\n className={cn(\"smwb-tab-panel\", className)}\n role=\"tabpanel\"\n hidden={tabs ? tabs.value !== index : rest.hidden}\n >\n {children}\n </div>\n );\n});\n"],"names":["TabPanel","React","props","ref","index","className","children","rest","tabs","TabsContext","jsx","cn"],"mappings":";;;;;;AAwBO,MAAMA,IAAWC,EAAM,WAA0C,SAAkBC,GAAOC,GAAK;AACpG,QAAM,EAAE,OAAAC,GAAO,WAAAC,GAAW,UAAAC,GAAU,GAAGC,MAASL,GAC1CM,IAAOP,EAAM,WAAWQ,CAAW;AAEzC,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MAGC,IAAIF,KAAA,gBAAAA,EAAM,QAAQJ;AAAA,MAClB,mBAAiBI,KAAA,gBAAAA,EAAM,MAAMJ;AAAA,MAC7B,UAAU;AAAA,MACT,GAAGG;AAAA,MACJ,KAAAJ;AAAA,MACA,WAAWQ,EAAG,kBAAkBN,CAAS;AAAA,MACzC,MAAK;AAAA,MACL,QAAQG,IAAOA,EAAK,UAAUJ,IAAQG,EAAK;AAAA,MAE1C,UAAAD;AAAA,IAAA;AAAA,EAAA;AAGP,CAAC;"}
@@ -1,13 +1,57 @@
1
1
  import React from "react";
2
- import { Tab, TabProps } from "./tab/tab";
2
+ import { Tab, TabProps, type TabActionsApi, type TabCloseReason } from "./tab/tab";
3
+ import { TabPanel, type TabPanelProps } from "./tabPanel/tabPanel";
4
+ /**
5
+ * Tabs follow the WAI-ARIA tabs pattern with manual activation. The selected tab is the row's one
6
+ * tab stop (`tabIndex` 0, the others -1). The arrow keys along the row's `orientation` move focus to
7
+ * the next or the previous tab (wrapping at the ends), Home and End to the first and the last one;
8
+ * disabled tabs are skipped. Enter or Space then selects the focused tab, as a click does:
9
+ * `onChange` is called for it, with the key's click. Moving focus changes nothing by itself, so a
10
+ * row of link tabs does not navigate as the arrows pass them. Tab leaves the row for what follows
11
+ * it, the selected `TabPanel` first when `panels` are given.
12
+ *
13
+ * A `Tab` can be `closable` and take `actions`; they sit beside the tab and out of the Tab order.
14
+ * Delete on the focused tab, its close button or its `actions` (through `close`) ask `onClose` to
15
+ * close it, and when it goes, focus moves to the tab that takes its place instead of falling to the
16
+ * page. A middle click on a closable tab closes it too.
17
+ *
18
+ * With `onReorder` the row's tabs drag onto one another to reorder: `onReorder(from, to)` reports
19
+ * the drop and the owner moves the tabs. With `overflowMenu` a scrollable row that overflows gains
20
+ * a trigger beside it listing the clipped tabs. The chords Mod+W (close the focused closable tab)
21
+ * and Mod+Shift+[ / Mod+Shift+] (switch to the previous / next tab) are handled on the row, as
22
+ * best-effort: a browser of its own tabs reserves them.
23
+ */
3
24
  export interface TabsProps {
4
25
  /**
5
26
  * Index of the selected tab. Tabs count in the order they render: a tab left out,
6
27
  * such as `{show && <Tab />}` while `show` is false, takes no index.
7
28
  */
8
29
  value: number;
9
- /** Called with the index of the clicked tab, counted as for `value`. */
30
+ /**
31
+ * Called with the index of the clicked tab, counted as for `value`. A tab chosen from the keyboard
32
+ * (Enter or Space on the focused tab) calls it with that click too. A modified or non-primary
33
+ * click (Ctrl, Meta, Shift or Alt held, or a button other than the main one) on a link tab
34
+ * (`Tab` with `href`) is the browser's, as "open in a new tab": it does not call `onChange`.
35
+ */
10
36
  onChange: (e: React.MouseEvent<HTMLButtonElement>, index: number) => void;
37
+ /**
38
+ * Which way the tabs run. It sets `aria-orientation` on the tab list and picks the arrow keys that
39
+ * move between tabs: Left and Right when horizontal, Up and Down when vertical. The styles draw
40
+ * a horizontal row; a vertical list is yours to lay out.
41
+ */
42
+ orientation?: "horizontal" | "vertical";
43
+ /**
44
+ * The content of the tabs: `TabPanel`s, rendered after the tab row. With them each tab gets
45
+ * `aria-controls` its panel and each panel `aria-labelledby` its tab. Without them the tabs link
46
+ * to nothing, as before. Give a panel to every tab: a tab whose panel is left out still names it.
47
+ * A `TabPanel` placed anywhere else is not linked to the tabs and is always shown.
48
+ */
49
+ panels?: React.ReactNode;
50
+ /**
51
+ * Base of the ids that link tabs and panels: tab `n` is `{id}-tab-{n}`, its panel `{id}-panel-{n}`.
52
+ * It is also the id of the root element. A generated one by default.
53
+ */
54
+ id?: string;
11
55
  /** Draw the indicator as wide as the selected tab's label rather than the whole tab. */
12
56
  indicatorContent?: boolean;
13
57
  /**
@@ -15,8 +59,34 @@ export interface TabsProps {
15
59
  * more tabs are hidden fades out.
16
60
  */
17
61
  scrollable?: boolean;
18
- /** With `scrollable`: buttons at both ends that scroll the row while it overflows. */
62
+ /**
63
+ * With `scrollable`: buttons at both ends that scroll the row while it overflows. They are for
64
+ * the pointer and stay out of the Tab order: the arrow keys reach every tab and scroll it into
65
+ * view.
66
+ */
19
67
  scrollButtons?: boolean;
68
+ /**
69
+ * Present ⇒ the row is reorderable by dragging a tab onto another (pointer-only; there is no
70
+ * keyboard reorder). `Tabs` does not move the tabs itself: it reports the drag with
71
+ * `onReorder(from, to)` — indexes counted as for `value` — and the owner reorders its state.
72
+ * The tabs keep their focus through a reorder, and a reorder keeps the selection on the same tab:
73
+ * when the dragged tab is the selected one, its new index is reported through `onChange` too, so
74
+ * a controlled owner moves its value along with its array. That report carries the drop event in
75
+ * place of the click a keyboard or menu choice makes, so the index argument is the authoritative
76
+ * one: on a drop `event.currentTarget` is the scroll area, not the moved tab.
77
+ */
78
+ onReorder?: (from: number, to: number) => void;
79
+ /**
80
+ * With `scrollable`: when the row overflows, a trigger button is rendered beside the scroller
81
+ * (in the scroll buttons' spot) that opens a menu of the tabs the viewport clips — any clipped
82
+ * part beyond a 1px tolerance counts. Each entry shows the tab's icon and label, the selected one
83
+ * is marked `aria-current="true"`, and choosing one calls `onChange` for it and scrolls it into
84
+ * view. The trigger appears only after the browser has measured an overflow, so the server markup
85
+ * shows none.
86
+ */
87
+ overflowMenu?: boolean;
88
+ /** Accessible label of the overflow-menu trigger. English by default; set it to localise. */
89
+ overflowMenuAriaLabel?: string;
20
90
  /** Compact tabs: labels as written (no capitals, no letter spacing) and less padding. */
21
91
  dense?: boolean;
22
92
  /** Accessible label of the button that scrolls back. */
@@ -29,5 +99,5 @@ export interface TabsProps {
29
99
  "aria-label"?: string;
30
100
  }
31
101
  export declare const Tabs: React.ForwardRefExoticComponent<TabsProps & React.RefAttributes<HTMLDivElement>>;
32
- export { Tab };
33
- export type { TabProps };
102
+ export { Tab, TabPanel };
103
+ export type { TabProps, TabPanelProps, TabActionsApi, TabCloseReason };