@dmitryvim/form-builder 0.2.29 → 0.2.32
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.
- package/README.md +51 -0
- package/dist/browser/formbuilder.min.js +578 -386
- package/dist/browser/formbuilder.v0.2.32.min.js +1148 -0
- package/dist/cjs/index.cjs +1477 -789
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +1449 -775
- package/dist/esm/index.js.map +1 -1
- package/dist/form-builder.js +578 -386
- package/dist/types/components/file/dom.d.ts +4 -5
- package/dist/types/components/file/preview.d.ts +5 -0
- package/dist/types/components/file/render-edit.d.ts +8 -1
- package/dist/types/components/file/render-readonly.d.ts +4 -7
- package/dist/types/components/file/upload.d.ts +6 -0
- package/dist/types/components/markdown/index.d.ts +15 -0
- package/dist/types/components/markdown/render.d.ts +6 -0
- package/dist/types/components/markdown/snarkdown.d.ts +2 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/instance/FormBuilderInstance.d.ts +10 -0
- package/dist/types/types/component-operations.d.ts +5 -0
- package/dist/types/types/config.d.ts +4 -0
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/schema.d.ts +22 -1
- package/dist/types/types/state.d.ts +5 -1
- package/dist/types/utils/helpers.d.ts +14 -0
- package/package.json +1 -1
- package/dist/browser/formbuilder.v0.2.29.min.js +0 -956
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { State } from "../../types/state.js";
|
|
2
|
-
export declare const TILE_SIZE = "160px";
|
|
3
2
|
/**
|
|
4
|
-
* Create a base square tile element
|
|
5
|
-
*
|
|
3
|
+
* Create a base square tile element. Sizing comes from CSS — `.fb-tile` and
|
|
4
|
+
* its descendants resolve aspect-ratio/dimensions via the theme variables.
|
|
6
5
|
*/
|
|
7
6
|
export declare function createFileTile(): HTMLElement;
|
|
8
7
|
/**
|
|
9
|
-
* Show an inline error message below the nearest
|
|
8
|
+
* Show an inline error message below the nearest [data-files-wrapper] ancestor.
|
|
10
9
|
*/
|
|
11
10
|
export declare function showFileError(container: HTMLElement, message: string): void;
|
|
12
11
|
/**
|
|
13
|
-
* Remove any inline file error message below the nearest
|
|
12
|
+
* Remove any inline file error message below the nearest [data-files-wrapper] ancestor.
|
|
14
13
|
*/
|
|
15
14
|
export declare function clearFileError(container: HTMLElement): void;
|
|
16
15
|
/**
|
|
@@ -14,6 +14,10 @@ export interface TileActionOptions {
|
|
|
14
14
|
* just-uploaded file.
|
|
15
15
|
*/
|
|
16
16
|
meta?: ResourceMetadata;
|
|
17
|
+
/** Single-only: replace current file by triggering the upload picker. */
|
|
18
|
+
replaceHandler?: (() => void) | null;
|
|
19
|
+
/** Single-only: open the host-owned library picker to pick a replacement. */
|
|
20
|
+
libraryHandler?: (() => void) | null;
|
|
17
21
|
}
|
|
18
22
|
/**
|
|
19
23
|
* Build a horizontal row of icon-only action buttons for a file tile.
|
|
@@ -22,6 +26,7 @@ export interface TileActionOptions {
|
|
|
22
26
|
* Remove is rendered only in edit mode.
|
|
23
27
|
*/
|
|
24
28
|
export declare function createTileActions(options: TileActionOptions): HTMLElement;
|
|
29
|
+
export declare function getLocalFileUrl(file: File): string;
|
|
25
30
|
export declare function releaseLocalFileUrl(file: File | undefined | null): void;
|
|
26
31
|
/**
|
|
27
32
|
* Populate a single-file edit-mode container with a file preview.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { State } from "../../types/state.js";
|
|
2
2
|
import type { FileElement, FilesElement, RenderContext } from "../../types/index.js";
|
|
3
|
-
export { TILE_SIZE } from "./dom.js";
|
|
4
3
|
export interface RenderPillsOptions {
|
|
5
4
|
container: HTMLElement;
|
|
6
5
|
rids: string[] | null;
|
|
@@ -11,8 +10,16 @@ export interface RenderPillsOptions {
|
|
|
11
10
|
maxCount?: number;
|
|
12
11
|
isReadonly?: boolean;
|
|
13
12
|
onLibraryPick?: (() => void) | null;
|
|
13
|
+
element?: {
|
|
14
|
+
maxSize?: number;
|
|
15
|
+
accept?: unknown;
|
|
16
|
+
};
|
|
17
|
+
onClearAll?: () => void;
|
|
18
|
+
openPicker?: () => void;
|
|
14
19
|
}
|
|
15
20
|
export declare function renderResourcePills(opts: RenderPillsOptions): void;
|
|
16
21
|
export declare function renderFileElementEdit(element: FileElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
|
|
22
|
+
/** Legacy `files` element — multi-file with no upper bound. */
|
|
17
23
|
export declare function renderFilesElementEdit(element: FilesElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
|
|
24
|
+
/** `file` element with `multiple: true` — multi-file honouring maxCount. */
|
|
18
25
|
export declare function renderMultipleFileElementEdit(element: FileElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import type { State } from "../../types/state.js";
|
|
2
2
|
import type { FileElement, FilesElement, RenderContext } from "../../types/index.js";
|
|
3
3
|
/**
|
|
4
|
-
* Render a
|
|
4
|
+
* Render a 220px readonly single-file container (object-contain preview + filename pill).
|
|
5
5
|
* If no prefill: shows a styled empty placeholder.
|
|
6
6
|
*/
|
|
7
7
|
export declare function renderFileElementReadonly(element: FileElement, ctx: RenderContext, wrapper: HTMLElement, pathKey: string): void;
|
|
8
8
|
/**
|
|
9
|
-
* Render a
|
|
10
|
-
*
|
|
11
|
-
* Issue 2 fix: exactly N tile elements for N files — no hidden pill stubs.
|
|
12
|
-
* The [data-files-wrapper] element carries data-resource-ids so validation
|
|
13
|
-
* can read IDs without touching the tile DOM.
|
|
9
|
+
* Render a CSS grid of readonly preview tiles.
|
|
10
|
+
* No add tile, no remove buttons, no drag handles.
|
|
14
11
|
*/
|
|
15
|
-
export declare function renderMultiFileReadonly(rids: string[], state: State, wrapper: HTMLElement, pathKey: string,
|
|
12
|
+
export declare function renderMultiFileReadonly(rids: string[], state: State, wrapper: HTMLElement, pathKey: string, _marginTop?: string): void;
|
|
16
13
|
/**
|
|
17
14
|
* Render legacy `files` element in readonly mode.
|
|
18
15
|
*/
|
|
@@ -8,6 +8,12 @@ export interface FileDeps {
|
|
|
8
8
|
setupDrop?: (container: HTMLElement) => void;
|
|
9
9
|
/** Called by the tile's remove button in single-file edit mode */
|
|
10
10
|
onRemove?: () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Optional override for post-upload rendering of a single-file field.
|
|
13
|
+
* When provided, called instead of renderSingleFileEditTile so the
|
|
14
|
+
* render-edit layer can use the new 220px filled-state container.
|
|
15
|
+
*/
|
|
16
|
+
onAfterUpload?: (container: HTMLElement, rid: string) => void;
|
|
11
17
|
}
|
|
12
18
|
export interface HandleFileSelectOptions {
|
|
13
19
|
file: File;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { MarkdownElement, ComponentContext, ValidationResult } from "../../types/index.js";
|
|
2
|
+
import { renderMarkdown } from "./render.js";
|
|
3
|
+
export { renderMarkdown };
|
|
4
|
+
/**
|
|
5
|
+
* Validate a markdown element.
|
|
6
|
+
* Markdown elements are display-only — they produce no value and no errors.
|
|
7
|
+
* Returning `{ value: undefined, errors: [] }` with the special `skip: true`
|
|
8
|
+
* flag tells the aggregation layer not to include this element in form data.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateMarkdown(_element: MarkdownElement, _key: string, _context: ComponentContext): ValidationResult;
|
|
11
|
+
/**
|
|
12
|
+
* Update handler for markdown elements — noop.
|
|
13
|
+
* Markdown content is static; no programmatic update path is needed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function updateMarkdown(_element: MarkdownElement, _fieldPath: string, _value: unknown, _context: ComponentContext): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { MarkdownElement, RenderContext } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Render a markdown element into the parent container.
|
|
4
|
+
* Returns the created wrapper element.
|
|
5
|
+
*/
|
|
6
|
+
export declare function renderMarkdown(element: MarkdownElement, _ctx: RenderContext, parent: HTMLElement): HTMLElement;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { FormBuilderInstance } from "./instance/FormBuilderInstance.js";
|
|
7
7
|
import { validateSchema } from "./utils/validation.js";
|
|
8
|
-
export type { SelectOption, ElementAction, BaseElement, TextElement, TextareaElement, NumberElement, SelectElement, FileElement, FilesElement, ContainerElement, GroupElement, RichInputElement, Element, Schema, ExternalAction, FormData, RenderContext, Translations, Locale, Config, ResourceMetadata, PickedResource, State, } from "./types/index.js";
|
|
8
|
+
export type { SelectOption, ElementAction, BaseElement, TextElement, TextareaElement, NumberElement, SelectElement, FileElement, FilesElement, ContainerElement, GroupElement, MarkdownElement, RichInputElement, Element, Schema, ExternalAction, FormData, RenderContext, Translations, Locale, Config, ResourceMetadata, PickedResource, State, } from "./types/index.js";
|
|
9
9
|
export type { Theme } from "./styles/theme.js";
|
|
10
10
|
export { defaultTheme, exampleThemes } from "./styles/theme.js";
|
|
11
11
|
/**
|
|
@@ -141,6 +141,16 @@ export declare class FormBuilderInstance {
|
|
|
141
141
|
* Delegates to component-specific updaters via registry
|
|
142
142
|
*/
|
|
143
143
|
private updateFieldValue;
|
|
144
|
+
/**
|
|
145
|
+
* Find the field wrapper DOM element for a given element+path combo.
|
|
146
|
+
* Used by reevaluateConditionalFields.
|
|
147
|
+
*/
|
|
148
|
+
private findFieldWrapper;
|
|
149
|
+
/**
|
|
150
|
+
* Apply enableIf show/hide logic to a single field wrapper.
|
|
151
|
+
* Extracted to reduce cyclomatic complexity of checkElements.
|
|
152
|
+
*/
|
|
153
|
+
private applyEnableIfVisibility;
|
|
144
154
|
/**
|
|
145
155
|
* Re-evaluate all conditional fields (enableIf) based on current form data
|
|
146
156
|
* This is called automatically when form data changes (via onChange events)
|
|
@@ -26,6 +26,11 @@ export interface ValidationResult {
|
|
|
26
26
|
errors: string[];
|
|
27
27
|
/** When true, value is spread into parent data instead of nested under element.key */
|
|
28
28
|
spread?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* When true, this element should be completely excluded from form data output.
|
|
31
|
+
* Used by display-only elements (e.g., markdown) that have no associated value.
|
|
32
|
+
*/
|
|
33
|
+
skip?: boolean;
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
36
|
* Component validator function type
|
|
@@ -38,6 +38,7 @@ export interface Translations {
|
|
|
38
38
|
hintPattern: string;
|
|
39
39
|
fileCountSingle: string;
|
|
40
40
|
fileCountPlural: string;
|
|
41
|
+
fileCountWithMax: string;
|
|
41
42
|
fileCountRange: string;
|
|
42
43
|
uploadingFile: string;
|
|
43
44
|
filesCounter: string;
|
|
@@ -45,6 +46,9 @@ export interface Translations {
|
|
|
45
46
|
libraryEmpty: string;
|
|
46
47
|
libraryHint: string;
|
|
47
48
|
pickerError: string;
|
|
49
|
+
dropToUpload: string;
|
|
50
|
+
replaceFile: string;
|
|
51
|
+
clearAll: string;
|
|
48
52
|
required: string;
|
|
49
53
|
minItems: string;
|
|
50
54
|
maxItems: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { SelectOption, ElementAction, EnableCondition, BaseElement, TextElement, TextareaElement, NumberElement, SelectElement, SwitcherElement, FileElement, FilesElement, ColourElement, SliderElement, ContainerElement, GroupElement, TableElement, TableMerge, TableData, RichInputElement, Element, Schema, ExternalAction, FormData, RenderContext, } from "./schema.js";
|
|
1
|
+
export type { SelectOption, ElementAction, EnableCondition, BaseElement, TextElement, TextareaElement, NumberElement, SelectElement, SwitcherElement, FileElement, FilesElement, ColourElement, SliderElement, ContainerElement, GroupElement, TableElement, TableMerge, TableData, RichInputElement, MarkdownElement, Element, Schema, ExternalAction, FormData, RenderContext, } from "./schema.js";
|
|
2
2
|
export type { Translations, Locale, Config, ResourceMetadata, PickedResource, } from "./config.js";
|
|
3
3
|
export type { State } from "./state.js";
|
|
4
4
|
export type { ComponentContext, ValidationResult, ComponentValidator, ComponentUpdater, ComponentOperations, } from "./component-operations.js";
|
|
@@ -110,6 +110,14 @@ export interface ContainerElement extends BaseElement {
|
|
|
110
110
|
maxCount?: number;
|
|
111
111
|
columns?: 1 | 2 | 3 | 4;
|
|
112
112
|
prefillHints?: PrefillHint[];
|
|
113
|
+
/**
|
|
114
|
+
* How items are arranged when `multiple: true`.
|
|
115
|
+
* - "stack" (default): vertical list, one item per row (current behavior).
|
|
116
|
+
* - "slides": horizontal grid, multiple items per row, auto-wrap.
|
|
117
|
+
* Each item card has min-width 280px and grows to fill available width.
|
|
118
|
+
* Ignored when `multiple: false`.
|
|
119
|
+
*/
|
|
120
|
+
displayMode?: "stack" | "slides";
|
|
113
121
|
}
|
|
114
122
|
export interface ColourElement extends BaseElement {
|
|
115
123
|
type: "colour";
|
|
@@ -186,6 +194,19 @@ export interface TableElement extends BaseElement {
|
|
|
186
194
|
export interface HiddenElement extends BaseElement {
|
|
187
195
|
type: "hidden";
|
|
188
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Markdown display element — renders arbitrary text/headings/lists/links
|
|
199
|
+
* between input fields. Produces no form data entry. `key` is optional
|
|
200
|
+
* (only used as a stable DOM id for enableIf targeting).
|
|
201
|
+
*
|
|
202
|
+
* Extends BaseElement (with key made optional) so that existing code that
|
|
203
|
+
* accesses BaseElement properties on Element union members continues to compile.
|
|
204
|
+
*/
|
|
205
|
+
export interface MarkdownElement extends Omit<BaseElement, "key"> {
|
|
206
|
+
type: "markdown";
|
|
207
|
+
content: string;
|
|
208
|
+
key?: string;
|
|
209
|
+
}
|
|
189
210
|
export interface RichInputElement extends BaseElement {
|
|
190
211
|
type: "richinput";
|
|
191
212
|
placeholder?: string;
|
|
@@ -200,7 +221,7 @@ export interface RichInputElement extends BaseElement {
|
|
|
200
221
|
filesKey?: string;
|
|
201
222
|
flatOutput?: boolean;
|
|
202
223
|
}
|
|
203
|
-
export type Element = TextElement | TextareaElement | NumberElement | SelectElement | SwitcherElement | FileElement | FilesElement | HiddenElement | ColourElement | SliderElement | ContainerElement | GroupElement | TableElement | RichInputElement;
|
|
224
|
+
export type Element = TextElement | TextareaElement | NumberElement | SelectElement | SwitcherElement | FileElement | FilesElement | HiddenElement | ColourElement | SliderElement | ContainerElement | GroupElement | TableElement | RichInputElement | MarkdownElement;
|
|
204
225
|
export interface Schema {
|
|
205
226
|
version?: string;
|
|
206
227
|
elements: Element[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Schema, ExternalAction } from "./schema.js";
|
|
1
|
+
import type { Schema, ExternalAction, Element } from "./schema.js";
|
|
2
2
|
import type { Config, ResourceMetadata } from "./config.js";
|
|
3
3
|
export interface State {
|
|
4
4
|
schema: Schema | null;
|
|
@@ -9,4 +9,8 @@ export interface State {
|
|
|
9
9
|
config: Config;
|
|
10
10
|
debounceTimer: number | null;
|
|
11
11
|
prefill: Record<string, any>;
|
|
12
|
+
/** Stable synthetic IDs for keyless elements (e.g. markdown without a key). WeakMap so elements can be GC'd. */
|
|
13
|
+
syntheticElementIds: WeakMap<Element, string>;
|
|
14
|
+
/** Counter for generating unique synthetic IDs. */
|
|
15
|
+
syntheticElementIdCounter: number;
|
|
12
16
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { State } from "../types/state.js";
|
|
2
|
+
import type { Element } from "../types/schema.js";
|
|
2
3
|
export declare function isElementReadonly(element: {
|
|
3
4
|
readonly?: boolean;
|
|
4
5
|
}, state: State, ctx?: {
|
|
@@ -10,6 +11,19 @@ export declare function isPlainObject(obj: any): obj is Record<string, any>;
|
|
|
10
11
|
* Use when inserting user-controlled or translated content via innerHTML
|
|
11
12
|
*/
|
|
12
13
|
export declare function escapeHtml(text: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Return a stable lookup key for a schema element.
|
|
16
|
+
*
|
|
17
|
+
* For elements that carry a `key`, returns that key directly.
|
|
18
|
+
* For keyless elements (e.g. markdown display blocks), generates and caches a
|
|
19
|
+
* synthetic id in `state.syntheticElementIds` so that the same id is returned
|
|
20
|
+
* on every subsequent call for the same element object. This makes enableIf
|
|
21
|
+
* re-evaluation work correctly for keyless elements.
|
|
22
|
+
*
|
|
23
|
+
* The WeakMap does not prevent GC of the element objects — correct for schema
|
|
24
|
+
* elements that are owned by the caller and may be released after `destroy()`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getElementLookupKey(element: Element, state: State): string;
|
|
13
27
|
export declare function pathJoin(base: string, key: string): string;
|
|
14
28
|
export declare function pretty(obj: any): string;
|
|
15
29
|
export declare function clear(node: HTMLElement): void;
|