@operato/property-panel 9.0.0-beta.14

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 (156) hide show
  1. package/.editorconfig +29 -0
  2. package/.storybook/main.js +5 -0
  3. package/.storybook/preview.js +52 -0
  4. package/.storybook/server.mjs +8 -0
  5. package/CHANGELOG.md +11 -0
  6. package/LICENSE +21 -0
  7. package/README.md +76 -0
  8. package/demo/index.html +30 -0
  9. package/dist/src/graphql/board.d.ts +6 -0
  10. package/dist/src/graphql/board.js +130 -0
  11. package/dist/src/graphql/board.js.map +1 -0
  12. package/dist/src/graphql/data-subscription.d.ts +5 -0
  13. package/dist/src/graphql/data-subscription.js +24 -0
  14. package/dist/src/graphql/data-subscription.js.map +1 -0
  15. package/dist/src/graphql/favorite-board.d.ts +1 -0
  16. package/dist/src/graphql/favorite-board.js +23 -0
  17. package/dist/src/graphql/favorite-board.js.map +1 -0
  18. package/dist/src/graphql/group.d.ts +7 -0
  19. package/dist/src/graphql/group.js +125 -0
  20. package/dist/src/graphql/group.js.map +1 -0
  21. package/dist/src/graphql/index.d.ts +4 -0
  22. package/dist/src/graphql/index.js +5 -0
  23. package/dist/src/graphql/index.js.map +1 -0
  24. package/dist/src/graphql/play-group.d.ts +13 -0
  25. package/dist/src/graphql/play-group.js +205 -0
  26. package/dist/src/graphql/play-group.js.map +1 -0
  27. package/dist/src/graphql/scenario.d.ts +6 -0
  28. package/dist/src/graphql/scenario.js +69 -0
  29. package/dist/src/graphql/scenario.js.map +1 -0
  30. package/dist/src/index.d.ts +7 -0
  31. package/dist/src/index.js +8 -0
  32. package/dist/src/index.js.map +1 -0
  33. package/dist/src/ox-property-panel.d.ts +46 -0
  34. package/dist/src/ox-property-panel.js +346 -0
  35. package/dist/src/ox-property-panel.js.map +1 -0
  36. package/dist/src/property-panel/abstract-property.d.ts +10 -0
  37. package/dist/src/property-panel/abstract-property.js +53 -0
  38. package/dist/src/property-panel/abstract-property.js.map +1 -0
  39. package/dist/src/property-panel/data-binding/data-binding-mapper.d.ts +58 -0
  40. package/dist/src/property-panel/data-binding/data-binding-mapper.js +380 -0
  41. package/dist/src/property-panel/data-binding/data-binding-mapper.js.map +1 -0
  42. package/dist/src/property-panel/data-binding/data-binding-value-map.d.ts +6 -0
  43. package/dist/src/property-panel/data-binding/data-binding-value-map.js +20 -0
  44. package/dist/src/property-panel/data-binding/data-binding-value-map.js.map +1 -0
  45. package/dist/src/property-panel/data-binding/data-binding-value-range.d.ts +6 -0
  46. package/dist/src/property-panel/data-binding/data-binding-value-range.js +20 -0
  47. package/dist/src/property-panel/data-binding/data-binding-value-range.js.map +1 -0
  48. package/dist/src/property-panel/data-binding/data-binding.d.ts +44 -0
  49. package/dist/src/property-panel/data-binding/data-binding.js +442 -0
  50. package/dist/src/property-panel/data-binding/data-binding.js.map +1 -0
  51. package/dist/src/property-panel/effects/effects.d.ts +24 -0
  52. package/dist/src/property-panel/effects/effects.js +72 -0
  53. package/dist/src/property-panel/effects/effects.js.map +1 -0
  54. package/dist/src/property-panel/effects/property-animation.d.ts +23 -0
  55. package/dist/src/property-panel/effects/property-animation.js +147 -0
  56. package/dist/src/property-panel/effects/property-animation.js.map +1 -0
  57. package/dist/src/property-panel/effects/property-animations.d.ts +22 -0
  58. package/dist/src/property-panel/effects/property-animations.js +70 -0
  59. package/dist/src/property-panel/effects/property-animations.js.map +1 -0
  60. package/dist/src/property-panel/effects/property-event-hover.d.ts +21 -0
  61. package/dist/src/property-panel/effects/property-event-hover.js +193 -0
  62. package/dist/src/property-panel/effects/property-event-hover.js.map +1 -0
  63. package/dist/src/property-panel/effects/property-event-tap.d.ts +36 -0
  64. package/dist/src/property-panel/effects/property-event-tap.js +262 -0
  65. package/dist/src/property-panel/effects/property-event-tap.js.map +1 -0
  66. package/dist/src/property-panel/effects/property-event.d.ts +22 -0
  67. package/dist/src/property-panel/effects/property-event.js +64 -0
  68. package/dist/src/property-panel/effects/property-event.js.map +1 -0
  69. package/dist/src/property-panel/effects/property-shadow.d.ts +23 -0
  70. package/dist/src/property-panel/effects/property-shadow.js +66 -0
  71. package/dist/src/property-panel/effects/property-shadow.js.map +1 -0
  72. package/dist/src/property-panel/effects/value-converter.d.ts +1 -0
  73. package/dist/src/property-panel/effects/value-converter.js +17 -0
  74. package/dist/src/property-panel/effects/value-converter.js.map +1 -0
  75. package/dist/src/property-panel/inspector/inspector.d.ts +27 -0
  76. package/dist/src/property-panel/inspector/inspector.js +357 -0
  77. package/dist/src/property-panel/inspector/inspector.js.map +1 -0
  78. package/dist/src/property-panel/shapes/shapes.d.ts +26 -0
  79. package/dist/src/property-panel/shapes/shapes.js +312 -0
  80. package/dist/src/property-panel/shapes/shapes.js.map +1 -0
  81. package/dist/src/property-panel/specifics/specific-properties-builder.d.ts +16 -0
  82. package/dist/src/property-panel/specifics/specific-properties-builder.js +138 -0
  83. package/dist/src/property-panel/specifics/specific-properties-builder.js.map +1 -0
  84. package/dist/src/property-panel/specifics/specifics.d.ts +25 -0
  85. package/dist/src/property-panel/specifics/specifics.js +84 -0
  86. package/dist/src/property-panel/specifics/specifics.js.map +1 -0
  87. package/dist/src/property-panel/styles/styles.d.ts +23 -0
  88. package/dist/src/property-panel/styles/styles.js +269 -0
  89. package/dist/src/property-panel/styles/styles.js.map +1 -0
  90. package/dist/src/types.d.ts +43 -0
  91. package/dist/src/types.js +2 -0
  92. package/dist/src/types.js.map +1 -0
  93. package/dist/stories/index.stories.d.ts +22 -0
  94. package/dist/stories/index.stories.js +121 -0
  95. package/dist/stories/index.stories.js.map +1 -0
  96. package/dist/stories/input-table-property.stories.d.ts +21 -0
  97. package/dist/stories/input-table-property.stories.js +84 -0
  98. package/dist/stories/input-table-property.stories.js.map +1 -0
  99. package/dist/test/ox-property-panel.test.d.ts +1 -0
  100. package/dist/test/ox-property-panel.test.js +24 -0
  101. package/dist/test/ox-property-panel.test.js.map +1 -0
  102. package/dist/tsconfig.tsbuildinfo +1 -0
  103. package/package.json +108 -0
  104. package/src/graphql/board.ts +144 -0
  105. package/src/graphql/data-subscription.ts +30 -0
  106. package/src/graphql/favorite-board.ts +25 -0
  107. package/src/graphql/group.ts +138 -0
  108. package/src/graphql/index.ts +4 -0
  109. package/src/graphql/play-group.ts +225 -0
  110. package/src/graphql/scenario.ts +79 -0
  111. package/src/index.ts +8 -0
  112. package/src/ox-property-panel.ts +347 -0
  113. package/src/property-panel/abstract-property.ts +67 -0
  114. package/src/property-panel/data-binding/data-binding-mapper.ts +412 -0
  115. package/src/property-panel/data-binding/data-binding-value-map.ts +19 -0
  116. package/src/property-panel/data-binding/data-binding-value-range.ts +19 -0
  117. package/src/property-panel/data-binding/data-binding.ts +464 -0
  118. package/src/property-panel/effects/effects.ts +77 -0
  119. package/src/property-panel/effects/property-animation.ts +155 -0
  120. package/src/property-panel/effects/property-animations.ts +74 -0
  121. package/src/property-panel/effects/property-event-hover.ts +212 -0
  122. package/src/property-panel/effects/property-event-tap.ts +269 -0
  123. package/src/property-panel/effects/property-event.ts +73 -0
  124. package/src/property-panel/effects/property-shadow.ts +77 -0
  125. package/src/property-panel/effects/value-converter.ts +17 -0
  126. package/src/property-panel/inspector/inspector.ts +407 -0
  127. package/src/property-panel/shapes/shapes.ts +321 -0
  128. package/src/property-panel/specifics/specific-properties-builder.ts +152 -0
  129. package/src/property-panel/specifics/specifics.ts +81 -0
  130. package/src/property-panel/styles/styles.ts +287 -0
  131. package/src/types.ts +63 -0
  132. package/stories/index.stories.ts +134 -0
  133. package/stories/input-table-property.stories.ts +96 -0
  134. package/test/ox-property-panel.test.ts +32 -0
  135. package/themes/app-theme.css +138 -0
  136. package/themes/calendar-theme.css +61 -0
  137. package/themes/dark.css +51 -0
  138. package/themes/grist-theme.css +175 -0
  139. package/themes/help-theme.css +57 -0
  140. package/themes/layout-theme.css +94 -0
  141. package/themes/light.css +51 -0
  142. package/themes/material-theme.css +23 -0
  143. package/themes/md-typescale-styles.css +100 -0
  144. package/themes/oops-theme.css +22 -0
  145. package/themes/report-theme.css +47 -0
  146. package/themes/spacing.css +23 -0
  147. package/themes/state-color.css +6 -0
  148. package/themes/tooltip-theme.css +11 -0
  149. package/translations/en.json +723 -0
  150. package/translations/ja.json +727 -0
  151. package/translations/ko.json +727 -0
  152. package/translations/ms.json +609 -0
  153. package/translations/zh.json +726 -0
  154. package/tsconfig.json +25 -0
  155. package/web-dev-server.config.mjs +27 -0
  156. package/web-test-runner.config.mjs +41 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import '@operato/i18n/ox-i18n.js'
6
+ import '@operato/input/ox-input-color.js'
7
+
8
+ import { css, html, LitElement } from 'lit'
9
+ import { property } from 'lit/decorators.js'
10
+
11
+ import { Properties } from '@hatiolab/things-scene'
12
+ import { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'
13
+
14
+ import { convert } from './value-converter.js'
15
+
16
+ /**
17
+ * 컴포넌트의 그림자 속성을 편집하는 element
18
+ *
19
+ * Example:
20
+ * <property-shadow
21
+ * @change="${e => { this.shadow = e.target.value }}"
22
+ * value="${this.shadow}"
23
+ * ></property-shadow>
24
+ */
25
+
26
+ export class PropertyShadow extends LitElement {
27
+ static styles = [
28
+ PropertyGridStyles,
29
+ css`
30
+ :host {
31
+ display: flex;
32
+ }
33
+ `
34
+ ]
35
+
36
+ @property({ type: Object }) value?: Properties
37
+
38
+ firstUpdated() {
39
+ this.renderRoot.addEventListener('change', this.onValueChange.bind(this))
40
+ }
41
+
42
+ render() {
43
+ const value = this.value || {}
44
+
45
+ return html`
46
+ <div class="property-grid">
47
+ <label> <ox-i18n msgid="label.shadowOffsetX">offset-X</ox-i18n> </label>
48
+ <input type="number" value-key="left" .value=${value.left} />
49
+
50
+ <label> <ox-i18n msgid="label.shadowOffsetY">offset-Y</ox-i18n> </label>
51
+ <input type="number" value-key="top" .value=${value.top} />
52
+
53
+ <label> <ox-i18n msgid="label.shadowSize">Size</ox-i18n> </label>
54
+ <input type="number" value-key="blurSize" .value=${value.blurSize} />
55
+
56
+ <label class="icon-only-label color"><md-icon>format_color_fill</md-icon></label>
57
+ <ox-input-color value-key="color" .value=${value.color}> </ox-input-color>
58
+ </div>
59
+ `
60
+ }
61
+
62
+ onValueChange(e: Event) {
63
+ var element = e.target as HTMLElement
64
+ var key = element.getAttribute('value-key')
65
+
66
+ if (!key) {
67
+ return
68
+ }
69
+
70
+ this.value = {
71
+ ...this.value,
72
+ [key]: convert(element)
73
+ }
74
+
75
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
76
+ }
77
+ }
@@ -0,0 +1,17 @@
1
+ export function convert(element: any) {
2
+ switch (element.tagName) {
3
+ case 'INPUT':
4
+ switch (element.type) {
5
+ case 'checkbox':
6
+ return element.checked
7
+ case 'number':
8
+ return Number(element.value) || 0
9
+ case 'text':
10
+ return String(element.value)
11
+ }
12
+ break
13
+
14
+ default:
15
+ return element.value
16
+ }
17
+ }
@@ -0,0 +1,407 @@
1
+ import '@operato/input/ox-input-search.js'
2
+
3
+ import { css, html, unsafeCSS, LitElement, PropertyValues, TemplateResult } from 'lit'
4
+ import { property, state } from 'lit/decorators.js'
5
+
6
+ // TODO test Sortable
7
+ // import Sortable from 'sortablejs'
8
+ import { i18next } from '@operato/i18n'
9
+
10
+ import { Component, Container, Scene } from '@hatiolab/things-scene'
11
+
12
+ const ICON_SHELL_INSPECTOR = new URL('../../../../icons/icon-shell-inspector.png', import.meta.url).href
13
+
14
+ export class SceneInspector extends LitElement {
15
+ static styles = [
16
+ css`
17
+ :host {
18
+ display: flex;
19
+ flex-direction: column;
20
+
21
+ color: var(--scene-inspector-color);
22
+ --url-icon-shell-inspector: url(${unsafeCSS(ICON_SHELL_INSPECTOR)});
23
+ }
24
+
25
+ ox-input-search {
26
+ --input-search-padding: 3px;
27
+ --input-search-focus-border-bottom: none;
28
+ --input-search-font: normal 16px var(--theme-font);
29
+
30
+ border-radius: 999px;
31
+ box-sizing: border-box;
32
+ border: 1px solid var(--md-sys-color-on-secondary-container);
33
+ padding: 0 10px;
34
+ margin: 5px;
35
+ }
36
+
37
+ div[result] {
38
+ flex: 1;
39
+
40
+ display: flex;
41
+ flex-direction: column;
42
+
43
+ overflow-y: auto;
44
+ }
45
+
46
+ .component {
47
+ display: block;
48
+ overflow: hidden;
49
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
50
+ font-size: 14px;
51
+ }
52
+
53
+ .component[selected] {
54
+ background-color: var(--scene-inspector-selected-background-color);
55
+ border-top: var(--scene-inspector-selected-border);
56
+ border-bottom: var(--scene-inspector-selected-border);
57
+ }
58
+ [selected] .type {
59
+ font-weight: bold;
60
+ }
61
+
62
+ span,
63
+ i {
64
+ display: inline-block;
65
+ }
66
+
67
+ span.type {
68
+ text-overflow: ellipses;
69
+ }
70
+
71
+ span.name {
72
+ background-color: var(--scene-inspector-name-background-color);
73
+ border-radius: var(--border-radius);
74
+ padding: 0 4px;
75
+ color: #fff;
76
+ font-size: 0.8em;
77
+ }
78
+
79
+ .eye {
80
+ margin: 0 0 0 5px;
81
+ vertical-align: middle;
82
+ opacity: 0.7;
83
+ font-size: 1.1em;
84
+ color: var(--scene-inspector-eye-icon-color);
85
+ }
86
+
87
+ .collapsed::before,
88
+ .extended::before,
89
+ .collapsespace::before {
90
+ background: var(--url-icon-shell-inspector) no-repeat;
91
+ width: 16px;
92
+ height: 18px;
93
+ display: inline-block;
94
+ content: '';
95
+ opacity: 0.6;
96
+ }
97
+
98
+ .collapsed::before {
99
+ background-position: 100% -195px;
100
+ }
101
+
102
+ .extended::before {
103
+ background-position: 100% -295px;
104
+ }
105
+
106
+ .collapsespace::before {
107
+ background-position: 100% -395px;
108
+ opacity: 0.9;
109
+ width: 16px;
110
+ }
111
+ .collapsed,
112
+ .extended,
113
+ .collapsespace {
114
+ border-left: 1px dotted rgba(0, 0, 0, 0.1);
115
+ }
116
+
117
+ pre {
118
+ display: inline;
119
+ }
120
+ `
121
+ ]
122
+
123
+ @property({ type: Object }) scene?: Scene
124
+
125
+ @state() private searchText: string = ''
126
+
127
+ private _extendedMap: any
128
+ private show: boolean = false
129
+ private count: number = -1
130
+
131
+ disconnectScene(scene?: Scene) {
132
+ if (scene) {
133
+ scene.off('selected', undefined, this)
134
+ scene.off('execute', undefined, this)
135
+ scene.off('undo', undefined, this)
136
+ scene.off('redo', undefined, this)
137
+ }
138
+ }
139
+
140
+ disconnectedCallback() {
141
+ super.disconnectedCallback()
142
+
143
+ this.disconnectScene(this.scene)
144
+ delete this._extendedMap
145
+ }
146
+
147
+ render() {
148
+ this.count = 0
149
+
150
+ return html`
151
+ <ox-input-search
152
+ .placeholder=${i18next.t('text.search with type, id or tag')}
153
+ autofocus
154
+ @change=${(e: Event) => (this.searchText = ((e.target as HTMLInputElement).value || '').toLowerCase())}
155
+ ></ox-input-search>
156
+
157
+ <div result>${!this.scene ? html`` : this.renderComponent(this.scene.root, 0)}</div>
158
+ `
159
+ }
160
+
161
+ firstUpdated() {
162
+ dispatchEvent(new Event('resize'))
163
+
164
+ this.renderRoot.addEventListener('click', this._onclick.bind(this) as EventListener)
165
+ this.renderRoot.addEventListener('dblclick', this._ondblclick.bind(this) as EventListener)
166
+ }
167
+
168
+ refresh() {
169
+ let selected = this.scene?.selected || []
170
+
171
+ selected.forEach(component => {
172
+ let parent = component.parent
173
+ while (parent && !this.extendedMap.get(parent)) {
174
+ this.extendedMap.set(parent, true)
175
+ parent = parent.parent
176
+ }
177
+ })
178
+
179
+ this.requestUpdate()
180
+ }
181
+
182
+ updated(change: PropertyValues<this>) {
183
+ if (change.has('scene')) {
184
+ let oldScene = change.get('scene') as Scene
185
+
186
+ if (oldScene) {
187
+ this.disconnectScene(oldScene)
188
+ delete this._extendedMap
189
+ }
190
+
191
+ if (this.scene && this.scene.root) {
192
+ this.scene.on('selected', this.refresh, this)
193
+ this.scene.on('execute', this.refresh, this)
194
+ this.scene.on('undo', this.refresh, this)
195
+ this.scene.on('redo', this.refresh, this)
196
+
197
+ this.refresh()
198
+ }
199
+ }
200
+
201
+ // TODO test Sortable
202
+ // this.updateComplete.then(() => {
203
+ // this.renderRoot.querySelectorAll('[sortable]').forEach(sortable => {
204
+ // new Sortable(sortable as HTMLElement, this.sortableConfig)
205
+ // })
206
+ // })
207
+ }
208
+
209
+ // TODO test Sortable
210
+ // sortableConfig: Sortable.Options = {
211
+ // group: 'inspector',
212
+ // animation: 150,
213
+ // draggable: '.component',
214
+ // swapThreshold: 1,
215
+ // onSort: this.onSort.bind(this)
216
+ // }
217
+
218
+ // TODO test Sortable
219
+ // onSort(e: Sortable.SortableEvent) {
220
+ // if (!this.scene) return
221
+
222
+ // var component = (e.item as HTMLElement & { component: Component }).component
223
+ // var to_container = (e.to as HTMLElement & { component: Component }).component as Container
224
+ // var to_index = e.newIndex! - 1
225
+
226
+ // this.scene.move(component, to_container, to_index)
227
+
228
+ // this.show = false
229
+ // this.updateComplete.then(() => {
230
+ // this.show = true
231
+ // })
232
+ // }
233
+
234
+ _onclick(e: MouseEvent) {
235
+ e.stopPropagation()
236
+
237
+ var targetElement = e.target as HTMLElement & { component: Component }
238
+ var classList = targetElement.classList
239
+ var component
240
+
241
+ while (!component && targetElement) {
242
+ component = targetElement.component
243
+
244
+ if (component) break
245
+
246
+ targetElement = targetElement.parentNode as HTMLElement & { component: Component }
247
+
248
+ if (!targetElement || targetElement === this.renderRoot) break
249
+ }
250
+
251
+ if (component) {
252
+ if (classList.contains('eye')) {
253
+ this.toggleHidden(component)
254
+ } else if (classList.contains('extended') || classList.contains('collapsed')) {
255
+ this.toggleExtended(component)
256
+ }
257
+
258
+ this.selectComponent(component, e.shiftKey)
259
+ } else {
260
+ if (classList.contains('inspector')) {
261
+ this.show = !this.show
262
+ this.style.height = this.show ? '100%' : ''
263
+ }
264
+ }
265
+
266
+ this.requestUpdate()
267
+ }
268
+
269
+ _ondblclick(e: MouseEvent) {
270
+ e.stopPropagation()
271
+
272
+ var targetElement = e.target as HTMLElement & { component: Component }
273
+ var component
274
+
275
+ while (!component && targetElement) {
276
+ component = targetElement.component
277
+
278
+ if (component) break
279
+
280
+ targetElement = targetElement.parentNode as HTMLElement & { component: Component }
281
+
282
+ if (!targetElement || targetElement === this.renderRoot) break
283
+ }
284
+
285
+ if (component && component.isContainer()) {
286
+ this.toggleExtended(component)
287
+ }
288
+
289
+ this.requestUpdate()
290
+ }
291
+
292
+ get extendedMap() {
293
+ if (!this._extendedMap) {
294
+ this._extendedMap = new WeakMap()
295
+ }
296
+
297
+ return this._extendedMap
298
+ }
299
+
300
+ getNodeHandleClass(component: Component) {
301
+ if (component.isContainer() && (component as Container).components.length > 0) {
302
+ return !!this.extendedMap.get(component) ? 'extended' : 'collapsed'
303
+ } else {
304
+ return 'collapsespace'
305
+ }
306
+ }
307
+
308
+ isExtended(component: Component) {
309
+ return !!this.extendedMap.get(component)
310
+ }
311
+
312
+ toggleExtended(component: Component) {
313
+ var extended = this.isExtended(component)
314
+
315
+ if (extended) {
316
+ this.extendedMap.delete(component)
317
+ } else {
318
+ this.extendedMap.set(component, !extended)
319
+ }
320
+
321
+ this.requestUpdate()
322
+ }
323
+
324
+ toggleHidden(component: Component) {
325
+ component.set('hidden', !component.hidden)
326
+
327
+ this.requestUpdate()
328
+ }
329
+
330
+ selectComponent(component: Component, append: boolean = false) {
331
+ const selected = this.scene!.selected
332
+
333
+ if (append) {
334
+ const idx = selected.findIndex(s => s === component)
335
+ if (idx != -1) {
336
+ selected.splice(idx, 1)
337
+ this.scene!.selected = [...selected]
338
+ } else {
339
+ this.scene!.selected = [...selected, component]
340
+ }
341
+ } else {
342
+ this.scene!.selected = [component]
343
+ }
344
+
345
+ component.trigger('reactionreset')
346
+ component.trigger('reaction')
347
+
348
+ this.requestUpdate()
349
+ }
350
+
351
+ shouldBeShown(component: Component, counting: boolean = false): boolean {
352
+ const { type, name, id, tag } = component.state
353
+ const found =
354
+ !this.searchText || `${type} ${name || ''} ${id || ''} ${tag || ''}`.toLowerCase().search(this.searchText) > -1
355
+
356
+ if (counting && found) {
357
+ this.count++
358
+ }
359
+
360
+ const foundChildren = ((component as Container).components || []).filter((child: Component) =>
361
+ this.shouldBeShown(child, counting)
362
+ ).length
363
+
364
+ return !!(found || foundChildren > 0)
365
+ }
366
+
367
+ renderComponent(component: Component, depth: number): TemplateResult {
368
+ if (!component) {
369
+ return html``
370
+ }
371
+
372
+ if (!this.shouldBeShown(component, depth == 0)) {
373
+ return html``
374
+ }
375
+
376
+ const children = (component.isContainer() && (component as Container).components) || []
377
+ const extended = this.isExtended(component) ? children.filter(child => this.shouldBeShown(child)) : []
378
+ const { type, id, tag, class: clazz } = component.state
379
+
380
+ const name = (id ? `#${id}` : '') + (tag ? `@${tag}` : '') + (clazz ? `.(${clazz})` : '')
381
+
382
+ return html`
383
+ <div
384
+ class="component"
385
+ ?selected=${(this.scene?.selected || []).indexOf(component) > -1}
386
+ .component=${component}
387
+ ?sortable=${component.isContainer()}
388
+ >
389
+ <span>
390
+ ${depth > 0
391
+ ? html`
392
+ <md-icon class="eye">${component.get('hidden') ? 'visibility_off' : 'visibility'}</md-icon>
393
+ <pre>${' '.repeat(depth)}</pre>
394
+ `
395
+ : html` <pre>${' '.repeat(depth + 2)}</pre> `}
396
+
397
+ <span class=${this.getNodeHandleClass(component)}> </span>
398
+
399
+ <span class="type">${depth == 0 ? html`ROOT(count: ${this.count})` : type}</span>
400
+ ${name ? html` <span class="name">${name}</span> ` : html``}
401
+ </span>
402
+
403
+ ${extended.map(child => this.renderComponent(child, depth + 1))}
404
+ </div>
405
+ `
406
+ }
407
+ }