Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 23 additions & 14 deletions semcore/notice-bubble/src/NoticeBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import i18nEnhance from '@semcore/core/lib/utils/enhances/i18nEnhance';
import fire from '@semcore/core/lib/utils/fire';
import { getFocusableIn } from '@semcore/core/lib/utils/focus-lock/getFocusableIn';
import isNode from '@semcore/core/lib/utils/isNode';
import { useForkRef } from '@semcore/core/lib/utils/ref';
import { contextThemeEnhance } from '@semcore/core/lib/utils/ThemeProvider';
import { useFocusLock, setFocus } from '@semcore/core/lib/utils/use/useFocusLock';
import { setFocus, isFocusInside } from '@semcore/core/lib/utils/use/useFocusLock';
import { cssVariableEnhance } from '@semcore/core/lib/utils/useCssVariable';
import {
ZIndexStackingContextProvider,
Expand Down Expand Up @@ -159,15 +158,6 @@ class NoticeBubbleContainerRoot extends Component<
}
}

const FocusLock = React.forwardRef((props: any, outerRef: React.ForwardedRef<HTMLDivElement>) => {
const { focusLock, ...other } = props;
const innerRef = React.useRef<HTMLDivElement | null>(null);
useFocusLock(innerRef, false, 'auto', !focusLock, true);
const ref = useForkRef(outerRef, innerRef);

return <Flex ref={ref} {...other} />;
});

const PortalForNoticeItem = (props: NoticeBubbleViewItemProps & { containerNode: HTMLElement; tag: typeof ViewInfo }) => {
const [showContent, setShowContent] = React.useState(false);

Expand Down Expand Up @@ -206,6 +196,7 @@ class ViewInfo extends Component<NoticeBubbleViewItemProps> {
timer: Timer | null = null;
ref = React.createRef<HTMLDivElement>();
closeButtonRef = React.createRef<HTMLButtonElement>();
triggerButtonComponent: Element | null = null;

componentDidMount() {
const { duration } = this.props;
Expand All @@ -214,6 +205,8 @@ class ViewInfo extends Component<NoticeBubbleViewItemProps> {
document.body.addEventListener('mousemove', this.handleBodyMouseMove);
}

this.triggerButtonComponent = document.activeElement;

const noticeElement = this.ref.current;

if (noticeElement) {
Expand All @@ -228,6 +221,11 @@ class ViewInfo extends Component<NoticeBubbleViewItemProps> {
}

componentWillUnmount() {
const triggerElement = this.triggerButtonComponent;
if (this.ref.current && isFocusInside(this.ref.current) && triggerElement instanceof HTMLElement) {
setTimeout(() => setFocus(triggerElement), 0);
}

this.clearTimer();
document.body.removeEventListener('mousemove', this.handleBodyMouseMove);
}
Expand All @@ -251,6 +249,16 @@ class ViewInfo extends Component<NoticeBubbleViewItemProps> {
}
};

handleFocus = () => {
if (!this.timer) return;
this.timer.pause();
};

handleBlur = () => {
if (!this.timer) return;
this.timer.resume();
};

handleMouseEnter = () => {
if (!this.timer) return;
this.timer.pause();
Expand All @@ -275,7 +283,7 @@ class ViewInfo extends Component<NoticeBubbleViewItemProps> {
};

render() {
const SBubble = FocusLock;
const SBubble = Root;
const SDismiss = Button;
const SContent = Flex;
const SMessage = 'div';
Expand All @@ -291,7 +299,6 @@ class ViewInfo extends Component<NoticeBubbleViewItemProps> {
icon,
children,
action,
focusLock,
} = this.props;

return sstyled(styles)(
Expand All @@ -303,13 +310,15 @@ class ViewInfo extends Component<NoticeBubbleViewItemProps> {
keyframes={[styles['@enter'], styles['@exit']]}
>
<SBubble
render={Flex}
type={type}
ref={this.ref}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onKeyDown={this.handleKeydown}
role={type === 'warning' ? 'alert' : undefined}
focusLock={focusLock}
>
<SDismiss
aria-haspopup={undefined}
Expand Down
2 changes: 2 additions & 0 deletions semcore/notice-bubble/src/NoticeBubble.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export type NoticeBubbleProps = BoxProps & {
* If enabled, browser focus will be locked in the notice
* until it's closed. After close focus should return to the element
* where it was placed before notice appear.
*
* @deprecated
*/
focusLock?: boolean;
/**
Expand Down
Loading