chore(core-blocks): Tabs context improvements

This commit is contained in:
Wroud
2020-09-06 23:56:29 +03:00
parent 993753a485
commit 913d257265
5 changed files with 49 additions and 16 deletions
@@ -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}>