@operato/property-panel 10.0.0-beta.53 → 10.0.0-beta.58
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 +41 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/property-panel/data-binding/data-binding.js +4 -3
- package/dist/src/property-panel/data-binding/data-binding.js.map +1 -1
- package/dist/src/property-panel/effects/effects.js +1 -1
- package/dist/src/property-panel/effects/effects.js.map +1 -1
- package/dist/src/property-panel/effects/property-event.d.ts +15 -7
- package/dist/src/property-panel/effects/property-event.js +17 -38
- package/dist/src/property-panel/effects/property-event.js.map +1 -1
- package/dist/src/property-panel/event-handlers/event-handlers-mapper.d.ts +31 -0
- package/dist/src/property-panel/event-handlers/event-handlers-mapper.js +176 -0
- package/dist/src/property-panel/event-handlers/event-handlers-mapper.js.map +1 -0
- package/dist/src/property-panel/event-handlers/event-handlers-popup.d.ts +35 -0
- package/dist/src/property-panel/event-handlers/event-handlers-popup.js +325 -0
- package/dist/src/property-panel/event-handlers/event-handlers-popup.js.map +1 -0
- package/dist/src/property-panel/event-handlers/event-handlers.d.ts +54 -0
- package/dist/src/property-panel/event-handlers/event-handlers.js +378 -0
- package/dist/src/property-panel/event-handlers/event-handlers.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/translations/en.json +7 -0
- package/translations/ja.json +7 -0
- package/translations/ko.json +7 -0
- package/translations/ms.json +7 -0
- package/translations/zh.json +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,47 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [10.0.0-beta.58](https://github.com/hatiolab/operato/compare/v10.0.0-beta.57...v10.0.0-beta.58) (2026-05-28)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
* **property-panel:** event handlers panel — eventHandlers[] 편집기 + popup ([268ed3d](https://github.com/hatiolab/operato/commit/268ed3d2558e9b9eab1ad24810d20dda8cd17b04))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## [10.0.0-beta.57](https://github.com/hatiolab/operato/compare/v10.0.0-beta.56...v10.0.0-beta.57) (2026-05-27)
|
|
16
|
+
|
|
17
|
+
**Note:** Version bump only for package @operato/property-panel
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## [10.0.0-beta.56](https://github.com/hatiolab/operato/compare/v10.0.0-beta.55...v10.0.0-beta.56) (2026-05-27)
|
|
24
|
+
|
|
25
|
+
**Note:** Version bump only for package @operato/property-panel
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## [10.0.0-beta.55](https://github.com/hatiolab/operato/compare/v10.0.0-beta.54...v10.0.0-beta.55) (2026-05-27)
|
|
32
|
+
|
|
33
|
+
**Note:** Version bump only for package @operato/property-panel
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## [10.0.0-beta.54](https://github.com/hatiolab/operato/compare/v10.0.0-beta.53...v10.0.0-beta.54) (2026-05-27)
|
|
40
|
+
|
|
41
|
+
**Note:** Version bump only for package @operato/property-panel
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
6
47
|
## [10.0.0-beta.53](https://github.com/hatiolab/operato/compare/v10.0.0-beta.52...v10.0.0-beta.53) (2026-05-24)
|
|
7
48
|
|
|
8
49
|
**Note:** Version bump only for package @operato/property-panel
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export { OxPropertyPanel } from './ox-property-panel.js';
|
|
2
2
|
export * from './property-panel/data-binding/data-binding.js';
|
|
3
|
+
export * from './property-panel/event-handlers/event-handlers-mapper.js';
|
|
4
|
+
export * from './property-panel/event-handlers/event-handlers.js';
|
|
5
|
+
export * from './property-panel/event-handlers/event-handlers-popup.js';
|
|
3
6
|
export * from './property-panel/effects/effects.js';
|
|
4
7
|
export * from './property-panel/inspector/inspector.js';
|
|
5
8
|
export * from './property-panel/shapes/shapes.js';
|
package/dist/src/index.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export { OxPropertyPanel } from './ox-property-panel.js';
|
|
2
2
|
export * from './property-panel/data-binding/data-binding.js';
|
|
3
|
+
// Event handlers — inline panel + popup (data-binding 패턴 동일). effects tab
|
|
4
|
+
// 의 PropertyEvent fieldset 에서 inline 으로 host. open_in_new 클릭 시 popup.
|
|
5
|
+
export * from './property-panel/event-handlers/event-handlers-mapper.js';
|
|
6
|
+
export * from './property-panel/event-handlers/event-handlers.js';
|
|
7
|
+
export * from './property-panel/event-handlers/event-handlers-popup.js';
|
|
3
8
|
export * from './property-panel/effects/effects.js';
|
|
4
9
|
export * from './property-panel/inspector/inspector.js';
|
|
5
10
|
export * from './property-panel/shapes/shapes.js';
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,cAAc,+CAA+C,CAAA;AAC7D,cAAc,qCAAqC,CAAA;AACnD,cAAc,yCAAyC,CAAA;AACvD,cAAc,mCAAmC,CAAA;AACjD,cAAc,yCAAyC,CAAA;AACvD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA","sourcesContent":["export { OxPropertyPanel } from './ox-property-panel.js'\n\nexport * from './property-panel/data-binding/data-binding.js'\nexport * from './property-panel/effects/effects.js'\nexport * from './property-panel/inspector/inspector.js'\nexport * from './property-panel/shapes/shapes.js'\nexport * from './property-panel/specifics/specifics.js'\nexport * from './property-panel/styles/styles.js'\nexport * from './property-panel/threed/threed.js'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,cAAc,+CAA+C,CAAA;AAC7D,0EAA0E;AAC1E,sEAAsE;AACtE,cAAc,0DAA0D,CAAA;AACxE,cAAc,mDAAmD,CAAA;AACjE,cAAc,yDAAyD,CAAA;AACvE,cAAc,qCAAqC,CAAA;AACnD,cAAc,yCAAyC,CAAA;AACvD,cAAc,mCAAmC,CAAA;AACjD,cAAc,yCAAyC,CAAA;AACvD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA","sourcesContent":["export { OxPropertyPanel } from './ox-property-panel.js'\n\nexport * from './property-panel/data-binding/data-binding.js'\n// Event handlers — inline panel + popup (data-binding 패턴 동일). effects tab\n// 의 PropertyEvent fieldset 에서 inline 으로 host. open_in_new 클릭 시 popup.\nexport * from './property-panel/event-handlers/event-handlers-mapper.js'\nexport * from './property-panel/event-handlers/event-handlers.js'\nexport * from './property-panel/event-handlers/event-handlers-popup.js'\nexport * from './property-panel/effects/effects.js'\nexport * from './property-panel/inspector/inspector.js'\nexport * from './property-panel/shapes/shapes.js'\nexport * from './property-panel/specifics/specifics.js'\nexport * from './property-panel/styles/styles.js'\nexport * from './property-panel/threed/threed.js'\n"]}
|
|
@@ -16,6 +16,9 @@ import { i18next } from '@operato/i18n';
|
|
|
16
16
|
import { AbstractProperty } from '../abstract-property.js';
|
|
17
17
|
import { DataBindingMapper } from './data-binding-mapper.js';
|
|
18
18
|
var clipboard = '{}';
|
|
19
|
+
// `'tap'` / `'(action)'` 는 *Event Handlers panel* 로 이동 — legacy data-binding
|
|
20
|
+
// 기반 핸들러 UI 는 제거. 데이터는 (`state.event`) 안전망으로 유지하되 편집 진입점
|
|
21
|
+
// 은 새 panel 만.
|
|
19
22
|
const PROPS = [
|
|
20
23
|
'',
|
|
21
24
|
'text',
|
|
@@ -36,9 +39,7 @@ const PROPS = [
|
|
|
36
39
|
'location',
|
|
37
40
|
'accessor',
|
|
38
41
|
'appendum',
|
|
39
|
-
'tag'
|
|
40
|
-
['tap', '(tap)'],
|
|
41
|
-
'(action)'
|
|
42
|
+
'tag'
|
|
42
43
|
].map(prop => {
|
|
43
44
|
return typeof prop == 'string' ? { name: prop, label: prop } : { name: prop[0], label: prop[1] };
|
|
44
45
|
});
|
|
@@ -1 +1 @@
|
|
|
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, 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\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 ['tap', '(tap)'],\n '(action)'\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, 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"]}
|
|
@@ -50,7 +50,7 @@ export class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {
|
|
|
50
50
|
<property-animations value-key="animation" .scene=${this.scene} .value=${value.animation || {}}>
|
|
51
51
|
</property-animations>
|
|
52
52
|
|
|
53
|
-
<property-event
|
|
53
|
+
<property-event .scene=${this.scene} .value=${this.value}></property-event>
|
|
54
54
|
`;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effects.js","sourceRoot":"","sources":["../../../../src/property-panel/effects/effects.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,0BAA0B,CAAA;AACjC,OAAO,qCAAqC,CAAA;AAE5C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAA;AAE5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,OAAO,eAAgB,SAAQ,mBAAmB,CAAC,gBAAgB,CAAC;IAcxE,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,iBAAiB,EAAE,cAAc;YACjC,qBAAqB,EAAE,kBAAkB;YACzC,gBAAgB,EAAE,aAAa;SAChC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,OAAO,IAAI,CAAA;;;;;;qDAMsC,KAAK,CAAC,MAAM,IAAI,EAAE;;;;;;;;;;;;8DAYT,KAAK,CAAC,SAAS;;;;0DAInB,IAAI,CAAC,KAAK,WAAW,KAAK,CAAC,SAAS,IAAI,EAAE
|
|
1
|
+
{"version":3,"file":"effects.js","sourceRoot":"","sources":["../../../../src/property-panel/effects/effects.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,0BAA0B,CAAA;AACjC,OAAO,qCAAqC,CAAA;AAE5C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAA;AAE5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,OAAO,eAAgB,SAAQ,mBAAmB,CAAC,gBAAgB,CAAC;IAcxE,YAAY;QACV,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,iBAAiB,EAAE,cAAc;YACjC,qBAAqB,EAAE,kBAAkB;YACzC,gBAAgB,EAAE,aAAa;SAChC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,OAAO,IAAI,CAAA;;;;;;qDAMsC,KAAK,CAAC,MAAM,IAAI,EAAE;;;;;;;;;;;;8DAYT,KAAK,CAAC,SAAS;;;;0DAInB,IAAI,CAAC,KAAK,WAAW,KAAK,CAAC,SAAS,IAAI,EAAE;;;+BAGrE,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK;KACzD,CAAA;IACH,CAAC;;AAvDM,sBAAM,GAAG;IACd,kBAAkB;IAClB,GAAG,CAAA;;;;;KAKF;CACF,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAmB;AAClB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAc","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/help/ox-title-with-help.js'\n\nimport { css, html } from 'lit'\nimport { property } 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'\n\nimport { AbstractProperty } from '../abstract-property.js'\nimport { PropertyAnimations } from './property-animations.js'\nimport { PropertyEvent } from './property-event.js'\nimport { PropertyShadow } from './property-shadow.js'\n\nexport class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {\n static styles = [\n PropertyGridStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n }\n `\n ]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n }\n\n static get scopedElements() {\n return {\n 'property-shadow': PropertyShadow,\n 'property-animations': PropertyAnimations,\n 'property-event': PropertyEvent\n }\n }\n\n render() {\n const value = this.value || {}\n\n return html`\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/effects/shadow\" msgid=\"label.shadow\">shadow</ox-title-with-help>\n </legend>\n\n <property-shadow value-key=\"shadow\" .value=${value.shadow || {}}> </property-shadow>\n </fieldset>\n\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/effects/retention\" msgid=\"label.retention\"\n >retention</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label> <ox-i18n msgid=\"label.retention\">retention</ox-i18n> </label>\n <input type=\"number\" value-key=\"retention\" .value=${value.retention} placeholder=\"ms\" />\n </div>\n </fieldset>\n\n <property-animations value-key=\"animation\" .scene=${this.scene} .value=${value.animation || {}}>\n </property-animations>\n\n <property-event .scene=${this.scene} .value=${this.value}></property-event>\n `\n }\n}\n"]}
|
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* PropertyEvent — effects tab 안의 이벤트 핸들러 진입점.
|
|
5
|
+
*
|
|
6
|
+
* data-binding 패턴 동일 — inline `<property-event-handlers>` (기본 UI: tabs +
|
|
7
|
+
* mapper + add/delete/copy/paste) 를 host. inline panel 의 우상단 `open_in_new`
|
|
8
|
+
* 클릭 시 *큰 popup* 으로 펼침.
|
|
9
|
+
*
|
|
10
|
+
* 자동 마이그레이션 — things-scene 의 Component constructor 가 legacy
|
|
11
|
+
* `state.event = { tap, hover, ... }` 를 *load 시점* 에 `state.eventHandlers[]`
|
|
12
|
+
* 로 변환. UI 는 항상 `eventHandlers` 만 read/write.
|
|
13
|
+
*
|
|
14
|
+
* Legacy 컴포넌트 (PropertyEventHover / PropertyEventTap) 파일은 *코드 유지*
|
|
15
|
+
* (rollback 안전망). UI 진입점만 끊음.
|
|
3
16
|
*/
|
|
4
|
-
import '@operato/help/ox-title-with-help.js';
|
|
5
17
|
import { LitElement } from 'lit';
|
|
6
18
|
import { Properties, Scene } from '@hatiolab/things-scene';
|
|
7
|
-
import {
|
|
8
|
-
import { PropertyEventTap } from './property-event-tap.js';
|
|
19
|
+
import { PropertyEventHandlers } from '../event-handlers/event-handlers.js';
|
|
9
20
|
declare const PropertyEvent_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
|
|
10
21
|
export declare class PropertyEvent extends PropertyEvent_base {
|
|
11
22
|
static styles: import("lit").CSSResult[];
|
|
12
23
|
value?: Properties;
|
|
13
24
|
scene?: Scene;
|
|
14
|
-
firstUpdated(): void;
|
|
15
25
|
static get scopedElements(): {
|
|
16
|
-
'property-event-
|
|
17
|
-
'property-event-tap': typeof PropertyEventTap;
|
|
26
|
+
'property-event-handlers': typeof PropertyEventHandlers;
|
|
18
27
|
};
|
|
19
28
|
render(): import("lit-html").TemplateResult<1>;
|
|
20
|
-
onValueChange(e: Event): void;
|
|
21
29
|
}
|
|
22
30
|
export {};
|
|
@@ -1,58 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* PropertyEvent — effects tab 안의 이벤트 핸들러 진입점.
|
|
5
|
+
*
|
|
6
|
+
* data-binding 패턴 동일 — inline `<property-event-handlers>` (기본 UI: tabs +
|
|
7
|
+
* mapper + add/delete/copy/paste) 를 host. inline panel 의 우상단 `open_in_new`
|
|
8
|
+
* 클릭 시 *큰 popup* 으로 펼침.
|
|
9
|
+
*
|
|
10
|
+
* 자동 마이그레이션 — things-scene 의 Component constructor 가 legacy
|
|
11
|
+
* `state.event = { tap, hover, ... }` 를 *load 시점* 에 `state.eventHandlers[]`
|
|
12
|
+
* 로 변환. UI 는 항상 `eventHandlers` 만 read/write.
|
|
13
|
+
*
|
|
14
|
+
* Legacy 컴포넌트 (PropertyEventHover / PropertyEventTap) 파일은 *코드 유지*
|
|
15
|
+
* (rollback 안전망). UI 진입점만 끊음.
|
|
3
16
|
*/
|
|
4
17
|
import { __decorate } from "tslib";
|
|
5
|
-
import '@operato/help/ox-title-with-help.js';
|
|
6
18
|
import { html, LitElement } from 'lit';
|
|
7
19
|
import { property } from 'lit/decorators.js';
|
|
8
20
|
import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|
9
21
|
import { PropertyGridStyles } from '@operato/styles/property-grid-styles.js';
|
|
10
|
-
import {
|
|
11
|
-
import { PropertyEventTap } from './property-event-tap.js';
|
|
12
|
-
import { convert } from './value-converter.js';
|
|
22
|
+
import { PropertyEventHandlers } from '../event-handlers/event-handlers.js';
|
|
13
23
|
export class PropertyEvent extends ScopedElementsMixin(LitElement) {
|
|
14
|
-
firstUpdated() {
|
|
15
|
-
this.renderRoot.addEventListener('change', this.onValueChange.bind(this));
|
|
16
|
-
}
|
|
17
24
|
static get scopedElements() {
|
|
18
25
|
return {
|
|
19
|
-
'property-event-
|
|
20
|
-
'property-event-tap': PropertyEventTap
|
|
26
|
+
'property-event-handlers': PropertyEventHandlers
|
|
21
27
|
};
|
|
22
28
|
}
|
|
23
29
|
render() {
|
|
24
|
-
const value = this.value || {};
|
|
25
30
|
return html `
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
<ox-title-with-help msgid="label.hover-event" topic="board-modeller/effects/hover-event"></ox-title-with-help>
|
|
29
|
-
</legend>
|
|
30
|
-
|
|
31
|
-
<property-event-hover value-key="hover" .scene=${this.scene} .value=${value.hover || {}}>
|
|
32
|
-
</property-event-hover>
|
|
33
|
-
</fieldset>
|
|
34
|
-
|
|
35
|
-
<fieldset>
|
|
36
|
-
<legend>
|
|
37
|
-
<ox-title-with-help msgid="label.tap-event" topic="board-modeller/effects/tap-event"></ox-title-with-help>
|
|
38
|
-
</legend>
|
|
39
|
-
|
|
40
|
-
<property-event-tap value-key="tap" .scene=${this.scene} .value=${value.tap || {}}> </property-event-tap>
|
|
41
|
-
</fieldset>
|
|
31
|
+
<property-event-handlers .value=${this.value} .scene=${this.scene}>
|
|
32
|
+
</property-event-handlers>
|
|
42
33
|
`;
|
|
43
34
|
}
|
|
44
|
-
onValueChange(e) {
|
|
45
|
-
var element = e.target;
|
|
46
|
-
var key = element.getAttribute('value-key');
|
|
47
|
-
if (!key) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this.value = {
|
|
51
|
-
...this.value,
|
|
52
|
-
[key]: convert(element)
|
|
53
|
-
};
|
|
54
|
-
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
|
55
|
-
}
|
|
56
35
|
}
|
|
57
36
|
PropertyEvent.styles = [PropertyGridStyles];
|
|
58
37
|
__decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"property-event.js","sourceRoot":"","sources":["../../../../src/property-panel/effects/property-event.ts"],"names":[],"mappings":"AAAA;;
|
|
1
|
+
{"version":3,"file":"property-event.js","sourceRoot":"","sources":["../../../../src/property-panel/effects/property-event.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAA;AAE5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAE3E,MAAM,OAAO,aAAc,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAMhE,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,yBAAyB,EAAE,qBAAqB;SACjD,CAAA;IACH,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;wCACyB,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK;;KAElE,CAAA;IACH,CAAC;;AAhBM,oBAAM,GAAG,CAAC,kBAAkB,CAAC,CAAA;AAER;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CAAmB;AAClB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CAAc","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * PropertyEvent — effects tab 안의 이벤트 핸들러 진입점.\n *\n * data-binding 패턴 동일 — inline `<property-event-handlers>` (기본 UI: tabs +\n * mapper + add/delete/copy/paste) 를 host. inline panel 의 우상단 `open_in_new`\n * 클릭 시 *큰 popup* 으로 펼침.\n *\n * 자동 마이그레이션 — things-scene 의 Component constructor 가 legacy\n * `state.event = { tap, hover, ... }` 를 *load 시점* 에 `state.eventHandlers[]`\n * 로 변환. UI 는 항상 `eventHandlers` 만 read/write.\n *\n * Legacy 컴포넌트 (PropertyEventHover / PropertyEventTap) 파일은 *코드 유지*\n * (rollback 안전망). UI 진입점만 끊음.\n */\n\nimport { html, LitElement } from 'lit'\nimport { property } 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'\n\nimport { PropertyEventHandlers } from '../event-handlers/event-handlers.js'\n\nexport class PropertyEvent extends ScopedElementsMixin(LitElement) {\n static styles = [PropertyGridStyles]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) scene?: Scene\n\n static get scopedElements() {\n return {\n 'property-event-handlers': PropertyEventHandlers\n }\n }\n\n render() {\n return html`\n <property-event-handlers .value=${this.value} .scene=${this.scene}>\n </property-event-handlers>\n `\n }\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Single EventHandler editor — trigger / action / (code 또는 target+value).
|
|
5
|
+
*
|
|
6
|
+
* 'script' 도 action 의 한 값. action='script' 시 code 필드를, 다른 declarative
|
|
7
|
+
* action 시 target+value 필드를 노출. action 미선택 (= '') 시 no-op.
|
|
8
|
+
*/
|
|
9
|
+
import '@operato/input/ox-input-code.js';
|
|
10
|
+
import '@operato/i18n/ox-i18n.js';
|
|
11
|
+
import { LitElement } from 'lit';
|
|
12
|
+
import type { Scene } from '@hatiolab/things-scene';
|
|
13
|
+
/** EventHandler model — things-scene 의 EventHandler interface 와 호환. */
|
|
14
|
+
export type EventHandlerSpec = {
|
|
15
|
+
trigger: string;
|
|
16
|
+
action?: string;
|
|
17
|
+
code?: string;
|
|
18
|
+
target?: string;
|
|
19
|
+
value?: any;
|
|
20
|
+
options?: Record<string, any>;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare class EventHandlersMapper extends LitElement {
|
|
24
|
+
static styles: import("lit").CSSResult[];
|
|
25
|
+
handler: EventHandlerSpec;
|
|
26
|
+
scene?: Scene;
|
|
27
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
28
|
+
private _renderScriptFields;
|
|
29
|
+
private _renderActionFields;
|
|
30
|
+
private _update;
|
|
31
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Single EventHandler editor — trigger / action / (code 또는 target+value).
|
|
5
|
+
*
|
|
6
|
+
* 'script' 도 action 의 한 값. action='script' 시 code 필드를, 다른 declarative
|
|
7
|
+
* action 시 target+value 필드를 노출. action 미선택 (= '') 시 no-op.
|
|
8
|
+
*/
|
|
9
|
+
import { __decorate } from "tslib";
|
|
10
|
+
import '@operato/input/ox-input-code.js';
|
|
11
|
+
import '@operato/i18n/ox-i18n.js';
|
|
12
|
+
import { css, html, LitElement } from 'lit';
|
|
13
|
+
import { property } from 'lit/decorators.js';
|
|
14
|
+
const TRIGGERS = [
|
|
15
|
+
'click', 'dblclick',
|
|
16
|
+
'mouseenter', 'mouseleave',
|
|
17
|
+
'longpress',
|
|
18
|
+
'mousedown', 'mouseup'
|
|
19
|
+
];
|
|
20
|
+
/** 'script' 는 action 의 한 값. */
|
|
21
|
+
const ACTIONS = [
|
|
22
|
+
'',
|
|
23
|
+
'script',
|
|
24
|
+
'data-toggle',
|
|
25
|
+
'data-tristate',
|
|
26
|
+
'data-spreading',
|
|
27
|
+
'data-set',
|
|
28
|
+
'partial-data-set',
|
|
29
|
+
'value-set',
|
|
30
|
+
'partial-value-set',
|
|
31
|
+
'info-window',
|
|
32
|
+
'emphasize'
|
|
33
|
+
];
|
|
34
|
+
export class EventHandlersMapper extends LitElement {
|
|
35
|
+
constructor() {
|
|
36
|
+
super(...arguments);
|
|
37
|
+
this.handler = { trigger: 'click', action: '' };
|
|
38
|
+
}
|
|
39
|
+
render() {
|
|
40
|
+
var _a;
|
|
41
|
+
const h = this.handler || { trigger: 'click', action: '' };
|
|
42
|
+
return html `
|
|
43
|
+
<div class="row">
|
|
44
|
+
<label><ox-i18n msgid="label.trigger">Trigger</ox-i18n></label>
|
|
45
|
+
<select
|
|
46
|
+
.value=${h.trigger || 'click'}
|
|
47
|
+
@change=${(e) => this._update('trigger', e.target.value)}
|
|
48
|
+
>
|
|
49
|
+
${TRIGGERS.map(t => html `<option value=${t} ?selected=${h.trigger === t}>${t}</option>`)}
|
|
50
|
+
</select>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div class="row">
|
|
54
|
+
<label><ox-i18n msgid="label.action">Action</ox-i18n></label>
|
|
55
|
+
<select
|
|
56
|
+
.value=${(_a = h.action) !== null && _a !== void 0 ? _a : ''}
|
|
57
|
+
@change=${(e) => this._update('action', e.target.value)}
|
|
58
|
+
>
|
|
59
|
+
${ACTIONS.map(a => { var _a; return html `<option value=${a} ?selected=${((_a = h.action) !== null && _a !== void 0 ? _a : '') === a}>${a || '(none)'}</option>`; })}
|
|
60
|
+
</select>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
${h.action === 'script'
|
|
64
|
+
? this._renderScriptFields(h)
|
|
65
|
+
: (h.action ? this._renderActionFields(h) : null)}
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
_renderScriptFields(h) {
|
|
69
|
+
return html `
|
|
70
|
+
<div class="row">
|
|
71
|
+
<label><ox-i18n msgid="label.target">Target</ox-i18n></label>
|
|
72
|
+
<input type="text"
|
|
73
|
+
placeholder="optional selector (#id, .class, ...)"
|
|
74
|
+
.value=${h.target || ''}
|
|
75
|
+
@change=${(e) => this._update('target', e.target.value)}
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
<div>
|
|
79
|
+
<label style="display:block;margin-bottom:4px">
|
|
80
|
+
<ox-i18n msgid="label.script">Script</ox-i18n>
|
|
81
|
+
<small style="opacity:0.7">vars: component, scene, event, targets, value · await 지원</small>
|
|
82
|
+
</label>
|
|
83
|
+
<ox-input-code
|
|
84
|
+
mode="javascript"
|
|
85
|
+
.value=${h.code || ''}
|
|
86
|
+
@change=${(e) => { var _a, _b, _c, _d; return this._update('code', (_d = (_b = (_a = e.detail) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : (_c = e.target) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : ''); }}
|
|
87
|
+
></ox-input-code>
|
|
88
|
+
</div>
|
|
89
|
+
`;
|
|
90
|
+
}
|
|
91
|
+
_renderActionFields(h) {
|
|
92
|
+
return html `
|
|
93
|
+
<div class="row">
|
|
94
|
+
<label><ox-i18n msgid="label.target">Target</ox-i18n></label>
|
|
95
|
+
<input type="text"
|
|
96
|
+
placeholder="selector (#id, .class, ...)"
|
|
97
|
+
.value=${h.target || ''}
|
|
98
|
+
@change=${(e) => this._update('target', e.target.value)}
|
|
99
|
+
/>
|
|
100
|
+
</div>
|
|
101
|
+
<div class="row">
|
|
102
|
+
<label><ox-i18n msgid="label.value">Value</ox-i18n></label>
|
|
103
|
+
<input type="text"
|
|
104
|
+
placeholder="value or accessor"
|
|
105
|
+
.value=${h.value !== undefined ? String(h.value) : ''}
|
|
106
|
+
@change=${(e) => this._update('value', e.target.value)}
|
|
107
|
+
/>
|
|
108
|
+
</div>
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
_update(key, value) {
|
|
112
|
+
const next = { ...(this.handler || { trigger: 'click', action: '' }), [key]: value };
|
|
113
|
+
// action 전환 시 비-script 진입은 code 정리. script 진입 시 target/value 는
|
|
114
|
+
// 의미가 호환 (target=findAll selector, value=script 입력) 이라 유지.
|
|
115
|
+
if (key === 'action' && value !== 'script') {
|
|
116
|
+
delete next.code;
|
|
117
|
+
}
|
|
118
|
+
this.handler = next;
|
|
119
|
+
this.dispatchEvent(new CustomEvent('value-change', {
|
|
120
|
+
bubbles: true,
|
|
121
|
+
composed: true,
|
|
122
|
+
detail: { handler: next, changed: { [key]: value } }
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
EventHandlersMapper.styles = [
|
|
127
|
+
css `
|
|
128
|
+
:host {
|
|
129
|
+
display: flex;
|
|
130
|
+
flex-direction: column;
|
|
131
|
+
gap: 6px;
|
|
132
|
+
padding: 7px;
|
|
133
|
+
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
134
|
+
border-width: 0 1px 1px 1px;
|
|
135
|
+
line-height: 2;
|
|
136
|
+
background: var(--md-sys-color-surface, #fff);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.row {
|
|
140
|
+
display: grid;
|
|
141
|
+
grid-template-columns: 80px 1fr;
|
|
142
|
+
gap: 6px;
|
|
143
|
+
align-items: center;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.row > select,
|
|
147
|
+
.row > input[type='text'] {
|
|
148
|
+
width: 100%;
|
|
149
|
+
box-sizing: border-box;
|
|
150
|
+
padding: 3px 6px;
|
|
151
|
+
font-size: 13px;
|
|
152
|
+
border-radius: 4px;
|
|
153
|
+
border: 1px solid rgba(0, 0, 0, 0.15);
|
|
154
|
+
background: #fff;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
ox-input-code {
|
|
158
|
+
min-height: 180px;
|
|
159
|
+
border: 1px solid rgba(0, 0, 0, 0.15);
|
|
160
|
+
border-radius: 4px;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
label {
|
|
164
|
+
font-size: 12px;
|
|
165
|
+
color: var(--md-sys-color-on-surface-variant, #49454f);
|
|
166
|
+
}
|
|
167
|
+
`
|
|
168
|
+
];
|
|
169
|
+
__decorate([
|
|
170
|
+
property({ type: Object })
|
|
171
|
+
], EventHandlersMapper.prototype, "handler", void 0);
|
|
172
|
+
__decorate([
|
|
173
|
+
property({ type: Object })
|
|
174
|
+
], EventHandlersMapper.prototype, "scene", void 0);
|
|
175
|
+
customElements.define('event-handlers-mapper', EventHandlersMapper);
|
|
176
|
+
//# sourceMappingURL=event-handlers-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-handlers-mapper.js","sourceRoot":"","sources":["../../../../src/property-panel/event-handlers/event-handlers-mapper.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * Single EventHandler editor — trigger / action / (code 또는 target+value).\n *\n * 'script' 도 action 의 한 값. action='script' 시 code 필드를, 다른 declarative\n * action 시 target+value 필드를 노출. action 미선택 (= '') 시 no-op.\n */\n\nimport '@operato/input/ox-input-code.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport type { Scene } from '@hatiolab/things-scene'\n\n/** EventHandler model — things-scene 의 EventHandler interface 와 호환. */\nexport type EventHandlerSpec = {\n trigger: string // click | dblclick | mouseenter | mouseleave | longpress | mousedown | mouseup\n action?: string // '' | 'script' | 'data-toggle' | 'data-set' | 'emphasize' | ...\n code?: string // action='script' 시 JS 코드\n target?: string // selector\n value?: any\n options?: Record<string, any>\n disabled?: boolean\n}\n\nconst TRIGGERS = [\n 'click', 'dblclick',\n 'mouseenter', 'mouseleave',\n 'longpress',\n 'mousedown', 'mouseup'\n]\n\n/** 'script' 는 action 의 한 값. */\nconst ACTIONS = [\n '',\n 'script',\n 'data-toggle',\n 'data-tristate',\n 'data-spreading',\n 'data-set',\n 'partial-data-set',\n 'value-set',\n 'partial-value-set',\n 'info-window',\n 'emphasize'\n]\n\nexport class EventHandlersMapper extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 7px;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-width: 0 1px 1px 1px;\n line-height: 2;\n background: var(--md-sys-color-surface, #fff);\n }\n\n .row {\n display: grid;\n grid-template-columns: 80px 1fr;\n gap: 6px;\n align-items: center;\n }\n\n .row > select,\n .row > input[type='text'] {\n width: 100%;\n box-sizing: border-box;\n padding: 3px 6px;\n font-size: 13px;\n border-radius: 4px;\n border: 1px solid rgba(0, 0, 0, 0.15);\n background: #fff;\n }\n\n ox-input-code {\n min-height: 180px;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n }\n\n label {\n font-size: 12px;\n color: var(--md-sys-color-on-surface-variant, #49454f);\n }\n `\n ]\n\n @property({ type: Object }) handler: EventHandlerSpec = { trigger: 'click', action: '' }\n @property({ type: Object }) scene?: Scene\n\n render() {\n const h = this.handler || { trigger: 'click', action: '' }\n return html`\n <div class=\"row\">\n <label><ox-i18n msgid=\"label.trigger\">Trigger</ox-i18n></label>\n <select\n .value=${h.trigger || 'click'}\n @change=${(e: Event) => this._update('trigger', (e.target as HTMLSelectElement).value)}\n >\n ${TRIGGERS.map(t => html`<option value=${t} ?selected=${h.trigger === t}>${t}</option>`)}\n </select>\n </div>\n\n <div class=\"row\">\n <label><ox-i18n msgid=\"label.action\">Action</ox-i18n></label>\n <select\n .value=${h.action ?? ''}\n @change=${(e: Event) => this._update('action', (e.target as HTMLSelectElement).value)}\n >\n ${ACTIONS.map(a => html`<option value=${a} ?selected=${(h.action ?? '') === a}>${a || '(none)'}</option>`)}\n </select>\n </div>\n\n ${h.action === 'script'\n ? this._renderScriptFields(h)\n : (h.action ? this._renderActionFields(h) : null)}\n `\n }\n\n private _renderScriptFields(h: EventHandlerSpec) {\n return html`\n <div class=\"row\">\n <label><ox-i18n msgid=\"label.target\">Target</ox-i18n></label>\n <input type=\"text\"\n placeholder=\"optional selector (#id, .class, ...)\"\n .value=${h.target || ''}\n @change=${(e: Event) => this._update('target', (e.target as HTMLInputElement).value)}\n />\n </div>\n <div>\n <label style=\"display:block;margin-bottom:4px\">\n <ox-i18n msgid=\"label.script\">Script</ox-i18n>\n <small style=\"opacity:0.7\">vars: component, scene, event, targets, value · await 지원</small>\n </label>\n <ox-input-code\n mode=\"javascript\"\n .value=${h.code || ''}\n @change=${(e: any) => this._update('code', e.detail?.value ?? e.target?.value ?? '')}\n ></ox-input-code>\n </div>\n `\n }\n\n private _renderActionFields(h: EventHandlerSpec) {\n return html`\n <div class=\"row\">\n <label><ox-i18n msgid=\"label.target\">Target</ox-i18n></label>\n <input type=\"text\"\n placeholder=\"selector (#id, .class, ...)\"\n .value=${h.target || ''}\n @change=${(e: Event) => this._update('target', (e.target as HTMLInputElement).value)}\n />\n </div>\n <div class=\"row\">\n <label><ox-i18n msgid=\"label.value\">Value</ox-i18n></label>\n <input type=\"text\"\n placeholder=\"value or accessor\"\n .value=${h.value !== undefined ? String(h.value) : ''}\n @change=${(e: Event) => this._update('value', (e.target as HTMLInputElement).value)}\n />\n </div>\n `\n }\n\n private _update(key: keyof EventHandlerSpec, value: any) {\n const next: EventHandlerSpec = { ...(this.handler || { trigger: 'click', action: '' }), [key]: value }\n // action 전환 시 비-script 진입은 code 정리. script 진입 시 target/value 는\n // 의미가 호환 (target=findAll selector, value=script 입력) 이라 유지.\n if (key === 'action' && value !== 'script') {\n delete next.code\n }\n this.handler = next\n this.dispatchEvent(\n new CustomEvent('value-change', {\n bubbles: true,\n composed: true,\n detail: { handler: next, changed: { [key]: value } }\n })\n )\n }\n}\n\ncustomElements.define('event-handlers-mapper', EventHandlersMapper)\n"]}
|