@operato/input 1.0.0-alpha.5 → 1.0.0-alpha.9

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 (61) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +9 -6
  3. package/assets/images/icon-editor-gradient-direction.png +0 -0
  4. package/assets/images/icon-properties-label.png +0 -0
  5. package/demo/index-color-gradient.html +35 -0
  6. package/demo/index-color-stops.html +62 -0
  7. package/demo/index-color.html +35 -0
  8. package/demo/index-multiple-colors.html +37 -0
  9. package/demo/index.html +4 -0
  10. package/dist/src/index.d.ts +15 -11
  11. package/dist/src/index.js +15 -11
  12. package/dist/src/index.js.map +1 -1
  13. package/dist/src/ox-input-background-pattern.d.ts +31 -0
  14. package/dist/src/ox-input-background-pattern.js +147 -0
  15. package/dist/src/ox-input-background-pattern.js.map +1 -0
  16. package/dist/src/ox-input-code.d.ts +4 -4
  17. package/dist/src/ox-input-code.js +8 -8
  18. package/dist/src/ox-input-code.js.map +1 -1
  19. package/dist/src/ox-input-color-gradient.d.ts +26 -0
  20. package/dist/src/ox-input-color-gradient.js +318 -0
  21. package/dist/src/ox-input-color-gradient.js.map +1 -0
  22. package/dist/src/ox-input-color-stops.d.ts +71 -0
  23. package/dist/src/ox-input-color-stops.js +445 -0
  24. package/dist/src/ox-input-color-stops.js.map +1 -0
  25. package/dist/src/ox-input-color.d.ts +176 -0
  26. package/dist/src/ox-input-color.js +298 -0
  27. package/dist/src/ox-input-color.js.map +1 -0
  28. package/dist/src/ox-input-data.d.ts +1 -1
  29. package/dist/src/ox-input-data.js +1 -1
  30. package/dist/src/ox-input-data.js.map +1 -1
  31. package/dist/src/ox-input-fill-style.d.ts +42 -0
  32. package/dist/src/ox-input-fill-style.js +323 -0
  33. package/dist/src/ox-input-fill-style.js.map +1 -0
  34. package/dist/src/ox-input-multiple-colors.d.ts +28 -0
  35. package/dist/src/ox-input-multiple-colors.js +113 -0
  36. package/dist/src/ox-input-multiple-colors.js.map +1 -0
  37. package/dist/src/ox-input-scene-component-id.d.ts +11 -0
  38. package/dist/src/ox-input-scene-component-id.js +68 -0
  39. package/dist/src/ox-input-scene-component-id.js.map +1 -0
  40. package/dist/src/ox-input-stack.d.ts +1 -1
  41. package/dist/src/ox-input-stack.js +1 -1
  42. package/dist/src/ox-input-stack.js.map +1 -1
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +14 -7
  45. package/src/index.ts +15 -11
  46. package/src/ox-input-background-pattern.ts.xxx +163 -0
  47. package/src/ox-input-code.ts +9 -10
  48. package/src/ox-input-color-gradient.ts.xxx +343 -0
  49. package/src/ox-input-color-stops.ts +499 -0
  50. package/src/ox-input-color.ts +323 -0
  51. package/src/ox-input-data.ts +2 -2
  52. package/src/ox-input-fill-style.ts.xxx +361 -0
  53. package/src/ox-input-keyvalues.ts.ing +10 -10
  54. package/src/ox-input-multiple-colors.ts +113 -0
  55. package/src/ox-input-ranges.ts.ing +12 -12
  56. package/src/{ox-input-id.ts → ox-input-scene-component-id.ts} +1 -1
  57. package/src/ox-input-stack.ts +1 -1
  58. package/translations/en.json +1 -0
  59. package/translations/ko.json +1 -0
  60. package/translations/ms.json +1 -0
  61. package/translations/zh.json +1 -0
@@ -0,0 +1,323 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import '@operato/color-picker/paper-color-picker.js'
6
+
7
+ import { css, html } from 'lit'
8
+ import { customElement, property } from 'lit/decorators.js'
9
+
10
+ import { OxFormField } from './ox-form-field'
11
+ import { tinycolor } from '@thebespokepixel/es-tinycolor'
12
+
13
+ /**
14
+ 색상을 입력하는데 사용되는 입력 컴포넌트이다.
15
+ 화면상에는 두개의 입력 필드가 보이며, 하나는 색상값을 키보드로 직접 입력하는 입력 픽드이며,
16
+ 다른 하나는 마우스로 클릭하여 컬러 파레트를 팝업 시키는 입력 필드이다.
17
+ 컬러 파레트를 팝업시키는 입력필드는 현재 입력된 색상으로 표시된다.
18
+
19
+ 색상값을 직접 입력하는 필드에서는 'white', 'red', 'yellow' 등 색상의미 단어를 사용할 수도 있고,
20
+ #fff, #123456 와 같이 스타일에서 지정하는 방식의 3자리 및 6자리 숫자 표현도 가능하다.
21
+ 컬러 파레트를 팝업시키는 입력 필드에서 색상을 지정하게되면, 모두 6자리 숫자 표현방식만을 사용한다.
22
+
23
+ 의미 단어를 지원하는 색상은 다음과 같다.
24
+
25
+ aliceblue : #f0f8ff<br>
26
+ antiquewhite : #faebd7<br>
27
+ aqua : #00ffff<br>
28
+ aquamarine : #7fffd4<br>
29
+ azure : #f0ffff<br>
30
+ beige : #f5f5dc<br>
31
+ bisque : #ffe4c4<br>
32
+ black : #000000<br>
33
+ blanchedalmond : #ffebcd<br>
34
+ blue : #0000ff<br>
35
+ blueviolet : #8a2be2<br>
36
+ brown : #a52a2a<br>
37
+ burlywood : #deb887<br>
38
+ cadetblue : #5f9ea0<br>
39
+ chartreuse : #7fff00<br>
40
+ chocolate : #d2691e<br>
41
+ coral : #ff7f50<br>
42
+ cornflowerblue : #6495ed<br>
43
+ cornsilk : #fff8dc<br>
44
+ crimson : #dc143c<br>
45
+ cyan : #00ffff<br>
46
+ darkblue : #00008b<br>
47
+ darkcyan : #008b8b<br>
48
+ darkgoldenrod : #b8860b<br>
49
+ darkgray : #a9a9a9<br>
50
+ darkgreen : #006400<br>
51
+ darkkhaki : #bdb76b<br>
52
+ darkmagenta : #8b008b<br>
53
+ darkolivegreen : #556b2f<br>
54
+ darkorange : #ff8c00<br>
55
+ darkorchid : #9932cc<br>
56
+ darkred : #8b0000<br>
57
+ darksalmon : #e9967a<br>
58
+ darkseagreen : #8fbc8f<br>
59
+ darkslateblue : #483d8b<br>
60
+ darkslategray : #2f4f4f<br>
61
+ darkturquoise : #00ced1<br>
62
+ darkviolet : #9400d3<br>
63
+ deeppink : #ff1493<br>
64
+ deepskyblue : #00bfff<br>
65
+ dimgray : #696969<br>
66
+ dodgerblue : #1e90ff<br>
67
+ firebrick : #b22222<br>
68
+ floralwhite : #fffaf0<br>
69
+ forestgreen : #228b22<br>
70
+ fuchsia : #ff00ff<br>
71
+ gainsboro : #dcdcdc<br>
72
+ ghostwhite : #f8f8ff<br>
73
+ gold : #ffd700<br>
74
+ goldenrod : #daa520<br>
75
+ gray : #808080<br>
76
+ green : #008000<br>
77
+ greenyellow : #adff2f<br>
78
+ honeydew : #f0fff0<br>
79
+ hotpink : #ff69b4<br>
80
+ indianred : #cd5c5c<br>
81
+ indigo : #4b0082<br>
82
+ ivory : #fffff0<br>
83
+ khaki : #f0e68c<br>
84
+ lavender : #e6e6fa<br>
85
+ lavenderblush : #fff0f5<br>
86
+ lawngreen : #7cfc00<br>
87
+ lemonchiffon : #fffacd<br>
88
+ lightblue : #add8e6<br>
89
+ lightcoral : #f08080<br>
90
+ lightcyan : #e0ffff<br>
91
+ lightgoldenrodyellow : #fafad2<br>
92
+ lightgrey : #d3d3d3<br>
93
+ lightgreen : #90ee90<br>
94
+ lightpink : #ffb6c1<br>
95
+ lightsalmon : #ffa07a<br>
96
+ lightseagreen : #20b2aa<br>
97
+ lightskyblue : #87cefa<br>
98
+ lightslategray : #778899<br>
99
+ lightsteelblue : #b0c4de<br>
100
+ lightyellow : #ffffe0<br>
101
+ lime : #00ff00<br>
102
+ limegreen : #32cd32<br>
103
+ linen : #faf0e6<br>
104
+ magenta : #ff00ff<br>
105
+ maroon : #800000<br>
106
+ mediumaquamarine : #66cdaa<br>
107
+ mediumblue : #0000cd<br>
108
+ mediumorchid : #ba55d3<br>
109
+ mediumpurple : #9370d8<br>
110
+ mediumseagreen : #3cb371<br>
111
+ mediumslateblue : #7b68ee<br>
112
+ mediumspringgreen : #00fa9a<br>
113
+ mediumturquoise : #48d1cc<br>
114
+ mediumvioletred : #c71585<br>
115
+ midnightblue : #191970<br>
116
+ mintcream : #f5fffa<br>
117
+ mistyrose : #ffe4e1<br>
118
+ moccasin : #ffe4b5<br>
119
+ navajowhite : #ffdead<br>
120
+ navy : #000080<br>
121
+ oldlace : #fdf5e6<br>
122
+ olive : #808000<br>
123
+ olivedrab : #6b8e23<br>
124
+ orange : #ffa500<br>
125
+ orangered : #ff4500<br>
126
+ orchid : #da70d6<br>
127
+ palegoldenrod : #eee8aa<br>
128
+ palegreen : #98fb98<br>
129
+ paleturquoise : #afeeee<br>
130
+ palevioletred : #d87093<br>
131
+ papayawhip : #ffefd5<br>
132
+ peachpuff : #ffdab9<br>
133
+ peru : #cd853f<br>
134
+ pink : #ffc0cb<br>
135
+ plum : #dda0dd<br>
136
+ powderblue : #b0e0e6<br>
137
+ purple : #800080<br>
138
+ red : #ff0000<br>
139
+ rosybrown : #bc8f8f<br>
140
+ royalblue : #4169e1<br>
141
+ saddlebrown : #8b4513<br>
142
+ salmon : #fa8072<br>
143
+ sandybrown : #f4a460<br>
144
+ seagreen : #2e8b57<br>
145
+ seashell : #fff5ee<br>
146
+ sienna : #a0522d<br>
147
+ silver : #c0c0c0<br>
148
+ skyblue : #87ceeb<br>
149
+ slateblue : #6a5acd<br>
150
+ slategray : #708090<br>
151
+ snow : #fffafa<br>
152
+ springgreen : #00ff7f<br>
153
+ steelblue : #4682b4<br>
154
+ tan : #d2b48c<br>
155
+ teal : #008080<br>
156
+ thistle : #d8bfd8<br>
157
+ tomato : #ff6347<br>
158
+ turquoise : #40e0d0<br>
159
+ violet : #ee82ee<br>
160
+ wheat : #f5deb3<br>
161
+ white : #ffffff<br>
162
+ whitesmoke : #f5f5f5<br>
163
+ yellow : #ffff00<br>
164
+ yellowgreen : #9acd32<br>
165
+
166
+ Example:
167
+
168
+ <ox-input-color .value=${color}>
169
+ </ox-input-color>
170
+ */
171
+
172
+ @customElement('ox-input-color')
173
+ export class OxInputColor extends OxFormField {
174
+ static styles = css`
175
+ :host {
176
+ position: relative;
177
+ display: inline-flex;
178
+ align-items: center;
179
+ justify-content: flex-end;
180
+ }
181
+
182
+ input[type='text'] {
183
+ padding-right: 24px;
184
+ width: 100%;
185
+ height: 100%;
186
+ box-sizing: border-box;
187
+ border: 1px solid rgba(0, 0, 0, 0.2);
188
+ }
189
+
190
+ a {
191
+ -webkit-appearance: none;
192
+ display: flex;
193
+ position: absolute;
194
+ width: 24px;
195
+ height: 100%;
196
+ box-sizing: border-box;
197
+ align-items: center;
198
+ justify-content: center;
199
+ }
200
+
201
+ span {
202
+ width: 18px;
203
+ height: 100%;
204
+ max-height: 18px;
205
+ border-radius: 10%;
206
+ border: 1px solid #eee;
207
+ }
208
+
209
+ span.transparent {
210
+ background-color: #fefefe;
211
+ background-image: linear-gradient(45deg, #cbcbcb 25%, transparent 25%, transparent 75%, #cbcbcb 75%, #cbcbcb),
212
+ linear-gradient(45deg, #cbcbcb 25%, transparent 25%, transparent 75%, #cbcbcb 75%, #cbcbcb);
213
+ background-position: 0 0, 9px 9px;
214
+ background-size: 18px 18px;
215
+ }
216
+ `
217
+
218
+ @property({ type: String }) value?: string
219
+ @property({ type: Object }) properties: any
220
+
221
+ render() {
222
+ return html`
223
+ <input
224
+ id="text"
225
+ type="text"
226
+ .value=${this.value || ''}
227
+ @change=${(e: Event) => this._onInputChanged(e)}
228
+ .placeholder=${this.getAttribute('placeholder') || ''}
229
+ />
230
+
231
+ <a @click=${(e: MouseEvent) => this.showPicker()}>
232
+ <span id="color-thumbnail" .style="background-color:${this._thumbnail()}" class=${this._thumbnail()}> </span>
233
+ </a>
234
+ `
235
+ }
236
+
237
+ set colorString(colorString: string) {
238
+ var color = tinycolor(colorString, {})
239
+ var { withoutAlpha, valueType } = this.properties || {}
240
+
241
+ if (color.isValid()) {
242
+ if (valueType == 'hex' || withoutAlpha) {
243
+ this.value = color.toHexString(false)
244
+ } else this.value = color.toRgbString()
245
+
246
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
247
+ }
248
+ }
249
+
250
+ _thumbnail() {
251
+ return tinycolor(this.value || 'transparent', {}).toRgbString()
252
+ }
253
+
254
+ _onInputChanged(e: Event) {
255
+ e.stopPropagation()
256
+ this.value = (e.target as HTMLInputElement).value
257
+
258
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
259
+ }
260
+
261
+ /**
262
+ * 외부에서 호출 가능한 메쏘드임.
263
+ */
264
+ showPicker() {
265
+ var { withoutAlpha } = this.properties || {}
266
+
267
+ var color = tinycolor(this.value, {})
268
+
269
+ var picker = document.createElement('paper-color-picker') as HTMLElement & {
270
+ shape: string
271
+ color: any
272
+ colorAsString: string
273
+ allowAlpha: boolean
274
+ alwaysShowAlpha: boolean
275
+ type: string
276
+ _initialAlphaValueHack: number
277
+ set: (name: string, value: number) => void
278
+ open: () => void
279
+ }
280
+
281
+ picker.shape = 'huebox'
282
+ picker.color = color
283
+ picker.colorAsString = color.toRgbString()
284
+ if (!withoutAlpha) {
285
+ picker.allowAlpha = true
286
+ picker.alwaysShowAlpha = true
287
+ }
288
+ picker.type = 'hsl'
289
+
290
+ if (color.isValid()) {
291
+ let rgb = color.toRgb() as { r: number; g: number; b: number }
292
+ let alpha = color.getAlpha()
293
+
294
+ picker._initialAlphaValueHack = alpha
295
+
296
+ picker.set('immediateColor.red', rgb.r)
297
+ picker.set('immediateColor.green', rgb.g)
298
+ picker.set('immediateColor.blue', rgb.b)
299
+
300
+ if (alpha != undefined) {
301
+ picker.set('immediateColor.alpha', alpha)
302
+ }
303
+ }
304
+
305
+ document.body.appendChild(picker)
306
+
307
+ var _ = (e: Event) => {
308
+ if (!(e as CustomEvent)?.detail?.confirmed) {
309
+ return
310
+ }
311
+
312
+ if (picker.colorAsString) {
313
+ this.colorString = picker.colorAsString
314
+ }
315
+
316
+ picker.removeEventListener('iron-overlay-closed', _)
317
+ picker.parentNode?.removeChild(picker)
318
+ }
319
+ picker.addEventListener('iron-overlay-closed', _)
320
+
321
+ setTimeout(() => picker.open())
322
+ }
323
+ }
@@ -7,7 +7,7 @@ import './ox-input-code'
7
7
  import { PropertyValues, css, html } from 'lit'
8
8
 
9
9
  import { OxFormField } from './ox-form-field.js'
10
- import OxInputCode from './ox-input-code.js'
10
+ import { OxInputCode } from './ox-input-code.js'
11
11
  import { customElement } from 'lit/decorators.js'
12
12
 
13
13
  /**
@@ -19,7 +19,7 @@ Example:
19
19
  </ox-input-data>
20
20
  */
21
21
  @customElement('ox-input-data')
22
- export default class OxInputData extends OxFormField {
22
+ export class OxInputData extends OxFormField {
23
23
  static styles = [
24
24
  css`
25
25
  :host {
@@ -0,0 +1,361 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import '@operato/i18n/ox-i18n.js'
6
+ import './ox-input-color'
7
+ import './ox-input-color-gradient'
8
+ import './ox-input-background-pattern'
9
+
10
+ import { BackgroundPatternOption, OxInputBackgroundPattern } from './ox-input-background-pattern'
11
+ import { GradientOption, OxInputColorGradient } from './ox-input-color-gradient'
12
+ import { PropertyValues, css, html } from 'lit'
13
+ import { customElement, property, query } from 'lit/decorators.js'
14
+
15
+ import { ColorStop } from './ox-input-color-stops'
16
+ import { OxFormField } from './ox-form-field'
17
+
18
+ export type FillStyle =
19
+ | {
20
+ type?: 'no' | 'solid' | 'gradient' | 'pattern'
21
+ gradientType?: 'linear' | 'radial'
22
+ colorStops?: ColorStop[]
23
+ rotation?: number
24
+ center?: 'center' | 'left-top' | 'right-top' | 'right-bottom' | 'left-bottom'
25
+ image?: HTMLImageElement | string
26
+ offsetX?: number
27
+ offsetY?: number
28
+ width?: number
29
+ height?: number
30
+ align?: 'left-top' | 'top' | 'right-top' | 'left' | 'center' | 'right' | 'left-bottom' | 'bottom' | 'right-bottom'
31
+ fitPattern?: boolean
32
+ }
33
+ | 'no'
34
+ | string
35
+
36
+ @customElement('ox-input-color-style')
37
+ export class OxInputColorStyle extends OxFormField {
38
+ static styles = css`
39
+ :host {
40
+ display: flex;
41
+ flex-direction: column;
42
+ }
43
+
44
+ [fill-type] {
45
+ display: flex;
46
+ margin: 0 0 14px 0;
47
+ }
48
+
49
+ [fill-type] * {
50
+ flex: auto;
51
+ margin: 0;
52
+ text-align: left;
53
+ align-self: center;
54
+ }
55
+
56
+ .grid-10 {
57
+ display: grid;
58
+
59
+ grid-template-columns: repeat(10, 1fr);
60
+ grid-gap: 5px;
61
+ grid-auto-rows: minmax(24px, auto);
62
+ }
63
+
64
+ .grid-10 > ox-input-color {
65
+ grid-column: span 4;
66
+ }
67
+
68
+ .grid-10 > .icon-only-label {
69
+ grid-column: span 1;
70
+
71
+ background: url(/assets/images/icon-properties-label.png) no-repeat;
72
+ float: left;
73
+ margin: 0;
74
+ }
75
+
76
+ .icon-only-label.color {
77
+ background-position: 70% -498px;
78
+ }
79
+
80
+ [editors] > :not([active]) {
81
+ display: none;
82
+ }
83
+ `
84
+
85
+ @property({ type: Object }) value?: FillStyle
86
+ @property({ type: String }) fillType?: string
87
+ @property({ type: String }) solid?: string
88
+ @property({ type: Object }) gradient?: GradientOption
89
+ @property({ type: Object }) pattern?: BackgroundPatternOption
90
+
91
+ private _block_reset: boolean = false
92
+
93
+ updated(changes: PropertyValues<this>) {
94
+ changes.has('value') && this._onChangedValue(this.value || {})
95
+ }
96
+
97
+ render() {
98
+ return html`
99
+ <div @change=${(e: Event) => this._onChangedFillType(e)} fill-type>
100
+ <input
101
+ type="radio"
102
+ id="fill-type-no"
103
+ name="fill-type"
104
+ value="no"
105
+ .checked=${!this.fillType || this.fillType == 'no'}
106
+ />
107
+ <label for="fill-type-no"><ox-i18n msgid="label.no-fill">no fill</ox-i18n></label>
108
+ <input type="radio" id="fill-type-solid" name="fill-type" value="solid" .checked=${this.fillType == 'solid'} />
109
+ <label for="fill-type-solid"><ox-i18n msgid="label.solid">solid</ox-i18n></label>
110
+ <input
111
+ type="radio"
112
+ id="fill-type-gradient"
113
+ name="fill-type"
114
+ value="gradient"
115
+ .checked=${this.fillType == 'gradient'}
116
+ />
117
+ <label for="fill-type-gradient"><ox-i18n msgid="label.gradient">gradient</ox-i18n></label>
118
+ <input
119
+ type="radio"
120
+ id="fill-type-pattern"
121
+ name="fill-type"
122
+ value="pattern"
123
+ .checked=${this.fillType == 'pattern'}
124
+ />
125
+ <label for="fill-type-pattern"><ox-i18n msgid="label.pattern">pattern</ox-i18n></label>
126
+ </div>
127
+
128
+ <div editors>
129
+ <div ?active=${this.fillType == 'no'}></div>
130
+
131
+ <div class="grid-10" ?active=${this.fillType == 'solid'}>
132
+ <label class="icon-only-label color"></label>
133
+ <ox-input-color @change=${(e: Event) => this._onChangedSolid(e)} .value=${this.solid}> </ox-input-color>
134
+ </div>
135
+
136
+ <div ?active=${this.fillType == 'gradient'}>
137
+ <ox-input-color-gradient @change=${(e: Event) => this._onChandedGradient(e)} .value=${this.gradient}>
138
+ </ox-input-color-gradient>
139
+ </div>
140
+
141
+ <div ?active=${this.fillType == 'pattern'}>
142
+ <ox-input-background-pattern @change=${(e: Event) => this._onChangedPattern(e)} .value=${this.pattern}>
143
+ </ox-input-background-pattern>
144
+ </div>
145
+ </div>
146
+ `
147
+ }
148
+
149
+ async _onChangedValue(value: FillStyle) {
150
+ /*
151
+ * this._block_reset의 역할은 내부 사용자 인터렉션에 의한 value의 변경시에는 각 type별 이전값을 유지하기 위함이다.
152
+ */
153
+ await this.requestUpdate()
154
+
155
+ /* 설정 값에 따라서, 멤버 속성을 설정한다. */
156
+ if (!value) {
157
+ this.fillType = 'no'
158
+
159
+ if (!this._block_reset) {
160
+ this.solid = undefined
161
+ this.gradient = undefined
162
+ this.pattern = undefined
163
+ }
164
+
165
+ this._block_reset = false
166
+ return
167
+ }
168
+
169
+ switch (typeof value) {
170
+ case 'string':
171
+ this.fillType = 'solid'
172
+ this.solid = value
173
+
174
+ if (!this._block_reset) {
175
+ this.gradient = undefined
176
+ this.pattern = undefined
177
+ }
178
+ break
179
+ case 'object':
180
+ this.fillType = value.type
181
+
182
+ if (value.type === 'gradient') {
183
+ this.gradient = {
184
+ type: value.gradientType || 'linear',
185
+ colorStops: value.colorStops || [
186
+ {
187
+ position: 0,
188
+ color: this.solid || '#000000'
189
+ },
190
+ {
191
+ position: 1,
192
+ color: this.solid || '#FFFFFF'
193
+ }
194
+ ],
195
+ rotation: Number(value.rotation) || 0,
196
+ center: value.center
197
+ }
198
+
199
+ if (!this._block_reset) {
200
+ this.pattern = undefined
201
+ this.solid = undefined
202
+ }
203
+ } else if (value.type === 'pattern') {
204
+ this.pattern = {
205
+ image: value.image,
206
+ offsetX: Number(value.offsetX) || 0,
207
+ offsetY: Number(value.offsetY) || 0,
208
+ width: Number(value.width),
209
+ height: Number(value.height),
210
+ align: value.align,
211
+ fitPattern: value.fitPattern
212
+ }
213
+
214
+ if (!this._block_reset) {
215
+ this.gradient = undefined
216
+ this.solid = undefined
217
+ }
218
+ }
219
+
220
+ break
221
+ default:
222
+ }
223
+
224
+ this._block_reset = false
225
+ }
226
+
227
+ _onChangedFillType(e: Event) {
228
+ const element = e.target as HTMLInputElement
229
+ this.fillType = element.value
230
+
231
+ switch (this.fillType) {
232
+ case 'gradient':
233
+ if (!this.gradient) {
234
+ this.gradient = {
235
+ type: 'linear',
236
+ colorStops: [
237
+ {
238
+ position: 0,
239
+ color: this.solid || '#000000'
240
+ },
241
+ {
242
+ position: 1,
243
+ color: this.solid || '#FFFFFF'
244
+ }
245
+ ],
246
+ rotation: 0,
247
+ center: 'center'
248
+ }
249
+ }
250
+
251
+ this.value = {
252
+ type: 'gradient',
253
+ gradientType: this.gradient.type || 'linear',
254
+ colorStops: this.gradient.colorStops || [
255
+ {
256
+ position: 0,
257
+ color: this.solid || '#000000'
258
+ },
259
+ {
260
+ position: 1,
261
+ color: this.solid || '#FFFFFF'
262
+ }
263
+ ],
264
+ rotation: Number(this.gradient.rotation) || 0,
265
+ center: this.gradient.center
266
+ }
267
+ break
268
+
269
+ case 'pattern':
270
+ if (!this.pattern) this.pattern = {}
271
+
272
+ this.value = {
273
+ type: 'pattern',
274
+ image: this.pattern.image,
275
+ offsetX: Number(this.pattern.offsetX) || 0,
276
+ offsetY: Number(this.pattern.offsetY) || 0,
277
+ width: Number(this.pattern.width),
278
+ height: Number(this.pattern.height),
279
+ align: this.pattern.align,
280
+ fitPattern: this.pattern.fitPattern
281
+ }
282
+ break
283
+
284
+ case 'solid':
285
+ if (!this.solid) this.solid = '#fff'
286
+ this.value = this.solid
287
+ break
288
+
289
+ case 'no':
290
+ this.value = ''
291
+ break
292
+ }
293
+
294
+ this._block_reset = true
295
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
296
+ }
297
+
298
+ _onChangedSolid(e: Event) {
299
+ if (this.fillType !== 'solid') return
300
+
301
+ this.solid = (e.target as HTMLInputElement).value
302
+
303
+ this.value = this.solid
304
+
305
+ this._block_reset = true
306
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
307
+ }
308
+
309
+ _onChandedGradient(e: Event) {
310
+ /*
311
+ * TODO Gradient의 rotation은 symmetry 기능 등으로 외부에서 변경될 수도 있다.
312
+ * 이 점을 감안해서, 외부 변경에 대한 대응을 해야 한다.
313
+ */
314
+
315
+ if (this.fillType !== 'gradient') {
316
+ return
317
+ }
318
+
319
+ this.gradient = (e.target as OxInputColorGradient).value
320
+
321
+ this.value = {
322
+ type: 'gradient',
323
+ gradientType: this.gradient.type || 'linear',
324
+ colorStops: this.gradient.colorStops || [
325
+ {
326
+ position: 0,
327
+ color: this.solid || '#000000'
328
+ },
329
+ {
330
+ position: 1,
331
+ color: this.solid || '#FFFFFF'
332
+ }
333
+ ],
334
+ rotation: Number(this.gradient.rotation) || 0,
335
+ center: this.gradient.center
336
+ }
337
+
338
+ this._block_reset = true
339
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
340
+ }
341
+
342
+ _onChangedPattern(e: Event) {
343
+ if (this.fillType !== 'pattern') return
344
+
345
+ this.pattern = (e.target as OxInputBackgroundPattern).value
346
+
347
+ this.value = {
348
+ type: 'pattern',
349
+ image: this.pattern?.image,
350
+ offsetX: Number(this.pattern?.offsetX) || 0,
351
+ offsetY: Number(this.pattern?.offsetY) || 0,
352
+ width: Number(this.pattern?.width),
353
+ height: Number(this.pattern?.height),
354
+ align: this.pattern?.align,
355
+ fitPattern: this.pattern?.fitPattern
356
+ }
357
+
358
+ this._block_reset = true
359
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
360
+ }
361
+ }