@msbci/form-editor 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode, ComponentType } from 'react';
3
- import { IFormDefinition, IFormPage, IFormRoster, IFormVariable, IFormType, IDataSourceConnector, IConditionRule, IRosterVariableRef } from '@msbci/form-core';
2
+ import React, { ReactNode, ComponentType } from 'react';
3
+ import { IFormDefinition, IFormPage, IFormRoster, IFormVariable, IVariableTemplate, IVariableTemplateOverrides, IFormType, IDataSourceConnector, VariableType, RosterType, IConditionRule, IRosterVariableRef } from '@msbci/form-core';
4
4
  export { IDataSourceConnector, IFormDefinition, IFormPage, IFormRoster, IFormVariable, IMosobiThemeBase } from '@msbci/form-core';
5
5
  import * as zustand from 'zustand';
6
+ import { DragEndEvent } from '@dnd-kit/core';
6
7
 
7
8
  /**
8
9
  * Editor store types.
@@ -40,6 +41,12 @@ interface IEditorAdapter {
40
41
  saveForm?: (form: IFormDefinition) => Promise<void>;
41
42
  loadFormTypes?: () => Promise<IFormType[]>;
42
43
  saveFormType?: (type: IFormType) => Promise<void>;
44
+ /**
45
+ * Optional — fetch the variable templates of a scope.
46
+ * When absent, the editor's "Variables" toolbox tab stays empty and
47
+ * shows the {@link IEditorLabels.toolbox.noTemplates} message.
48
+ */
49
+ loadTemplates?: (scopeId: string) => Promise<IVariableTemplate[]>;
43
50
  }
44
51
  /** Complete editor state */
45
52
  interface EditorState {
@@ -52,6 +59,13 @@ interface EditorState {
52
59
  history: HistoryEntry[];
53
60
  historyIndex: number;
54
61
  adapter: IEditorAdapter | null;
62
+ /**
63
+ * Variable templates surfaced to the "Variables" toolbox tab. Populated
64
+ * via `setAvailableTemplates` (typically by `FormEditor` after
65
+ * `adapter.loadTemplates(form.scopeId)`). Out of the undo/redo history —
66
+ * this is editor-UI state, not form state.
67
+ */
68
+ availableTemplates: IVariableTemplate[];
55
69
  }
56
70
  /** Editor actions */
57
71
  interface EditorActions {
@@ -67,7 +81,33 @@ interface EditorActions {
67
81
  addVariable: (pageCode: string, variable: IFormVariable, rosterCode?: string) => void;
68
82
  updateVariable: (pageCode: string, variableCode: string, updates: Partial<IFormVariable>, rosterCode?: string) => void;
69
83
  removeVariable: (pageCode: string, variableCode: string, rosterCode?: string) => void;
84
+ /**
85
+ * Insert a variable that inherits from a `IVariableTemplate`. Template
86
+ * fields are denormalised onto the new variable; `code` and `name` come
87
+ * from the template; `templateOverrides` starts empty.
88
+ */
89
+ addVariableFromTemplate: (pageCode: string, template: IVariableTemplate, rosterCode?: string) => void;
90
+ /**
91
+ * Override a single field of a template-linked variable. Writes the new
92
+ * value into `templateOverrides[key]` AND mirrors it on the variable so
93
+ * the canvas can render without invoking the resolver.
94
+ */
95
+ setVariableOverride: <K extends keyof IVariableTemplateOverrides>(pageCode: string, variableCode: string, key: K, value: IVariableTemplateOverrides[K], rosterCode?: string) => void;
96
+ /**
97
+ * Drop one override key — removes it from `templateOverrides` and
98
+ * restores the variable's mirrored field from the linked template.
99
+ */
100
+ resetVariableOverride: (pageCode: string, variableCode: string, key: keyof IVariableTemplateOverrides, rosterCode?: string) => void;
101
+ /**
102
+ * Cross-page / cross-roster move (kept for the existing dnd flow). Use
103
+ * {@link moveItem} for intra-page reordering of `page.items[]`.
104
+ */
70
105
  moveVariable: (fromPageCode: string, toPageCode: string, variableCode: string, newOrder: number, fromRosterCode?: string, toRosterCode?: string) => void;
106
+ /**
107
+ * Reorder the items of a page (variables + rosters mixed) by index.
108
+ * Updates each item's `order` to its new position.
109
+ */
110
+ moveItem: (pageCode: string, fromIndex: number, toIndex: number) => void;
71
111
  select: (selection: EditorSelection) => void;
72
112
  clearSelection: () => void;
73
113
  setView: (view: EditorView) => void;
@@ -78,6 +118,8 @@ interface EditorActions {
78
118
  addFormType: (type: Omit<IFormType, 'id'>) => void;
79
119
  updateFormType: (id: string, patch: Partial<IFormType>) => void;
80
120
  removeFormType: (id: string) => void;
121
+ /** Replace the variable-template list shown in the Variables tab. */
122
+ setAvailableTemplates: (templates: IVariableTemplate[]) => void;
81
123
  setAdapter: (adapter: IEditorAdapter) => void;
82
124
  save: () => Promise<void>;
83
125
  load: (formId: string) => Promise<void>;
@@ -120,11 +162,26 @@ interface IEditorLabels {
120
162
  toolbox: {
121
163
  searchPlaceholder: string;
122
164
  addPageFirst: string;
165
+ /** Label of the first tab (existing variable/roster types). */
166
+ tabFields: string;
167
+ /** Label of the second tab (variable library from current scope). */
168
+ tabVariables: string;
169
+ /** Empty state for the Variables tab when the form has a scope but no templates. */
170
+ noTemplates: string;
171
+ /** Empty state for the Variables tab when the form has no scope at all. */
172
+ noScope: string;
123
173
  groupText: string;
124
174
  groupSelection: string;
125
175
  groupDateTime: string;
126
176
  groupMedia: string;
127
177
  groupAdvanced: string;
178
+ /** Section label for the four roster variants, displayed after ADVANCED. */
179
+ groupRoster: string;
180
+ /** Roster type labels — surface the four supported variants. */
181
+ typeRosterCheck: string;
182
+ typeRosterList: string;
183
+ typeRosterCollection: string;
184
+ typeRosterCollectionExtend: string;
128
185
  /**
129
186
  * Shared variable-type labels. Re-used by both Toolbox(Simple) and
130
187
  * VariableProperties (single source of truth).
@@ -211,6 +268,14 @@ interface IEditorLabels {
211
268
  collection: string;
212
269
  collection_extend: string;
213
270
  };
271
+ /** Banner title shown on top of VariableProperties when the variable links to a template. */
272
+ linkedTemplate: string;
273
+ /** Label for the read-only code field on a linked variable. */
274
+ templateCode: string;
275
+ /** Label for the read-only name field on a linked variable. */
276
+ templateName: string;
277
+ /** Per-override reset button label. */
278
+ resetOverride: string;
214
279
  type: string;
215
280
  ratingStyle: string;
216
281
  ratingStyles: {
@@ -378,11 +443,25 @@ interface FormEditorProps {
378
443
  dataSources?: Record<string, IDataSourceConnector>;
379
444
  mode?: string;
380
445
  }>;
381
- /** Custom Toolbox component (e.g. with drag & drop) */
446
+ /**
447
+ * Override the default DnD-enabled Toolbox. Most consumers should leave
448
+ * this undefined and rely on the default `Toolbox` component, which
449
+ * already supports drag & drop and the click-to-add flow.
450
+ */
382
451
  ToolboxComponent?: ComponentType<any>;
383
- /** Custom Canvas component (e.g. with sortable drag & drop) */
452
+ /**
453
+ * Override the default DnD-enabled Canvas. Most consumers should leave
454
+ * this undefined; the default `Canvas` component handles reordering and
455
+ * cross-container drops automatically.
456
+ */
384
457
  CanvasComponent?: ComponentType<any>;
385
- /** Wrapper around the entire editor (e.g. DndContext) */
458
+ /**
459
+ * @deprecated Drag & drop is now provided by `DndManager` internally.
460
+ * If you still pass a `Wrapper`, it is applied AROUND the internal
461
+ * `<DndManager>` so your wrapper keeps running, but you no longer need
462
+ * to mount your own `<DndContext>`. A one-time console warning is
463
+ * emitted to make the deprecation visible.
464
+ */
386
465
  Wrapper?: ComponentType<any>;
387
466
  }
388
467
  declare function FormEditor({ theme, dataSources, adapter, initialForm, formId, onChange, onSave, labels, PreviewComponent, ToolboxComponent, CanvasComponent, Wrapper, }: FormEditorProps): react_jsx_runtime.JSX.Element;
@@ -400,14 +479,80 @@ interface EditorToolbarProps {
400
479
  declare function EditorToolbar({ onSave, onExport, onImport }: EditorToolbarProps): react_jsx_runtime.JSX.Element;
401
480
 
402
481
  /**
403
- * Toolbox — left panel. Click to add variables to selected page.
404
- * No drag & drop dependency.
482
+ * Toolbox panel (DnD) left side of the editor.
483
+ * Two tabs:
484
+ * - Champs : variable types + roster variants (draggable).
485
+ * - Variables : reusable templates from the current scope (draggable
486
+ * with data.type='new-variable-from-template').
487
+ */
488
+ declare function Toolbox(): react_jsx_runtime.JSX.Element;
489
+
490
+ /**
491
+ * Canvas panel — center of the editor.
492
+ * Displays the form structure as pages with a unified list of items
493
+ * (variables + rosters). Items share a single SortableContext so the
494
+ * drag & drop reordering works across both kinds.
495
+ */
496
+ declare function Canvas(): react_jsx_runtime.JSX.Element;
497
+
498
+ /**
499
+ * Subset of the editor store the drag-end logic actually needs. Decoupling
500
+ * makes the handler trivially mockable in unit tests.
501
+ */
502
+ interface DragEndActions {
503
+ addVariable: (pageCode: string, variable: IFormVariable, rosterCode?: string) => void;
504
+ addRoster: (pageCode: string, roster: IFormRoster) => void;
505
+ addVariableFromTemplate: (pageCode: string, template: IVariableTemplate, rosterCode?: string) => void;
506
+ moveItem: (pageCode: string, fromIndex: number, toIndex: number) => void;
507
+ moveVariable: (fromPageCode: string, toPageCode: string, variableCode: string, newOrder: number, fromRosterCode?: string, toRosterCode?: string) => void;
508
+ reorderPages: (orderedCodes: string[]) => void;
509
+ }
510
+ /** Active draggable payload — what Canvas / Toolbox put under `data.current`. */
511
+ interface ActiveDragData {
512
+ type?: 'new-variable' | 'new-roster' | 'new-variable-from-template' | 'variable' | 'roster' | 'page';
513
+ variableType?: VariableType;
514
+ rosterType?: RosterType;
515
+ template?: IVariableTemplate;
516
+ pageCode?: string;
517
+ variableCode?: string;
518
+ rosterCode?: string;
519
+ }
520
+ /** Over (drop-target) payload. */
521
+ interface OverDropData {
522
+ type?: 'page' | 'variable' | 'roster' | 'roster-drop';
523
+ pageCode?: string;
524
+ rosterCode?: string;
525
+ }
526
+ /**
527
+ * Build a pure drag-end handler. Given a snapshot accessor for the form
528
+ * and the store actions, returns a function that translates a DragEndEvent
529
+ * into the right action call. Exported for unit tests.
530
+ */
531
+ declare function createDragEndHandler(actions: DragEndActions, getForm: () => IFormDefinition): (event: DragEndEvent) => void;
532
+ /**
533
+ * Wraps the editor tree in a `<DndContext>` configured with pointer +
534
+ * keyboard sensors and the drag-end handler returned by
535
+ * {@link createDragEndHandler}. A `<DragOverlay>` shows a label while
536
+ * something is being dragged.
537
+ */
538
+ declare function DndManager({ children }: {
539
+ children: React.ReactNode;
540
+ }): react_jsx_runtime.JSX.Element;
541
+
542
+ /**
543
+ * Toolbox — left panel. Two tabs:
544
+ * - Champs : variable types + roster variants (original content).
545
+ * - Variables : reusable templates from the current scope.
546
+ *
547
+ * Click to add. No drag & drop dependency (see Toolbox.tsx for DnD).
405
548
  */
406
549
  declare function ToolboxSimple(): react_jsx_runtime.JSX.Element;
407
550
 
408
551
  /**
409
552
  * Canvas — center panel. Displays form structure.
410
- * Click to select. Supports roster creation and variable management.
553
+ * Click to select. Variables and rosters share a single ordered list
554
+ * (`page.items[]`) and are rendered together; rosters always break the
555
+ * current multi-column row and span the full width.
411
556
  */
412
557
  declare function CanvasSimple(): react_jsx_runtime.JSX.Element;
413
558
 
@@ -459,4 +604,4 @@ interface DataSourceSelectorProps {
459
604
  }
460
605
  declare function DataSourceSelector({ dataSourceId, dependencies, availableConnectors, availableVariables, onConnectorChange, onDependenciesChange, }: DataSourceSelectorProps): react_jsx_runtime.JSX.Element;
461
606
 
462
- export { CanvasSimple as Canvas, ConditionBuilder, type ConditionBuilderProps, DataSourceSelector, type DataSourceSelectorProps, type DeepPartial, type EditorActions, EditorLabelsProvider, type EditorSelection, type EditorState, type EditorStore, EditorToolbar, type EditorView, FormEditor, type FormEditorProps, type HistoryEntry, type IEditorAdapter, type IEditorLabels, PropertiesPanel, ToolboxSimple as Toolbox, frLabels as defaultLabels, enLabels, frLabels, mergeLabels, useEditorStore, useLabels };
607
+ export { type ActiveDragData, Canvas, Canvas as CanvasDnd, CanvasSimple, ConditionBuilder, type ConditionBuilderProps, DataSourceSelector, type DataSourceSelectorProps, type DeepPartial, DndManager, type DragEndActions, type EditorActions, EditorLabelsProvider, type EditorSelection, type EditorState, type EditorStore, EditorToolbar, type EditorView, FormEditor, type FormEditorProps, type HistoryEntry, type IEditorAdapter, type IEditorLabels, type OverDropData, PropertiesPanel, Toolbox, Toolbox as ToolboxDnd, ToolboxSimple, createDragEndHandler, frLabels as defaultLabels, enLabels, frLabels, mergeLabels, useEditorStore, useLabels };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode, ComponentType } from 'react';
3
- import { IFormDefinition, IFormPage, IFormRoster, IFormVariable, IFormType, IDataSourceConnector, IConditionRule, IRosterVariableRef } from '@msbci/form-core';
2
+ import React, { ReactNode, ComponentType } from 'react';
3
+ import { IFormDefinition, IFormPage, IFormRoster, IFormVariable, IVariableTemplate, IVariableTemplateOverrides, IFormType, IDataSourceConnector, VariableType, RosterType, IConditionRule, IRosterVariableRef } from '@msbci/form-core';
4
4
  export { IDataSourceConnector, IFormDefinition, IFormPage, IFormRoster, IFormVariable, IMosobiThemeBase } from '@msbci/form-core';
5
5
  import * as zustand from 'zustand';
6
+ import { DragEndEvent } from '@dnd-kit/core';
6
7
 
7
8
  /**
8
9
  * Editor store types.
@@ -40,6 +41,12 @@ interface IEditorAdapter {
40
41
  saveForm?: (form: IFormDefinition) => Promise<void>;
41
42
  loadFormTypes?: () => Promise<IFormType[]>;
42
43
  saveFormType?: (type: IFormType) => Promise<void>;
44
+ /**
45
+ * Optional — fetch the variable templates of a scope.
46
+ * When absent, the editor's "Variables" toolbox tab stays empty and
47
+ * shows the {@link IEditorLabels.toolbox.noTemplates} message.
48
+ */
49
+ loadTemplates?: (scopeId: string) => Promise<IVariableTemplate[]>;
43
50
  }
44
51
  /** Complete editor state */
45
52
  interface EditorState {
@@ -52,6 +59,13 @@ interface EditorState {
52
59
  history: HistoryEntry[];
53
60
  historyIndex: number;
54
61
  adapter: IEditorAdapter | null;
62
+ /**
63
+ * Variable templates surfaced to the "Variables" toolbox tab. Populated
64
+ * via `setAvailableTemplates` (typically by `FormEditor` after
65
+ * `adapter.loadTemplates(form.scopeId)`). Out of the undo/redo history —
66
+ * this is editor-UI state, not form state.
67
+ */
68
+ availableTemplates: IVariableTemplate[];
55
69
  }
56
70
  /** Editor actions */
57
71
  interface EditorActions {
@@ -67,7 +81,33 @@ interface EditorActions {
67
81
  addVariable: (pageCode: string, variable: IFormVariable, rosterCode?: string) => void;
68
82
  updateVariable: (pageCode: string, variableCode: string, updates: Partial<IFormVariable>, rosterCode?: string) => void;
69
83
  removeVariable: (pageCode: string, variableCode: string, rosterCode?: string) => void;
84
+ /**
85
+ * Insert a variable that inherits from a `IVariableTemplate`. Template
86
+ * fields are denormalised onto the new variable; `code` and `name` come
87
+ * from the template; `templateOverrides` starts empty.
88
+ */
89
+ addVariableFromTemplate: (pageCode: string, template: IVariableTemplate, rosterCode?: string) => void;
90
+ /**
91
+ * Override a single field of a template-linked variable. Writes the new
92
+ * value into `templateOverrides[key]` AND mirrors it on the variable so
93
+ * the canvas can render without invoking the resolver.
94
+ */
95
+ setVariableOverride: <K extends keyof IVariableTemplateOverrides>(pageCode: string, variableCode: string, key: K, value: IVariableTemplateOverrides[K], rosterCode?: string) => void;
96
+ /**
97
+ * Drop one override key — removes it from `templateOverrides` and
98
+ * restores the variable's mirrored field from the linked template.
99
+ */
100
+ resetVariableOverride: (pageCode: string, variableCode: string, key: keyof IVariableTemplateOverrides, rosterCode?: string) => void;
101
+ /**
102
+ * Cross-page / cross-roster move (kept for the existing dnd flow). Use
103
+ * {@link moveItem} for intra-page reordering of `page.items[]`.
104
+ */
70
105
  moveVariable: (fromPageCode: string, toPageCode: string, variableCode: string, newOrder: number, fromRosterCode?: string, toRosterCode?: string) => void;
106
+ /**
107
+ * Reorder the items of a page (variables + rosters mixed) by index.
108
+ * Updates each item's `order` to its new position.
109
+ */
110
+ moveItem: (pageCode: string, fromIndex: number, toIndex: number) => void;
71
111
  select: (selection: EditorSelection) => void;
72
112
  clearSelection: () => void;
73
113
  setView: (view: EditorView) => void;
@@ -78,6 +118,8 @@ interface EditorActions {
78
118
  addFormType: (type: Omit<IFormType, 'id'>) => void;
79
119
  updateFormType: (id: string, patch: Partial<IFormType>) => void;
80
120
  removeFormType: (id: string) => void;
121
+ /** Replace the variable-template list shown in the Variables tab. */
122
+ setAvailableTemplates: (templates: IVariableTemplate[]) => void;
81
123
  setAdapter: (adapter: IEditorAdapter) => void;
82
124
  save: () => Promise<void>;
83
125
  load: (formId: string) => Promise<void>;
@@ -120,11 +162,26 @@ interface IEditorLabels {
120
162
  toolbox: {
121
163
  searchPlaceholder: string;
122
164
  addPageFirst: string;
165
+ /** Label of the first tab (existing variable/roster types). */
166
+ tabFields: string;
167
+ /** Label of the second tab (variable library from current scope). */
168
+ tabVariables: string;
169
+ /** Empty state for the Variables tab when the form has a scope but no templates. */
170
+ noTemplates: string;
171
+ /** Empty state for the Variables tab when the form has no scope at all. */
172
+ noScope: string;
123
173
  groupText: string;
124
174
  groupSelection: string;
125
175
  groupDateTime: string;
126
176
  groupMedia: string;
127
177
  groupAdvanced: string;
178
+ /** Section label for the four roster variants, displayed after ADVANCED. */
179
+ groupRoster: string;
180
+ /** Roster type labels — surface the four supported variants. */
181
+ typeRosterCheck: string;
182
+ typeRosterList: string;
183
+ typeRosterCollection: string;
184
+ typeRosterCollectionExtend: string;
128
185
  /**
129
186
  * Shared variable-type labels. Re-used by both Toolbox(Simple) and
130
187
  * VariableProperties (single source of truth).
@@ -211,6 +268,14 @@ interface IEditorLabels {
211
268
  collection: string;
212
269
  collection_extend: string;
213
270
  };
271
+ /** Banner title shown on top of VariableProperties when the variable links to a template. */
272
+ linkedTemplate: string;
273
+ /** Label for the read-only code field on a linked variable. */
274
+ templateCode: string;
275
+ /** Label for the read-only name field on a linked variable. */
276
+ templateName: string;
277
+ /** Per-override reset button label. */
278
+ resetOverride: string;
214
279
  type: string;
215
280
  ratingStyle: string;
216
281
  ratingStyles: {
@@ -378,11 +443,25 @@ interface FormEditorProps {
378
443
  dataSources?: Record<string, IDataSourceConnector>;
379
444
  mode?: string;
380
445
  }>;
381
- /** Custom Toolbox component (e.g. with drag & drop) */
446
+ /**
447
+ * Override the default DnD-enabled Toolbox. Most consumers should leave
448
+ * this undefined and rely on the default `Toolbox` component, which
449
+ * already supports drag & drop and the click-to-add flow.
450
+ */
382
451
  ToolboxComponent?: ComponentType<any>;
383
- /** Custom Canvas component (e.g. with sortable drag & drop) */
452
+ /**
453
+ * Override the default DnD-enabled Canvas. Most consumers should leave
454
+ * this undefined; the default `Canvas` component handles reordering and
455
+ * cross-container drops automatically.
456
+ */
384
457
  CanvasComponent?: ComponentType<any>;
385
- /** Wrapper around the entire editor (e.g. DndContext) */
458
+ /**
459
+ * @deprecated Drag & drop is now provided by `DndManager` internally.
460
+ * If you still pass a `Wrapper`, it is applied AROUND the internal
461
+ * `<DndManager>` so your wrapper keeps running, but you no longer need
462
+ * to mount your own `<DndContext>`. A one-time console warning is
463
+ * emitted to make the deprecation visible.
464
+ */
386
465
  Wrapper?: ComponentType<any>;
387
466
  }
388
467
  declare function FormEditor({ theme, dataSources, adapter, initialForm, formId, onChange, onSave, labels, PreviewComponent, ToolboxComponent, CanvasComponent, Wrapper, }: FormEditorProps): react_jsx_runtime.JSX.Element;
@@ -400,14 +479,80 @@ interface EditorToolbarProps {
400
479
  declare function EditorToolbar({ onSave, onExport, onImport }: EditorToolbarProps): react_jsx_runtime.JSX.Element;
401
480
 
402
481
  /**
403
- * Toolbox — left panel. Click to add variables to selected page.
404
- * No drag & drop dependency.
482
+ * Toolbox panel (DnD) left side of the editor.
483
+ * Two tabs:
484
+ * - Champs : variable types + roster variants (draggable).
485
+ * - Variables : reusable templates from the current scope (draggable
486
+ * with data.type='new-variable-from-template').
487
+ */
488
+ declare function Toolbox(): react_jsx_runtime.JSX.Element;
489
+
490
+ /**
491
+ * Canvas panel — center of the editor.
492
+ * Displays the form structure as pages with a unified list of items
493
+ * (variables + rosters). Items share a single SortableContext so the
494
+ * drag & drop reordering works across both kinds.
495
+ */
496
+ declare function Canvas(): react_jsx_runtime.JSX.Element;
497
+
498
+ /**
499
+ * Subset of the editor store the drag-end logic actually needs. Decoupling
500
+ * makes the handler trivially mockable in unit tests.
501
+ */
502
+ interface DragEndActions {
503
+ addVariable: (pageCode: string, variable: IFormVariable, rosterCode?: string) => void;
504
+ addRoster: (pageCode: string, roster: IFormRoster) => void;
505
+ addVariableFromTemplate: (pageCode: string, template: IVariableTemplate, rosterCode?: string) => void;
506
+ moveItem: (pageCode: string, fromIndex: number, toIndex: number) => void;
507
+ moveVariable: (fromPageCode: string, toPageCode: string, variableCode: string, newOrder: number, fromRosterCode?: string, toRosterCode?: string) => void;
508
+ reorderPages: (orderedCodes: string[]) => void;
509
+ }
510
+ /** Active draggable payload — what Canvas / Toolbox put under `data.current`. */
511
+ interface ActiveDragData {
512
+ type?: 'new-variable' | 'new-roster' | 'new-variable-from-template' | 'variable' | 'roster' | 'page';
513
+ variableType?: VariableType;
514
+ rosterType?: RosterType;
515
+ template?: IVariableTemplate;
516
+ pageCode?: string;
517
+ variableCode?: string;
518
+ rosterCode?: string;
519
+ }
520
+ /** Over (drop-target) payload. */
521
+ interface OverDropData {
522
+ type?: 'page' | 'variable' | 'roster' | 'roster-drop';
523
+ pageCode?: string;
524
+ rosterCode?: string;
525
+ }
526
+ /**
527
+ * Build a pure drag-end handler. Given a snapshot accessor for the form
528
+ * and the store actions, returns a function that translates a DragEndEvent
529
+ * into the right action call. Exported for unit tests.
530
+ */
531
+ declare function createDragEndHandler(actions: DragEndActions, getForm: () => IFormDefinition): (event: DragEndEvent) => void;
532
+ /**
533
+ * Wraps the editor tree in a `<DndContext>` configured with pointer +
534
+ * keyboard sensors and the drag-end handler returned by
535
+ * {@link createDragEndHandler}. A `<DragOverlay>` shows a label while
536
+ * something is being dragged.
537
+ */
538
+ declare function DndManager({ children }: {
539
+ children: React.ReactNode;
540
+ }): react_jsx_runtime.JSX.Element;
541
+
542
+ /**
543
+ * Toolbox — left panel. Two tabs:
544
+ * - Champs : variable types + roster variants (original content).
545
+ * - Variables : reusable templates from the current scope.
546
+ *
547
+ * Click to add. No drag & drop dependency (see Toolbox.tsx for DnD).
405
548
  */
406
549
  declare function ToolboxSimple(): react_jsx_runtime.JSX.Element;
407
550
 
408
551
  /**
409
552
  * Canvas — center panel. Displays form structure.
410
- * Click to select. Supports roster creation and variable management.
553
+ * Click to select. Variables and rosters share a single ordered list
554
+ * (`page.items[]`) and are rendered together; rosters always break the
555
+ * current multi-column row and span the full width.
411
556
  */
412
557
  declare function CanvasSimple(): react_jsx_runtime.JSX.Element;
413
558
 
@@ -459,4 +604,4 @@ interface DataSourceSelectorProps {
459
604
  }
460
605
  declare function DataSourceSelector({ dataSourceId, dependencies, availableConnectors, availableVariables, onConnectorChange, onDependenciesChange, }: DataSourceSelectorProps): react_jsx_runtime.JSX.Element;
461
606
 
462
- export { CanvasSimple as Canvas, ConditionBuilder, type ConditionBuilderProps, DataSourceSelector, type DataSourceSelectorProps, type DeepPartial, type EditorActions, EditorLabelsProvider, type EditorSelection, type EditorState, type EditorStore, EditorToolbar, type EditorView, FormEditor, type FormEditorProps, type HistoryEntry, type IEditorAdapter, type IEditorLabels, PropertiesPanel, ToolboxSimple as Toolbox, frLabels as defaultLabels, enLabels, frLabels, mergeLabels, useEditorStore, useLabels };
607
+ export { type ActiveDragData, Canvas, Canvas as CanvasDnd, CanvasSimple, ConditionBuilder, type ConditionBuilderProps, DataSourceSelector, type DataSourceSelectorProps, type DeepPartial, DndManager, type DragEndActions, type EditorActions, EditorLabelsProvider, type EditorSelection, type EditorState, type EditorStore, EditorToolbar, type EditorView, FormEditor, type FormEditorProps, type HistoryEntry, type IEditorAdapter, type IEditorLabels, type OverDropData, PropertiesPanel, Toolbox, Toolbox as ToolboxDnd, ToolboxSimple, createDragEndHandler, frLabels as defaultLabels, enLabels, frLabels, mergeLabels, useEditorStore, useLabels };