@mosaicoo/form-angular 0.6.0 → 0.8.0
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 +19 -0
- package/fesm2022/mosaicoo-form-angular-designer.mjs +573 -82
- package/fesm2022/mosaicoo-form-angular-designer.mjs.map +1 -1
- package/fesm2022/mosaicoo-form-angular.mjs +191 -41
- package/fesm2022/mosaicoo-form-angular.mjs.map +1 -1
- package/package.json +2 -2
- package/types/mosaicoo-form-angular-designer.d.ts +153 -4
- package/types/mosaicoo-form-angular.d.ts +25 -2
|
@@ -83,6 +83,76 @@ interface CatalogGroup {
|
|
|
83
83
|
}
|
|
84
84
|
declare const DEFAULT_CATALOG: CatalogGroup[];
|
|
85
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Reusable blocks: a named node subtree (an address group, a payment panel,
|
|
88
|
+
* a compliance section) that can be dropped into any form. Blocks are plain
|
|
89
|
+
* schema fragments — serializable, portable and free of runtime state.
|
|
90
|
+
*
|
|
91
|
+
* The designer keeps them locally by default; hosts that want blocks shared
|
|
92
|
+
* across users bind `[blocks]` and persist `(blocksChanged)` themselves.
|
|
93
|
+
*/
|
|
94
|
+
interface FormBlock {
|
|
95
|
+
id: string;
|
|
96
|
+
label: string;
|
|
97
|
+
/** Schema subtree; keys are regenerated on insert to stay unique. */
|
|
98
|
+
node: FieldNode;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Every visible string of the designer, so hosts can localize the authoring
|
|
103
|
+
* experience the same way they already localize the runtime. Override
|
|
104
|
+
* partially — unset entries fall back to English.
|
|
105
|
+
*
|
|
106
|
+
* The palette itself is DATA: translate `DEFAULT_CATALOG` (or supply your own
|
|
107
|
+
* groups) and pass it through the `[catalog]` input.
|
|
108
|
+
*/
|
|
109
|
+
interface DesignerLabels {
|
|
110
|
+
undo: string;
|
|
111
|
+
redo: string;
|
|
112
|
+
moveUp: string;
|
|
113
|
+
moveDown: string;
|
|
114
|
+
duplicate: string;
|
|
115
|
+
delete: string;
|
|
116
|
+
saveBlock: string;
|
|
117
|
+
workspace: string;
|
|
118
|
+
panels: string;
|
|
119
|
+
presets: string;
|
|
120
|
+
resetLayout: string;
|
|
121
|
+
moveLeft: string;
|
|
122
|
+
moveRight: string;
|
|
123
|
+
hidePanel: string;
|
|
124
|
+
import: string;
|
|
125
|
+
export: string;
|
|
126
|
+
preview: string;
|
|
127
|
+
design: string;
|
|
128
|
+
cancel: string;
|
|
129
|
+
close: string;
|
|
130
|
+
importTitle: string;
|
|
131
|
+
importPlaceholder: string;
|
|
132
|
+
importError: string;
|
|
133
|
+
exportTitle: string;
|
|
134
|
+
canvasEmpty: string;
|
|
135
|
+
selectField: string;
|
|
136
|
+
testData: string;
|
|
137
|
+
panelFields: string;
|
|
138
|
+
panelStructure: string;
|
|
139
|
+
panelProperties: string;
|
|
140
|
+
noFields: string;
|
|
141
|
+
}
|
|
142
|
+
declare const DESIGNER_LABELS_EN: DesignerLabels;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Drop-target identity shared by the canvas and the node components.
|
|
146
|
+
* A target is a position in a parent's children list, optionally bound to a
|
|
147
|
+
* column of a `columns` container.
|
|
148
|
+
*/
|
|
149
|
+
interface DropTarget {
|
|
150
|
+
path: NodePath;
|
|
151
|
+
/** Column index when the parent lays children out in columns. */
|
|
152
|
+
column?: number;
|
|
153
|
+
}
|
|
154
|
+
declare function dropId(target: DropTarget): string;
|
|
155
|
+
|
|
86
156
|
/**
|
|
87
157
|
* Designer workspace layout.
|
|
88
158
|
*
|
|
@@ -126,6 +196,42 @@ declare class FormDesignerComponent {
|
|
|
126
196
|
readonly source: _angular_core.InputSignal<unknown>;
|
|
127
197
|
/** Extra palette groups contributed by the host. */
|
|
128
198
|
readonly extraCatalog: _angular_core.InputSignal<CatalogGroup[]>;
|
|
199
|
+
/** Replaces the built-in palette (e.g. a translated DEFAULT_CATALOG). */
|
|
200
|
+
readonly catalogOverride: _angular_core.InputSignal<CatalogGroup[] | null>;
|
|
201
|
+
/** Designer texts; partial overrides fall back to English. */
|
|
202
|
+
readonly labels: _angular_core.InputSignalWithTransform<{
|
|
203
|
+
undo: string;
|
|
204
|
+
redo: string;
|
|
205
|
+
moveUp: string;
|
|
206
|
+
moveDown: string;
|
|
207
|
+
duplicate: string;
|
|
208
|
+
delete: string;
|
|
209
|
+
saveBlock: string;
|
|
210
|
+
workspace: string;
|
|
211
|
+
panels: string;
|
|
212
|
+
presets: string;
|
|
213
|
+
resetLayout: string;
|
|
214
|
+
moveLeft: string;
|
|
215
|
+
moveRight: string;
|
|
216
|
+
hidePanel: string;
|
|
217
|
+
import: string;
|
|
218
|
+
export: string;
|
|
219
|
+
preview: string;
|
|
220
|
+
design: string;
|
|
221
|
+
cancel: string;
|
|
222
|
+
close: string;
|
|
223
|
+
importTitle: string;
|
|
224
|
+
importPlaceholder: string;
|
|
225
|
+
importError: string;
|
|
226
|
+
exportTitle: string;
|
|
227
|
+
canvasEmpty: string;
|
|
228
|
+
selectField: string;
|
|
229
|
+
testData: string;
|
|
230
|
+
panelFields: string;
|
|
231
|
+
panelStructure: string;
|
|
232
|
+
panelProperties: string;
|
|
233
|
+
noFields: string;
|
|
234
|
+
}, Partial<DesignerLabels>>;
|
|
129
235
|
/** Emitted after every committed edit (undo/redo included). */
|
|
130
236
|
readonly schemaChanged: _angular_core.OutputEmitterRef<FormSchema>;
|
|
131
237
|
readonly draft: _angular_core.WritableSignal<FormSchema>;
|
|
@@ -155,8 +261,19 @@ declare class FormDesignerComponent {
|
|
|
155
261
|
dock(panel: PanelId, side: DockSide): void;
|
|
156
262
|
applyPreset(id: string): void;
|
|
157
263
|
resetLayout(): void;
|
|
264
|
+
/** Live drag state of a dock splitter. */
|
|
265
|
+
private resizing;
|
|
266
|
+
startResize(side: 'left' | 'right', event: PointerEvent): void;
|
|
267
|
+
onResizeMove(event: PointerEvent): void;
|
|
268
|
+
endResize(): void;
|
|
158
269
|
isGroupOpen(label: string): boolean;
|
|
159
270
|
toggleGroup(label: string): void;
|
|
271
|
+
/** Saved blocks (host-controlled when `[blocks]` is bound). */
|
|
272
|
+
readonly blocks: _angular_core.InputSignal<FormBlock[] | null>;
|
|
273
|
+
readonly blocksChanged: _angular_core.OutputEmitterRef<FormBlock[]>;
|
|
274
|
+
private readonly localBlocks;
|
|
275
|
+
readonly effectiveBlocks: _angular_core.Signal<FormBlock[]>;
|
|
276
|
+
/** Palette = built-ins + host extras + saved blocks as a group. */
|
|
160
277
|
readonly catalog: _angular_core.Signal<CatalogGroup[]>;
|
|
161
278
|
readonly diagnostics: _angular_core.Signal<SchemaDiagnostic[]>;
|
|
162
279
|
readonly exportedJson: _angular_core.Signal<string>;
|
|
@@ -181,13 +298,30 @@ declare class FormDesignerComponent {
|
|
|
181
298
|
duplicateSelected(): void;
|
|
182
299
|
moveSelected(delta: -1 | 1): void;
|
|
183
300
|
applyPatch(event: InspectorPatch): void;
|
|
301
|
+
/** Saves the selected node (with its subtree) as a reusable block. */
|
|
302
|
+
saveAsBlock(): void;
|
|
303
|
+
removeBlock(id: string): void;
|
|
304
|
+
isBlockEntry(entry: CatalogEntry): boolean;
|
|
305
|
+
blockIdOf(entry: CatalogEntry): string;
|
|
306
|
+
/** What is being dragged: a palette entry or an existing node. */
|
|
307
|
+
private readonly dragging;
|
|
308
|
+
/** Drop zone highlighted while hovering (see `dropId`). */
|
|
309
|
+
readonly dropTarget: _angular_core.WritableSignal<string | null>;
|
|
310
|
+
startEntryDrag(entry: CatalogEntry, event: DragEvent): void;
|
|
311
|
+
startNodeDrag(path: NodePath, event?: DragEvent): void;
|
|
312
|
+
endDrag(): void;
|
|
313
|
+
allowDrop(target: DropTarget, event?: DragEvent): void;
|
|
314
|
+
/** Drops onto `target` — the position (and column) the node should occupy. */
|
|
315
|
+
drop(target: DropTarget, event?: DragEvent): void;
|
|
316
|
+
isDropTarget(target: DropTarget): boolean;
|
|
317
|
+
isDragging(): boolean;
|
|
184
318
|
select(path: NodePath | null): void;
|
|
185
319
|
isSelectedPath(path: NodePath): boolean;
|
|
186
320
|
openExport(): void;
|
|
187
321
|
doImport(raw: string): void;
|
|
188
322
|
onKeydown(event: KeyboardEvent): void;
|
|
189
323
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormDesignerComponent, never>;
|
|
190
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormDesignerComponent, "mform-designer", never, { "schema": { "alias": "schema"; "required": false; "isSignal": true; }; "source": { "alias": "source"; "required": false; "isSignal": true; }; "extraCatalog": { "alias": "extraCatalog"; "required": false; "isSignal": true; }; }, { "schemaChanged": "schemaChanged"; }, never, never, true, never>;
|
|
324
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormDesignerComponent, "mform-designer", never, { "schema": { "alias": "schema"; "required": false; "isSignal": true; }; "source": { "alias": "source"; "required": false; "isSignal": true; }; "extraCatalog": { "alias": "extraCatalog"; "required": false; "isSignal": true; }; "catalogOverride": { "alias": "catalog"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; "blocks": { "alias": "blocks"; "required": false; "isSignal": true; }; }, { "schemaChanged": "schemaChanged"; "blocksChanged": "blocksChanged"; }, never, never, true, never>;
|
|
191
325
|
}
|
|
192
326
|
|
|
193
327
|
/**
|
|
@@ -195,13 +329,24 @@ declare class FormDesignerComponent {
|
|
|
195
329
|
* leaf rendering to the RUNTIME `<mform-node>` so what you see is what the
|
|
196
330
|
* renderer will produce. Canvas controls are non-interactive — testing
|
|
197
331
|
* happens in Preview mode.
|
|
332
|
+
*
|
|
333
|
+
* Drop zones sit between children (and inside each column), so fields can be
|
|
334
|
+
* dragged INTO containers, not just reordered at the root.
|
|
198
335
|
*/
|
|
199
336
|
declare class DesignerNodeComponent {
|
|
200
337
|
readonly node: _angular_core.InputSignal<FieldNode>;
|
|
201
338
|
readonly path: _angular_core.InputSignal<NodePath>;
|
|
202
339
|
readonly engine: _angular_core.InputSignal<FormEngine>;
|
|
203
340
|
readonly selected: _angular_core.InputSignal<NodePath | null>;
|
|
341
|
+
/** True while something is being dragged (reveals the drop zones). */
|
|
342
|
+
readonly dragging: _angular_core.InputSignal<boolean>;
|
|
343
|
+
/** Id of the drop zone currently hovered. */
|
|
344
|
+
readonly activeDrop: _angular_core.InputSignal<string | null>;
|
|
204
345
|
readonly selectNode: _angular_core.OutputEmitterRef<NodePath>;
|
|
346
|
+
readonly nodeDragStart: _angular_core.OutputEmitterRef<NodePath>;
|
|
347
|
+
readonly dragOverTarget: _angular_core.OutputEmitterRef<DropTarget>;
|
|
348
|
+
readonly dropOnTarget: _angular_core.OutputEmitterRef<DropTarget>;
|
|
349
|
+
readonly dragFinished: _angular_core.OutputEmitterRef<void>;
|
|
205
350
|
readonly activeTab: _angular_core.WritableSignal<number>;
|
|
206
351
|
container(): ContainerField;
|
|
207
352
|
chip(): string;
|
|
@@ -210,9 +355,13 @@ declare class DesignerNodeComponent {
|
|
|
210
355
|
columnsTemplate(): string;
|
|
211
356
|
onSelect(event: Event): void;
|
|
212
357
|
setTab(index: number, event: Event): void;
|
|
358
|
+
isOver(path: NodePath, column?: number): boolean;
|
|
359
|
+
onDragStart(path: NodePath, event: Event): void;
|
|
360
|
+
onDragOver(path: NodePath, column: number | undefined, event: DragEvent): void;
|
|
361
|
+
onDrop(path: NodePath, column: number | undefined, event: DragEvent): void;
|
|
213
362
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DesignerNodeComponent, never>;
|
|
214
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DesignerNodeComponent, "mform-designer-node", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; "path": { "alias": "path"; "required": true; "isSignal": true; }; "engine": { "alias": "engine"; "required": true; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; }, { "selectNode": "selectNode"; }, never, never, true, never>;
|
|
363
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DesignerNodeComponent, "mform-designer-node", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; "path": { "alias": "path"; "required": true; "isSignal": true; }; "engine": { "alias": "engine"; "required": true; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "dragging": { "alias": "dragging"; "required": false; "isSignal": true; }; "activeDrop": { "alias": "activeDrop"; "required": false; "isSignal": true; }; }, { "selectNode": "selectNode"; "nodeDragStart": "nodeDragStart"; "dragOverTarget": "dragOverTarget"; "dropOnTarget": "dropOnTarget"; "dragFinished": "dragFinished"; }, never, never, true, never>;
|
|
215
364
|
}
|
|
216
365
|
|
|
217
|
-
export { DEFAULT_CATALOG, DEFAULT_LAYOUT, DesignerNodeComponent, FormDesignerComponent, InspectorComponent, PANEL_LABELS, WORKSPACE_PRESETS };
|
|
218
|
-
export type { CatalogEntry, CatalogGroup, DockSide, InspectorPatch, PanelId, WorkspaceLayout, WorkspacePreset };
|
|
366
|
+
export { DEFAULT_CATALOG, DEFAULT_LAYOUT, DESIGNER_LABELS_EN, DesignerNodeComponent, FormDesignerComponent, InspectorComponent, PANEL_LABELS, WORKSPACE_PRESETS, dropId };
|
|
367
|
+
export type { CatalogEntry, CatalogGroup, DesignerLabels, DockSide, DropTarget, FormBlock, InspectorPatch, PanelId, WorkspaceLayout, WorkspacePreset };
|
|
@@ -72,11 +72,21 @@ declare class FormNodeComponent {
|
|
|
72
72
|
readonly childScope: _angular_core.Signal<string>;
|
|
73
73
|
rowScope(index: number): string;
|
|
74
74
|
visible(): boolean;
|
|
75
|
-
containerLayout(): 'columns' | 'tabs' | 'array' | 'block';
|
|
75
|
+
containerLayout(): 'columns' | 'tabs' | 'accordion' | 'array' | 'block';
|
|
76
|
+
/** Open accordion sections; the first one starts expanded. */
|
|
77
|
+
private readonly openSections;
|
|
78
|
+
isSectionOpen(index: number): boolean;
|
|
79
|
+
toggleSection(index: number): void;
|
|
76
80
|
columns(): FieldNode[][];
|
|
77
81
|
columnsTemplate(): string;
|
|
78
82
|
value(): unknown;
|
|
79
83
|
stringValue(): string;
|
|
84
|
+
/** Tracks focus so numeric formatting steps aside during typing. */
|
|
85
|
+
readonly focused: _angular_core.WritableSignal<boolean>;
|
|
86
|
+
onFocus(): void;
|
|
87
|
+
onBlur(): void;
|
|
88
|
+
/** Numeric inputs stay `text` when formatted (a number input rejects `R$`). */
|
|
89
|
+
numericFormatted(): boolean;
|
|
80
90
|
mapValue(): Record<string, unknown>;
|
|
81
91
|
rows(): unknown[];
|
|
82
92
|
required(): boolean;
|
|
@@ -113,6 +123,15 @@ declare class FormNodeComponent {
|
|
|
113
123
|
private refTimer;
|
|
114
124
|
/** Label of the chosen option (falls back to the raw value). */
|
|
115
125
|
readonly refLabel: _angular_core.WritableSignal<string | null>;
|
|
126
|
+
/** Last query typed, replayed when `refreshOn` invalidates the results. */
|
|
127
|
+
private refQuery;
|
|
128
|
+
private refRefreshKey;
|
|
129
|
+
/**
|
|
130
|
+
* `refreshOn` for autocomplete: when the observed data changes, cached
|
|
131
|
+
* results are dropped so the next search runs against the new context
|
|
132
|
+
* (e.g. properties filtered by the selected client).
|
|
133
|
+
*/
|
|
134
|
+
private watchReferenceRefresh;
|
|
116
135
|
refDisplay(): string;
|
|
117
136
|
refSearch(event: Event): void;
|
|
118
137
|
private refResolve;
|
|
@@ -192,7 +211,11 @@ declare class FormRendererComponent {
|
|
|
192
211
|
readonly errorSummary: _angular_core.WritableSignal<FieldError[]>;
|
|
193
212
|
constructor();
|
|
194
213
|
previousStep(): void;
|
|
195
|
-
|
|
214
|
+
/**
|
|
215
|
+
* Advances only when the step is valid INCLUDING async rules, so a
|
|
216
|
+
* server-side check can still block the transition.
|
|
217
|
+
*/
|
|
218
|
+
nextStep(): Promise<void>;
|
|
196
219
|
onSubmit(event: Event): Promise<void>;
|
|
197
220
|
/** Finds the wizard step that owns a (possibly row-indexed) data path. */
|
|
198
221
|
private stepIndexForPath;
|