parent
81833c4938
commit
109906d083
@ -0,0 +1,19 @@
|
||||
import { useEscHint } from '@/hooks/use-esc-hint';
|
||||
import { Drawer, type DrawerProps } from 'antd';
|
||||
|
||||
const ScrollerModal = (props: DrawerProps) => {
|
||||
const { EscHint } = useEscHint({
|
||||
enabled: !props.keyboard && props.open
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Drawer {...props}>
|
||||
{props.children}
|
||||
{EscHint}
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ScrollerModal;
|
||||
@ -0,0 +1,93 @@
|
||||
import HotKeys from '@/config/hotkeys';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { throttle } from 'lodash';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
hintOverlay: css`
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: var(--color-esc-hint-bg);
|
||||
color: ${token.colorTextLightSolid};
|
||||
padding: 16px 24px;
|
||||
border-radius: 4px;
|
||||
z-index: 2000;
|
||||
font-size: 14px;
|
||||
pointer-events: none;
|
||||
animation: fadeInOut 2s ease-in-out;
|
||||
@keyframes fadeInOut {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
10% {
|
||||
opacity: 1;
|
||||
}
|
||||
90% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
`
|
||||
}));
|
||||
|
||||
export function useEscHint(options?: {
|
||||
enabled?: boolean;
|
||||
message?: string;
|
||||
throttleDelay?: number;
|
||||
}) {
|
||||
const { enabled = true, message, throttleDelay = 3000 } = options || {};
|
||||
const intl = useIntl();
|
||||
const { styles } = useStyles();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const timeoutRef = useRef<any>(null);
|
||||
|
||||
const showHintThrottled = useMemo(
|
||||
() =>
|
||||
throttle(
|
||||
() => {
|
||||
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
||||
setVisible(true);
|
||||
timeoutRef.current = setTimeout(() => setVisible(false), 2000);
|
||||
},
|
||||
throttleDelay,
|
||||
{
|
||||
leading: true,
|
||||
trailing: false
|
||||
}
|
||||
),
|
||||
[throttleDelay]
|
||||
);
|
||||
|
||||
useHotkeys(
|
||||
HotKeys.ESC,
|
||||
() => {
|
||||
showHintThrottled();
|
||||
},
|
||||
{
|
||||
enabled: enabled
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
}
|
||||
showHintThrottled.cancel();
|
||||
};
|
||||
}, [showHintThrottled]);
|
||||
|
||||
const EscHint = visible ? (
|
||||
<div className={styles.hintOverlay}>
|
||||
{message || intl.formatMessage({ id: 'common.tips.escape.disable' })}
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
return { EscHint };
|
||||
}
|
||||
Loading…
Reference in new issue