Skip to content

Commit 3168468

Browse files
authored
Tweak custom content (#630)
* refactor: update CustomContent and useCustomContent to support language parameter - Modified useCustomContent to accept an optional language parameter, enhancing its flexibility. - Updated CustomContent to conditionally display content based on both page type and language, improving content rendering logic. * refactor: improve language handling in CustomContent component - Updated CustomContent to split the language parameter into an array, allowing for more flexible language matching. - Enhanced the logic to determine content display based on both page type and language, improving overall rendering accuracy. * refactor: enhance SimpleTab component to support dynamic tab rendering
1 parent 34a8199 commit 3168468

File tree

3 files changed

+138
-30
lines changed

3 files changed

+138
-30
lines changed
Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,56 @@
1-
import { PropsWithChildren, useEffect, useState } from "react";
1+
import { PropsWithChildren } from "react";
22
import { PageType } from "shared/utils";
33

44
interface CustomContentProps {
5-
platform: "tidb" | "tidb-cloud";
5+
platform?: "tidb" | "tidb-cloud";
6+
language?: string;
67
pageTypeFromURL?: PageType;
8+
languageFromURL?: string;
79
}
810

9-
export const useCustomContent = (pageTypeFromURL: PageType) => {
11+
export const useCustomContent = (
12+
pageTypeFromURL: PageType,
13+
languageFromURL?: string
14+
) => {
1015
return (props: PropsWithChildren<CustomContentProps>) => {
11-
return <CustomContent {...props} pageTypeFromURL={pageTypeFromURL} />;
16+
return (
17+
<CustomContent
18+
{...props}
19+
pageTypeFromURL={pageTypeFromURL}
20+
languageFromURL={languageFromURL}
21+
/>
22+
);
1223
};
1324
};
1425

1526
export const CustomContent: React.FC<PropsWithChildren<CustomContentProps>> = (
1627
props
1728
) => {
18-
const { platform: _pageType, pageTypeFromURL, children } = props;
19-
const pageType = _pageType.replace("-", "");
20-
const [shouldDisplay, setShouldDisplay] = useState(
21-
pageTypeFromURL === pageType
22-
);
23-
useEffect(() => {
24-
const currentPath = window?.location?.pathname || "";
25-
if (currentPath.includes(`/${pageType}/`)) {
26-
setShouldDisplay(true);
27-
} else {
28-
setShouldDisplay(false);
29-
}
30-
}, []);
29+
const {
30+
platform: _pageType,
31+
pageTypeFromURL,
32+
children,
33+
languageFromURL,
34+
language,
35+
} = props;
36+
const pageType = _pageType?.replace("-", "") || "";
37+
const shouldDisplayByPageType = pageTypeFromURL === pageType;
38+
39+
const languageArray = language
40+
? language.split(",").map((lang) => lang.trim())
41+
: [];
42+
const shouldDisplayByLanguage = languageArray.includes(languageFromURL || "");
43+
44+
const onlyPageType = !!pageType && !language;
45+
const onlyLanguage = !pageType && !!language;
46+
const showOnlyPageType = onlyPageType && shouldDisplayByPageType;
47+
const showOnlyLanguage = onlyLanguage && shouldDisplayByLanguage;
48+
const showAll =
49+
!!pageType &&
50+
!!languageFromURL &&
51+
shouldDisplayByPageType &&
52+
shouldDisplayByLanguage;
53+
const shouldDisplay = showOnlyPageType || showOnlyLanguage || showAll;
54+
3155
return <>{shouldDisplay ? children : <></>}</>;
3256
};

src/components/MDXComponents/SimpleTab.tsx

Lines changed: 95 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import { tabs, active, hidden } from "./simple-tab.module.css";
22

3-
import { ReactElement, useState } from "react";
3+
import { ReactElement, useState, useMemo, useEffect, useRef } from "react";
44
import { useDispatch, useSelector } from "react-redux";
55
import { setTabGroup } from "state";
66
import clsx from "clsx";
77

8-
// TODO: refactor with MUI and Recoil
9-
108
export function SimpleTab({
119
groupId,
1210
children,
@@ -18,7 +16,32 @@ export function SimpleTab({
1816
children: ReactElement[];
1917
}>[];
2018
}) {
21-
const defaultValue = children[0]!.props?.value || children[0].props.label;
19+
const [renderedTabs, setRenderedTabs] = useState<string[]>([]);
20+
const actualTabs = useMemo(() => {
21+
const tabs: ReactElement[] = [];
22+
23+
const extractTabs = (elements: ReactElement[]) => {
24+
elements.forEach((element) => {
25+
if (element.props.mdxType === "CustomContent") {
26+
if (element.props.children) {
27+
const childrenArray = Array.isArray(element.props.children)
28+
? element.props.children
29+
: [element.props.children];
30+
extractTabs(childrenArray);
31+
}
32+
} else {
33+
tabs.push(element);
34+
}
35+
});
36+
};
37+
38+
extractTabs(children);
39+
40+
return tabs;
41+
}, [children]);
42+
43+
const defaultValue =
44+
actualTabs[0]?.props?.value || actualTabs[0]?.props.label;
2245
const [activeTab, setActiveTab] = useState(defaultValue);
2346
const dispatch = useDispatch();
2447
const { tabGroup } = useSelector((state) => state) as any;
@@ -28,7 +51,7 @@ export function SimpleTab({
2851
if (
2952
activeTabGroup &&
3053
activeTabGroup !== activeTab &&
31-
children.some(
54+
actualTabs.some(
3255
(child) => child.props?.value || child.props.label === activeTabGroup
3356
)
3457
) {
@@ -43,11 +66,25 @@ export function SimpleTab({
4366
}
4467
};
4568

69+
if (!actualTabs.length) {
70+
return null;
71+
}
72+
73+
useEffect(() => {
74+
if (!renderedTabs.length) {
75+
return;
76+
}
77+
setActiveTab(renderedTabs[0]);
78+
}, [renderedTabs]);
79+
4680
return (
4781
<>
4882
<ul className={clsx(tabs, "simple-tab-container")}>
49-
{children.map((child) => {
83+
{actualTabs.map((child) => {
5084
const id: string = child.props?.value || child.props.label;
85+
if (!renderedTabs.includes(id)) {
86+
return null;
87+
}
5188
return (
5289
<li
5390
key={id}
@@ -59,14 +96,61 @@ export function SimpleTab({
5996
);
6097
})}
6198
</ul>
62-
{children.map((child) => {
63-
const id: string = child.props?.value || child.props.label;
99+
{children.map((child, index) => {
100+
const actualChild = actualTabs[index];
101+
const id: string = actualChild.props?.value || actualChild.props.label;
64102
return (
65-
<div key={id} className={clsx({ [hidden]: activeTab !== id })}>
66-
{child.props.children}
67-
</div>
103+
<TabContentDetector
104+
key={id}
105+
id={id}
106+
activeTab={activeTab}
107+
onRendered={() => {
108+
setRenderedTabs((prev) => {
109+
if (prev.includes(id)) {
110+
return prev;
111+
}
112+
// Add the new tab and then sort based on actualTabs order
113+
const newTabs = [...prev, id];
114+
return newTabs.sort((a, b) => {
115+
const aIndex = actualTabs.findIndex(
116+
(tab) => (tab.props?.value || tab.props.label) === a
117+
);
118+
const bIndex = actualTabs.findIndex(
119+
(tab) => (tab.props?.value || tab.props.label) === b
120+
);
121+
return aIndex - bIndex;
122+
});
123+
});
124+
}}
125+
>
126+
{child}
127+
</TabContentDetector>
68128
);
69129
})}
70130
</>
71131
);
72132
}
133+
134+
export const TabContentDetector = ({
135+
children,
136+
id,
137+
activeTab,
138+
onRendered,
139+
}: {
140+
children: ReactElement;
141+
id: string;
142+
activeTab: string;
143+
onRendered: (id: string) => void;
144+
}) => {
145+
const ref = useRef<HTMLDivElement>(null);
146+
useEffect(() => {
147+
if (ref.current && ref.current.children.length > 0) {
148+
onRendered(id);
149+
}
150+
}, []);
151+
return (
152+
<div ref={ref} key={id} className={clsx({ [hidden]: activeTab !== id })}>
153+
{children}
154+
</div>
155+
);
156+
};

src/components/MDXContent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default function MDXContent(props: {
4141
} = props;
4242

4343
const pageType = getPageType(language, pageUrl);
44-
const CustomContentWithPageType = useCustomContent(pageType);
44+
const CustomContent = useCustomContent(pageType, language);
4545
// const isAutoTranslation = useIsAutoTranslation(pageUrl || "");
4646

4747
React.useEffect(() => {
@@ -67,7 +67,7 @@ export default function MDXContent(props: {
6767
components={{
6868
...MDXComponents,
6969
pre: Pre,
70-
CustomContent: CustomContentWithPageType,
70+
CustomContent,
7171
}}
7272
>
7373
<MDXRenderer>{data}</MDXRenderer>

0 commit comments

Comments
 (0)