@themarioga/grid-editor 9.0.0-beta.1 → 9.0.0-beta.3

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.
@@ -178,6 +178,10 @@ export interface GridEditorOptions {
178
178
  elements?: { enabled?: boolean | 'auto'; selector?: string; auto?: boolean; types?: ElementType[] };
179
179
  /** The autosave plugin: what is edited, kept in the browser's storage as it changes. */
180
180
  autosave?: AutosaveOptions;
181
+ /** The clipboard plugin. `shortcuts`: Ctrl+C and Ctrl+V on the node selected or the target; default active_target. */
182
+ clipboard?: { shortcuts?: boolean };
183
+ /** The history plugin: undo and redo. */
184
+ history?: HistoryOptions;
181
185
  custom_filter?: CustomFilter | CustomFilter[] | '';
182
186
  valid_col_sizes?: ColumnSize[];
183
187
  valid_col_offsets?: number[];
@@ -220,6 +224,18 @@ export interface AutosaveOptions {
220
224
  maxAge?: number | null;
221
225
  }
222
226
 
227
+ /** The history plugin's options. */
228
+ export interface HistoryOptions {
229
+ /** Ctrl+Z, and Ctrl+Y or Ctrl+Shift+Z (⌘ on a Mac). Default true. */
230
+ shortcuts?: boolean;
231
+ /** The undo and redo buttons on the right of the toolbar. Default true. */
232
+ buttons?: boolean;
233
+ /** The steps that can be undone. Default 50. */
234
+ max?: number;
235
+ /** Milliseconds after the last change that make a step. Default 500. */
236
+ delay?: number;
237
+ }
238
+
223
239
  /** A draft the autosave plugin kept. */
224
240
  export interface AutosaveDraft {
225
241
  html: string;
@@ -250,6 +266,19 @@ export interface AutosaveErrorPayload {
250
266
  error: unknown;
251
267
  }
252
268
 
269
+ export interface HistoryPayload {
270
+ canvas: HTMLElement;
271
+ /** The markup the canvas went to. */
272
+ html: string;
273
+ source: 'shortcut' | 'tool' | 'api';
274
+ }
275
+
276
+ export interface HistoryChangePayload {
277
+ canvas: HTMLElement;
278
+ canUndo: boolean;
279
+ canRedo: boolean;
280
+ }
281
+
253
282
  /** Where a node was, or went: its parent and its index among the blocks there. */
254
283
  export interface Position {
255
284
  parent: HTMLElement;
@@ -271,7 +300,7 @@ export interface Payload {
271
300
  parent: HTMLElement | null;
272
301
  canvas: HTMLElement;
273
302
  breakpoint: View;
274
- source: 'api' | 'tool' | 'dragdrop' | 'paste' | 'panel' | string;
303
+ source: 'api' | 'tool' | 'dragdrop' | 'paste' | 'panel' | 'shortcut' | string;
275
304
  /** A pane inside a container. */
276
305
  container?: HTMLElement;
277
306
  }
@@ -383,6 +412,9 @@ export interface GridEditorEventMap {
383
412
  'grideditor:after-autosave': AutosavePayload;
384
413
  'grideditor:after-restore-draft': RestoreDraftPayload;
385
414
  'grideditor:autosave-error': AutosaveErrorPayload;
415
+ 'grideditor:after-undo': HistoryPayload;
416
+ 'grideditor:after-redo': HistoryPayload;
417
+ 'grideditor:history-change': HistoryChangePayload;
386
418
  }
387
419
 
388
420
  /** An event the editor dispatches on its canvas: a CustomEvent whose detail is the payload. */
@@ -521,6 +553,14 @@ export declare class GridEditor {
521
553
  saveDraft?(): boolean;
522
554
  getDraft?(): AutosaveDraft | null;
523
555
  clearDraft?(): boolean;
556
+ /** The history plugin's, when it is loaded: true when it went to another step. */
557
+ undo?(): boolean;
558
+ redo?(): boolean;
559
+ /** Whether there is a step to go back to, a change not yet a step counting. */
560
+ canUndo?(): boolean;
561
+ canRedo?(): boolean;
562
+ /** What there is now becomes the first step, with nothing before or after it. */
563
+ clearHistory?(): boolean;
524
564
  }
525
565
 
526
566
  export default GridEditor;
@@ -1545,6 +1545,7 @@ function build(instance, baseElem, optionsOrMethod) {
1545
1545
  var label = typeof item.label === "function" ? item.label() : item.label || t(item.labelKey);
1546
1546
  var colour = item.align === "end" ? "btn-primary" : "btn-light";
1547
1547
  var button = labelButton(element("a", { "class": "btn btn-sm " + colour + " ge-add-container ge-add-feature" }), label, iconClass);
1548
+ var acting = typeof item.action === "function";
1548
1549
  addClass(button, item.className || "");
1549
1550
  if (typeof item.hidden === "function" ? item.hidden() : item.hidden) {
1550
1551
  hide(button);
@@ -1554,7 +1555,20 @@ function build(instance, baseElem, optionsOrMethod) {
1554
1555
  "data-ge-feature": name,
1555
1556
  "data-ge-item": index
1556
1557
  });
1558
+ if (acting) {
1559
+ button.setAttribute("data-ge-action", "");
1560
+ if (typeof item.disabled === "function" ? item.disabled() : item.disabled) {
1561
+ addClass(button, "disabled");
1562
+ button.setAttribute("aria-disabled", "true");
1563
+ }
1564
+ }
1557
1565
  button.addEventListener("click", function() {
1566
+ if (acting) {
1567
+ if (!hasClass(button, "disabled")) {
1568
+ item.action(button);
1569
+ }
1570
+ return;
1571
+ }
1558
1572
  if (activeTarget) {
1559
1573
  addToTarget(button, item.source || "tool");
1560
1574
  return;
@@ -1580,7 +1594,7 @@ function build(instance, baseElem, optionsOrMethod) {
1580
1594
  return !!settings.toolbar_drag;
1581
1595
  }
1582
1596
  function makeToolbarDraggable() {
1583
- var buttons = all(mainControls, "[data-ge-toolbar]");
1597
+ var buttons = all(mainControls, "[data-ge-toolbar]:not([data-ge-action])");
1584
1598
  buttons.forEach(function(button) {
1585
1599
  removeClass(button, "ge-palette-button");
1586
1600
  button.removeEventListener("pointerdown", startToolbarDrag);
@@ -2349,6 +2363,58 @@ function build(instance, baseElem, optionsOrMethod) {
2349
2363
  refreshToolbar,
2350
2364
  toolbarItems: function(name) {
2351
2365
  return mainControls ? all(mainControls, '[data-ge-toolbar="feature"][data-ge-feature="' + name + '"]') : [];
2366
+ },
2367
+ getSelected: function() {
2368
+ return panelMode() === "sidebar" ? selected : null;
2369
+ },
2370
+ getActiveTarget: function() {
2371
+ return settings.active_target ? activeTarget : null;
2372
+ },
2373
+ // True when it took: a node that cannot be, or no setting
2374
+ // for it, says nothing, since a plugin putting back what it
2375
+ // remembers cannot know the node is still one
2376
+ setSelected: function(node) {
2377
+ var chosen = panelMode() === "sidebar" && !!node && node !== canvas && canvas.contains(node) && detailsFor.has(node);
2378
+ if (chosen) {
2379
+ changeSelection(node);
2380
+ }
2381
+ return chosen;
2382
+ },
2383
+ setActiveTarget: function(node) {
2384
+ var chosen = !!settings.active_target && isTarget(node);
2385
+ if (chosen) {
2386
+ changeTarget(node);
2387
+ }
2388
+ return chosen;
2389
+ },
2390
+ // What keeps Escape from the selection and the target, and an
2391
+ // inline panel unfolded in a drawer, which Escape leaves alone
2392
+ panelOpen: function() {
2393
+ if (openSettingsState || dialogState) {
2394
+ return true;
2395
+ }
2396
+ if (confirmDialog && hasClass(confirmDialog, "show")) {
2397
+ return true;
2398
+ }
2399
+ return panelMode() === "inline" && all(canvas, ".ge-tools-drawer > .ge-details").some(visible);
2400
+ },
2401
+ // The toolbar and the settings panels are outside the canvas
2402
+ contains: function(node) {
2403
+ if (!node || node.nodeType !== 1) {
2404
+ return false;
2405
+ }
2406
+ if (canvas.contains(node) || mainControls && mainControls.contains(node)) {
2407
+ return true;
2408
+ }
2409
+ if (dialogPanel && dialogPanel.contains(node)) {
2410
+ return true;
2411
+ }
2412
+ if (confirmDialog && confirmDialog.contains(node)) {
2413
+ return true;
2414
+ }
2415
+ return Object.keys(settingsPanels).some(function(mode) {
2416
+ return settingsPanels[mode].contains(node);
2417
+ });
2352
2418
  }
2353
2419
  };
2354
2420
  }
@@ -5113,7 +5179,7 @@ GridEditor.t = translate;
5113
5179
  GridEditor._plainHtml = plainHtml;
5114
5180
  GridEditor.Sortable = null;
5115
5181
  GridEditor.bootstrap = null;
5116
- GridEditor.version = false ? "dev" : "9.0.0-beta.1";
5182
+ GridEditor.version = false ? "dev" : "9.0.0-beta.3";
5117
5183
  GridEditor.locales = {
5118
5184
  en: {
5119
5185
  "tool.move": "Move",
@@ -1546,6 +1546,7 @@
1546
1546
  var label = typeof item.label === "function" ? item.label() : item.label || t(item.labelKey);
1547
1547
  var colour = item.align === "end" ? "btn-primary" : "btn-light";
1548
1548
  var button = labelButton(element("a", { "class": "btn btn-sm " + colour + " ge-add-container ge-add-feature" }), label, iconClass);
1549
+ var acting = typeof item.action === "function";
1549
1550
  addClass(button, item.className || "");
1550
1551
  if (typeof item.hidden === "function" ? item.hidden() : item.hidden) {
1551
1552
  hide(button);
@@ -1555,7 +1556,20 @@
1555
1556
  "data-ge-feature": name,
1556
1557
  "data-ge-item": index
1557
1558
  });
1559
+ if (acting) {
1560
+ button.setAttribute("data-ge-action", "");
1561
+ if (typeof item.disabled === "function" ? item.disabled() : item.disabled) {
1562
+ addClass(button, "disabled");
1563
+ button.setAttribute("aria-disabled", "true");
1564
+ }
1565
+ }
1558
1566
  button.addEventListener("click", function() {
1567
+ if (acting) {
1568
+ if (!hasClass(button, "disabled")) {
1569
+ item.action(button);
1570
+ }
1571
+ return;
1572
+ }
1559
1573
  if (activeTarget) {
1560
1574
  addToTarget(button, item.source || "tool");
1561
1575
  return;
@@ -1581,7 +1595,7 @@
1581
1595
  return !!settings.toolbar_drag;
1582
1596
  }
1583
1597
  function makeToolbarDraggable() {
1584
- var buttons = all(mainControls, "[data-ge-toolbar]");
1598
+ var buttons = all(mainControls, "[data-ge-toolbar]:not([data-ge-action])");
1585
1599
  buttons.forEach(function(button) {
1586
1600
  removeClass(button, "ge-palette-button");
1587
1601
  button.removeEventListener("pointerdown", startToolbarDrag);
@@ -2350,6 +2364,58 @@
2350
2364
  refreshToolbar,
2351
2365
  toolbarItems: function(name) {
2352
2366
  return mainControls ? all(mainControls, '[data-ge-toolbar="feature"][data-ge-feature="' + name + '"]') : [];
2367
+ },
2368
+ getSelected: function() {
2369
+ return panelMode() === "sidebar" ? selected : null;
2370
+ },
2371
+ getActiveTarget: function() {
2372
+ return settings.active_target ? activeTarget : null;
2373
+ },
2374
+ // True when it took: a node that cannot be, or no setting
2375
+ // for it, says nothing, since a plugin putting back what it
2376
+ // remembers cannot know the node is still one
2377
+ setSelected: function(node) {
2378
+ var chosen = panelMode() === "sidebar" && !!node && node !== canvas && canvas.contains(node) && detailsFor.has(node);
2379
+ if (chosen) {
2380
+ changeSelection(node);
2381
+ }
2382
+ return chosen;
2383
+ },
2384
+ setActiveTarget: function(node) {
2385
+ var chosen = !!settings.active_target && isTarget(node);
2386
+ if (chosen) {
2387
+ changeTarget(node);
2388
+ }
2389
+ return chosen;
2390
+ },
2391
+ // What keeps Escape from the selection and the target, and an
2392
+ // inline panel unfolded in a drawer, which Escape leaves alone
2393
+ panelOpen: function() {
2394
+ if (openSettingsState || dialogState) {
2395
+ return true;
2396
+ }
2397
+ if (confirmDialog && hasClass(confirmDialog, "show")) {
2398
+ return true;
2399
+ }
2400
+ return panelMode() === "inline" && all(canvas, ".ge-tools-drawer > .ge-details").some(visible);
2401
+ },
2402
+ // The toolbar and the settings panels are outside the canvas
2403
+ contains: function(node) {
2404
+ if (!node || node.nodeType !== 1) {
2405
+ return false;
2406
+ }
2407
+ if (canvas.contains(node) || mainControls && mainControls.contains(node)) {
2408
+ return true;
2409
+ }
2410
+ if (dialogPanel && dialogPanel.contains(node)) {
2411
+ return true;
2412
+ }
2413
+ if (confirmDialog && confirmDialog.contains(node)) {
2414
+ return true;
2415
+ }
2416
+ return Object.keys(settingsPanels).some(function(mode) {
2417
+ return settingsPanels[mode].contains(node);
2418
+ });
2353
2419
  }
2354
2420
  };
2355
2421
  }
@@ -5114,7 +5180,7 @@
5114
5180
  GridEditor._plainHtml = plainHtml;
5115
5181
  GridEditor.Sortable = null;
5116
5182
  GridEditor.bootstrap = null;
5117
- GridEditor.version = false ? "dev" : "9.0.0-beta.1";
5183
+ GridEditor.version = false ? "dev" : "9.0.0-beta.3";
5118
5184
  GridEditor.locales = {
5119
5185
  en: {
5120
5186
  "tool.move": "Move",