Skip to content

Repository files navigation

Gnomon UI

Accessible primitives for spatial interfaces.

Official site: ray0907.github.io/gnomon-ui

Source: github.com/Ray0907/gnomon-ui

Gnomon UI spatial primitives and WebGL scene

Gnomon UI separates collection state and input contracts from rendering. A React, Vue, or future framework adapter can drive the same Three.js scene without moving selection logic, keyboard behavior, or accessibility into the canvas.

The website is a live consumer of the workspace packages. Its books, lamp, vessel, device, textile, and modular object are synthetic examples—not a required catalog shape or bundled content library.

Status

Gnomon UI is a public v0.1 framework prototype. The repository implements and tests the package boundaries, state contracts, React/Vue bindings, Three.js lifecycle, and documentation demo. The 0.1.0-alpha.2 packages are published under the public @gnomon-ui npm scope.

Packages

Package Responsibility Framework dependency
@gnomon-ui/core Store, collection order, navigation, controlled state None
@gnomon-ui/react Compound components, hooks, asChild React
@gnomon-ui/vue Components, composables, v-model Vue
@gnomon-ui/three Renderer lifecycle and selection bridge None
@gnomon-ui/theme Optional CSS variables and state tokens None

The core and renderer contracts are intentionally open so Svelte, Solid, other renderers, and non-Three scenes can integrate without changing the data model. Every item value is a unique collection identity. Adapter items belong inside Spatial.Collection, which keeps DOM focus and aria-activedescendant synchronized.

Install

The current release is an alpha. Use the next tag while APIs are settling.

pnpm add @gnomon-ui/core@next @gnomon-ui/react@next

For Vue:

pnpm add @gnomon-ui/core@next @gnomon-ui/vue@next

Add the optional Three.js renderer lifecycle when needed:

pnpm add @gnomon-ui/three@next three

The visual theme is optional:

pnpm add @gnomon-ui/theme@next

Run the demo

Requires Node.js 22 or newer and pnpm.

pnpm install
pnpm dev

Open http://127.0.0.1:5203.

Validate

pnpm check

This builds ESM and declaration output for every package, lints and type-checks the workspace, exports the static documentation site, and runs the state/API tests.

React

import { useState } from "react";
import type { SpatialItemRecord } from "@gnomon-ui/core";
import { Spatial } from "@gnomon-ui/react";

type CatalogItem = SpatialItemRecord & {
	name: string;
};

export function Catalog({ items }: { items: readonly CatalogItem[] }) {
	const [value, setValue] = useState(items[0]?.value ?? null);

	return (
		<Spatial.Root
			items={items}
			value={value}
			onValueChange={({ value: value_next }) => setValue(value_next)}
			loop
		>
			<Spatial.Scene asChild>
				<canvas aria-label="Project-owned spatial renderer" />
			</Spatial.Scene>
			<Spatial.Collection aria-label="Objects">
				{items.map((item) => (
					<Spatial.Item key={item.value} value={item.value}>
						{item.name}
					</Spatial.Item>
				))}
			</Spatial.Collection>
			<Spatial.Previous>Previous</Spatial.Previous>
			<Spatial.Next>Next</Spatial.Next>
		</Spatial.Root>
	);
}

Vue

<script setup lang="ts">
import { ref } from "vue";
import type { SpatialItemRecord } from "@gnomon-ui/core";
import { Spatial } from "@gnomon-ui/vue";

const { items } = defineProps<{
	items: readonly (SpatialItemRecord & { name: string })[];
}>();
const selected = ref(items[0]?.value ?? null);
</script>

<template>
	<Spatial.Root v-model="selected" :items="items" loop>
		<Spatial.Scene as="canvas" aria-label="Project-owned spatial renderer" />
		<Spatial.Collection aria-label="Objects">
			<Spatial.Item
				v-for="item in items"
				:key="item.value"
				:value="item.value"
			>
				{{ item.name }}
			</Spatial.Item>
		</Spatial.Collection>
	</Spatial.Root>
</template>

See Framework adapters for the shared contract and renderer lifecycle.

WebGL and fallback behavior

When WebGL is available, the demo mounts SpatialDemoEngine, renders procedural Three.js objects, and reports raycast, drag, and wheel selection to the core store. If context creation fails, the site keeps the semantic collection, keyboard controls, framework examples, and a DOM representation active. The fallback is a resilience path, not the default renderer.

Build the static site

pnpm build

The site exports to dist/. Set NEXT_PUBLIC_SITE_URL before a production build to override the official social metadata origin. GitHub Pages additionally builds with NEXT_PUBLIC_BASE_PATH=/gnomon-ui.

Provenance

The first renderer foundation was derived from the MIT-licensed mintdotgg/mint-playground. Gnomon UI replaces its product, catalog, data, visual system, package architecture, and renderer surface. See Third-party notices.

About

Accessible primitives for spatial interfaces with React, Vue, and Three.js adapters.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages