@pictogrammers/components 0.5.15 → 0.5.18

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 (149) 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/inputPill/inputPill.html +6 -0
  13. package/pg/inputPill/inputPill.html.tmp.26852.84ac63f4c46f +6 -0
  14. package/pg/inputPill/inputPill.ts +41 -0
  15. package/pg/inputPills/__examples__/basic/basic.html +9 -0
  16. package/pg/inputPills/__examples__/basic/basic.html.tmp.26852.4771e4cad5b7 +9 -0
  17. package/pg/inputPills/__examples__/basic/basic.ts.tmp.26852.d8fe41df18bd +0 -0
  18. package/pg/inputPixelEditor/README.md +104 -69
  19. package/pg/inputPixelEditor/README.md.tmp.42596.658de5f0a6f5 +0 -0
  20. package/pg/inputPixelEditor/__examples__/basic/basic.ts +6 -5
  21. package/pg/inputPixelEditor/inputPixelEditor.ts +96 -24
  22. package/pg/inputPixelEditor/inputPixelEditor.ts.tmp.38516.96529dd82670 +1703 -0
  23. package/pg/inputPixelEditor/inputPixelEditor.ts.tmp.42596.48ecc3ad9c72 +1724 -0
  24. package/pg/inputPixelEditor/utils/bitmapToMask.ts +113 -79
  25. package/pg/inputPixelEditor/utils/getLassoPixels.ts +51 -0
  26. package/pg/inputSelect/inputSelect.ts +5 -1
  27. package/pg/inputText/README.md +6 -6
  28. package/pg/inputText/__examples__/basic/basic.ts +1 -1
  29. package/pg/inputText/inputText.css +2 -2
  30. package/pg/inputText copy/README.md +38 -0
  31. package/pg/inputText copy/inputText.css +41 -0
  32. package/pg/inputText copy/inputText.html +1 -0
  33. package/pg/inputText copy/inputText.spec.ts +59 -0
  34. package/pg/inputText copy/inputText.ts +67 -0
  35. package/pg/inputTextarea/README.md +39 -0
  36. package/pg/inputTextarea/__examples__/basic/basic.html +9 -0
  37. package/pg/inputTextarea/__examples__/basic/basic.ts +30 -0
  38. package/pg/inputTextarea/inputTextarea.ts +121 -0
  39. package/pg/inputTextarea copy/README.md +39 -0
  40. package/pg/inputTextarea copy/inputTextarea.css +41 -0
  41. package/pg/inputTextarea copy/inputTextarea.html +1 -0
  42. package/pg/inputTextarea copy/inputTextarea.spec.ts +59 -0
  43. package/pg/inputTextarea copy/inputTextarea.ts +79 -0
  44. package/pg/inputTextareaAutocomplete/README.md +70 -0
  45. package/pg/inputTextareaAutocomplete/__examples__/basic/basic.ts +67 -0
  46. package/pg/inputTextareaAutocomplete/inputTextareaAutocomplete.ts +267 -0
  47. package/pg/node/README.md +35 -0
  48. package/pg/node/__examples__/basic/basic.ts +34 -0
  49. package/pg/node/index.ts +3 -0
  50. package/pg/node/node.css +53 -0
  51. package/pg/node/node.html +5 -0
  52. package/pg/node/node.ts +270 -0
  53. package/pg/nodeEditorLink/nodeEditorLink.css +69 -0
  54. package/pg/nodeEditorLink/nodeEditorLink.css.tmp.1408.09e961fd0dcc +69 -0
  55. package/pg/nodeEditorLink/nodeEditorLink.html +9 -0
  56. package/pg/nodeEditorNumber/nodeEditorNumber.css +59 -0
  57. package/pg/nodeEditorNumber/nodeEditorNumber.ts +57 -0
  58. package/pg/nodeEditorRange/nodeEditorRange.css +23 -0
  59. package/pg/nodeEditorRange/nodeEditorRange.ts +69 -0
  60. package/pg/nodeEditorText/__examples__/basic/basic.html +9 -0
  61. package/pg/nodeEditorText/__examples__/basic/basic.ts +30 -0
  62. package/pg/nodeEditorText/nodeEditorText.css +17 -0
  63. package/pg/nodeEditorText/nodeEditorText.html +4 -0
  64. package/pg/nodeEditorText/nodeEditorText.ts +57 -0
  65. package/pg/nodeEditorText copy/README.md +35 -0
  66. package/pg/nodeEditorText copy/nodeEditorText.css +49 -0
  67. package/pg/nodeEditorText copy/nodeEditorText.html +4 -0
  68. package/pg/nodeEditorText copy/nodeEditorText.ts +50 -0
  69. package/pg/nodeEditorTextArray/nodeEditorTextArray.css +68 -0
  70. package/pg/nodeEditorTextArray/nodeEditorTextArray.html +9 -0
  71. package/pg/nodeEditorTextArray/nodeEditorTextArray.ts +162 -0
  72. package/pg/nodeEntry/nodeEntry.css +61 -0
  73. package/pg/nodeEntry/nodeEntry.ts +164 -0
  74. package/pg/nodeEntry/nodeEntry.ts.tmp.28724.dda67762bca5 +164 -0
  75. package/pg/nodeInputText/nodeInputText.css +75 -0
  76. package/pg/nodeInputText/nodeInputText.html +4 -0
  77. package/pg/nodeInputText/nodeInputText.ts +105 -0
  78. package/pg/nodeOutput/nodeOutput.css +32 -0
  79. package/pg/nodeResize/README.md +3 -0
  80. package/pg/nodeResize/THINKING.md +81 -0
  81. package/pg/nodeResize/THINKING.md.tmp.24812.99a70ba81062 +81 -0
  82. package/pg/nodeResize/basic/basic.ts +17 -0
  83. package/pg/nodeResize/dragUtil.ts +105 -0
  84. package/pg/nodeResize/dragUtil.ts.tmp.34372.787464c73309 +75 -0
  85. package/pg/nodeResize/nodeResize.css +187 -0
  86. package/pg/nodeResize/nodeResize.html +9 -0
  87. package/pg/nodeResize/nodeResize.ts +156 -0
  88. package/pg/nodes/README.md +177 -0
  89. package/pg/nodes/__examples__/basic/basic.html +33 -0
  90. package/pg/nodes/__examples__/basic/basic.ts +716 -0
  91. package/pg/nodes/__examples__/basic/exampleNodes.ts +129 -0
  92. package/pg/nodes/__examples__/basic/exampleScripts.ts +129 -0
  93. package/pg/nodes/__examples__/basic/keystore.ts +38 -0
  94. package/pg/nodes/executeInSandbox.ts +32 -0
  95. package/pg/nodes/index.ts +3 -0
  96. package/pg/nodes/nodes.css +69 -0
  97. package/pg/nodes/nodes.html +6 -0
  98. package/pg/nodes/nodes.ts +1240 -0
  99. package/pg/nodes copy/nodes.css +41 -0
  100. package/pg/nodes copy/nodes.html +1 -0
  101. package/pg/overlayContextMenu/__examples__/filter/filter.ts +87 -0
  102. package/pg/overlayContextMenu/overlayContextMenu.css +14 -0
  103. package/pg/overlayContextMenu/overlayContextMenu.html +4 -3
  104. package/pg/overlayContextMenu/overlayContextMenu.ts +6 -2
  105. package/pg/overlayContextMenu/overlayContextMenu.ts.tmp.37088.530ff1c0a321 +0 -0
  106. package/pg/overlayMenu/overlayMenu.css +3 -1
  107. package/pg/overlayMenu/overlayMenu.ts +11 -2
  108. package/pg/overlayMenu/overlayMenu.ts.tmp.44252.9bb22fd59ede +80 -0
  109. package/pg/overlaySelectMenu/overlaySelectMenu.css +2 -0
  110. package/pg/overlaySubMenu/overlaySubMenu.css +8 -6
  111. package/pg/poco/README.md +22 -0
  112. package/pg/poco/__examples__/basic/basic.html +11 -0
  113. package/pg/poco/__examples__/basic/basic.ts +95 -0
  114. package/pg/poco/__examples__/basic/examples.ts +258 -0
  115. package/pg/poco/__examples__/basic/myFont.ts +1300 -0
  116. package/pg/poco/index.ts +3 -0
  117. package/pg/poco/mockPoco.ts +640 -0
  118. package/pg/poco/poco.css +7 -0
  119. package/pg/poco/poco.html +1 -0
  120. package/pg/poco/poco.ts +75 -0
  121. package/pg/popover/README.md +47 -0
  122. package/pg/popover/__examples__/basic/basic.html +3 -0
  123. package/pg/popover/popover.html +3 -0
  124. package/pg/popover/popover.ts +44 -0
  125. package/pg/popoverAutocomplete/__examples__/basic/basic.html +4 -0
  126. package/pg/popoverAutocomplete/__examples__/basic/basic.ts +46 -0
  127. package/pg/popoverAutocomplete/popoverAutocomplete.css +25 -0
  128. package/pg/popoverAutocomplete/popoverAutocomplete.html +1 -0
  129. package/pg/popoverAutocomplete/popoverAutocomplete.ts +134 -0
  130. package/pg/popoverAutocompleteItem/popoverAutocompleteItem.css +69 -0
  131. package/pg/popoverAutocompleteItem/popoverAutocompleteItem.ts +90 -0
  132. package/pg/table/__examples__/basic/basic.ts +1 -0
  133. package/pg/tableCellFileLocal/tableCellFileLocal.html +3 -0
  134. package/pg/tableCellFileLocal/tableCellFileLocal.html.tmp.20484.68ee2e30710e +3 -0
  135. package/pg/tableCellFileLocal/tableCellFileLocal.ts +44 -0
  136. package/pg/tableCellSelect/tableCellSelect.html +3 -0
  137. package/pg/tableCellSelect/tableCellSelect.html.tmp.41808.99c1a6f14340 +3 -0
  138. package/pg/tableCellSelect/tableCellSelect.ts +51 -0
  139. package/pg/tree/__examples__/basic/basic.ts +12 -5
  140. package/pg/tree/tree.html +1 -1
  141. package/pg/tree/tree.ts +385 -227
  142. package/pg/tree/tree.ts.tmp.38376.07d376a04f41 +343 -0
  143. package/pg/tree/tree.ts.tmp.38376.2a04599ade9f +361 -0
  144. package/pg/tree/tree.ts.tmp.38376.6cb2c663d476 +0 -0
  145. package/pg/tree/tree.ts.tmp.38376.ac5af1aff2b0 +393 -0
  146. package/pg/tree/tree.ts.tmp.38376.ac9acfc4f95f +324 -0
  147. package/pg/treeItem/treeItem.ts +536 -558
  148. package/pg/treeItem/treeItem.ts.tmp.38376.145d3121d648 +530 -0
  149. package/pg/treeItem/treeItem.ts.tmp.38376.b5224d48e5c0 +0 -0
@@ -0,0 +1,156 @@
1
+ import { Component, Prop, Part } from '@pictogrammers/element';
2
+
3
+ import template from './nodeResize.html';
4
+ import style from './nodeResize.css';
5
+ import { drag } from './dragUtil';
6
+
7
+ @Component({
8
+ selector: 'pg-node-resize',
9
+ style,
10
+ template,
11
+ })
12
+ export default class PgNodeResize extends HTMLElement {
13
+
14
+ @Prop() gridSize: number = 16;
15
+ @Prop() x: number = 0;
16
+ @Prop() y: number = 0;
17
+ @Prop() width: number = 12;
18
+ @Prop() height: number = 3;
19
+ @Prop() minWidth: number = 12;
20
+ @Prop() minHeight: number = 3;
21
+
22
+ @Part() $header: HTMLDivElement;
23
+ @Part() $northWest: HTMLDivElement;
24
+ @Part() $north: HTMLDivElement;
25
+ @Part() $northEast: HTMLDivElement;
26
+ @Part() $west: HTMLDivElement;
27
+ @Part() $east: HTMLDivElement;
28
+ @Part() $southWest: HTMLDivElement;
29
+ @Part() $south: HTMLDivElement;
30
+ @Part() $southEast: HTMLDivElement;
31
+
32
+ connectedCallback() {
33
+ let startX = 0, startY = 0, startWidth = 0, startHeight = 0;
34
+
35
+ const start = () => {
36
+ startX = this.x;
37
+ startY = this.y;
38
+ startWidth = this.width;
39
+ startHeight = this.height;
40
+ this.classList.toggle('preview', true);
41
+ };
42
+
43
+ // wDir: -1 = west edge moves (x + width change), 0 = no width, 1 = east edge (width only)
44
+ // hDir: -1 = north edge moves (y + height change), 0 = no height, 1 = south edge (height only)
45
+ const addHandle = (source: HTMLElement, wDir: -1 | 0 | 1, hDir: -1 | 0 | 1) => {
46
+ drag({
47
+ source,
48
+ gridSize: this.gridSize,
49
+ start,
50
+ move: (dx, dy) => {
51
+ const gs = this.gridSize;
52
+
53
+ // Snap units — must mirror dragUtil's snapUnits exactly
54
+ const snapDx = Math.floor((dx + gs / 2) / gs);
55
+ const snapDy = Math.floor((dy + gs / 2) / gs);
56
+
57
+ // Snapped dimension in grid units, clamped to min (what the anchor currently reflects)
58
+ const snappedW = wDir !== 0 ? Math.max(startWidth + wDir * snapDx, this.minWidth) : startWidth;
59
+ const snappedH = hDir !== 0 ? Math.max(startHeight + hDir * snapDy, this.minHeight) : startHeight;
60
+
61
+ // Pixel-accurate cursor tracking, clamped so the preview never goes below min.
62
+ // When clamped, effectivePx === snappedPx and the delta becomes 0 (overlay freezes).
63
+ const effectiveWPx = wDir !== 0 ? Math.max(startWidth * gs + wDir * dx, this.minWidth * gs) : startWidth * gs;
64
+ const effectiveHPx = hDir !== 0 ? Math.max(startHeight * gs + hDir * dy, this.minHeight * gs) : startHeight * gs;
65
+
66
+ // Sub-pixel delta from the snapped anchor position
67
+ const dw = effectiveWPx - snappedW * gs;
68
+ const dh = effectiveHPx - snappedH * gs;
69
+
70
+ // For west/north handles the opposite edge is fixed, so x/y shift opposite to size.
71
+ this.style.setProperty('--node-resize-delta-x', `${wDir === -1 ? -dw : 0}px`);
72
+ this.style.setProperty('--node-resize-delta-width', `${dw}px`);
73
+ this.style.setProperty('--node-resize-delta-y', `${hDir === -1 ? -dh : 0}px`);
74
+ this.style.setProperty('--node-resize-delta-height', `${dh}px`);
75
+
76
+ const atMinW = wDir !== 0 && startWidth * gs + wDir * dx < this.minWidth * gs;
77
+ const atMinH = hDir !== 0 && startHeight * gs + hDir * dy < this.minHeight * gs;
78
+ source.classList.toggle('stop', atMinW || atMinH);
79
+ },
80
+ snap: (dx, dy) => {
81
+ this.emit(...this.#compute(startX, startY, startWidth, startHeight, dx, dy, wDir, hDir));
82
+ },
83
+ end: (dx, dy, complete) => {
84
+ if (complete) {
85
+ this.emit(...this.#compute(startX, startY, startWidth, startHeight, dx, dy, wDir, hDir));
86
+ } else {
87
+ this.emit(startX, startY, startWidth, startHeight);
88
+ }
89
+ source.classList.toggle('stop', false);
90
+ this.classList.toggle('preview', false);
91
+ this.style.setProperty('--node-resize-delta-x', '0px');
92
+ this.style.setProperty('--node-resize-delta-y', '0px');
93
+ this.style.setProperty('--node-resize-delta-width', '0px');
94
+ this.style.setProperty('--node-resize-delta-height', '0px');
95
+ },
96
+ });
97
+ };
98
+
99
+ addHandle(this.$northWest, -1, -1);
100
+ addHandle(this.$north, 0, -1);
101
+ addHandle(this.$northEast, 1, -1);
102
+ addHandle(this.$west, -1, 0);
103
+ addHandle(this.$east, 1, 0);
104
+ addHandle(this.$southWest, -1, 1);
105
+ addHandle(this.$south, 0, 1);
106
+ addHandle(this.$southEast, 1, 1);
107
+
108
+ // Header: translate the whole node — no resize, both x and y move together.
109
+ // The node is not moved while dragging; drag events let the host draw
110
+ // snapped previews and commit the final position on release.
111
+ let didDrag = false;
112
+ drag({
113
+ source: this.$header,
114
+ gridSize: this.gridSize,
115
+ start: () => {
116
+ didDrag = false;
117
+ this.dispatchEvent(new CustomEvent('dragstart'));
118
+ },
119
+ snap: (dx, dy) => {
120
+ didDrag = true;
121
+ this.dispatchEvent(new CustomEvent('dragmove', { detail: { dx, dy } }));
122
+ },
123
+ end: (dx, dy, complete) => {
124
+ this.dispatchEvent(new CustomEvent('dragend', { detail: { dx, dy, complete } }));
125
+ },
126
+ });
127
+ this.$header.addEventListener('click', (e: MouseEvent) => {
128
+ // The click after a drag must not change the selection.
129
+ if (didDrag) return;
130
+ this.dispatchEvent(new CustomEvent('select', {
131
+ detail: { shiftKey: e.shiftKey, ctrlKey: e.ctrlKey },
132
+ }));
133
+ });
134
+ }
135
+
136
+ render(_changes: any) {}
137
+
138
+ #compute(
139
+ startX: number, startY: number,
140
+ startWidth: number, startHeight: number,
141
+ dx: number, dy: number,
142
+ wDir: -1 | 0 | 1, hDir: -1 | 0 | 1
143
+ ): [number, number, number, number] {
144
+ const newWidth = wDir !== 0 ? Math.max(startWidth + wDir * dx, this.minWidth) : startWidth;
145
+ const newHeight = hDir !== 0 ? Math.max(startHeight + hDir * dy, this.minHeight) : startHeight;
146
+ const newX = wDir === -1 ? startX + (startWidth - newWidth) : startX;
147
+ const newY = hDir === -1 ? startY + (startHeight - newHeight) : startY;
148
+ return [newX, newY, newWidth, newHeight];
149
+ }
150
+
151
+ emit(x: number, y: number, width: number, height: number) {
152
+ this.dispatchEvent(new CustomEvent('change', {
153
+ detail: { x, y, width, height },
154
+ }));
155
+ }
156
+ }
@@ -0,0 +1,177 @@
1
+ # `<pg-nodes>`
2
+
3
+ The `pg-nodes` component renders an interactive connected node graph.
4
+
5
+ ```typescript
6
+ import '@pictogrammers/components/pgNodes';
7
+ ```
8
+
9
+ ```html
10
+ <pg-nodes part="script"></pg-nodes>
11
+ ```
12
+
13
+ ## Attributes
14
+
15
+ | Attributes | Tested | Description |
16
+ | ----------- | -------- | ----------- |
17
+ | `items` | | Node list |
18
+
19
+ > Note: All nodes are sized off a `1rem` grid.
20
+
21
+ ## Events
22
+
23
+ | Events | Tested | Description |
24
+ | ----------- | -------- | ----------- |
25
+ | change | | `{ detail: { index, item[, field] }` |
26
+ | input | | `{ detail: { index, item[, field] }` |
27
+ | statechange | | `{ detail: { nodeId, state }` |
28
+
29
+ ## Methods
30
+
31
+ | Method | Tested
32
+
33
+ ## CSS Variables
34
+
35
+ | CSS Variables | Default | Description |
36
+ | ------------------- | --------- | ----------- |
37
+ | n/a | | |
38
+
39
+
40
+ ### Editors
41
+
42
+ ```typescript
43
+ this.$script.editors.push(PgNodeEditorText);
44
+ ```
45
+
46
+ ### Nodes
47
+
48
+ Node types define the argument schema and execution handler for reusable logic blocks.
49
+
50
+ ```typescript
51
+ this.$script.nodes.push({
52
+ name: 'setState',
53
+ label: 'Set',
54
+ args: [{
55
+ key: 'key',
56
+ label: 'Key',
57
+ editor: 'Text',
58
+ }, {
59
+ key: 'value',
60
+ label: 'Value',
61
+ editor: 'Text',
62
+ }],
63
+ nodes: [{
64
+ key: 'then',
65
+ label: 'Then',
66
+ }],
67
+ handler: ({ state, nodes, key, value }) => {
68
+ state.set(key, value);
69
+ return nodes;
70
+ },
71
+ }, {
72
+ name: 'equals',
73
+ label: 'State Equals',
74
+ width: 8,
75
+ args: [{
76
+ key: 'key',
77
+ label: 'Key',
78
+ editor: 'Text',
79
+ }, {
80
+ key: 'value',
81
+ label: 'Value',
82
+ editor: 'Text',
83
+ }],
84
+ nodes: [{
85
+ key: 't',
86
+ label: 'True',
87
+ }, {
88
+ key: 'f',
89
+ label: 'False',
90
+ }],
91
+ handler: ({ state, t, f, key, value }) => {
92
+ if (state.get(key) === value) {
93
+ return t;
94
+ } else {
95
+ return f;
96
+ }
97
+ },
98
+ }, {
99
+ name: 'log',
100
+ label: 'Log',
101
+ width: 12,
102
+ args: [{
103
+ key: 'message',
104
+ label: 'Message',
105
+ editor: 'Text',
106
+ }],
107
+ nodes: [{
108
+ key: 'then',
109
+ label: 'Then',
110
+ }],
111
+ handler: ({ state, nodes, message }) => {
112
+ console.log(message);
113
+ return nodes;
114
+ },
115
+ });
116
+ ```
117
+
118
+ ### Items
119
+
120
+ Items are instances of node types positioned on the canvas grid.
121
+
122
+ ```typescript
123
+ // Entry node (id 0 is implicitly type 'entry')
124
+ this.$script.items.push({
125
+ id: 0,
126
+ x: 2,
127
+ y: 2,
128
+ args: {
129
+ key: 'description',
130
+ value: 'Script description',
131
+ },
132
+ nodes: {
133
+ then: [1]
134
+ }
135
+ });
136
+ // Script nodes
137
+ this.$script.items.push({
138
+ id: 1,
139
+ x: 12,
140
+ y: 2,
141
+ node: 'equals',
142
+ args: {
143
+ key: 'health',
144
+ value: 5,
145
+ },
146
+ nodes: {
147
+ t: [2],
148
+ f: [3],
149
+ }
150
+ });
151
+ this.$script.items.push({
152
+ id: 2,
153
+ x: 24,
154
+ y: 2,
155
+ node: 'setState',
156
+ args: {
157
+ key: 'health',
158
+ value: 10,
159
+ },
160
+ nodes: {
161
+ then: []
162
+ }
163
+ });
164
+ this.$script.items.push({
165
+ id: 3,
166
+ x: 24,
167
+ y: 10,
168
+ node: 'setState',
169
+ args: {
170
+ key: 'health',
171
+ value: 20,
172
+ },
173
+ nodes: {
174
+ then: []
175
+ }
176
+ });
177
+ ```
@@ -0,0 +1,33 @@
1
+ <div class="example">
2
+ <div style="display: flex;height: 20rem;align-self: stretch;flex-direction: column;">
3
+ <pg-nodes part="script"></pg-nodes>
4
+ </div>
5
+ <div>
6
+ <button part="debug">Debug</button>
7
+ <button part="play">Play</button>
8
+ <button>Pause</button>
9
+ <button>Previous</button>
10
+ <button part="debugNext">Next</button>
11
+ <button part="restart">Restart</button>
12
+ |
13
+ <button part="save">Save</button>
14
+ |
15
+ <pg-input-select part="files"></pg-input-select>
16
+ <button part="open">Open</button>
17
+ <button part="delete">Delete</button>
18
+ |
19
+ <button part="new">New</button>
20
+ |
21
+ <button part="fullscreen">Fullscreen</button>
22
+ </div>
23
+ <div>
24
+ <code>onchange: <span part="value1"></span></code>
25
+ </div>
26
+ <div>
27
+ <code>oninput: <span part="value2"></span></code>
28
+ </div>
29
+ <h3 style="margin: 0;">State</h3>
30
+ <pre part="state"></pre>
31
+ <h3 style="margin: 0;">Log</h3>
32
+ <pre part="log"></pre>
33
+ </div>