@box/blueprint-web 13.19.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.
- package/THIRD_PARTY_LICENSES +206 -27
- package/dist/lib-esm/button/button.d.ts +0 -2
- package/dist/lib-esm/button/button.js +2 -4
- package/dist/lib-esm/button/types.d.ts +0 -4
- package/dist/lib-esm/card-tooltip/card-tooltip.d.ts +3 -6
- package/dist/lib-esm/card-tooltip/card-tooltip.js +96 -42
- package/dist/lib-esm/card-tooltip/card-tooltip.module.js +1 -1
- package/dist/lib-esm/card-tooltip/types.d.ts +21 -36
- package/dist/lib-esm/combobox/chips-group.js +1 -5
- package/dist/lib-esm/combobox/types.d.ts +2 -2
- package/dist/lib-esm/combobox-group/combobox-group-combobox.js +0 -1
- package/dist/lib-esm/data-table/data-table-wrapper.js +2 -0
- package/dist/lib-esm/data-table/use-table-scroll-correction.d.ts +15 -0
- package/dist/lib-esm/data-table/use-table-scroll-correction.js +211 -0
- package/dist/lib-esm/empty-state/empty-state.d.ts +0 -2
- package/dist/lib-esm/guided-tooltip/guided-tooltip-footer.d.ts +0 -4
- package/dist/lib-esm/guided-tooltip/guided-tooltip.d.ts +0 -4
- package/dist/lib-esm/index.css +49 -243
- package/dist/lib-esm/index.d.ts +0 -3
- package/dist/lib-esm/index.js +0 -3
- package/dist/lib-esm/list-item/table-header-dropdown.js +1 -1
- package/dist/lib-esm/modal/alert-modal.d.ts +0 -4
- package/dist/lib-esm/modal/modal-footer.d.ts +0 -4
- package/dist/lib-esm/modal/modal.d.ts +0 -4
- package/dist/lib-esm/primitives/context-menu/context-menu.module.js +1 -1
- package/dist/lib-esm/primitives/select-menu-grid/select-menu-grid-option.js +0 -1
- package/dist/lib-esm/side-panel/side-panel-footer.d.ts +0 -4
- package/dist/lib-esm/side-panel/side-panel.d.ts +0 -4
- package/dist/lib-esm/tooltip/tooltip.d.ts +3 -2
- package/dist/lib-esm/tooltip/tooltip.js +2 -36
- package/dist/lib-esm/tooltip/types.d.ts +0 -9
- package/dist/lib-esm/util-components/base-grid-list-item/types.d.ts +2 -2
- package/dist/lib-esm/utils/useMedia.js +13 -1
- package/package.json +14 -14
- package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.d.ts +0 -10
- package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.js +0 -119
- package/dist/lib-esm/card-tooltip-v2/card-tooltip-v2.module.js +0 -4
- package/dist/lib-esm/card-tooltip-v2/index.d.ts +0 -2
- package/dist/lib-esm/card-tooltip-v2/types.d.ts +0 -30
- package/dist/lib-esm/content-field/content-field.d.ts +0 -4
- package/dist/lib-esm/content-field/content-field.js +0 -126
- package/dist/lib-esm/content-field/content-field.module.js +0 -4
- package/dist/lib-esm/content-field/index.d.ts +0 -2
- package/dist/lib-esm/content-field/messages.d.ts +0 -7
- package/dist/lib-esm/content-field/messages.js +0 -8
- package/dist/lib-esm/content-field/types.d.ts +0 -35
- package/dist/lib-esm/util-components/focus-trap/focus-trap.d.ts +0 -2
- package/dist/lib-esm/util-components/focus-trap/focus-trap.js +0 -52
- package/dist/lib-esm/util-components/focus-trap/index.d.ts +0 -1
- package/dist/lib-esm/util-components/focus-trap/types.d.ts +0 -8
- package/dist/lib-esm/utils/useIsTriggerInteractive.d.ts +0 -4
- package/dist/lib-esm/utils/useIsTriggerInteractive.js +0 -21
|
@@ -7,23 +7,19 @@ export declare const SidePanel: ((props: SidePanelProps) => import("react/jsx-ru
|
|
|
7
7
|
Footer: import("react").ForwardRefExoticComponent<Omit<import("./types").SidePanelFooterProps, "ref"> & import("react").RefAttributes<HTMLDivElement>> & {
|
|
8
8
|
PrimaryButton: import("react").ForwardRefExoticComponent<(Omit<import("../primitives/base-button").BaseButtonInterface & Required<Pick<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
9
9
|
children?: string | string[];
|
|
10
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
11
10
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
12
11
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
13
12
|
}, "ref"> | Omit<import("../primitives/base-button").BaseButtonInterface & Partial<Record<keyof import("../primitives/base-button").Loading, never>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
14
13
|
children?: string | string[];
|
|
15
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
16
14
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
17
15
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
18
16
|
}, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
|
|
19
17
|
SecondaryButton: import("react").ForwardRefExoticComponent<(Omit<import("../primitives/base-button").BaseButtonInterface & Required<Pick<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
20
18
|
children?: string | string[];
|
|
21
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
22
19
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
23
20
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
24
21
|
}, "ref"> | Omit<import("../primitives/base-button").BaseButtonInterface & Partial<Record<keyof import("../primitives/base-button").Loading, never>> & Omit<import("../primitives/base-button").Loading, keyof import("../primitives/base-button").Loading> & {
|
|
25
22
|
children?: string | string[];
|
|
26
|
-
icon?: import("../button/types").SvgIconComponent;
|
|
27
23
|
endIcon?: import("../button/types").SvgIconComponent;
|
|
28
24
|
startIcon?: import("../button/types").SvgIconComponent;
|
|
29
25
|
}, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import * as RadixTooltip from '@radix-ui/react-tooltip';
|
|
1
2
|
import React from 'react';
|
|
2
|
-
import { type TooltipProps, type TooltipProviderProps
|
|
3
|
+
import { type TooltipProps, type TooltipProviderProps } from './types';
|
|
3
4
|
export declare const Tooltip: (props: TooltipProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
5
|
export declare const ContainerContext: React.Context<HTMLElement | null | undefined>;
|
|
5
6
|
export declare const TooltipProvider: (props: TooltipProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export declare const TooltipTrigger:
|
|
7
|
+
export declare const TooltipTrigger: typeof RadixTooltip.Trigger;
|
|
@@ -4,8 +4,6 @@ import * as RadixTooltip from '@radix-ui/react-tooltip';
|
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
import React__default, { useContext } from 'react';
|
|
6
6
|
import { useBlueprintModernization } from '../blueprint-modernization-context/useBlueprintModernization.js';
|
|
7
|
-
import { useForkRef } from '../utils/useForkRef.js';
|
|
8
|
-
import { useIsTriggerInteractive } from '../utils/useIsTriggerInteractive.js';
|
|
9
7
|
import styles from './tooltip.module.js';
|
|
10
8
|
|
|
11
9
|
/**
|
|
@@ -27,7 +25,6 @@ const Tooltip = props => {
|
|
|
27
25
|
open,
|
|
28
26
|
defaultOpen,
|
|
29
27
|
forceMount,
|
|
30
|
-
__checkInteractivity,
|
|
31
28
|
...contentProps
|
|
32
29
|
} = props;
|
|
33
30
|
const container = useContext(ContainerContext);
|
|
@@ -36,8 +33,6 @@ const Tooltip = props => {
|
|
|
36
33
|
onOpenChange: onOpenChange,
|
|
37
34
|
open: open,
|
|
38
35
|
children: [jsx(TooltipTrigger, {
|
|
39
|
-
__checkInteractivity: __checkInteractivity,
|
|
40
|
-
open: open,
|
|
41
36
|
children: children
|
|
42
37
|
}), jsx(RadixTooltip.Portal, {
|
|
43
38
|
container: container,
|
|
@@ -65,43 +60,14 @@ const TooltipProvider = props => {
|
|
|
65
60
|
})
|
|
66
61
|
});
|
|
67
62
|
};
|
|
68
|
-
const
|
|
63
|
+
const TooltipTrigger = /*#__PURE__*/React__default.forwardRef(function TooltipTrigger(props, ref) {
|
|
69
64
|
return jsx(RadixTooltip.Trigger, {
|
|
70
65
|
ref: ref,
|
|
71
66
|
asChild: true,
|
|
67
|
+
"data-blueprint-tooltip-trigger": "",
|
|
72
68
|
children: props.children
|
|
73
69
|
});
|
|
74
70
|
});
|
|
75
|
-
/**
|
|
76
|
-
* Trigger component with interactivity check.
|
|
77
|
-
* Encapsulation in separate component is a workaround which allows to render hooks
|
|
78
|
-
* responsible for check only when it's specifically needed, without breaking rule of hooks
|
|
79
|
-
* by calling them conditionally.
|
|
80
|
-
*/
|
|
81
|
-
const TriggerWithInteractivityCheck = /*#__PURE__*/React__default.forwardRef(function TriggerWithInteractivityCheck(props, ref) {
|
|
82
|
-
const triggerRef = useIsTriggerInteractive();
|
|
83
|
-
return jsx(Trigger, {
|
|
84
|
-
ref: useForkRef(triggerRef, ref),
|
|
85
|
-
children: props.children
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
const TooltipTrigger = /*#__PURE__*/React__default.forwardRef(({
|
|
89
|
-
children,
|
|
90
|
-
open,
|
|
91
|
-
__checkInteractivity = true
|
|
92
|
-
}, ref) => {
|
|
93
|
-
// in dev environment, if Tooltip open state is not explicitly controlled by user, check if it's used with interactive element
|
|
94
|
-
if (process.env.NODE_ENV !== 'production' && open === undefined && __checkInteractivity) {
|
|
95
|
-
return jsx(TriggerWithInteractivityCheck, {
|
|
96
|
-
ref: ref,
|
|
97
|
-
children: children
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
return jsx(Trigger, {
|
|
101
|
-
ref: ref,
|
|
102
|
-
children: children
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
71
|
const Arrow = /*#__PURE__*/React__default.forwardRef(function Arrow({
|
|
106
72
|
variant
|
|
107
73
|
}, ref) {
|
|
@@ -23,8 +23,6 @@ export interface TooltipProps extends Omit<React.ComponentProps<typeof RadixTool
|
|
|
23
23
|
defaultOpen?: RadixTooltip.TooltipProps['defaultOpen'];
|
|
24
24
|
/** Used to force mounting when more control is needed. */
|
|
25
25
|
forceMount?: RadixTooltip.TooltipPortalProps['forceMount'];
|
|
26
|
-
/** Blueprint internal prop. Checks whether the trigger element is interactive to provide a warning if it's not interactive. Defaults to `true`. */
|
|
27
|
-
__checkInteractivity?: boolean;
|
|
28
26
|
}
|
|
29
27
|
export interface TooltipProviderProps {
|
|
30
28
|
/** The rest of the application */
|
|
@@ -37,10 +35,3 @@ export interface TooltipProviderProps {
|
|
|
37
35
|
export interface ArrowProps {
|
|
38
36
|
variant: TooltipVariant;
|
|
39
37
|
}
|
|
40
|
-
export interface TooltipTriggerProps {
|
|
41
|
-
children?: React.ReactNode;
|
|
42
|
-
/** The controlled open state of the tooltip. */
|
|
43
|
-
open?: TooltipProps['open'];
|
|
44
|
-
/** Blueprint internal prop. Checks whether the trigger element is interactive to provide a warning if it's not interactive. Defaults to `true`. */
|
|
45
|
-
__checkInteractivity?: boolean;
|
|
46
|
-
}
|
|
@@ -99,9 +99,9 @@ export type BaseGridListThumbnailProps = ComponentPropsWithRef<'div'> & {
|
|
|
99
99
|
* fileExtension="xlsx"
|
|
100
100
|
* fileCategory="excel-spreadsheet"
|
|
101
101
|
* statusBadge={
|
|
102
|
-
* <
|
|
102
|
+
* <CardTooltip content="Classification: Confidential">
|
|
103
103
|
* <Status colorIndex={2} hideText icon={Shield} text="Confidential" />
|
|
104
|
-
* </
|
|
104
|
+
* </CardTooltip>
|
|
105
105
|
* }
|
|
106
106
|
* >
|
|
107
107
|
* <img src={thumbnailUrl} alt={fileName} />
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { useState, useEffect } from 'react';
|
|
2
2
|
|
|
3
|
+
const canUseMatchMedia = () => typeof window !== 'undefined' && typeof window.matchMedia === 'function';
|
|
3
4
|
const useMedia = query => {
|
|
4
|
-
|
|
5
|
+
// SSR-safe: use lazy initializer to defer window access
|
|
6
|
+
const [matches, setMatches] = useState(() => {
|
|
7
|
+
if (!canUseMatchMedia()) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
return window.matchMedia(query).matches;
|
|
11
|
+
});
|
|
5
12
|
useEffect(() => {
|
|
13
|
+
if (!canUseMatchMedia()) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
6
16
|
const mediaQueryList = window.matchMedia(query);
|
|
17
|
+
// Sync state on mount (handles SSR hydration mismatch)
|
|
18
|
+
setMatches(mediaQueryList.matches);
|
|
7
19
|
const onChange = e => setMatches(e.matches);
|
|
8
20
|
mediaQueryList.addEventListener('change', onChange);
|
|
9
21
|
return () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@box/blueprint-web",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"publishConfig": {
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"THIRD_PARTY_LICENSES"
|
|
12
12
|
],
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"react": "^
|
|
15
|
-
"react-dom": "^
|
|
14
|
+
"react": "^18.0.0",
|
|
15
|
+
"react-dom": "^18.0.0"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build-storybook": "nx run blueprint-web:build-storybook",
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@ariakit/react": "0.4.
|
|
49
|
-
"@ariakit/react-core": "0.4.
|
|
50
|
-
"@box/blueprint-web-assets": "^4.111.
|
|
51
|
-
"@internationalized/date": "^3.
|
|
48
|
+
"@ariakit/react": "0.4.21",
|
|
49
|
+
"@ariakit/react-core": "0.4.21",
|
|
50
|
+
"@box/blueprint-web-assets": "^4.111.15",
|
|
51
|
+
"@internationalized/date": "^3.12.0",
|
|
52
52
|
"@radix-ui/react-accordion": "1.1.2",
|
|
53
53
|
"@radix-ui/react-checkbox": "1.0.4",
|
|
54
54
|
"@radix-ui/react-collapsible": "1.0.3",
|
|
@@ -66,24 +66,24 @@
|
|
|
66
66
|
"@radix-ui/react-toggle-group": "1.0.4",
|
|
67
67
|
"@radix-ui/react-toolbar": "1.0.4",
|
|
68
68
|
"@radix-ui/react-tooltip": "1.0.7",
|
|
69
|
-
"@react-aria/i18n": "3.12.
|
|
70
|
-
"@react-aria/
|
|
69
|
+
"@react-aria/i18n": "3.12.16",
|
|
70
|
+
"@react-aria/interactions": "3.27.1",
|
|
71
|
+
"@react-aria/utils": "3.33.1",
|
|
71
72
|
"clsx": "^1.2.1",
|
|
72
73
|
"color": "2.0.1",
|
|
73
74
|
"lodash": "^4.17.15",
|
|
74
|
-
"react-aria": "3.
|
|
75
|
-
"react-aria-components": "1.
|
|
76
|
-
"tabbable": "^4.0.0",
|
|
75
|
+
"react-aria": "3.47.0",
|
|
76
|
+
"react-aria-components": "1.16.0",
|
|
77
77
|
"type-fest": "^3.2.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
|
-
"@box/storybook-utils": "^0.17.
|
|
80
|
+
"@box/storybook-utils": "^0.17.15",
|
|
81
81
|
"@figma/code-connect": "1.3.12",
|
|
82
82
|
"@types/react": "^18.0.0",
|
|
83
83
|
"@types/react-dom": "^18.0.0",
|
|
84
84
|
"react": "^18.3.0",
|
|
85
85
|
"react-dom": "^18.3.0",
|
|
86
|
-
"react-stately": "^3.
|
|
86
|
+
"react-stately": "^3.45.0",
|
|
87
87
|
"tsx": "^4.16.5"
|
|
88
88
|
}
|
|
89
89
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { type CardTooltipV2Props } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* 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.
|
|
4
|
-
*
|
|
5
|
-
* You must only pass non-interactive content inside `content` prop.
|
|
6
|
-
*
|
|
7
|
-
* **IMPORTANT**: Must wrap interactive component/element (such as: HTMLInputElement, HTMLAnchorElement, HTMLTextAreaElement, etc. [list of focusable elements](https://allyjs.io/data-tables/focusable.html))
|
|
8
|
-
*
|
|
9
|
-
*/
|
|
10
|
-
export declare const CardTooltipV2: import("react").ForwardRefExoticComponent<CardTooltipV2Props & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -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,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,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,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';
|