diff --git a/eslint.config.js b/eslint.config.js
index 6f4ebde..6f2857a 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -6,7 +6,12 @@ import globals from "globals";
import tseslint from "typescript-eslint";
export default tseslint.config([
- globalIgnores(["dist", "docs", "generated", "integrations/next/.next"]),
+ globalIgnores([
+ "dist",
+ "docs",
+ "public/generated",
+ "integrations/next/.next"
+ ]),
{
files: ["**/*.{ts,tsx}"],
ignores: ["**/*.example.tsx"],
diff --git a/index.css b/index.css
index 3da6c53..81fb533 100644
--- a/index.css
+++ b/index.css
@@ -1,92 +1,14 @@
+@source "node_modules/react-lib-tools";
+
@import "tailwindcss";
+@import "react-lib-tools/styles.css";
:root {
- font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
- font-size: 12px;
-
- @media only screen and (max-width: 600px) {
- font-size: 16px;
- }
-
- color-scheme: dark;
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-@keyframes background-gradient-animation {
- 0% {
- background-position: 0% 50%;
- }
- 50% {
- background-position: 100% 50%;
- }
- 100% {
- background-position: 0% 50%;
- }
-}
-
-#root {
- width: 100dvw;
- height: 100dvh;
- overflow: auto;
- background: linear-gradient(
- -45deg,
- var(--color-fuchsia-500),
- var(--color-violet-500),
- var(--color-fuchsia-700)
- );
- background-size: 400% 400%;
- animation: background-gradient-animation 20s ease infinite;
-}
-
-* {
- scrollbar-width: thin;
- scrollbar-color: var(--color-slate-600) transparent;
- outline: none;
- transition:
- color 0.25s ease,
- background-color 0.25s ease,
- border-color 0.25s ease,
- opacity 0.25s ease,
- outline-color 0.25s ease;
-}
-
-main {
- [data-link],
- a {
- cursor: pointer;
- color: var(--color-sky-400);
- &:hover {
- color: var(--color-sky-300);
- }
- }
-}
-
-*[data-focus] {
- border: 2px solid transparent;
- &:focus {
- border: 2px solid var(--color-sky-300);
- }
-}
-
-*[data-focus-within] {
- border: 2px solid transparent;
- &:focus-within {
- border: 2px solid var(--color-sky-300);
- }
-
- &[data-focus-within="bold"] {
- border-color: var(--color-sky-600);
- &:focus-within {
- border: 2px solid var(--color-sky-300);
- }
- }
-}
+ --template-gradient-color-1: var(--color-rose-700);
+ --template-gradient-color-2: var(--color-violet-800);
+ --template-gradient-color-3: var(--color-blue-700);
-code {
- color: rgba(255, 255, 255, 0.8);
+ --template-focus-color-300: var(--color-sky-300);
+ --template-focus-color-400: var(--color-sky-400);
+ --template-focus-color-600: var(--color-sky-600);
}
diff --git a/package.json b/package.json
index 3e19635..5c87af8 100644
--- a/package.json
+++ b/package.json
@@ -38,9 +38,9 @@
"build": "pnpm run build:lib && pnpm run build:docs",
"build:docs": "TARGET=docs vite build",
"build:lib": "TARGET=lib vite build",
- "compile": "pnpm run compile:code-snippets && pnpm run compile:docs",
- "compile:code-snippets": "node --loader ts-node/esm ./scripts/compile-code-snippets.ts",
- "compile:docs": "node --loader ts-node/esm ./scripts/compile-docs.ts",
+ "compile": "pnpm run compile:docs && pnpm run compile:examples",
+ "compile:docs": "tsx ./scripts/compile-docs",
+ "compile:examples": "tsx ./scripts/compile-examples",
"e2e:install": "pnpm -C integrations/vite/ exec playwright install --with-deps",
"e2e:test": "pnpm -C integrations/vite/ run test",
"lint": "eslint .",
@@ -106,6 +106,7 @@
"react-docgen-typescript": "^2.4.0",
"react-dom": "^19.2.3",
"react-error-boundary": "^6.0.0",
+ "react-lib-tools": "^0.0.6",
"react-router-dom": "^7.6.3",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-visualizer": "^6.0.3",
@@ -116,14 +117,15 @@
"terser": "^5.43.1",
"ts-blank-space": "^0.6.2",
"ts-node": "^10.9.2",
+ "tsx": "^4.21.0",
"typescript": "~5.8.3",
"typescript-eslint": "^8.35.1",
"typescript-json-schema": "^0.65.1",
"vite": "^7.0.4",
- "vitest-fail-on-console": "^0.10.1",
"vite-plugin-dts": "^4.5.4",
"vite-plugin-svgr": "^4.3.0",
"vitest": "^3.2.4",
+ "vitest-fail-on-console": "^0.10.1",
"zustand": "^5.0.7"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ef4beac..f88a2b6 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -46,7 +46,7 @@ importers:
version: 1.2.1
'@tailwindcss/vite':
specifier: ^4.1.11
- version: 4.1.17(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))
+ version: 4.1.17(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))
'@tailwindplus/elements':
specifier: ^1.0.5
version: 1.0.19
@@ -82,7 +82,7 @@ importers:
version: 19.2.3(@types/react@19.2.7)
'@vitejs/plugin-react-swc':
specifier: ^3.10.2
- version: 3.11.0(@swc/helpers@0.5.17)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))
+ version: 3.11.0(@swc/helpers@0.5.17)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))
clsx:
specifier: ^2.1.1
version: 2.1.1
@@ -143,6 +143,9 @@ importers:
react-error-boundary:
specifier: ^6.0.0
version: 6.0.0(react@19.2.3)
+ react-lib-tools:
+ specifier: ^0.0.6
+ version: 0.0.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
react-router-dom:
specifier: ^7.6.3
version: 7.10.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -173,6 +176,9 @@ importers:
ts-node:
specifier: ^10.9.2
version: 10.9.2(@swc/core@1.13.5(@swc/helpers@0.5.17))(@types/node@24.10.4)(typescript@5.8.3)
+ tsx:
+ specifier: ^4.21.0
+ version: 4.21.0
typescript:
specifier: ~5.8.3
version: 5.8.3
@@ -184,19 +190,19 @@ importers:
version: 0.65.1(@swc/core@1.13.5(@swc/helpers@0.5.17))
vite:
specifier: ^7.0.4
- version: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ version: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
vite-plugin-dts:
specifier: ^4.5.4
- version: 4.5.4(@types/node@24.10.4)(rollup@4.49.0)(typescript@5.8.3)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))
+ version: 4.5.4(@types/node@24.10.4)(rollup@4.49.0)(typescript@5.8.3)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))
vite-plugin-svgr:
specifier: ^4.3.0
- version: 4.5.0(rollup@4.49.0)(typescript@5.8.3)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))
+ version: 4.5.0(rollup@4.49.0)(typescript@5.8.3)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))
vitest:
specifier: ^3.2.4
- version: 3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ version: 3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
vitest-fail-on-console:
specifier: ^0.10.1
- version: 0.10.1(@vitest/utils@3.2.4)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))(vitest@3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))
+ version: 0.10.1(@vitest/utils@3.2.4)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))(vitest@3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))
zustand:
specifier: ^5.0.7
version: 5.0.9(@types/react@19.2.7)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
@@ -224,7 +230,7 @@ importers:
version: 1.57.0
'@tailwindcss/vite':
specifier: ^4.1.17
- version: 4.1.17(vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))
+ version: 4.1.17(vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))
'@types/react':
specifier: ^19.1.2
version: 19.2.7
@@ -233,7 +239,7 @@ importers:
version: 19.2.3(@types/react@19.2.7)
'@vitejs/plugin-react':
specifier: ^4.4.1
- version: 4.7.0(vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))
+ version: 4.7.0(vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))
eslint:
specifier: ^9.25.0
version: 9.39.2(jiti@2.6.1)
@@ -257,7 +263,7 @@ importers:
version: 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3)
vite:
specifier: ^6.3.5
- version: 6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ version: 6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
packages:
@@ -2192,6 +2198,9 @@ packages:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
+ get-tsconfig@4.13.0:
+ resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
+
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -2904,6 +2913,12 @@ packages:
react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+ react-lib-tools@0.0.6:
+ resolution: {integrity: sha512-1oJB9AqKSL/wmUzBr98PDXeNCuWhKFZs1A+XDOQsNbgSscXPSmoHle0D+sNmRwjKw5Fw5JHKYPcpISaVIwk/3g==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+
react-refresh@0.17.0:
resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==}
engines: {node: '>=0.10.0'}
@@ -2945,6 +2960,9 @@ packages:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
resolve@1.22.10:
resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
engines: {node: '>= 0.4'}
@@ -3276,6 +3294,11 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+ tsx@4.21.0:
+ resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
@@ -4571,19 +4594,19 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.17
'@tailwindcss/oxide-win32-x64-msvc': 4.1.17
- '@tailwindcss/vite@4.1.17(vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))':
+ '@tailwindcss/vite@4.1.17(vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@tailwindcss/node': 4.1.17
'@tailwindcss/oxide': 4.1.17
tailwindcss: 4.1.17
- vite: 6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
- '@tailwindcss/vite@4.1.17(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))':
+ '@tailwindcss/vite@4.1.17(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@tailwindcss/node': 4.1.17
'@tailwindcss/oxide': 4.1.17
tailwindcss: 4.1.17
- vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
'@tailwindplus/elements@1.0.19': {}
@@ -4849,15 +4872,15 @@ snapshots:
'@typescript-eslint/types': 8.50.0
eslint-visitor-keys: 4.2.1
- '@vitejs/plugin-react-swc@3.11.0(@swc/helpers@0.5.17)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))':
+ '@vitejs/plugin-react-swc@3.11.0(@swc/helpers@0.5.17)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@rolldown/pluginutils': 1.0.0-beta.27
'@swc/core': 1.13.5(@swc/helpers@0.5.17)
- vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- '@swc/helpers'
- '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))':
+ '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@babel/core': 7.28.5
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5)
@@ -4865,7 +4888,7 @@ snapshots:
'@rolldown/pluginutils': 1.0.0-beta.27
'@types/babel__core': 7.20.5
react-refresh: 0.17.0
- vite: 6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
@@ -4877,13 +4900,13 @@ snapshots:
chai: 5.3.3
tinyrainbow: 2.0.0
- '@vitest/mocker@3.2.4(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))':
+ '@vitest/mocker@3.2.4(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
- vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
'@vitest/pretty-format@3.2.4':
dependencies:
@@ -5570,6 +5593,10 @@ snapshots:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
+ get-tsconfig@4.13.0:
+ dependencies:
+ resolve-pkg-maps: 1.0.0
+
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
@@ -6165,6 +6192,11 @@ snapshots:
react-is@17.0.2: {}
+ react-lib-tools@0.0.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ dependencies:
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+
react-refresh@0.17.0: {}
react-router-dom@7.10.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
@@ -6194,6 +6226,8 @@ snapshots:
resolve-from@4.0.0: {}
+ resolve-pkg-maps@1.0.0: {}
+
resolve@1.22.10:
dependencies:
is-core-module: 2.16.1
@@ -6558,6 +6592,13 @@ snapshots:
tslib@2.8.1: {}
+ tsx@4.21.0:
+ dependencies:
+ esbuild: 0.27.2
+ get-tsconfig: 4.13.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
type-check@0.4.0:
dependencies:
prelude-ls: 1.2.1
@@ -6631,13 +6672,13 @@ snapshots:
vary@1.1.2: {}
- vite-node@3.2.4(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1):
+ vite-node@3.2.4(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
cac: 6.7.14
debug: 4.4.1
es-module-lexer: 1.7.0
pathe: 2.0.3
- vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- '@types/node'
- jiti
@@ -6652,7 +6693,7 @@ snapshots:
- tsx
- yaml
- vite-plugin-dts@4.5.4(@types/node@24.10.4)(rollup@4.49.0)(typescript@5.8.3)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)):
+ vite-plugin-dts@4.5.4(@types/node@24.10.4)(rollup@4.49.0)(typescript@5.8.3)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)):
dependencies:
'@microsoft/api-extractor': 7.52.13(@types/node@24.10.4)
'@rollup/pluginutils': 5.3.0(rollup@4.49.0)
@@ -6665,24 +6706,24 @@ snapshots:
magic-string: 0.30.21
typescript: 5.8.3
optionalDependencies:
- vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- '@types/node'
- rollup
- supports-color
- vite-plugin-svgr@4.5.0(rollup@4.49.0)(typescript@5.8.3)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)):
+ vite-plugin-svgr@4.5.0(rollup@4.49.0)(typescript@5.8.3)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)):
dependencies:
'@rollup/pluginutils': 5.3.0(rollup@4.49.0)
'@svgr/core': 8.1.0(typescript@5.8.3)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.8.3))
- vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- rollup
- supports-color
- typescript
- vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1):
+ vite@6.4.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.3)
@@ -6696,9 +6737,10 @@ snapshots:
jiti: 2.6.1
lightningcss: 1.30.2
terser: 5.43.1
+ tsx: 4.21.0
yaml: 2.8.1
- vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1):
+ vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
esbuild: 0.27.2
fdir: 6.5.0(picomatch@4.0.3)
@@ -6712,20 +6754,21 @@ snapshots:
jiti: 2.6.1
lightningcss: 1.30.2
terser: 5.43.1
+ tsx: 4.21.0
yaml: 2.8.1
- vitest-fail-on-console@0.10.1(@vitest/utils@3.2.4)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))(vitest@3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)):
+ vitest-fail-on-console@0.10.1(@vitest/utils@3.2.4)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))(vitest@3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)):
dependencies:
'@vitest/utils': 3.2.4
chalk: 5.6.0
- vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
- vitest: 3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
+ vitest: 3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
- vitest@3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1):
+ vitest@3.2.4(@types/node@24.10.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
'@types/chai': 5.2.2
'@vitest/expect': 3.2.4
- '@vitest/mocker': 3.2.4(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1))
+ '@vitest/mocker': 3.2.4(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1))
'@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4
@@ -6743,8 +6786,8 @@ snapshots:
tinyglobby: 0.2.15
tinypool: 1.1.1
tinyrainbow: 2.0.0
- vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
- vite-node: 3.2.4(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.1)
+ vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
+ vite-node: 3.2.4(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.1)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 24.10.4
diff --git a/public/generated/js-docs/AutoSizer.json b/public/generated/docs/AutoSizer.json
similarity index 100%
rename from public/generated/js-docs/AutoSizer.json
rename to public/generated/docs/AutoSizer.json
diff --git a/public/generated/examples/AutoSizerPropsRoute.tsx b/public/generated/examples/AutoSizerPropsRoute.tsx
new file mode 100644
index 0000000..d380665
--- /dev/null
+++ b/public/generated/examples/AutoSizerPropsRoute.tsx
@@ -0,0 +1,3 @@
+{
+ "html": "
import { Box , ComponentProps } from \"react-lib-tools\" ;
\nimport json from \"../../public/generated/docs/AutoSizer.json\" ;
\nimport type { ComponentMetadata } from \"../types\" ;
\n
\nexport default function AutoSizerPropsRoute ( ) {
\n return (
\n < Box direction = \"column\" gap = { 4 } >
\n < ComponentProps json = { json as ComponentMetadata } section = \"Props\" />
\n </ Box >
\n ) ;
\n}
"
+}
\ No newline at end of file
diff --git a/public/generated/examples/BasicUsageRoute.tsx b/public/generated/examples/BasicUsageRoute.tsx
new file mode 100644
index 0000000..d39ee79
--- /dev/null
+++ b/public/generated/examples/BasicUsageRoute.tsx
@@ -0,0 +1,3 @@
+{
+ "html": "import { Box , Code , Header } from \"react-lib-tools\" ;
\nimport { html } from \"../../public/generated/examples/ChildComponent.json\" ;
\n
\nexport default function BasicUsageRoute ( ) {
\n return (
\n < Box direction = \"column\" gap = { 4 } >
\n < Header section = \"Examples\" title = \"Basic usage\" />
\n < div >
\n < code > AutoSizer </ code > measures the available width and height of its
\n parent < code > HTMLElement </ code > and passes them as props to a { \" \" }
\n < code > Child </ code > component.
\n </ div >
\n < Code html = { html } />
\n </ Box >
\n ) ;
\n}
"
+}
\ No newline at end of file
diff --git a/public/generated/code-snippets/ChildComponent.json b/public/generated/examples/ChildComponent.json
similarity index 100%
rename from public/generated/code-snippets/ChildComponent.json
rename to public/generated/examples/ChildComponent.json
diff --git a/public/generated/examples/GettingStartedRoute.tsx b/public/generated/examples/GettingStartedRoute.tsx
new file mode 100644
index 0000000..cda353a
--- /dev/null
+++ b/public/generated/examples/GettingStartedRoute.tsx
@@ -0,0 +1,3 @@
+{
+ "html": "import { Box , Callout , ExternalLink , Header } from \"react-lib-tools\" ;
\nimport { Link } from \"../components/Link\" ;
\n
\nexport default function GettingStartedRoute ( ) {
\n return (
\n < Box direction = \"column\" gap = { 4 } >
\n < Header title = \"Getting started\" />
\n < div >
\n This package measures the available width and height of an { \" \" }
\n < code > HTMLElement </ code > and passes those values as props to a { \" \" }
\n < code > Child </ code > component. Refer to the { \" \" }
\n < Link to = \"/examples/basic-usage\" > examples </ Link > or { \" \" }
\n < Link to = \"/props/auto-sizer\" > props </ Link > pages for more information.
\n </ div >
\n < Callout intent = \"primary\" >
\n This package began as a fork of the < code > AutoSizer </ code > component
\n from { \" \" }
\n < ExternalLink href = \"https://github.com/bvaughn/react-virtualized\" >
\n react-virtualized
\n </ ExternalLink >
\n , and was intended for use with earlier versions of { \" \" }
\n < ExternalLink href = \"https://github.com/bvaughn/react-virtualized\" >
\n react-window
\n </ ExternalLink >
\n . More recent versions of < code > react-window </ code > use { \" \" }
\n < code > ResizeObserver </ code > natively and do not require this package.
\n </ Callout >
\n < div className = \"text-xl mt-4\" > Installation </ div >
\n < div > Begin by installing the library from NPM: </ div >
\n < code className = \"grow text-xs md:text-sm block text-left whitespace-pre-wrap rounded-md p-3 bg-black text-white!\" >
\n npm install { \" \" }
\n < span className = \"tok-keyword\" > react-virtualized-auto-sizer </ span >
\n </ code >
\n < Callout intent = \"primary\" >
\n TypeScript definitions are included within the published { \" \" }
\n < code > dist </ code > folder.
\n </ Callout >
\n < div className = \"text-xl mt-4\" > Support </ div >
\n < div > Here are some ways to support this project: </ div >
\n < ul className = \"pl-8\" >
\n < li className = \"list-disc\" >
\n < ExternalLink href = \"https://github.com/sponsors/bvaughn/\" >
\n Become a GitHub sponsor
\n </ ExternalLink >
\n </ li >
\n < li className = \"list-disc\" >
\n < ExternalLink href = \"http://givebrian.coffee/\" >
\n Buy me a coffee
\n </ ExternalLink >
\n </ li >
\n </ ul >
\n </ Box >
\n ) ;
\n}
"
+}
\ No newline at end of file
diff --git a/public/generated/examples/PageNotFound.tsx b/public/generated/examples/PageNotFound.tsx
new file mode 100644
index 0000000..859d7f7
--- /dev/null
+++ b/public/generated/examples/PageNotFound.tsx
@@ -0,0 +1,3 @@
+{
+ "html": "import { Box , Callout , ExternalLink , Header } from \"react-lib-tools\" ;
\n
\nexport default function PageNotFound ( ) {
\n return (
\n < Box direction = \"column\" gap = { 4 } >
\n < Header title = \"Page not found\" />
\n < Callout intent = \"danger\" >
\n The URL you requested can't be found. If you think this is an error, { \" \" }
\n < ExternalLink href = \"https://github.com/bvaughn/react-virtualized-auto-sizer/issues/new\" >
\n please file a GitHub issue
\n </ ExternalLink >
\n .
\n </ Callout >
\n </ Box >
\n ) ;
\n}
"
+}
\ No newline at end of file
diff --git a/public/generated/code-snippets/RenderProp.json b/public/generated/examples/RenderProp.json
similarity index 100%
rename from public/generated/code-snippets/RenderProp.json
rename to public/generated/examples/RenderProp.json
diff --git a/public/generated/examples/RenderPropRoute.tsx b/public/generated/examples/RenderPropRoute.tsx
new file mode 100644
index 0000000..35f0aa2
--- /dev/null
+++ b/public/generated/examples/RenderPropRoute.tsx
@@ -0,0 +1,3 @@
+{
+ "html": "import { Box , Callout , Code , ExternalLink , Header } from \"react-lib-tools\" ;
\nimport { html } from \"../../public/generated/examples/RenderProp.json\" ;
\n
\nexport default function RenderPropRoute ( ) {
\n return (
\n < Box direction = \"column\" gap = { 4 } >
\n < Header section = \"Examples\" title = \"Render props\" />
\n < div >
\n The < code > Child </ code > component can also be a { \" \" }
\n < ExternalLink href = \"https://legacy.reactjs.org/docs/render-props.html\" >
\n render prop
\n </ ExternalLink >
\n .
\n </ div >
\n < Code html = { html } />
\n < Callout intent = \"primary\" >
\n Render props provide the added benefit of being able to reference other
\n values that are in scope.
\n </ Callout >
\n </ Box >
\n ) ;
\n}
"
+}
\ No newline at end of file
diff --git a/public/generated/examples/SupportRoute.tsx b/public/generated/examples/SupportRoute.tsx
new file mode 100644
index 0000000..d612a56
--- /dev/null
+++ b/public/generated/examples/SupportRoute.tsx
@@ -0,0 +1,3 @@
+{
+ "html": "import { Box , ExternalLink , Header } from \"react-lib-tools\" ;
\n
\nexport default function SupportRoute ( ) {
\n return (
\n < Box direction = \"column\" gap = { 4 } >
\n < Header title = \"Support\" />
\n < div >
\n < ExternalLink href = \"https://github.com/bvaughn/react-virtualized-auto-sizer\" >
\n GitHub
\n </ ExternalLink > { \" \" }
\n is the easiest place to look for help, but it's probably not the
\n fastest. This project is maintained by a single developer so there is
\n limited bandwidth for answering questions.
\n </ div >
\n < div >
\n I recommend asking questions on { \" \" }
\n < ExternalLink href = \"https://stackoverflow.com/search?q=react-virtualized-auto-sizer\" >
\n Stack Overflow
\n </ ExternalLink > { \" \" }
\n or { \" \" }
\n < ExternalLink href = \"https://reddit.com/r/reactjs\" > Reddit </ ExternalLink > { \" \" }
\n to start with. Both sites have active communities who often respond
\n quickly. If you don't find an answer there you can try opening a GitHub
\n issue- but please take a moment first to see if your question has { \" \" }
\n < ExternalLink href = \"https://github.com/bvaughn/react-virtualized-auto-sizer/issues?q=is%3Aissue%20state%3Aclosed\" >
\n has already been answered
\n </ ExternalLink > { \" \" }
\n before opening a new one.
\n </ div >
\n </ Box >
\n ) ;
\n}
"
+}
\ No newline at end of file
diff --git a/public/svgs/checkbox-checked.svg b/public/svgs/checkbox-checked.svg
deleted file mode 100644
index 59a2e3f..0000000
--- a/public/svgs/checkbox-checked.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/checkbox-indeterminate.svg b/public/svgs/checkbox-indeterminate.svg
deleted file mode 100644
index f11c023..0000000
--- a/public/svgs/checkbox-indeterminate.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/checkbox-unchecked.svg b/public/svgs/checkbox-unchecked.svg
deleted file mode 100644
index c1d6a33..0000000
--- a/public/svgs/checkbox-unchecked.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/chevron.svg b/public/svgs/chevron.svg
deleted file mode 100644
index 952fe81..0000000
--- a/public/svgs/chevron.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/github.svg b/public/svgs/github.svg
deleted file mode 100644
index 45e75bf..0000000
--- a/public/svgs/github.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/public/svgs/globe.svg b/public/svgs/globe.svg
deleted file mode 100644
index dedd9a1..0000000
--- a/public/svgs/globe.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/grab-dots.svg b/public/svgs/grab-dots.svg
deleted file mode 100644
index 8f2a342..0000000
--- a/public/svgs/grab-dots.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/npm.svg b/public/svgs/npm.svg
deleted file mode 100644
index 0cb019b..0000000
--- a/public/svgs/npm.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/radio-checked.svg b/public/svgs/radio-checked.svg
deleted file mode 100644
index 013b1bc..0000000
--- a/public/svgs/radio-checked.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/radio-unchecked.svg b/public/svgs/radio-unchecked.svg
deleted file mode 100644
index 903679f..0000000
--- a/public/svgs/radio-unchecked.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/svgs/tags.svg b/public/svgs/tags.svg
deleted file mode 100644
index 6f0d794..0000000
--- a/public/svgs/tags.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/scripts/compile-code-snippets.ts b/scripts/compile-code-snippets.ts
deleted file mode 100644
index 0471781..0000000
--- a/scripts/compile-code-snippets.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { readFile, writeFile } from "node:fs/promises";
-import { basename, join } from "node:path";
-import { initialize } from "./utils/initialize.ts";
-import { syntaxHighlight } from "./utils/syntax-highlight.ts";
-import { trimExcludedText } from "./utils/code-snippets/trimExcludedText.ts";
-
-async function run() {
- const { files, outputDir } = await initialize({
- fileExtensions: [".html", ".ts", ".tsx"],
- inputPath: ["src", "routes"],
- outputDirName: "code-snippets"
- });
-
- const exampleFiles = files.filter((file) => file.includes(".example."));
-
- for (const file of exampleFiles) {
- const buffer = await readFile(file);
-
- let rawText = buffer.toString();
-
- {
- // Remove special comments and directives before syntax highlighting
- rawText = trimExcludedText(rawText);
-
- rawText = rawText
- .split("\n")
- .filter(
- (line) =>
- !line.includes("prettier-ignore") &&
- !line.includes("eslint-disable-next-line") &&
- !line.includes("@ts-expect-error") &&
- !line.includes("// hidden")
- )
- .join("\n");
- }
-
- let html;
- if (file.endsWith(".html")) {
- html = await syntaxHighlight(rawText, "HTML");
- } else if (file.endsWith(".js") || file.endsWith(".jsx")) {
- html = await syntaxHighlight(
- rawText,
- file.endsWith("jsx") ? "JSX" : "JS"
- );
- } else if (file.endsWith(".ts") || file.endsWith(".tsx")) {
- html = await syntaxHighlight(
- rawText,
- file.endsWith("tsx") ? "TSX" : "TS"
- );
- } else {
- throw Error(`Unsupported file type: ${file}`);
- }
-
- const fileName = basename(file);
-
- const outputFile = join(
- outputDir,
- fileName.replace(/\.example\..+$/, ".json")
- );
-
- console.debug("Writing to", outputFile);
-
- await writeFile(outputFile, JSON.stringify({ html }, null, 2));
- }
-}
-
-run();
diff --git a/scripts/compile-docs.ts b/scripts/compile-docs.ts
index 757e7ec..c51acf3 100644
--- a/scripts/compile-docs.ts
+++ b/scripts/compile-docs.ts
@@ -1,10 +1,6 @@
-import { compileComponents } from "./utils/docs/compileComponents.ts";
+import { compileDocs } from "react-lib-tools/scripts/compile-docs.ts";
-async function run() {
- await compileComponents({
- componentNames: ["AutoSizer.tsx"],
- outputDirName: "js-docs"
- });
-}
-
-run();
+await compileDocs({
+ componentNames: ["AutoSizer.tsx"],
+ imperativeHandleNames: []
+});
diff --git a/scripts/compile-examples.ts b/scripts/compile-examples.ts
new file mode 100644
index 0000000..0b0c76d
--- /dev/null
+++ b/scripts/compile-examples.ts
@@ -0,0 +1,3 @@
+import { compileExamples } from "react-lib-tools/scripts/compile-examples.ts";
+
+await compileExamples();
diff --git a/scripts/utils/code-snippets/trimExcludedText.ts b/scripts/utils/code-snippets/trimExcludedText.ts
deleted file mode 100644
index 7869932..0000000
--- a/scripts/utils/code-snippets/trimExcludedText.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export function trimExcludedText(rawText: string) {
- {
- const pieces = rawText.split("// ");
- rawText = pieces[pieces.length - 1].trim();
- }
-
- {
- const pieces = rawText.split("// ");
- rawText = pieces[0].trim();
- }
-
- return rawText;
-}
diff --git a/scripts/utils/docs/compileComponent.ts b/scripts/utils/docs/compileComponent.ts
deleted file mode 100644
index 166cd9b..0000000
--- a/scripts/utils/docs/compileComponent.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { writeFile } from "node:fs/promises";
-import { join, relative } from "node:path";
-import { cwd } from "node:process";
-import { type FileParser, type PropItem } from "react-docgen-typescript";
-import { assert } from "../../../lib/utils/assert.ts";
-import type { ComponentMetadata } from "../../../src/types.ts";
-import { getPropTypeText } from "./getPropTypeText.ts";
-import { parseDescription } from "./parseDescription.ts";
-import { syntaxHighlight } from "../syntax-highlight.ts";
-import { propsToTable } from "./propsToTable.ts";
-
-const TOKEN_TO_REPLACE = "TOKEN_TO_REPLACE";
-
-export async function compileComponent({
- filePath,
- outputDir,
- parser
-}: {
- filePath: string;
- outputDir: string;
- parser: FileParser;
-}) {
- const parsed = parser.parse(filePath);
- assert(
- parsed.length === 1,
- `Expected 1 parsed component but found ${parsed.length}`
- );
-
- const component = parsed[0];
-
- // Convert to local paths
- component.filePath = relative(cwd(), filePath);
-
- // Filter inherited HTML attributes
- for (const key in component.props) {
- const prop = component.props[key];
- if (
- prop.declarations?.filter(
- (declaration) => !declaration.fileName.includes("node_modules")
- ).length === 0
- ) {
- delete component.props[key];
- }
- }
-
- // Generate syntax highlighted HTML for prop types
- {
- const componentMetadata: ComponentMetadata = {
- description: await parseDescription(component.description),
- filePath: component.filePath,
- name: component.displayName,
- props: {}
- };
-
- for (const name in component.props) {
- const prop = component.props[name];
-
- let textToFormat = getPropTypeText(prop);
-
- if (prop.defaultValue?.value) {
- const formattedValue =
- typeof prop.defaultValue.value === "string"
- ? `"${prop.defaultValue.value}"`
- : prop.defaultValue.value;
-
- textToFormat = `${textToFormat} = ${formattedValue}`;
- }
-
- // Format with a placeholder token so we can replace it with a formatted string
- textToFormat = `${TOKEN_TO_REPLACE}${prop.required ? "" : "?"}: ${textToFormat}`;
-
- try {
- let html = await syntaxHighlight(textToFormat, "TS");
- html = html.replace(
- TOKEN_TO_REPLACE,
- `${name} `
- );
-
- componentMetadata.props[name] = {
- description: await parseDescription(prop.description),
- html,
- name,
- required: prop.required
- };
- } catch (error) {
- console.error(error);
- }
- }
-
- const outputFile = join(outputDir, `${component.displayName}.json`);
-
- console.debug("Writing to", outputFile);
-
- await writeFile(outputFile, JSON.stringify(componentMetadata, null, 2));
- }
-
- // Generate markdown for prop types
- const requiredProps: PropItem[] = [];
- const optionalProps: PropItem[] = [];
-
- for (const propName in component.props) {
- const prop = component.props[propName];
- if (prop.required) {
- requiredProps.push(prop);
- } else {
- optionalProps.push(prop);
- }
- }
-
- return {
- componentName: component.displayName,
- description: component.description,
- optionalPropsTable: await propsToTable(optionalProps),
- requiredPropsTable: await propsToTable(requiredProps)
- };
-}
diff --git a/scripts/utils/docs/compileComponents.ts b/scripts/utils/docs/compileComponents.ts
deleted file mode 100644
index da09c42..0000000
--- a/scripts/utils/docs/compileComponents.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import { readFile, writeFile } from "node:fs/promises";
-import { join } from "node:path";
-import { cwd } from "node:process";
-import { withCustomConfig } from "react-docgen-typescript";
-import { initialize } from "../initialize.ts";
-import { compileComponent } from "./compileComponent.ts";
-import { insertPropsMarkdown } from "./insertPropsMarkdown.ts";
-
-export async function compileComponents({
- componentNames,
- outputDirName
-}: {
- componentNames: string[];
- outputDirName: string;
-}) {
- const parser = withCustomConfig("./tsconfig.json", {
- savePropValueAsString: true,
- shouldExtractLiteralValuesFromEnum: true,
- shouldExtractValuesFromUnion: true,
- shouldRemoveUndefinedFromOptional: true
- });
-
- const { files, outputDir } = await initialize({
- fileExtensions: [".ts", ".tsx"],
- fileFilter: (file) =>
- componentNames.some((componentName) => file.endsWith(componentName)),
- inputPath: ["lib", "components"],
- outputDirName
- });
-
- const markdownPath = join(cwd(), "README.md");
-
- let markdown = await readFile(markdownPath, { encoding: "utf-8" });
-
- await Promise.all(
- files.map((filePath) =>
- compileComponent({
- filePath,
- outputDir,
- parser
- }).then(
- ({
- componentName,
- description,
- optionalPropsTable,
- requiredPropsTable
- }) => {
- markdown = insertPropsMarkdown({
- componentMarkdown: description,
- componentName,
- markdown,
- section: "description"
- });
-
- markdown = insertPropsMarkdown({
- componentMarkdown: requiredPropsTable,
- componentName,
- markdown,
- section: "required-props"
- });
-
- markdown = insertPropsMarkdown({
- componentMarkdown: optionalPropsTable,
- componentName,
- markdown,
- section: "optional-props"
- });
- }
- )
- )
- );
-
- await writeFile(markdownPath, markdown);
-}
diff --git a/scripts/utils/docs/compileImperativeHandle.ts b/scripts/utils/docs/compileImperativeHandle.ts
deleted file mode 100644
index 3e218e8..0000000
--- a/scripts/utils/docs/compileImperativeHandle.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import type { InterfaceNode } from "@ts-ast-parser/core";
-import assert from "node:assert";
-import { writeFile } from "node:fs/promises";
-import { join } from "path";
-import type { ImperativeHandleMetadata } from "../../../src/types";
-import { syntaxHighlight } from "../syntax-highlight.ts";
-import { parseDescription } from "./parseDescription.ts";
-
-export async function compileImperativeHandle({
- filePath,
- interfaceNode,
- outputDir
-}: {
- filePath: string;
- interfaceNode: InterfaceNode;
- outputDir: string;
-}) {
- const name = interfaceNode.getName();
-
- const json: ImperativeHandleMetadata = {
- description: await parseDescription(
- "" + interfaceNode.getJSDoc().getTag("description")?.text
- ),
- filePath,
- methods: [],
- name
- };
-
- const methods = interfaceNode.getMethods();
- for (const method of methods) {
- const jsDoc = method.getJSDoc();
- assert(jsDoc);
-
- json.methods.push({
- description: await parseDescription(
- "" + jsDoc.getTag("description")?.text
- ),
- html: await syntaxHighlight(method.getTSNode().getText(), "TS"),
- name: method.getName()
- });
- }
-
- const outputFile = join(outputDir, `${name}.json`);
-
- console.debug("Writing to", outputFile);
-
- await writeFile(outputFile, JSON.stringify(json, null, 2));
-}
diff --git a/scripts/utils/docs/compileImperativeHandles.ts b/scripts/utils/docs/compileImperativeHandles.ts
deleted file mode 100644
index 57fbdbe..0000000
--- a/scripts/utils/docs/compileImperativeHandles.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { parseFromProject, type InterfaceNode } from "@ts-ast-parser/core";
-import tsConfig from "../../../tsconfig.json" with { type: "json" };
-import { compileImperativeHandle } from "./compileImperativeHandle.ts";
-import { join } from "node:path";
-import { cwd } from "node:process";
-
-export async function compileImperativeHandles({
- names,
- outputDirName
-}: {
- names: string[];
- outputDirName: string;
-}) {
- const outputDir = join(cwd(), "public", "generated", outputDirName);
-
- const result = await parseFromProject(tsConfig);
- const reflectedModules = result.project?.getModules() ?? [];
-
- const nodes: {
- filePath: string;
- node: InterfaceNode;
- }[] = [];
-
- names.forEach((name) => {
- reflectedModules.forEach((reflectedModule) => {
- const node = reflectedModule.getDeclarationByName(name);
- if (node) {
- nodes.push({
- filePath: reflectedModule.getSourcePath(),
- node: node as unknown as InterfaceNode
- });
- }
- });
- });
-
- await Promise.all(
- nodes.map(({ filePath, node }) =>
- compileImperativeHandle({
- filePath,
- interfaceNode: node,
- outputDir
- })
- )
- );
-}
diff --git a/scripts/utils/docs/formatDescriptionText.ts b/scripts/utils/docs/formatDescriptionText.ts
deleted file mode 100644
index 9e047cf..0000000
--- a/scripts/utils/docs/formatDescriptionText.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import Markdown from "markdown-it";
-
-let processor: Markdown | undefined = undefined;
-
-export function formatDescriptionText(text: string) {
- if (processor === undefined) {
- processor = new Markdown();
- }
-
- return processor.render(text);
-}
diff --git a/scripts/utils/docs/getPropTypeText.ts b/scripts/utils/docs/getPropTypeText.ts
deleted file mode 100644
index b79cc7a..0000000
--- a/scripts/utils/docs/getPropTypeText.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import type { PropItem } from "react-docgen-typescript";
-
-export function getPropTypeText(prop: PropItem) {
- let textToFormat = prop.type.raw;
- if (!textToFormat && prop.type.name.includes(":")) {
- // Edge case where some prop types aren't registered as containing raw TS
- textToFormat = prop.type.name;
-
- // List/Grid and rowComponent/cellComponent are annotated with a return type of ReactElement instead of ReactNode
- // As a result of this change the generated docs are significantly less readable, so tidy them up here
- // See github.com/bvaughn/react-virtualized-auto-sizer/issues/875
- textToFormat = textToFormat.replace(
- "ReactElement>",
- "ReactNode"
- );
- }
-
- if (!textToFormat) {
- textToFormat = `${prop.type.name}`;
-
- const match = textToFormat.match(/ExcludeForbiddenKeys<([^>]+)>/);
- if (match) {
- textToFormat = match[1];
- }
- }
-
- return textToFormat;
-}
diff --git a/scripts/utils/docs/insertPropsMarkdown.ts b/scripts/utils/docs/insertPropsMarkdown.ts
deleted file mode 100644
index 2cce2ad..0000000
--- a/scripts/utils/docs/insertPropsMarkdown.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-export function insertPropsMarkdown({
- componentMarkdown,
- componentName,
- markdown,
- section
-}: {
- componentMarkdown: string;
- componentName: string;
- markdown: string;
- section: string;
-}) {
- const flag = `${componentName}:${section}`;
- const startToken = ``;
- const stopToken = ``;
-
- const startIndex = markdown.indexOf(startToken) + startToken.length;
- const stopIndex = markdown.indexOf(stopToken);
- if (startIndex < 0 || stopIndex < 0) {
- throw Error("Parsing README failed");
- }
-
- return (
- markdown.substring(0, startIndex) +
- "\n" +
- (componentMarkdown || "None") +
- "\n" +
- markdown.substring(stopIndex)
- );
-}
diff --git a/scripts/utils/docs/parseDescription.ts b/scripts/utils/docs/parseDescription.ts
deleted file mode 100644
index 22a4300..0000000
--- a/scripts/utils/docs/parseDescription.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import type { Intent, Section } from "../../../src/types.ts";
-import { formatDescriptionText } from "./formatDescriptionText.ts";
-import { syntaxHighlight, type Language } from "../syntax-highlight.ts";
-
-export async function parseDescription(rawText: string) {
- const sections: Section[] = [];
-
- // Paper over differences between "@ts-ast-parser/core" and "react-docgen-typescript"
- let text = rawText;
- Object.keys(INTENT_FLAGS).forEach((flag) => {
- text = text
- .split(`\n${flag}`)
- .join(`\n\n${flag}`)
- .replaceAll("\n\n\n", "\n\n");
- });
-
- for (const chunk of text.split("\n\n")) {
- let content = "";
- let intent: Intent | undefined = undefined;
-
- if (chunk.startsWith("```")) {
- const match = chunk.match(/^```([a-z]+)/)!;
- const language = match[1].toUpperCase() as Language;
-
- content = await syntaxHighlight(
- chunk.substring(language.length + 3, chunk.length - 3).trim(),
- language
- );
- } else {
- content = formatDescriptionText(chunk.trim());
-
- for (const char in INTENT_FLAGS) {
- if (content.startsWith(`${char} `)) {
- intent = INTENT_FLAGS[char as keyof typeof INTENT_FLAGS] as Intent;
- content = content.replace(`
${char} `, "
");
- }
- }
- }
-
- // Strip TSDoc comments
- content = content.replace(/\n@param.+/, "");
- content = content.replace(/\n@return.+/, "");
-
- sections.push({
- content,
- intent
- });
- }
-
- return sections;
-}
-
-const INTENT_FLAGS = {
- "❌": "danger",
- "NOTE:": "none",
- ℹ️: "primary",
- "✅": "success",
- "⚠️": "warning"
-};
diff --git a/scripts/utils/docs/propsToTable.ts b/scripts/utils/docs/propsToTable.ts
deleted file mode 100644
index 7cd96ae..0000000
--- a/scripts/utils/docs/propsToTable.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { marked } from "marked";
-import type { PropItem } from "react-docgen-typescript";
-import { getPropTypeText } from "./getPropTypeText.ts";
-
-const TABLE_TAG_START = `
-
-
-
- Name
- Description
-
-
- `;
-
-const PROP_ROW = `
-
- [[name]]
- [[description]]
- `;
-
-const TABLE_TAG_STOP = `
-
-
-`;
-
-export async function propsToTable(props: PropItem[]) {
- const htmlStrings = [];
-
- if (props.length > 0) {
- htmlStrings.push(TABLE_TAG_START);
-
- for (const prop of props) {
- const type = getPropTypeText(prop);
-
- const description = await marked(prop.description);
-
- htmlStrings.push(
- PROP_ROW.replace("[[name]]", prop.name)
- .replace("[[type]]", type)
- .replace("[[description]]", description)
- );
- }
-
- htmlStrings.push(TABLE_TAG_STOP);
- }
-
- return htmlStrings.join("");
-}
diff --git a/scripts/utils/getFilesWithExtensions.ts b/scripts/utils/getFilesWithExtensions.ts
deleted file mode 100644
index 8e9dd33..0000000
--- a/scripts/utils/getFilesWithExtensions.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { readdir } from "fs/promises";
-import { extname, join } from "node:path";
-
-export async function getFilesWithExtensions(
- directory: string,
- extensions: string[],
- filter?: (path: string) => boolean
-) {
- const files: string[] = [];
-
- const entries = await readdir(directory, { withFileTypes: true });
-
- for (const entry of entries) {
- const fullPath = join(directory, entry.name);
-
- if (entry.isDirectory()) {
- files.push(
- ...(await getFilesWithExtensions(fullPath, extensions, filter))
- );
- } else if (entry.isFile()) {
- const fileExtension = extname(entry.name);
- if (extensions.includes(fileExtension)) {
- if (typeof filter !== "function" || filter(fullPath)) {
- files.push(fullPath);
- }
- }
- }
- }
-
- return files;
-}
diff --git a/scripts/utils/initialize.ts b/scripts/utils/initialize.ts
deleted file mode 100644
index ffdfba6..0000000
--- a/scripts/utils/initialize.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { mkdir } from "node:fs/promises";
-import { join } from "node:path";
-import { cwd } from "node:process";
-import { getFilesWithExtensions } from "./getFilesWithExtensions.ts";
-import { rmFilesWithExtensions } from "./rmFilesWithExtensions.ts";
-
-export async function initialize({
- fileExtensions,
- fileFilter,
- inputPath,
- outputDirName
-}: {
- fileExtensions: string[];
- fileFilter?: (path: string) => boolean;
- inputPath: string[];
- outputDirName: string;
-}) {
- const inputDir = join(cwd(), ...inputPath);
- const outputDir = join(cwd(), "public", "generated", outputDirName);
- await mkdir(outputDir, { recursive: true });
- await rmFilesWithExtensions(outputDir, [".json"]);
-
- const files = await getFilesWithExtensions(
- inputDir,
- fileExtensions,
- fileFilter
- );
-
- return {
- files,
- inputDir,
- outputDir
- };
-}
diff --git a/scripts/utils/rmFilesWithExtensions.ts b/scripts/utils/rmFilesWithExtensions.ts
deleted file mode 100644
index 29eb30b..0000000
--- a/scripts/utils/rmFilesWithExtensions.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { rm } from "fs/promises";
-import { getFilesWithExtensions } from "./getFilesWithExtensions.ts";
-
-export async function rmFilesWithExtensions(
- directory: string,
- extensions: string[]
-) {
- const files = await getFilesWithExtensions(directory, extensions);
-
- for (const file of files) {
- await rm(file);
- }
-}
diff --git a/scripts/utils/syntax-highlight.ts b/scripts/utils/syntax-highlight.ts
deleted file mode 100644
index abd8926..0000000
--- a/scripts/utils/syntax-highlight.ts
+++ /dev/null
@@ -1,255 +0,0 @@
-import { htmlLanguage } from "@codemirror/lang-html";
-import {
- jsxLanguage,
- tsxLanguage,
- typescriptLanguage
-} from "@codemirror/lang-javascript";
-import { ensureSyntaxTree, LRLanguage } from "@codemirror/language";
-import { EditorState } from "@codemirror/state";
-import { classHighlighter, highlightTree } from "@lezer/highlight";
-import { type BuiltInParserName } from "prettier";
-
-type TokenType = string;
-type Token = {
- columnIndex: number;
- type: TokenType | null;
- value: string;
-};
-
-export type Language = "HTML" | "JS" | "JSX" | "TS" | "TSX";
-
-type State = {
- parsedTokens: Token[];
- rawString: string;
-};
-
-export const DEFAULT_MAX_CHARACTERS = 500000;
-export const DEFAULT_MAX_TIME = 5000;
-
-export async function syntaxHighlight(code: string, language: Language) {
- let extension: LRLanguage;
- let prettierParser: BuiltInParserName;
- switch (language) {
- case "HTML": {
- extension = htmlLanguage.configure({ dialect: "selfClosing" });
- prettierParser = "html";
- break;
- }
- case "JS":
- case "JSX": {
- extension = jsxLanguage;
- prettierParser = "babel";
- break;
- }
- case "TS": {
- extension = typescriptLanguage;
- prettierParser = "typescript";
- break;
- }
- case "TSX": {
- extension = tsxLanguage;
- prettierParser = "typescript";
- break;
- }
- }
- if (!extension) {
- console.error("Unsupported language %o", language);
- }
-
- const tokens = await parser(code, extension, prettierParser);
-
- return tokens.map(parsedTokensToHtml).join("\n");
-}
-
-async function parser(
- code: string,
- languageExtension: LRLanguage,
-
- // @ts-expect-error TS6133
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- prettierParser: BuiltInParserName
-) {
- const parsedTokens: Token[][] = [];
- const currentLineState: State = {
- parsedTokens: [],
- rawString: ""
- };
-
- // The logic below to trim code sections only works with "\n"
- code = code.replace(/\r\n?|\n|\u2028|\u2029/g, "\n");
- if (code.length > DEFAULT_MAX_CHARACTERS) {
- let index = DEFAULT_MAX_CHARACTERS - 1;
- while (index > 0 && code.charAt(index) !== "\n") {
- index--;
- }
- if (index === 0) {
- while (index < code.length && code.charAt(index) !== "\n") {
- index++;
- }
- }
- code = code.slice(0, index + 1);
- }
-
- // In the future I may want to (re)format code examples for different screen widths
- // code = await format(code, {
- // parser: prettierParser,
- // plugins: ["prettier-plugin-tailwindcss"],
- // printWidth: 100,
- // proseWrap: "always",
- // semi: true
- // });
-
- const state = EditorState.create({
- doc: code,
- extensions: [languageExtension]
- });
-
- const tree = ensureSyntaxTree(
- state,
- DEFAULT_MAX_CHARACTERS,
- DEFAULT_MAX_TIME
- );
-
- if (tree === null) {
- return [];
- }
-
- let characterIndex = 0;
- let parsedCharacterIndex = 0;
- highlightTree(
- tree,
- classHighlighter,
- (from: number, to: number, className: string) => {
- if (from > characterIndex) {
- // No style applied to the token between position and from.
- // This typically indicates white space or newline characters.
- processSection(
- currentLineState,
- parsedTokens,
- code.slice(characterIndex, from),
- ""
- );
- }
- processSection(
- currentLineState,
- parsedTokens,
- code.slice(from, to),
- className
- );
- characterIndex = to;
- }
- );
-
- const maxPosition = code.length;
-
- if (characterIndex < maxPosition) {
- // No style applied on the trailing text.
- // This typically indicates white space or newline characters.
- processSection(
- currentLineState,
- parsedTokens,
- code.slice(characterIndex, maxPosition),
- ""
- );
- }
- if (currentLineState.parsedTokens.length) {
- parsedTokens.push(currentLineState.parsedTokens);
- }
-
- parsedCharacterIndex += characterIndex + 1;
-
- // Anything that's left should de-opt to plain text.
- if (parsedCharacterIndex < code.length) {
- let nextIndex = code.indexOf("\n", parsedCharacterIndex);
- let parsedLineTokens = [];
- while (true) {
- const line =
- nextIndex >= 0
- ? code.substring(parsedCharacterIndex, nextIndex)
- : code.substring(parsedCharacterIndex);
- parsedLineTokens.push({
- columnIndex: 0,
- type: null,
- value: line
- });
- if (nextIndex >= 0) {
- parsedTokens.push(parsedLineTokens);
- parsedLineTokens = [];
- } else if (nextIndex === -1) {
- break;
- }
- parsedCharacterIndex = nextIndex + 1;
- nextIndex = code.indexOf("\n", parsedCharacterIndex);
- }
- if (parsedLineTokens.length) {
- parsedTokens.push(parsedLineTokens);
- }
- }
-
- return parsedTokens;
-}
-
-function processSection(
- currentLineState: State,
- parsedTokens: Token[][],
- section: string,
- className: string
-) {
- // Remove "tok-" prefix;
- const tokenType =
- className === null || className === void 0
- ? null
- : className.substring(4) || null;
-
- let index = 0;
- let nextIndex = section.indexOf("\n");
- while (true) {
- const substring =
- nextIndex >= 0
- ? section.substring(index, nextIndex)
- : section.substring(index);
- const token: Token = {
- columnIndex: currentLineState.rawString.length,
- type: tokenType,
- value: substring
- };
- currentLineState.parsedTokens.push(token);
- currentLineState.rawString += substring;
- if (nextIndex === -1) {
- break;
- }
- if (nextIndex >= 0) {
- parsedTokens.push(currentLineState.parsedTokens);
- currentLineState.parsedTokens = [];
- currentLineState.rawString = "";
- }
- index = nextIndex + 1;
- nextIndex = section.indexOf("\n", index);
- }
-}
-
-function parsedTokensToHtml(tokens: Token[]) {
- const htmlStrings = tokens.map((token) => {
- const className = token.type ? `tok-${token.type}` : "";
- const escapedValue = escapeHtmlEntities(token.value);
-
- return `${escapedValue} `;
- });
-
- // Edge case to avoid empty line
- let htmlString = htmlStrings.join("");
- if (tokens.length <= 1) {
- if (!tokens[0].value) {
- htmlString = " ";
- }
- }
-
- return `${htmlString}
`;
-}
-
-function escapeHtmlEntities(rawString: string) {
- return rawString.replace(
- /[\u00A0-\u9999<>&]/g,
- (substring) => "" + substring.charCodeAt(0) + ";"
- );
-}
diff --git a/src/App.tsx b/src/App.tsx
index 2394e8c..d6f92c6 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,117 +1,25 @@
-import { Bars4Icon, XMarkIcon } from "@heroicons/react/20/solid";
-import { BrowserRouter, Route, Routes } from "react-router-dom";
-import GitHubIcon from "../public/svgs/github.svg?react";
-import NpmHubIcon from "../public/svgs/npm.svg?react";
-import { Box } from "./components/Box";
-import { ErrorBoundary } from "./components/ErrorBoundary";
-import { ExternalLink } from "./components/ExternalLink";
-import { Link } from "./components/Link";
-import { RouteChangeHandler } from "./components/RouteChangeHandler";
-import { useNavStore } from "./hooks/useNavStore";
-import { Nav } from "./nav/Nav";
+import { AppRoot, NavLink, NavSection } from "react-lib-tools";
import { routes } from "./routes";
-import { cn } from "./utils/cn";
export default function App() {
- const { toggle, visible } = useNavStore();
-
return (
-
-
-
-
-
-
-
-
- (re)sizing helper component
-
-
-
-
-
-
-
-
-
-
- {visible ? (
-
- ) : (
-
- )}
-
-
-
-
-
-
-
-
- {Object.entries(routes).map(([path, Component]) => (
-
-
-
- }
- key={path}
- path={path}
- />
- ))}
-
-
-
+
+ Getting started
+
+ Basic usage
+ Render prop
+
+
+ AutoSizer component
+
+ Support
-
-
+ }
+ packageDescription="(re)sizing helper component"
+ packageName="react-virtualized-auto-sizer"
+ routes={routes}
+ />
);
}
diff --git a/src/components/Block.tsx b/src/components/Block.tsx
deleted file mode 100644
index 679a0e5..0000000
--- a/src/components/Block.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import type { HTMLAttributes, PropsWithChildren } from "react";
-import { ErrorBoundary } from "./ErrorBoundary";
-
-export function Block({
- children,
- className,
- ...rest
-}: PropsWithChildren & { className?: string }>) {
- return (
-
-
- {children}
-
-
- );
-}
diff --git a/src/components/Box.tsx b/src/components/Box.tsx
deleted file mode 100644
index 936faa5..0000000
--- a/src/components/Box.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import type { CSSProperties, HTMLAttributes } from "react";
-import { cn } from "../utils/cn";
-
-export function Box({
- align,
- children,
- className,
- direction,
- gap = 0,
- grow,
- justify,
- shrink,
- style,
- wrap,
- ...rest
-}: HTMLAttributes & {
- align?: "center" | "end" | "start" | "stretch" | undefined;
- className?: string | undefined;
- direction: "column" | "row";
- gap?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | undefined;
- grow?: 0 | 1 | undefined;
- justify?:
- | "around"
- | "between"
- | "center"
- | "end"
- | "start"
- | "stretch"
- | undefined;
- shrink?: 0 | 1 | undefined;
- style?: CSSProperties | undefined;
- wrap?: boolean | undefined;
-}) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/components/Button.tsx b/src/components/Button.tsx
deleted file mode 100644
index e3ef221..0000000
--- a/src/components/Button.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import { Button as HeadlessButton } from "@headlessui/react";
-import type { MouseEvent, PropsWithChildren } from "react";
-import type { Intent } from "../types";
-import { cn } from "../utils/cn";
-
-export function Button({
- children,
- className,
- disabled = false,
- intent = "none",
- ...rest
-}: PropsWithChildren<{
- className?: string | undefined;
- disabled?: boolean | undefined;
- intent?: Intent | undefined;
- onClick?: ((event: MouseEvent) => void) | undefined;
-}>) {
- return (
-
- {children}
-
- );
-}
-
-function getClassNames(intent: Intent, disabled: boolean) {
- switch (intent) {
- case "danger": {
- return cn("bg-red-400 text-red-800 focus:text-black", {
- "hover:bg-red-500 hover:text-red-950 focus:text-black": !disabled
- });
- }
- case "none": {
- return cn("bg-emerald-400 text-emerald-800 focus:text-black", {
- "hover:bg-emerald-500 hover:text-emerald-950 focus:text-black":
- !disabled
- });
- }
- case "success":
- case "primary": {
- return cn("bg-sky-400 text-sky-800 focus:text-black", {
- "hover:bg-sky-500 hover:text-sky-950 focus:text-black": !disabled
- });
- }
- case "warning": {
- return cn("bg-amber-400 text-amber-800 focus:text-black", {
- "hover:bg-amber-500 hover:text-amber-950 focus:text-black": !disabled
- });
- }
- }
-}
diff --git a/src/components/Callout.tsx b/src/components/Callout.tsx
deleted file mode 100644
index 1e3bc98..0000000
--- a/src/components/Callout.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import {
- CheckCircleIcon,
- ExclamationTriangleIcon,
- InformationCircleIcon
-} from "@heroicons/react/20/solid";
-import type { HTMLAttributes, PropsWithChildren } from "react";
-import type { Intent } from "../types";
-
-export function Callout({
- children,
- className,
- html = false,
- inline = false,
- intent = "none",
- minimal,
- ...rest
-}: PropsWithChildren<
- HTMLAttributes & {
- className?: string | undefined;
- html?: boolean;
- inline?: boolean;
- intent?: Intent;
- minimal?: boolean;
- }
->) {
- let Icon = ExclamationTriangleIcon;
- switch (intent) {
- case "none":
- case "primary": {
- Icon = InformationCircleIcon;
- break;
- }
- case "success": {
- Icon = CheckCircleIcon;
- break;
- }
- }
-
- return (
-
-
-
- {html ? (
-
- ) : (
-
{children}
- )}
-
-
- );
-}
-
-function getClassNames(intent: Intent, minimal: boolean) {
- switch (intent) {
- case "danger": {
- if (minimal) {
- return "bg-red-950 text-red-300 [&_svg]:text-red-500";
- }
- return "bg-black/10 bg-border border-2 border-red-500 text-white [&_svg]:text-red-500 [&_a]:text-red-400!";
- }
- case "none": {
- if (minimal) {
- return "bg-white/10 text-slate-300 [&_svg]:text-slate-400";
- }
- return "bg-black/10 bg-border border-2 border-white/40 text-white [&_svg]:text-white/60";
- }
- case "primary": {
- if (minimal) {
- return "bg-sky-950 text-sky-300 [&_svg]:text-sky-400";
- }
- return "bg-black/10 bg-border border-2 border-sky-400 text-white [&_svg]:text-sky-400";
- }
- case "success": {
- if (minimal) {
- return "bg-emerald-950 text-emerald-300 [&_svg]:text-emerald-400";
- }
- return "bg-black/10 bg-border border-2 border-emerald-400 text-white [&_svg]:text-emerald-400";
- }
- case "warning": {
- if (minimal) {
- return "bg-amber-950/65 text-amber-200 [&_svg]:text-amber-300";
- }
- return "bg-black/10 bg-border border-2 border-amber-400 text-white [&_svg]:text-amber-400 [&_a]:text-amber-400!";
- }
- }
-}
diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx
deleted file mode 100644
index 93375c9..0000000
--- a/src/components/Checkbox.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import {
- type FunctionComponent,
- type HTMLAttributes,
- type PropsWithChildren,
- type SVGProps
-} from "react";
-import CheckedIcon from "../../public/svgs/checkbox-checked.svg?react";
-import IndeterminateIcon from "../../public/svgs/checkbox-indeterminate.svg?react";
-import UncheckedIcon from "../../public/svgs/checkbox-unchecked.svg?react";
-
-export function Checkbox({
- checked,
- children,
- className,
- indeterminate,
- onChange,
- ...rest
-}: PropsWithChildren<
- Omit, "defaultChecked" | "onChange"> & {
- checked: boolean;
- className?: string | undefined;
- indeterminate?: boolean;
- onChange: (value: boolean) => void;
- }
->) {
- let IconElement: FunctionComponent>;
- let iconClassName: string;
- if (indeterminate) {
- IconElement = IndeterminateIcon;
- iconClassName = "fill-white";
- } else if (checked) {
- IconElement = CheckedIcon;
- iconClassName = "fill-blue-600";
- } else {
- IconElement = UncheckedIcon;
- iconClassName = "fill-slate-600";
- }
-
- return (
-
- {
- onChange(event.currentTarget.checked);
- }}
- type="checkbox"
- />
-
- {children && <> {children}>}
-
- );
-}
diff --git a/src/components/DocsSection.tsx b/src/components/DocsSection.tsx
deleted file mode 100644
index c6e3ca6..0000000
--- a/src/components/DocsSection.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import type { Section } from "../types";
-import { Box } from "./Box";
-import { Callout } from "./Callout";
-
-export function DocsSection({
- className,
- sections
-}: {
- className?: string;
- sections: Section[];
-}) {
- return (
-
- {sections.map(({ content, intent }, index) => {
- if (intent) {
- return (
-
- {content}
-
- );
- }
-
- return (
-
- );
- })}
-
- );
-}
diff --git a/src/components/ErrorBoundary.tsx b/src/components/ErrorBoundary.tsx
deleted file mode 100644
index d2200c8..0000000
--- a/src/components/ErrorBoundary.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import type { PropsWithChildren } from "react";
-import {
- ErrorBoundary as ErrorBoundaryExternal,
- type FallbackProps
-} from "react-error-boundary";
-import { Callout } from "./Callout";
-import { Box } from "./Box";
-import { Button } from "./Button";
-
-export function ErrorBoundary({ children }: PropsWithChildren) {
- return (
-
- {children}
-
- );
-}
-
-function FallbackComponent({ error, resetErrorBoundary }: FallbackProps) {
- return (
-
-
- Something went wrong!
-
- {error.message}
-
-
- Retry
-
-
-
- );
-}
diff --git a/src/components/ExternalLink.tsx b/src/components/ExternalLink.tsx
deleted file mode 100644
index dbec8a3..0000000
--- a/src/components/ExternalLink.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import type { AnchorHTMLAttributes } from "react";
-
-export function ExternalLink({
- children,
- className,
- href,
- target = "_blank",
- ...rest
-}: AnchorHTMLAttributes) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
deleted file mode 100644
index c358d13..0000000
--- a/src/components/Header.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { ChevronRightIcon } from "@heroicons/react/20/solid";
-import { Box } from "./Box";
-import { useEffect } from "react";
-
-export function Header({
- section,
- title
-}: {
- section?: string;
- title: string;
-}) {
- useEffect(() => {
- const originalTitle = document.title;
-
- document.title = `react-virtualized-auto-sizer: ${section ? `${section}: ${title}` : title}`;
-
- return () => {
- document.title = originalTitle;
- };
- });
-
- return (
-
- {section && (
- <>
- {section}
-
- >
- )}
- {title}
-
- );
-}
diff --git a/src/components/Input.tsx b/src/components/Input.tsx
deleted file mode 100644
index 2102c6a..0000000
--- a/src/components/Input.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import type { InputHTMLAttributes, PropsWithChildren } from "react";
-
-export function Input({
- children,
- className,
- onChange,
- value,
- ...rest
-}: PropsWithChildren<
- Omit, "onChange"> & {
- className?: string | undefined;
- onChange: (value: Type) => void;
- value: Type;
- }
->) {
- return (
- {
- onChange(event.currentTarget.value as Type);
- }}
- value={value}
- {...rest}
- >
- {children}
-
- );
-}
diff --git a/src/components/Link.tsx b/src/components/Link.tsx
index cb4f650..855ab65 100644
--- a/src/components/Link.tsx
+++ b/src/components/Link.tsx
@@ -1,6 +1,6 @@
import type { HTMLAttributes } from "react";
+import { Link as ExternalLink } from "react-lib-tools";
import type { Path } from "../routes";
-import { TransitionLink } from "./TransitionLink";
export function Link({
to,
@@ -8,5 +8,5 @@ export function Link({
}: HTMLAttributes & {
to: Path;
}) {
- return ;
+ return ;
}
diff --git a/src/components/LoadingSpinner.tsx b/src/components/LoadingSpinner.tsx
deleted file mode 100644
index 6f61bd2..0000000
--- a/src/components/LoadingSpinner.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { ArrowPathIcon } from "@heroicons/react/20/solid";
-import { Box } from "./Box";
-
-export function LoadingSpinner() {
- return (
-
-
- Loading...
-
- );
-}
diff --git a/src/components/Radio.tsx b/src/components/Radio.tsx
deleted file mode 100644
index cd25653..0000000
--- a/src/components/Radio.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import {
- type FunctionComponent,
- type HTMLAttributes,
- type PropsWithChildren,
- type SVGProps
-} from "react";
-import CheckedIcon from "../../public/svgs/radio-checked.svg?react";
-import UncheckedIcon from "../../public/svgs/radio-unchecked.svg?react";
-
-export function Radio({
- checked,
- children,
- className,
- name,
- onChange,
- value,
- ...rest
-}: PropsWithChildren<
- Omit, "defaultChecked" | "onChange"> & {
- checked: boolean;
- name: string;
- onChange: (value: Value) => void;
- value: Value;
- }
->) {
- let IconElement: FunctionComponent>;
- let iconClassName: string;
- if (checked) {
- IconElement = CheckedIcon;
- iconClassName = "fill-blue-600";
- } else {
- IconElement = UncheckedIcon;
- iconClassName = "fill-slate-600";
- }
-
- return (
-
- {
- onChange(value);
- }}
- type="radio"
- value={value}
- />
-
- {children && <> {children}>}
-
- );
-}
diff --git a/src/components/RouteChangeHandler.tsx b/src/components/RouteChangeHandler.tsx
deleted file mode 100644
index ccf7228..0000000
--- a/src/components/RouteChangeHandler.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { useLayoutEffect } from "react";
-import { useLocation } from "react-router-dom";
-import { useNavStore } from "../hooks/useNavStore";
-
-export function RouteChangeHandler() {
- const { hide } = useNavStore();
-
- const { pathname } = useLocation();
-
- useLayoutEffect(() => {
- hide();
-
- const main = document.body.querySelector("[data-main-scrollable]");
- if (main) {
- const timeout = setTimeout(() => {
- main.scrollTo(0, 0);
- }, 1);
-
- return () => {
- clearTimeout(timeout);
- };
- }
- }, [hide, pathname]);
-
- return null;
-}
diff --git a/src/components/Select.tsx b/src/components/Select.tsx
deleted file mode 100644
index d115f0b..0000000
--- a/src/components/Select.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import {
- Listbox,
- ListboxButton,
- ListboxOption,
- ListboxOptions,
- Transition
-} from "@headlessui/react";
-import { ChevronUpDownIcon } from "@heroicons/react/20/solid";
-import { Fragment } from "react";
-import { cn } from "../utils/cn";
-
-export type Option = {
- label: string;
- value: Value;
-};
-
-export function Select({
- className,
- defaultValue,
- onChange,
- options,
- placeholder = "",
- value
-}: {
- className?: string;
- defaultValue?: Option | undefined;
- onChange: (value: Option) => void;
- options: Option[];
- placeholder?: string;
- value: Option | undefined;
-}) {
- return (
-
-
-
- {value?.label ? (
- {value.label}
- ) : (
- {placeholder}
- )}
-
-
-
-
-
-
- {options.map((option, index) => (
-
- {option.label}
-
- ))}
-
-
-
-
- );
-}
diff --git a/src/components/TransitionLink.tsx b/src/components/TransitionLink.tsx
deleted file mode 100644
index 75daaec..0000000
--- a/src/components/TransitionLink.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { useTransition, type HTMLAttributes, type ReactNode } from "react";
-import { useMatch, useNavigate } from "react-router-dom";
-import type { Path } from "../routes";
-
-type RenderFunction = (params: {
- isActive: boolean;
- isPending: boolean;
-}) => ReactNode;
-
-export function TransitionLink({
- children,
- onClick,
- to,
- ...rest
-}: Omit, "children"> & {
- children?: ReactNode | RenderFunction;
- to: Path;
-}) {
- const isActive = !!useMatch(to);
- const [isPending, startTransition] = useTransition();
- const navigate = useNavigate();
-
- return (
- {
- onClick?.(event);
-
- startTransition(() => {
- navigate(to);
- });
- }}
- {...rest}
- />
- );
-}
diff --git a/src/components/code/Code.tsx b/src/components/code/Code.tsx
deleted file mode 100644
index 8dfe734..0000000
--- a/src/components/code/Code.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { cn } from "../../utils/cn";
-import "./code-mirror.css";
-
-export function Code({
- className = "",
- html
-}: {
- className?: string;
- html: string;
-}) {
- return (
-
-
-
- );
-}
diff --git a/src/components/code/code-mirror.css b/src/components/code/code-mirror.css
deleted file mode 100644
index 2a44b5b..0000000
--- a/src/components/code/code-mirror.css
+++ /dev/null
@@ -1,36 +0,0 @@
-.tok-comment {
- color: var(--color-slate-500);
-}
-.tok-definition {
-}
-.tok-local {
-}
-.tok-keyword {
- color: var(--color-pink-400);
-}
-.tok-meta {
-}
-.tok-number {
-}
-.tok-operator {
- color: var(--color-slate-400);
-}
-.tok-propertyName {
- color: var(--color-sky-300);
-}
-.tok-punctuation {
- color: var(--color-slate-400);
-}
-.tok-string {
- color: var(--color-teal-300);
-}
-.tok-string2 {
- color: var(--color-sky-300);
-}
-.tok-typeName {
- color: var(--color-pink-400);
-}
-.tok-variableName:not(.tok-definition) {
-}
-.tok-variableName2 {
-}
diff --git a/src/components/code/types.ts b/src/components/code/types.ts
deleted file mode 100644
index 37c8821..0000000
--- a/src/components/code/types.ts
+++ /dev/null
@@ -1 +0,0 @@
-export type Language = "JSX" | "TypeScript" | "TSX";
diff --git a/src/components/handles/ImperativeHandle.tsx b/src/components/handles/ImperativeHandle.tsx
deleted file mode 100644
index 463ca7d..0000000
--- a/src/components/handles/ImperativeHandle.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { ArrowTopRightOnSquareIcon } from "@heroicons/react/20/solid";
-import { repository } from "../../../package.json";
-import type { ImperativeHandleMetadata } from "../../types";
-import { Box } from "../Box";
-import { DocsSection } from "../DocsSection";
-import { ExternalLink } from "../ExternalLink";
-import { Header } from "../Header";
-import { ImperativeHandleMethod } from "./ImperativeHandleMethod";
-
-export function ImperativeHandle({
- json,
- section
-}: {
- json: ImperativeHandleMetadata;
- section: string;
-}) {
- return (
-
-
-
-
-
-
-
-
-
-
- {json.methods.map((method, index) => (
-
- ))}
-
-
-
- );
-}
diff --git a/src/components/handles/ImperativeHandleMethod.tsx b/src/components/handles/ImperativeHandleMethod.tsx
deleted file mode 100644
index a552bb5..0000000
--- a/src/components/handles/ImperativeHandleMethod.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import type { ImperativeHandleMethodMetadata } from "../../types";
-import { Code } from "../code/Code";
-import { DocsSection } from "../DocsSection";
-
-export function ImperativeHandleMethod({
- method
-}: {
- method: ImperativeHandleMethodMetadata;
-}) {
- return (
- <>
- {method.name}
-
-
-
-
- >
- );
-}
diff --git a/src/components/props/ComponentProp.tsx b/src/components/props/ComponentProp.tsx
deleted file mode 100644
index 1a0dc49..0000000
--- a/src/components/props/ComponentProp.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import type { ComponentPropMetadata } from "../../types";
-import { Code } from "../code/Code";
-import { DocsSection } from "../DocsSection";
-
-export function ComponentProp({ prop }: { prop: ComponentPropMetadata }) {
- return (
- <>
-
-
-
-
-
-
- >
- );
-}
diff --git a/src/components/props/ComponentProps.tsx b/src/components/props/ComponentProps.tsx
deleted file mode 100644
index c26ba9f..0000000
--- a/src/components/props/ComponentProps.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { ArrowTopRightOnSquareIcon } from "@heroicons/react/20/solid";
-import { useMemo } from "react";
-import { repository } from "../../../package.json";
-import type { ComponentMetadata } from "../../types";
-import { processPropsJSON } from "../../utils/processPropsJSON";
-import { Box } from "../Box";
-import { DocsSection } from "../DocsSection";
-import { ExternalLink } from "../ExternalLink";
-import { Header } from "../Header";
-import { ComponentPropsSection } from "./ComponentPropsSection";
-
-export function ComponentProps({
- json,
- section
-}: {
- json: ComponentMetadata;
- section: string;
-}) {
- const { optionalProps, requiredProps } = useMemo(
- () => processPropsJSON(json),
- [json]
- );
-
- return (
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/src/components/props/ComponentPropsSection.tsx b/src/components/props/ComponentPropsSection.tsx
deleted file mode 100644
index 5fb6256..0000000
--- a/src/components/props/ComponentPropsSection.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import type { ComponentPropMetadata } from "../../types";
-import { Box } from "../Box";
-import { ComponentProp } from "./ComponentProp";
-
-export function ComponentPropsSection({
- header,
- props
-}: {
- header: string;
- props: ComponentPropMetadata[];
-}) {
- if (props.length === 0) {
- return null;
- }
-
- return (
-
- {header}
-
- {props.map((prop) => (
-
- ))}
-
-
- );
-}
diff --git a/src/hooks/useNavStore.tsx b/src/hooks/useNavStore.tsx
deleted file mode 100644
index 2594830..0000000
--- a/src/hooks/useNavStore.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { create } from "zustand";
-
-export const useNavStore = create<{
- visible: boolean;
-
- hide: () => void;
- show: () => void;
- toggle: () => void;
-}>((set) => ({
- visible: false,
-
- hide: () => set({ visible: false }),
- show: () => set({ visible: true }),
- toggle: () => set((state) => ({ visible: !state.visible }))
-}));
diff --git a/src/nav/MobileNav.tsx b/src/nav/MobileNav.tsx
deleted file mode 100644
index 4c90452..0000000
--- a/src/nav/MobileNav.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { useLayoutEffect } from "react";
-import { useLocation } from "react-router-dom";
-import { useNavStore } from "../hooks/useNavStore";
-import { cn } from "../utils/cn";
-
-export function Nav() {
- const { hide, visible } = useNavStore();
-
- const { pathname } = useLocation();
- useLayoutEffect(() => {
- hide();
- }, [hide, pathname]);
-
- return (
-
- MOBILE NAV
-
- );
-}
diff --git a/src/nav/Nav.tsx b/src/nav/Nav.tsx
deleted file mode 100644
index 892cb71..0000000
--- a/src/nav/Nav.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { NavLink } from "./NavLink";
-import { NavSection } from "./NavSection";
-
-export function Nav() {
- return (
-
-
- Getting started
-
- Basic usage
- Render prop
-
-
- AutoSizer component
-
- Support
-
-
- );
-}
diff --git a/src/nav/NavButton.tsx b/src/nav/NavButton.tsx
deleted file mode 100644
index e796921..0000000
--- a/src/nav/NavButton.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { PropsWithChildren } from "react";
-import { Box } from "../components/Box";
-import { cn } from "../utils/cn";
-
-export function NavButton({
- children,
- className,
- disabled
-}: PropsWithChildren<{ className?: string; disabled?: boolean }>) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/nav/NavLink.tsx b/src/nav/NavLink.tsx
deleted file mode 100644
index d17584b..0000000
--- a/src/nav/NavLink.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { type PropsWithChildren } from "react";
-import { Box } from "../components/Box";
-import { TransitionLink } from "../components/TransitionLink";
-import { type Path } from "../routes";
-import { cn } from "../utils/cn";
-import { NavButton } from "./NavButton";
-
-export function NavLink({
- children,
- className,
- path
-}: PropsWithChildren<{
- className?: string;
- path: Path;
-}>) {
- return (
-
- {({ isActive, isPending }) => (
-
-
- {children}
-
-
- )}
-
- );
-}
diff --git a/src/nav/NavRoute.tsx b/src/nav/NavRoute.tsx
deleted file mode 100644
index a38ed27..0000000
--- a/src/nav/NavRoute.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import type { ReactNode } from "react";
-import { Route } from "react-router-dom";
-
-export function NavRoute({
- route
-}: {
- route: {
- component: ReactNode;
- path: string;
- };
-}) {
- return ;
-}
diff --git a/src/nav/NavSection.tsx b/src/nav/NavSection.tsx
deleted file mode 100644
index 1622536..0000000
--- a/src/nav/NavSection.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import {
- Disclosure,
- DisclosureButton,
- DisclosurePanel
-} from "@headlessui/react";
-import { ChevronRightIcon } from "@heroicons/react/20/solid";
-import type { PropsWithChildren, ReactNode } from "react";
-import { NavButton } from "./NavButton";
-
-export function NavSection({
- children,
- label
-}: PropsWithChildren<{ label: ReactNode }>) {
- return (
-
-
-
-
- {label}
-
-
-
-
-
- {children}
-
- );
-}
diff --git a/src/routes/AutoSizerPropsRoute.tsx b/src/routes/AutoSizerPropsRoute.tsx
index d4384d1..31c682f 100644
--- a/src/routes/AutoSizerPropsRoute.tsx
+++ b/src/routes/AutoSizerPropsRoute.tsx
@@ -1,6 +1,5 @@
-import json from "../../public/generated/js-docs/AutoSizer.json";
-import { Box } from "../components/Box";
-import { ComponentProps } from "../components/props/ComponentProps";
+import { Box, ComponentProps } from "react-lib-tools";
+import json from "../../public/generated/docs/AutoSizer.json";
import type { ComponentMetadata } from "../types";
export default function AutoSizerPropsRoute() {
diff --git a/src/routes/BasicUsageRoute.tsx b/src/routes/BasicUsageRoute.tsx
index 55f92a9..5be0639 100644
--- a/src/routes/BasicUsageRoute.tsx
+++ b/src/routes/BasicUsageRoute.tsx
@@ -1,7 +1,5 @@
-import { html } from "../../public/generated/code-snippets/ChildComponent.json";
-import { Box } from "../components/Box";
-import { Code } from "../components/code/Code";
-import { Header } from "../components/Header";
+import { Box, Code, Header } from "react-lib-tools";
+import { html } from "../../public/generated/examples/ChildComponent.json";
export default function BasicUsageRoute() {
return (
diff --git a/src/routes/GettingStartedRoute.tsx b/src/routes/GettingStartedRoute.tsx
index 2b25eab..8dd7fd8 100644
--- a/src/routes/GettingStartedRoute.tsx
+++ b/src/routes/GettingStartedRoute.tsx
@@ -1,7 +1,4 @@
-import { Box } from "../components/Box";
-import { Callout } from "../components/Callout";
-import { ExternalLink } from "../components/ExternalLink";
-import { Header } from "../components/Header";
+import { Box, Callout, ExternalLink, Header } from "react-lib-tools";
import { Link } from "../components/Link";
export default function GettingStartedRoute() {
diff --git a/src/routes/PageNotFound.tsx b/src/routes/PageNotFound.tsx
index 7c1addc..9b63aac 100644
--- a/src/routes/PageNotFound.tsx
+++ b/src/routes/PageNotFound.tsx
@@ -1,7 +1,4 @@
-import { Box } from "../components/Box";
-import { Callout } from "../components/Callout";
-import { ExternalLink } from "../components/ExternalLink";
-import { Header } from "../components/Header";
+import { Box, Callout, ExternalLink, Header } from "react-lib-tools";
export default function PageNotFound() {
return (
diff --git a/src/routes/RenderPropRoute.tsx b/src/routes/RenderPropRoute.tsx
index 5e0f231..6edcc52 100644
--- a/src/routes/RenderPropRoute.tsx
+++ b/src/routes/RenderPropRoute.tsx
@@ -1,9 +1,5 @@
-import { html } from "../../public/generated/code-snippets/RenderProp.json";
-import { Box } from "../components/Box";
-import { Callout } from "../components/Callout";
-import { ExternalLink } from "../components/ExternalLink";
-import { Header } from "../components/Header";
-import { Code } from "../components/code/Code";
+import { Box, Callout, Code, ExternalLink, Header } from "react-lib-tools";
+import { html } from "../../public/generated/examples/RenderProp.json";
export default function RenderPropRoute() {
return (
diff --git a/src/routes/SupportRoute.tsx b/src/routes/SupportRoute.tsx
index c64e9dc..9685e64 100644
--- a/src/routes/SupportRoute.tsx
+++ b/src/routes/SupportRoute.tsx
@@ -1,6 +1,4 @@
-import { Box } from "../components/Box";
-import { ExternalLink } from "../components/ExternalLink";
-import { Header } from "../components/Header";
+import { Box, ExternalLink, Header } from "react-lib-tools";
export default function SupportRoute() {
return (
diff --git a/src/utils/cn.ts b/src/utils/cn.ts
deleted file mode 100644
index 365058c..0000000
--- a/src/utils/cn.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { type ClassValue, clsx } from "clsx";
-import { twMerge } from "tailwind-merge";
-
-export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs));
-}