@operato/property-panel 10.0.0-beta.57 → 10.0.0-beta.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/src/index.d.ts +4 -0
  3. package/dist/src/index.js +6 -0
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/property-panel/data-binding/data-binding.js +4 -3
  6. package/dist/src/property-panel/data-binding/data-binding.js.map +1 -1
  7. package/dist/src/property-panel/effects/effects.js +1 -1
  8. package/dist/src/property-panel/effects/effects.js.map +1 -1
  9. package/dist/src/property-panel/effects/property-event-hover.d.ts +1 -1
  10. package/dist/src/property-panel/effects/property-event.d.ts +15 -7
  11. package/dist/src/property-panel/effects/property-event.js +17 -38
  12. package/dist/src/property-panel/effects/property-event.js.map +1 -1
  13. package/dist/src/property-panel/event-handlers/event-handlers-help.d.ts +23 -0
  14. package/dist/src/property-panel/event-handlers/event-handlers-help.js +356 -0
  15. package/dist/src/property-panel/event-handlers/event-handlers-help.js.map +1 -0
  16. package/dist/src/property-panel/event-handlers/event-handlers-mapper.d.ts +31 -0
  17. package/dist/src/property-panel/event-handlers/event-handlers-mapper.js +238 -0
  18. package/dist/src/property-panel/event-handlers/event-handlers-mapper.js.map +1 -0
  19. package/dist/src/property-panel/event-handlers/event-handlers-popup.d.ts +42 -0
  20. package/dist/src/property-panel/event-handlers/event-handlers-popup.js +375 -0
  21. package/dist/src/property-panel/event-handlers/event-handlers-popup.js.map +1 -0
  22. package/dist/src/property-panel/event-handlers/event-handlers.d.ts +54 -0
  23. package/dist/src/property-panel/event-handlers/event-handlers.js +410 -0
  24. package/dist/src/property-panel/event-handlers/event-handlers.js.map +1 -0
  25. package/dist/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +4 -4
  27. package/translations/en.json +7 -0
  28. package/translations/ja.json +7 -0
  29. package/translations/ko.json +7 -0
  30. package/translations/ms.json +7 -0
  31. package/translations/zh.json +7 -0
@@ -0,0 +1,356 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ *
4
+ * EventHandlers help pane — popup 의 우측 docs 컬럼.
5
+ *
6
+ * 현재 선택된 handler 의 trigger / action / target / value (또는 script vars)
7
+ * 의미를 *동적으로* 안내. script 모드에서는 자주 쓰는 코드 snippet 을
8
+ * 삽입할 수 있는 버튼도 제공.
9
+ *
10
+ * 다국어 — 1차안은 한국어 hard-code (5 언어 동시 유지 부담 회피).
11
+ * 추후 안정화 후 i18n 키로 분리.
12
+ */
13
+ import { __decorate } from "tslib";
14
+ import '@material/web/icon/icon.js';
15
+ import { css, html, LitElement } from 'lit';
16
+ import { property } from 'lit/decorators.js';
17
+ import { ScrollbarStyles } from '@operato/styles';
18
+ const TRIGGER_DESC = {
19
+ click: {
20
+ summary: '마우스 클릭 (터치 환경에선 tap 과 동일).',
21
+ example: '가장 일반적인 버튼/아이콘 액션에 사용.'
22
+ },
23
+ tap: {
24
+ summary: 'click 의 alias (legacy 호환). 신규 등록은 click 권장.'
25
+ },
26
+ dblclick: {
27
+ summary: '더블 클릭. 빠른 연속 2회 클릭으로만 발화.'
28
+ },
29
+ mouseenter: {
30
+ summary: '포인터가 컴포넌트 영역에 *진입* 한 순간 1회.',
31
+ example: 'hover 강조 / tooltip 표시에 사용.'
32
+ },
33
+ hover: {
34
+ summary: 'mouseenter 의 alias (legacy). 신규 등록은 mouseenter 권장.'
35
+ },
36
+ mouseleave: {
37
+ summary: '포인터가 컴포넌트 영역을 *이탈* 한 순간 1회.',
38
+ example: 'mouseenter 와 짝지어 강조 해제에 사용.'
39
+ },
40
+ longpress: {
41
+ summary: '약 500ms 이상 누름. 클릭과 별개로 발화.'
42
+ },
43
+ mousedown: {
44
+ summary: '버튼 누름 시작 시점. mouseup 과 짝지어 pressed 패턴 가능.'
45
+ },
46
+ mouseup: {
47
+ summary: '버튼 누름 해제 시점.'
48
+ },
49
+ pressed: {
50
+ summary: 'mousedown ↔ mouseup 페어 자동 매핑 (legacy 호환).'
51
+ }
52
+ };
53
+ const ACTION_DESC = {
54
+ '': {
55
+ summary: '액션이 선택되지 않음. 핸들러는 등록되지만 아무 동작도 하지 않는다.'
56
+ },
57
+ script: {
58
+ summary: '자유 JavaScript 코드. component / scene / event / targets / value 를 변수로 받아 임의 동작을 수행.',
59
+ example: 'await 사용 가능 — 비동기 동작도 그대로 작성.'
60
+ },
61
+ 'data-toggle': {
62
+ summary: 'target 컴포넌트의 data 값을 truthy ↔ falsy 로 토글.',
63
+ example: 'value 필드는 무시. target 미설정 시 자기 자신.'
64
+ },
65
+ 'data-tristate': {
66
+ summary: 'target 의 data 값을 0 → 1 → 2 → 0 순환.',
67
+ example: '세 상태 토글 (off / on / mixed 같은) 용.'
68
+ },
69
+ 'data-spreading': {
70
+ summary: 'target 들에 value 를 분배 (배열 또는 매핑).',
71
+ example: 'value 가 배열이면 target N개에 각각 매칭.'
72
+ },
73
+ 'data-set': {
74
+ summary: 'target 의 data 를 value 로 설정. value 는 정적 값 또는 accessor.',
75
+ example: '예) value=1 / value=accessor.someField'
76
+ },
77
+ 'partial-data-set': {
78
+ summary: 'target.data 가 객체일 때, value 의 키들만 partial merge.',
79
+ example: 'value 는 객체 또는 객체를 가리키는 accessor.'
80
+ },
81
+ 'value-set': {
82
+ summary: 'target 의 value 속성을 value 로 설정.',
83
+ example: 'data 가 아니라 value 속성을 다루는 컴포넌트용.'
84
+ },
85
+ 'partial-value-set': {
86
+ summary: 'target.value 가 객체일 때, partial merge.'
87
+ },
88
+ 'info-window': {
89
+ summary: 'target 의 info-window (팝업) 를 띄움.',
90
+ example: 'target 컴포넌트의 popup 정보가 미리 정의되어 있어야 함.'
91
+ },
92
+ emphasize: {
93
+ summary: 'target 을 시각적으로 강조 (애니메이션).',
94
+ example: 'mouseenter / mouseleave 와 짝지어 emphasize/restore 패턴 자주 사용.'
95
+ }
96
+ };
97
+ const SCRIPT_VARS = [
98
+ { name: 'component', desc: '핸들러가 등록된 현재 컴포넌트.' },
99
+ { name: 'scene', desc: '루트 scene. scene.root 로 다른 컴포넌트 검색.' },
100
+ { name: 'event', desc: '원본 DOM 이벤트 (또는 합성 이벤트) 객체.' },
101
+ { name: 'targets', desc: 'target selector 로 찾은 컴포넌트 배열. target 비면 빈 배열.' },
102
+ { name: 'value', desc: '핸들러의 value 필드 (정적 또는 accessor).' }
103
+ ];
104
+ const SNIPPETS = [
105
+ {
106
+ label: 'console.log',
107
+ code: `console.log('event handler', { component, event })`
108
+ },
109
+ {
110
+ label: 'data 토글',
111
+ code: `component.data = !component.data`
112
+ },
113
+ {
114
+ label: 'targets 에 값 세팅',
115
+ code: `targets.forEach(t => { t.data = value })`
116
+ },
117
+ {
118
+ label: 'findById 로 특정 컴포넌트 변경',
119
+ code: `// '#someId' 는 대상 컴포넌트의 id 로 바꿔 쓴다.
120
+ const target = scene.root.findAll('#someId', component)[0]
121
+ if (target) {
122
+ target.data = component.data
123
+ }`
124
+ },
125
+ {
126
+ label: 'async fetch + data 반영',
127
+ code: `const res = await fetch('/api/something')
128
+ const json = await res.json()
129
+ component.data = json`
130
+ }
131
+ ];
132
+ export class EventHandlersHelp extends LitElement {
133
+ render() {
134
+ var _a;
135
+ const h = this.handler || { trigger: 'click', action: '' };
136
+ const trigDesc = TRIGGER_DESC[h.trigger] || { summary: '(unknown trigger)' };
137
+ const actDesc = ACTION_DESC[(_a = h.action) !== null && _a !== void 0 ? _a : ''] || { summary: '(unknown action)' };
138
+ const isScript = h.action === 'script';
139
+ return html `
140
+ <section>
141
+ <h4>Trigger</h4>
142
+ <div class="name">${h.trigger}</div>
143
+ <p class="summary">${trigDesc.summary}</p>
144
+ ${trigDesc.example ? html `<div class="example">${trigDesc.example}</div>` : ''}
145
+ </section>
146
+
147
+ <section>
148
+ <h4>Action</h4>
149
+ <div class="name">${h.action || '(none)'}</div>
150
+ <p class="summary">${actDesc.summary}</p>
151
+ ${actDesc.example ? html `<div class="example">${actDesc.example}</div>` : ''}
152
+ </section>
153
+
154
+ ${isScript ? this._renderScriptHelp() : this._renderDeclarativeHelp()}
155
+ `;
156
+ }
157
+ _renderDeclarativeHelp() {
158
+ return html `
159
+ <section>
160
+ <h4>Target selector</h4>
161
+ <div class="selector-grid">
162
+ <code>#id</code><span>id 일치</span>
163
+ <code>.class</code><span>class 일치 (공백 구분 다중)</span>
164
+ <code>&lt;타입&gt;</code><span>type 일치 (예: rect, button)</span>
165
+ <code>(self)</code><span>현재 컴포넌트 자기 자신</span>
166
+ <code>(all)</code><span>모든 컴포넌트</span>
167
+ <code>(root)</code><span>루트 컴포넌트</span>
168
+ <code>(parent)</code><span>부모</span>
169
+ <code>(children)</code><span>직접 자식들</span>
170
+ <code>(siblings)</code><span>형제들 (자기 제외)</span>
171
+ </div>
172
+ <div class="example" style="margin-top:6px">
173
+ 비워두면 매칭 없음 — 자기 자신을 대상으로 하려면 <code style="background:transparent;padding:0">(self)</code>.
174
+ </div>
175
+ </section>
176
+
177
+ <section>
178
+ <h4>Value</h4>
179
+ <p class="summary">정적 값 또는 accessor 표현식. accessor 인 경우 component.access(value) 로 평가되어 컴포넌트 컨텍스트의 데이터를 참조한다.</p>
180
+ </section>
181
+ `;
182
+ }
183
+ _renderScriptHelp() {
184
+ return html `
185
+ <section>
186
+ <h4>Script 변수</h4>
187
+ <ul class="vars">
188
+ ${SCRIPT_VARS.map(v => html `
189
+ <li><code>${v.name}</code>${v.desc}</li>
190
+ `)}
191
+ </ul>
192
+ <div class="example" style="margin-top:8px">
193
+ <code style="background:transparent;padding:0">await</code> 키워드 사용 시 스크립트는 비동기로 실행. 결과 wait 후 다음 핸들러가 영향 받지는 않는다 (각 핸들러는 독립 실행).
194
+ </div>
195
+ </section>
196
+
197
+ <section>
198
+ <h4>Snippet 삽입</h4>
199
+ <div class="snippet-list">
200
+ ${SNIPPETS.map(s => html `
201
+ <button
202
+ type="button"
203
+ class="snippet-btn"
204
+ @click=${() => this._emitSnippet(s.code)}
205
+ title="현재 스크립트 영역에 삽입 (덮어쓰지 않고 끝에 추가)"
206
+ >
207
+ <span>${s.label}</span>
208
+ <md-icon>add</md-icon>
209
+ </button>
210
+ `)}
211
+ </div>
212
+ </section>
213
+ `;
214
+ }
215
+ _emitSnippet(code) {
216
+ this.dispatchEvent(new CustomEvent('insert-snippet', {
217
+ bubbles: true,
218
+ composed: true,
219
+ detail: { code }
220
+ }));
221
+ }
222
+ }
223
+ EventHandlersHelp.styles = [
224
+ ScrollbarStyles,
225
+ css `
226
+ :host {
227
+ display: flex;
228
+ flex-direction: column;
229
+ width: 100%;
230
+ height: 100%;
231
+ box-sizing: border-box;
232
+ background: var(--md-sys-color-surface-container-lowest, #fffbfe);
233
+ border-left: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.12));
234
+ padding: 16px 18px;
235
+ overflow-y: auto;
236
+ font-family: 'Roboto', Arial, sans-serif;
237
+ font-size: 12.5px;
238
+ color: var(--md-sys-color-on-surface, #1c1b1f);
239
+ line-height: 1.5;
240
+ min-width: 0;
241
+ }
242
+
243
+ h4 {
244
+ margin: 0 0 6px 0;
245
+ font-size: 11px;
246
+ font-weight: 700;
247
+ letter-spacing: 0.5px;
248
+ text-transform: uppercase;
249
+ color: var(--md-sys-color-on-surface-variant, #49454f);
250
+ }
251
+
252
+ section {
253
+ margin-bottom: 18px;
254
+ }
255
+
256
+ .name {
257
+ display: inline-block;
258
+ padding: 2px 6px;
259
+ margin-bottom: 6px;
260
+ background: var(--md-sys-color-secondary-container, #e8def8);
261
+ color: var(--md-sys-color-on-secondary-container, #1d192b);
262
+ border-radius: 4px;
263
+ font-weight: 600;
264
+ font-size: 11.5px;
265
+ }
266
+
267
+ .summary {
268
+ margin: 0 0 6px 0;
269
+ }
270
+
271
+ .example {
272
+ margin: 4px 0 0 0;
273
+ padding: 6px 8px;
274
+ background: rgba(0, 0, 0, 0.04);
275
+ border-left: 2px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.2));
276
+ font-size: 11.5px;
277
+ color: var(--md-sys-color-on-surface-variant, #49454f);
278
+ }
279
+
280
+ ul.vars {
281
+ list-style: none;
282
+ margin: 0;
283
+ padding: 0;
284
+ }
285
+
286
+ ul.vars li {
287
+ padding: 4px 0;
288
+ border-bottom: 1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.08));
289
+ }
290
+
291
+ ul.vars li:last-child {
292
+ border-bottom: none;
293
+ }
294
+
295
+ ul.vars code {
296
+ display: inline-block;
297
+ padding: 1px 5px;
298
+ margin-right: 6px;
299
+ background: var(--md-sys-color-surface-container-high, #ede7f6);
300
+ border-radius: 3px;
301
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
302
+ font-size: 11px;
303
+ color: var(--md-sys-color-on-surface, #1c1b1f);
304
+ }
305
+
306
+ .snippet-list {
307
+ display: flex;
308
+ flex-direction: column;
309
+ gap: 6px;
310
+ }
311
+
312
+ .snippet-btn {
313
+ display: flex;
314
+ align-items: center;
315
+ justify-content: space-between;
316
+ gap: 6px;
317
+ padding: 6px 10px;
318
+ border: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.18));
319
+ border-radius: 4px;
320
+ background: var(--md-sys-color-surface, #fff);
321
+ color: var(--md-sys-color-on-surface, #1c1b1f);
322
+ font-size: 12px;
323
+ cursor: pointer;
324
+ text-align: left;
325
+ }
326
+
327
+ .snippet-btn:hover {
328
+ background: var(--md-sys-color-surface-container-low, #f7f2fa);
329
+ }
330
+
331
+ .snippet-btn md-icon {
332
+ --md-icon-size: 16px;
333
+ opacity: 0.7;
334
+ }
335
+
336
+ .selector-grid {
337
+ display: grid;
338
+ grid-template-columns: max-content 1fr;
339
+ column-gap: 10px;
340
+ row-gap: 4px;
341
+ font-size: 11.5px;
342
+ }
343
+
344
+ .selector-grid code {
345
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
346
+ background: var(--md-sys-color-surface-container-high, #ede7f6);
347
+ padding: 1px 5px;
348
+ border-radius: 3px;
349
+ }
350
+ `
351
+ ];
352
+ __decorate([
353
+ property({ type: Object })
354
+ ], EventHandlersHelp.prototype, "handler", void 0);
355
+ customElements.define('event-handlers-help', EventHandlersHelp);
356
+ //# sourceMappingURL=event-handlers-help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-handlers-help.js","sourceRoot":"","sources":["../../../../src/property-panel/event-handlers/event-handlers-help.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n *\n * EventHandlers help pane — popup 의 우측 docs 컬럼.\n *\n * 현재 선택된 handler 의 trigger / action / target / value (또는 script vars)\n * 의미를 *동적으로* 안내. script 모드에서는 자주 쓰는 코드 snippet 을\n * 삽입할 수 있는 버튼도 제공.\n *\n * 다국어 — 1차안은 한국어 hard-code (5 언어 동시 유지 부담 회피).\n * 추후 안정화 후 i18n 키로 분리.\n */\n\nimport '@material/web/icon/icon.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { ScrollbarStyles } from '@operato/styles'\n\nimport type { EventHandlerSpec } from './event-handlers-mapper.js'\n\ntype DescEntry = { summary: string; example?: string }\n\nconst TRIGGER_DESC: Record<string, DescEntry> = {\n click: {\n summary: '마우스 클릭 (터치 환경에선 tap 과 동일).',\n example: '가장 일반적인 버튼/아이콘 액션에 사용.'\n },\n tap: {\n summary: 'click 의 alias (legacy 호환). 신규 등록은 click 권장.'\n },\n dblclick: {\n summary: '더블 클릭. 빠른 연속 2회 클릭으로만 발화.'\n },\n mouseenter: {\n summary: '포인터가 컴포넌트 영역에 *진입* 한 순간 1회.',\n example: 'hover 강조 / tooltip 표시에 사용.'\n },\n hover: {\n summary: 'mouseenter 의 alias (legacy). 신규 등록은 mouseenter 권장.'\n },\n mouseleave: {\n summary: '포인터가 컴포넌트 영역을 *이탈* 한 순간 1회.',\n example: 'mouseenter 와 짝지어 강조 해제에 사용.'\n },\n longpress: {\n summary: '약 500ms 이상 누름. 클릭과 별개로 발화.'\n },\n mousedown: {\n summary: '버튼 누름 시작 시점. mouseup 과 짝지어 pressed 패턴 가능.'\n },\n mouseup: {\n summary: '버튼 누름 해제 시점.'\n },\n pressed: {\n summary: 'mousedown ↔ mouseup 페어 자동 매핑 (legacy 호환).'\n }\n}\n\nconst ACTION_DESC: Record<string, DescEntry> = {\n '': {\n summary: '액션이 선택되지 않음. 핸들러는 등록되지만 아무 동작도 하지 않는다.'\n },\n script: {\n summary: '자유 JavaScript 코드. component / scene / event / targets / value 를 변수로 받아 임의 동작을 수행.',\n example: 'await 사용 가능 — 비동기 동작도 그대로 작성.'\n },\n 'data-toggle': {\n summary: 'target 컴포넌트의 data 값을 truthy ↔ falsy 로 토글.',\n example: 'value 필드는 무시. target 미설정 시 자기 자신.'\n },\n 'data-tristate': {\n summary: 'target 의 data 값을 0 → 1 → 2 → 0 순환.',\n example: '세 상태 토글 (off / on / mixed 같은) 용.'\n },\n 'data-spreading': {\n summary: 'target 들에 value 를 분배 (배열 또는 매핑).',\n example: 'value 가 배열이면 target N개에 각각 매칭.'\n },\n 'data-set': {\n summary: 'target 의 data 를 value 로 설정. value 는 정적 값 또는 accessor.',\n example: '예) value=1 / value=accessor.someField'\n },\n 'partial-data-set': {\n summary: 'target.data 가 객체일 때, value 의 키들만 partial merge.',\n example: 'value 는 객체 또는 객체를 가리키는 accessor.'\n },\n 'value-set': {\n summary: 'target 의 value 속성을 value 로 설정.',\n example: 'data 가 아니라 value 속성을 다루는 컴포넌트용.'\n },\n 'partial-value-set': {\n summary: 'target.value 가 객체일 때, partial merge.'\n },\n 'info-window': {\n summary: 'target 의 info-window (팝업) 를 띄움.',\n example: 'target 컴포넌트의 popup 정보가 미리 정의되어 있어야 함.'\n },\n emphasize: {\n summary: 'target 을 시각적으로 강조 (애니메이션).',\n example: 'mouseenter / mouseleave 와 짝지어 emphasize/restore 패턴 자주 사용.'\n }\n}\n\nconst SCRIPT_VARS = [\n { name: 'component', desc: '핸들러가 등록된 현재 컴포넌트.' },\n { name: 'scene', desc: '루트 scene. scene.root 로 다른 컴포넌트 검색.' },\n { name: 'event', desc: '원본 DOM 이벤트 (또는 합성 이벤트) 객체.' },\n { name: 'targets', desc: 'target selector 로 찾은 컴포넌트 배열. target 비면 빈 배열.' },\n { name: 'value', desc: '핸들러의 value 필드 (정적 또는 accessor).' }\n]\n\nconst SNIPPETS: { label: string; code: string }[] = [\n {\n label: 'console.log',\n code: `console.log('event handler', { component, event })`\n },\n {\n label: 'data 토글',\n code: `component.data = !component.data`\n },\n {\n label: 'targets 에 값 세팅',\n code: `targets.forEach(t => { t.data = value })`\n },\n {\n label: 'findById 로 특정 컴포넌트 변경',\n code: `// '#someId' 는 대상 컴포넌트의 id 로 바꿔 쓴다.\nconst target = scene.root.findAll('#someId', component)[0]\nif (target) {\n target.data = component.data\n}`\n },\n {\n label: 'async fetch + data 반영',\n code: `const res = await fetch('/api/something')\nconst json = await res.json()\ncomponent.data = json`\n }\n]\n\nexport class EventHandlersHelp extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n background: var(--md-sys-color-surface-container-lowest, #fffbfe);\n border-left: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.12));\n padding: 16px 18px;\n overflow-y: auto;\n font-family: 'Roboto', Arial, sans-serif;\n font-size: 12.5px;\n color: var(--md-sys-color-on-surface, #1c1b1f);\n line-height: 1.5;\n min-width: 0;\n }\n\n h4 {\n margin: 0 0 6px 0;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.5px;\n text-transform: uppercase;\n color: var(--md-sys-color-on-surface-variant, #49454f);\n }\n\n section {\n margin-bottom: 18px;\n }\n\n .name {\n display: inline-block;\n padding: 2px 6px;\n margin-bottom: 6px;\n background: var(--md-sys-color-secondary-container, #e8def8);\n color: var(--md-sys-color-on-secondary-container, #1d192b);\n border-radius: 4px;\n font-weight: 600;\n font-size: 11.5px;\n }\n\n .summary {\n margin: 0 0 6px 0;\n }\n\n .example {\n margin: 4px 0 0 0;\n padding: 6px 8px;\n background: rgba(0, 0, 0, 0.04);\n border-left: 2px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.2));\n font-size: 11.5px;\n color: var(--md-sys-color-on-surface-variant, #49454f);\n }\n\n ul.vars {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n ul.vars li {\n padding: 4px 0;\n border-bottom: 1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.08));\n }\n\n ul.vars li:last-child {\n border-bottom: none;\n }\n\n ul.vars code {\n display: inline-block;\n padding: 1px 5px;\n margin-right: 6px;\n background: var(--md-sys-color-surface-container-high, #ede7f6);\n border-radius: 3px;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n color: var(--md-sys-color-on-surface, #1c1b1f);\n }\n\n .snippet-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .snippet-btn {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n padding: 6px 10px;\n border: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.18));\n border-radius: 4px;\n background: var(--md-sys-color-surface, #fff);\n color: var(--md-sys-color-on-surface, #1c1b1f);\n font-size: 12px;\n cursor: pointer;\n text-align: left;\n }\n\n .snippet-btn:hover {\n background: var(--md-sys-color-surface-container-low, #f7f2fa);\n }\n\n .snippet-btn md-icon {\n --md-icon-size: 16px;\n opacity: 0.7;\n }\n\n .selector-grid {\n display: grid;\n grid-template-columns: max-content 1fr;\n column-gap: 10px;\n row-gap: 4px;\n font-size: 11.5px;\n }\n\n .selector-grid code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n background: var(--md-sys-color-surface-container-high, #ede7f6);\n padding: 1px 5px;\n border-radius: 3px;\n }\n `\n ]\n\n @property({ type: Object }) handler?: EventHandlerSpec\n\n render() {\n const h = this.handler || { trigger: 'click', action: '' }\n const trigDesc = TRIGGER_DESC[h.trigger] || { summary: '(unknown trigger)' }\n const actDesc = ACTION_DESC[h.action ?? ''] || { summary: '(unknown action)' }\n const isScript = h.action === 'script'\n\n return html`\n <section>\n <h4>Trigger</h4>\n <div class=\"name\">${h.trigger}</div>\n <p class=\"summary\">${trigDesc.summary}</p>\n ${trigDesc.example ? html`<div class=\"example\">${trigDesc.example}</div>` : ''}\n </section>\n\n <section>\n <h4>Action</h4>\n <div class=\"name\">${h.action || '(none)'}</div>\n <p class=\"summary\">${actDesc.summary}</p>\n ${actDesc.example ? html`<div class=\"example\">${actDesc.example}</div>` : ''}\n </section>\n\n ${isScript ? this._renderScriptHelp() : this._renderDeclarativeHelp()}\n `\n }\n\n private _renderDeclarativeHelp() {\n return html`\n <section>\n <h4>Target selector</h4>\n <div class=\"selector-grid\">\n <code>#id</code><span>id 일치</span>\n <code>.class</code><span>class 일치 (공백 구분 다중)</span>\n <code>&lt;타입&gt;</code><span>type 일치 (예: rect, button)</span>\n <code>(self)</code><span>현재 컴포넌트 자기 자신</span>\n <code>(all)</code><span>모든 컴포넌트</span>\n <code>(root)</code><span>루트 컴포넌트</span>\n <code>(parent)</code><span>부모</span>\n <code>(children)</code><span>직접 자식들</span>\n <code>(siblings)</code><span>형제들 (자기 제외)</span>\n </div>\n <div class=\"example\" style=\"margin-top:6px\">\n 비워두면 매칭 없음 — 자기 자신을 대상으로 하려면 <code style=\"background:transparent;padding:0\">(self)</code>.\n </div>\n </section>\n\n <section>\n <h4>Value</h4>\n <p class=\"summary\">정적 값 또는 accessor 표현식. accessor 인 경우 component.access(value) 로 평가되어 컴포넌트 컨텍스트의 데이터를 참조한다.</p>\n </section>\n `\n }\n\n private _renderScriptHelp() {\n return html`\n <section>\n <h4>Script 변수</h4>\n <ul class=\"vars\">\n ${SCRIPT_VARS.map(\n v => html`\n <li><code>${v.name}</code>${v.desc}</li>\n `\n )}\n </ul>\n <div class=\"example\" style=\"margin-top:8px\">\n <code style=\"background:transparent;padding:0\">await</code> 키워드 사용 시 스크립트는 비동기로 실행. 결과 wait 후 다음 핸들러가 영향 받지는 않는다 (각 핸들러는 독립 실행).\n </div>\n </section>\n\n <section>\n <h4>Snippet 삽입</h4>\n <div class=\"snippet-list\">\n ${SNIPPETS.map(\n s => html`\n <button\n type=\"button\"\n class=\"snippet-btn\"\n @click=${() => this._emitSnippet(s.code)}\n title=\"현재 스크립트 영역에 삽입 (덮어쓰지 않고 끝에 추가)\"\n >\n <span>${s.label}</span>\n <md-icon>add</md-icon>\n </button>\n `\n )}\n </div>\n </section>\n `\n }\n\n private _emitSnippet(code: string) {\n this.dispatchEvent(\n new CustomEvent('insert-snippet', {\n bubbles: true,\n composed: true,\n detail: { code }\n })\n )\n }\n}\n\ncustomElements.define('event-handlers-help', EventHandlersHelp)\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,238 @@
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 class="row">
79
+ <label><ox-i18n msgid="label.value">Value</ox-i18n></label>
80
+ <input type="text"
81
+ placeholder="optional · script 안 value 변수로 전달"
82
+ .value=${h.value !== undefined ? String(h.value) : ''}
83
+ @change=${(e) => this._update('value', e.target.value)}
84
+ />
85
+ </div>
86
+ <div script-field>
87
+ <div class="script-header">
88
+ <ox-i18n msgid="label.script">Script</ox-i18n>
89
+ <small>vars: component, scene, event, targets, value · await 지원</small>
90
+ </div>
91
+ <ox-input-code
92
+ mode="javascript"
93
+ .value=${h.code || ''}
94
+ @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 : ''); }}
95
+ ></ox-input-code>
96
+ </div>
97
+ `;
98
+ }
99
+ _renderActionFields(h) {
100
+ return html `
101
+ <div class="row">
102
+ <label><ox-i18n msgid="label.target">Target</ox-i18n></label>
103
+ <input type="text"
104
+ placeholder="selector (#id, .class, ...)"
105
+ .value=${h.target || ''}
106
+ @change=${(e) => this._update('target', e.target.value)}
107
+ />
108
+ </div>
109
+ <div class="row">
110
+ <label><ox-i18n msgid="label.value">Value</ox-i18n></label>
111
+ <input type="text"
112
+ placeholder="value or accessor"
113
+ .value=${h.value !== undefined ? String(h.value) : ''}
114
+ @change=${(e) => this._update('value', e.target.value)}
115
+ />
116
+ </div>
117
+ `;
118
+ }
119
+ _update(key, value) {
120
+ const next = { ...(this.handler || { trigger: 'click', action: '' }), [key]: value };
121
+ // action 전환 시 비-script 진입은 code 정리. script 진입 시 target/value 는
122
+ // 의미가 호환 (target=findAll selector, value=script 입력) 이라 유지.
123
+ if (key === 'action' && value !== 'script') {
124
+ delete next.code;
125
+ }
126
+ this.handler = next;
127
+ this.dispatchEvent(new CustomEvent('value-change', {
128
+ bubbles: true,
129
+ composed: true,
130
+ detail: { handler: next, changed: { [key]: value } }
131
+ }));
132
+ }
133
+ }
134
+ EventHandlersMapper.styles = [
135
+ css `
136
+ :host {
137
+ display: flex;
138
+ flex-direction: column;
139
+ gap: 6px;
140
+ padding: 10px 10px 10px 10px;
141
+ /* 카드 외곽 — tabs (위) + toolbar (중간) + mapper (아래) 가 하나의 카드.
142
+ * 위쪽 1px 는 toolbar 와의 internal divider. radius 6px 으로 통일. */
143
+ border: 1px solid rgba(0, 0, 0, 0.18);
144
+ border-radius: 0 0 6px 6px;
145
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
146
+ line-height: 2;
147
+ background: var(--md-sys-color-surface, #fff);
148
+ min-width: 0;
149
+ width: 100%;
150
+ box-sizing: border-box;
151
+ overflow: hidden;
152
+ flex: 1;
153
+ min-height: 0;
154
+ }
155
+
156
+ [script-field] {
157
+ display: flex;
158
+ flex-direction: column;
159
+ min-height: 0;
160
+ flex: 1;
161
+ margin-top: 6px;
162
+ padding-top: 10px;
163
+ /* trigger/action/target/value 입력 묶음과 code editor 사이의 구분선.
164
+ * dashed 대신 solid + 옅은 opacity 로 modern. */
165
+ border-top: 1px solid rgba(0, 0, 0, 0.08);
166
+ }
167
+
168
+ [script-field] > .script-header {
169
+ display: flex;
170
+ align-items: baseline;
171
+ gap: 8px;
172
+ margin-bottom: 6px;
173
+ font-size: 10.5px;
174
+ font-weight: 700;
175
+ text-transform: uppercase;
176
+ letter-spacing: 0.6px;
177
+ color: var(--md-sys-color-on-surface-variant, #49454f);
178
+ }
179
+
180
+ [script-field] > .script-header small {
181
+ font-weight: 400;
182
+ text-transform: none;
183
+ letter-spacing: 0;
184
+ opacity: 0.65;
185
+ font-size: 10.5px;
186
+ }
187
+
188
+ .row {
189
+ display: grid;
190
+ grid-template-columns: 80px 1fr;
191
+ gap: 6px;
192
+ align-items: center;
193
+ min-width: 0;
194
+ }
195
+
196
+ .row > select,
197
+ .row > input[type='text'] {
198
+ width: 100%;
199
+ min-width: 0;
200
+ box-sizing: border-box;
201
+ padding: 3px 6px;
202
+ font-size: 13px;
203
+ border-radius: 4px;
204
+ border: 1px solid rgba(0, 0, 0, 0.15);
205
+ background: #fff;
206
+ }
207
+
208
+ ox-input-code {
209
+ /* display 는 *지정하지 않는다* — outside selector 가 ox-input-code 의
210
+ * :host { display: flex; flex-direction: column } 를 덮어쓰면, 그 안의
211
+ * .cm-editor { flex: 1 } 가 작동을 멈춰 텍스트 라인 1개 크기로 축소된다. */
212
+ width: 100%;
213
+ max-width: 100%;
214
+ min-width: 0;
215
+ box-sizing: border-box;
216
+ overflow: hidden;
217
+ min-height: 180px;
218
+ border: 1px solid rgba(0, 0, 0, 0.15);
219
+ border-radius: 4px;
220
+ /* popup 모드에서 script-field 의 남은 세로 공간을 모두 차지 — 아래 빈공간 X.
221
+ * inline 모드에서는 script-field 가 grow 하지 않으므로 min-height 180px 만 사용. */
222
+ flex: 1;
223
+ }
224
+
225
+ label {
226
+ font-size: 12px;
227
+ color: var(--md-sys-color-on-surface-variant, #49454f);
228
+ }
229
+ `
230
+ ];
231
+ __decorate([
232
+ property({ type: Object })
233
+ ], EventHandlersMapper.prototype, "handler", void 0);
234
+ __decorate([
235
+ property({ type: Object })
236
+ ], EventHandlersMapper.prototype, "scene", void 0);
237
+ customElements.define('event-handlers-mapper', EventHandlersMapper);
238
+ //# sourceMappingURL=event-handlers-mapper.js.map