@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
@@ -105,4 +105,14 @@ export declare const makeLinearKeyboardNavigationWithConfirm: <T extends Keyboar
105
105
  onSelect?: ((event: T) => void) | undefined;
106
106
  onUnhandledKeyDown?: ((event: T) => void) | undefined;
107
107
  }, options?: IHandleActionOptions) => (event: T) => void;
108
+ /**
109
+ * Home and End are left out so they reach an enclosing toolbar.
110
+ *
111
+ * @internal
112
+ */
113
+ export declare const makeRadioGroupKeyboardNavigation: <T extends KeyboardEvent = KeyboardEvent<Element>>(handlers: {
114
+ onFocusNext?: ((event: T) => void) | undefined;
115
+ onFocusPrevious?: ((event: T) => void) | undefined;
116
+ onUnhandledKeyDown?: ((event: T) => void) | undefined;
117
+ }, options?: IHandleActionOptions) => (event: T) => void;
108
118
  //# sourceMappingURL=keyboardNavigation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardNavigation.d.ts","sourceRoot":"","sources":["../../../src/@ui/@utils/keyboardNavigation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACnC;AAqBD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAG,GAAY,CAAC;AAC5C;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,GAAG,OAAO,eAAe,GAAG,WAAW,EAAE,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAC9B,aAAa,SAAS;IAAE,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,iBACrF,aAAa,MAE/B,CAAC,SAAS,aAAa,GAAG,aAAa,YAC1B,GAAG,MAAM,IAAI,MAAM,aAAa,GAAG,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAE,YAChF,oBAAoB,aAEd,CAAC,SAmCnB,CAAC;AAEN;;GAEG;AACH,eAAO,MAAM,0BAA0B,GA5ClC,CAAC,SAAS,aAAa;6BAC+D,IAAI;;;;;;;;;aAC9E,oBAAoB,uBAmDnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,0BAA0B,GA1DlC,CAAC,SAAS,aAAa;iCAC+D,IAAI;;;;;;;;aAC9E,oBAAoB,uBAgEnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,4BAA4B,GAvEpC,CAAC,SAAS,aAAa;6BAC+D,IAAI;;;;;;;aAC9E,oBAAoB,uBA4EnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,4BAA4B,GAnFpC,CAAC,SAAS,aAAa;6BAC+D,IAAI;;;;aAC9E,oBAAoB,uBAqFnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,0BAA0B,GA5FlC,CAAC,SAAS,aAAa;kCAC+D,IAAI;;;;;;aAC9E,oBAAoB,uBAgGnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gCAAgC,GAvGxC,CAAC,SAAS,aAAa;kCAC+D,IAAI;;;;;aAC9E,oBAAoB,uBA0GnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,uCAAuC,GAjH/C,CAAC,SAAS,aAAa;6BAC+D,IAAI;;;;;;;;aAC9E,oBAAoB,uBAuHnC,CAAC"}
1
+ {"version":3,"file":"keyboardNavigation.d.ts","sourceRoot":"","sources":["../../../src/@ui/@utils/keyboardNavigation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACnC;AAqBD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAG,GAAY,CAAC;AAC5C;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,GAAG,OAAO,eAAe,GAAG,WAAW,EAAE,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAC9B,aAAa,SAAS;IAAE,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,iBACrF,aAAa,MAE/B,CAAC,SAAS,aAAa,GAAG,aAAa,YAC1B,GAAG,MAAM,IAAI,MAAM,aAAa,GAAG,oBAAoB,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAE,YAChF,oBAAoB,aAEd,CAAC,SAmCnB,CAAC;AAEN;;GAEG;AACH,eAAO,MAAM,0BAA0B,GA5ClC,CAAC,SAAS,aAAa;6BAC+D,IAAI;;;;;;;;;aAC9E,oBAAoB,uBAmDnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,0BAA0B,GA1DlC,CAAC,SAAS,aAAa;iCAC+D,IAAI;;;;;;;;aAC9E,oBAAoB,uBAgEnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,4BAA4B,GAvEpC,CAAC,SAAS,aAAa;6BAC+D,IAAI;;;;;;;aAC9E,oBAAoB,uBA4EnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,4BAA4B,GAnFpC,CAAC,SAAS,aAAa;6BAC+D,IAAI;;;;aAC9E,oBAAoB,uBAqFnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,0BAA0B,GA5FlC,CAAC,SAAS,aAAa;kCAC+D,IAAI;;;;;;aAC9E,oBAAoB,uBAgGnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gCAAgC,GAvGxC,CAAC,SAAS,aAAa;kCAC+D,IAAI;;;;;aAC9E,oBAAoB,uBA0GnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,uCAAuC,GAjH/C,CAAC,SAAS,aAAa;6BAC+D,IAAI;;;;;;;;aAC9E,oBAAoB,uBAuHnC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,GAhIxC,CAAC,SAAS,aAAa;iCAC+D,IAAI;;;aAC9E,oBAAoB,uBAiInC,CAAC"}
@@ -119,3 +119,12 @@ export const makeLinearKeyboardNavigationWithConfirm = makeKeyboardNavigation({
119
119
  onConfirm: [{ code: "Enter" }],
120
120
  onClose: [{ code: "Escape" }],
121
121
  });
122
+ /**
123
+ * Home and End are left out so they reach an enclosing toolbar.
124
+ *
125
+ * @internal
126
+ */
127
+ export const makeRadioGroupKeyboardNavigation = makeKeyboardNavigation({
128
+ onFocusPrevious: [{ code: ["ArrowLeft", "ArrowUp"] }],
129
+ onFocusNext: [{ code: ["ArrowRight", "ArrowDown"] }],
130
+ });
@@ -5,8 +5,6 @@ import { type PermissionMenuLevel } from "../UiPermissionMenu/UiPermissionMenu.j
5
5
  * @internal
6
6
  */
7
7
  export interface IUiAddGranteeDialogCardProps {
8
- /** Object title shown in the header — wrapped into `Share "\{title\}"`. */
9
- objectTitle: string;
10
8
  /** Loader passed straight through to the embedded `UiGranteeAsyncPicker`. */
11
9
  loadOptions: (search: string) => Promise<IUiGranteeAsyncOptions>;
12
10
  /**
@@ -54,9 +52,9 @@ export interface IUiAddGranteeDialogCardProps {
54
52
  dataTestId?: string;
55
53
  }
56
54
  /**
57
- * Add-grantee dialog card — header + grantee picker (search input with
58
- * sectioned Groups/Users dropdown and picked-rows list) + footer with Cancel
59
- * and Share. Renders inline as a plain card. For modal behavior (portal,
55
+ * Add-grantee dialog card — header ("Add users or groups", which also names the
56
+ * search input) + grantee picker (search input with sectioned Groups/Users
57
+ * dropdown and picked-rows list) + footer with Cancel and Add. Renders inline as a plain card. For modal behavior (portal,
60
58
  * backdrop, focus trap, dismiss), use `UiAddGranteeDialog` which wraps this
61
59
  * in `UiModalDialog`.
62
60
  *
@@ -66,5 +64,5 @@ export interface IUiAddGranteeDialogCardProps {
66
64
  *
67
65
  * @internal
68
66
  */
69
- export declare function UiAddGranteeDialogCard({ objectTitle, loadOptions, disabledLevels, disabledTooltip, selectedGrantees, onSelectedGranteesChange, initialPermissionLevel, labels, onBack, onClose, onCancel, onShare, dataTestId, }: IUiAddGranteeDialogCardProps): import("react/jsx-runtime").JSX.Element;
67
+ export declare function UiAddGranteeDialogCard({ loadOptions, disabledLevels, disabledTooltip, selectedGrantees, onSelectedGranteesChange, initialPermissionLevel, labels, onBack, onClose, onCancel, onShare, dataTestId, }: IUiAddGranteeDialogCardProps): import("react/jsx-runtime").JSX.Element;
70
68
  //# sourceMappingURL=UiAddGranteeDialogCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UiAddGranteeDialogCard.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiAddGranteeDialog/UiAddGranteeDialogCard.tsx"],"names":[],"mappings":"AAWA,OAAO,EACH,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EAExB,MAAM,iDAAiD,CAAC;AAEzD,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAGxF,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAMnF;;GAEG;AACH,MAAM,WAAW,4BAA4B;IACzC,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IAEpB,6EAA6E;IAC7E,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjE;;;OAGG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACpD,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAClD;;;;OAIG;IACH,wBAAwB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC7D;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,mBAAmB,CAAC;IAC7C;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAE/C,+DAA+D;IAC/D,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,EACnC,WAAW,EACX,WAAW,EACX,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,sBAA+B,EAC/B,MAAM,EACN,MAAM,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,UAAU,GACb,EAAE,4BAA4B,2CAoD9B"}
1
+ {"version":3,"file":"UiAddGranteeDialogCard.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiAddGranteeDialog/UiAddGranteeDialogCard.tsx"],"names":[],"mappings":"AAOA,OAAO,EACH,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EAExB,MAAM,iDAAiD,CAAC;AAEzD,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAGxF,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAMnF;;GAEG;AACH,MAAM,WAAW,4BAA4B;IACzC,6EAA6E;IAC7E,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjE;;;OAGG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACpD,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAClD;;;;OAIG;IACH,wBAAwB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC7D;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,mBAAmB,CAAC;IAC7C;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAE/C,+DAA+D;IAC/D,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,EACnC,WAAW,EACX,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,sBAA+B,EAC/B,MAAM,EACN,MAAM,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,UAAU,GACb,EAAE,4BAA4B,2CAuD9B"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2026 GoodData Corporation
3
3
  import { useIntl } from "react-intl";
4
- import { commonDialogMessages, olpAddGranteeDialogMessages, olpObjectShareDialogMessages, } from "../../locales.js";
4
+ import { commonDialogMessages, olpAddGranteeDialogMessages } from "../../locales.js";
5
5
  import { bem } from "../@utils/bem.js";
6
6
  import { UiButton } from "../UiButton/UiButton.js";
7
7
  import { UiGranteeAsyncPicker, } from "../UiGranteeAsyncPicker/UiGranteeAsyncPicker.js";
@@ -11,9 +11,9 @@ import { UiDialogHeader } from "../UiModalDialog/UiDialogHeader.js";
11
11
  import { useGranteeSelection } from "./useGranteeSelection.js";
12
12
  const { b } = bem("gd-ui-kit-add-grantee-dialog");
13
13
  /**
14
- * Add-grantee dialog card — header + grantee picker (search input with
15
- * sectioned Groups/Users dropdown and picked-rows list) + footer with Cancel
16
- * and Share. Renders inline as a plain card. For modal behavior (portal,
14
+ * Add-grantee dialog card — header ("Add users or groups", which also names the
15
+ * search input) + grantee picker (search input with sectioned Groups/Users
16
+ * dropdown and picked-rows list) + footer with Cancel and Add. Renders inline as a plain card. For modal behavior (portal,
17
17
  * backdrop, focus trap, dismiss), use `UiAddGranteeDialog` which wraps this
18
18
  * in `UiModalDialog`.
19
19
  *
@@ -23,14 +23,16 @@ const { b } = bem("gd-ui-kit-add-grantee-dialog");
23
23
  *
24
24
  * @internal
25
25
  */
26
- export function UiAddGranteeDialogCard({ objectTitle, loadOptions, disabledLevels, disabledTooltip, selectedGrantees, onSelectedGranteesChange, initialPermissionLevel = "VIEW", labels, onBack, onClose, onCancel, onShare, dataTestId, }) {
26
+ export function UiAddGranteeDialogCard({ loadOptions, disabledLevels, disabledTooltip, selectedGrantees, onSelectedGranteesChange, initialPermissionLevel = "VIEW", labels, onBack, onClose, onCancel, onShare, dataTestId, }) {
27
27
  const intl = useIntl();
28
- const dialogTitle = intl.formatMessage(olpObjectShareDialogMessages.title, { title: objectTitle });
29
- const backButton = (_jsx(UiIconButton, { icon: "chevronLeft", variant: "tertiary", size: "small", onClick: onBack, accessibilityConfig: { ariaLabel: intl.formatMessage(olpAddGranteeDialogMessages.back) } }));
28
+ // The title doubles as the accessible name of the picker's search input, which has
29
+ // no visible label of its own.
30
+ const dialogTitle = intl.formatMessage(olpAddGranteeDialogMessages.title);
31
+ const backButton = (_jsx(UiIconButton, { icon: "chevronLeft", variant: "secondary", size: "small", onClick: onBack, accessibilityConfig: { ariaLabel: intl.formatMessage(olpAddGranteeDialogMessages.back) } }));
30
32
  const { select, changePermission, changeLabels, remove } = useGranteeSelection({
31
33
  selectedGrantees,
32
34
  onSelectedGranteesChange,
33
35
  initialPermissionLevel,
34
36
  });
35
- return (_jsxs("div", { className: b(), "data-testid": dataTestId, children: [_jsx(UiDialogHeader, { title: dialogTitle, titleSize: "large", onClose: onClose, leading: backButton }), _jsx(UiGranteeAsyncPicker, { loadOptions: loadOptions, disabledLevels: disabledLevels, disabledTooltip: disabledTooltip, selectedGrantees: selectedGrantees, onSelect: select, onPermissionChange: changePermission, labels: labels, onLabelsChange: changeLabels, onRemove: remove }), _jsxs(UiDialogFooter, { divider: true, children: [_jsx(UiButton, { label: intl.formatMessage(commonDialogMessages.cancel), variant: "secondary", size: "medium", onClick: onCancel }), _jsx(UiButton, { label: intl.formatMessage(olpAddGranteeDialogMessages.add), variant: "primary", size: "medium", onClick: onShare, isDisabled: selectedGrantees.length === 0 })] })] }));
37
+ return (_jsxs("div", { className: b(), "data-testid": dataTestId, children: [_jsx(UiDialogHeader, { title: dialogTitle, onClose: onClose, leading: backButton }), _jsx(UiGranteeAsyncPicker, { accessibilityConfig: { ariaLabel: dialogTitle }, loadOptions: loadOptions, disabledLevels: disabledLevels, disabledTooltip: disabledTooltip, selectedGrantees: selectedGrantees, onSelect: select, onPermissionChange: changePermission, labels: labels, onLabelsChange: changeLabels, onRemove: remove }), _jsxs(UiDialogFooter, { divider: true, children: [_jsx(UiButton, { label: intl.formatMessage(commonDialogMessages.cancel), variant: "secondary", size: "medium", onClick: onCancel }), _jsx(UiButton, { label: intl.formatMessage(olpAddGranteeDialogMessages.add), variant: "primary", size: "medium", onClick: onShare, isDisabled: selectedGrantees.length === 0 })] })] }));
36
38
  }
@@ -83,7 +83,7 @@ export function useAsyncListSource(loadOptions, { debounceMs }) {
83
83
  const reset = useCallback(() => {
84
84
  setInputValueImmediate("");
85
85
  setPagination(null);
86
- // eslint-disable-next-line react-hooks/exhaustive-deps
86
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
87
87
  }, []);
88
88
  return useMemo(() => ({
89
89
  inputValue,
@@ -1,4 +1,5 @@
1
1
  import { type ObjRef } from "@gooddata/sdk-model";
2
+ import { type IAccessibilityConfigBase } from "../../typings/accessibility.js";
2
3
  import { type GranteeAvatarKind } from "../UiGranteeAvatar/UiGranteeAvatar.js";
3
4
  import { type IUiLabelsChecklistItem } from "../UiLabelsChecklist/UiLabelsChecklist.js";
4
5
  import { type PermissionMenuLevel } from "../UiPermissionMenu/UiPermissionMenu.js";
@@ -84,6 +85,12 @@ export interface IUiGranteeAsyncPickerProps {
84
85
  * stays hidden rather than offering an Apply that discards it.
85
86
  */
86
87
  labels?: ReadonlyArray<IUiLabelsChecklistItem>;
88
+ /**
89
+ * Accessible name of the search input, which has no visible label of its own — the
90
+ * surrounding dialog's title names it, so pass that title here. Defaults to the
91
+ * add-grantee dialog title.
92
+ */
93
+ accessibilityConfig?: Pick<IAccessibilityConfigBase, "ariaLabel">;
87
94
  /** Fires with the applied label scope of a picked row. Enables `labels`. */
88
95
  onLabelsChange?: (grantee: IUiPickedGrantee, selectedLabelIds: string[]) => void;
89
96
  /** Test id forwarded to the root element. */
@@ -98,5 +105,5 @@ export interface IUiGranteeAsyncPickerProps {
98
105
  *
99
106
  * @internal
100
107
  */
101
- export declare function UiGranteeAsyncPicker({ loadOptions, selectedGrantees, onSelect, onPermissionChange, disabledLevels, disabledTooltip, onRemove, labels, onLabelsChange, dataTestId, }: IUiGranteeAsyncPickerProps): import("react/jsx-runtime").JSX.Element;
108
+ export declare function UiGranteeAsyncPicker({ loadOptions, selectedGrantees, onSelect, onPermissionChange, disabledLevels, disabledTooltip, onRemove, labels, onLabelsChange, accessibilityConfig, dataTestId, }: IUiGranteeAsyncPickerProps): import("react/jsx-runtime").JSX.Element;
102
109
  //# sourceMappingURL=UiGranteeAsyncPicker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UiGranteeAsyncPicker.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiGranteeAsyncPicker/UiGranteeAsyncPicker.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAOlD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE/E,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACxF,OAAO,EACH,KAAK,mBAAmB,EAG3B,MAAM,yCAAyC,CAAC;AAIjD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IAClC,uFAAuF;IACvF,EAAE,EAAE,MAAM,CAAC;IACX;;yBAEqB;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,sBAAsB;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC3D,gGAAgG;IAChG,eAAe,EAAE,mBAAmB,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACpC;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACnC,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,KAAK,EAAE,qBAAqB,EAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC;;;;;OAKG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjE;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACnD,6DAA6D;IAC7D,QAAQ,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACpF;;;OAGG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACpD,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC/C,4EAA4E;IAC5E,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACjF,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAOD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,WAAW,EACX,gBAAqB,EACrB,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,MAAM,EACN,cAAc,EACd,UAAU,GACb,EAAE,0BAA0B,2CAyH5B"}
1
+ {"version":3,"file":"UiGranteeAsyncPicker.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiGranteeAsyncPicker/UiGranteeAsyncPicker.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAK/E,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE/E,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACxF,OAAO,EACH,KAAK,mBAAmB,EAG3B,MAAM,yCAAyC,CAAC;AAIjD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IAClC,uFAAuF;IACvF,EAAE,EAAE,MAAM,CAAC;IACX;;yBAEqB;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,sBAAsB;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC3D,gGAAgG;IAChG,eAAe,EAAE,mBAAmB,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACpC;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACnC,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,KAAK,EAAE,qBAAqB,EAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC;;;;;OAKG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjE;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACnD,6DAA6D;IAC7D,QAAQ,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACpF;;;OAGG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACpD,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC/C;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,WAAW,CAAC,CAAC;IAClE,4EAA4E;IAC5E,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACjF,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAOD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EACjC,WAAW,EACX,gBAAqB,EACrB,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,MAAM,EACN,cAAc,EACd,mBAAmB,EACnB,UAAU,GACb,EAAE,0BAA0B,2CA+H5B"}
@@ -18,7 +18,7 @@ const { b, e } = bem("gd-ui-kit-grantee-async-picker");
18
18
  *
19
19
  * @internal
20
20
  */
21
- export function UiGranteeAsyncPicker({ loadOptions, selectedGrantees = [], onSelect, onPermissionChange, disabledLevels, disabledTooltip, onRemove, labels, onLabelsChange, dataTestId, }) {
21
+ export function UiGranteeAsyncPicker({ loadOptions, selectedGrantees = [], onSelect, onPermissionChange, disabledLevels, disabledTooltip, onRemove, labels, onLabelsChange, accessibilityConfig, dataTestId, }) {
22
22
  const intl = useIntl();
23
23
  const groupsLabel = intl.formatMessage(uiGranteeAsyncPickerMessages.sectionGroups);
24
24
  const usersLabel = intl.formatMessage(uiGranteeAsyncPickerMessages.sectionUsers);
@@ -57,16 +57,20 @@ export function UiGranteeAsyncPicker({ loadOptions, selectedGrantees = [], onSel
57
57
  stateError: intl.formatMessage(uiGranteeAsyncPickerMessages.stateError),
58
58
  stateNoMatch: intl.formatMessage(uiGranteeAsyncPickerMessages.stateNoMatch),
59
59
  }), [intl]);
60
- const fieldLabel = intl.formatMessage(olpAddGranteeDialogMessages.userOrGroup);
60
+ // `||`, not `??`: an empty custom label must not leave the combobox unnamed.
61
+ const fieldLabel = accessibilityConfig?.ariaLabel || intl.formatMessage(olpAddGranteeDialogMessages.title);
61
62
  // A row with no scope of its own covers every label (see `labelIds`). The drill-in is
62
63
  // offered only when the pick has somewhere to go — otherwise Apply would silently
63
64
  // discard it.
64
65
  const scopeLabels = onLabelsChange ? labels : undefined;
65
66
  const allLabelIds = useMemo(() => (scopeLabels ?? []).map((l) => l.id), [scopeLabels]);
66
- return (_jsxs("div", { className: b(), "data-testid": dataTestId, children: [_jsxs("div", { className: e("field"), children: [_jsx("div", { className: e("field-label"), children: fieldLabel }), _jsx(UiAutocomplete, { loadOptions: adaptedLoadOptions, selectedIds: selectedIds, onSelect: handleSelect, messages: autocompleteMessages, accessibilityConfig: {
67
- ariaLabel: fieldLabel,
68
- } })] }), selectedGrantees.length === 0 ? (_jsx("div", { className: e("empty-state"), children: intl.formatMessage(olpAddGranteeDialogMessages.emptyState) })) : null, selectedGrantees.length > 0 ? (_jsx("ul", { className: e("picked-list"), children: selectedGrantees.map((g) => {
67
+ return (_jsxs("div", { className: b(), "data-testid": dataTestId, children: [_jsx("div", { className: e("field"), children: _jsx(UiAutocomplete, { loadOptions: adaptedLoadOptions, selectedIds: selectedIds, onSelect: handleSelect, messages: autocompleteMessages, accessibilityConfig: {
68
+ ariaLabel: fieldLabel,
69
+ } }) }), selectedGrantees.length === 0 ? (_jsx("div", { className: e("empty-state"), children: intl.formatMessage(olpAddGranteeDialogMessages.emptyState) })) : null, selectedGrantees.length > 0 ? (_jsx("ul", { className: e("picked-list"), children: selectedGrantees.map((g) => {
69
70
  const triggerLabel = intl.formatMessage(permissionLevelMessage(g.permissionLevel));
70
- return (_jsx("li", { className: e("picked-item"), children: _jsx(UiGranteeRow, { kind: g.kind, name: g.name, email: g.email, controls: _jsx(UiPermissionMenu, { selectedLevel: g.permissionLevel, onPermissionChange: (next) => onPermissionChange?.(g, next), disabledLevels: disabledLevels, disabledTooltip: disabledTooltip, labels: scopeLabels, selectedLabelIds: g.labelIds ?? allLabelIds, onLabelsChange: (ids) => onLabelsChange?.(g, ids), onRemoveAccess: onRemove ? () => onRemove(g) : undefined, anchor: _jsx(UiButton, { label: triggerLabel, variant: "dropdownInline", size: "small", iconAfter: "navigateDown" }) }) }) }, g.id));
71
+ return (_jsx("li", { className: e("picked-item"), children: _jsx(UiGranteeRow, { kind: g.kind, name: g.name, email: g.email, controls: _jsx(UiPermissionMenu, { selectedLevel: g.permissionLevel, onPermissionChange: (next) => onPermissionChange?.(g, next), disabledLevels: disabledLevels, disabledTooltip: disabledTooltip, labels: scopeLabels, selectedLabelIds: g.labelIds ?? allLabelIds, onLabelsChange: (ids) => onLabelsChange?.(g, ids), onRemoveAccess: onRemove ? () => onRemove(g) : undefined,
72
+ // Nothing is granted yet, so the row drops the
73
+ // candidate rather than revoking access.
74
+ removeAccessLabel: intl.formatMessage(olpAddGranteeDialogMessages.remove), anchor: _jsx(UiButton, { label: triggerLabel, variant: "dropdownInline", size: "small", iconAfter: "navigateDown" }) }) }) }, g.id));
71
75
  }) })) : null] }));
72
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultUiListboxInteractiveItemComponent.d.ts","sourceRoot":"","sources":["../../../../src/@ui/UiListbox/defaults/DefaultUiListboxInteractiveItemComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAElE;;GAEG;AACH,wBAAgB,wCAAwC,CAAC,CAAC,EAAE,EACxD,IAAI,EACJ,SAAS,EACT,UAAU,EACV,SAAS,EACT,QAAQ,GACX,EAAE,8BAA8B,CAAC,CAAC,CAAC,GAAG,SAAS,CAuC/C"}
1
+ {"version":3,"file":"DefaultUiListboxInteractiveItemComponent.d.ts","sourceRoot":"","sources":["../../../../src/@ui/UiListbox/defaults/DefaultUiListboxInteractiveItemComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAKlE;;GAEG;AACH,wBAAgB,wCAAwC,CAAC,CAAC,EAAE,EACxD,IAAI,EACJ,SAAS,EACT,UAAU,EACV,SAAS,EACT,QAAQ,GACX,EAAE,8BAA8B,CAAC,CAAC,CAAC,GAAG,SAAS,CA0D/C"}
@@ -1,16 +1,20 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ShortenedText } from "../../../ShortenedText/ShortenedText.js";
2
+ import { useIsTextTruncated } from "../../hooks/useIsTextTruncated.js";
3
3
  import { UiIcon } from "../../UiIcon/UiIcon.js";
4
4
  import { UiTooltip } from "../../UiTooltip/UiTooltip.js";
5
5
  import { e } from "../listboxBem.js";
6
+ // The tooltip anchor wrapper defaults to fit-content; the title must be allowed to shrink and clip.
7
+ const TITLE_ANCHOR_STYLE = { display: "block", minWidth: 0, flex: "1 1 0%" };
6
8
  /**
7
9
  * @internal
8
10
  */
9
11
  export function DefaultUiListboxInteractiveItemComponent({ item, isFocused, isSelected, isCompact, onSelect, }) {
12
+ const title = useIsTextTruncated(item.stringTitle);
13
+ const titleElement = (_jsx("span", { ref: title.ref, className: e("item-title"), children: item.stringTitle }));
10
14
  return (_jsxs("div", { className: e("item", {
11
15
  isFocused,
12
16
  isSelected,
13
17
  isCompact,
14
18
  isDisabled: !!item.isDisabled,
15
- }), onClick: item.isDisabled ? undefined : onSelect, children: [item.icon ? _jsx(UiIcon, { type: item.icon, size: 14, color: "complementary-7" }) : null, _jsx(ShortenedText, { className: e("item-title"), ellipsisPosition: "end", children: item.stringTitle }), item.tooltip ? (_jsxs(_Fragment, { children: [_jsx(UiTooltip, { anchor: _jsx("div", { className: e("item-explanation"), children: _jsx(UiIcon, { type: "question", size: 14, color: "complementary-7" }) }), content: item.tooltip, triggerBy: ["hover"], accessibilityHidden: true, arrowPlacement: "left", optimalPlacement: true, width: 200, offset: 10 }), _jsx("span", { className: "sr-only", children: item.tooltip })] })) : null] }));
19
+ }), onClick: item.isDisabled ? undefined : onSelect, children: [item.icon ? _jsx(UiIcon, { type: item.icon, size: 14, color: "complementary-7" }) : null, title.isTruncated ? (_jsx(UiTooltip, { anchor: titleElement, content: item.stringTitle, triggerBy: ["hover"], accessibilityHidden: true, arrowPlacement: "left", optimalPlacement: true, offset: 10, component: "span", anchorWrapperStyles: TITLE_ANCHOR_STYLE })) : (titleElement), item.tooltip ? (_jsxs(_Fragment, { children: [_jsx(UiTooltip, { anchor: _jsx("div", { className: e("item-explanation"), children: _jsx(UiIcon, { type: "question", size: 14, color: "complementary-7" }) }), content: item.tooltip, triggerBy: ["hover"], accessibilityHidden: true, arrowPlacement: "left", optimalPlacement: true, width: 200, offset: 10 }), _jsx("span", { className: "sr-only", children: item.tooltip })] })) : null] }));
16
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultUiMenuContentItem.d.ts","sourceRoot":"","sources":["../../../../../src/@ui/UiMenu/components/defaults/DefaultUiMenuContentItem.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIH,KAAK,SAAS,EAGjB,MAAM,OAAO,CAAC;AAOf,OAAO,EACH,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,eAAe,EACvB,MAAM,gBAAgB,CAAC;AACxB;;;GAGG;AACH,eAAO,MAAM,+BAA+B,8EAgF3C,CAAC;AAEF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,eAAe,GAAG,MAAM,EAAE,EACzE,IAAI,EACJ,SAAS,GACZ,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,SAAS,CAgBxC"}
1
+ {"version":3,"file":"DefaultUiMenuContentItem.d.ts","sourceRoot":"","sources":["../../../../../src/@ui/UiMenu/components/defaults/DefaultUiMenuContentItem.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIH,KAAK,SAAS,EAGjB,MAAM,OAAO,CAAC;AAWf,OAAO,EACH,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,eAAe,EACvB,MAAM,gBAAgB,CAAC;AACxB;;;GAGG;AACH,eAAO,MAAM,+BAA+B,8EAgF3C,CAAC;AAEF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,eAAe,GAAG,MAAM,EAAE,EACzE,IAAI,EACJ,SAAS,GACZ,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,SAAS,CAmCxC"}
@@ -2,7 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2025-2026 GoodData Corporation
3
3
  import { memo, useCallback, } from "react";
4
4
  import cx from "classnames";
5
- import { ShortenedText } from "../../../../ShortenedText/ShortenedText.js";
5
+ // The tooltip anchor wrapper defaults to fit-content; the title must be allowed to shrink and clip.
6
+ const TITLE_ANCHOR_STYLE = { display: "block", minWidth: 0, flex: "1 1 0%" };
7
+ import { useIsTextTruncated } from "../../../hooks/useIsTextTruncated.js";
8
+ import { UiTooltip } from "../../../UiTooltip/UiTooltip.js";
6
9
  import { typedUiMenuContextStore } from "../../context.js";
7
10
  import { e } from "../../menuBem.js";
8
11
  /**
@@ -52,8 +55,10 @@ export const DefaultUiMenuContentItemWrapper = memo(function DefaultUiMenuConten
52
55
  * @internal
53
56
  */
54
57
  export function DefaultUiMenuContentItem({ item, isFocused, }) {
58
+ const title = useIsTextTruncated(item.stringTitle);
59
+ const titleElement = (_jsx("span", { ref: title.ref, className: e("item-title"), children: item.stringTitle }));
55
60
  return (_jsxs("div", { className: e("item", {
56
61
  isFocused,
57
62
  isDisabled: !!item.isDisabled,
58
- }), children: [item.iconLeft ? item.iconLeft : null, _jsx(ShortenedText, { className: e("item-title"), ellipsisPosition: "end", children: item.stringTitle }), !!item.Component && _jsx("i", { className: "gd-icon-navigateright" })] }));
63
+ }), children: [item.iconLeft ? item.iconLeft : null, title.isTruncated ? (_jsx(UiTooltip, { anchor: titleElement, content: item.stringTitle, triggerBy: ["hover"], accessibilityHidden: true, arrowPlacement: "left", optimalPlacement: true, offset: 10, component: "span", anchorWrapperStyles: TITLE_ANCHOR_STYLE })) : (titleElement), !!item.Component && _jsx("i", { className: "gd-icon-navigateright" })] }));
59
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultUiMenuInteractiveItem.d.ts","sourceRoot":"","sources":["../../../../../src/@ui/UiMenu/components/defaults/DefaultUiMenuInteractiveItem.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAuC,KAAK,SAAS,EAAyB,MAAM,OAAO,CAAC;AASnG,OAAO,EAEH,KAAK,2BAA2B,EAChC,KAAK,kCAAkC,EACvC,KAAK,eAAe,EACvB,MAAM,gBAAgB,CAAC;AAmBxB;;GAEG;AACH,wBAAgB,mCAAmC,CAAC,CAAC,SAAS,eAAe,GAAG,MAAM,EAAE,EACpF,IAAI,EACJ,SAAS,GACZ,EAAE,kCAAkC,CAAC,CAAC,CAAC,GAAG,SAAS,CA0GnD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,SAAS,eAAe,GAAG,MAAM,EAAE,EAC7E,IAAI,EACJ,SAAS,EACT,aAAa,GAChB,EAAE,2BAA2B,CAAC,CAAC,CAAC,GAAG,SAAS,CAoD5C"}
1
+ {"version":3,"file":"DefaultUiMenuInteractiveItem.d.ts","sourceRoot":"","sources":["../../../../../src/@ui/UiMenu/components/defaults/DefaultUiMenuInteractiveItem.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAuC,KAAK,SAAS,EAAyB,MAAM,OAAO,CAAC;AASnG,OAAO,EAEH,KAAK,2BAA2B,EAChC,KAAK,kCAAkC,EACvC,KAAK,eAAe,EACvB,MAAM,gBAAgB,CAAC;AAsBxB;;GAEG;AACH,wBAAgB,mCAAmC,CAAC,CAAC,SAAS,eAAe,GAAG,MAAM,EAAE,EACpF,IAAI,EACJ,SAAS,GACZ,EAAE,kCAAkC,CAAC,CAAC,CAAC,GAAG,SAAS,CA0GnD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,SAAS,eAAe,GAAG,MAAM,EAAE,EAC7E,IAAI,EACJ,SAAS,EACT,aAAa,GAChB,EAAE,2BAA2B,CAAC,CAAC,CAAC,GAAG,SAAS,CAuE5C"}
@@ -2,11 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2025-2026 GoodData Corporation
3
3
  import { useCallback, useState } from "react";
4
4
  import cx from "classnames";
5
- import { ShortenedText } from "../../../../ShortenedText/ShortenedText.js";
6
5
  import { useCloseOnEscape } from "../../../hooks/useCloseOnEscape.js";
6
+ import { useIsTextTruncated } from "../../../hooks/useIsTextTruncated.js";
7
7
  import { UiTooltip } from "../../../UiTooltip/UiTooltip.js";
8
8
  import { typedUiMenuContextStore } from "../../context.js";
9
9
  import { e } from "../../menuBem.js";
10
+ // The tooltip anchor wrapper defaults to fit-content; the title must be allowed to shrink and clip.
11
+ const TITLE_ANCHOR_STYLE = { display: "block", minWidth: 0, flex: "1 1 0%" };
10
12
  function hasIconTooltip(item) {
11
13
  return !!item.tooltip && !!item.iconRight;
12
14
  }
@@ -85,12 +87,15 @@ export function DefaultUiMenuInteractiveItemWrapper({ item, Component, }) {
85
87
  */
86
88
  export function DefaultUiMenuInteractiveItem({ item, isFocused, isTooltipOpen, }) {
87
89
  const useIconTooltip = hasIconTooltip(item);
90
+ const isRowTooltip = !!item.tooltip && !useIconTooltip;
91
+ const title = useIsTextTruncated(item.stringTitle);
92
+ const titleElement = (_jsx("span", { ref: title.ref, className: e("item-title"), children: item.stringTitle }));
88
93
  const itemInner = (_jsxs("div", { className: e("item", {
89
94
  isFocused,
90
95
  isSelected: !!item.isSelected,
91
96
  isDisabled: !!item.isDisabled,
92
97
  isDestructive: !!item.isDestructive,
93
- }), children: [item.iconLeft ? item.iconLeft : null, _jsx(ShortenedText, { className: e("item-title"), ellipsisPosition: "end", children: item.stringTitle }), !!item.subItems && _jsx("i", { className: "gd-icon-navigateright" }), useIconTooltip ? (_jsx(UiTooltip, { anchor: item.iconRight, content: item.tooltip, optimalPlacement: true, triggerBy: ["hover"], inlineAnchor: true, accessibilityHidden: true, arrowPlacement: "bottom-end", width: item.tooltipWidth })) : item.iconRight ? (item.iconRight) : null, item.tooltip ? _jsx("span", { className: "sr-only", children: item.tooltip }) : null] }));
98
+ }), children: [item.iconLeft ? item.iconLeft : null, title.isTruncated && !isRowTooltip ? (_jsx(UiTooltip, { anchor: titleElement, content: item.stringTitle, triggerBy: ["hover"], accessibilityHidden: true, arrowPlacement: "left", optimalPlacement: true, offset: 10, component: "span", anchorWrapperStyles: TITLE_ANCHOR_STYLE })) : (titleElement), !!item.subItems && _jsx("i", { className: "gd-icon-navigateright" }), useIconTooltip ? (_jsx(UiTooltip, { anchor: item.iconRight, content: item.tooltip, optimalPlacement: true, triggerBy: ["hover"], inlineAnchor: true, accessibilityHidden: true, arrowPlacement: "bottom-end", width: item.tooltipWidth })) : item.iconRight ? (item.iconRight) : null, item.tooltip ? _jsx("span", { className: "sr-only", children: item.tooltip }) : null] }));
94
99
  if (!item.tooltip) {
95
100
  return itemInner;
96
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"UiDialogHeader.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiModalDialog/UiDialogHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAYvC;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,SAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,oBAAoB,2CAsBtG"}
1
+ {"version":3,"file":"UiDialogHeader.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiModalDialog/UiDialogHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAYvC;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,SAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,oBAAoB,2CA2BtG"}
@@ -13,7 +13,10 @@ const { b, e } = bem("gd-ui-kit-dialog-header");
13
13
  export function UiDialogHeader({ title, titleSize = "default", onClose, leading }) {
14
14
  const intl = useIntl();
15
15
  const dialogContext = useUiDialogContext();
16
- return (_jsxs("div", { className: b(), children: [leading ? _jsx("span", { className: e("leading"), children: leading }) : null, _jsx("h2", { id: dialogContext?.titleId, className: e("title", { size: titleSize }), children: title }), onClose ? (_jsx(UiIconButton, { icon: "cross", variant: "tertiary", size: "small", onClick: onClose, accessibilityConfig: {
17
- ariaLabel: intl.formatMessage(commonDialogMessages.close),
18
- } })) : null] }));
16
+ return (_jsxs("div", { className: b(), children: [leading ? _jsx("span", { className: e("leading"), children: leading }) : null, _jsx("h2", { id: dialogContext?.titleId, className: e("title", { size: titleSize }), children: title }), onClose ? (_jsx("span", { className: e("close"), children: _jsx(UiIconButton, { icon: "cross", variant: "tertiary",
17
+ // 18px cross, matching the design; the tertiary box has no fill or
18
+ // border of its own, so only the icon size shows.
19
+ size: "medium", onClick: onClose, accessibilityConfig: {
20
+ ariaLabel: intl.formatMessage(commonDialogMessages.close),
21
+ } }) })) : null] }));
19
22
  }
@@ -29,12 +29,25 @@ export interface IUiObjectShareDialogGrantee {
29
29
  * @internal
30
30
  */
31
31
  export interface IUiObjectShareDialogCardProps {
32
- /** Object title shown in the header — wrapped into `Share "\{title\}"`. */
33
- objectTitle: string;
32
+ /**
33
+ * Dialog heading, composed by the caller — it names the shared object's type
34
+ * ("Share attribute"), which only the caller knows.
35
+ */
36
+ title: string;
34
37
  /** Fires when the user clicks the header X button OR the footer Close button. */
35
38
  onClose: () => void;
39
+ /**
40
+ * Optional informational note rendered right below the header — e.g. a reminder
41
+ * that administrators have full access regardless of the grants listed.
42
+ */
43
+ note?: ReactNode;
36
44
  /** Grantee rows shown inside the SHARED WITH section, in render order. */
37
45
  grantees: IUiObjectShareDialogGrantee[];
46
+ /**
47
+ * Placeholder shown inside the SHARED WITH section when `grantees` is empty and the
48
+ * list is not loading — tells the user nobody has been granted access yet.
49
+ */
50
+ emptyMessage?: ReactNode;
38
51
  /**
39
52
  * When true, skeleton rows stand in for the grantee list and the
40
53
  * general-access radio — set it while the access list is loading, so the
@@ -86,5 +99,5 @@ export interface IUiObjectShareDialogCardProps {
86
99
  *
87
100
  * @internal
88
101
  */
89
- export declare function UiObjectShareDialogCard({ objectTitle, onClose, grantees, isLoading, onAddClick, isAddDisabled, generalAccess, onGeneralAccessChange, isGeneralAccessDisabled, workspaceAccessInherited, workspaceControls, workspaceLevel, error, dataTestId, }: IUiObjectShareDialogCardProps): import("react/jsx-runtime").JSX.Element;
102
+ export declare function UiObjectShareDialogCard({ title, onClose, note, grantees, emptyMessage, isLoading, onAddClick, isAddDisabled, generalAccess, onGeneralAccessChange, isGeneralAccessDisabled, workspaceAccessInherited, workspaceControls, workspaceLevel, error, dataTestId, }: IUiObjectShareDialogCardProps): import("react/jsx-runtime").JSX.Element;
90
103
  //# sourceMappingURL=UiObjectShareDialogCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UiObjectShareDialogCard.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiObjectShareDialog/UiObjectShareDialogCard.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,EACH,KAAK,kBAAkB,EAE1B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAS/E;;;;;;GAMG;AACH,MAAM,WAAW,2BAA2B;IACxC,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC1C,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,0EAA0E;IAC1E,QAAQ,EAAE,2BAA2B,EAAE,CAAC;IACxC;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,oFAAoF;IACpF,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,sCAAsC;IACtC,aAAa,EAAE,kBAAkB,CAAC;IAClC,mEAAmE;IACnE,qBAAqB,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC3D,uFAAuF;IACvF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAE3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,EACpC,WAAW,EACX,OAAO,EACP,QAAQ,EACR,SAAS,EACT,UAAU,EACV,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EACjB,cAAc,EACd,KAAK,EACL,UAAU,GACb,EAAE,6BAA6B,2CAuE/B"}
1
+ {"version":3,"file":"UiObjectShareDialogCard.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiObjectShareDialog/UiObjectShareDialogCard.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,EACH,KAAK,kBAAkB,EAE1B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAS/E;;;;;;GAMG;AACH,MAAM,WAAW,2BAA2B;IACxC,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC1C;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB,0EAA0E;IAC1E,QAAQ,EAAE,2BAA2B,EAAE,CAAC;IACxC;;;OAGG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,oFAAoF;IACpF,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,sCAAsC;IACtC,aAAa,EAAE,kBAAkB,CAAC;IAClC,mEAAmE;IACnE,qBAAqB,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC3D,uFAAuF;IACvF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAE3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,EACpC,KAAK,EACL,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,UAAU,EACV,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EACjB,cAAc,EACd,KAAK,EACL,UAAU,GACb,EAAE,6BAA6B,2CA8E/B"}
@@ -18,8 +18,7 @@ const { b, e } = bem("gd-ui-kit-object-share-dialog");
18
18
  *
19
19
  * @internal
20
20
  */
21
- export function UiObjectShareDialogCard({ objectTitle, onClose, grantees, isLoading, onAddClick, isAddDisabled, generalAccess, onGeneralAccessChange, isGeneralAccessDisabled, workspaceAccessInherited, workspaceControls, workspaceLevel, error, dataTestId, }) {
21
+ export function UiObjectShareDialogCard({ title, onClose, note, grantees, emptyMessage, isLoading, onAddClick, isAddDisabled, generalAccess, onGeneralAccessChange, isGeneralAccessDisabled, workspaceAccessInherited, workspaceControls, workspaceLevel, error, dataTestId, }) {
22
22
  const intl = useIntl();
23
- const dialogTitle = intl.formatMessage(olpObjectShareDialogMessages.title, { title: objectTitle });
24
- return (_jsxs("div", { className: b(), "data-testid": dataTestId, children: [_jsx(UiDialogHeader, { title: dialogTitle, onClose: onClose }), error ? (_jsx("div", { className: e("error"), role: "alert", children: error })) : (_jsxs(_Fragment, { children: [_jsx(UiSectionHeading, { label: intl.formatMessage(olpObjectShareDialogMessages.sharedWith), action: _jsx(UiButton, { label: intl.formatMessage(olpObjectShareDialogMessages.add), variant: "popout", size: "small", iconBefore: "plus", isDisabled: isAddDisabled, onClick: onAddClick }) }), _jsx("div", { className: e("grantees"), children: isLoading ? (_jsx(UiSkeleton, { itemsCount: 2, itemHeight: 40, itemsGap: 10 })) : (grantees.map((grantee) => (_jsx(UiGranteeRow, { kind: grantee.kind, name: grantee.name, email: grantee.email, isPending: grantee.isPending, controls: grantee.controls }, grantee.id)))) }), _jsx(UiSectionHeading, { label: intl.formatMessage(olpObjectShareDialogMessages.generalAccess) }), isLoading ? (_jsx(UiSkeleton, { itemsCount: 2, itemHeight: 40, itemsGap: 10 })) : (_jsx(UiGeneralAccessRadio, { value: generalAccess, onChange: onGeneralAccessChange, disabled: isGeneralAccessDisabled, workspaceAccessInherited: workspaceAccessInherited, workspaceControls: workspaceControls, workspaceLevel: workspaceLevel }))] })), _jsx(UiDialogFooter, { divider: true, children: _jsx(UiButton, { label: intl.formatMessage(commonDialogMessages.close), variant: "secondary", size: "medium", onClick: onClose }) })] }));
23
+ return (_jsxs("div", { className: b(), "data-testid": dataTestId, children: [_jsx(UiDialogHeader, { title: title, onClose: onClose }), note ? (_jsx("div", { className: e("note"), role: "note", children: note })) : null, error ? (_jsx("div", { className: e("error"), role: "alert", children: error })) : (_jsxs(_Fragment, { children: [_jsx(UiSectionHeading, { label: intl.formatMessage(olpObjectShareDialogMessages.sharedWith), action: _jsx(UiButton, { label: intl.formatMessage(olpObjectShareDialogMessages.add), variant: "popout", size: "small", iconBefore: "plus", isDisabled: isAddDisabled, onClick: onAddClick }) }), _jsx("div", { className: e("grantees"), children: isLoading ? (_jsx(UiSkeleton, { itemsCount: 2, itemHeight: 40, itemsGap: 10 })) : grantees.length === 0 && emptyMessage ? (_jsx("div", { className: e("empty"), children: emptyMessage })) : (grantees.map((grantee) => (_jsx(UiGranteeRow, { kind: grantee.kind, name: grantee.name, email: grantee.email, isPending: grantee.isPending, controls: grantee.controls }, grantee.id)))) }), _jsx(UiSectionHeading, { label: intl.formatMessage(olpObjectShareDialogMessages.generalAccess) }), isLoading ? (_jsx(UiSkeleton, { itemsCount: 2, itemHeight: 40, itemsGap: 10 })) : (_jsx(UiGeneralAccessRadio, { value: generalAccess, onChange: onGeneralAccessChange, disabled: isGeneralAccessDisabled, workspaceAccessInherited: workspaceAccessInherited, workspaceControls: workspaceControls, workspaceLevel: workspaceLevel }))] })), _jsx(UiDialogFooter, { divider: true, children: _jsx(UiButton, { label: intl.formatMessage(commonDialogMessages.close), variant: "secondary", size: "medium", onClick: onClose }) })] }));
25
24
  }
@@ -31,7 +31,7 @@ export interface IUiPermissionMenuProps {
31
31
  * the signed-in user may not pick because they exceed their own.
32
32
  */
33
33
  disabledLevels?: ReadonlyArray<PermissionMenuLevel>;
34
- /** Tooltip shown on disabled level rows in place of the level's info text. */
34
+ /** Tooltip shown on disabled level rows, explaining why the level can't be picked. */
35
35
  disabledTooltip?: string;
36
36
  /**
37
37
  * Per-level override of `disabledTooltip`, for menus whose disabled levels have
@@ -57,6 +57,11 @@ export interface IUiPermissionMenuProps {
57
57
  isRemoveDisabled?: boolean;
58
58
  /** Tooltip shown on Remove access while it is disabled. */
59
59
  removeDisabledTooltip?: string;
60
+ /**
61
+ * Label of the remove row. Defaults to "Remove access"; a picker staging a grantee
62
+ * that holds no access yet passes the shorter "Remove".
63
+ */
64
+ removeAccessLabel?: string;
60
65
  /** Test id forwarded to the menu body. */
61
66
  dataTestId?: string;
62
67
  }
@@ -64,10 +69,10 @@ export interface IUiPermissionMenuProps {
64
69
  * Per-grantee permission popover. Renders a fixed set of rows — three
65
70
  * permission levels (Can edit & share / Can view & share / Can view), an
66
71
  * optional divider, an optional labels drill-in and an optional Remove access
67
- * action row. Each level row carries an `infoCircle` tooltip; disabled level
68
- * rows (`disabledLevels`) swap it for `disabledTooltip`.
72
+ * action row. Enabled rows carry no tooltip; a disabled row (`disabledLevels`,
73
+ * `isRemoveDisabled`) shows its explanation as a tooltip over the whole row.
69
74
  *
70
75
  * @internal
71
76
  */
72
- export declare function UiPermissionMenu({ anchor, selectedLevel, onPermissionChange, disabledLevels, disabledTooltip, disabledLevelTooltips, labels, selectedLabelIds, onLabelsChange, onRemoveAccess, isRemoveDisabled, removeDisabledTooltip, dataTestId, }: IUiPermissionMenuProps): import("react/jsx-runtime").JSX.Element;
77
+ export declare function UiPermissionMenu({ anchor, selectedLevel, onPermissionChange, disabledLevels, disabledTooltip, disabledLevelTooltips, labels, selectedLabelIds, onLabelsChange, onRemoveAccess, isRemoveDisabled, removeDisabledTooltip, removeAccessLabel, dataTestId, }: IUiPermissionMenuProps): import("react/jsx-runtime").JSX.Element;
73
78
  //# sourceMappingURL=UiPermissionMenu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UiPermissionMenu.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiPermissionMenu/UiPermissionMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,YAAY,EAAiC,MAAM,OAAO,CAAC;AAE7F,OAAO,EAAE,KAAK,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAO7D,OAAO,EAAE,KAAK,sBAAsB,EAAqB,MAAM,2CAA2C,CAAC;AAM3G;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAQ5D;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,GAAG,iBAAiB,CAEpF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,4CAA4C;IAC5C,MAAM,EAAE,YAAY,CAAC;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,oDAAoD;IACpD,kBAAkB,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACzD;;;OAGG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACpD,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC;IACrE;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC/C,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,uEAAuE;IACvE,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACjD,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAsBD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,EAC7B,MAAM,EACN,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,MAAM,EACN,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,UAAU,GACb,EAAE,sBAAsB,2CA0BxB"}
1
+ {"version":3,"file":"UiPermissionMenu.d.ts","sourceRoot":"","sources":["../../../src/@ui/UiPermissionMenu/UiPermissionMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,YAAY,EAAwC,MAAM,OAAO,CAAC;AAEpG,OAAO,EAAE,KAAK,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAM7D,OAAO,EAAE,KAAK,sBAAsB,EAAqB,MAAM,2CAA2C,CAAC;AAM3G;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAQ5D;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,GAAG,iBAAiB,CAEpF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,4CAA4C;IAC5C,MAAM,EAAE,YAAY,CAAC;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,oDAAoD;IACpD,kBAAkB,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACzD;;;OAGG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACpD,sFAAsF;IACtF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC;IACrE;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC/C,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,uEAAuE;IACvE,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACjD,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,EAC7B,MAAM,EACN,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,MAAM,EACN,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,GACb,EAAE,sBAAsB,2CA2BxB"}
@@ -1,11 +1,10 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2026 GoodData Corporation
3
- import { useCallback, useRef, useState } from "react";
3
+ import { useCallback, useId, useRef, useState } from "react";
4
4
  import { useIntl } from "react-intl";
5
5
  import { olpPermissionMessages } from "../../locales.js";
6
6
  import { bem } from "../@utils/bem.js";
7
7
  import { UiIcon } from "../UiIcon/UiIcon.js";
8
- import { UiIconButton } from "../UiIconButton/UiIconButton.js";
9
8
  import { UiLabelsChecklist } from "../UiLabelsChecklist/UiLabelsChecklist.js";
10
9
  import { UiPopover } from "../UiPopover/UiPopover.js";
11
10
  import { UiTooltip } from "../UiTooltip/UiTooltip.js";
@@ -28,16 +27,16 @@ export function permissionLevelMessage(level) {
28
27
  * Per-grantee permission popover. Renders a fixed set of rows — three
29
28
  * permission levels (Can edit & share / Can view & share / Can view), an
30
29
  * optional divider, an optional labels drill-in and an optional Remove access
31
- * action row. Each level row carries an `infoCircle` tooltip; disabled level
32
- * rows (`disabledLevels`) swap it for `disabledTooltip`.
30
+ * action row. Enabled rows carry no tooltip; a disabled row (`disabledLevels`,
31
+ * `isRemoveDisabled`) shows its explanation as a tooltip over the whole row.
33
32
  *
34
33
  * @internal
35
34
  */
36
- export function UiPermissionMenu({ anchor, selectedLevel, onPermissionChange, disabledLevels, disabledTooltip, disabledLevelTooltips, labels, selectedLabelIds, onLabelsChange, onRemoveAccess, isRemoveDisabled, removeDisabledTooltip, dataTestId, }) {
35
+ export function UiPermissionMenu({ anchor, selectedLevel, onPermissionChange, disabledLevels, disabledTooltip, disabledLevelTooltips, labels, selectedLabelIds, onLabelsChange, onRemoveAccess, isRemoveDisabled, removeDisabledTooltip, removeAccessLabel, dataTestId, }) {
37
36
  const hasLabels = (labels?.length ?? 0) > 0;
38
- return (_jsx(UiPopover, { anchor: anchor, anchorAccessibilityConfig: { ariaHaspopup: "menu" }, width: hasLabels ? 200 : 180, content: ({ onClose }) => (_jsx(MenuBody, { selectedLevel: selectedLevel, onPermissionChange: onPermissionChange, disabledLevels: disabledLevels, disabledTooltip: disabledTooltip, disabledLevelTooltips: disabledLevelTooltips, labels: labels, selectedLabelIds: selectedLabelIds, onLabelsChange: onLabelsChange, onRemoveAccess: onRemoveAccess, isRemoveDisabled: isRemoveDisabled, removeDisabledTooltip: removeDisabledTooltip, onClose: onClose, dataTestId: dataTestId })) }));
37
+ return (_jsx(UiPopover, { anchor: anchor, anchorAccessibilityConfig: { ariaHaspopup: "menu" }, width: hasLabels ? 200 : 180, content: ({ onClose }) => (_jsx(MenuBody, { selectedLevel: selectedLevel, onPermissionChange: onPermissionChange, disabledLevels: disabledLevels, disabledTooltip: disabledTooltip, disabledLevelTooltips: disabledLevelTooltips, labels: labels, selectedLabelIds: selectedLabelIds, onLabelsChange: onLabelsChange, onRemoveAccess: onRemoveAccess, isRemoveDisabled: isRemoveDisabled, removeDisabledTooltip: removeDisabledTooltip, removeAccessLabel: removeAccessLabel, onClose: onClose, dataTestId: dataTestId })) }));
39
38
  }
40
- function MenuBody({ selectedLevel, onPermissionChange, disabledLevels, disabledTooltip, disabledLevelTooltips, labels, selectedLabelIds, onLabelsChange, onRemoveAccess, isRemoveDisabled, removeDisabledTooltip, onClose, dataTestId, }) {
39
+ function MenuBody({ selectedLevel, onPermissionChange, disabledLevels, disabledTooltip, disabledLevelTooltips, labels, selectedLabelIds, onLabelsChange, onRemoveAccess, isRemoveDisabled, removeDisabledTooltip, removeAccessLabel, onClose, dataTestId, }) {
41
40
  const intl = useIntl();
42
41
  // Drill-in state — swaps the row list for the labels checklist. Local to the
43
42
  // popover content, so it resets every time the menu opens. `origin` is what
@@ -54,30 +53,28 @@ function MenuBody({ selectedLevel, onPermissionChange, disabledLevels, disabledT
54
53
  onClose();
55
54
  };
56
55
  const hasLabels = (labels?.length ?? 0) > 0;
57
- const levelItem = (level, label, tooltip) => {
56
+ const levelItem = (level, label) => {
58
57
  const disabled = disabledLevels?.includes(level) ?? false;
59
58
  return {
60
59
  key: level,
61
60
  label,
62
- // A disabled level explains why it can't be picked instead of what it does.
63
- // `||`, not `??`: an empty explanation must not suppress the info button.
64
- tooltip: disabled ? (disabledLevelTooltips?.[level] ?? disabledTooltip) || tooltip : tooltip,
61
+ // Only a disabled level explains itself — why it can't be picked.
62
+ tooltip: disabled ? (disabledLevelTooltips?.[level] ?? disabledTooltip) : undefined,
65
63
  radioValue: level,
66
64
  disabled,
67
65
  onClick: disabled ? () => { } : choose(() => onPermissionChange(level)),
68
66
  };
69
67
  };
70
68
  const levelItems = [
71
- levelItem("EDIT", intl.formatMessage(olpPermissionMessages.canEditAndShare), intl.formatMessage(olpPermissionMessages.canEditAndShareTooltip)),
72
- levelItem("SHARE", intl.formatMessage(olpPermissionMessages.canViewAndShare), intl.formatMessage(olpPermissionMessages.canViewAndShareTooltip)),
73
- levelItem("VIEW", intl.formatMessage(olpPermissionMessages.canView), intl.formatMessage(olpPermissionMessages.canViewTooltip)),
69
+ levelItem("EDIT", intl.formatMessage(olpPermissionMessages.canEditAndShare)),
70
+ levelItem("SHARE", intl.formatMessage(olpPermissionMessages.canViewAndShare)),
71
+ levelItem("VIEW", intl.formatMessage(olpPermissionMessages.canView)),
74
72
  ];
75
73
  const actionItems = [];
76
74
  if (hasLabels) {
77
75
  actionItems.push({
78
76
  key: "labels",
79
77
  label: intl.formatMessage(olpPermissionMessages.labels),
80
- icon: "ldmLabel",
81
78
  iconRight: "navigateRight",
82
79
  // Drill in — the checklist owns Back/Cancel/Apply and closes the menu itself.
83
80
  onClick: () => setView({ view: "labels", origin: "nav" }),
@@ -88,8 +85,7 @@ function MenuBody({ selectedLevel, onPermissionChange, disabledLevels, disabledT
88
85
  // row can explain why instead of the action silently going missing.
89
86
  actionItems.push({
90
87
  key: "remove",
91
- label: intl.formatMessage(olpPermissionMessages.removeAccess),
92
- icon: "trash",
88
+ label: removeAccessLabel ?? intl.formatMessage(olpPermissionMessages.removeAccess),
93
89
  tooltip: isRemoveDisabled ? removeDisabledTooltip : undefined,
94
90
  disabled: isRemoveDisabled,
95
91
  onClick: isRemoveDisabled ? () => { } : choose(onRemoveAccess),
@@ -132,12 +128,6 @@ function MenuBody({ selectedLevel, onPermissionChange, disabledLevels, disabledT
132
128
  autoFocus: item.key === "labels" && origin === "nav" }, item.key)))] }) }));
133
129
  }
134
130
  function PermissionMenuItem({ item, selectedLevel, autoFocus }) {
135
- const intl = useIntl();
136
- // Tooltip anchor must live OUTSIDE the menu-item button so we don't nest an
137
- // interactive element inside a button (invalid HTML, breaks focus). The row
138
- // wrapper provides the flex layout; the button covers the label; the
139
- // tooltip sits next to the button.
140
- //
141
131
  // When this row opens as the drill-in return target, focus it as it mounts via
142
132
  // a callback ref — no effect, and it can't race the button's mount.
143
133
  const focusOnAttach = useCallback((node) => {
@@ -147,9 +137,10 @@ function PermissionMenuItem({ item, selectedLevel, autoFocus }) {
147
137
  }, [autoFocus]);
148
138
  const isRadio = !!item.radioValue;
149
139
  const isChecked = isRadio && item.radioValue === selectedLevel;
150
- return (_jsxs("div", { className: e("item-row"), children: [_jsxs("button", { type: "button", ref: focusOnAttach, role: isRadio ? "menuitemradio" : "menuitem", "aria-checked": isRadio ? isChecked : undefined, "aria-disabled": item.disabled ? true : undefined, className: e("item", { disabled: Boolean(item.disabled) }), onClick: item.onClick, children: [item.icon ? _jsx(UiIcon, { type: item.icon, size: 16, color: "complementary-7" }) : null, _jsx("span", { className: e("item-label"), children: item.label }), item.iconRight ? _jsx(UiIcon, { type: item.iconRight, size: 14, color: "complementary-7" }) : null] }), item.tooltip ? (_jsx(UiTooltip, { triggerBy: ["hover", "focus"], content: item.tooltip, anchor: _jsx(UiIconButton, { icon: "infoCircle", variant: "tertiary", size: "small", accessibilityConfig: {
151
- ariaLabel: intl.formatMessage(olpPermissionMessages.moreInfoAriaLabel, {
152
- label: item.label,
153
- }),
154
- } }) })) : null] }));
140
+ // The visual tooltip exists only while open, so the explanation is also kept as a
141
+ // persistent hidden description the button points at for assistive tech.
142
+ const descriptionId = useId();
143
+ const button = (_jsxs("button", { type: "button", ref: focusOnAttach, role: isRadio ? "menuitemradio" : "menuitem", "aria-checked": isRadio ? isChecked : undefined, "aria-disabled": item.disabled ? true : undefined, "aria-describedby": item.tooltip ? descriptionId : undefined, className: e("item", { disabled: Boolean(item.disabled) }), onClick: item.onClick, children: [_jsx("span", { className: e("item-label"), children: item.label }), item.iconRight ? _jsx(UiIcon, { type: item.iconRight, size: 14, color: "complementary-7" }) : null] }));
144
+ return (_jsx("div", { className: e("item-row"), children: item.tooltip ? (_jsxs(_Fragment, { children: [_jsx(UiTooltip, { triggerBy: ["hover", "focus"], content: _jsx("div", { className: e("item-tooltip"), children: item.tooltip }), anchorWrapperStyles: ROW_ANCHOR_STYLES, anchor: button }), _jsx("span", { className: "sr-only", id: descriptionId, children: item.tooltip })] })) : (button) }));
155
145
  }
146
+ const ROW_ANCHOR_STYLES = { display: "flex", flex: "1 1 auto", minWidth: 0 };
@@ -42,7 +42,7 @@ export function useResponsiveTags(tags, mode, deps) {
42
42
  hiddenTagsContainerRef,
43
43
  addButtonRef,
44
44
  mode,
45
- // eslint-disable-next-line react-hooks/exhaustive-deps
45
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
46
46
  ...(deps ?? []),
47
47
  ]);
48
48
  useLayoutEffect(() => {