mirror of
https://github.com/datahub-project/datahub.git
synced 2025-06-27 05:03:31 +00:00
refactor(web): Embed url mapping into Tabs component for general use (#13648)
This commit is contained in:
parent
5041677082
commit
7d5519f2e1
@ -25,6 +25,33 @@ const exampleTabs = [
|
||||
},
|
||||
];
|
||||
|
||||
const urlAwareTabs = [
|
||||
{
|
||||
key: 'overview',
|
||||
name: 'Overview',
|
||||
tooltip: 'View the overview',
|
||||
component: <div>This is the overview content</div>,
|
||||
},
|
||||
{
|
||||
key: 'details',
|
||||
name: 'Details',
|
||||
tooltip: 'View the details',
|
||||
component: <div>This is the details content</div>,
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
name: 'Settings',
|
||||
tooltip: 'View the settings',
|
||||
component: <div>This is the settings content</div>,
|
||||
},
|
||||
];
|
||||
|
||||
const urlMap = {
|
||||
overview: '/overview',
|
||||
details: '/details',
|
||||
settings: '/settings',
|
||||
};
|
||||
|
||||
// Auto Docs
|
||||
const meta = {
|
||||
title: 'Components / Tabs',
|
||||
@ -50,6 +77,19 @@ const meta = {
|
||||
onChange: {
|
||||
description: 'The handler called when any tab is clicked',
|
||||
},
|
||||
urlMap: {
|
||||
description:
|
||||
'A mapping of tab keys to URLs. When provided, the component will sync tab selection with the URL',
|
||||
},
|
||||
onUrlChange: {
|
||||
description: 'A custom handler for URL changes. Defaults to window.history.replaceState',
|
||||
},
|
||||
defaultTab: {
|
||||
description: 'The default tab to select when the URL does not match any tab',
|
||||
},
|
||||
getCurrentUrl: {
|
||||
description: 'A custom function to get the current URL. Defaults to window.location.pathname',
|
||||
},
|
||||
},
|
||||
|
||||
// Args for the story
|
||||
@ -71,3 +111,28 @@ export const sandbox: Story = {
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
const UrlAwareTabsDemo = () => {
|
||||
const [selectedTab, setSelectedTab] = React.useState('overview');
|
||||
|
||||
return (
|
||||
<div style={{ width: 225 }}>
|
||||
<div style={{ marginBottom: '1rem' }}>
|
||||
<p>Current URL: {window.location.pathname}</p>
|
||||
<p>Selected Tab: {selectedTab}</p>
|
||||
</div>
|
||||
<Tabs
|
||||
tabs={urlAwareTabs}
|
||||
selectedTab={selectedTab}
|
||||
onChange={setSelectedTab}
|
||||
urlMap={urlMap}
|
||||
defaultTab="overview"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const urlAware: Story = {
|
||||
tags: ['dev'],
|
||||
render: () => <UrlAwareTabsDemo />,
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Tabs as AntTabs } from 'antd';
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Pill } from '@components/components/Pills';
|
||||
@ -74,15 +74,57 @@ export interface Props {
|
||||
tabs: Tab[];
|
||||
selectedTab?: string;
|
||||
onChange?: (selectedTabKey: string) => void;
|
||||
urlMap?: Record<string, string>;
|
||||
onUrlChange?: (url: string) => void;
|
||||
defaultTab?: string;
|
||||
getCurrentUrl?: () => string;
|
||||
}
|
||||
|
||||
export function Tabs({ tabs, selectedTab, onChange }: Props) {
|
||||
export function Tabs({
|
||||
tabs,
|
||||
selectedTab,
|
||||
onChange,
|
||||
urlMap,
|
||||
onUrlChange = (url) => window.history.replaceState({}, '', url),
|
||||
defaultTab,
|
||||
getCurrentUrl = () => window.location.pathname,
|
||||
}: Props) {
|
||||
const { TabPane } = AntTabs;
|
||||
|
||||
// Create reverse mapping from URLs to tab keys if urlMap is provided
|
||||
const urlToTabMap = React.useMemo(() => {
|
||||
if (!urlMap) return {};
|
||||
const map: Record<string, string> = {};
|
||||
Object.entries(urlMap).forEach(([tabKey, url]) => {
|
||||
map[url] = tabKey;
|
||||
});
|
||||
return map;
|
||||
}, [urlMap]);
|
||||
|
||||
// Handle initial tab selection based on URL if urlMap is provided
|
||||
useEffect(() => {
|
||||
if (!urlMap || !onChange) return;
|
||||
|
||||
const currentUrl = getCurrentUrl();
|
||||
const tabFromUrl = urlToTabMap[currentUrl];
|
||||
|
||||
if (tabFromUrl && tabFromUrl !== selectedTab) {
|
||||
onChange(tabFromUrl);
|
||||
} else if (!tabFromUrl && defaultTab && defaultTab !== selectedTab) {
|
||||
onChange(defaultTab);
|
||||
onUrlChange(urlMap[defaultTab]);
|
||||
}
|
||||
}, [getCurrentUrl, onChange, onUrlChange, selectedTab, urlMap, urlToTabMap, defaultTab]);
|
||||
|
||||
function handleTabClick(key: string) {
|
||||
onChange?.(key);
|
||||
const newTab = tabs.find((t) => t.key === key);
|
||||
newTab?.onSelectTab?.();
|
||||
|
||||
// Update URL if urlMap is provided
|
||||
if (urlMap && urlMap[key]) {
|
||||
onUrlChange(urlMap[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
Loading…
x
Reference in New Issue
Block a user