@dmsi/wedgekit-react 0.0.50 → 0.0.52

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 (34) hide show
  1. package/dist/{chunk-VC3R5EUH.js → chunk-6R2HCLEL.js} +2 -2
  2. package/dist/{chunk-VKMJ63WV.js → chunk-ATOEGP3V.js} +3 -3
  3. package/dist/{chunk-Z4UCFUF7.js → chunk-B6PDZCU7.js} +7 -3
  4. package/dist/{chunk-T22EH3MG.js → chunk-FOC6LTSX.js} +1 -1
  5. package/dist/chunk-SWA5WVQO.js +49 -0
  6. package/dist/components/DataGrid.cjs +83 -85
  7. package/dist/components/DataGrid.js +5 -5
  8. package/dist/components/DataGridCell.cjs +51 -53
  9. package/dist/components/DataGridCell.js +5 -5
  10. package/dist/components/Menu.cjs +21 -27
  11. package/dist/components/Menu.js +3 -3
  12. package/dist/components/MenuOption.cjs +14 -20
  13. package/dist/components/MenuOption.js +2 -2
  14. package/dist/components/Modal.cjs +22 -28
  15. package/dist/components/Modal.js +1 -1
  16. package/dist/components/NestedMenu.cjs +40 -49
  17. package/dist/components/NestedMenu.js +4 -33
  18. package/dist/components/ProjectBar.cjs +10 -16
  19. package/dist/components/ProjectBar.js +1 -1
  20. package/dist/components/useMenuSystem.cjs +29 -31
  21. package/dist/components/useMenuSystem.js +2 -2
  22. package/dist/hooks/index.cjs +77 -0
  23. package/dist/{components/useMatchesMedia.js → hooks/index.js} +3 -1
  24. package/package.json +6 -1
  25. package/src/components/Menu.tsx +1 -1
  26. package/src/components/MenuOption.tsx +11 -10
  27. package/src/components/Modal.tsx +1 -1
  28. package/src/components/ProjectBar.tsx +1 -1
  29. package/src/components/useMenuSystem.tsx +23 -12
  30. package/src/hooks/index.ts +1 -0
  31. package/src/hooks/useMatchesMedia.ts +18 -0
  32. package/dist/chunk-SEKKGFM6.js +0 -28
  33. package/dist/components/useMatchesMedia.cjs +0 -53
  34. package/src/components/useMatchesMedia.tsx +0 -28
@@ -99,7 +99,7 @@ function Icon(_a) {
99
99
 
100
100
  // src/components/MenuOption.tsx
101
101
  var import_clsx5 = __toESM(require("clsx"), 1);
102
- var import_react2 = require("react");
102
+ var import_react3 = require("react");
103
103
 
104
104
  // src/classNames.ts
105
105
  var import_clsx2 = __toESM(require("clsx"), 1);
@@ -318,29 +318,49 @@ var Paragraph = (_a) => {
318
318
  };
319
319
  Paragraph.displayName = "Paragraph";
320
320
 
321
- // src/components/useMatchesMedia.tsx
321
+ // src/hooks/useKeydown.ts
322
322
  var import_react = require("react");
323
+ function useKeydown(keys, isActive) {
324
+ function handleKeyDown(event) {
325
+ if (!Object.keys(keys).includes(event.key) && !Object.keys(keys).join("").includes("/"))
326
+ return;
327
+ Object.entries(keys).forEach(([key, handler]) => {
328
+ if (event.key !== key && !key.includes("/")) return;
329
+ if (key.includes("/") && key.replace("Space", " ").split("/").includes(event.key)) {
330
+ event.preventDefault();
331
+ handler(event);
332
+ return;
333
+ }
334
+ if (event.key === key) {
335
+ event.preventDefault();
336
+ handler(event);
337
+ }
338
+ });
339
+ }
340
+ (0, import_react.useEffect)(() => {
341
+ if (!isActive)
342
+ return document.removeEventListener("keydown", handleKeyDown);
343
+ document.addEventListener("keydown", handleKeyDown);
344
+ return () => {
345
+ document.removeEventListener("keydown", handleKeyDown);
346
+ };
347
+ }, [keys, isActive]);
348
+ }
349
+
350
+ // src/hooks/useMatchesMedia.ts
351
+ var import_react2 = require("react");
323
352
  var useMatchesMedia = (query) => {
324
- const [matches, setMatches] = (0, import_react.useState)(
325
- () => typeof window !== "undefined" ? window.matchMedia(query).matches : false
326
- );
327
- (0, import_react.useLayoutEffect)(() => {
353
+ const [matches, setMatches] = (0, import_react2.useState)();
354
+ (0, import_react2.useLayoutEffect)(() => {
328
355
  const mediaQueryList = window.matchMedia(query);
329
- const listener = (event) => {
330
- setMatches(event.matches);
331
- };
356
+ const listener = () => setMatches(mediaQueryList.matches);
357
+ listener();
332
358
  mediaQueryList.addEventListener("change", listener);
333
- setMatches(mediaQueryList.matches);
334
- return () => {
335
- mediaQueryList.removeEventListener("change", listener);
336
- };
359
+ return () => mediaQueryList.removeEventListener("change", listener);
337
360
  }, [query]);
338
361
  return matches;
339
362
  };
340
- var useMatchesMobile = () => {
341
- const isMobile = useMatchesMedia("(width < 48rem)");
342
- return isMobile;
343
- };
363
+ var useMatchesMobile = () => useMatchesMedia("(width < 48rem)");
344
364
 
345
365
  // src/components/MenuOption.tsx
346
366
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -368,10 +388,10 @@ var MenuOption = ({
368
388
  highlightMatchingText = false,
369
389
  menuValue
370
390
  }) => {
371
- const uniqueId = (0, import_react2.useId)();
372
- const internalRef = (0, import_react2.useRef)(null);
391
+ const uniqueId = (0, import_react3.useId)();
392
+ const internalRef = (0, import_react3.useRef)(null);
373
393
  const actualRef = ref || internalRef;
374
- const menuId = (0, import_react2.useRef)(`menu-${uniqueId}`);
394
+ const menuId = (0, import_react3.useRef)(`menu-${uniqueId}`);
375
395
  const isMobile = useMatchesMobile();
376
396
  const handleMouseEnter = () => {
377
397
  if (subMenu && onSubMenuHover && !disabled) {
@@ -512,35 +532,6 @@ function highlightMatch(text, searchValue) {
512
532
  );
513
533
  }
514
534
 
515
- // src/hooks/useKeydown.ts
516
- var import_react3 = require("react");
517
- function useKeydown(keys, isActive) {
518
- function handleKeyDown(event) {
519
- if (!Object.keys(keys).includes(event.key) && !Object.keys(keys).join("").includes("/"))
520
- return;
521
- Object.entries(keys).forEach(([key, handler]) => {
522
- if (event.key !== key && !key.includes("/")) return;
523
- if (key.includes("/") && key.replace("Space", " ").split("/").includes(event.key)) {
524
- event.preventDefault();
525
- handler(event);
526
- return;
527
- }
528
- if (event.key === key) {
529
- event.preventDefault();
530
- handler(event);
531
- }
532
- });
533
- }
534
- (0, import_react3.useEffect)(() => {
535
- if (!isActive)
536
- return document.removeEventListener("keydown", handleKeyDown);
537
- document.addEventListener("keydown", handleKeyDown);
538
- return () => {
539
- document.removeEventListener("keydown", handleKeyDown);
540
- };
541
- }, [keys, isActive]);
542
- }
543
-
544
535
  // src/components/NestedMenu.tsx
545
536
  var import_jsx_runtime5 = require("react/jsx-runtime");
546
537
  function NestedMenu(props) {
@@ -1,8 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  MenuOption
4
- } from "../chunk-T22EH3MG.js";
5
- import "../chunk-SEKKGFM6.js";
4
+ } from "../chunk-FOC6LTSX.js";
5
+ import {
6
+ useKeydown
7
+ } from "../chunk-SWA5WVQO.js";
6
8
  import "../chunk-VG4EPHJA.js";
7
9
  import "../chunk-S5K22XTH.js";
8
10
  import {
@@ -15,37 +17,6 @@ import {
15
17
 
16
18
  // src/components/NestedMenu.tsx
17
19
  import { useState } from "react";
18
-
19
- // src/hooks/useKeydown.ts
20
- import { useEffect } from "react";
21
- function useKeydown(keys, isActive) {
22
- function handleKeyDown(event) {
23
- if (!Object.keys(keys).includes(event.key) && !Object.keys(keys).join("").includes("/"))
24
- return;
25
- Object.entries(keys).forEach(([key, handler]) => {
26
- if (event.key !== key && !key.includes("/")) return;
27
- if (key.includes("/") && key.replace("Space", " ").split("/").includes(event.key)) {
28
- event.preventDefault();
29
- handler(event);
30
- return;
31
- }
32
- if (event.key === key) {
33
- event.preventDefault();
34
- handler(event);
35
- }
36
- });
37
- }
38
- useEffect(() => {
39
- if (!isActive)
40
- return document.removeEventListener("keydown", handleKeyDown);
41
- document.addEventListener("keydown", handleKeyDown);
42
- return () => {
43
- document.removeEventListener("keydown", handleKeyDown);
44
- };
45
- }, [keys, isActive]);
46
- }
47
-
48
- // src/components/NestedMenu.tsx
49
20
  import { jsx, jsxs } from "react/jsx-runtime";
50
21
  function NestedMenu(props) {
51
22
  var _a;
@@ -175,29 +175,23 @@ var gapUsingContainerPadding = (0, import_clsx.default)(
175
175
  "gap-mobile-container-padding desktop:gap-desktop-container-padding compact:gap-desktop-compact-container-padding"
176
176
  );
177
177
 
178
- // src/components/useMatchesMedia.tsx
178
+ // src/hooks/useKeydown.ts
179
179
  var import_react = require("react");
180
+
181
+ // src/hooks/useMatchesMedia.ts
182
+ var import_react2 = require("react");
180
183
  var useMatchesMedia = (query) => {
181
- const [matches, setMatches] = (0, import_react.useState)(
182
- () => typeof window !== "undefined" ? window.matchMedia(query).matches : false
183
- );
184
- (0, import_react.useLayoutEffect)(() => {
184
+ const [matches, setMatches] = (0, import_react2.useState)();
185
+ (0, import_react2.useLayoutEffect)(() => {
185
186
  const mediaQueryList = window.matchMedia(query);
186
- const listener = (event) => {
187
- setMatches(event.matches);
188
- };
187
+ const listener = () => setMatches(mediaQueryList.matches);
188
+ listener();
189
189
  mediaQueryList.addEventListener("change", listener);
190
- setMatches(mediaQueryList.matches);
191
- return () => {
192
- mediaQueryList.removeEventListener("change", listener);
193
- };
190
+ return () => mediaQueryList.removeEventListener("change", listener);
194
191
  }, [query]);
195
192
  return matches;
196
193
  };
197
- var useMatchesMobile = () => {
198
- const isMobile = useMatchesMedia("(width < 48rem)");
199
- return isMobile;
200
- };
194
+ var useMatchesMobile = () => useMatchesMedia("(width < 48rem)");
201
195
 
202
196
  // src/components/ProjectBar.tsx
203
197
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useMatchesMobile
3
- } from "../chunk-SEKKGFM6.js";
3
+ } from "../chunk-SWA5WVQO.js";
4
4
  import {
5
5
  containerPaddingX,
6
6
  layoutGap,
@@ -39,43 +39,39 @@ __export(useMenuSystem_exports, {
39
39
  useSubMenuSystem: () => useSubMenuSystem
40
40
  });
41
41
  module.exports = __toCommonJS(useMenuSystem_exports);
42
- var import_react2 = require("react");
42
+ var import_react3 = require("react");
43
43
 
44
- // src/components/useMatchesMedia.tsx
44
+ // src/hooks/useKeydown.ts
45
45
  var import_react = require("react");
46
+
47
+ // src/hooks/useMatchesMedia.ts
48
+ var import_react2 = require("react");
46
49
  var useMatchesMedia = (query) => {
47
- const [matches, setMatches] = (0, import_react.useState)(
48
- () => typeof window !== "undefined" ? window.matchMedia(query).matches : false
49
- );
50
- (0, import_react.useLayoutEffect)(() => {
50
+ const [matches, setMatches] = (0, import_react2.useState)();
51
+ (0, import_react2.useLayoutEffect)(() => {
51
52
  const mediaQueryList = window.matchMedia(query);
52
- const listener = (event) => {
53
- setMatches(event.matches);
54
- };
53
+ const listener = () => setMatches(mediaQueryList.matches);
54
+ listener();
55
55
  mediaQueryList.addEventListener("change", listener);
56
- setMatches(mediaQueryList.matches);
57
- return () => {
58
- mediaQueryList.removeEventListener("change", listener);
59
- };
56
+ return () => mediaQueryList.removeEventListener("change", listener);
60
57
  }, [query]);
61
58
  return matches;
62
59
  };
63
- var useMatchesMobile = () => {
64
- const isMobile = useMatchesMedia("(width < 48rem)");
65
- return isMobile;
66
- };
60
+ var useMatchesMobile = () => useMatchesMedia("(width < 48rem)");
67
61
 
68
62
  // src/components/useMenuSystem.tsx
69
63
  function useSubMenuSystem(mobilePositionTo) {
70
- const [activeMenus, setActiveMenus] = (0, import_react2.useState)(
64
+ const [activeMenus, setActiveMenus] = (0, import_react3.useState)(
71
65
  {}
72
66
  );
73
- const [activeMenu, setActiveMenu] = (0, import_react2.useState)("");
74
- const [currentSubMenuLevel, setCurrentSubMenuLevel] = (0, import_react2.useState)(null);
75
- const menuRootRef = (0, import_react2.useRef)(null);
76
- const subMenuRefs = (0, import_react2.useRef)({});
77
- const hoverTimeoutRef = (0, import_react2.useRef)(null);
78
- const closeTimeoutRef = (0, import_react2.useRef)(null);
67
+ const [activeMenu, setActiveMenu] = (0, import_react3.useState)("");
68
+ const [currentSubMenuLevel, setCurrentSubMenuLevel] = (0, import_react3.useState)(
69
+ null
70
+ );
71
+ const menuRootRef = (0, import_react3.useRef)(null);
72
+ const subMenuRefs = (0, import_react3.useRef)({});
73
+ const hoverTimeoutRef = (0, import_react3.useRef)(null);
74
+ const closeTimeoutRef = (0, import_react3.useRef)(null);
79
75
  const isMobile = useMatchesMobile();
80
76
  const toggleMenu = (menuId, level) => {
81
77
  if (closeTimeoutRef.current) {
@@ -173,7 +169,7 @@ function useSubMenuSystem(mobilePositionTo) {
173
169
  const isMenuActive = (menuId, level) => {
174
170
  return activeMenus[level] === menuId;
175
171
  };
176
- (0, import_react2.useEffect)(() => {
172
+ (0, import_react3.useEffect)(() => {
177
173
  const handleClickOutside = (event) => {
178
174
  var _a;
179
175
  if (Object.keys(activeMenus).length === 0) return;
@@ -192,7 +188,7 @@ function useSubMenuSystem(mobilePositionTo) {
192
188
  document.removeEventListener("mousedown", handleClickOutside);
193
189
  };
194
190
  }, [activeMenus]);
195
- (0, import_react2.useEffect)(() => {
191
+ (0, import_react3.useEffect)(() => {
196
192
  return () => {
197
193
  if (hoverTimeoutRef.current) {
198
194
  clearTimeout(hoverTimeoutRef.current);
@@ -205,7 +201,9 @@ function useSubMenuSystem(mobilePositionTo) {
205
201
  const getAllFocusableMenuElements = () => {
206
202
  const elements = [];
207
203
  if (menuRootRef.current) {
208
- elements.push(...Array.from(menuRootRef.current.children));
204
+ elements.push(
205
+ ...Array.from(menuRootRef.current.children)
206
+ );
209
207
  }
210
208
  Object.values(activeMenus).forEach((menuId) => {
211
209
  const submenuEl = subMenuRefs.current[menuId];
@@ -267,13 +265,13 @@ function useSubMenuSystem(mobilePositionTo) {
267
265
  };
268
266
  }
269
267
  function useMenuPosition(elementRef, position = "bottom", options) {
270
- const [menuPosition, setMenuPosition] = (0, import_react2.useState)({
268
+ const [menuPosition, setMenuPosition] = (0, import_react3.useState)({
271
269
  top: 0,
272
270
  left: 0,
273
271
  minWidth: 0
274
272
  });
275
273
  const isMobile = useMatchesMobile();
276
- const updatePosition = (0, import_react2.useCallback)(() => {
274
+ const updatePosition = (0, import_react3.useCallback)(() => {
277
275
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
278
276
  if (!(elementRef == null ? void 0 : elementRef.current)) return;
279
277
  const triggerRect = elementRef.current.getBoundingClientRect();
@@ -309,7 +307,7 @@ function useMenuPosition(elementRef, position = "bottom", options) {
309
307
  minWidth: triggerRect.width
310
308
  });
311
309
  }, [elementRef, position, options == null ? void 0 : options.menuRef, options == null ? void 0 : options.topOffset, isMobile]);
312
- (0, import_react2.useEffect)(() => {
310
+ (0, import_react3.useEffect)(() => {
313
311
  if (!(options == null ? void 0 : options.isOpen) || !(options == null ? void 0 : options.setIsOpen)) return;
314
312
  const handleClickOutside = (event) => {
315
313
  var _a, _b, _c, _d, _e;
@@ -335,7 +333,7 @@ function useMenuPosition(elementRef, position = "bottom", options) {
335
333
  options == null ? void 0 : options.menuRef,
336
334
  options == null ? void 0 : options.additionalRefs
337
335
  ]);
338
- (0, import_react2.useEffect)(() => {
336
+ (0, import_react3.useEffect)(() => {
339
337
  updatePosition();
340
338
  const resizeObserver = new ResizeObserver(updatePosition);
341
339
  if (elementRef == null ? void 0 : elementRef.current) {
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  useMenuPosition,
4
4
  useSubMenuSystem
5
- } from "../chunk-Z4UCFUF7.js";
6
- import "../chunk-SEKKGFM6.js";
5
+ } from "../chunk-B6PDZCU7.js";
6
+ import "../chunk-SWA5WVQO.js";
7
7
  import "../chunk-ORMEWXMH.js";
8
8
  export {
9
9
  useMenuPosition,
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/hooks/index.ts
21
+ var hooks_exports = {};
22
+ __export(hooks_exports, {
23
+ useKeydown: () => useKeydown,
24
+ useMatchesMedia: () => useMatchesMedia,
25
+ useMatchesMobile: () => useMatchesMobile
26
+ });
27
+ module.exports = __toCommonJS(hooks_exports);
28
+
29
+ // src/hooks/useKeydown.ts
30
+ var import_react = require("react");
31
+ function useKeydown(keys, isActive) {
32
+ function handleKeyDown(event) {
33
+ if (!Object.keys(keys).includes(event.key) && !Object.keys(keys).join("").includes("/"))
34
+ return;
35
+ Object.entries(keys).forEach(([key, handler]) => {
36
+ if (event.key !== key && !key.includes("/")) return;
37
+ if (key.includes("/") && key.replace("Space", " ").split("/").includes(event.key)) {
38
+ event.preventDefault();
39
+ handler(event);
40
+ return;
41
+ }
42
+ if (event.key === key) {
43
+ event.preventDefault();
44
+ handler(event);
45
+ }
46
+ });
47
+ }
48
+ (0, import_react.useEffect)(() => {
49
+ if (!isActive)
50
+ return document.removeEventListener("keydown", handleKeyDown);
51
+ document.addEventListener("keydown", handleKeyDown);
52
+ return () => {
53
+ document.removeEventListener("keydown", handleKeyDown);
54
+ };
55
+ }, [keys, isActive]);
56
+ }
57
+
58
+ // src/hooks/useMatchesMedia.ts
59
+ var import_react2 = require("react");
60
+ var useMatchesMedia = (query) => {
61
+ const [matches, setMatches] = (0, import_react2.useState)();
62
+ (0, import_react2.useLayoutEffect)(() => {
63
+ const mediaQueryList = window.matchMedia(query);
64
+ const listener = () => setMatches(mediaQueryList.matches);
65
+ listener();
66
+ mediaQueryList.addEventListener("change", listener);
67
+ return () => mediaQueryList.removeEventListener("change", listener);
68
+ }, [query]);
69
+ return matches;
70
+ };
71
+ var useMatchesMobile = () => useMatchesMedia("(width < 48rem)");
72
+ // Annotate the CommonJS export names for ESM import in node:
73
+ 0 && (module.exports = {
74
+ useKeydown,
75
+ useMatchesMedia,
76
+ useMatchesMobile
77
+ });
@@ -1,9 +1,11 @@
1
1
  import {
2
+ useKeydown,
2
3
  useMatchesMedia,
3
4
  useMatchesMobile
4
- } from "../chunk-SEKKGFM6.js";
5
+ } from "../chunk-SWA5WVQO.js";
5
6
  import "../chunk-ORMEWXMH.js";
6
7
  export {
8
+ useKeydown,
7
9
  useMatchesMedia,
8
10
  useMatchesMobile
9
11
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dmsi/wedgekit-react",
3
3
  "private": false,
4
- "version": "0.0.50",
4
+ "version": "0.0.52",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "tsup",
@@ -19,6 +19,11 @@
19
19
  "import": "./dist/components/*.js",
20
20
  "require": "./dist/components/*.cjs"
21
21
  },
22
+ "./hooks": {
23
+ "types": "./src/hooks/index.ts",
24
+ "import": "./dist/hooks/index.js",
25
+ "require": "./dist/hooks/index.cjs"
26
+ },
22
27
  "./types": {
23
28
  "types": "./src/types.ts",
24
29
  "import": "./dist/types.js",
@@ -12,7 +12,7 @@ import {
12
12
  import { createPortal } from "react-dom";
13
13
  import { useMenuPosition } from "./useMenuSystem";
14
14
  import { findDocumentRoot } from "../utils";
15
- import { useMatchesMobile } from "./useMatchesMedia";
15
+ import { useMatchesMobile } from "../hooks";
16
16
 
17
17
  export type MenuPosition = "right" | "bottom" | "bottom-right";
18
18
 
@@ -8,7 +8,7 @@ import { Label, Tags } from "./Label";
8
8
  import { Paragraph } from "./Paragraph";
9
9
  import { Icon } from "./Icon";
10
10
  import { MenuPosition } from "./Menu";
11
- import { useMatchesMobile } from "./useMatchesMedia";
11
+ import { useMatchesMobile } from "../hooks";
12
12
 
13
13
  type BaseProps = PropsWithChildren<{
14
14
  id?: string;
@@ -162,14 +162,15 @@ export const MenuOption = ({
162
162
  const disabledStyles =
163
163
  disabled && clsx("bg-transparent cursor-default pointer-events-none");
164
164
 
165
- const processChildren = typeof children === 'string' && highlightMatchingText
166
- ? (
167
- highlightMatch(children, menuValue)
168
- ) : children;
165
+ const processChildren =
166
+ typeof children === "string" && highlightMatchingText
167
+ ? highlightMatch(children, menuValue)
168
+ : children;
169
169
 
170
- const renderChildren = typeof children === 'object'
171
- ? children
172
- : variant === "action" ? (
170
+ const renderChildren =
171
+ typeof children === "object" ? (
172
+ children
173
+ ) : variant === "action" ? (
173
174
  <Label padded className={textLabelStyles}>
174
175
  {processChildren}
175
176
  </Label>
@@ -177,7 +178,7 @@ export const MenuOption = ({
177
178
  <Paragraph padded className={textLabelStyles}>
178
179
  {processChildren}
179
180
  </Paragraph>
180
- )
181
+ );
181
182
 
182
183
  return (
183
184
  <>
@@ -213,7 +214,7 @@ export const MenuOption = ({
213
214
  {before && <div className="shrink-0 flex items-center">{before}</div>}
214
215
 
215
216
  {renderChildren}
216
-
217
+
217
218
  {renderAfterProp()}
218
219
  </div>
219
220
 
@@ -9,7 +9,7 @@ import { ModalScrim } from "./ModalScrim";
9
9
  import { createPortal } from "react-dom";
10
10
  import { findDocumentRoot } from "../utils";
11
11
  import { usePrevious } from "react-use";
12
- import { useMatchesMobile } from "./useMatchesMedia";
12
+ import { useMatchesMobile } from "../hooks";
13
13
  import { useMounted } from "./useMounted";
14
14
 
15
15
  type ModalProps = PropsWithChildren<{
@@ -6,7 +6,7 @@ import {
6
6
  layoutGroupGap,
7
7
  paddingYUsingLayoutGroupGap,
8
8
  } from "../classNames";
9
- import { useMatchesMobile } from "./useMatchesMedia";
9
+ import { useMatchesMobile } from "../hooks";
10
10
 
11
11
  type ProjectBarProps = {
12
12
  left: ReactNode;
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useState, useRef, useEffect, RefObject, useCallback } from "react";
4
- import { useMatchesMobile } from "./useMatchesMedia";
4
+ import { useMatchesMobile } from "../hooks";
5
5
 
6
6
  type MenuPosition = {
7
7
  top: number;
@@ -9,12 +9,16 @@ type MenuPosition = {
9
9
  minWidth: number;
10
10
  };
11
11
 
12
- export function useSubMenuSystem(mobilePositionTo: RefObject<HTMLElement | null>) {
12
+ export function useSubMenuSystem(
13
+ mobilePositionTo: RefObject<HTMLElement | null>,
14
+ ) {
13
15
  const [activeMenus, setActiveMenus] = useState<{ [level: number]: string }>(
14
16
  {},
15
17
  );
16
18
  const [activeMenu, setActiveMenu] = useState("");
17
- const [currentSubMenuLevel, setCurrentSubMenuLevel] = useState<number | null>(null);
19
+ const [currentSubMenuLevel, setCurrentSubMenuLevel] = useState<number | null>(
20
+ null,
21
+ );
18
22
  const menuRootRef = useRef<HTMLDivElement>(null);
19
23
  const subMenuRefs = useRef<{ [id: string]: HTMLElement | null }>({});
20
24
  const hoverTimeoutRef = useRef<NodeJS.Timeout | null>(null);
@@ -181,13 +185,15 @@ export function useSubMenuSystem(mobilePositionTo: RefObject<HTMLElement | null>
181
185
  const elements: HTMLElement[] = [];
182
186
 
183
187
  if (menuRootRef.current) {
184
- elements.push(...Array.from(menuRootRef.current.children) as HTMLElement[]);
188
+ elements.push(
189
+ ...(Array.from(menuRootRef.current.children) as HTMLElement[]),
190
+ );
185
191
  }
186
192
 
187
193
  Object.values(activeMenus).forEach((menuId) => {
188
194
  const submenuEl = subMenuRefs.current[menuId];
189
195
  if (submenuEl) {
190
- elements.push(...Array.from(submenuEl.children) as HTMLElement[]);
196
+ elements.push(...(Array.from(submenuEl.children) as HTMLElement[]));
191
197
  }
192
198
  });
193
199
 
@@ -248,8 +254,8 @@ export function useSubMenuSystem(mobilePositionTo: RefObject<HTMLElement | null>
248
254
  mobilePositionTo,
249
255
  activeMenu,
250
256
  currentSubMenuLevel,
251
- closeSubMenuLevel
252
- }
257
+ closeSubMenuLevel,
258
+ },
253
259
  };
254
260
  }
255
261
 
@@ -302,14 +308,19 @@ export function useMenuPosition(
302
308
  const overflowsLeftViewport = left + menuWidth > viewportWidth;
303
309
 
304
310
  if (overflowsLeftViewport) {
305
- left = triggerRect.left - menuWidth
311
+ left = triggerRect.left - menuWidth;
306
312
  }
307
313
 
308
314
  if (isMobile) {
309
- left = triggerRect.left + menuWidth > viewportWidth
310
- ? Math.max(viewportWidth - menuWidth, 0) - 8
311
- : triggerRect.left;
312
- top = (elementRef.current.parentElement?.getBoundingClientRect()?.top ?? 0) + (elementRef.current.parentElement?.getBoundingClientRect()?.height ?? 0) + topOffset;
315
+ left =
316
+ triggerRect.left + menuWidth > viewportWidth
317
+ ? Math.max(viewportWidth - menuWidth, 0) - 8
318
+ : triggerRect.left;
319
+ top =
320
+ (elementRef.current.parentElement?.getBoundingClientRect()?.top ?? 0) +
321
+ (elementRef.current.parentElement?.getBoundingClientRect()?.height ??
322
+ 0) +
323
+ topOffset;
313
324
  }
314
325
 
315
326
  setMenuPosition({
@@ -1 +1,2 @@
1
1
  export { useKeydown } from "./useKeydown";
2
+ export { useMatchesMedia, useMatchesMobile } from "./useMatchesMedia";
@@ -0,0 +1,18 @@
1
+ import { useLayoutEffect, useState } from "react";
2
+
3
+ export const useMatchesMedia = (query: string) => {
4
+ const [matches, setMatches] = useState<boolean>();
5
+
6
+ useLayoutEffect(() => {
7
+ const mediaQueryList = window.matchMedia(query);
8
+ const listener = () => setMatches(mediaQueryList.matches);
9
+ listener();
10
+ mediaQueryList.addEventListener("change", listener);
11
+ return () => mediaQueryList.removeEventListener("change", listener);
12
+ }, [query]);
13
+
14
+ return matches;
15
+ };
16
+
17
+ export const useMatchesMobile = (): boolean | undefined =>
18
+ useMatchesMedia("(width < 48rem)");