mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-09-07 00:27:44 +08:00
feat: implement double-click navigation and click timer for breadcrumb items
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import { Flex, Typography, Divider, Button, Space, Tooltip, Segmented, Breadcrumb, Input, theme, Dropdown } from 'antd';
|
import { Flex, Typography, Divider, Button, Space, Tooltip, Segmented, Breadcrumb, Input, theme, Dropdown } from 'antd';
|
||||||
import { ArrowUpOutlined, ArrowDownOutlined, ReloadOutlined, PlusOutlined, UploadOutlined, AppstoreOutlined, UnorderedListOutlined } from '@ant-design/icons';
|
import { ArrowUpOutlined, ArrowDownOutlined, ReloadOutlined, PlusOutlined, UploadOutlined, AppstoreOutlined, UnorderedListOutlined } from '@ant-design/icons';
|
||||||
import { Select } from 'antd';
|
import { Select } from 'antd';
|
||||||
@@ -41,9 +41,26 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const [editingPath, setEditingPath] = useState(false);
|
const [editingPath, setEditingPath] = useState(false);
|
||||||
const [pathInputValue, setPathInputValue] = useState('');
|
const [pathInputValue, setPathInputValue] = useState('');
|
||||||
|
const clickTimerRef = useRef<number | null>(null);
|
||||||
const pathEditorHeight = token.fontSizeSM * token.lineHeight + token.paddingXXS * 2;
|
const pathEditorHeight = token.fontSizeSM * token.lineHeight + token.paddingXXS * 2;
|
||||||
|
|
||||||
|
const clearClickTimer = () => {
|
||||||
|
if (clickTimerRef.current !== null) {
|
||||||
|
window.clearTimeout(clickTimerRef.current);
|
||||||
|
clickTimerRef.current = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const scheduleNavigate = (nextPath: string) => {
|
||||||
|
clearClickTimer();
|
||||||
|
clickTimerRef.current = window.setTimeout(() => {
|
||||||
|
onNavigate(nextPath);
|
||||||
|
clickTimerRef.current = null;
|
||||||
|
}, 250);
|
||||||
|
};
|
||||||
|
|
||||||
const handlePathEdit = () => {
|
const handlePathEdit = () => {
|
||||||
|
clearClickTimer();
|
||||||
setEditingPath(true);
|
setEditingPath(true);
|
||||||
setPathInputValue(path);
|
setPathInputValue(path);
|
||||||
};
|
};
|
||||||
@@ -61,6 +78,10 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
setPathInputValue('');
|
setPathInputValue('');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBreadcrumbDoubleClick = () => {
|
||||||
|
handlePathEdit();
|
||||||
|
};
|
||||||
|
|
||||||
const renderBreadcrumb = () => {
|
const renderBreadcrumb = () => {
|
||||||
if (editingPath) {
|
if (editingPath) {
|
||||||
return (
|
return (
|
||||||
@@ -78,12 +99,12 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const breadcrumbItems = [
|
const breadcrumbItems = [
|
||||||
{ key: 'root', title: <span style={{ cursor: 'pointer' }} onClick={() => onNavigate('/')}>{t('Home')}</span> },
|
{ key: 'root', title: <span style={{ cursor: 'pointer' }} onClick={() => scheduleNavigate('/')}>{t('Home')}</span> },
|
||||||
...path.split('/').filter(Boolean).map((segment, index, arr) => {
|
...path.split('/').filter(Boolean).map((segment, index, arr) => {
|
||||||
const segmentPath = '/' + arr.slice(0, index + 1).join('/');
|
const segmentPath = '/' + arr.slice(0, index + 1).join('/');
|
||||||
return {
|
return {
|
||||||
key: segmentPath,
|
key: segmentPath,
|
||||||
title: <span style={{ cursor: 'pointer' }} onClick={() => onNavigate(segmentPath)}>{segment}</span>
|
title: <span style={{ cursor: 'pointer' }} onClick={() => scheduleNavigate(segmentPath)}>{segment}</span>
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
@@ -91,7 +112,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
cursor: 'pointer',
|
cursor: 'text',
|
||||||
padding: `${token.paddingXXS}px ${token.paddingXS}px`,
|
padding: `${token.paddingXXS}px ${token.paddingXS}px`,
|
||||||
borderRadius: token.borderRadius,
|
borderRadius: token.borderRadius,
|
||||||
transition: 'background-color 0.2s',
|
transition: 'background-color 0.2s',
|
||||||
@@ -104,7 +125,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
}}
|
}}
|
||||||
onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = token.colorFillTertiary; }}
|
onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = token.colorFillTertiary; }}
|
||||||
onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent'; }}
|
onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent'; }}
|
||||||
onClick={handlePathEdit}
|
onDoubleClick={handleBreadcrumbDoubleClick}
|
||||||
>
|
>
|
||||||
<Breadcrumb items={breadcrumbItems} separator="/" style={{ fontSize: token.fontSizeSM }} />
|
<Breadcrumb items={breadcrumbItems} separator="/" style={{ fontSize: token.fontSizeSM }} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user