diff --git a/README.md b/README.md
index 497a1f53..f2903c0b 100644
--- a/README.md
+++ b/README.md
@@ -14,13 +14,13 @@ Build performant 3D user interfaces for Three.js using @react-three/fiber and yo
TODO Release
+- drag/click threshold
- add shadcn components
- cli for kits
- add apfel components
- Content "measureContent" flag => allow disabling content measuring and scaling
- support for visibility="hidden"
- input
-- Label
- decrease clipping rect when scrollbar present
TODO Later
diff --git a/docs/getting-started/introduction.md b/docs/getting-started/introduction.md
index 72742a80..ec8f5ffa 100644
--- a/docs/getting-started/introduction.md
+++ b/docs/getting-started/introduction.md
@@ -42,10 +42,18 @@ createRoot(document.getElementById('root')).render(
| [View All Components]() | - |
| `uikit add default {Component}` | - |
-## Tutorials
+## How to get started ?
The tutorials expect some level of familarity with react, threejs, and @react-three/fiber.
-1. First Layout
+1. Build your [First Layout]()
+2. Learn about the [Available Components and Their Properties]()
+3. Get inspired by our [Examples]()
+4. Learn more about
+- Using [Custom Materials]()
+- Using [Custom Fonts]()
+- Creating [Responsivene User Interfaces]()
+- [Scrolling]()
+- [Sizing]()
+5. Learn about [Common Pitfalls]() and how to [Optimize Performance]()
-- Custom Material
diff --git a/docs/tutorials/content.mdx b/docs/tutorials/content.mdx
deleted file mode 100644
index 27ccd3d6..00000000
--- a/docs/tutorials/content.mdx
+++ /dev/null
@@ -1,146 +0,0 @@
-import Image from '@theme/IdealImage';
-import { CodesandboxEmbed } from '../CodesandboxEmbed.tsx'
-
-# 3D Content
-
-The previous examples showed 2D elements positioned in the x/y plane. Integrating 3D geometries into the UI will make use of the z-Axis. In addition to having width and height, all components now have depth, which is their size on the z-Axis. All UI elements will be placed in front of their parent along the z-Axis.
-
-
-
-[Image Source](https://mayaposch.wordpress.com/2012/12/17/on-the-coordinate-system-of-qgraphicsscene-in-qt/opengl_coordinate_system/)
-
-**Koestlich** supports any Three.js geometry and material. The following example shows how to use the `GLTF` component to import a 3D model directly and how to use the `Object` component to insert an object with a `SphereGeomerty` and a `MeshPhongMaterial` into the layout.
-
-
-
-
-
-```tsx
-import { RootContainer, Object, GLTF, Container } from "@coconut-xr/koestlich";
-import { OrbitControls } from "@react-three/drei";
-import { Canvas } from "@react-three/fiber";
-import { Suspense, useMemo } from "react";
-import { Mesh, MeshPhongMaterial, SphereBufferGeometry } from "three";
-
-export default function App() {
- const sphere = useMemo(
- () =>
- new Mesh(
- new SphereBufferGeometry(),
- new MeshPhongMaterial({ toneMapped: false, color: "blue" }),
- ),
- [],
- );
-
- return (
-
- );
-}
-```
-
-Our example dashboard interface can be built using `ExtrudeGeometry` from three.js and the SVGs from any icon library. However, we use the `SVGLoader` code from the three.js/examples, which has limited features.
-
-
-
-
-
-```tsx
-import { RootContainer, Object, SVG } from "@coconut-xr/koestlich";
-import { OrbitControls } from "@react-three/drei";
-import { Canvas } from "@react-three/fiber";
-import { ExtrudeGeometry, Shape, Mesh, MeshPhongMaterial } from "three";
-import { Suspense, useMemo } from "react";
-
-export default function App() {
- const mesh1 = useMemo(() => new Mesh(new CardGeometry(1, 1, 0.1),new MeshPhongMaterial({
- toneMapped: false,
- transparent: true
- })), []);
- const mesh2 = useMemo(() => new Mesh(new CardGeometry(1, 1, 0.1),new MeshPhongMaterial({
- toneMapped: false,
- transparent: true
- })), []);
- const mesh3 = useMemo(() => new Mesh(new CardGeometry(1, 1, 0.1),new MeshPhongMaterial({
- toneMapped: false,
- transparent: true
- })), []);
- return (
-
- );
-}
-
-class CardGeometry extends ExtrudeGeometry {
- constructor(width: number, height: number, radius: number) {
- const roundedRectShape = new Shape();
- roundedRectShape.moveTo(0, radius);
- roundedRectShape.lineTo(0, height - radius);
- roundedRectShape.quadraticCurveTo(0, height, radius, height);
- roundedRectShape.lineTo(width - radius, height);
- roundedRectShape.quadraticCurveTo(width, height, width, height - radius);
- roundedRectShape.lineTo(width, radius);
- roundedRectShape.quadraticCurveTo(width, 0, width - radius, 0);
- roundedRectShape.lineTo(radius, 0);
- roundedRectShape.quadraticCurveTo(0, 0, 0, radius);
- super(roundedRectShape, { depth: 1, bevelEnabled: false });
- }
-}
-```
diff --git a/examples/dashboard/vite.config.ts b/examples/dashboard/vite.config.ts
index 9a823cca..5eb10be6 100644
--- a/examples/dashboard/vite.config.ts
+++ b/examples/dashboard/vite.config.ts
@@ -5,6 +5,9 @@ import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
+ optimizeDeps: {
+ include: ['@react-three/uikit-lucide', '@react-three/uikit'],
+ },
resolve: {
alias: [
{ find: '@', replacement: path.resolve(__dirname, '../../packages/kits/default') },
diff --git a/examples/default/vite.config.ts b/examples/default/vite.config.ts
index 9a823cca..5eb10be6 100644
--- a/examples/default/vite.config.ts
+++ b/examples/default/vite.config.ts
@@ -5,6 +5,9 @@ import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
+ optimizeDeps: {
+ include: ['@react-three/uikit-lucide', '@react-three/uikit'],
+ },
resolve: {
alias: [
{ find: '@', replacement: path.resolve(__dirname, '../../packages/kits/default') },
diff --git a/examples/lucide/vite.config.ts b/examples/lucide/vite.config.ts
index 9a823cca..5eb10be6 100644
--- a/examples/lucide/vite.config.ts
+++ b/examples/lucide/vite.config.ts
@@ -5,6 +5,9 @@ import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
+ optimizeDeps: {
+ include: ['@react-three/uikit-lucide', '@react-three/uikit'],
+ },
resolve: {
alias: [
{ find: '@', replacement: path.resolve(__dirname, '../../packages/kits/default') },
diff --git a/examples/market/vite.config.ts b/examples/market/vite.config.ts
index 9a823cca..5eb10be6 100644
--- a/examples/market/vite.config.ts
+++ b/examples/market/vite.config.ts
@@ -5,6 +5,9 @@ import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
+ optimizeDeps: {
+ include: ['@react-three/uikit-lucide', '@react-three/uikit'],
+ },
resolve: {
alias: [
{ find: '@', replacement: path.resolve(__dirname, '../../packages/kits/default') },
diff --git a/examples/uikit/src/App.tsx b/examples/uikit/src/App.tsx
index 8db6c2d5..cb62ee28 100644
--- a/examples/uikit/src/App.tsx
+++ b/examples/uikit/src/App.tsx
@@ -60,6 +60,7 @@ export default function App() {
(x.value = hover ? 'yellow' : undefined)}
backgroundColor={x}
+ borderColor="white"
borderBend={1}
border={20}
borderRadius={30}
diff --git a/examples/uikit/vite.config.ts b/examples/uikit/vite.config.ts
index 9a823cca..5eb10be6 100644
--- a/examples/uikit/vite.config.ts
+++ b/examples/uikit/vite.config.ts
@@ -5,6 +5,9 @@ import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
+ optimizeDeps: {
+ include: ['@react-three/uikit-lucide', '@react-three/uikit'],
+ },
resolve: {
alias: [
{ find: '@', replacement: path.resolve(__dirname, '../../packages/kits/default') },
diff --git a/packages/icons/lucide/convert.ts b/packages/icons/lucide/convert.ts
index 9309b070..e34a20d2 100644
--- a/packages/icons/lucide/convert.ts
+++ b/packages/icons/lucide/convert.ts
@@ -1,11 +1,11 @@
//@ts-ignore
-import SVGFixer from 'oslllo-svg-fixer';
+import SVGFixer from 'oslllo-svg-fixer'
-const searchDir = "node_modules/lucide-static/icons/";
-const outDir = "./icons/"
+const searchDir = 'node_modules/lucide-static/icons/'
+const outDir = './icons/'
async function main() {
await SVGFixer(searchDir, outDir).fix()
}
-main();
+main()
diff --git a/packages/icons/lucide/generate.ts b/packages/icons/lucide/generate.ts
index de72d939..227b55d5 100644
--- a/packages/icons/lucide/generate.ts
+++ b/packages/icons/lucide/generate.ts
@@ -1,37 +1,40 @@
-import { readdir, readFile, writeFile } from "fs/promises";
+import { readdir, readFile, writeFile } from 'fs/promises'
-const baseDir = "icons/";
+const baseDir = 'icons/'
async function main() {
- const icons = await readdir(baseDir);
+ const icons = await readdir(baseDir)
for (const icon of icons) {
- if (icon === ".gitkeep") {
- continue;
+ if (icon === '.gitkeep') {
+ continue
}
- const name = getName(icon);
- const raw = await readFile(`${baseDir}${icon}`);
- const svg = raw.toString();
+ const name = getName(icon)
+ const raw = await readFile(`${baseDir}${icon}`)
+ const svg = raw.toString()
const code = `
/* eslint-disable no-shadow-restricted-names */
import { SvgIconFromText, ComponentInternals } from "@react-three/uikit";
import { ComponentPropsWithoutRef, forwardRef } from "react";
export type ${name}Props = Omit, "text" | "svgWidth" | "svgHeight">;
const text = \`${svg}\`;
- export const ${name} = forwardRef((props, ref) => {
+ export const ${name} = /*@__PURE__*/ forwardRef((props, ref) => {
return
})
- `;
- writeFile(`src/${name}.tsx`, code);
+ `
+ writeFile(`src/${name}.tsx`, code)
}
writeFile(
- "src/index.tsx",
- icons.filter(icon => icon != ".gitkeep").map((icon) => `export * from "./${getName(icon)}.js";`).join("\n"),
- );
+ 'src/index.tsx',
+ icons
+ .filter((icon) => icon != '.gitkeep')
+ .map((icon) => `export * from "./${getName(icon)}.js";`)
+ .join('\n'),
+ )
}
function getName(file: string): string {
- const name = file.slice(0, -4);
- return name[0].toUpperCase() + name.slice(1).replace(/-./g, (x) => x[1].toUpperCase());
+ const name = file.slice(0, -4)
+ return name[0].toUpperCase() + name.slice(1).replace(/-./g, (x) => x[1].toUpperCase())
}
-main();
+main()
diff --git a/packages/uikit/src/text/interaction-text-mesh.ts b/packages/uikit/src/text/interaction-text-mesh.ts
deleted file mode 100644
index e69de29b..00000000