@operato/property-editor 10.0.0-beta.7 → 10.0.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 +260 -0
- package/dist/src/ox-property-editor-backdrop-faces.d.ts +60 -0
- package/dist/src/ox-property-editor-backdrop-faces.js +530 -0
- package/dist/src/ox-property-editor-backdrop-faces.js.map +1 -0
- package/dist/src/ox-property-editor-date.js +9 -1
- package/dist/src/ox-property-editor-date.js.map +1 -1
- package/dist/src/ox-property-editor-datetime.js +9 -1
- package/dist/src/ox-property-editor-datetime.js.map +1 -1
- package/dist/src/ox-property-editor-fill-style.d.ts +20 -0
- package/dist/src/ox-property-editor-fill-style.js +55 -0
- package/dist/src/ox-property-editor-fill-style.js.map +1 -0
- package/dist/src/ox-property-editor-time.js +9 -1
- package/dist/src/ox-property-editor-time.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -6
- package/themes/grist-theme.css +1 -1
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import '@operato/input/ox-input-fill-style.js';
|
|
3
|
+
import '@operato/i18n/ox-i18n.js';
|
|
4
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
5
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
6
|
+
import { OxPropertyEditor } from './ox-property-editor.js';
|
|
7
|
+
const OPPOSITE = {
|
|
8
|
+
east: 'west',
|
|
9
|
+
west: 'east',
|
|
10
|
+
north: 'south',
|
|
11
|
+
south: 'north',
|
|
12
|
+
ceiling: 'floor',
|
|
13
|
+
floor: 'ceiling'
|
|
14
|
+
};
|
|
15
|
+
const AXIS_LABEL = {
|
|
16
|
+
east: '+X',
|
|
17
|
+
west: '−X',
|
|
18
|
+
north: '−Z',
|
|
19
|
+
south: '+Z',
|
|
20
|
+
ceiling: '+Y',
|
|
21
|
+
floor: '−Y'
|
|
22
|
+
};
|
|
23
|
+
const DEFAULT_FACES = {
|
|
24
|
+
east: { fillStyle: '#dde2e8', visible: true, alpha: 0.35, rotation: 0, mirror: false },
|
|
25
|
+
west: { fillStyle: '#dde2e8', visible: true, alpha: 0.35, rotation: 0, mirror: false },
|
|
26
|
+
north: { fillStyle: '#dde2e8', visible: true, alpha: 0.35, rotation: 0, mirror: false },
|
|
27
|
+
south: { fillStyle: '#dde2e8', visible: true, alpha: 0.35, rotation: 0, mirror: false },
|
|
28
|
+
ceiling: { fillStyle: '#e8e8ec', visible: true, alpha: 1.0, rotation: 0, mirror: false },
|
|
29
|
+
floor: { fillStyle: '#9c9c9c', visible: true, alpha: 1.0, rotation: 0, mirror: false }
|
|
30
|
+
};
|
|
31
|
+
let OxInputBackdropFaces = class OxInputBackdropFaces extends LitElement {
|
|
32
|
+
constructor() {
|
|
33
|
+
super(...arguments);
|
|
34
|
+
this.value = {};
|
|
35
|
+
this._selected = 'ceiling';
|
|
36
|
+
}
|
|
37
|
+
_face(name) {
|
|
38
|
+
var _a, _b;
|
|
39
|
+
return { ...DEFAULT_FACES[name], ...((_b = (_a = this.value) === null || _a === void 0 ? void 0 : _a[name]) !== null && _b !== void 0 ? _b : {}) };
|
|
40
|
+
}
|
|
41
|
+
/** fillStyle 의 대표 색을 swatch 용으로 추출. 없으면 undefined → hatched 표시. */
|
|
42
|
+
_swatchColor(name) {
|
|
43
|
+
var _a;
|
|
44
|
+
const fs = this._face(name).fillStyle;
|
|
45
|
+
if (typeof fs === 'string' && fs && fs !== 'transparent')
|
|
46
|
+
return fs;
|
|
47
|
+
if (fs && typeof fs === 'object') {
|
|
48
|
+
if (fs.type === 'gradient' && Array.isArray(fs.colorStops) && ((_a = fs.colorStops[0]) === null || _a === void 0 ? void 0 : _a.color)) {
|
|
49
|
+
return fs.colorStops[0].color;
|
|
50
|
+
}
|
|
51
|
+
if (fs.color)
|
|
52
|
+
return fs.color;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
_select(name) {
|
|
57
|
+
this._selected = name;
|
|
58
|
+
}
|
|
59
|
+
_commit(next) {
|
|
60
|
+
this.value = next;
|
|
61
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
|
62
|
+
}
|
|
63
|
+
_patchFace(name, patch) {
|
|
64
|
+
const next = { ...(this.value || {}) };
|
|
65
|
+
next[name] = { ...this._face(name), ...patch };
|
|
66
|
+
this._commit(next);
|
|
67
|
+
}
|
|
68
|
+
_onFillStyleChange(e) {
|
|
69
|
+
e.stopPropagation();
|
|
70
|
+
const target = e.target;
|
|
71
|
+
this._patchFace(this._selected, { fillStyle: target.value });
|
|
72
|
+
}
|
|
73
|
+
_onVisibleChange(e) {
|
|
74
|
+
e.stopPropagation();
|
|
75
|
+
const target = e.target;
|
|
76
|
+
this._patchFace(this._selected, { visible: target.checked });
|
|
77
|
+
}
|
|
78
|
+
_onAlphaChange(e) {
|
|
79
|
+
e.stopPropagation();
|
|
80
|
+
const target = e.target;
|
|
81
|
+
const v = parseFloat(target.value);
|
|
82
|
+
const alpha = Number.isFinite(v) ? Math.max(0, Math.min(1, v)) : 1;
|
|
83
|
+
this._patchFace(this._selected, { alpha });
|
|
84
|
+
}
|
|
85
|
+
_onRotationChange(e) {
|
|
86
|
+
e.stopPropagation();
|
|
87
|
+
const target = e.target;
|
|
88
|
+
const n = parseInt(target.value, 10);
|
|
89
|
+
const rotation = n === 90 || n === 180 || n === 270 ? n : 0;
|
|
90
|
+
this._patchFace(this._selected, { rotation });
|
|
91
|
+
}
|
|
92
|
+
_onMirrorChange(e) {
|
|
93
|
+
e.stopPropagation();
|
|
94
|
+
const target = e.target;
|
|
95
|
+
this._patchFace(this._selected, { mirror: target.checked });
|
|
96
|
+
}
|
|
97
|
+
_copyToOpposite() {
|
|
98
|
+
const src = this._face(this._selected);
|
|
99
|
+
const opposite = OPPOSITE[this._selected];
|
|
100
|
+
const next = { ...(this.value || {}) };
|
|
101
|
+
next[opposite] = { ...src };
|
|
102
|
+
this._commit(next);
|
|
103
|
+
}
|
|
104
|
+
_copyToAllWalls() {
|
|
105
|
+
const src = this._face(this._selected);
|
|
106
|
+
const next = { ...(this.value || {}) };
|
|
107
|
+
for (const w of ['east', 'west', 'north', 'south']) {
|
|
108
|
+
next[w] = { ...src };
|
|
109
|
+
}
|
|
110
|
+
this._commit(next);
|
|
111
|
+
}
|
|
112
|
+
_renderLabel(name, x, y) {
|
|
113
|
+
const f = this._face(name);
|
|
114
|
+
const swatch = this._swatchColor(name);
|
|
115
|
+
const selected = this._selected === name;
|
|
116
|
+
return html `
|
|
117
|
+
<div
|
|
118
|
+
class="face-label ${selected ? 'selected' : ''}"
|
|
119
|
+
style="left: ${x}px; top: ${y}px;"
|
|
120
|
+
@click=${() => this._select(name)}
|
|
121
|
+
title=${`${name} (${AXIS_LABEL[name]})`}
|
|
122
|
+
>
|
|
123
|
+
<span
|
|
124
|
+
class="swatch"
|
|
125
|
+
style=${swatch ? `background: ${swatch};` : ''}
|
|
126
|
+
?data-empty=${!swatch}
|
|
127
|
+
></span>
|
|
128
|
+
<ox-i18n msgid="label.${name}">${name}</ox-i18n>
|
|
129
|
+
${f.visible === false ? html `<span class="eye" title="hidden">⊘</span>` : nothing}
|
|
130
|
+
</div>
|
|
131
|
+
`;
|
|
132
|
+
}
|
|
133
|
+
_faceClass(name) {
|
|
134
|
+
const cls = ['face-poly'];
|
|
135
|
+
if (this._selected === name)
|
|
136
|
+
cls.push('selected');
|
|
137
|
+
if (this._face(name).visible === false)
|
|
138
|
+
cls.push('hidden-face');
|
|
139
|
+
return cls.join(' ');
|
|
140
|
+
}
|
|
141
|
+
_ghostClass(name) {
|
|
142
|
+
const cls = ['face-ghost'];
|
|
143
|
+
if (this._selected === name)
|
|
144
|
+
cls.push('selected');
|
|
145
|
+
if (this._face(name).visible === false)
|
|
146
|
+
cls.push('invisible');
|
|
147
|
+
return cls.join(' ');
|
|
148
|
+
}
|
|
149
|
+
render() {
|
|
150
|
+
var _a, _b, _c, _d, _e, _f;
|
|
151
|
+
const sel = this._face(this._selected);
|
|
152
|
+
return html `
|
|
153
|
+
<div class="cube-picker">
|
|
154
|
+
<svg viewBox="0 0 288 160" aria-label="Backdrop face picker">
|
|
155
|
+
<!-- Cabinet projection — south face 정면 1:1 (큰 사각형),
|
|
156
|
+
east axis 는 30° 위방향으로 절반 foreshortened (좁게 보임),
|
|
157
|
+
vertical 은 0.7 배로 압축해 안정감 있는 납작한 형태.
|
|
158
|
+
L=80, depth=40, yScale=0.7 → vertical edge 56.
|
|
159
|
+
south face (z=L) 좌하단을 (90,125) 로 배치. -->
|
|
160
|
+
|
|
161
|
+
<!-- Ceiling (+Y, top) — trapezoid -->
|
|
162
|
+
<polygon
|
|
163
|
+
class=${this._faceClass('ceiling')}
|
|
164
|
+
points="90,69 170,69 198,41 118,41"
|
|
165
|
+
fill="${(_a = this._swatchColor('ceiling')) !== null && _a !== void 0 ? _a : '#fff8e1'}"
|
|
166
|
+
@click=${() => this._select('ceiling')}
|
|
167
|
+
/>
|
|
168
|
+
<!-- East face (+X, right) — narrow parallelogram -->
|
|
169
|
+
<polygon
|
|
170
|
+
class=${this._faceClass('east')}
|
|
171
|
+
points="170,125 198,97 198,41 170,69"
|
|
172
|
+
fill="${(_b = this._swatchColor('east')) !== null && _b !== void 0 ? _b : '#ffcdd2'}"
|
|
173
|
+
@click=${() => this._select('east')}
|
|
174
|
+
/>
|
|
175
|
+
<!-- South face (+Z, front) — dominant rectangle 80×56 -->
|
|
176
|
+
<polygon
|
|
177
|
+
class=${this._faceClass('south')}
|
|
178
|
+
points="90,125 170,125 170,69 90,69"
|
|
179
|
+
fill="${(_c = this._swatchColor('south')) !== null && _c !== void 0 ? _c : '#c8e6c9'}"
|
|
180
|
+
@click=${() => this._select('south')}
|
|
181
|
+
/>
|
|
182
|
+
|
|
183
|
+
<!-- Back-face ghost outlines (always faint, accent on selection). -->
|
|
184
|
+
<polygon
|
|
185
|
+
class=${this._ghostClass('north')}
|
|
186
|
+
points="118,97 198,97 198,41 118,41"
|
|
187
|
+
@click=${() => this._select('north')}
|
|
188
|
+
/>
|
|
189
|
+
<polygon
|
|
190
|
+
class=${this._ghostClass('west')}
|
|
191
|
+
points="118,97 90,125 90,69 118,41"
|
|
192
|
+
@click=${() => this._select('west')}
|
|
193
|
+
/>
|
|
194
|
+
<polygon
|
|
195
|
+
class=${this._ghostClass('floor')}
|
|
196
|
+
points="118,97 198,97 170,125 90,125"
|
|
197
|
+
@click=${() => this._select('floor')}
|
|
198
|
+
/>
|
|
199
|
+
</svg>
|
|
200
|
+
|
|
201
|
+
${this._renderLabel('ceiling', 144, 20)} ${this._renderLabel('floor', 144, 146)}
|
|
202
|
+
${this._renderLabel('east', 220, 83)} ${this._renderLabel('west', 38, 83)}
|
|
203
|
+
${this._renderLabel('north', 220, 51)} ${this._renderLabel('south', 38, 115)}
|
|
204
|
+
</div>
|
|
205
|
+
|
|
206
|
+
<div class="face-detail">
|
|
207
|
+
<div class="face-detail-title">
|
|
208
|
+
<span><ox-i18n msgid="label.${this._selected}">${this._selected}</ox-i18n></span>
|
|
209
|
+
<small>${AXIS_LABEL[this._selected]}</small>
|
|
210
|
+
</div>
|
|
211
|
+
|
|
212
|
+
<div class="row">
|
|
213
|
+
<label><ox-i18n msgid="label.visible">visible</ox-i18n></label>
|
|
214
|
+
<div class="ctl">
|
|
215
|
+
<input type="checkbox" ?checked=${sel.visible !== false} @change=${this._onVisibleChange} />
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
<div class="fill-row">
|
|
220
|
+
<ox-input-fill-style .value=${sel.fillStyle} fullwidth @change=${this._onFillStyleChange}>
|
|
221
|
+
</ox-input-fill-style>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
<div class="row">
|
|
225
|
+
<label><ox-i18n msgid="label.alpha">alpha</ox-i18n></label>
|
|
226
|
+
<div class="ctl">
|
|
227
|
+
<input
|
|
228
|
+
type="range"
|
|
229
|
+
min="0"
|
|
230
|
+
max="1"
|
|
231
|
+
step="0.05"
|
|
232
|
+
.value=${String((_d = sel.alpha) !== null && _d !== void 0 ? _d : 1)}
|
|
233
|
+
@input=${this._onAlphaChange}
|
|
234
|
+
/>
|
|
235
|
+
<span class="alpha-readout">${((_e = sel.alpha) !== null && _e !== void 0 ? _e : 1).toFixed(2)}</span>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<div class="row">
|
|
240
|
+
<label><ox-i18n msgid="label.rotation">rotation</ox-i18n></label>
|
|
241
|
+
<div class="ctl">
|
|
242
|
+
<select .value=${String((_f = sel.rotation) !== null && _f !== void 0 ? _f : 0)} @change=${this._onRotationChange}>
|
|
243
|
+
<option value="0">0°</option>
|
|
244
|
+
<option value="90">90°</option>
|
|
245
|
+
<option value="180">180°</option>
|
|
246
|
+
<option value="270">270°</option>
|
|
247
|
+
</select>
|
|
248
|
+
<label class="mirror-toggle">
|
|
249
|
+
<input type="checkbox" ?checked=${sel.mirror === true} @change=${this._onMirrorChange} />
|
|
250
|
+
<ox-i18n msgid="label.mirror">mirror</ox-i18n>
|
|
251
|
+
</label>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
|
|
255
|
+
<div class="actions">
|
|
256
|
+
<button @click=${this._copyToOpposite} title="Copy current face to opposite">
|
|
257
|
+
↔ <ox-i18n msgid="label.copy-to-opposite">opposite</ox-i18n>
|
|
258
|
+
</button>
|
|
259
|
+
<button @click=${this._copyToAllWalls} title="Copy current face to all 4 walls">
|
|
260
|
+
<ox-i18n msgid="label.copy-to-walls">all walls</ox-i18n>
|
|
261
|
+
</button>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
`;
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
OxInputBackdropFaces.styles = css `
|
|
268
|
+
:host {
|
|
269
|
+
display: block;
|
|
270
|
+
font: 12px Arial, sans-serif;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.cube-picker {
|
|
274
|
+
position: relative;
|
|
275
|
+
width: 100%;
|
|
276
|
+
max-width: 260px;
|
|
277
|
+
height: 160px;
|
|
278
|
+
margin: 0 auto 8px;
|
|
279
|
+
}
|
|
280
|
+
.cube-picker svg {
|
|
281
|
+
display: block;
|
|
282
|
+
width: 100%;
|
|
283
|
+
height: 100%;
|
|
284
|
+
overflow: visible;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.face-poly {
|
|
288
|
+
cursor: pointer;
|
|
289
|
+
stroke: #3a3f4a;
|
|
290
|
+
stroke-width: 1;
|
|
291
|
+
stroke-linejoin: round;
|
|
292
|
+
transition:
|
|
293
|
+
filter 0.15s,
|
|
294
|
+
stroke 0.15s,
|
|
295
|
+
stroke-width 0.15s;
|
|
296
|
+
}
|
|
297
|
+
.face-poly:hover {
|
|
298
|
+
filter: brightness(1.15);
|
|
299
|
+
}
|
|
300
|
+
.face-poly.selected {
|
|
301
|
+
stroke: var(--md-sys-color-primary, #e15c5c);
|
|
302
|
+
stroke-width: 2.5;
|
|
303
|
+
}
|
|
304
|
+
.face-poly.hidden-face {
|
|
305
|
+
stroke-dasharray: 3 2;
|
|
306
|
+
opacity: 0.4;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* 뒷면 3 개 (north/west/floor) — 항상 dashed 프레임으로 희미하게 표시.
|
|
310
|
+
선택되면 accent 컬러로 강조되어 라벨 highlight 와 함께 시각적 feedback. */
|
|
311
|
+
.face-ghost {
|
|
312
|
+
cursor: pointer;
|
|
313
|
+
fill: none;
|
|
314
|
+
stroke: #8a93a6;
|
|
315
|
+
stroke-width: 1;
|
|
316
|
+
stroke-dasharray: 3 3;
|
|
317
|
+
stroke-linejoin: round;
|
|
318
|
+
opacity: 0.4;
|
|
319
|
+
pointer-events: stroke;
|
|
320
|
+
transition:
|
|
321
|
+
stroke 0.15s,
|
|
322
|
+
stroke-width 0.15s,
|
|
323
|
+
opacity 0.15s;
|
|
324
|
+
}
|
|
325
|
+
.face-ghost:hover {
|
|
326
|
+
opacity: 0.85;
|
|
327
|
+
stroke: var(--md-sys-color-primary, #e15c5c);
|
|
328
|
+
}
|
|
329
|
+
.face-ghost.selected {
|
|
330
|
+
stroke: var(--md-sys-color-primary, #e15c5c);
|
|
331
|
+
stroke-width: 2;
|
|
332
|
+
opacity: 1;
|
|
333
|
+
}
|
|
334
|
+
.face-ghost.invisible {
|
|
335
|
+
opacity: 0.2;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.face-label {
|
|
339
|
+
position: absolute;
|
|
340
|
+
display: inline-flex;
|
|
341
|
+
align-items: center;
|
|
342
|
+
gap: 4px;
|
|
343
|
+
padding: 2px 6px 2px 4px;
|
|
344
|
+
font: 600 10px Arial, sans-serif;
|
|
345
|
+
background: var(--md-sys-color-surface, #fff);
|
|
346
|
+
border: 1px solid var(--md-sys-color-outline-variant, #d8dde6);
|
|
347
|
+
border-radius: 10px;
|
|
348
|
+
cursor: pointer;
|
|
349
|
+
user-select: none;
|
|
350
|
+
transform: translate(-50%, -50%);
|
|
351
|
+
white-space: nowrap;
|
|
352
|
+
transition:
|
|
353
|
+
border-color 0.15s,
|
|
354
|
+
background 0.15s,
|
|
355
|
+
color 0.15s;
|
|
356
|
+
text-transform: capitalize;
|
|
357
|
+
}
|
|
358
|
+
.face-label:hover {
|
|
359
|
+
border-color: var(--md-sys-color-primary, #e15c5c);
|
|
360
|
+
}
|
|
361
|
+
.face-label.selected {
|
|
362
|
+
border-color: var(--md-sys-color-primary, #e15c5c);
|
|
363
|
+
background: var(--md-sys-color-primary-container, #fde7e7);
|
|
364
|
+
color: var(--md-sys-color-on-primary-container, #b91c1c);
|
|
365
|
+
}
|
|
366
|
+
.face-label .swatch {
|
|
367
|
+
width: 12px;
|
|
368
|
+
height: 12px;
|
|
369
|
+
border-radius: 2px;
|
|
370
|
+
border: 1px solid rgba(0, 0, 0, 0.15);
|
|
371
|
+
flex: none;
|
|
372
|
+
}
|
|
373
|
+
.face-label .swatch[data-empty] {
|
|
374
|
+
background: repeating-linear-gradient(45deg, #fff, #fff 2px, #ccc 2px, #ccc 4px);
|
|
375
|
+
}
|
|
376
|
+
.face-label .eye {
|
|
377
|
+
font-size: 9px;
|
|
378
|
+
opacity: 0.55;
|
|
379
|
+
margin-left: 1px;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.face-detail {
|
|
383
|
+
border-top: 1px dashed var(--md-sys-color-outline-variant, #d8dde6);
|
|
384
|
+
padding-top: 10px;
|
|
385
|
+
margin-top: 4px;
|
|
386
|
+
}
|
|
387
|
+
.face-detail-title {
|
|
388
|
+
display: flex;
|
|
389
|
+
justify-content: space-between;
|
|
390
|
+
align-items: baseline;
|
|
391
|
+
font-weight: 600;
|
|
392
|
+
font-size: 11px;
|
|
393
|
+
color: var(--md-sys-color-primary, #e15c5c);
|
|
394
|
+
text-transform: uppercase;
|
|
395
|
+
letter-spacing: 0.5px;
|
|
396
|
+
margin-bottom: 8px;
|
|
397
|
+
}
|
|
398
|
+
.face-detail-title small {
|
|
399
|
+
font-weight: 400;
|
|
400
|
+
text-transform: none;
|
|
401
|
+
letter-spacing: 0;
|
|
402
|
+
color: var(--md-sys-color-on-secondary-container, #8a93a6);
|
|
403
|
+
font: 10px monospace;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.row {
|
|
407
|
+
display: grid;
|
|
408
|
+
grid-template-columns: 60px 1fr;
|
|
409
|
+
gap: 8px;
|
|
410
|
+
align-items: center;
|
|
411
|
+
margin-bottom: 6px;
|
|
412
|
+
}
|
|
413
|
+
.row > label {
|
|
414
|
+
text-align: right;
|
|
415
|
+
font-size: 11px;
|
|
416
|
+
color: var(--md-sys-color-on-secondary-container, #6b7280);
|
|
417
|
+
}
|
|
418
|
+
.row .ctl {
|
|
419
|
+
display: flex;
|
|
420
|
+
align-items: center;
|
|
421
|
+
gap: 6px;
|
|
422
|
+
}
|
|
423
|
+
.ctl input[type='range'] {
|
|
424
|
+
flex: 1;
|
|
425
|
+
accent-color: var(--md-sys-color-primary, #e15c5c);
|
|
426
|
+
}
|
|
427
|
+
.ctl input[type='checkbox'] {
|
|
428
|
+
accent-color: var(--md-sys-color-primary, #e15c5c);
|
|
429
|
+
}
|
|
430
|
+
.alpha-readout {
|
|
431
|
+
width: 30px;
|
|
432
|
+
text-align: right;
|
|
433
|
+
font: 11px monospace;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/* Rotation select + mirror toggle — actions 버튼과 동일한 border 스타일. */
|
|
437
|
+
.row select,
|
|
438
|
+
.row .mirror-toggle {
|
|
439
|
+
font: 10px Arial, sans-serif;
|
|
440
|
+
padding: 5px 6px;
|
|
441
|
+
border: 1px solid var(--md-sys-color-outline-variant, #d8dde6);
|
|
442
|
+
border-radius: 4px;
|
|
443
|
+
background: var(--md-sys-color-surface, #fff);
|
|
444
|
+
color: inherit;
|
|
445
|
+
cursor: pointer;
|
|
446
|
+
}
|
|
447
|
+
.row select {
|
|
448
|
+
flex: 1;
|
|
449
|
+
outline: none;
|
|
450
|
+
}
|
|
451
|
+
.row select:hover,
|
|
452
|
+
.row .mirror-toggle:hover {
|
|
453
|
+
border-color: var(--md-sys-color-primary, #e15c5c);
|
|
454
|
+
color: var(--md-sys-color-primary, #e15c5c);
|
|
455
|
+
}
|
|
456
|
+
.row .mirror-toggle {
|
|
457
|
+
display: inline-flex;
|
|
458
|
+
align-items: center;
|
|
459
|
+
gap: 4px;
|
|
460
|
+
}
|
|
461
|
+
.row .mirror-toggle input[type='checkbox'] {
|
|
462
|
+
margin: 0;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.fill-row {
|
|
466
|
+
margin-bottom: 6px;
|
|
467
|
+
}
|
|
468
|
+
ox-input-fill-style {
|
|
469
|
+
font: 12px Arial, sans-serif;
|
|
470
|
+
display: block;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.actions {
|
|
474
|
+
margin-top: 8px;
|
|
475
|
+
display: flex;
|
|
476
|
+
gap: 6px;
|
|
477
|
+
}
|
|
478
|
+
.actions button {
|
|
479
|
+
flex: 1;
|
|
480
|
+
font: 10px Arial, sans-serif;
|
|
481
|
+
padding: 5px 6px;
|
|
482
|
+
border: 1px solid var(--md-sys-color-outline-variant, #d8dde6);
|
|
483
|
+
border-radius: 4px;
|
|
484
|
+
background: var(--md-sys-color-surface, #fff);
|
|
485
|
+
color: inherit;
|
|
486
|
+
cursor: pointer;
|
|
487
|
+
}
|
|
488
|
+
.actions button:hover {
|
|
489
|
+
border-color: var(--md-sys-color-primary, #e15c5c);
|
|
490
|
+
color: var(--md-sys-color-primary, #e15c5c);
|
|
491
|
+
}
|
|
492
|
+
`;
|
|
493
|
+
__decorate([
|
|
494
|
+
property({ type: Object })
|
|
495
|
+
], OxInputBackdropFaces.prototype, "value", void 0);
|
|
496
|
+
__decorate([
|
|
497
|
+
state()
|
|
498
|
+
], OxInputBackdropFaces.prototype, "_selected", void 0);
|
|
499
|
+
OxInputBackdropFaces = __decorate([
|
|
500
|
+
customElement('ox-input-backdrop-faces')
|
|
501
|
+
], OxInputBackdropFaces);
|
|
502
|
+
export { OxInputBackdropFaces };
|
|
503
|
+
let OxPropertyEditorBackdropFaces = class OxPropertyEditorBackdropFaces extends OxPropertyEditor {
|
|
504
|
+
editorTemplate(value, spec) {
|
|
505
|
+
// 큐브 + detail panel 이 좁은 column 에서는 답답하므로 기본 fullwidth=true.
|
|
506
|
+
// PropertySpec.editor.fullwidth = false 로 좁게 둘 수도 있다.
|
|
507
|
+
const { fullwidth = true } = spec.editor || {};
|
|
508
|
+
return html `
|
|
509
|
+
<ox-input-backdrop-faces
|
|
510
|
+
id="editor"
|
|
511
|
+
.value=${value}
|
|
512
|
+
?fullwidth=${fullwidth}
|
|
513
|
+
?disabled=${this.disabled}
|
|
514
|
+
></ox-input-backdrop-faces>
|
|
515
|
+
`;
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
OxPropertyEditorBackdropFaces.styles = [
|
|
519
|
+
...OxPropertyEditor.styles,
|
|
520
|
+
css `
|
|
521
|
+
ox-input-backdrop-faces#editor {
|
|
522
|
+
font: 12px Arial, sans-serif;
|
|
523
|
+
}
|
|
524
|
+
`
|
|
525
|
+
];
|
|
526
|
+
OxPropertyEditorBackdropFaces = __decorate([
|
|
527
|
+
customElement('ox-property-editor-backdrop-faces')
|
|
528
|
+
], OxPropertyEditorBackdropFaces);
|
|
529
|
+
export { OxPropertyEditorBackdropFaces };
|
|
530
|
+
//# sourceMappingURL=ox-property-editor-backdrop-faces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ox-property-editor-backdrop-faces.js","sourceRoot":"","sources":["../../src/ox-property-editor-backdrop-faces.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/input/ox-input-fill-style.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, LitElement, nothing, type TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { OxPropertyEditor } from './ox-property-editor.js'\nimport type { PropertySpec } from './types.js'\n\n/**\n * Backdrop 의 6개 면 (east/west/north/south/ceiling/floor) 을 한 번에\n * 편집하는 합성 에디터.\n *\n * 면당 5개 속성 (fillStyle/visible/alpha/rotation/mirror) 을 flat NATURE 로\n * 펼치면 30+개 항목 폼이 되어 좌표 감각이 사라진다. 이 에디터는:\n * 1) cabinet projection cube 로 6면을 시각화 — 앞 3면(ceiling/east/south)\n * 은 fill polygon, 뒤 3면(north/west/floor)은 dashed ghost outline\n * 2) 각 면 라벨에 fillStyle swatch — 6면 색 분포 한 눈에\n * 3) 면/라벨 클릭 → 그 면 detail 패널만 표시\n * 4) \"반대편 복사\" / \"벽 4면 일괄\" 단축 동작\n *\n * value 형태:\n * {\n * east: { fillStyle, visible, alpha, rotation, mirror },\n * west: { ... },\n * ...\n * }\n */\n\ntype FaceName = 'east' | 'west' | 'north' | 'south' | 'ceiling' | 'floor'\nconst OPPOSITE: Record<FaceName, FaceName> = {\n east: 'west',\n west: 'east',\n north: 'south',\n south: 'north',\n ceiling: 'floor',\n floor: 'ceiling'\n}\nconst AXIS_LABEL: Record<FaceName, string> = {\n east: '+X',\n west: '−X',\n north: '−Z',\n south: '+Z',\n ceiling: '+Y',\n floor: '−Y'\n}\n\ninterface FaceState {\n fillStyle?: any\n visible?: boolean\n alpha?: number\n rotation?: 0 | 90 | 180 | 270\n mirror?: boolean\n}\ntype FacesValue = Partial<Record<FaceName, FaceState>>\n\nconst DEFAULT_FACES: Record<FaceName, FaceState> = {\n east: { fillStyle: '#dde2e8', visible: true, alpha: 0.35, rotation: 0, mirror: false },\n west: { fillStyle: '#dde2e8', visible: true, alpha: 0.35, rotation: 0, mirror: false },\n north: { fillStyle: '#dde2e8', visible: true, alpha: 0.35, rotation: 0, mirror: false },\n south: { fillStyle: '#dde2e8', visible: true, alpha: 0.35, rotation: 0, mirror: false },\n ceiling: { fillStyle: '#e8e8ec', visible: true, alpha: 1.0, rotation: 0, mirror: false },\n floor: { fillStyle: '#9c9c9c', visible: true, alpha: 1.0, rotation: 0, mirror: false }\n}\n\n@customElement('ox-input-backdrop-faces')\nexport class OxInputBackdropFaces extends LitElement {\n @property({ type: Object }) value: FacesValue = {}\n @state() private _selected: FaceName = 'ceiling'\n\n static styles = css`\n :host {\n display: block;\n font: 12px Arial, sans-serif;\n }\n\n .cube-picker {\n position: relative;\n width: 100%;\n max-width: 260px;\n height: 160px;\n margin: 0 auto 8px;\n }\n .cube-picker svg {\n display: block;\n width: 100%;\n height: 100%;\n overflow: visible;\n }\n\n .face-poly {\n cursor: pointer;\n stroke: #3a3f4a;\n stroke-width: 1;\n stroke-linejoin: round;\n transition:\n filter 0.15s,\n stroke 0.15s,\n stroke-width 0.15s;\n }\n .face-poly:hover {\n filter: brightness(1.15);\n }\n .face-poly.selected {\n stroke: var(--md-sys-color-primary, #e15c5c);\n stroke-width: 2.5;\n }\n .face-poly.hidden-face {\n stroke-dasharray: 3 2;\n opacity: 0.4;\n }\n\n /* 뒷면 3 개 (north/west/floor) — 항상 dashed 프레임으로 희미하게 표시.\n 선택되면 accent 컬러로 강조되어 라벨 highlight 와 함께 시각적 feedback. */\n .face-ghost {\n cursor: pointer;\n fill: none;\n stroke: #8a93a6;\n stroke-width: 1;\n stroke-dasharray: 3 3;\n stroke-linejoin: round;\n opacity: 0.4;\n pointer-events: stroke;\n transition:\n stroke 0.15s,\n stroke-width 0.15s,\n opacity 0.15s;\n }\n .face-ghost:hover {\n opacity: 0.85;\n stroke: var(--md-sys-color-primary, #e15c5c);\n }\n .face-ghost.selected {\n stroke: var(--md-sys-color-primary, #e15c5c);\n stroke-width: 2;\n opacity: 1;\n }\n .face-ghost.invisible {\n opacity: 0.2;\n }\n\n .face-label {\n position: absolute;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px 2px 4px;\n font: 600 10px Arial, sans-serif;\n background: var(--md-sys-color-surface, #fff);\n border: 1px solid var(--md-sys-color-outline-variant, #d8dde6);\n border-radius: 10px;\n cursor: pointer;\n user-select: none;\n transform: translate(-50%, -50%);\n white-space: nowrap;\n transition:\n border-color 0.15s,\n background 0.15s,\n color 0.15s;\n text-transform: capitalize;\n }\n .face-label:hover {\n border-color: var(--md-sys-color-primary, #e15c5c);\n }\n .face-label.selected {\n border-color: var(--md-sys-color-primary, #e15c5c);\n background: var(--md-sys-color-primary-container, #fde7e7);\n color: var(--md-sys-color-on-primary-container, #b91c1c);\n }\n .face-label .swatch {\n width: 12px;\n height: 12px;\n border-radius: 2px;\n border: 1px solid rgba(0, 0, 0, 0.15);\n flex: none;\n }\n .face-label .swatch[data-empty] {\n background: repeating-linear-gradient(45deg, #fff, #fff 2px, #ccc 2px, #ccc 4px);\n }\n .face-label .eye {\n font-size: 9px;\n opacity: 0.55;\n margin-left: 1px;\n }\n\n .face-detail {\n border-top: 1px dashed var(--md-sys-color-outline-variant, #d8dde6);\n padding-top: 10px;\n margin-top: 4px;\n }\n .face-detail-title {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n font-weight: 600;\n font-size: 11px;\n color: var(--md-sys-color-primary, #e15c5c);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n .face-detail-title small {\n font-weight: 400;\n text-transform: none;\n letter-spacing: 0;\n color: var(--md-sys-color-on-secondary-container, #8a93a6);\n font: 10px monospace;\n }\n\n .row {\n display: grid;\n grid-template-columns: 60px 1fr;\n gap: 8px;\n align-items: center;\n margin-bottom: 6px;\n }\n .row > label {\n text-align: right;\n font-size: 11px;\n color: var(--md-sys-color-on-secondary-container, #6b7280);\n }\n .row .ctl {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n .ctl input[type='range'] {\n flex: 1;\n accent-color: var(--md-sys-color-primary, #e15c5c);\n }\n .ctl input[type='checkbox'] {\n accent-color: var(--md-sys-color-primary, #e15c5c);\n }\n .alpha-readout {\n width: 30px;\n text-align: right;\n font: 11px monospace;\n }\n\n /* Rotation select + mirror toggle — actions 버튼과 동일한 border 스타일. */\n .row select,\n .row .mirror-toggle {\n font: 10px Arial, sans-serif;\n padding: 5px 6px;\n border: 1px solid var(--md-sys-color-outline-variant, #d8dde6);\n border-radius: 4px;\n background: var(--md-sys-color-surface, #fff);\n color: inherit;\n cursor: pointer;\n }\n .row select {\n flex: 1;\n outline: none;\n }\n .row select:hover,\n .row .mirror-toggle:hover {\n border-color: var(--md-sys-color-primary, #e15c5c);\n color: var(--md-sys-color-primary, #e15c5c);\n }\n .row .mirror-toggle {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n }\n .row .mirror-toggle input[type='checkbox'] {\n margin: 0;\n }\n\n .fill-row {\n margin-bottom: 6px;\n }\n ox-input-fill-style {\n font: 12px Arial, sans-serif;\n display: block;\n }\n\n .actions {\n margin-top: 8px;\n display: flex;\n gap: 6px;\n }\n .actions button {\n flex: 1;\n font: 10px Arial, sans-serif;\n padding: 5px 6px;\n border: 1px solid var(--md-sys-color-outline-variant, #d8dde6);\n border-radius: 4px;\n background: var(--md-sys-color-surface, #fff);\n color: inherit;\n cursor: pointer;\n }\n .actions button:hover {\n border-color: var(--md-sys-color-primary, #e15c5c);\n color: var(--md-sys-color-primary, #e15c5c);\n }\n `\n\n private _face(name: FaceName): FaceState {\n return { ...DEFAULT_FACES[name], ...(this.value?.[name] ?? {}) }\n }\n\n /** fillStyle 의 대표 색을 swatch 용으로 추출. 없으면 undefined → hatched 표시. */\n private _swatchColor(name: FaceName): string | undefined {\n const fs = this._face(name).fillStyle\n if (typeof fs === 'string' && fs && fs !== 'transparent') return fs\n if (fs && typeof fs === 'object') {\n if (fs.type === 'gradient' && Array.isArray(fs.colorStops) && fs.colorStops[0]?.color) {\n return fs.colorStops[0].color\n }\n if (fs.color) return fs.color\n }\n return undefined\n }\n\n private _select(name: FaceName) {\n this._selected = name\n }\n\n private _commit(next: FacesValue) {\n this.value = next\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n }\n\n private _patchFace(name: FaceName, patch: Partial<FaceState>) {\n const next: FacesValue = { ...(this.value || {}) }\n next[name] = { ...this._face(name), ...patch }\n this._commit(next)\n }\n\n private _onFillStyleChange(e: Event) {\n e.stopPropagation()\n const target = e.target as { value?: any }\n this._patchFace(this._selected, { fillStyle: target.value })\n }\n\n private _onVisibleChange(e: Event) {\n e.stopPropagation()\n const target = e.target as HTMLInputElement\n this._patchFace(this._selected, { visible: target.checked })\n }\n\n private _onAlphaChange(e: Event) {\n e.stopPropagation()\n const target = e.target as HTMLInputElement\n const v = parseFloat(target.value)\n const alpha = Number.isFinite(v) ? Math.max(0, Math.min(1, v)) : 1\n this._patchFace(this._selected, { alpha })\n }\n\n private _onRotationChange(e: Event) {\n e.stopPropagation()\n const target = e.target as HTMLSelectElement\n const n = parseInt(target.value, 10)\n const rotation: 0 | 90 | 180 | 270 = n === 90 || n === 180 || n === 270 ? n : 0\n this._patchFace(this._selected, { rotation })\n }\n\n private _onMirrorChange(e: Event) {\n e.stopPropagation()\n const target = e.target as HTMLInputElement\n this._patchFace(this._selected, { mirror: target.checked })\n }\n\n private _copyToOpposite() {\n const src = this._face(this._selected)\n const opposite = OPPOSITE[this._selected]\n const next: FacesValue = { ...(this.value || {}) }\n next[opposite] = { ...src }\n this._commit(next)\n }\n\n private _copyToAllWalls() {\n const src = this._face(this._selected)\n const next: FacesValue = { ...(this.value || {}) }\n for (const w of ['east', 'west', 'north', 'south'] as const) {\n next[w] = { ...src }\n }\n this._commit(next)\n }\n\n private _renderLabel(name: FaceName, x: number, y: number) {\n const f = this._face(name)\n const swatch = this._swatchColor(name)\n const selected = this._selected === name\n return html`\n <div\n class=\"face-label ${selected ? 'selected' : ''}\"\n style=\"left: ${x}px; top: ${y}px;\"\n @click=${() => this._select(name)}\n title=${`${name} (${AXIS_LABEL[name]})`}\n >\n <span\n class=\"swatch\"\n style=${swatch ? `background: ${swatch};` : ''}\n ?data-empty=${!swatch}\n ></span>\n <ox-i18n msgid=\"label.${name}\">${name}</ox-i18n>\n ${f.visible === false ? html`<span class=\"eye\" title=\"hidden\">⊘</span>` : nothing}\n </div>\n `\n }\n\n private _faceClass(name: FaceName): string {\n const cls = ['face-poly']\n if (this._selected === name) cls.push('selected')\n if (this._face(name).visible === false) cls.push('hidden-face')\n return cls.join(' ')\n }\n\n private _ghostClass(name: FaceName): string {\n const cls = ['face-ghost']\n if (this._selected === name) cls.push('selected')\n if (this._face(name).visible === false) cls.push('invisible')\n return cls.join(' ')\n }\n\n override render() {\n const sel = this._face(this._selected)\n return html`\n <div class=\"cube-picker\">\n <svg viewBox=\"0 0 288 160\" aria-label=\"Backdrop face picker\">\n <!-- Cabinet projection — south face 정면 1:1 (큰 사각형),\n east axis 는 30° 위방향으로 절반 foreshortened (좁게 보임),\n vertical 은 0.7 배로 압축해 안정감 있는 납작한 형태.\n L=80, depth=40, yScale=0.7 → vertical edge 56.\n south face (z=L) 좌하단을 (90,125) 로 배치. -->\n\n <!-- Ceiling (+Y, top) — trapezoid -->\n <polygon\n class=${this._faceClass('ceiling')}\n points=\"90,69 170,69 198,41 118,41\"\n fill=\"${this._swatchColor('ceiling') ?? '#fff8e1'}\"\n @click=${() => this._select('ceiling')}\n />\n <!-- East face (+X, right) — narrow parallelogram -->\n <polygon\n class=${this._faceClass('east')}\n points=\"170,125 198,97 198,41 170,69\"\n fill=\"${this._swatchColor('east') ?? '#ffcdd2'}\"\n @click=${() => this._select('east')}\n />\n <!-- South face (+Z, front) — dominant rectangle 80×56 -->\n <polygon\n class=${this._faceClass('south')}\n points=\"90,125 170,125 170,69 90,69\"\n fill=\"${this._swatchColor('south') ?? '#c8e6c9'}\"\n @click=${() => this._select('south')}\n />\n\n <!-- Back-face ghost outlines (always faint, accent on selection). -->\n <polygon\n class=${this._ghostClass('north')}\n points=\"118,97 198,97 198,41 118,41\"\n @click=${() => this._select('north')}\n />\n <polygon\n class=${this._ghostClass('west')}\n points=\"118,97 90,125 90,69 118,41\"\n @click=${() => this._select('west')}\n />\n <polygon\n class=${this._ghostClass('floor')}\n points=\"118,97 198,97 170,125 90,125\"\n @click=${() => this._select('floor')}\n />\n </svg>\n\n ${this._renderLabel('ceiling', 144, 20)} ${this._renderLabel('floor', 144, 146)}\n ${this._renderLabel('east', 220, 83)} ${this._renderLabel('west', 38, 83)}\n ${this._renderLabel('north', 220, 51)} ${this._renderLabel('south', 38, 115)}\n </div>\n\n <div class=\"face-detail\">\n <div class=\"face-detail-title\">\n <span><ox-i18n msgid=\"label.${this._selected}\">${this._selected}</ox-i18n></span>\n <small>${AXIS_LABEL[this._selected]}</small>\n </div>\n\n <div class=\"row\">\n <label><ox-i18n msgid=\"label.visible\">visible</ox-i18n></label>\n <div class=\"ctl\">\n <input type=\"checkbox\" ?checked=${sel.visible !== false} @change=${this._onVisibleChange} />\n </div>\n </div>\n\n <div class=\"fill-row\">\n <ox-input-fill-style .value=${sel.fillStyle} fullwidth @change=${this._onFillStyleChange}>\n </ox-input-fill-style>\n </div>\n\n <div class=\"row\">\n <label><ox-i18n msgid=\"label.alpha\">alpha</ox-i18n></label>\n <div class=\"ctl\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n .value=${String(sel.alpha ?? 1)}\n @input=${this._onAlphaChange}\n />\n <span class=\"alpha-readout\">${(sel.alpha ?? 1).toFixed(2)}</span>\n </div>\n </div>\n\n <div class=\"row\">\n <label><ox-i18n msgid=\"label.rotation\">rotation</ox-i18n></label>\n <div class=\"ctl\">\n <select .value=${String(sel.rotation ?? 0)} @change=${this._onRotationChange}>\n <option value=\"0\">0°</option>\n <option value=\"90\">90°</option>\n <option value=\"180\">180°</option>\n <option value=\"270\">270°</option>\n </select>\n <label class=\"mirror-toggle\">\n <input type=\"checkbox\" ?checked=${sel.mirror === true} @change=${this._onMirrorChange} />\n <ox-i18n msgid=\"label.mirror\">mirror</ox-i18n>\n </label>\n </div>\n </div>\n\n <div class=\"actions\">\n <button @click=${this._copyToOpposite} title=\"Copy current face to opposite\">\n ↔ <ox-i18n msgid=\"label.copy-to-opposite\">opposite</ox-i18n>\n </button>\n <button @click=${this._copyToAllWalls} title=\"Copy current face to all 4 walls\">\n <ox-i18n msgid=\"label.copy-to-walls\">all walls</ox-i18n>\n </button>\n </div>\n </div>\n `\n }\n}\n\n@customElement('ox-property-editor-backdrop-faces')\nexport class OxPropertyEditorBackdropFaces extends OxPropertyEditor {\n static styles = [\n ...OxPropertyEditor.styles,\n css`\n ox-input-backdrop-faces#editor {\n font: 12px Arial, sans-serif;\n }\n `\n ]\n\n override editorTemplate(value: any, spec: PropertySpec): TemplateResult {\n // 큐브 + detail panel 이 좁은 column 에서는 답답하므로 기본 fullwidth=true.\n // PropertySpec.editor.fullwidth = false 로 좁게 둘 수도 있다.\n const { fullwidth = true } = spec.editor || {}\n return html`\n <ox-input-backdrop-faces\n id=\"editor\"\n .value=${value}\n ?fullwidth=${fullwidth}\n ?disabled=${this.disabled}\n ></ox-input-backdrop-faces>\n `\n }\n}\n"]}
|
|
@@ -4,7 +4,15 @@ import { customElement } from 'lit/decorators.js';
|
|
|
4
4
|
import { OxPropertyEditor } from './ox-property-editor.js';
|
|
5
5
|
let OxPropertyEditorDate = class OxPropertyEditorDate extends OxPropertyEditor {
|
|
6
6
|
editorTemplate(value, spec) {
|
|
7
|
-
return html `
|
|
7
|
+
return html `
|
|
8
|
+
<input
|
|
9
|
+
type="date"
|
|
10
|
+
id="editor"
|
|
11
|
+
.value=${value}
|
|
12
|
+
?disabled=${this.disabled}
|
|
13
|
+
@click=${(e) => e.currentTarget.showPicker()}
|
|
14
|
+
/>
|
|
15
|
+
`;
|
|
8
16
|
}
|
|
9
17
|
};
|
|
10
18
|
OxPropertyEditorDate = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-property-editor-date.js","sourceRoot":"","sources":["../../src/ox-property-editor-date.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAInD,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,gBAAgB;IACxD,cAAc,CAAC,KAAU,EAAE,IAAkB;QAC3C,OAAO,IAAI,CAAA,
|
|
1
|
+
{"version":3,"file":"ox-property-editor-date.js","sourceRoot":"","sources":["../../src/ox-property-editor-date.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAInD,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,gBAAgB;IACxD,cAAc,CAAC,KAAU,EAAE,IAAkB;QAC3C,OAAO,IAAI,CAAA;;;;iBAIE,KAAK;oBACF,IAAI,CAAC,QAAQ;iBAChB,CAAC,CAAQ,EAAE,EAAE,CAAE,CAAC,CAAC,aAAkC,CAAC,UAAU,EAAE;;KAE5E,CAAA;IACH,CAAC;CACF,CAAA;AAZY,oBAAoB;IADhC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,oBAAoB,CAYhC","sourcesContent":["import { html, TemplateResult } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { OxPropertyEditor } from './ox-property-editor.js'\nimport { PropertySpec } from './types.js'\n\n@customElement('ox-property-editor-date')\nexport class OxPropertyEditorDate extends OxPropertyEditor {\n editorTemplate(value: any, spec: PropertySpec): TemplateResult {\n return html`\n <input\n type=\"date\"\n id=\"editor\"\n .value=${value}\n ?disabled=${this.disabled}\n @click=${(e: Event) => (e.currentTarget as HTMLInputElement).showPicker()}\n />\n `\n }\n}\n"]}
|
|
@@ -4,7 +4,15 @@ import { customElement } from 'lit/decorators.js';
|
|
|
4
4
|
import { OxPropertyEditor } from './ox-property-editor.js';
|
|
5
5
|
let OxPropertyEditorDatetime = class OxPropertyEditorDatetime extends OxPropertyEditor {
|
|
6
6
|
editorTemplate(value, spec) {
|
|
7
|
-
return html `
|
|
7
|
+
return html `
|
|
8
|
+
<input
|
|
9
|
+
type="datetime-local"
|
|
10
|
+
id="editor"
|
|
11
|
+
.value=${value}
|
|
12
|
+
?disabled=${this.disabled}
|
|
13
|
+
@click=${(e) => e.currentTarget.showPicker()}
|
|
14
|
+
/>
|
|
15
|
+
`;
|
|
8
16
|
}
|
|
9
17
|
};
|
|
10
18
|
OxPropertyEditorDatetime = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-property-editor-datetime.js","sourceRoot":"","sources":["../../src/ox-property-editor-datetime.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAInD,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,gBAAgB;IAC5D,cAAc,CAAC,KAAU,EAAE,IAAkB;QAC3C,OAAO,IAAI,CAAA,
|
|
1
|
+
{"version":3,"file":"ox-property-editor-datetime.js","sourceRoot":"","sources":["../../src/ox-property-editor-datetime.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAInD,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,gBAAgB;IAC5D,cAAc,CAAC,KAAU,EAAE,IAAkB;QAC3C,OAAO,IAAI,CAAA;;;;iBAIE,KAAK;oBACF,IAAI,CAAC,QAAQ;iBAChB,CAAC,CAAQ,EAAE,EAAE,CAAE,CAAC,CAAC,aAAkC,CAAC,UAAU,EAAE;;KAE5E,CAAA;IACH,CAAC;CACF,CAAA;AAZY,wBAAwB;IADpC,aAAa,CAAC,6BAA6B,CAAC;GAChC,wBAAwB,CAYpC","sourcesContent":["import { html, TemplateResult } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { OxPropertyEditor } from './ox-property-editor.js'\nimport { PropertySpec } from './types.js'\n\n@customElement('ox-property-editor-datetime')\nexport class OxPropertyEditorDatetime extends OxPropertyEditor {\n editorTemplate(value: any, spec: PropertySpec): TemplateResult {\n return html`\n <input\n type=\"datetime-local\"\n id=\"editor\"\n .value=${value}\n ?disabled=${this.disabled}\n @click=${(e: Event) => (e.currentTarget as HTMLInputElement).showPicker()}\n />\n `\n }\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import '@operato/input/ox-input-fill-style.js';
|
|
2
|
+
import { TemplateResult } from 'lit';
|
|
3
|
+
import { OxPropertyEditor } from './ox-property-editor.js';
|
|
4
|
+
import { PropertySpec } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Property editor for the COMPOSITE `FillStyle` type — the same widget
|
|
7
|
+
* used for the standard component-level `fillStyle` (color / pattern /
|
|
8
|
+
* gradient / image). Wraps `<ox-input-fill-style>` so that NATURE
|
|
9
|
+
* properties declared with `type: 'fill-style'` get the full editor in
|
|
10
|
+
* the property panel.
|
|
11
|
+
*
|
|
12
|
+
* Use this when a component exposes MULTIPLE fillStyle slots (e.g. a
|
|
13
|
+
* Backdrop's per-face fillStyles) and each needs the same rich editor.
|
|
14
|
+
* For a simple solid-color slot, use `type: 'color'` (which uses
|
|
15
|
+
* `<ox-input-color>` — string value, no pattern/gradient/image).
|
|
16
|
+
*/
|
|
17
|
+
export declare class OxPropertyEditorFillStyle extends OxPropertyEditor {
|
|
18
|
+
static styles: import("lit").CSSResult[];
|
|
19
|
+
editorTemplate(value: any, spec: PropertySpec): TemplateResult;
|
|
20
|
+
}
|