@gooddata/sdk-ui-kit 11.57.0-alpha.2 → 11.57.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/esm/@ui/@utils/keyboardNavigation.d.ts +10 -0
  2. package/esm/@ui/@utils/keyboardNavigation.d.ts.map +1 -1
  3. package/esm/@ui/@utils/keyboardNavigation.js +9 -0
  4. package/esm/@ui/UiAddGranteeDialog/UiAddGranteeDialogCard.d.ts +4 -6
  5. package/esm/@ui/UiAddGranteeDialog/UiAddGranteeDialogCard.d.ts.map +1 -1
  6. package/esm/@ui/UiAddGranteeDialog/UiAddGranteeDialogCard.js +10 -8
  7. package/esm/@ui/UiAutocomplete/useAsyncListSource.js +1 -1
  8. package/esm/@ui/UiGranteeAsyncPicker/UiGranteeAsyncPicker.d.ts +8 -1
  9. package/esm/@ui/UiGranteeAsyncPicker/UiGranteeAsyncPicker.d.ts.map +1 -1
  10. package/esm/@ui/UiGranteeAsyncPicker/UiGranteeAsyncPicker.js +10 -6
  11. package/esm/@ui/UiListbox/defaults/DefaultUiListboxInteractiveItemComponent.d.ts.map +1 -1
  12. package/esm/@ui/UiListbox/defaults/DefaultUiListboxInteractiveItemComponent.js +6 -2
  13. package/esm/@ui/UiMenu/components/defaults/DefaultUiMenuContentItem.d.ts.map +1 -1
  14. package/esm/@ui/UiMenu/components/defaults/DefaultUiMenuContentItem.js +7 -2
  15. package/esm/@ui/UiMenu/components/defaults/DefaultUiMenuInteractiveItem.d.ts.map +1 -1
  16. package/esm/@ui/UiMenu/components/defaults/DefaultUiMenuInteractiveItem.js +7 -2
  17. package/esm/@ui/UiModalDialog/UiDialogHeader.d.ts.map +1 -1
  18. package/esm/@ui/UiModalDialog/UiDialogHeader.js +6 -3
  19. package/esm/@ui/UiObjectShareDialog/UiObjectShareDialogCard.d.ts +16 -3
  20. package/esm/@ui/UiObjectShareDialog/UiObjectShareDialogCard.d.ts.map +1 -1
  21. package/esm/@ui/UiObjectShareDialog/UiObjectShareDialogCard.js +2 -3
  22. package/esm/@ui/UiPermissionMenu/UiPermissionMenu.d.ts +9 -4
  23. package/esm/@ui/UiPermissionMenu/UiPermissionMenu.d.ts.map +1 -1
  24. package/esm/@ui/UiPermissionMenu/UiPermissionMenu.js +20 -29
  25. package/esm/@ui/UiTags/hooks/useResponsiveTags.js +1 -1
  26. package/esm/@ui/UiToolbar/UiToolbar.d.ts +52 -0
  27. package/esm/@ui/UiToolbar/UiToolbar.d.ts.map +1 -0
  28. package/esm/@ui/UiToolbar/UiToolbar.js +44 -0
  29. package/esm/@ui/UiToolbar/UiToolbarChevron.d.ts +8 -0
  30. package/esm/@ui/UiToolbar/UiToolbarChevron.d.ts.map +1 -0
  31. package/esm/@ui/UiToolbar/UiToolbarChevron.js +12 -0
  32. package/esm/@ui/UiToolbar/UiToolbarItemTooltip.d.ts +14 -0
  33. package/esm/@ui/UiToolbar/UiToolbarItemTooltip.d.ts.map +1 -0
  34. package/esm/@ui/UiToolbar/UiToolbarItemTooltip.js +11 -0
  35. package/esm/@ui/UiToolbar/constants.d.ts +5 -0
  36. package/esm/@ui/UiToolbar/constants.d.ts.map +1 -0
  37. package/esm/@ui/UiToolbar/constants.js +6 -0
  38. package/esm/@ui/UiToolbar/context.d.ts +23 -0
  39. package/esm/@ui/UiToolbar/context.d.ts.map +1 -0
  40. package/esm/@ui/UiToolbar/context.js +6 -0
  41. package/esm/@ui/UiToolbar/rovingFocusUtils.d.ts +55 -0
  42. package/esm/@ui/UiToolbar/rovingFocusUtils.d.ts.map +1 -0
  43. package/esm/@ui/UiToolbar/rovingFocusUtils.js +220 -0
  44. package/esm/@ui/UiToolbar/toolbarItemProps.d.ts +35 -0
  45. package/esm/@ui/UiToolbar/toolbarItemProps.d.ts.map +1 -0
  46. package/esm/@ui/UiToolbar/toolbarItemProps.js +2 -0
  47. package/esm/@ui/UiToolbar/useToolbarRovingFocus.d.ts +19 -0
  48. package/esm/@ui/UiToolbar/useToolbarRovingFocus.d.ts.map +1 -0
  49. package/esm/@ui/UiToolbar/useToolbarRovingFocus.js +172 -0
  50. package/esm/@ui/UiToolbarButton/UiToolbarButton.d.ts +19 -0
  51. package/esm/@ui/UiToolbarButton/UiToolbarButton.d.ts.map +1 -0
  52. package/esm/@ui/UiToolbarButton/UiToolbarButton.js +29 -0
  53. package/esm/@ui/UiToolbarButton/useToolbarItemRole.d.ts +38 -0
  54. package/esm/@ui/UiToolbarButton/useToolbarItemRole.d.ts.map +1 -0
  55. package/esm/@ui/UiToolbarButton/useToolbarItemRole.js +67 -0
  56. package/esm/@ui/UiToolbarColorSwatch/UiToolbarColorSwatch.d.ts +38 -0
  57. package/esm/@ui/UiToolbarColorSwatch/UiToolbarColorSwatch.d.ts.map +1 -0
  58. package/esm/@ui/UiToolbarColorSwatch/UiToolbarColorSwatch.js +13 -0
  59. package/esm/@ui/UiToolbarDivider/UiToolbarDivider.d.ts +7 -0
  60. package/esm/@ui/UiToolbarDivider/UiToolbarDivider.d.ts.map +1 -0
  61. package/esm/@ui/UiToolbarDivider/UiToolbarDivider.js +12 -0
  62. package/esm/@ui/UiToolbarIconButton/UiToolbarIconButton.d.ts +34 -0
  63. package/esm/@ui/UiToolbarIconButton/UiToolbarIconButton.d.ts.map +1 -0
  64. package/esm/@ui/UiToolbarIconButton/UiToolbarIconButton.js +34 -0
  65. package/esm/@ui/UiToolbarIconSelect/UiToolbarIconSelect.d.ts +54 -0
  66. package/esm/@ui/UiToolbarIconSelect/UiToolbarIconSelect.d.ts.map +1 -0
  67. package/esm/@ui/UiToolbarIconSelect/UiToolbarIconSelect.js +26 -0
  68. package/esm/@ui/UiToolbarMoreButton/UiToolbarMoreButton.d.ts +41 -0
  69. package/esm/@ui/UiToolbarMoreButton/UiToolbarMoreButton.d.ts.map +1 -0
  70. package/esm/@ui/UiToolbarMoreButton/UiToolbarMoreButton.js +12 -0
  71. package/esm/@ui/UiToolbarSegmentedControl/UiToolbarSegmentedControl.d.ts +37 -0
  72. package/esm/@ui/UiToolbarSegmentedControl/UiToolbarSegmentedControl.d.ts.map +1 -0
  73. package/esm/@ui/UiToolbarSegmentedControl/UiToolbarSegmentedControl.js +145 -0
  74. package/esm/@ui/UiToolbarSegmentedControl/context.d.ts +12 -0
  75. package/esm/@ui/UiToolbarSegmentedControl/context.d.ts.map +1 -0
  76. package/esm/@ui/UiToolbarSegmentedControl/context.js +3 -0
  77. package/esm/@ui/UiToolbarSelect/UiToolbarSelect.d.ts +51 -0
  78. package/esm/@ui/UiToolbarSelect/UiToolbarSelect.d.ts.map +1 -0
  79. package/esm/@ui/UiToolbarSelect/UiToolbarSelect.js +24 -0
  80. package/esm/@ui/UiToolbarStepper/UiToolbarStepper.d.ts +75 -0
  81. package/esm/@ui/UiToolbarStepper/UiToolbarStepper.d.ts.map +1 -0
  82. package/esm/@ui/UiToolbarStepper/UiToolbarStepper.js +85 -0
  83. package/esm/@ui/UiTooltip/UiTooltip.d.ts +1 -1
  84. package/esm/@ui/UiTooltip/UiTooltip.d.ts.map +1 -1
  85. package/esm/@ui/UiTooltip/UiTooltip.js +30 -8
  86. package/esm/@ui/UiTooltip/types.d.ts +17 -1
  87. package/esm/@ui/UiTooltip/types.d.ts.map +1 -1
  88. package/esm/@ui/hooks/useElementSize.d.ts.map +1 -1
  89. package/esm/@ui/hooks/useElementSize.js +2 -1
  90. package/esm/@ui/hooks/useIsTextTruncated.d.ts +12 -0
  91. package/esm/@ui/hooks/useIsTextTruncated.d.ts.map +1 -0
  92. package/esm/@ui/hooks/useIsTextTruncated.js +29 -0
  93. package/esm/Dropdown/Dropdown.js +1 -1
  94. package/esm/EditableLabel/EditableLabel.js +1 -1
  95. package/esm/List/LegacyList.js +1 -1
  96. package/esm/List/List.js +1 -1
  97. package/esm/Menu/positioning/PositionedMenuContent.d.ts.map +1 -1
  98. package/esm/Menu/positioning/PositionedMenuContent.js +3 -0
  99. package/esm/Messages/toasts/NonContextToastsInterop.js +1 -1
  100. package/esm/Messages/toasts/ToastsCenterMessage.d.ts.map +1 -1
  101. package/esm/Messages/toasts/ToastsCenterMessage.js +1 -1
  102. package/esm/ResponsiveText/ResponsiveText.js +3 -3
  103. package/esm/ShortenedText/ShortenedText.js +1 -1
  104. package/esm/index.d.ts +15 -1
  105. package/esm/index.d.ts.map +1 -1
  106. package/esm/index.js +12 -1
  107. package/esm/locales.d.ts +4 -16
  108. package/esm/locales.d.ts.map +1 -1
  109. package/esm/locales.js +2 -6
  110. package/esm/sdk-ui-kit.d.ts +518 -16
  111. package/esm/syntaxHighlightingInput/hooks/useCodemirror.js +1 -1
  112. package/esm/utils/domUtilities.d.ts +4 -0
  113. package/esm/utils/domUtilities.d.ts.map +1 -1
  114. package/esm/utils/domUtilities.js +11 -3
  115. package/esm/utils/events.d.ts +3 -0
  116. package/esm/utils/events.d.ts.map +1 -1
  117. package/esm/utils/events.js +4 -1
  118. package/package.json +13 -14
  119. package/src/@ui/UiAddGranteeDialog/UiAddGranteeDialog.scss +8 -0
  120. package/src/@ui/UiGranteeAsyncPicker/UiGranteeAsyncPicker.scss +0 -6
  121. package/src/@ui/UiGranteeRow/UiGranteeRow.scss +5 -0
  122. package/src/@ui/UiListbox/UiListbox.scss +4 -0
  123. package/src/@ui/UiMenu/UiMenu.scss +3 -0
  124. package/src/@ui/UiModalDialog/UiModalDialog.scss +16 -3
  125. package/src/@ui/UiObjectShareDialog/UiObjectShareDialog.scss +40 -1
  126. package/src/@ui/UiPermissionMenu/UiPermissionMenu.scss +7 -3
  127. package/src/@ui/UiToolbar/UiToolbar.scss +15 -0
  128. package/src/@ui/UiToolbar/UiToolbarChevron.scss +11 -0
  129. package/src/@ui/UiToolbar/toolbarItem.scss +133 -0
  130. package/src/@ui/UiToolbarButton/UiToolbarButton.scss +15 -0
  131. package/src/@ui/UiToolbarColorSwatch/UiToolbarColorSwatch.scss +66 -0
  132. package/src/@ui/UiToolbarDivider/UiToolbarDivider.scss +11 -0
  133. package/src/@ui/UiToolbarIconButton/UiToolbarIconButton.scss +30 -0
  134. package/src/@ui/UiToolbarIconSelect/UiToolbarIconSelect.scss +12 -0
  135. package/src/@ui/UiToolbarSegmentedControl/UiToolbarSegmentedControl.scss +10 -0
  136. package/src/@ui/UiToolbarSelect/UiToolbarSelect.scss +29 -0
  137. package/src/@ui/UiToolbarStepper/UiToolbarStepper.scss +53 -0
  138. package/src/@ui/UiTooltip/UiTooltip.scss +5 -0
  139. package/src/@ui/defaultTheme.scss +8 -3
  140. package/src/@ui/index.scss +10 -0
  141. package/styles/css/main.css +573 -11
  142. package/styles/css/main.css.map +1 -1
@@ -0,0 +1,52 @@
1
+ import { type ReactNode } from "react";
2
+ import { type UiToolbarNamingConfig } from "./context.js";
3
+ /**
4
+ * @internal
5
+ */
6
+ export interface IUiToolbarProps {
7
+ /**
8
+ * The toolbar needs an accessible name.
9
+ */
10
+ accessibilityConfig: UiToolbarNamingConfig;
11
+ children: ReactNode;
12
+ /**
13
+ * Side of the toolbar on which item tooltips open. Use "above" for a toolbar docked at the bottom.
14
+ * @defaultValue "below"
15
+ */
16
+ tooltipPlacement?: "below" | "above";
17
+ /**
18
+ * Keep disabled items reachable with arrow keys.
19
+ * @defaultValue true
20
+ */
21
+ isDisabledFocusable?: boolean;
22
+ /**
23
+ * Wrap from the last item to the first one and back.
24
+ * @defaultValue true
25
+ */
26
+ loop?: boolean;
27
+ dataTestId?: string;
28
+ }
29
+ /**
30
+ * Horizontal toolbar with one tab stop. Arrow keys move between items, Home and End jump to the
31
+ * ends, and the last focused item is remembered when focus leaves and comes back. Inside a
32
+ * {@link UiToolbarSegmentedControl} the arrows change the selection first and continue to the
33
+ * neighbouring item at the ends.
34
+ *
35
+ * Editable values inside a toolbar must be text-like inputs (`type="text"` with an `inputMode`, or
36
+ * a textarea): the arrows move the caret and hand off to the neighbouring item at the text edges.
37
+ * Inputs without a caret API, such as `type="number"`, cannot hand off; wrap such custom controls in
38
+ * an element with {@link TOOLBAR_SKIP_ATTR} so they keep their own keyboard handling.
39
+ *
40
+ * @example
41
+ * ```
42
+ * <UiToolbar accessibilityConfig={{ ariaLabel: "Formatting" }}>
43
+ * <UiToolbarIconButton icon="bold" label="Bold" isSelected onClick={toggleBold} />
44
+ * <UiToolbarDivider />
45
+ * <UiToolbarButton label="Reset" onClick={reset} />
46
+ * </UiToolbar>
47
+ * ```
48
+ *
49
+ * @internal
50
+ */
51
+ export declare const UiToolbar: import("react").ForwardRefExoticComponent<IUiToolbarProps & import("react").RefAttributes<HTMLDivElement>>;
52
+ //# sourceMappingURL=UiToolbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UiToolbar.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiToolbar/UiToolbar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAoD,MAAM,OAAO,CAAC;AAYzF,OAAO,EAAiD,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAIzG;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B;;OAEG;IACH,mBAAmB,EAAE,qBAAqB,CAAC;IAC3C,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACrC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,SAAS,4GAgDpB,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { forwardRef, useImperativeHandle, useMemo, useRef } from "react";
4
+ import { FloatingDelayGroup } from "@floating-ui/react";
5
+ import { accessibilityConfigToAttributes } from "../../typings/utilities.js";
6
+ import { bem } from "../@utils/bem.js";
7
+ import { TOOLBAR_TOOLTIP_CLOSE_DELAY, TOOLBAR_TOOLTIP_OPEN_DELAY, TOOLBAR_TOOLTIP_WARM_TIMEOUT, } from "./constants.js";
8
+ import { UiToolbarContext } from "./context.js";
9
+ import { TOOLBAR_ROOT_ATTR } from "./rovingFocusUtils.js";
10
+ import { useToolbarRovingFocus } from "./useToolbarRovingFocus.js";
11
+ const { b } = bem("gd-ui-kit-toolbar");
12
+ /**
13
+ * Horizontal toolbar with one tab stop. Arrow keys move between items, Home and End jump to the
14
+ * ends, and the last focused item is remembered when focus leaves and comes back. Inside a
15
+ * {@link UiToolbarSegmentedControl} the arrows change the selection first and continue to the
16
+ * neighbouring item at the ends.
17
+ *
18
+ * Editable values inside a toolbar must be text-like inputs (`type="text"` with an `inputMode`, or
19
+ * a textarea): the arrows move the caret and hand off to the neighbouring item at the text edges.
20
+ * Inputs without a caret API, such as `type="number"`, cannot hand off; wrap such custom controls in
21
+ * an element with {@link TOOLBAR_SKIP_ATTR} so they keep their own keyboard handling.
22
+ *
23
+ * @example
24
+ * ```
25
+ * <UiToolbar accessibilityConfig={{ ariaLabel: "Formatting" }}>
26
+ * <UiToolbarIconButton icon="bold" label="Bold" isSelected onClick={toggleBold} />
27
+ * <UiToolbarDivider />
28
+ * <UiToolbarButton label="Reset" onClick={reset} />
29
+ * </UiToolbar>
30
+ * ```
31
+ *
32
+ * @internal
33
+ */
34
+ export const UiToolbar = forwardRef(function UiToolbar({ accessibilityConfig, children, tooltipPlacement = "below", isDisabledFocusable = true, loop = true, dataTestId, }, ref) {
35
+ const containerRef = useRef(null);
36
+ useImperativeHandle(ref, () => containerRef.current, []);
37
+ const { onKeyDown, onFocusCapture, onBlurCapture } = useToolbarRovingFocus({
38
+ containerRef,
39
+ isDisabledFocusable,
40
+ loop,
41
+ });
42
+ const contextValue = useMemo(() => ({ tooltipArrowPlacement: tooltipPlacement === "above" ? "bottom" : "top" }), [tooltipPlacement]);
43
+ return (_jsx(UiToolbarContext.Provider, { value: contextValue, children: _jsx(FloatingDelayGroup, { delay: { open: TOOLBAR_TOOLTIP_OPEN_DELAY, close: TOOLBAR_TOOLTIP_CLOSE_DELAY }, timeoutMs: TOOLBAR_TOOLTIP_WARM_TIMEOUT, children: _jsx("div", { ref: containerRef, className: b(), ...accessibilityConfigToAttributes(accessibilityConfig), role: "toolbar", "aria-orientation": "horizontal", [TOOLBAR_ROOT_ATTR]: "", "data-testid": dataTestId, onKeyDown: onKeyDown, onFocusCapture: onFocusCapture, onBlurCapture: onBlurCapture, children: children }) }) }));
44
+ });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Popup affordance of the toolbar selects. It rotates instead of swapping the icon, so the flip
3
+ * animates. Decorative: the owning control carries the accessible name and `aria-expanded`.
4
+ */
5
+ export declare function UiToolbarChevron({ isOpen }: {
6
+ isOpen: boolean;
7
+ }): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=UiToolbarChevron.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UiToolbarChevron.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiToolbar/UiToolbarChevron.tsx"],"names":[],"mappings":"AAOA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,2CAM/D"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { bem } from "../@utils/bem.js";
4
+ import { UiIcon } from "../UiIcon/UiIcon.js";
5
+ const { b } = bem("gd-ui-kit-toolbar-chevron");
6
+ /**
7
+ * Popup affordance of the toolbar selects. It rotates instead of swapping the icon, so the flip
8
+ * animates. Decorative: the owning control carries the accessible name and `aria-expanded`.
9
+ */
10
+ export function UiToolbarChevron({ isOpen }) {
11
+ return (_jsx("span", { className: b({ isOpen }), children: _jsx(UiIcon, { type: "navigateDown", size: 14, layout: "block", accessibilityConfig: { ariaHidden: true } }) }));
12
+ }
@@ -0,0 +1,14 @@
1
+ import { type ReactNode } from "react";
2
+ export interface IUiToolbarItemTooltipProps {
3
+ content: ReactNode;
4
+ children: ReactNode;
5
+ /**
6
+ * Hides the tooltip, for example while the item's popup is open.
7
+ */
8
+ isDisabled?: boolean;
9
+ }
10
+ /**
11
+ * Tooltip of a toolbar item. It is visual only: the item keeps its own accessible name.
12
+ */
13
+ export declare function UiToolbarItemTooltip({ content, children, isDisabled }: IUiToolbarItemTooltipProps): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=UiToolbarItemTooltip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UiToolbarItemTooltip.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiToolbar/UiToolbarItemTooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAWvC,MAAM,WAAW,0BAA0B;IACvC,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAkB,EAAE,EAAE,0BAA0B,2CAoBzG"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { UiTooltip } from "../UiTooltip/UiTooltip.js";
3
+ import { TOOLBAR_TOOLTIP_CLOSE_DELAY, TOOLBAR_TOOLTIP_OFFSET, TOOLBAR_TOOLTIP_OPEN_DELAY, } from "./constants.js";
4
+ import { useUiToolbarContextOptional } from "./context.js";
5
+ /**
6
+ * Tooltip of a toolbar item. It is visual only: the item keeps its own accessible name.
7
+ */
8
+ export function UiToolbarItemTooltip({ content, children, isDisabled = false }) {
9
+ const toolbar = useUiToolbarContextOptional();
10
+ return (_jsx(UiTooltip, { anchor: children, content: content, triggerBy: ["hover", "focus"], arrowPlacement: toolbar?.tooltipArrowPlacement ?? "top", offset: TOOLBAR_TOOLTIP_OFFSET, hoverOpenDelay: TOOLBAR_TOOLTIP_OPEN_DELAY, hoverCloseDelay: TOOLBAR_TOOLTIP_CLOSE_DELAY, delayGroup: toolbar !== null, closeOnAnchorClick: true, accessibilityHidden: true, component: "span", inlineAnchor: true, disabled: isDisabled }));
11
+ }
@@ -0,0 +1,5 @@
1
+ export declare const TOOLBAR_TOOLTIP_OPEN_DELAY = 300;
2
+ export declare const TOOLBAR_TOOLTIP_CLOSE_DELAY = 100;
3
+ export declare const TOOLBAR_TOOLTIP_WARM_TIMEOUT = 500;
4
+ export declare const TOOLBAR_TOOLTIP_OFFSET: number;
5
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiToolbar/constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,eAAO,MAAM,sBAAsB,QAAmB,CAAC"}
@@ -0,0 +1,6 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { ARROW_HEIGHT } from "../UiTooltip/constants.js";
3
+ export const TOOLBAR_TOOLTIP_OPEN_DELAY = 300;
4
+ export const TOOLBAR_TOOLTIP_CLOSE_DELAY = 100;
5
+ export const TOOLBAR_TOOLTIP_WARM_TIMEOUT = 500;
6
+ export const TOOLBAR_TOOLTIP_OFFSET = ARROW_HEIGHT + 2;
@@ -0,0 +1,23 @@
1
+ import { type IAccessibilityConfigBase } from "../../typings/accessibility.js";
2
+ import { type TooltipArrowPlacement } from "../UiTooltip/types.js";
3
+ /**
4
+ * An accessible name for a toolbar or a group: a label, or a reference to a labelling element.
5
+ *
6
+ * @internal
7
+ */
8
+ export type UiToolbarNamingConfig = {
9
+ ariaLabel: NonNullable<IAccessibilityConfigBase["ariaLabel"]>;
10
+ ariaLabelledBy?: IAccessibilityConfigBase["ariaLabelledBy"];
11
+ } | {
12
+ ariaLabel?: IAccessibilityConfigBase["ariaLabel"];
13
+ ariaLabelledBy: NonNullable<IAccessibilityConfigBase["ariaLabelledBy"]>;
14
+ };
15
+ /**
16
+ * @internal
17
+ */
18
+ export interface IUiToolbarContextValue {
19
+ tooltipArrowPlacement: Extract<TooltipArrowPlacement, "top" | "bottom">;
20
+ }
21
+ export declare const UiToolbarContext: import("react").Context<IUiToolbarContextValue | null>;
22
+ export declare function useUiToolbarContextOptional(): IUiToolbarContextValue | null;
23
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiToolbar/context.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAC3B;IACI,SAAS,EAAE,WAAW,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9D,cAAc,CAAC,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;CAC/D,GACD;IACI,SAAS,CAAC,EAAE,wBAAwB,CAAC,WAAW,CAAC,CAAC;IAClD,cAAc,EAAE,WAAW,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC3E,CAAC;AAER;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;CAC3E;AAED,eAAO,MAAM,gBAAgB,wDAAqD,CAAC;AAEnF,wBAAgB,2BAA2B,IAAI,sBAAsB,GAAG,IAAI,CAE3E"}
@@ -0,0 +1,6 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { createContext, useContext } from "react";
3
+ export const UiToolbarContext = createContext(null);
4
+ export function useUiToolbarContextOptional() {
5
+ return useContext(UiToolbarContext);
6
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Marks an element that holds several focusable children but counts as one toolbar stop (a radiogroup).
3
+ */
4
+ export declare const TOOLBAR_COMPOSITE_ATTR = "data-gd-toolbar-composite";
5
+ /**
6
+ * Marks a subtree the toolbar keyboard navigation must ignore. Set it as a data attribute on a
7
+ * wrapper element inside a {@link UiToolbar}.
8
+ *
9
+ * @internal
10
+ */
11
+ export declare const TOOLBAR_SKIP_ATTR = "data-gd-toolbar-skip";
12
+ /**
13
+ * Set on every element whose tabindex the toolbar wrote, so the write can be undone when the element
14
+ * leaves the managed set.
15
+ */
16
+ export declare const TOOLBAR_MANAGED_ATTR = "data-gd-toolbar-managed";
17
+ /**
18
+ * Marks the root of a {@link UiToolbar}; composites use it to tell a managing toolbar from any other
19
+ * `role="toolbar"` element.
20
+ */
21
+ export declare const TOOLBAR_ROOT_ATTR = "data-gd-toolbar";
22
+ export interface IRovingFocusOptions {
23
+ isDisabledFocusable: boolean;
24
+ }
25
+ /**
26
+ * True while the element is still one of the container's eligible focus targets.
27
+ */
28
+ export declare function isEligibleFocusable(container: HTMLElement, element: HTMLElement, options: IRovingFocusOptions): boolean;
29
+ /**
30
+ * True when the element sits in a subtree marked with {@link TOOLBAR_SKIP_ATTR} below the container.
31
+ */
32
+ export declare function isSkipped(container: HTMLElement, element: HTMLElement): boolean;
33
+ export declare function isEligible(element: HTMLElement, options: IRovingFocusOptions): boolean;
34
+ export declare function getFocusableDescendants(container: HTMLElement): HTMLElement[];
35
+ export declare function getToolbarStops(container: HTMLElement, options: IRovingFocusOptions): HTMLElement[];
36
+ export declare function resolveStop(container: HTMLElement, element: Element | null): HTMLElement | null;
37
+ export declare function getStopFocusTarget(stop: HTMLElement, remembered: HTMLElement | null, options: IRovingFocusOptions): HTMLElement | null;
38
+ /**
39
+ * Makes exactly one focusable descendant reachable with Tab and returns it.
40
+ */
41
+ export declare function applyRovingTabIndex(container: HTMLElement, remembered: HTMLElement | null, options: IRovingFocusOptions): HTMLElement | null;
42
+ export declare function isCaretAtEdge(target: EventTarget | null, direction: "ArrowLeft" | "ArrowRight"): boolean;
43
+ /**
44
+ * True for elements that use arrow, Home and End keys to move a caret or a value.
45
+ */
46
+ export declare function isEditingTarget(target: EventTarget | null): boolean;
47
+ /**
48
+ * True when Alt, Ctrl or Meta is held. Those arrow combinations belong to the browser or the OS.
49
+ */
50
+ export declare function hasSystemModifier(event: {
51
+ altKey: boolean;
52
+ ctrlKey: boolean;
53
+ metaKey: boolean;
54
+ }): boolean;
55
+ //# sourceMappingURL=rovingFocusUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rovingFocusUtils.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiToolbar/rovingFocusUtils.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,sBAAsB,8BAA8B,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,yBAAyB,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IAChC,mBAAmB,EAAE,OAAO,CAAC;CAChC;AAmDD;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,mBAAmB,GAC7B,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAG/E;AAYD,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAEtF;AAOD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,EAAE,CAI7E;AAMD,wBAAgB,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,GAAG,WAAW,EAAE,CAoBnG;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,WAAW,GAAG,IAAI,CAM/F;AAED,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,WAAW,GAAG,IAAI,EAC9B,OAAO,EAAE,mBAAmB,GAC7B,WAAW,GAAG,IAAI,CAYpB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,WAAW,EACtB,UAAU,EAAE,WAAW,GAAG,IAAI,EAC9B,OAAO,EAAE,mBAAmB,GAC7B,WAAW,GAAG,IAAI,CAyBpB;AA0CD,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,SAAS,EAAE,WAAW,GAAG,YAAY,GAAG,OAAO,CAgBxG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAQnE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAEzG"}
@@ -0,0 +1,220 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { focusableElementsSelector } from "../../utils/domUtilities.js";
3
+ /**
4
+ * Marks an element that holds several focusable children but counts as one toolbar stop (a radiogroup).
5
+ */
6
+ export const TOOLBAR_COMPOSITE_ATTR = "data-gd-toolbar-composite";
7
+ /**
8
+ * Marks a subtree the toolbar keyboard navigation must ignore. Set it as a data attribute on a
9
+ * wrapper element inside a {@link UiToolbar}.
10
+ *
11
+ * @internal
12
+ */
13
+ export const TOOLBAR_SKIP_ATTR = "data-gd-toolbar-skip";
14
+ /**
15
+ * Set on every element whose tabindex the toolbar wrote, so the write can be undone when the element
16
+ * leaves the managed set.
17
+ */
18
+ export const TOOLBAR_MANAGED_ATTR = "data-gd-toolbar-managed";
19
+ /**
20
+ * Marks the root of a {@link UiToolbar}; composites use it to tell a managing toolbar from any other
21
+ * `role="toolbar"` element.
22
+ */
23
+ export const TOOLBAR_ROOT_ATTR = "data-gd-toolbar";
24
+ function matchesDisabled(element) {
25
+ try {
26
+ return element.matches(":disabled");
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ // A disabled fieldset disables its descendants too, except those in its first legend.
33
+ function isNativelyDisabled(element) {
34
+ if (("disabled" in element && element.disabled === true) ||
35
+ matchesDisabled(element)) {
36
+ return true;
37
+ }
38
+ const fieldset = element.closest("fieldset[disabled]");
39
+ if (fieldset === null) {
40
+ return false;
41
+ }
42
+ const legend = fieldset.querySelector(":scope > legend");
43
+ return legend === null || !legend.contains(element);
44
+ }
45
+ function isHiddenByStyle(element) {
46
+ const style = element.ownerDocument.defaultView?.getComputedStyle(element);
47
+ return style !== undefined && (style.display === "none" || style.visibility === "hidden");
48
+ }
49
+ /**
50
+ * Hidden by an attribute or by CSS, on the element or on any ancestor below the container.
51
+ */
52
+ function isHidden(container, element) {
53
+ const hidden = element.closest('[hidden], [aria-hidden="true"]');
54
+ if (hidden !== null && hidden !== container && container.contains(hidden)) {
55
+ return true;
56
+ }
57
+ for (let node = element; node !== null && node !== container; node = node.parentElement) {
58
+ if (isHiddenByStyle(node)) {
59
+ return true;
60
+ }
61
+ }
62
+ return false;
63
+ }
64
+ /**
65
+ * True while the element is still one of the container's eligible focus targets.
66
+ */
67
+ export function isEligibleFocusable(container, element, options) {
68
+ return element.isConnected && isFocusable(container, element) && isEligible(element, options);
69
+ }
70
+ /**
71
+ * True when the element sits in a subtree marked with {@link TOOLBAR_SKIP_ATTR} below the container.
72
+ */
73
+ export function isSkipped(container, element) {
74
+ const skipped = element.closest(`[${TOOLBAR_SKIP_ATTR}]`);
75
+ return skipped !== null && skipped !== container && container.contains(skipped);
76
+ }
77
+ function isFocusable(container, element) {
78
+ return (element.matches(focusableElementsSelector) &&
79
+ !isNativelyDisabled(element) &&
80
+ element.getAttribute("role") !== "separator" &&
81
+ !isHidden(container, element) &&
82
+ !isSkipped(container, element));
83
+ }
84
+ export function isEligible(element, options) {
85
+ return options.isDisabledFocusable || element.getAttribute("aria-disabled") !== "true";
86
+ }
87
+ function getCompositeOf(container, element) {
88
+ const composite = element.parentElement?.closest(`[${TOOLBAR_COMPOSITE_ATTR}]`) ?? null;
89
+ return composite !== null && composite !== container && container.contains(composite) ? composite : null;
90
+ }
91
+ export function getFocusableDescendants(container) {
92
+ return Array.from(container.querySelectorAll(focusableElementsSelector)).filter((element) => isFocusable(container, element));
93
+ }
94
+ function getEligibleWithin(composite, options) {
95
+ return getFocusableDescendants(composite).filter((element) => isEligible(element, options));
96
+ }
97
+ export function getToolbarStops(container, options) {
98
+ const candidates = container.querySelectorAll(`${focusableElementsSelector}, [${TOOLBAR_COMPOSITE_ATTR}]`);
99
+ return Array.from(candidates).filter((element) => {
100
+ if (element.hasAttribute(TOOLBAR_COMPOSITE_ATTR)) {
101
+ return (!isHidden(container, element) &&
102
+ !isSkipped(container, element) &&
103
+ getEligibleWithin(element, options).length > 0);
104
+ }
105
+ return (getCompositeOf(container, element) === null &&
106
+ isFocusable(container, element) &&
107
+ isEligible(element, options));
108
+ });
109
+ }
110
+ export function resolveStop(container, element) {
111
+ if (!(element instanceof HTMLElement) || !container.contains(element)) {
112
+ return null;
113
+ }
114
+ return getCompositeOf(container, element) ?? element;
115
+ }
116
+ export function getStopFocusTarget(stop, remembered, options) {
117
+ if (!stop.hasAttribute(TOOLBAR_COMPOSITE_ATTR)) {
118
+ return stop;
119
+ }
120
+ const within = getEligibleWithin(stop, options);
121
+ if (remembered && within.includes(remembered)) {
122
+ return remembered;
123
+ }
124
+ return within.find((element) => element.getAttribute("aria-checked") === "true") ?? within[0] ?? null;
125
+ }
126
+ /**
127
+ * Makes exactly one focusable descendant reachable with Tab and returns it.
128
+ */
129
+ export function applyRovingTabIndex(container, remembered, options) {
130
+ const stops = getToolbarStops(container, options);
131
+ let stop = remembered ? resolveStop(container, remembered) : null;
132
+ if (stop === null || !stops.includes(stop)) {
133
+ stop = stops[0] ?? null;
134
+ }
135
+ const target = stop === null ? null : (getStopFocusTarget(stop, remembered, options) ?? stops[0]);
136
+ // Hidden and disabled descendants are reset too, so a stop that became hidden or disabled cannot
137
+ // keep tabindex 0. An element that moved into a skipped subtree gets the toolbar's write undone.
138
+ for (const element of container.querySelectorAll(focusableElementsSelector)) {
139
+ if (isSkipped(container, element)) {
140
+ if (element.hasAttribute(TOOLBAR_MANAGED_ATTR)) {
141
+ element.removeAttribute("tabindex");
142
+ element.removeAttribute(TOOLBAR_MANAGED_ATTR);
143
+ }
144
+ continue;
145
+ }
146
+ element.tabIndex = element === target ? 0 : -1;
147
+ element.setAttribute(TOOLBAR_MANAGED_ATTR, "");
148
+ }
149
+ return target;
150
+ }
151
+ const NON_EDITING_INPUT_TYPES = new Set(["button", "checkbox", "radio", "submit", "reset", "image", "file"]);
152
+ /**
153
+ * The logical offset a horizontal arrow leaves the text at. In an RTL field offset 0 sits at the
154
+ * visual right edge, so the two arrows swap.
155
+ *
156
+ * An explicit `dir` attribute wins over the computed style: it is what a consumer sets to mark a
157
+ * right-to-left value, and test environments do not resolve it into `direction`.
158
+ */
159
+ function isStartEdgeKey(target, direction) {
160
+ const declared = target.closest("[dir]")?.getAttribute("dir")?.toLowerCase();
161
+ const isRtl = declared === "rtl" ||
162
+ (declared !== "ltr" &&
163
+ target.ownerDocument.defaultView?.getComputedStyle(target).direction === "rtl");
164
+ return isRtl ? direction === "ArrowRight" : direction === "ArrowLeft";
165
+ }
166
+ function isContentEditableCaretAtEdge(target, direction) {
167
+ const selection = target.ownerDocument.getSelection();
168
+ if (!selection || !selection.isCollapsed || selection.rangeCount === 0) {
169
+ return false;
170
+ }
171
+ const caret = selection.getRangeAt(0);
172
+ if (!target.contains(caret.startContainer)) {
173
+ return false;
174
+ }
175
+ const before = target.ownerDocument.createRange();
176
+ before.selectNodeContents(target);
177
+ before.setEnd(caret.startContainer, caret.startOffset);
178
+ const offset = before.toString().length;
179
+ return isStartEdgeKey(target, direction) ? offset === 0 : offset === (target.textContent ?? "").length;
180
+ }
181
+ /**
182
+ * True when a horizontal arrow key in an editing target would move the caret past its edge, so the
183
+ * key can be handed to the toolbar instead.
184
+ */
185
+ const SELECTION_INPUT_TYPES = new Set(["text", "search", "url", "tel", "password"]);
186
+ export function isCaretAtEdge(target, direction) {
187
+ // Other input types have no caret selection; reading it returns null or throws.
188
+ if (target instanceof HTMLInputElement && !SELECTION_INPUT_TYPES.has(target.type)) {
189
+ return false;
190
+ }
191
+ if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
192
+ const { selectionStart, selectionEnd, value } = target;
193
+ if (selectionStart === null || selectionEnd === null || selectionStart !== selectionEnd) {
194
+ return false;
195
+ }
196
+ return isStartEdgeKey(target, direction) ? selectionStart === 0 : selectionEnd === value.length;
197
+ }
198
+ if (target instanceof HTMLElement && target.isContentEditable) {
199
+ return isContentEditableCaretAtEdge(target, direction);
200
+ }
201
+ return false;
202
+ }
203
+ /**
204
+ * True for elements that use arrow, Home and End keys to move a caret or a value.
205
+ */
206
+ export function isEditingTarget(target) {
207
+ if (!(target instanceof HTMLElement)) {
208
+ return false;
209
+ }
210
+ if (target.isContentEditable || target instanceof HTMLTextAreaElement) {
211
+ return true;
212
+ }
213
+ return target instanceof HTMLInputElement && !NON_EDITING_INPUT_TYPES.has(target.type);
214
+ }
215
+ /**
216
+ * True when Alt, Ctrl or Meta is held. Those arrow combinations belong to the browser or the OS.
217
+ */
218
+ export function hasSystemModifier(event) {
219
+ return event.altKey || event.ctrlKey || event.metaKey;
220
+ }
@@ -0,0 +1,35 @@
1
+ import { type KeyboardEvent, type MouseEvent } from "react";
2
+ import { type IAccessibilityConfigBase } from "../../typings/accessibility.js";
3
+ import { type IUiDropdownButtonRenderProps } from "../UiDropdown/types.js";
4
+ /**
5
+ * Props every interactive toolbar item shares.
6
+ *
7
+ * @internal
8
+ */
9
+ export interface IUiToolbarItemBaseProps {
10
+ /**
11
+ * Identifies the item inside a {@link UiToolbarSegmentedControl}.
12
+ */
13
+ value?: string;
14
+ /**
15
+ * Toggle state, exposed as `aria-pressed`. Inside a segmented control the group's value wins.
16
+ */
17
+ isSelected?: boolean;
18
+ isDestructive?: boolean;
19
+ isDisabled?: boolean;
20
+ /**
21
+ * Pressed look held while a popup opened by the item is on screen.
22
+ */
23
+ isActive?: boolean;
24
+ onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
25
+ onKeyDown?: (event: KeyboardEvent<HTMLButtonElement>) => void;
26
+ id?: string;
27
+ dataId?: string;
28
+ dataTestId?: string;
29
+ accessibilityConfig?: IAccessibilityConfigBase;
30
+ /**
31
+ * Attributes from the `renderButton` callback of {@link UiDropdown}.
32
+ */
33
+ ariaAttributes?: IUiDropdownButtonRenderProps["ariaAttributes"];
34
+ }
35
+ //# sourceMappingURL=toolbarItemProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolbarItemProps.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiToolbar/toolbarItemProps.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACzD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC9D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,wBAAwB,CAAC;IAC/C;;OAEG;IACH,cAAc,CAAC,EAAE,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;CACnE"}
@@ -0,0 +1,2 @@
1
+ // (C) 2026 GoodData Corporation
2
+ export {};
@@ -0,0 +1,19 @@
1
+ import { type FocusEvent, type KeyboardEvent, type RefObject } from "react";
2
+ export interface IUseToolbarRovingFocusOptions {
3
+ containerRef: RefObject<HTMLElement | null>;
4
+ isDisabledFocusable: boolean;
5
+ loop: boolean;
6
+ }
7
+ export interface IUseToolbarRovingFocusResult {
8
+ onKeyDown: (event: KeyboardEvent<HTMLElement>) => void;
9
+ onFocusCapture: (event: FocusEvent<HTMLElement>) => void;
10
+ onBlurCapture: (event: FocusEvent<HTMLElement>) => void;
11
+ }
12
+ /**
13
+ * Roving tabindex over the focusable descendants of a container, driven by the DOM.
14
+ *
15
+ * Children must not render a tabIndex that changes between renders. React only rewrites the
16
+ * attribute when the prop changes, so a constant value never overrides what this hook writes.
17
+ */
18
+ export declare function useToolbarRovingFocus({ containerRef, isDisabledFocusable, loop, }: IUseToolbarRovingFocusOptions): IUseToolbarRovingFocusResult;
19
+ //# sourceMappingURL=useToolbarRovingFocus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useToolbarRovingFocus.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiToolbar/useToolbarRovingFocus.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,SAAS,EAMjB,MAAM,OAAO,CAAC;AAoBf,MAAM,WAAW,6BAA6B;IAC1C,YAAY,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC5C,mBAAmB,EAAE,OAAO,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,4BAA4B;IACzC,SAAS,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACzD,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;CAC3D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,EAClC,YAAY,EACZ,mBAAmB,EACnB,IAAI,GACP,EAAE,6BAA6B,GAAG,4BAA4B,CAmN9D"}