code: nextjs,frontends,tsx (4 files)

This commit is contained in:
Richard Ward
2025-12-30 20:47:27 +00:00
parent 3b97d281c3
commit fcd4791d18
4 changed files with 234 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
import type { StorybookConfig } from '@storybook/react-vite'
import { mergeConfig } from 'vite'
import path from 'path'
const config: StorybookConfig = {
stories: [
'../src/**/*.mdx',
'../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
// Include Lua package stories
'../src/storybook/**/*.stories.@(js|jsx|mjs|ts|tsx)',
],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
docs: {},
staticDirs: [
// Serve package static content
{ from: '../../packages', to: '/packages' },
],
async viteFinal(config) {
return mergeConfig(config, {
resolve: {
alias: {
'@': path.resolve(__dirname, '../src'),
},
},
// Mock Node.js modules that aren't available in browser
define: {
'process.env': {},
},
})
},
}
export default config

View File

@@ -0,0 +1,43 @@
import type { Preview } from '@storybook/react'
import React from 'react'
// Import global styles
import '../src/app/globals.scss'
// Create a mock context provider for Storybook
const MockProviders: React.FC<{ children: React.ReactNode }> = ({ children }) => {
return <>{children}</>
}
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
// Default viewport
viewport: {
defaultViewport: 'desktop',
},
// Background options
backgrounds: {
default: 'light',
values: [
{ name: 'light', value: '#ffffff' },
{ name: 'dark', value: '#1a1a2e' },
{ name: 'canvas', value: '#f5f5f5' },
],
},
},
decorators: [
(Story) => (
<MockProviders>
<Story />
</MockProviders>
),
],
}
export default preview

View File

@@ -99,7 +99,10 @@ const nextConfig: NextConfig = {
path: false,
crypto: false,
stream: false,
'stream/promises': false,
os: false,
buffer: false,
util: false,
}
}

View File

@@ -0,0 +1,148 @@
/**
* Mock Lua Engine for Storybook
*
* Since fengari requires a real Lua VM, we mock the execution
* by interpreting the JSON-like component trees that Lua packages produce.
* This allows Storybook to render Lua packages without running actual Lua code.
*/
import type { LuaUIComponent } from '@/lib/lua/ui/types/lua-ui-package'
import type { JsonValue } from '@/types/utility-types'
export interface MockLuaContext {
user?: {
id: string
username: string
level: number
email?: string
}
nerdMode?: boolean
theme?: 'light' | 'dark'
[key: string]: JsonValue | undefined
}
export interface MockLuaScript {
id: string
name: string
code: string
/**
* Pre-computed output for this script given specific contexts.
* Keys are JSON-stringified context objects.
*/
mockOutputs?: Record<string, LuaUIComponent>
/**
* Default output to use when no matching mock is found
*/
defaultOutput?: LuaUIComponent
}
export interface MockPackageManifest {
id: string
name: string
version: string
description: string
category: string
minLevel: number
scripts: MockLuaScript[]
/**
* Pre-rendered component trees for different contexts
*/
renderedPages?: Record<string, LuaUIComponent>
}
/**
* Create a mock user context for Storybook stories
*/
export function createMockUser(overrides?: Partial<MockLuaContext['user']>): MockLuaContext['user'] {
return {
id: 'mock-user-1',
username: 'storybook_user',
level: 4,
email: 'user@example.com',
...overrides,
}
}
/**
* Create a full mock context for Lua package rendering
*/
export function createMockContext(overrides?: Partial<MockLuaContext>): MockLuaContext {
return {
user: createMockUser(overrides?.user),
nerdMode: false,
theme: 'light',
...overrides,
}
}
/**
* Mock Lua execution result
*/
export interface MockLuaResult {
success: boolean
result?: LuaUIComponent
error?: string
logs: string[]
}
/**
* Execute a mock Lua script with the given context
* Returns pre-computed output based on the context
*/
export function executeMockLuaScript(
script: MockLuaScript,
context: MockLuaContext
): MockLuaResult {
const contextKey = JSON.stringify(context)
// Check for exact context match
if (script.mockOutputs && script.mockOutputs[contextKey]) {
return {
success: true,
result: script.mockOutputs[contextKey],
logs: [],
}
}
// Fall back to default output
if (script.defaultOutput) {
return {
success: true,
result: script.defaultOutput,
logs: [],
}
}
return {
success: false,
error: `No mock output defined for script: ${script.id}`,
logs: [`Mock script ${script.id} has no output for context`],
}
}
/**
* Registry of mock package outputs
* This is populated by individual package mock files
*/
export const mockPackageRegistry: Map<string, MockPackageManifest> = new Map()
/**
* Register a mock package for Storybook rendering
*/
export function registerMockPackage(manifest: MockPackageManifest): void {
mockPackageRegistry.set(manifest.id, manifest)
}
/**
* Get a registered mock package
*/
export function getMockPackage(packageId: string): MockPackageManifest | undefined {
return mockPackageRegistry.get(packageId)
}
/**
* List all registered mock packages
*/
export function listMockPackages(): MockPackageManifest[] {
return Array.from(mockPackageRegistry.values())
}