@operato/input 1.0.0-alpha.3 → 1.0.0-alpha.6

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.
@@ -0,0 +1,165 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import { LitElement, 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,147 @@
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.js'
9
+
10
+ @customElement('ox-input-range')
11
+ class OxInputRange extends OxFormField {
12
+ static styles = css`
13
+ :host {
14
+ font-size: 16px;
15
+ display: flex;
16
+ align-items: center;
17
+ padding: 1px 0;
18
+
19
+ width: 100%;
20
+ user-select: text;
21
+ }
22
+
23
+ input[type='number'] {
24
+ width: 48px;
25
+ overflow: hidden;
26
+ }
27
+
28
+ input[type='number'] {
29
+ color: black;
30
+ border: none;
31
+ font-weight: 300;
32
+ background: white;
33
+ padding: 1px 2px;
34
+ }
35
+
36
+ input[type='range'] {
37
+ -webkit-appearance: none;
38
+ border: none;
39
+ outline: none;
40
+ width: 100%;
41
+ flex: 1;
42
+ height: 16px;
43
+ background-color: transparent;
44
+ }
45
+ input[type='range']::-webkit-slider-runnable-track {
46
+ width: 100%;
47
+ height: 1px;
48
+ background: black;
49
+ border: none;
50
+ border-radius: 5px;
51
+ }
52
+ input[type='range']::-webkit-slider-thumb {
53
+ -webkit-appearance: none;
54
+ border: none;
55
+ height: 10px;
56
+ width: 10px;
57
+ border-radius: 50%;
58
+ background: black;
59
+ margin-top: -5px;
60
+ }
61
+ input[type='range']:focus {
62
+ outline: none;
63
+ }
64
+ input[type='range']:focus::-webkit-slider-runnable-track {
65
+ background: black;
66
+ }
67
+
68
+ input[type='range']::-moz-range-track {
69
+ width: 100%;
70
+ height: 1px;
71
+ background: black;
72
+ border: none;
73
+ border-radius: 5px;
74
+ }
75
+ input[type='range']::-moz-range-thumb {
76
+ border: none;
77
+ height: 10px;
78
+ width: 10px;
79
+ border-radius: 50%;
80
+ background: black;
81
+ }
82
+
83
+ input[type='range']:-moz-focusring {
84
+ outline: 1px solid black;
85
+ outline-offset: -1px;
86
+ }
87
+
88
+ input[type='range']::-ms-track {
89
+ width: 100%;
90
+ height: 1px;
91
+ background: black;
92
+ border-radius: 10px;
93
+ color: transparent;
94
+ border: none;
95
+ outline: none;
96
+ }
97
+ input[type='range']::-ms-thumb {
98
+ height: 10px;
99
+ width: 10px;
100
+ border-radius: 50%;
101
+ background: black;
102
+ border: none;
103
+ outline: none;
104
+ margin-top: 2px;
105
+ }
106
+
107
+ input:focus {
108
+ outline: none;
109
+ opacity: 1;
110
+ }
111
+ `
112
+
113
+ @property({ type: Number }) value: number = 0
114
+ @property({ type: Number }) step: number = 1
115
+ @property({ type: Number }) min: number = -100
116
+ @property({ type: Number }) max: number = 100
117
+
118
+ render() {
119
+ return html`
120
+ <input
121
+ type="range"
122
+ .value=${this.value}
123
+ .step=${this.step}
124
+ .min=${this.min}
125
+ .max=${this.max}
126
+ @input=${(e: InputEvent) => {
127
+ e.stopPropagation()
128
+ this.value = Number((e.target as HTMLInputElement).value)
129
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
130
+ }}
131
+ />
132
+
133
+ <input
134
+ type="number"
135
+ .value=${this.value}
136
+ .step=${this.step}
137
+ .min=${this.min}
138
+ .max=${this.max}
139
+ @change=${(e: Event) => {
140
+ e.stopPropagation()
141
+ this.value = Number((e.target as HTMLInputElement).value)
142
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
143
+ }}
144
+ />
145
+ `
146
+ }
147
+ }