Skip to content

Commit 029d670

Browse files
authored
[Docs] Add compatibility table (#3882)
## Description This PR adds compatibility table to our documentation 🎉 >[!IMPORTANT] >_Any resemblance to [Reanimated compatibility table](https://docs.swmansion.com/react-native-reanimated/docs/guides/compatibility) is purely coincidental._ ## Test plan Read docs 🤓
1 parent 2dfec2d commit 029d670

4 files changed

Lines changed: 200 additions & 12 deletions

File tree

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import { useDocsVersion } from '@docusaurus/plugin-content-docs/client';
2+
import React from 'react';
3+
4+
// It would be great to import from package, but unfortunately it does not work on CI :c
5+
// eslint-disable-next-line import-x/no-relative-packages
6+
import untypedCompatibilityData from '../../../react-native-gesture-handler/compatibility.json';
7+
import styles from './styles.module.css';
8+
9+
interface CompatibilityEntry {
10+
'react-native': string[];
11+
}
12+
13+
type CompatibilityData = Record<string, CompatibilityEntry>;
14+
15+
const compatibilityData = untypedCompatibilityData as CompatibilityData;
16+
17+
export function Yes() {
18+
return <div className={styles.supported}>yes</div>;
19+
}
20+
21+
export function No() {
22+
return <div className={styles.notSupported}>no</div>;
23+
}
24+
25+
interface VersionProps {
26+
version: string;
27+
}
28+
29+
export function Version({ version }: VersionProps) {
30+
return <div className={styles.version}>{version}</div>;
31+
}
32+
33+
export function Spacer() {
34+
return <div className={styles.spacer}></div>;
35+
}
36+
37+
interface CompatibilityItem {
38+
version: string;
39+
isSpacer: boolean;
40+
compatibility: Record<string, boolean>;
41+
}
42+
43+
type GestureHandlerCompatibilityProps = {
44+
spacerAfterIndex?: number;
45+
};
46+
47+
const getCompatibilityEntriesForVersion = (
48+
version: string,
49+
shouldInclude: (data: CompatibilityEntry) => boolean = () => true
50+
) => {
51+
if (version === 'current') {
52+
// For current version, find the highest major version and include nightly
53+
const highestMajorVersion = Math.max(
54+
...Object.keys(compatibilityData).map((key) => {
55+
const num = key.split('.')[0];
56+
return isNaN(+num) ? 0 : +num;
57+
})
58+
);
59+
60+
return Object.entries(compatibilityData).filter(
61+
([key, data]) =>
62+
(key === 'nightly' || key.startsWith(`${highestMajorVersion}.`)) &&
63+
shouldInclude(data)
64+
);
65+
}
66+
67+
// For versioned docs (e.g. "3.x", "2.x", "1.x"), extract the major version number
68+
const majorVersion = version.replace('.x', '');
69+
return Object.entries(compatibilityData).filter(
70+
([key, data]) => key.startsWith(`${majorVersion}.`) && shouldInclude(data)
71+
);
72+
};
73+
74+
const extractVersions = (
75+
data: [string, CompatibilityEntry][],
76+
getVersions: (entry: CompatibilityEntry) => string[]
77+
): string[] =>
78+
Array.from(new Set(data.flatMap(([, entry]) => getVersions(entry)))).sort();
79+
80+
const createCompatibilityItems = (
81+
filteredData: [string, CompatibilityEntry][],
82+
versions: string[],
83+
getSupportedVersions: (data: CompatibilityEntry) => Set<string>,
84+
spacerAfterIndex?: number
85+
): CompatibilityItem[] =>
86+
filteredData.map(([version, data], index) => {
87+
const supportedVersions = getSupportedVersions(data);
88+
const compatibility = Object.fromEntries(
89+
versions.map((versionNumber) => [
90+
versionNumber,
91+
supportedVersions.has(versionNumber),
92+
])
93+
);
94+
95+
return {
96+
version,
97+
isSpacer: index === spacerAfterIndex,
98+
compatibility,
99+
};
100+
});
101+
102+
interface CompatibilityTableProps {
103+
versions: string[];
104+
items: CompatibilityItem[];
105+
}
106+
107+
function CompatibilityTable({ versions, items }: CompatibilityTableProps) {
108+
return (
109+
<div className="compatibility">
110+
<table className={styles.table}>
111+
<thead>
112+
<tr>
113+
<th></th>
114+
{versions.map((version) => (
115+
<th key={version}>{version}</th>
116+
))}
117+
</tr>
118+
</thead>
119+
<tbody>
120+
{items.map((item, index) => (
121+
<React.Fragment key={index}>
122+
<tr>
123+
<td>
124+
<Version version={item.version} />
125+
</td>
126+
{versions.map((version) => (
127+
<td key={version}>
128+
{item.compatibility[version] ? <Yes /> : <No />}
129+
</td>
130+
))}
131+
</tr>
132+
{item.isSpacer && <Spacer />}
133+
</React.Fragment>
134+
))}
135+
</tbody>
136+
</table>
137+
</div>
138+
);
139+
}
140+
141+
export function GestureHandlerCompatibility({
142+
spacerAfterIndex,
143+
}: GestureHandlerCompatibilityProps) {
144+
const docsVersion = useDocsVersion();
145+
const filteredCompatibilityData = getCompatibilityEntriesForVersion(
146+
docsVersion.version
147+
);
148+
149+
const reactNativeVersions = extractVersions(
150+
filteredCompatibilityData,
151+
(data) => data['react-native']
152+
);
153+
154+
const compatibilityItems = createCompatibilityItems(
155+
filteredCompatibilityData,
156+
reactNativeVersions,
157+
(data) => new Set(data['react-native']),
158+
spacerAfterIndex
159+
);
160+
161+
return (
162+
<CompatibilityTable
163+
versions={reactNativeVersions}
164+
items={compatibilityItems}
165+
/>
166+
);
167+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.supported {
2+
color: var(--swm-compatibility-text-color);
3+
background-color: var(--swm-compatibility-supported-background);
4+
text-align: center;
5+
text-transform: capitalize;
6+
padding: 12px;
7+
}
8+
9+
.notSupported {
10+
color: var(--swm-compatibility-text-color);
11+
background-color: var(--swm-compatibility-not-supported-background);
12+
text-align: center;
13+
text-transform: capitalize;
14+
padding: 12px;
15+
}
16+
17+
.version {
18+
font-weight: bold;
19+
text-align: center;
20+
padding: 12px;
21+
}
22+
23+
.spacer {
24+
padding-top: 10px;
25+
}

packages/docs-gesture-handler/docs/fundamentals/installation.md renamed to packages/docs-gesture-handler/docs/fundamentals/installation.mdx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,13 @@ sidebar_position: 2
77
import Tabs from '@theme/Tabs';
88
import TabItem from '@theme/TabItem';
99

10+
import { GestureHandlerCompatibility } from '../../components/Compatibility';
11+
1012
## Requirements
1113

1214
`react-native-gesture-handler` supports the three latest minor releases of `react-native`.
1315

14-
| version | `react-native` version |
15-
| ------- | ---------------------- |
16-
| 2.28.0+ | 0.79.0+ |
17-
| 2.26.0+ | 0.78.0+ |
18-
| 2.25.0+ | 0.76.0+ |
19-
| 2.24.0+ | 0.75.0+ |
20-
| 2.21.0+ | 0.74.0+ |
21-
| 2.18.0+ | 0.73.0+ |
22-
| 2.16.0+ | 0.68.0+ |
23-
| 2.14.0+ | 0.67.0+ |
24-
| 2.10.0+ | 0.64.0+ |
25-
| 2.0.0+ | 0.63.0+ |
16+
<GestureHandlerCompatibility spacerAfterIndex={1} />
2617

2718
In order to fully utilize the [touch events](/docs/gestures/touch-events/) you also need to use `react-native-reanimated` 2.3.0 or newer.
2819

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"3.0.0": {
3+
"react-native": ["?"]
4+
}
5+
}

0 commit comments

Comments
 (0)