@mosaicoo/form-angular 0.8.0 → 0.9.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 CHANGED
@@ -85,6 +85,14 @@ overrides fall back to English); translate the palette by passing your own
85
85
  **Resizable docks** — drag the splitter between a panel rail and the canvas;
86
86
  widths persist with the layout.
87
87
 
88
+ **Keyboard** — Ctrl+Z/Y undo/redo, Ctrl+D duplicate, Del delete, Alt+↑/↓ move,
89
+ **Alt+→ nest into the container above**, **Alt+← move out of it**, Esc clears
90
+ the selection.
91
+
92
+ **Responsive preview** — preview at desktop, tablet or mobile width. Layout
93
+ reacts to the FORM's own width (CSS container queries), so a form inside a
94
+ narrow drawer stacks its columns even on a wide screen.
95
+
88
96
  **Reusable blocks** — save any subtree as a named block and drop it into other
89
97
  forms (keys are regenerated). Blocks persist locally by default; bind
90
98
  `[blocks]` / `(blocksChanged)` to store them wherever your platform keeps
@@ -1171,11 +1171,14 @@ function saveBlocks(storage, blocks) {
1171
1171
  const DESIGNER_LABELS_EN = {
1172
1172
  undo: 'Undo (Ctrl+Z)',
1173
1173
  redo: 'Redo (Ctrl+Y)',
1174
- moveUp: 'Move up',
1175
- moveDown: 'Move down',
1174
+ moveUp: 'Move up (Alt+↑)',
1175
+ moveDown: 'Move down (Alt+↓)',
1176
+ nest: 'Nest into the container above (Alt+→)',
1177
+ unnest: 'Move out of the container (Alt+←)',
1176
1178
  duplicate: 'Duplicate (Ctrl+D)',
1177
1179
  delete: 'Delete (Del)',
1178
1180
  saveBlock: 'Save as reusable block',
1181
+ viewport: 'Preview width',
1179
1182
  workspace: 'Workspace',
1180
1183
  panels: 'Panels',
1181
1184
  presets: 'Presets',
@@ -1324,6 +1327,16 @@ class FormDesignerComponent {
1324
1327
  selected = signal(null, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
1325
1328
  preview = signal(false, ...(ngDevMode ? [{ debugName: "preview" }] : /* istanbul ignore next */ []));
1326
1329
  previewData = signal({}, ...(ngDevMode ? [{ debugName: "previewData" }] : /* istanbul ignore next */ []));
1330
+ /** Preview viewport: the frame drives the form's container queries. */
1331
+ viewport = signal('desktop', ...(ngDevMode ? [{ debugName: "viewport" }] : /* istanbul ignore next */ []));
1332
+ viewports = [
1333
+ { id: 'desktop', label: 'Desktop', icon: '🖥', width: null },
1334
+ { id: 'tablet', label: 'Tablet', icon: '▭', width: 768 },
1335
+ { id: 'mobile', label: 'Mobile', icon: '▯', width: 375 },
1336
+ ];
1337
+ viewportWidth() {
1338
+ return this.viewports.find((option) => option.id === this.viewport())?.width ?? null;
1339
+ }
1327
1340
  dialog = signal(null, ...(ngDevMode ? [{ debugName: "dialog" }] : /* istanbul ignore next */ []));
1328
1341
  importError = signal('', ...(ngDevMode ? [{ debugName: "importError" }] : /* istanbul ignore next */ []));
1329
1342
  showDiagnostics = signal(false, ...(ngDevMode ? [{ debugName: "showDiagnostics" }] : /* istanbul ignore next */ []));
@@ -1587,6 +1600,49 @@ class FormDesignerComponent {
1587
1600
  return;
1588
1601
  this.commit(updateNode(this.draft(), selected, event.patch));
1589
1602
  }
1603
+ /** Whether the selection can be nested into the container above it. */
1604
+ canNest() {
1605
+ const selected = this.selected();
1606
+ if (!selected)
1607
+ return false;
1608
+ const { parent, index } = parentOf(selected);
1609
+ if (index === 0)
1610
+ return false;
1611
+ return getNodeAt(this.draft(), [...parent, index - 1])?.kind === 'container';
1612
+ }
1613
+ canUnnest() {
1614
+ return (this.selected()?.length ?? 0) > 1;
1615
+ }
1616
+ /**
1617
+ * Nests the selection into the container right above it (Alt+→) — the
1618
+ * keyboard equivalent of dragging a field into a panel.
1619
+ */
1620
+ nestSelected() {
1621
+ const selected = this.selected();
1622
+ if (!selected)
1623
+ return;
1624
+ const { parent, index } = parentOf(selected);
1625
+ if (index === 0)
1626
+ return;
1627
+ const previous = getNodeAt(this.draft(), [...parent, index - 1]);
1628
+ if (!previous || previous.kind !== 'container')
1629
+ return;
1630
+ // after the removal the container keeps its position (it sits before)
1631
+ const target = [...parent, index - 1, previous.children.length];
1632
+ this.commit(moveNode(this.draft(), selected, target));
1633
+ this.select(target);
1634
+ }
1635
+ /** Moves the selection out of its container, right after it (Alt+←). */
1636
+ unnestSelected() {
1637
+ const selected = this.selected();
1638
+ if (!selected || selected.length < 2)
1639
+ return;
1640
+ const { parent } = parentOf(selected);
1641
+ const { parent: grandparent, index: parentIndex } = parentOf(parent);
1642
+ const target = [...grandparent, parentIndex + 1];
1643
+ this.commit(moveNode(this.draft(), selected, target));
1644
+ this.select(target);
1645
+ }
1590
1646
  // -- reusable blocks ------------------------------------------------------
1591
1647
  /** Saves the selected node (with its subtree) as a reusable block. */
1592
1648
  saveAsBlock() {
@@ -1723,6 +1779,28 @@ class FormDesignerComponent {
1723
1779
  event.preventDefault();
1724
1780
  this.removeSelected();
1725
1781
  }
1782
+ else if (key === 'escape') {
1783
+ event.preventDefault();
1784
+ this.workspaceMenu.set(false);
1785
+ this.dialog.set(null);
1786
+ this.select(null);
1787
+ }
1788
+ else if (event.altKey && key === 'arrowup') {
1789
+ event.preventDefault();
1790
+ this.moveSelected(-1);
1791
+ }
1792
+ else if (event.altKey && key === 'arrowdown') {
1793
+ event.preventDefault();
1794
+ this.moveSelected(1);
1795
+ }
1796
+ else if (event.altKey && key === 'arrowright') {
1797
+ event.preventDefault();
1798
+ this.nestSelected();
1799
+ }
1800
+ else if (event.altKey && key === 'arrowleft') {
1801
+ event.preventDefault();
1802
+ this.unnestSelected();
1803
+ }
1726
1804
  }
1727
1805
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: FormDesignerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1728
1806
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: FormDesignerComponent, isStandalone: true, selector: "mform-designer", inputs: { schema: { classPropertyName: "schema", publicName: "schema", isSignal: true, isRequired: false, transformFunction: null }, source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, extraCatalog: { classPropertyName: "extraCatalog", publicName: "extraCatalog", isSignal: true, isRequired: false, transformFunction: null }, catalogOverride: { classPropertyName: "catalogOverride", publicName: "catalog", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, blocks: { classPropertyName: "blocks", publicName: "blocks", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { schemaChanged: "schemaChanged", blocksChanged: "blocksChanged" }, ngImport: i0, template: `
@@ -1734,6 +1812,8 @@ class FormDesignerComponent {
1734
1812
  <span class="dz-sep"></span>
1735
1813
  <button type="button" (click)="moveSelected(-1)" [disabled]="!selected()" [title]="labels().moveUp">↑</button>
1736
1814
  <button type="button" (click)="moveSelected(1)" [disabled]="!selected()" [title]="labels().moveDown">↓</button>
1815
+ <button type="button" (click)="unnestSelected()" [disabled]="!canUnnest()" [title]="labels().unnest">⇤</button>
1816
+ <button type="button" (click)="nestSelected()" [disabled]="!canNest()" [title]="labels().nest">⇥</button>
1737
1817
  <button type="button" (click)="duplicateSelected()" [disabled]="!selected()" [title]="labels().duplicate">⧉</button>
1738
1818
  <button type="button" (click)="removeSelected()" [disabled]="!selected()" [title]="labels().delete">🗑</button>
1739
1819
  <button type="button" (click)="saveAsBlock()" [disabled]="!selected()" [title]="labels().saveBlock">⊞</button>
@@ -1818,7 +1898,23 @@ class FormDesignerComponent {
1818
1898
 
1819
1899
  @if (preview()) {
1820
1900
  <div class="dz-preview">
1821
- <mform-renderer [schema]="draft()" (valueChanged)="previewData.set($event)" />
1901
+ <div class="dz-viewports" role="group" [attr.aria-label]="labels().viewport">
1902
+ @for (option of viewports; track option.id) {
1903
+ <button
1904
+ type="button"
1905
+ [class.is-on]="viewport() === option.id"
1906
+ (click)="viewport.set(option.id)"
1907
+ [title]="option.width ? option.label + ' · ' + option.width + 'px' : option.label"
1908
+ >{{ option.icon }} {{ option.label }}</button>
1909
+ }
1910
+ </div>
1911
+ <div
1912
+ class="dz-preview-frame"
1913
+ [class.is-constrained]="viewportWidth() !== null"
1914
+ [style.max-width.px]="viewportWidth()"
1915
+ >
1916
+ <mform-renderer [schema]="draft()" (valueChanged)="previewData.set($event)" />
1917
+ </div>
1822
1918
  <details class="dz-preview-data">
1823
1919
  <summary>{{ labels().testData }}</summary>
1824
1920
  <pre>{{ previewData() | json }}</pre>
@@ -1993,7 +2089,7 @@ class FormDesignerComponent {
1993
2089
  </div>
1994
2090
  </section>
1995
2091
  </ng-template>
1996
- `, isInline: true, styles: [".dz-shell{display:flex;flex-direction:column;height:100%;min-height:480px;font-family:var(--mform-font, system-ui, \"Segoe UI\", sans-serif);color:var(--mform-text, #1f1b2e);background:var(--mform-bg, #f6f5fa);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);overflow:hidden}.dz-toolbar{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:8px 12px;background:var(--mform-surface, #fff);border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-tools{display:flex;align-items:center;gap:6px}.dz-toolbar button{font:inherit;font-size:13px;padding:6px 10px;border:1px solid transparent;border-radius:8px;background:none;color:inherit;cursor:pointer}.dz-toolbar button:hover:not(:disabled){background:var(--mform-bg, #f6f5fa)}.dz-toolbar button:disabled{opacity:.35;cursor:default}.dz-toolbar .dz-primary{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.dz-sep{width:1px;height:18px;background:var(--mform-border, #d9d5e6)}.dz-diag-badge{color:#b45309;font-weight:600}.dz-diagnostics{max-height:140px;overflow-y:auto;padding:8px 14px;background:#fdf5ef;border-bottom:1px solid var(--mform-border, #d9d5e6);font-size:12px}.dz-diag{padding:2px 0;color:#9a3412}.dz-diag.is-warning{color:#92400e}.dz-diag code{font-weight:600;margin-right:6px}.dz-diag em{color:var(--mform-muted, #6b6580);margin-left:6px}.dz-dialog{padding:14px;background:var(--mform-surface, #fff);border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-dialog h4{margin:0 0 8px;font-size:13px}.dz-dialog textarea{width:100%;font-family:ui-monospace,Consolas,monospace;font-size:12px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;padding:10px;box-sizing:border-box;resize:vertical}.dz-dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}.dz-dialog-actions button{font:inherit;font-size:13px;padding:7px 14px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;background:none;cursor:pointer}.dz-dialog-actions .dz-primary{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border-color:transparent}.dz-import-error{color:var(--mform-danger, #c62842);font-size:12px}.dz-body{display:grid;flex:1;min-height:0}.dz-dock{display:flex;flex-direction:column;min-height:0;overflow-y:auto;background:var(--mform-surface, #fff)}.dz-dock-left{border-right:1px solid var(--mform-border, #d9d5e6);position:relative}.dz-dock-right{border-left:1px solid var(--mform-border, #d9d5e6);position:relative}.dz-splitter{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;touch-action:none;z-index:2}.dz-splitter-left{right:-3px}.dz-splitter-right{left:-3px}.dz-splitter:hover,.dz-splitter:active{background:var(--mform-primary, #6d4bd0);opacity:.35}.dz-panel{display:flex;flex-direction:column;border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-panel:last-child{border-bottom:none;flex:1}.dz-panel-head{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--mform-muted, #6b6580);background:var(--mform-bg, #f6f5fa);position:sticky;top:0;z-index:1}.dz-panel-actions{display:flex;gap:2px;opacity:0;transition:opacity .12s}.dz-panel:hover .dz-panel-actions,.dz-panel:focus-within .dz-panel-actions{opacity:1}.dz-panel-actions button{border:none;background:none;color:inherit;cursor:pointer;font-size:11px;padding:2px 4px;border-radius:4px}.dz-panel-actions button:hover{background:var(--mform-surface, #fff)}.dz-panel-body{padding:10px}.dz-menu{position:relative}.dz-menu-panel{position:absolute;top:calc(100% + 6px);right:0;z-index:20;min-width:260px;padding:8px;background:var(--mform-surface, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);box-shadow:0 10px 30px #1f1b2e26}.dz-menu-title{display:block;font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--mform-muted, #6b6580);padding:6px 6px 4px}.dz-menu-row{display:flex;align-items:center;justify-content:space-between;padding:4px 6px;font-size:13px}.dz-seg{display:flex;gap:2px}.dz-seg button{border:1px solid var(--mform-border, #d9d5e6);background:none;color:var(--mform-muted, #6b6580);border-radius:6px;font-size:11px;padding:3px 8px;cursor:pointer}.dz-seg button.is-on{background:var(--mform-primary, #6d4bd0);border-color:transparent;color:var(--mform-primary-contrast, #fff)}.dz-menu-item{display:block;width:100%;text-align:left;font:inherit;font-size:13px;padding:6px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.dz-menu-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-group{margin-bottom:4px}.dz-group-toggle{display:flex;align-items:center;gap:6px;width:100%;font:inherit;font-size:12px;font-weight:600;text-align:left;padding:6px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.dz-group-toggle:hover{background:var(--mform-bg, #f6f5fa)}.dz-caret{font-size:10px;color:var(--mform-muted, #6b6580);width:10px}.dz-group-count{margin-left:auto;font-size:10px;font-weight:400;color:var(--mform-muted, #6b6580);background:var(--mform-bg, #f6f5fa);border-radius:999px;padding:1px 7px}.dz-group-entries{display:flex;flex-direction:column;gap:2px;margin:2px 0 6px 10px}.dz-palette-item{display:flex;align-items:center;gap:8px;font:inherit;font-size:13px;text-align:left;padding:6px 8px;border:none;border-radius:8px;background:none;color:inherit;cursor:pointer}.dz-palette-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-icon{width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--mform-border, #d9d5e6);border-radius:6px;font-size:11px}.dz-tree{display:flex;flex-direction:column;gap:1px}.dz-tree-item{font:inherit;font-size:12px;text-align:left;padding:4px 8px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dz-tree-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-tree-item.is-selected{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.dz-canvas{padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:10px}.dz-canvas-empty,.dz-empty{color:var(--mform-muted, #6b6580);font-size:13px;border:1px dashed var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:18px;text-align:center}.dz-dropzone{height:4px;border-radius:999px;transition:height .1s,background .1s}.dz-canvas.is-dragging .dz-dropzone{height:14px;background:repeating-linear-gradient(90deg,var(--mform-border, #d9d5e6) 0 6px,transparent 6px 12px)}.dz-canvas.is-dragging .dz-dropzone.is-over{height:22px;background:var(--mform-primary, #6d4bd0)}.dz-palette-row{display:flex;align-items:center;gap:2px}.dz-palette-row .dz-palette-item{flex:1;cursor:grab}.dz-block-remove{border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer;font-size:11px;padding:2px 4px;opacity:0}.dz-palette-row:hover .dz-block-remove{opacity:1}.dz-node{position:relative;border:1px solid transparent;border-radius:var(--mform-radius, 10px);padding:20px 10px 10px;cursor:pointer;background:var(--mform-surface, #fff)}.dz-node:hover{border-color:var(--mform-border, #d9d5e6)}.dz-node.is-selected{border-color:var(--mform-primary, #6d4bd0);box-shadow:0 0 0 1px var(--mform-primary, #6d4bd0)}.dz-chip{position:absolute;top:2px;left:10px;font-size:10px;color:var(--mform-muted, #6b6580);pointer-events:none}.dz-node.is-selected>.dz-chip{color:var(--mform-primary, #6d4bd0);font-weight:600}.dz-children{display:flex;flex-direction:column;gap:8px}.dz-columns{display:grid;gap:10px}.dz-column{display:flex;flex-direction:column;gap:8px;border:1px dashed var(--mform-border, #d9d5e6);border-radius:8px;padding:8px;min-height:40px}.dz-tabbar{display:flex;gap:4px;margin-bottom:8px;border-bottom:2px solid var(--mform-border, #d9d5e6)}.dz-tab{font:inherit;font-size:12px;padding:5px 12px;border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer}.dz-tab.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600;border-bottom:2px solid var(--mform-primary, #6d4bd0);margin-bottom:-2px}.dz-leaf{pointer-events:none}.dz-props-empty{margin:4px 0}.dz-inspector{display:flex;flex-direction:column;gap:10px}.dz-inspector h3{margin:0;font-size:13px}.dz-inspector h3 code{color:var(--mform-muted, #6b6580);font-weight:400}.dz-prop{display:flex;flex-direction:column;gap:4px;font-size:12px}.dz-prop span{color:var(--mform-muted, #6b6580)}.dz-prop input,.dz-prop select,.dz-prop textarea{font:inherit;font-size:13px;padding:7px 9px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;background:#fff;width:100%;box-sizing:border-box}.dz-check{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer}.dz-check input{accent-color:var(--mform-primary, #6d4bd0)}.dz-section{border-top:1px solid var(--mform-border, #d9d5e6);padding-top:8px}.dz-section summary{font-size:12px;font-weight:600;cursor:pointer;margin-bottom:8px}.dz-section .dz-prop{margin-bottom:8px}.dz-option-row{display:flex;gap:6px;margin-bottom:6px}.dz-option-row input{flex:1;min-width:0;font-size:12px;padding:6px 8px;border:1px solid var(--mform-border, #d9d5e6);border-radius:6px}.dz-option-row button{border:none;background:none;cursor:pointer;color:var(--mform-muted, #6b6580)}.dz-add{font:inherit;font-size:12px;border:1px dashed var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0);background:none;border-radius:8px;padding:6px 10px;cursor:pointer}.dz-preview{padding:20px;overflow-y:auto}.dz-preview-data{margin-top:16px;font-size:12px}.dz-preview-data pre{background:var(--mform-surface, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;padding:10px;overflow-x:auto}\n"], dependencies: [{ kind: "component", type: DesignerNodeComponent, selector: "mform-designer-node", inputs: ["node", "path", "engine", "selected", "dragging", "activeDrop"], outputs: ["selectNode", "nodeDragStart", "dragOverTarget", "dropOnTarget", "dragFinished"] }, { kind: "component", type: InspectorComponent, selector: "mform-inspector", inputs: ["node", "schema"], outputs: ["nodePatch"] }, { kind: "component", type: FormRendererComponent, selector: "mform-renderer", inputs: ["schema", "source", "initialData", "optionsProviders", "messages", "validators", "mode", "submitHandler", "labels"], outputs: ["submitted", "valueChanged"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2092
+ `, isInline: true, styles: [".dz-shell{display:flex;flex-direction:column;height:100%;min-height:480px;font-family:var(--mform-font, system-ui, \"Segoe UI\", sans-serif);color:var(--mform-text, #1f1b2e);background:var(--mform-bg, #f6f5fa);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);overflow:hidden}.dz-toolbar{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:8px 12px;background:var(--mform-surface, #fff);border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-tools{display:flex;align-items:center;gap:6px}.dz-toolbar button{font:inherit;font-size:13px;padding:6px 10px;border:1px solid transparent;border-radius:8px;background:none;color:inherit;cursor:pointer}.dz-toolbar button:hover:not(:disabled){background:var(--mform-bg, #f6f5fa)}.dz-toolbar button:disabled{opacity:.35;cursor:default}.dz-toolbar .dz-primary{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.dz-sep{width:1px;height:18px;background:var(--mform-border, #d9d5e6)}.dz-diag-badge{color:#b45309;font-weight:600}.dz-diagnostics{max-height:140px;overflow-y:auto;padding:8px 14px;background:#fdf5ef;border-bottom:1px solid var(--mform-border, #d9d5e6);font-size:12px}.dz-diag{padding:2px 0;color:#9a3412}.dz-diag.is-warning{color:#92400e}.dz-diag code{font-weight:600;margin-right:6px}.dz-diag em{color:var(--mform-muted, #6b6580);margin-left:6px}.dz-dialog{padding:14px;background:var(--mform-surface, #fff);border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-dialog h4{margin:0 0 8px;font-size:13px}.dz-dialog textarea{width:100%;font-family:ui-monospace,Consolas,monospace;font-size:12px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;padding:10px;box-sizing:border-box;resize:vertical}.dz-dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}.dz-dialog-actions button{font:inherit;font-size:13px;padding:7px 14px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;background:none;cursor:pointer}.dz-dialog-actions .dz-primary{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border-color:transparent}.dz-import-error{color:var(--mform-danger, #c62842);font-size:12px}.dz-body{display:grid;flex:1;min-height:0}.dz-dock{display:flex;flex-direction:column;min-height:0;overflow-y:auto;background:var(--mform-surface, #fff)}.dz-dock-left{border-right:1px solid var(--mform-border, #d9d5e6);position:relative}.dz-dock-right{border-left:1px solid var(--mform-border, #d9d5e6);position:relative}.dz-splitter{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;touch-action:none;z-index:2}.dz-splitter-left{right:-3px}.dz-splitter-right{left:-3px}.dz-splitter:hover,.dz-splitter:active{background:var(--mform-primary, #6d4bd0);opacity:.35}.dz-panel{display:flex;flex-direction:column;border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-panel:last-child{border-bottom:none;flex:1}.dz-panel-head{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--mform-muted, #6b6580);background:var(--mform-bg, #f6f5fa);position:sticky;top:0;z-index:1}.dz-panel-actions{display:flex;gap:2px;opacity:0;transition:opacity .12s}.dz-panel:hover .dz-panel-actions,.dz-panel:focus-within .dz-panel-actions{opacity:1}.dz-panel-actions button{border:none;background:none;color:inherit;cursor:pointer;font-size:11px;padding:2px 4px;border-radius:4px}.dz-panel-actions button:hover{background:var(--mform-surface, #fff)}.dz-panel-body{padding:10px}.dz-menu{position:relative}.dz-menu-panel{position:absolute;top:calc(100% + 6px);right:0;z-index:20;min-width:260px;padding:8px;background:var(--mform-surface, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);box-shadow:0 10px 30px #1f1b2e26}.dz-menu-title{display:block;font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--mform-muted, #6b6580);padding:6px 6px 4px}.dz-menu-row{display:flex;align-items:center;justify-content:space-between;padding:4px 6px;font-size:13px}.dz-seg{display:flex;gap:2px}.dz-seg button{border:1px solid var(--mform-border, #d9d5e6);background:none;color:var(--mform-muted, #6b6580);border-radius:6px;font-size:11px;padding:3px 8px;cursor:pointer}.dz-seg button.is-on{background:var(--mform-primary, #6d4bd0);border-color:transparent;color:var(--mform-primary-contrast, #fff)}.dz-menu-item{display:block;width:100%;text-align:left;font:inherit;font-size:13px;padding:6px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.dz-menu-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-group{margin-bottom:4px}.dz-group-toggle{display:flex;align-items:center;gap:6px;width:100%;font:inherit;font-size:12px;font-weight:600;text-align:left;padding:6px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.dz-group-toggle:hover{background:var(--mform-bg, #f6f5fa)}.dz-caret{font-size:10px;color:var(--mform-muted, #6b6580);width:10px}.dz-group-count{margin-left:auto;font-size:10px;font-weight:400;color:var(--mform-muted, #6b6580);background:var(--mform-bg, #f6f5fa);border-radius:999px;padding:1px 7px}.dz-group-entries{display:flex;flex-direction:column;gap:2px;margin:2px 0 6px 10px}.dz-palette-item{display:flex;align-items:center;gap:8px;font:inherit;font-size:13px;text-align:left;padding:6px 8px;border:none;border-radius:8px;background:none;color:inherit;cursor:pointer}.dz-palette-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-icon{width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--mform-border, #d9d5e6);border-radius:6px;font-size:11px}.dz-tree{display:flex;flex-direction:column;gap:1px}.dz-tree-item{font:inherit;font-size:12px;text-align:left;padding:4px 8px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dz-tree-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-tree-item.is-selected{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.dz-canvas{padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:10px}.dz-canvas-empty,.dz-empty{color:var(--mform-muted, #6b6580);font-size:13px;border:1px dashed var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:18px;text-align:center}.dz-dropzone{height:4px;border-radius:999px;transition:height .1s,background .1s}.dz-canvas.is-dragging .dz-dropzone{height:14px;background:repeating-linear-gradient(90deg,var(--mform-border, #d9d5e6) 0 6px,transparent 6px 12px)}.dz-canvas.is-dragging .dz-dropzone.is-over{height:22px;background:var(--mform-primary, #6d4bd0)}.dz-palette-row{display:flex;align-items:center;gap:2px}.dz-palette-row .dz-palette-item{flex:1;cursor:grab}.dz-block-remove{border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer;font-size:11px;padding:2px 4px;opacity:0}.dz-palette-row:hover .dz-block-remove{opacity:1}.dz-node{position:relative;border:1px solid transparent;border-radius:var(--mform-radius, 10px);padding:20px 10px 10px;cursor:pointer;background:var(--mform-surface, #fff)}.dz-node:hover{border-color:var(--mform-border, #d9d5e6)}.dz-node.is-selected{border-color:var(--mform-primary, #6d4bd0);box-shadow:0 0 0 1px var(--mform-primary, #6d4bd0)}.dz-chip{position:absolute;top:2px;left:10px;font-size:10px;color:var(--mform-muted, #6b6580);pointer-events:none}.dz-node.is-selected>.dz-chip{color:var(--mform-primary, #6d4bd0);font-weight:600}.dz-children{display:flex;flex-direction:column;gap:8px}.dz-columns{display:grid;gap:10px}.dz-column{display:flex;flex-direction:column;gap:8px;border:1px dashed var(--mform-border, #d9d5e6);border-radius:8px;padding:8px;min-height:40px}.dz-tabbar{display:flex;gap:4px;margin-bottom:8px;border-bottom:2px solid var(--mform-border, #d9d5e6)}.dz-tab{font:inherit;font-size:12px;padding:5px 12px;border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer}.dz-tab.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600;border-bottom:2px solid var(--mform-primary, #6d4bd0);margin-bottom:-2px}.dz-leaf{pointer-events:none}.dz-props-empty{margin:4px 0}.dz-inspector{display:flex;flex-direction:column;gap:10px}.dz-inspector h3{margin:0;font-size:13px}.dz-inspector h3 code{color:var(--mform-muted, #6b6580);font-weight:400}.dz-prop{display:flex;flex-direction:column;gap:4px;font-size:12px}.dz-prop span{color:var(--mform-muted, #6b6580)}.dz-prop input,.dz-prop select,.dz-prop textarea{font:inherit;font-size:13px;padding:7px 9px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;background:#fff;width:100%;box-sizing:border-box}.dz-check{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer}.dz-check input{accent-color:var(--mform-primary, #6d4bd0)}.dz-section{border-top:1px solid var(--mform-border, #d9d5e6);padding-top:8px}.dz-section summary{font-size:12px;font-weight:600;cursor:pointer;margin-bottom:8px}.dz-section .dz-prop{margin-bottom:8px}.dz-option-row{display:flex;gap:6px;margin-bottom:6px}.dz-option-row input{flex:1;min-width:0;font-size:12px;padding:6px 8px;border:1px solid var(--mform-border, #d9d5e6);border-radius:6px}.dz-option-row button{border:none;background:none;cursor:pointer;color:var(--mform-muted, #6b6580)}.dz-add{font:inherit;font-size:12px;border:1px dashed var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0);background:none;border-radius:8px;padding:6px 10px;cursor:pointer}.dz-preview{padding:20px;overflow-y:auto}.dz-viewports{display:flex;gap:4px;justify-content:center;margin-bottom:16px}.dz-viewports button{font:inherit;font-size:12px;padding:5px 12px;border:1px solid var(--mform-border, #d9d5e6);border-radius:999px;background:var(--mform-surface, #fff);color:var(--mform-muted, #6b6580);cursor:pointer}.dz-viewports button.is-on{background:var(--mform-primary, #6d4bd0);border-color:transparent;color:var(--mform-primary-contrast, #fff)}.dz-preview-frame{margin:0 auto;transition:max-width .16s}.dz-preview-frame.is-constrained{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:16px;background:var(--mform-surface, #fff);box-shadow:0 8px 28px #1f1b2e14}.dz-preview-data{margin-top:16px;font-size:12px}.dz-preview-data pre{background:var(--mform-surface, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;padding:10px;overflow-x:auto}\n"], dependencies: [{ kind: "component", type: DesignerNodeComponent, selector: "mform-designer-node", inputs: ["node", "path", "engine", "selected", "dragging", "activeDrop"], outputs: ["selectNode", "nodeDragStart", "dragOverTarget", "dropOnTarget", "dragFinished"] }, { kind: "component", type: InspectorComponent, selector: "mform-inspector", inputs: ["node", "schema"], outputs: ["nodePatch"] }, { kind: "component", type: FormRendererComponent, selector: "mform-renderer", inputs: ["schema", "source", "initialData", "optionsProviders", "messages", "validators", "mode", "submitHandler", "labels"], outputs: ["submitted", "valueChanged"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1997
2093
  }
1998
2094
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: FormDesignerComponent, decorators: [{
1999
2095
  type: Component,
@@ -2012,6 +2108,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
2012
2108
  <span class="dz-sep"></span>
2013
2109
  <button type="button" (click)="moveSelected(-1)" [disabled]="!selected()" [title]="labels().moveUp">↑</button>
2014
2110
  <button type="button" (click)="moveSelected(1)" [disabled]="!selected()" [title]="labels().moveDown">↓</button>
2111
+ <button type="button" (click)="unnestSelected()" [disabled]="!canUnnest()" [title]="labels().unnest">⇤</button>
2112
+ <button type="button" (click)="nestSelected()" [disabled]="!canNest()" [title]="labels().nest">⇥</button>
2015
2113
  <button type="button" (click)="duplicateSelected()" [disabled]="!selected()" [title]="labels().duplicate">⧉</button>
2016
2114
  <button type="button" (click)="removeSelected()" [disabled]="!selected()" [title]="labels().delete">🗑</button>
2017
2115
  <button type="button" (click)="saveAsBlock()" [disabled]="!selected()" [title]="labels().saveBlock">⊞</button>
@@ -2096,7 +2194,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
2096
2194
 
2097
2195
  @if (preview()) {
2098
2196
  <div class="dz-preview">
2099
- <mform-renderer [schema]="draft()" (valueChanged)="previewData.set($event)" />
2197
+ <div class="dz-viewports" role="group" [attr.aria-label]="labels().viewport">
2198
+ @for (option of viewports; track option.id) {
2199
+ <button
2200
+ type="button"
2201
+ [class.is-on]="viewport() === option.id"
2202
+ (click)="viewport.set(option.id)"
2203
+ [title]="option.width ? option.label + ' · ' + option.width + 'px' : option.label"
2204
+ >{{ option.icon }} {{ option.label }}</button>
2205
+ }
2206
+ </div>
2207
+ <div
2208
+ class="dz-preview-frame"
2209
+ [class.is-constrained]="viewportWidth() !== null"
2210
+ [style.max-width.px]="viewportWidth()"
2211
+ >
2212
+ <mform-renderer [schema]="draft()" (valueChanged)="previewData.set($event)" />
2213
+ </div>
2100
2214
  <details class="dz-preview-data">
2101
2215
  <summary>{{ labels().testData }}</summary>
2102
2216
  <pre>{{ previewData() | json }}</pre>
@@ -2271,7 +2385,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
2271
2385
  </div>
2272
2386
  </section>
2273
2387
  </ng-template>
2274
- `, styles: [".dz-shell{display:flex;flex-direction:column;height:100%;min-height:480px;font-family:var(--mform-font, system-ui, \"Segoe UI\", sans-serif);color:var(--mform-text, #1f1b2e);background:var(--mform-bg, #f6f5fa);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);overflow:hidden}.dz-toolbar{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:8px 12px;background:var(--mform-surface, #fff);border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-tools{display:flex;align-items:center;gap:6px}.dz-toolbar button{font:inherit;font-size:13px;padding:6px 10px;border:1px solid transparent;border-radius:8px;background:none;color:inherit;cursor:pointer}.dz-toolbar button:hover:not(:disabled){background:var(--mform-bg, #f6f5fa)}.dz-toolbar button:disabled{opacity:.35;cursor:default}.dz-toolbar .dz-primary{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.dz-sep{width:1px;height:18px;background:var(--mform-border, #d9d5e6)}.dz-diag-badge{color:#b45309;font-weight:600}.dz-diagnostics{max-height:140px;overflow-y:auto;padding:8px 14px;background:#fdf5ef;border-bottom:1px solid var(--mform-border, #d9d5e6);font-size:12px}.dz-diag{padding:2px 0;color:#9a3412}.dz-diag.is-warning{color:#92400e}.dz-diag code{font-weight:600;margin-right:6px}.dz-diag em{color:var(--mform-muted, #6b6580);margin-left:6px}.dz-dialog{padding:14px;background:var(--mform-surface, #fff);border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-dialog h4{margin:0 0 8px;font-size:13px}.dz-dialog textarea{width:100%;font-family:ui-monospace,Consolas,monospace;font-size:12px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;padding:10px;box-sizing:border-box;resize:vertical}.dz-dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}.dz-dialog-actions button{font:inherit;font-size:13px;padding:7px 14px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;background:none;cursor:pointer}.dz-dialog-actions .dz-primary{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border-color:transparent}.dz-import-error{color:var(--mform-danger, #c62842);font-size:12px}.dz-body{display:grid;flex:1;min-height:0}.dz-dock{display:flex;flex-direction:column;min-height:0;overflow-y:auto;background:var(--mform-surface, #fff)}.dz-dock-left{border-right:1px solid var(--mform-border, #d9d5e6);position:relative}.dz-dock-right{border-left:1px solid var(--mform-border, #d9d5e6);position:relative}.dz-splitter{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;touch-action:none;z-index:2}.dz-splitter-left{right:-3px}.dz-splitter-right{left:-3px}.dz-splitter:hover,.dz-splitter:active{background:var(--mform-primary, #6d4bd0);opacity:.35}.dz-panel{display:flex;flex-direction:column;border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-panel:last-child{border-bottom:none;flex:1}.dz-panel-head{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--mform-muted, #6b6580);background:var(--mform-bg, #f6f5fa);position:sticky;top:0;z-index:1}.dz-panel-actions{display:flex;gap:2px;opacity:0;transition:opacity .12s}.dz-panel:hover .dz-panel-actions,.dz-panel:focus-within .dz-panel-actions{opacity:1}.dz-panel-actions button{border:none;background:none;color:inherit;cursor:pointer;font-size:11px;padding:2px 4px;border-radius:4px}.dz-panel-actions button:hover{background:var(--mform-surface, #fff)}.dz-panel-body{padding:10px}.dz-menu{position:relative}.dz-menu-panel{position:absolute;top:calc(100% + 6px);right:0;z-index:20;min-width:260px;padding:8px;background:var(--mform-surface, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);box-shadow:0 10px 30px #1f1b2e26}.dz-menu-title{display:block;font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--mform-muted, #6b6580);padding:6px 6px 4px}.dz-menu-row{display:flex;align-items:center;justify-content:space-between;padding:4px 6px;font-size:13px}.dz-seg{display:flex;gap:2px}.dz-seg button{border:1px solid var(--mform-border, #d9d5e6);background:none;color:var(--mform-muted, #6b6580);border-radius:6px;font-size:11px;padding:3px 8px;cursor:pointer}.dz-seg button.is-on{background:var(--mform-primary, #6d4bd0);border-color:transparent;color:var(--mform-primary-contrast, #fff)}.dz-menu-item{display:block;width:100%;text-align:left;font:inherit;font-size:13px;padding:6px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.dz-menu-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-group{margin-bottom:4px}.dz-group-toggle{display:flex;align-items:center;gap:6px;width:100%;font:inherit;font-size:12px;font-weight:600;text-align:left;padding:6px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.dz-group-toggle:hover{background:var(--mform-bg, #f6f5fa)}.dz-caret{font-size:10px;color:var(--mform-muted, #6b6580);width:10px}.dz-group-count{margin-left:auto;font-size:10px;font-weight:400;color:var(--mform-muted, #6b6580);background:var(--mform-bg, #f6f5fa);border-radius:999px;padding:1px 7px}.dz-group-entries{display:flex;flex-direction:column;gap:2px;margin:2px 0 6px 10px}.dz-palette-item{display:flex;align-items:center;gap:8px;font:inherit;font-size:13px;text-align:left;padding:6px 8px;border:none;border-radius:8px;background:none;color:inherit;cursor:pointer}.dz-palette-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-icon{width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--mform-border, #d9d5e6);border-radius:6px;font-size:11px}.dz-tree{display:flex;flex-direction:column;gap:1px}.dz-tree-item{font:inherit;font-size:12px;text-align:left;padding:4px 8px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dz-tree-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-tree-item.is-selected{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.dz-canvas{padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:10px}.dz-canvas-empty,.dz-empty{color:var(--mform-muted, #6b6580);font-size:13px;border:1px dashed var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:18px;text-align:center}.dz-dropzone{height:4px;border-radius:999px;transition:height .1s,background .1s}.dz-canvas.is-dragging .dz-dropzone{height:14px;background:repeating-linear-gradient(90deg,var(--mform-border, #d9d5e6) 0 6px,transparent 6px 12px)}.dz-canvas.is-dragging .dz-dropzone.is-over{height:22px;background:var(--mform-primary, #6d4bd0)}.dz-palette-row{display:flex;align-items:center;gap:2px}.dz-palette-row .dz-palette-item{flex:1;cursor:grab}.dz-block-remove{border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer;font-size:11px;padding:2px 4px;opacity:0}.dz-palette-row:hover .dz-block-remove{opacity:1}.dz-node{position:relative;border:1px solid transparent;border-radius:var(--mform-radius, 10px);padding:20px 10px 10px;cursor:pointer;background:var(--mform-surface, #fff)}.dz-node:hover{border-color:var(--mform-border, #d9d5e6)}.dz-node.is-selected{border-color:var(--mform-primary, #6d4bd0);box-shadow:0 0 0 1px var(--mform-primary, #6d4bd0)}.dz-chip{position:absolute;top:2px;left:10px;font-size:10px;color:var(--mform-muted, #6b6580);pointer-events:none}.dz-node.is-selected>.dz-chip{color:var(--mform-primary, #6d4bd0);font-weight:600}.dz-children{display:flex;flex-direction:column;gap:8px}.dz-columns{display:grid;gap:10px}.dz-column{display:flex;flex-direction:column;gap:8px;border:1px dashed var(--mform-border, #d9d5e6);border-radius:8px;padding:8px;min-height:40px}.dz-tabbar{display:flex;gap:4px;margin-bottom:8px;border-bottom:2px solid var(--mform-border, #d9d5e6)}.dz-tab{font:inherit;font-size:12px;padding:5px 12px;border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer}.dz-tab.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600;border-bottom:2px solid var(--mform-primary, #6d4bd0);margin-bottom:-2px}.dz-leaf{pointer-events:none}.dz-props-empty{margin:4px 0}.dz-inspector{display:flex;flex-direction:column;gap:10px}.dz-inspector h3{margin:0;font-size:13px}.dz-inspector h3 code{color:var(--mform-muted, #6b6580);font-weight:400}.dz-prop{display:flex;flex-direction:column;gap:4px;font-size:12px}.dz-prop span{color:var(--mform-muted, #6b6580)}.dz-prop input,.dz-prop select,.dz-prop textarea{font:inherit;font-size:13px;padding:7px 9px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;background:#fff;width:100%;box-sizing:border-box}.dz-check{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer}.dz-check input{accent-color:var(--mform-primary, #6d4bd0)}.dz-section{border-top:1px solid var(--mform-border, #d9d5e6);padding-top:8px}.dz-section summary{font-size:12px;font-weight:600;cursor:pointer;margin-bottom:8px}.dz-section .dz-prop{margin-bottom:8px}.dz-option-row{display:flex;gap:6px;margin-bottom:6px}.dz-option-row input{flex:1;min-width:0;font-size:12px;padding:6px 8px;border:1px solid var(--mform-border, #d9d5e6);border-radius:6px}.dz-option-row button{border:none;background:none;cursor:pointer;color:var(--mform-muted, #6b6580)}.dz-add{font:inherit;font-size:12px;border:1px dashed var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0);background:none;border-radius:8px;padding:6px 10px;cursor:pointer}.dz-preview{padding:20px;overflow-y:auto}.dz-preview-data{margin-top:16px;font-size:12px}.dz-preview-data pre{background:var(--mform-surface, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;padding:10px;overflow-x:auto}\n"] }]
2388
+ `, styles: [".dz-shell{display:flex;flex-direction:column;height:100%;min-height:480px;font-family:var(--mform-font, system-ui, \"Segoe UI\", sans-serif);color:var(--mform-text, #1f1b2e);background:var(--mform-bg, #f6f5fa);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);overflow:hidden}.dz-toolbar{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:8px 12px;background:var(--mform-surface, #fff);border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-tools{display:flex;align-items:center;gap:6px}.dz-toolbar button{font:inherit;font-size:13px;padding:6px 10px;border:1px solid transparent;border-radius:8px;background:none;color:inherit;cursor:pointer}.dz-toolbar button:hover:not(:disabled){background:var(--mform-bg, #f6f5fa)}.dz-toolbar button:disabled{opacity:.35;cursor:default}.dz-toolbar .dz-primary{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.dz-sep{width:1px;height:18px;background:var(--mform-border, #d9d5e6)}.dz-diag-badge{color:#b45309;font-weight:600}.dz-diagnostics{max-height:140px;overflow-y:auto;padding:8px 14px;background:#fdf5ef;border-bottom:1px solid var(--mform-border, #d9d5e6);font-size:12px}.dz-diag{padding:2px 0;color:#9a3412}.dz-diag.is-warning{color:#92400e}.dz-diag code{font-weight:600;margin-right:6px}.dz-diag em{color:var(--mform-muted, #6b6580);margin-left:6px}.dz-dialog{padding:14px;background:var(--mform-surface, #fff);border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-dialog h4{margin:0 0 8px;font-size:13px}.dz-dialog textarea{width:100%;font-family:ui-monospace,Consolas,monospace;font-size:12px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;padding:10px;box-sizing:border-box;resize:vertical}.dz-dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}.dz-dialog-actions button{font:inherit;font-size:13px;padding:7px 14px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;background:none;cursor:pointer}.dz-dialog-actions .dz-primary{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border-color:transparent}.dz-import-error{color:var(--mform-danger, #c62842);font-size:12px}.dz-body{display:grid;flex:1;min-height:0}.dz-dock{display:flex;flex-direction:column;min-height:0;overflow-y:auto;background:var(--mform-surface, #fff)}.dz-dock-left{border-right:1px solid var(--mform-border, #d9d5e6);position:relative}.dz-dock-right{border-left:1px solid var(--mform-border, #d9d5e6);position:relative}.dz-splitter{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;touch-action:none;z-index:2}.dz-splitter-left{right:-3px}.dz-splitter-right{left:-3px}.dz-splitter:hover,.dz-splitter:active{background:var(--mform-primary, #6d4bd0);opacity:.35}.dz-panel{display:flex;flex-direction:column;border-bottom:1px solid var(--mform-border, #d9d5e6)}.dz-panel:last-child{border-bottom:none;flex:1}.dz-panel-head{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--mform-muted, #6b6580);background:var(--mform-bg, #f6f5fa);position:sticky;top:0;z-index:1}.dz-panel-actions{display:flex;gap:2px;opacity:0;transition:opacity .12s}.dz-panel:hover .dz-panel-actions,.dz-panel:focus-within .dz-panel-actions{opacity:1}.dz-panel-actions button{border:none;background:none;color:inherit;cursor:pointer;font-size:11px;padding:2px 4px;border-radius:4px}.dz-panel-actions button:hover{background:var(--mform-surface, #fff)}.dz-panel-body{padding:10px}.dz-menu{position:relative}.dz-menu-panel{position:absolute;top:calc(100% + 6px);right:0;z-index:20;min-width:260px;padding:8px;background:var(--mform-surface, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);box-shadow:0 10px 30px #1f1b2e26}.dz-menu-title{display:block;font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--mform-muted, #6b6580);padding:6px 6px 4px}.dz-menu-row{display:flex;align-items:center;justify-content:space-between;padding:4px 6px;font-size:13px}.dz-seg{display:flex;gap:2px}.dz-seg button{border:1px solid var(--mform-border, #d9d5e6);background:none;color:var(--mform-muted, #6b6580);border-radius:6px;font-size:11px;padding:3px 8px;cursor:pointer}.dz-seg button.is-on{background:var(--mform-primary, #6d4bd0);border-color:transparent;color:var(--mform-primary-contrast, #fff)}.dz-menu-item{display:block;width:100%;text-align:left;font:inherit;font-size:13px;padding:6px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.dz-menu-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-group{margin-bottom:4px}.dz-group-toggle{display:flex;align-items:center;gap:6px;width:100%;font:inherit;font-size:12px;font-weight:600;text-align:left;padding:6px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.dz-group-toggle:hover{background:var(--mform-bg, #f6f5fa)}.dz-caret{font-size:10px;color:var(--mform-muted, #6b6580);width:10px}.dz-group-count{margin-left:auto;font-size:10px;font-weight:400;color:var(--mform-muted, #6b6580);background:var(--mform-bg, #f6f5fa);border-radius:999px;padding:1px 7px}.dz-group-entries{display:flex;flex-direction:column;gap:2px;margin:2px 0 6px 10px}.dz-palette-item{display:flex;align-items:center;gap:8px;font:inherit;font-size:13px;text-align:left;padding:6px 8px;border:none;border-radius:8px;background:none;color:inherit;cursor:pointer}.dz-palette-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-icon{width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--mform-border, #d9d5e6);border-radius:6px;font-size:11px}.dz-tree{display:flex;flex-direction:column;gap:1px}.dz-tree-item{font:inherit;font-size:12px;text-align:left;padding:4px 8px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dz-tree-item:hover{background:var(--mform-bg, #f6f5fa)}.dz-tree-item.is-selected{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.dz-canvas{padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:10px}.dz-canvas-empty,.dz-empty{color:var(--mform-muted, #6b6580);font-size:13px;border:1px dashed var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:18px;text-align:center}.dz-dropzone{height:4px;border-radius:999px;transition:height .1s,background .1s}.dz-canvas.is-dragging .dz-dropzone{height:14px;background:repeating-linear-gradient(90deg,var(--mform-border, #d9d5e6) 0 6px,transparent 6px 12px)}.dz-canvas.is-dragging .dz-dropzone.is-over{height:22px;background:var(--mform-primary, #6d4bd0)}.dz-palette-row{display:flex;align-items:center;gap:2px}.dz-palette-row .dz-palette-item{flex:1;cursor:grab}.dz-block-remove{border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer;font-size:11px;padding:2px 4px;opacity:0}.dz-palette-row:hover .dz-block-remove{opacity:1}.dz-node{position:relative;border:1px solid transparent;border-radius:var(--mform-radius, 10px);padding:20px 10px 10px;cursor:pointer;background:var(--mform-surface, #fff)}.dz-node:hover{border-color:var(--mform-border, #d9d5e6)}.dz-node.is-selected{border-color:var(--mform-primary, #6d4bd0);box-shadow:0 0 0 1px var(--mform-primary, #6d4bd0)}.dz-chip{position:absolute;top:2px;left:10px;font-size:10px;color:var(--mform-muted, #6b6580);pointer-events:none}.dz-node.is-selected>.dz-chip{color:var(--mform-primary, #6d4bd0);font-weight:600}.dz-children{display:flex;flex-direction:column;gap:8px}.dz-columns{display:grid;gap:10px}.dz-column{display:flex;flex-direction:column;gap:8px;border:1px dashed var(--mform-border, #d9d5e6);border-radius:8px;padding:8px;min-height:40px}.dz-tabbar{display:flex;gap:4px;margin-bottom:8px;border-bottom:2px solid var(--mform-border, #d9d5e6)}.dz-tab{font:inherit;font-size:12px;padding:5px 12px;border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer}.dz-tab.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600;border-bottom:2px solid var(--mform-primary, #6d4bd0);margin-bottom:-2px}.dz-leaf{pointer-events:none}.dz-props-empty{margin:4px 0}.dz-inspector{display:flex;flex-direction:column;gap:10px}.dz-inspector h3{margin:0;font-size:13px}.dz-inspector h3 code{color:var(--mform-muted, #6b6580);font-weight:400}.dz-prop{display:flex;flex-direction:column;gap:4px;font-size:12px}.dz-prop span{color:var(--mform-muted, #6b6580)}.dz-prop input,.dz-prop select,.dz-prop textarea{font:inherit;font-size:13px;padding:7px 9px;border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;background:#fff;width:100%;box-sizing:border-box}.dz-check{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer}.dz-check input{accent-color:var(--mform-primary, #6d4bd0)}.dz-section{border-top:1px solid var(--mform-border, #d9d5e6);padding-top:8px}.dz-section summary{font-size:12px;font-weight:600;cursor:pointer;margin-bottom:8px}.dz-section .dz-prop{margin-bottom:8px}.dz-option-row{display:flex;gap:6px;margin-bottom:6px}.dz-option-row input{flex:1;min-width:0;font-size:12px;padding:6px 8px;border:1px solid var(--mform-border, #d9d5e6);border-radius:6px}.dz-option-row button{border:none;background:none;cursor:pointer;color:var(--mform-muted, #6b6580)}.dz-add{font:inherit;font-size:12px;border:1px dashed var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0);background:none;border-radius:8px;padding:6px 10px;cursor:pointer}.dz-preview{padding:20px;overflow-y:auto}.dz-viewports{display:flex;gap:4px;justify-content:center;margin-bottom:16px}.dz-viewports button{font:inherit;font-size:12px;padding:5px 12px;border:1px solid var(--mform-border, #d9d5e6);border-radius:999px;background:var(--mform-surface, #fff);color:var(--mform-muted, #6b6580);cursor:pointer}.dz-viewports button.is-on{background:var(--mform-primary, #6d4bd0);border-color:transparent;color:var(--mform-primary-contrast, #fff)}.dz-preview-frame{margin:0 auto;transition:max-width .16s}.dz-preview-frame.is-constrained{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:16px;background:var(--mform-surface, #fff);box-shadow:0 8px 28px #1f1b2e14}.dz-preview-data{margin-top:16px;font-size:12px}.dz-preview-data pre{background:var(--mform-surface, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:8px;padding:10px;overflow-x:auto}\n"] }]
2275
2389
  }], ctorParameters: () => [], propDecorators: { schema: [{ type: i0.Input, args: [{ isSignal: true, alias: "schema", required: false }] }], source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], extraCatalog: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraCatalog", required: false }] }], catalogOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "catalog", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], schemaChanged: [{ type: i0.Output, args: ["schemaChanged"] }], blocks: [{ type: i0.Input, args: [{ isSignal: true, alias: "blocks", required: false }] }], blocksChanged: [{ type: i0.Output, args: ["blocksChanged"] }] } });
2276
2390
 
2277
2391
  /*