use first tab as default, use state for tabs and an effect to update
This commit is contained in:
parent
5c0d21578f
commit
82cdd245c3
@ -6,6 +6,7 @@ import React, {
|
|||||||
Children,
|
Children,
|
||||||
isValidElement,
|
isValidElement,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
@ -131,6 +132,25 @@ interface GridTabsProps {
|
|||||||
|
|
||||||
const GridTabs = ({ children, group }: GridTabsProps) => {
|
const GridTabs = ({ children, group }: GridTabsProps) => {
|
||||||
const { query, asPath, replace } = useRouter();
|
const { query, asPath, replace } = useRouter();
|
||||||
|
const [activeTab, setActiveTab] = useState<string>(() => {
|
||||||
|
if (query[group]) {
|
||||||
|
return query[group];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to first tab
|
||||||
|
return children[0].props.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Using replace inside an effect causes a render loop. Seems like its not using useCallback
|
||||||
|
// eslint-disable-next-line
|
||||||
|
const safeReplace = useCallback((path: string) => replace(path), []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const [url, queryString] = asPath.split('?');
|
||||||
|
const searchParams = new URLSearchParams(queryString);
|
||||||
|
searchParams.set(group, activeTab as string);
|
||||||
|
safeReplace(`${url}?${searchParams.toString()}`);
|
||||||
|
}, [activeTab, group, asPath, safeReplace]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full grid grid-rows-[min-content_1fr]">
|
<div className="h-full grid grid-rows-[min-content_1fr]">
|
||||||
@ -138,7 +158,7 @@ const GridTabs = ({ children, group }: GridTabsProps) => {
|
|||||||
<div className="flex gap-[2px] bg-neutral-200" role="tablist">
|
<div className="flex gap-[2px] bg-neutral-200" role="tablist">
|
||||||
{Children.map(children, (child) => {
|
{Children.map(children, (child) => {
|
||||||
if (!isValidElement(child)) return null;
|
if (!isValidElement(child)) return null;
|
||||||
const isActive = query[group] === child.props.name;
|
const isActive = activeTab === child.props.name;
|
||||||
const buttonClass = classNames(
|
const buttonClass = classNames(
|
||||||
'py-4',
|
'py-4',
|
||||||
'px-12',
|
'px-12',
|
||||||
@ -152,12 +172,7 @@ const GridTabs = ({ children, group }: GridTabsProps) => {
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={buttonClass}
|
className={buttonClass}
|
||||||
onClick={() => {
|
onClick={() => setActiveTab(child.props.name)}
|
||||||
const [url, queryString] = asPath.split('?');
|
|
||||||
const searchParams = new URLSearchParams(queryString);
|
|
||||||
searchParams.set(group, child.props.name);
|
|
||||||
replace(`${url}?${searchParams.toString()}`);
|
|
||||||
}}
|
|
||||||
role="tab"
|
role="tab"
|
||||||
aria-selected={isActive}
|
aria-selected={isActive}
|
||||||
aria-controls={`tabpanel-${group}-${child.props.name}`}
|
aria-controls={`tabpanel-${group}-${child.props.name}`}
|
||||||
@ -171,7 +186,7 @@ const GridTabs = ({ children, group }: GridTabsProps) => {
|
|||||||
{/* the content */}
|
{/* the content */}
|
||||||
<div className="h-full overflow-auto">
|
<div className="h-full overflow-auto">
|
||||||
{Children.map(children, (child) => {
|
{Children.map(children, (child) => {
|
||||||
if (isValidElement(child) && query[group] === child.props.name) {
|
if (isValidElement(child) && activeTab === child.props.name) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import { PageQueryContainer } from '../../components/page-query-container';
|
import { PageQueryContainer } from '../../components/page-query-container';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
Loading…
Reference in New Issue
Block a user