diff --git a/docs.json b/docs.json index eb22219d4..0ae694caf 100644 --- a/docs.json +++ b/docs.json @@ -48,7 +48,8 @@ "image-embeds", "list-table", "code", - "reusable-snippets" + "reusable-snippets", + "react-hooks" ] }, { @@ -203,9 +204,7 @@ }, { "group": "Custom Components", - "pages": [ - "content/components/reusable-components" - ] + "pages": ["content/components/reusable-components"] }, { "group": "API Components", diff --git a/react-hooks.mdx b/react-hooks.mdx new file mode 100644 index 000000000..b9adc95ba --- /dev/null +++ b/react-hooks.mdx @@ -0,0 +1,212 @@ +--- +title: "React Hooks" +description: "Learn how to use React hooks" +icon: "react" +--- + +import { Counter } from "/snippets/counter.mdx"; +import { ColorGenerator } from "/snippets/color-generator.mdx"; + +Create interactive examples and dynamic content in your documentation using familiar [React hooks](https://react.dev/reference/react/hooks). + + + No imports needed! All standard React hooks are automatically available in your MDX files. + + +## Available Hooks + +You can use all standard React hooks in your documentation, such as `useState`, `useEffect`, and other [React hooks](https://react.dev/reference/react/hooks). + +## Interactive Examples + +### 1. Creating Components Directly in MDX + +Create a component directly in your MDX file using React hooks to build interactive elements that respond to user actions: + +*A basic counter component created with `useState` hook* + + + +```jsx +export const Counter = () => { + const [count, setCount] = useState(0); + + return ( +
+

Current count: {count}

+ +
+ ); +} + + +``` + + +### 2. Importing Components from Snippet Files + +Import snippets into your MDX files to create reusable interactive components. Store snippets in the `snippets` folder for better organization. Learn more in the [reusable snippets documentation](/reusable-snippets). + +*Interactive HSL color generator created with multiple React hooks* + + + + + + + Create a new file in the `snippets` folder with your component code. + + ```jsx /snippets/color-generator.mdx [expandable] + export const ColorGenerator = () => { + const [hue, setHue] = useState(180) + const [saturation, setSaturation] = useState(50) + const [lightness, setLightness] = useState(50) + const [colors, setColors] = useState([]) + + useEffect(() => { + const newColors = [] + for (let i = 0; i < 5; i++) { + const l = Math.max(10, Math.min(90, lightness - 20 + i * 10)) + newColors.push(`hsl(${hue}, ${saturation}%, ${l}%)`) + } + setColors(newColors) + }, [hue, saturation, lightness]) + + const copyToClipboard = (color) => { + navigator.clipboard + .writeText(color) + .then(() => { + console.log(`Copied ${color} to clipboard!`) + }) + .catch((err) => { + console.error("Failed to copy: ", err) + }) + } + + return ( +
+ HSL Color Generator + +
+
+ + + + + +
+ +
+ {colors.map((color, idx) => ( +
copyToClipboard(color)} + /> + ))} +
+ +
+

+ Base color: hsl({hue}, {saturation}%, {lightness}%) +

+
+
+
+ ) + } + ``` + + + Add an import statement at the top of your MDX file: + + ```jsx + import { ColorGenerator } from "/snippets/color-generator.mdx" + ``` + + +

Add the component to your MDX content wherever needed:

+ + ```jsx + + ``` +
+ + +## Important Considerations + + + + React hook components render on the client-side, which has several implications: + + - **SEO**: Search engines might not fully index dynamic content + - **Initial Load**: Visitors may experience a flash of loading content before components render + - **Accessibility**: Ensure dynamic content changes are announced to screen readers + + + + - **Optimize Dependency Arrays**: Include only necessary dependencies in your `useEffect` dependency arrays + - **Memoize Complex Calculations**: Use `useMemo` or `useCallback` for expensive operations + - **Reduce Re-renders**: Break large components into smaller ones to prevent cascading re-renders + - **Lazy Loading**: Consider lazy loading complex components to improve initial page load time + + + + + diff --git a/snippets/color-generator.mdx b/snippets/color-generator.mdx new file mode 100644 index 000000000..ef84154f1 --- /dev/null +++ b/snippets/color-generator.mdx @@ -0,0 +1,112 @@ +export const ColorGenerator = () => { + const [hue, setHue] = useState(165) + const [saturation, setSaturation] = useState(84) + const [lightness, setLightness] = useState(31) + const [colors, setColors] = useState([]) + + useEffect(() => { + const newColors = [] + for (let i = 0; i < 5; i++) { + const l = Math.max(10, Math.min(90, lightness - 20 + i * 10)) + newColors.push(`hsl(${hue}, ${saturation}%, ${l}%)`) + } + setColors(newColors) + }, [hue, saturation, lightness]) + + const copyToClipboard = (color) => { + navigator.clipboard + .writeText(color) + .then(() => { + console.log(`Copied ${color} to clipboard!`) + }) + .catch((err) => { + console.error("Failed to copy: ", err) + }) + } + + return ( +
+

HSL Color Generator

+ +
+
+ + + + + +
+ +
+ {colors.map((color, idx) => ( +
copyToClipboard(color)} + /> + ))} +
+ +
+

+ Base color: hsl({hue}, {saturation}%, {lightness}%) +

+
+
+
+ ) +} diff --git a/snippets/counter.mdx b/snippets/counter.mdx new file mode 100644 index 000000000..50b526a94 --- /dev/null +++ b/snippets/counter.mdx @@ -0,0 +1,32 @@ +export const Counter = () => { + const [count, setCount] = useState(0) + + const increment = () => setCount(count + 1) + const decrement = () => setCount(count - 1) + + return ( +
+
+ + +
+ {count} +
+ + +
+
+ ) +} \ No newline at end of file