@cloudscape-design/board-components 3.0.30 → 3.0.32

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.
@@ -1,97 +1,105 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { Position } from "../utils/position";
4
- import { LayoutEngineStepState, refloatGrid, resolveOverlaps } from "./engine-step";
4
+ import { LayoutEngineCacheNode } from "./engine-cache";
5
+ import { LayoutEngineState } from "./engine-state";
6
+ import { resolveOverlaps } from "./engine-step";
5
7
  import { LayoutEngineGrid } from "./grid";
6
- import { normalizeMovePath, normalizeResizePath, sortGridItems } from "./utils";
8
+ import { createMove, normalizeMovePath, normalizeResizePath, sortGridItems } from "./utils";
9
+ /**
10
+ * Layout engine is an abstraction to compute effects of user actions (move, resize, insert, remove).
11
+ * The engine is initialized with the board state and then takes a command to calculate the respective layout shift.
12
+ * Use a single engine instance until the user commits their move to take advantage of the internal cache.
13
+ * Once user move is committed the layout engine needs to be re-initialized with the updated layout state.
14
+ */
7
15
  export class LayoutEngine {
8
- constructor(args) {
9
- this.chained = false;
10
- if (args instanceof LayoutEngine) {
11
- this.current = args.current;
12
- this.step = args.step;
13
- this.chained = true;
14
- }
15
- else {
16
- this.current = args;
17
- this.step = new LayoutEngineStepState(new LayoutEngineGrid(args.items, args.columns));
18
- }
16
+ constructor(layout) {
17
+ this.layout = layout;
18
+ this.cache = new LayoutEngineCacheNode(new LayoutEngineState(new LayoutEngineGrid(layout.items, layout.columns)));
19
19
  }
20
- move(moveCommand) {
21
- this.cleanup();
22
- const { itemId, path } = this.validateMoveCommand(moveCommand);
20
+ move(moveCommand, cache = this.cache) {
21
+ // The validation ensures no position in the path is outside the board and updates the path so that all
22
+ // positions are incremental (moving one cell at a time) and no loops are present (no position can occur twice).
23
+ // Removing the loops guarantees that moving back to one of the previous positions including the starting one
24
+ // revives the previous state as is. The same behavior might cause confusion in case the user comes back
25
+ // to a previous position accidentally especially if the move path is long.
26
+ const path = this.validateMovePath({ ...moveCommand }, cache.state);
27
+ // The user command is resolved one step at a time. When layout engine is reused withing one transition
28
+ // it is expected that all steps but the last one are already cached.
23
29
  for (let stepIndex = 0; stepIndex < path.length; stepIndex++) {
24
- const step = path[stepIndex];
25
- const { width, height } = this.step.grid.getItem(itemId);
26
- const move = { itemId, x: step.x, y: step.y, width, height, type: "MOVE" };
27
- this.step = resolveOverlaps(move, this.step);
30
+ const item = cache.state.grid.getItem(moveCommand.itemId);
31
+ const move = createMove("MOVE", item, path[stepIndex]);
32
+ cache = cache.matches(path[stepIndex], () => resolveOverlaps(cache.state, move));
28
33
  }
29
- return new LayoutEngine(this);
34
+ return this.getLayoutShift(cache.state);
30
35
  }
31
- resize(resize) {
32
- this.cleanup();
33
- const { itemId, path } = this.validateResizeCommand(resize);
34
- const resizeTarget = this.step.grid.getItem(itemId);
36
+ resize(resizeCommand) {
37
+ // The validation ensures no position in the path is outside the board and the width/height are above 0.
38
+ // The resize path is updated so that all positions are incremental (moving one cell at a time) and
39
+ // no loops are present (no position can occur twice).
40
+ // Removing the loops guarantees that moving back to one of the previous positions including the starting one
41
+ // revives the previous state as is. The same behavior might cause confusion in case the user comes back
42
+ // to a previous position accidentally especially if the move path is long.
43
+ const path = this.validateResizePath(resizeCommand, this.cache.state);
44
+ // The user command is resolved one step at a time. When layout engine is reused withing one transition
45
+ // it is expected that all steps but the last one are already cached.
46
+ let cache = this.cache;
35
47
  for (let stepIndex = 0; stepIndex < path.length; stepIndex++) {
48
+ const resizeTarget = cache.state.grid.getItem(resizeCommand.itemId);
36
49
  const width = path[stepIndex].x - resizeTarget.x;
37
50
  const height = path[stepIndex].y - resizeTarget.y;
38
- this.step = resolveOverlaps({ itemId, x: resizeTarget.x, y: resizeTarget.y, width, height, type: "RESIZE" }, this.step);
51
+ const move = createMove("RESIZE", resizeTarget, new Position({ x: width, y: height }));
52
+ cache = cache.matches(path[stepIndex], () => resolveOverlaps(cache.state, move));
39
53
  }
40
- return new LayoutEngine(this);
54
+ return this.getLayoutShift(cache.state);
41
55
  }
42
- insert({ itemId, width, height, path: [position, ...path] }) {
43
- this.cleanup();
44
- this.step = resolveOverlaps({ itemId, ...position, width, height, type: "INSERT" }, this.step);
45
- return new LayoutEngine(this).move({ itemId, path });
56
+ insert({ itemId, width, height, path: [position, ...movePath] }) {
57
+ // For insert command the new item is injected to the given location first and then it can be moved
58
+ // the same way as the existing item would.
59
+ const insertMove = createMove("INSERT", { id: itemId, x: position.x, y: position.y, width, height }, position);
60
+ const cache = this.cache.matches(position, () => resolveOverlaps(this.cache.state, insertMove));
61
+ return this.move({ itemId, path: movePath }, cache);
46
62
  }
47
63
  remove(itemId) {
48
- this.cleanup();
49
- const { x, y, width, height } = this.step.grid.getItem(itemId);
50
- this.step = resolveOverlaps({ itemId, x, y, width, height, type: "REMOVE" }, this.step);
51
- return new LayoutEngine(this);
52
- }
53
- refloat() {
54
- this.step = refloatGrid(this.step);
55
- return new LayoutEngine(this);
64
+ // The remove command does not define the move path and is not cached. It is expected to be performed only once.
65
+ const { x, y, width, height } = this.cache.state.grid.getItem(itemId);
66
+ const move = createMove("REMOVE", { id: itemId, x, y, width, height }, new Position({ x, y }));
67
+ const state = resolveOverlaps(this.cache.state, move);
68
+ return this.getLayoutShift(state);
56
69
  }
57
- getLayoutShift() {
70
+ getLayoutShift(state) {
58
71
  return {
59
- current: this.current,
72
+ current: this.layout,
60
73
  next: {
61
- items: sortGridItems(this.step.grid.items.map((item) => ({ ...item }))),
62
- columns: this.step.grid.width,
63
- rows: this.step.grid.height,
74
+ items: sortGridItems(state.grid.items),
75
+ columns: state.grid.width,
76
+ rows: state.grid.height,
64
77
  },
65
- moves: [...this.step.moves],
66
- conflicts: [...this.step.conflicts],
78
+ moves: state.moves,
79
+ conflicts: state.conflicts ? [...state.conflicts.items] : [],
67
80
  };
68
81
  }
69
- cleanup() {
70
- if (!this.chained) {
71
- this.step = new LayoutEngineStepState(new LayoutEngineGrid(this.current.items, this.current.columns));
72
- }
73
- }
74
- validateMoveCommand({ itemId, path }) {
75
- const moveTarget = this.step.grid.getItem(itemId);
82
+ validateMovePath({ itemId, path }, state) {
83
+ const moveTarget = state.grid.getItem(itemId);
76
84
  for (const step of path) {
77
- if (step.x < 0 || step.y < 0 || step.x + moveTarget.width > this.step.grid.width) {
85
+ if (step.x < 0 || step.y < 0 || step.x + moveTarget.width > state.grid.width) {
78
86
  throw new Error("Invalid move: outside grid.");
79
87
  }
80
88
  }
81
- return { itemId, path: normalizeMovePath(new Position({ x: moveTarget.x, y: moveTarget.y }), path) };
89
+ return normalizeMovePath(new Position({ x: moveTarget.x, y: moveTarget.y }), path);
82
90
  }
83
- validateResizeCommand({ itemId, path }) {
84
- const resizeTarget = this.step.grid.getItem(itemId);
91
+ validateResizePath({ itemId, path }, state) {
92
+ const resizeTarget = state.grid.getItem(itemId);
85
93
  const x = resizeTarget.x + resizeTarget.width;
86
94
  const y = resizeTarget.y + resizeTarget.height;
87
95
  for (const step of path) {
88
96
  if (step.x < 1 || step.y < 1) {
89
97
  throw new Error("Invalid resize: can't resize to 0.");
90
98
  }
91
- if (step.x > this.step.grid.width) {
99
+ if (step.x > state.grid.width) {
92
100
  throw new Error("Invalid resize: outside grid.");
93
101
  }
94
102
  }
95
- return { itemId, path: normalizeResizePath(new Position({ x, y }), path) };
103
+ return normalizeResizePath(new Position({ x, y }), path);
96
104
  }
97
105
  }
@@ -1,31 +1,20 @@
1
1
  import { GridLayoutItem, ItemId } from "../interfaces";
2
- import { Rect } from "./utils";
3
- export interface LayoutEngineItem extends GridLayoutItem, Rect {
4
- originalX: number;
5
- originalY: number;
6
- originalWidth: number;
7
- originalHeight: number;
8
- }
9
2
  export declare class ReadonlyLayoutEngineGrid {
10
3
  protected _width: number;
11
4
  protected _height: number;
12
- protected _items: Map<string, LayoutEngineItem>;
13
- protected _layout: Set<ItemId>[][];
5
+ protected _items: GridLayoutItem[];
6
+ protected _itemsMap: Map<string, GridLayoutItem>;
14
7
  static clone(grid: ReadonlyLayoutEngineGrid): LayoutEngineGrid;
15
8
  constructor(items: readonly GridLayoutItem[], columns: number);
16
9
  get width(): number;
17
10
  get height(): number;
18
- get items(): LayoutEngineItem[];
19
- getItem(itemId: ItemId): LayoutEngineItem;
20
- getCell(x: number, y: number): LayoutEngineItem[];
21
- getCellOverlap(x: number, y: number, itemId: ItemId): null | LayoutEngineItem;
22
- protected makeNewRow(): void;
11
+ get items(): GridLayoutItem[];
12
+ getItem(itemId: ItemId): GridLayoutItem;
13
+ getOverlaps(item: GridLayoutItem): GridLayoutItem[];
23
14
  }
24
15
  export declare class LayoutEngineGrid extends ReadonlyLayoutEngineGrid {
25
- move(itemId: ItemId, x: number, y: number, onOverlap?: (overlapId: ItemId) => void): void;
26
- resize(itemId: ItemId, width: number, height: number, onOverlap?: (overlapId: ItemId) => void): void;
27
- insert(item: GridLayoutItem, onOverlap: (overlapId: ItemId) => void): void;
16
+ move(itemId: ItemId, x: number, y: number): void;
17
+ resize(itemId: ItemId, width: number, height: number): void;
18
+ insert(item: GridLayoutItem): void;
28
19
  remove(itemId: ItemId): void;
29
- private removeLayoutItem;
30
- private insertLayoutItem;
31
20
  }
@@ -1,46 +1,39 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { getItemRect } from "./utils";
3
+ import { checkItemsIntersection } from "./utils";
4
4
  export class ReadonlyLayoutEngineGrid {
5
5
  static clone(grid) {
6
6
  const clone = new LayoutEngineGrid([], 0);
7
7
  clone._width = grid._width;
8
8
  clone._height = grid._height;
9
- clone._items = new Map([...grid._items].map(([k, v]) => [k, { ...v }]));
10
- clone._layout = grid._layout.map((row) => row.map((set) => new Set([...set])));
9
+ for (const item of grid._items) {
10
+ const itemClone = { ...item };
11
+ clone._itemsMap.set(itemClone.id, itemClone);
12
+ clone._items.push(itemClone);
13
+ }
11
14
  return clone;
12
15
  }
13
16
  constructor(items, columns) {
14
- this._items = new Map();
15
- this._layout = [];
17
+ this._items = new Array();
18
+ this._itemsMap = new Map();
16
19
  this._width = columns;
17
20
  this._height = 0;
18
21
  for (const item of items) {
19
- this._items.set(item.id, {
20
- ...item,
21
- originalY: item.y,
22
- originalX: item.x,
23
- originalWidth: item.width,
24
- originalHeight: item.height,
25
- ...getItemRect(item),
26
- });
27
22
  if (item.x < 0 || item.y < 0 || item.x + item.width > this._width) {
28
23
  throw new Error("Invalid grid: items outside the boundaries.");
29
24
  }
30
25
  if (item.width < 1 || item.height < 1) {
31
26
  throw new Error("Invalid grid: items of invalid size.");
32
27
  }
33
- for (let y = item.y; y < item.y + item.height; y++) {
34
- while (this._layout.length <= y) {
35
- this.makeNewRow();
36
- }
37
- for (let x = item.x; x < item.x + item.width; x++) {
38
- this._layout[y][x].add(item.id);
39
- if (this._layout[y][x].size > 1) {
40
- throw new Error("Invalid grid: items overlap.");
41
- }
28
+ for (const gridItem of this._items) {
29
+ if (checkItemsIntersection(gridItem, item)) {
30
+ throw new Error("Invalid grid: items overlap.");
42
31
  }
43
32
  }
33
+ const itemClone = { ...item };
34
+ this._itemsMap.set(itemClone.id, itemClone);
35
+ this._items.push(itemClone);
36
+ this._height = Math.max(this.height, itemClone.y + itemClone.height);
44
37
  }
45
38
  }
46
39
  get width() {
@@ -50,101 +43,46 @@ export class ReadonlyLayoutEngineGrid {
50
43
  return this._height;
51
44
  }
52
45
  get items() {
53
- return [...this._items.values()];
46
+ return this._items;
54
47
  }
55
48
  getItem(itemId) {
56
- const item = this._items.get(itemId);
49
+ const item = this._itemsMap.get(itemId);
57
50
  if (!item) {
58
51
  throw new Error(`Item with id "${itemId}" not found in the grid.`);
59
52
  }
60
53
  return item;
61
54
  }
62
- getCell(x, y) {
63
- if (!this._layout[y] || !this._layout[y][x]) {
64
- return [];
65
- }
66
- return [...this._layout[y][x]].map((itemId) => this.getItem(itemId));
67
- }
68
- getCellOverlap(x, y, itemId) {
69
- for (const item of this.getCell(x, y)) {
70
- if (item.id !== itemId) {
71
- return item;
72
- }
73
- }
74
- return null;
75
- }
76
- makeNewRow() {
77
- this._layout.push([...Array(this._width)].map(() => new Set()));
78
- this._height = this._layout.length;
55
+ getOverlaps(item) {
56
+ return this._items.filter((gridItem) => checkItemsIntersection(gridItem, item));
79
57
  }
80
58
  }
81
59
  export class LayoutEngineGrid extends ReadonlyLayoutEngineGrid {
82
- move(itemId, x, y, onOverlap) {
83
- const moveTarget = this.getItem(itemId);
84
- this.removeLayoutItem(moveTarget);
85
- moveTarget.x = x;
86
- moveTarget.y = y;
87
- Object.assign(moveTarget, getItemRect(moveTarget));
88
- this.insertLayoutItem(moveTarget, onOverlap);
60
+ move(itemId, x, y) {
61
+ const item = this.getItem(itemId);
62
+ item.x = x;
63
+ item.y = y;
64
+ this._height = Math.max(this.height, item.y + item.height);
89
65
  }
90
- resize(itemId, width, height, onOverlap) {
91
- const resizeTarget = this.getItem(itemId);
92
- this.removeLayoutItem(resizeTarget);
93
- resizeTarget.width = width;
94
- resizeTarget.height = height;
95
- Object.assign(resizeTarget, getItemRect(resizeTarget));
96
- this.insertLayoutItem(resizeTarget, onOverlap);
66
+ resize(itemId, width, height) {
67
+ const item = this.getItem(itemId);
68
+ item.width = width;
69
+ item.height = height;
70
+ this._height = Math.max(this.height, item.y + item.height);
97
71
  }
98
- insert(item, onOverlap) {
99
- this._items.set(item.id, {
100
- ...item,
101
- originalY: item.y,
102
- originalX: item.x,
103
- originalWidth: item.width,
104
- originalHeight: item.height,
105
- ...getItemRect(item),
106
- });
72
+ insert(item) {
107
73
  if (item.x < 0 || item.y < 0 || item.x + item.width > this._width) {
108
74
  throw new Error("Inserting item is outside the boundaries.");
109
75
  }
110
76
  if (item.width < 1 || item.height < 1) {
111
77
  throw new Error("Inserting item has invalid size.");
112
78
  }
113
- for (let y = item.y; y < item.y + item.height; y++) {
114
- while (this._layout.length <= y) {
115
- this.makeNewRow();
116
- }
117
- for (let x = item.x; x < item.x + item.width; x++) {
118
- for (const overlapId of this._layout[y][x]) {
119
- onOverlap(overlapId);
120
- }
121
- this._layout[y][x].add(item.id);
122
- }
123
- }
79
+ const itemClone = { ...item };
80
+ this._itemsMap.set(itemClone.id, itemClone);
81
+ this._items.push(itemClone);
82
+ this._height = Math.max(this.height, item.y + item.height);
124
83
  }
125
84
  remove(itemId) {
126
- const removeTarget = this.getItem(itemId);
127
- this._items.delete(itemId);
128
- this.removeLayoutItem(removeTarget);
129
- }
130
- removeLayoutItem(item) {
131
- for (let y = item.y; y < item.y + item.height; y++) {
132
- for (let x = item.x; x < item.x + item.width; x++) {
133
- this._layout[y][x].delete(item.id);
134
- }
135
- }
136
- }
137
- insertLayoutItem(item, onOverlap) {
138
- for (let y = item.y; y < item.y + item.height; y++) {
139
- for (let x = item.x; x < item.x + item.width; x++) {
140
- while (!this._layout[y]) {
141
- this.makeNewRow();
142
- }
143
- for (const overlapId of this._layout[y][x]) {
144
- onOverlap === null || onOverlap === void 0 ? void 0 : onOverlap(overlapId);
145
- }
146
- this._layout[y][x].add(item.id);
147
- }
148
- }
85
+ this._itemsMap.delete(itemId);
86
+ this._items = this._items.filter((item) => item.id !== itemId);
149
87
  }
150
88
  }
@@ -1,4 +1,4 @@
1
- import { GridLayout, ItemId } from "../interfaces";
1
+ import { Direction, GridLayout, ItemId } from "../interfaces";
2
2
  import { Position } from "../utils/position";
3
3
  export interface MoveCommand {
4
4
  itemId: ItemId;
@@ -20,7 +20,11 @@ export interface CommittedMove {
20
20
  y: number;
21
21
  width: number;
22
22
  height: number;
23
- type: "MOVE" | "VACANT" | "PRIORITY" | "ESCAPE" | "FLOAT" | "RESIZE" | "INSERT" | "REMOVE";
23
+ type: "MOVE" | "RESIZE" | "INSERT" | "REMOVE" | "OVERLAP" | "FLOAT";
24
+ direction: Direction;
25
+ distanceX: number;
26
+ distanceY: number;
27
+ score: number;
24
28
  }
25
29
  export interface LayoutShift {
26
30
  current: GridLayout;
@@ -1,12 +1,17 @@
1
- import { GridLayoutItem } from "../interfaces";
1
+ import { Direction, GridLayoutItem } from "../interfaces";
2
2
  import { Position } from "../utils/position";
3
+ import { CommittedMove } from "./interfaces";
3
4
  export interface Rect {
4
5
  left: number;
5
6
  right: number;
6
7
  top: number;
7
8
  bottom: number;
8
9
  }
9
- export declare function sortGridItems(items: readonly GridLayoutItem[]): readonly GridLayoutItem[];
10
- export declare function getItemRect(item: GridLayoutItem): Rect;
10
+ export declare function sortGridItems(items: GridLayoutItem[]): readonly GridLayoutItem[];
11
11
  export declare function normalizeMovePath(origin: Position, path: readonly Position[]): readonly Position[];
12
12
  export declare function normalizeResizePath(origin: Position, path: readonly Position[]): readonly Position[];
13
+ export declare function createMove(type: CommittedMove["type"], item: GridLayoutItem, next: Position, score?: number): CommittedMove;
14
+ export declare function getMoveOriginalRect(move: CommittedMove): Rect;
15
+ export declare function getMoveRect(move: CommittedMove): Rect;
16
+ export declare function checkItemsIntersection(i1: GridLayoutItem, i2: GridLayoutItem): boolean;
17
+ export declare function checkOppositeDirections(d1: Direction, d2: Direction): boolean;
@@ -2,15 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { Position } from "../utils/position";
4
4
  export function sortGridItems(items) {
5
- return [...items].sort((a, b) => (b.y - a.y === 0 ? b.x - a.x : b.y - a.y));
6
- }
7
- export function getItemRect(item) {
8
- return {
9
- left: item.x,
10
- right: item.x + item.width - 1,
11
- top: item.y,
12
- bottom: item.y + item.height - 1,
13
- };
5
+ return items.sort((a, b) => (b.y - a.y === 0 ? b.x - a.x : b.y - a.y));
14
6
  }
15
7
  export function normalizeMovePath(origin, path) {
16
8
  path = normalizePathOrigin(origin, path);
@@ -45,6 +37,53 @@ export function normalizeResizePath(origin, path) {
45
37
  normalizedPath.reverse();
46
38
  return normalizePathSteps(origin, normalizedPath);
47
39
  }
40
+ export function createMove(type, item, next, score = 0) {
41
+ const distanceX = type === "RESIZE" ? next.x - item.width : next.x - item.x;
42
+ const distanceY = type === "RESIZE" ? next.y - item.height : next.y - item.y;
43
+ return {
44
+ type,
45
+ itemId: item.id,
46
+ x: type !== "RESIZE" ? next.x : item.x,
47
+ y: type !== "RESIZE" ? next.y : item.y,
48
+ width: type === "RESIZE" ? next.x : item.width,
49
+ height: type === "RESIZE" ? next.y : item.height,
50
+ direction: distanceX > 0 ? "right" : distanceX < 0 ? "left" : distanceY < 0 ? "up" : "down",
51
+ distanceX,
52
+ distanceY,
53
+ score,
54
+ };
55
+ }
56
+ export function getMoveOriginalRect(move) {
57
+ return {
58
+ left: move.x - move.distanceX,
59
+ right: move.x - move.distanceX + move.width - 1,
60
+ top: move.y - move.distanceY,
61
+ bottom: move.y - move.distanceY + move.height - 1,
62
+ };
63
+ }
64
+ export function getMoveRect(move) {
65
+ return {
66
+ left: move.x,
67
+ right: move.x + move.width - 1,
68
+ top: move.y,
69
+ bottom: move.y + move.height - 1,
70
+ };
71
+ }
72
+ export function checkItemsIntersection(i1, i2) {
73
+ if (i1.id === i2.id) {
74
+ return false;
75
+ }
76
+ return (i1.x <= i2.x + i2.width - 1 &&
77
+ i2.x <= i1.x + i1.width - 1 &&
78
+ i1.y <= i2.y + i2.height - 1 &&
79
+ i2.y <= i1.y + i1.height - 1);
80
+ }
81
+ export function checkOppositeDirections(d1, d2) {
82
+ return ((d1 === "down" && d2 === "up") ||
83
+ (d1 === "up" && d2 === "down") ||
84
+ (d1 === "left" && d2 === "right") ||
85
+ (d1 === "right" && d2 === "left"));
86
+ }
48
87
  // Removes path prefixes that return to the original location.
49
88
  function normalizePathOrigin(origin, path) {
50
89
  let lastOriginIndex = -1;
@@ -1,3 +1,3 @@
1
1
  {
2
- "commit": "5dff29478d324c1d9508bb43b94dcef2e723a177"
2
+ "commit": "4a7c9c80e8d3f01df0e46772e037635bd3aee13c"
3
3
  }
@@ -18,7 +18,7 @@ export function InternalItemsPalette({ items, renderItem, i18nStrings, __interna
18
18
  itemContainerRef.current[itemId].focusDragHandle();
19
19
  }
20
20
  useDragSubscription("start", ({ draggableItem: { id } }) => {
21
- setDropState({ id, isExpanded: false });
21
+ setDropState({ id });
22
22
  // Announce only if the target item belongs to the palette.
23
23
  if (items.some((it) => it.id === id)) {
24
24
  setAnnouncement(i18nStrings.liveAnnouncementDndStarted);
@@ -27,8 +27,8 @@ export function InternalItemsPalette({ items, renderItem, i18nStrings, __interna
27
27
  setAnnouncement("");
28
28
  }
29
29
  });
30
- useDragSubscription("update", ({ draggableItem: { id }, dropTarget }) => {
31
- setDropState({ id, isExpanded: !!dropTarget });
30
+ useDragSubscription("update", ({ draggableItem: { id } }) => {
31
+ setDropState({ id });
32
32
  });
33
33
  useDragSubscription("submit", () => {
34
34
  setDropState(undefined);
@@ -68,7 +68,5 @@ export function InternalItemsPalette({ items, renderItem, i18nStrings, __interna
68
68
  }
69
69
  const { width, height } = dropContext.scale(item);
70
70
  return { width, minWidth: width, maxWidth: width, height, minHeight: height, maxHeight: height };
71
- }, children: () => renderItem(item, {
72
- showPreview: (dropState === null || dropState === void 0 ? void 0 : dropState.id) === item.id && dropState.isExpanded,
73
- }) }, item.id))) }) }), _jsx(LiveRegion, { children: announcement })] }));
71
+ }, children: (hasDropTarget) => renderItem(item, { showPreview: hasDropTarget }) }, item.id))) }) }), _jsx(LiveRegion, { children: announcement })] }));
74
72
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudscape-design/board-components",
3
- "version": "3.0.30",
3
+ "version": "3.0.32",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/cloudscape-design/board-components.git"
@@ -1,8 +0,0 @@
1
- export declare class StackSet<T> implements Iterable<T> {
2
- private list;
3
- private set;
4
- constructor(input?: Iterable<T>);
5
- push(value: T): void;
6
- pop(): null | T;
7
- [Symbol.iterator](): Iterator<T>;
8
- }
@@ -1,23 +0,0 @@
1
- // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- // SPDX-License-Identifier: Apache-2.0
3
- export class StackSet {
4
- constructor(input = []) {
5
- this.list = [...input];
6
- this.set = new Set(this.list);
7
- }
8
- push(value) {
9
- if (!this.set.has(value)) {
10
- this.list.push(value);
11
- this.set.add(value);
12
- }
13
- }
14
- pop() {
15
- var _a;
16
- const value = (_a = this.list.pop()) !== null && _a !== void 0 ? _a : null;
17
- value && this.set.delete(value);
18
- return value;
19
- }
20
- [Symbol.iterator]() {
21
- return this.list[Symbol.iterator]();
22
- }
23
- }