Skip to content

Commit

Permalink
Rewrite examples in documentation to TypeScript (#5873) (#5914)
Browse files Browse the repository at this point in the history
## Summary
This pr adds TypeScript templates of code in the Reanimated Docs.

## How is it work?
I rewrote the `.jsx` exercises to `.tsx` and I added tsx to jsx code
compilation in the InteractiveExample component.

## How to test this feature?
Command to change current working dictionary:
> cd docs

Command to download libraries:
> yarn install

Command to preview the project:
> yarn start

# Screenshots
![Zrzut ekranu 2024-04-8 o 11 33

57](https://github.com/software-mansion/react-native-reanimated/assets/80314375/219ad5ed-681a-43a7-b962-e9fff0a739a5)
![Zrzut ekranu 2024-04-8 o 11 34

26](https://github.com/software-mansion/react-native-reanimated/assets/80314375/69e59174-0273-4c6f-a356-4c231180884b)
![Zrzut ekranu 2024-04-8 o 11 34

46](https://github.com/software-mansion/react-native-reanimated/assets/80314375/acc3a65a-50d6-453f-8a10-b808d173bffa)
  • Loading branch information
xnameTM authored Apr 26, 2024
1 parent 7c45f81 commit 5c350e5
Show file tree
Hide file tree
Showing 48 changed files with 1,051 additions and 176 deletions.
10 changes: 10 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@
"workletization",
"workletize",
"workletized",
"barfoo",
"devs",
"chlgm",
"bfrg",
"typecheck",
"usehooks",
"animable",
"ispreview",
"pressable",
"inout",
"workletizes",
"worklets"
],
Expand Down
3 changes: 3 additions & 0 deletions docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ const config = {
test: /\.txt/,
type: 'asset/source',
},
{
test: /\.tsx?$/
}
],
},
resolve: {
Expand Down
4 changes: 1 addition & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
"@babel/preset-env": "^7.24.4",
"@docusaurus/core": "^2.4.3",
"@docusaurus/plugin-debug": "^2.4.3",
"@docusaurus/preset-classic": "^2.4.3",
Expand Down
99 changes: 86 additions & 13 deletions docs/src/components/InteractiveExample/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,58 @@ import ResetDark from '@site/static/img/reset-dark.svg';

import styles from './styles.module.css';

import ts from 'typescript';
import prettier from 'prettier/standalone';
import babelParser from 'prettier/parser-babel';

function compileTSXtoJSX(tsxCode: string) {
const PLACEHOLDER_FOR_EMPTY_LINES = '// PLACEHOLDER-FOR-EMPTY-LINES';
const PLACEHOLDER_FOR_BREAKING_LINES = '// PLACEHOLDER-FOR-BREAKING-LINES';

// Adding comments to the end of each line to avoid vanishing empty lines
tsxCode = tsxCode
.split('\n')
.map((line) =>
line.trim() === ''
? PLACEHOLDER_FOR_EMPTY_LINES
: line + PLACEHOLDER_FOR_BREAKING_LINES
)
.join('\n');
const result = ts.transpileModule(tsxCode, {
compilerOptions: {
module: ts.ModuleKind.ESNext,
jsx: ts.JsxEmit.Preserve,
pretty: true,
target: ts.ScriptTarget.ES2015,
removeComments: false,
noEmit: false,
indentSize: 2,
},
});

const output = result.outputText
.split('\n')
.map((l) =>
l.trim() === PLACEHOLDER_FOR_EMPTY_LINES
? ''
: l.trim().endsWith(PLACEHOLDER_FOR_BREAKING_LINES)
? l.slice(0, l.indexOf(PLACEHOLDER_FOR_BREAKING_LINES)).trimEnd()
: l
)
.join('\n');

return prettier.format(output, {
parser: 'babel',
bracketSameLine: true,
printWidth: 80,
singleQuote: true,
trailingComma: 'es5',
tabWidth: 2,
arrowParens: 'always',
plugins: [babelParser],
});
}

interface Props {
src: string;
component: React.ReactNode;
Expand All @@ -23,16 +75,23 @@ interface Props {
larger?: boolean; // should the view be enlarged?
}

enum Tab {
PREVIEW,
TYPESCRIPT,
JAVASCRIPT,
}

export default function InteractiveExample({
src,
src: tsxCode,
component,
label,
showCode = false,
larger = false,
}: Props) {
const [_, copy] = useCopyToClipboard();
const [key, setKey] = React.useState(0);
const [showPreview, setShowPreview] = React.useState(!showCode);
const [tab, setTab] = React.useState<Tab>(Tab.PREVIEW);
const [jsxCode, setJsxCode] = React.useState(() => compileTSXtoJSX(tsxCode));

const resetExample = () => {
setKey(key + 1);
Expand All @@ -45,9 +104,11 @@ export default function InteractiveExample({
{() => (
<div
className={`${styles.container} ${larger && styles.largerContainer}
${!showPreview ? styles.code : ''}`}
data-ispreview={showPreview}>
{showPreview && prefersReducedMotion && <ReducedMotionWarning />}
${tab !== Tab.PREVIEW ? styles.code : ''}`}
data-ispreview={tab === Tab.PREVIEW}>
{tab === Tab.PREVIEW && prefersReducedMotion && (
<ReducedMotionWarning />
)}
<div
className={clsx(
styles.buttonsContainer,
Expand All @@ -57,18 +118,26 @@ export default function InteractiveExample({
<button
className={clsx(
styles.actionButton,
showPreview ? styles.actionButtonActive : ''
tab === Tab.PREVIEW ? styles.actionButtonActive : ''
)}
onClick={() => setShowPreview(true)}>
onClick={() => setTab(Tab.PREVIEW)}>
Preview
</button>
<button
className={clsx(
styles.actionButton,
!showPreview ? styles.actionButtonActive : ''
tab === Tab.TYPESCRIPT ? styles.actionButtonActive : ''
)}
onClick={() => setShowPreview(false)}>
Code
onClick={() => setTab(Tab.TYPESCRIPT)}>
TS
</button>
<button
className={clsx(
styles.actionButton,
tab === Tab.JAVASCRIPT ? styles.actionButtonActive : ''
)}
onClick={() => setTab(Tab.JAVASCRIPT)}>
JS
</button>
</div>
<AnimableIcon
Expand All @@ -77,14 +146,14 @@ export default function InteractiveExample({
animation={Animation.FADE_IN_OUT}
onClick={(actionPerformed, setActionPerformed) => {
if (!actionPerformed) {
copy(src);
copy(tab === Tab.JAVASCRIPT ? jsxCode : tsxCode);
setActionPerformed(true);
}
}}
/>
</div>
<div className={styles.previewContainer}>
{showPreview ? (
{tab === Tab.PREVIEW ? (
<>
<React.Fragment key={key}>{component}</React.Fragment>

Expand All @@ -108,9 +177,13 @@ export default function InteractiveExample({
/>
</div>
</>
) : tab === Tab.TYPESCRIPT ? (
<div className={styles.interactiveCodeBlock}>
<CodeBlock language="tsx">{tsxCode}</CodeBlock>
</div>
) : (
<div className={styles.interactiveCodeBlock}>
<CodeBlock language="jsx">{src}</CodeBlock>
<CodeBlock language="jsx">{jsxCode}</CodeBlock>
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const adapter = createAnimatedPropAdapter(
);

export default function App() {
const opacity = useSharedValue(0);
const opacity = useSharedValue<number>(0);

React.useEffect(() => {
opacity.value = withRepeat(withTiming(1), -1, true);
Expand Down
55 changes: 0 additions & 55 deletions docs/src/examples/AnimatedReactionBasic.jsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import Animated, {
} from 'react-native-reanimated';

export default function App() {
const animatedRef = useAnimatedRef();
const width = useSharedValue(100);
const animatedRef = useAnimatedRef<Animated.View>();
const width = useSharedValue<number>(100);
const [text, setText] = React.useState(width.value);

const handlePress = () => {
Expand All @@ -25,8 +25,7 @@ export default function App() {
const measurement = measure(animatedRef);

if (measurement !== null) {
const measuredWidth = parseInt(measurement.width, 10);
runOnJS(setText)(measuredWidth);
runOnJS(setText)(measurement.width);
}
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Animated, { useAnimatedRef } from 'react-native-reanimated';

export default function App() {
// highlight-next-line
const animatedRef = useAnimatedRef();
const animatedRef = useAnimatedRef<Animated.View>();

return (
<View style={styles.container}>
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Svg, Circle } from 'react-native-svg';
const AnimatedCircle = Animated.createAnimatedComponent(Circle);

export default function App() {
const r = useSharedValue(20);
const r = useSharedValue<number>(20);

const handlePress = () => {
r.value += 10;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Animated, {
} from 'react-native-reanimated';

export default function App() {
const translateX = useSharedValue(0);
const translateX = useSharedValue<number>(0);

const handlePress = () => {
translateX.value += 50;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { View, Button, StyleSheet } from 'react-native';
import React from 'react';

export default function App() {
const offset = useSharedValue(0);
const offset = useSharedValue<number>(0);

const style = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { View, Button, StyleSheet } from 'react-native';
import React from 'react';

export default function App() {
const offset = useSharedValue(0);
const offset = useSharedValue<number>(0);

const style = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Animated, {
useSharedValue,
withTiming,
Easing,
useAnimatedStyle,
withRepeat,
withSequence,
Expand All @@ -10,7 +9,7 @@ import { View, Button, StyleSheet } from 'react-native';
import React from 'react';

export default function App() {
const offset = useSharedValue(0);
const offset = useSharedValue<number>(0);

const style = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { View, Button, StyleSheet } from 'react-native';
import React from 'react';

export default function App() {
const offset = useSharedValue(0);
const offset = useSharedValue<number>(0);

// highlight-start
const style = useAnimatedStyle(() => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Animated, {
const OFFSET = 200;

export default function App() {
const offset = useSharedValue(OFFSET);
const offset = useSharedValue<number>(OFFSET);

const animatedStyles = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
Expand Down
5 changes: 3 additions & 2 deletions docs/src/examples/Clamp.jsx → docs/src/examples/Clamp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import {
Gesture,
GestureDetector,
GestureHandlerRootView,
PanGesture,
} from 'react-native-gesture-handler';

export default function App() {
const offset = useSharedValue(0);
const offset = useSharedValue<number>(0);

const pan = Gesture.Pan().onChange((event) => {
const pan: PanGesture = Gesture.Pan().onChange((event) => {
// highlight-next-line
offset.value += clamp(event.changeX, -5, 5);
});
Expand Down
Loading

0 comments on commit 5c350e5

Please sign in to comment.