архитектура добавления элементов, список эталонов

This commit is contained in:
2025-07-18 07:45:43 +03:00
parent dfb4d377d0
commit 7cf319f25d
36 changed files with 2100 additions and 123 deletions

View File

@@ -0,0 +1,26 @@
import {
checkboxDefinition,
dateDefinition,
numberDefinition,
radioDefinition,
selectDefinition,
textareaDefinition,
textDefinition
} from "@/components/BasicElements";
import { standardsDefinition } from "@/components/StandardsElement/definition";
import { registerElement } from "./element-registry";
// Регистрация всех элементов
export function initializeElementRegistry() {
// Базовые элементы
registerElement("text", textDefinition);
registerElement("select", selectDefinition);
registerElement("number", numberDefinition);
registerElement("date", dateDefinition);
registerElement("textarea", textareaDefinition);
registerElement("checkbox", checkboxDefinition);
registerElement("radio", radioDefinition);
// Специальные элементы
registerElement("standards", standardsDefinition);
}

View File

@@ -0,0 +1,42 @@
import { ReactNode } from "react";
import { CellTarget, ElementType } from "../types/template";
export interface ElementDefinition<Config = any, Value = any> {
/* служебные */
type: ElementType; // "text" | "select" | ...
label: string; // Человекочитаемое имя
icon: ReactNode;
/* React-компоненты */
Editor: React.FC<{ config: Config; onChange(c: Config): void }>;
Preview: React.FC<{ config: Config }>;
Render: React.FC<{ config: Config; value: Value; onChange?(v: Value): void }>;
/* бизнес-логика */
defaultConfig: Config;
mapToCells?(config: Config): CellTarget[]; // куда пишем данные
}
export const elementRegistry: Record<ElementType, ElementDefinition> = {} as any;
// Функция для регистрации элемента
export function registerElement<T extends ElementType>(
type: T,
definition: ElementDefinition
) {
elementRegistry[type] = definition;
}
// Получить все доступные типы элементов
export function getAvailableElementTypes(): Array<{ type: ElementType; label: string; icon: ReactNode }> {
return Object.values(elementRegistry).map(({ type, label, icon }) => ({
type,
label,
icon,
}));
}
// Получить определение элемента по типу
export function getElementDefinition(type: ElementType): ElementDefinition | undefined {
return elementRegistry[type];
}

View File

@@ -1,4 +1,4 @@
import { DEFAULT_FUNCTIONS, VOLATILE_FUNCTIONS } from './functions'
import { DEFAULT_FUNCTIONS, ExcelFunction, VOLATILE_FUNCTIONS } from './functions'
// Регулярные выражения для ссылок
const QUALIFIED_REF_RE = /\b[A-Za-z0-9_]+![A-Z]+[0-9]+\b/g // SheetName!A1

View File

@@ -39,8 +39,6 @@ export function migrateTemplateElement(element: any): TemplateElement {
// Получение настроек отображения по умолчанию
export function getDefaultLayoutSettings(): FormLayoutSettings {
return {
canvasWidth: 1200,
canvasHeight: 800,
gridSize: 20,
showGrid: true,
};