@cloudscape-design/board-components 3.0.26 → 3.0.28

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.
package/board/internal.js CHANGED
@@ -7,6 +7,7 @@ import { getDataAttributes } from "../internal/base-component/get-data-attribute
7
7
  import { useContainerColumns } from "../internal/breakpoints";
8
8
  import { TRANSITION_DURATION_MS } from "../internal/constants";
9
9
  import { useDragSubscription } from "../internal/dnd-controller/controller";
10
+ import { useGlobalDragStateStyles } from "../internal/global-drag-state-styles";
10
11
  import Grid from "../internal/grid";
11
12
  import { ItemContainer } from "../internal/item-container";
12
13
  import { LayoutEngine } from "../internal/layout-engine/engine";
@@ -28,6 +29,7 @@ export function InternalBoard({ items, renderItem, onItemsChange, empty, i18nStr
28
29
  const [currentColumns, containerQueryRef] = useContainerColumns();
29
30
  const containerRef = useMergeRefs(containerAccessRef, containerQueryRef);
30
31
  const itemContainerRef = useRef({});
32
+ useGlobalDragStateStyles();
31
33
  const autoScrollHandlers = useAutoScroll();
32
34
  const [transitionState, dispatch] = useTransition();
33
35
  const transition = transitionState.transition;
@@ -97,7 +99,6 @@ export function InternalBoard({ items, renderItem, onItemsChange, empty, i18nStr
97
99
  collisionIds: interactionType === "pointer" && isElementOverBoard(collisionRect) ? collisionIds : [],
98
100
  });
99
101
  autoScrollHandlers.addPointerEventHandlers();
100
- document.body.classList.add(styles[`current-operation-${operation}`]);
101
102
  });
102
103
  useDragSubscription("update", ({ interactionType, collisionIds, positionOffset, collisionRect }) => {
103
104
  dispatch({
@@ -110,7 +111,6 @@ export function InternalBoard({ items, renderItem, onItemsChange, empty, i18nStr
110
111
  useDragSubscription("submit", () => {
111
112
  dispatch({ type: "submit" });
112
113
  autoScrollHandlers.removePointerEventHandlers();
113
- document.body.classList.remove(styles["current-operation-reorder"], styles["current-operation-resize"]);
114
114
  if (!transition) {
115
115
  throw new Error("Invariant violation: no transition.");
116
116
  }
@@ -130,7 +130,6 @@ export function InternalBoard({ items, renderItem, onItemsChange, empty, i18nStr
130
130
  });
131
131
  useDragSubscription("discard", () => {
132
132
  dispatch({ type: "discard" });
133
- document.body.classList.remove(styles["current-operation-reorder"], styles["current-operation-resize"]);
134
133
  autoScrollHandlers.removePointerEventHandlers();
135
134
  });
136
135
  useDragSubscription("acquire", ({ droppableId, draggableItem, acquiredItemElement }) => {
@@ -1,12 +1,10 @@
1
1
 
2
2
  import './styles.scoped.css';
3
3
  export default {
4
- "placeholder": "awsui_placeholder_1h7dk_1vsa2_1",
5
- "placeholder--active": "awsui_placeholder--active_1h7dk_1vsa2_5",
6
- "placeholder--hover": "awsui_placeholder--hover_1h7dk_1vsa2_8",
7
- "root": "awsui_root_1h7dk_1vsa2_12",
8
- "empty": "awsui_empty_1h7dk_1vsa2_16",
9
- "current-operation-reorder": "awsui_current-operation-reorder_1h7dk_1vsa2_25",
10
- "current-operation-resize": "awsui_current-operation-resize_1h7dk_1vsa2_29"
4
+ "placeholder": "awsui_placeholder_1h7dk_1yaxu_1",
5
+ "placeholder--active": "awsui_placeholder--active_1h7dk_1yaxu_5",
6
+ "placeholder--hover": "awsui_placeholder--hover_1h7dk_1yaxu_8",
7
+ "root": "awsui_root_1h7dk_1yaxu_12",
8
+ "empty": "awsui_empty_1h7dk_1yaxu_16"
11
9
  };
12
10
 
@@ -1,31 +1,23 @@
1
- .awsui_placeholder_1h7dk_1vsa2_1:not(#\9) {
1
+ .awsui_placeholder_1h7dk_1yaxu_1:not(#\9) {
2
2
  border-radius: var(--border-radius-container-pmtq2d, 16px);
3
3
  height: 100%;
4
4
  }
5
- .awsui_placeholder--active_1h7dk_1vsa2_5:not(#\9) {
5
+ .awsui_placeholder--active_1h7dk_1yaxu_5:not(#\9) {
6
6
  background-color: var(--color-board-placeholder-active-kxfgmn, #e9ebed);
7
7
  }
8
- .awsui_placeholder--hover_1h7dk_1vsa2_8:not(#\9) {
8
+ .awsui_placeholder--hover_1h7dk_1yaxu_8:not(#\9) {
9
9
  background-color: var(--color-board-placeholder-hover-8tcom5, #d3e7f9);
10
10
  }
11
11
 
12
- .awsui_root_1h7dk_1vsa2_12:not(#\9) {
12
+ .awsui_root_1h7dk_1yaxu_12:not(#\9) {
13
13
  /* used in test-utils */
14
14
  }
15
15
 
16
- .awsui_empty_1h7dk_1vsa2_16:not(#\9) {
16
+ .awsui_empty_1h7dk_1yaxu_16:not(#\9) {
17
17
  box-sizing: border-box;
18
18
  width: 100%;
19
19
  padding: var(--space-scaled-m-gxhdpl, 16px) var(--space-scaled-l-2rs0gk, 20px) var(--space-scaled-l-2rs0gk, 20px);
20
20
  color: var(--color-text-empty-v5xueo, #5f6b7a);
21
21
  display: flex;
22
22
  justify-content: center;
23
- }
24
-
25
- .awsui_current-operation-reorder_1h7dk_1vsa2_25:not(#\9) {
26
- cursor: grabbing;
27
- }
28
-
29
- .awsui_current-operation-resize_1h7dk_1vsa2_29:not(#\9) {
30
- cursor: nwse-resize;
31
23
  }
@@ -2,12 +2,10 @@
2
2
  // es-module interop with Babel and Typescript
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  module.exports.default = {
5
- "placeholder": "awsui_placeholder_1h7dk_1vsa2_1",
6
- "placeholder--active": "awsui_placeholder--active_1h7dk_1vsa2_5",
7
- "placeholder--hover": "awsui_placeholder--hover_1h7dk_1vsa2_8",
8
- "root": "awsui_root_1h7dk_1vsa2_12",
9
- "empty": "awsui_empty_1h7dk_1vsa2_16",
10
- "current-operation-reorder": "awsui_current-operation-reorder_1h7dk_1vsa2_25",
11
- "current-operation-resize": "awsui_current-operation-resize_1h7dk_1vsa2_29"
5
+ "placeholder": "awsui_placeholder_1h7dk_1yaxu_1",
6
+ "placeholder--active": "awsui_placeholder--active_1h7dk_1yaxu_5",
7
+ "placeholder--hover": "awsui_placeholder--hover_1h7dk_1yaxu_8",
8
+ "root": "awsui_root_1h7dk_1yaxu_12",
9
+ "empty": "awsui_empty_1h7dk_1yaxu_16"
12
10
  };
13
11
 
@@ -1,4 +1,4 @@
1
1
  export var PACKAGE_SOURCE = "board-components";
2
- export var PACKAGE_VERSION = "3.0.0 (a2fe5f8e)";
2
+ export var PACKAGE_VERSION = "3.0.0 (49652ff5)";
3
3
  export var THEME = "open-source-visual-refresh";
4
4
  export var ALWAYS_VISUAL_REFRESH = true;
@@ -0,0 +1,6 @@
1
+ {
2
+ "PACKAGE_SOURCE": "board-components",
3
+ "PACKAGE_VERSION": "3.0.0 (49652ff5)",
4
+ "THEME": "open-source-visual-refresh",
5
+ "ALWAYS_VISUAL_REFRESH": true
6
+ }
@@ -0,0 +1 @@
1
+ export declare function useGlobalDragStateStyles(): void;
@@ -0,0 +1,32 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { useDragSubscription } from "../dnd-controller/controller";
4
+ import styles from "./styles.css.js";
5
+ function assertNever(value) {
6
+ throw new Error("Unexpected value: " + value);
7
+ }
8
+ function setup({ operation, interactionType }) {
9
+ switch (operation) {
10
+ case "insert":
11
+ case "reorder":
12
+ document.body.classList.add(styles["show-grab-cursor"]);
13
+ break;
14
+ case "resize":
15
+ document.body.classList.add(styles["show-resize-cursor"]);
16
+ break;
17
+ default:
18
+ // there will be a type error if not all operation types are handled
19
+ assertNever(operation);
20
+ }
21
+ if (interactionType === "pointer") {
22
+ document.body.classList.add(styles["disable-selection"]);
23
+ }
24
+ }
25
+ function teardown() {
26
+ document.body.classList.remove(styles["show-grab-cursor"], styles["show-resize-cursor"], styles["disable-selection"]);
27
+ }
28
+ export function useGlobalDragStateStyles() {
29
+ useDragSubscription("start", setup);
30
+ useDragSubscription("discard", teardown);
31
+ useDragSubscription("submit", teardown);
32
+ }
@@ -0,0 +1,8 @@
1
+
2
+ import './styles.scoped.css';
3
+ export default {
4
+ "show-grab-cursor": "awsui_show-grab-cursor_1fgk7_1nqmi_1",
5
+ "show-resize-cursor": "awsui_show-resize-cursor_1fgk7_1nqmi_5",
6
+ "disable-selection": "awsui_disable-selection_1fgk7_1nqmi_9"
7
+ };
8
+
@@ -0,0 +1,12 @@
1
+ .awsui_show-grab-cursor_1fgk7_1nqmi_1 *:not(#\9) {
2
+ cursor: grabbing;
3
+ }
4
+
5
+ .awsui_show-resize-cursor_1fgk7_1nqmi_5 *:not(#\9) {
6
+ cursor: nwse-resize;
7
+ }
8
+
9
+ .awsui_disable-selection_1fgk7_1nqmi_9 *:not(#\9) {
10
+ -webkit-user-select: none;
11
+ user-select: none;
12
+ }
@@ -0,0 +1,9 @@
1
+
2
+ // es-module interop with Babel and Typescript
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ module.exports.default = {
5
+ "show-grab-cursor": "awsui_show-grab-cursor_1fgk7_1nqmi_1",
6
+ "show-resize-cursor": "awsui_show-resize-cursor_1fgk7_1nqmi_5",
7
+ "disable-selection": "awsui_disable-selection_1fgk7_1nqmi_9"
8
+ };
9
+
@@ -2,13 +2,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
  import { useContainerQuery } from "@cloudscape-design/component-toolkit";
5
+ import { useDensityMode } from "@cloudscape-design/component-toolkit/internal";
5
6
  import clsx from "clsx";
6
7
  import { Children, useRef } from "react";
7
8
  import { useMergeRefs } from "../utils/use-merge-refs";
8
9
  import { zipTwoArrays } from "../utils/zip-arrays";
9
10
  import GridItem from "./item";
10
11
  import styles from "./styles.css.js";
11
- import { useDensityMode } from "./use-density-mode";
12
12
  /* Matches grid gap in CSS. */
13
13
  const GRID_GAP = {
14
14
  comfortable: 20,
@@ -4,6 +4,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
4
4
  import { CSS as CSSUtil } from "@dnd-kit/utilities";
5
5
  import clsx from "clsx";
6
6
  import { createContext, forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState, } from "react";
7
+ import { createPortal } from "react-dom";
7
8
  import { useDragSubscription, useDraggable, } from "../dnd-controller/controller";
8
9
  import { Coordinates } from "../utils/coordinates";
9
10
  import { getNormalizedElementRect } from "../utils/screen";
@@ -265,11 +266,13 @@ function ItemContainerComponent({ item, placed, acquired, inTransition, transfor
265
266
  focusDragHandle: () => { var _a; return (_a = dragHandleRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
266
267
  }));
267
268
  const isActive = (!!transition && !transition.isBorrowed) || !!acquired;
269
+ const shouldUsePortal = ((transition === null || transition === void 0 ? void 0 : transition.operation) === "insert" || (transition === null || transition === void 0 ? void 0 : transition.operation) === "reorder") &&
270
+ (transition === null || transition === void 0 ? void 0 : transition.interactionType) === "pointer";
268
271
  const childrenRef = useRef(null);
269
272
  if (!inTransition || isActive) {
270
273
  childrenRef.current = children();
271
274
  }
272
- return (_jsx("div", { ref: itemRef, className: clsx(styles.root, ...itemTransitionClassNames), style: itemTransitionStyle, "data-item-id": item.id, onBlur: onBlur, children: _jsx(ItemContext.Provider, { value: {
275
+ const content = (_jsx("div", { ref: itemRef, className: clsx(styles.root, ...itemTransitionClassNames), style: itemTransitionStyle, "data-item-id": item.id, onBlur: onBlur, children: _jsx(ItemContext.Provider, { value: {
273
276
  isActive,
274
277
  dragHandle: {
275
278
  ref: dragHandleRef,
@@ -285,4 +288,5 @@ function ItemContainerComponent({ item, placed, acquired, inTransition, transfor
285
288
  }
286
289
  : null,
287
290
  }, children: childrenRef.current }) }));
291
+ return shouldUsePortal ? _jsx("div", { children: createPortal(content, document.body) }) : content;
288
292
  }
@@ -1,12 +1,12 @@
1
1
 
2
2
  import './styles.scoped.css';
3
3
  export default {
4
- "root": "awsui_root_lljvd_gj9xm_1",
5
- "inTransition": "awsui_inTransition_lljvd_gj9xm_7",
6
- "transformed": "awsui_transformed_lljvd_gj9xm_12",
7
- "removed": "awsui_removed_lljvd_gj9xm_17",
8
- "dragged": "awsui_dragged_lljvd_gj9xm_21",
9
- "resized": "awsui_resized_lljvd_gj9xm_26",
10
- "borrowed": "awsui_borrowed_lljvd_gj9xm_31"
4
+ "root": "awsui_root_lljvd_1nttw_1",
5
+ "inTransition": "awsui_inTransition_lljvd_1nttw_7",
6
+ "transformed": "awsui_transformed_lljvd_1nttw_12",
7
+ "removed": "awsui_removed_lljvd_1nttw_17",
8
+ "dragged": "awsui_dragged_lljvd_1nttw_21",
9
+ "resized": "awsui_resized_lljvd_1nttw_26",
10
+ "borrowed": "awsui_borrowed_lljvd_1nttw_31"
11
11
  };
12
12
 
@@ -1,33 +1,33 @@
1
- .awsui_root_lljvd_gj9xm_1:not(#\9) {
1
+ .awsui_root_lljvd_1nttw_1:not(#\9) {
2
2
  touch-action: none;
3
3
  position: relative;
4
4
  height: 100%;
5
5
  }
6
6
 
7
- .awsui_inTransition_lljvd_gj9xm_7:not(#\9) {
7
+ .awsui_inTransition_lljvd_1nttw_7:not(#\9) {
8
8
  transition: transform 200ms;
9
9
  transition-timing-function: ease;
10
10
  }
11
11
 
12
- .awsui_transformed_lljvd_gj9xm_12:not(#\9) {
12
+ .awsui_transformed_lljvd_1nttw_12:not(#\9) {
13
13
  position: absolute;
14
14
  z-index: 1;
15
15
  }
16
16
 
17
- .awsui_removed_lljvd_gj9xm_17:not(#\9) {
17
+ .awsui_removed_lljvd_1nttw_17:not(#\9) {
18
18
  display: none;
19
19
  }
20
20
 
21
- .awsui_dragged_lljvd_gj9xm_21:not(#\9) {
22
- z-index: 5000;
21
+ .awsui_dragged_lljvd_1nttw_21:not(#\9) {
22
+ z-index: 2000;
23
23
  position: fixed;
24
24
  }
25
25
 
26
- .awsui_resized_lljvd_gj9xm_26:not(#\9) {
27
- z-index: 5000;
26
+ .awsui_resized_lljvd_1nttw_26:not(#\9) {
27
+ z-index: 2000;
28
28
  position: absolute;
29
29
  }
30
30
 
31
- .awsui_borrowed_lljvd_gj9xm_31:not(#\9) {
31
+ .awsui_borrowed_lljvd_1nttw_31:not(#\9) {
32
32
  display: none;
33
33
  }
@@ -2,12 +2,12 @@
2
2
  // es-module interop with Babel and Typescript
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  module.exports.default = {
5
- "root": "awsui_root_lljvd_gj9xm_1",
6
- "inTransition": "awsui_inTransition_lljvd_gj9xm_7",
7
- "transformed": "awsui_transformed_lljvd_gj9xm_12",
8
- "removed": "awsui_removed_lljvd_gj9xm_17",
9
- "dragged": "awsui_dragged_lljvd_gj9xm_21",
10
- "resized": "awsui_resized_lljvd_gj9xm_26",
11
- "borrowed": "awsui_borrowed_lljvd_gj9xm_31"
5
+ "root": "awsui_root_lljvd_1nttw_1",
6
+ "inTransition": "awsui_inTransition_lljvd_1nttw_7",
7
+ "transformed": "awsui_transformed_lljvd_1nttw_12",
8
+ "removed": "awsui_removed_lljvd_1nttw_17",
9
+ "dragged": "awsui_dragged_lljvd_1nttw_21",
10
+ "resized": "awsui_resized_lljvd_1nttw_26",
11
+ "borrowed": "awsui_borrowed_lljvd_1nttw_31"
12
12
  };
13
13
 
@@ -1,3 +1,3 @@
1
1
  {
2
- "commit": "a2fe5f8eb68cda2710cf0e62974bbea6e998da30"
2
+ "commit": "49652ff586f1bf37480d83de685ced23a5bbf1fc"
3
3
  }
@@ -51,10 +51,11 @@ export function useAutoScroll() {
51
51
  scrollIntoViewTimerRef.current && clearTimeout(scrollIntoViewTimerRef.current);
52
52
  const activeElementBeforeDelay = document.activeElement;
53
53
  scrollIntoViewTimerRef.current = setTimeout(() => {
54
+ var _a, _b;
54
55
  if (document.activeElement &&
55
56
  document.activeElement === activeElementBeforeDelay &&
56
57
  getLastInteraction() === "keyboard") {
57
- document.activeElement.scrollIntoView({ behavior: "smooth", block: "nearest" });
58
+ (_b = (_a = document.activeElement).scrollIntoView) === null || _b === void 0 ? void 0 : _b.call(_a, { behavior: "smooth", block: "nearest" });
58
59
  }
59
60
  }, delay);
60
61
  }, [getLastInteraction]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudscape-design/board-components",
3
- "version": "3.0.26",
3
+ "version": "3.0.28",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/cloudscape-design/board-components.git"
@@ -7,7 +7,7 @@ const styles_selectors_js_1 = require("../../../board/styles.selectors.js");
7
7
  const board_item_1 = require("../board-item");
8
8
  class BoardWrapper extends dom_1.ComponentWrapper {
9
9
  findItemById(itemId) {
10
- return this.findComponent(`[data-item-id="${itemId}"]`, board_item_1.default);
10
+ return (0, dom_1.createWrapper)().findComponent(`[data-item-id="${itemId}"]`, board_item_1.default);
11
11
  }
12
12
  }
13
13
  exports.default = BoardWrapper;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/test-utils/dom/board/index.ts"],"names":[],"mappings":";;AAAA,qEAAqE;AACrE,sCAAsC;AACtC,gEAA0E;AAC1E,4EAA6D;AAC7D,8CAA6C;AAE7C,MAAqB,YAAa,SAAQ,sBAAgB;IAGxD,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,aAAa,CAAC,kBAAkB,MAAM,IAAI,EAAE,oBAAgB,CAAC,CAAC;IAC5E,CAAC;;AALH,+BAMC;AALQ,yBAAY,GAAW,6BAAW,CAAC,IAAI,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/test-utils/dom/board/index.ts"],"names":[],"mappings":";;AAAA,qEAAqE;AACrE,sCAAsC;AACtC,gEAAyF;AACzF,4EAA6D;AAC7D,8CAA6C;AAE7C,MAAqB,YAAa,SAAQ,sBAAgB;IAGxD,YAAY,CAAC,MAAc;QACzB,OAAO,IAAA,mBAAa,GAAE,CAAC,aAAa,CAAC,kBAAkB,MAAM,IAAI,EAAE,oBAAgB,CAAC,CAAC;IACvF,CAAC;;AALH,+BAMC;AALQ,yBAAY,GAAW,6BAAW,CAAC,IAAI,CAAC"}
@@ -7,7 +7,7 @@ const styles_selectors_js_1 = require("../../../board/styles.selectors.js");
7
7
  const board_item_1 = require("../board-item");
8
8
  class BoardWrapper extends selectors_1.ComponentWrapper {
9
9
  findItemById(itemId) {
10
- return this.findComponent(`[data-item-id="${itemId}"]`, board_item_1.default);
10
+ return (0, selectors_1.createWrapper)().findComponent(`[data-item-id="${itemId}"]`, board_item_1.default);
11
11
  }
12
12
  }
13
13
  exports.default = BoardWrapper;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/test-utils/selectors/board/index.ts"],"names":[],"mappings":";;AAAA,qEAAqE;AACrE,sCAAsC;AACtC,4EAAgF;AAChF,4EAA6D;AAC7D,8CAA6C;AAC7C,MAAqB,YAAa,SAAQ,4BAAgB;IAExD,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,aAAa,CAAC,kBAAkB,MAAM,IAAI,EAAE,oBAAgB,CAAC,CAAC;IAC5E,CAAC;;AAJH,+BAKC;AAJQ,yBAAY,GAAW,6BAAW,CAAC,IAAI,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/test-utils/selectors/board/index.ts"],"names":[],"mappings":";;AAAA,qEAAqE;AACrE,sCAAsC;AACtC,4EAA+F;AAC/F,4EAA6D;AAC7D,8CAA6C;AAC7C,MAAqB,YAAa,SAAQ,4BAAgB;IAExD,YAAY,CAAC,MAAc;QACzB,OAAO,IAAA,yBAAa,GAAE,CAAC,aAAa,CAAC,kBAAkB,MAAM,IAAI,EAAE,oBAAgB,CAAC,CAAC;IACvF,CAAC;;AAJH,+BAKC;AAJQ,yBAAY,GAAW,6BAAW,CAAC,IAAI,CAAC"}
@@ -1,2 +0,0 @@
1
- /// <reference types="react" />
2
- export declare function useDensityMode(elementRef: React.RefObject<HTMLElement>): "comfortable" | "compact";
@@ -1,59 +0,0 @@
1
- // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- // SPDX-License-Identifier: Apache-2.0
3
- import { findUpUntil } from "@cloudscape-design/component-toolkit/dom";
4
- import { useEffect, useState } from "react";
5
- import { unstable_batchedUpdates } from "react-dom";
6
- import { useStableEventHandler } from "../utils/use-stable-event-handler";
7
- // Matches: https://github.com/cloudscape-design/components/blob/main/src/internal/hooks/use-visual-mode/index.ts
8
- export function useDensityMode(elementRef) {
9
- const [value, setValue] = useState("comfortable");
10
- useMutationObserver(elementRef, (node) => {
11
- const compactModeParent = findUpUntil(node, (node) => node.classList.contains("awsui-polaris-compact-mode") || node.classList.contains("awsui-compact-mode"));
12
- setValue(compactModeParent ? "compact" : "comfortable");
13
- });
14
- return value;
15
- }
16
- const useMutationSingleton = createSingletonHandler((handler) => {
17
- const observer = new MutationObserver(() => handler());
18
- observer.observe(document.body, { attributes: true, subtree: true });
19
- return () => observer.disconnect();
20
- });
21
- function useMutationObserver(elementRef, onChange) {
22
- const handler = useStableEventHandler(() => {
23
- if (elementRef.current) {
24
- onChange(elementRef.current);
25
- }
26
- });
27
- useMutationSingleton(handler);
28
- useEffect(() => {
29
- handler();
30
- }, [handler]);
31
- }
32
- function createSingletonHandler(factory) {
33
- const listeners = [];
34
- const callback = (value) => {
35
- unstable_batchedUpdates(() => {
36
- for (const listener of listeners) {
37
- listener(value);
38
- }
39
- });
40
- };
41
- let cleanup;
42
- return function useSingleton(listener) {
43
- useEffect(() => {
44
- if (listeners.length === 0) {
45
- cleanup = factory(callback);
46
- }
47
- listeners.push(listener);
48
- return () => {
49
- listeners.splice(listeners.indexOf(listener), 1);
50
- if (listeners.length === 0) {
51
- cleanup();
52
- cleanup = undefined;
53
- }
54
- };
55
- // register handlers only on mount
56
- // eslint-disable-next-line react-hooks/exhaustive-deps
57
- }, []);
58
- };
59
- }