4

I'm using semantic-ui's Tab component and I have different components in each tab's pane. When I click on a tab, I would like the URL to change to "/tabname" so that a specific tab can be bookmarked by users who only need the functionality in that tab.

All the examples on the semantic-ui site define tabs like the code below.

const panes = [
  { menuItem: 'Component 1', render: () => <Tab.Pane><Component1 /></Tab.Pane> },
  { menuItem: 'Component 2', render: () => <Tab.Pane><Component2 /></Tab.Pane> }
]

render() {
  return (
    <Tab panes={panes} />
  )
}

I tried changing the menuItem to:

{ menuItem: () => <NavLink to="/component2">Component 2</NavLink>, render: () => <Tab.Pane><Component2 /></Tab.Pane> }

Or this:

{ menuItem: () => <Menu.Item as={Link} to="/component2">Component 2</Menu.Item>, render: () => <Tab.Pane><Component2 /></Tab.Pane> }

and while it does make the link change, it also disables the tab switching (so clicking the 'Component 2' tab adds '/component2' to the URL, but <Component1 /> is still displayed in the pane). The issue is that the Tab's onClick event is overridden by Link's onClick event, so it breaks the tab switching.

There has to be a way to make a tab change the link AND change the pane content. The component augmentation feature of semantic-ui-react is supposed to solve these kinds of issues but it seems to fail with the Tab component. If only their documentation would not be paper thin.

voidmind
  • 137
  • 1
  • 6

2 Answers2

4

Here is a similar question answered.

https://github.com/Semantic-Org/Semantic-UI-React/issues/3935

The sample code is here:

https://codesandbox.io/s/react-example-5jtuo?file=/index.js

I don't know how code snippet works. I prefer using code sandbox. If someone wants to fix the snippet and share, that would be awesome. I just coppied the code over so it is visible in case code sandbox goes down in the future.

import "react-app-polyfill/ie11";
import "react-app-polyfill/stable";
import ReactDOM from "react-dom";
import React, { Component } from "react";
import { Tab } from "semantic-ui-react";
import {
  BrowserRouter as Router,
  Route,
  NavLink,
  Switch
} from "react-router-dom";

import "semantic-ui-css/semantic.min.css";

class App extends Component {
  render() {
    const panes = [
      {
        menuItem: {
          as: NavLink,
          id: "tab1",
          content: "Home",
          to: "/",
          exact: true,
          key: "home"
        },
        pane: (
          <Route
            path="/"
            exact
            render={() => (
              <Tab.Pane>
                <div>Home</div>
              </Tab.Pane>
            )}
          />
        )
      },
      {
        menuItem: {
          as: NavLink,
          id: "tab2",
          content: "Authentication",
          to: "/auth",
          exact: true,
          key: "auth"
        },
        pane: (
          <Route
            path="/auth"
            exact
            render={() => (
              <Tab.Pane>
                <div>Authentication content here</div>
              </Tab.Pane>
            )}
          />
        )
      },
      {
        menuItem: {
          as: NavLink,
          id: "tab3",
          content: "Config Lists",
          to: "/configs",
          exact: true,
          key: "configs"
        },
        pane: (
          <Route
            path="/configs"
            exact
            render={() => (
              <Tab.Pane>
                <div>Config Lists content here</div>
              </Tab.Pane>
            )}
          />
        )
      }
    ];

    return (
      <Router>
        <div className="App" style={{ margin: "50px" }}>
          <Switch>
            <Tab renderActiveOnly={false} activeIndex={-1} panes={panes} />
          </Switch>
        </div>
      </Router>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.11.8/semantic.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react-router-dom/umd/react-router-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui-react/1.2.0/semantic-ui-react.min.js"></script>
<div id="root"></div>
Greg Weigner
  • 191
  • 1
  • 6
0

You should try this:

const panes = [
  { menuItem: 'Component 1', render: () => <Tab.Pane as="NavLink" to="/component1"><Component1 /></Tab.Pane> },
  { menuItem: 'Component 2', render: () => <Tab.Pane as="NavLink" to="/component2"><Component2 /></Tab.Pane> }
]

render() {
  return (
    <Tab panes={panes} />
  )
}
Lazar Nikolic
  • 4,261
  • 1
  • 22
  • 46