Skip to content

Commit c85a023

Browse files
committed
fix(CompositeBar): improve hover detection
1 parent 2faab2f commit c85a023

File tree

3 files changed

+81
-11
lines changed

3 files changed

+81
-11
lines changed

src/components/CompositeBar/CompositeBar.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,16 @@ $block: '.#{variables.$ns}composite-bar';
1212
& &__root-menu-item[class] {
1313
background-color: transparent;
1414
}
15+
16+
&__list_hover::after{
17+
content: '';
18+
position: absolute;
19+
inset: 0;
20+
border: solid 1px red;
21+
}
22+
23+
&__list:hover > div > div:first-child {
24+
transform: translateY(0);
25+
outline: solid 2px var(--g-color-line-info);
26+
}
1527
}

src/components/CompositeBar/CompositeBar.tsx

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ type CompositeBarViewProps = CompositeBarProps & {
4949
collapseItems?: MenuItem[];
5050
};
5151

52+
function getTime() {
53+
const now = new Date();
54+
const hours = String(now.getHours()).padStart(2, '0');
55+
const minutes = String(now.getMinutes()).padStart(2, '0');
56+
const seconds = String(now.getSeconds()).padStart(2, '0');
57+
const milliseconds = String(now.getMilliseconds()).padStart(3, '0');
58+
59+
const formattedTime = `${hours}:${minutes}:${seconds}.${milliseconds}`;
60+
return formattedTime;
61+
}
62+
5263
const CompositeBarView: FC<CompositeBarViewProps> = ({
5364
type,
5465
items,
@@ -65,9 +76,42 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
6576
active: multipleTooltipActive,
6677
activeIndex,
6778
lastClickedItemIndex,
79+
hoverState,
6880
} = useContext(MultipleTooltipContext);
6981
const {compact} = useAsideHeaderContext();
7082

83+
const handleTransitionRun = React.useCallback<(e: TransitionEvent) => void>(
84+
(e) => {
85+
if (e.target) {
86+
const computedStyle = getComputedStyle(e.target as HTMLElement);
87+
const isHovered = computedStyle.transform !== 'none';
88+
console.log('isHovered=', isHovered, getTime());
89+
if (hoverState !== isHovered) {
90+
setMultipleTooltipContextValue({hoverState: isHovered});
91+
}
92+
}
93+
},
94+
[multipleTooltip, multipleTooltipActive],
95+
);
96+
97+
React.useEffect(() => {
98+
if (ref.current?.refContainer.current?.node) {
99+
const listNode = ref.current.refContainer.current.node as HTMLElement;
100+
// this hack allow to detect hover events on element like browser css engine
101+
listNode.style.setProperty('transition', 'transform 0.001ms step-start');
102+
listNode.style.setProperty('transition-behavior', 'allow-discrete');
103+
listNode.addEventListener('transitionrun', handleTransitionRun);
104+
105+
return () => {
106+
listNode.removeEventListener('transitionrun', handleTransitionRun);
107+
listNode.style.removeProperty('transition-behavior');
108+
listNode.style.removeProperty('transition');
109+
};
110+
}
111+
112+
return;
113+
}, []);
114+
71115
React.useEffect(() => {
72116
function handleBlurWindow() {
73117
if (multipleTooltip && multipleTooltipActive) {
@@ -91,9 +135,9 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
91135
!multipleTooltipActive &&
92136
document.hasFocus() &&
93137
activeIndex !== lastClickedItemIndex &&
94-
e.clientX <= ASIDE_HEADER_COMPACT_WIDTH
138+
e.clientX <= ASIDE_HEADER_COMPACT_WIDTH &&
139+
hoverState
95140
) {
96-
console.log(`onTooltipMouseEnter: active=true`);
97141
setMultipleTooltipContextValue?.({
98142
active: true,
99143
});
@@ -112,16 +156,21 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
112156
activeIndex,
113157
lastClickedItemIndex,
114158
setMultipleTooltipContextValue,
159+
hoverState,
115160
],
116161
);
117162

118163
const onTooltipMouseLeave = useCallback(
119164
debounce(
120165
() => {
121-
if (multipleTooltip && multipleTooltipActive && document.hasFocus()) {
122-
console.log(`onTooltipMouseLeave: active=false`);
166+
if (
167+
multipleTooltip &&
168+
(multipleTooltipActive || !hoverState) &&
169+
document.hasFocus()
170+
) {
123171
setMultipleTooltipContextValue?.({
124172
active: false,
173+
activeIndex: undefined,
125174
lastClickedItemIndex: undefined,
126175
});
127176
}
@@ -132,15 +181,21 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
132181
trailing: false,
133182
},
134183
),
135-
[multipleTooltip, multipleTooltipActive, setMultipleTooltipContextValue],
184+
[multipleTooltip, multipleTooltipActive, setMultipleTooltipContextValue, hoverState],
136185
);
137186

138187
const onMouseEnterByIndex = useCallback(
139188
(itemIndex: number) =>
140189
debounce(
141190
() => {
142-
console.log(`onMouseEnterByIndex: itemIndex=${itemIndex}`);
143191
if (multipleTooltip && document.hasFocus()) {
192+
if (multipleTooltipActive && !hoverState) {
193+
setMultipleTooltipContextValue({
194+
active: false,
195+
activeIndex: undefined,
196+
});
197+
return;
198+
}
144199
let multipleTooltipActiveValue = multipleTooltipActive;
145200
if (!multipleTooltipActive && itemIndex !== lastClickedItemIndex) {
146201
multipleTooltipActiveValue = true;
@@ -149,10 +204,8 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
149204
activeIndex === itemIndex &&
150205
multipleTooltipActive === multipleTooltipActiveValue
151206
) {
152-
console.log('onMouseEnterByIndex: skip change');
153207
return;
154208
}
155-
console.log(`onMouseEnterByIndex: set active=${itemIndex}`);
156209
setMultipleTooltipContextValue({
157210
activeIndex: itemIndex,
158211
active: multipleTooltipActiveValue,
@@ -171,6 +224,7 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
171224
lastClickedItemIndex,
172225
activeIndex,
173226
setMultipleTooltipContextValue,
227+
hoverState,
174228
],
175229
);
176230

@@ -181,9 +235,10 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
181235
ref.current?.activateItem(undefined as unknown as number);
182236
if (
183237
multipleTooltip &&
184-
(activeIndex !== undefined || lastClickedItemIndex !== undefined)
238+
(activeIndex !== undefined ||
239+
lastClickedItemIndex !== undefined ||
240+
!hoverState)
185241
) {
186-
console.log('onMouseLeave: deactivate tooltip');
187242
setMultipleTooltipContextValue({
188243
activeIndex: undefined,
189244
lastClickedItemIndex: undefined,
@@ -203,6 +258,7 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
203258
lastClickedItemIndex,
204259
multipleTooltip,
205260
setMultipleTooltipContextValue,
261+
hoverState,
206262
],
207263
);
208264

@@ -239,6 +295,7 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
239295
onMouseLeave={onTooltipMouseLeave}
240296
>
241297
<List<CompositeBarItem>
298+
className={b('list', {hover: hoverState})}
242299
ref={ref}
243300
items={items}
244301
selectedItemIndex={type === 'menu' ? getSelectedItemIndex(items) : undefined}
@@ -249,7 +306,6 @@ const CompositeBarView: FC<CompositeBarViewProps> = ({
249306
filterable={false}
250307
sortable={false}
251308
renderItem={(item, _isItemActive, itemIndex) => {
252-
// console.log('renderItem: ', itemIndex);
253309
const itemExtraProps = isMenuItem(item) ? {item} : item;
254310
const enableTooltip = isMenuItem(item)
255311
? !multipleTooltip

src/components/CompositeBar/MultipleTooltip/MultipleTooltipContext.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ interface MultipleTooltipContextProps {
55
activeIndex: number | undefined;
66
hideCollapseItemTooltip: boolean;
77
lastClickedItemIndex: number | undefined;
8+
hoverState: boolean | undefined;
89
setValue<K extends keyof Omit<MultipleTooltipContextProps, 'setValue'>>(
910
value:
1011
| Pick<Omit<MultipleTooltipContextProps, 'setValue'>, K>
@@ -17,6 +18,7 @@ const multipleTooltipContextDefaults = {
1718
activeIndex: undefined,
1819
hideCollapseItemTooltip: false,
1920
lastClickedItemIndex: undefined,
21+
hoverState: undefined,
2022
setValue: () => {},
2123
};
2224

0 commit comments

Comments
 (0)