@box/blueprint-web 13.18.0 → 14.0.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.
Files changed (59) hide show
  1. package/THIRD_PARTY_LICENSES +206 -27
  2. package/dist/lib-esm/button/button.d.ts +0 -2
  3. package/dist/lib-esm/button/button.js +2 -4
  4. package/dist/lib-esm/button/types.d.ts +0 -4
  5. package/dist/lib-esm/card-tooltip/card-tooltip.d.ts +3 -6
  6. package/dist/lib-esm/card-tooltip/card-tooltip.js +96 -42
  7. package/dist/lib-esm/card-tooltip/card-tooltip.module.js +1 -1
  8. package/dist/lib-esm/card-tooltip/types.d.ts +21 -36
  9. package/dist/lib-esm/combobox/chips-group.js +1 -5
  10. package/dist/lib-esm/combobox/types.d.ts +2 -2
  11. package/dist/lib-esm/combobox-group/combobox-group-combobox.js +0 -1
  12. package/dist/lib-esm/data-table/data-table-wrapper.js +2 -0
  13. package/dist/lib-esm/data-table/use-table-scroll-correction.d.ts +15 -0
  14. package/dist/lib-esm/data-table/use-table-scroll-correction.js +211 -0
  15. package/dist/lib-esm/empty-state/empty-state.d.ts +0 -2
  16. package/dist/lib-esm/guided-tooltip/guided-tooltip-footer.d.ts +0 -4
  17. package/dist/lib-esm/guided-tooltip/guided-tooltip.d.ts +0 -4
  18. package/dist/lib-esm/index.css +232 -360
  19. package/dist/lib-esm/index.d.ts +0 -3
  20. package/dist/lib-esm/index.js +0 -3
  21. package/dist/lib-esm/list-item/table-header-dropdown.js +1 -1
  22. package/dist/lib-esm/modal/alert-modal.d.ts +0 -4
  23. package/dist/lib-esm/modal/modal-footer.d.ts +0 -4
  24. package/dist/lib-esm/modal/modal.d.ts +0 -4
  25. package/dist/lib-esm/primitives/context-menu/context-menu.module.js +1 -1
  26. package/dist/lib-esm/primitives/dropdown-menu/dropdown-menu-checkbox-item.js +6 -6
  27. package/dist/lib-esm/primitives/dropdown-menu/dropdown-menu-item.js +4 -4
  28. package/dist/lib-esm/primitives/dropdown-menu/dropdown-menu-radio-select-item.js +6 -6
  29. package/dist/lib-esm/primitives/dropdown-menu/dropdown-menu.module.js +1 -1
  30. package/dist/lib-esm/primitives/select-menu-grid/select-menu-grid-option.js +0 -1
  31. package/dist/lib-esm/select/select.js +2 -6
  32. package/dist/lib-esm/select/select.module.js +1 -1
  33. package/dist/lib-esm/side-panel/side-panel-footer.d.ts +0 -4
  34. package/dist/lib-esm/side-panel/side-panel.d.ts +0 -4
  35. package/dist/lib-esm/tooltip/tooltip.d.ts +3 -2
  36. package/dist/lib-esm/tooltip/tooltip.js +2 -36
  37. package/dist/lib-esm/tooltip/types.d.ts +0 -9
  38. package/dist/lib-esm/util-components/base-grid-list-item/types.d.ts +2 -2
  39. package/dist/lib-esm/util-components/menu-item-sections/menu-item-sections.module.js +1 -1
  40. package/dist/lib-esm/utils/useMedia.js +13 -1
  41. package/package.json +14 -14
  42. package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.d.ts +0 -10
  43. package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.js +0 -119
  44. package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.module.js +0 -4
  45. package/dist/lib-esm/card-tooltip-v2/index.d.ts +0 -2
  46. package/dist/lib-esm/card-tooltip-v2/types.d.ts +0 -30
  47. package/dist/lib-esm/content-field/content-field.d.ts +0 -4
  48. package/dist/lib-esm/content-field/content-field.js +0 -126
  49. package/dist/lib-esm/content-field/content-field.module.js +0 -4
  50. package/dist/lib-esm/content-field/index.d.ts +0 -2
  51. package/dist/lib-esm/content-field/messages.d.ts +0 -7
  52. package/dist/lib-esm/content-field/messages.js +0 -8
  53. package/dist/lib-esm/content-field/types.d.ts +0 -35
  54. package/dist/lib-esm/util-components/focus-trap/focus-trap.d.ts +0 -2
  55. package/dist/lib-esm/util-components/focus-trap/focus-trap.js +0 -52
  56. package/dist/lib-esm/util-components/focus-trap/index.d.ts +0 -1
  57. package/dist/lib-esm/util-components/focus-trap/types.d.ts +0 -8
  58. package/dist/lib-esm/utils/useIsTriggerInteractive.d.ts +0 -4
  59. package/dist/lib-esm/utils/useIsTriggerInteractive.js +0 -21
@@ -1,119 +0,0 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import * as Ariakit from '@ariakit/react';
3
- import clsx from 'clsx';
4
- import { forwardRef, useRef, useLayoutEffect, useCallback } from 'react';
5
- import { useBlueprintModernization } from '../blueprint-modernization-context/useBlueprintModernization.js';
6
- import { Card } from '../card/card.js';
7
- import { composeEventHandlers } from '../utils/composeEventHandlers.js';
8
- import styles from './card-tooltip-v2.module.js';
9
-
10
- /**
11
- * CardTooltipV2 is a component that wraps a Card component inside a Tooltip component. The main difference between CardTooltipV2 and CardTooltip is that CardTooltipV2 uses Ariakit Tooltip component instead of Radix Tooltip component.
12
- *
13
- * You must only pass non-interactive content inside `content` prop.
14
- *
15
- * **IMPORTANT**: Must wrap interactive component/element (such as: HTMLInputElement, HTMLAnchorElement, HTMLTextAreaElement, etc. [list of focusable elements](https://allyjs.io/data-tables/focusable.html))
16
- *
17
- */
18
- const CardTooltipV2 = /*#__PURE__*/forwardRef((props, ref) => {
19
- const {
20
- children,
21
- content,
22
- setOpen,
23
- open,
24
- defaultOpen,
25
- className,
26
- skipTimeout,
27
- hideTooltipOnContentClick,
28
- hideOnInteractOutside,
29
- placement = 'bottom',
30
- elevation = 'dropshadow-3',
31
- addDelayOnFocus,
32
- ...contentProps
33
- } = props;
34
- const SHOW_TIMEOUT = 300;
35
- const tooltipStore = Ariakit.useTooltipStore({
36
- open,
37
- setOpen,
38
- defaultOpen,
39
- placement,
40
- showTimeout: SHOW_TIMEOUT,
41
- hideTimeout: 0,
42
- skipTimeout
43
- });
44
- const side = Ariakit.useStoreState(tooltipStore, 'currentPlacement').split('-')[0];
45
- const contentId = Ariakit.useStoreState(tooltipStore, state => state.contentElement?.id);
46
- const mounted = Ariakit.useStoreState(tooltipStore, 'mounted');
47
- const isOpen = Ariakit.useStoreState(tooltipStore, 'open');
48
- const focusTimeout = useRef(0);
49
- const {
50
- enableModernizedComponents
51
- } = useBlueprintModernization();
52
- useLayoutEffect(() => {
53
- if (mounted && !isOpen) {
54
- // Make sure that tooltip disappears instantly after it is closed.
55
- // Otherwise, once a tooltip is hovered, moving mouse to other tooltips
56
- // could open them without honoring `showTimeout`.
57
- tooltipStore.setState('animating', false);
58
- }
59
- }, [isOpen, mounted, tooltipStore]);
60
- const handleHideOnInteractOutside = useCallback(e => {
61
- if (typeof hideOnInteractOutside === 'function') {
62
- hideOnInteractOutside(e);
63
- }
64
- if (e.type === 'focusin') {
65
- const state = tooltipStore.getState();
66
- const contentElement = state?.contentElement;
67
- // If tooltip content is losing focus, do not hide it
68
- // since it can be stolen sometimes by elements outside of it.
69
- if (e?.relatedTarget === contentElement) {
70
- return false;
71
- }
72
- }
73
- return true;
74
- }, [hideOnInteractOutside, tooltipStore]);
75
- const handleOnFocusVisibleWithDelay = event => {
76
- event.preventDefault();
77
- event.currentTarget.setAttribute('data-focus-visible', 'true');
78
- focusTimeout.current = window.setTimeout(() => {
79
- tooltipStore?.setAnchorElement(event.currentTarget);
80
- tooltipStore?.show();
81
- }, SHOW_TIMEOUT);
82
- };
83
- const handleBlur = event => {
84
- event.currentTarget.removeAttribute('data-focus-visible');
85
- window.clearTimeout(focusTimeout.current);
86
- };
87
- return jsxs(Ariakit.TooltipProvider, {
88
- store: tooltipStore,
89
- children: [jsx(Ariakit.TooltipAnchor, {
90
- ...(mounted && {
91
- 'aria-describedby': contentId
92
- }),
93
- onClick: tooltipStore.hide,
94
- render: children,
95
- ...(addDelayOnFocus && {
96
- onFocusVisible: handleOnFocusVisibleWithDelay,
97
- onBlur: handleBlur
98
- })
99
- }), jsx(Ariakit.Tooltip, {
100
- ...contentProps,
101
- ...(hideTooltipOnContentClick && {
102
- onClick: composeEventHandlers(tooltipStore.hide, contentProps.onClick)
103
- }),
104
- ref: ref,
105
- className: clsx(styles.content, className),
106
- "data-modern": enableModernizedComponents ? 'true' : 'false',
107
- "data-side": side,
108
- fitViewport: true,
109
- gutter: 4,
110
- hideOnInteractOutside: handleHideOnInteractOutside,
111
- children: jsx(Card, {
112
- elevation: elevation,
113
- children: content
114
- })
115
- })]
116
- });
117
- });
118
-
119
- export { CardTooltipV2 };
@@ -1,4 +0,0 @@
1
- import '../index.css';
2
- var styles = {"content":"bp_card_tooltip_v2_module_content--0d2ae"};
3
-
4
- export { styles as default };
@@ -1,2 +0,0 @@
1
- export { CardTooltipV2 } from './card-tooltip-v2';
2
- export { type CardTooltipV2Props } from './types';
@@ -1,30 +0,0 @@
1
- import { type TooltipProps, type TooltipStoreProps } from '@ariakit/react';
2
- import { type ReactElement, type ReactNode } from 'react';
3
- import { type CardProps } from '../card/types';
4
- export interface CardTooltipV2Props extends Omit<TooltipProps, 'content' | 'ref'> {
5
- /**
6
- * If true, the tooltip will be opened with delay when user focuses on the anchor. Be mindful that are accessibility concerns when using this prop. It should only be used in cases where the content is purely decorative and does not convey important information that needs to be accessible to screen readers or assistive technologies.
7
- * @default false
8
- */
9
- addDelayOnFocus?: boolean;
10
- /** The anchor for the tooltip. */
11
- children: ReactElement;
12
- /** The content of the tooltip. */
13
- content: ReactNode;
14
- defaultOpen?: TooltipStoreProps['defaultOpen'];
15
- /**
16
- * The elevation of the Card inside.
17
- * @default dropshadow-3
18
- */
19
- elevation?: CardProps['elevation'];
20
- /**
21
- * If true, the tooltip will close itself when the content area is clicked.
22
- * @default false
23
- */
24
- hideTooltipOnContentClick?: boolean;
25
- open?: TooltipStoreProps['open'];
26
- placement?: TooltipStoreProps['placement'];
27
- portalElement?: TooltipProps['portalElement'];
28
- setOpen?: TooltipStoreProps['setOpen'];
29
- skipTimeout?: TooltipStoreProps['skipTimeout'];
30
- }
@@ -1,4 +0,0 @@
1
- import { type ContentFieldProps } from './types';
2
- export declare const contentFieldButtonTestId = "ContentField-button";
3
- /** @deprecated Use ContentField from @box/content-field package */
4
- export declare const ContentField: import("react").ForwardRefExoticComponent<ContentFieldProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -1,126 +0,0 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { Button } from '@ariakit/react';
3
- import { FolderShared } from '@box/blueprint-web-assets/icons/Content';
4
- import { XMark, Folder } from '@box/blueprint-web-assets/icons/Fill';
5
- import { Space6, Space4 } from '@box/blueprint-web-assets/tokens/tokens';
6
- import clsx from 'clsx';
7
- import { forwardRef, createRef } from 'react';
8
- import { InlineError } from '../primitives/inline-error/inline-error.js';
9
- import { useFullTextTooltip } from '../utils/useFullTextTooltip.js';
10
- import { useUniqueId } from '../utils/useUniqueId.js';
11
- import styles from './content-field.module.js';
12
- import { messages } from './messages.js';
13
-
14
- const ContentIconContainer = ({
15
- children
16
- }) => jsx("div", {
17
- className: styles.contentIconContainer,
18
- children: children
19
- });
20
- const ContentIcon = ({
21
- isSharedFolder,
22
- itemIcon
23
- }) => {
24
- if (itemIcon) {
25
- return itemIcon;
26
- }
27
- if (isSharedFolder) {
28
- return jsx(FolderShared, {
29
- "aria-label": messages.sharedFolderIconLabel,
30
- className: styles.contentIconShared,
31
- height: Space6,
32
- width: Space6
33
- });
34
- }
35
- return jsx(ContentIconContainer, {
36
- children: jsx(Folder, {
37
- "aria-label": messages.folderIconLabel,
38
- height: Space4,
39
- width: Space4
40
- })
41
- });
42
- };
43
- const handleOnClickClearButton = ({
44
- ref,
45
- onClickClearButton
46
- }) => e => {
47
- ref.current?.focus();
48
- onClickClearButton(e);
49
- };
50
- const contentFieldButtonTestId = 'ContentField-button';
51
- /** @deprecated Use ContentField from @box/content-field package */
52
- const ContentField = /*#__PURE__*/forwardRef(({
53
- clearButtonAriaLabel,
54
- itemIcon,
55
- hintText,
56
- isSharedFolder,
57
- onClick,
58
- onClickClearButton,
59
- title,
60
- error,
61
- ...rest
62
- }, forwardedRef) => {
63
- const labelRef = /*#__PURE__*/createRef();
64
- const {
65
- Wrapper: Tooltip,
66
- wrapperProps
67
- } = useFullTextTooltip({
68
- ref: labelRef,
69
- textValue: title ?? hintText
70
- });
71
- const inlineErrorId = useUniqueId('inline-error-');
72
- return jsxs("div", {
73
- className: styles.contentFieldWrapper,
74
- children: [jsxs("div", {
75
- className: styles.contentField,
76
- children: [jsx(Tooltip, {
77
- ...wrapperProps,
78
- children: jsxs(Button, {
79
- ref: forwardedRef,
80
- "aria-describedby": inlineErrorId,
81
- className: clsx(styles.contentButton, {
82
- [styles.hasSelection]: title,
83
- [styles.error]: !!error
84
- }),
85
- "data-testid": contentFieldButtonTestId,
86
- onClick: onClick,
87
- type: "button",
88
- ...rest,
89
- children: [jsx(ContentIcon, {
90
- isSharedFolder: isSharedFolder,
91
- itemIcon: itemIcon
92
- }), jsx("div", {
93
- className: styles.contentLabelWrapper,
94
- children: jsx("div", {
95
- ref: labelRef,
96
- className: styles.contentLabel,
97
- children: title ?? hintText
98
- })
99
- })]
100
- })
101
- }), title && jsx(Button, {
102
- "aria-label": clearButtonAriaLabel ?? messages.clearContentFieldButtonLabel,
103
- className: clsx(styles.clearButton, {
104
- [styles.hasSelection]: title,
105
- [styles.error]: !!error
106
- }),
107
- onClick: handleOnClickClearButton({
108
- ref: labelRef,
109
- onClickClearButton
110
- }),
111
- type: "button",
112
- children: jsx(XMark, {
113
- "aria-label": messages.clearContentFieldIconLabel,
114
- height: Space6,
115
- width: Space6
116
- })
117
- })]
118
- }), jsx(InlineError, {
119
- className: styles.inlineError,
120
- id: inlineErrorId,
121
- children: error
122
- })]
123
- });
124
- });
125
-
126
- export { ContentField, contentFieldButtonTestId };
@@ -1,4 +0,0 @@
1
- import '../index.css';
2
- var styles = {"contentFieldWrapper":"bp_content_field_module_contentFieldWrapper--67a59","contentField":"bp_content_field_module_contentField--67a59","inlineError":"bp_content_field_module_inlineError--67a59","contentButton":"bp_content_field_module_contentButton--67a59","error":"bp_content_field_module_error--67a59","hasSelection":"bp_content_field_module_hasSelection--67a59","contentIconContainer":"bp_content_field_module_contentIconContainer--67a59","contentIconShared":"bp_content_field_module_contentIconShared--67a59","contentLabelWrapper":"bp_content_field_module_contentLabelWrapper--67a59","contentLabel":"bp_content_field_module_contentLabel--67a59","clearButton":"bp_content_field_module_clearButton--67a59"};
3
-
4
- export { styles as default };
@@ -1,2 +0,0 @@
1
- export { ContentField } from './content-field';
2
- export { type ContentFieldProps } from './types';
@@ -1,7 +0,0 @@
1
- export declare const messages: {
2
- sharedFolderIconLabel: string;
3
- folderIconLabel: string;
4
- fileIconLabel: string;
5
- clearContentFieldButtonLabel: string;
6
- clearContentFieldIconLabel: string;
7
- };
@@ -1,8 +0,0 @@
1
- const messages = {
2
- sharedFolderIconLabel: 'Shared Folder Icon',
3
- folderIconLabel: 'Folder Icon',
4
- clearContentFieldButtonLabel: 'Clear Content Field',
5
- clearContentFieldIconLabel: 'Clear Content Field icon'
6
- };
7
-
8
- export { messages };
@@ -1,35 +0,0 @@
1
- import { type ReactElement } from 'react';
2
- export interface ContentFieldProps {
3
- /**
4
- * custom aria label for the content field clear button.
5
- */
6
- clearButtonAriaLabel?: string;
7
- /**
8
- * placeholder text for the content field.
9
- */
10
- hintText: string;
11
- /**
12
- * type of the selected content(document, folder, etc.)
13
- */
14
- itemIcon?: ReactElement;
15
- /**
16
- * whether or not the selected content is a shared folder.
17
- */
18
- isSharedFolder?: boolean;
19
- /**
20
- * callback used by consumer to open content picker or equivalent.
21
- */
22
- onClick: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
23
- /**
24
- * callback to clear selected content
25
- */
26
- onClickClearButton: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
27
- /**
28
- * title of the selected content selected content
29
- */
30
- title?: string;
31
- /**
32
- * The content of the error message
33
- */
34
- error?: React.ReactNode;
35
- }
@@ -1,2 +0,0 @@
1
- import { type FocusTrapProps } from './types';
2
- export declare const FocusTrap: ({ containerRef, children, customInitialFocus }: FocusTrapProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,52 +0,0 @@
1
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { useRef, useCallback, useEffect } from 'react';
3
- import tabbable from 'tabbable';
4
-
5
- // TODO(DISC-1141): write unit tests
6
- const FocusTrap = ({
7
- containerRef,
8
- children,
9
- customInitialFocus
10
- }) => {
11
- const previousFocusEl = useRef(null);
12
- const getTabbableElements = useCallback(() => {
13
- if (!containerRef.current) {
14
- throw new Error('Could not initialize focus-trapping - container is missing');
15
- }
16
- const tabbableEls = tabbable(containerRef.current);
17
- if (!tabbableEls.length) {
18
- throw new Error('Could not initialize focus-trapping - focusable elements are missing');
19
- }
20
- return tabbableEls;
21
- }, [containerRef]);
22
- const focusFirstTabbableElement = useCallback(() => {
23
- const tabbableEls = getTabbableElements();
24
- tabbableEls[0].focus();
25
- }, [getTabbableElements]);
26
- const focusLastTabbableElement = useCallback(() => {
27
- const tabbableEls = getTabbableElements();
28
- tabbableEls[tabbableEls.length - 1].focus();
29
- }, [getTabbableElements]);
30
- useEffect(() => {
31
- previousFocusEl.current = document.activeElement;
32
- customInitialFocus ? customInitialFocus(getTabbableElements()) : focusFirstTabbableElement();
33
- return () => {
34
- if (previousFocusEl.current) {
35
- previousFocusEl.current.focus();
36
- }
37
- };
38
- }, [customInitialFocus, focusFirstTabbableElement, getTabbableElements]);
39
- return jsxs(Fragment, {
40
- children: [jsx("i", {
41
- "aria-hidden": true,
42
- onFocus: focusLastTabbableElement,
43
- tabIndex: 0
44
- }), children, jsx("i", {
45
- "aria-hidden": true,
46
- onFocus: focusFirstTabbableElement,
47
- tabIndex: 0
48
- })]
49
- });
50
- };
51
-
52
- export { FocusTrap };
@@ -1 +0,0 @@
1
- export { FocusTrap } from './focus-trap';
@@ -1,8 +0,0 @@
1
- import { type MutableRefObject } from 'react';
2
- export interface FocusTrapProps {
3
- children: React.ReactNode;
4
- /** Reference to the container element */
5
- containerRef: MutableRefObject<HTMLDivElement | null>;
6
- /** Function to set the focus to a desired element when the focus trap is activated */
7
- customInitialFocus?: (tabbableEls: (HTMLElement | SVGElement)[]) => void;
8
- }
@@ -1,4 +0,0 @@
1
- /**
2
- * React helper hook, which checks interactivity of Tooltip trigger
3
- */
4
- export declare const useIsTriggerInteractive: () => import("react").RefObject<HTMLButtonElement>;
@@ -1,21 +0,0 @@
1
- import { useRef, useEffect } from 'react';
2
- import { isTabbable } from 'tabbable';
3
-
4
- /**
5
- * React helper hook, which checks interactivity of Tooltip trigger
6
- */
7
- const useIsTriggerInteractive = () => {
8
- // We assert button type for compatibility with ref type of radix trigger
9
- const triggerRef = useRef(null);
10
- useEffect(() => {
11
- const triggerElement = triggerRef.current;
12
- if (!triggerElement || !isTabbable(triggerElement)) {
13
- const tagName = triggerElement?.tagName ? `<${triggerElement.tagName}>`.toLowerCase() : 'element';
14
- /* eslint-disable-next-line no-console */
15
- console.error(`${tagName} which acts as a tooltip trigger is not interactive. Make sure that trigger element is focusable, visible, and with a tabindex !== -1. More about tooltip accessibility in the Design System Portal.`);
16
- }
17
- }, []);
18
- return triggerRef;
19
- };
20
-
21
- export { useIsTriggerInteractive };