diff --git a/apps/docs/src/examples/loading-spinner/sizes.tsx b/apps/docs/src/examples/loading-spinner/sizes.tsx
index 4569af47..e35f85b7 100644
--- a/apps/docs/src/examples/loading-spinner/sizes.tsx
+++ b/apps/docs/src/examples/loading-spinner/sizes.tsx
@@ -1,7 +1,6 @@
import { LoadingSpinner } from '@luke-ui/react/loading-spinner';
-import type { JSX } from 'react';
-export default function Sizes(): JSX.Element {
+export default function Sizes() {
return (
diff --git a/apps/docs/src/examples/numeral/basic.tsx b/apps/docs/src/examples/numeral/basic.tsx
index 376a4fb4..0f5056fc 100644
--- a/apps/docs/src/examples/numeral/basic.tsx
+++ b/apps/docs/src/examples/numeral/basic.tsx
@@ -1,6 +1,5 @@
import { Numeral } from '@luke-ui/react/numeral';
-import type { JSX } from 'react';
-export default function Basic(): JSX.Element {
+export default function Basic() {
return
;
}
diff --git a/apps/docs/src/examples/numeral/compact.tsx b/apps/docs/src/examples/numeral/compact.tsx
index b8d020a3..005f121f 100644
--- a/apps/docs/src/examples/numeral/compact.tsx
+++ b/apps/docs/src/examples/numeral/compact.tsx
@@ -1,11 +1,10 @@
import { Numeral } from '@luke-ui/react/numeral';
-import type { JSX } from 'react';
-export default function Compact(): JSX.Element {
+export default function Compact() {
return (
-
-
+
+
);
}
diff --git a/apps/docs/src/examples/numeral/formats.tsx b/apps/docs/src/examples/numeral/formats.tsx
index 560e3e7b..af99ecb9 100644
--- a/apps/docs/src/examples/numeral/formats.tsx
+++ b/apps/docs/src/examples/numeral/formats.tsx
@@ -1,13 +1,12 @@
import { Numeral } from '@luke-ui/react/numeral';
-import type { JSX } from 'react';
-export default function Formats(): JSX.Element {
+export default function Formats() {
return (
-
-
-
-
+
+
+
+
);
}
diff --git a/apps/docs/src/examples/numeral/precision.tsx b/apps/docs/src/examples/numeral/precision.tsx
index ae1d9064..1c1fe84e 100644
--- a/apps/docs/src/examples/numeral/precision.tsx
+++ b/apps/docs/src/examples/numeral/precision.tsx
@@ -1,11 +1,10 @@
import { Numeral } from '@luke-ui/react/numeral';
-import type { JSX } from 'react';
-export default function Precision(): JSX.Element {
+export default function Precision() {
return (
-
-
+
+
);
}
diff --git a/apps/docs/src/examples/text-field/adornments.tsx b/apps/docs/src/examples/text-field/adornments.tsx
index 3fa6a34c..52a9868a 100644
--- a/apps/docs/src/examples/text-field/adornments.tsx
+++ b/apps/docs/src/examples/text-field/adornments.tsx
@@ -1,17 +1,16 @@
import { Icon } from '@luke-ui/react/icon';
import { TextField } from '@luke-ui/react/text-field';
-import type { JSX } from 'react';
-export default function Adornments(): JSX.Element {
+export default function Adornments() {
return (
}
label="Search"
- adornmentStart={}
+ name="search"
/>
-
-
+
+
);
}
diff --git a/apps/docs/src/examples/text-field/basic.tsx b/apps/docs/src/examples/text-field/basic.tsx
index bd4d0a95..ec82f24d 100644
--- a/apps/docs/src/examples/text-field/basic.tsx
+++ b/apps/docs/src/examples/text-field/basic.tsx
@@ -1,12 +1,11 @@
import { TextField } from '@luke-ui/react/text-field';
-import type { JSX } from 'react';
-export default function Basic(): JSX.Element {
+export default function Basic() {
return (
);
diff --git a/apps/docs/src/examples/text-field/required.tsx b/apps/docs/src/examples/text-field/required.tsx
index 278ca85c..6273004b 100644
--- a/apps/docs/src/examples/text-field/required.tsx
+++ b/apps/docs/src/examples/text-field/required.tsx
@@ -1,11 +1,10 @@
import { TextField } from '@luke-ui/react/text-field';
-import type { JSX } from 'react';
-export default function Required(): JSX.Element {
+export default function Required() {
return (
-
-
+
+
);
}
diff --git a/apps/docs/src/examples/text-field/sizes.tsx b/apps/docs/src/examples/text-field/sizes.tsx
index a04e83a7..35789690 100644
--- a/apps/docs/src/examples/text-field/sizes.tsx
+++ b/apps/docs/src/examples/text-field/sizes.tsx
@@ -1,11 +1,10 @@
import { TextField } from '@luke-ui/react/text-field';
-import type { JSX } from 'react';
-export default function Sizes(): JSX.Element {
+export default function Sizes() {
return (
-
-
+
+
);
}
diff --git a/apps/docs/src/examples/text/alignment.tsx b/apps/docs/src/examples/text/alignment.tsx
index d30791a4..07e295ea 100644
--- a/apps/docs/src/examples/text/alignment.tsx
+++ b/apps/docs/src/examples/text/alignment.tsx
@@ -1,9 +1,8 @@
import { Text } from '@luke-ui/react/text';
-import type { JSX } from 'react';
-export default function Alignment(): JSX.Element {
+export default function Alignment() {
return (
-
+
12121.21
);
diff --git a/apps/docs/src/examples/text/transform.tsx b/apps/docs/src/examples/text/transform.tsx
index c66696ad..f77b5698 100644
--- a/apps/docs/src/examples/text/transform.tsx
+++ b/apps/docs/src/examples/text/transform.tsx
@@ -1,9 +1,8 @@
import { Text } from '@luke-ui/react/text';
-import type { JSX } from 'react';
-export default function Transform(): JSX.Element {
+export default function Transform() {
return (
-
+
Emphasized text
);
diff --git a/apps/docs/src/examples/text/truncation.tsx b/apps/docs/src/examples/text/truncation.tsx
index a25d698b..f9c14f4c 100644
--- a/apps/docs/src/examples/text/truncation.tsx
+++ b/apps/docs/src/examples/text/truncation.tsx
@@ -1,7 +1,6 @@
import { Text } from '@luke-ui/react/text';
-import type { JSX } from 'react';
-export default function Truncation(): JSX.Element {
+export default function Truncation() {
return (
Long content that should be line clamped to two lines.
diff --git a/apps/docs/src/examples/text/typography.tsx b/apps/docs/src/examples/text/typography.tsx
index 125c8adf..d6209716 100644
--- a/apps/docs/src/examples/text/typography.tsx
+++ b/apps/docs/src/examples/text/typography.tsx
@@ -1,7 +1,6 @@
import { Text } from '@luke-ui/react/text';
-import type { JSX } from 'react';
-export default function Typography(): JSX.Element {
+export default function Typography() {
return (
diff --git a/apps/docs/src/lib/remark-validate-examples.ts b/apps/docs/src/lib/remark-validate-examples.ts
new file mode 100644
index 00000000..3f511499
--- /dev/null
+++ b/apps/docs/src/lib/remark-validate-examples.ts
@@ -0,0 +1,50 @@
+import { existsSync } from 'node:fs';
+import { resolve } from 'node:path';
+import { visit } from 'unist-util-visit';
+
+interface Position {
+ start: { line: number; column: number };
+}
+
+interface MdxJsxAttribute {
+ name: string;
+ type: 'mdxJsxAttribute';
+ value: string | { type: 'mdxJsxAttributeValueExpression'; value: string };
+}
+
+interface MdxJsxFlowElement {
+ attributes: Array;
+ name: string;
+ position?: Position;
+ type: string;
+}
+
+export function remarkValidateExamples() {
+ return (tree: unknown, file: { cwd?: string; path?: string }) => {
+ const examplesDir = resolve(file.cwd ?? process.cwd(), 'src/examples');
+
+ visit(tree as never, 'mdxJsxFlowElement', (node: MdxJsxFlowElement) => {
+ if (node.name !== 'ExampleBlock') return;
+
+ const srcAttr = node.attributes.find(
+ (attr: MdxJsxAttribute | { type: 'mdxJsxExpressionAttribute'; value: string }) =>
+ attr.type === 'mdxJsxAttribute' && attr.name === 'src',
+ ) as MdxJsxAttribute | undefined;
+
+ if (!srcAttr || typeof srcAttr.value !== 'string') {
+ const location = node.position ? `${file.path}:${node.position.start.line}` : file.path;
+ throw new Error(`${location}: requires a string \`src\` prop`);
+ }
+
+ const { value: src } = srcAttr;
+ const examplePath = resolve(examplesDir, `${src}.tsx`);
+
+ if (!existsSync(examplePath)) {
+ const location = node.position ? `${file.path}:${node.position.start.line}` : file.path;
+ throw new Error(
+ `${location}: does not match any file at src/examples/${src}.tsx`,
+ );
+ }
+ });
+ };
+}
diff --git a/apps/docs/src/routes/docs/$.tsx b/apps/docs/src/routes/docs/$.tsx
index b09bc0a3..916f4d3f 100644
--- a/apps/docs/src/routes/docs/$.tsx
+++ b/apps/docs/src/routes/docs/$.tsx
@@ -18,7 +18,7 @@ import { getStorybookStoryUrl, withBasePath } from '../../lib/storybook';
const GITHUB_DOCS_URL = 'https://github.com/lukebennett88/luke-ui/blob/main/apps/docs/content/docs';
-const mdxComponents = { ...defaultMdxComponents, AutoTypeTable, TypeTable, ExampleBlock };
+const mdxComponents = { ...defaultMdxComponents, AutoTypeTable, ExampleBlock, TypeTable };
export const Route = createFileRoute('/docs/$')({
component: Page,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 38e84ce2..546ed943 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -165,6 +165,9 @@ catalogs:
typescript:
specifier: ^6.0.3
version: 6.0.3
+ unist-util-visit:
+ specifier: ^5.1.0
+ version: 5.1.0
vite-plus:
specifier: 0.2.2
version: 0.2.2
@@ -292,6 +295,9 @@ importers:
typescript:
specifier: 'catalog:'
version: 6.0.3
+ unist-util-visit:
+ specifier: 'catalog:'
+ version: 5.1.0
vite-plus:
specifier: 'catalog:'
version: 0.2.2(@arethetypeswrong/core@0.18.4)(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(@voidzero-dev/vite-plus-core@0.2.2(@arethetypeswrong/core@0.18.4)(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(publint@0.3.21)(tsx@4.22.4)(typescript@6.0.3)(unrun@0.2.37)(yaml@2.9.0))(esbuild@0.28.1)(jiti@2.7.0)(publint@0.3.21)(tsx@4.22.4)(typescript@6.0.3)(unrun@0.2.37)(yaml@2.9.0)
@@ -9111,9 +9117,9 @@ snapshots:
obug: 2.1.3
std-env: 4.1.0
tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/browser-preview@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(vite@8.1.3(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
+ vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/browser-preview@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(@voidzero-dev/vite-plus-core@0.2.2(@arethetypeswrong/core@0.18.4)(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(publint@0.3.21)(tsx@4.22.4)(typescript@6.0.3)(unrun@0.2.37)(yaml@2.9.0))
optionalDependencies:
- '@vitest/browser': 4.1.9(vite@8.1.3(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))(vitest@4.1.9)
+ '@vitest/browser': 4.1.9(@voidzero-dev/vite-plus-core@0.2.2(@arethetypeswrong/core@0.18.4)(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(publint@0.3.21)(tsx@4.22.4)(typescript@6.0.3)(unrun@0.2.37)(yaml@2.9.0))(vitest@4.1.9)
'@vitest/expect@3.2.4':
dependencies:
@@ -9183,7 +9189,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.17
tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/browser-preview@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(vite@8.1.3(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
+ vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/browser-preview@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(@voidzero-dev/vite-plus-core@0.2.2(@arethetypeswrong/core@0.18.4)(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(publint@0.3.21)(tsx@4.22.4)(typescript@6.0.3)(unrun@0.2.37)(yaml@2.9.0))
'@vitest/utils@3.2.4':
dependencies:
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index ec22e483..f91f16aa 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -65,6 +65,7 @@ catalog:
vite: npm:@voidzero-dev/vite-plus-core@0.2.2
vitest: 4.1.9
vite-plus: 0.2.2
+ unist-util-visit: ^5.1.0
catalogMode: prefer