Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 173 additions & 4 deletions bun.lock

Large diffs are not rendered by default.

21 changes: 18 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,18 @@
"types": "./dist/react/index.d.ts",
"import": "./dist/react/index.js"
},
"./solid": {
"types": "./dist/solid/solid/index.d.ts",
"import": "./dist/solid/index.js"
},
"./server": {
"types": "./dist/server/index.d.ts",
"import": "./dist/server/index.js"
}
},
"files": ["dist"],
"files": [
"dist"
],
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
Expand All @@ -51,26 +57,35 @@
"@chenglou/pretext": "^0.0.8"
},
"peerDependencies": {
"react": ">=19.0.0"
"react": ">=19.0.0",
"solid-js": ">=1.9.0 <2.0.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"solid-js": {
"optional": true
}
},
"devDependencies": {
"@biomejs/biome": "^2.5.1",
"@types/react": "^19.0.0",
"@typescript/native-preview": "^7.0.0-dev.20260623.1",
"esbuild-plugin-d.ts": "^2.0.1",
"husky": "^9.1.7",
"lint-staged": "^17.0.8",
"react": "^19.0.0",
"solid-js": "^1.9.14",
"tsup": "^8.5.1",
"tsup-preset-solid": "^2.2.0",
"typescript": "^6.0.3",
"vitest": "^4.1.9"
},
"lint-staged": {
"src/**/*.{ts,tsx,js,jsx,json}": ["biome check --write --no-errors-on-unmatched"]
"src/**/*.{ts,tsx,js,jsx,json}": [
"biome check --write --no-errors-on-unmatched"
]
},
"overrides": {
"esbuild": "^0.28.1"
Expand Down
28 changes: 28 additions & 0 deletions site-solid/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
dist
.wrangler
.output
.vercel
.netlify
.vinxi
app.config.timestamp_*.js

# Environment
.env
.env*.local

# dependencies
/node_modules

# IDEs and editors
/.idea
.project
.classpath
*.launch
.settings/

# Temp
gitignore

# System Files
.DS_Store
Thumbs.db
12 changes: 12 additions & 0 deletions site-solid/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from "@solidjs/start/config";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
vite: {
plugins: [tailwindcss()],
ssr: {
// Prevents the server environment from attempting to evaluate three.js
noExternal: ["solid-three", "three"],
},
},
});
1,714 changes: 1,714 additions & 0 deletions site-solid/bun.lock

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions site-solid/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "site-solid",
"type": "module",
"scripts": {
"dev": "vinxi dev",
"build": "vinxi build",
"start": "vinxi start",
"preview": "vinxi preview"
},
"dependencies": {
"@darkroomengineering/fitbox": "file:..",
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.16.2",
"@solidjs/start": "1.3.2",
"@tailwindcss/vite": "^4.3.3",
"solid-js": "^1.9.5",
"solid-three": "^0.2.0",
"tailwindcss": "^4.3.3",
"vinxi": "^0.5.7"
},
"engines": {
"node": ">=22"
},
"devDependencies": {
"@types/three": "^0.185.1"
}
}
Binary file added site-solid/public/favicon.ico
Binary file not shown.
19 changes: 19 additions & 0 deletions site-solid/solid-three-jsx.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { JSX } from "solid-js";
import * as THREE from "three";

// Map ThreeJS elements to their corresponding types for Solid's JSX engine
type ThreeIntrinsicElements = {
mesh: JSX.HTMLAttributes<THREE.Mesh> & { position?: any; rotation?: any; scale?: any };
boxGeometry: JSX.HTMLAttributes<THREE.BoxGeometry> & { args?: any };
meshStandardMaterial: JSX.HTMLAttributes<THREE.MeshStandardMaterial> & { color?: any };
ambientLight: JSX.HTMLAttributes<THREE.AmbientLight> & { intensity?: any };
directionalLight: JSX.HTMLAttributes<THREE.DirectionalLight> & { position?: any; intensity?: any };
orbitControls: any;
group: JSX.HTMLAttributes<THREE.Group> & { position?: any; rotation?: any };
};

declare module "solid-js" {
namespace JSX {
interface IntrinsicElements extends ThreeIntrinsicElements {}
}
}
46 changes: 46 additions & 0 deletions site-solid/src/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@import "tailwindcss";

@theme {
--color-bg: #0a0a0a;
--color-fg: #fafafa;
--color-muted: #6b7280;
--color-line: #1f1f1f;
--color-accent: #9cf;

--font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
}

@layer base {
html {
background: var(--color-bg);
color: var(--color-fg);
font-family: system-ui, -apple-system, sans-serif;
font-feature-settings: 'ss01', 'cv11';
-webkit-font-smoothing: antialiased;
}

body {
margin: 0;
}

a {
color: inherit;
text-decoration: underline;
text-decoration-color: var(--color-line);
text-underline-offset: 3px;
transition: text-decoration-color 180ms ease;
}
a:hover {
text-decoration-color: var(--color-accent);
}

code {
font-family: var(--font-mono);
font-size: 0.9em;
}

::selection {
background: var(--color-accent);
color: var(--color-bg);
}
}
20 changes: 20 additions & 0 deletions site-solid/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { MetaProvider, Title } from "@solidjs/meta";
import { Router } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start/router";
import { Suspense } from "solid-js";
import "./app.css";

export default function App() {
return (
<Router
root={props => (
<MetaProvider>
<Title>SolidStart - Basic</Title>
<Suspense>{props.children}</Suspense>
</MetaProvider>
)}
>
<FileRoutes />
</Router>
);
}
21 changes: 21 additions & 0 deletions site-solid/src/components/DemoFrame.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { JSXElement } from "solid-js";

export default function DemoFrame(props: {
title: string;
description: string;
children: JSXElement;
code: string;
}) {
return (
<div class="space-y-4">
<div class="space-y-1">
<h3 class="text-lg font-medium">{props.title}</h3>
<p class="max-w-2xl text-sm text-[var(--color-muted)]">{props.description}</p>
</div>
<div class="overflow-hidden rounded-lg border border-[var(--color-line)]">{props.children}</div>
<pre class="overflow-x-auto rounded-lg border border-[var(--color-line)] bg-black/40 p-4 text-xs leading-relaxed text-[var(--color-muted)]">
<code>{props.code}</code>
</pre>
</div>
);
}
39 changes: 39 additions & 0 deletions site-solid/src/components/FluidDemo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/** @jsxImportSource solid-js */
import DemoFrame from "./DemoFrame";
import { FitText } from "@darkroomengineering/fitbox/solid";
import { fluidFit, prepare } from "@darkroomengineering/fitbox";

export default function FluidDemo() {
// Static: computed on the server (or once on the client), shipped as a CSS string.
const fluid = fluidFit(prepare("fluid typography", "system-ui"), {
minViewport: 360,
maxViewport: 1440,
minSize: 28,
maxSize: 120,
});
return (
<DemoFrame
title="Fluid CSS clamp — zero JS at runtime"
description="The browser interpolates this clamp() natively. Resize the window and watch it move."
code={`fluidFit(prepare('fluid typography'), {
minViewport: 360, maxViewport: 1440, minSize: 28, maxSize: 120,
})
// → ${fluid.cssClamp}`}
>
<div class="p-6">
<FitText
as="h3"
fluid={fluid}
style={{
margin: 0,
"font-weight": 600,
"letter-spacing": "-0.02em",
"line-height": 0.95,
}}
>
fluid typography
</FitText>
</div>
</DemoFrame>
);
}
89 changes: 89 additions & 0 deletions site-solid/src/components/WebGLDemo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// TODO...
/** @jsxImportSource solid-js */
// import { FitHandle, layoutFit, prepare } from "@darkroomengineering/fitbox";
// import { Canvas, For, useFrame, useThree } from "solid-three";
// import { Text } from "@bigmistqke/solid-drei/import";
// import DemoFrame from "./DemoFrame";

// type MaybeAccess<T extends (...args: any) => any> = Parameters<T>[0];

// /** @jsxImportSource solid-js */
// export default function WebGLDemo() {
// const handle = prepare(
// "typography that renders into a texture, not the DOM",
// "system-ui",
// );
// return (
// <DemoFrame
// title="Beyond the DOM — WebGL"
// description="layoutFit reads the live canvas width via useThree() and refits on resize. Each line is a drei <Text> mesh with a neon outline, animated per-line via useFrame — impossible with pure CSS, free with layoutFit."
// code={`const { size } = useThree()
// const layout = layoutFit(handle, { width: size.width, maxLines: 2, maxSize: 64 })
// useFrame(({ clock }) => group.current.children.forEach((child, i) => {
// child.position.y = baseY[i] + Math.sin(clock.elapsedTime * 1.4 + i * 0.9) * 6
// }))`}
// >
// <div class="h-[320px] w-full bg-black">
// <Canvas
// orthographic
// camera={{ position: [0, 0, 100], zoom: 1, near: 0.1, far: 1000 }}
// dpr={[1, 2]}
// gl={{ antialias: true }}
// >
// <color attach="background" args={["#050505"]} />
// <FittedText handle={handle} />
// </Canvas>
// </div>
// </DemoFrame>
// );
// }

// function FittedText(props: { handle: FitHandle }) {
// const three = useThree();
// let group: any = null!;
// const layout = () =>
// layoutFit(props.handle, {
// width: three().size.width,
// maxLines: 2,
// maxSize: 64,
// lineHeight: 1.1,
// });

// useFrame(({ clock }) => {
// if (!group) return;
// const _layout = layout();
// const t = clock.elapsedTime;
// for (let i = 0; i < group.children.length; i++) {
// const child = group.children[i];
// const base = _layout.height / 2 - (_layout.lines[i]?.y ?? 0);
// if (child) child.position.y = base + Math.sin(t * 1.4 + i * 0.9) * 6;
// }
// });

// return (
// <group ref={(g) => (group = g)}>
// <For each={layout().lines}>
// {(line) => (
// <Text
// fontSize={layout().fontSize}
// anchorX="left"
// anchorY="top"
// color="#fafafa"
// sdfGlyphSize={256}
// outlineWidth={0}
// outlineColor="#7cf"
// outlineOpacity={0.6}
// outlineBlur={layout().fontSize * 0.08}
// position={[
// -three().size.width / 2,
// layout().height / 2 - line.y,
// 0,
// ]}
// >
// {line.text}
// </Text>
// )}
// </For>
// </group>
// );
// }
4 changes: 4 additions & 0 deletions site-solid/src/entry-client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @refresh reload
import { mount, StartClient } from "@solidjs/start/client";

mount(() => <StartClient />, document.getElementById("app")!);
21 changes: 21 additions & 0 deletions site-solid/src/entry-server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @refresh reload
import { createHandler, StartServer } from "@solidjs/start/server";

export default createHandler(() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
{assets}
</head>
<body>
<div id="app">{children}</div>
{scripts}
</body>
</html>
)}
/>
));
1 change: 1 addition & 0 deletions site-solid/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="@solidjs/start/env" />
Loading