@operato/input 0.2.50 → 0.3.2

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 (59) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/src/index.d.ts +2 -1
  3. package/dist/src/index.js +2 -1
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/ox-buttons-radio.d.ts +1 -1
  6. package/dist/src/ox-buttons-radio.js +3 -5
  7. package/dist/src/ox-buttons-radio.js.map +1 -1
  8. package/dist/src/ox-checkbox.d.ts +1 -2
  9. package/dist/src/ox-checkbox.js +1 -4
  10. package/dist/src/ox-checkbox.js.map +1 -1
  11. package/dist/src/{ox-formfield.d.ts → ox-form-field.d.ts} +0 -0
  12. package/dist/src/{ox-formfield.js → ox-form-field.js} +2 -2
  13. package/dist/src/ox-form-field.js.map +1 -0
  14. package/dist/src/ox-input-3dish.d.ts +1 -1
  15. package/dist/src/ox-input-3dish.js +13 -14
  16. package/dist/src/ox-input-3dish.js.map +1 -1
  17. package/dist/src/ox-input-angle.d.ts +1 -1
  18. package/dist/src/ox-input-angle.js +1 -1
  19. package/dist/src/ox-input-angle.js.map +1 -1
  20. package/dist/src/ox-input-barcode.d.ts +3 -4
  21. package/dist/src/ox-input-barcode.js +3 -7
  22. package/dist/src/ox-input-barcode.js.map +1 -1
  23. package/dist/src/ox-input-code.d.ts +2 -2
  24. package/dist/src/ox-input-code.js +7 -8
  25. package/dist/src/ox-input-code.js.map +1 -1
  26. package/dist/src/ox-input-container.d.ts +10 -0
  27. package/dist/src/ox-input-container.js +35 -0
  28. package/dist/src/ox-input-container.js.map +1 -0
  29. package/dist/src/ox-input-data.d.ts +1 -5
  30. package/dist/src/ox-input-data.js +3 -7
  31. package/dist/src/ox-input-data.js.map +1 -1
  32. package/dist/src/ox-input-file.d.ts +19 -0
  33. package/dist/src/ox-input-file.js +186 -0
  34. package/dist/src/ox-input-file.js.map +1 -0
  35. package/dist/src/ox-input-stack.d.ts +1 -1
  36. package/dist/src/ox-input-stack.js +1 -1
  37. package/dist/src/ox-input-stack.js.map +1 -1
  38. package/dist/src/ox-select.d.ts +2 -2
  39. package/dist/src/ox-select.js +2 -2
  40. package/dist/src/ox-select.js.map +1 -1
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +18 -6
  43. package/src/index.ts +2 -1
  44. package/src/ox-buttons-radio.ts +1 -1
  45. package/src/ox-checkbox.ts +1 -2
  46. package/src/{ox-formfield.ts → ox-form-field.ts} +1 -1
  47. package/src/ox-input-3dish.ts +1 -1
  48. package/src/ox-input-angle.ts +1 -1
  49. package/src/ox-input-barcode.ts +5 -5
  50. package/src/ox-input-code.ts +7 -6
  51. package/src/ox-input-container.ts +35 -0
  52. package/src/ox-input-data.ts +3 -8
  53. package/src/ox-input-file.ts +185 -0
  54. package/src/ox-input-keyvalues.ts.ing +277 -0
  55. package/src/ox-input-ranges.ts.ing +292 -0
  56. package/src/ox-input-stack.ts +1 -1
  57. package/src/ox-select.ts +2 -2
  58. package/tsconfig.json +3 -1
  59. package/dist/src/ox-formfield.js.map +0 -1
@@ -0,0 +1,185 @@
1
+ import '@material/mwc-icon'
2
+
3
+ import { css, html } from 'lit'
4
+ import { customElement, property, query } from 'lit/decorators.js'
5
+
6
+ import { ScrollbarStyles } from '@operato/styles'
7
+ import { FileDropHelper } from '@operato/utils'
8
+
9
+ import { OxFormField } from './ox-form-field.js'
10
+
11
+ @customElement('ox-input-file')
12
+ export class OxInputFile extends OxFormField {
13
+ static styles = [
14
+ ScrollbarStyles,
15
+ css`
16
+ :host {
17
+ display: flex;
18
+ flex-direction: column;
19
+ border-radius: var(--border-radius);
20
+ align-items: center;
21
+ justify-content: center;
22
+ padding: var(--padding-default, 9px);
23
+ min-height: 100px;
24
+ text-transform: capitalize;
25
+
26
+ border: var(--file-uploader-border);
27
+ background-color: var(--main-section-background-color);
28
+ font: var(--file-uploader-font) !important;
29
+ color: var(--file-uploader-color);
30
+ }
31
+ :host > mwc-icon {
32
+ color: var(--file-uploader-icon-color);
33
+ --mdc-icon-size: var(--file-uploader-icon-size, 36px);
34
+ }
35
+
36
+ :host(.candrop) {
37
+ background-color: var(--file-uploader-candrop-background-color);
38
+ }
39
+
40
+ #input-file {
41
+ display: none;
42
+ }
43
+
44
+ label {
45
+ position: relative;
46
+ width: auto;
47
+ border: none;
48
+ text-transform: capitalize;
49
+
50
+ padding: var(--file-uploader-label-padding);
51
+ border-radius: var(--file-uploader-label-border-radius);
52
+ background-color: var(--file-uploader-label-background-color);
53
+ color: var(--file-uploader-label-color);
54
+ font: var(--file-uploader-label-font) !important;
55
+ }
56
+
57
+ ul {
58
+ max-width: 500px;
59
+ width: 100%;
60
+ list-style: none;
61
+ margin: 5px 0 0 0;
62
+ padding: 0;
63
+ max-height: 46px;
64
+ overflow: auto;
65
+ background-color: rgba(var(--primary-color-rgb), 0.1);
66
+ }
67
+ li {
68
+ text-align: left;
69
+
70
+ padding: 3px 5px 2px 5px;
71
+ border-bottom: var(--file-uploader-li-border-bottom);
72
+ font: normal 14px var(--theme-font);
73
+ }
74
+ li mwc-icon {
75
+ float: right;
76
+ cursor: pointer;
77
+ margin: var(--file-uploader-li-icon-margin);
78
+ font-size: 1em;
79
+ }
80
+ li mwc-icon:hover,
81
+ li mwc-icon:active {
82
+ color: var(--file-uploader-li-icon-focus-color);
83
+ }
84
+ `
85
+ ]
86
+
87
+ @property({ type: Boolean }) multiple?: boolean
88
+ @property({ type: String }) accept?: string
89
+ @property({ type: String }) icon?: string
90
+ @property({ type: String }) label?: string
91
+ @property({ type: String }) description?: string
92
+ @property({ type: Boolean, reflect: true, attribute: 'hide-filelist' })
93
+ hideFileList: boolean = false
94
+ @property({ type: Boolean, reflect: true, attribute: 'attach-filelist' })
95
+ attachFileList: boolean = false
96
+
97
+ @query('#input-file') fileInput!: HTMLInputElement
98
+
99
+ render() {
100
+ var files: File[] = this.value || []
101
+
102
+ return html`
103
+ <mwc-icon>upload</mwc-icon>
104
+
105
+ <span>drop files here!</span>
106
+
107
+ <input
108
+ id="input-file"
109
+ type="file"
110
+ accept=${this.accept}
111
+ ?multiple=${this.multiple}
112
+ hidden
113
+ capture="environment"
114
+ @change=${(e: Event) => this._onChangeValue(e)}
115
+ />
116
+
117
+ <label for="input-file">${this.label || 'select files'}</label>
118
+
119
+ ${!this.hideFileList && files?.length
120
+ ? html` <ul>
121
+ ${files.map(
122
+ file => html`
123
+ <li>
124
+ - ${file.name}
125
+ <mwc-icon
126
+ @click=${(e: Event) => {
127
+ files.splice(files.indexOf(file), 1)
128
+ this.value = [...files]
129
+ this._notifyChange()
130
+ }}
131
+ >delete_outline</mwc-icon
132
+ >
133
+ </li>
134
+ `
135
+ )}
136
+ </ul>`
137
+ : html``}
138
+ `
139
+ }
140
+
141
+ firstUpdated() {
142
+ FileDropHelper.set(this)
143
+
144
+ this.addEventListener('file-drop', (e: Event) => {
145
+ const detail = (e as CustomEvent).detail
146
+ this.value = this.multiple ? detail : detail[0] ? [detail[0]] : []
147
+
148
+ this._notifyChange()
149
+ })
150
+ }
151
+
152
+ get files() {
153
+ return this.value
154
+ }
155
+
156
+ reset() {
157
+ this.fileInput.value = ''
158
+ this.value = []
159
+
160
+ this._notifyChange()
161
+ }
162
+
163
+ _onChangeValue(e: Event) {
164
+ const fileInput = e.currentTarget as HTMLInputElement
165
+ const files = this.value || []
166
+
167
+ this.value = this.attachFileList
168
+ ? [...files, ...Array.from(fileInput.files as FileList)]
169
+ : [...Array.from(fileInput.files as FileList)]
170
+
171
+ fileInput.files = null
172
+
173
+ this._notifyChange()
174
+ }
175
+
176
+ _notifyChange() {
177
+ this.dispatchEvent(
178
+ new CustomEvent('change', {
179
+ bubbles: true,
180
+ composed: true,
181
+ detail: this.value
182
+ })
183
+ )
184
+ }
185
+ }
@@ -0,0 +1,277 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import './things-editor-color'
6
+
7
+ import { LitElement, css, html } from 'lit'
8
+ import { customElement, property } from 'lit/decorators.js'
9
+
10
+ /**
11
+ key-value map editor element
12
+
13
+ Example:
14
+
15
+ <ox-input-value-map
16
+ value=${map}
17
+ keytype=${keytype}
18
+ valuetype=${valuetype}>
19
+ </ox-input-value-map>
20
+ */
21
+ @customElement('ox-input-keyvalues')
22
+ export default class OxInputValueMap extends LitElement {
23
+ static styles = [
24
+ css`
25
+ :host {
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-content: center;
29
+
30
+ width: 100%;
31
+ overflow: hidden;
32
+ border: 1px solid #ccc;
33
+ }
34
+
35
+ div {
36
+ display: flex;
37
+ flex-flow: row nowrap;
38
+ align-items: center;
39
+
40
+ border-bottom: 1px solid #c0c0c0;
41
+ }
42
+
43
+ div:last-child {
44
+ border-bottom: none;
45
+ }
46
+
47
+ div > * {
48
+ min-width: 0px;
49
+ margin: 2px;
50
+ padding: 0;
51
+ }
52
+
53
+ button {
54
+ width: 20px;
55
+ text-align: center;
56
+ }
57
+
58
+ input,
59
+ things-editor-color {
60
+ flex: 1;
61
+ }
62
+
63
+ things-editor-color {
64
+ --things-editor-color-input-color: {
65
+ margin: 1px;
66
+ }
67
+ --things-editor-color-input-span: {
68
+ width: 10px;
69
+ height: 10px;
70
+ }
71
+ }
72
+
73
+ input[type='checkbox'] {
74
+ width: initial;
75
+ }
76
+ `
77
+ ]
78
+
79
+ @property({ type: Object }) value: any = {}
80
+ @property({ type: Object }) valuetype: string = 'string'
81
+ @property({ type: Object }) keytype: string = 'string'
82
+
83
+ firstUpdated() {
84
+ this.renderRoot.addEventListener('change', this._onChange.bind(this))
85
+ }
86
+
87
+ render() {
88
+ return html`
89
+ ${this._toArray(this.value).map(
90
+ item => html`
91
+ <div data-record>
92
+ <input type="text" data-key placeholder="key" .value=${item.key} /> ${this.valuetype == 'boolean'
93
+ ? html` <input type="checkbox" data-value .checked=${item.value} data-value-type=${this.valuetype} /> `
94
+ : this.valuetype == 'color'
95
+ ? html` <things-editor-color data-value .value=${item.value} tabindex="-1"> </things-editor-color> `
96
+ : html`
97
+ <input
98
+ type="text"
99
+ data-value
100
+ placeholder="value"
101
+ .value=${item.value}
102
+ data-value-type=${this.valuetype}
103
+ />
104
+ `} <button class="record-action" @click=${(e: MouseEvent) => this._delete(e)} tabindex="-1">-</button>
105
+ </div>
106
+ `
107
+ )}
108
+
109
+ <div data-record-new>
110
+ <input type="text" data-key placeholder="key" value="" /> ${this.valuetype == 'boolean'
111
+ ? html` <input type="checkbox" data-value data-value-type=${this.valuetype} /> `
112
+ : this.valuetype == 'color'
113
+ ? html` <things-editor-color data-value value="" tabindex="-1" placeholder="value"> </things-editor-color> `
114
+ : html` <input type="text" data-value placeholder="value" value="" data-value-type=${this.valuetype} /> `}
115
+ <button class="record-action" @click=${(e: MouseEvent) => this._add(e)} tabindex="-1">+</button>
116
+ </div>
117
+
118
+ <div data-record>
119
+ <input type="text" data-key data-default="" value="default" disabled /> ${this.valuetype == 'boolean'
120
+ ? html`
121
+ <input
122
+ type="checkbox"
123
+ data-value
124
+ .checked=${this.value && this.value.default}
125
+ data-value-type=${this.valuetype}
126
+ />
127
+ `
128
+ : this.valuetype == 'color'
129
+ ? html`
130
+ <things-editor-color
131
+ data-value
132
+ .value=${(this.value && this.value.default) || ''}
133
+ placeholder="value"
134
+ tabindex="-1"
135
+ >
136
+ </things-editor-color>
137
+ `
138
+ : html`
139
+ <input
140
+ type="text"
141
+ data-value
142
+ placeholder="value"
143
+ .value=${(this.value && this.value.default) || ''}
144
+ data-value-type=${this.valuetype}
145
+ />
146
+ `} <button class="record-action" @click=${e => this._sort(e)} tabindex="-1">&gt;</button>
147
+ </div>
148
+ `
149
+ }
150
+
151
+ _defaultValue(type) {
152
+ switch (type || this.valuetype) {
153
+ case 'color':
154
+ return '#000000'
155
+ case 'boolean':
156
+ case 'checkbox':
157
+ return false
158
+ default:
159
+ return ''
160
+ }
161
+ }
162
+
163
+ _onChange(e) {
164
+ if (this._changingNow) {
165
+ return
166
+ }
167
+
168
+ this._changingNow = true
169
+
170
+ var input = e.target
171
+ var value
172
+
173
+ if (input.type == 'checkbox') value = Boolean(input.checked)
174
+ else value = input.value
175
+
176
+ var div = input.parentElement
177
+
178
+ if (div.hasAttribute('data-record')) {
179
+ var dataList = div.querySelectorAll('[data-value]:not([hidden])')
180
+ for (var i = 0; i < dataList.length; i++)
181
+ if (dataList[i] !== input) dataList[i].value = value || this._defaultValue()
182
+ }
183
+
184
+ if (div.hasAttribute('data-record')) this._build()
185
+ else if (div.hasAttribute('data-record-new') && input.hasAttribute('data-value')) this._add()
186
+
187
+ this._changingNow = false
188
+ }
189
+
190
+ _build(includeNewRecord?: boolean) {
191
+ if (includeNewRecord) var records = this.renderRoot.querySelectorAll('[data-record],[data-record-new]')
192
+ else var records = this.renderRoot.querySelectorAll('[data-record]')
193
+
194
+ var newmap = {}
195
+
196
+ for (var i = 0; i < records.length; i++) {
197
+ var record = records[i]
198
+
199
+ var key = record.querySelector('[data-key]').value
200
+ var inputs = record.querySelectorAll('[data-value]:not([style*="display: none"])')
201
+ if (!inputs || inputs.length == 0) continue
202
+
203
+ var input = inputs[inputs.length - 1]
204
+
205
+ var value
206
+
207
+ if (input.type == 'checkbox') value = Boolean(input.checked)
208
+ else value = input.value
209
+
210
+ if (key) newmap[key] = value || this._defaultValue()
211
+ }
212
+
213
+ this.value = newmap
214
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
215
+ }
216
+
217
+ /* default를 제외한 map아이템들을 template(dom-repeat)용 배열로 변환하는 함수 */
218
+ _toArray(map) {
219
+ var array = []
220
+
221
+ for (var key in map) {
222
+ if (key == 'default') continue
223
+ array.push({
224
+ key: key,
225
+ value: map[key]
226
+ })
227
+ }
228
+
229
+ return array
230
+ }
231
+
232
+ _sort(e) {
233
+ var sorter =
234
+ this.keytype === 'number'
235
+ ? function (a, b) {
236
+ return parseFloat(b.key) < parseFloat(a.key)
237
+ }
238
+ : function (a, b) {
239
+ return b.key < a.key
240
+ }
241
+
242
+ var map = this._toArray(this.value)
243
+ .sort(sorter)
244
+ .reduce(function (sum, i) {
245
+ sum[i.key] = i.value
246
+ return sum
247
+ }, {})
248
+
249
+ map.default = this.value.default
250
+
251
+ this.value = map
252
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
253
+ }
254
+
255
+ _add(e: MouseEvent) {
256
+ this._build(true)
257
+
258
+ var inputs = this.renderRoot.querySelectorAll('[data-record-new] input:not([style*="display: none"])')
259
+
260
+ for (var i = 0; i < inputs.length; i++) {
261
+ let input = inputs[i]
262
+
263
+ if (input.type == 'checkbox') input.checked = false
264
+ else input.value = this._defaultValue(input.type)
265
+ }
266
+
267
+ inputs[0].focus()
268
+ }
269
+
270
+ _delete(e: MouseEvent) {
271
+ var record = (e.target as HTMLElement).parentElement
272
+
273
+ ;(record!.querySelector('[data-key]') as HTMLInputElement)!.value = ''
274
+
275
+ this._build()
276
+ }
277
+ }