@box/blueprint-web 12.108.4 → 12.109.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { forwardRef, useCallback } from 'react';
2
+ import { forwardRef, useCallback, useRef } from 'react';
3
3
  import { FolderTree, PointerRight } from '@box/blueprint-web-assets/icons/Fill';
4
4
  import { Ellipsis } from '@box/blueprint-web-assets/icons/Medium';
5
5
  import { Home } from '@box/blueprint-web-assets/icons/MediumFilled';
@@ -9,6 +9,7 @@ import { IconButton } from '../primitives/icon-button/icon-button.js';
9
9
  import { Text } from '../text/text.js';
10
10
  import { useBreakpoint, Breakpoint } from '../utils/useBreakpoint.js';
11
11
  import { PageLink } from './page-link.js';
12
+ import { useFolderTreeTruncation } from './useFolderTreeTruncation.js';
12
13
  import styles from './breadcrumb.module.js';
13
14
  import { getSeparatorSize } from './utils.js';
14
15
 
@@ -33,17 +34,28 @@ const Breadcrumb = /*#__PURE__*/forwardRef((props, forwardedRef) => {
33
34
  const breakpoint = useBreakpoint();
34
35
  const isMobile = isResponsiveEnabled || breakpoint <= Breakpoint.Medium;
35
36
  // If there are more than 7 crumbs, break up crumbs into first link, ellipsis icon button, and current page ancestor
36
- const shouldTruncateCrumbs = crumbs.length > 7;
37
- const shouldUseEllipsisTruncation = !isMobile && truncationMethod === 'ellipsis' && shouldTruncateCrumbs;
37
+ const shouldUseEllipsisTruncation = !isMobile && truncationMethod === 'ellipsis' && crumbs && crumbs.length > 7;
38
38
  // Get the current page (last crumb) and all ancestors (all crumbs except last)
39
39
  const currentPage = crumbs[crumbs.length - 1];
40
40
  const ancestorCrumbs = crumbs.slice(0, -1);
41
+ // Folder-tree truncation: detect overflow and show up to 3 visible crumbs
42
+ const breadcrumbListRef = useRef(null);
43
+ const isFolderTreeTruncationEnabled = !isMobile && truncationMethod === 'folder-tree';
44
+ const {
45
+ isTruncationRequired,
46
+ visibleCrumbCount,
47
+ iconButtonRef
48
+ } = useFolderTreeTruncation(breadcrumbListRef, crumbs, isFolderTreeTruncationEnabled);
49
+ const shouldUseFolderTreeTruncation = isFolderTreeTruncationEnabled && isTruncationRequired && crumbs;
50
+ const visibleCrumbs = shouldUseFolderTreeTruncation ? crumbs.slice(-visibleCrumbCount) : [];
51
+ const hiddenCrumbs = shouldUseFolderTreeTruncation ? crumbs.slice(0, -visibleCrumbCount) : [];
41
52
  return jsx("nav", {
42
53
  ref: forwardedRef,
43
54
  "aria-label": breadcrumbAriaLabel,
44
55
  className: styles.container,
45
56
  ...rest,
46
57
  children: jsxs("ol", {
58
+ ref: breadcrumbListRef,
47
59
  className: styles.breadcrumb,
48
60
  children: [!isMobile && rootIconVariant && jsxs("li", {
49
61
  className: styles.pageLink,
@@ -134,7 +146,40 @@ const Breadcrumb = /*#__PURE__*/forwardRef((props, forwardedRef) => {
134
146
  onPageLinkClick: onPageLinkClick,
135
147
  size: size
136
148
  })]
137
- }), !isMobile && !shouldUseEllipsisTruncation && crumbs.map((crumb, index) => {
149
+ }), shouldUseFolderTreeTruncation && jsxs(Fragment, {
150
+ children: [jsxs("li", {
151
+ ref: iconButtonRef,
152
+ className: styles.pageLink,
153
+ children: [jsxs(DropdownMenu.Root, {
154
+ children: [jsx(DropdownMenu.Trigger, {
155
+ children: jsx(IconButton, {
156
+ "aria-label": truncatedLinksIconAriaLabel,
157
+ icon: FolderTree,
158
+ size: "small"
159
+ })
160
+ }), jsx(DropdownMenu.Content, {
161
+ align: "start",
162
+ children: hiddenCrumbs.map(crumb => jsx(DropdownMenu.Item, {
163
+ onSelect: handlePageLinkClick(crumb.id),
164
+ children: jsx(Text, {
165
+ as: "span",
166
+ children: crumb.name
167
+ })
168
+ }, crumb.id))
169
+ })]
170
+ }), jsx(PointerRight, {
171
+ height: getSeparatorSize(size),
172
+ role: "presentation",
173
+ width: getSeparatorSize(size)
174
+ })]
175
+ }), visibleCrumbs.map((crumb, index) => jsx(PageLink, {
176
+ crumb: crumb,
177
+ isInteractive: isInteractive,
178
+ isLast: index === visibleCrumbs.length - 1,
179
+ onPageLinkClick: onPageLinkClick,
180
+ size: size
181
+ }, crumb.id))]
182
+ }), !isMobile && !shouldUseEllipsisTruncation && !shouldUseFolderTreeTruncation && crumbs?.map((crumb, index) => {
138
183
  return jsx(PageLink, {
139
184
  crumb: crumb,
140
185
  isInteractive: isInteractive,
@@ -1,4 +1,4 @@
1
1
  import '../index.css';
2
- var styles = {"container":"bp_breadcrumb_module_container--51e29","breadcrumb":"bp_breadcrumb_module_breadcrumb--51e29","pageLink":"bp_breadcrumb_module_pageLink--51e29","linkWithHover":"bp_breadcrumb_module_linkWithHover--51e29"};
2
+ var styles = {"container":"bp_breadcrumb_module_container--bac4c","breadcrumb":"bp_breadcrumb_module_breadcrumb--bac4c","pageLink":"bp_breadcrumb_module_pageLink--bac4c","linkWithHover":"bp_breadcrumb_module_linkWithHover--bac4c"};
3
3
 
4
4
  export { styles as default };
@@ -25,9 +25,9 @@ export type BreadcrumbProps = {
25
25
  truncatedLinksIconAriaLabel: string;
26
26
  /** Controls behavior when there are too many crumbs to display.
27
27
  * Ellipsis shows the crumbs at the beginning and end, with an ellipsis icon in between.
28
- * Folder shows only the last crumb, preceded by a folder tree icon.
28
+ * Folder-tree dynamically detects container overflow and shows up to 3 visible crumbs with a folder tree icon dropdown.
29
29
  */
30
- truncationMethod?: 'ellipsis' | 'folder';
30
+ truncationMethod?: 'ellipsis' | 'folder-tree';
31
31
  } & RequireAllOrNone<rootIconProps, keyof rootIconProps>;
32
32
  /** Props for the root icon. These can be ommitted entirely to show no root icon. */
33
33
  export interface rootIconProps {
@@ -0,0 +1,25 @@
1
+ import { type Crumb } from './types';
2
+ interface FolderTreeTruncationState {
3
+ /** Whether the breadcrumb content would exceed the container width IF no truncation was being applied */
4
+ isTruncationRequired: boolean;
5
+ /** Number of visible crumbs (not in dropdown) to show (1-3) */
6
+ visibleCrumbCount: number;
7
+ }
8
+ interface FolderTreeTruncationResult extends FolderTreeTruncationState {
9
+ /** Ref to attach to the icon button container li element for width measurement */
10
+ iconButtonRef: React.RefObject<HTMLLIElement>;
11
+ }
12
+ /**
13
+ * Hook which calculates how many crumbs can be displayed when folder-tree truncation is enabled.
14
+ *
15
+ * ## Truncation Rules
16
+ * - **≤3 crumbs**: Render all crumbs first, detect overflow, truncate only if needed
17
+ * - **>3 crumbs**: Render truncated state immediately, show icon button + up to 3 crumbs
18
+ *
19
+ * @param containerRef - Ref to the main ol element
20
+ * @param crumbs - Array of breadcrumb items
21
+ * @param isEnabled - Whether folder-tree truncation is enabled. Can be false when responsive behavior is triggered
22
+ * @returns Object containing wouldCrumbsOverflow, visibleCrumbCount, and iconButtonRef
23
+ */
24
+ export declare const useFolderTreeTruncation: (containerRef: React.RefObject<HTMLOListElement>, crumbs: Crumb[], isEnabled: boolean) => FolderTreeTruncationResult;
25
+ export {};
@@ -0,0 +1,244 @@
1
+ import noop from 'lodash/noop';
2
+ import { useState, useRef, useCallback, useEffect } from 'react';
3
+
4
+ const getInitialState = (crumbCount, isTruncationRequiredBasedOnCrumbCount) => ({
5
+ isTruncationRequired: isTruncationRequiredBasedOnCrumbCount,
6
+ visibleCrumbCount: isTruncationRequiredBasedOnCrumbCount ? 3 : crumbCount
7
+ });
8
+ const calculateVisibleCrumbCount = (crumbWidths, availableWidth, gap, maxVisible) => {
9
+ let crumbWidthWithoutGaps = 0;
10
+ let visibleCount = 0;
11
+ for (let i = crumbWidths.length - 1; i >= 0 && visibleCount < maxVisible; i -= 1) {
12
+ const gapWidthsAfterAddingCrumb = gap * visibleCount; // This adds a gap for the space between the previous crumb and the proposed new crumb
13
+ const totalWidthAfterAddingCrumb = crumbWidthWithoutGaps + crumbWidths[i] + gapWidthsAfterAddingCrumb;
14
+ if (totalWidthAfterAddingCrumb <= availableWidth) {
15
+ crumbWidthWithoutGaps += crumbWidths[i];
16
+ visibleCount += 1;
17
+ } else {
18
+ break;
19
+ }
20
+ }
21
+ return Math.max(1, visibleCount);
22
+ };
23
+ const measureCrumbWidths = (children, totalCrumbCount) => {
24
+ // The first child is the icon button when we always truncate
25
+ const crumbs = children.slice(1);
26
+ const widths = [];
27
+ const startIndex = totalCrumbCount - crumbs.length;
28
+ crumbs.forEach((crumb, i) => {
29
+ widths[startIndex + i] = crumb.offsetWidth;
30
+ });
31
+ return widths;
32
+ };
33
+ /**
34
+ * Calculate total width of crumbs including gaps
35
+ */
36
+ const calculateTotalWidth = (widths, gap) => {
37
+ const totalCrumbsWidth = widths.reduce((sum, width) => sum + width, 0);
38
+ const totalGapWidth = gap * Math.max(0, widths.length - 1);
39
+ return totalCrumbsWidth + totalGapWidth;
40
+ };
41
+ /**
42
+ * Handle >3 crumbs case: Always truncate, show icon button + up to 3 crumbs
43
+ */
44
+ const handleAlwaysTruncate = (children, context) => {
45
+ const {
46
+ containerWidth,
47
+ gap,
48
+ iconButtonWidth,
49
+ crumbCount,
50
+ storedCrumbWidths
51
+ } = context;
52
+ // If we don't have stored crumb widths yet, measure them
53
+ const crumbWidths = storedCrumbWidths.length < crumbCount ? measureCrumbWidths(children, crumbCount) : storedCrumbWidths;
54
+ // Icon button not yet rendered - use conservative fallback
55
+ if (iconButtonWidth === 0) {
56
+ return {
57
+ state: {
58
+ isTruncationRequired: true,
59
+ visibleCrumbCount: 1
60
+ },
61
+ crumbWidths
62
+ };
63
+ }
64
+ const availableWidth = containerWidth - iconButtonWidth - gap;
65
+ const visibleCount = calculateVisibleCrumbCount(crumbWidths, availableWidth, gap, 3);
66
+ return {
67
+ state: {
68
+ isTruncationRequired: true,
69
+ visibleCrumbCount: visibleCount
70
+ },
71
+ crumbWidths
72
+ };
73
+ };
74
+ /**
75
+ * Get crumb widths for total width calculation
76
+ * Factored out into its own function to reduce cognitive complexity
77
+ */
78
+ const getCrumbWidths = (children, storedWidths, crumbCount, isCurrentlyTruncated) => {
79
+ if (storedWidths.length === crumbCount) {
80
+ return storedWidths; // Already have all widths
81
+ }
82
+ // The first child could be the icon button, so we don't want to measure it as part of the crumbs
83
+ const crumbElements = isCurrentlyTruncated ? children.slice(1) : children;
84
+ return crumbElements.map(crumbElement => crumbElement.offsetWidth);
85
+ };
86
+ /**
87
+ * Handle ≤3 crumbs case: Render all first, detect overflow, truncate if needed
88
+ */
89
+ const handleConditionalTruncate = (children, context, isCurrentlyTruncated) => {
90
+ const {
91
+ containerWidth,
92
+ gap,
93
+ iconButtonWidth,
94
+ crumbCount,
95
+ storedCrumbWidths
96
+ } = context;
97
+ // Get crumb widths when all crumbs are visible (not truncated)
98
+ const crumbWidths = !isCurrentlyTruncated && children.length === crumbCount ? children.map(crumbElement => crumbElement.offsetWidth) // fresh measurement
99
+ : storedCrumbWidths; // Reuse stored
100
+ // Calculate total width to check for overflow
101
+ const widthsForCalculation = getCrumbWidths(children, crumbWidths, crumbCount, isCurrentlyTruncated);
102
+ const totalWidth = calculateTotalWidth(widthsForCalculation, gap);
103
+ const areCrumbsOverflowingWithoutTruncation = totalWidth > containerWidth;
104
+ // No overflow - show all crumbs
105
+ if (!areCrumbsOverflowingWithoutTruncation) {
106
+ return {
107
+ state: {
108
+ isTruncationRequired: false,
109
+ visibleCrumbCount: crumbCount
110
+ },
111
+ crumbWidths
112
+ };
113
+ }
114
+ // If we are overflowing, now calculate how many crumbs fit with icon button
115
+ // Icon button not yet rendered - use conservative fallback
116
+ if (iconButtonWidth === 0) {
117
+ return {
118
+ state: {
119
+ isTruncationRequired: true,
120
+ visibleCrumbCount: 1
121
+ },
122
+ crumbWidths
123
+ };
124
+ }
125
+ const availableWidth = containerWidth - iconButtonWidth - gap;
126
+ const visibleCount = calculateVisibleCrumbCount(crumbWidths, availableWidth, gap, crumbCount);
127
+ return {
128
+ state: {
129
+ isTruncationRequired: true,
130
+ visibleCrumbCount: visibleCount
131
+ },
132
+ crumbWidths
133
+ };
134
+ };
135
+ /**
136
+ * Measures DOM elements and calculates truncation state
137
+ */
138
+ const performTruncationCalculation = ({
139
+ container,
140
+ iconButtonRef,
141
+ measuredIconButtonWidth,
142
+ storedCrumbWidths,
143
+ crumbCount,
144
+ isTruncationRequiredBaseOnCrumbLength,
145
+ isTruncationRequired,
146
+ setState
147
+ }) => {
148
+ const containerWidth = container.clientWidth;
149
+ const children = Array.from(container.children);
150
+ const computedStyle = getComputedStyle(container);
151
+ const gap = parseFloat(computedStyle.gap) || 0;
152
+ if (iconButtonRef.current) {
153
+ measuredIconButtonWidth.current = iconButtonRef.current.offsetWidth;
154
+ }
155
+ const context = {
156
+ containerWidth,
157
+ gap,
158
+ iconButtonWidth: measuredIconButtonWidth.current,
159
+ crumbCount,
160
+ storedCrumbWidths: storedCrumbWidths.current
161
+ };
162
+ const result = isTruncationRequiredBaseOnCrumbLength ? handleAlwaysTruncate(children, context) : handleConditionalTruncate(children, context, isTruncationRequired);
163
+ storedCrumbWidths.current = result.crumbWidths;
164
+ setState(result.state);
165
+ };
166
+ /**
167
+ * Hook which calculates how many crumbs can be displayed when folder-tree truncation is enabled.
168
+ *
169
+ * ## Truncation Rules
170
+ * - **≤3 crumbs**: Render all crumbs first, detect overflow, truncate only if needed
171
+ * - **>3 crumbs**: Render truncated state immediately, show icon button + up to 3 crumbs
172
+ *
173
+ * @param containerRef - Ref to the main ol element
174
+ * @param crumbs - Array of breadcrumb items
175
+ * @param isEnabled - Whether folder-tree truncation is enabled. Can be false when responsive behavior is triggered
176
+ * @returns Object containing wouldCrumbsOverflow, visibleCrumbCount, and iconButtonRef
177
+ */
178
+ const useFolderTreeTruncation = (containerRef, crumbs, isEnabled) => {
179
+ const isTruncationRequiredBaseOnCrumbLength = crumbs.length > 3;
180
+ const [state, setState] = useState(() => getInitialState(crumbs.length, isTruncationRequiredBaseOnCrumbLength));
181
+ const animationFrameId = useRef(null);
182
+ const iconButtonRef = useRef(null);
183
+ // Refs are used here to persist values
184
+ const measuredIconButtonWidth = useRef(0);
185
+ const storedCrumbWidths = useRef([]);
186
+ const prevCrumbsLength = useRef(crumbs.length);
187
+ // Clear stored widths when user navigates and the visible crumbs change
188
+ if (prevCrumbsLength.current !== crumbs.length) {
189
+ storedCrumbWidths.current = [];
190
+ setState(getInitialState(crumbs.length, isTruncationRequiredBaseOnCrumbLength));
191
+ prevCrumbsLength.current = crumbs.length;
192
+ }
193
+ const calculateTruncation = useCallback(() => {
194
+ const container = containerRef.current;
195
+ if (!container) {
196
+ return;
197
+ }
198
+ animationFrameId.current = requestAnimationFrame(() => {
199
+ performTruncationCalculation({
200
+ container,
201
+ iconButtonRef,
202
+ measuredIconButtonWidth,
203
+ storedCrumbWidths,
204
+ crumbCount: crumbs.length,
205
+ isTruncationRequiredBaseOnCrumbLength,
206
+ isTruncationRequired: state.isTruncationRequired,
207
+ setState
208
+ });
209
+ });
210
+ }, [containerRef, crumbs.length, state.isTruncationRequired, isTruncationRequiredBaseOnCrumbLength]);
211
+ useEffect(() => {
212
+ // Reset state when truncation is disabled (e.g., responsive breakpoint triggers mobile view)
213
+ if (!isEnabled) {
214
+ setState({
215
+ isTruncationRequired: false,
216
+ visibleCrumbCount: crumbs.length
217
+ });
218
+ measuredIconButtonWidth.current = 0;
219
+ storedCrumbWidths.current = [];
220
+ return noop;
221
+ }
222
+ const container = containerRef.current;
223
+ if (!container) {
224
+ return noop;
225
+ }
226
+ const observer = new ResizeObserver(() => {
227
+ calculateTruncation();
228
+ });
229
+ observer.observe(container);
230
+ calculateTruncation();
231
+ return () => {
232
+ observer.disconnect();
233
+ if (animationFrameId.current !== null) {
234
+ cancelAnimationFrame(animationFrameId.current);
235
+ }
236
+ };
237
+ }, [containerRef, isEnabled, calculateTruncation, crumbs.length]);
238
+ return {
239
+ ...state,
240
+ iconButtonRef
241
+ };
242
+ };
243
+
244
+ export { useFolderTreeTruncation };
@@ -2405,28 +2405,33 @@
2405
2405
  text-decoration-thickness:auto;
2406
2406
  text-underline-offset:auto;
2407
2407
  }
2408
- .bp_breadcrumb_module_container--51e29{
2408
+ .bp_breadcrumb_module_container--bac4c{
2409
2409
  height:var(--bp-size-060);
2410
+ width:100%;
2410
2411
  }
2411
- .bp_breadcrumb_module_container--51e29 .bp_breadcrumb_module_breadcrumb--51e29{
2412
+ .bp_breadcrumb_module_container--bac4c .bp_breadcrumb_module_breadcrumb--bac4c{
2412
2413
  align-items:center;
2413
2414
  display:flex;
2415
+ flex-wrap:nowrap;
2414
2416
  gap:var(--bp-size-010);
2415
2417
  height:100%;
2416
2418
  list-style:none;
2417
2419
  margin:0;
2420
+ overflow:hidden;
2418
2421
  padding:0;
2419
2422
  }
2420
- .bp_breadcrumb_module_container--51e29 .bp_breadcrumb_module_pageLink--51e29{
2423
+ .bp_breadcrumb_module_container--bac4c .bp_breadcrumb_module_pageLink--bac4c{
2421
2424
  align-items:center;
2422
2425
  display:flex;
2426
+ flex-shrink:0;
2423
2427
  gap:var(--bp-size-010);
2428
+ white-space:nowrap;
2424
2429
  }
2425
2430
 
2426
- .bp_breadcrumb_module_linkWithHover--51e29{
2431
+ .bp_breadcrumb_module_linkWithHover--bac4c{
2427
2432
  position:relative;
2428
2433
  }
2429
- .bp_breadcrumb_module_linkWithHover--51e29::after{
2434
+ .bp_breadcrumb_module_linkWithHover--bac4c::after{
2430
2435
  background-color:var(--bp-text-text-on-light-secondary);
2431
2436
  bottom:0;
2432
2437
  content:"";
@@ -2438,7 +2443,7 @@
2438
2443
  transition:transform var(--animation-duration-2) var(--animation-easing-ease-base);
2439
2444
  width:100%;
2440
2445
  }
2441
- .bp_breadcrumb_module_linkWithHover--51e29:hover::after{
2446
+ .bp_breadcrumb_module_linkWithHover--bac4c:hover::after{
2442
2447
  transform:scaleX(1);
2443
2448
  }
2444
2449
  .bp_button_wrapper_module_buttonWrapper--b0897{
@@ -7949,7 +7954,7 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
7949
7954
  .bp_base_text_input_module_textInputContainerOuter--93760 .bp_base_text_input_module_inlineError--93760,.bp_base_text_input_module_textInputContainerOuter--93760 .bp_base_text_input_module_subtext--93760{
7950
7955
  margin-block-start:var(--text-input-inline-error-subtext-block-margin);
7951
7956
  }
7952
- .bp_chip_module_chip--1f41c[data-modern=false]{
7957
+ .bp_chip_module_chip--7e98e[data-modern=false]{
7953
7958
  --chip-gap:var(--space-2);
7954
7959
  --chip-height:var(--size-8);
7955
7960
  --chip-radius:var(--radius-half);
@@ -7967,10 +7972,12 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
7967
7972
  --chip-button-background-hover:var(--surface-chip-button-surface-hover);
7968
7973
  --chip-button-status-text-color:var(--text-text-on-dark);
7969
7974
  --chip-button-status-background:var(--box-blue-100);
7975
+ --chip-button-icon-color:var(--icon-icon-on-light);
7970
7976
  --chip-button-focus-box-shadow:0 0 0 var(--border-2) var(--outline-focus-on-light);
7971
7977
  --chip-button-outline-width:var(--border-2);
7972
7978
  --chip-button-outline-color:var(--outline-focus-on-light);
7973
7979
  --chip-single-select-background:var(--surface-filterchip-surface-single);
7980
+ --chip-single-select-icon-color:var(--icon-icon-on-light);
7974
7981
  --chip-single-select-background-hover:var(--surface-filterchip-surface-single-hover);
7975
7982
  --chip-single-select-background-selected:var(--surface-filterchip-surface-single-on);
7976
7983
  --chip-single-select-background-selected-hover:var(--surface-filterchip-surface-single-on-hover);
@@ -7996,7 +8003,7 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
7996
8003
  text-decoration:var(--body-default-bold-text-decoration);
7997
8004
  text-transform:var(--body-default-bold-text-case);
7998
8005
  }
7999
- .bp_chip_module_chip--1f41c[data-modern=false].bp_chip_module_chipButton--1f41c,.bp_chip_module_chip--1f41c[data-modern=false].bp_chip_module_multiSelectChip--1f41c{
8006
+ .bp_chip_module_chip--7e98e[data-modern=false].bp_chip_module_chipButton--7e98e,.bp_chip_module_chip--7e98e[data-modern=false].bp_chip_module_multiSelectChip--7e98e{
8000
8007
  font-family:var(--body-default-font-family);
8001
8008
  font-size:var(--body-default-font-size);
8002
8009
  font-weight:var(--body-default-font-weight);
@@ -8006,7 +8013,7 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8006
8013
  text-decoration:var(--body-default-text-decoration);
8007
8014
  text-transform:var(--body-default-text-case);
8008
8015
  }
8009
- .bp_chip_module_chip--1f41c[data-modern=false].bp_chip_module_multiSelectChip--1f41c span::before,.bp_chip_module_chip--1f41c[data-modern=false].bp_chip_module_multiSelectChip--1f41c[data-state=on]{
8016
+ .bp_chip_module_chip--7e98e[data-modern=false].bp_chip_module_multiSelectChip--7e98e span::before,.bp_chip_module_chip--7e98e[data-modern=false].bp_chip_module_multiSelectChip--7e98e[data-state=on]{
8010
8017
  font-family:var(--body-default-bold-font-family);
8011
8018
  font-size:var(--body-default-bold-font-size);
8012
8019
  font-weight:var(--body-default-bold-font-weight);
@@ -8016,7 +8023,7 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8016
8023
  text-decoration:var(--body-default-bold-text-decoration);
8017
8024
  text-transform:var(--body-default-bold-text-case);
8018
8025
  }
8019
- .bp_chip_module_chip--1f41c[data-modern=false] .bp_chip_module_chipStatus--1f41c{
8026
+ .bp_chip_module_chip--7e98e[data-modern=false] .bp_chip_module_chipStatus--7e98e{
8020
8027
  font-family:var(--label-bold-font-family);
8021
8028
  font-size:var(--label-bold-font-size);
8022
8029
  font-weight:var(--label-bold-font-weight);
@@ -8027,7 +8034,7 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8027
8034
  text-transform:var(--label-bold-text-case);
8028
8035
  }
8029
8036
 
8030
- .bp_chip_module_chip--1f41c[data-modern=true]{
8037
+ .bp_chip_module_chip--7e98e[data-modern=true]{
8031
8038
  --chip-gap:var(--bp-space-020);
8032
8039
  --chip-height:var(--bp-size-090);
8033
8040
  --chip-radius:var(--bp-radius-16);
@@ -8045,10 +8052,12 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8045
8052
  --chip-button-background-hover:var(--bp-surface-chip-button-surface-hover);
8046
8053
  --chip-button-status-text-color:var(--bp-text-text-on-dark);
8047
8054
  --chip-button-status-background:var(--bp-surface-status-surface-boxblue);
8055
+ --chip-button-icon-color:var(--bp-icon-icon-on-light);
8048
8056
  --chip-button-focus-box-shadow:0 0 0 var(--bp-border-02) var(--bp-outline-focus-on-light);
8049
8057
  --chip-button-outline-width:var(--bp-border-02);
8050
8058
  --chip-button-outline-color:var(--bp-outline-focus-on-light);
8051
8059
  --chip-single-select-background:var(--bp-surface-filter-chip-surface-single);
8060
+ --chip-single-select-icon-color:var(--bp-icon-icon-on-light);
8052
8061
  --chip-single-select-background-hover:var(--bp-surface-filter-chip-surface-single-hover);
8053
8062
  --chip-single-select-background-selected:var(--bp-surface-filter-chip-surface-single-on);
8054
8063
  --chip-single-select-background-selected-hover:var(--bp-surface-filter-chip-surface-single-on-hover);
@@ -8072,7 +8081,7 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8072
8081
  letter-spacing:var(--bp-font-letter-spacing-01);
8073
8082
  line-height:var(--bp-font-line-height-04);
8074
8083
  }
8075
- .bp_chip_module_chip--1f41c[data-modern=true].bp_chip_module_chipButton--1f41c,.bp_chip_module_chip--1f41c[data-modern=true].bp_chip_module_multiSelectChip--1f41c{
8084
+ .bp_chip_module_chip--7e98e[data-modern=true].bp_chip_module_chipButton--7e98e,.bp_chip_module_chip--7e98e[data-modern=true].bp_chip_module_multiSelectChip--7e98e{
8076
8085
  font-family:var(--bp-font-font-family), -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
8077
8086
  font-size:var(--bp-font-size-05);
8078
8087
  font-style:normal;
@@ -8080,7 +8089,7 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8080
8089
  letter-spacing:var(--bp-font-letter-spacing-01);
8081
8090
  line-height:var(--bp-font-line-height-04);
8082
8091
  }
8083
- .bp_chip_module_chip--1f41c[data-modern=true].bp_chip_module_multiSelectChip--1f41c span::before,.bp_chip_module_chip--1f41c[data-modern=true].bp_chip_module_multiSelectChip--1f41c[data-state=on]{
8092
+ .bp_chip_module_chip--7e98e[data-modern=true].bp_chip_module_multiSelectChip--7e98e span::before,.bp_chip_module_chip--7e98e[data-modern=true].bp_chip_module_multiSelectChip--7e98e[data-state=on]{
8084
8093
  font-family:var(--bp-font-font-family), -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
8085
8094
  font-size:var(--bp-font-size-05);
8086
8095
  font-style:normal;
@@ -8088,7 +8097,7 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8088
8097
  letter-spacing:var(--bp-font-letter-spacing-01);
8089
8098
  line-height:var(--bp-font-line-height-04);
8090
8099
  }
8091
- .bp_chip_module_chip--1f41c[data-modern=true] .bp_chip_module_chipStatus--1f41c{
8100
+ .bp_chip_module_chip--7e98e[data-modern=true] .bp_chip_module_chipStatus--7e98e{
8092
8101
  font-family:var(--bp-font-font-family), -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
8093
8102
  font-size:var(--bp-font-size-02);
8094
8103
  font-style:normal;
@@ -8097,22 +8106,22 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8097
8106
  line-height:var(--bp-font-line-height-03);
8098
8107
  }
8099
8108
 
8100
- .bp_chip_module_chip--1f41c{
8109
+ .bp_chip_module_chip--7e98e{
8101
8110
  padding-inline:var(--chip-padding-inline);
8102
8111
  }
8103
- .bp_chip_module_chip--1f41c .bp_chip_module_labelText--1f41c:first-child{
8112
+ .bp_chip_module_chip--7e98e .bp_chip_module_labelText--7e98e:first-child{
8104
8113
  margin-inline-start:var(--chip-label-inline-padding);
8105
8114
  }
8106
- .bp_chip_module_chip--1f41c .bp_chip_module_labelText--1f41c:last-child{
8115
+ .bp_chip_module_chip--7e98e .bp_chip_module_labelText--7e98e:last-child{
8107
8116
  margin-inline-end:var(--chip-label-inline-padding);
8108
8117
  }
8109
- .bp_chip_module_chip--1f41c .bp_chip_module_chipStatus--1f41c:first-child,.bp_chip_module_chip--1f41c svg:first-child{
8118
+ .bp_chip_module_chip--7e98e .bp_chip_module_chipStatus--7e98e:first-child,.bp_chip_module_chip--7e98e svg:first-child{
8110
8119
  margin-inline-start:var(--chip-item-inline-padding);
8111
8120
  }
8112
- .bp_chip_module_chip--1f41c .bp_chip_module_chipStatus--1f41c:last-child,.bp_chip_module_chip--1f41c svg:last-child{
8121
+ .bp_chip_module_chip--7e98e .bp_chip_module_chipStatus--7e98e:last-child,.bp_chip_module_chip--7e98e svg:last-child{
8113
8122
  margin-inline-end:var(--chip-item-inline-padding);
8114
8123
  }
8115
- .bp_chip_module_chip--1f41c{
8124
+ .bp_chip_module_chip--7e98e{
8116
8125
  align-items:center;
8117
8126
  border:none;
8118
8127
  border-radius:var(--chip-radius);
@@ -8122,15 +8131,15 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8122
8131
  gap:var(--chip-gap);
8123
8132
  height:var(--chip-height);
8124
8133
  }
8125
- .bp_chip_module_chip--1f41c:disabled{
8134
+ .bp_chip_module_chip--7e98e:disabled{
8126
8135
  color:var(--chip-text-color-disabled);
8127
8136
  cursor:default;
8128
8137
  pointer-events:none;
8129
8138
  }
8130
- .bp_chip_module_chip--1f41c:disabled svg{
8139
+ .bp_chip_module_chip--7e98e:disabled svg{
8131
8140
  opacity:.4;
8132
8141
  }
8133
- .bp_chip_module_chip--1f41c .bp_chip_module_chipStatus--1f41c{
8142
+ .bp_chip_module_chip--7e98e .bp_chip_module_chipStatus--7e98e{
8134
8143
  align-items:center;
8135
8144
  background-color:var(--chip-status-background-default);
8136
8145
  border-radius:var(--chip-status-radius);
@@ -8142,91 +8151,100 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8142
8151
  justify-content:center;
8143
8152
  padding:var(--chip-status-padding);
8144
8153
  }
8145
- .bp_chip_module_chip--1f41c .bp_chip_module_labelText--1f41c{
8154
+ .bp_chip_module_chip--7e98e .bp_chip_module_labelText--7e98e{
8146
8155
  white-space:nowrap;
8147
8156
  }
8148
- .bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c:focus-visible{
8157
+ .bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e:focus-visible{
8149
8158
  box-shadow:0 0 0 var(--chip-button-outline-width) var(--chip-button-outline-width);
8150
8159
  outline:none;
8151
8160
  overflow:visible;
8152
8161
  }
8153
- .bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c{
8162
+ .bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e path{
8163
+ fill:var(--chip-button-icon-color);
8164
+ }
8165
+ .bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e{
8154
8166
  background-color:var(--chip-button-background);
8155
8167
  }
8156
- .bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c .bp_chip_module_chipStatus--1f41c{
8168
+ .bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e .bp_chip_module_chipStatus--7e98e{
8157
8169
  background-color:var(--chip-button-status-background);
8158
8170
  color:var(--chip-button-status-text-color);
8159
8171
  }
8160
- .bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c:focus-visible,.bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c[data-active-item]{
8172
+ .bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e:focus-visible,.bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e[data-active-item]{
8161
8173
  box-shadow:var(--chip-button-focus-box-shadow);
8162
8174
  outline:none;
8163
8175
  }
8164
- .bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c:disabled{
8176
+ .bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e:disabled{
8165
8177
  pointer-events:none;
8166
8178
  }
8167
- .bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c:disabled .bp_chip_module_chipStatus--1f41c,.bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c:disabled svg{
8179
+ .bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e:disabled .bp_chip_module_chipStatus--7e98e,.bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e:disabled svg{
8168
8180
  opacity:.4;
8169
8181
  }
8170
- .bp_chip_module_chip--1f41c.bp_chip_module_chipButton--1f41c:hover:enabled{
8182
+ .bp_chip_module_chip--7e98e.bp_chip_module_chipButton--7e98e:hover:enabled{
8171
8183
  background-color:var(--chip-button-background-hover);
8172
8184
  }
8173
- .bp_chip_module_chip--1f41c.bp_chip_module_singleSelectChip--1f41c{
8185
+ .bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e path{
8186
+ fill:var(--chip-single-select-icon-color);
8187
+ }
8188
+ .bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e{
8174
8189
  background-color:var(--chip-single-select-background);
8175
8190
  }
8176
- .bp_chip_module_chip--1f41c.bp_chip_module_singleSelectChip--1f41c[data-state=on]{
8191
+ .bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e[data-state=on] path{
8192
+ fill:var(--chip-single-select-text-color-selected);
8193
+ }
8194
+ .bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e[data-state=on]{
8177
8195
  background-color:var(--chip-single-select-background-selected);
8178
8196
  color:var(--chip-single-select-text-color-selected);
8179
8197
  }
8180
- .bp_chip_module_chip--1f41c.bp_chip_module_singleSelectChip--1f41c[data-state=on]:hover{
8198
+ .bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e[data-state=on]:hover{
8181
8199
  background-color:var(--chip-single-select-background-selected-hover);
8182
8200
  }
8183
- .bp_chip_module_chip--1f41c.bp_chip_module_singleSelectChip--1f41c[data-state=on] .bp_chip_module_chipStatus--1f41c{
8201
+ .bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e[data-state=on] .bp_chip_module_chipStatus--7e98e{
8184
8202
  color:var(--chip-single-select-status-text-color-selected);
8185
8203
  }
8186
- .bp_chip_module_chip--1f41c.bp_chip_module_singleSelectChip--1f41c:focus-visible,.bp_chip_module_chip--1f41c.bp_chip_module_singleSelectChip--1f41c[data-active-item]{
8204
+ .bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e:focus-visible,.bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e[data-active-item]{
8187
8205
  box-shadow:0 0 0 var(--border-2) var(--outline-focus-on-light);
8188
8206
  outline:var(--border-1) solid var(--gray-white);
8189
8207
  outline-offset:calc(var(--border-1)*-1);
8190
8208
  }
8191
- .bp_chip_module_chip--1f41c.bp_chip_module_singleSelectChip--1f41c:hover:not([data-state=on]){
8209
+ .bp_chip_module_chip--7e98e.bp_chip_module_singleSelectChip--7e98e:hover:not([data-state=on]){
8192
8210
  background-color:var(--chip-single-select-background-hover);
8193
8211
  }
8194
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c path{
8212
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e path{
8195
8213
  fill:var(--chip-multi-select-icon-color);
8196
8214
  }
8197
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c{
8215
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e{
8198
8216
  background-color:var(--chip-multi-select-background);
8199
8217
  }
8200
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c[data-state=on] path{
8218
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e[data-state=on] path{
8201
8219
  fill:var(--chip-multi-select-text-color-selected);
8202
8220
  }
8203
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c[data-state=on]{
8221
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e[data-state=on]{
8204
8222
  background-color:var(--chip-multi-select-background-selected);
8205
8223
  border:var(--chip-multi-select-border-selected);
8206
8224
  color:var(--chip-multi-select-text-color-selected);
8207
8225
  }
8208
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c[data-state=on]:hover{
8226
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e[data-state=on]:hover{
8209
8227
  background-color:var(--chip-multi-select-background-selected-hover);
8210
8228
  }
8211
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c[data-state=on]:focus-visible,.bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c[data-state=on][data-active-item]{
8229
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e[data-state=on]:focus-visible,.bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e[data-state=on][data-active-item]{
8212
8230
  border:var(--chip-multi-select-focus-border-selected);
8213
8231
  box-shadow:0 0 0 var(--border-2) var(--outline-focus-on-light);
8214
8232
  outline:var(--border-1) solid var(--chip-multi-select-border-color-selected);
8215
8233
  outline-offset:calc(var(--border-2)*-1);
8216
8234
  }
8217
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c[data-state=on] .bp_chip_module_chipStatus--1f41c{
8235
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e[data-state=on] .bp_chip_module_chipStatus--7e98e{
8218
8236
  background-color:var(--chip-multi-select-status-background-selected);
8219
8237
  color:var(--chip-multi-select-status-text-color-selected);
8220
8238
  }
8221
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c:focus-visible:not([data-state=on]),.bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c[data-active-item]:not([data-state=on]){
8239
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e:focus-visible:not([data-state=on]),.bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e[data-active-item]:not([data-state=on]){
8222
8240
  box-shadow:0 0 0 var(--border-2) var(--outline-focus-on-light);
8223
8241
  outline:var(--border-1) solid var(--gray-white);
8224
8242
  outline-offset:calc(var(--border-1)*-1);
8225
8243
  }
8226
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c:hover:not([data-state=on]){
8244
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e:hover:not([data-state=on]){
8227
8245
  background-color:var(--chip-multi-select-background-hover);
8228
8246
  }
8229
- .bp_chip_module_chip--1f41c.bp_chip_module_multiSelectChip--1f41c span::before{
8247
+ .bp_chip_module_chip--7e98e.bp_chip_module_multiSelectChip--7e98e span::before{
8230
8248
  content:attr(data-text);
8231
8249
  display:block;
8232
8250
  height:0;
@@ -8234,30 +8252,30 @@ table.bp_inline_table_module_inlineTable--fc100[data-modern=true] td:last-child,
8234
8252
  visibility:hidden;
8235
8253
  }
8236
8254
 
8237
- .bp_chip_module_chipsGroup--1f41c[data-modern=false]{
8255
+ .bp_chip_module_chipsGroup--7e98e[data-modern=false]{
8238
8256
  --chips-group-gap:var(--space-2);
8239
8257
  --chips-group-small-screen-padding:var(--space-5);
8240
8258
  }
8241
8259
 
8242
- .bp_chip_module_chipsGroup--1f41c[data-modern=true]{
8260
+ .bp_chip_module_chipsGroup--7e98e[data-modern=true]{
8243
8261
  --chips-group-gap:var(--bp-space-020);
8244
8262
  --chips-group-small-screen-padding:var(--bp-space-050);
8245
8263
  }
8246
8264
 
8247
- .bp_chip_module_chipsGroup--1f41c{
8265
+ .bp_chip_module_chipsGroup--7e98e{
8248
8266
  display:flex;
8249
8267
  flex-wrap:wrap;
8250
8268
  gap:var(--chips-group-gap);
8251
8269
  }
8252
8270
  @media (max-width: 767px){
8253
- .bp_chip_module_chipsGroup--1f41c{
8271
+ .bp_chip_module_chipsGroup--7e98e{
8254
8272
  -ms-overflow-style:none;
8255
8273
  scrollbar-width:none;
8256
8274
  }
8257
- .bp_chip_module_chipsGroup--1f41c::-webkit-scrollbar{
8275
+ .bp_chip_module_chipsGroup--7e98e::-webkit-scrollbar{
8258
8276
  display:none;
8259
8277
  }
8260
- .bp_chip_module_chipsGroup--1f41c{
8278
+ .bp_chip_module_chipsGroup--7e98e{
8261
8279
  flex-wrap:nowrap;
8262
8280
  overflow-x:scroll;
8263
8281
  padding:var(--chips-group-small-screen-padding);
@@ -1,4 +1,4 @@
1
1
  import '../../index.css';
2
- var styles = {"chip":"bp_chip_module_chip--1f41c","chipButton":"bp_chip_module_chipButton--1f41c","multiSelectChip":"bp_chip_module_multiSelectChip--1f41c","chipStatus":"bp_chip_module_chipStatus--1f41c","labelText":"bp_chip_module_labelText--1f41c","singleSelectChip":"bp_chip_module_singleSelectChip--1f41c","chipsGroup":"bp_chip_module_chipsGroup--1f41c"};
2
+ var styles = {"chip":"bp_chip_module_chip--7e98e","chipButton":"bp_chip_module_chipButton--7e98e","multiSelectChip":"bp_chip_module_multiSelectChip--7e98e","chipStatus":"bp_chip_module_chipStatus--7e98e","labelText":"bp_chip_module_labelText--7e98e","singleSelectChip":"bp_chip_module_singleSelectChip--7e98e","chipsGroup":"bp_chip_module_chipsGroup--7e98e"};
3
3
 
4
4
  export { styles as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@box/blueprint-web",
3
- "version": "12.108.4",
3
+ "version": "12.109.0",
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.15",
49
49
  "@ariakit/react-core": "0.4.15",
50
- "@box/blueprint-web-assets": "^4.89.3",
50
+ "@box/blueprint-web-assets": "^4.89.4",
51
51
  "@internationalized/date": "^3.7.0",
52
52
  "@radix-ui/react-accordion": "1.1.2",
53
53
  "@radix-ui/react-checkbox": "1.0.4",
@@ -77,7 +77,7 @@
77
77
  "type-fest": "^3.2.0"
78
78
  },
79
79
  "devDependencies": {
80
- "@box/storybook-utils": "^0.14.37",
80
+ "@box/storybook-utils": "^0.14.38",
81
81
  "@types/react": "^18.0.0",
82
82
  "@types/react-dom": "^18.0.0",
83
83
  "react": "^18.3.0",