@operato/input 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 (111) hide show
  1. package/CHANGELOG.md +235 -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 +36 -0
  11. package/demo/index-file.html +41 -0
  12. package/demo/index-image.html +1 -1
  13. package/demo/index-multiple-colors.html +37 -0
  14. package/demo/index-options.html +43 -0
  15. package/demo/index-partition-keys.html +71 -0
  16. package/demo/index-range.html +40 -0
  17. package/demo/index-table.html +39 -0
  18. package/demo/index-value-map.html +80 -0
  19. package/demo/index-value-ranges.html +80 -0
  20. package/demo/index.html +23 -54
  21. package/dist/src/index.d.ts +21 -11
  22. package/dist/src/index.js +21 -11
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/ox-checkbox.js +1 -1
  25. package/dist/src/ox-checkbox.js.map +1 -1
  26. package/dist/src/ox-input-code.d.ts +4 -4
  27. package/dist/src/ox-input-code.js +8 -8
  28. package/dist/src/ox-input-code.js.map +1 -1
  29. package/dist/src/ox-input-color-gradient.d.ts +26 -0
  30. package/dist/src/ox-input-color-gradient.js +318 -0
  31. package/dist/src/ox-input-color-gradient.js.map +1 -0
  32. package/dist/src/ox-input-color-stops.d.ts +71 -0
  33. package/dist/src/ox-input-color-stops.js +445 -0
  34. package/dist/src/ox-input-color-stops.js.map +1 -0
  35. package/dist/src/ox-input-color.d.ts +176 -0
  36. package/dist/src/ox-input-color.js +298 -0
  37. package/dist/src/ox-input-color.js.map +1 -0
  38. package/dist/src/ox-input-crontab.d.ts +23 -0
  39. package/dist/src/ox-input-crontab.js +560 -0
  40. package/dist/src/ox-input-crontab.js.map +1 -0
  41. package/dist/src/ox-input-data.d.ts +2 -2
  42. package/dist/src/ox-input-data.js +2 -2
  43. package/dist/src/ox-input-data.js.map +1 -1
  44. package/dist/src/ox-input-file.d.ts +2 -0
  45. package/dist/src/ox-input-file.js +6 -1
  46. package/dist/src/ox-input-file.js.map +1 -1
  47. package/dist/src/ox-input-layout/ox-input-card-layout.d.ts +4 -0
  48. package/dist/src/ox-input-layout/ox-input-card-layout.js +57 -0
  49. package/dist/src/ox-input-layout/ox-input-card-layout.js.map +1 -0
  50. package/dist/src/ox-input-layout/ox-input-grid-layout.d.ts +4 -0
  51. package/dist/src/ox-input-layout/ox-input-grid-layout.js +63 -0
  52. package/dist/src/ox-input-layout/ox-input-grid-layout.js.map +1 -0
  53. package/dist/src/ox-input-layout/ox-input-layout.d.ts +5 -0
  54. package/dist/src/ox-input-layout/ox-input-layout.js +73 -0
  55. package/dist/src/ox-input-layout/ox-input-layout.js.map +1 -0
  56. package/dist/src/ox-input-multiple-colors.d.ts +28 -0
  57. package/dist/src/ox-input-multiple-colors.js +113 -0
  58. package/dist/src/ox-input-multiple-colors.js.map +1 -0
  59. package/dist/src/ox-input-options.d.ts +22 -0
  60. package/dist/src/ox-input-options.js +137 -0
  61. package/dist/src/ox-input-options.js.map +1 -0
  62. package/dist/src/ox-input-partition-keys.d.ts +36 -0
  63. package/dist/src/ox-input-partition-keys.js +202 -0
  64. package/dist/src/ox-input-partition-keys.js.map +1 -0
  65. package/dist/src/ox-input-range.d.ts +4 -0
  66. package/dist/src/ox-input-range.js +161 -0
  67. package/dist/src/ox-input-range.js.map +1 -0
  68. package/dist/src/{ox-input-id.d.ts → ox-input-scene-component-id.d.ts} +0 -0
  69. package/dist/src/{ox-input-id.js → ox-input-scene-component-id.js} +2 -2
  70. package/dist/src/ox-input-scene-component-id.js.map +1 -0
  71. package/dist/src/ox-input-stack.d.ts +1 -1
  72. package/dist/src/ox-input-stack.js +1 -1
  73. package/dist/src/ox-input-stack.js.map +1 -1
  74. package/dist/src/ox-input-table.d.ts +8 -0
  75. package/dist/src/ox-input-table.js +379 -0
  76. package/dist/src/ox-input-table.js.map +1 -0
  77. package/dist/src/ox-input-value-map.d.ts +41 -0
  78. package/dist/src/ox-input-value-map.js +279 -0
  79. package/dist/src/ox-input-value-map.js.map +1 -0
  80. package/dist/src/ox-input-value-ranges.d.ts +41 -0
  81. package/dist/src/ox-input-value-ranges.js +298 -0
  82. package/dist/src/ox-input-value-ranges.js.map +1 -0
  83. package/dist/tsconfig.tsbuildinfo +1 -1
  84. package/package.json +25 -7
  85. package/src/index.ts +21 -11
  86. package/src/ox-checkbox.ts +1 -1
  87. package/src/ox-input-code.ts +9 -10
  88. package/src/ox-input-color-gradient.ts +343 -0
  89. package/src/ox-input-color-stops.ts +499 -0
  90. package/src/ox-input-color.ts +323 -0
  91. package/src/ox-input-crontab.ts +560 -0
  92. package/src/ox-input-data.ts +5 -5
  93. package/src/ox-input-file.ts +8 -3
  94. package/src/ox-input-layout/ox-input-card-layout.ts +58 -0
  95. package/src/ox-input-layout/ox-input-grid-layout.ts +64 -0
  96. package/src/ox-input-layout/ox-input-layout.ts +77 -0
  97. package/src/ox-input-multiple-colors.ts +113 -0
  98. package/src/ox-input-options.ts +165 -0
  99. package/src/ox-input-partition-keys.ts +240 -0
  100. package/src/ox-input-range.ts +147 -0
  101. package/src/{ox-input-id.ts → ox-input-scene-component-id.ts} +1 -1
  102. package/src/ox-input-stack.ts +1 -1
  103. package/src/ox-input-table.ts +404 -0
  104. package/src/{ox-input-keyvalues.ts.ing → ox-input-value-map.ts} +125 -94
  105. package/src/ox-input-value-ranges.ts +325 -0
  106. package/translations/en.json +1 -0
  107. package/translations/ko.json +1 -0
  108. package/translations/ms.json +1 -0
  109. package/translations/zh.json +1 -0
  110. package/dist/src/ox-input-id.js.map +0 -1
  111. package/src/ox-input-ranges.ts.ing +0 -292
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import { LitElement, PropertyValues, css, html } from 'lit'
6
+ import { customElement, property, state } from 'lit/decorators.js'
7
+
8
+ @customElement('ox-input-grid-layout')
9
+ class OxInputGridLayout extends LitElement {
10
+ static styles = css`
11
+ :host {
12
+ display: inline-block;
13
+ }
14
+ `
15
+
16
+ @property({ type: Object }) value: any
17
+ @property({ type: String }) direction: 'row' | 'column' = 'row'
18
+
19
+ firstUpdated() {
20
+ this.renderRoot.addEventListener('change', this._onValueChange.bind(this))
21
+ }
22
+
23
+ updated(changes: PropertyValues<this>) {
24
+ if (changes.has('value')) {
25
+ let { direction = 'row' } = this.value || {}
26
+
27
+ this.direction = direction
28
+ }
29
+
30
+ if (changes.has('value')) {
31
+ }
32
+ }
33
+
34
+ render() {
35
+ return html`
36
+ <label>direction</label>
37
+ <select value-key="direction" .value=${this.direction}>
38
+ <option value="row" selected>row</option>
39
+ <option value="column">column</option>
40
+ </select>
41
+ `
42
+ }
43
+
44
+ _onValueChange(e: Event) {
45
+ var element = e.target as HTMLSelectElement
46
+ var key = element.getAttribute('value-key')
47
+
48
+ if (!key) {
49
+ return
50
+ }
51
+
52
+ switch (key) {
53
+ case 'direction':
54
+ this.direction = element.value as 'row' | 'column'
55
+ default:
56
+ }
57
+
58
+ this.value = {
59
+ direction: this.direction
60
+ }
61
+
62
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
63
+ }
64
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import './things-grid-layout'
6
+ import './things-card-layout'
7
+
8
+ import { LitElement, PropertyValues, html } from 'lit'
9
+ import { customElement, property, state } from 'lit/decorators.js'
10
+
11
+ // import './things-linear-horizontal-layout'
12
+ // import './things-linear-vertical-layout'
13
+
14
+ const layouts = ['absolute', 'card', 'grid', 'linear-horizontal', 'linear-vertical', 'table']
15
+
16
+ @customElement('ox-input-layout')
17
+ class OxInputLayout extends LitElement {
18
+ @property({ type: Object }) value: any = {}
19
+ @property({ type: String }) layout:
20
+ | ''
21
+ | 'absolute'
22
+ | 'card'
23
+ | 'grid'
24
+ | 'linear-horizontal'
25
+ | 'linear-vertical'
26
+ | 'table' = ''
27
+ @property({ type: Object }) options: any = {}
28
+
29
+ firstUpdated() {
30
+ this.renderRoot.addEventListener('change', this._onValueChange.bind(this))
31
+ }
32
+
33
+ updated(changes: PropertyValues<this>) {
34
+ if (changes.has('value')) {
35
+ this.layout = this.value.layout
36
+ this.options = this.value.options
37
+ }
38
+ }
39
+
40
+ render() {
41
+ return html`
42
+ <div>
43
+ <select value-key="layout" .value=${this.layout}>
44
+ <option value="" selected></option>
45
+ ${layouts.map(layout => {
46
+ return html` <option value=${layout}>${layout}</option> `
47
+ })}
48
+ </select>
49
+
50
+ ${this.layout == 'grid'
51
+ ? html` <things-grid-layout value-key="options" .value=${this.options}></things-grid-layout> `
52
+ : this.layout == 'card'
53
+ ? html` <things-card-layout value-key="options" .value=${this.options}></things-card-layout> `
54
+ : html``}
55
+ </div>
56
+ `
57
+ }
58
+
59
+ _onValueChange(e: Event) {
60
+ var element = e.target as HTMLElement
61
+ var key = element.getAttribute('value-key')
62
+
63
+ if (!key) {
64
+ return
65
+ }
66
+
67
+ //@ts-ignore
68
+ this[key] = element.value
69
+
70
+ this.value = {
71
+ layout: this.layout,
72
+ options: this.options
73
+ }
74
+
75
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
76
+ }
77
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import './ox-input-color.js'
6
+
7
+ import { css, html } from 'lit'
8
+ import { customElement, property, query, queryAll } from 'lit/decorators.js'
9
+
10
+ import { OxFormField } from './ox-form-field.js'
11
+ import { OxInputColor } from './ox-input-color.js'
12
+
13
+ /**
14
+ 색상 배열을 편집하는 컴포넌트이다.
15
+
16
+ 새로운 색상을 추가하고자 할 때는 `+` 버튼을 클릭한다.<br />
17
+ 색상을 제거하고자 할 때는 `-` 버튼을 클릭한다.<br />
18
+
19
+ Example:
20
+
21
+ <ox-input-multiple-colors values=${values}>
22
+ </ox-input-multiple-colors>
23
+ */
24
+
25
+ @customElement('ox-input-multiple-colors')
26
+ export class OxInputMultipleColors extends OxFormField {
27
+ static styles = css`
28
+ :host {
29
+ display: inline-block;
30
+ }
31
+
32
+ #colors-container > div {
33
+ display: grid;
34
+ grid-template-columns: 22px 1fr 22px;
35
+ grid-gap: 5px;
36
+ align-items: center;
37
+ justify-content: left;
38
+ }
39
+
40
+ ox-input-color {
41
+ height: 25px;
42
+ width: 100%;
43
+ }
44
+
45
+ input[type='button'] {
46
+ width: 22px;
47
+ height: 25px;
48
+ border: 1px solid rgba(0, 0, 0, 0.15);
49
+ padding-top: 0px;
50
+ padding-bottom: 2px;
51
+ background-color: #f1f2f4;
52
+ color: #8f9192;
53
+ font-size: 16px;
54
+ }
55
+ `
56
+
57
+ @property({ type: Array }) value: string[] = []
58
+
59
+ @query('#colors-container') colorsContainer!: HTMLDivElement
60
+ @queryAll('ox-input-color') colors!: NodeListOf<OxInputColor>
61
+
62
+ firstUpdated() {
63
+ this.renderRoot.addEventListener('change', this._onValueChanged.bind(this))
64
+ }
65
+
66
+ render() {
67
+ return html`
68
+ <div id="colors-container">
69
+ ${(this.value || []).map(
70
+ (item, index) => html`
71
+ <div>
72
+ <input type="button" value="+" @click=${() => this._appendEditorColor()} data-index=${index} />
73
+
74
+ <ox-input-color .value=${item}> </ox-input-color>
75
+
76
+ ${(this.value || []).length > 1
77
+ ? html`
78
+ <input
79
+ type="button"
80
+ value="-"
81
+ @click=${(e: Event) => this._removeEditorColor(e)}
82
+ data-index=${index}
83
+ />
84
+ `
85
+ : html``}
86
+ </div>
87
+ `
88
+ )}
89
+ </div>
90
+ `
91
+ }
92
+
93
+ _onValueChanged() {
94
+ this.value = Array.from(this.colors).map(color => color.value!)
95
+ }
96
+
97
+ _appendEditorColor() {
98
+ this.value = [...this.value, 'black']
99
+
100
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
101
+ }
102
+
103
+ _removeEditorColor(e: Event) {
104
+ var values = []
105
+ for (var i = 0; i < this.value.length; i++) {
106
+ if (i == Number((e.target as HTMLElement).dataset.index)) continue
107
+ else values.push(this.value[i])
108
+ }
109
+
110
+ this.value = values
111
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
112
+ }
113
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import { css, html } from 'lit'
6
+ import { customElement, property } from 'lit/decorators.js'
7
+
8
+ import { OxFormField } from './ox-form-field'
9
+
10
+ type Option = { text: string; value: string }
11
+
12
+ @customElement('ox-input-options')
13
+ export class OxInputOptions extends OxFormField {
14
+ static styles = css`
15
+ div {
16
+ display: grid;
17
+ grid-template-columns: repeat(10, 1fr);
18
+ grid-gap: 5px;
19
+ grid-auto-rows: minmax(24px, auto);
20
+ }
21
+
22
+ input[data-text] {
23
+ grid-column: span 5;
24
+ }
25
+
26
+ input[data-value] {
27
+ grid-column: span 4;
28
+ }
29
+
30
+ button {
31
+ grid-column: span 1;
32
+ }
33
+ `
34
+
35
+ @property({ type: Array }) value: Option[] = []
36
+
37
+ firstUpdated() {
38
+ this.renderRoot.addEventListener('change', this._onChange.bind(this))
39
+ }
40
+
41
+ render() {
42
+ const options = this.value instanceof Array ? this.value : []
43
+
44
+ return html`
45
+ ${(options || []).map(
46
+ item => html`
47
+ <div data-record="">
48
+ <input type="text" data-text="" placeholder="text" .value=${item.text} />
49
+ <input type="text" data-value="" placeholder="value" .value=${item.value} />
50
+ <button class="record-action" @click=${(e: MouseEvent) => this._delete(e)} tabindex="-1">-</button>
51
+ </div>
52
+ `
53
+ )}
54
+
55
+ <div data-record-new="">
56
+ <input type="text" data-text="" placeholder="text" value="" />
57
+ <input type="text" data-value="" placeholder="value" value="" @change=${(e: Event) => this._add()} />
58
+ <button class="record-action" @click=${(e: MouseEvent) => this._add()} tabindex="-1">+</button>
59
+ </div>
60
+ `
61
+ }
62
+
63
+ private _changingNow: boolean = false
64
+
65
+ _onChange(e: Event) {
66
+ if (this._changingNow) return
67
+
68
+ this._changingNow = true
69
+
70
+ var input = e.target as HTMLInputElement
71
+ var value = input.value
72
+
73
+ var div = input.parentElement
74
+
75
+ if (div && div.hasAttribute('data-record')) {
76
+ var dataList = div.querySelectorAll('[data-value]:not([hidden])') as NodeListOf<HTMLInputElement>
77
+
78
+ for (var i = 0; i < dataList.length; i++) {
79
+ if (dataList[i] !== input) {
80
+ dataList[i].value = value || ''
81
+ }
82
+ }
83
+ }
84
+
85
+ if (div && div.hasAttribute('data-record')) this._build(true)
86
+ else if (div && div.hasAttribute('data-record-new') && input.hasAttribute('data-value')) this._add()
87
+
88
+ e.stopPropagation()
89
+
90
+ this._changingNow = false
91
+ }
92
+
93
+ _build(includeNewRecord?: any) {
94
+ if (includeNewRecord) {
95
+ var records = this.renderRoot.querySelectorAll('[data-record],[data-record-new]') as NodeListOf<HTMLElement>
96
+ } else {
97
+ var records = this.renderRoot.querySelectorAll('[data-record]') as NodeListOf<HTMLElement>
98
+ }
99
+
100
+ var newoptions: Option[] = []
101
+
102
+ for (var i = 0; i < records.length; i++) {
103
+ var record = records[i]
104
+
105
+ var text = (record.querySelector('[data-text]') as HTMLInputElement).value
106
+ var inputs = record.querySelectorAll('[data-value]:not([style*="display: none"])') as NodeListOf<HTMLInputElement>
107
+ if (!inputs || inputs.length == 0) continue
108
+
109
+ var input = inputs[inputs.length - 1]
110
+ var value = input.value
111
+
112
+ if (text) newoptions.push({ text: text, value: value || text })
113
+ }
114
+
115
+ this.value = newoptions
116
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
117
+ }
118
+
119
+ sort() {
120
+ var sorter = function (a: Option, b: Option) {
121
+ return b.text < a.text ? 1 : -1
122
+ }
123
+
124
+ this.value = [...this.value.sort(sorter)]
125
+
126
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
127
+ }
128
+
129
+ _add() {
130
+ this._build(true)
131
+
132
+ var inputs = this.renderRoot.querySelectorAll(
133
+ '[data-record-new] input:not([style*="display: none"])'
134
+ ) as NodeListOf<HTMLInputElement>
135
+
136
+ for (var i = 0; i < inputs.length; i++) {
137
+ let input = inputs[i]
138
+ input.value = ''
139
+ }
140
+
141
+ inputs[0].focus()
142
+ }
143
+
144
+ _delete(e: Event) {
145
+ const record = (e.target as HTMLElement).parentElement
146
+ const input = record && (record.querySelector('[data-text]') as HTMLInputElement)
147
+
148
+ if (input) {
149
+ input.value = ''
150
+ }
151
+
152
+ this._build()
153
+ }
154
+
155
+ protected appendFormData({ formData }: FormDataEvent): void {
156
+ if (!this.name) return
157
+
158
+ const value = this.value
159
+
160
+ formData.append(
161
+ this.name!,
162
+ typeof value === 'string' ? value : value === undefined || value === null ? '' : JSON.stringify(value)
163
+ )
164
+ }
165
+ }
@@ -0,0 +1,240 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import { css, html } from 'lit'
6
+ import { customElement, property, queryAll } from 'lit/decorators.js'
7
+
8
+ import { OxFormField } from './ox-form-field'
9
+
10
+ type PartitionKeys = { [key: string]: any }
11
+ type ArrayedPartitionKeys = { key: string; value: any }
12
+
13
+ /**
14
+ key-value map for partitions editor element
15
+
16
+ Example:
17
+
18
+ <ox-input-partition-keys
19
+ value=${map}
20
+ </ox-input-partition-keys>
21
+ */
22
+ @customElement('ox-input-partition-keys')
23
+ export class OxInputPartitionKeys extends OxFormField {
24
+ static styles = 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
+ flex: 1;
60
+ }
61
+ `
62
+
63
+ @property({ type: Object }) value: PartitionKeys = {}
64
+
65
+ private _changingNow: boolean = false
66
+
67
+ firstUpdated() {
68
+ this.renderRoot.addEventListener('change', this._onChange.bind(this))
69
+ }
70
+
71
+ render() {
72
+ return html`
73
+ ${this._toArray(this.value).map(
74
+ item => html`
75
+ <div data-record>
76
+ <input type="text" data-key placeholder="key" .value=${item.key} />
77
+ <input type="text" data-value placeholder="value" .value=${item.value} list="value-template" />
78
+ <button class="record-action" @click=${(e: MouseEvent) => this._delete(e)} tabindex="-1">-</button>
79
+ <button class="record-action" @click=${(e: MouseEvent) => this._up(e)} tabindex="-1">↑</button>
80
+ <button class="record-action" @click=${(e: MouseEvent) => this._down(e)} tabindex="-1">↓</button>
81
+ </div>
82
+ `
83
+ )}
84
+
85
+ <div data-record-new>
86
+ <input type="text" data-key placeholder="key" value="" />
87
+ <input type="text" data-value placeholder="value" value="" list="value-template" />
88
+ <button class="record-action" @click=${(e: MouseEvent) => this._add()} tabindex="-1">+</button>
89
+ </div>
90
+
91
+ <datalist id="value-template">
92
+ <option value="%%YY">year</option>
93
+ <option value="%%MM">month</option>
94
+ <option value="%%DD">day</option>
95
+ </datalist>
96
+ `
97
+ }
98
+
99
+ _onChange(e: Event) {
100
+ if (this._changingNow) {
101
+ return
102
+ }
103
+
104
+ this._changingNow = true
105
+
106
+ const input = e.target as HTMLInputElement
107
+ var value = input.value
108
+
109
+ const record = (e.target as Element).closest('[data-record],[data-record-new]') as HTMLElement
110
+
111
+ if (record.hasAttribute('data-record')) {
112
+ this._build()
113
+ } else if (record.hasAttribute('data-record-new') && input.hasAttribute('data-value')) {
114
+ this._add()
115
+ }
116
+
117
+ this._changingNow = false
118
+ }
119
+
120
+ _build(includeNewRecord?: boolean) {
121
+ if (includeNewRecord) {
122
+ var records = this.renderRoot.querySelectorAll('[data-record],[data-record-new]') as NodeListOf<HTMLElement>
123
+ } else {
124
+ var records = this.renderRoot.querySelectorAll('[data-record]') as NodeListOf<HTMLElement>
125
+ }
126
+
127
+ var newmap: PartitionKeys = {}
128
+
129
+ for (var i = 0; i < records.length; i++) {
130
+ var record = records[i]
131
+
132
+ const key = (record.querySelector('[data-key]') as HTMLInputElement).value
133
+ const inputs = record.querySelectorAll(
134
+ '[data-value]:not([style*="display: none"])'
135
+ ) as NodeListOf<HTMLInputElement>
136
+
137
+ if (!inputs || inputs.length == 0) {
138
+ continue
139
+ }
140
+
141
+ var input = inputs[inputs.length - 1]
142
+
143
+ var value = input.value
144
+
145
+ if (key) {
146
+ newmap[key] = value || ''
147
+ }
148
+ }
149
+
150
+ this.value = newmap
151
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
152
+ }
153
+
154
+ /* map아이템들을 template(dom-repeat)용 배열로 변환하는 함수 */
155
+ _toArray(map: PartitionKeys) {
156
+ var array: ArrayedPartitionKeys[] = []
157
+
158
+ for (var key in map) {
159
+ array.push({
160
+ key: key,
161
+ value: map[key]
162
+ })
163
+ }
164
+
165
+ return array
166
+ }
167
+
168
+ _add() {
169
+ this._build(true)
170
+
171
+ const inputs = this.renderRoot.querySelectorAll(
172
+ '[data-record-new] input:not([style*="display: none"])'
173
+ ) as NodeListOf<HTMLInputElement & { value: any }>
174
+
175
+ for (var i = 0; i < inputs.length; i++) {
176
+ let input = inputs[i]
177
+
178
+ if (input.type == 'checkbox') input.checked = false
179
+ else input.value = ''
180
+ }
181
+
182
+ inputs[0].focus()
183
+ }
184
+
185
+ _delete(e: MouseEvent) {
186
+ const record = (e.target as Element).closest('[data-record]') as HTMLElement
187
+
188
+ ;(record!.querySelector('[data-key]') as HTMLInputElement)!.value = ''
189
+
190
+ this._build()
191
+ }
192
+
193
+ @queryAll('[data-record]') records!: NodeListOf<HTMLElement>
194
+
195
+ _up(e: MouseEvent) {
196
+ const record = (e.target as Element).closest('[data-record]') as HTMLElement
197
+ const array = Array.from(this.records)
198
+ const index = array.indexOf(record) - 1
199
+
200
+ if (index < 0) {
201
+ return
202
+ }
203
+
204
+ const deleted = array.splice(index, 1)
205
+ array.splice(index + 1, 0, ...deleted)
206
+
207
+ this.value = array.reduce((sum, record) => {
208
+ const key = (record.querySelector('[data-key]') as HTMLInputElement).value
209
+ const value = (record.querySelector('[data-value]') as HTMLInputElement).value
210
+
211
+ sum[key] = value
212
+ return sum
213
+ }, {} as { [key: string]: string })
214
+
215
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
216
+ }
217
+
218
+ _down(e: MouseEvent) {
219
+ const record = (e.target as Element).closest('[data-record]') as HTMLElement
220
+ const array = Array.from(this.records)
221
+ const index = array.indexOf(record)
222
+
223
+ if (index > array.length) {
224
+ return
225
+ }
226
+
227
+ array.splice(index, 1)
228
+ array.splice(index + 1, 0, record)
229
+
230
+ this.value = array.reduce((sum, record) => {
231
+ const key = (record.querySelector('[data-key]') as HTMLInputElement).value
232
+ const value = (record.querySelector('[data-value]') as HTMLInputElement).value
233
+
234
+ sum[key] = value
235
+ return sum
236
+ }, {} as { [key: string]: string })
237
+
238
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
239
+ }
240
+ }