@operato/input 1.0.0-alpha.8 → 1.0.0-beta.1

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 (119) hide show
  1. package/CHANGELOG.md +412 -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/assets/images/icon-properties-line-type.png +0 -0
  6. package/assets/images/icon-properties-table.png +0 -0
  7. package/demo/index-color-gradient.html +35 -0
  8. package/demo/index-color-stops.html +62 -0
  9. package/demo/index-color.html +35 -0
  10. package/demo/index-crontab.html +37 -0
  11. package/demo/index-multiple-colors.html +37 -0
  12. package/demo/index-partition-keys.html +71 -0
  13. package/demo/index-select.html +21 -14
  14. package/demo/index-table.html +39 -0
  15. package/demo/index-value-map.html +80 -0
  16. package/demo/index-value-ranges.html +80 -0
  17. package/demo/index-work-shift.html +59 -0
  18. package/demo/index.html +14 -0
  19. package/dist/src/index.d.ts +21 -11
  20. package/dist/src/index.js +21 -11
  21. package/dist/src/index.js.map +1 -1
  22. package/dist/src/ox-checkbox.d.ts +1 -1
  23. package/dist/src/ox-checkbox.js +1 -1
  24. package/dist/src/ox-checkbox.js.map +1 -1
  25. package/dist/src/ox-form-field.d.ts +2 -2
  26. package/dist/src/ox-form-field.js.map +1 -1
  27. package/dist/src/ox-input-barcode.d.ts +1 -1
  28. package/dist/src/ox-input-barcode.js +1 -1
  29. package/dist/src/ox-input-barcode.js.map +1 -1
  30. package/dist/src/ox-input-code.d.ts +4 -4
  31. package/dist/src/ox-input-code.js +8 -8
  32. package/dist/src/ox-input-code.js.map +1 -1
  33. package/dist/src/ox-input-color-gradient.d.ts +26 -0
  34. package/dist/src/ox-input-color-gradient.js +318 -0
  35. package/dist/src/ox-input-color-gradient.js.map +1 -0
  36. package/dist/src/ox-input-color-stops.d.ts +71 -0
  37. package/dist/src/ox-input-color-stops.js +445 -0
  38. package/dist/src/ox-input-color-stops.js.map +1 -0
  39. package/dist/src/ox-input-color.d.ts +176 -0
  40. package/dist/src/ox-input-color.js +298 -0
  41. package/dist/src/ox-input-color.js.map +1 -0
  42. package/dist/src/ox-input-crontab.d.ts +23 -0
  43. package/dist/src/ox-input-crontab.js +560 -0
  44. package/dist/src/ox-input-crontab.js.map +1 -0
  45. package/dist/src/ox-input-data.d.ts +1 -1
  46. package/dist/src/ox-input-data.js +1 -1
  47. package/dist/src/ox-input-data.js.map +1 -1
  48. package/dist/src/ox-input-layout/ox-input-card-layout.d.ts +4 -0
  49. package/dist/src/ox-input-layout/ox-input-card-layout.js +57 -0
  50. package/dist/src/ox-input-layout/ox-input-card-layout.js.map +1 -0
  51. package/dist/src/ox-input-layout/ox-input-grid-layout.d.ts +4 -0
  52. package/dist/src/ox-input-layout/ox-input-grid-layout.js +63 -0
  53. package/dist/src/ox-input-layout/ox-input-grid-layout.js.map +1 -0
  54. package/dist/src/ox-input-layout/ox-input-layout.d.ts +5 -0
  55. package/dist/src/ox-input-layout/ox-input-layout.js +73 -0
  56. package/dist/src/ox-input-layout/ox-input-layout.js.map +1 -0
  57. package/dist/src/ox-input-multiple-colors.d.ts +28 -0
  58. package/dist/src/ox-input-multiple-colors.js +113 -0
  59. package/dist/src/ox-input-multiple-colors.js.map +1 -0
  60. package/dist/src/ox-input-options.js.map +1 -1
  61. package/dist/src/ox-input-partition-keys.d.ts +36 -0
  62. package/dist/src/ox-input-partition-keys.js +204 -0
  63. package/dist/src/ox-input-partition-keys.js.map +1 -0
  64. package/dist/src/{ox-input-id.d.ts → ox-input-scene-component-id.d.ts} +0 -0
  65. package/dist/src/{ox-input-id.js → ox-input-scene-component-id.js} +2 -2
  66. package/dist/src/ox-input-scene-component-id.js.map +1 -0
  67. package/dist/src/ox-input-search.d.ts +1 -0
  68. package/dist/src/ox-input-search.js +7 -1
  69. package/dist/src/ox-input-search.js.map +1 -1
  70. package/dist/src/ox-input-stack.d.ts +1 -1
  71. package/dist/src/ox-input-stack.js +1 -1
  72. package/dist/src/ox-input-stack.js.map +1 -1
  73. package/dist/src/ox-input-table.d.ts +8 -0
  74. package/dist/src/ox-input-table.js +379 -0
  75. package/dist/src/ox-input-table.js.map +1 -0
  76. package/dist/src/ox-input-value-map.d.ts +41 -0
  77. package/dist/src/ox-input-value-map.js +279 -0
  78. package/dist/src/ox-input-value-map.js.map +1 -0
  79. package/dist/src/ox-input-value-ranges.d.ts +41 -0
  80. package/dist/src/ox-input-value-ranges.js +298 -0
  81. package/dist/src/ox-input-value-ranges.js.map +1 -0
  82. package/dist/src/ox-input-work-shift.d.ts +33 -0
  83. package/dist/src/ox-input-work-shift.js +229 -0
  84. package/dist/src/ox-input-work-shift.js.map +1 -0
  85. package/dist/src/ox-select.d.ts +3 -0
  86. package/dist/src/ox-select.js +28 -3
  87. package/dist/src/ox-select.js.map +1 -1
  88. package/dist/tsconfig.tsbuildinfo +1 -1
  89. package/package.json +24 -7
  90. package/src/index.ts +21 -11
  91. package/src/ox-checkbox.ts +2 -2
  92. package/src/ox-form-field.ts +2 -2
  93. package/src/ox-input-barcode.ts +2 -3
  94. package/src/ox-input-code.ts +9 -10
  95. package/src/ox-input-color-gradient.ts +343 -0
  96. package/src/ox-input-color-stops.ts +499 -0
  97. package/src/ox-input-color.ts +323 -0
  98. package/src/ox-input-crontab.ts +561 -0
  99. package/src/ox-input-data.ts +2 -2
  100. package/src/ox-input-layout/ox-input-card-layout.ts +58 -0
  101. package/src/ox-input-layout/ox-input-grid-layout.ts +64 -0
  102. package/src/ox-input-layout/ox-input-layout.ts +77 -0
  103. package/src/ox-input-multiple-colors.ts +113 -0
  104. package/src/ox-input-options.ts +1 -1
  105. package/src/ox-input-partition-keys.ts +243 -0
  106. package/src/{ox-input-id.ts → ox-input-scene-component-id.ts} +1 -1
  107. package/src/ox-input-search.ts +9 -1
  108. package/src/ox-input-stack.ts +1 -1
  109. package/src/ox-input-table.ts +404 -0
  110. package/src/{ox-input-keyvalues.ts.ing → ox-input-value-map.ts} +125 -94
  111. package/src/ox-input-value-ranges.ts +325 -0
  112. package/src/ox-input-work-shift.ts +251 -0
  113. package/src/ox-select.ts +31 -5
  114. package/translations/en.json +1 -0
  115. package/translations/ko.json +1 -0
  116. package/translations/ms.json +1 -0
  117. package/translations/zh.json +1 -0
  118. package/dist/src/ox-input-id.js.map +0 -1
  119. package/src/ox-input-ranges.ts.ing +0 -292
@@ -0,0 +1,251 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import './ox-input-color'
6
+
7
+ import { css, html } from 'lit'
8
+ import { customElement, property } from 'lit/decorators.js'
9
+
10
+ import { OxFormField } from './ox-form-field.js'
11
+
12
+ type WorkShift = { name: string; fromDate: number; fromTime: string; toDate: number; toTime: string }
13
+
14
+ /**
15
+ work-shift array value editor element
16
+
17
+ Example:
18
+
19
+ <ox-input-work-shift
20
+ .value=${value}
21
+ </ox-input-work-shift>
22
+ */
23
+
24
+ @customElement('ox-input-work-shift')
25
+ export class OxInputWorkShift extends OxFormField {
26
+ static styles = css`
27
+ :host {
28
+ display: flex;
29
+ flex-direction: column;
30
+ align-content: center;
31
+
32
+ width: 100%;
33
+ overflow: hidden;
34
+ border: 1px solid #ccc;
35
+ }
36
+
37
+ div {
38
+ display: flex;
39
+ flex-flow: row nowrap;
40
+ align-items: center;
41
+
42
+ border-bottom: 1px solid #c0c0c0;
43
+ }
44
+
45
+ div:last-child {
46
+ border-bottom: none;
47
+ }
48
+
49
+ div > * {
50
+ min-width: 0px;
51
+ margin: 2px;
52
+ padding: 0;
53
+ }
54
+
55
+ button,
56
+ empty-element {
57
+ width: 20px;
58
+ text-align: center;
59
+ }
60
+
61
+ input,
62
+ select,
63
+ span {
64
+ flex: 1;
65
+ }
66
+
67
+ input:required:invalid {
68
+ border: 1px dashed red;
69
+ }
70
+
71
+ [placeholder='value'] {
72
+ flex: 2;
73
+ }
74
+
75
+ div {
76
+ border-bottom: 1px solid #c0c0c0;
77
+ }
78
+
79
+ div:last-child {
80
+ border-bottom: none;
81
+ }
82
+ `
83
+
84
+ @property({ type: Object }) value: WorkShift[] = []
85
+
86
+ private _changingNow: boolean = false
87
+
88
+ firstUpdated() {
89
+ this.renderRoot.addEventListener('change', this._onChange.bind(this))
90
+ }
91
+
92
+ render() {
93
+ return html`
94
+ <div data-header>
95
+ <span>name</span>
96
+ <span>from date</span>
97
+ <span>from time</span>
98
+ <span>to date</span>
99
+ <span>to time</span>
100
+ <empty-element></empty-element>
101
+ </div>
102
+
103
+ ${this.value.map(
104
+ item => html`
105
+ <div data-record>
106
+ <input type="text" data-name .value=${item.name} required />
107
+
108
+ <select data-from-date .value=${item.fromDate || 0}>
109
+ <option value="-1">The day before</option>
110
+ <option value="0">The day</option>
111
+ <option value="1">The day after</option>
112
+ </select>
113
+ <input type="time" data-from-time .value=${item.fromTime} step="1800" required />
114
+
115
+ <select data-to-date .value=${item.toDate || 0}>
116
+ <option value="-1">The day before</option>
117
+ <option value="0">The day</option>
118
+ <option value="1">The day after</option>
119
+ </select>
120
+ <input type="time" data-to-time .value=${item.toTime} step="1800" required />
121
+
122
+ <button class="record-action" @click=${(e: Event) => this._delete(e)} tabindex="-1">-</button>
123
+ </div>
124
+ `
125
+ )}
126
+
127
+ <div data-record-new>
128
+ <input type="text" data-name />
129
+
130
+ <select data-from-date>
131
+ <option value="-1">The day before</option>
132
+ <option value="0" selected>The day</option>
133
+ <option value="+1">The day after</option>
134
+ </select>
135
+ <input type="time" data-from-time step="1800" />
136
+
137
+ <select data-to-date>
138
+ <option value="-1">The day before</option>
139
+ <option value="0" selected>The day</option>
140
+ <option value="+1">The day after</option>
141
+ </select>
142
+ <input type="time" data-to-time step="1800" />
143
+
144
+ <button class="record-action" @click=${(e: Event) => this._add()} tabindex="-1">+</button>
145
+ </div>
146
+ `
147
+ }
148
+
149
+ _onChange(e: Event) {
150
+ if (this._changingNow) {
151
+ return
152
+ }
153
+
154
+ this._changingNow = true
155
+
156
+ const input = e.target as HTMLInputElement
157
+
158
+ const div = input.parentElement as HTMLDivElement
159
+
160
+ if (div.hasAttribute('data-record')) {
161
+ this._build()
162
+ } else if (div.hasAttribute('data-record-new') && input.hasAttribute('data-value')) {
163
+ this._add()
164
+ }
165
+
166
+ this._changingNow = false
167
+ }
168
+
169
+ _build(includeNewRecord?: boolean) {
170
+ if (includeNewRecord) {
171
+ var records = this.renderRoot.querySelectorAll('[data-record],[data-record-new]')
172
+ } else {
173
+ var records = this.renderRoot.querySelectorAll('[data-record]')
174
+ }
175
+
176
+ var value: WorkShift[] = []
177
+ for (var i = 0; i < records.length; i++) {
178
+ const record = records[i]
179
+
180
+ const name = (record.querySelector('[data-name]') as HTMLInputElement).value
181
+
182
+ const fromDate = (record.querySelector('[data-from-date]') as HTMLSelectElement).value
183
+ const fromTime = (record.querySelector('[data-from-time]') as HTMLInputElement).value
184
+ const toDate = (record.querySelector('[data-to-date]') as HTMLSelectElement).value
185
+ const toTime = (record.querySelector('[data-to-time]') as HTMLInputElement).value
186
+
187
+ if (!name) {
188
+ ;(record.querySelector('[data-name]') as HTMLInputElement).focus()
189
+ return
190
+ }
191
+
192
+ if (!fromDate) {
193
+ ;(record.querySelector('[data-from-date]') as HTMLInputElement).focus()
194
+ return
195
+ }
196
+
197
+ if (!fromTime) {
198
+ ;(record.querySelector('[data-from-time]') as HTMLInputElement).focus()
199
+ return
200
+ }
201
+
202
+ if (!toDate) {
203
+ ;(record.querySelector('[data-to-date]') as HTMLInputElement).focus()
204
+ return
205
+ }
206
+
207
+ if (!toTime) {
208
+ ;(record.querySelector('[data-to-time]') as HTMLInputElement).focus()
209
+ return
210
+ }
211
+
212
+ if (name) {
213
+ value.push({
214
+ name,
215
+ fromDate: Number(fromDate),
216
+ fromTime,
217
+ toDate: Number(toDate),
218
+ toTime
219
+ })
220
+ }
221
+ }
222
+
223
+ this.value = value
224
+
225
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
226
+ }
227
+
228
+ _add() {
229
+ this._build(true)
230
+
231
+ const inputs = this.renderRoot.querySelectorAll(
232
+ '[data-record-new] input:not([style*="display: none"])'
233
+ ) as NodeListOf<HTMLInputElement & { value: any; type: string }>
234
+
235
+ for (var i = 0; i < inputs.length; i++) {
236
+ let input = inputs[i]
237
+ input.value = ''
238
+ }
239
+
240
+ inputs[0].focus()
241
+ }
242
+
243
+ _delete(e: Event) {
244
+ const record = (e.target as Element).parentElement
245
+
246
+ const dataName = record!.querySelector('[data-name]') as HTMLInputElement
247
+ dataName.name = ''
248
+
249
+ this._build()
250
+ }
251
+ }
package/src/ox-select.ts CHANGED
@@ -5,16 +5,30 @@
5
5
  import '@material/mwc-icon'
6
6
  import '@operato/popup/ox-popup-list.js'
7
7
 
8
- import { css, html } from 'lit'
9
- import { customElement, property } from 'lit/decorators.js'
8
+ import { PropertyValues, css, html } from 'lit'
9
+ import { customElement, property, query, state } from 'lit/decorators.js'
10
10
 
11
+ import { OxFormField } from './ox-form-field.js'
11
12
  import { OxPopupList } from '@operato/popup'
13
+ import { TooltipStyles } from '@operato/styles'
14
+ import { detectOverflow } from '@operato/utils'
12
15
 
13
- import { OxFormField } from './ox-form-field.js'
16
+ function onmouseover(e: Event) {
17
+ const element = e.target as HTMLSpanElement
18
+ if (detectOverflow(element)) {
19
+ element.setAttribute('data-tooltip', element.textContent!)
20
+ }
21
+ }
22
+
23
+ function onmouseout(e: Event) {
24
+ const element = e.target as HTMLSpanElement
25
+ element.removeAttribute('data-tooltip')
26
+ }
14
27
 
15
28
  @customElement('ox-select')
16
29
  export class Select extends OxFormField {
17
30
  static styles = [
31
+ TooltipStyles,
18
32
  css`
19
33
  :host {
20
34
  display: block;
@@ -54,12 +68,14 @@ export class Select extends OxFormField {
54
68
  @property({ type: String }) name: string = ''
55
69
  @property({ type: String }) placeholder: string = ''
56
70
 
71
+ @state() label: string | string[] = ''
72
+
57
73
  render() {
58
- const label = (this.value instanceof Array ? this.value.join(', ') : this.value) || this.placeholder || ''
74
+ const label = (this.label instanceof Array ? this.label.join(', ') : this.label?.trim()) || this.placeholder || ''
59
75
 
60
76
  return html`
61
77
  <div @click=${this.expand}>
62
- <span>${label}</span>
78
+ <span @mouseover=${onmouseover} @mouseout=${onmouseout}>${label}</span>
63
79
  <mwc-icon>expand_more</mwc-icon>
64
80
  </div>
65
81
 
@@ -93,6 +109,16 @@ export class Select extends OxFormField {
93
109
  })
94
110
  }
95
111
 
112
+ async updated(changes: PropertyValues<this>) {
113
+ if (changes.has('value')) {
114
+ const popupList = this.querySelector('ox-popup-list') as OxPopupList
115
+ popupList.value = this.value
116
+
117
+ await this.requestUpdate()
118
+ this.label = popupList.getSelectedLabels()
119
+ }
120
+ }
121
+
96
122
  expand() {
97
123
  const popupList = this.querySelector('ox-popup-list') as OxPopupList
98
124
 
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1 @@
1
+ {}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ox-input-id.js","sourceRoot":"","sources":["../../src/ox-input-id.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG7C,IAAa,SAAS,GAAtB,MAAa,SAAU,SAAQ,WAAW;IAA1C;;QAmBW,SAAI,GAAkB,EAAE,CAAA;IA0CnC,CAAC;aA5DQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;GAclB,CAAA;IAMD,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAA;QAE3B,OAAO,IAAI,CAAA;;;;iBAIE,IAAI,CAAC,KAAK,IAAI,EAAE;mBACd,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;kBAC3C,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;uBACrC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,EAAE;;;;2BAIlC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAA,kBAAkB,EAAE,aAAa,CAAC;KAC1E,CAAA;IACH,CAAC;IAED,eAAe,CAAC,CAAa;QAC3B,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAA;QAEvC,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,6BAA6B,EAAE;YAC7C,MAAM,EAAE;gBACN,SAAS;gBACT,QAAQ,EAAE,CAAC,GAAa,EAAE,EAAE;oBAC1B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAA;gBACjB,CAAC;aACF;SACF,CAAC,CACH,CAAA;IACH,CAAC;IAED,eAAe,CAAC,CAAa;QAC3B,CAAC,CAAC,eAAe,EAAE,CAAA;QAEnB,IAAI,CAAC,KAAK,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAA;QAEjD,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAClF,CAAC;CACF,CAAA;AA5C6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CAAoD;AAEtE;IAAR,KAAK,EAAE;uCAAyB;AAnBtB,SAAS;IADrB,aAAa,CAAC,aAAa,CAAC;GAChB,SAAS,CA6DrB;SA7DY,SAAS","sourcesContent":["import { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { OxFormField } from './ox-form-field'\n\n@customElement('ox-input-id')\nexport class OxInputId extends OxFormField {\n static styles = css`\n :host {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: flex-end;\n }\n\n input {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n }\n `\n\n @property({ type: Object }) property: { component?: string } | null | undefined\n\n @state() _ids: Array<string> = []\n\n render() {\n const ids = this._ids || []\n\n return html`\n <input\n id=\"text\"\n type=\"text\"\n .value=${this.value || ''}\n @focusin=${(e: FocusEvent) => this._onInputFocused(e)}\n @change=${(e: InputEvent) => this._onInputChanged(e)}\n .placeholder=${this.getAttribute('placeholder') || ''}\n list=\"ids\"\n />\n\n <datalist id=\"ids\">${ids.map(id => html` <option value=${id}></option> `)}</datalist>\n `\n }\n\n _onInputFocused(e: FocusEvent) {\n var { component } = this.property || {}\n\n document.dispatchEvent(\n new CustomEvent('get-all-scene-component-ids', {\n detail: {\n component,\n callback: (ids: string[]) => {\n this._ids = ids\n }\n }\n })\n )\n }\n\n _onInputChanged(e: InputEvent) {\n e.stopPropagation()\n\n this.value = (e.target as HTMLInputElement).value\n\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n }\n}\n"]}
@@ -1,292 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import { LitElement, html, css } from 'lit'
6
-
7
- import './things-editor-color'
8
-
9
- /**
10
- range value editor element
11
-
12
- Example:
13
-
14
- <things-editor-value-range range=${range}
15
- rangetype=${type}
16
- valuetype=${valuetype}>
17
- </things-editor-value-range>
18
- */
19
- export default class ThingsEditorValueRange extends LitElement {
20
- static get is() {
21
- return 'things-editor-value-range'
22
- }
23
-
24
- static get properties() {
25
- return {
26
- value: Object,
27
- valuetype: String
28
- }
29
- }
30
-
31
- static get styles() {
32
- return [
33
- css`
34
- :host {
35
- display: flex;
36
- flex-direction: column;
37
- align-content: center;
38
-
39
- width: 100%;
40
- overflow: hidden;
41
- border: 1px solid #ccc;
42
- }
43
-
44
- div {
45
- display: flex;
46
- flex-flow: row nowrap;
47
- align-items: center;
48
-
49
- border-bottom: 1px solid #c0c0c0;
50
- }
51
-
52
- div:last-child {
53
- border-bottom: none;
54
- }
55
-
56
- div > * {
57
- min-width: 0px;
58
- margin: 2px;
59
- padding: 0;
60
- }
61
-
62
- button {
63
- width: 20px;
64
- text-align: center;
65
- }
66
-
67
- input,
68
- things-editor-color {
69
- flex: 1;
70
- }
71
-
72
- things-editor-color {
73
- --things-editor-color-input-color: {
74
- margin: 2px;
75
- }
76
- --things-editor-color-input-span: {
77
- width: 12px;
78
- height: 12px;
79
- }
80
- }
81
-
82
- [placeholder='value'] {
83
- flex: 2;
84
- }
85
-
86
- div {
87
- border-bottom: 1px solid #c0c0c0;
88
- }
89
-
90
- div:last-child {
91
- border-bottom: none;
92
- }
93
-
94
- input[type='checkbox'] {
95
- width: initial;
96
- }
97
- `
98
- ]
99
- }
100
-
101
- constructor() {
102
- super()
103
-
104
- this.value = {}
105
- this.valuetype = 'string'
106
- this.rangetype = 'number'
107
- }
108
-
109
- firstUpdated() {
110
- this.renderRoot.addEventListener('change', this._onChange.bind(this))
111
- }
112
-
113
- render() {
114
- return html`
115
- ${this._toArray(this.value).map(
116
- item => html`
117
- <div data-record>
118
- <input type="text" data-from placeholder="<=" .value=${item.from} />
119
- <input type="text" data-to placeholder="&gt;" .value=${item.to} />
120
-
121
- ${this.valuetype == 'boolean'
122
- ? html` <input type="checkbox" data-value .checked=${item.value} data-value-type=${this.valuetype} /> `
123
- : this.valuetype == 'color'
124
- ? html` <things-editor-color data-value .value=${item.value}> </things-editor-color> `
125
- : html`
126
- <input
127
- type="text"
128
- data-value
129
- placeholder="value"
130
- .value=${item.value}
131
- data-value-type=${this.valuetype}
132
- />
133
- `} <button class="record-action" @click=${e => this._delete(e)} tabindex="-1">-</button>
134
- </div>
135
- `
136
- )}
137
-
138
- <div data-record-new>
139
- <input type="text" data-from placeholder="<=" value="" />
140
- <input type="text" data-to placeholder="&gt;" value="" />
141
-
142
- ${this.valuetype == 'boolean'
143
- ? html` <input type="checkbox" data-value data-value-type=${this.valuetype} /> `
144
- : this.valuetype == 'color'
145
- ? html` <things-editor-color data-value value="" placeholder="value"> </things-editor-color> `
146
- : html` <input type="text" data-value placeholder="value" value="" data-value-type=${this.valuetype} /> `}
147
- <button class="record-action" @click=${e => this._add(e)} tabindex="-1">+</button>
148
- </div>
149
-
150
- <div data-record>
151
- <input type="text" data-from data-default="" disabled value="default" />
152
- <input type="text" data-to placeholder="&gt;" value="" hidden />
153
-
154
- ${this.valuetype == 'boolean'
155
- ? html`
156
- <input
157
- type="checkbox"
158
- data-value
159
- .checked=${this.value && this.value.default}
160
- data-value-type=${this.valuetype}
161
- />
162
- `
163
- : this.valuetype == 'color'
164
- ? html`
165
- <things-editor-color data-value .value=${(this.value && this.value.default) || ''} placeholder="value">
166
- </things-editor-color>
167
- `
168
- : html`
169
- <input
170
- type="text"
171
- data-value
172
- .value=${(this.value && this.value.default) || ''}
173
- placeholder="value"
174
- class="default-value"
175
- data-value-type=${this.valuetype}
176
- />
177
- `} <button class="record-action" @click="${e => this._sort(e)}">&gt;</button>
178
- </div>
179
- `
180
- }
181
-
182
- _defaultValue(type) {
183
- switch (type || this.valuetype) {
184
- case 'color':
185
- return '#000000'
186
- case 'boolean':
187
- case 'checkbox':
188
- return false
189
- default:
190
- return ''
191
- }
192
- }
193
-
194
- _onChange(e) {
195
- if (this._changingNow) return
196
-
197
- this._changingNow = true
198
-
199
- var input = e.target
200
- var value
201
- if (input.type == 'checkbox') value = Boolean(input.checked)
202
- else value = input.value
203
- var div = input.parentElement
204
- if (input.hasAttribute('data-value')) {
205
- var dataList = div.querySelectorAll('[data-value]:not([hidden])')
206
- for (var i = 0; i < dataList.length; i++) if (dataList[i] !== input) dataList[i].value = value
207
- }
208
- if (div.hasAttribute('data-record')) this._build()
209
- else if (div.hasAttribute('data-record-new') && input.hasAttribute('data-value')) this._add()
210
-
211
- this._changingNow = false
212
- }
213
-
214
- _build(includeNewRecord) {
215
- if (includeNewRecord) var records = this.renderRoot.querySelectorAll('[data-record],[data-record-new]')
216
- else var records = this.renderRoot.querySelectorAll('[data-record]')
217
- var newrange = {}
218
- for (var i = 0; i < records.length; i++) {
219
- var record = records[i]
220
- var from = record.querySelector('[data-from]').value
221
- var to = record.querySelector('[data-to]').value
222
- var inputs = record.querySelectorAll('[data-value]:not([style*="display: none"])')
223
- if (!inputs || inputs.length == 0) continue
224
- var input = inputs[inputs.length - 1]
225
- var value
226
- if (input.type == 'checkbox') value = Boolean(input.checked)
227
- else value = input.value
228
- if (from) {
229
- if (from === 'default') newrange['default'] = value || (this.valuetype == 'color' ? '#000000' : '')
230
- else newrange[`${from}~${to}`] = value
231
- }
232
- }
233
-
234
- this.value = newrange
235
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
236
- }
237
-
238
- /* default를 제외한 range아이템들을 template(dom-repeat)용 배열로 변환하는 함수 */
239
- _toArray(range) {
240
- var array = []
241
- for (var key in range) {
242
- if (key == 'default') continue
243
- var fromto = key.split('~')
244
- array.push({
245
- from: fromto[0],
246
- to: fromto[1],
247
- value: range[key]
248
- })
249
- }
250
- return array
251
- }
252
-
253
- _sort(e) {
254
- var sorter =
255
- this.rangetype === 'number'
256
- ? function (a, b) {
257
- return parseFloat(b.from) < parseFloat(a.from)
258
- }
259
- : function (a, b) {
260
- return b.from < a.from
261
- }
262
- var range = this._toArray(this.value)
263
- .sort(sorter)
264
- .reduce(function (sum, i) {
265
- sum[`${i.from}~${i.to}`] = i.value
266
- return sum
267
- }, {})
268
- range.default = this.value.default
269
-
270
- this.value = range
271
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
272
- }
273
-
274
- _add(e) {
275
- this._build(true)
276
- var inputs = this.renderRoot.querySelectorAll('[data-record-new] input:not([style*="display: none"])')
277
- for (var i = 0; i < inputs.length; i++) {
278
- let input = inputs[i]
279
- if (input.type == 'checkbox') input.checked = false
280
- else input.value = this._defaultValue(input.type)
281
- }
282
- inputs[0].focus()
283
- }
284
-
285
- _delete(e) {
286
- var record = e.target.parentElement
287
- record.querySelector('[data-from]').value = ''
288
- this._build()
289
- }
290
- }
291
-
292
- customElements.define(ThingsEditorValueRange.is, ThingsEditorValueRange)