@amboss/design-system 1.19.1 → 1.20.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/build/cjs/src/components/Popover/Popover.js +22 -0
- package/build/cjs/src/components/Toggletip/BasePopover.js +144 -0
- package/build/cjs/src/components/Toggletip/Toggletip.js +8 -121
- package/build/cjs/src/components/Tooltip/TooltipContent.js +55 -26
- package/build/cjs/src/components/Tooltip/utils.js +23 -13
- package/build/cjs/src/index.js +2 -0
- package/build/esm/src/components/Popover/Popover.d.ts +6 -0
- package/build/esm/src/components/Popover/Popover.js +16 -0
- package/build/esm/src/components/Popover/Popover.js.map +1 -0
- package/build/esm/src/components/Toggletip/BasePopover.d.ts +16 -0
- package/build/esm/src/components/Toggletip/BasePopover.js +137 -0
- package/build/esm/src/components/Toggletip/BasePopover.js.map +1 -0
- package/build/esm/src/components/Toggletip/Toggletip.d.ts +5 -13
- package/build/esm/src/components/Toggletip/Toggletip.js +8 -121
- package/build/esm/src/components/Toggletip/Toggletip.js.map +1 -1
- package/build/esm/src/components/Tooltip/TooltipContent.d.ts +6 -1
- package/build/esm/src/components/Tooltip/TooltipContent.js +57 -28
- package/build/esm/src/components/Tooltip/TooltipContent.js.map +1 -1
- package/build/esm/src/components/Tooltip/utils.d.ts +3 -3
- package/build/esm/src/components/Tooltip/utils.js +22 -12
- package/build/esm/src/components/Tooltip/utils.js.map +1 -1
- package/build/esm/src/index.d.ts +1 -0
- package/build/esm/src/index.js +1 -0
- package/build/esm/src/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,20 +3,28 @@
|
|
|
3
3
|
const DISTANCE_FROM_TRIGGER = 4;
|
|
4
4
|
const ANIMATION_DISTANCE = 8;
|
|
5
5
|
const ARROW_SIZE = 6;
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
6
|
+
const ARROW_SIZE_BIG = 8;
|
|
7
|
+
const getArrowOffset = size => size * 2;
|
|
9
8
|
/**
|
|
10
9
|
* Get tooltip position and width
|
|
11
10
|
*/
|
|
12
|
-
function getTooltipStyle(placement
|
|
11
|
+
function getTooltipStyle(placement) {
|
|
12
|
+
let defaultVerticalPlacement = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "top";
|
|
13
|
+
let triggerRef = arguments.length > 2 ? arguments[2] : undefined;
|
|
14
|
+
let tooltipRef = arguments.length > 3 ? arguments[3] : undefined;
|
|
15
|
+
let document = arguments.length > 4 ? arguments[4] : undefined;
|
|
16
|
+
let window = arguments.length > 5 ? arguments[5] : undefined;
|
|
17
|
+
let arrowSize = arguments.length > 6 ? arguments[6] : undefined;
|
|
13
18
|
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
14
19
|
const tooltipRect = tooltipRef.current.getBoundingClientRect();
|
|
15
20
|
const viewportWidth = document.documentElement.clientWidth;
|
|
21
|
+
const viewportHeight = document.documentElement.clientHeight;
|
|
16
22
|
let top = 0;
|
|
17
23
|
let left = 0;
|
|
18
|
-
let verticalPlacement =
|
|
24
|
+
let verticalPlacement = defaultVerticalPlacement;
|
|
19
25
|
let horizontalPlacement = "center";
|
|
26
|
+
const arrowOffset = getArrowOffset(arrowSize);
|
|
27
|
+
const tooltipMargin = arrowSize + ANIMATION_DISTANCE + DISTANCE_FROM_TRIGGER;
|
|
20
28
|
switch (placement) {
|
|
21
29
|
case "top":
|
|
22
30
|
case "bottom":
|
|
@@ -33,9 +41,11 @@ function getTooltipStyle(placement, triggerRef, tooltipRef, document, window) {
|
|
|
33
41
|
break;
|
|
34
42
|
}
|
|
35
43
|
default:
|
|
36
|
-
// If there is no space
|
|
37
|
-
if (triggerRect.top < tooltipRect.height) {
|
|
44
|
+
// If there is no space for the default vertical position of the trigger place it on the opposite side
|
|
45
|
+
if (verticalPlacement === "top" && triggerRect.top < tooltipRect.height) {
|
|
38
46
|
verticalPlacement = "bottom";
|
|
47
|
+
} else if (verticalPlacement === "bottom" && triggerRect.bottom + tooltipRect.height > viewportHeight) {
|
|
48
|
+
verticalPlacement = "top";
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
// Check if we have space on the left for half of the tooltip width
|
|
@@ -51,16 +61,16 @@ function getTooltipStyle(placement, triggerRef, tooltipRef, document, window) {
|
|
|
51
61
|
}
|
|
52
62
|
}
|
|
53
63
|
if (verticalPlacement === "top") {
|
|
54
|
-
top = triggerRect.top - tooltipRect.height -
|
|
64
|
+
top = triggerRect.top - tooltipRect.height - tooltipMargin;
|
|
55
65
|
} else {
|
|
56
|
-
top = triggerRect.bottom +
|
|
66
|
+
top = triggerRect.bottom + tooltipMargin;
|
|
57
67
|
}
|
|
58
68
|
switch (horizontalPlacement) {
|
|
59
69
|
case "left":
|
|
60
|
-
left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width +
|
|
70
|
+
left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width + arrowOffset + arrowSize;
|
|
61
71
|
break;
|
|
62
72
|
case "right":
|
|
63
|
-
left = triggerRect.left + triggerRect.width / 2 -
|
|
73
|
+
left = triggerRect.left + triggerRect.width / 2 - arrowOffset - arrowSize;
|
|
64
74
|
break;
|
|
65
75
|
default:
|
|
66
76
|
left = triggerRect.left + triggerRect.width / 2;
|
|
@@ -74,8 +84,8 @@ function getTooltipStyle(placement, triggerRef, tooltipRef, document, window) {
|
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
exports.ANIMATION_DISTANCE = ANIMATION_DISTANCE;
|
|
77
|
-
exports.ARROW_OFFSET = ARROW_OFFSET;
|
|
78
87
|
exports.ARROW_SIZE = ARROW_SIZE;
|
|
88
|
+
exports.ARROW_SIZE_BIG = ARROW_SIZE_BIG;
|
|
79
89
|
exports.DISTANCE_FROM_TRIGGER = DISTANCE_FROM_TRIGGER;
|
|
80
|
-
exports.
|
|
90
|
+
exports.getArrowOffset = getArrowOffset;
|
|
81
91
|
exports.getTooltipStyle = getTooltipStyle;
|
package/build/cjs/src/index.js
CHANGED
|
@@ -50,6 +50,7 @@ var Tooltip = require('./components/Tooltip/Tooltip.js');
|
|
|
50
50
|
var Tag = require('./components/Tag/Tag.js');
|
|
51
51
|
var TagGroup = require('./components/TagGroup/TagGroup.js');
|
|
52
52
|
var Toggletip = require('./components/Toggletip/Toggletip.js');
|
|
53
|
+
var Popover = require('./components/Popover/Popover.js');
|
|
53
54
|
var UserHighlightTooltip = require('./components/UserHighlightTooltip/UserHighlightTooltip.js');
|
|
54
55
|
var Input = require('./components/Form/Input/Input.js');
|
|
55
56
|
var PasswordInput = require('./components/Form/PasswordInput/PasswordInput.js');
|
|
@@ -134,6 +135,7 @@ exports.MAX_TAG_WIDTH = Tag.MAX_TAG_WIDTH;
|
|
|
134
135
|
exports.Tag = Tag.Tag;
|
|
135
136
|
exports.TagGroup = TagGroup.TagGroup;
|
|
136
137
|
exports.Toggletip = Toggletip.Toggletip;
|
|
138
|
+
exports.Popover = Popover.Popover;
|
|
137
139
|
exports.UserHighlightTooltip = UserHighlightTooltip.UserHighlightTooltip;
|
|
138
140
|
exports.Input = Input.Input;
|
|
139
141
|
exports.PasswordInput = PasswordInput.PasswordInput;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { BasePopoverProps } from "../Toggletip/BasePopover";
|
|
3
|
+
import { TooltipContentProps } from "../Tooltip/TooltipContent";
|
|
4
|
+
import { TooltipConditionalProps } from "../Tooltip/types";
|
|
5
|
+
export type PopoverProps = Omit<BasePopoverProps, "contentPadding"> & TooltipConditionalProps & Pick<TooltipContentProps, "hideArrow">;
|
|
6
|
+
export declare function Popover(props: PopoverProps): React.ReactElement;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import _extends from '@babel/runtime/helpers/extends';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { BasePopover } from '../Toggletip/BasePopover.js';
|
|
4
|
+
|
|
5
|
+
function Popover(props) {
|
|
6
|
+
return /*#__PURE__*/React.createElement(BasePopover, _extends({
|
|
7
|
+
name: "Popover",
|
|
8
|
+
maxWidth: 400,
|
|
9
|
+
defaultVerticalPlacement: "bottom",
|
|
10
|
+
hasInvertedSubTheme: false,
|
|
11
|
+
borderRadius: "s"
|
|
12
|
+
}, props));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { Popover };
|
|
16
|
+
//# sourceMappingURL=Popover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover.js","sources":["../../../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { BasePopover, BasePopoverProps } from \"../Toggletip/BasePopover\";\nimport { TooltipContentProps } from \"../Tooltip/TooltipContent\";\nimport { TooltipConditionalProps } from \"../Tooltip/types\";\n\nexport type PopoverProps = Omit<BasePopoverProps, \"contentPadding\"> &\n TooltipConditionalProps &\n Pick<TooltipContentProps, \"hideArrow\">;\n\nexport function Popover(props: PopoverProps): React.ReactElement {\n return (\n <BasePopover\n name=\"Popover\"\n maxWidth={400}\n defaultVerticalPlacement=\"bottom\"\n hasInvertedSubTheme={false}\n borderRadius=\"s\"\n {...props} // eslint-disable-line react/jsx-props-no-spreading\n />\n );\n}\n"],"names":["Popover","props","React","createElement","BasePopover","_extends","name","maxWidth","defaultVerticalPlacement","hasInvertedSubTheme","borderRadius"],"mappings":";;;;AAUO,SAASA,OAAOA,CAACC,KAAmB,EAAsB;AAC/D,EAAA,oBACEC,KAAA,CAAAC,aAAA,CAACC,WAAW,EAAAC,QAAA,CAAA;AACVC,IAAAA,IAAI,EAAC,SAAS;AACdC,IAAAA,QAAQ,EAAE,GAAI;AACdC,IAAAA,wBAAwB,EAAC,QAAQ;AACjCC,IAAAA,mBAAmB,EAAE,KAAM;AAC3BC,IAAAA,YAAY,EAAC,GAAA;GACTT,EAAAA,KAAK,CACV,CAAC,CAAA;AAEN;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { ReactElement } from "react";
|
|
2
|
+
import type { TooltipContentProps } from "../Tooltip/TooltipContent";
|
|
3
|
+
import { TooltipConditionalProps } from "../Tooltip/types";
|
|
4
|
+
type BaseProps = Pick<TooltipContentProps, "placement" | "portalContainer" | "maxWidth" | "contentPadding" | "hideArrow" | "borderRadius" | "hasInvertedSubTheme"> & {
|
|
5
|
+
name?: string;
|
|
6
|
+
content: ReactElement;
|
|
7
|
+
"data-e2e-test-id"?: string;
|
|
8
|
+
isVisible?: boolean;
|
|
9
|
+
onVisibilityChange?: (isVisible: boolean) => void;
|
|
10
|
+
dismissOnOutsideClick?: boolean;
|
|
11
|
+
preventScroll?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type BasePopoverProps = BaseProps;
|
|
14
|
+
type BasePopoverInternalProps = BaseProps & TooltipConditionalProps & Pick<TooltipContentProps, "defaultVerticalPlacement">;
|
|
15
|
+
export declare function BasePopover({ placement, content, children, contentPadding, maxWidth, externalTriggerRef, portalContainer, name, isVisible: isPopoverVisible, dismissOnOutsideClick, "data-e2e-test-id": dataE2eTestId, hasInvertedSubTheme, defaultVerticalPlacement, onVisibilityChange, preventScroll, ...restContentProps }: BasePopoverInternalProps): React.ReactElement;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import _extends from '@babel/runtime/helpers/extends';
|
|
2
|
+
import React, { useMemo, useState, useRef, useCallback, useEffect } from 'react';
|
|
3
|
+
import FocusTrap from 'focus-trap-react';
|
|
4
|
+
import { TooltipContent } from '../Tooltip/TooltipContent.js';
|
|
5
|
+
|
|
6
|
+
const FocusTrapContent = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
7
|
+
let {
|
|
8
|
+
children
|
|
9
|
+
} = _ref;
|
|
10
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
11
|
+
ref: ref
|
|
12
|
+
}, children);
|
|
13
|
+
});
|
|
14
|
+
function BasePopover(_ref2) {
|
|
15
|
+
let {
|
|
16
|
+
placement = "auto",
|
|
17
|
+
content,
|
|
18
|
+
children,
|
|
19
|
+
contentPadding = "m",
|
|
20
|
+
maxWidth,
|
|
21
|
+
externalTriggerRef,
|
|
22
|
+
portalContainer,
|
|
23
|
+
name = "Popover",
|
|
24
|
+
isVisible: isPopoverVisible,
|
|
25
|
+
dismissOnOutsideClick = true,
|
|
26
|
+
"data-e2e-test-id": dataE2eTestId,
|
|
27
|
+
hasInvertedSubTheme,
|
|
28
|
+
defaultVerticalPlacement,
|
|
29
|
+
onVisibilityChange,
|
|
30
|
+
preventScroll = false,
|
|
31
|
+
...restContentProps
|
|
32
|
+
} = _ref2;
|
|
33
|
+
const tooltipId = useMemo(() => `DS${name}_${Math.floor(Date.now() * Math.random())}`, [name]);
|
|
34
|
+
const [isVisible, setVisible] = useState(isPopoverVisible);
|
|
35
|
+
const internalTriggerRef = useRef(null);
|
|
36
|
+
const triggerRef = externalTriggerRef || internalTriggerRef;
|
|
37
|
+
const isOutsideClickOnTrigger = useRef(false);
|
|
38
|
+
const toggleVisibility = useCallback(status => {
|
|
39
|
+
setVisible(status);
|
|
40
|
+
if (onVisibilityChange) {
|
|
41
|
+
onVisibilityChange(status);
|
|
42
|
+
}
|
|
43
|
+
}, [onVisibilityChange]);
|
|
44
|
+
|
|
45
|
+
// Outside click is also fired when the Popover is open and trigger is clicked. `isOutsideClickOnTrigger` saves this condition and we check for it so as to not toggle the Popover twice.
|
|
46
|
+
const handleTriggerClick = useCallback(() => {
|
|
47
|
+
if (!isOutsideClickOnTrigger.current) {
|
|
48
|
+
toggleVisibility(!isVisible);
|
|
49
|
+
} else {
|
|
50
|
+
// reset this value so that Popover can open in next click
|
|
51
|
+
isOutsideClickOnTrigger.current = false;
|
|
52
|
+
}
|
|
53
|
+
}, [toggleVisibility, isVisible]);
|
|
54
|
+
const handleClickOutsideDeactivates = useCallback(evt => {
|
|
55
|
+
if (triggerRef.current.contains(evt.target)) {
|
|
56
|
+
isOutsideClickOnTrigger.current = true;
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}, [triggerRef, isOutsideClickOnTrigger]);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
toggleVisibility(isPopoverVisible);
|
|
62
|
+
}, [isPopoverVisible, toggleVisibility]);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
let trigger;
|
|
65
|
+
if (externalTriggerRef?.current && !children) {
|
|
66
|
+
trigger = externalTriggerRef.current;
|
|
67
|
+
trigger.setAttribute("tabindex", "0");
|
|
68
|
+
trigger.addEventListener("click", handleTriggerClick);
|
|
69
|
+
}
|
|
70
|
+
return () => {
|
|
71
|
+
if (trigger) {
|
|
72
|
+
trigger.removeEventListener("click", handleTriggerClick);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}, [externalTriggerRef, children, handleTriggerClick]);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (externalTriggerRef?.current && !children) {
|
|
78
|
+
const trigger = externalTriggerRef.current;
|
|
79
|
+
if (isVisible) {
|
|
80
|
+
trigger.setAttribute("aria-expanded", true);
|
|
81
|
+
trigger.setAttribute("aria-controls", tooltipId);
|
|
82
|
+
} else {
|
|
83
|
+
trigger.removeAttribute("aria-expanded");
|
|
84
|
+
trigger.removeAttribute("aria-controls");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}, [externalTriggerRef, children, tooltipId, isVisible]);
|
|
88
|
+
const triggerElm = children ? /*#__PURE__*/React.cloneElement(children, {
|
|
89
|
+
ref: triggerRef,
|
|
90
|
+
...(isVisible && {
|
|
91
|
+
"aria-expanded": true,
|
|
92
|
+
"aria-controls": tooltipId
|
|
93
|
+
}),
|
|
94
|
+
tabIndex: 0,
|
|
95
|
+
onClick: evt => {
|
|
96
|
+
handleTriggerClick();
|
|
97
|
+
if (children.props.onClick) {
|
|
98
|
+
children.props.onClick(evt);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}) : null;
|
|
102
|
+
const contentElm = /*#__PURE__*/React.createElement(FocusTrap, {
|
|
103
|
+
focusTrapOptions: {
|
|
104
|
+
clickOutsideDeactivates: dismissOnOutsideClick && handleClickOutsideDeactivates,
|
|
105
|
+
// de-active focus trap on outside click
|
|
106
|
+
allowOutsideClick: true,
|
|
107
|
+
escapeDeactivates: true,
|
|
108
|
+
// de-activate focus trap on escape key
|
|
109
|
+
fallbackFocus: `#${tooltipId}`,
|
|
110
|
+
// set focus to tooltip content container if it has no focusable element
|
|
111
|
+
onDeactivate: () => {
|
|
112
|
+
toggleVisibility(false);
|
|
113
|
+
},
|
|
114
|
+
preventScroll
|
|
115
|
+
}
|
|
116
|
+
}, /*#__PURE__*/React.createElement(FocusTrapContent, null, content));
|
|
117
|
+
const tooltipElm = /*#__PURE__*/React.createElement(TooltipContent, _extends({}, restContentProps, {
|
|
118
|
+
// eslint-disable-line react/jsx-props-no-spreading
|
|
119
|
+
defaultVerticalPlacement: defaultVerticalPlacement,
|
|
120
|
+
dataDSId: name,
|
|
121
|
+
content: contentElm,
|
|
122
|
+
contentPadding: contentPadding,
|
|
123
|
+
maxWidth: maxWidth,
|
|
124
|
+
placement: placement,
|
|
125
|
+
portalContainer: portalContainer,
|
|
126
|
+
dataE2eTestId: dataE2eTestId,
|
|
127
|
+
hasInvertedSubTheme: hasInvertedSubTheme,
|
|
128
|
+
isVisible: isVisible,
|
|
129
|
+
tooltipId: tooltipId,
|
|
130
|
+
tabIndex: -1,
|
|
131
|
+
triggerRef: triggerRef
|
|
132
|
+
}));
|
|
133
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, triggerElm, tooltipElm);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { BasePopover };
|
|
137
|
+
//# sourceMappingURL=BasePopover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BasePopover.js","sources":["../../../../../src/components/Toggletip/BasePopover.tsx"],"sourcesContent":["import React, {\n useState,\n useRef,\n useEffect,\n useCallback,\n useMemo,\n ReactElement,\n PropsWithChildren,\n} from \"react\";\nimport FocusTrap from \"focus-trap-react\";\nimport type { TooltipContentProps } from \"../Tooltip/TooltipContent\";\nimport { TooltipContent } from \"../Tooltip/TooltipContent\";\nimport { TooltipConditionalProps } from \"../Tooltip/types\";\n\ntype BaseProps = Pick<\n TooltipContentProps,\n | \"placement\"\n | \"portalContainer\"\n | \"maxWidth\"\n | \"contentPadding\"\n | \"hideArrow\"\n | \"borderRadius\"\n | \"hasInvertedSubTheme\"\n> & {\n name?: string;\n // Popover content\n content: ReactElement;\n \"data-e2e-test-id\"?: string;\n // Programmatically toggle Popover visibility with this prop\n isVisible?: boolean;\n /* Called when tooltip appears and disappears */\n onVisibilityChange?: (isVisible: boolean) => void;\n /* Controls whether BasePopover closes on outside click */\n dismissOnOutsideClick?: boolean;\n preventScroll?: boolean;\n};\n\nexport type BasePopoverProps = BaseProps;\n\ntype BasePopoverInternalProps = BaseProps &\n TooltipConditionalProps &\n Pick<TooltipContentProps, \"defaultVerticalPlacement\">;\n\nconst FocusTrapContent = React.forwardRef<\n HTMLDivElement,\n PropsWithChildren<unknown>\n>(({ children }, ref) => <div ref={ref}>{children}</div>);\n\nexport function BasePopover({\n placement = \"auto\",\n content,\n children,\n contentPadding = \"m\",\n maxWidth,\n externalTriggerRef,\n portalContainer,\n name = \"Popover\",\n isVisible: isPopoverVisible,\n dismissOnOutsideClick = true,\n \"data-e2e-test-id\": dataE2eTestId,\n hasInvertedSubTheme,\n defaultVerticalPlacement,\n onVisibilityChange,\n preventScroll = false,\n ...restContentProps\n}: BasePopoverInternalProps): React.ReactElement {\n const tooltipId = useMemo(\n () => `DS${name}_${Math.floor(Date.now() * Math.random())}`,\n [name]\n );\n const [isVisible, setVisible] = useState(isPopoverVisible);\n const internalTriggerRef = useRef(null);\n const triggerRef = externalTriggerRef || internalTriggerRef;\n const isOutsideClickOnTrigger = useRef(false);\n\n const toggleVisibility = useCallback(\n (status: boolean) => {\n setVisible(status);\n\n if (onVisibilityChange) {\n onVisibilityChange(status);\n }\n },\n [onVisibilityChange]\n );\n\n // Outside click is also fired when the Popover is open and trigger is clicked. `isOutsideClickOnTrigger` saves this condition and we check for it so as to not toggle the Popover twice.\n const handleTriggerClick = useCallback(() => {\n if (!isOutsideClickOnTrigger.current) {\n toggleVisibility(!isVisible);\n } else {\n // reset this value so that Popover can open in next click\n isOutsideClickOnTrigger.current = false;\n }\n }, [toggleVisibility, isVisible]);\n\n const handleClickOutsideDeactivates = useCallback(\n (evt) => {\n if (triggerRef.current.contains(evt.target)) {\n isOutsideClickOnTrigger.current = true;\n }\n return true;\n },\n [triggerRef, isOutsideClickOnTrigger]\n );\n\n useEffect(() => {\n toggleVisibility(isPopoverVisible);\n }, [isPopoverVisible, toggleVisibility]);\n\n useEffect(() => {\n let trigger: HTMLElement;\n\n if (externalTriggerRef?.current && !children) {\n trigger = externalTriggerRef.current;\n\n trigger.setAttribute(\"tabindex\", \"0\");\n trigger.addEventListener(\"click\", handleTriggerClick);\n }\n\n return () => {\n if (trigger) {\n trigger.removeEventListener(\"click\", handleTriggerClick);\n }\n };\n }, [externalTriggerRef, children, handleTriggerClick]);\n\n useEffect(() => {\n if (externalTriggerRef?.current && !children) {\n const trigger = externalTriggerRef.current;\n\n if (isVisible) {\n trigger.setAttribute(\"aria-expanded\", true);\n trigger.setAttribute(\"aria-controls\", tooltipId);\n } else {\n trigger.removeAttribute(\"aria-expanded\");\n trigger.removeAttribute(\"aria-controls\");\n }\n }\n }, [externalTriggerRef, children, tooltipId, isVisible]);\n\n const triggerElm = children\n ? React.cloneElement(children, {\n ref: triggerRef,\n ...(isVisible && {\n \"aria-expanded\": true,\n \"aria-controls\": tooltipId,\n }),\n tabIndex: 0,\n onClick: (evt: React.MouseEvent) => {\n handleTriggerClick();\n if (children.props.onClick) {\n children.props.onClick(evt);\n }\n },\n })\n : null;\n\n const contentElm = (\n <FocusTrap\n focusTrapOptions={{\n clickOutsideDeactivates:\n dismissOnOutsideClick && handleClickOutsideDeactivates, // de-active focus trap on outside click\n allowOutsideClick: true,\n escapeDeactivates: true, // de-activate focus trap on escape key\n fallbackFocus: `#${tooltipId}`, // set focus to tooltip content container if it has no focusable element\n onDeactivate: () => {\n toggleVisibility(false);\n },\n preventScroll,\n }}\n >\n <FocusTrapContent>{content}</FocusTrapContent>\n </FocusTrap>\n );\n\n const tooltipElm = (\n <TooltipContent\n {...restContentProps} // eslint-disable-line react/jsx-props-no-spreading\n defaultVerticalPlacement={defaultVerticalPlacement}\n dataDSId={name}\n content={contentElm}\n contentPadding={contentPadding}\n maxWidth={maxWidth}\n placement={placement}\n portalContainer={portalContainer}\n dataE2eTestId={dataE2eTestId}\n hasInvertedSubTheme={hasInvertedSubTheme}\n isVisible={isVisible}\n tooltipId={tooltipId}\n tabIndex={-1}\n triggerRef={triggerRef}\n />\n );\n return (\n <>\n {triggerElm}\n {tooltipElm}\n </>\n );\n}\n"],"names":["FocusTrapContent","React","forwardRef","_ref","ref","children","createElement","BasePopover","_ref2","placement","content","contentPadding","maxWidth","externalTriggerRef","portalContainer","name","isVisible","isPopoverVisible","dismissOnOutsideClick","dataE2eTestId","hasInvertedSubTheme","defaultVerticalPlacement","onVisibilityChange","preventScroll","restContentProps","tooltipId","useMemo","Math","floor","Date","now","random","setVisible","useState","internalTriggerRef","useRef","triggerRef","isOutsideClickOnTrigger","toggleVisibility","useCallback","status","handleTriggerClick","current","handleClickOutsideDeactivates","evt","contains","target","useEffect","trigger","setAttribute","addEventListener","removeEventListener","removeAttribute","triggerElm","cloneElement","tabIndex","onClick","props","contentElm","FocusTrap","focusTrapOptions","clickOutsideDeactivates","allowOutsideClick","escapeDeactivates","fallbackFocus","onDeactivate","tooltipElm","TooltipContent","_extends","dataDSId","Fragment"],"mappings":"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"}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
"data-e2e-test-id"?: string;
|
|
7
|
-
isVisible?: boolean;
|
|
8
|
-
onVisibilityChange?: (isVisible: boolean) => void;
|
|
9
|
-
dismissOnOutsideClick?: boolean;
|
|
10
|
-
};
|
|
11
|
-
export type ToggletipProps = BaseProps & TooltipConditionalProps;
|
|
12
|
-
export declare function Toggletip({ placement, content, children, contentPadding, maxWidth, externalTriggerRef, portalContainer, isVisible: isToggletipVisible, dismissOnOutsideClick, "data-e2e-test-id": dataE2eTestId, onVisibilityChange, }: ToggletipProps): React.ReactElement;
|
|
13
|
-
export {};
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { BasePopoverProps } from "./BasePopover";
|
|
3
|
+
import { TooltipConditionalProps } from "../Tooltip/types";
|
|
4
|
+
export type ToggletipProps = BasePopoverProps & TooltipConditionalProps;
|
|
5
|
+
export declare function Toggletip(props: ToggletipProps): React.ReactElement;
|
|
@@ -1,125 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import _extends from '@babel/runtime/helpers/extends';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { BasePopover } from './BasePopover.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
ref: ref
|
|
11
|
-
}, children);
|
|
12
|
-
});
|
|
13
|
-
function Toggletip(_ref2) {
|
|
14
|
-
let {
|
|
15
|
-
placement = "auto",
|
|
16
|
-
content,
|
|
17
|
-
children,
|
|
18
|
-
contentPadding = "m",
|
|
19
|
-
maxWidth,
|
|
20
|
-
externalTriggerRef,
|
|
21
|
-
portalContainer,
|
|
22
|
-
isVisible: isToggletipVisible,
|
|
23
|
-
dismissOnOutsideClick = true,
|
|
24
|
-
"data-e2e-test-id": dataE2eTestId,
|
|
25
|
-
onVisibilityChange
|
|
26
|
-
} = _ref2;
|
|
27
|
-
const tooltipId = useMemo(() => `DSToggletip_${Math.floor(Date.now() * Math.random())}`, []);
|
|
28
|
-
const [isVisible, setVisible] = useState(isToggletipVisible);
|
|
29
|
-
const internalTriggerRef = useRef(null);
|
|
30
|
-
const triggerRef = externalTriggerRef || internalTriggerRef;
|
|
31
|
-
const isOutsideClickOnTrigger = useRef(false);
|
|
32
|
-
const toggleVisibility = useCallback(status => {
|
|
33
|
-
setVisible(status);
|
|
34
|
-
if (onVisibilityChange) {
|
|
35
|
-
onVisibilityChange(status);
|
|
36
|
-
}
|
|
37
|
-
}, [onVisibilityChange]);
|
|
38
|
-
|
|
39
|
-
// Outside click is also fired when the Toggletip is open and trigger is clicked. `isOutsideClickOnTrigger` saves this condition and we check for it so as to not toggle the Toggletip twice.
|
|
40
|
-
const handleTriggerClick = useCallback(() => {
|
|
41
|
-
if (!isOutsideClickOnTrigger.current) {
|
|
42
|
-
toggleVisibility(!isVisible);
|
|
43
|
-
} else {
|
|
44
|
-
// reset this value so that Toggletip can open in next click
|
|
45
|
-
isOutsideClickOnTrigger.current = false;
|
|
46
|
-
}
|
|
47
|
-
}, [toggleVisibility, isVisible]);
|
|
48
|
-
const handleClickOutsideDeactivates = useCallback(evt => {
|
|
49
|
-
if (triggerRef.current.contains(evt.target)) {
|
|
50
|
-
isOutsideClickOnTrigger.current = true;
|
|
51
|
-
}
|
|
52
|
-
return true;
|
|
53
|
-
}, [triggerRef, isOutsideClickOnTrigger]);
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
toggleVisibility(isToggletipVisible);
|
|
56
|
-
}, [isToggletipVisible, toggleVisibility]);
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
let trigger;
|
|
59
|
-
if (externalTriggerRef?.current && !children) {
|
|
60
|
-
trigger = externalTriggerRef.current;
|
|
61
|
-
trigger.setAttribute("tabindex", "0");
|
|
62
|
-
trigger.addEventListener("click", handleTriggerClick);
|
|
63
|
-
}
|
|
64
|
-
return () => {
|
|
65
|
-
if (trigger) {
|
|
66
|
-
trigger.removeEventListener("click", handleTriggerClick);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
}, [externalTriggerRef, children, handleTriggerClick]);
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
if (externalTriggerRef?.current && !children) {
|
|
72
|
-
const trigger = externalTriggerRef.current;
|
|
73
|
-
if (isVisible) {
|
|
74
|
-
trigger.setAttribute("aria-expanded", true);
|
|
75
|
-
trigger.setAttribute("aria-controls", tooltipId);
|
|
76
|
-
} else {
|
|
77
|
-
trigger.removeAttribute("aria-expanded");
|
|
78
|
-
trigger.removeAttribute("aria-controls");
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}, [externalTriggerRef, children, tooltipId, isVisible]);
|
|
82
|
-
const triggerElm = children ? /*#__PURE__*/React.cloneElement(children, {
|
|
83
|
-
ref: triggerRef,
|
|
84
|
-
...(isVisible && {
|
|
85
|
-
"aria-expanded": true,
|
|
86
|
-
"aria-controls": tooltipId
|
|
87
|
-
}),
|
|
88
|
-
tabIndex: 0,
|
|
89
|
-
onClick: evt => {
|
|
90
|
-
handleTriggerClick();
|
|
91
|
-
if (children.props.onClick) {
|
|
92
|
-
children.props.onClick(evt);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}) : null;
|
|
96
|
-
const contentElm = /*#__PURE__*/React.createElement(FocusTrap, {
|
|
97
|
-
focusTrapOptions: {
|
|
98
|
-
clickOutsideDeactivates: dismissOnOutsideClick && handleClickOutsideDeactivates,
|
|
99
|
-
// de-active focus trap on outside click
|
|
100
|
-
allowOutsideClick: true,
|
|
101
|
-
escapeDeactivates: true,
|
|
102
|
-
// de-activate focus trap on escape key
|
|
103
|
-
fallbackFocus: `#${tooltipId}`,
|
|
104
|
-
// set focus to tooltip content container if it has no focusable element
|
|
105
|
-
onDeactivate: () => {
|
|
106
|
-
toggleVisibility(false);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}, /*#__PURE__*/React.createElement(FocusTrapContent, null, content));
|
|
110
|
-
const tooltipElm = /*#__PURE__*/React.createElement(TooltipContent, {
|
|
111
|
-
dataDSId: "Toggletip",
|
|
112
|
-
content: contentElm,
|
|
113
|
-
contentPadding: contentPadding,
|
|
114
|
-
maxWidth: maxWidth,
|
|
115
|
-
placement: placement,
|
|
116
|
-
portalContainer: portalContainer,
|
|
117
|
-
dataE2eTestId: dataE2eTestId,
|
|
118
|
-
isVisible: isVisible,
|
|
119
|
-
tooltipId: tooltipId,
|
|
120
|
-
triggerRef: triggerRef
|
|
121
|
-
});
|
|
122
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, triggerElm, tooltipElm);
|
|
5
|
+
function Toggletip(props) {
|
|
6
|
+
return /*#__PURE__*/React.createElement(BasePopover, _extends({
|
|
7
|
+
name: "Toggletip",
|
|
8
|
+
defaultVerticalPlacement: "top"
|
|
9
|
+
}, props));
|
|
123
10
|
}
|
|
124
11
|
|
|
125
12
|
export { Toggletip };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toggletip.js","sources":["../../../../../src/components/Toggletip/Toggletip.tsx"],"sourcesContent":["import React, {\n useState,\n useRef,\n useEffect,\n useCallback,\n useMemo,\n ReactElement,\n PropsWithChildren,\n} from \"react\";\nimport FocusTrap from \"focus-trap-react\";\nimport type { TooltipContentProps } from \"../Tooltip/TooltipContent\";\nimport { TooltipContent } from \"../Tooltip/TooltipContent\";\nimport type { TooltipConditionalProps } from \"../Tooltip/types\";\n\ntype BaseProps = Pick<\n TooltipContentProps,\n \"placement\" | \"portalContainer\" | \"contentPadding\" | \"maxWidth\"\n> & {\n // Toggletip content\n content: ReactElement;\n \"data-e2e-test-id\"?: string;\n // Programmatically toggle Toggletip visibility with this prop\n isVisible?: boolean;\n /* Called when Toggletip appears and disappears */\n onVisibilityChange?: (isVisible: boolean) => void;\n /* Controls whether Toggletip closes on outside click */\n dismissOnOutsideClick?: boolean;\n};\n\nexport type ToggletipProps = BaseProps & TooltipConditionalProps;\n\nconst FocusTrapContent = React.forwardRef<\n HTMLDivElement,\n PropsWithChildren<unknown>\n>(({ children }, ref) => <div ref={ref}>{children}</div>);\n\nexport function Toggletip({\n placement = \"auto\",\n content,\n children,\n contentPadding = \"m\",\n maxWidth,\n externalTriggerRef,\n portalContainer,\n isVisible: isToggletipVisible,\n dismissOnOutsideClick = true,\n \"data-e2e-test-id\": dataE2eTestId,\n onVisibilityChange,\n}: ToggletipProps): React.ReactElement {\n const tooltipId = useMemo(\n () => `DSToggletip_${Math.floor(Date.now() * Math.random())}`,\n []\n );\n const [isVisible, setVisible] = useState(isToggletipVisible);\n const internalTriggerRef = useRef(null);\n const triggerRef = externalTriggerRef || internalTriggerRef;\n const isOutsideClickOnTrigger = useRef(false);\n\n const toggleVisibility = useCallback(\n (status: boolean) => {\n setVisible(status);\n\n if (onVisibilityChange) {\n onVisibilityChange(status);\n }\n },\n [onVisibilityChange]\n );\n\n // Outside click is also fired when the Toggletip is open and trigger is clicked. `isOutsideClickOnTrigger` saves this condition and we check for it so as to not toggle the Toggletip twice.\n const handleTriggerClick = useCallback(() => {\n if (!isOutsideClickOnTrigger.current) {\n toggleVisibility(!isVisible);\n } else {\n // reset this value so that Toggletip can open in next click\n isOutsideClickOnTrigger.current = false;\n }\n }, [toggleVisibility, isVisible]);\n\n const handleClickOutsideDeactivates = useCallback(\n (evt) => {\n if (triggerRef.current.contains(evt.target)) {\n isOutsideClickOnTrigger.current = true;\n }\n return true;\n },\n [triggerRef, isOutsideClickOnTrigger]\n );\n\n useEffect(() => {\n toggleVisibility(isToggletipVisible);\n }, [isToggletipVisible, toggleVisibility]);\n\n useEffect(() => {\n let trigger: HTMLElement;\n\n if (externalTriggerRef?.current && !children) {\n trigger = externalTriggerRef.current;\n\n trigger.setAttribute(\"tabindex\", \"0\");\n trigger.addEventListener(\"click\", handleTriggerClick);\n }\n\n return () => {\n if (trigger) {\n trigger.removeEventListener(\"click\", handleTriggerClick);\n }\n };\n }, [externalTriggerRef, children, handleTriggerClick]);\n\n useEffect(() => {\n if (externalTriggerRef?.current && !children) {\n const trigger = externalTriggerRef.current;\n\n if (isVisible) {\n trigger.setAttribute(\"aria-expanded\", true);\n trigger.setAttribute(\"aria-controls\", tooltipId);\n } else {\n trigger.removeAttribute(\"aria-expanded\");\n trigger.removeAttribute(\"aria-controls\");\n }\n }\n }, [externalTriggerRef, children, tooltipId, isVisible]);\n\n const triggerElm = children\n ? React.cloneElement(children, {\n ref: triggerRef,\n ...(isVisible && {\n \"aria-expanded\": true,\n \"aria-controls\": tooltipId,\n }),\n tabIndex: 0,\n onClick: (evt: React.MouseEvent) => {\n handleTriggerClick();\n if (children.props.onClick) {\n children.props.onClick(evt);\n }\n },\n })\n : null;\n\n const contentElm = (\n <FocusTrap\n focusTrapOptions={{\n clickOutsideDeactivates:\n dismissOnOutsideClick && handleClickOutsideDeactivates, // de-active focus trap on outside click\n allowOutsideClick: true,\n escapeDeactivates: true, // de-activate focus trap on escape key\n fallbackFocus: `#${tooltipId}`, // set focus to tooltip content container if it has no focusable element\n onDeactivate: () => {\n toggleVisibility(false);\n },\n }}\n >\n <FocusTrapContent>{content}</FocusTrapContent>\n </FocusTrap>\n );\n const tooltipElm = (\n <TooltipContent\n dataDSId=\"Toggletip\"\n content={contentElm}\n contentPadding={contentPadding}\n maxWidth={maxWidth}\n placement={placement}\n portalContainer={portalContainer}\n dataE2eTestId={dataE2eTestId}\n isVisible={isVisible}\n tooltipId={tooltipId}\n triggerRef={triggerRef}\n />\n );\n\n return (\n <>\n {triggerElm}\n {tooltipElm}\n </>\n );\n}\n"],"names":["FocusTrapContent","React","forwardRef","_ref","ref","children","createElement","Toggletip","_ref2","placement","content","contentPadding","maxWidth","externalTriggerRef","portalContainer","isVisible","isToggletipVisible","dismissOnOutsideClick","dataE2eTestId","onVisibilityChange","tooltipId","useMemo","Math","floor","Date","now","random","setVisible","useState","internalTriggerRef","useRef","triggerRef","isOutsideClickOnTrigger","toggleVisibility","useCallback","status","handleTriggerClick","current","handleClickOutsideDeactivates","evt","contains","target","useEffect","trigger","setAttribute","addEventListener","removeEventListener","removeAttribute","triggerElm","cloneElement","tabIndex","onClick","props","contentElm","FocusTrap","focusTrapOptions","clickOutsideDeactivates","allowOutsideClick","escapeDeactivates","fallbackFocus","onDeactivate","tooltipElm","TooltipContent","dataDSId","Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Toggletip.js","sources":["../../../../../src/components/Toggletip/Toggletip.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { BasePopover, BasePopoverProps } from \"./BasePopover\";\nimport { TooltipConditionalProps } from \"../Tooltip/types\";\n\nexport type ToggletipProps = BasePopoverProps & TooltipConditionalProps;\n\nexport function Toggletip(props: ToggletipProps): React.ReactElement {\n return (\n <BasePopover\n name=\"Toggletip\"\n defaultVerticalPlacement=\"top\"\n {...props} // eslint-disable-line react/jsx-props-no-spreading\n />\n );\n}\n"],"names":["Toggletip","props","React","createElement","BasePopover","_extends","name","defaultVerticalPlacement"],"mappings":";;;;AAOO,SAASA,SAASA,CAACC,KAAqB,EAAsB;AACnE,EAAA,oBACEC,KAAA,CAAAC,aAAA,CAACC,WAAW,EAAAC,QAAA,CAAA;AACVC,IAAAA,IAAI,EAAC,WAAW;AAChBC,IAAAA,wBAAwB,EAAC,KAAA;GACrBN,EAAAA,KAAK,CACV,CAAC,CAAA;AAEN;;;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { MutableRefObject, ReactElement } from "react";
|
|
2
|
+
import { BorderRadius } from "../../types";
|
|
2
3
|
export type TooltipContentProps = {
|
|
3
4
|
content: ReactElement;
|
|
4
5
|
triggerRef: MutableRefObject<any>;
|
|
@@ -12,9 +13,13 @@ export type TooltipContentProps = {
|
|
|
12
13
|
role?: string;
|
|
13
14
|
tabIndex?: number;
|
|
14
15
|
contentPadding?: "s" | "m";
|
|
16
|
+
hasInvertedSubTheme?: boolean;
|
|
15
17
|
maxWidth?: number;
|
|
18
|
+
defaultVerticalPlacement?: TooltipStyle["verticalPlacement"];
|
|
16
19
|
onTooltipPointerEnter?: React.PointerEventHandler<HTMLDivElement>;
|
|
17
20
|
onTooltipPointerLeave?: React.PointerEventHandler<HTMLDivElement>;
|
|
21
|
+
hideArrow?: boolean;
|
|
22
|
+
borderRadius?: BorderRadius;
|
|
18
23
|
};
|
|
19
24
|
export type TooltipStyle = {
|
|
20
25
|
top: number;
|
|
@@ -23,4 +28,4 @@ export type TooltipStyle = {
|
|
|
23
28
|
verticalPlacement: "top" | "bottom";
|
|
24
29
|
};
|
|
25
30
|
/** This component is used to display the overlay for both Toggletip and Tooltip components */
|
|
26
|
-
export declare function TooltipContent({ placement, content, tooltipId, triggerRef, portalContainer, dataE2eTestId, dataDSId, isVisible, "aria-hidden": ariaHidden, role, tabIndex, contentPadding, maxWidth, onTooltipPointerEnter, onTooltipPointerLeave, }: TooltipContentProps): React.ReactElement;
|
|
31
|
+
export declare function TooltipContent({ placement, content, tooltipId, triggerRef, portalContainer, dataE2eTestId, dataDSId, isVisible, "aria-hidden": ariaHidden, role, tabIndex, contentPadding, maxWidth, hasInvertedSubTheme, defaultVerticalPlacement, onTooltipPointerEnter, onTooltipPointerLeave, hideArrow, borderRadius, }: TooltipContentProps): React.ReactElement;
|