]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/common/tabs.tsx
fix(tabs): Fix tab semantics and a11y (#1382)
[lemmy-ui.git] / src / shared / components / common / tabs.tsx
index 17980a476ce2b6f448a9c56039da29b7cd6b0dcc..3c2726a56727f0e1447d44f8d4ff290aa9f905c8 100644 (file)
@@ -1,8 +1,9 @@
+import classNames from "classnames";
 import { Component, InfernoNode, linkEvent } from "inferno";
 
 interface TabItem {
   key: string;
-  getNode: () => InfernoNode;
+  getNode: (isSelected: boolean) => InfernoNode;
   label: string;
 }
 
@@ -30,24 +31,33 @@ export default class Tabs extends Component<TabsProps, TabsState> {
   render() {
     return (
       <div>
-        <ul className="nav nav-tabs mb-2">
+        <ul className="nav nav-tabs mb-2" role="tablist">
           {this.props.tabs.map(({ key, label }) => (
             <li key={key} className="nav-item">
               <button
                 type="button"
-                className={`nav-link btn${
-                  this.state?.currentTab === key ? " active" : ""
-                }`}
+                className={classNames("nav-link", {
+                  active: this.state?.currentTab === key,
+                })}
                 onClick={linkEvent({ ctx: this, tab: key }, handleSwitchTab)}
+                aria-controls={`${key}-tab-pane`}
+                {...(this.state?.currentTab === key && {
+                  ...{
+                    "aria-current": "page",
+                    "aria-selected": "true",
+                  },
+                })}
               >
                 {label}
               </button>
             </li>
           ))}
         </ul>
-        {this.props.tabs
-          .find(tab => tab.key === this.state?.currentTab)
-          ?.getNode()}
+        <div className="tab-content">
+          {this.props.tabs.map(({ key, getNode }) => {
+            return getNode(this.state?.currentTab === key);
+          })}
+        </div>
       </div>
     );
   }