@things-factory/barcode-ui 7.0.0-alpha.8 → 7.0.0
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/client/components/barcode-input.ts +56 -0
- package/client/components/{barcode-scanable-input.js → barcode-scanable-input.ts} +62 -70
- package/client/components/{barcode-tag.js → barcode-tag.ts} +40 -43
- package/dist-client/components/barcode-input.d.ts +12 -0
- package/dist-client/components/barcode-input.js +71 -0
- package/dist-client/components/barcode-input.js.map +1 -0
- package/dist-client/components/barcode-scanable-input.d.ts +21 -0
- package/dist-client/components/barcode-scanable-input.js +177 -0
- package/dist-client/components/barcode-scanable-input.js.map +1 -0
- package/dist-client/components/barcode-tag.d.ts +18 -0
- package/dist-client/components/barcode-tag.js +130 -0
- package/dist-client/components/barcode-tag.js.map +1 -0
- package/dist-client/index.d.ts +3 -0
- package/dist-client/index.js +4 -0
- package/dist-client/index.js.map +1 -0
- package/dist-client/themes/barcode-theme.css +4 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -0
- package/dist-server/index.d.ts +0 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -10
- package/things-factory.config.js +1 -5
- package/client/bootstrap.js +0 -1
- package/client/components/barcode-input.js +0 -62
- package/client/route.js +0 -7
- /package/client/{index.js → index.ts} +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import './barcode-tag'
|
|
2
|
+
|
|
3
|
+
import { css, html, LitElement } from 'lit'
|
|
4
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
5
|
+
|
|
6
|
+
@customElement('barcode-input')
|
|
7
|
+
export class BarcodeInput extends LitElement {
|
|
8
|
+
static styles = [
|
|
9
|
+
css`
|
|
10
|
+
:host {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
align-items: center;
|
|
14
|
+
|
|
15
|
+
padding: initial;
|
|
16
|
+
border: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
:host * {
|
|
20
|
+
align-self: stretch;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
input {
|
|
24
|
+
margin: 5px 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
barcode-tag {
|
|
28
|
+
margin: 5px 0;
|
|
29
|
+
}
|
|
30
|
+
`
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
@property({ type: String }) bcid?: string
|
|
34
|
+
@property({ type: Number }) bcWidth?: number
|
|
35
|
+
@property({ type: Number }) bcHeight?: number
|
|
36
|
+
@property({ type: Number }) bcScale?: number
|
|
37
|
+
@property({ type: String }) value?: string
|
|
38
|
+
|
|
39
|
+
render() {
|
|
40
|
+
return html`
|
|
41
|
+
<input type="text" @change=${this.onChange.bind(this)} .value=${this.value || ''} />
|
|
42
|
+
<barcode-tag
|
|
43
|
+
.bcid=${this.bcid}
|
|
44
|
+
.value=${this.value}
|
|
45
|
+
.bcWidth=${this.bcWidth}
|
|
46
|
+
.bcHeight=${this.bcHeight}
|
|
47
|
+
.bcScale=${this.bcScale}
|
|
48
|
+
></barcode-tag>
|
|
49
|
+
`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
onChange(e) {
|
|
53
|
+
this.value = e.target.value
|
|
54
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { css, html, LitElement } from 'lit'
|
|
2
|
+
import { customElement, property, query } from 'lit/decorators.js'
|
|
2
3
|
|
|
3
4
|
import { openPopup } from '@operato/layout'
|
|
4
5
|
import { BrowserMultiFormatReader } from '@zxing/library'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
const barcodeIcon = new URL('../../assets/images/barcode.png', import.meta.url).href
|
|
7
8
|
|
|
9
|
+
@customElement('scan-camera-template')
|
|
8
10
|
class ScanCameraTemplate extends LitElement {
|
|
9
11
|
get video() {
|
|
10
|
-
return this.
|
|
12
|
+
return this.renderRoot.querySelector('video')
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
render() {
|
|
@@ -15,75 +17,68 @@ class ScanCameraTemplate extends LitElement {
|
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
customElements.define('scan-camera-template', ScanCameraTemplate)
|
|
19
|
-
|
|
20
20
|
/**
|
|
21
21
|
* @deprecated use ox-input-barcode from @operato/input/ox-input-barcode.js
|
|
22
22
|
*
|
|
23
23
|
* BarcodeScanableInput is using mediadevice api of html5
|
|
24
24
|
*/
|
|
25
|
+
@customElement('barcode-scanable-input')
|
|
25
26
|
export class BarcodeScanableInput extends LitElement {
|
|
26
|
-
static
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
}
|
|
27
|
+
static styles = [
|
|
28
|
+
css`
|
|
29
|
+
:host {
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
border: none;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
background-color: var(--md-sys-color-surface);
|
|
35
|
+
|
|
36
|
+
padding: var(--custom-input-barcode-field-padding) !important;
|
|
37
|
+
}
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
:host {
|
|
44
|
-
display: flex;
|
|
45
|
-
align-items: center;
|
|
46
|
-
border: none;
|
|
47
|
-
overflow: hidden;
|
|
48
|
-
background-color: #fff;
|
|
49
|
-
|
|
50
|
-
padding: var(--custom-input-barcode-field-padding) !important;
|
|
51
|
-
}
|
|
39
|
+
* {
|
|
40
|
+
align-self: stretch;
|
|
41
|
+
}
|
|
52
42
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
43
|
+
*:focus {
|
|
44
|
+
outline: none;
|
|
45
|
+
}
|
|
56
46
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
47
|
+
input {
|
|
48
|
+
flex: 1 !important;
|
|
49
|
+
border: none;
|
|
50
|
+
font: var(--custom-input-barcode-field-font);
|
|
51
|
+
width: 10px;
|
|
52
|
+
flex-grow: 1;
|
|
53
|
+
}
|
|
60
54
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
#scan-button {
|
|
56
|
+
display: block;
|
|
57
|
+
width: 30px;
|
|
58
|
+
height: 100%;
|
|
59
|
+
min-height: 24px;
|
|
60
|
+
border: none;
|
|
61
|
+
background-color: transparent;
|
|
62
|
+
background-repeat: no-repeat;
|
|
63
|
+
background-position: center;
|
|
64
|
+
background-image: var(--barcodescan-input-button-icon);
|
|
65
|
+
}
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
border: none;
|
|
75
|
-
background-color: transparent;
|
|
76
|
-
background-repeat: no-repeat;
|
|
77
|
-
background-position: center;
|
|
78
|
-
background-image: var(--barcodescan-input-button-icon);
|
|
79
|
-
}
|
|
67
|
+
#scan-button[hidden] {
|
|
68
|
+
display: none;
|
|
69
|
+
}
|
|
70
|
+
`
|
|
71
|
+
]
|
|
80
72
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
73
|
+
@property({ type: String, attribute: true }) name?: string
|
|
74
|
+
@property({ type: Boolean }) scannable?: boolean
|
|
75
|
+
@property({ type: Boolean, attribute: 'without-enter' }) withoutEnter?: boolean
|
|
76
|
+
@property({ type: String }) value?: string
|
|
77
|
+
|
|
78
|
+
@query('input') input!: HTMLInputElement
|
|
79
|
+
|
|
80
|
+
private stream?: MediaStream
|
|
81
|
+
private reader?: BrowserMultiFormatReader
|
|
87
82
|
|
|
88
83
|
connectedCallback() {
|
|
89
84
|
super.connectedCallback()
|
|
@@ -124,20 +119,19 @@ export class BarcodeScanableInput extends LitElement {
|
|
|
124
119
|
`
|
|
125
120
|
}
|
|
126
121
|
|
|
127
|
-
get input() {
|
|
128
|
-
return this.shadowRoot.querySelector('input')
|
|
129
|
-
}
|
|
130
|
-
|
|
131
122
|
async scan(e) {
|
|
123
|
+
var popup
|
|
124
|
+
|
|
132
125
|
try {
|
|
133
|
-
var template = document.createElement('scan-camera-template')
|
|
126
|
+
var template = document.createElement('scan-camera-template') as any
|
|
134
127
|
|
|
135
|
-
|
|
128
|
+
popup = openPopup(template, {
|
|
136
129
|
backdrop: true,
|
|
137
130
|
size: 'large',
|
|
138
131
|
closable: false
|
|
139
132
|
})
|
|
140
|
-
|
|
133
|
+
|
|
134
|
+
popup.onclosed = () => {
|
|
141
135
|
/* 뒤로가기 등으로 popup이 종료된 경우에도 scan 자원을 clear해준다. */
|
|
142
136
|
this.stopScan()
|
|
143
137
|
}
|
|
@@ -152,7 +146,7 @@ export class BarcodeScanableInput extends LitElement {
|
|
|
152
146
|
if (!popup.closed && this.stream) {
|
|
153
147
|
var result = await this.reader.decodeOnceFromStream(this.stream, template.video)
|
|
154
148
|
|
|
155
|
-
this.input.value = result
|
|
149
|
+
this.input.value = result as any
|
|
156
150
|
if (!this.withoutEnter) {
|
|
157
151
|
this.dispatchEvent(new KeyboardEvent('keypress', { keyCode: 0x0d }))
|
|
158
152
|
}
|
|
@@ -167,7 +161,7 @@ export class BarcodeScanableInput extends LitElement {
|
|
|
167
161
|
*/
|
|
168
162
|
console.warn(err)
|
|
169
163
|
} finally {
|
|
170
|
-
popup
|
|
164
|
+
popup?.close()
|
|
171
165
|
|
|
172
166
|
this.stopScan()
|
|
173
167
|
}
|
|
@@ -181,5 +175,3 @@ export class BarcodeScanableInput extends LitElement {
|
|
|
181
175
|
delete this.reader
|
|
182
176
|
}
|
|
183
177
|
}
|
|
184
|
-
|
|
185
|
-
customElements.define('barcode-scanable-input', BarcodeScanableInput)
|
|
@@ -1,49 +1,45 @@
|
|
|
1
|
-
import bwipjs from '
|
|
1
|
+
import bwipjs from 'bwip-js'
|
|
2
2
|
import { css, html, LitElement } from 'lit'
|
|
3
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @deprecated use ox-barcode from @operato/barcode/ox-barcode.js
|
|
6
7
|
*/
|
|
8
|
+
@customElement('barcode-tag')
|
|
7
9
|
export class BarcodeTag extends LitElement {
|
|
8
|
-
static
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
bcScale: Number,
|
|
14
|
-
value: String,
|
|
15
|
-
validity: Boolean,
|
|
16
|
-
padding: Number
|
|
17
|
-
}
|
|
18
|
-
}
|
|
10
|
+
static styles = [
|
|
11
|
+
css`
|
|
12
|
+
:host {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
canvas {
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: 100px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
[dimmer] {
|
|
25
|
+
display: block;
|
|
26
|
+
position: absolute;
|
|
27
|
+
width: 100%;
|
|
28
|
+
height: 100%;
|
|
29
|
+
top: 0;
|
|
30
|
+
left: 0;
|
|
31
|
+
background-color: rgba(255, 0, 0, 0.5);
|
|
32
|
+
}
|
|
33
|
+
`
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
@property({ type: String }) bcid?: string
|
|
37
|
+
@property({ type: Number }) bcWidth?: number
|
|
38
|
+
@property({ type: Number }) bcHeight?: number
|
|
39
|
+
@property({ type: Number }) bcScale?: number
|
|
40
|
+
@property({ type: String }) value?: string
|
|
41
|
+
@property({ type: Boolean }) validity?: boolean
|
|
42
|
+
@property({ type: Number }) padding?: number
|
|
47
43
|
|
|
48
44
|
render() {
|
|
49
45
|
return html`
|
|
@@ -61,7 +57,7 @@ export class BarcodeTag extends LitElement {
|
|
|
61
57
|
_downloadQR() {
|
|
62
58
|
if (this.value && this.value != '') {
|
|
63
59
|
let link = document.createElement('a')
|
|
64
|
-
let canvas = this.
|
|
60
|
+
let canvas = this.renderRoot.querySelector('canvas') as HTMLCanvasElement
|
|
65
61
|
|
|
66
62
|
let options = {
|
|
67
63
|
bcid: this.bcid || 'code128', // Barcode type
|
|
@@ -74,12 +70,14 @@ export class BarcodeTag extends LitElement {
|
|
|
74
70
|
textalign: 'center',
|
|
75
71
|
backgroundcolor: 'ffffff'
|
|
76
72
|
}
|
|
73
|
+
//@ts-ignore
|
|
77
74
|
canvas = bwipjs.toCanvas(canvas, options)
|
|
78
75
|
|
|
79
76
|
link.download = `${this.value}` + '-barcode.png'
|
|
80
77
|
link.href = canvas.toDataURL()
|
|
81
78
|
link.click()
|
|
82
79
|
|
|
80
|
+
//@ts-ignore
|
|
83
81
|
bwipjs.toCanvas(canvas, {
|
|
84
82
|
bcid: this.bcid || 'code128', // Barcode type
|
|
85
83
|
height: this.bcHeight || 20, // Bar height, in millimeters
|
|
@@ -101,9 +99,10 @@ export class BarcodeTag extends LitElement {
|
|
|
101
99
|
textalign: 'center'
|
|
102
100
|
}
|
|
103
101
|
|
|
104
|
-
let canvas = this.
|
|
102
|
+
let canvas = this.renderRoot.querySelector('canvas')
|
|
105
103
|
|
|
106
104
|
try {
|
|
105
|
+
//@ts-ignore
|
|
107
106
|
bwipjs.toCanvas(canvas, options)
|
|
108
107
|
|
|
109
108
|
this.validity = true
|
|
@@ -114,5 +113,3 @@ export class BarcodeTag extends LitElement {
|
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
115
|
}
|
|
117
|
-
|
|
118
|
-
customElements.define('barcode-tag', BarcodeTag)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import './barcode-tag';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
export declare class BarcodeInput extends LitElement {
|
|
4
|
+
static styles: import("lit").CSSResult[];
|
|
5
|
+
bcid?: string;
|
|
6
|
+
bcWidth?: number;
|
|
7
|
+
bcHeight?: number;
|
|
8
|
+
bcScale?: number;
|
|
9
|
+
value?: string;
|
|
10
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
11
|
+
onChange(e: any): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import './barcode-tag';
|
|
3
|
+
import { css, html, LitElement } from 'lit';
|
|
4
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
5
|
+
let BarcodeInput = class BarcodeInput extends LitElement {
|
|
6
|
+
render() {
|
|
7
|
+
return html `
|
|
8
|
+
<input type="text" @change=${this.onChange.bind(this)} .value=${this.value || ''} />
|
|
9
|
+
<barcode-tag
|
|
10
|
+
.bcid=${this.bcid}
|
|
11
|
+
.value=${this.value}
|
|
12
|
+
.bcWidth=${this.bcWidth}
|
|
13
|
+
.bcHeight=${this.bcHeight}
|
|
14
|
+
.bcScale=${this.bcScale}
|
|
15
|
+
></barcode-tag>
|
|
16
|
+
`;
|
|
17
|
+
}
|
|
18
|
+
onChange(e) {
|
|
19
|
+
this.value = e.target.value;
|
|
20
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
BarcodeInput.styles = [
|
|
24
|
+
css `
|
|
25
|
+
:host {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
align-items: center;
|
|
29
|
+
|
|
30
|
+
padding: initial;
|
|
31
|
+
border: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
:host * {
|
|
35
|
+
align-self: stretch;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
input {
|
|
39
|
+
margin: 5px 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
barcode-tag {
|
|
43
|
+
margin: 5px 0;
|
|
44
|
+
}
|
|
45
|
+
`
|
|
46
|
+
];
|
|
47
|
+
__decorate([
|
|
48
|
+
property({ type: String }),
|
|
49
|
+
__metadata("design:type", String)
|
|
50
|
+
], BarcodeInput.prototype, "bcid", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
property({ type: Number }),
|
|
53
|
+
__metadata("design:type", Number)
|
|
54
|
+
], BarcodeInput.prototype, "bcWidth", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
property({ type: Number }),
|
|
57
|
+
__metadata("design:type", Number)
|
|
58
|
+
], BarcodeInput.prototype, "bcHeight", void 0);
|
|
59
|
+
__decorate([
|
|
60
|
+
property({ type: Number }),
|
|
61
|
+
__metadata("design:type", Number)
|
|
62
|
+
], BarcodeInput.prototype, "bcScale", void 0);
|
|
63
|
+
__decorate([
|
|
64
|
+
property({ type: String }),
|
|
65
|
+
__metadata("design:type", String)
|
|
66
|
+
], BarcodeInput.prototype, "value", void 0);
|
|
67
|
+
BarcodeInput = __decorate([
|
|
68
|
+
customElement('barcode-input')
|
|
69
|
+
], BarcodeInput);
|
|
70
|
+
export { BarcodeInput };
|
|
71
|
+
//# sourceMappingURL=barcode-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"barcode-input.js","sourceRoot":"","sources":["../../client/components/barcode-input.ts"],"names":[],"mappings":";AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAGpD,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;IAgC1C,MAAM;QACJ,OAAO,IAAI,CAAA;mCACoB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,KAAK,IAAI,EAAE;;gBAEtE,IAAI,CAAC,IAAI;iBACR,IAAI,CAAC,KAAK;mBACR,IAAI,CAAC,OAAO;oBACX,IAAI,CAAC,QAAQ;mBACd,IAAI,CAAC,OAAO;;KAE1B,CAAA;IACH,CAAC;IAED,QAAQ,CAAC,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;QAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAClF,CAAC;;AA/CM,mBAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;KAqBF;CACF,AAvBY,CAuBZ;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;0CAAc;AACb;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;6CAAiB;AAChB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;8CAAkB;AACjB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;6CAAiB;AAChB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;2CAAe;AA9B/B,YAAY;IADxB,aAAa,CAAC,eAAe,CAAC;GAClB,YAAY,CAiDxB","sourcesContent":["import './barcode-tag'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n@customElement('barcode-input')\nexport class BarcodeInput extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n\n padding: initial;\n border: 0;\n }\n\n :host * {\n align-self: stretch;\n }\n\n input {\n margin: 5px 0;\n }\n\n barcode-tag {\n margin: 5px 0;\n }\n `\n ]\n\n @property({ type: String }) bcid?: string\n @property({ type: Number }) bcWidth?: number\n @property({ type: Number }) bcHeight?: number\n @property({ type: Number }) bcScale?: number\n @property({ type: String }) value?: string\n\n render() {\n return html`\n <input type=\"text\" @change=${this.onChange.bind(this)} .value=${this.value || ''} />\n <barcode-tag\n .bcid=${this.bcid}\n .value=${this.value}\n .bcWidth=${this.bcWidth}\n .bcHeight=${this.bcHeight}\n .bcScale=${this.bcScale}\n ></barcode-tag>\n `\n }\n\n onChange(e) {\n this.value = e.target.value\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n }\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated use ox-input-barcode from @operato/input/ox-input-barcode.js
|
|
4
|
+
*
|
|
5
|
+
* BarcodeScanableInput is using mediadevice api of html5
|
|
6
|
+
*/
|
|
7
|
+
export declare class BarcodeScanableInput extends LitElement {
|
|
8
|
+
static styles: import("lit").CSSResult[];
|
|
9
|
+
name?: string;
|
|
10
|
+
scannable?: boolean;
|
|
11
|
+
withoutEnter?: boolean;
|
|
12
|
+
value?: string;
|
|
13
|
+
input: HTMLInputElement;
|
|
14
|
+
private stream?;
|
|
15
|
+
private reader?;
|
|
16
|
+
connectedCallback(): void;
|
|
17
|
+
disconnectedCallback(): void;
|
|
18
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
19
|
+
scan(e: any): Promise<void>;
|
|
20
|
+
stopScan(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { css, html, LitElement } from 'lit';
|
|
3
|
+
import { customElement, property, query } from 'lit/decorators.js';
|
|
4
|
+
import { openPopup } from '@operato/layout';
|
|
5
|
+
import { BrowserMultiFormatReader } from '@zxing/library';
|
|
6
|
+
const barcodeIcon = new URL('../../assets/images/barcode.png', import.meta.url).href;
|
|
7
|
+
let ScanCameraTemplate = class ScanCameraTemplate extends LitElement {
|
|
8
|
+
get video() {
|
|
9
|
+
return this.renderRoot.querySelector('video');
|
|
10
|
+
}
|
|
11
|
+
render() {
|
|
12
|
+
return html ` <video></video> `;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
ScanCameraTemplate = __decorate([
|
|
16
|
+
customElement('scan-camera-template')
|
|
17
|
+
], ScanCameraTemplate);
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated use ox-input-barcode from @operato/input/ox-input-barcode.js
|
|
20
|
+
*
|
|
21
|
+
* BarcodeScanableInput is using mediadevice api of html5
|
|
22
|
+
*/
|
|
23
|
+
let BarcodeScanableInput = class BarcodeScanableInput extends LitElement {
|
|
24
|
+
connectedCallback() {
|
|
25
|
+
super.connectedCallback();
|
|
26
|
+
this.scannable = false;
|
|
27
|
+
if (navigator.mediaDevices) {
|
|
28
|
+
;
|
|
29
|
+
(async () => {
|
|
30
|
+
try {
|
|
31
|
+
var stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } });
|
|
32
|
+
if (stream) {
|
|
33
|
+
stream.getTracks().forEach(track => track.stop());
|
|
34
|
+
this.scannable = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
console.warn('this device not support camera for barcode scan', e);
|
|
39
|
+
}
|
|
40
|
+
})();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
disconnectedCallback() {
|
|
44
|
+
this.stopScan();
|
|
45
|
+
}
|
|
46
|
+
render() {
|
|
47
|
+
this.style.setProperty('--barcodescan-input-button-icon', `url(${barcodeIcon})`);
|
|
48
|
+
return html `
|
|
49
|
+
<input type="search" .value=${this.value || ''} maxlength="50" />
|
|
50
|
+
<button
|
|
51
|
+
?hidden=${!this.scannable}
|
|
52
|
+
id="scan-button"
|
|
53
|
+
@click=${e => {
|
|
54
|
+
this.scan(e);
|
|
55
|
+
}}
|
|
56
|
+
></button>
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
async scan(e) {
|
|
60
|
+
var popup;
|
|
61
|
+
try {
|
|
62
|
+
var template = document.createElement('scan-camera-template');
|
|
63
|
+
popup = openPopup(template, {
|
|
64
|
+
backdrop: true,
|
|
65
|
+
size: 'large',
|
|
66
|
+
closable: false
|
|
67
|
+
});
|
|
68
|
+
popup.onclosed = () => {
|
|
69
|
+
/* 뒤로가기 등으로 popup이 종료된 경우에도 scan 자원을 clear해준다. */
|
|
70
|
+
this.stopScan();
|
|
71
|
+
};
|
|
72
|
+
/* template.video가 생성된 후에 접근하기 위해서, 한 프레임을 강제로 건너뛴다. */
|
|
73
|
+
await this.updateComplete;
|
|
74
|
+
var constraints = { video: { facingMode: 'environment' } }; /* backside camera first */
|
|
75
|
+
this.stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
76
|
+
this.reader = new BrowserMultiFormatReader();
|
|
77
|
+
if (!popup.closed && this.stream) {
|
|
78
|
+
var result = await this.reader.decodeOnceFromStream(this.stream, template.video);
|
|
79
|
+
this.input.value = result;
|
|
80
|
+
if (!this.withoutEnter) {
|
|
81
|
+
this.dispatchEvent(new KeyboardEvent('keypress', { keyCode: 0x0d }));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
/* popup이 비동기 진행 중에 close된 경우라면, stopScan()을 처리하지 못하게 되므로, 다시한번 clear해준다. */
|
|
86
|
+
this.stopScan();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
/*
|
|
91
|
+
* 1. stream device 문제로 예외 발생한 경우.
|
|
92
|
+
* 2. 뒤로가기 등으로 popup이 종료된 경우에도 NotFoundException: Video stream has ended before any code could be detected. 이 발생한다.
|
|
93
|
+
*/
|
|
94
|
+
console.warn(err);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
popup === null || popup === void 0 ? void 0 : popup.close();
|
|
98
|
+
this.stopScan();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
stopScan() {
|
|
102
|
+
this.stream && this.stream.getTracks().forEach(track => track.stop());
|
|
103
|
+
this.reader && this.reader.reset();
|
|
104
|
+
delete this.stream;
|
|
105
|
+
delete this.reader;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
BarcodeScanableInput.styles = [
|
|
109
|
+
css `
|
|
110
|
+
:host {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
border: none;
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
background-color: var(--md-sys-color-surface);
|
|
116
|
+
|
|
117
|
+
padding: var(--custom-input-barcode-field-padding) !important;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
* {
|
|
121
|
+
align-self: stretch;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
*:focus {
|
|
125
|
+
outline: none;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
input {
|
|
129
|
+
flex: 1 !important;
|
|
130
|
+
border: none;
|
|
131
|
+
font: var(--custom-input-barcode-field-font);
|
|
132
|
+
width: 10px;
|
|
133
|
+
flex-grow: 1;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
#scan-button {
|
|
137
|
+
display: block;
|
|
138
|
+
width: 30px;
|
|
139
|
+
height: 100%;
|
|
140
|
+
min-height: 24px;
|
|
141
|
+
border: none;
|
|
142
|
+
background-color: transparent;
|
|
143
|
+
background-repeat: no-repeat;
|
|
144
|
+
background-position: center;
|
|
145
|
+
background-image: var(--barcodescan-input-button-icon);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#scan-button[hidden] {
|
|
149
|
+
display: none;
|
|
150
|
+
}
|
|
151
|
+
`
|
|
152
|
+
];
|
|
153
|
+
__decorate([
|
|
154
|
+
property({ type: String, attribute: true }),
|
|
155
|
+
__metadata("design:type", String)
|
|
156
|
+
], BarcodeScanableInput.prototype, "name", void 0);
|
|
157
|
+
__decorate([
|
|
158
|
+
property({ type: Boolean }),
|
|
159
|
+
__metadata("design:type", Boolean)
|
|
160
|
+
], BarcodeScanableInput.prototype, "scannable", void 0);
|
|
161
|
+
__decorate([
|
|
162
|
+
property({ type: Boolean, attribute: 'without-enter' }),
|
|
163
|
+
__metadata("design:type", Boolean)
|
|
164
|
+
], BarcodeScanableInput.prototype, "withoutEnter", void 0);
|
|
165
|
+
__decorate([
|
|
166
|
+
property({ type: String }),
|
|
167
|
+
__metadata("design:type", String)
|
|
168
|
+
], BarcodeScanableInput.prototype, "value", void 0);
|
|
169
|
+
__decorate([
|
|
170
|
+
query('input'),
|
|
171
|
+
__metadata("design:type", HTMLInputElement)
|
|
172
|
+
], BarcodeScanableInput.prototype, "input", void 0);
|
|
173
|
+
BarcodeScanableInput = __decorate([
|
|
174
|
+
customElement('barcode-scanable-input')
|
|
175
|
+
], BarcodeScanableInput);
|
|
176
|
+
export { BarcodeScanableInput };
|
|
177
|
+
//# sourceMappingURL=barcode-scanable-input.js.map
|