@dmitryvim/form-builder 0.2.29 → 0.2.30

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.
@@ -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;
@@ -0,0 +1,2 @@
1
+ /** Parse Markdown into an HTML String. */
2
+ export default function parse(md: string, prevLinks?: Record<string, string>): string;
@@ -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
@@ -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";
@@ -186,6 +186,19 @@ export interface TableElement extends BaseElement {
186
186
  export interface HiddenElement extends BaseElement {
187
187
  type: "hidden";
188
188
  }
189
+ /**
190
+ * Markdown display element — renders arbitrary text/headings/lists/links
191
+ * between input fields. Produces no form data entry. `key` is optional
192
+ * (only used as a stable DOM id for enableIf targeting).
193
+ *
194
+ * Extends BaseElement (with key made optional) so that existing code that
195
+ * accesses BaseElement properties on Element union members continues to compile.
196
+ */
197
+ export interface MarkdownElement extends Omit<BaseElement, "key"> {
198
+ type: "markdown";
199
+ content: string;
200
+ key?: string;
201
+ }
189
202
  export interface RichInputElement extends BaseElement {
190
203
  type: "richinput";
191
204
  placeholder?: string;
@@ -200,7 +213,7 @@ export interface RichInputElement extends BaseElement {
200
213
  filesKey?: string;
201
214
  flatOutput?: boolean;
202
215
  }
203
- export type Element = TextElement | TextareaElement | NumberElement | SelectElement | SwitcherElement | FileElement | FilesElement | HiddenElement | ColourElement | SliderElement | ContainerElement | GroupElement | TableElement | RichInputElement;
216
+ export type Element = TextElement | TextareaElement | NumberElement | SelectElement | SwitcherElement | FileElement | FilesElement | HiddenElement | ColourElement | SliderElement | ContainerElement | GroupElement | TableElement | RichInputElement | MarkdownElement;
204
217
  export interface Schema {
205
218
  version?: string;
206
219
  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;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.2.29",
6
+ "version": "0.2.30",
7
7
  "description": "A reusable JSON schema form builder library",
8
8
  "main": "./dist/cjs/index.cjs",
9
9
  "module": "./dist/esm/index.js",