@operato/input 0.2.35 → 0.2.42

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 (46) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/demo/index-3dish.html +15 -2
  3. package/demo/index-angle.html +9 -4
  4. package/demo/index-barcode.html +66 -0
  5. package/demo/index-button-radio.html +18 -6
  6. package/demo/index-checkbox.html +17 -9
  7. package/demo/index-select.html +118 -0
  8. package/demo/index-stack.html +15 -3
  9. package/demo/index.html +42 -86
  10. package/dist/src/ox-buttons-radio.d.ts +7 -5
  11. package/dist/src/ox-buttons-radio.js +18 -10
  12. package/dist/src/ox-buttons-radio.js.map +1 -1
  13. package/dist/src/ox-checkbox.d.ts +5 -6
  14. package/dist/src/ox-checkbox.js +33 -33
  15. package/dist/src/ox-checkbox.js.map +1 -1
  16. package/dist/src/ox-formfield.d.ts +10 -0
  17. package/dist/src/ox-formfield.js +38 -0
  18. package/dist/src/ox-formfield.js.map +1 -0
  19. package/dist/src/ox-input-3dish.d.ts +15 -14
  20. package/dist/src/ox-input-3dish.js +49 -23
  21. package/dist/src/ox-input-3dish.js.map +1 -1
  22. package/dist/src/ox-input-angle.d.ts +4 -5
  23. package/dist/src/ox-input-angle.js +15 -13
  24. package/dist/src/ox-input-angle.js.map +1 -1
  25. package/dist/src/ox-input-barcode.d.ts +22 -0
  26. package/dist/src/ox-input-barcode.js +205 -0
  27. package/dist/src/ox-input-barcode.js.map +1 -0
  28. package/dist/src/ox-input-stack.d.ts +5 -3
  29. package/dist/src/ox-input-stack.js +44 -35
  30. package/dist/src/ox-input-stack.js.map +1 -1
  31. package/dist/src/ox-select.d.ts +5 -4
  32. package/dist/src/ox-select.js +34 -12
  33. package/dist/src/ox-select.js.map +1 -1
  34. package/dist/test/property-angle.test.js +3 -3
  35. package/dist/test/property-angle.test.js.map +1 -1
  36. package/dist/tsconfig.tsbuildinfo +1 -1
  37. package/package.json +4 -3
  38. package/src/ox-buttons-radio.ts +22 -10
  39. package/src/ox-checkbox.ts +37 -33
  40. package/src/ox-formfield.ts +36 -0
  41. package/src/ox-input-3dish.ts +63 -29
  42. package/src/ox-input-angle.ts +19 -14
  43. package/src/ox-input-barcode.ts +203 -0
  44. package/src/ox-input-stack.ts +49 -24
  45. package/src/ox-select.ts +46 -16
  46. package/test/property-angle.test.ts +3 -4
@@ -2,28 +2,30 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
  import { __decorate } from "tslib";
5
- import { css, html, LitElement } from 'lit';
5
+ import { css, html } from 'lit';
6
6
  import { customElement, property, query } from 'lit/decorators.js';
7
- let OxInputAngle = class OxInputAngle extends LitElement {
7
+ import { OxFormField } from './ox-formfield';
8
+ let OxInputAngle = class OxInputAngle extends OxFormField {
8
9
  render() {
9
10
  return html `
10
11
  <input
11
12
  type="number"
12
- .value=${this._toDegree(this.radian)}
13
+ .value=${this._toDegree(this.value)}
14
+ .placeholder=${this.placeholder || '0°'}
13
15
  @change=${(e) => this._onChangeValue(e)}
14
- .placeholder=${this.placeholder}
15
16
  />
16
17
  `;
17
18
  }
18
- get placeholder() {
19
- return this.getAttribute('placeholder') || '0°';
20
- }
21
19
  _onChangeValue(e) {
22
- this.radian = this._toRadian(this.input.value);
23
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
20
+ this.value = this._toRadian(this.input.value);
21
+ this.dispatchEvent(new CustomEvent('change', {
22
+ bubbles: true,
23
+ composed: true,
24
+ detail: this.value
25
+ }));
24
26
  }
25
- _toDegree(radian) {
26
- return Math.round(((Number(radian) || 0) * 180) / Math.PI);
27
+ _toDegree(value) {
28
+ return Math.round(((Number(value) || 0) * 180) / Math.PI);
27
29
  }
28
30
  _toRadian(degree) {
29
31
  return isNaN(Number(degree)) ? undefined : Number(degree) * (Math.PI / 180);
@@ -44,8 +46,8 @@ OxInputAngle.styles = [
44
46
  `
45
47
  ];
46
48
  __decorate([
47
- property({ type: Number })
48
- ], OxInputAngle.prototype, "radian", void 0);
49
+ property({ type: String })
50
+ ], OxInputAngle.prototype, "placeholder", void 0);
49
51
  __decorate([
50
52
  query('input')
51
53
  ], OxInputAngle.prototype, "input", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"ox-input-angle.js","sourceRoot":"","sources":["../../src/ox-input-angle.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGlE,IAAa,YAAY,GAAzB,MAAa,YAAa,SAAQ,UAAU;IAmB1C,MAAM;QACJ,OAAO,IAAI,CAAA;;;iBAGE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;kBAC1B,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;uBAC/B,IAAI,CAAC,WAAW;;KAElC,CAAA;IACH,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,IAAI,CAAA;IACjD,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAE9C,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAClF,CAAC;IAED,SAAS,CAAC,MAAmC;QAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAA;IAC5D,CAAC;IAED,SAAS,CAAC,MAAmC;QAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,CAAA;IAC7E,CAAC;CACF,CAAA;AA9CQ,mBAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;KAWF;CACF,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CAAyB;AACpC;IAAf,KAAK,CAAC,OAAO,CAAC;2CAAyB;AAjB7B,YAAY;IADxB,aAAa,CAAC,gBAAgB,CAAC;GACnB,YAAY,CA+CxB;SA/CY,YAAY","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\n@customElement('ox-input-angle')\nexport class OxInputAngle extends LitElement {\n static styles = [\n css`\n :host {\n display: inline-block;\n }\n\n input {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n }\n `\n ]\n\n @property({ type: Number }) radian?: string | number\n @query('input') input!: HTMLInputElement\n\n render() {\n return html`\n <input\n type=\"number\"\n .value=${this._toDegree(this.radian)}\n @change=${(e: Event) => this._onChangeValue(e)}\n .placeholder=${this.placeholder}\n />\n `\n }\n\n get placeholder() {\n return this.getAttribute('placeholder') || '0°'\n }\n\n _onChangeValue(e: Event) {\n this.radian = this._toRadian(this.input.value)\n\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n }\n\n _toDegree(radian: string | number | undefined) {\n return Math.round(((Number(radian) || 0) * 180) / Math.PI)\n }\n\n _toRadian(degree: string | number | undefined) {\n return isNaN(Number(degree)) ? undefined : Number(degree) * (Math.PI / 180)\n }\n}\n"]}
1
+ {"version":3,"file":"ox-input-angle.js","sourceRoot":"","sources":["../../src/ox-input-angle.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG5C,IAAa,YAAY,GAAzB,MAAa,YAAa,SAAQ,WAAW;IAoB3C,MAAM;QACJ,OAAO,IAAI,CAAA;;;iBAGE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;uBACpB,IAAI,CAAC,WAAW,IAAI,IAAI;kBAC7B,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;;KAEjD,CAAA;IACH,CAAC;IAED,cAAc,CAAC,CAAQ;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAE7C,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,QAAQ,EAAE;YACxB,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,IAAI,CAAC,KAAK;SACnB,CAAC,CACH,CAAA;IACH,CAAC;IAED,SAAS,CAAC,KAAkC;QAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED,SAAS,CAAC,MAAmC;QAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,CAAA;IAC7E,CAAC;CACF,CAAA;AAjDQ,mBAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;KAWF;CACF,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iDAAqB;AAEhC;IAAf,KAAK,CAAC,OAAO,CAAC;2CAAyB;AAlB7B,YAAY;IADxB,aAAa,CAAC,gBAAgB,CAAC;GACnB,YAAY,CAkDxB;SAlDY,YAAY","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { OxFormField } from './ox-formfield'\n\n@customElement('ox-input-angle')\nexport class OxInputAngle extends OxFormField {\n static styles = [\n css`\n :host {\n display: inline-block;\n }\n\n input {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n }\n `\n ]\n\n @property({ type: String }) placeholder?: string\n\n @query('input') input!: HTMLInputElement\n\n render() {\n return html`\n <input\n type=\"number\"\n .value=${this._toDegree(this.value)}\n .placeholder=${this.placeholder || '0°'}\n @change=${(e: Event) => this._onChangeValue(e)}\n />\n `\n }\n\n _onChangeValue(e: Event) {\n this.value = this._toRadian(this.input.value)\n\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: this.value\n })\n )\n }\n\n _toDegree(value: string | number | undefined) {\n return Math.round(((Number(value) || 0) * 180) / Math.PI)\n }\n\n _toRadian(degree: string | number | undefined) {\n return isNaN(Number(degree)) ? undefined : Number(degree) * (Math.PI / 180)\n }\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import '@operato/popup';
2
+ import { OxPopup } from '@operato/popup';
3
+ import { BrowserMultiFormatReader } from '@zxing/library';
4
+ import { OxFormField } from './ox-formfield';
5
+ export declare class OxInputBarcode extends OxFormField {
6
+ static styles: import("lit").CSSResult[];
7
+ name?: string;
8
+ scannable?: boolean;
9
+ withoutEnter?: boolean;
10
+ value?: string;
11
+ stream?: MediaStream;
12
+ reader?: BrowserMultiFormatReader;
13
+ input: HTMLInputElement;
14
+ popup: OxPopup;
15
+ video: HTMLVideoElement;
16
+ connectedCallback(): void;
17
+ disconnectedCallback(): void;
18
+ render(): import("lit-html").TemplateResult<1>;
19
+ onChange(e: Event): void;
20
+ scan(e: MouseEvent): Promise<void>;
21
+ stopScan(): void;
22
+ }
@@ -0,0 +1,205 @@
1
+ import { __decorate } from "tslib";
2
+ import '@operato/popup';
3
+ import { css, html } from 'lit';
4
+ import { customElement, property, query, state } from 'lit/decorators.js';
5
+ import { BrowserMultiFormatReader } from '@zxing/library';
6
+ import { OxFormField } from './ox-formfield';
7
+ const barcodeIcon = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAYBAMAAAAfR1CMAAADKGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFNjM4RURDQkQ1OUExMUU5QkExMkQ4NUY3NkMxNzBFOSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFNjM4RURDQ0Q1OUExMUU5QkExMkQ4NUY3NkMxNzBFOSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU2MzhFREM5RDU5QTExRTlCQTEyRDg1Rjc2QzE3MEU5IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU2MzhFRENBRDU5QTExRTlCQTEyRDg1Rjc2QzE3MEU5Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+55pr/QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAkUExURQAAAEdwTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEus/7UCWQwAAAALdFJOU9YAg3wKBFBDSz9PnvQNDgAAAE9JREFUGNNjEEQFDKLJSnCOklkgg9QUJFn3RgZhRyS+iCGDEIp2RSBfQICRkRGIgTSQL4jCF6ScvxsZYOFT2T50/6D7Fz080MMLPTzRwhsAHVspfelur08AAAAASUVORK5CYII=`;
8
+ let OxInputBarcode = class OxInputBarcode extends OxFormField {
9
+ connectedCallback() {
10
+ super.connectedCallback();
11
+ this.scannable = false;
12
+ if (navigator.mediaDevices) {
13
+ ;
14
+ (async () => {
15
+ try {
16
+ var stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } });
17
+ if (stream) {
18
+ stream.getTracks().forEach(track => track.stop());
19
+ this.scannable = true;
20
+ }
21
+ }
22
+ catch (e) {
23
+ console.warn('this device not support camera for barcode scan', e);
24
+ }
25
+ })();
26
+ }
27
+ }
28
+ disconnectedCallback() {
29
+ this.stopScan();
30
+ }
31
+ render() {
32
+ this.style.setProperty('--barcodescan-input-button-icon', `url(${barcodeIcon})`);
33
+ return html `
34
+ <input type="text" .value=${this.value || ''} maxlength="50" @change=${(e) => this.onChange(e)} />
35
+ <button
36
+ ?hidden=${!this.scannable}
37
+ id="scan-button"
38
+ @click=${(e) => {
39
+ this.scan(e);
40
+ }}
41
+ ></button>
42
+
43
+ <ox-popup
44
+ @focusout=${() => {
45
+ this.stopScan();
46
+ }}
47
+ >
48
+ <video></video>
49
+ </ox-popup>
50
+ `;
51
+ }
52
+ onChange(e) {
53
+ var _a;
54
+ this.value = (_a = e.target) === null || _a === void 0 ? void 0 : _a.value;
55
+ //@ts-ignore
56
+ this.dispatchEvent(new e.constructor(e.type, e));
57
+ }
58
+ async scan(e) {
59
+ try {
60
+ this.popup.open({});
61
+ /* template.video가 생성된 후에 접근하기 위해서, 한 프레임을 강제로 건너뛴다. */
62
+ await this.updateComplete;
63
+ var constraints = { video: { facingMode: 'environment' } }; /* backside camera first */
64
+ this.stream = await navigator.mediaDevices.getUserMedia(constraints);
65
+ this.reader = new BrowserMultiFormatReader();
66
+ if (getComputedStyle(this.popup).display !== 'none' /* popup not hidden */ && this.stream) {
67
+ var result = await this.reader.decodeOnceFromStream(this.stream, this.video);
68
+ var input = this.input;
69
+ input.focus();
70
+ input.value = String(result);
71
+ if (!this.withoutEnter) {
72
+ input.dispatchEvent(new KeyboardEvent('keypress', { keyCode: 0x0d }));
73
+ input.dispatchEvent(new CustomEvent('change', {
74
+ bubbles: true,
75
+ composed: true,
76
+ detail: String(result)
77
+ }));
78
+ }
79
+ }
80
+ else {
81
+ /* popup이 비동기 진행 중에 close된 경우라면, stopScan()을 처리하지 못하게 되므로, 다시한번 clear해준다. */
82
+ this.stopScan();
83
+ }
84
+ }
85
+ catch (err) {
86
+ /*
87
+ * 1. stream device 문제로 예외 발생한 경우.
88
+ * 2. 뒤로가기 등으로 popup이 종료된 경우에도 NotFoundException: Video stream has ended before any code could be detected. 이 발생한다.
89
+ */
90
+ console.warn(err);
91
+ }
92
+ finally {
93
+ this.popup.close();
94
+ this.stopScan();
95
+ }
96
+ }
97
+ stopScan() {
98
+ this.video.pause();
99
+ this.stream && this.stream.getTracks().forEach(track => track.stop());
100
+ this.reader && this.reader.reset();
101
+ delete this.stream;
102
+ delete this.reader;
103
+ }
104
+ };
105
+ OxInputBarcode.styles = [
106
+ css `
107
+ :host {
108
+ display: flex;
109
+ align-items: center;
110
+ border: none;
111
+ overflow: hidden;
112
+ background-color: #fff;
113
+
114
+ padding: var(--custom-input-barcode-field-padding) !important;
115
+ }
116
+
117
+ * {
118
+ align-self: stretch;
119
+ }
120
+
121
+ *:focus {
122
+ outline: none;
123
+ }
124
+
125
+ input {
126
+ flex: 1 !important;
127
+ border: none;
128
+ font: var(--custom-input-barcode-field-font);
129
+ width: 10px;
130
+ flex-grow: 1;
131
+ }
132
+
133
+ #scan-button {
134
+ display: block;
135
+ width: 30px;
136
+ height: 100%;
137
+ min-height: 24px;
138
+ border: none;
139
+ background-color: transparent;
140
+ background-repeat: no-repeat;
141
+ background-position: center;
142
+ background-image: var(--barcodescan-input-button-icon);
143
+ }
144
+
145
+ #scan-button[hidden] {
146
+ display: none;
147
+ }
148
+
149
+ ox-popup {
150
+ position: fixed;
151
+
152
+ width: 80vw;
153
+ height: 80vh;
154
+ transform: translate(10%, 10%);
155
+ }
156
+
157
+ video {
158
+ width: 100%;
159
+ height: 100%;
160
+ }
161
+
162
+ @media screen and (max-width: 460px) {
163
+ ox-popup {
164
+ position: fixed;
165
+ left: 0;
166
+ top: 0;
167
+ width: 100vw;
168
+ height: 100vh;
169
+ transform: translate(0%, 0%);
170
+ }
171
+ }
172
+ `
173
+ ];
174
+ __decorate([
175
+ property({ type: String, attribute: true })
176
+ ], OxInputBarcode.prototype, "name", void 0);
177
+ __decorate([
178
+ property({ type: Boolean })
179
+ ], OxInputBarcode.prototype, "scannable", void 0);
180
+ __decorate([
181
+ property({ attribute: 'without-enter', type: Boolean })
182
+ ], OxInputBarcode.prototype, "withoutEnter", void 0);
183
+ __decorate([
184
+ property({ type: String })
185
+ ], OxInputBarcode.prototype, "value", void 0);
186
+ __decorate([
187
+ state()
188
+ ], OxInputBarcode.prototype, "stream", void 0);
189
+ __decorate([
190
+ state()
191
+ ], OxInputBarcode.prototype, "reader", void 0);
192
+ __decorate([
193
+ query('input')
194
+ ], OxInputBarcode.prototype, "input", void 0);
195
+ __decorate([
196
+ query('ox-popup')
197
+ ], OxInputBarcode.prototype, "popup", void 0);
198
+ __decorate([
199
+ query('video')
200
+ ], OxInputBarcode.prototype, "video", void 0);
201
+ OxInputBarcode = __decorate([
202
+ customElement('ox-input-barcode')
203
+ ], OxInputBarcode);
204
+ export { OxInputBarcode };
205
+ //# sourceMappingURL=ox-input-barcode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-input-barcode.js","sourceRoot":"","sources":["../../src/ox-input-barcode.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/popup'\n\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { OxPopup } from '@operato/popup'\nimport { BrowserMultiFormatReader } from '@zxing/library'\n\nimport { OxFormField } from './ox-formfield'\n\nconst barcodeIcon = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAYBAMAAAAfR1CMAAADKGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFNjM4RURDQkQ1OUExMUU5QkExMkQ4NUY3NkMxNzBFOSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFNjM4RURDQ0Q1OUExMUU5QkExMkQ4NUY3NkMxNzBFOSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU2MzhFREM5RDU5QTExRTlCQTEyRDg1Rjc2QzE3MEU5IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU2MzhFRENBRDU5QTExRTlCQTEyRDg1Rjc2QzE3MEU5Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+55pr/QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAkUExURQAAAEdwTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEus/7UCWQwAAAALdFJOU9YAg3wKBFBDSz9PnvQNDgAAAE9JREFUGNNjEEQFDKLJSnCOklkgg9QUJFn3RgZhRyS+iCGDEIp2RSBfQICRkRGIgTSQL4jCF6ScvxsZYOFT2T50/6D7Fz080MMLPTzRwhsAHVspfelur08AAAAASUVORK5CYII=`\n\n@customElement('ox-input-barcode')\nexport class OxInputBarcode extends OxFormField {\n static styles = [\n css`\n :host {\n display: flex;\n align-items: center;\n border: none;\n overflow: hidden;\n background-color: #fff;\n\n padding: var(--custom-input-barcode-field-padding) !important;\n }\n\n * {\n align-self: stretch;\n }\n\n *:focus {\n outline: none;\n }\n\n input {\n flex: 1 !important;\n border: none;\n font: var(--custom-input-barcode-field-font);\n width: 10px;\n flex-grow: 1;\n }\n\n #scan-button {\n display: block;\n width: 30px;\n height: 100%;\n min-height: 24px;\n border: none;\n background-color: transparent;\n background-repeat: no-repeat;\n background-position: center;\n background-image: var(--barcodescan-input-button-icon);\n }\n\n #scan-button[hidden] {\n display: none;\n }\n\n ox-popup {\n position: fixed;\n\n width: 80vw;\n height: 80vh;\n transform: translate(10%, 10%);\n }\n\n video {\n width: 100%;\n height: 100%;\n }\n\n @media screen and (max-width: 460px) {\n ox-popup {\n position: fixed;\n left: 0;\n top: 0;\n width: 100vw;\n height: 100vh;\n transform: translate(0%, 0%);\n }\n }\n `\n ]\n\n @property({ type: String, attribute: true }) name?: string\n @property({ type: Boolean }) scannable?: boolean\n @property({ attribute: 'without-enter', type: Boolean }) withoutEnter?: boolean\n @property({ type: String }) value?: string\n\n @state() stream?: MediaStream\n @state() reader?: BrowserMultiFormatReader\n\n @query('input') input!: HTMLInputElement\n @query('ox-popup') popup!: OxPopup\n @query('video') video!: HTMLVideoElement\n\n connectedCallback() {\n super.connectedCallback()\n\n this.scannable = false\n\n if (navigator.mediaDevices) {\n ;(async () => {\n try {\n var stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })\n if (stream) {\n stream.getTracks().forEach(track => track.stop())\n this.scannable = true\n }\n } catch (e) {\n console.warn('this device not support camera for barcode scan', e)\n }\n })()\n }\n }\n\n disconnectedCallback() {\n this.stopScan()\n }\n\n render() {\n this.style.setProperty('--barcodescan-input-button-icon', `url(${barcodeIcon})`)\n\n return html`\n <input type=\"text\" .value=${this.value || ''} maxlength=\"50\" @change=${(e: Event) => this.onChange(e)} />\n <button\n ?hidden=${!this.scannable}\n id=\"scan-button\"\n @click=${(e: MouseEvent) => {\n this.scan(e)\n }}\n ></button>\n\n <ox-popup\n @focusout=${() => {\n this.stopScan()\n }}\n >\n <video></video>\n </ox-popup>\n `\n }\n\n onChange(e: Event) {\n this.value = (e.target as HTMLInputElement)?.value\n //@ts-ignore\n this.dispatchEvent(new e.constructor(e.type, e))\n }\n\n async scan(e: MouseEvent) {\n try {\n this.popup.open({})\n\n /* template.video가 생성된 후에 접근하기 위해서, 한 프레임을 강제로 건너뛴다. */\n await this.updateComplete\n\n var constraints = { video: { facingMode: 'environment' } } /* backside camera first */\n this.stream = await navigator.mediaDevices.getUserMedia(constraints)\n\n this.reader = new BrowserMultiFormatReader()\n if (getComputedStyle(this.popup).display !== 'none' /* popup not hidden */ && this.stream) {\n var result = await this.reader.decodeOnceFromStream(this.stream, this.video)\n var input = this.input\n input.focus()\n input.value = String(result)\n\n if (!this.withoutEnter) {\n input.dispatchEvent(new KeyboardEvent('keypress', { keyCode: 0x0d }))\n input.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: String(result)\n })\n )\n }\n } else {\n /* popup이 비동기 진행 중에 close된 경우라면, stopScan()을 처리하지 못하게 되므로, 다시한번 clear해준다. */\n this.stopScan()\n }\n } catch (err) {\n /*\n * 1. stream device 문제로 예외 발생한 경우.\n * 2. 뒤로가기 등으로 popup이 종료된 경우에도 NotFoundException: Video stream has ended before any code could be detected. 이 발생한다.\n */\n console.warn(err)\n } finally {\n this.popup.close()\n\n this.stopScan()\n }\n }\n\n stopScan() {\n this.video.pause()\n\n this.stream && this.stream.getTracks().forEach(track => track.stop())\n this.reader && this.reader.reset()\n\n delete this.stream\n delete this.reader\n }\n}\n"]}
@@ -1,21 +1,23 @@
1
1
  /**
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
- import { LitElement } from 'lit';
5
- export default class OxStack extends LitElement {
4
+ import { OxFormField } from './ox-formfield';
5
+ export default class OxInputStack extends OxFormField {
6
6
  static styles: import("lit").CSSResult[];
7
7
  /**
8
8
  * `stack`은 stack에 의해 만들어진 층의 배열을 유지한다.
9
9
  */
10
10
  stack: {
11
11
  name: string;
12
+ active?: boolean;
12
13
  }[];
13
14
  /**
14
15
  * `activeIndex`은 현재 active된 층의 인덱스를 유지한다.
15
16
  */
16
- activeIndex: number;
17
17
  render(): import("lit-html").TemplateResult<1>;
18
+ _notifyChange(): void;
18
19
  _onClickAddFloor(e: Event): void;
19
20
  _onClickToActive(e: Event): void;
20
21
  _onClickRemoveFloor(e: Event): void;
22
+ protected appendFormData({ formData }: FormDataEvent): void;
21
23
  }
@@ -2,20 +2,21 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
  import { __decorate } from "tslib";
5
- import { css, html, LitElement } from 'lit';
5
+ import { css, html } from 'lit';
6
6
  import { customElement, property } from 'lit/decorators.js';
7
- let OxStack = class OxStack extends LitElement {
7
+ import { OxFormField } from './ox-formfield';
8
+ let OxInputStack = class OxInputStack extends OxFormField {
8
9
  constructor() {
9
10
  super(...arguments);
10
11
  /**
11
12
  * `stack`은 stack에 의해 만들어진 층의 배열을 유지한다.
12
13
  */
13
14
  this.stack = [];
14
- /**
15
- * `activeIndex`은 현재 active된 층의 인덱스를 유지한다.
16
- */
17
- this.activeIndex = 0;
18
15
  }
16
+ /**
17
+ * `activeIndex`은 현재 active된 층의 인덱스를 유지한다.
18
+ */
19
+ // @property({ type: Number }) activeIndex: number = 0
19
20
  render() {
20
21
  const stack = [...this.stack].reverse();
21
22
  const length = stack.length;
@@ -23,47 +24,58 @@ let OxStack = class OxStack extends LitElement {
23
24
  <button id="add-floor" @click=${(e) => this._onClickAddFloor(e)}>+</button>
24
25
 
25
26
  ${stack.map((item, index) => html `
26
- <div
27
- ?active=${length - index - 1 == this.activeIndex}
28
- @click=${(e) => this._onClickToActive(e)}
29
- idx=${length - index - 1}
30
- >
27
+ <div floor ?active=${item.active} @click=${(e) => this._onClickToActive(e)} idx=${length - index - 1}>
31
28
  ${item.name} <button @click=${(e) => this._onClickRemoveFloor(e)}>-</button>
32
29
  </div>
33
30
  `)}
34
31
  `;
35
32
  }
33
+ _notifyChange() {
34
+ this.value = this.stack;
35
+ this.dispatchEvent(new CustomEvent('change', {
36
+ detail: this.value,
37
+ bubbles: true,
38
+ composed: true
39
+ }));
40
+ }
36
41
  _onClickAddFloor(e) {
37
42
  this.stack.push({ name: String(this.stack.length + 1) });
38
43
  this.requestUpdate();
44
+ this._notifyChange();
39
45
  }
40
46
  _onClickToActive(e) {
41
- const div = e.target;
42
- if (div.tagName != 'DIV') {
47
+ const floor = e.target.closest('[floor]');
48
+ if (!floor) {
43
49
  return;
44
50
  }
45
- this.activeIndex = Number(div.getAttribute('idx'));
51
+ e.stopPropagation();
52
+ const activeIndex = Number(floor.getAttribute('idx'));
53
+ this.stack = this.stack.map((floor, index) => {
54
+ return activeIndex === index
55
+ ? {
56
+ name: floor.name,
57
+ active: true
58
+ }
59
+ : { name: floor.name };
60
+ });
61
+ this._notifyChange();
46
62
  }
47
63
  _onClickRemoveFloor(e) {
48
- const div = e.target.parentElement;
49
- if ((div === null || div === void 0 ? void 0 : div.tagName) != 'DIV') {
64
+ const floor = e.target.closest('[floor]');
65
+ if (!floor) {
50
66
  return;
51
67
  }
52
- const idx = Number(div.getAttribute('idx'));
68
+ e.stopPropagation();
69
+ const idx = Number(floor.getAttribute('idx'));
53
70
  this.stack.splice(idx, 1);
54
- if (this.activeIndex == idx) {
55
- this.activeIndex = 0;
56
- }
57
- else if (this.activeIndex >= idx) {
58
- this.activeIndex--;
59
- }
60
- else if (this.activeIndex >= this.stack.length) {
61
- this.activeIndex = 0;
62
- }
63
71
  this.requestUpdate();
72
+ this._notifyChange();
73
+ }
74
+ appendFormData({ formData }) {
75
+ this.name && formData.append(this.name, JSON.stringify(this.value));
64
76
  }
65
77
  };
66
- OxStack.styles = [
78
+ OxInputStack.styles = [
67
79
  css `
68
80
  :host {
69
81
  display: block;
@@ -97,12 +109,9 @@ OxStack.styles = [
97
109
  ];
98
110
  __decorate([
99
111
  property({ type: Array })
100
- ], OxStack.prototype, "stack", void 0);
101
- __decorate([
102
- property({ type: Number })
103
- ], OxStack.prototype, "activeIndex", void 0);
104
- OxStack = __decorate([
105
- customElement('ox-stack')
106
- ], OxStack);
107
- export default OxStack;
112
+ ], OxInputStack.prototype, "stack", void 0);
113
+ OxInputStack = __decorate([
114
+ customElement('ox-input-stack')
115
+ ], OxInputStack);
116
+ export default OxInputStack;
108
117
  //# sourceMappingURL=ox-input-stack.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ox-input-stack.js","sourceRoot":"","sources":["../../src/ox-input-stack.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n@customElement('ox-stack')\nexport default class OxStack extends LitElement {\n static styles = [\n css`\n :host {\n display: block;\n }\n\n #add-floor {\n width: 100%;\n height: 20px;\n background-color: blue;\n color: white;\n }\n\n div {\n background-color: blue;\n width: calc(100% - 40px);\n width: -webkit-calc(100% - 40px);\n min-height: 20px;\n }\n\n div[active] {\n background-color: red;\n }\n\n div button {\n position: absolute;\n right: 10px;\n width: 30px;\n min-height: 20px;\n }\n `\n ]\n\n /**\n * `stack`은 stack에 의해 만들어진 층의 배열을 유지한다.\n */\n @property({ type: Array }) stack: { name: string }[] = []\n\n /**\n * `activeIndex`은 현재 active된 층의 인덱스를 유지한다.\n */\n @property({ type: Number }) activeIndex: number = 0\n\n render() {\n const stack = [...this.stack].reverse()\n const length = stack.length\n\n return html`\n <button id=\"add-floor\" @click=${(e: Event) => this._onClickAddFloor(e)}>+</button>\n\n ${stack.map(\n (item, index) => html`\n <div\n ?active=${length - index - 1 == this.activeIndex}\n @click=${(e: Event) => this._onClickToActive(e)}\n idx=${length - index - 1}\n >\n ${item.name} <button @click=${(e: Event) => this._onClickRemoveFloor(e)}>-</button>\n </div>\n `\n )}\n `\n }\n\n _onClickAddFloor(e: Event) {\n this.stack.push({ name: String(this.stack.length + 1) })\n this.requestUpdate()\n }\n\n _onClickToActive(e: Event) {\n const div = e.target as HTMLElement\n if (div.tagName != 'DIV') {\n return\n }\n\n this.activeIndex = Number(div.getAttribute('idx'))\n }\n\n _onClickRemoveFloor(e: Event) {\n const div = (e.target as HTMLElement).parentElement\n\n if (div?.tagName != 'DIV') {\n return\n }\n\n const idx = Number(div.getAttribute('idx'))\n\n this.stack.splice(idx, 1)\n\n if (this.activeIndex == idx) {\n this.activeIndex = 0\n } else if (this.activeIndex >= idx) {\n this.activeIndex--\n } else if (this.activeIndex >= this.stack.length) {\n this.activeIndex = 0\n }\n\n this.requestUpdate()\n }\n}\n"]}
1
+ {"version":3,"file":"ox-input-stack.js","sourceRoot":"","sources":["../../src/ox-input-stack.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { OxFormField } from './ox-formfield'\n\n@customElement('ox-input-stack')\nexport default class OxInputStack extends OxFormField {\n static styles = [\n css`\n :host {\n display: block;\n }\n\n #add-floor {\n width: 100%;\n height: 20px;\n background-color: blue;\n color: white;\n }\n\n div {\n background-color: blue;\n width: calc(100% - 40px);\n width: -webkit-calc(100% - 40px);\n min-height: 20px;\n }\n\n div[active] {\n background-color: red;\n }\n\n div button {\n position: absolute;\n right: 10px;\n width: 30px;\n min-height: 20px;\n }\n `\n ]\n\n /**\n * `stack`은 stack에 의해 만들어진 층의 배열을 유지한다.\n */\n @property({ type: Array }) stack: { name: string; active?: boolean }[] = []\n\n /**\n * `activeIndex`은 현재 active된 층의 인덱스를 유지한다.\n */\n // @property({ type: Number }) activeIndex: number = 0\n\n render() {\n const stack = [...this.stack].reverse()\n const length = stack.length\n\n return html`\n <button id=\"add-floor\" @click=${(e: Event) => this._onClickAddFloor(e)}>+</button>\n\n ${stack.map(\n (item, index) => html`\n <div floor ?active=${item.active} @click=${(e: Event) => this._onClickToActive(e)} idx=${length - index - 1}>\n ${item.name} <button @click=${(e: Event) => this._onClickRemoveFloor(e)}>-</button>\n </div>\n `\n )}\n `\n }\n\n _notifyChange() {\n this.value = this.stack\n\n this.dispatchEvent(\n new CustomEvent('change', {\n detail: this.value,\n bubbles: true,\n composed: true\n })\n )\n }\n\n _onClickAddFloor(e: Event) {\n this.stack.push({ name: String(this.stack.length + 1) })\n this.requestUpdate()\n\n this._notifyChange()\n }\n\n _onClickToActive(e: Event) {\n const floor = (e.target as HTMLElement).closest('[floor]')\n\n if (!floor) {\n return\n }\n\n e.stopPropagation()\n\n const activeIndex = Number(floor.getAttribute('idx'))\n this.stack = this.stack.map((floor, index) => {\n return activeIndex === index\n ? {\n name: floor.name,\n active: true\n }\n : { name: floor.name }\n })\n\n this._notifyChange()\n }\n\n _onClickRemoveFloor(e: Event) {\n const floor = (e.target as HTMLElement).closest('[floor]')\n\n if (!floor) {\n return\n }\n\n e.stopPropagation()\n\n const idx = Number(floor.getAttribute('idx'))\n\n this.stack.splice(idx, 1)\n\n this.requestUpdate()\n\n this._notifyChange()\n }\n\n protected appendFormData({ formData }: FormDataEvent): void {\n this.name && formData.append(this.name, JSON.stringify(this.value))\n }\n}\n"]}
@@ -3,12 +3,13 @@
3
3
  */
4
4
  import '@material/mwc-icon';
5
5
  import '@operato/popup';
6
- import { LitElement } from 'lit';
7
- export declare class Select extends LitElement {
6
+ import { OxFormField } from './ox-formfield';
7
+ export declare class Select extends OxFormField {
8
8
  static styles: import("lit").CSSResult[];
9
9
  name: string;
10
- label: string;
10
+ placeholder: string;
11
11
  render(): import("lit-html").TemplateResult<1>;
12
+ connectedCallback(): void;
12
13
  expand(): void;
13
- onKeyDown(e: KeyboardEvent): void;
14
+ protected appendFormData({ formData }: FormDataEvent): void;
14
15
  }
@@ -4,44 +4,63 @@
4
4
  import { __decorate } from "tslib";
5
5
  import '@material/mwc-icon';
6
6
  import '@operato/popup';
7
- import { LitElement, css, html } from 'lit';
7
+ import { css, html } from 'lit';
8
8
  import { customElement, property } from 'lit/decorators.js';
9
- let Select = class Select extends LitElement {
9
+ import { OxFormField } from './ox-formfield';
10
+ let Select = class Select extends OxFormField {
10
11
  constructor() {
11
12
  super(...arguments);
12
13
  this.name = '';
13
- this.label = '';
14
+ this.placeholder = '';
14
15
  }
15
16
  render() {
17
+ const label = (this.value instanceof Array ? this.value.join(', ') : this.value) || this.placeholder || '';
16
18
  return html `
17
19
  <div @click=${this.expand}>
18
- <span>${this.label}</span>
20
+ <span>${label}</span>
19
21
  <mwc-icon>expand_more</mwc-icon>
20
22
  </div>
23
+
21
24
  <slot></slot>
22
25
  `;
23
26
  }
27
+ connectedCallback() {
28
+ super.connectedCallback();
29
+ this.setAttribute('tabindex', '0');
30
+ this.addEventListener('select', (e) => {
31
+ this.value = e.detail;
32
+ this.dispatchEvent(new CustomEvent('change', {
33
+ bubbles: true,
34
+ composed: true,
35
+ detail: this.value
36
+ }));
37
+ });
38
+ this.addEventListener('keydown', (e) => {
39
+ e.preventDefault();
40
+ if (e.key === ' ' || e.key == 'Spacebar' || e.key == 'ArrowDown') {
41
+ this.expand();
42
+ }
43
+ });
44
+ }
24
45
  expand() {
25
46
  const popupList = this.querySelector('ox-popup-list');
26
47
  if (popupList) {
27
48
  popupList.style.width = `${this.offsetWidth}px`;
28
49
  popupList.open({
29
- top: this.offsetTop + this.offsetHeight,
30
- left: this.offsetLeft
50
+ top: this.offsetHeight,
51
+ left: 0
31
52
  });
32
53
  }
33
54
  }
34
- onKeyDown(e) {
35
- e.preventDefault();
36
- if (e.keyCode == 32 || e.code == 'Space') {
37
- this.expand();
38
- }
55
+ appendFormData({ formData }) {
56
+ this.name && formData.append(this.name, JSON.stringify(this.value));
39
57
  }
40
58
  };
41
59
  Select.styles = [
42
60
  css `
43
61
  :host {
44
62
  display: block;
63
+ position: relative;
45
64
  }
46
65
 
47
66
  div {
@@ -54,6 +73,9 @@ Select.styles = [
54
73
 
55
74
  span {
56
75
  flex: 1;
76
+ overflow: hidden;
77
+ text-overflow: ellipsis;
78
+ white-space: nowrap;
57
79
  }
58
80
 
59
81
  mwc-icon {
@@ -75,7 +97,7 @@ __decorate([
75
97
  ], Select.prototype, "name", void 0);
76
98
  __decorate([
77
99
  property({ type: String })
78
- ], Select.prototype, "label", void 0);
100
+ ], Select.prototype, "placeholder", void 0);
79
101
  Select = __decorate([
80
102
  customElement('ox-select')
81
103
  ], Select);
@@ -1 +1 @@
1
- {"version":3,"file":"ox-select.js","sourceRoot":"","sources":["../../src/ox-select.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,oBAAoB,CAAA;AAC3B,OAAO,gBAAgB,CAAA;AAEvB,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAS,MAAM,mBAAmB,CAAA;AAMlE,IAAa,MAAM,GAAnB,MAAa,MAAO,SAAQ,UAAU;IAAtC;;QAkC8B,SAAI,GAAW,EAAE,CAAA;QACjB,UAAK,GAAW,EAAE,CAAA;IAgChD,CAAC;IA9BC,MAAM;QACJ,OAAO,IAAI,CAAA;oBACK,IAAI,CAAC,MAAM;gBACf,IAAI,CAAC,KAAK;;;;KAIrB,CAAA;IACH,CAAC;IAED,MAAM;QACJ,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,eAAe,CAAc,CAAA;QAElE,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,CAAA;YAE/C,SAAS,CAAC,IAAI,CAAC;gBACb,GAAG,EAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY;gBACvC,IAAI,EAAE,IAAI,CAAC,UAAU;aACtB,CAAC,CAAA;SACH;IACH,CAAC;IAED,SAAS,CAAC,CAAgB;QACxB,CAAC,CAAC,cAAc,EAAE,CAAA;QAElB,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,EAAE;YACxC,IAAI,CAAC,MAAM,EAAE,CAAA;SACd;IACH,CAAC;CACF,CAAA;AAlEQ,aAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6BF;CACF,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAAkB;AACjB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;qCAAmB;AAnCnC,MAAM;IADlB,aAAa,CAAC,WAAW,CAAC;GACd,MAAM,CAmElB;SAnEY,MAAM","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/mwc-icon'\nimport '@operato/popup'\n\nimport { LitElement, css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { PopupList } from '@operato/popup'\nimport { render } from 'lit-html'\n\n@customElement('ox-select')\nexport class Select extends LitElement {\n static styles = [\n css`\n :host {\n display: block;\n }\n\n div {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n }\n\n span {\n flex: 1;\n }\n\n mwc-icon {\n display: block;\n width: 24px;\n text-align: right;\n font-size: 18px;\n color: var(--theme-primary-text-color, #3c3938);\n opacity: 0.7;\n }\n\n ::slotted(ox-popup-list) {\n width: 100%;\n }\n `\n ]\n\n @property({ type: String }) name: string = ''\n @property({ type: String }) label: string = ''\n\n render() {\n return html`\n <div @click=${this.expand}>\n <span>${this.label}</span>\n <mwc-icon>expand_more</mwc-icon>\n </div>\n <slot></slot>\n `\n }\n\n expand() {\n const popupList = this.querySelector('ox-popup-list') as PopupList\n\n if (popupList) {\n popupList.style.width = `${this.offsetWidth}px`\n\n popupList.open({\n top: this.offsetTop + this.offsetHeight,\n left: this.offsetLeft\n })\n }\n }\n\n onKeyDown(e: KeyboardEvent) {\n e.preventDefault()\n\n if (e.keyCode == 32 || e.code == 'Space') {\n this.expand()\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ox-select.js","sourceRoot":"","sources":["../../src/ox-select.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,oBAAoB,CAAA;AAC3B,OAAO,gBAAgB,CAAA;AAEvB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAI3D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG5C,IAAa,MAAM,GAAnB,MAAa,MAAO,SAAQ,WAAW;IAAvC;;QAsC8B,SAAI,GAAW,EAAE,CAAA;QACjB,gBAAW,GAAW,EAAE,CAAA;IAyDtD,CAAC;IAvDC,MAAM;QACJ,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAA;QAE1G,OAAO,IAAI,CAAA;oBACK,IAAI,CAAC,MAAM;gBACf,KAAK;;;;;KAKhB,CAAA;IACH,CAAC;IAED,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAA;QAEzB,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;QAElC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAQ,EAAE,EAAE;YAC3C,IAAI,CAAC,KAAK,GAAI,CAAiB,CAAC,MAAM,CAAA;YAEtC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,QAAQ,EAAE;gBACxB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,IAAI,CAAC,KAAK;aACnB,CAAC,CACH,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAgB,EAAE,EAAE;YACpD,CAAC,CAAC,cAAc,EAAE,CAAA;YAElB,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,UAAU,IAAI,CAAC,CAAC,GAAG,IAAI,WAAW,EAAE;gBAChE,IAAI,CAAC,MAAM,EAAE,CAAA;aACd;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,MAAM;QACJ,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,eAAe,CAAgB,CAAA;QAEpE,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,CAAA;YAE/C,SAAS,CAAC,IAAI,CAAC;gBACb,GAAG,EAAE,IAAI,CAAC,YAAY;gBACtB,IAAI,EAAE,CAAC;aACR,CAAC,CAAA;SACH;IACH,CAAC;IAES,cAAc,CAAC,EAAE,QAAQ,EAAiB;QAClD,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACrE,CAAC;CACF,CAAA;AA/FQ,aAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiCF;CACF,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAAkB;AACjB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CAAyB;AAvCzC,MAAM;IADlB,aAAa,CAAC,WAAW,CAAC;GACd,MAAM,CAgGlB;SAhGY,MAAM","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/mwc-icon'\nimport '@operato/popup'\n\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { OxPopupList } from '@operato/popup'\n\nimport { OxFormField } from './ox-formfield'\n\n@customElement('ox-select')\nexport class Select extends OxFormField {\n static styles = [\n css`\n :host {\n display: block;\n position: relative;\n }\n\n div {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n }\n\n span {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n mwc-icon {\n display: block;\n width: 24px;\n text-align: right;\n font-size: 18px;\n color: var(--theme-primary-text-color, #3c3938);\n opacity: 0.7;\n }\n\n ::slotted(ox-popup-list) {\n width: 100%;\n }\n `\n ]\n\n @property({ type: String }) name: string = ''\n @property({ type: String }) placeholder: string = ''\n\n render() {\n const label = (this.value instanceof Array ? this.value.join(', ') : this.value) || this.placeholder || ''\n\n return html`\n <div @click=${this.expand}>\n <span>${label}</span>\n <mwc-icon>expand_more</mwc-icon>\n </div>\n\n <slot></slot>\n `\n }\n\n connectedCallback() {\n super.connectedCallback()\n\n this.setAttribute('tabindex', '0')\n\n this.addEventListener('select', (e: Event) => {\n this.value = (e as CustomEvent).detail\n\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: this.value\n })\n )\n })\n\n this.addEventListener('keydown', (e: KeyboardEvent) => {\n e.preventDefault()\n\n if (e.key === ' ' || e.key == 'Spacebar' || e.key == 'ArrowDown') {\n this.expand()\n }\n })\n }\n\n expand() {\n const popupList = this.querySelector('ox-popup-list') as OxPopupList\n\n if (popupList) {\n popupList.style.width = `${this.offsetWidth}px`\n\n popupList.open({\n top: this.offsetHeight,\n left: 0\n })\n }\n }\n\n protected appendFormData({ formData }: FormDataEvent): void {\n this.name && formData.append(this.name, JSON.stringify(this.value))\n }\n}\n"]}