@operato/input 2.0.0-alpha.0 → 2.0.0-alpha.11
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.
- package/CHANGELOG.md +56 -0
- package/dist/src/ox-input-barcode.d.ts +48 -5
- package/dist/src/ox-input-barcode.js +96 -69
- package/dist/src/ox-input-barcode.js.map +1 -1
- package/dist/src/ox-input-data.d.ts +1 -3
- package/dist/src/ox-input-data.js +18 -13
- package/dist/src/ox-input-data.js.map +1 -1
- package/dist/src/ox-input-mass-fraction.d.ts +1 -0
- package/dist/src/ox-input-mass-fraction.js +48 -31
- package/dist/src/ox-input-mass-fraction.js.map +1 -1
- package/dist/src/ox-input-unit-number.d.ts +2 -1
- package/dist/src/ox-input-unit-number.js +24 -10
- package/dist/src/ox-input-unit-number.js.map +1 -1
- package/dist/stories/ox-input-barcode.stories.js +4 -0
- package/dist/stories/ox-input-barcode.stories.js.map +1 -1
- package/dist/stories/ox-input-data.stories.d.ts +33 -0
- package/dist/stories/ox-input-data.stories.js +40 -0
- package/dist/stories/ox-input-data.stories.js.map +1 -0
- package/dist/stories/ox-input-mass-fraction.stories.d.ts +4 -0
- package/dist/stories/ox-input-mass-fraction.stories.js +9 -2
- package/dist/stories/ox-input-mass-fraction.stories.js.map +1 -1
- package/dist/stories/ox-input-unit.stories.js +1 -0
- package/dist/stories/ox-input-unit.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/ox-input-barcode.ts +127 -63
- package/src/ox-input-data.ts +20 -15
- package/src/ox-input-mass-fraction.ts +46 -32
- package/src/ox-input-unit-number.ts +17 -2
- package/stories/ox-input-barcode.stories.ts +4 -0
- package/stories/ox-input-data.stories.ts +55 -0
- package/stories/ox-input-mass-fraction.stories.ts +10 -1
- package/stories/ox-input-unit.stories.ts +1 -0
package/src/ox-input-barcode.ts
CHANGED
@@ -6,14 +6,40 @@ import '@operato/popup/ox-popup.js'
|
|
6
6
|
|
7
7
|
import { css, html } from 'lit'
|
8
8
|
import { customElement, property, query, state } from 'lit/decorators.js'
|
9
|
+
import { scanImageData } from '@undecaf/zbar-wasm'
|
9
10
|
|
10
11
|
import { OxPopup } from '@operato/popup'
|
11
|
-
import { BrowserMultiFormatReader } from '@zxing/library'
|
12
12
|
|
13
13
|
import { OxFormField } from './ox-form-field.js'
|
14
14
|
|
15
15
|
const barcodeIcon = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAYBAMAAAAfR1CMAAADKGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFNjM4RURDQkQ1OUExMUU5QkExMkQ4NUY3NkMxNzBFOSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFNjM4RURDQ0Q1OUExMUU5QkExMkQ4NUY3NkMxNzBFOSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU2MzhFREM5RDU5QTExRTlCQTEyRDg1Rjc2QzE3MEU5IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU2MzhFRENBRDU5QTExRTlCQTEyRDg1Rjc2QzE3MEU5Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+55pr/QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAkUExURQAAAEdwTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEus/7UCWQwAAAALdFJOU9YAg3wKBFBDSz9PnvQNDgAAAE9JREFUGNNjEEQFDKLJSnCOklkgg9QUJFn3RgZhRyS+iCGDEIp2RSBfQICRkRGIgTSQL4jCF6ScvxsZYOFT2T50/6D7Fz080MMLPTzRwhsAHVspfelur08AAAAASUVORK5CYII=`
|
16
16
|
|
17
|
+
/**
|
18
|
+
* Custom input component for barcode scanning.
|
19
|
+
*
|
20
|
+
* This component provides a text input field and a barcode scanning button. Users can input text
|
21
|
+
* manually or scan barcodes using the device camera. Supported barcode formats include:
|
22
|
+
*
|
23
|
+
* - Code-39
|
24
|
+
* - Code-93
|
25
|
+
* - Code-128
|
26
|
+
* - Codabar
|
27
|
+
* - Databar/Expanded
|
28
|
+
* - EAN/GTIN-5/8/13
|
29
|
+
* - ISBN-10/13
|
30
|
+
* - ISBN-13+2
|
31
|
+
* - ISBN-13+5
|
32
|
+
* - ITF (Interleaved 2 of 5)
|
33
|
+
* - QR Code
|
34
|
+
* - UPC-A/E
|
35
|
+
*
|
36
|
+
* @fires CustomEvent#change - Dispatched when the input value changes.
|
37
|
+
* @fires KeyboardEvent#keydown - Dispatched when the Enter key is pressed (if not withoutEnter).
|
38
|
+
*
|
39
|
+
* @cssprop {String} --barcodescan-input-button-icon - Icon for the barcode scanning button.
|
40
|
+
*
|
41
|
+
* @customElement
|
42
|
+
*/
|
17
43
|
@customElement('ox-input-barcode')
|
18
44
|
export class OxInputBarcode extends OxFormField {
|
19
45
|
static styles = [
|
@@ -59,46 +85,45 @@ export class OxInputBarcode extends OxFormField {
|
|
59
85
|
#scan-button[hidden] {
|
60
86
|
display: none;
|
61
87
|
}
|
62
|
-
|
63
|
-
ox-popup {
|
64
|
-
position: fixed;
|
65
|
-
|
66
|
-
width: 80vw;
|
67
|
-
height: 80vh;
|
68
|
-
transform: translate(10%, 10%);
|
69
|
-
}
|
70
|
-
|
71
|
-
video {
|
72
|
-
width: 100%;
|
73
|
-
height: 100%;
|
74
|
-
}
|
75
|
-
|
76
|
-
@media screen and (max-width: 460px) {
|
77
|
-
ox-popup {
|
78
|
-
position: fixed;
|
79
|
-
left: 0;
|
80
|
-
top: 0;
|
81
|
-
width: 100vw;
|
82
|
-
height: 100vh;
|
83
|
-
height: 100dvh;
|
84
|
-
transform: translate(0%, 0%);
|
85
|
-
}
|
86
|
-
}
|
87
88
|
`
|
88
89
|
]
|
89
90
|
|
91
|
+
/**
|
92
|
+
* Indicates whether barcode scanning is enabled.
|
93
|
+
* @property {Boolean} scannable
|
94
|
+
*/
|
90
95
|
@property({ type: Boolean }) scannable?: boolean
|
96
|
+
|
97
|
+
/**
|
98
|
+
* If true, the "Enter" key press event is not fired after scanning a barcode.
|
99
|
+
* @property {Boolean} withoutEnter
|
100
|
+
*/
|
91
101
|
@property({ attribute: 'without-enter', type: Boolean }) withoutEnter?: boolean
|
102
|
+
|
103
|
+
/**
|
104
|
+
* The value of the input field.
|
105
|
+
* @property {String} declare value
|
106
|
+
*/
|
92
107
|
@property({ type: String }) declare value?: string
|
108
|
+
|
109
|
+
/**
|
110
|
+
* If true, only English characters are allowed in the input field.
|
111
|
+
* @property {Boolean} englishOnly
|
112
|
+
*/
|
93
113
|
@property({ attribute: 'english-only', type: Boolean }) englishOnly?: boolean
|
114
|
+
|
115
|
+
/**
|
116
|
+
* If true, the input field is automatically selected after a change event.
|
117
|
+
* @property {Boolean} selectAfterChange
|
118
|
+
*/
|
94
119
|
@property({ attribute: 'select-after-change', type: Boolean }) selectAfterChange?: boolean
|
95
120
|
|
96
121
|
@state() stream?: MediaStream
|
97
|
-
@state() reader?: BrowserMultiFormatReader
|
98
122
|
|
99
123
|
@query('input') input!: HTMLInputElement
|
100
|
-
|
101
|
-
|
124
|
+
|
125
|
+
private popup: OxPopup | null = null
|
126
|
+
private video: HTMLVideoElement | null = null
|
102
127
|
|
103
128
|
connectedCallback() {
|
104
129
|
super.connectedCallback()
|
@@ -108,7 +133,7 @@ export class OxInputBarcode extends OxFormField {
|
|
108
133
|
if (navigator.mediaDevices) {
|
109
134
|
;(async () => {
|
110
135
|
try {
|
111
|
-
var stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
|
136
|
+
var stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: { facingMode: 'environment' } })
|
112
137
|
if (stream) {
|
113
138
|
stream.getTracks().forEach(track => track.stop())
|
114
139
|
this.scannable = true
|
@@ -143,14 +168,6 @@ export class OxInputBarcode extends OxFormField {
|
|
143
168
|
}}
|
144
169
|
?disabled=${this.disabled}
|
145
170
|
></button>
|
146
|
-
|
147
|
-
<ox-popup
|
148
|
-
@focusout=${() => {
|
149
|
-
this.stopScan()
|
150
|
-
}}
|
151
|
-
>
|
152
|
-
<video></video>
|
153
|
-
</ox-popup>
|
154
171
|
`
|
155
172
|
}
|
156
173
|
|
@@ -201,27 +218,74 @@ export class OxInputBarcode extends OxFormField {
|
|
201
218
|
|
202
219
|
async scan(e: MouseEvent) {
|
203
220
|
try {
|
204
|
-
this.popup
|
221
|
+
if (this.popup) {
|
222
|
+
this.stopScan()
|
223
|
+
}
|
224
|
+
|
225
|
+
this.popup = OxPopup.open({
|
226
|
+
template: html`
|
227
|
+
<video></video>
|
228
|
+
<mwc-icon
|
229
|
+
style="position: fixed; right: 0; top: 0; color: red; tabindex: 0"
|
230
|
+
@click=${() => {
|
231
|
+
this.stopScan()
|
232
|
+
}}
|
233
|
+
>close</mwc-icon
|
234
|
+
>
|
235
|
+
`,
|
236
|
+
width: '100vw',
|
237
|
+
height: '100dvh'
|
238
|
+
})
|
205
239
|
|
206
|
-
|
207
|
-
await this.updateComplete
|
240
|
+
this.video! = this.popup.querySelector('video') as HTMLVideoElement
|
208
241
|
|
209
|
-
var constraints = { video: { facingMode: 'environment' } } /* backside camera first */
|
242
|
+
var constraints = { audio: false, video: { facingMode: 'environment' } } /* backside camera first */
|
210
243
|
this.stream = await navigator.mediaDevices.getUserMedia(constraints)
|
211
244
|
|
212
|
-
this.
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
245
|
+
this.video.srcObject = this.stream
|
246
|
+
this.video.play()
|
247
|
+
|
248
|
+
this.video.onloadedmetadata = async e => {
|
249
|
+
var canvas = new OffscreenCanvas(
|
250
|
+
this.video!.videoWidth || this.video!.width,
|
251
|
+
this.video!.videoHeight || this.video!.height
|
252
|
+
)
|
253
|
+
|
254
|
+
var context = canvas.getContext('2d', {
|
255
|
+
willReadFrequently: true
|
256
|
+
})
|
257
|
+
|
258
|
+
const detect = async () => {
|
259
|
+
try {
|
260
|
+
if (!this.stream?.active) {
|
261
|
+
return
|
262
|
+
}
|
263
|
+
|
264
|
+
context!.drawImage(this.video!, 0, 0, canvas.width, canvas.height)
|
265
|
+
const imageData = context!.getImageData(0, 0, canvas.width, canvas.height)
|
266
|
+
const symbols = await scanImageData(imageData)
|
267
|
+
const result = symbols[0]?.decode()
|
268
|
+
|
269
|
+
if (result) {
|
270
|
+
this.stopScan()
|
271
|
+
|
272
|
+
var input = this.input
|
273
|
+
input.focus()
|
274
|
+
this.value = input.value = String(result)
|
275
|
+
|
276
|
+
if (!this.withoutEnter) {
|
277
|
+
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }))
|
278
|
+
}
|
279
|
+
} else {
|
280
|
+
requestAnimationFrame(async () => await detect())
|
281
|
+
}
|
282
|
+
} catch (e) {
|
283
|
+
console.warn(e)
|
284
|
+
this.stopScan()
|
285
|
+
}
|
221
286
|
}
|
222
|
-
|
223
|
-
|
224
|
-
this.stopScan()
|
287
|
+
|
288
|
+
await detect()
|
225
289
|
}
|
226
290
|
} catch (err) {
|
227
291
|
/*
|
@@ -229,20 +293,20 @@ export class OxInputBarcode extends OxFormField {
|
|
229
293
|
* 2. 뒤로가기 등으로 popup이 종료된 경우에도 NotFoundException: Video stream has ended before any code could be detected. 이 발생한다.
|
230
294
|
*/
|
231
295
|
console.warn(err)
|
232
|
-
} finally {
|
233
|
-
this.popup.close()
|
234
|
-
|
235
|
-
this.stopScan()
|
236
296
|
}
|
237
297
|
}
|
238
298
|
|
239
299
|
stopScan() {
|
240
|
-
this.video
|
300
|
+
if (this.video) {
|
301
|
+
this.video.pause()
|
302
|
+
this.video.srcObject = null
|
303
|
+
}
|
241
304
|
|
242
|
-
this.
|
243
|
-
|
305
|
+
if (this.popup) {
|
306
|
+
this.popup.close()
|
307
|
+
this.popup = null
|
308
|
+
}
|
244
309
|
|
245
|
-
|
246
|
-
delete this.reader
|
310
|
+
this.stream?.getTracks().forEach(track => track.stop())
|
247
311
|
}
|
248
312
|
}
|
package/src/ox-input-data.ts
CHANGED
@@ -5,7 +5,8 @@
|
|
5
5
|
import './ox-input-code'
|
6
6
|
|
7
7
|
import { css, html, PropertyValues } from 'lit'
|
8
|
-
import { customElement } from 'lit/decorators.js'
|
8
|
+
import { customElement, state } from 'lit/decorators.js'
|
9
|
+
import { live } from 'lit/directives/live.js'
|
9
10
|
|
10
11
|
import { OxFormField } from './ox-form-field.js'
|
11
12
|
import { OxInputCode } from './ox-input-code.js'
|
@@ -49,34 +50,43 @@ export class OxInputData extends OxFormField {
|
|
49
50
|
]
|
50
51
|
|
51
52
|
render() {
|
53
|
+
const valueType = typeof this.value
|
54
|
+
|
52
55
|
return html`
|
53
56
|
<div datatype>
|
54
57
|
<input
|
58
|
+
id="string"
|
55
59
|
type="radio"
|
56
60
|
name="data-type"
|
57
61
|
data-value="string"
|
58
|
-
.checked=${
|
62
|
+
.checked=${live(valueType == 'string')}
|
59
63
|
@click=${() => this._setDataType('string')}
|
60
64
|
?disabled=${this.disabled}
|
61
|
-
/>
|
65
|
+
/>
|
66
|
+
<label for="string">string</label>
|
62
67
|
|
63
68
|
<input
|
69
|
+
id="number"
|
64
70
|
type="radio"
|
65
71
|
name="data-type"
|
66
72
|
data-value="number"
|
67
|
-
.checked=${
|
73
|
+
.checked=${live(valueType == 'number')}
|
68
74
|
@click=${() => this._setDataType('number')}
|
69
75
|
?disabled=${this.disabled}
|
70
|
-
/>
|
76
|
+
/>
|
77
|
+
<label for="number">number</label>
|
71
78
|
|
72
79
|
<input
|
80
|
+
id="object"
|
73
81
|
type="radio"
|
74
82
|
name="data-type"
|
75
83
|
data-value="object"
|
76
|
-
.checked=${
|
84
|
+
.checked=${live(valueType == 'object')}
|
77
85
|
@click=${() => this._setDataType('object')}
|
78
86
|
?disabled=${this.disabled}
|
79
|
-
/>
|
87
|
+
/>
|
88
|
+
<label for="object">object</label>
|
89
|
+
|
80
90
|
<mwc-icon @click=${() => this._clearData()} title="delete">delete_forever</mwc-icon>
|
81
91
|
</div>
|
82
92
|
|
@@ -98,12 +108,6 @@ export class OxInputData extends OxFormField {
|
|
98
108
|
})
|
99
109
|
}
|
100
110
|
|
101
|
-
udpated(changes: PropertyValues<this>) {
|
102
|
-
if (changes.has('value')) {
|
103
|
-
this.value = this._getData(this.value)
|
104
|
-
}
|
105
|
-
}
|
106
|
-
|
107
111
|
_setDataType(type: string | undefined | null) {
|
108
112
|
if (typeof this.value !== type) {
|
109
113
|
var value = this.value
|
@@ -111,7 +115,7 @@ export class OxInputData extends OxFormField {
|
|
111
115
|
try {
|
112
116
|
switch (type) {
|
113
117
|
case 'string':
|
114
|
-
this.value =
|
118
|
+
this.value = this._getData(value)
|
115
119
|
break
|
116
120
|
case 'number':
|
117
121
|
if (!isNaN(value)) {
|
@@ -127,6 +131,7 @@ export class OxInputData extends OxFormField {
|
|
127
131
|
}
|
128
132
|
}
|
129
133
|
|
134
|
+
this.requestUpdate()
|
130
135
|
this._onAfterValueChange()
|
131
136
|
}
|
132
137
|
|
@@ -139,7 +144,7 @@ export class OxInputData extends OxFormField {
|
|
139
144
|
return typeof data !== 'object' ? data || '' : JSON.stringify(data, null, 1)
|
140
145
|
}
|
141
146
|
|
142
|
-
_onAfterValueChange() {
|
147
|
+
async _onAfterValueChange() {
|
143
148
|
this.dispatchEvent(
|
144
149
|
new CustomEvent('change', {
|
145
150
|
bubbles: true,
|
@@ -131,11 +131,16 @@ export class OxInputMassFraction extends OxFormField {
|
|
131
131
|
display: block;
|
132
132
|
text-align: center;
|
133
133
|
}
|
134
|
+
|
135
|
+
[right-end] {
|
136
|
+
margin-left: auto;
|
137
|
+
}
|
134
138
|
`
|
135
139
|
]
|
136
140
|
|
137
141
|
@property({ type: Object }) defaultValue: MassFraction = {}
|
138
142
|
@property({ type: Object }) value: MassFraction = {}
|
143
|
+
@property({ type: Boolean, attribute: true }) composable: boolean = false
|
139
144
|
|
140
145
|
@queryAll('[data-record]') records!: NodeListOf<HTMLElement>
|
141
146
|
|
@@ -168,14 +173,18 @@ export class OxInputMassFraction extends OxFormField {
|
|
168
173
|
list="value-template"
|
169
174
|
?disabled=${this.disabled}
|
170
175
|
/>
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
176
|
+
${this.composable
|
177
|
+
? html`
|
178
|
+
<button
|
179
|
+
class="record-action"
|
180
|
+
@click=${(e: MouseEvent) => this._delete(e)}
|
181
|
+
tabindex="-1"
|
182
|
+
?disabled=${this.disabled}
|
183
|
+
>
|
184
|
+
<mwc-icon>remove</mwc-icon>
|
185
|
+
</button>
|
186
|
+
`
|
187
|
+
: nothing}
|
179
188
|
<button
|
180
189
|
class="record-action"
|
181
190
|
@click=${(e: MouseEvent) => this._up(e)}
|
@@ -202,36 +211,41 @@ export class OxInputMassFraction extends OxFormField {
|
|
202
211
|
? nothing
|
203
212
|
: html`
|
204
213
|
<div data-record-new>
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
214
|
+
${this.composable
|
215
|
+
? html`
|
216
|
+
<ox-select
|
217
|
+
data-key
|
218
|
+
placeholder="Fluid"
|
219
|
+
.value=${live('')}
|
220
|
+
@change=${(e: Event) => {
|
221
|
+
e.stopPropagation()
|
222
|
+
}}
|
223
|
+
>
|
224
|
+
<ox-popup-list with-search> ${this.options} </ox-popup-list>
|
225
|
+
</ox-select>
|
226
|
+
|
227
|
+
<input
|
228
|
+
type="number"
|
229
|
+
data-value
|
230
|
+
placeholder="proportion"
|
231
|
+
min="0"
|
232
|
+
max="1"
|
233
|
+
step="0.01"
|
234
|
+
value=""
|
235
|
+
list="value-template"
|
236
|
+
/>
|
237
|
+
<button class="record-action" @click=${(e: MouseEvent) => this._add()} tabindex="-1">
|
238
|
+
<mwc-icon>add</mwc-icon>
|
239
|
+
</button>
|
240
|
+
`
|
241
|
+
: nothing}
|
229
242
|
<button
|
230
243
|
title="fill with the values suggested"
|
231
244
|
@click=${() => {
|
232
245
|
this.value = { ...this.defaultValue }
|
233
246
|
this.dispatchChangeEvent()
|
234
247
|
}}
|
248
|
+
right-end
|
235
249
|
>
|
236
250
|
<mwc-icon>settings_suggest</mwc-icon>
|
237
251
|
</button>
|
@@ -2,6 +2,8 @@
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
3
3
|
*/
|
4
4
|
|
5
|
+
import '@material/mwc-icon'
|
6
|
+
|
5
7
|
import { css, html, PropertyValues } from 'lit'
|
6
8
|
import { customElement, property, query } from 'lit/decorators.js'
|
7
9
|
import { ifDefined } from 'lit/directives/if-defined.js'
|
@@ -169,7 +171,7 @@ const UNIT_SYSTEMS: { [unit: string]: { [unit: string]: number | ((v: number) =>
|
|
169
171
|
}
|
170
172
|
|
171
173
|
@customElement('ox-input-unit-number')
|
172
|
-
export class
|
174
|
+
export class OxInputUnitNumber extends OxFormField {
|
173
175
|
static styles = [
|
174
176
|
css`
|
175
177
|
:host {
|
@@ -205,13 +207,25 @@ export class OxInputUnit extends OxFormField {
|
|
205
207
|
}
|
206
208
|
|
207
209
|
#unit {
|
208
|
-
|
210
|
+
flex: 1;
|
211
|
+
display: flex;
|
212
|
+
align-items: center;
|
209
213
|
position: relative;
|
210
214
|
margin-left: var(--margin-narrow);
|
211
215
|
font: var(--label-font);
|
212
216
|
color: var(--label-color);
|
213
217
|
min-width: 24px;
|
214
218
|
}
|
219
|
+
|
220
|
+
mwc-icon {
|
221
|
+
font-size: 18px;
|
222
|
+
color: var(--primary-color, #3c3938);
|
223
|
+
margin-left: auto;
|
224
|
+
}
|
225
|
+
|
226
|
+
ox-popup-list {
|
227
|
+
right: 0;
|
228
|
+
}
|
215
229
|
`
|
216
230
|
]
|
217
231
|
|
@@ -258,6 +272,7 @@ export class OxInputUnit extends OxFormField {
|
|
258
272
|
<div option value=${this.stdUnit}>${this.stdUnit}</div>
|
259
273
|
${units.map(unit => html`<div option value=${unit}>${unit}</div>`)}
|
260
274
|
</ox-popup-list>
|
275
|
+
<mwc-icon>expand_more</mwc-icon>
|
261
276
|
</div>
|
262
277
|
`
|
263
278
|
}
|
@@ -43,6 +43,10 @@ const Template: Story<ArgTypes> = ({
|
|
43
43
|
<link href="/themes/app-theme.css" rel="stylesheet" />
|
44
44
|
<link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
|
45
45
|
<style>
|
46
|
+
#root {
|
47
|
+
height: 500px;
|
48
|
+
}
|
49
|
+
|
46
50
|
ox-input-barcode {
|
47
51
|
font-size: 80px;
|
48
52
|
--input-font: initial;
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import '../src/ox-input-data.js'
|
2
|
+
|
3
|
+
import { html, TemplateResult } from 'lit'
|
4
|
+
|
5
|
+
export default {
|
6
|
+
title: 'ox-input-data',
|
7
|
+
component: 'ox-input-data',
|
8
|
+
argTypes: {
|
9
|
+
value: { control: 'text' },
|
10
|
+
name: { control: 'text' },
|
11
|
+
language: { control: 'select', options: ['javascript', 'sql', 'json'] },
|
12
|
+
disabled: { control: 'boolean' }
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
interface Story<T> {
|
17
|
+
(args: T): TemplateResult
|
18
|
+
args?: Partial<T>
|
19
|
+
argTypes?: Record<string, unknown>
|
20
|
+
}
|
21
|
+
|
22
|
+
interface ArgTypes {
|
23
|
+
name?: string
|
24
|
+
value?: string | number | object
|
25
|
+
disabled?: boolean
|
26
|
+
}
|
27
|
+
|
28
|
+
const Template: Story<ArgTypes> = ({ name = 'code', value = '', disabled }: ArgTypes) => html`
|
29
|
+
<link href="/themes/app-theme.css" rel="stylesheet" />
|
30
|
+
<link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
|
31
|
+
<style>
|
32
|
+
body {
|
33
|
+
}
|
34
|
+
ox-input-data {
|
35
|
+
height: 300px;
|
36
|
+
}
|
37
|
+
</style>
|
38
|
+
|
39
|
+
<ox-input-data
|
40
|
+
@change=${(e: Event) => {
|
41
|
+
const value = (e.target as HTMLInputElement).value
|
42
|
+
console.log('value : ', value, typeof value)
|
43
|
+
}}
|
44
|
+
name=${name}
|
45
|
+
.value=${value}
|
46
|
+
?disabled=${disabled}
|
47
|
+
>
|
48
|
+
</ox-input-data>
|
49
|
+
`
|
50
|
+
|
51
|
+
export const Regular = Template.bind({})
|
52
|
+
Regular.args = {
|
53
|
+
name: 'data',
|
54
|
+
value: ''
|
55
|
+
}
|
@@ -9,6 +9,7 @@ export default {
|
|
9
9
|
name: { control: 'text' },
|
10
10
|
value: { control: 'object' },
|
11
11
|
defaultValue: { control: 'object' },
|
12
|
+
composable: { control: 'boolean' },
|
12
13
|
disabled: { control: 'boolean' }
|
13
14
|
}
|
14
15
|
}
|
@@ -23,6 +24,7 @@ interface ArgTypes {
|
|
23
24
|
name?: string
|
24
25
|
value?: object
|
25
26
|
defaultValue?: object
|
27
|
+
composable?: boolean
|
26
28
|
disabled?: boolean
|
27
29
|
}
|
28
30
|
|
@@ -30,6 +32,7 @@ const Template: Story<ArgTypes> = ({
|
|
30
32
|
name = 'mass-fraction',
|
31
33
|
value = {},
|
32
34
|
defaultValue = {},
|
35
|
+
composable = true,
|
33
36
|
disabled
|
34
37
|
}: ArgTypes) => html`
|
35
38
|
<link href="/themes/app-theme.css" rel="stylesheet" />
|
@@ -46,6 +49,7 @@ const Template: Story<ArgTypes> = ({
|
|
46
49
|
name=${name}
|
47
50
|
.value=${value}
|
48
51
|
.defaultValue=${defaultValue}
|
52
|
+
?composable=${composable}
|
49
53
|
?disabled=${disabled}
|
50
54
|
>
|
51
55
|
</ox-input-mass-fraction>
|
@@ -54,7 +58,12 @@ const Template: Story<ArgTypes> = ({
|
|
54
58
|
export const Regular = Template.bind({})
|
55
59
|
Regular.args = {
|
56
60
|
name: 'mass-fraction',
|
57
|
-
value: {
|
61
|
+
value: {
|
62
|
+
H2O: 0.8,
|
63
|
+
N2O: 0.1,
|
64
|
+
CO2: 0.1
|
65
|
+
},
|
66
|
+
composable: true,
|
58
67
|
defaultValue: {
|
59
68
|
H2O: 0.8,
|
60
69
|
N2O: 0.1,
|
@@ -68,6 +68,7 @@ const Template: Story<ArgTypes> = ({
|
|
68
68
|
userUnit,
|
69
69
|
disabled
|
70
70
|
}: ArgTypes) => html`
|
71
|
+
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet" />
|
71
72
|
<link href="/themes/app-theme.css" rel="stylesheet" />
|
72
73
|
<ox-input-unit-number
|
73
74
|
name=${name}
|