@operato/app 1.0.0-alpha.3 → 1.0.0-alpha.30

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 (123) hide show
  1. package/@types/global/index.d.ts +2 -0
  2. package/CHANGELOG.md +159 -8
  3. package/demo/data-grist-test.html +456 -0
  4. package/dist/src/{grist → grist-editor}/index.d.ts +0 -0
  5. package/dist/src/grist-editor/index.js +24 -0
  6. package/dist/src/grist-editor/index.js.map +1 -0
  7. package/dist/src/grist-editor/ox-grist-editor-code.d.ts +7 -0
  8. package/dist/src/grist-editor/ox-grist-editor-code.js +56 -0
  9. package/dist/src/grist-editor/ox-grist-editor-code.js.map +1 -0
  10. package/dist/src/grist-editor/ox-grist-editor-crontab.d.ts +8 -0
  11. package/dist/src/grist-editor/ox-grist-editor-crontab.js +50 -0
  12. package/dist/src/grist-editor/ox-grist-editor-crontab.js.map +1 -0
  13. package/dist/src/grist-editor/ox-grist-editor-json.d.ts +7 -0
  14. package/dist/src/grist-editor/ox-grist-editor-json.js +54 -0
  15. package/dist/src/grist-editor/ox-grist-editor-json.js.map +1 -0
  16. package/dist/src/grist-editor/ox-grist-editor-parameters.d.ts +12 -0
  17. package/dist/src/grist-editor/ox-grist-editor-parameters.js +84 -0
  18. package/dist/src/grist-editor/ox-grist-editor-parameters.js.map +1 -0
  19. package/dist/src/grist-editor/ox-grist-editor-partition-keys.d.ts +11 -0
  20. package/dist/src/grist-editor/ox-grist-editor-partition-keys.js +74 -0
  21. package/dist/src/grist-editor/ox-grist-editor-partition-keys.js.map +1 -0
  22. package/dist/src/{grist/code-editor.d.ts → grist-editor/ox-grist-editor-resource-code.d.ts} +1 -1
  23. package/dist/src/{grist/code-editor.js → grist-editor/ox-grist-editor-resource-code.js} +9 -4
  24. package/dist/src/grist-editor/ox-grist-editor-resource-code.js.map +1 -0
  25. package/dist/src/grist-editor/ox-grist-editor-resource-id.d.ts +10 -0
  26. package/dist/src/{grist/id-input.js → grist-editor/ox-grist-editor-resource-id.js} +17 -66
  27. package/dist/src/grist-editor/ox-grist-editor-resource-id.js.map +1 -0
  28. package/dist/src/grist-editor/ox-grist-editor-resource-object.d.ts +11 -0
  29. package/dist/src/{grist/object-editor.js → grist-editor/ox-grist-editor-resource-object.js} +14 -64
  30. package/dist/src/grist-editor/ox-grist-editor-resource-object.js.map +1 -0
  31. package/dist/src/grist-editor/ox-grist-editor-value-map.d.ts +11 -0
  32. package/dist/src/grist-editor/ox-grist-editor-value-map.js +74 -0
  33. package/dist/src/grist-editor/ox-grist-editor-value-map.js.map +1 -0
  34. package/dist/src/grist-editor/ox-grist-renderer-resource-id.d.ts +2 -0
  35. package/dist/src/{grist/id-renderer.js → grist-editor/ox-grist-renderer-resource-id.js} +2 -2
  36. package/dist/src/grist-editor/ox-grist-renderer-resource-id.js.map +1 -0
  37. package/dist/src/grist-editor/ox-parameters-builder.d.ts +4 -0
  38. package/dist/src/grist-editor/ox-parameters-builder.js +118 -0
  39. package/dist/src/grist-editor/ox-parameters-builder.js.map +1 -0
  40. package/dist/src/grist-editor/ox-popup-code-input.d.ts +12 -0
  41. package/dist/src/grist-editor/ox-popup-code-input.js +71 -0
  42. package/dist/src/grist-editor/ox-popup-code-input.js.map +1 -0
  43. package/dist/src/grist-editor/ox-popup-crontab-input.d.ts +11 -0
  44. package/dist/src/grist-editor/ox-popup-crontab-input.js +74 -0
  45. package/dist/src/grist-editor/ox-popup-crontab-input.js.map +1 -0
  46. package/dist/src/grist-editor/ox-popup-parameters-builder.d.ts +13 -0
  47. package/dist/src/grist-editor/ox-popup-parameters-builder.js +111 -0
  48. package/dist/src/grist-editor/ox-popup-parameters-builder.js.map +1 -0
  49. package/dist/src/grist-editor/ox-popup-partition-keys-input.d.ts +12 -0
  50. package/dist/src/grist-editor/ox-popup-partition-keys-input.js +98 -0
  51. package/dist/src/grist-editor/ox-popup-partition-keys-input.js.map +1 -0
  52. package/dist/src/grist-editor/ox-popup-value-map-input.d.ts +12 -0
  53. package/dist/src/grist-editor/ox-popup-value-map-input.js +104 -0
  54. package/dist/src/grist-editor/ox-popup-value-map-input.js.map +1 -0
  55. package/dist/src/{grist/id-selector.d.ts → grist-editor/ox-selector-resource-id.d.ts} +1 -1
  56. package/dist/src/{grist/id-selector.js → grist-editor/ox-selector-resource-id.js} +15 -15
  57. package/dist/src/grist-editor/ox-selector-resource-id.js.map +1 -0
  58. package/dist/src/{grist/object-selector.d.ts → grist-editor/ox-selector-resource-object.d.ts} +1 -1
  59. package/dist/src/{grist/object-selector.js → grist-editor/ox-selector-resource-object.js} +21 -21
  60. package/dist/src/grist-editor/ox-selector-resource-object.js.map +1 -0
  61. package/dist/src/index.d.ts +3 -1
  62. package/dist/src/index.js +3 -1
  63. package/dist/src/index.js.map +1 -1
  64. package/dist/src/input/index.d.ts +3 -0
  65. package/dist/src/input/index.js +4 -0
  66. package/dist/src/input/index.js.map +1 -0
  67. package/dist/src/input/ox-input-background-pattern.d.ts +31 -0
  68. package/dist/src/input/ox-input-background-pattern.js +150 -0
  69. package/dist/src/input/ox-input-background-pattern.js.map +1 -0
  70. package/dist/src/input/ox-input-fill-style.d.ts +41 -0
  71. package/dist/src/input/ox-input-fill-style.js +325 -0
  72. package/dist/src/input/ox-input-fill-style.js.map +1 -0
  73. package/dist/src/input/ox-input-graphql.d.ts +36 -0
  74. package/dist/src/input/ox-input-graphql.js +161 -0
  75. package/dist/src/input/ox-input-graphql.js.map +1 -0
  76. package/dist/src/property-editor/index.d.ts +24 -0
  77. package/dist/src/property-editor/index.js +58 -0
  78. package/dist/src/property-editor/index.js.map +1 -0
  79. package/dist/src/property-editor/ox-property-editor-graphql.d.ts +5 -0
  80. package/dist/src/property-editor/ox-property-editor-graphql.js +15 -0
  81. package/dist/src/property-editor/ox-property-editor-graphql.js.map +1 -0
  82. package/dist/tsconfig.tsbuildinfo +1 -1
  83. package/package.json +41 -16
  84. package/src/grist-editor/index.ts +26 -0
  85. package/src/grist-editor/ox-grist-editor-code.ts +64 -0
  86. package/src/grist-editor/ox-grist-editor-crontab.ts +62 -0
  87. package/src/grist-editor/ox-grist-editor-json.ts +62 -0
  88. package/src/grist-editor/ox-grist-editor-parameters.ts +99 -0
  89. package/src/grist-editor/ox-grist-editor-partition-keys.ts +86 -0
  90. package/src/{grist/code-editor.ts → grist-editor/ox-grist-editor-resource-code.ts} +3 -4
  91. package/src/grist-editor/ox-grist-editor-resource-id.ts +83 -0
  92. package/src/{grist/object-editor.ts → grist-editor/ox-grist-editor-resource-object.ts} +11 -48
  93. package/src/grist-editor/ox-grist-editor-value-map.ts +86 -0
  94. package/src/{grist/id-renderer.ts → grist-editor/ox-grist-renderer-resource-id.ts} +1 -1
  95. package/src/grist-editor/ox-parameters-builder.ts +128 -0
  96. package/src/grist-editor/ox-popup-code-input.ts +65 -0
  97. package/src/grist-editor/ox-popup-crontab-input.ts +74 -0
  98. package/src/grist-editor/ox-popup-parameters-builder.ts +106 -0
  99. package/src/grist-editor/ox-popup-partition-keys-input.ts +95 -0
  100. package/src/grist-editor/ox-popup-value-map-input.ts +101 -0
  101. package/src/{grist/id-selector.ts → grist-editor/ox-selector-resource-id.ts} +2 -2
  102. package/src/{grist/object-selector.ts → grist-editor/ox-selector-resource-object.ts} +3 -3
  103. package/src/index.ts +3 -1
  104. package/src/input/index.ts +3 -0
  105. package/src/input/ox-input-background-pattern.ts +166 -0
  106. package/src/input/ox-input-fill-style.ts +359 -0
  107. package/src/input/ox-input-graphql.ts +169 -0
  108. package/src/property-editor/index.ts +59 -0
  109. package/src/property-editor/ox-property-editor-graphql.ts +12 -0
  110. package/yarn-error.log +17112 -0
  111. package/dist/src/grist/code-editor.js.map +0 -1
  112. package/dist/src/grist/id-input.d.ts +0 -19
  113. package/dist/src/grist/id-input.js.map +0 -1
  114. package/dist/src/grist/id-renderer.d.ts +0 -2
  115. package/dist/src/grist/id-renderer.js.map +0 -1
  116. package/dist/src/grist/id-selector.js.map +0 -1
  117. package/dist/src/grist/index.js +0 -9
  118. package/dist/src/grist/index.js.map +0 -1
  119. package/dist/src/grist/object-editor.d.ts +0 -18
  120. package/dist/src/grist/object-editor.js.map +0 -1
  121. package/dist/src/grist/object-selector.js.map +0 -1
  122. package/src/grist/id-input.ts +0 -135
  123. package/src/grist/index.ts +0 -11
@@ -0,0 +1,101 @@
1
+ import '@operato/input/ox-input-value-map.js'
2
+
3
+ import { LitElement, css, html } from 'lit'
4
+ import { customElement, property } from 'lit/decorators.js'
5
+
6
+ import { ScrollbarStyles } from '@operato/styles'
7
+ import { i18next } from '@operato/i18n'
8
+
9
+ @customElement('ox-popup-value-map-input')
10
+ export class OxPopupValueMapInput extends LitElement {
11
+ static styles = [
12
+ ScrollbarStyles,
13
+ css`
14
+ :host {
15
+ display: flex;
16
+ flex-direction: column;
17
+
18
+ background-color: #fff;
19
+
20
+ width: var(--overlay-center-normal-width, 50%);
21
+ height: var(--overlay-center-normal-height, 50%);
22
+ }
23
+
24
+ ox-input-value-map {
25
+ flex: 1;
26
+ overflow-y: auto;
27
+ }
28
+
29
+ span {
30
+ flex: 1;
31
+
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+
36
+ color: var(--primary-color);
37
+ }
38
+
39
+ .button-container {
40
+ display: flex;
41
+ margin-left: auto;
42
+ }
43
+ `
44
+ ]
45
+
46
+ @property({ type: Object }) value: any
47
+ @property({ type: String }) valuetype: string = 'string'
48
+ @property({ type: Object }) confirmCallback!: (newval: any) => void
49
+
50
+ render() {
51
+ return html`
52
+ <ox-input-value-map
53
+ .value=${this.value}
54
+ keytype="string"
55
+ .valuetype=${this.valuetype}
56
+ @change=${this.onChange.bind(this)}
57
+ >
58
+ </ox-input-value-map>
59
+
60
+ <div class="button-container">
61
+ <mwc-button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</mwc-button>
62
+ <mwc-button @click=${this.onConfirm.bind(this)}>${i18next.t('button.confirm')}</mwc-button>
63
+ </div>
64
+ `
65
+ }
66
+
67
+ private onChange(e: CustomEvent) {
68
+ e.stopPropagation()
69
+
70
+ /*
71
+ 주의 : 이 팝업 템플릿은 layout 모듈에 의해서 render 되므로,
72
+ layout의 구성에 변화가 발생하면, 다시 render된다.
73
+ 이 팝업이 떠 있는 상태에서, 또 다른 팝업이 뜨는 경우도 layout 구성의 변화를 야기한다. (overlay의 갯수의 증가)
74
+ 이 경우 value, options, confirmCallback 등 클로져를 사용한 것들이 초기 바인딩된 값으로 다시 바인딩되게 되는데,
75
+ 만약, 템플릿 내부에서 이들 속성의 레퍼런스가 변화했다면, 원래 상태로 되돌아가는 현상이 발생하게 된다.
76
+ 따라서, 가급적 이들 속성의 레퍼런스를 변화시키지 않는 것이 좋다.
77
+ (이 팝업 클래스를 템플릿으로 사용한 곳의 코드를 참조하세요.)
78
+ =>
79
+ 이런 이유로, Object.assign(...)을 사용하였다.
80
+ */
81
+
82
+ if (!this.value) {
83
+ this.value = {}
84
+ }
85
+
86
+ for (let key in this.value) {
87
+ delete this.value[key]
88
+ }
89
+
90
+ Object.assign(this.value, e.detail)
91
+ }
92
+
93
+ private onCancel(e: Event) {
94
+ history.back()
95
+ }
96
+
97
+ private onConfirm(e: Event) {
98
+ this.confirmCallback && this.confirmCallback(this.value)
99
+ history.back()
100
+ }
101
+ }
@@ -9,8 +9,8 @@ import gql from 'graphql-tag'
9
9
  import { i18next } from '@operato/i18n'
10
10
  import { isMobileDevice } from '@operato/utils'
11
11
 
12
- @customElement('ox-id-selector')
13
- export class IdSelector extends LitElement {
12
+ @customElement('ox-selector-resource-id')
13
+ export class OxSelectorResourceId extends LitElement {
14
14
  static styles = css`
15
15
  :host {
16
16
  display: flex;
@@ -20,8 +20,8 @@ import gql from 'graphql-tag'
20
20
  import { i18next } from '@operato/i18n'
21
21
  import { isMobileDevice } from '@operato/utils'
22
22
 
23
- @customElement('ox-object-selector')
24
- export class ObjectSelector extends LitElement {
23
+ @customElement('ox-selector-resource-object')
24
+ export class OxSelectorResourceObject extends LitElement {
25
25
  static styles = [
26
26
  MultiColumnFormStyles,
27
27
  css`
@@ -32,7 +32,7 @@ export class ObjectSelector extends LitElement {
32
32
  background-color: #fff;
33
33
  }
34
34
 
35
- data-grist {
35
+ ox-grist {
36
36
  flex: 1;
37
37
  }
38
38
 
package/src/index.ts CHANGED
@@ -1 +1,3 @@
1
- export * from './grist/index.js'
1
+ export * from './input/index.js'
2
+ export * from './property-editor'
3
+ export * from './grist-editor/index.js'
@@ -0,0 +1,3 @@
1
+ export * from './ox-input-background-pattern.js'
2
+ export * from './ox-input-fill-style.js'
3
+ export * from './ox-input-graphql.js'
@@ -0,0 +1,166 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import '@operato/i18n/ox-i18n.js'
6
+ import '@operato/attachment/ox-attachment-selector.js'
7
+
8
+ import { css, html } from 'lit'
9
+ import { customElement, property } from 'lit/decorators.js'
10
+
11
+ import { OxFormField } from '@operato/input'
12
+
13
+ export type BackgroundPatternOption = {
14
+ image?: HTMLImageElement | string
15
+ align?: 'left-top' | 'top' | 'right-top' | 'left' | 'center' | 'right' | 'left-bottom' | 'bottom' | 'right-bottom'
16
+ offsetX?: number
17
+ offsetY?: number
18
+ width?: number
19
+ height?: number
20
+ fitPattern?: boolean
21
+ }
22
+
23
+ /**
24
+ * 컴포넌트의 fill pattern을 편집하는 element
25
+ *
26
+ * Example:
27
+ * <ox-input-background-pattern
28
+ * @change="${e => { this.pattern = e.target.value }}"
29
+ * .value=${this.pattern}"
30
+ * ></ox-input-background-pattern>
31
+ */
32
+
33
+ @customElement('ox-input-background-pattern')
34
+ export class OxInputBackgroundPattern extends OxFormField {
35
+ static styles = css`
36
+ :host,
37
+ .grid-10 {
38
+ display: grid;
39
+ grid-template-columns: repeat(10, 1fr);
40
+ grid-gap: 5px;
41
+ grid-auto-rows: minmax(24px, auto);
42
+
43
+ align-items: center;
44
+ }
45
+
46
+ * {
47
+ align-self: stretch;
48
+ }
49
+
50
+ label {
51
+ grid-column: span 2;
52
+ text-align: right;
53
+ text-transform: capitalize;
54
+
55
+ align-self: center;
56
+ }
57
+
58
+ .grid-10 {
59
+ grid-column: span 10;
60
+ }
61
+
62
+ select,
63
+ input,
64
+ [custom-editor] {
65
+ grid-column: span 8;
66
+ }
67
+
68
+ select {
69
+ height: 100%;
70
+ border: 1px solid rgba(0, 0, 0, 0.2);
71
+ }
72
+
73
+ input[type='checkbox'] {
74
+ grid-column: 3 / 4;
75
+ align-self: center;
76
+ }
77
+
78
+ input[type='checkbox'] ~ label {
79
+ grid-column: span 7;
80
+ text-align: left;
81
+ }
82
+
83
+ .grid-10 > input[type='number'] {
84
+ grid-column: span 3;
85
+ border: 1px solid rgba(0, 0, 0, 0.2);
86
+ }
87
+
88
+ .grid-10 > label {
89
+ grid-column: span 2;
90
+ text-align: right;
91
+ }
92
+ `
93
+
94
+ @property({ type: Object }) value?: BackgroundPatternOption
95
+
96
+ render() {
97
+ const value = this.value || ({} as BackgroundPatternOption)
98
+
99
+ return html`
100
+ <label> <ox-i18n msgid="label.image" auto="">image</ox-i18n> </label>
101
+
102
+ <ox-attachment-selector
103
+ value-key="image"
104
+ .value=${value.image || ''}
105
+ .properties=${{
106
+ category: 'image'
107
+ }}
108
+ custom-editor
109
+ ></ox-attachment-selector>
110
+
111
+ <label> <ox-i18n msgid="label.align" auto="">align</ox-i18n> </label>
112
+
113
+ <select value-key="align" class="select-content" .value=${value.align}>
114
+ <option value="left-top">Left Top</option>
115
+ <option value="top">Top</option>
116
+ <option value="right-top">Right Top</option>
117
+ <option value="left">Left</option>
118
+ <option value="center">Center</option>
119
+ <option value="right">Right</option>
120
+ <option value="left-bottom">Left Bottom</option>
121
+ <option value="bottom">Bottom</option>
122
+ <option value="right-bottom">Right Bottom</option>
123
+ </select>
124
+
125
+ <div class="grid-10">
126
+ <label> <ox-i18n msgid="label.offset-x" auto="">offsetX</ox-i18n> </label>
127
+ <input type="number" value-key="offsetX" .value=${value.offsetX} />
128
+
129
+ <label> <ox-i18n msgid="label.offset-y" auto="">offsetY</ox-i18n> </label>
130
+ <input type="number" value-key="offsetY" .value=${value.offsetY} />
131
+
132
+ <label> <ox-i18n msgid="label.width" auto="">width</ox-i18n> </label>
133
+ <input type="number" value-key="width" .value=${value.width} />
134
+
135
+ <label> <ox-i18n msgid="label.height" auto="">height</ox-i18n> </label>
136
+ <input type="number" value-key="height" .value=${value.height} />
137
+ </div>
138
+
139
+ <div class="grid-10">
140
+ <input value-key="fitPattern" type="checkbox" .checked=${value.fitPattern} required />
141
+ <label> <ox-i18n msgid="label.fit" auto="">Fit</ox-i18n> </label>
142
+ </div>
143
+ `
144
+ }
145
+
146
+ firstUpdated() {
147
+ this.renderRoot.addEventListener('change', this._onChange.bind(this))
148
+ }
149
+
150
+ _onChange(e: Event) {
151
+ var element = e.target as HTMLInputElement
152
+ var key = element.getAttribute('value-key')
153
+ var value: any = element.value
154
+
155
+ if (key == 'fitPattern') {
156
+ value = element.checked
157
+ }
158
+
159
+ this.value = {
160
+ ...this.value,
161
+ [key!]: value
162
+ }
163
+
164
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
165
+ }
166
+ }
@@ -0,0 +1,359 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import '@operato/i18n/ox-i18n.js'
6
+ import '@operato/input/ox-input-color.js'
7
+ import '@operato/input/ox-input-color-stops.js'
8
+ import '@operato/input/ox-input-color-gradient.js'
9
+ import './ox-input-background-pattern.js'
10
+
11
+ import { BackgroundPatternOption, OxInputBackgroundPattern } from './ox-input-background-pattern.js'
12
+ import { ColorStop, GradientOption, OxFormField, OxInputColorGradient } from '@operato/input'
13
+ import { PropertyValues, css, html } from 'lit'
14
+ import { customElement, property, query } from 'lit/decorators.js'
15
+
16
+ export type FillStyle =
17
+ | {
18
+ type?: 'no' | 'solid' | 'gradient' | 'pattern'
19
+ gradientType?: 'linear' | 'radial'
20
+ colorStops?: ColorStop[]
21
+ rotation?: number
22
+ center?: 'center' | 'left-top' | 'right-top' | 'right-bottom' | 'left-bottom'
23
+ image?: HTMLImageElement | string
24
+ offsetX?: number
25
+ offsetY?: number
26
+ width?: number
27
+ height?: number
28
+ align?: 'left-top' | 'top' | 'right-top' | 'left' | 'center' | 'right' | 'left-bottom' | 'bottom' | 'right-bottom'
29
+ fitPattern?: boolean
30
+ }
31
+ | 'no'
32
+ | string
33
+
34
+ @customElement('ox-input-fill-style')
35
+ export class OxInputColorStyle extends OxFormField {
36
+ static styles = css`
37
+ :host {
38
+ display: flex;
39
+ flex-direction: column;
40
+ }
41
+
42
+ [fill-type] {
43
+ display: flex;
44
+ margin: 0 0 14px 0;
45
+ }
46
+
47
+ [fill-type] * {
48
+ flex: auto;
49
+ margin: 0;
50
+ text-align: left;
51
+ align-self: center;
52
+ }
53
+
54
+ .grid-10 {
55
+ display: grid;
56
+
57
+ grid-template-columns: repeat(10, 1fr);
58
+ grid-gap: 5px;
59
+ grid-auto-rows: minmax(24px, auto);
60
+ }
61
+
62
+ .grid-10 > ox-input-color {
63
+ grid-column: span 4;
64
+ }
65
+
66
+ .grid-10 > .icon-only-label {
67
+ grid-column: span 1;
68
+
69
+ background: url(/assets/images/icon-properties-label.png) no-repeat;
70
+ float: left;
71
+ margin: 0;
72
+ }
73
+
74
+ .icon-only-label.color {
75
+ background-position: 70% -498px;
76
+ }
77
+
78
+ [editors] > :not([active]) {
79
+ display: none;
80
+ }
81
+ `
82
+
83
+ @property({ type: Object }) value?: FillStyle
84
+ @property({ type: String }) fillType?: string
85
+ @property({ type: String }) solid?: string
86
+ @property({ type: Object }) gradient?: GradientOption
87
+ @property({ type: Object }) pattern?: BackgroundPatternOption
88
+
89
+ private _block_reset: boolean = false
90
+
91
+ updated(changes: PropertyValues<this>) {
92
+ changes.has('value') && this._onChangedValue(this.value || {})
93
+ }
94
+
95
+ render() {
96
+ return html`
97
+ <div @change=${(e: Event) => this._onChangedFillType(e)} fill-type>
98
+ <input
99
+ type="radio"
100
+ id="fill-type-no"
101
+ name="fill-type"
102
+ value="no"
103
+ .checked=${!this.fillType || this.fillType == 'no'}
104
+ />
105
+ <label for="fill-type-no"><ox-i18n msgid="label.no-fill">no fill</ox-i18n></label>
106
+ <input type="radio" id="fill-type-solid" name="fill-type" value="solid" .checked=${this.fillType == 'solid'} />
107
+ <label for="fill-type-solid"><ox-i18n msgid="label.solid">solid</ox-i18n></label>
108
+ <input
109
+ type="radio"
110
+ id="fill-type-gradient"
111
+ name="fill-type"
112
+ value="gradient"
113
+ .checked=${this.fillType == 'gradient'}
114
+ />
115
+ <label for="fill-type-gradient"><ox-i18n msgid="label.gradient">gradient</ox-i18n></label>
116
+ <input
117
+ type="radio"
118
+ id="fill-type-pattern"
119
+ name="fill-type"
120
+ value="pattern"
121
+ .checked=${this.fillType == 'pattern'}
122
+ />
123
+ <label for="fill-type-pattern"><ox-i18n msgid="label.pattern">pattern</ox-i18n></label>
124
+ </div>
125
+
126
+ <div editors>
127
+ <div ?active=${this.fillType == 'no'}></div>
128
+
129
+ <div class="grid-10" ?active=${this.fillType == 'solid'}>
130
+ <label class="icon-only-label color"></label>
131
+ <ox-input-color @change=${(e: Event) => this._onChangedSolid(e)} .value=${this.solid}> </ox-input-color>
132
+ </div>
133
+
134
+ <div ?active=${this.fillType == 'gradient'}>
135
+ <ox-input-color-gradient @change=${(e: Event) => this._onChandedGradient(e)} .value=${this.gradient}>
136
+ </ox-input-color-gradient>
137
+ </div>
138
+
139
+ <div ?active=${this.fillType == 'pattern'}>
140
+ <ox-input-background-pattern @change=${(e: Event) => this._onChangedPattern(e)} .value=${this.pattern}>
141
+ </ox-input-background-pattern>
142
+ </div>
143
+ </div>
144
+ `
145
+ }
146
+
147
+ async _onChangedValue(value: FillStyle) {
148
+ /*
149
+ * this._block_reset의 역할은 내부 사용자 인터렉션에 의한 value의 변경시에는 각 type별 이전값을 유지하기 위함이다.
150
+ */
151
+ await this.requestUpdate()
152
+
153
+ /* 설정 값에 따라서, 멤버 속성을 설정한다. */
154
+ if (!value) {
155
+ this.fillType = 'no'
156
+
157
+ if (!this._block_reset) {
158
+ this.solid = undefined
159
+ this.gradient = undefined
160
+ this.pattern = undefined
161
+ }
162
+
163
+ this._block_reset = false
164
+ return
165
+ }
166
+
167
+ switch (typeof value) {
168
+ case 'string':
169
+ this.fillType = 'solid'
170
+ this.solid = value
171
+
172
+ if (!this._block_reset) {
173
+ this.gradient = undefined
174
+ this.pattern = undefined
175
+ }
176
+ break
177
+ case 'object':
178
+ this.fillType = value.type
179
+
180
+ if (value.type === 'gradient') {
181
+ this.gradient = {
182
+ type: value.gradientType || 'linear',
183
+ colorStops: value.colorStops || [
184
+ {
185
+ position: 0,
186
+ color: this.solid || '#000000'
187
+ },
188
+ {
189
+ position: 1,
190
+ color: this.solid || '#FFFFFF'
191
+ }
192
+ ],
193
+ rotation: Number(value.rotation) || 0,
194
+ center: value.center
195
+ }
196
+
197
+ if (!this._block_reset) {
198
+ this.pattern = undefined
199
+ this.solid = undefined
200
+ }
201
+ } else if (value.type === 'pattern') {
202
+ this.pattern = {
203
+ image: value.image,
204
+ offsetX: Number(value.offsetX) || 0,
205
+ offsetY: Number(value.offsetY) || 0,
206
+ width: Number(value.width),
207
+ height: Number(value.height),
208
+ align: value.align,
209
+ fitPattern: value.fitPattern
210
+ }
211
+
212
+ if (!this._block_reset) {
213
+ this.gradient = undefined
214
+ this.solid = undefined
215
+ }
216
+ }
217
+
218
+ break
219
+ default:
220
+ }
221
+
222
+ this._block_reset = false
223
+ }
224
+
225
+ _onChangedFillType(e: Event) {
226
+ const element = e.target as HTMLInputElement
227
+ this.fillType = element.value
228
+
229
+ switch (this.fillType) {
230
+ case 'gradient':
231
+ if (!this.gradient) {
232
+ this.gradient = {
233
+ type: 'linear',
234
+ colorStops: [
235
+ {
236
+ position: 0,
237
+ color: this.solid || '#000000'
238
+ },
239
+ {
240
+ position: 1,
241
+ color: this.solid || '#FFFFFF'
242
+ }
243
+ ],
244
+ rotation: 0,
245
+ center: 'center'
246
+ }
247
+ }
248
+
249
+ this.value = {
250
+ type: 'gradient',
251
+ gradientType: this.gradient.type || 'linear',
252
+ colorStops: this.gradient.colorStops || [
253
+ {
254
+ position: 0,
255
+ color: this.solid || '#000000'
256
+ },
257
+ {
258
+ position: 1,
259
+ color: this.solid || '#FFFFFF'
260
+ }
261
+ ],
262
+ rotation: Number(this.gradient.rotation) || 0,
263
+ center: this.gradient.center
264
+ }
265
+ break
266
+
267
+ case 'pattern':
268
+ if (!this.pattern) this.pattern = {}
269
+
270
+ this.value = {
271
+ type: 'pattern',
272
+ image: this.pattern.image,
273
+ offsetX: Number(this.pattern.offsetX) || 0,
274
+ offsetY: Number(this.pattern.offsetY) || 0,
275
+ width: Number(this.pattern.width),
276
+ height: Number(this.pattern.height),
277
+ align: this.pattern.align,
278
+ fitPattern: this.pattern.fitPattern
279
+ }
280
+ break
281
+
282
+ case 'solid':
283
+ if (!this.solid) this.solid = '#fff'
284
+ this.value = this.solid
285
+ break
286
+
287
+ case 'no':
288
+ this.value = ''
289
+ break
290
+ }
291
+
292
+ this._block_reset = true
293
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
294
+ }
295
+
296
+ _onChangedSolid(e: Event) {
297
+ if (this.fillType !== 'solid') return
298
+
299
+ this.solid = (e.target as HTMLInputElement).value
300
+
301
+ this.value = this.solid
302
+
303
+ this._block_reset = true
304
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
305
+ }
306
+
307
+ _onChandedGradient(e: Event) {
308
+ /*
309
+ * TODO Gradient의 rotation은 symmetry 기능 등으로 외부에서 변경될 수도 있다.
310
+ * 이 점을 감안해서, 외부 변경에 대한 대응을 해야 한다.
311
+ */
312
+
313
+ if (this.fillType !== 'gradient') {
314
+ return
315
+ }
316
+
317
+ this.gradient = (e.target as OxInputColorGradient).value
318
+
319
+ this.value = {
320
+ type: 'gradient',
321
+ gradientType: this.gradient.type || 'linear',
322
+ colorStops: this.gradient.colorStops || [
323
+ {
324
+ position: 0,
325
+ color: this.solid || '#000000'
326
+ },
327
+ {
328
+ position: 1,
329
+ color: this.solid || '#FFFFFF'
330
+ }
331
+ ],
332
+ rotation: Number(this.gradient.rotation) || 0,
333
+ center: this.gradient.center
334
+ }
335
+
336
+ this._block_reset = true
337
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
338
+ }
339
+
340
+ _onChangedPattern(e: Event) {
341
+ if (this.fillType !== 'pattern') return
342
+
343
+ this.pattern = (e.target as OxInputBackgroundPattern).value
344
+
345
+ this.value = {
346
+ type: 'pattern',
347
+ image: this.pattern?.image,
348
+ offsetX: Number(this.pattern?.offsetX) || 0,
349
+ offsetY: Number(this.pattern?.offsetY) || 0,
350
+ width: Number(this.pattern?.width),
351
+ height: Number(this.pattern?.height),
352
+ align: this.pattern?.align,
353
+ fitPattern: this.pattern?.fitPattern
354
+ }
355
+
356
+ this._block_reset = true
357
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
358
+ }
359
+ }