chore(docs): add Docusaurus components

For:
- Class blocks
- Codelab cards
- Homepage features
- Images
This commit is contained in:
Greg Annandale
2026-03-31 11:30:35 +01:00
parent f5d792b365
commit 89d608ddbb
5 changed files with 158 additions and 0 deletions
@@ -0,0 +1,14 @@
import React from 'react';
/**
* ClassBlock Component
* Renders a block of content with a CSS class applied
* Used for styling specific content blocks (e.g., compare-worse, compare-better)
*
* @param {string} className - The CSS class name to apply
* @param {React.ReactNode} children - The content to render
* @returns {JSX.Element}
*/
export default function ClassBlock({ className, children }) {
return <p className={className}>{children}</p>;
}
@@ -0,0 +1,26 @@
import React from 'react';
import Link from '@docusaurus/Link';
import styles from './styles.module.css';
// This component renders the grid layout
export function CodelabGrid({ children }) {
return <div className={styles.codelabGrid}>{children}</div>;
}
// This component renders a single card
export function CodelabCard({ href, title, description, children, level }) {
return (
<div className={styles.codelabCard}>
<div className={styles.cardHeader}>
<span className={styles.cardIcon}>{children}</span>
</div>
<div>
<span className={styles.eyebrow}>{level}</span>
</div>
<div className={styles.cardFooter}>
<h3 className={styles.cardTitle}>{title}</h3>
<Link href={href}><span className={styles.cardButton}>Start</span></Link>
</div>
</div>
);
}
@@ -0,0 +1,62 @@
import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
const FeatureList = [
{
title: 'Accessible by design',
Svg: require('@site/static/images/HomePage/Accessibility-tier-4.svg').default,
description: (
<>
Built so everyone can engage with visual code helping developers create experiences that are inclusive by default.
</>
),
},
{
title: 'Built for flexibility',
Svg: require('@site/static/images/HomePage/Explore-tier-4.svg').default,
description: (
<>
An open-source library that adapts to your needs. With APIs, generators, and integrations, Blockly fits into most platforms, and environments.
</>
),
},
{
title: 'Driven by community',
Svg: require('@site/static/images/HomePage/Connect-tier-4.svg').default,
description: (
<>
A global community of passionate developers and educators helps Blockly stay open, innovative, and ready for whats next.
</>
),
},
];
function Feature({Svg, title, description}) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<Heading as="h2">{title}</Heading>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures() {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}
@@ -0,0 +1,11 @@
.features {
display: flex;
align-items: center;
padding: 3rem 0 5rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}
+45
View File
@@ -0,0 +1,45 @@
import React from 'react';
import {useColorMode} from '@docusaurus/theme-common';
/**
* Image component for use in MDX docs
* Wraps HTML img tag with additional styling and responsiveness
* Supports theme-based image loading (light/dark mode)
*
* @param {string} src - Image source path (for light mode)
* @param {string} srcDark - Optional image source path for dark mode
* @param {string} alt - Alt text for accessibility
* @param {number|string} width - Optional width (in pixels)
* @param {number|string} height - Optional height (in pixels)
* @param {string} className - Optional CSS class for custom styling
* @param {object} style - Optional inline styles
*/
export default function Image({ src, srcDark, alt, width, height, className, style = {}, ...props }) {
const {colorMode} = useColorMode();
// Select image source based on current theme
const imageSrc = colorMode === 'dark' && srcDark ? srcDark : src;
const imgStyle = {
maxWidth: '100%',
height: 'auto',
...style,
};
if (width) {
imgStyle.width = typeof width === 'number' ? `${width}px` : width;
}
if (height) {
imgStyle.height = typeof height === 'number' ? `${height}px` : height;
}
return (
<img
src={imageSrc}
alt={alt}
className={className}
style={{ ...imgStyle }}
{...props}
/>
);
}