@dmitryvim/form-builder 0.1.42 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +260 -22
  2. package/dist/browser/formbuilder.min.js +184 -0
  3. package/dist/browser/formbuilder.v0.2.1.min.js +184 -0
  4. package/dist/cjs/index.cjs +3652 -0
  5. package/dist/cjs/index.cjs.map +1 -0
  6. package/dist/esm/index.js +3603 -0
  7. package/dist/esm/index.js.map +1 -0
  8. package/dist/form-builder.js +154 -3369
  9. package/dist/types/components/container.d.ts +15 -0
  10. package/dist/types/components/file.d.ts +26 -0
  11. package/dist/types/components/group.d.ts +24 -0
  12. package/dist/types/components/index.d.ts +11 -0
  13. package/dist/types/components/number.d.ts +11 -0
  14. package/dist/types/components/registry.d.ts +15 -0
  15. package/dist/types/components/select.d.ts +11 -0
  16. package/dist/types/components/text.d.ts +11 -0
  17. package/dist/types/components/textarea.d.ts +11 -0
  18. package/dist/types/index.d.ts +33 -0
  19. package/dist/types/instance/FormBuilderInstance.d.ts +134 -0
  20. package/dist/types/instance/state.d.ts +13 -0
  21. package/dist/types/styles/theme.d.ts +63 -0
  22. package/dist/types/types/component-operations.d.ts +45 -0
  23. package/dist/types/types/config.d.ts +47 -0
  24. package/dist/types/types/index.d.ts +4 -0
  25. package/dist/types/types/schema.d.ts +115 -0
  26. package/dist/types/types/state.d.ts +11 -0
  27. package/dist/types/utils/helpers.d.ts +4 -0
  28. package/dist/types/utils/styles.d.ts +21 -0
  29. package/dist/types/utils/translation.d.ts +8 -0
  30. package/dist/types/utils/validation.d.ts +2 -0
  31. package/package.json +32 -15
  32. package/dist/demo.js +0 -861
  33. package/dist/elements.html +0 -1130
  34. package/dist/elements.js +0 -488
  35. package/dist/index.html +0 -315
@@ -0,0 +1,15 @@
1
+ import type { ContainerElement, RenderContext, ComponentContext, ValidationResult, Element } from "../types/index.js";
2
+ export declare function setRenderElement(fn: (element: any, ctx: RenderContext) => HTMLElement): void;
3
+ export declare function renderSingleContainerElement(element: ContainerElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
4
+ export declare function renderMultipleContainerElement(element: ContainerElement, ctx: RenderContext, wrapper: HTMLElement, _pathKey: string): void;
5
+ export declare function setValidateElement(fn: (element: Element, ctx: {
6
+ path: string;
7
+ }, customScopeRoot?: HTMLElement | null) => any): void;
8
+ /**
9
+ * Validate container field and return extracted value with errors
10
+ */
11
+ export declare function validateContainerElement(element: Element, key: string, context: ComponentContext): ValidationResult;
12
+ /**
13
+ * Update container field value in DOM without re-render
14
+ */
15
+ export declare function updateContainerField(element: Element, fieldPath: string, value: any, context: ComponentContext): void;
@@ -0,0 +1,26 @@
1
+ import type { FileElement, FilesElement, RenderContext, ComponentContext, ValidationResult, Element } from "../types/index.js";
2
+ import type { State } from "../types/state.js";
3
+ interface FileDeps {
4
+ picker: HTMLInputElement;
5
+ fileUploadHandler: () => void;
6
+ dragHandler: (files: FileList) => void;
7
+ }
8
+ export declare function renderFilePreview(container: HTMLElement, resourceId: string, state: State, options?: {
9
+ fileName?: string;
10
+ isReadonly?: boolean;
11
+ deps?: FileDeps | null;
12
+ }): Promise<void>;
13
+ export declare function renderFilePreviewReadonly(resourceId: string, state: State, fileName?: string): Promise<HTMLElement>;
14
+ export declare function renderResourcePills(container: HTMLElement, rids: string[] | null, state: State, onRemove: ((rid: string) => void) | null): void;
15
+ export declare function renderFileElement(element: FileElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
16
+ export declare function renderFilesElement(element: FilesElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
17
+ export declare function renderMultipleFileElement(element: FileElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
18
+ /**
19
+ * Validate file field and return extracted value with errors
20
+ */
21
+ export declare function validateFileElement(element: Element, key: string, context: ComponentContext): ValidationResult;
22
+ /**
23
+ * Update file field value in DOM without re-render
24
+ */
25
+ export declare function updateFileField(element: Element, fieldPath: string, value: any, context: ComponentContext): void;
26
+ export {};
@@ -0,0 +1,24 @@
1
+ import type { GroupElement, RenderContext, ComponentContext, ValidationResult, Element } from "../types/index.js";
2
+ export declare function setRenderElement(_fn: (element: any, ctx: RenderContext) => HTMLElement): void;
3
+ /**
4
+ * Renders a group element by translating it to a ContainerElement
5
+ * and delegating to container rendering functions.
6
+ *
7
+ * This maintains backward compatibility with the legacy group type
8
+ * while eliminating code duplication.
9
+ *
10
+ * @deprecated Use type: "container" with multiple: true instead of type: "group" with repeat: {min, max}
11
+ */
12
+ export declare function renderGroupElement(element: GroupElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
13
+ export { renderGroupElement as renderRepeatableGroup };
14
+ export { renderGroupElement as renderSingleGroup };
15
+ /**
16
+ * Validate group field by delegating to container validation
17
+ * @deprecated Use validateContainerElement with type: "container" instead
18
+ */
19
+ export declare function validateGroupElement(element: Element, key: string, context: ComponentContext): ValidationResult;
20
+ /**
21
+ * Update group field by delegating to container update
22
+ * @deprecated Use updateContainerField with type: "container" instead
23
+ */
24
+ export declare function updateGroupField(element: Element, fieldPath: string, value: any, context: ComponentContext): void;
@@ -0,0 +1,11 @@
1
+ import type { Element, RenderContext } from "../types/index.js";
2
+ import { renderTextElement, renderMultipleTextElement } from "./text.js";
3
+ import { renderTextareaElement, renderMultipleTextareaElement } from "./textarea.js";
4
+ import { renderNumberElement, renderMultipleNumberElement } from "./number.js";
5
+ import { renderSelectElement, renderMultipleSelectElement } from "./select.js";
6
+ import { renderFileElement, renderFilesElement, renderMultipleFileElement } from "./file.js";
7
+ import { renderSingleContainerElement, renderMultipleContainerElement, setValidateElement as setContainerValidateElement } from "./container.js";
8
+ import { renderGroupElement } from "./group.js";
9
+ export declare function renderElement(element: Element, ctx: RenderContext): HTMLElement;
10
+ export { setContainerValidateElement };
11
+ export { renderTextElement, renderMultipleTextElement, renderTextareaElement, renderMultipleTextareaElement, renderNumberElement, renderMultipleNumberElement, renderSelectElement, renderMultipleSelectElement, renderFileElement, renderFilesElement, renderMultipleFileElement, renderSingleContainerElement, renderMultipleContainerElement, renderGroupElement, };
@@ -0,0 +1,11 @@
1
+ import type { NumberElement, RenderContext, ComponentContext, ValidationResult } from "../types/index.js";
2
+ export declare function renderNumberElement(element: NumberElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
3
+ export declare function renderMultipleNumberElement(element: NumberElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
4
+ /**
5
+ * Validate number input field and return extracted value with errors
6
+ */
7
+ export declare function validateNumberElement(element: NumberElement, key: string, context: ComponentContext): ValidationResult;
8
+ /**
9
+ * Update number field value in DOM without re-render
10
+ */
11
+ export declare function updateNumberField(element: NumberElement, fieldPath: string, value: any, context: ComponentContext): void;
@@ -0,0 +1,15 @@
1
+ import type { Element, ComponentContext, ValidationResult, ComponentOperations } from "../types/index.js";
2
+ /**
3
+ * Get component operations for a given element type
4
+ */
5
+ export declare function getComponentOperations(elementType: string): ComponentOperations | null;
6
+ /**
7
+ * Validate element using component-specific validator
8
+ * Falls back to legacy implementation if component not yet migrated
9
+ */
10
+ export declare function validateElementWithComponent(element: Element, key: string, context: ComponentContext): ValidationResult | null;
11
+ /**
12
+ * Update element using component-specific updater
13
+ * Falls back to legacy implementation if component not yet migrated
14
+ */
15
+ export declare function updateElementWithComponent(element: Element, fieldPath: string, value: any, context: ComponentContext): boolean;
@@ -0,0 +1,11 @@
1
+ import type { SelectElement, RenderContext, ComponentContext, ValidationResult, Element } from "../types/index.js";
2
+ export declare function renderSelectElement(element: SelectElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
3
+ export declare function renderMultipleSelectElement(element: SelectElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
4
+ /**
5
+ * Validate select field and return extracted value with errors
6
+ */
7
+ export declare function validateSelectElement(element: Element, key: string, context: ComponentContext): ValidationResult;
8
+ /**
9
+ * Update select field value in DOM without re-render
10
+ */
11
+ export declare function updateSelectField(element: Element, fieldPath: string, value: any, context: ComponentContext): void;
@@ -0,0 +1,11 @@
1
+ import type { TextElement, RenderContext, ComponentContext, ValidationResult } from "../types/index.js";
2
+ export declare function renderTextElement(element: TextElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
3
+ export declare function renderMultipleTextElement(element: TextElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
4
+ /**
5
+ * Validate text input field and return extracted value with errors
6
+ */
7
+ export declare function validateTextElement(element: TextElement, key: string, context: ComponentContext): ValidationResult;
8
+ /**
9
+ * Update text field value in DOM without re-render
10
+ */
11
+ export declare function updateTextField(element: TextElement, fieldPath: string, value: any, context: ComponentContext): void;
@@ -0,0 +1,11 @@
1
+ import type { TextareaElement, RenderContext, ComponentContext, ValidationResult } from "../types/index.js";
2
+ export declare function renderTextareaElement(element: TextareaElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
3
+ export declare function renderMultipleTextareaElement(element: TextareaElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
4
+ /**
5
+ * Validate textarea element - delegates to text validator since they share validation logic
6
+ */
7
+ export declare function validateTextareaElement(element: TextareaElement, key: string, context: ComponentContext): ValidationResult;
8
+ /**
9
+ * Update textarea field - delegates to text updater since they share update logic
10
+ */
11
+ export declare function updateTextareaField(element: TextareaElement, fieldPath: string, value: any, context: ComponentContext): void;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Form Builder - Instance-Based API
3
+ *
4
+ * Zero-dependency JSON Schema form builder library with multi-instance support
5
+ */
6
+ import { FormBuilderInstance } from "./instance/FormBuilderInstance.js";
7
+ import { validateSchema } from "./utils/validation.js";
8
+ export type { SelectOption, ElementAction, BaseElement, TextElement, TextareaElement, NumberElement, SelectElement, FileElement, FilesElement, ContainerElement, GroupElement, Element, Schema, ExternalAction, FormData, RenderContext, Translations, Locale, Config, ResourceMetadata, State, } from "./types/index.js";
9
+ export type { Theme } from "./styles/theme.js";
10
+ export { defaultTheme, exampleThemes } from "./styles/theme.js";
11
+ /**
12
+ * Factory function for creating new form instances
13
+ *
14
+ * @param config Optional configuration for the instance
15
+ * @returns FormBuilderInstance
16
+ *
17
+ * @example
18
+ * const form = createFormBuilder({
19
+ * uploadFile: async (file) => {
20
+ * // Upload logic
21
+ * return "resource-id-123";
22
+ * },
23
+ * downloadFile: (resourceId, fileName) => {
24
+ * // Download logic
25
+ * }
26
+ * });
27
+ *
28
+ * form.renderForm(containerElement, schema, prefillData);
29
+ */
30
+ export declare function createFormBuilder(config?: Partial<import("./types/index.js").Config>): FormBuilderInstance;
31
+ export { FormBuilderInstance };
32
+ export { validateSchema };
33
+ export default FormBuilderInstance;
@@ -0,0 +1,134 @@
1
+ import type { Schema, ExternalAction, FormData as FormDataResult, Config, State } from "../types/index.js";
2
+ /**
3
+ * FormBuilderInstance - Encapsulates all form state and operations
4
+ * Allows multiple independent forms on the same page without state collisions
5
+ */
6
+ export declare class FormBuilderInstance {
7
+ private state;
8
+ private instanceId;
9
+ constructor(config?: Partial<Config>);
10
+ /**
11
+ * Get instance ID (useful for debugging and resource prefixing)
12
+ */
13
+ getInstanceId(): string;
14
+ /**
15
+ * Get current state (for advanced use cases)
16
+ */
17
+ getState(): State;
18
+ /**
19
+ * Set the form root element
20
+ */
21
+ setFormRoot(element: HTMLElement): void;
22
+ /**
23
+ * Configure the form builder
24
+ */
25
+ configure(config: Partial<Config>): void;
26
+ /**
27
+ * Set file upload handler
28
+ */
29
+ setUploadHandler(uploadFn: ((file: File) => Promise<string>) | null): void;
30
+ /**
31
+ * Set file download handler
32
+ */
33
+ setDownloadHandler(downloadFn: ((resourceId: string, fileName: string) => void) | null): void;
34
+ /**
35
+ * Set thumbnail generation handler
36
+ */
37
+ setThumbnailHandler(thumbnailFn: ((resourceId: string) => Promise<string | null>) | null): void;
38
+ /**
39
+ * Set action handler
40
+ */
41
+ setActionHandler(actionFn: ((value: string, key: string, relatedField: string | null) => void) | null): void;
42
+ /**
43
+ * Set mode (edit or readonly)
44
+ */
45
+ setMode(mode: "edit" | "readonly"): void;
46
+ /**
47
+ * Set locale
48
+ */
49
+ setLocale(locale: "en" | "ru"): void;
50
+ /**
51
+ * Trigger onChange callbacks with debouncing
52
+ * @param fieldPath - Optional field path for field-specific change events
53
+ * @param fieldValue - Optional field value for field-specific change events
54
+ */
55
+ triggerOnChange(fieldPath?: string, fieldValue?: any): void;
56
+ /**
57
+ * Register an external action that will be displayed as a button
58
+ * External actions can be form-level (no related_field) or field-level (with related_field)
59
+ * @param action - External action definition
60
+ */
61
+ registerAction(action: ExternalAction): void;
62
+ /**
63
+ * Find the DOM element corresponding to a field path (instance-scoped)
64
+ */
65
+ private findFormElementByFieldPath;
66
+ /**
67
+ * Find schema element by field path
68
+ */
69
+ private findSchemaElement;
70
+ /**
71
+ * Resolve action label from schema or external action
72
+ */
73
+ private resolveActionLabel;
74
+ /**
75
+ * Render form-level action buttons at the bottom of the form
76
+ */
77
+ private renderFormLevelActions;
78
+ /**
79
+ * Render external action buttons for fields
80
+ */
81
+ renderExternalActions(): void;
82
+ /**
83
+ * Render form from schema
84
+ */
85
+ renderForm(root: HTMLElement, schema: Schema, prefill?: Record<string, any>, actions?: ExternalAction[]): void;
86
+ /**
87
+ * Validate form and extract data
88
+ * This is a complete copy of the validateForm logic from form-builder.ts
89
+ * but uses instance state instead of global state
90
+ */
91
+ validateForm(skipValidation?: boolean): FormDataResult;
92
+ /**
93
+ * Get form data
94
+ */
95
+ getFormData(): FormDataResult;
96
+ /**
97
+ * Submit form with validation
98
+ */
99
+ submitForm(): FormDataResult;
100
+ /**
101
+ * Save draft without validation
102
+ */
103
+ saveDraft(): FormDataResult;
104
+ /**
105
+ * Clear the form - reset all field values to empty while preserving form structure
106
+ * This is done by re-rendering the form with empty data
107
+ */
108
+ clearForm(): void;
109
+ /**
110
+ * Build prefill data for hidden fields only
111
+ * Hidden fields should retain their values when clearing
112
+ */
113
+ private buildHiddenFieldsData;
114
+ /**
115
+ * Set form data - update multiple fields without full re-render
116
+ * @param data - Object with field paths and their values
117
+ */
118
+ setFormData(data: Record<string, any>): void;
119
+ /**
120
+ * Update a single field by path without full re-render
121
+ * @param fieldPath - Field path (e.g., "email", "address.city", "items[0].name")
122
+ * @param value - New value for the field
123
+ */
124
+ updateField(fieldPath: string, value: any): void;
125
+ /**
126
+ * Update field value in DOM based on field type
127
+ * Delegates to component-specific updaters via registry
128
+ */
129
+ private updateFieldValue;
130
+ /**
131
+ * Destroy instance and clean up resources
132
+ */
133
+ destroy(): void;
134
+ }
@@ -0,0 +1,13 @@
1
+ import type { State, Config } from "../types/index.js";
2
+ /**
3
+ * Default configuration for new instances
4
+ */
5
+ export declare const defaultConfig: Config;
6
+ /**
7
+ * Create a new isolated state object for a FormBuilderInstance
8
+ */
9
+ export declare function createInstanceState(config?: Partial<Config>): State;
10
+ /**
11
+ * Generate unique instance ID for resource prefixing
12
+ */
13
+ export declare function generateInstanceId(): string;
@@ -0,0 +1,63 @@
1
+ export interface Theme {
2
+ primaryColor: string;
3
+ primaryHoverColor: string;
4
+ errorColor: string;
5
+ errorHoverColor: string;
6
+ successColor: string;
7
+ borderColor: string;
8
+ borderHoverColor: string;
9
+ borderFocusColor: string;
10
+ backgroundColor: string;
11
+ backgroundHoverColor: string;
12
+ backgroundReadonlyColor: string;
13
+ textColor: string;
14
+ textSecondaryColor: string;
15
+ textPlaceholderColor: string;
16
+ textDisabledColor: string;
17
+ buttonBgColor: string;
18
+ buttonTextColor: string;
19
+ buttonBorderColor: string;
20
+ buttonHoverBgColor: string;
21
+ buttonHoverBorderColor: string;
22
+ actionBgColor: string;
23
+ actionTextColor: string;
24
+ actionBorderColor: string;
25
+ actionHoverBgColor: string;
26
+ actionHoverBorderColor: string;
27
+ fileUploadBgColor: string;
28
+ fileUploadBorderColor: string;
29
+ fileUploadTextColor: string;
30
+ fileUploadHoverBorderColor: string;
31
+ inputPaddingX: string;
32
+ inputPaddingY: string;
33
+ borderRadius: string;
34
+ borderWidth: string;
35
+ fontSize: string;
36
+ fontSizeSmall: string;
37
+ fontSizeExtraSmall: string;
38
+ fontFamily: string;
39
+ fontWeightNormal: string;
40
+ fontWeightMedium: string;
41
+ focusRingWidth: string;
42
+ focusRingColor: string;
43
+ focusRingOpacity: string;
44
+ transitionDuration: string;
45
+ }
46
+ export declare const defaultTheme: Theme;
47
+ /**
48
+ * Generate CSS custom properties from theme object
49
+ * Prefixes all variables with --fb- to avoid conflicts
50
+ */
51
+ export declare function generateCSSVariables(theme: Partial<Theme>): string;
52
+ /**
53
+ * Inject theme CSS variables into a container element or create a style tag
54
+ */
55
+ export declare function injectThemeVariables(container: HTMLElement, theme: Partial<Theme>): void;
56
+ /**
57
+ * Example theme configurations for documentation
58
+ */
59
+ export declare const exampleThemes: {
60
+ default: Theme;
61
+ dark: Theme;
62
+ klein: Theme;
63
+ };
@@ -0,0 +1,45 @@
1
+ import type { Element } from "./schema.js";
2
+ import type { State } from "./state.js";
3
+ import type { FormBuilderInstance } from "../instance/FormBuilderInstance.js";
4
+ /**
5
+ * Context passed to component validation and update functions
6
+ */
7
+ export interface ComponentContext {
8
+ /** DOM element scope for queries (usually formRoot or container) */
9
+ scopeRoot: HTMLElement;
10
+ /** Form state */
11
+ state: State;
12
+ /** Form builder instance reference */
13
+ instance: FormBuilderInstance;
14
+ /** Path prefix for nested fields */
15
+ path: string;
16
+ /** Skip validation checks (for draft mode) */
17
+ skipValidation?: boolean;
18
+ }
19
+ /**
20
+ * Validation result from a component validator
21
+ */
22
+ export interface ValidationResult {
23
+ /** Extracted data value */
24
+ value: any;
25
+ /** Validation errors encountered */
26
+ errors: string[];
27
+ }
28
+ /**
29
+ * Component validator function type
30
+ * Extracts data from DOM and validates it based on schema element rules
31
+ */
32
+ export type ComponentValidator = (element: Element, key: string, context: ComponentContext) => ValidationResult;
33
+ /**
34
+ * Component updater function type
35
+ * Updates DOM with new value without full re-render
36
+ */
37
+ export type ComponentUpdater = (element: Element, fieldPath: string, value: any, context: ComponentContext) => void;
38
+ /**
39
+ * Component operations registry
40
+ * Maps element type to validator and updater functions
41
+ */
42
+ export interface ComponentOperations {
43
+ validate: ComponentValidator;
44
+ update: ComponentUpdater;
45
+ }
@@ -0,0 +1,47 @@
1
+ import type { Theme } from "../styles/theme.js";
2
+ export interface Translations {
3
+ addElement: string;
4
+ removeElement: string;
5
+ uploadText: string;
6
+ dragDropText: string;
7
+ dragDropTextSingle: string;
8
+ clickDragText: string;
9
+ noFileSelected: string;
10
+ noFilesSelected: string;
11
+ downloadButton: string;
12
+ }
13
+ export type Locale = "en" | "ru";
14
+ export interface Config {
15
+ uploadFile: ((file: File) => Promise<string>) | null;
16
+ downloadFile: ((resourceId: string, fileName: string) => void) | null;
17
+ getThumbnail: ((resourceId: string) => Promise<string | null>) | null;
18
+ getDownloadUrl: ((resourceId: string) => string | null) | null;
19
+ actionHandler: ((value: string, key: string, relatedField: string | null) => void) | null;
20
+ onChange: ((data: {
21
+ valid: boolean;
22
+ errors: string[];
23
+ data: Record<string, any>;
24
+ }) => void) | null;
25
+ onFieldChange: ((fieldPath: string, value: any, formData: {
26
+ valid: boolean;
27
+ errors: string[];
28
+ data: Record<string, any>;
29
+ }) => void) | null;
30
+ onThumbnailError: ((error: Error, resourceId: string) => void) | null;
31
+ onUploadError: ((error: Error, file: File) => void) | null;
32
+ onDownloadError: ((error: Error, resourceId: string, fileName: string) => void) | null;
33
+ debounceMs: number;
34
+ enableFilePreview: boolean;
35
+ maxPreviewSize: string;
36
+ readonly: boolean;
37
+ locale: Locale;
38
+ translations: Record<Locale, Translations>;
39
+ theme: Partial<Theme>;
40
+ }
41
+ export interface ResourceMetadata {
42
+ name: string;
43
+ type: string;
44
+ size: number;
45
+ uploadedAt: Date;
46
+ file?: File;
47
+ }
@@ -0,0 +1,4 @@
1
+ export type { SelectOption, ElementAction, BaseElement, TextElement, TextareaElement, NumberElement, SelectElement, FileElement, FilesElement, ContainerElement, GroupElement, Element, Schema, ExternalAction, FormData, RenderContext, } from "./schema.js";
2
+ export type { Translations, Locale, Config, ResourceMetadata, } from "./config.js";
3
+ export type { State } from "./state.js";
4
+ export type { ComponentContext, ValidationResult, ComponentValidator, ComponentUpdater, ComponentOperations, } from "./component-operations.js";
@@ -0,0 +1,115 @@
1
+ export interface SelectOption {
2
+ value: string;
3
+ label: string;
4
+ }
5
+ export interface ElementAction {
6
+ key: string;
7
+ label: string;
8
+ }
9
+ export interface BaseElement {
10
+ type: string;
11
+ key: string;
12
+ label?: string;
13
+ description?: string;
14
+ hint?: string;
15
+ required?: boolean;
16
+ hidden?: boolean;
17
+ default?: any;
18
+ actions?: ElementAction[];
19
+ }
20
+ export interface TextElement extends BaseElement {
21
+ type: "text";
22
+ pattern?: string;
23
+ minLength?: number;
24
+ maxLength?: number;
25
+ placeholder?: string;
26
+ multiple?: boolean;
27
+ minCount?: number;
28
+ maxCount?: number;
29
+ }
30
+ export interface TextareaElement extends BaseElement {
31
+ type: "textarea";
32
+ rows?: number;
33
+ minLength?: number;
34
+ maxLength?: number;
35
+ pattern?: string;
36
+ placeholder?: string;
37
+ multiple?: boolean;
38
+ minCount?: number;
39
+ maxCount?: number;
40
+ }
41
+ export interface NumberElement extends BaseElement {
42
+ type: "number";
43
+ min?: number;
44
+ max?: number;
45
+ decimals?: number;
46
+ step?: number;
47
+ placeholder?: string;
48
+ multiple?: boolean;
49
+ minCount?: number;
50
+ maxCount?: number;
51
+ }
52
+ export interface SelectElement extends BaseElement {
53
+ type: "select";
54
+ options: SelectOption[];
55
+ placeholder?: string;
56
+ multiple?: boolean;
57
+ minCount?: number;
58
+ maxCount?: number;
59
+ }
60
+ export interface FileElement extends BaseElement {
61
+ type: "file";
62
+ accept?: string | {
63
+ extensions: string[];
64
+ };
65
+ maxSize?: number;
66
+ multiple?: boolean;
67
+ minCount?: number;
68
+ maxCount?: number;
69
+ }
70
+ export interface FilesElement extends BaseElement {
71
+ type: "files";
72
+ accept?: string | {
73
+ extensions: string[];
74
+ };
75
+ maxSize?: number;
76
+ minCount?: number;
77
+ maxCount?: number;
78
+ }
79
+ export interface ContainerElement extends BaseElement {
80
+ type: "container";
81
+ elements: Element[];
82
+ multiple?: boolean;
83
+ minCount?: number;
84
+ maxCount?: number;
85
+ }
86
+ export interface GroupElement extends BaseElement {
87
+ type: "group";
88
+ elements: Element[];
89
+ repeat?: {
90
+ min?: number;
91
+ max?: number;
92
+ };
93
+ }
94
+ export type Element = TextElement | TextareaElement | NumberElement | SelectElement | FileElement | FilesElement | ContainerElement | GroupElement;
95
+ export interface Schema {
96
+ version: string;
97
+ elements: Element[];
98
+ }
99
+ export interface ExternalAction {
100
+ key: string;
101
+ value: string;
102
+ related_field: string;
103
+ label?: string;
104
+ }
105
+ export interface FormData {
106
+ valid: boolean;
107
+ errors: string[];
108
+ data: Record<string, any>;
109
+ }
110
+ export interface RenderContext {
111
+ path: string;
112
+ prefill: Record<string, any>;
113
+ state: import("./state.js").State;
114
+ instance?: any;
115
+ }
@@ -0,0 +1,11 @@
1
+ import type { Schema, ExternalAction } from "./schema.js";
2
+ import type { Config, ResourceMetadata } from "./config.js";
3
+ export interface State {
4
+ schema: Schema | null;
5
+ formRoot: HTMLElement | null;
6
+ resourceIndex: Map<string, ResourceMetadata>;
7
+ externalActions: ExternalAction[] | null;
8
+ version: string;
9
+ config: Config;
10
+ debounceTimer: number | null;
11
+ }
@@ -0,0 +1,4 @@
1
+ export declare function isPlainObject(obj: any): obj is Record<string, any>;
2
+ export declare function pathJoin(base: string, key: string): string;
3
+ export declare function pretty(obj: any): string;
4
+ export declare function clear(node: HTMLElement): void;
@@ -0,0 +1,21 @@
1
+ import type { State } from "../types/index.js";
2
+ /**
3
+ * Apply themed input styles to an HTMLInputElement, HTMLTextAreaElement, or HTMLSelectElement
4
+ */
5
+ export declare function applyInputStyles(element: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement, state: State, className?: string): void;
6
+ /**
7
+ * Apply themed hint/description styles to a paragraph element
8
+ */
9
+ export declare function applyHintStyles(element: HTMLParagraphElement): void;
10
+ /**
11
+ * Create a styled add button with theme support
12
+ */
13
+ export declare function createAddButton(text: string, onClick: () => void): HTMLButtonElement;
14
+ /**
15
+ * Create a styled remove button with theme support
16
+ */
17
+ export declare function createRemoveButton(text: string, onClick: () => void): HTMLButtonElement;
18
+ /**
19
+ * Apply themed action button styles (for external actions in readonly mode)
20
+ */
21
+ export declare function applyActionButtonStyles(button: HTMLButtonElement, isFormLevel?: boolean): void;
@@ -0,0 +1,8 @@
1
+ import type { State } from "../types/state.js";
2
+ /**
3
+ * Get translated string for a key
4
+ * @param key Translation key
5
+ * @param state Form state containing locale and translations
6
+ * @returns Translated string or key if not found
7
+ */
8
+ export declare function t(key: string, state: State): string;
@@ -0,0 +1,2 @@
1
+ export declare function makeFieldHint(element: any): string;
2
+ export declare function validateSchema(schema: any): string[];