@gooddata/sdk-ui-kit 11.43.0-alpha.4 → 11.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/esm/@ui/UiGeneralAccessRadio/UiGeneralAccessRadio.d.ts +7 -1
  2. package/esm/@ui/UiGeneralAccessRadio/UiGeneralAccessRadio.d.ts.map +1 -1
  3. package/esm/@ui/UiGeneralAccessRadio/UiGeneralAccessRadio.js +4 -2
  4. package/esm/@ui/UiGranteeRowControls/UiGranteeRowControls.d.ts +5 -2
  5. package/esm/@ui/UiGranteeRowControls/UiGranteeRowControls.d.ts.map +1 -1
  6. package/esm/@ui/UiGranteeRowControls/UiGranteeRowControls.js +16 -4
  7. package/esm/@ui/UiMenu/UiMenu.d.ts.map +1 -1
  8. package/esm/@ui/UiMenu/UiMenu.js +1 -1
  9. package/esm/@ui/UiMoreOptionsMenu/UiMoreOptionsMenu.d.ts +10 -3
  10. package/esm/@ui/UiMoreOptionsMenu/UiMoreOptionsMenu.d.ts.map +1 -1
  11. package/esm/@ui/UiMoreOptionsMenu/UiMoreOptionsMenu.js +18 -4
  12. package/esm/@ui/UiObjectShareDialog/UiObjectShareDialogCard.d.ts +6 -1
  13. package/esm/@ui/UiObjectShareDialog/UiObjectShareDialogCard.d.ts.map +1 -1
  14. package/esm/@ui/UiObjectShareDialog/UiObjectShareDialogCard.js +2 -2
  15. package/esm/@ui/UiPermissionMenu/UiPermissionMenu.d.ts +3 -1
  16. package/esm/@ui/UiPermissionMenu/UiPermissionMenu.d.ts.map +1 -1
  17. package/esm/@ui/UiPopover/UiPopover.d.ts.map +1 -1
  18. package/esm/@ui/UiPopover/UiPopover.js +1 -1
  19. package/esm/List/LegacyList.d.ts +1 -1
  20. package/esm/List/LegacyList.d.ts.map +1 -1
  21. package/esm/List/LegacyList.js +103 -55
  22. package/esm/List/List.d.ts +1 -1
  23. package/esm/List/List.d.ts.map +1 -1
  24. package/esm/List/List.js +95 -53
  25. package/esm/Overlay/Overlay.js +2 -2
  26. package/esm/locales.d.ts +6 -0
  27. package/esm/locales.d.ts.map +1 -1
  28. package/esm/locales.js +2 -0
  29. package/esm/sdk-ui-kit.d.ts +32 -10
  30. package/package.json +12 -13
  31. package/src/@ui/UiGranteeRowControls/UiGranteeRowControls.scss +8 -0
  32. package/src/@ui/UiLabelsChecklist/UiLabelsChecklist.scss +11 -0
  33. package/src/@ui/UiMenu/UiMenu.scss +9 -0
  34. package/styles/css/insightList.css +1 -3
  35. package/styles/css/insightList.css.map +1 -1
  36. package/styles/css/list.css +14 -655
  37. package/styles/css/list.css.map +1 -1
  38. package/styles/css/main.css +33 -658
  39. package/styles/css/main.css.map +1 -1
  40. package/styles/css/menu.css +14 -655
  41. package/styles/css/menu.css.map +1 -1
  42. package/styles/scss/insightList.scss +1 -3
  43. package/styles/scss/list.scss +15 -65
package/esm/List/List.js CHANGED
@@ -1,87 +1,129 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  // (C) 2007-2026 GoodData Corporation
3
- import { useCallback, useEffect, useMemo } from "react";
3
+ import { useCallback, useEffect, useMemo, useRef, } from "react";
4
+ import { useVirtualizer } from "@tanstack/react-virtual";
4
5
  import cx from "classnames";
5
- import { Cell, Column, Table } from "fixed-data-table-2";
6
- import { DROPDOWN_BODY_CLASS } from "../Dropdown/Dropdown.js";
7
6
  // it configures max number of records due to
8
7
  // inefficiency with virtual memory allocation
9
8
  // that causes application crash (TNT-787)
10
9
  const MAX_NUMBER_OF_ROWS = 1000000;
11
- const BORDER_HEIGHT = 1;
12
10
  const HALF_ROW = 0.5;
11
+ // delay (ms) after the last scroll event before onScrollEnd is fired
12
+ const SCROLL_END_DELAY = 100;
13
13
  export const MAX_VISIBLE_ITEMS_COUNT = 10;
14
14
  export const DEFAULT_ITEM_HEIGHT = 28;
15
15
  /**
16
16
  * @internal
17
17
  */
18
- export function List({ id, className = "", compensateBorder = true, width = 200, height, maxHeight, items = [], itemsCount = items.length, itemHeight = DEFAULT_ITEM_HEIGHT, itemHeightGetter = null, maxVisibleItemsCount = MAX_VISIBLE_ITEMS_COUNT, renderItem, onScrollStart, onScrollEnd, scrollToItem, scrollDirection, accessibilityConfig, }) {
18
+ export function List({ id, className = "", width = 200, height, maxHeight, items = [], itemsCount = items.length, itemHeight = DEFAULT_ITEM_HEIGHT, itemHeightGetter = null, maxVisibleItemsCount = MAX_VISIBLE_ITEMS_COUNT, renderItem, onScrollStart, onScrollEnd, scrollToItem, scrollDirection, accessibilityConfig, }) {
19
+ const scrollContainerRef = useRef(null);
20
+ const rowsCount = Math.min(itemsCount, MAX_NUMBER_OF_ROWS);
21
+ // when there are more items than fit, show half of the next row to hint scrollability
19
22
  const currentItemsCount = itemsCount > maxVisibleItemsCount ? maxVisibleItemsCount + HALF_ROW : itemsCount;
20
23
  const listHeight = height || currentItemsCount * itemHeight;
21
- const listHeightWithBorder = compensateBorder ? listHeight + BORDER_HEIGHT * 2 : listHeight;
24
+ // the visible viewport height; the list is prop-sized so this is deterministic
25
+ const viewportHeight = maxHeight ? Math.min(maxHeight, listHeight) : listHeight;
26
+ const estimateSize = useCallback((index) => (itemHeightGetter ? itemHeightGetter(index) : itemHeight), [itemHeightGetter, itemHeight]);
27
+ // Report the viewport size to the virtualizer from the known props, falling back from a real
28
+ // measurement when the DOM has no layout (e.g. jsdom in tests). Keeps virtualization correct
29
+ // without depending on layout being available.
30
+ const observeElementRect = useCallback((_instance, cb) => {
31
+ const el = scrollContainerRef.current;
32
+ if (!el) {
33
+ return undefined;
34
+ }
35
+ const report = () => {
36
+ const rect = el.getBoundingClientRect();
37
+ cb({ width: rect.width || width, height: rect.height || viewportHeight });
38
+ };
39
+ report();
40
+ if (typeof ResizeObserver === "undefined") {
41
+ return undefined;
42
+ }
43
+ const resizeObserver = new ResizeObserver(report);
44
+ resizeObserver.observe(el);
45
+ return () => resizeObserver.disconnect();
46
+ }, [width, viewportHeight]);
47
+ const rowVirtualizer = useVirtualizer({
48
+ count: rowsCount,
49
+ getScrollElement: () => scrollContainerRef.current,
50
+ estimateSize,
51
+ observeElementRect,
52
+ overscan: 5,
53
+ });
54
+ const virtualItems = rowVirtualizer.getVirtualItems();
55
+ // scroll the requested item into view (preserves the legacy +scrollDirection offset)
22
56
  const scrollToItemRowIndex = useMemo(() => {
23
57
  if (!scrollToItem) {
24
58
  return undefined;
25
59
  }
26
- return items.indexOf(scrollToItem) + (scrollDirection ?? 1);
60
+ const index = items.indexOf(scrollToItem);
61
+ if (index < 0) {
62
+ return undefined;
63
+ }
64
+ return index + (scrollDirection ?? 1);
27
65
  }, [items, scrollToItem, scrollDirection]);
66
+ useEffect(() => {
67
+ if (scrollToItemRowIndex === undefined || rowsCount === 0) {
68
+ return;
69
+ }
70
+ rowVirtualizer.scrollToIndex(Math.min(Math.max(scrollToItemRowIndex, 0), rowsCount - 1));
71
+ // rowVirtualizer identity is stable; intentionally only react to the target index changing
72
+ // eslint-disable-next-line react-hooks/exhaustive-deps
73
+ }, [scrollToItemRowIndex, rowsCount]);
74
+ // converts vertical scroll position to the [first, last] visible item index range,
75
+ // matching the legacy fixed-data-table-based behavior consumers (e.g. AsyncList) depend on
28
76
  const getVisibleScrollRange = useCallback((scrollY) => {
29
77
  const rowIndex = Math.floor(scrollY / itemHeight);
30
78
  const visibleRange = Math.ceil(listHeight / itemHeight);
31
79
  return [rowIndex, rowIndex + visibleRange];
32
80
  }, [itemHeight, listHeight]);
33
- const handleScrollStart = useCallback((_, y) => {
34
- if (onScrollStart) {
35
- const [startIndex, endIndex] = getVisibleScrollRange(y);
36
- onScrollStart(startIndex, endIndex);
81
+ const isScrollingRef = useRef(false);
82
+ const scrollEndTimerRef = useRef(undefined);
83
+ const handleScroll = useCallback((event) => {
84
+ const scrollY = event.currentTarget.scrollTop;
85
+ const [startIndex, endIndex] = getVisibleScrollRange(scrollY);
86
+ if (!isScrollingRef.current) {
87
+ isScrollingRef.current = true;
88
+ onScrollStart?.(startIndex, endIndex);
37
89
  }
38
- }, [onScrollStart, getVisibleScrollRange]);
39
- const handleScrollEnd = useCallback((_, y) => {
40
- if (onScrollEnd) {
41
- const [startIndex, endIndex] = getVisibleScrollRange(y);
42
- onScrollEnd(startIndex, endIndex);
90
+ if (scrollEndTimerRef.current) {
91
+ clearTimeout(scrollEndTimerRef.current);
43
92
  }
44
- }, [onScrollEnd, getVisibleScrollRange]);
93
+ scrollEndTimerRef.current = setTimeout(() => {
94
+ isScrollingRef.current = false;
95
+ onScrollEnd?.(startIndex, endIndex);
96
+ }, SCROLL_END_DELAY);
97
+ }, [getVisibleScrollRange, onScrollStart, onScrollEnd]);
98
+ // clear any pending scroll-end timer on unmount so callbacks don't fire on an unmounted tree
45
99
  useEffect(() => {
46
100
  return () => {
47
- enablePageScrolling();
101
+ if (scrollEndTimerRef.current) {
102
+ clearTimeout(scrollEndTimerRef.current);
103
+ }
48
104
  };
49
105
  }, []);
50
- const styles = useMemo(() => {
51
- return {
52
- width,
53
- };
54
- }, [width]);
55
- return (_jsx("div", { id: id, "data-testid": "gd-list", className: cx("gd-list gd-infinite-list", className), style: styles, onMouseOver: disablePageScrolling, onMouseOut: enablePageScrolling, role: accessibilityConfig?.role, "aria-labelledby": accessibilityConfig?.ariaLabelledBy, children: _jsx(Table, { width: width,
56
- // compensates for https://github.com/facebook/fixed-data-table/blob/5373535d98b08b270edd84d7ce12833a4478c6b6/src/FixedDataTableNew.react.js#L872
57
- height: maxHeight ? undefined : listHeightWithBorder, maxHeight: maxHeight, headerHeight: 0, rowHeight: itemHeight, rowHeightGetter: itemHeightGetter, rowsCount: Math.min(itemsCount, MAX_NUMBER_OF_ROWS), onScrollStart: handleScrollStart, onScrollEnd: handleScrollEnd, scrollToRow: scrollToItemRowIndex, touchScrollEnabled: isTouchDevice(), keyboardScrollEnabled: true, children: _jsx(Column, { flexGrow: 1, width: 1, cell: ({ columnKey, height, width, rowIndex, }) => {
58
- const item = items[rowIndex];
59
- return (_jsx(Cell, { width: width, height: height, rowIndex: rowIndex, columnKey: columnKey, children: renderItem({
60
- rowIndex,
106
+ const containerStyle = useMemo(() => ({
107
+ width,
108
+ height: maxHeight ? undefined : listHeight,
109
+ maxHeight,
110
+ }), [width, maxHeight, listHeight]);
111
+ return (_jsx("div", { id: id, "data-testid": "gd-list", className: cx("gd-list gd-infinite-list", className), style: { width }, role: accessibilityConfig?.role, "aria-labelledby": accessibilityConfig?.ariaLabelledBy, children: _jsx("div", { ref: scrollContainerRef, className: "gd-infinite-list-scroll-container", style: containerStyle, onScroll: handleScroll, children: _jsx("div", { className: "gd-infinite-list-sizer", style: { height: rowVirtualizer.getTotalSize(), width: "100%", position: "relative" }, children: virtualItems.map((virtualRow) => {
112
+ const item = items[virtualRow.index];
113
+ return (_jsx("div", { className: "gd-infinite-list-item", style: {
114
+ position: "absolute",
115
+ top: 0,
116
+ left: 0,
117
+ width: "100%",
118
+ height: virtualRow.size,
119
+ transform: `translateY(${virtualRow.start}px)`,
120
+ }, children: renderItem({
121
+ rowIndex: virtualRow.index,
61
122
  item,
62
123
  width,
63
- height,
64
- isFirst: rowIndex === 0,
65
- isLast: rowIndex === itemsCount - 1,
66
- }) }));
67
- } }) }) }));
68
- }
69
- function preventDefault(e) {
70
- const wheelEvent = e;
71
- const target = wheelEvent.target;
72
- const isDropdownBodyScroll = target?.closest?.(`.${DROPDOWN_BODY_CLASS}`);
73
- if (isDropdownBodyScroll) {
74
- // allow to scroll another lists placed in dropdowns (e.g. in Filter Groups)
75
- return;
76
- }
77
- e.preventDefault();
78
- }
79
- function isTouchDevice() {
80
- return "ontouchstart" in document.documentElement;
81
- }
82
- function disablePageScrolling() {
83
- document.body.addEventListener("wheel", preventDefault, { passive: false });
84
- }
85
- function enablePageScrolling() {
86
- document.body.removeEventListener("wheel", preventDefault);
124
+ height: virtualRow.size,
125
+ isFirst: virtualRow.index === 0,
126
+ isLast: virtualRow.index === itemsCount - 1,
127
+ }) }, virtualRow.key));
128
+ }) }) }) }));
87
129
  }
@@ -50,8 +50,8 @@ function alignExceedsThreshold(firstAlignment, secondAlignment) {
50
50
  * Stops React synthetic event propagation but re-dispatches native events
51
51
  * to document and documentElement so that:
52
52
  * - Other Overlays can detect outside clicks and close themselves
53
- * - Libraries listening on document.documentElement (like fixed-data-table-2's
54
- * DOMMouseMoveTracker for scrollbar drag release) receive the events
53
+ * - Libraries listening on document / document.documentElement (e.g. for drag/scroll
54
+ * release tracking) still receive the events
55
55
  */
56
56
  const stopPropagation = (e) => {
57
57
  e.stopPropagation();
package/esm/locales.d.ts CHANGED
@@ -150,6 +150,9 @@ export declare const olpGeneralAccessMessages: {
150
150
  workspaceDescription: {
151
151
  id: string;
152
152
  };
153
+ workspaceDescriptionShare: {
154
+ id: string;
155
+ };
153
156
  };
154
157
  export declare const olpLabelMessages: {
155
158
  suffixPrimary: {
@@ -175,6 +178,9 @@ export declare const olpPermissionMessages: {
175
178
  canView: {
176
179
  id: string;
177
180
  };
181
+ canEdit: {
182
+ id: string;
183
+ };
178
184
  canViewAndShareTooltip: {
179
185
  id: string;
180
186
  };
@@ -1 +1 @@
1
- {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../src/locales.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB;;;;CAE/B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;CAMpC,CAAC;AAEH,eAAO,MAAM,+BAA+B;;;;;;;CAG1C,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;CAG/B,CAAC;AAEH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;CAK1C,CAAC;AAEH,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgB5C,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;CAI/B,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;CAGnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;CAEhC,CAAC;AAEH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;CAKvC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;CAMtC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;CAMnC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;CAM3B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAchC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;CAMjC,CAAC;AAEH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;CAMvC,CAAC"}
1
+ {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../src/locales.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB;;;;CAE/B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;CAMpC,CAAC;AAEH,eAAO,MAAM,+BAA+B;;;;;;;CAG1C,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;CAG/B,CAAC;AAEH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;CAK1C,CAAC;AAEH,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgB5C,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;CAI/B,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;CAGnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;CAEhC,CAAC;AAEH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;CAKvC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;CAMtC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;CAOnC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;CAM3B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAehC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;CAMjC,CAAC;AAEH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;CAMvC,CAAC"}
package/esm/locales.js CHANGED
@@ -73,6 +73,7 @@ export const olpGeneralAccessMessages = defineMessages({
73
73
  restrictedDescription: { id: "shareDialog.olp.generalAccess.restricted.description" },
74
74
  workspaceTitle: { id: "shareDialog.olp.generalAccess.workspace.title" },
75
75
  workspaceDescription: { id: "shareDialog.olp.generalAccess.workspace.description" },
76
+ workspaceDescriptionShare: { id: "shareDialog.olp.generalAccess.workspace.description.share" },
76
77
  });
77
78
  export const olpLabelMessages = defineMessages({
78
79
  suffixPrimary: { id: "shareDialog.olp.label.suffix.primary" },
@@ -84,6 +85,7 @@ export const olpLabelMessages = defineMessages({
84
85
  export const olpPermissionMessages = defineMessages({
85
86
  canViewAndShare: { id: "shareDialog.share.granular.grantee.permission.share" },
86
87
  canView: { id: "shareDialog.share.granular.grantee.permission.view" },
88
+ canEdit: { id: "shareDialog.olp.permission.edit" },
87
89
  canViewAndShareTooltip: { id: "shareDialog.olp.permission.tooltip.share" },
88
90
  canViewTooltip: { id: "shareDialog.olp.permission.tooltip.view" },
89
91
  transferOwnership: { id: "shareDialog.olp.permission.transferOwnership" },
@@ -7290,6 +7290,12 @@ export declare interface IUiGeneralAccessRadioProps {
7290
7290
  * author pick labels and the workspace-wide permission level.
7291
7291
  */
7292
7292
  workspaceControls?: ReactNode;
7293
+ /**
7294
+ * Workspace-wide permission level, used to keep the `All workspace members`
7295
+ * description in sync with the level picked in `workspaceControls`
7296
+ * (`view` → "can view", `share` → "can view and share"). Defaults to `view`.
7297
+ */
7298
+ workspaceLevel?: "VIEW" | "SHARE";
7293
7299
  /** Test id forwarded to the root element. */
7294
7300
  dataTestId?: string;
7295
7301
  }
@@ -7371,13 +7377,15 @@ export declare interface IUiGranteeRowControlsProps {
7371
7377
  /** Locked items are always treated as selected. */
7372
7378
  labels: ReadonlyArray<IUiLabelsChecklistItem>;
7373
7379
  selectedLabelIds: ReadonlyArray<string>;
7374
- permissionLevel: PermissionMenuLevel;
7380
+ /** The level to display. `EDIT` renders read-only; VIEW/SHARE are selectable. */
7381
+ permissionLevel: AccessGranularPermission;
7375
7382
  /**
7376
7383
  * Set only when the grantee inherits a higher permission than `permissionLevel`
7377
7384
  * (e.g. from a group); drives the warning badge. Undefined when not elevated.
7378
7385
  */
7379
- effectivePermission?: PermissionMenuLevel;
7386
+ effectivePermission?: AccessGranularPermission;
7380
7387
  onLabelsChange: (selectedIds: string[]) => void;
7388
+ /** Fires only for selectable rows (VIEW/SHARE); EDIT rows have no level control. */
7381
7389
  onPermissionChange: (level: PermissionMenuLevel) => void;
7382
7390
  onTransferOwnership?: () => void;
7383
7391
  onRemoveAccess?: () => void;
@@ -7975,6 +7983,11 @@ export declare interface IUiMoreOptionsMenuProps {
7975
7983
  onLabelsChange?: (selectedIds: string[]) => void;
7976
7984
  /** Omit to hide the row (Transfer ownership is gated until wired). */
7977
7985
  onTransferOwnership?: () => void;
7986
+ /**
7987
+ * Omit to hide the row. Used for read-only permission rows (e.g. EDIT), whose
7988
+ * level control has no dropdown to host Remove access — so the action lives here.
7989
+ */
7990
+ onRemoveAccess?: () => void;
7978
7991
  isDisabled?: boolean;
7979
7992
  dataTestId?: string;
7980
7993
  }
@@ -8025,6 +8038,11 @@ export declare interface IUiObjectShareDialogCardProps {
8025
8038
  * and permission level.
8026
8039
  */
8027
8040
  workspaceControls?: ReactNode;
8041
+ /**
8042
+ * Workspace-wide permission level, so the "All workspace members" description
8043
+ * matches the level picked in `workspaceControls`. Defaults to `view`.
8044
+ */
8045
+ workspaceLevel?: "VIEW" | "SHARE";
8028
8046
  /**
8029
8047
  * Optional error notice. When set, it replaces the grantee list and
8030
8048
  * general-access sections (which can't reflect a real policy on a failed
@@ -9246,7 +9264,7 @@ export declare function LegacyInvertableList<T>({ className, filteredItemsCount,
9246
9264
  * @deprecated This component is deprecated use List instead
9247
9265
  * @internal
9248
9266
  */
9249
- export declare function LegacyList({ className, onScroll, onScrollStart, onSelect, width, height, itemHeight, itemHeightGetter, compensateBorder, scrollToSelected, dataSource, rowItem }: ILegacyListProps): JSX.Element;
9267
+ export declare function LegacyList({ className, onScroll, onScrollStart, onSelect, width, height, itemHeight, itemHeightGetter, scrollToSelected, dataSource, rowItem }: ILegacyListProps): JSX.Element;
9250
9268
 
9251
9269
  /**
9252
9270
  * @internal
@@ -9286,7 +9304,7 @@ export declare type LevelTypesUnion<Levels extends unknown[]> = Levels[number];
9286
9304
  /**
9287
9305
  * @internal
9288
9306
  */
9289
- export declare function List<T>({ id, className, compensateBorder, width, height, maxHeight, items, itemsCount, itemHeight, itemHeightGetter, maxVisibleItemsCount, renderItem, onScrollStart, onScrollEnd, scrollToItem, scrollDirection, accessibilityConfig }: IListProps<T>): ReactElement;
9307
+ export declare function List<T>({ id, className, width, height, maxHeight, items, itemsCount, itemHeight, itemHeightGetter, maxVisibleItemsCount, renderItem, onScrollStart, onScrollEnd, scrollToItem, scrollDirection, accessibilityConfig }: IListProps<T>): ReactElement;
9290
9308
 
9291
9309
  /**
9292
9310
  * @internal
@@ -9649,7 +9667,9 @@ export declare function ParameterControlDropdown({ name, value, resetValue, cons
9649
9667
  export declare function ParameterPicker({ parameters, excludedKeys, isLoading, maxListHeight, onAdd, onCancel }: IParameterPickerProps): JSX.Element;
9650
9668
 
9651
9669
  /**
9652
- * Permission level offered by the menu.
9670
+ * Selectable permission level. The menu and the add-grantee picker only ever
9671
+ * assign VIEW or SHARE — EDIT is shown as a read-only row (via the model's
9672
+ * `AccessGranularPermission`) and is never selectable from the UI.
9653
9673
  *
9654
9674
  * @internal
9655
9675
  */
@@ -10631,7 +10651,7 @@ export declare function UiFocusTrap({ root, children, focusCheckFn }: {
10631
10651
  *
10632
10652
  * @internal
10633
10653
  */
10634
- export declare function UiGeneralAccessRadio({ value, onChange, disabled, workspaceControls, dataTestId }: IUiGeneralAccessRadioProps): JSX.Element;
10654
+ export declare function UiGeneralAccessRadio({ value, onChange, disabled, workspaceControls, workspaceLevel, dataTestId }: IUiGeneralAccessRadioProps): JSX.Element;
10635
10655
 
10636
10656
  /**
10637
10657
  * Sectioned async grantee picker — specialization of `UiAutocomplete` for the
@@ -10785,12 +10805,14 @@ export declare function UiMenu<T extends IUiMenuItemData = object, M extends obj
10785
10805
  export declare function UiModalDialog({ children, isOpen, onClose, width, accessibilityConfig, dataTestId }: IUiModalDialogProps): JSX.Element | null;
10786
10806
 
10787
10807
  /**
10788
- * Per-grantee "⋯" menu: "Manage labels access" (drills into {@link UiLabelsChecklist})
10789
- * and "Transfer ownership". Each row shows only when its data/handler is given.
10808
+ * Per-grantee "⋯" menu: "Manage labels access" (drills into {@link UiLabelsChecklist}),
10809
+ * "Transfer ownership" and "Remove access". Each row shows only when its data/handler
10810
+ * is given. Remove access appears here for read-only permission rows whose level control
10811
+ * has no dropdown to host it.
10790
10812
  *
10791
10813
  * @internal
10792
10814
  */
10793
- export declare function UiMoreOptionsMenu({ labels, selectedLabelIds, onLabelsChange, onTransferOwnership, isDisabled, dataTestId }: IUiMoreOptionsMenuProps): JSX.Element;
10815
+ export declare function UiMoreOptionsMenu({ labels, selectedLabelIds, onLabelsChange, onTransferOwnership, onRemoveAccess, isDisabled, dataTestId }: IUiMoreOptionsMenuProps): JSX.Element;
10794
10816
 
10795
10817
  /**
10796
10818
  * @internal
@@ -10814,7 +10836,7 @@ export declare function UiObjectShareDialog({ isOpen, ...cardProps }: IUiObjectS
10814
10836
  *
10815
10837
  * @internal
10816
10838
  */
10817
- export declare function UiObjectShareDialogCard({ objectTitle, onClose, grantees, onAddClick, isAddDisabled, generalAccess, onGeneralAccessChange, isGeneralAccessDisabled, workspaceControls, error, dataTestId }: IUiObjectShareDialogCardProps): JSX.Element;
10839
+ export declare function UiObjectShareDialogCard({ objectTitle, onClose, grantees, onAddClick, isAddDisabled, generalAccess, onGeneralAccessChange, isGeneralAccessDisabled, workspaceControls, workspaceLevel, error, dataTestId }: IUiObjectShareDialogCardProps): JSX.Element;
10818
10840
 
10819
10841
  /**
10820
10842
  * @internal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-kit",
3
- "version": "11.43.0-alpha.4",
3
+ "version": "11.43.0",
4
4
  "description": "GoodData SDK - UI Building Components",
5
5
  "license": "MIT",
6
6
  "author": "GoodData Corporation",
@@ -56,7 +56,6 @@
56
56
  "date-fns-tz": "^3.2.0",
57
57
  "debounce-promise": "^3.1.2",
58
58
  "default-import": "1.1.5",
59
- "fixed-data-table-2": "2.0.22",
60
59
  "lodash-es": "^4.17.23",
61
60
  "moment": "^2.29.4",
62
61
  "react-content-loader": "^7.1.1",
@@ -75,11 +74,11 @@
75
74
  "tslib": "2.8.1",
76
75
  "unified": "^11.0.5",
77
76
  "uuid": "11.1.1",
78
- "@gooddata/sdk-model": "11.43.0-alpha.4",
79
- "@gooddata/sdk-ui": "11.43.0-alpha.4",
80
- "@gooddata/sdk-backend-spi": "11.43.0-alpha.4",
81
- "@gooddata/util": "11.43.0-alpha.4",
82
- "@gooddata/sdk-ui-theme-provider": "11.43.0-alpha.4"
77
+ "@gooddata/sdk-backend-spi": "11.43.0",
78
+ "@gooddata/sdk-ui": "11.43.0",
79
+ "@gooddata/sdk-model": "11.43.0",
80
+ "@gooddata/sdk-ui-theme-provider": "11.43.0",
81
+ "@gooddata/util": "11.43.0"
83
82
  },
84
83
  "devDependencies": {
85
84
  "@microsoft/api-documenter": "^7.17.0",
@@ -128,11 +127,11 @@
128
127
  "typescript": "5.9.3",
129
128
  "vitest": "4.1.8",
130
129
  "vitest-dom": "0.1.1",
131
- "@gooddata/eslint-config": "11.43.0-alpha.4",
132
- "@gooddata/oxlint-config": "11.43.0-alpha.4",
133
- "@gooddata/reference-workspace": "11.43.0-alpha.4",
134
- "@gooddata/sdk-backend-mockingbird": "11.43.0-alpha.4",
135
- "@gooddata/stylelint-config": "11.43.0-alpha.4"
130
+ "@gooddata/eslint-config": "11.43.0",
131
+ "@gooddata/oxlint-config": "11.43.0",
132
+ "@gooddata/reference-workspace": "11.43.0",
133
+ "@gooddata/sdk-backend-mockingbird": "11.43.0",
134
+ "@gooddata/stylelint-config": "11.43.0"
136
135
  },
137
136
  "peerDependencies": {
138
137
  "react": "^18.0.0 || ^19.0.0",
@@ -153,7 +152,7 @@
153
152
  "generate-theme": "node scripts/generateDefaultThemeScss.js && oxfmt --no-error-on-unmatched-pattern ./src/@ui/defaultTheme.scss",
154
153
  "lint": "oxlint . --quiet && eslint .",
155
154
  "lint-fix": "oxlint . --quiet --fix && eslint . --fix",
156
- "scss": "sass --load-path=node_modules --load-path=node_modules/fixed-data-table-2/dist styles/scss:styles/css",
155
+ "scss": "sass --load-path=node_modules styles/scss:styles/css",
157
156
  "stylelint": "stylelint '**/*.scss'",
158
157
  "stylelint-fix": "stylelint '**/*.scss' --fix",
159
158
  "test": "vitest watch",
@@ -12,4 +12,12 @@
12
12
  align-items: center;
13
13
  cursor: default;
14
14
  }
15
+
16
+ // Static label for a display-only level (EDIT): the grant can't be managed
17
+ // from this dialog, so it reads as plain text with no dropdown affordance.
18
+ &__readonly-permission {
19
+ font-size: 12px;
20
+ color: var(--gd-palette-complementary-6);
21
+ white-space: nowrap;
22
+ }
15
23
  }
@@ -7,22 +7,33 @@
7
7
  align-self: stretch;
8
8
  display: flex;
9
9
  flex-direction: column;
10
+ // Fill the menu's bounded height so the header and actions stay pinned while
11
+ // only the rows scroll (see &__items).
12
+ min-height: 0;
13
+ flex: 1 1 auto;
10
14
 
11
15
  // The submenu header is width:100% + content-box, so its 10px side padding
12
16
  // would overflow the column by 20px. Make it border-box so it lines up with
13
17
  // the rows and the actions strip below.
14
18
  .gd-ui-kit-submenu-header {
15
19
  box-sizing: border-box;
20
+ flex: none;
16
21
  }
17
22
 
18
23
  &__items {
19
24
  display: flex;
20
25
  flex-direction: column;
21
26
  padding: var(--gd-spacing-5px) 0;
27
+ // Scroll the rows when the label list is taller than the menu, keeping the
28
+ // header and Cancel/Apply footer always visible.
29
+ overflow-y: auto;
30
+ overscroll-behavior: contain;
31
+ min-height: 0;
22
32
  }
23
33
 
24
34
  &__actions {
25
35
  display: flex;
36
+ flex: none;
26
37
  justify-content: flex-end;
27
38
  gap: var(--gd-spacing-10px);
28
39
  padding: var(--gd-spacing-10px);
@@ -33,6 +33,15 @@
33
33
  display: contents;
34
34
  }
35
35
 
36
+ // Wraps custom (drill-in) content. Becomes a flex child so its content is
37
+ // bounded by the menu's max-height and can scroll instead of overflowing.
38
+ &__content-wrapper {
39
+ display: flex;
40
+ flex-direction: column;
41
+ flex: 1 1 auto;
42
+ min-height: 0;
43
+ }
44
+
36
45
  &__items-container {
37
46
  width: 100%;
38
47
  height: 100%;
@@ -504,9 +504,7 @@
504
504
  background-image: url("@gooddata/sdk-ui-kit/styles/images/visualization-types/pushpin.svg"), url("@gooddata/sdk-ui-kit/styles/images/visualization-types/pushpin-active.svg");
505
505
  }
506
506
 
507
- .gd-visualizations-list .public_fixedDataTableRow_main,
508
- .gd-visualizations-list .public_fixedDataTableCell_main,
509
- .gd-visualizations-list .fixedDataTableCellGroupLayout_cellGroup {
507
+ .gd-visualizations-list .gd-infinite-list-item {
510
508
  overflow: visible;
511
509
  }
512
510
 
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../scss/Button/_variables.scss","../scss/indigoFont.scss","../scss/insightList.scss","../scss/variables.scss"],"names":[],"mappings":"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","file":"insightList.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../scss/Button/_variables.scss","../scss/indigoFont.scss","../scss/insightList.scss","../scss/variables.scss"],"names":[],"mappings":"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","file":"insightList.css"}