Skip to content

Commit 68e8f11

Browse files
Minor improvements
1 parent c541891 commit 68e8f11

4 files changed

Lines changed: 45 additions & 30 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
99
### Added
1010

1111
- `<ContextOverlay />`
12-
- `usePlaceholder` property, can be used to display the target but include the component later when the first interaction happens, this can improve performance
12+
- `usePlaceholder` property: can be used to display the target but include the component later when the first interaction happens, this can improve performance
1313
- `<ContextMenu />`
14-
- `preventPlaceholder` property, to prevent the default usage of placeholders waiting for the first user interaction before inserting the full context menu
14+
- `preventPlaceholder` property to prevent the default usage of placeholders waiting for the first user interaction before inserting the full context menu
1515
- `<Tooltip />`
16-
- `usePlaceholder` property, can be used to display the target but include the full component later when the first interaction happens, this can improve performance. It is turned on for text tooltips by default.
16+
- `usePlaceholder` property: can be used to display the target but include the full component later when the first interaction happens, this can improve performance. It is turned on for text tooltips by default.
1717
- `<OverviewItemActions />`
18-
- `delayDisplayChildren` property, set a time (in ms) to delay the actual rendering of elements inside the actions container. When enabled the containing `OverviewItem` can be displayed faster. Can be used e.g. to boost performance when rendering `OverviewItemActions` with `hiddenInteractions` set to `true`.
18+
- `delayDisplayChildren` property: set a time (in ms) to delay the actual rendering of elements inside the actions container. When enabled the containing `OverviewItem` can be displayed faster. Can be used e.g. to boost performance when rendering `OverviewItemActions` with `hiddenInteractions` set to `true`.
1919
- `delaySkeleton` property to set the placeholder/skeleton as long as the delayed display is waiting to get processed
2020
- `intent` property to `Button`, `FieldItem`, `FieldSet`, `Notification`, and `Spinner`
2121

src/components/ContextOverlay/ContextOverlay.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,38 +38,44 @@ export const ContextOverlay = ({
3838
...otherPopoverProps
3939
}: ContextOverlayProps) => {
4040
const placeholderRef = React.useRef(null);
41-
const eventmemory = React.useRef<undefined | "afterhover" | "afterfocus">(undefined);
41+
const eventMemory = React.useRef<undefined | "afterhover" | "afterfocus">(undefined);
4242
const [placeholder, setPlaceholder] = React.useState<boolean>(
4343
// use placeholder only for "simple" overlays without special states
44-
otherPopoverProps.disabled !== true &&
45-
otherPopoverProps.defaultIsOpen !== true &&
46-
otherPopoverProps.isOpen !== true &&
47-
typeof otherPopoverProps.renderTarget === "undefined" &&
44+
!otherPopoverProps.disabled &&
45+
!otherPopoverProps.defaultIsOpen &&
46+
!otherPopoverProps.isOpen &&
47+
otherPopoverProps.renderTarget === undefined &&
4848
usePlaceholder
4949
);
5050

51-
const targetClassName = `${eccgui}-contextoverlay` + (className ? ` ${className}` : "");
52-
5351
React.useEffect(() => {
5452
if (placeholderRef.current) {
5553
const swap = (ev: MouseEvent | globalThis.FocusEvent) => {
56-
eventmemory.current = ev.type === "focusin" ? "afterfocus" : "afterhover";
54+
eventMemory.current = ev.type === "focusin" ? "afterfocus" : "afterhover";
5755
setPlaceholder(false);
5856
};
5957
(placeholderRef.current as HTMLElement).addEventListener("mouseenter", swap);
6058
(placeholderRef.current as HTMLElement).addEventListener("focusin", swap);
59+
return () => {
60+
if (placeholderRef.current) {
61+
(placeholderRef.current as HTMLElement).removeEventListener("mouseenter", swap);
62+
(placeholderRef.current as HTMLElement).removeEventListener("focusin", swap);
63+
}
64+
};
6165
}
6266
}, [!!placeholderRef.current]);
6367

6468
const refocus = React.useCallback((node) => {
65-
if (eventmemory.current === "afterfocus" && node) {
69+
if (eventMemory.current === "afterfocus" && node) {
6670
const target = node.targetRef.current.children[0];
6771
if (target) {
6872
target.focus();
6973
}
7074
}
7175
}, []);
7276

77+
const targetClassName = `${eccgui}-contextoverlay` + (className ? ` ${className}` : "");
78+
7379
const displayPlaceholder = () => {
7480
const PlaceholderElement = otherPopoverProps?.targetTagName ?? (otherPopoverProps?.fill ? "div" : "span");
7581
const childTarget = BlueprintUtils.ensureElement(React.Children.toArray(children)[0]);

src/components/OverviewItem/OverviewItemActions.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ export interface OverviewItemActionsProps extends React.HTMLAttributes<HTMLDivEl
1010
/**
1111
* Delay the rendering of the children by a time in milliseconds.
1212
* Could be used to prevent browser freezes for the initial `OverviewItem` rendering.
13+
* In general, it is better to fix the cause, i.e. action elements that are expensive to initialize/render should be
14+
* optimized or replaced etc. This workaround only prevents the browser from getting blocked completely and does NOT
15+
* solve the actual performance issue.
1316
*/
1417
delayDisplayChildren?: number;
1518
/**

src/components/Tooltip/Tooltip.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ export const Tooltip = ({
5757
...otherTooltipProps
5858
}: TooltipProps) => {
5959
const placeholderRef = React.useRef(null);
60-
const eventmemory = React.useRef<null | "afterhover" | "afterfocus">(null);
60+
const eventMemory = React.useRef<null | "afterhover" | "afterfocus">(null);
6161
const searchId = React.useRef<null | string>(null);
62-
const swapdelayTime = 100;
62+
const swapDelayTime = 100;
6363
const [placeholder, setPlaceholder] = React.useState<boolean>(
64-
otherTooltipProps.disabled !== true &&
65-
otherTooltipProps.defaultIsOpen !== true &&
66-
otherTooltipProps.isOpen !== true &&
67-
typeof otherTooltipProps.renderTarget === "undefined" &&
68-
hoverOpenDelay > swapdelayTime &&
64+
!otherTooltipProps.disabled &&
65+
!otherTooltipProps.defaultIsOpen &&
66+
!otherTooltipProps.isOpen &&
67+
otherTooltipProps.renderTarget === undefined &&
68+
hoverOpenDelay > swapDelayTime &&
6969
(usePlaceholder === true || (typeof content === "string" && usePlaceholder !== false))
7070
);
7171

@@ -77,33 +77,39 @@ export const Tooltip = ({
7777
React.useEffect(() => {
7878
if (placeholderRef.current !== null) {
7979
const swap = (ev: MouseEvent | globalThis.FocusEvent) => {
80-
const swapdelay = setTimeout(() => {
80+
const swapDelay = setTimeout(() => {
8181
// we delay the swap to prevent unwanted effects
82-
// (e.g. forced mouseover after the swap but the curser is already somewhere else)
83-
eventmemory.current = ev.type === "focusin" ? "afterfocus" : "afterhover";
82+
// (e.g. forced mouseover after the swap but the cursor is already somewhere else)
83+
eventMemory.current = ev.type === "focusin" ? "afterfocus" : "afterhover";
8484
searchId.current = Date.now().toString(16) + Math.random().toString(16).slice(2);
8585
setPlaceholder(false);
86-
}, swapdelayTime);
86+
}, swapDelayTime);
8787
if (placeholderRef.current !== null)
8888
(placeholderRef.current as HTMLElement).addEventListener(
8989
ev.type === "focusin" ? "focusout" : "mouseleave",
90-
() => clearTimeout(swapdelay)
90+
() => clearTimeout(swapDelay)
9191
);
9292
};
9393
(placeholderRef.current as HTMLElement).addEventListener("mouseenter", swap);
9494
(placeholderRef.current as HTMLElement).addEventListener("focusin", swap);
95+
return () => {
96+
if (placeholderRef.current) {
97+
(placeholderRef.current as HTMLElement).removeEventListener("mouseenter", swap);
98+
(placeholderRef.current as HTMLElement).removeEventListener("focusin", swap);
99+
}
100+
};
95101
}
96102
}, [!!placeholderRef.current]);
97103

98104
const refocus = React.useCallback((node) => {
99-
if (eventmemory.current && node) {
105+
if (eventMemory.current && node) {
100106
// we do not have a `targetRef` here, so we need to workaround it
101107
// const target = node.targetRef.current.children[0];
102108
const target = document.body.querySelector(
103-
`[data-postplaceholder=id${eventmemory.current}${searchId.current}]`
109+
`[data-postplaceholder=id${eventMemory.current}${searchId.current}]`
104110
)?.children[0];
105111
if (target) {
106-
switch (eventmemory.current) {
112+
switch (eventMemory.current) {
107113
case "afterfocus":
108114
(target as HTMLElement).focus();
109115
break;
@@ -152,7 +158,7 @@ export const Tooltip = ({
152158
) : (
153159
<BlueprintTooltip
154160
lazy={true}
155-
hoverOpenDelay={hoverOpenDelay - swapdelayTime}
161+
hoverOpenDelay={hoverOpenDelay - swapDelayTime}
156162
{...otherTooltipProps}
157163
content={tooltipContent}
158164
className={targetClassName}
@@ -165,7 +171,7 @@ export const Tooltip = ({
165171
targetProps={
166172
{
167173
...otherTooltipProps.targetProps,
168-
"data-postplaceholder": `id${eventmemory.current}${searchId.current}`,
174+
"data-postplaceholder": `id${eventMemory.current}${searchId.current}`,
169175
} as React.HTMLProps<HTMLElement>
170176
}
171177
>

0 commit comments

Comments
 (0)