@operato/property-panel 10.20.0 → 10.23.0
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/CHANGELOG.md +32 -0
- package/dist/src/ox-property-panel.d.ts +1 -0
- package/dist/src/ox-property-panel.js +15 -0
- package/dist/src/ox-property-panel.js.map +1 -1
- package/dist/src/property-panel/data-binding/data-binding-mapper.js +20 -7
- package/dist/src/property-panel/data-binding/data-binding-mapper.js.map +1 -1
- package/dist/src/property-panel/data-binding/data-binding.d.ts +4 -0
- package/dist/src/property-panel/data-binding/data-binding.js +167 -56
- package/dist/src/property-panel/data-binding/data-binding.js.map +1 -1
- package/dist/src/property-panel/event-handlers/event-handlers-mapper.js +37 -16
- package/dist/src/property-panel/event-handlers/event-handlers-mapper.js.map +1 -1
- package/dist/src/property-panel/event-handlers/event-handlers-popup.d.ts +1 -0
- package/dist/src/property-panel/event-handlers/event-handlers-popup.js +48 -0
- package/dist/src/property-panel/event-handlers/event-handlers-popup.js.map +1 -1
- package/dist/src/property-panel/event-handlers/event-handlers.d.ts +3 -0
- package/dist/src/property-panel/event-handlers/event-handlers.js +173 -86
- package/dist/src/property-panel/event-handlers/event-handlers.js.map +1 -1
- package/dist/src/property-panel/shapes/shapes.d.ts +2 -0
- package/dist/src/property-panel/shapes/shapes.js +78 -29
- package/dist/src/property-panel/shapes/shapes.js.map +1 -1
- package/dist/src/property-panel/specifics/specifics.js +62 -6
- package/dist/src/property-panel/specifics/specifics.js.map +1 -1
- package/dist/src/property-panel/styles/styles.js +61 -31
- package/dist/src/property-panel/styles/styles.js.map +1 -1
- package/dist/src/property-panel/threed/property-material3d.js +10 -9
- package/dist/src/property-panel/threed/property-material3d.js.map +1 -1
- package/dist/src/property-panel/threed/property-scene3d.js +11 -9
- package/dist/src/property-panel/threed/property-scene3d.js.map +1 -1
- package/dist/src/property-panel/threed/threed.js +41 -18
- package/dist/src/property-panel/threed/threed.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -7,7 +7,7 @@ import '@operato/help/ox-title-with-help.js';
|
|
|
7
7
|
import '@operato/input/ox-buttons-radio.js';
|
|
8
8
|
import '@operato/input/ox-input-data.js';
|
|
9
9
|
import '@operato/i18n/ox-i18n.js';
|
|
10
|
-
import { css, html } from 'lit';
|
|
10
|
+
import { css, html, nothing } from 'lit';
|
|
11
11
|
import { property, query, state } from 'lit/decorators.js';
|
|
12
12
|
import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|
13
13
|
import { PropertyGridStyles } from '@operato/styles/property-grid-styles.js';
|
|
@@ -47,7 +47,15 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
47
47
|
constructor() {
|
|
48
48
|
super(...arguments);
|
|
49
49
|
this.mappingIndex = 0;
|
|
50
|
+
/*
|
|
51
|
+
* A mapping is written to the model only once it names a property. Until then the mapper's
|
|
52
|
+
* edits (rule, source, target...) live here, per tab, so the choice does not snap back to the
|
|
53
|
+
* empty mapping on the next render. Cleared when another shape is selected.
|
|
54
|
+
*/
|
|
55
|
+
this._drafts = {};
|
|
50
56
|
this._dataExpanded = false;
|
|
57
|
+
/* True while a new mapping is being composed and is not yet in the model (no property chosen). */
|
|
58
|
+
this._composing = false;
|
|
51
59
|
this.mapping = {};
|
|
52
60
|
}
|
|
53
61
|
get mappings() {
|
|
@@ -56,13 +64,20 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
56
64
|
}
|
|
57
65
|
firstUpdated() {
|
|
58
66
|
this.renderRoot.addEventListener('change', this.onValueChange.bind(this));
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
/* The tab strip only exists once there is a mapping, so listen from the root (scroll does not
|
|
68
|
+
* bubble; capture catches it) instead of on an element that may not be there yet. */
|
|
69
|
+
this.renderRoot.addEventListener('scroll', e => e.target.id === 'tabs' && this._onTabScroll(), true);
|
|
62
70
|
}
|
|
63
71
|
updated(changes) {
|
|
72
|
+
var _a, _b;
|
|
64
73
|
if (changes.has('value')) {
|
|
65
74
|
this.onValueChanged();
|
|
75
|
+
const selected = (_b = (_a = this.scene) === null || _a === void 0 ? void 0 : _a.selected) === null || _b === void 0 ? void 0 : _b[0];
|
|
76
|
+
if (selected !== this._draftsFor) {
|
|
77
|
+
this._draftsFor = selected;
|
|
78
|
+
this._drafts = {};
|
|
79
|
+
this._composing = false;
|
|
80
|
+
}
|
|
66
81
|
}
|
|
67
82
|
}
|
|
68
83
|
static get scopedElements() {
|
|
@@ -128,20 +143,23 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
128
143
|
<ox-title-with-help topic="board-modeller/data-spread" msgid="label.data-spread"
|
|
129
144
|
>Data Spread</ox-title-with-help
|
|
130
145
|
>
|
|
146
|
+
${this.mappings.length ? html `<span class="count">${this.mappings.length}</span>` : nothing}
|
|
131
147
|
<md-icon
|
|
132
|
-
|
|
148
|
+
class="open-popup"
|
|
133
149
|
@click=${() => this._openBindingPopup()}
|
|
134
150
|
title="open in popup (D)"
|
|
135
151
|
>open_in_new</md-icon
|
|
136
152
|
>
|
|
137
153
|
</legend>
|
|
138
154
|
|
|
155
|
+
${this.mappings.length || this._composing
|
|
156
|
+
? html `
|
|
139
157
|
<div id="tab-header">
|
|
140
158
|
<md-icon
|
|
141
159
|
id="tab-nav-left-button"
|
|
142
160
|
@click=${() => {
|
|
143
|
-
|
|
144
|
-
|
|
161
|
+
this._onTabScrollNavLeft();
|
|
162
|
+
}}
|
|
145
163
|
disabled
|
|
146
164
|
>chevron_left</md-icon
|
|
147
165
|
>
|
|
@@ -150,25 +168,26 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
150
168
|
id="tabs"
|
|
151
169
|
.value=${String(this.mappingIndex)}
|
|
152
170
|
@change=${(e) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
171
|
+
e.stopPropagation();
|
|
172
|
+
this._setMappingIndex(e.target.value);
|
|
173
|
+
}}
|
|
156
174
|
>
|
|
157
175
|
${this.mappings.map((m, i) => html ` <div data-value=${i} data-mapping>${i + 1}</div> `)}
|
|
158
|
-
<div data-value=${this.mappings.length}
|
|
176
|
+
<div data-value=${this.mappings.length} class="add-tab" title="add" @click=${() => (this._composing = true)}>
|
|
177
|
+
+
|
|
178
|
+
</div>
|
|
159
179
|
</ox-buttons-radio>
|
|
160
180
|
|
|
161
181
|
<md-icon
|
|
162
182
|
id="tab-nav-right-button"
|
|
163
183
|
@click=${(e) => {
|
|
164
|
-
|
|
165
|
-
|
|
184
|
+
this._onTabScrollNavRight();
|
|
185
|
+
}}
|
|
166
186
|
disabled
|
|
167
187
|
>chevron_right</md-icon
|
|
168
188
|
>
|
|
169
|
-
</div>
|
|
170
189
|
|
|
171
|
-
|
|
190
|
+
<div binding>
|
|
172
191
|
<md-icon style="font-size:19px" @click=${() => this._clearDataBindingMapper()} title="delete current tab"
|
|
173
192
|
>delete_forever</md-icon
|
|
174
193
|
>
|
|
@@ -176,18 +195,30 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
176
195
|
<md-icon style="font-size:17px" @click=${() => this._copyDataBindingMapper()} title="copy current tab"
|
|
177
196
|
>content_copy</md-icon
|
|
178
197
|
>
|
|
198
|
+
</div>
|
|
179
199
|
</div>
|
|
180
200
|
|
|
201
|
+
|
|
181
202
|
<data-binding-mapper
|
|
182
203
|
@value-change=${(e) => this._onMappingChanged(e)}
|
|
183
204
|
.scene=${this.scene}
|
|
184
|
-
.mapping=${(value.mappings && value.mappings[this.mappingIndex]) || {}}
|
|
205
|
+
.mapping=${(value.mappings && value.mappings[this.mappingIndex]) || this._drafts[this.mappingIndex] || {}}
|
|
185
206
|
.properties=${PROPS}
|
|
186
207
|
>
|
|
187
208
|
</data-binding-mapper>
|
|
209
|
+
`
|
|
210
|
+
: html `
|
|
211
|
+
<button class="add" @click=${() => this._startMapping()}>
|
|
212
|
+
<md-icon>add</md-icon>${i18next.t('button.add-mapping', { defaultValue: 'Add a mapping' })}
|
|
213
|
+
</button>
|
|
214
|
+
`}
|
|
188
215
|
</fieldset>
|
|
189
216
|
`;
|
|
190
217
|
}
|
|
218
|
+
_startMapping() {
|
|
219
|
+
this._composing = true;
|
|
220
|
+
this.mappingIndex = this.mappings.length;
|
|
221
|
+
}
|
|
191
222
|
_setMappingIndex(idx) {
|
|
192
223
|
this.mappingIndex = isNaN(Number(idx)) ? 0 : Number(idx);
|
|
193
224
|
this._onTabScroll();
|
|
@@ -275,6 +306,9 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
275
306
|
/* mapping의 모든 속성이 편집되면, 모델에 반영한다. */
|
|
276
307
|
var mappings = [...(((_a = this.value) === null || _a === void 0 ? void 0 : _a.mappings) || [])];
|
|
277
308
|
if (mapping.property) {
|
|
309
|
+
const drafts = { ...this._drafts };
|
|
310
|
+
delete drafts[this.mappingIndex];
|
|
311
|
+
this._drafts = drafts;
|
|
278
312
|
mappings[this.mappingIndex] = mapping;
|
|
279
313
|
var mappingIdx = this.mappingIndex;
|
|
280
314
|
this._afterRender = () => {
|
|
@@ -290,7 +324,12 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
290
324
|
}));
|
|
291
325
|
await this.requestUpdate();
|
|
292
326
|
}
|
|
293
|
-
else
|
|
327
|
+
else {
|
|
328
|
+
/* Not complete yet: keep what has been chosen so far for this tab. */
|
|
329
|
+
this._drafts = { ...this._drafts, [this.mappingIndex]: mapping };
|
|
330
|
+
}
|
|
331
|
+
/* Only a mapping the model already holds can be "cleared"; an unfinished draft is just unfinished. */
|
|
332
|
+
if (!mapping.property && !mapping.target && mappings[this.mappingIndex]) {
|
|
294
333
|
const { accessor, source } = ((_b = e.detail) === null || _b === void 0 ? void 0 : _b.changed) || {};
|
|
295
334
|
// accessor나 source를 입력중인 경우 tabIndex Change 방지
|
|
296
335
|
if (!accessor && !source) {
|
|
@@ -310,6 +349,8 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
310
349
|
}
|
|
311
350
|
}
|
|
312
351
|
_onTabScroll() {
|
|
352
|
+
if (!this.tabContainer || !this.tabNavLeftButton)
|
|
353
|
+
return;
|
|
313
354
|
if (this.tabContainer.clientWidth == this.tabContainer.scrollWidth) {
|
|
314
355
|
this.tabNavLeftButton.setAttribute('disabled', '');
|
|
315
356
|
this.tabNavRightButton.setAttribute('disabled', '');
|
|
@@ -343,19 +384,86 @@ export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
|
|
|
343
384
|
PropertyDataBinding.styles = [
|
|
344
385
|
PropertyGridStyles,
|
|
345
386
|
css `
|
|
387
|
+
/* The "open in popup" action is the last thing on the title line, at the far right. */
|
|
388
|
+
legend > md-icon.open-popup {
|
|
389
|
+
margin-left: auto;
|
|
390
|
+
--md-icon-size: 16px;
|
|
391
|
+
color: var(--md-sys-color-outline);
|
|
392
|
+
opacity: 0.6;
|
|
393
|
+
cursor: pointer;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
legend > md-icon.open-popup:hover {
|
|
397
|
+
color: var(--md-sys-color-on-surface);
|
|
398
|
+
}
|
|
399
|
+
|
|
346
400
|
#tab-header {
|
|
347
401
|
display: flex;
|
|
348
402
|
align-items: center;
|
|
349
403
|
justify-content: space-between;
|
|
350
404
|
}
|
|
351
405
|
|
|
406
|
+
#tab-header {
|
|
407
|
+
display: flex;
|
|
408
|
+
align-items: center;
|
|
409
|
+
gap: 2px;
|
|
410
|
+
margin-bottom: 6px;
|
|
411
|
+
}
|
|
412
|
+
|
|
352
413
|
#tab-header > md-icon {
|
|
353
414
|
padding: 0;
|
|
354
415
|
margin: 0;
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
416
|
+
--md-icon-size: 18px;
|
|
417
|
+
color: var(--md-sys-color-outline);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
#tab-header > md-icon[disabled] {
|
|
421
|
+
opacity: 0.3;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/* How many there are, as a small muted count next to the title. */
|
|
425
|
+
legend > .count {
|
|
426
|
+
margin-left: 6px;
|
|
427
|
+
padding: 0 6px;
|
|
428
|
+
border-radius: 999px;
|
|
429
|
+
font-size: 0.66rem;
|
|
430
|
+
font-weight: 500;
|
|
431
|
+
line-height: 16px;
|
|
432
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
433
|
+
background: var(--md-sys-color-surface-container-high);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/* Nothing yet: one quiet way in, instead of an empty form for a handler that does not exist. */
|
|
437
|
+
button.add {
|
|
438
|
+
display: inline-flex;
|
|
439
|
+
align-items: center;
|
|
440
|
+
gap: 4px;
|
|
441
|
+
height: 26px;
|
|
442
|
+
padding: 0 10px 0 6px;
|
|
443
|
+
border: 1px dashed var(--md-sys-color-outline-variant);
|
|
444
|
+
border-radius: 999px;
|
|
445
|
+
background: transparent;
|
|
446
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
447
|
+
font: inherit;
|
|
448
|
+
font-size: 0.74rem;
|
|
449
|
+
cursor: pointer;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
button.add md-icon {
|
|
453
|
+
--md-icon-size: 16px;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
button.add:hover {
|
|
457
|
+
color: var(--md-sys-color-on-surface);
|
|
458
|
+
border-color: var(--md-sys-color-outline);
|
|
459
|
+
background: var(--md-sys-color-surface-container-high);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* The "+" chip is an offer until it is pressed; pressed, it is the same chip as the numbered ones. */
|
|
463
|
+
ox-buttons-radio > div.add-tab:not([active]) {
|
|
464
|
+
line-height: 20px;
|
|
465
|
+
border: 1px dashed var(--md-sys-color-outline-variant);
|
|
466
|
+
background: transparent;
|
|
359
467
|
}
|
|
360
468
|
|
|
361
469
|
fieldset[collapsable][collapsed] > :not(legend) {
|
|
@@ -364,77 +472,74 @@ PropertyDataBinding.styles = [
|
|
|
364
472
|
|
|
365
473
|
ox-buttons-radio {
|
|
366
474
|
flex: 1;
|
|
367
|
-
height: 25px;
|
|
368
|
-
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
369
|
-
border-width: 1px 1px 0 1px;
|
|
370
|
-
text-align: center;
|
|
371
|
-
|
|
372
475
|
display: flex;
|
|
476
|
+
gap: 4px;
|
|
373
477
|
padding: 0;
|
|
374
478
|
box-sizing: border-box;
|
|
375
|
-
|
|
376
479
|
width: 0; /* limit width */
|
|
377
480
|
overflow-x: hidden;
|
|
378
481
|
}
|
|
379
482
|
|
|
483
|
+
/* Tabs are quiet chips on the strip; the open one is lifted to the card's surface. */
|
|
380
484
|
ox-buttons-radio > div {
|
|
381
|
-
|
|
382
|
-
border:
|
|
383
|
-
border-width: 0 0 2px 0;
|
|
485
|
+
border: 0;
|
|
486
|
+
border-radius: 999px;
|
|
384
487
|
padding: 0;
|
|
385
488
|
margin: 0;
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
489
|
+
width: 24px;
|
|
490
|
+
height: 22px;
|
|
491
|
+
line-height: 22px;
|
|
492
|
+
text-align: center;
|
|
493
|
+
font-size: 0.72rem;
|
|
494
|
+
box-sizing: border-box;
|
|
495
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
496
|
+
background-color: var(--md-sys-color-surface-container-high);
|
|
497
|
+
cursor: pointer;
|
|
390
498
|
}
|
|
391
499
|
|
|
392
500
|
ox-buttons-radio > div[disabled] {
|
|
393
|
-
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
ox-buttons-radio > div[active] {
|
|
397
|
-
border-color: rgb(242, 71, 28);
|
|
501
|
+
opacity: 0.4;
|
|
398
502
|
}
|
|
399
503
|
|
|
504
|
+
ox-buttons-radio > div[active],
|
|
400
505
|
ox-buttons-radio > div.iron-selected {
|
|
401
|
-
|
|
402
|
-
color: var(--md-sys-color-
|
|
506
|
+
color: var(--md-sys-color-on-secondary-container);
|
|
507
|
+
background-color: var(--md-sys-color-secondary-container);
|
|
403
508
|
}
|
|
404
509
|
|
|
405
510
|
ox-input-data {
|
|
406
|
-
height:
|
|
407
|
-
border-radius: var(--spacing-small);
|
|
511
|
+
height: 220px;
|
|
408
512
|
}
|
|
409
513
|
|
|
410
514
|
div[binding] {
|
|
411
515
|
display: flex;
|
|
412
516
|
flex-direction: row-reverse;
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
padding: 7px 5px 2px 5px;
|
|
517
|
+
gap: 2px;
|
|
518
|
+
margin-left: auto;
|
|
519
|
+
padding-left: 6px;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
#tab-header > md-icon[disabled] {
|
|
523
|
+
display: none;
|
|
421
524
|
}
|
|
422
525
|
|
|
526
|
+
/* Section actions are offers, not content: outline ink at half strength until hovered. */
|
|
423
527
|
md-icon {
|
|
424
528
|
margin-left: 5px;
|
|
425
|
-
color: var(--md-sys-color-
|
|
426
|
-
opacity: 0.
|
|
529
|
+
color: var(--md-sys-color-outline);
|
|
530
|
+
opacity: 0.6;
|
|
427
531
|
cursor: pointer;
|
|
428
532
|
--md-icon-size: 18px;
|
|
429
533
|
}
|
|
430
534
|
|
|
431
535
|
md-icon:hover {
|
|
432
|
-
color: var(--md-sys-color-on-
|
|
536
|
+
color: var(--md-sys-color-on-surface);
|
|
433
537
|
opacity: 1;
|
|
434
538
|
}
|
|
435
539
|
|
|
436
540
|
md-icon[disabled] {
|
|
437
|
-
color:
|
|
541
|
+
color: var(--md-sys-color-outline-variant);
|
|
542
|
+
cursor: default;
|
|
438
543
|
}
|
|
439
544
|
|
|
440
545
|
data-binding-mapper {
|
|
@@ -445,7 +550,7 @@ PropertyDataBinding.styles = [
|
|
|
445
550
|
-webkit-border-radius: 4px;
|
|
446
551
|
-moz-border-radius: 4px;
|
|
447
552
|
border-radius: 4px;
|
|
448
|
-
border: 1px solid
|
|
553
|
+
border: 1px solid var(--md-sys-color-outline-variant);
|
|
449
554
|
font-size: 15px;
|
|
450
555
|
font-weight: 300;
|
|
451
556
|
-webkit-appearance: none;
|
|
@@ -462,12 +567,18 @@ __decorate([
|
|
|
462
567
|
__decorate([
|
|
463
568
|
state()
|
|
464
569
|
], PropertyDataBinding.prototype, "mappingIndex", void 0);
|
|
570
|
+
__decorate([
|
|
571
|
+
state()
|
|
572
|
+
], PropertyDataBinding.prototype, "_drafts", void 0);
|
|
465
573
|
__decorate([
|
|
466
574
|
state()
|
|
467
575
|
], PropertyDataBinding.prototype, "_afterRender", void 0);
|
|
468
576
|
__decorate([
|
|
469
577
|
state()
|
|
470
578
|
], PropertyDataBinding.prototype, "_dataExpanded", void 0);
|
|
579
|
+
__decorate([
|
|
580
|
+
state()
|
|
581
|
+
], PropertyDataBinding.prototype, "_composing", void 0);
|
|
471
582
|
__decorate([
|
|
472
583
|
query('#tabs')
|
|
473
584
|
], PropertyDataBinding.prototype, "tabs", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-binding.js","sourceRoot":"","sources":["../../../../src/property-panel/data-binding/data-binding.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,4BAA4B,CAAA;AACnC,OAAO,qCAAqC,CAAA;AAC5C,OAAO,oCAAoC,CAAA;AAC3C,OAAO,iCAAiC,CAAA;AACxC,OAAO,0BAA0B,CAAA;AAEjC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5D,IAAI,SAAS,GAAG,IAAI,CAAA;AAEpB,6EAA6E;AAC7E,yDAAyD;AACzD,eAAe;AACf,MAAM,KAAK,GAAG;IACZ,EAAE;IACF,MAAM;IACN,CAAC,WAAW,EAAE,YAAY,CAAC;IAC3B,CAAC,aAAa,EAAE,cAAc,CAAC;IAC/B,CAAC,WAAW,EAAE,YAAY,CAAC;IAC3B,OAAO;IACP,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,MAAM;IACN,CAAC,KAAK,EAAE,WAAW,CAAC;IACpB,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,WAAW;IACX,UAAU;IACV,UAAU;IACV,UAAU;IACV,KAAK;CACN,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;IACX,OAAO,OAAO,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AAClG,CAAC,CAAC,CAAA;AAEF,MAAM,OAAO,mBAAoB,SAAQ,mBAAmB,CAAC,gBAAgB,CAAC;IAA9E;;QAsHW,iBAAY,GAAW,CAAC,CAAA;QAExB,kBAAa,GAAY,KAAK,CAAA;QAM/B,YAAO,GAAe,EAAE,CAAA;IAyUlC,CAAC;IAvUC,IAAI,QAAQ;;QACV,OAAO,CAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,KAAI,EAAE,CAAA;IACnC,CAAC;IAED,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAEzE,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;YAChD,IAAI,CAAC,YAAY,EAAE,CAAA;QACrB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CAAC,OAA6B;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,EAAE,CAAA;QACvB,CAAC;IACH,CAAC;IAED,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,qBAAqB,EAAE,iBAAiB;SACzC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI;YAC1B,QAAQ,EAAE,EAAE;SACb,CAAA;QAED,OAAO,IAAI,CAAA;;;;;;;;;yCAS0B,KAAK,CAAC,EAAE,IAAI,EAAE;;;4CAGX,KAAK,CAAC,KAAK,IAAI,EAAE;;;0CAGnB,KAAK,CAAC,GAAG,IAAI,EAAE;;;qDAGJ,KAAK,CAAC,cAAc,IAAI,EAAE;;gFAEC,KAAK,CAAC,IAAI;;;0FAGA,KAAK,CAAC,SAAS;;;;;4FAKb,KAAK,CAAC,UAAU;;;;;;;yCAOnE,CAAC,IAAI,CAAC,aAAa;;mBAEzC,GAAG,EAAE;YACZ,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,aAAa,CAAA;QAC1C,CAAC;;;;;qBAKU,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa;;iDAEtB,KAAK,CAAC,IAAI;;;;;;;;;;qBAUtC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE;;;;;;;;;qBAS9B,GAAG,EAAE;YACZ,IAAI,CAAC,mBAAmB,EAAE,CAAA;QAC5B,CAAC;;;;;;;qBAOQ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;sBACxB,CAAC,CAAQ,EAAE,EAAE;YACrB,CAAC,CAAC,eAAe,EAAE,CAAA;YACnB,IAAI,CAAC,gBAAgB,CAAE,CAAC,CAAC,MAAc,CAAC,KAAK,CAAC,CAAA;QAChD,CAAC;;cAEC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAA,oBAAoB,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC;8BACrF,IAAI,CAAC,QAAQ,CAAC,MAAM,0BAA0B,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;;;;;qBAK/E,CAAC,CAAQ,EAAE,EAAE;YACpB,IAAI,CAAC,oBAAoB,EAAE,CAAA;QAC7B,CAAC;;;;;;;mDAOsC,GAAG,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE;;;4BAG3D,GAAG,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE;mDACb,GAAG,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE;;;;;;0BAM5D,CAAC,CAAc,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;mBACpD,IAAI,CAAC,KAAK;qBACR,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE;wBACxD,KAAK;;;;KAIxB,CAAA;IACH,CAAC;IAED,gBAAgB,CAAC,GAAW;QAC1B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAExD,IAAI,CAAC,YAAY,EAAE,CAAA;IACrB,CAAC;IAED,iBAAiB;QACf,MAAM,CAAC,yBAAyB,CAAC,CAAA;QAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;QAE5C,MAAM,QAAQ,GAAG,IAAI,CAAA;;oBAEL,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;sBACzB,KAAK;iBACV,IAAI,CAAC,KAAK;2BACA,CAAC,CAAc,EAAE,EAAE;YACpC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;gBACjC,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;aACxC,CAAC,CACH,CAAA;QACH,CAAC;;KAEJ,CAAA;QAED,SAAS,CAAC,QAAQ,EAAE;YAClB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;SACtC,CAAC,CAAA;IACJ,CAAC;IAED,uBAAuB;;QACrB,IAAI,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,KAAI,EAAE,CAAC,CAAC,CAAA;QAChD,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;QACrC,IAAI,CAAC,kBAAkB,CACrB,UAAU,EACV,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAC1B,CAAA;IACH,CAAC;IAED,sBAAsB;QACpB,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAA;IAC9D,CAAC;IAED,KAAK,CAAC,uBAAuB;;QAC3B,IAAI,KAAK,GAAG,IAAI,CAAC,YAAY,CAAA;QAC7B,IAAI,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,KAAI,EAAE,CAAC,CAAC,CAAA;QAChD,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAEnD,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QAE7C,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC,EAAE,GAAG,CAAC,CAAA;IACT,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,CAAC,cAAc,CAAA;QAEzB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,EAAE,CAAA;QACrB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;IAC1B,CAAC;IAED,aAAa,CAAC,CAAQ;QACpB,IAAI,OAAO,GAAG,CAAC,CAAC,MAAqB,CAAA;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAE3C,IAAI,KAAK,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAA;QAEjD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QAED,IAAI,CAAC,KAAK,GAAG;YACX,GAAG,IAAI,CAAC,KAAK;YACb,CAAC,GAAG,CAAC,EAAE,KAAK;SACb,CAAA;QAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACrC,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,CAAc;;QACpC,IAAI,OAAO,GAAI,CAAC,CAAC,MAAc,CAAC,OAAO,CAAA;QAEvC,8DAA8D;QAC9D,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK;gBACR,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE;oBAC3G,IAAI,CAAC,IAAI,CAAC;wBAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;oBACrC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;gBAC1B,CAAC,CAAC,CAAA;QACN,CAAC;QAED,qCAAqC;QACrC,IAAI,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,KAAI,EAAE,CAAC,CAAC,CAAA;QAEhD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,OAAO,CAAA;YAErC,IAAI,UAAU,GAAG,IAAI,CAAC,YAAY,CAAA;YAClC,IAAI,CAAC,YAAY,GAAG,GAAG,EAAE;gBACvB,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAA;gBACjC,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAA;YAC9D,CAAC,CAAA;YAED,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;gBACjC,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE;oBACN,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;iBACpC;aACF,CAAC,CACH,CAAA;YAED,MAAM,IAAI,CAAC,aAAa,EAAE,CAAA;QAC5B,CAAC;aAAM,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAChD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAA,MAAA,CAAC,CAAC,MAAM,0CAAE,OAAO,KAAI,EAAE,CAAA;YAEpD,+CAA+C;YAC/C,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzB,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAA;gBAClC,IAAI,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;gBACvD,IAAI,CAAC,YAAY,GAAG,GAAG,EAAE;oBACvB,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAA;gBACvC,CAAC,CAAA;gBACD,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,iBAAiB,EAAE;oBACjC,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE;wBACN,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;qBACpC;iBACF,CAAC,CACH,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;YACnE,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;YAClD,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;QACrD,CAAC;QACD,WAAW;aACN,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;YAClD,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;QACpD,CAAC;QACD,YAAY;aACP,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;YACvG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;YACjD,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;QACrD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;YACjD,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;QACpD,CAAC;IACH,CAAC;IAED,mBAAmB;QACjB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,cAAc,GAAG,QAAQ,CAAA;QACjD,IAAI,CAAC,YAAY,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,CAAA;QAC7D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,cAAc,GAAG,MAAM,CAAA;IACjD,CAAC;IAED,oBAAoB;QAClB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,cAAc,GAAG,QAAQ,CAAA;QACjD,IAAI,CAAC,YAAY,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,CAAA;QAC7D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,cAAc,GAAG,MAAM,CAAA;IACjD,CAAC;;AArcM,0BAAM,GAAG;IACd,kBAAkB;IAClB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6GF;CACF,AAhHY,CAgHZ;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDAAmB;AAClB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDAAc;AAEhC;IAAR,KAAK,EAAE;yDAAyB;AACxB;IAAR,KAAK,EAAE;yDAA+B;AAC9B;IAAR,KAAK,EAAE;0DAA+B;AAEvB;IAAf,KAAK,CAAC,OAAO,CAAC;iDAAmB;AACH;IAA9B,KAAK,CAAC,sBAAsB,CAAC;6DAA+B;AAC7B;IAA/B,KAAK,CAAC,uBAAuB,CAAC;8DAAgC","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/web/icon/icon.js'\nimport '@operato/help/ox-title-with-help.js'\nimport '@operato/input/ox-buttons-radio.js'\nimport '@operato/input/ox-input-data.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, PropertyValues } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\n\nimport { Properties, Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\nimport { openPopup } from '@operato/layout'\nimport { i18next } from '@operato/i18n'\n\nimport { AbstractProperty } from '../abstract-property.js'\nimport { DataBindingMapper } from './data-binding-mapper.js'\n\nvar clipboard = '{}'\n\n// `'tap'` / `'(action)'` 는 *Event Handlers panel* 로 이동 — legacy data-binding\n// 기반 핸들러 UI 는 제거. 데이터는 (`state.event`) 안전망으로 유지하되 편집 진입점\n// 은 새 panel 만.\nconst PROPS = [\n '',\n 'text',\n ['fillStyle', 'fill style'],\n ['strokeStyle', 'stroke style'],\n ['fontColor', 'font color'],\n 'value',\n 'data',\n 'source',\n 'hidden',\n 'started',\n 'play',\n ['ref', 'reference'],\n 'action',\n 'options',\n 'rotate',\n 'dimension',\n 'location',\n 'accessor',\n 'appendum',\n 'tag'\n].map(prop => {\n return typeof prop == 'string' ? { name: prop, label: prop } : { name: prop[0], label: prop[1] }\n})\n\nexport class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {\n static styles = [\n PropertyGridStyles,\n css`\n #tab-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n #tab-header > md-icon {\n padding: 0;\n margin: 0;\n width: 25px;\n height: 25px;\n font-size: x-large;\n border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n }\n\n fieldset[collapsable][collapsed] > :not(legend) {\n display: none;\n }\n\n ox-buttons-radio {\n flex: 1;\n height: 25px;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-width: 1px 1px 0 1px;\n text-align: center;\n\n display: flex;\n padding: 0;\n box-sizing: border-box;\n\n width: 0; /* limit width */\n overflow-x: hidden;\n }\n\n ox-buttons-radio > div {\n background-color: rgba(0, 0, 0, 0.2);\n border: 1px solid rgba(0, 0, 0, 0.07);\n border-width: 0 0 2px 0;\n padding: 0;\n margin: 0;\n color: #fff;\n font-size: 13px;\n max-width: 25px;\n min-width: 25px;\n }\n\n ox-buttons-radio > div[disabled] {\n background-color: rgba(0, 0, 0, 0.1);\n }\n\n ox-buttons-radio > div[active] {\n border-color: rgb(242, 71, 28);\n }\n\n ox-buttons-radio > div.iron-selected {\n background-color: var(--md-sys-color-surface);\n color: var(--md-sys-color-on-surface);\n }\n\n ox-input-data {\n height: 300px;\n border-radius: var(--spacing-small);\n }\n\n div[binding] {\n display: flex;\n flex-direction: row-reverse;\n background-color: var(--md-sys-color-surface);\n color: var(--md-sys-color-on-surface);\n overflow: hidden;\n border-style: solid;\n border-color: rgba(0, 0, 0, 0.2);\n border-image: initial;\n border-width: 0px 1px;\n padding: 7px 5px 2px 5px;\n }\n\n md-icon {\n margin-left: 5px;\n color: var(--md-sys-color-on-secondary-container);\n opacity: 0.8;\n cursor: pointer;\n --md-icon-size: 18px;\n }\n\n md-icon:hover {\n color: var(--md-sys-color-on-primary-container);\n opacity: 1;\n }\n\n md-icon[disabled] {\n color: rgba(0, 0, 0, 0.1);\n }\n\n data-binding-mapper {\n --things-select: {\n min-width: 50%;\n margin-bottom: 10px;\n padding: 3px 20px 2px 5px;\n -webkit-border-radius: 4px;\n -moz-border-radius: 4px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.15);\n font-size: 15px;\n font-weight: 300;\n -webkit-appearance: none;\n };\n }\n `\n ]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n\n @state() mappingIndex: number = 0\n @state() _afterRender?: Function | null\n @state() _dataExpanded: boolean = false\n\n @query('#tabs') tabs!: HTMLElement\n @query('#tab-nav-left-button') tabNavLeftButton!: HTMLElement\n @query('#tab-nav-right-button') tabNavRightButton!: HTMLElement\n\n private mapping: Properties = {}\n\n get mappings() {\n return this.value?.mappings || []\n }\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n\n this.tabContainer.addEventListener('scroll', () => {\n this._onTabScroll()\n })\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('value')) {\n this.onValueChanged()\n }\n }\n\n static get scopedElements() {\n return {\n 'data-binding-mapper': DataBindingMapper\n }\n }\n\n render() {\n const value = this.value || {\n mappings: []\n }\n\n return html`\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/data-binding\" msgid=\"label.identifier\"\n >identifier</ox-title-with-help\n >\n </legend>\n <div class=\"property-grid\">\n <label> <ox-i18n msgid=\"label.id\">ID</ox-i18n> </label>\n <input value-key=\"id\" .value=${value.id || ''} />\n\n <label> <ox-i18n msgid=\"label.class\">Class</ox-i18n> </label>\n <input value-key=\"class\" .value=${value.class || ''} />\n\n <label> <ox-i18n msgid=\"label.tag\">Tag</ox-i18n> </label>\n <input value-key=\"tag\" .value=${value.tag || ''} />\n\n <label> <ox-i18n msgid=\"label.template-prefix\">Template Prefix</ox-i18n> </label>\n <input value-key=\"templatePrefix\" .value=${value.templatePrefix || ''} />\n\n <input id=\"checkbox-ndns\" type=\"checkbox\" value-key=\"ndns\" .checked=${value.ndns} />\n <label for=\"checkbox-ndns\"> <ox-i18n msgid=\"label.ndns\">No Data No Show</ox-i18n> </label>\n\n <input id=\"checkbox-sensitive\" type=\"checkbox\" value-key=\"sensitive\" .checked=${value.sensitive} />\n <label for=\"checkbox-sensitive\">\n <ox-i18n msgid=\"label.intent-sensitive\">Intent Sensitive</ox-i18n>\n </label>\n\n <input id=\"checkbox-persistent\" type=\"checkbox\" value-key=\"persistent\" .checked=${value.persistent} />\n <label for=\"checkbox-persistent\">\n <ox-i18n msgid=\"label.persistent-data\">Persistent Data</ox-i18n>\n </label>\n </div>\n </fieldset>\n\n <fieldset collapsable ?collapsed=${!this._dataExpanded}>\n <legend\n @click=${() => {\n this._dataExpanded = !this._dataExpanded\n }}\n >\n <ox-title-with-help topic=\"board-modeller/initial-data\" msgid=\"label.initial-data\"\n >initial value</ox-title-with-help\n >\n <md-icon>${this._dataExpanded ? 'expand_less' : 'expand_more'}</md-icon>\n </legend>\n <ox-input-data value-key=\"data\" .value=${value.data}> </ox-input-data>\n </fieldset>\n\n <fieldset>\n <legend style=\"box-sizing:border-box;width:100%\">\n <ox-title-with-help topic=\"board-modeller/data-spread\" msgid=\"label.data-spread\"\n >Data Spread</ox-title-with-help\n >\n <md-icon\n style=\"float:right;font-size:medium;margin:0;cursor:pointer\"\n @click=${() => this._openBindingPopup()}\n title=\"open in popup (D)\"\n >open_in_new</md-icon\n >\n </legend>\n\n <div id=\"tab-header\">\n <md-icon\n id=\"tab-nav-left-button\"\n @click=${() => {\n this._onTabScrollNavLeft()\n }}\n disabled\n >chevron_left</md-icon\n >\n\n <ox-buttons-radio\n id=\"tabs\"\n .value=${String(this.mappingIndex)}\n @change=${(e: Event) => {\n e.stopPropagation()\n this._setMappingIndex((e.target as any).value)\n }}\n >\n ${this.mappings.map((m: string, i: number) => html` <div data-value=${i} data-mapping>${i + 1}</div> `)}\n <div data-value=${this.mappings.length} data-mapping disabled>${this.mappings.length + 1}</div>\n </ox-buttons-radio>\n\n <md-icon\n id=\"tab-nav-right-button\"\n @click=${(e: Event) => {\n this._onTabScrollNavRight()\n }}\n disabled\n >chevron_right</md-icon\n >\n </div>\n\n <div binding>\n <md-icon style=\"font-size:19px\" @click=${() => this._clearDataBindingMapper()} title=\"delete current tab\"\n >delete_forever</md-icon\n >\n <md-icon @click=${() => this._pasteDataBindingMapper()} title=\"replace current tab\">content_paste</md-icon>\n <md-icon style=\"font-size:17px\" @click=${() => this._copyDataBindingMapper()} title=\"copy current tab\"\n >content_copy</md-icon\n >\n </div>\n\n <data-binding-mapper\n @value-change=${(e: CustomEvent) => this._onMappingChanged(e)}\n .scene=${this.scene}\n .mapping=${(value.mappings && value.mappings[this.mappingIndex]) || {}}\n .properties=${PROPS}\n >\n </data-binding-mapper>\n </fieldset>\n `\n }\n\n _setMappingIndex(idx: number) {\n this.mappingIndex = isNaN(Number(idx)) ? 0 : Number(idx)\n\n this._onTabScroll()\n }\n\n _openBindingPopup() {\n import('./data-binding-popup.js')\n\n const value = this.value || { mappings: [] }\n\n const template = html`\n <data-binding-popup\n .mappings=${[...(value.mappings || [])]}\n .properties=${PROPS}\n .scene=${this.scene}\n @mappings-change=${(e: CustomEvent) => {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: { mappings: e.detail.mappings }\n })\n )\n }}\n ></data-binding-popup>\n `\n\n openPopup(template, {\n backdrop: true,\n size: 'large',\n title: i18next.t('label.data-spread')\n })\n }\n\n _clearDataBindingMapper() {\n var mappings = [...(this.value?.mappings || [])]\n mappings.splice(this.mappingIndex, 1)\n this.onAfterValueChange(\n 'mappings',\n mappings.filter(m => !!m)\n )\n }\n\n _copyDataBindingMapper() {\n clipboard = JSON.stringify(this.mappings[this.mappingIndex])\n }\n\n async _pasteDataBindingMapper() {\n var index = this.mappingIndex\n var mappings = [...(this.value?.mappings || [])]\n mappings[this.mappingIndex] = JSON.parse(clipboard)\n\n this.onAfterValueChange('mappings', mappings)\n\n setTimeout(() => {\n this._setMappingIndex(index)\n }, 100)\n }\n\n async onValueChanged() {\n await this.updateComplete\n\n if (this._afterRender) {\n this._afterRender()\n } else {\n this._setMappingIndex(0)\n }\n\n this._afterRender = null\n }\n\n onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n var value = this.getValueFromEventTarget(element)\n\n if (!key) {\n return\n }\n\n this.value = {\n ...this.value,\n [key]: value\n }\n\n this.onAfterValueChange(key, value)\n }\n\n get tabContainer() {\n return this.tabs\n }\n\n async _onMappingChanged(e: CustomEvent) {\n var mapping = (e.target as any).mapping\n\n /* data spread target의 변경이 있는 경우, target 컴포넌트들의 태그를 블링크 시킨다 */\n if (mapping && mapping.target) {\n this.scene &&\n this.scene.findAll(mapping.target, this.scene.selected && this.scene.selected[0]).forEach((c: any, i: any) => {\n if (i == 0) c.trigger('decotagreset')\n c.trigger('decotag', {})\n })\n }\n\n /* mapping의 모든 속성이 편집되면, 모델에 반영한다. */\n var mappings = [...(this.value?.mappings || [])]\n\n if (mapping.property) {\n mappings[this.mappingIndex] = mapping\n\n var mappingIdx = this.mappingIndex\n this._afterRender = () => {\n this._setMappingIndex(mappingIdx)\n this.tabContainer.scrollLeft = this.tabContainer.scrollWidth\n }\n\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n mappings: mappings.filter(m => !!m)\n }\n })\n )\n\n await this.requestUpdate()\n } else if (!mapping.target && !mapping.property) {\n const { accessor, source } = e.detail?.changed || {}\n\n // accessor나 source를 입력중인 경우 tabIndex Change 방지\n if (!accessor && !source) {\n mappings[this.mappingIndex] = null\n var nextMappingIdx = Math.max(this.mappingIndex - 1, 0)\n this._afterRender = () => {\n this._setMappingIndex(nextMappingIdx)\n }\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n mappings: mappings.filter(m => !!m)\n }\n })\n )\n }\n }\n }\n\n _onTabScroll() {\n if (this.tabContainer.clientWidth == this.tabContainer.scrollWidth) {\n this.tabNavLeftButton.setAttribute('disabled', '')\n this.tabNavRightButton.setAttribute('disabled', '')\n }\n // left-end\n else if (this.tabContainer.scrollLeft == 0) {\n this.tabNavLeftButton.setAttribute('disabled', '')\n this.tabNavRightButton.removeAttribute('disabled')\n }\n // right-end\n else if (this.tabContainer.scrollLeft + this.tabContainer.clientWidth >= this.tabContainer.scrollWidth) {\n this.tabNavLeftButton.removeAttribute('disabled')\n this.tabNavRightButton.setAttribute('disabled', '')\n } else {\n this.tabNavLeftButton.removeAttribute('disabled')\n this.tabNavRightButton.removeAttribute('disabled')\n }\n }\n\n _onTabScrollNavLeft() {\n this.tabContainer.style.scrollBehavior = 'smooth'\n this.tabContainer.scrollLeft -= this.tabContainer.clientWidth\n this.tabContainer.style.scrollBehavior = 'auto'\n }\n\n _onTabScrollNavRight() {\n this.tabContainer.style.scrollBehavior = 'smooth'\n this.tabContainer.scrollLeft += this.tabContainer.clientWidth\n this.tabContainer.style.scrollBehavior = 'auto'\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"data-binding.js","sourceRoot":"","sources":["../../../../src/property-panel/data-binding/data-binding.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/web/icon/icon.js'\nimport '@operato/help/ox-title-with-help.js'\nimport '@operato/input/ox-buttons-radio.js'\nimport '@operato/input/ox-input-data.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, nothing, PropertyValues } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\n\nimport { Properties, Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\nimport { openPopup } from '@operato/layout'\nimport { i18next } from '@operato/i18n'\n\nimport { AbstractProperty } from '../abstract-property.js'\nimport { DataBindingMapper } from './data-binding-mapper.js'\n\nvar clipboard = '{}'\n\n// `'tap'` / `'(action)'` 는 *Event Handlers panel* 로 이동 — legacy data-binding\n// 기반 핸들러 UI 는 제거. 데이터는 (`state.event`) 안전망으로 유지하되 편집 진입점\n// 은 새 panel 만.\nconst PROPS = [\n '',\n 'text',\n ['fillStyle', 'fill style'],\n ['strokeStyle', 'stroke style'],\n ['fontColor', 'font color'],\n 'value',\n 'data',\n 'source',\n 'hidden',\n 'started',\n 'play',\n ['ref', 'reference'],\n 'action',\n 'options',\n 'rotate',\n 'dimension',\n 'location',\n 'accessor',\n 'appendum',\n 'tag'\n].map(prop => {\n return typeof prop == 'string' ? { name: prop, label: prop } : { name: prop[0], label: prop[1] }\n})\n\nexport class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {\n static styles = [\n PropertyGridStyles,\n css`\n /* The \"open in popup\" action is the last thing on the title line, at the far right. */\n legend > md-icon.open-popup {\n margin-left: auto;\n --md-icon-size: 16px;\n color: var(--md-sys-color-outline);\n opacity: 0.6;\n cursor: pointer;\n }\n\n legend > md-icon.open-popup:hover {\n color: var(--md-sys-color-on-surface);\n }\n\n #tab-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n #tab-header {\n display: flex;\n align-items: center;\n gap: 2px;\n margin-bottom: 6px;\n }\n\n #tab-header > md-icon {\n padding: 0;\n margin: 0;\n --md-icon-size: 18px;\n color: var(--md-sys-color-outline);\n }\n\n #tab-header > md-icon[disabled] {\n opacity: 0.3;\n }\n\n /* How many there are, as a small muted count next to the title. */\n legend > .count {\n margin-left: 6px;\n padding: 0 6px;\n border-radius: 999px;\n font-size: 0.66rem;\n font-weight: 500;\n line-height: 16px;\n color: var(--md-sys-color-on-surface-variant);\n background: var(--md-sys-color-surface-container-high);\n }\n\n /* Nothing yet: one quiet way in, instead of an empty form for a handler that does not exist. */\n button.add {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 26px;\n padding: 0 10px 0 6px;\n border: 1px dashed var(--md-sys-color-outline-variant);\n border-radius: 999px;\n background: transparent;\n color: var(--md-sys-color-on-surface-variant);\n font: inherit;\n font-size: 0.74rem;\n cursor: pointer;\n }\n\n button.add md-icon {\n --md-icon-size: 16px;\n }\n\n button.add:hover {\n color: var(--md-sys-color-on-surface);\n border-color: var(--md-sys-color-outline);\n background: var(--md-sys-color-surface-container-high);\n }\n\n /* The \"+\" chip is an offer until it is pressed; pressed, it is the same chip as the numbered ones. */\n ox-buttons-radio > div.add-tab:not([active]) {\n line-height: 20px;\n border: 1px dashed var(--md-sys-color-outline-variant);\n background: transparent;\n }\n\n fieldset[collapsable][collapsed] > :not(legend) {\n display: none;\n }\n\n ox-buttons-radio {\n flex: 1;\n display: flex;\n gap: 4px;\n padding: 0;\n box-sizing: border-box;\n width: 0; /* limit width */\n overflow-x: hidden;\n }\n\n /* Tabs are quiet chips on the strip; the open one is lifted to the card's surface. */\n ox-buttons-radio > div {\n border: 0;\n border-radius: 999px;\n padding: 0;\n margin: 0;\n width: 24px;\n height: 22px;\n line-height: 22px;\n text-align: center;\n font-size: 0.72rem;\n box-sizing: border-box;\n color: var(--md-sys-color-on-surface-variant);\n background-color: var(--md-sys-color-surface-container-high);\n cursor: pointer;\n }\n\n ox-buttons-radio > div[disabled] {\n opacity: 0.4;\n }\n\n ox-buttons-radio > div[active],\n ox-buttons-radio > div.iron-selected {\n color: var(--md-sys-color-on-secondary-container);\n background-color: var(--md-sys-color-secondary-container);\n }\n\n ox-input-data {\n height: 220px;\n }\n\n div[binding] {\n display: flex;\n flex-direction: row-reverse;\n gap: 2px;\n margin-left: auto;\n padding-left: 6px;\n }\n\n #tab-header > md-icon[disabled] {\n display: none;\n }\n\n /* Section actions are offers, not content: outline ink at half strength until hovered. */\n md-icon {\n margin-left: 5px;\n color: var(--md-sys-color-outline);\n opacity: 0.6;\n cursor: pointer;\n --md-icon-size: 18px;\n }\n\n md-icon:hover {\n color: var(--md-sys-color-on-surface);\n opacity: 1;\n }\n\n md-icon[disabled] {\n color: var(--md-sys-color-outline-variant);\n cursor: default;\n }\n\n data-binding-mapper {\n --things-select: {\n min-width: 50%;\n margin-bottom: 10px;\n padding: 3px 20px 2px 5px;\n -webkit-border-radius: 4px;\n -moz-border-radius: 4px;\n border-radius: 4px;\n border: 1px solid var(--md-sys-color-outline-variant);\n font-size: 15px;\n font-weight: 300;\n -webkit-appearance: none;\n };\n }\n `\n ]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n\n @state() mappingIndex: number = 0\n /*\n * A mapping is written to the model only once it names a property. Until then the mapper's\n * edits (rule, source, target...) live here, per tab, so the choice does not snap back to the\n * empty mapping on the next render. Cleared when another shape is selected.\n */\n @state() private _drafts: Record<number, any> = {}\n private _draftsFor?: unknown\n @state() _afterRender?: Function | null\n @state() _dataExpanded: boolean = false\n /* True while a new mapping is being composed and is not yet in the model (no property chosen). */\n @state() private _composing: boolean = false\n\n @query('#tabs') tabs!: HTMLElement\n @query('#tab-nav-left-button') tabNavLeftButton!: HTMLElement\n @query('#tab-nav-right-button') tabNavRightButton!: HTMLElement\n\n private mapping: Properties = {}\n\n get mappings() {\n return this.value?.mappings || []\n }\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n\n /* The tab strip only exists once there is a mapping, so listen from the root (scroll does not\n * bubble; capture catches it) instead of on an element that may not be there yet. */\n this.renderRoot.addEventListener('scroll', e => (e.target as Element).id === 'tabs' && this._onTabScroll(), true)\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('value')) {\n this.onValueChanged()\n\n const selected = this.scene?.selected?.[0]\n if (selected !== this._draftsFor) {\n this._draftsFor = selected\n this._drafts = {}\n this._composing = false\n }\n }\n }\n\n static get scopedElements() {\n return {\n 'data-binding-mapper': DataBindingMapper\n }\n }\n\n render() {\n const value = this.value || {\n mappings: []\n }\n\n return html`\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/data-binding\" msgid=\"label.identifier\"\n >identifier</ox-title-with-help\n >\n </legend>\n <div class=\"property-grid\">\n <label> <ox-i18n msgid=\"label.id\">ID</ox-i18n> </label>\n <input value-key=\"id\" .value=${value.id || ''} />\n\n <label> <ox-i18n msgid=\"label.class\">Class</ox-i18n> </label>\n <input value-key=\"class\" .value=${value.class || ''} />\n\n <label> <ox-i18n msgid=\"label.tag\">Tag</ox-i18n> </label>\n <input value-key=\"tag\" .value=${value.tag || ''} />\n\n <label> <ox-i18n msgid=\"label.template-prefix\">Template Prefix</ox-i18n> </label>\n <input value-key=\"templatePrefix\" .value=${value.templatePrefix || ''} />\n\n <input id=\"checkbox-ndns\" type=\"checkbox\" value-key=\"ndns\" .checked=${value.ndns} />\n <label for=\"checkbox-ndns\"> <ox-i18n msgid=\"label.ndns\">No Data No Show</ox-i18n> </label>\n\n <input id=\"checkbox-sensitive\" type=\"checkbox\" value-key=\"sensitive\" .checked=${value.sensitive} />\n <label for=\"checkbox-sensitive\">\n <ox-i18n msgid=\"label.intent-sensitive\">Intent Sensitive</ox-i18n>\n </label>\n\n <input id=\"checkbox-persistent\" type=\"checkbox\" value-key=\"persistent\" .checked=${value.persistent} />\n <label for=\"checkbox-persistent\">\n <ox-i18n msgid=\"label.persistent-data\">Persistent Data</ox-i18n>\n </label>\n </div>\n </fieldset>\n\n <fieldset collapsable ?collapsed=${!this._dataExpanded}>\n <legend\n @click=${() => {\n this._dataExpanded = !this._dataExpanded\n }}\n >\n <ox-title-with-help topic=\"board-modeller/initial-data\" msgid=\"label.initial-data\"\n >initial value</ox-title-with-help\n >\n <md-icon>${this._dataExpanded ? 'expand_less' : 'expand_more'}</md-icon>\n </legend>\n <ox-input-data value-key=\"data\" .value=${value.data}> </ox-input-data>\n </fieldset>\n\n <fieldset>\n <legend style=\"box-sizing:border-box;width:100%\">\n <ox-title-with-help topic=\"board-modeller/data-spread\" msgid=\"label.data-spread\"\n >Data Spread</ox-title-with-help\n >\n ${this.mappings.length ? html`<span class=\"count\">${this.mappings.length}</span>` : nothing}\n <md-icon\n class=\"open-popup\"\n @click=${() => this._openBindingPopup()}\n title=\"open in popup (D)\"\n >open_in_new</md-icon\n >\n </legend>\n\n ${this.mappings.length || this._composing\n ? html`\n <div id=\"tab-header\">\n <md-icon\n id=\"tab-nav-left-button\"\n @click=${() => {\n this._onTabScrollNavLeft()\n }}\n disabled\n >chevron_left</md-icon\n >\n\n <ox-buttons-radio\n id=\"tabs\"\n .value=${String(this.mappingIndex)}\n @change=${(e: Event) => {\n e.stopPropagation()\n this._setMappingIndex((e.target as any).value)\n }}\n >\n ${this.mappings.map((m: string, i: number) => html` <div data-value=${i} data-mapping>${i + 1}</div> `)}\n <div data-value=${this.mappings.length} class=\"add-tab\" title=\"add\" @click=${() => (this._composing = true)}>\n +\n </div>\n </ox-buttons-radio>\n\n <md-icon\n id=\"tab-nav-right-button\"\n @click=${(e: Event) => {\n this._onTabScrollNavRight()\n }}\n disabled\n >chevron_right</md-icon\n >\n\n <div binding>\n <md-icon style=\"font-size:19px\" @click=${() => this._clearDataBindingMapper()} title=\"delete current tab\"\n >delete_forever</md-icon\n >\n <md-icon @click=${() => this._pasteDataBindingMapper()} title=\"replace current tab\">content_paste</md-icon>\n <md-icon style=\"font-size:17px\" @click=${() => this._copyDataBindingMapper()} title=\"copy current tab\"\n >content_copy</md-icon\n >\n </div>\n </div>\n\n\n <data-binding-mapper\n @value-change=${(e: CustomEvent) => this._onMappingChanged(e)}\n .scene=${this.scene}\n .mapping=${(value.mappings && value.mappings[this.mappingIndex]) || this._drafts[this.mappingIndex] || {}}\n .properties=${PROPS}\n >\n </data-binding-mapper>\n `\n : html`\n <button class=\"add\" @click=${() => this._startMapping()}>\n <md-icon>add</md-icon>${i18next.t('button.add-mapping', { defaultValue: 'Add a mapping' })}\n </button>\n `}\n </fieldset>\n `\n }\n\n private _startMapping() {\n this._composing = true\n this.mappingIndex = this.mappings.length\n }\n\n _setMappingIndex(idx: number) {\n this.mappingIndex = isNaN(Number(idx)) ? 0 : Number(idx)\n\n this._onTabScroll()\n }\n\n _openBindingPopup() {\n import('./data-binding-popup.js')\n\n const value = this.value || { mappings: [] }\n\n const template = html`\n <data-binding-popup\n .mappings=${[...(value.mappings || [])]}\n .properties=${PROPS}\n .scene=${this.scene}\n @mappings-change=${(e: CustomEvent) => {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: { mappings: e.detail.mappings }\n })\n )\n }}\n ></data-binding-popup>\n `\n\n openPopup(template, {\n backdrop: true,\n size: 'large',\n title: i18next.t('label.data-spread')\n })\n }\n\n _clearDataBindingMapper() {\n var mappings = [...(this.value?.mappings || [])]\n mappings.splice(this.mappingIndex, 1)\n this.onAfterValueChange(\n 'mappings',\n mappings.filter(m => !!m)\n )\n }\n\n _copyDataBindingMapper() {\n clipboard = JSON.stringify(this.mappings[this.mappingIndex])\n }\n\n async _pasteDataBindingMapper() {\n var index = this.mappingIndex\n var mappings = [...(this.value?.mappings || [])]\n mappings[this.mappingIndex] = JSON.parse(clipboard)\n\n this.onAfterValueChange('mappings', mappings)\n\n setTimeout(() => {\n this._setMappingIndex(index)\n }, 100)\n }\n\n async onValueChanged() {\n await this.updateComplete\n\n if (this._afterRender) {\n this._afterRender()\n } else {\n this._setMappingIndex(0)\n }\n\n this._afterRender = null\n }\n\n onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n var value = this.getValueFromEventTarget(element)\n\n if (!key) {\n return\n }\n\n this.value = {\n ...this.value,\n [key]: value\n }\n\n this.onAfterValueChange(key, value)\n }\n\n get tabContainer() {\n return this.tabs\n }\n\n async _onMappingChanged(e: CustomEvent) {\n var mapping = (e.target as any).mapping\n\n /* data spread target의 변경이 있는 경우, target 컴포넌트들의 태그를 블링크 시킨다 */\n if (mapping && mapping.target) {\n this.scene &&\n this.scene.findAll(mapping.target, this.scene.selected && this.scene.selected[0]).forEach((c: any, i: any) => {\n if (i == 0) c.trigger('decotagreset')\n c.trigger('decotag', {})\n })\n }\n\n /* mapping의 모든 속성이 편집되면, 모델에 반영한다. */\n var mappings = [...(this.value?.mappings || [])]\n\n if (mapping.property) {\n const drafts = { ...this._drafts }\n delete drafts[this.mappingIndex]\n this._drafts = drafts\n\n mappings[this.mappingIndex] = mapping\n\n var mappingIdx = this.mappingIndex\n this._afterRender = () => {\n this._setMappingIndex(mappingIdx)\n this.tabContainer.scrollLeft = this.tabContainer.scrollWidth\n }\n\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n mappings: mappings.filter(m => !!m)\n }\n })\n )\n\n await this.requestUpdate()\n } else {\n /* Not complete yet: keep what has been chosen so far for this tab. */\n this._drafts = { ...this._drafts, [this.mappingIndex]: mapping }\n }\n\n /* Only a mapping the model already holds can be \"cleared\"; an unfinished draft is just unfinished. */\n if (!mapping.property && !mapping.target && mappings[this.mappingIndex]) {\n const { accessor, source } = e.detail?.changed || {}\n\n // accessor나 source를 입력중인 경우 tabIndex Change 방지\n if (!accessor && !source) {\n mappings[this.mappingIndex] = null\n var nextMappingIdx = Math.max(this.mappingIndex - 1, 0)\n this._afterRender = () => {\n this._setMappingIndex(nextMappingIdx)\n }\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: {\n mappings: mappings.filter(m => !!m)\n }\n })\n )\n }\n }\n }\n\n _onTabScroll() {\n if (!this.tabContainer || !this.tabNavLeftButton) return\n if (this.tabContainer.clientWidth == this.tabContainer.scrollWidth) {\n this.tabNavLeftButton.setAttribute('disabled', '')\n this.tabNavRightButton.setAttribute('disabled', '')\n }\n // left-end\n else if (this.tabContainer.scrollLeft == 0) {\n this.tabNavLeftButton.setAttribute('disabled', '')\n this.tabNavRightButton.removeAttribute('disabled')\n }\n // right-end\n else if (this.tabContainer.scrollLeft + this.tabContainer.clientWidth >= this.tabContainer.scrollWidth) {\n this.tabNavLeftButton.removeAttribute('disabled')\n this.tabNavRightButton.setAttribute('disabled', '')\n } else {\n this.tabNavLeftButton.removeAttribute('disabled')\n this.tabNavRightButton.removeAttribute('disabled')\n }\n }\n\n _onTabScrollNavLeft() {\n this.tabContainer.style.scrollBehavior = 'smooth'\n this.tabContainer.scrollLeft -= this.tabContainer.clientWidth\n this.tabContainer.style.scrollBehavior = 'auto'\n }\n\n _onTabScrollNavRight() {\n this.tabContainer.style.scrollBehavior = 'smooth'\n this.tabContainer.scrollLeft += this.tabContainer.clientWidth\n this.tabContainer.style.scrollBehavior = 'auto'\n }\n}\n"]}
|
|
@@ -137,14 +137,14 @@ EventHandlersMapper.styles = [
|
|
|
137
137
|
display: flex;
|
|
138
138
|
flex-direction: column;
|
|
139
139
|
gap: 6px;
|
|
140
|
-
padding:
|
|
140
|
+
padding: 0;
|
|
141
141
|
/* 카드 외곽 — tabs (위) + toolbar (중간) + mapper (아래) 가 하나의 카드.
|
|
142
142
|
* 위쪽 1px 는 toolbar 와의 internal divider. radius 6px 으로 통일. */
|
|
143
|
-
border:
|
|
144
|
-
border-radius: 0
|
|
145
|
-
box-shadow:
|
|
146
|
-
line-height:
|
|
147
|
-
background:
|
|
143
|
+
border: 0;
|
|
144
|
+
border-radius: 0;
|
|
145
|
+
box-shadow: none;
|
|
146
|
+
line-height: normal;
|
|
147
|
+
background: transparent;
|
|
148
148
|
min-width: 0;
|
|
149
149
|
width: 100%;
|
|
150
150
|
box-sizing: border-box;
|
|
@@ -162,7 +162,7 @@ EventHandlersMapper.styles = [
|
|
|
162
162
|
padding-top: 10px;
|
|
163
163
|
/* trigger/action/target/value 입력 묶음과 code editor 사이의 구분선.
|
|
164
164
|
* dashed 대신 solid + 옅은 opacity 로 modern. */
|
|
165
|
-
border-top: 1px solid
|
|
165
|
+
border-top: 1px solid var(--md-sys-color-outline-variant);
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
[script-field] > .script-header {
|
|
@@ -185,27 +185,48 @@ EventHandlersMapper.styles = [
|
|
|
185
185
|
font-size: 10.5px;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
/* The same label/editor split as the panel grid (9 of 24 columns for the label). */
|
|
188
189
|
.row {
|
|
189
190
|
display: grid;
|
|
190
|
-
grid-template-columns:
|
|
191
|
-
gap: 6px;
|
|
191
|
+
grid-template-columns: 9fr 15fr;
|
|
192
|
+
gap: 6px 10px;
|
|
192
193
|
align-items: center;
|
|
193
194
|
min-width: 0;
|
|
194
195
|
}
|
|
195
196
|
|
|
197
|
+
.row > label {
|
|
198
|
+
justify-self: end;
|
|
199
|
+
text-align: right;
|
|
200
|
+
font-size: 0.74rem;
|
|
201
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
202
|
+
text-transform: capitalize;
|
|
203
|
+
}
|
|
204
|
+
|
|
196
205
|
.row > select,
|
|
197
206
|
.row > input[type='text'] {
|
|
198
207
|
width: 100%;
|
|
199
208
|
min-width: 0;
|
|
200
209
|
box-sizing: border-box;
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
210
|
+
min-height: 24px;
|
|
211
|
+
padding: 2px 8px;
|
|
212
|
+
font-size: 0.76rem;
|
|
213
|
+
border-radius: 6px;
|
|
204
214
|
/* #fff 와 rgba(0,0,0,.15) 는 다크에서 흰 칸 + 안 보이는 테두리가 된다.
|
|
205
215
|
프레임워크의 --input-field-* 가족을 쓰고, 없을 때도 자립하도록 md 토큰을 기본값으로 둔다. */
|
|
206
|
-
border:
|
|
207
|
-
background: var(--input-
|
|
208
|
-
color: var(--
|
|
216
|
+
border: 1px solid transparent;
|
|
217
|
+
background: var(--property-input-background, var(--md-sys-color-surface-container-high));
|
|
218
|
+
color: var(--md-sys-color-on-surface);
|
|
219
|
+
outline: none;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.row > select:hover,
|
|
223
|
+
.row > input[type='text']:hover {
|
|
224
|
+
border-color: var(--md-sys-color-outline-variant);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.row > select:focus,
|
|
228
|
+
.row > input[type='text']:focus {
|
|
229
|
+
border-color: var(--md-sys-color-primary);
|
|
209
230
|
}
|
|
210
231
|
|
|
211
232
|
ox-input-code {
|
|
@@ -218,7 +239,7 @@ EventHandlersMapper.styles = [
|
|
|
218
239
|
box-sizing: border-box;
|
|
219
240
|
overflow: hidden;
|
|
220
241
|
min-height: 180px;
|
|
221
|
-
border: 1px solid
|
|
242
|
+
border: 1px solid var(--md-sys-color-outline-variant);
|
|
222
243
|
border-radius: 4px;
|
|
223
244
|
/* popup 모드에서 script-field 의 남은 세로 공간을 모두 차지 — 아래 빈공간 X.
|
|
224
245
|
* inline 모드에서는 script-field 가 grow 하지 않으므로 min-height 180px 만 사용. */
|