Adding slurve sound

This commit is contained in:
2026-03-26 10:50:04 +01:00
parent 9e15e32b94
commit 644599cc56
14 changed files with 58 additions and 352 deletions
+15
View File
@@ -0,0 +1,15 @@
# Assumption Toggle
CRT-styled toggle puzzle component for Glitch University.
## Commands
- `npm install`
- `npm run dev`
- `npm run build`
## Notes
- Host bridge support lives in `src/hostBridge.ts` and `src/devHostBridge.ts`
- Dev-only font loading lives in `src/dev-theme.css`
- Integration manifest lives in `glitch.manifest.json`
+10 -10
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
export {};
import './dev-theme.css';
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
{
"componentId": "assumption-toggle",
"displayName": "Assumption Toggle",
"version": "1.0.0",
"folderName": "glitch_assumption_toggle",
"packageName": "@nommo/assumption-toggle",
"entry": "dist/assumption-toggle.js",
"source": "src/index.tsx",
"tags": [
"glitch-component",
"crt",
"logic"
]
}
+5 -337
View File
@@ -1,341 +1,9 @@
# Create GlitchComponent
Create a new GlitchComponent project that conforms to the standardized plugin architecture for Glitch University.
The canonical Glitch University component workflow now lives at the workspace root:
## Arguments
- `/Users/jenstandstad/Projects/glitch-components/GLITCH_COMPONENT_STANDARD.md`
- `/Users/jenstandstad/Projects/glitch-components/templates/react-vite-glitch-component/`
- `/Users/jenstandstad/Projects/glitch-components/scripts/new-glitch-component.mjs`
- `$ARGUMENTS` - Component name (e.g., "matrix-rain", "particle-system")
## Instructions
When creating a new GlitchComponent:
1. **If no directory specified**, create in a sibling directory: `../glitch-components/$ARGUMENTS/`
2. **Create the full project structure**:
```
$ARGUMENTS/
├── src/
│ ├── index.tsx # Main export with metadata
│ ├── Component.tsx # Component implementation
│ ├── styles.module.css # Scoped CSS styles
│ ├── types.ts # TypeScript interfaces
│ └── dev.tsx # Leva dev harness
├── vite.config.ts
├── package.json
├── tsconfig.json
└── index.html
```
3. After creation, explain how to:
- Run `npm install && npm run dev` for local development
- Build with `npm run build`
- Deploy output to host app
---
## Architecture Principles
1. **Build as Library**: Use Vite Library Mode to output a self-contained bundle
2. **CSS Isolation**: Use CSS Modules to prevent style bleeding
3. **Inversion of Control**: Accept props for all configurable parameters
4. **Local Dev Support**: Use Leva controls during development, props in production
---
## Required TypeScript Interfaces
```typescript
// src/types.ts
export interface GlitchComponentConfig {
id: string;
name: string;
version: string;
params: Record<string, unknown>;
}
export interface GlitchComponentProps {
config: GlitchComponentConfig;
onComplete: (result: GlitchComponentResult) => void;
onProgress?: (percent: number) => void;
theme?: GlitchTheme;
className?: string;
}
export interface GlitchComponentResult {
success: boolean;
score?: number;
data?: unknown;
error?: string;
}
export interface GlitchTheme {
primary: string; // #6366f1
accent: string; // #22d3ee
bg: string; // #0a0a0f
bgSecondary: string; // #12121a
text: string; // #e8e8ec
textMuted: string; // #9999a8
border: string; // #2a2a3a
}
export interface GlitchComponentMetadata {
name: string;
displayName: string;
version: string;
paramSchema: ParamSchema;
defaultParams: Record<string, unknown>;
}
export interface ParamSchema {
[key: string]: {
type: 'number' | 'string' | 'boolean' | 'color' | 'select' | 'range';
label?: string;
description?: string;
default: unknown;
options?: { value: string | number; label: string }[];
min?: number;
max?: number;
step?: number;
};
}
```
---
## Main Export Structure
```typescript
// src/index.tsx
import Component from './Component';
import type { GlitchComponentMetadata } from './types';
export default Component;
export const metadata: GlitchComponentMetadata = {
name: 'my-component',
displayName: 'My Component',
version: '1.0.0',
paramSchema: {
speed: { type: 'range', label: 'Speed', default: 1.0, min: 0.1, max: 5.0, step: 0.1 },
primaryColor: { type: 'color', label: 'Color', default: '#6366f1' }
},
defaultParams: { speed: 1.0, primaryColor: '#6366f1' }
};
export type { GlitchComponentProps, GlitchComponentConfig, GlitchComponentResult } from './types';
```
---
## Component Template
```typescript
// src/Component.tsx
import { useCallback, useEffect, useState } from 'react';
import styles from './styles.module.css';
import type { GlitchComponentProps } from './types';
interface ComponentParams {
speed: number;
primaryColor: string;
}
export default function MyComponent({ config, onComplete, onProgress, theme, className }: GlitchComponentProps) {
const params = config.params as ComponentParams;
const { speed = 1.0, primaryColor } = params;
const handleComplete = useCallback((success: boolean, score?: number) => {
onComplete({ success, score, data: { completedAt: new Date().toISOString() } });
}, [onComplete]);
const cssVars = {
'--gc-primary': primaryColor || theme?.primary || '#6366f1',
'--gc-accent': theme?.accent || '#22d3ee',
'--gc-bg': theme?.bg || '#0a0a0f',
'--gc-text': theme?.text || '#e8e8ec',
} as React.CSSProperties;
return (
<div className={`${styles.container} ${className || ''}`} style={cssVars}>
<h2 className={styles.title}>My GlitchComponent</h2>
<button className={styles.button} onClick={() => handleComplete(true, 100)}>
Complete
</button>
</div>
);
}
```
---
## CSS Module Template
```css
/* src/styles.module.css */
.container {
background: var(--gc-bg, #0a0a0f);
color: var(--gc-text, #e8e8ec);
padding: 2rem;
border-radius: 12px;
box-sizing: border-box;
font-family: system-ui, -apple-system, sans-serif;
line-height: 1.5;
}
.container *, .container *::before, .container *::after {
box-sizing: inherit;
}
.title {
color: var(--gc-primary, #6366f1);
margin: 0 0 1rem;
font-size: 1.5rem;
font-weight: 600;
}
.button {
background: var(--gc-primary, #6366f1);
color: white;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: opacity 0.2s ease;
}
.button:hover { opacity: 0.9; }
.button:disabled { opacity: 0.5; cursor: not-allowed; }
```
---
## Vite Configuration
```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
import { resolve } from 'path';
export default defineConfig(({ mode }) => ({
plugins: [react(), cssInjectedByJsPlugin()],
build: {
lib: {
entry: resolve(__dirname, 'src/index.tsx'),
name: 'MyGlitchComponent',
fileName: 'my-glitch-component',
formats: ['es']
},
rollupOptions: {
external: ['react', 'react-dom', 'react/jsx-runtime'],
output: {
globals: { react: 'React', 'react-dom': 'ReactDOM', 'react/jsx-runtime': 'jsxRuntime' },
assetFileNames: 'assets/[name][extname]'
}
},
sourcemap: true,
minify: mode === 'production'
},
server: { port: 3001, open: true }
}));
```
---
## Package.json
```json
{
"name": "my-glitch-component",
"version": "1.0.0",
"type": "module",
"main": "./dist/my-glitch-component.js",
"module": "./dist/my-glitch-component.js",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@vitejs/plugin-react": "^4.2.0",
"leva": "^0.9.35",
"typescript": "^5.3.0",
"vite": "^5.0.0",
"vite-plugin-css-injected-by-js": "^3.3.0"
}
}
```
---
## Dev Harness with Leva
```typescript
// src/dev.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { useControls, Leva } from 'leva';
import Component from './Component';
import { metadata } from './index';
function DevHarness() {
const levaSchema = Object.entries(metadata.paramSchema).reduce((acc, [key, schema]) => {
if (schema.type === 'range' || schema.type === 'number') {
acc[key] = { value: schema.default, min: schema.min, max: schema.max, step: schema.step };
} else if (schema.type === 'select') {
acc[key] = { value: schema.default, options: schema.options?.reduce((o, opt) => ({ ...o, [opt.label]: opt.value }), {}) };
} else {
acc[key] = schema.default;
}
return acc;
}, {} as Record<string, unknown>);
const params = useControls(levaSchema);
return (
<div style={{ minHeight: '100vh', background: '#0a0a0f', padding: '2rem' }}>
<Leva collapsed={false} />
<Component
config={{ id: 'dev', name: metadata.name, version: metadata.version, params }}
theme={{ primary: '#6366f1', accent: '#22d3ee', bg: '#0a0a0f', bgSecondary: '#12121a', text: '#e8e8ec', textMuted: '#9999a8', border: '#2a2a3a' }}
onComplete={(r) => { console.log('Complete:', r); alert(`Done! Score: ${r.score}`); }}
/>
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')!).render(<React.StrictMode><DevHarness /></React.StrictMode>);
```
---
## Three.js / R3F Components
For 3D components, add to externals in vite.config.ts:
```typescript
external: ['react', 'react-dom', 'react/jsx-runtime', 'three', '@react-three/fiber', '@react-three/drei']
```
---
## Deployment
0. `nvm use 20` # to select node version 20
1. `npm run build`
2. Copy `dist/*.js` to host app's `src/components/glitch/`
3. Add database entry:
```sql
INSERT INTO glitch_components (name, display_name, version, file_path, param_schema, default_params)
VALUES ('my-component', 'My Component', '1.0.0', 'my-component.js', '{"speed":{"type":"range","default":1.0}}', '{"speed":1.0}');
```
4. Link to tech via `glitch_component_id`
Use the root scaffold instead of copying this folder or reusing older component boilerplate.
+10
View File
@@ -0,0 +1,10 @@
@import url("https://fonts.googleapis.com/css2?family=Iceland&family=Russo+One&family=VT323&display=swap");
body {
margin: 0;
background:
radial-gradient(circle at top, rgb(36 138 0 / 15%), transparent 34%),
linear-gradient(180deg, #050805, #0b110b);
color: #f4f5ee;
font-family: "Iceland", sans-serif;
}
+1
View File
@@ -1,6 +1,7 @@
import React, { useEffect, useMemo, useState } from 'react';
import ReactDOM from 'react-dom/client';
import Component from './Component';
import './dev-theme.css';
import { attachWindowSoundBridge, createDevHostBridge } from './devHostBridge';
import { metadata } from './index';
-2
View File
@@ -1,5 +1,3 @@
@import url("https://fonts.googleapis.com/css2?family=Iceland&family=Russo+One&family=VT323&display=swap");
.gc-assumption-toggle {
--shell-bg: radial-gradient(circle at top, rgba(40, 58, 34, 0.35), transparent 42%), linear-gradient(180deg, #070a08, #0f160f 58%, #090b09);
--screen-bg: #616161;
+1 -1
View File
@@ -1310,7 +1310,7 @@ body::after {
.splash-content h2 {
font-size: 1.2rem;
margin-bottom: 48px;
margin-bottom: 20px;
color: var(--text-secondary);
font-weight: 500;
}