mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-13 07:42:55 +01:00
working on problem opening projet
This commit is contained in:
@@ -59,6 +59,7 @@ const RouterNode = {
|
||||
displayNodeName: 'Page Router',
|
||||
category: 'Visuals',
|
||||
docs: 'https://docs.noodl.net/nodes/navigation/page-router',
|
||||
allowAsExportRoot: true,
|
||||
useVariants: false,
|
||||
connectionPanel: {
|
||||
groupPriority: ['General', 'Actions', 'Events', 'Mounted']
|
||||
|
||||
163
packages/noodl-viewer-react/src/style-tokens-injector.ts
Normal file
163
packages/noodl-viewer-react/src/style-tokens-injector.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* Style Tokens Injector
|
||||
*
|
||||
* Injects CSS custom properties (design tokens) into the DOM
|
||||
* for use in Noodl projects.
|
||||
*
|
||||
* This class is responsible for:
|
||||
* - Injecting default tokens into the page
|
||||
* - Updating tokens when project settings change
|
||||
* - Cleaning up on unmount
|
||||
*/
|
||||
|
||||
interface GraphModel {
|
||||
getMetaData(): Record<string, unknown> | undefined;
|
||||
on(event: string, handler: (data: unknown) => void): void;
|
||||
off(event: string): void;
|
||||
}
|
||||
|
||||
interface StyleTokensInjectorOptions {
|
||||
graphModel: GraphModel;
|
||||
}
|
||||
|
||||
export class StyleTokensInjector {
|
||||
private styleElement: HTMLStyleElement | null = null;
|
||||
private graphModel: GraphModel;
|
||||
private tokens: Record<string, string> = {};
|
||||
|
||||
constructor(options: StyleTokensInjectorOptions) {
|
||||
this.graphModel = options.graphModel;
|
||||
|
||||
// Load tokens from project metadata
|
||||
this.loadTokens();
|
||||
|
||||
// Inject tokens into DOM
|
||||
this.injectTokens();
|
||||
|
||||
// Listen for project changes
|
||||
this.bindListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load tokens from project metadata
|
||||
*/
|
||||
private loadTokens() {
|
||||
try {
|
||||
const metadata = this.graphModel.getMetaData();
|
||||
const styleTokens = metadata?.styleTokens;
|
||||
|
||||
// Validate that styleTokens is a proper object
|
||||
if (styleTokens && typeof styleTokens === 'object' && !Array.isArray(styleTokens)) {
|
||||
this.tokens = styleTokens as Record<string, string>;
|
||||
} else {
|
||||
this.tokens = this.getDefaultTokens();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to load style tokens, using defaults:', error);
|
||||
this.tokens = this.getDefaultTokens();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default tokens (fallback if project doesn't have custom tokens)
|
||||
*/
|
||||
private getDefaultTokens(): Record<string, string> {
|
||||
return {
|
||||
// Colors
|
||||
'--primary': '#3b82f6',
|
||||
'--background': '#ffffff',
|
||||
'--foreground': '#0f172a',
|
||||
'--border': '#e2e8f0',
|
||||
// Spacing
|
||||
'--space-sm': '8px',
|
||||
'--space-md': '16px',
|
||||
'--space-lg': '24px',
|
||||
// Borders
|
||||
'--radius-md': '8px',
|
||||
// Shadows
|
||||
'--shadow-sm': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
|
||||
'--shadow-md': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject tokens as CSS custom properties
|
||||
*/
|
||||
private injectTokens() {
|
||||
// Support SSR
|
||||
if (typeof document === 'undefined') return;
|
||||
|
||||
// Remove existing style element if any
|
||||
this.removeStyleElement();
|
||||
|
||||
// Create new style element
|
||||
this.styleElement = document.createElement('style');
|
||||
this.styleElement.id = 'noodl-style-tokens';
|
||||
this.styleElement.textContent = this.generateCSS();
|
||||
|
||||
// Inject into head
|
||||
document.head.appendChild(this.styleElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate CSS string from tokens
|
||||
*/
|
||||
private generateCSS(): string {
|
||||
const entries = Object.entries(this.tokens);
|
||||
|
||||
if (entries.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const declarations = entries.map(([name, value]) => ` ${name}: ${value};`).join('\n');
|
||||
|
||||
return `:root {\n${declarations}\n}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update tokens and re-inject
|
||||
*/
|
||||
updateTokens(newTokens: Record<string, string>) {
|
||||
this.tokens = { ...this.getDefaultTokens(), ...newTokens };
|
||||
this.injectTokens();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind to graph model events
|
||||
*/
|
||||
private bindListeners() {
|
||||
if (!this.graphModel) return;
|
||||
|
||||
// Listen for metadata changes
|
||||
this.graphModel.on('metadataChanged', (metadata: unknown) => {
|
||||
if (metadata && typeof metadata === 'object' && 'styleTokens' in metadata) {
|
||||
const data = metadata as Record<string, unknown>;
|
||||
if (data.styleTokens && typeof data.styleTokens === 'object') {
|
||||
this.updateTokens(data.styleTokens as Record<string, string>);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove style element from DOM
|
||||
*/
|
||||
private removeStyleElement() {
|
||||
if (this.styleElement && this.styleElement.parentNode) {
|
||||
this.styleElement.parentNode.removeChild(this.styleElement);
|
||||
this.styleElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup
|
||||
*/
|
||||
dispose() {
|
||||
this.removeStyleElement();
|
||||
if (this.graphModel) {
|
||||
this.graphModel.off('metadataChanged');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default StyleTokensInjector;
|
||||
@@ -8,6 +8,7 @@ import NoodlJSAPI from './noodl-js-api';
|
||||
import projectSettings from './project-settings';
|
||||
import { createNodeFromReactComponent } from './react-component-node';
|
||||
import registerNodes from './register-nodes';
|
||||
import { StyleTokensInjector } from './style-tokens-injector';
|
||||
import Styles from './styles';
|
||||
|
||||
if (typeof window !== 'undefined' && window.NoodlEditor) {
|
||||
@@ -189,6 +190,11 @@ export default class Viewer extends React.Component {
|
||||
//make the styles available to all nodes via `this.context.styles`
|
||||
noodlRuntime.context.styles = this.styles;
|
||||
|
||||
// Initialize style tokens injector
|
||||
this.styleTokensInjector = new StyleTokensInjector({
|
||||
graphModel: noodlRuntime.graphModel
|
||||
});
|
||||
|
||||
this.state.waitingForExport = !this.runningDeployed;
|
||||
|
||||
if (this.runningDeployed) {
|
||||
|
||||
Reference in New Issue
Block a user