couds / react-bulma-components

React components for Bulma framework
MIT License
1.2k stars 129 forks source link

Tab switching #398

Closed thebpmgroup closed 1 year ago

thebpmgroup commented 2 years ago

Is it possible to get an example where you can switch the active tab to the tab that was last clicked?

I am trying using refs so I can set the active property but this isn't working.

const Components = (props: IComponents) => {
    const tabRefs:[string, any][]=[
        ["schemas", useRef(null)],
        ["responses", useRef(null)]
    ];
    const getTabRef = (tr: string): React.MutableRefObject<null> => tabRefs.filter(t => t[0]===tr)[0][1];
    const onTabClick = (e:React.FormEvent<HTMLAnchorElement>) => {
        const currentTab:any  = getTabRef(e.currentTarget.id).current;
        console.log(currentTab);
        currentTab.active = true;
    }
    return (
        <Container>
            <Tabs>
                <Tabs.Tab  
                    onClick={onTabClick}
                    id='schemas'
                    active={true}
                    domRef={getTabRef('schemas')}
                >
                    Schemas
                </Tabs.Tab>
                <Tabs.Tab
                    onClick={onTabClick}
                    id='responses'
                    domRef={getTabRef('responses')}
                >
                    Responses
                </Tabs.Tab>
thebpmgroup commented 2 years ago

I came up with this which works but is quite long winded

interface ITabState {
    schemas: boolean;
    responses: boolean;
}

type TabKeys = keyof ITabState;

const Components = (props: IComponents) => {
    const [tabState, setTabState] = useState({
        schemas: true,
        responses: false,
    } as Record<TabKeys,boolean>);

    const onTabClick = (e:React.FormEvent<HTMLAnchorElement>) => {
        const { id } = e.currentTarget;
        Object.keys(tabState).forEach(i => {
            i!=id ? setTabState(prevState => ({
                ...prevState,
                [i]: false
            })) :
            setTabState(prevState => ({
                ...prevState,
                [i]: true
            }))
        });
    }

    return (
        <Container>
            <Tabs>
                <Tabs.Tab  
                    onClick={onTabClick}
                    id='schemas'
                    active={tabState.schemas}
                >
                    Schemas
                </Tabs.Tab>
                <Tabs.Tab
                    onClick={onTabClick}
                    id='responses'
                    active={tabState.responses}
                >
                    Responses
                </Tabs.Tab>
couds commented 1 year ago

Hi, you need to handle the state on your end, something similar of what you did. but you can simplify it a little like this

const Component = {
  const [activeTab, setActiveTab] = useState('schemas');
  const changeTab = ({ target }) => setActiveTab(target.id)
  return (
    <Tabs>
      <Tabs.Tab id="schemas" active={activeTab === 'schemas'} onClick={changeTab}>Schemas</Tabs.Tab>
      <Tabs.Tab id="responses" active={activeTab === 'responses'} onClick={changeTab}>Response</Tabs.Tab>
    </Tabs>
  )
}