mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
chore(core-blocks): Tabs context improvements
This commit is contained in:
@@ -38,10 +38,11 @@ export function Tab({
|
||||
|
||||
const handleOpen = useCallback((e: React.MouseEvent<any>) => {
|
||||
e.preventDefault();
|
||||
state.select(tabId);
|
||||
if (onOpen) {
|
||||
onOpen(tabId);
|
||||
}
|
||||
}, [onOpen]);
|
||||
}, [state, onOpen, tabId]);
|
||||
|
||||
const handleClose = useCallback((e: React.MouseEvent<any>) => {
|
||||
e.preventDefault();
|
||||
@@ -49,11 +50,11 @@ export function Tab({
|
||||
if (onClose) {
|
||||
onClose(tabId);
|
||||
}
|
||||
}, [onClose]);
|
||||
}, [onClose, tabId]);
|
||||
|
||||
return styled(useStyles())(
|
||||
<BaseTab
|
||||
{...state}
|
||||
{...state.state}
|
||||
id={tabId}
|
||||
className={className}
|
||||
onClick={handleOpen}
|
||||
|
||||
@@ -18,5 +18,5 @@ export function TabList(props: React.PropsWithChildren<Omit<TabListOptions, keyo
|
||||
throw new Error('Tabs context was not provided');
|
||||
}
|
||||
|
||||
return <BaseTabList {...props} {...state} />;
|
||||
return <BaseTabList {...props} {...state.state} />;
|
||||
}
|
||||
|
||||
@@ -7,22 +7,23 @@
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import {
|
||||
useContext, PropsWithChildren,
|
||||
} from 'react';
|
||||
import { TabPanel as BaseTabPanel } from 'reakit/Tab';
|
||||
import { useContext } from 'react';
|
||||
import { TabPanel as BaseTabPanel, TabStateReturn } from 'reakit/Tab';
|
||||
|
||||
import { TabsContext } from './TabsContext';
|
||||
|
||||
type TabProps = PropsWithChildren<{
|
||||
type TabProps = {
|
||||
tabId: string;
|
||||
className?: string;
|
||||
}>;
|
||||
children?: React.ReactNode | ((state: TabStateReturn) => React.ReactNode);
|
||||
lazy?: boolean;
|
||||
};
|
||||
|
||||
export const TabPanel = observer(function TabPanel({
|
||||
tabId,
|
||||
children,
|
||||
className,
|
||||
lazy,
|
||||
}: TabProps) {
|
||||
const state = useContext(TabsContext);
|
||||
|
||||
@@ -30,8 +31,20 @@ export const TabPanel = observer(function TabPanel({
|
||||
throw new Error('Tabs context was not provided');
|
||||
}
|
||||
|
||||
if (lazy && state.state.selectedId !== tabId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof children === 'function') {
|
||||
return (
|
||||
<BaseTabPanel {...state.state} tabId={tabId} className={className}>
|
||||
{children(state.state)}
|
||||
</BaseTabPanel>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseTabPanel {...state} tabId={tabId} className={className}>
|
||||
<BaseTabPanel {...state.state} tabId={tabId} className={className}>
|
||||
{children}
|
||||
</BaseTabPanel>
|
||||
);
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
import { createContext } from 'react';
|
||||
import { TabStateReturn } from 'reakit/Tab';
|
||||
|
||||
export const TabsContext = createContext<TabStateReturn | undefined>(
|
||||
export interface ITabsContext {
|
||||
state: TabStateReturn;
|
||||
select: (tabId: string) => any;
|
||||
}
|
||||
|
||||
export const TabsContext = createContext<ITabsContext | undefined>(
|
||||
undefined
|
||||
);
|
||||
|
||||
@@ -6,36 +6,50 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useEffect, useMemo, useCallback } from 'react';
|
||||
import { useTabState } from 'reakit/Tab';
|
||||
|
||||
import { TabsContext } from './TabsContext';
|
||||
import { TabsContext, ITabsContext } from './TabsContext';
|
||||
|
||||
type Props = React.PropsWithChildren<{
|
||||
selectedId?: string;
|
||||
orientation?: 'horizontal' | 'vertical';
|
||||
currentTabId?: string | null;
|
||||
manual?: boolean;
|
||||
onChange?: (tabId: string) => any;
|
||||
}>
|
||||
|
||||
export function TabsState({
|
||||
selectedId, orientation, currentTabId, children, manual,
|
||||
selectedId,
|
||||
orientation,
|
||||
currentTabId,
|
||||
children,
|
||||
manual,
|
||||
onChange,
|
||||
}: Props) {
|
||||
const state = useTabState({
|
||||
selectedId: selectedId || currentTabId,
|
||||
orientation,
|
||||
manual,
|
||||
});
|
||||
|
||||
if (currentTabId) {
|
||||
state.selectedId = currentTabId;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentTabId) {
|
||||
return;
|
||||
}
|
||||
state.select(currentTabId);
|
||||
}, [currentTabId]); // hack currentId and selectedId not works
|
||||
const value = useMemo(() => state, Object.values(state));
|
||||
|
||||
const handleChange = useCallback((tabId: string) => onChange && onChange(tabId), [onChange]);
|
||||
|
||||
const value = useMemo<ITabsContext>(() => ({
|
||||
state,
|
||||
select: handleChange,
|
||||
}), [...Object.values(state), handleChange]);
|
||||
|
||||
return (
|
||||
<TabsContext.Provider value={value}>
|
||||
|
||||
Reference in New Issue
Block a user