@pictogrammers/components 0.5.14 → 0.5.17

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.
Files changed (153) hide show
  1. package/package.json +1 -1
  2. package/pg/autocompleteItem/__examples__/basic/basic.html +3 -0
  3. package/pg/autocompleteItem/autocompleteItem.css +55 -0
  4. package/pg/autocompleteItem/autocompleteItem.html +1 -0
  5. package/pg/autocompleteItem/autocompleteItem.ts +65 -0
  6. package/pg/button/button.css +5 -0
  7. package/pg/buttonMenu/buttonMenu.ts +1 -1
  8. package/pg/inputCombobox/__examples__/basic/basic.ts +33 -0
  9. package/pg/inputCombobox/inputCombobox.ts +158 -0
  10. package/pg/inputCombobox/inputCombobox.ts.tmp.44252.751480cb81cc +158 -0
  11. package/pg/inputCombobox/inputCombobox.ts.tmp.44252.dcea847c40a8 +156 -0
  12. package/pg/inputNumber/inputNumber.ts +31 -13
  13. package/pg/inputPill/inputPill.html +6 -0
  14. package/pg/inputPill/inputPill.html.tmp.26852.84ac63f4c46f +6 -0
  15. package/pg/inputPill/inputPill.ts +41 -0
  16. package/pg/inputPills/__examples__/basic/basic.html +9 -0
  17. package/pg/inputPills/__examples__/basic/basic.html.tmp.26852.4771e4cad5b7 +9 -0
  18. package/pg/inputPills/__examples__/basic/basic.ts.tmp.26852.d8fe41df18bd +0 -0
  19. package/pg/inputPixelEditor/README.md +104 -69
  20. package/pg/inputPixelEditor/README.md.tmp.42596.658de5f0a6f5 +0 -0
  21. package/pg/inputPixelEditor/__examples__/basic/basic.ts +6 -5
  22. package/pg/inputPixelEditor/inputPixelEditor.ts +95 -23
  23. package/pg/inputPixelEditor/inputPixelEditor.ts.tmp.38516.96529dd82670 +1703 -0
  24. package/pg/inputPixelEditor/inputPixelEditor.ts.tmp.42596.48ecc3ad9c72 +1724 -0
  25. package/pg/inputPixelEditor/utils/bitmapToMask.ts +113 -79
  26. package/pg/inputPixelEditor/utils/getLassoPixels.ts +51 -0
  27. package/pg/inputRange/inputRange.css +7 -0
  28. package/pg/inputSelect/__examples__/basic/basic.ts +2 -2
  29. package/pg/inputSelect/inputSelect.css +1 -1
  30. package/pg/inputSelect/inputSelect.ts +62 -5
  31. package/pg/inputText/README.md +6 -6
  32. package/pg/inputText/__examples__/basic/basic.ts +1 -1
  33. package/pg/inputText/inputText.css +2 -2
  34. package/pg/inputText copy/README.md +38 -0
  35. package/pg/inputText copy/inputText.css +41 -0
  36. package/pg/inputText copy/inputText.html +1 -0
  37. package/pg/inputText copy/inputText.spec.ts +59 -0
  38. package/pg/inputText copy/inputText.ts +67 -0
  39. package/pg/inputTextarea/README.md +39 -0
  40. package/pg/inputTextarea/__examples__/basic/basic.html +9 -0
  41. package/pg/inputTextarea/__examples__/basic/basic.ts +30 -0
  42. package/pg/inputTextarea/inputTextarea.ts +121 -0
  43. package/pg/inputTextarea copy/README.md +39 -0
  44. package/pg/inputTextarea copy/inputTextarea.css +41 -0
  45. package/pg/inputTextarea copy/inputTextarea.html +1 -0
  46. package/pg/inputTextarea copy/inputTextarea.spec.ts +59 -0
  47. package/pg/inputTextarea copy/inputTextarea.ts +79 -0
  48. package/pg/inputTextareaAutocomplete/README.md +70 -0
  49. package/pg/inputTextareaAutocomplete/__examples__/basic/basic.ts +67 -0
  50. package/pg/inputTextareaAutocomplete/inputTextareaAutocomplete.ts +267 -0
  51. package/pg/node/README.md +35 -0
  52. package/pg/node/__examples__/basic/basic.ts +34 -0
  53. package/pg/node/index.ts +3 -0
  54. package/pg/node/node.css +53 -0
  55. package/pg/node/node.html +5 -0
  56. package/pg/node/node.ts +270 -0
  57. package/pg/nodeEditorLink/nodeEditorLink.css +69 -0
  58. package/pg/nodeEditorLink/nodeEditorLink.css.tmp.1408.09e961fd0dcc +69 -0
  59. package/pg/nodeEditorLink/nodeEditorLink.html +9 -0
  60. package/pg/nodeEditorNumber/nodeEditorNumber.css +59 -0
  61. package/pg/nodeEditorNumber/nodeEditorNumber.ts +57 -0
  62. package/pg/nodeEditorRange/nodeEditorRange.css +23 -0
  63. package/pg/nodeEditorRange/nodeEditorRange.ts +69 -0
  64. package/pg/nodeEditorText/__examples__/basic/basic.html +9 -0
  65. package/pg/nodeEditorText/__examples__/basic/basic.ts +30 -0
  66. package/pg/nodeEditorText/nodeEditorText.css +17 -0
  67. package/pg/nodeEditorText/nodeEditorText.html +4 -0
  68. package/pg/nodeEditorText/nodeEditorText.ts +57 -0
  69. package/pg/nodeEditorText copy/README.md +35 -0
  70. package/pg/nodeEditorText copy/nodeEditorText.css +49 -0
  71. package/pg/nodeEditorText copy/nodeEditorText.html +4 -0
  72. package/pg/nodeEditorText copy/nodeEditorText.ts +50 -0
  73. package/pg/nodeEditorTextArray/nodeEditorTextArray.css +68 -0
  74. package/pg/nodeEditorTextArray/nodeEditorTextArray.html +9 -0
  75. package/pg/nodeEditorTextArray/nodeEditorTextArray.ts +162 -0
  76. package/pg/nodeEntry/nodeEntry.css +61 -0
  77. package/pg/nodeEntry/nodeEntry.ts +164 -0
  78. package/pg/nodeEntry/nodeEntry.ts.tmp.28724.dda67762bca5 +164 -0
  79. package/pg/nodeInputText/nodeInputText.css +75 -0
  80. package/pg/nodeInputText/nodeInputText.html +4 -0
  81. package/pg/nodeInputText/nodeInputText.ts +105 -0
  82. package/pg/nodeOutput/nodeOutput.css +32 -0
  83. package/pg/nodeResize/README.md +3 -0
  84. package/pg/nodeResize/THINKING.md +81 -0
  85. package/pg/nodeResize/THINKING.md.tmp.24812.99a70ba81062 +81 -0
  86. package/pg/nodeResize/basic/basic.ts +17 -0
  87. package/pg/nodeResize/dragUtil.ts +105 -0
  88. package/pg/nodeResize/dragUtil.ts.tmp.34372.787464c73309 +75 -0
  89. package/pg/nodeResize/nodeResize.css +187 -0
  90. package/pg/nodeResize/nodeResize.html +9 -0
  91. package/pg/nodeResize/nodeResize.ts +156 -0
  92. package/pg/nodes/README.md +177 -0
  93. package/pg/nodes/__examples__/basic/basic.html +33 -0
  94. package/pg/nodes/__examples__/basic/basic.ts +716 -0
  95. package/pg/nodes/__examples__/basic/exampleNodes.ts +129 -0
  96. package/pg/nodes/__examples__/basic/exampleScripts.ts +129 -0
  97. package/pg/nodes/__examples__/basic/keystore.ts +38 -0
  98. package/pg/nodes/executeInSandbox.ts +32 -0
  99. package/pg/nodes/index.ts +3 -0
  100. package/pg/nodes/nodes.css +69 -0
  101. package/pg/nodes/nodes.html +6 -0
  102. package/pg/nodes/nodes.ts +1240 -0
  103. package/pg/nodes copy/nodes.css +41 -0
  104. package/pg/nodes copy/nodes.html +1 -0
  105. package/pg/overlayContextMenu/__examples__/filter/filter.ts +87 -0
  106. package/pg/overlayContextMenu/overlayContextMenu.css +14 -0
  107. package/pg/overlayContextMenu/overlayContextMenu.html +4 -3
  108. package/pg/overlayContextMenu/overlayContextMenu.ts +6 -2
  109. package/pg/overlayContextMenu/overlayContextMenu.ts.tmp.37088.530ff1c0a321 +0 -0
  110. package/pg/overlayMenu/overlayMenu.css +3 -1
  111. package/pg/overlayMenu/overlayMenu.ts +11 -2
  112. package/pg/overlayMenu/overlayMenu.ts.tmp.44252.9bb22fd59ede +80 -0
  113. package/pg/overlaySelectMenu/overlaySelectMenu.css +2 -0
  114. package/pg/overlaySubMenu/overlaySubMenu.css +8 -6
  115. package/pg/poco/README.md +22 -0
  116. package/pg/poco/__examples__/basic/basic.html +11 -0
  117. package/pg/poco/__examples__/basic/basic.ts +95 -0
  118. package/pg/poco/__examples__/basic/examples.ts +258 -0
  119. package/pg/poco/__examples__/basic/myFont.ts +1300 -0
  120. package/pg/poco/index.ts +3 -0
  121. package/pg/poco/mockPoco.ts +640 -0
  122. package/pg/poco/poco.css +7 -0
  123. package/pg/poco/poco.html +1 -0
  124. package/pg/poco/poco.ts +75 -0
  125. package/pg/popover/README.md +47 -0
  126. package/pg/popover/__examples__/basic/basic.html +3 -0
  127. package/pg/popover/popover.html +3 -0
  128. package/pg/popover/popover.ts +44 -0
  129. package/pg/popoverAutocomplete/__examples__/basic/basic.html +4 -0
  130. package/pg/popoverAutocomplete/__examples__/basic/basic.ts +46 -0
  131. package/pg/popoverAutocomplete/popoverAutocomplete.css +25 -0
  132. package/pg/popoverAutocomplete/popoverAutocomplete.html +1 -0
  133. package/pg/popoverAutocomplete/popoverAutocomplete.ts +134 -0
  134. package/pg/popoverAutocompleteItem/popoverAutocompleteItem.css +69 -0
  135. package/pg/popoverAutocompleteItem/popoverAutocompleteItem.ts +90 -0
  136. package/pg/table/__examples__/basic/basic.ts +1 -0
  137. package/pg/tableCellFileLocal/tableCellFileLocal.html +3 -0
  138. package/pg/tableCellFileLocal/tableCellFileLocal.html.tmp.20484.68ee2e30710e +3 -0
  139. package/pg/tableCellFileLocal/tableCellFileLocal.ts +44 -0
  140. package/pg/tableCellSelect/tableCellSelect.html +3 -0
  141. package/pg/tableCellSelect/tableCellSelect.html.tmp.41808.99c1a6f14340 +3 -0
  142. package/pg/tableCellSelect/tableCellSelect.ts +51 -0
  143. package/pg/tree/__examples__/basic/basic.ts +12 -5
  144. package/pg/tree/tree.html +1 -1
  145. package/pg/tree/tree.ts +385 -227
  146. package/pg/tree/tree.ts.tmp.38376.07d376a04f41 +343 -0
  147. package/pg/tree/tree.ts.tmp.38376.2a04599ade9f +361 -0
  148. package/pg/tree/tree.ts.tmp.38376.6cb2c663d476 +0 -0
  149. package/pg/tree/tree.ts.tmp.38376.ac5af1aff2b0 +393 -0
  150. package/pg/tree/tree.ts.tmp.38376.ac9acfc4f95f +324 -0
  151. package/pg/treeItem/treeItem.ts +536 -558
  152. package/pg/treeItem/treeItem.ts.tmp.38376.145d3121d648 +530 -0
  153. package/pg/treeItem/treeItem.ts.tmp.38376.b5224d48e5c0 +0 -0
@@ -26,6 +26,16 @@ export default class PgInputNumber extends HTMLElement {
26
26
  connectedCallback() {
27
27
  this.$input.addEventListener('input', this.handleInput.bind(this));
28
28
  this.$input.addEventListener('change', this.handleChange.bind(this));
29
+ this.$input.addEventListener('beforeinput', (e: KeyboardEvent) => {
30
+ switch (e.key) {
31
+ case 'ArrowUp':
32
+ this.#triggerInput(this.value + this.step);
33
+ break;
34
+ case 'ArrowDown':
35
+ this.#triggerInput(this.value - this.step);
36
+ break;
37
+ }
38
+ });
29
39
  this.$buttonMinus.addEventListener('increment', (e: any) => {
30
40
  this.#triggerInput(this.value - this.step);
31
41
  });
@@ -33,18 +43,10 @@ export default class PgInputNumber extends HTMLElement {
33
43
  this.#triggerInput(this.value + this.step);
34
44
  });
35
45
  this.$buttonMinus.addEventListener('finish', (e: any) => {
36
- this.dispatchEvent(new CustomEvent('change', {
37
- detail: {
38
- value: this.value,
39
- },
40
- }));
46
+ this.#triggerChange(this.value);
41
47
  });
42
48
  this.$buttonPlus.addEventListener('finish', (e: any) => {
43
- this.dispatchEvent(new CustomEvent('change', {
44
- detail: {
45
- value: this.value,
46
- },
47
- }));
49
+ this.#triggerChange(this.value);
48
50
  });
49
51
  }
50
52
 
@@ -54,6 +56,12 @@ export default class PgInputNumber extends HTMLElement {
54
56
  if (changes.value && !this.skipValue) {
55
57
  this.$input.value = `${this.value}`;
56
58
  }
59
+ if (changes.min) {
60
+ this.$input.min = `${this.min}`;
61
+ }
62
+ if (changes.max) {
63
+ this.$input.max = `${this.max}`;
64
+ }
57
65
  if (changes.placeholder) {
58
66
  this.$input.placeholder = this.placeholder;
59
67
  }
@@ -64,6 +72,9 @@ export default class PgInputNumber extends HTMLElement {
64
72
  }
65
73
 
66
74
  #triggerInput(value) {
75
+ if (value < this.min || value > this.max) {
76
+ return;
77
+ }
67
78
  this.dispatchEvent(
68
79
  new CustomEvent('input', {
69
80
  detail: {
@@ -81,14 +92,21 @@ export default class PgInputNumber extends HTMLElement {
81
92
  this.#triggerInput(value);
82
93
  }
83
94
 
84
- handleChange(e) {
95
+ #triggerChange(value) {
96
+ if (value < this.min || value > this.max) {
97
+ return;
98
+ }
85
99
  this.dispatchEvent(
86
100
  new CustomEvent('change', {
87
101
  detail: {
88
- value: e.target.value,
89
- name: e.name
102
+ value: value,
103
+ name: this.name,
90
104
  }
91
105
  })
92
106
  );
93
107
  }
108
+
109
+ handleChange(e) {
110
+ this.#triggerChange(e.target.value);
111
+ }
94
112
  }
@@ -0,0 +1,6 @@
1
+ <span part="label"></span>
2
+ <button part="remove" type="button" aria-label="Remove">
3
+ <svg part="removeIcon" viewBox="0 0 24 24">
4
+ <path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
5
+ </svg>
6
+ </button>
@@ -0,0 +1,6 @@
1
+ <span part="label"></span>
2
+ <button part="remove" type="button" aria-label="Remove">
3
+ <svg part="removeIcon" viewBox="0 0 24 24">
4
+ <path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
5
+ </svg>
6
+ </button>
@@ -0,0 +1,41 @@
1
+ import { Component, Prop, Part } from '@pictogrammers/element';
2
+
3
+ import template from './inputPill.html';
4
+ import style from './inputPill.css';
5
+
6
+ @Component({
7
+ selector: 'pg-input-pill',
8
+ style,
9
+ template,
10
+ })
11
+ export default class PgInputPill extends HTMLElement {
12
+ @Prop() label: string = '';
13
+ @Prop() value: string = '';
14
+
15
+ @Part() $label: HTMLSpanElement;
16
+ @Part() $remove: HTMLButtonElement;
17
+
18
+ #initialized: boolean = false;
19
+
20
+ connectedCallback() {
21
+ // Reconnects re-invoke connectedCallback; guard against duplicate listeners.
22
+ if (this.#initialized) return;
23
+ this.#initialized = true;
24
+ this.$remove.addEventListener('click', () => {
25
+ this.dispatchEvent(
26
+ new CustomEvent('remove', {
27
+ detail: {
28
+ value: this.value,
29
+ label: this.label,
30
+ }
31
+ })
32
+ );
33
+ });
34
+ }
35
+
36
+ render(changes) {
37
+ if (changes.label) {
38
+ this.$label.textContent = this.label;
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,9 @@
1
+ <div class="example">
2
+ <pg-input-pills part="input"></pg-input-pills>
3
+ <div>
4
+ <button part="add" type="button">Add Pill</button>
5
+ </div>
6
+ <div>
7
+ <code>onchange: <span part="value"></span></code>
8
+ </div>
9
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="example">
2
+ <pg-input-pills part="input"></pg-input-pills>
3
+ <div>
4
+ <button part="add" type="button">Add Pill</button>
5
+ </div>
6
+ <div>
7
+ <code>onchange: <span part="value"></span></code>
8
+ </div>
9
+ </div>
@@ -16,20 +16,23 @@ import PgInputPixelEditor, {
16
16
 
17
17
  ## Attributes
18
18
 
19
- | Attributes | Tested | Description |
20
- | ----------- | -------- | ----------- |
21
- | `name` | | Unique name in `pg-form` |
22
- | `width` | | Pixel width. Default `10` |
23
- | `height` | | Pixel height. Default `10` |
24
- | `size` | | Pixel size, minimum value `4`. Default `10` |
25
- | `gridSize` | | Grid spacing between cells. Default `1` |
19
+ | Attributes | Tested | Description |
20
+ | ------------- | -------- | ----------- |
21
+ | `width` | | Pixel width. Default `10` |
22
+ | `height` | | Pixel height. Default `10` |
23
+ | `size` | | Pixel size, minimum value `4`. Default `10` |
24
+ | `gridSize` | | Grid spacing between cells. Default `1` (changing after init does not currently re-render) |
25
+ | `transparent` | | Show checkerboard background. Default `false` |
26
+ | `placeholder` | | Placeholder text (not yet implemented) |
26
27
 
27
28
  ## Events
28
29
 
29
- | Events | Tested | Description |
30
- | ----------- | -------- | ----------- |
31
- | `change` | | `{ detail: { value }` |
32
- | `reference` | | `{ detail: { id, callback } }` |
30
+ | Events | Tested | Description |
31
+ | ------------- | -------- | ----------- |
32
+ | `change` | | `{ detail: { export } }` — debounced, fires 1 second after the last edit |
33
+ | `selectlayer` | | `{ detail: { color, index } }` — fired in cursor input mode |
34
+ | `debug` | | `{ detail: { x, y, width, height, canvas, context, baseLayer, editLayer, noEditLayer, previewLayer } }` — internal layers for debugging previews |
35
+ | `reference` | | `{ detail: { id, callback } }` (not yet implemented) |
33
36
 
34
37
  ```typescript
35
38
  this.$input.addEventListener('reference', (e: any) => {
@@ -46,59 +49,71 @@ See usage for each method below.
46
49
  | Method | Tested | Description |
47
50
  | ---------- | -------- | ----------- |
48
51
  | `getJson(options)` | - | Get JSON file. |
49
- | `getData()` | - | Get layer data. |
50
- | `setData()` | - | Set layer data. |
51
52
  | `setJson(json)` | - | Set JSON file. |
53
+ | `getData()` | - | Get layer data as paths by color. |
54
+ | `setData(data)` | - | Set layer data from paths. |
52
55
  | `reset()` | - | Reset canvas and data. |
56
+ | `clear()` | - | Clear all pixel data (deprecated, will be removed). |
57
+ | `applyTemplate(grid)` | - | Replace all data with a single-layer 2d color-index grid. |
53
58
  | `getExport()` | - | 2d array of pixel color indexes. Already calculated. |
54
- | `getExport(id)` | - | 2d array of pixel color indexes by export size. Minimal perf. |
55
- | `getExportCanvas()` | - | Get new prepopulated HTML canvas, ideal for advanced export screens. |
59
+ | `getExportPath()` | - | SVG path string(s) for the export grid. |
60
+ | `getExportLayerIndexes()` | - | Indexes of layers flagged for export. |
61
+ | `getExportCanvas(options)` | - | Get new prepopulated HTML canvas, ideal for advanced export screens. |
56
62
  | `await getExportPng(options, meta)` | - | Get png image with optional metadata. |
57
- | `undo()` | - | Undo. |
58
- | `hasUndo()` | - | Has undo |
59
- | `hasRedo()` | - | Has redo |
60
- | `redo()` | - | Redo. |
63
+ | `await getSelectionPng(options, meta)` | - | Get png of the current selection bounding box. Requires an active selection. |
64
+ | `await copyPngToClipboard(blob, data)` | - | Copy a png blob and JSON data to the clipboard. |
65
+ | `undo()` | - | Undo (partial — history is not yet recorded). |
66
+ | `hasUndo()` | - | Has undo. |
67
+ | `hasRedo()` | - | Has redo. |
68
+ | `redo()` | - | Redo (not yet implemented). |
61
69
  | `getHistory()` | - | History list. |
62
- | `inputModeSelectRectangle()` | - | Input Mode Select Rectangle |
63
- | `inputModeSelectEllipse()` | - | Input Mode Select Ellipse |
64
- | `inputModeSelectLasso()` | - | Input Mode Lasso |
65
- | `inputModeSelectMagicWand()` | - | Input Mode Magic Wand |
66
- | `inputModePixel()` | - | Input Mode Pixel |
67
- | `inputModeStamp(stamp)` | - | Input Mode Stamp |
68
- | `inputModeLine()` | - | Input Mode Line |
69
- | `inputModeRectangle()` | - | Input Mode Rectangle |
70
- | `inputModeRectangleOutline()` | - | Input Mode Rectangle Outline |
71
- | `inputModeEllipse()` | - | Input Mode Ellipse |
72
- | `inputModeEllipseOutline()` | - | Input Mode Ellipse Outline |
73
- | `selectLayer(index)` | - | Select layer. |
74
- | `getLayers()` | - | Get layer array. |
70
+ | `clearHistory()` | - | Clear undo/redo history. |
71
+ | `inputModeCursor()` | - | Input Mode Cursor click to select layer. |
72
+ | `inputModeSelectRectangle()` | - | Input Mode Select Rectangle. |
73
+ | `inputModeSelectEllipse()` | - | Input Mode Select Ellipse. |
74
+ | `inputModeSelectLasso()` | - | Input Mode Lasso. |
75
+ | `inputModeSelectMagicWand()` | - | Input Mode Magic Wand. |
76
+ | `inputModePixel()` | - | Input Mode Pixel. |
77
+ | `inputModePixelSize(size)` | - | Set pixel brush size (not yet implemented). |
78
+ | `inputModeStamp(stamp)` | - | Input Mode Stamp. Accepts a `[x, y][]` offset array; a hover preview is shown. |
79
+ | `inputModeLine()` | - | Input Mode Line. |
80
+ | `inputModeRectangle()` | - | Input Mode Rectangle. |
81
+ | `inputModeRectangleOutline()` | - | Input Mode Rectangle Outline. |
82
+ | `inputModeEllipse()` | - | Input Mode Ellipse. |
83
+ | `inputModeEllipseOutline()` | - | Input Mode Ellipse Outline. |
84
+ | `selectLayers(indexes)` | - | Select one or more layers by index array. |
85
+ | `getLayers()` | - | Get layer index array. |
75
86
  | `addLayer(option)` | - | Add layer. `name`, `type` required. |
76
- | `removeLayer(index)` | - | Remove layer. |
77
- | `flattenLayers(layerIndexes)` | - | Flatten layers. |
78
- | `getColor()` | - | Get selected color |
79
- | `getColors()` | - | Get colors. |
80
- | `getLayerColorIndexes()` | - | Get selected layer colors. |
81
- | `selectColor(index)` | - | Select color. |
82
- | `setColor(index, r, g, b, a)` | - | Set Color. |
83
- | `addColor(r, g, b, a)` | - | Add color. |
84
- | `removeColor(index)` | - | Remove color. |
85
- | `moveColor(startIndex, endIndex)` | - | Move index. |
86
- | `rotateClockwise()` | - | Rotate. |
87
- | `rotateCounterclockwise()` | - | Rotate. |
88
- | `move(x, y[, layer])` | - | Move. |
89
- | `getSelection()` | - | Get selection pixels. |
90
- | `clearSelection()` | - | Clear selection. |
91
- | `moveSelection(x, y)` | - | Move selection. |
92
- | `flipHorizontal()` | - | Flip horizontal selection. |
93
- | `flipVertical()` | - | Flip vertical selection. |
94
- | `invert()` | - | Invert layer. |
95
- | `outline()` | - | Outline layer with selected color. |
96
- | `glow()` | - | Glow layer with selected color. |
97
- | `drawPixels([[x, y, color], ...])` | - | Draw pixels. Color optional. |
98
- | `drawRectangle(x, y, width, height, isOutline)` | - | Draw rectangle |
99
- | `drawEllipse(x, y, width, height, isOutline)` | - | Draw ellipse. |
100
- | `drawLine()` | - | Draw line. |
101
- | `flush()` | - | Flush changes to history. |
87
+ | `removeLayer(index)` | - | Remove layer by index. |
88
+ | `flattenLayers(layerIndexes)` | - | Flatten layers (not yet implemented). |
89
+ | `getColor(index)` | - | Get color by index. |
90
+ | `getColors()` | - | Get all colors. |
91
+ | `getColorAt(x, y)` | - | Get the export color index at a coordinate. |
92
+ | `getLayerAt(x, y)` | - | Get the top-most layer index with a color at a coordinate, or `null`. |
93
+ | `getLayerColorIndexes(layerIndex?)` | - | Get unique color indexes on selected (or given) layer. |
94
+ | `getLayerPaths()` | - | Get SVG path strings per color per layer. |
95
+ | `selectColor(index)` | - | Set the active draw color. |
96
+ | `setColor(index, r, g, b, a)` | - | Update a color by index. |
97
+ | `addColor(r, g, b, a)` | - | Append a color. |
98
+ | `removeColor(index)` | - | Remove a color by index. |
99
+ | `moveColor(startIndex, endIndex)` | - | Move a color (not yet implemented). |
100
+ | `mergeColor(fromIndex, toIndex)` | - | Merge one color into another (not yet implemented). |
101
+ | `rotateClockwise()` | - | Rotate active layer 90° clockwise. |
102
+ | `rotateCounterclockwise()` | - | Rotate active layer 90° counter-clockwise. |
103
+ | `move(x, y)` | - | Translate active layer by x/y pixels. |
104
+ | `flipHorizontal()` | - | Flip active layer horizontally. |
105
+ | `flipVertical()` | - | Flip active layer vertically. |
106
+ | `invert()` | - | Invert active layer (2-color only). |
107
+ | `outline(include?)` | - | Draw outline around active layer with selected color. |
108
+ | `glow(include?)` | - | Draw glow (outer outline) with selected color. |
109
+ | `applyGuides()` | - | Draw guide lines onto the base layer. |
110
+ | `clearGuides()` | - | Clear guide lines (not yet implemented). |
111
+ | `drawGrid(grid, layer?)` | - | Draw a full 2d color-index grid onto a layer. |
112
+ | `drawPixel(x, y, color, layer?)` | - | Draw a single pixel. |
113
+ | `hasSelection()` | - | Returns true when pixels are selected. |
114
+ | `getSelection()` | - | Get selection pixels (not yet implemented). |
115
+ | `clearSelection()` | - | Deselect all pixels. |
116
+ | `moveSelection(x, y)` | - | Translate selection and its pixels by x/y. |
102
117
 
103
118
  ### `getJson(options)` Method
104
119
 
@@ -107,8 +122,8 @@ The `getJson` method allows getting the JSON representation of the current edito
107
122
  ```typescript
108
123
  @Part() $editor: PgInputPixelEditor;
109
124
 
110
- handleSave() {
111
- const json = await this.$editor.save({
125
+ async handleSave() {
126
+ const json = await this.$editor.getJson({
112
127
  // Include history
113
128
  history: true,
114
129
  });
@@ -118,16 +133,13 @@ handleSave() {
118
133
 
119
134
  ### `setJson(json)` Method
120
135
 
121
- The open method allows loading json for previously created images.
136
+ The `setJson` method loads a previously saved JSON file into the editor.
122
137
 
123
138
  ```typescript
124
139
  @Part() $editor: PgInputPixelEditor;
125
140
 
126
- handleOpen() {
127
- const error = await this.$editor.open(json);
128
- if (error) {
129
- throw new Error(error.message);
130
- }
141
+ async handleOpen(json) {
142
+ await this.$editor.setJson(json);
131
143
  }
132
144
  ```
133
145
 
@@ -135,6 +147,14 @@ handleOpen() {
135
147
 
136
148
  ### `change`
137
149
 
150
+ Debounced — fires 1 second after the last edit. The detail contains the cached export grid.
151
+
152
+ ```typescript
153
+ this.$input.addEventListener('change', (e: any) => {
154
+ const { export: grid } = e.detail;
155
+ });
156
+ ```
157
+
138
158
  ### `selectLayer`
139
159
 
140
160
  Using `InputMode.Cursor` individual pixels can be clicked on to select the layer. Note, selecting a layer does not automatically select it. The event must be handled.
@@ -142,10 +162,25 @@ Using `InputMode.Cursor` individual pixels can be clicked on to select the layer
142
162
  ```typescript
143
163
  this.$input.addEventListener('selectlayer', (e: any) => {
144
164
  const { color, index } = e.detail;
145
- this.selectLayers([index]);
165
+ this.$input.selectLayers([index]);
146
166
  })
147
167
  ```
148
168
 
169
+ ## Keyboard Shortcuts
170
+
171
+ The wrapper is focusable (`tabindex="0"`); shortcuts apply while the editor has focus.
172
+
173
+ | Keys | Description |
174
+ | ---- | ----------- |
175
+ | `Escape` | Clear the current selection. |
176
+ | `Delete` | Delete the pixels in the current selection. |
177
+ | `Arrow Keys` | Move the current selection by 1 pixel. |
178
+ | `Shift + Arrow Keys` | Move the current selection by 10 pixels. |
179
+ | `Ctrl + C` | Copy the selection (or the full export when nothing is selected) to the clipboard as a PNG. |
180
+ | `Ctrl + V` | Paste clipboard PNG / easel JSON (work in progress — currently logs metadata only). |
181
+ | `Ctrl + Z` | Undo. |
182
+ | `Ctrl + Shift + Z` / `Ctrl + Y` | Redo. |
183
+
149
184
  ## JSON Format
150
185
 
151
186
  - `width` - Image width.
@@ -360,7 +395,7 @@ To create a repeating 10 pixel grid with an offset `5` and limit `10`. The use c
360
395
 
361
396
  Exports by default include the entire canvas, but can be resized to a specific pixel size or grid. The `x`, `y`, `width`, and `height` are optional.
362
397
 
363
- Use `getExport(id)` with a `id` value to get the data grid. This is ideal for export previews.
398
+ Use `getExport()` to get the cached 2d color-index grid. Use `getExportCanvas(options)` with `x`, `y`, `width`, `height` to crop to a region ideal for export previews.
364
399
 
365
400
  ```json
366
401
  {
@@ -388,7 +423,7 @@ Use `getExport(id)` with a `id` value to get the data grid. This is ideal for ex
388
423
 
389
424
  The history list contains every change made to the canvas. All feature insert an entry into history. Pens and pattern tools will group as to cut down history entries.
390
425
 
391
- Note: Calling the `draw*()` commands programatically will group into a single history item. To create multiple entries call `flush()`.
426
+ Note: Calling the `draw*()` commands programmatically will group into a single history item.
392
427
 
393
428
  - Undo a change
394
429
  - Redo an undo
@@ -253,7 +253,7 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
253
253
  }
254
254
  })
255
255
  );
256
- this.$input.addLayer();
256
+ this.$input.addLayer({ name: 'layer 1', type: 'pixel' });
257
257
  });
258
258
  this.$addLayerReference.addEventListener('click', () => {
259
259
  this.$layers.data.push(
@@ -268,7 +268,7 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
268
268
  }
269
269
  })
270
270
  );
271
- this.$input.addLayer();
271
+ this.$input.addLayer({ name: 'layer 1', type: 'pixel' });
272
272
  });
273
273
  // Colors
274
274
  this.$colors.columns = [{
@@ -346,9 +346,9 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
346
346
  });
347
347
  this.$addColor.addEventListener('click', () => {
348
348
  this.$colors.data.push(createTableItem({
349
- r: 5,
350
- g: 5,
351
- b: 5,
349
+ r: 0,
350
+ g: 0,
351
+ b: 0,
352
352
  a: 1,
353
353
  selected: false,
354
354
  select: {
@@ -361,6 +361,7 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
361
361
  icon: IconTrash
362
362
  }
363
363
  }));
364
+ this.$input.addColor(0, 0, 0, 1);
364
365
  });
365
366
  }
366
367