@box/blueprint-web 16.8.4 → 16.8.5

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 (38) hide show
  1. package/THIRD_PARTY_LICENSES +0 -50
  2. package/dist/lib-esm/badge/base-badge.js +1 -1
  3. package/dist/lib-esm/badge/icon-badge.js +1 -1
  4. package/dist/lib-esm/branding-styles/utils/createTheme.d.ts +16 -16
  5. package/dist/lib-esm/branding-styles/utils/createTheme.js +5 -6
  6. package/dist/lib-esm/breadcrumb/breadcrumb.js +1 -1
  7. package/dist/lib-esm/breadcrumb/useFolderTreeTruncation.js +1 -1
  8. package/dist/lib-esm/list-item/index.js +0 -1
  9. package/dist/lib-esm/list-item/table.js +1 -1
  10. package/dist/lib-esm/list-item/utils/column-visibility-context/useThrottledContainerResize.js +1 -1
  11. package/dist/lib-esm/primitives/context-menu/context-menu-sub-menu-root.js +0 -1
  12. package/dist/lib-esm/primitives/dropdown-menu/dropdown-menu-sub-menu-root.js +0 -1
  13. package/dist/lib-esm/primitives/inline-error/utils/use-inline-error-presence.js +1 -1
  14. package/dist/lib-esm/primitives/notification/notification-provider.js +8 -3
  15. package/dist/lib-esm/primitives/select-menu-grid/select-menu-grid-option.js +1 -1
  16. package/dist/lib-esm/primitives/select-menu-grid/select-menu-grid.js +1 -1
  17. package/dist/lib-esm/toolbar/utils/horizontal-scroll-context.js +1 -1
  18. package/dist/lib-esm/toolbar/utils/use-scroll-state.js +1 -1
  19. package/dist/lib-esm/util-components/base-grid-list-item/base-grid-list-item.js +1 -1
  20. package/dist/lib-esm/util-components/base-grid-list-item/base-grid-list.js +1 -1
  21. package/dist/lib-esm/util-components/scrollable-container/scrollable-container.d.ts +1 -1
  22. package/dist/lib-esm/util-components/scrollable-container/scrollable-container.js +1 -1
  23. package/dist/lib-esm/utils/chunk.d.ts +5 -0
  24. package/dist/lib-esm/utils/chunk.js +17 -0
  25. package/dist/lib-esm/utils/deepMerge.d.ts +13 -0
  26. package/dist/lib-esm/utils/deepMerge.js +70 -0
  27. package/dist/lib-esm/utils/isDefined.js +1 -3
  28. package/dist/lib-esm/utils/mapValues.d.ts +7 -0
  29. package/dist/lib-esm/utils/mapValues.js +20 -0
  30. package/dist/lib-esm/utils/noop.d.ts +1 -0
  31. package/dist/lib-esm/utils/noop.js +5 -0
  32. package/dist/lib-esm/utils/omit.d.ts +6 -0
  33. package/dist/lib-esm/utils/omit.js +20 -0
  34. package/dist/lib-esm/utils/scroll-context.js +1 -1
  35. package/dist/lib-esm/utils/throttle.d.ts +11 -0
  36. package/dist/lib-esm/utils/throttle.js +51 -0
  37. package/dist/lib-esm/utils/useIsEllipsized.js +1 -1
  38. package/package.json +4 -4
@@ -1328,56 +1328,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1328
1328
 
1329
1329
 
1330
1330
 
1331
- License for lodash:
1332
- Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
1333
-
1334
- Based on Underscore.js, copyright Jeremy Ashkenas,
1335
- DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
1336
-
1337
- This software consists of voluntary contributions made by many
1338
- individuals. For exact contribution history, see the revision history
1339
- available at https://github.com/lodash/lodash
1340
-
1341
- The following license applies to all parts of this software except as
1342
- documented below:
1343
-
1344
- ====
1345
-
1346
- Permission is hereby granted, free of charge, to any person obtaining
1347
- a copy of this software and associated documentation files (the
1348
- "Software"), to deal in the Software without restriction, including
1349
- without limitation the rights to use, copy, modify, merge, publish,
1350
- distribute, sublicense, and/or sell copies of the Software, and to
1351
- permit persons to whom the Software is furnished to do so, subject to
1352
- the following conditions:
1353
-
1354
- The above copyright notice and this permission notice shall be
1355
- included in all copies or substantial portions of the Software.
1356
-
1357
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1358
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1359
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1360
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
1361
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
1362
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1363
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1364
-
1365
- ====
1366
-
1367
- Copyright and related rights for sample code are waived via CC0. Sample
1368
- code is defined as all source code displayed within the prose of the
1369
- documentation.
1370
-
1371
- CC0: http://creativecommons.org/publicdomain/zero/1.0/
1372
-
1373
- ====
1374
-
1375
- Files located in the node_modules and vendor directories are externally
1376
- maintained libraries used by this software which have their own
1377
- licenses; we recommend you read them, as their terms may differ from the
1378
- terms above.
1379
-
1380
-
1381
1331
  License for react-aria:
1382
1332
  Apache License
1383
1333
  Version 2.0, January 2004
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import clsx from 'clsx';
3
- import mapValues from 'lodash/mapValues';
3
+ import { mapValues } from '../utils/mapValues.js';
4
4
  import styles from './base-badge.module.js';
5
5
 
6
6
  const BaseBadge = ({
@@ -2,9 +2,9 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { Alert, ArrowRight, Ellipsis, ClockBadge, Loader, CheckmarkUnderline, Arrow, Pin, Star, GlobeBadge, XMark, Checkmark, Annotation, ApprovalTask, Task, EllipsisBubble, Relay, FolderShared, FolderExternal, FileZip, FileWord, FileVideo, FileVector, FileThreeD, FileText, FileSpreadsheet, FileSlides, FileSheets, FilePresentation, FilePowerpoint, FilePhotoshop, FilePdf, FilePages, FileNumbers, FileKeynote, FileIndesign, FileImage, FileIllustrator, Hubs, FileExcel, FileDrawing, FileDocs, FileDefault, Code, FileCanvas, FileBoxNote, BoxApps, FileBookmark, FileAudio } from '@box/blueprint-web-assets/icons/Fill';
3
3
  import { GrayWhite, SurfaceBadgeAlertSurface, SurfaceBadgeForwardSurface, SurfaceBadgeInprogressSurface, Orange100, SurfaceBadgeErrorSurface, SurfaceBadgeDefaultSurface, SurfaceBadgeProgressSurface, SurfaceBadgeOfflineSurface, Gray80, SurfaceBadgeCollectionSurface, SurfaceBadgePinSurface, SurfaceBadgeCoadminSurface, SurfaceBadgeAdminSurface, SurfaceBadgeExternalSurface, SurfaceBadgeRejectedSurface, SurfaceBadgeCompletedSurface, SurfaceBadgeAnnotationSurface, SurfaceBadgeTaskapprovalSurface, SurfaceBadgeTaskSurface, SurfaceBadgeMentionSurface, SurfaceBadgeRelaySurface, SurfaceBadgeFoldersharedSurface, SurfaceBadgeFolderexternalSurface, SurfaceBadgeZipSurface, SurfaceBadgeWordSurface, SurfaceBadgeVideoSurface, SurfaceBadgeVectorSurface, SurfaceBadgeThreeDSurface, SurfaceBadgeTextSurface, SurfaceBadgeSpreadsheetSurface, GrayBlack, SurfaceBadgeSlidesSurface, SurfaceBadgeSheetsSurface, SurfaceBadgePresentationSurface, SurfaceBadgePowerpointSurface, IconIconPhotoshop, SurfaceBadgePhotoshopSurface, SurfaceBadgePdfSurface, SurfaceBadgePagesSurface, SurfaceBadgeNumbersSurface, SurfaceBadgeKeynoteSurface, IconIconIndesign, SurfaceBadgeIndesignSurface, SurfaceBadgeImageSurface, IconIconIllustrator, SurfaceBadgeIllustratorSurface, SurfaceBadgeHubsSurface, SurfaceBadgeExcelSurface, SurfaceBadgeDrawingSurface, SurfaceBadgeDocsSurface, SurfaceBadgeCodeSurface, SurfaceBadgeCanvasSurface, Gray100, SurfaceBadgeBoxnoteSurface, SurfaceBadgeBoxappsSurface, SurfaceBadgeBookmarkSurface, SurfaceBadgeAudioSurface } from '@box/blueprint-web-assets/tokens/tokens';
4
4
  import clsx from 'clsx';
5
- import mapValues from 'lodash/mapValues';
6
5
  import { createElement } from 'react';
7
6
  import { TooltipWrapper } from '../utils/TooltipWrapper.js';
7
+ import { mapValues } from '../utils/mapValues.js';
8
8
  import { BaseBadge } from './base-badge.js';
9
9
  import styles from './base-badge.module.js';
10
10
  import { useSingleChildCheck } from './utils/useSingleChildCheck.js';
@@ -51,22 +51,22 @@ declare function createTheme(colorKey: string): {
51
51
  _debug: {
52
52
  colorRange: string | undefined;
53
53
  };
54
- background: any;
55
- backgroundHover: any;
56
- backgroundActive: any;
57
- backgroundGradient: any;
58
- foreground: any;
59
- border: any;
60
- buttonForeground: any;
61
- buttonBackground: any;
62
- buttonBackgroundHover: any;
63
- buttonBackgroundActive: any;
64
- buttonBorder: any;
65
- buttonBorderHover: any;
66
- buttonBorderActive: any;
67
- progressBarBackground: any;
68
- scrollShadowRgba: any;
69
- dividerBackground: any;
54
+ background: string | undefined;
55
+ backgroundHover: string | undefined;
56
+ backgroundActive: string | undefined;
57
+ backgroundGradient: string | undefined;
58
+ foreground: string | undefined;
59
+ border: string | undefined;
60
+ buttonForeground: string | undefined;
61
+ buttonBackground: string | undefined;
62
+ buttonBackgroundHover: string | undefined;
63
+ buttonBackgroundActive: string | undefined;
64
+ buttonBorder: string | undefined;
65
+ buttonBorderHover: string | undefined;
66
+ buttonBorderActive: string | undefined;
67
+ progressBarBackground: string | undefined;
68
+ scrollShadowRgba: string | undefined;
69
+ dividerBackground: string | undefined;
70
70
  };
71
71
  };
72
72
  export { createTheme };
@@ -1,7 +1,6 @@
1
1
  import Color from 'color';
2
- import mapValues from 'lodash/mapValues';
3
- import merge from 'lodash/merge';
4
- import method from 'lodash/method';
2
+ import { deepMerge } from '../../utils/deepMerge.js';
3
+ import { mapValues } from '../../utils/mapValues.js';
5
4
  import theme from './theme.js';
6
5
  import { white, black, bdlGray65, bdlGray80, bdlGray, bdlGray10, bdlGray50 } from './variables.js';
7
6
 
@@ -163,15 +162,15 @@ function createTheme(colorKey) {
163
162
  colorValues.progressBarBackground = exceedsLightThreshold ? bdlGray50 : hoverHex;
164
163
  }
165
164
  const dynamicTheme = {
166
- // To avoid a mixture of casing, we force all values to lower
165
+ // To avoid a mixture of casing, we force all string values to lower
167
166
  primary: {
168
- ...mapValues(colorValues, method('toLowerCase')),
167
+ ...mapValues(colorValues, value => typeof value === 'string' ? value.toLowerCase() : undefined),
169
168
  _debug: {
170
169
  colorRange
171
170
  }
172
171
  }
173
172
  };
174
- return merge({}, theme, dynamicTheme);
173
+ return deepMerge({}, theme, dynamicTheme);
175
174
  }
176
175
 
177
176
  export { MIN_CONTRAST, THEME_DARK, THEME_MIDTONE, THEME_MID_DARK, THEME_MID_LIGHT, THEME_VERY_DARK, THEME_VERY_LIGHT, createTheme };
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import noop from 'lodash/noop';
3
2
  import { forwardRef, useRef } from 'react';
4
3
  import { FolderTree } from '@box/blueprint-web-assets/icons/Fill';
5
4
  import { Taxonomy } from '@box/blueprint-web-assets/icons/Medium';
6
5
  import { Home } from '@box/blueprint-web-assets/icons/MediumFilled';
6
+ import { noop } from '../utils/noop.js';
7
7
  import { useBreakpoint, Breakpoint } from '../utils/useBreakpoint.js';
8
8
  import { EllipsisTruncationView } from './ellipsis-truncation-view.js';
9
9
  import { FolderTreeTruncationView } from './folder-tree-truncation-view.js';
@@ -1,5 +1,5 @@
1
- import noop from 'lodash/noop';
2
1
  import { useState, useRef, useCallback, useLayoutEffect } from 'react';
2
+ import { noop } from '../utils/noop.js';
3
3
 
4
4
  const MAX_VISIBLE_CRUMBS = 3;
5
5
  /**
@@ -5,7 +5,6 @@ import '@box/blueprint-web-assets/icons/Fill';
5
5
  import '@box/blueprint-web-assets/tokens/tokens';
6
6
  import 'clsx';
7
7
  import { Cell as Cell$1 } from './cell/cell.js';
8
- import 'lodash/noop';
9
8
  import '../utils/useBreakpoint.js';
10
9
  import '@box/blueprint-web-assets/icons/Medium';
11
10
  import 'react-aria';
@@ -1,8 +1,8 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import noop from 'lodash/noop';
3
2
  import { forwardRef, useRef } from 'react';
4
3
  import { ResizableTableContainer, Table as Table$1 } from 'react-aria-components';
5
4
  import clsx from 'clsx';
5
+ import { noop } from '../utils/noop.js';
6
6
  import { useBlueprintModernization } from '../blueprint-modernization-context/useBlueprintModernization.js';
7
7
  import styles from './main.module.js';
8
8
  import { ColumnVisibilityProvider, useColumnVisibilityContext } from './utils/column-visibility-context/columnVisibilityContext.js';
@@ -1,5 +1,5 @@
1
- import noop from 'lodash/noop';
2
1
  import { useState, useRef, useEffect } from 'react';
2
+ import { noop } from '../../../utils/noop.js';
3
3
 
4
4
  const useThrottledContainerResize = (containerRef, isColumnDroppingEnabled) => {
5
5
  const [containerWidth, setContainerWidth] = useState(0);
@@ -1,6 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { Sub } from '@radix-ui/react-context-menu';
3
- import 'lodash/noop';
4
3
  import { useCallback } from 'react';
5
4
  import { useControllableState } from '../../utils/useControllableState.js';
6
5
  import { SubMenuMenuProvider } from '../menu-utils/responsiveness/SubMenuContext.js';
@@ -1,6 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
3
- import 'lodash/noop';
4
3
  import { useCallback } from 'react';
5
4
  import { useControllableState } from '../../utils/useControllableState.js';
6
5
  import { SubMenuMenuProvider } from '../menu-utils/responsiveness/SubMenuContext.js';
@@ -1,5 +1,5 @@
1
- import noop from 'lodash/noop';
2
1
  import { useState, useCallback } from 'react';
2
+ import { noop } from '../../../utils/noop.js';
3
3
  import { useEnhancedEffect } from '../../../utils/useEnhancedEffect.js';
4
4
 
5
5
  const animationEndNoop = noop;
@@ -1,8 +1,8 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import * as Toast from '@radix-ui/react-toast';
3
- import merge from 'lodash/merge';
4
3
  import * as React from 'react';
5
4
  import { useState, useContext } from 'react';
5
+ import { deepMerge } from '../../utils/deepMerge.js';
6
6
  import { getUniqueId } from '../../utils/useUniqueId.js';
7
7
 
8
8
  const DEFAULT_NOTIFICATION_DELAY = 5000;
@@ -71,9 +71,14 @@ const NotificationProvider = props => {
71
71
  }, []);
72
72
  const updateNotification = React.useCallback((id, newProps) => {
73
73
  setNotifications(oldValue => {
74
+ const oldNotificationProps = oldValue.get(id);
75
+ // Nothing to merge into if the notification no longer exists; leave the map untouched
76
+ // rather than inserting a partial (and possibly invalid) entry.
77
+ if (oldNotificationProps === undefined) {
78
+ return oldValue;
79
+ }
74
80
  const newNotifications = new Map(oldValue);
75
- const oldNotificationProps = newNotifications.get(id);
76
- newNotifications.set(id, merge(oldNotificationProps, newProps));
81
+ newNotifications.set(id, deepMerge(oldNotificationProps, newProps));
77
82
  return newNotifications;
78
83
  });
79
84
  }, []);
@@ -3,12 +3,12 @@ import { CompositeItem, Button } from '@ariakit/react';
3
3
  import { Gray05, bpSize060, bpSize040, Size6, Size4, BrandDocgenPrimary, BrandFormsPrimary, BrandSignPrimary, BrandBoxPrimary, bpIconIconOnLight, Grimace100, GreenLight100, DarkBlue100, BoxBlue100, Gray100 } from '@box/blueprint-web-assets/tokens/tokens';
4
4
  import clsx from 'clsx';
5
5
  import Color from 'color';
6
- import omit from 'lodash/omit';
7
6
  import { forwardRef, createElement } from 'react';
8
7
  import { useBlueprintModernization } from '../../blueprint-modernization-context/useBlueprintModernization.js';
9
8
  import { Ghost } from '../../ghost/ghost.js';
10
9
  import { Text } from '../../text/text.js';
11
10
  import { Tooltip } from '../../tooltip/tooltip.js';
11
+ import { omit } from '../../utils/omit.js';
12
12
  import styles from './select-menu-grid-option.module.js';
13
13
 
14
14
  const SelectMenuGridSquare = /*#__PURE__*/forwardRef((props, forwardedRef) => jsx(SelectMenuGridOption, {
@@ -1,8 +1,8 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { CompositeProvider, Composite, CompositeRow } from '@ariakit/react';
3
3
  import clsx from 'clsx';
4
- import chunk from 'lodash/chunk';
5
4
  import { forwardRef, Children } from 'react';
5
+ import { chunk } from '../../utils/chunk.js';
6
6
  import styles from './select-menu-grid.module.js';
7
7
 
8
8
  const Row = props => jsx(CompositeRow, {
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import noop from 'lodash/noop';
3
2
  import { useState, useCallback, useMemo, createContext, useContext } from 'react';
3
+ import { noop } from '../../utils/noop.js';
4
4
  import { useScrollState } from './use-scroll-state.js';
5
5
 
6
6
  const HorizontalScrollContext = /*#__PURE__*/createContext({
@@ -1,5 +1,5 @@
1
- import noop from 'lodash/noop';
2
1
  import { useState, useRef, useCallback, useEffect } from 'react';
2
+ import { noop } from '../../utils/noop.js';
3
3
 
4
4
  // The hook that manages the scroll position logic and provides scroll control functions
5
5
  const useScrollState = (scrollableElement, scrollStep = 50) => {
@@ -1,8 +1,8 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import clsx from 'clsx';
3
- import noop from 'lodash/noop';
4
3
  import { forwardRef, useState, useMemo, useContext, createContext } from 'react';
5
4
  import { GridListItem } from 'react-aria-components';
5
+ import { noop } from '../../utils/noop.js';
6
6
  import { useDebounce } from '../../utils/use-debounce.js';
7
7
  import { useBaseGridListContext } from './base-grid-list.js';
8
8
  import styles from './base-grid-list-item.module.js';
@@ -1,8 +1,8 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import clsx from 'clsx';
3
- import noop from 'lodash/noop';
4
3
  import { forwardRef, useMemo, createContext, useContext } from 'react';
5
4
  import { GridList } from 'react-aria-components';
5
+ import { noop } from '../../utils/noop.js';
6
6
  import { useBlueprintModernization } from '../../blueprint-modernization-context/useBlueprintModernization.js';
7
7
  import { isCtrlKeyPressed } from '../../utils/keyboardUtils.js';
8
8
  import styles from './base-grid-list-item.module.js';
@@ -26,6 +26,6 @@ export declare const useScroll: (forwardedRef: RefObject<HTMLDivElement>, scroll
26
26
  isScrolledToEndY: boolean;
27
27
  isScrolledToEndX: boolean;
28
28
  };
29
- onScrollThrottled: import("lodash").DebouncedFuncLeading<(e: UIEvent<HTMLElement>) => void>;
29
+ onScrollThrottled: import("../../utils/throttle").ThrottledFunction<[e: UIEvent<HTMLElement, globalThis.UIEvent>]>;
30
30
  };
31
31
  export {};
@@ -1,7 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { clsx } from 'clsx';
3
- import throttle from 'lodash/throttle';
4
3
  import { createContext, forwardRef, useRef, useState, useMemo, useContext } from 'react';
4
+ import { throttle } from '../../utils/throttle.js';
5
5
  import { useForkRef } from '../../utils/useForkRef.js';
6
6
  import styles from './scrollable-container.module.js';
7
7
 
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Splits `array` into groups of length `size`. The final group holds the remaining
3
+ * elements. Mirrors `lodash/chunk`: a size below 1 yields an empty array.
4
+ */
5
+ export declare const chunk: <T>(array: readonly T[], size?: number) => T[][];
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Splits `array` into groups of length `size`. The final group holds the remaining
3
+ * elements. Mirrors `lodash/chunk`: a size below 1 yields an empty array.
4
+ */
5
+ const chunk = (array, size = 1) => {
6
+ const chunkSize = Math.max(Math.trunc(size), 0);
7
+ if (!Array.isArray(array) || chunkSize < 1) {
8
+ return [];
9
+ }
10
+ const result = [];
11
+ for (let i = 0; i < array.length; i += chunkSize) {
12
+ result.push(array.slice(i, i + chunkSize));
13
+ }
14
+ return result;
15
+ };
16
+
17
+ export { chunk };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Recursively merges own enumerable properties of the `sources` into `target`, mutating and
3
+ * returning `target`. Covers the plain-object usage of `lodash/merge` in this package:
4
+ * undefined source values are skipped and source objects are never mutated. React elements
5
+ * (and other `$$typeof`-tagged objects) are treated as opaque values rather than merged.
6
+ *
7
+ * `target` and the sources are constrained to objects: primitives cannot be mutated in place and
8
+ * would fail at runtime. A nullish `target` is returned unchanged (nothing is merged), so callers
9
+ * holding a possibly-undefined target (e.g. `Map.get()`) must narrow it before merging into it.
10
+ */
11
+ export declare function deepMerge<TObject extends object, TSource extends object>(target: TObject, source: TSource): TObject & TSource;
12
+ export declare function deepMerge<TObject extends object, TSource1 extends object, TSource2 extends object>(target: TObject, source1: TSource1, source2: TSource2): TObject & TSource1 & TSource2;
13
+ export declare function deepMerge<TTarget extends null | undefined>(target: TTarget, ...sources: object[]): TTarget;
@@ -0,0 +1,70 @@
1
+ // Keys that can mutate an object's prototype chain (prototype pollution). Sources passed to
2
+ // deepMerge are not guaranteed to be trusted (e.g. caller-provided notification props), so these
3
+ // are never copied or merged onto the target.
4
+ const UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
5
+ const isUnsafeKey = key => UNSAFE_KEYS.has(key);
6
+ const isPlainObject = value => {
7
+ if (typeof value !== 'object' || value === null) {
8
+ return false;
9
+ }
10
+ // Never recurse into React elements (or other tagged objects): treat them as opaque values.
11
+ if ('$$typeof' in value) {
12
+ return false;
13
+ }
14
+ const proto = Object.getPrototypeOf(value);
15
+ return proto === Object.prototype || proto === null;
16
+ };
17
+ const cloneDeep = value => {
18
+ if (Array.isArray(value)) {
19
+ return value.map(cloneDeep);
20
+ }
21
+ if (isPlainObject(value)) {
22
+ const output = {};
23
+ for (const key of Object.keys(value)) {
24
+ if (isUnsafeKey(key)) {
25
+ continue; // eslint-disable-line no-continue
26
+ }
27
+ output[key] = cloneDeep(value[key]);
28
+ }
29
+ return output;
30
+ }
31
+ return value;
32
+ };
33
+ const mergeInto = (target, source) => {
34
+ for (const key of Object.keys(source)) {
35
+ // Skip prototype-polluting keys before touching the target.
36
+ if (isUnsafeKey(key)) {
37
+ continue; // eslint-disable-line no-continue
38
+ }
39
+ const sourceValue = source[key];
40
+ // Matches lodash/merge: undefined source values never overwrite an existing value.
41
+ if (sourceValue === undefined) {
42
+ continue; // eslint-disable-line no-continue
43
+ }
44
+ const targetValue = target[key];
45
+ if (isPlainObject(sourceValue)) {
46
+ if (isPlainObject(targetValue)) {
47
+ mergeInto(targetValue, sourceValue);
48
+ } else {
49
+ // Clone so the merged result never shares references with (and cannot mutate) a source.
50
+ target[key] = cloneDeep(sourceValue);
51
+ }
52
+ } else {
53
+ target[key] = sourceValue;
54
+ }
55
+ }
56
+ };
57
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, no-redeclare -- overload implementation
58
+ function deepMerge(target, ...sources) {
59
+ if (target == null) {
60
+ return target;
61
+ }
62
+ for (const source of sources) {
63
+ if (source != null) {
64
+ mergeInto(target, source);
65
+ }
66
+ }
67
+ return target;
68
+ }
69
+
70
+ export { deepMerge };
@@ -1,8 +1,6 @@
1
- import isUndefined from 'lodash/isUndefined';
2
-
3
1
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
2
  const isDefined = value => {
5
- return !isUndefined(value);
3
+ return value !== undefined;
6
4
  };
7
5
 
8
6
  export { isDefined };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Creates a new object with the same keys as `object`, running each own enumerable
3
+ * value through `iteratee`. Mirrors `lodash/mapValues`: a nullish input yields `{}`.
4
+ * The iteratee value is intentionally `any` to match lodash's permissive typing so that
5
+ * existing call sites compile unchanged under `strictFunctionTypes`.
6
+ */
7
+ export declare const mapValues: <T extends object, R>(object: T | null | undefined, iteratee: (value: any, key: string, collection: T) => R) => { [K in keyof T]: R; };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Creates a new object with the same keys as `object`, running each own enumerable
3
+ * value through `iteratee`. Mirrors `lodash/mapValues`: a nullish input yields `{}`.
4
+ * The iteratee value is intentionally `any` to match lodash's permissive typing so that
5
+ * existing call sites compile unchanged under `strictFunctionTypes`.
6
+ */
7
+ const mapValues = (object,
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ iteratee) => {
10
+ const result = {};
11
+ if (object == null) {
12
+ return result;
13
+ }
14
+ for (const key of Object.keys(object)) {
15
+ result[key] = iteratee(object[key], key, object);
16
+ }
17
+ return result;
18
+ };
19
+
20
+ export { mapValues };
@@ -0,0 +1 @@
1
+ export declare const noop: () => void;
@@ -0,0 +1,5 @@
1
+ const noop = () => {
2
+ // Intentionally does nothing. Local replacement for `lodash/noop`.
3
+ };
4
+
5
+ export { noop };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Returns a shallow copy of `object` without the given top-level `keys`.
3
+ * Covers the flat-key usage of `lodash/omit` in this package (no deep paths). Keys that
4
+ * are not present on `object` are ignored, mirroring lodash's permissive behavior.
5
+ */
6
+ export declare const omit: <T extends object>(object: T | null | undefined, keys: readonly PropertyKey[]) => Partial<T>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Returns a shallow copy of `object` without the given top-level `keys`.
3
+ * Covers the flat-key usage of `lodash/omit` in this package (no deep paths). Keys that
4
+ * are not present on `object` are ignored, mirroring lodash's permissive behavior.
5
+ */
6
+ const omit = (object, keys) => {
7
+ const result = {};
8
+ if (object == null) {
9
+ return result;
10
+ }
11
+ const excluded = new Set(keys);
12
+ for (const key of Object.keys(object)) {
13
+ if (!excluded.has(key)) {
14
+ result[key] = object[key];
15
+ }
16
+ }
17
+ return result;
18
+ };
19
+
20
+ export { omit };
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import noop from 'lodash/noop';
3
2
  import { useContext, createContext, useState, useCallback, useMemo } from 'react';
3
+ import { noop } from './noop.js';
4
4
 
5
5
  const ScrollContext = /*#__PURE__*/createContext({
6
6
  isScrolledUnderFooter: false,
@@ -0,0 +1,11 @@
1
+ export interface ThrottledFunction<Args extends unknown[]> {
2
+ (...args: Args): void;
3
+ cancel(): void;
4
+ }
5
+ /**
6
+ * Leading + trailing edge throttle, matching the default behavior of `lodash/throttle`
7
+ * for the subset of the API used in this package. The wrapped function is invoked
8
+ * immediately on the first call, then at most once per `wait` ms, and once more on the
9
+ * trailing edge with the most recent arguments.
10
+ */
11
+ export declare const throttle: <Args extends unknown[]>(func: (...args: Args) => void, wait?: number) => ThrottledFunction<Args>;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Leading + trailing edge throttle, matching the default behavior of `lodash/throttle`
3
+ * for the subset of the API used in this package. The wrapped function is invoked
4
+ * immediately on the first call, then at most once per `wait` ms, and once more on the
5
+ * trailing edge with the most recent arguments.
6
+ */
7
+ const throttle = (func, wait = 0) => {
8
+ let lastInvokeTime;
9
+ let timeout;
10
+ let trailingArgs;
11
+ const invoke = (time, args) => {
12
+ lastInvokeTime = time;
13
+ func(...args);
14
+ };
15
+ const throttled = (...args) => {
16
+ const now = Date.now();
17
+ if (lastInvokeTime === undefined) {
18
+ invoke(now, args);
19
+ return;
20
+ }
21
+ const remaining = wait - (now - lastInvokeTime);
22
+ trailingArgs = args;
23
+ if (remaining <= 0) {
24
+ if (timeout) {
25
+ clearTimeout(timeout);
26
+ timeout = undefined;
27
+ }
28
+ invoke(now, args);
29
+ trailingArgs = undefined;
30
+ } else if (!timeout) {
31
+ timeout = setTimeout(() => {
32
+ timeout = undefined;
33
+ if (trailingArgs) {
34
+ invoke(Date.now(), trailingArgs);
35
+ trailingArgs = undefined;
36
+ }
37
+ }, remaining);
38
+ }
39
+ };
40
+ throttled.cancel = () => {
41
+ if (timeout) {
42
+ clearTimeout(timeout);
43
+ }
44
+ timeout = undefined;
45
+ lastInvokeTime = undefined;
46
+ trailingArgs = undefined;
47
+ };
48
+ return throttled;
49
+ };
50
+
51
+ export { throttle };
@@ -1,5 +1,5 @@
1
- import noop from 'lodash/noop';
2
1
  import { useState, useEffect } from 'react';
2
+ import { noop } from './noop.js';
3
3
 
4
4
  const useIsEllipsized = ref => {
5
5
  const [isEllipsized, setIsEllipsized] = useState(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@box/blueprint-web",
3
- "version": "16.8.4",
3
+ "version": "16.8.5",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "publishConfig": {
@@ -47,7 +47,7 @@
47
47
  "dependencies": {
48
48
  "@ariakit/react": "0.4.21",
49
49
  "@ariakit/react-core": "0.4.21",
50
- "@box/blueprint-web-assets": "^5.5.2",
50
+ "@box/blueprint-web-assets": "^5.5.3",
51
51
  "@internationalized/date": "^3.12.0",
52
52
  "@radix-ui/react-accordion": "1.1.2",
53
53
  "@radix-ui/react-checkbox": "1.0.4",
@@ -71,16 +71,16 @@
71
71
  "@react-aria/utils": "3.33.1",
72
72
  "clsx": "^1.2.1",
73
73
  "color": "2.0.1",
74
- "lodash": "^4.17.15",
75
74
  "react-aria": "3.47.0",
76
75
  "react-aria-components": "1.16.0",
77
76
  "type-fest": "^3.2.0"
78
77
  },
79
78
  "devDependencies": {
80
- "@box/storybook-utils": "^1.1.26",
79
+ "@box/storybook-utils": "^1.1.27",
81
80
  "@figma/code-connect": "1.4.4",
82
81
  "@types/react": "^18.0.0",
83
82
  "@types/react-dom": "^18.0.0",
83
+ "lodash": "^4.17.15",
84
84
  "react": "^18.3.0",
85
85
  "react-dom": "^18.3.0",
86
86
  "react-stately": "^3.45.0",