zunokit-builder
Version:
🎨 Figma-style drag-and-drop UI builder for React developers. Create UI visually, export clean Tailwind CSS code. Perfect for rapid prototyping and component creation.
355 lines (340 loc) • 11.1 kB
text/typescript
import * as react_jsx_runtime from 'react/jsx-runtime';
import React$1 from 'react';
interface BlockPosition {
x: number;
y: number;
width: number;
height: number;
}
interface BlockStyle {
className?: string;
customStyles?: Record<string, string>;
}
interface BaseBlockProps {
id: string;
className?: string;
style?: React.CSSProperties;
[key: string]: any;
}
interface BaseBlock<T extends BaseBlockProps = BaseBlockProps> {
id: string;
type: string;
props: T;
style: BlockStyle;
children?: string[];
position: BlockPosition;
metadata?: {
createdAt: string;
updatedAt: string;
version: string;
};
}
interface TextBlockProps extends BaseBlockProps {
content: string;
tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div';
fontSize?: 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl';
fontWeight?: 'thin' | 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold' | 'black';
textAlign?: 'left' | 'center' | 'right' | 'justify';
color?: string;
lineHeight?: 'none' | 'tight' | 'snug' | 'normal' | 'relaxed' | 'loose';
}
interface TextBlock extends BaseBlock<TextBlockProps> {
type: 'text';
}
interface ButtonBlockProps extends BaseBlockProps {
text: string;
variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
size?: 'default' | 'sm' | 'lg' | 'icon';
disabled?: boolean;
loading?: boolean;
href?: string;
target?: '_blank' | '_self' | '_parent' | '_top';
onClick?: string;
type?: 'button' | 'submit' | 'reset';
icon?: {
name: string;
position: 'left' | 'right';
};
}
interface ButtonBlock extends BaseBlock<ButtonBlockProps> {
type: 'button';
}
interface InputBlockProps extends BaseBlockProps {
type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'time' | 'datetime-local';
placeholder?: string;
label?: string;
helperText?: string;
errorText?: string;
required?: boolean;
disabled?: boolean;
readOnly?: boolean;
value?: string;
name?: string;
autoComplete?: string;
maxLength?: number;
minLength?: number;
pattern?: string;
size?: 'sm' | 'default' | 'lg';
variant?: 'default' | 'outline' | 'filled';
icon?: {
name: string;
position: 'left' | 'right';
};
}
interface InputBlock extends BaseBlock<InputBlockProps> {
type: 'input';
}
interface ImageBlockProps extends BaseBlockProps {
src: string;
alt: string;
width?: number;
height?: number;
objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
objectPosition?: string;
loading?: 'lazy' | 'eager';
placeholder?: string;
blurDataURL?: string;
quality?: number;
priority?: boolean;
sizes?: string;
fill?: boolean;
rounded?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';
border?: boolean;
shadow?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
}
interface ImageBlock extends BaseBlock<ImageBlockProps> {
type: 'image';
}
interface ContainerBlockProps extends BaseBlockProps {
tag?: 'div' | 'section' | 'article' | 'aside' | 'header' | 'footer' | 'main' | 'nav';
maxWidth?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | 'full';
padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
margin?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'auto';
background?: string;
border?: boolean;
borderRadius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';
shadow?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
justifyContent?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
alignItems?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';
gap?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
display?: 'block' | 'flex' | 'grid' | 'inline' | 'inline-block' | 'inline-flex';
}
interface SectionBlock extends BaseBlock<ContainerBlockProps> {
type: 'section';
}
interface CardBlock extends BaseBlock<ContainerBlockProps> {
type: 'card';
}
interface DivBlock extends BaseBlock<ContainerBlockProps> {
type: 'div';
}
type ZunoBlock = TextBlock | ButtonBlock | InputBlock | ImageBlock | SectionBlock | CardBlock | DivBlock;
type ZunoBlockType = ZunoBlock['type'];
type ZunoBlockProps = TextBlockProps | ButtonBlockProps | InputBlockProps | ImageBlockProps | ContainerBlockProps;
interface ZunoBuilderConfig {
/** Enable/disable the builder (default: process.env.NODE_ENV === 'development') */
enabled?: boolean;
/** Target file path for code generation */
targetPath?: string;
/** Layout storage path (default: '.zuno/layout.json') */
layoutPath?: string;
/** Theme configuration */
theme?: {
primaryColor?: string;
borderRadius?: string;
fontFamily?: string;
};
/** Builder UI configuration */
ui?: {
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
showGrid?: boolean;
gridSize?: number;
snapToGrid?: boolean;
showRuler?: boolean;
darkMode?: boolean;
};
/** Code generation settings */
codegen?: {
/** Component naming convention */
componentNaming?: 'PascalCase' | 'camelCase' | 'kebab-case';
/** File organization strategy */
fileOrganization?: 'single-file' | 'component-per-file' | 'grouped-by-type';
/** Import style for generated components */
importStyle?: 'named' | 'default' | 'namespace';
/** Add TypeScript interfaces for props */
generateTypes?: boolean;
/** Include comments in generated code */
includeComments?: boolean;
/** Custom template for component generation */
componentTemplate?: string;
/** Tailwind CSS configuration */
tailwind?: {
prefix?: string;
important?: boolean;
customClasses?: Record<string, string>;
};
};
/** Plugin system */
plugins?: ZunoPlugin[];
/** Custom block definitions */
customBlocks?: CustomBlockDefinition[];
}
interface ZunoPlugin {
name: string;
version: string;
init: (builder: any) => void;
destroy?: () => void;
}
interface CustomBlockDefinition {
type: string;
name: string;
icon: string;
category: string;
defaultProps: Record<string, any>;
propSchema: Record<string, any>;
component: React.ComponentType<any>;
codeGenerator: (props: any) => string;
}
interface BuilderEvents {
'block:add': (block: ZunoBlock) => void;
'block:update': (blockId: string, updates: Partial<ZunoBlock>) => void;
'block:delete': (blockId: string) => void;
'block:select': (blockId: string | null) => void;
'block:move': (blockId: string, position: {
x: number;
y: number;
}) => void;
'block:resize': (blockId: string, size: {
width: number;
height: number;
}) => void;
'layout:save': (layout: any) => void;
'layout:load': (layout: any) => void;
'code:generate': (code: string) => void;
'builder:ready': () => void;
'builder:destroy': () => void;
}
interface BuilderEventEmitter {
on<K extends keyof BuilderEvents>(event: K, listener: BuilderEvents[K]): void;
off<K extends keyof BuilderEvents>(event: K, listener: BuilderEvents[K]): void;
emit<K extends keyof BuilderEvents>(event: K, ...args: Parameters<BuilderEvents[K]>): void;
}
interface ZunoLayout {
version: string;
id: string;
name: string;
description?: string;
blocks: ZunoBlock[];
metadata: LayoutMetadata;
viewport: ViewportConfig;
breakpoints?: BreakpointConfig;
}
interface LayoutMetadata {
createdAt: string;
updatedAt: string;
targetPath: string;
author?: string;
tags?: string[];
version: string;
}
interface ViewportConfig {
width: number;
height: number;
scale: number;
offsetX: number;
offsetY: number;
}
interface BreakpointConfig {
sm: number;
md: number;
lg: number;
xl: number;
'2xl': number;
}
interface LayoutHistory {
id: string;
timestamp: string;
action: 'create' | 'update' | 'delete' | 'move' | 'resize';
blockId?: string;
changes: any;
layout: ZunoLayout;
}
interface LayoutVersion {
id: string;
version: string;
timestamp: string;
author?: string;
description?: string;
layout: ZunoLayout;
}
interface BuilderState {
layout: ZunoLayout | null;
selectedBlockId: string | null;
hoveredBlockId: string | null;
draggedBlockId: string | null;
clipboard: ZunoBlock | null;
isLoading: boolean;
isDirty: boolean;
mode: BuilderMode;
tool: BuilderTool;
viewport: ViewportState;
history: HistoryState;
}
type BuilderMode = 'design' | 'preview' | 'code' | 'responsive';
type BuilderTool = 'select' | 'hand' | 'zoom' | 'text' | 'shape';
interface ViewportState {
width: number;
height: number;
scale: number;
offsetX: number;
offsetY: number;
showGrid: boolean;
gridSize: number;
snapToGrid: boolean;
showRulers: boolean;
}
interface HistoryState {
past: LayoutHistory[];
present: LayoutHistory | null;
future: LayoutHistory[];
maxHistorySize: number;
}
interface SelectionState {
selectedBlocks: string[];
selectionBounds?: {
x: number;
y: number;
width: number;
height: number;
};
}
interface DragState {
isDragging: boolean;
draggedBlockId: string | null;
dragOffset: {
x: number;
y: number;
};
dropTarget: string | null;
dragPreview?: {
x: number;
y: number;
width: number;
height: number;
};
}
interface ZunoBuilderProps {
config?: ZunoBuilderConfig;
children: React$1.ReactNode;
}
declare function ZunoBuilder({ config, children }: ZunoBuilderProps): react_jsx_runtime.JSX.Element;
declare function useZunoBuilder(): {
layout: ZunoLayout | null;
isLoading: boolean;
addBlock: (block: ZunoBlock) => void;
updateBlock: (blockId: string, updates: Partial<ZunoBlock>) => void;
removeBlock: (blockId: string) => void;
saveLayout: (newLayout: ZunoLayout) => Promise<void>;
};
export { BaseBlock, BaseBlockProps, BlockPosition, BlockStyle, BreakpointConfig, BuilderEventEmitter, BuilderEvents, BuilderMode, BuilderState, BuilderTool, ButtonBlock, ButtonBlockProps, CardBlock, ContainerBlockProps, CustomBlockDefinition, DivBlock, DragState, HistoryState, ImageBlock, ImageBlockProps, InputBlock, InputBlockProps, LayoutHistory, LayoutMetadata, LayoutVersion, SectionBlock, SelectionState, TextBlock, TextBlockProps, ViewportConfig, ViewportState, ZunoBlock, ZunoBlockProps, ZunoBlockType, ZunoBuilder, ZunoBuilderConfig, ZunoLayout, ZunoPlugin, useZunoBuilder };