@operato/input 1.17.5 → 2.0.0-alpha.100

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 (199) hide show
  1. package/CHANGELOG.md +269 -20
  2. package/demo/index-multiple-colors.html +14 -2
  3. package/demo/index-partition-keys.html +13 -2
  4. package/demo/index-select.html +20 -9
  5. package/demo/index-table.html +13 -2
  6. package/demo/index.html +13 -2
  7. package/dist/src/locale/locale-picker.d.ts +1 -1
  8. package/dist/src/ox-buttons-radio.d.ts +1 -1
  9. package/dist/src/ox-checkbox.d.ts +5 -4
  10. package/dist/src/ox-checkbox.js +12 -6
  11. package/dist/src/ox-checkbox.js.map +1 -1
  12. package/dist/src/ox-input-3axis.d.ts +1 -1
  13. package/dist/src/ox-input-3dish.d.ts +1 -1
  14. package/dist/src/ox-input-angle.d.ts +1 -1
  15. package/dist/src/ox-input-barcode.d.ts +49 -6
  16. package/dist/src/ox-input-barcode.js +97 -69
  17. package/dist/src/ox-input-barcode.js.map +1 -1
  18. package/dist/src/ox-input-code.d.ts +2 -3
  19. package/dist/src/ox-input-code.js +8 -15
  20. package/dist/src/ox-input-code.js.map +1 -1
  21. package/dist/src/ox-input-color-gradient.d.ts +1 -1
  22. package/dist/src/ox-input-color-stops.d.ts +1 -1
  23. package/dist/src/ox-input-color.d.ts +1 -1
  24. package/dist/src/ox-input-container.d.ts +2 -2
  25. package/dist/src/ox-input-container.js +2 -2
  26. package/dist/src/ox-input-container.js.map +1 -1
  27. package/dist/src/ox-input-crontab.d.ts +1 -2
  28. package/dist/src/ox-input-crontab.js +4 -7
  29. package/dist/src/ox-input-crontab.js.map +1 -1
  30. package/dist/src/ox-input-data.d.ts +1 -1
  31. package/dist/src/ox-input-data.js +2 -2
  32. package/dist/src/ox-input-data.js.map +1 -1
  33. package/dist/src/ox-input-duration.d.ts +1 -2
  34. package/dist/src/ox-input-duration.js +13 -9
  35. package/dist/src/ox-input-duration.js.map +1 -1
  36. package/dist/src/ox-input-file.d.ts +2 -2
  37. package/dist/src/ox-input-file.js +10 -9
  38. package/dist/src/ox-input-file.js.map +1 -1
  39. package/dist/src/ox-input-hashtags.d.ts +1 -1
  40. package/dist/src/ox-input-i18n-label.d.ts +2 -2
  41. package/dist/src/ox-input-i18n-label.js +3 -2
  42. package/dist/src/ox-input-i18n-label.js.map +1 -1
  43. package/dist/src/ox-input-image.d.ts +2 -2
  44. package/dist/src/ox-input-image.js +4 -4
  45. package/dist/src/ox-input-image.js.map +1 -1
  46. package/dist/src/ox-input-key-values.d.ts +2 -2
  47. package/dist/src/ox-input-key-values.js +9 -10
  48. package/dist/src/ox-input-key-values.js.map +1 -1
  49. package/dist/src/ox-input-mass-fraction.d.ts +2 -2
  50. package/dist/src/ox-input-mass-fraction.js +46 -29
  51. package/dist/src/ox-input-mass-fraction.js.map +1 -1
  52. package/dist/src/ox-input-multiple-colors.d.ts +2 -2
  53. package/dist/src/ox-input-multiple-colors.js +7 -7
  54. package/dist/src/ox-input-multiple-colors.js.map +1 -1
  55. package/dist/src/ox-input-options.d.ts +2 -2
  56. package/dist/src/ox-input-options.js +5 -7
  57. package/dist/src/ox-input-options.js.map +1 -1
  58. package/dist/src/ox-input-partition-keys.d.ts +2 -2
  59. package/dist/src/ox-input-partition-keys.js +10 -10
  60. package/dist/src/ox-input-partition-keys.js.map +1 -1
  61. package/dist/src/ox-input-privilege.d.ts +1 -2
  62. package/dist/src/ox-input-privilege.js +15 -31
  63. package/dist/src/ox-input-privilege.js.map +1 -1
  64. package/dist/src/ox-input-quantifier.d.ts +1 -1
  65. package/dist/src/ox-input-scene-component-id.d.ts +1 -1
  66. package/dist/src/ox-input-search.d.ts +2 -2
  67. package/dist/src/ox-input-search.js +5 -4
  68. package/dist/src/ox-input-search.js.map +1 -1
  69. package/dist/src/ox-input-select-buttons.d.ts +1 -1
  70. package/dist/src/ox-input-select-buttons.js +1 -1
  71. package/dist/src/ox-input-select-buttons.js.map +1 -1
  72. package/dist/src/ox-input-stack.d.ts +1 -1
  73. package/dist/src/ox-input-table.d.ts +1 -1
  74. package/dist/src/ox-input-table.js +12 -12
  75. package/dist/src/ox-input-table.js.map +1 -1
  76. package/dist/src/ox-input-textarea.d.ts +1 -1
  77. package/dist/src/ox-input-unit-number.d.ts +2 -2
  78. package/dist/src/ox-input-unit-number.js +5 -4
  79. package/dist/src/ox-input-unit-number.js.map +1 -1
  80. package/dist/src/ox-input-value-map.d.ts +2 -2
  81. package/dist/src/ox-input-value-map.js +17 -17
  82. package/dist/src/ox-input-value-map.js.map +1 -1
  83. package/dist/src/ox-input-value-ranges.d.ts +2 -2
  84. package/dist/src/ox-input-value-ranges.js +22 -17
  85. package/dist/src/ox-input-value-ranges.js.map +1 -1
  86. package/dist/src/ox-input-work-shift.d.ts +1 -1
  87. package/dist/src/ox-input-work-shift.js +4 -8
  88. package/dist/src/ox-input-work-shift.js.map +1 -1
  89. package/dist/src/ox-select.d.ts +2 -2
  90. package/dist/src/ox-select.js +16 -10
  91. package/dist/src/ox-select.js.map +1 -1
  92. package/dist/stories/ox-input-3axis.stories.js +14 -1
  93. package/dist/stories/ox-input-3axis.stories.js.map +1 -1
  94. package/dist/stories/ox-input-3dish.stories.js +14 -1
  95. package/dist/stories/ox-input-3dish.stories.js.map +1 -1
  96. package/dist/stories/ox-input-angle.stories.js +13 -1
  97. package/dist/stories/ox-input-angle.stories.js.map +1 -1
  98. package/dist/stories/ox-input-barcode.stories.js +17 -1
  99. package/dist/stories/ox-input-barcode.stories.js.map +1 -1
  100. package/dist/stories/ox-input-code.stories.d.ts +4 -0
  101. package/dist/stories/ox-input-code.stories.js +18 -3
  102. package/dist/stories/ox-input-code.stories.js.map +1 -1
  103. package/dist/stories/ox-input-crontab.stories.js +13 -1
  104. package/dist/stories/ox-input-crontab.stories.js.map +1 -1
  105. package/dist/stories/ox-input-data.stories.d.ts +0 -4
  106. package/dist/stories/ox-input-data.stories.js +14 -4
  107. package/dist/stories/ox-input-data.stories.js.map +1 -1
  108. package/dist/stories/ox-input-duration.stories.js +13 -1
  109. package/dist/stories/ox-input-duration.stories.js.map +1 -1
  110. package/dist/stories/ox-input-file.stories.js +13 -1
  111. package/dist/stories/ox-input-file.stories.js.map +1 -1
  112. package/dist/stories/ox-input-hashtags.stories.js +13 -1
  113. package/dist/stories/ox-input-hashtags.stories.js.map +1 -1
  114. package/dist/stories/ox-input-i18n-label.stories.js +14 -2
  115. package/dist/stories/ox-input-i18n-label.stories.js.map +1 -1
  116. package/dist/stories/ox-input-key-values.stories.js +13 -1
  117. package/dist/stories/ox-input-key-values.stories.js.map +1 -1
  118. package/dist/stories/ox-input-mass-fraction.stories.js +13 -1
  119. package/dist/stories/ox-input-mass-fraction.stories.js.map +1 -1
  120. package/dist/stories/ox-input-multiple-colors.stories.js +21 -11
  121. package/dist/stories/ox-input-multiple-colors.stories.js.map +1 -1
  122. package/dist/stories/ox-input-options.stories.js +13 -1
  123. package/dist/stories/ox-input-options.stories.js.map +1 -1
  124. package/dist/stories/ox-input-partition-keys.stories.js +13 -1
  125. package/dist/stories/ox-input-partition-keys.stories.js.map +1 -1
  126. package/dist/stories/ox-input-privilege.stories.js +13 -1
  127. package/dist/stories/ox-input-privilege.stories.js.map +1 -1
  128. package/dist/stories/ox-input-quantifier.stories.js +13 -1
  129. package/dist/stories/ox-input-quantifier.stories.js.map +1 -1
  130. package/dist/stories/ox-input-range.stories.js +13 -1
  131. package/dist/stories/ox-input-range.stories.js.map +1 -1
  132. package/dist/stories/ox-input-search.stories.js +13 -1
  133. package/dist/stories/ox-input-search.stories.js.map +1 -1
  134. package/dist/stories/ox-input-select-buttons.stories.js +13 -1
  135. package/dist/stories/ox-input-select-buttons.stories.js.map +1 -1
  136. package/dist/stories/ox-input-unit.stories.js +14 -1
  137. package/dist/stories/ox-input-unit.stories.js.map +1 -1
  138. package/dist/stories/ox-input-value-map.stories.js +13 -1
  139. package/dist/stories/ox-input-value-map.stories.js.map +1 -1
  140. package/dist/stories/ox-input-value-ranges.stories.js +13 -1
  141. package/dist/stories/ox-input-value-ranges.stories.js.map +1 -1
  142. package/dist/stories/ox-input-work-shift.stories.js +13 -1
  143. package/dist/stories/ox-input-work-shift.stories.js.map +1 -1
  144. package/dist/stories/ox-select.stories.js +13 -1
  145. package/dist/stories/ox-select.stories.js.map +1 -1
  146. package/dist/tsconfig.tsbuildinfo +1 -1
  147. package/package.json +22 -22
  148. package/src/ox-checkbox.ts +9 -6
  149. package/src/ox-input-barcode.ts +128 -63
  150. package/src/ox-input-code.ts +6 -13
  151. package/src/ox-input-container.ts +2 -2
  152. package/src/ox-input-crontab.ts +4 -8
  153. package/src/ox-input-data.ts +2 -2
  154. package/src/ox-input-duration.ts +13 -10
  155. package/src/ox-input-file.ts +10 -9
  156. package/src/ox-input-i18n-label.ts +3 -2
  157. package/src/ox-input-image.ts +4 -4
  158. package/src/ox-input-key-values.ts +27 -22
  159. package/src/ox-input-mass-fraction.ts +46 -29
  160. package/src/ox-input-multiple-colors.ts +7 -7
  161. package/src/ox-input-options.ts +5 -7
  162. package/src/ox-input-partition-keys.ts +28 -22
  163. package/src/ox-input-privilege.ts +15 -32
  164. package/src/ox-input-search.ts +5 -4
  165. package/src/ox-input-select-buttons.ts +1 -1
  166. package/src/ox-input-table.ts +12 -12
  167. package/src/ox-input-unit-number.ts +5 -4
  168. package/src/ox-input-value-map.ts +19 -19
  169. package/src/ox-input-value-ranges.ts +24 -19
  170. package/src/ox-input-work-shift.ts +4 -8
  171. package/src/ox-select.ts +16 -10
  172. package/stories/ox-input-3axis.stories.ts +14 -1
  173. package/stories/ox-input-3dish.stories.ts +14 -1
  174. package/stories/ox-input-angle.stories.ts +13 -1
  175. package/stories/ox-input-barcode.stories.ts +17 -1
  176. package/stories/ox-input-code.stories.ts +25 -3
  177. package/stories/ox-input-crontab.stories.ts +13 -1
  178. package/stories/ox-input-data.stories.ts +14 -4
  179. package/stories/ox-input-duration.stories.ts +13 -1
  180. package/stories/ox-input-file.stories.ts +13 -1
  181. package/stories/ox-input-hashtags.stories.ts +13 -1
  182. package/stories/ox-input-i18n-label.stories.ts +14 -2
  183. package/stories/ox-input-key-values.stories.ts +13 -1
  184. package/stories/ox-input-mass-fraction.stories.ts +13 -1
  185. package/stories/ox-input-multiple-colors.stories.ts +21 -11
  186. package/stories/ox-input-options.stories.ts +13 -1
  187. package/stories/ox-input-partition-keys.stories.ts +13 -1
  188. package/stories/ox-input-privilege.stories.ts +13 -1
  189. package/stories/ox-input-quantifier.stories.ts +13 -1
  190. package/stories/ox-input-range.stories.ts +13 -1
  191. package/stories/ox-input-search.stories.ts +13 -1
  192. package/stories/ox-input-select-buttons.stories.ts +13 -1
  193. package/stories/ox-input-unit.stories.ts +14 -1
  194. package/stories/ox-input-value-map.stories.ts +13 -1
  195. package/stories/ox-input-value-ranges.stories.ts +13 -1
  196. package/stories/ox-input-work-shift.stories.ts +13 -1
  197. package/stories/ox-select.stories.ts +13 -1
  198. package/themes/app-theme.css +1 -1
  199. package/themes/input-theme.css +20 -7
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/input",
3
3
  "description": "Webcomponents for input following open-wc recommendations",
4
4
  "author": "heartyoh@hatiolab.com",
5
- "version": "1.17.5",
5
+ "version": "2.0.0-alpha.100",
6
6
  "main": "dist/src/index.js",
7
7
  "module": "dist/src/index.js",
8
8
  "license": "MIT",
@@ -193,39 +193,39 @@
193
193
  "@codemirror/state": "^6.3.3",
194
194
  "@codemirror/theme-one-dark": "^6.1.2",
195
195
  "@codemirror/view": "^6.22.1",
196
- "@lit/localize": "^0.11.2",
197
- "@material/mwc-icon": "^0.27.0",
198
- "@operato/color-picker": "^1.4.64",
199
- "@operato/i18n": "^1.5.14",
200
- "@operato/popup": "^1.17.2",
201
- "@operato/styles": "^1.12.3",
202
- "@operato/utils": "^1.13.9",
196
+ "@lit/localize": "^0.12.1",
197
+ "@material/web": "^1.4.0",
198
+ "@operato/color-picker": "^2.0.0-alpha.57",
199
+ "@operato/i18n": "^2.0.0-alpha.59",
200
+ "@operato/popup": "^2.0.0-alpha.100",
201
+ "@operato/styles": "^2.0.0-alpha.100",
202
+ "@operato/utils": "^2.0.0-alpha.68",
203
203
  "@polymer/paper-dropdown-menu": "^3.2.0",
204
204
  "@polymer/paper-item": "^3.0.1",
205
205
  "@thebespokepixel/es-tinycolor": "^3.1.0",
206
206
  "@types/codemirror": "^5.60.5",
207
- "@zxing/library": "^0.20.0",
207
+ "@undecaf/zbar-wasm": "^0.10.1",
208
208
  "codemirror": "^6.0.1",
209
- "lit": "^2.5.0",
209
+ "lit": "^3.1.2",
210
210
  "lodash-es": "^4.17.21"
211
211
  },
212
212
  "devDependencies": {
213
- "@custom-elements-manifest/analyzer": "^0.8.1",
213
+ "@custom-elements-manifest/analyzer": "^0.9.2",
214
214
  "@hatiolab/prettier-config": "^1.0.0",
215
- "@lit/localize-tools": "^0.6.3",
216
- "@open-wc/eslint-config": "^10.0.0",
215
+ "@lit/localize-tools": "^0.7.2",
216
+ "@open-wc/eslint-config": "^12.0.3",
217
217
  "@open-wc/testing": "^3.1.6",
218
- "@typescript-eslint/eslint-plugin": "^5.59.1",
219
- "@typescript-eslint/parser": "^5.59.1",
218
+ "@typescript-eslint/eslint-plugin": "^7.0.1",
219
+ "@typescript-eslint/parser": "^7.0.1",
220
220
  "@web/dev-server": "^0.3.0",
221
- "@web/dev-server-storybook": "^0.7.4",
222
- "@web/test-runner": "^0.17.0",
221
+ "@web/dev-server-storybook": "^2.0.1",
222
+ "@web/test-runner": "^0.18.0",
223
223
  "concurrently": "^8.0.1",
224
224
  "eslint": "^8.39.0",
225
- "eslint-config-prettier": "^8.3.0",
226
- "husky": "^8.0.1",
227
- "lint-staged": "^13.2.2",
228
- "prettier": "^2.4.1",
225
+ "eslint-config-prettier": "^9.1.0",
226
+ "husky": "^9.0.11",
227
+ "lint-staged": "^15.2.2",
228
+ "prettier": "^3.2.5",
229
229
  "tslib": "^2.3.1",
230
230
  "typescript": "^5.0.4"
231
231
  },
@@ -243,5 +243,5 @@
243
243
  "prettier --write"
244
244
  ]
245
245
  },
246
- "gitHead": "76dc38d183190e7f0874a7e30cd29779cadd86c1"
246
+ "gitHead": "efe5f575ce5241aeb84a0af45915dca63dcce68e"
247
247
  }
@@ -15,12 +15,10 @@ import { OxFormField } from './ox-form-field'
15
15
  export class OxCheckbox extends OxFormField {
16
16
  static styles = [
17
17
  css`
18
- :host {
19
- display: flex;
20
- }
21
-
22
18
  div {
23
19
  display: flex;
20
+ gap: var(--input-intra-gap, 7px);
21
+
24
22
  align-items: center;
25
23
  cursor: pointer;
26
24
  }
@@ -65,7 +63,6 @@ export class OxCheckbox extends OxFormField {
65
63
  }
66
64
 
67
65
  [label] {
68
- margin: var(--ox-checkbox-label-margin, 0 0 0 7px);
69
66
  color: var(--ox-checkbox-label-color, #3a5877);
70
67
  }
71
68
 
@@ -78,16 +75,22 @@ export class OxCheckbox extends OxFormField {
78
75
  @property({ type: Boolean, attribute: 'checked', reflect: true }) checked: boolean | undefined = false
79
76
  @property({ type: Boolean, attribute: 'indeterminatable' }) indeterminatable: boolean = false
80
77
  @property({ type: Boolean, attribute: 'indeterminate', reflect: true }) indeterminate: boolean = false
78
+ @property({ type: Boolean, attribute: 'left-label' }) left: boolean = false
81
79
 
82
80
  @state() _hasInner: boolean = !!this.innerHTML.trim().length
83
81
 
84
82
  render() {
85
83
  return html`
86
84
  <div @click=${this.onClick} ?disabled=${this.disabled}>
85
+ ${this._hasInner && this.left
86
+ ? html` <span label>
87
+ <slot></slot>
88
+ </span>`
89
+ : ''}
87
90
  <a href="#" @click=${(e: Event) => e.preventDefault()} checkbox>
88
91
  ${this.indeterminate ? this.indeterminateIcon : this.checked ? this.checkedIcon : this.uncheckedIcon}
89
92
  </a>
90
- ${this._hasInner
93
+ ${this._hasInner && !this.left
91
94
  ? html` <span label>
92
95
  <slot></slot>
93
96
  </span>`
@@ -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 = [
@@ -41,6 +67,7 @@ export class OxInputBarcode extends OxFormField {
41
67
  padding-right: 35px;
42
68
  font: var(--input-font);
43
69
  color: var(--primary-text-color);
70
+ background-color: inherit;
44
71
  }
45
72
  input:focus {
46
73
  outline: none;
@@ -59,46 +86,45 @@ export class OxInputBarcode extends OxFormField {
59
86
  #scan-button[hidden] {
60
87
  display: none;
61
88
  }
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
89
  `
88
90
  ]
89
91
 
92
+ /**
93
+ * Indicates whether barcode scanning is enabled.
94
+ * @property {Boolean} scannable
95
+ */
90
96
  @property({ type: Boolean }) scannable?: boolean
97
+
98
+ /**
99
+ * If true, the "Enter" key press event is not fired after scanning a barcode.
100
+ * @property {Boolean} withoutEnter
101
+ */
91
102
  @property({ attribute: 'without-enter', type: Boolean }) withoutEnter?: boolean
103
+
104
+ /**
105
+ * The value of the input field.
106
+ * @property {String} declare value
107
+ */
92
108
  @property({ type: String }) declare value?: string
109
+
110
+ /**
111
+ * If true, only English characters are allowed in the input field.
112
+ * @property {Boolean} englishOnly
113
+ */
93
114
  @property({ attribute: 'english-only', type: Boolean }) englishOnly?: boolean
115
+
116
+ /**
117
+ * If true, the input field is automatically selected after a change event.
118
+ * @property {Boolean} selectAfterChange
119
+ */
94
120
  @property({ attribute: 'select-after-change', type: Boolean }) selectAfterChange?: boolean
95
121
 
96
122
  @state() stream?: MediaStream
97
- @state() reader?: BrowserMultiFormatReader
98
123
 
99
124
  @query('input') input!: HTMLInputElement
100
- @query('ox-popup') popup!: OxPopup
101
- @query('video') video!: HTMLVideoElement
125
+
126
+ private popup: OxPopup | null = null
127
+ private video: HTMLVideoElement | null = null
102
128
 
103
129
  connectedCallback() {
104
130
  super.connectedCallback()
@@ -108,7 +134,7 @@ export class OxInputBarcode extends OxFormField {
108
134
  if (navigator.mediaDevices) {
109
135
  ;(async () => {
110
136
  try {
111
- var stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
137
+ var stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: { facingMode: 'environment' } })
112
138
  if (stream) {
113
139
  stream.getTracks().forEach(track => track.stop())
114
140
  this.scannable = true
@@ -143,14 +169,6 @@ export class OxInputBarcode extends OxFormField {
143
169
  }}
144
170
  ?disabled=${this.disabled}
145
171
  ></button>
146
-
147
- <ox-popup
148
- @focusout=${() => {
149
- this.stopScan()
150
- }}
151
- >
152
- <video></video>
153
- </ox-popup>
154
172
  `
155
173
  }
156
174
 
@@ -201,27 +219,74 @@ export class OxInputBarcode extends OxFormField {
201
219
 
202
220
  async scan(e: MouseEvent) {
203
221
  try {
204
- this.popup.open({})
222
+ if (this.popup) {
223
+ this.stopScan()
224
+ }
225
+
226
+ this.popup = OxPopup.open({
227
+ template: html`
228
+ <video></video>
229
+ <md-icon
230
+ style="position: fixed; right: 0; top: 0; color: red; tabindex: 0"
231
+ @click=${() => {
232
+ this.stopScan()
233
+ }}
234
+ >close</md-icon
235
+ >
236
+ `,
237
+ width: '100vw',
238
+ height: '100dvh'
239
+ })
205
240
 
206
- /* template.video 생성된 후에 접근하기 위해서, 한 프레임을 강제로 건너뛴다. */
207
- await this.updateComplete
241
+ this.video! = this.popup.querySelector('video') as HTMLVideoElement
208
242
 
209
- var constraints = { video: { facingMode: 'environment' } } /* backside camera first */
243
+ var constraints = { audio: false, video: { facingMode: 'environment' } } /* backside camera first */
210
244
  this.stream = await navigator.mediaDevices.getUserMedia(constraints)
211
245
 
212
- this.reader = new BrowserMultiFormatReader()
213
- if (getComputedStyle(this.popup).display !== 'none' /* popup not hidden */ && this.stream) {
214
- var result = await this.reader.decodeOnceFromStream(this.stream, this.video)
215
- var input = this.input
216
- input.focus()
217
- this.value = input.value = String(result)
218
-
219
- if (!this.withoutEnter) {
220
- input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }))
246
+ this.video.srcObject = this.stream
247
+ this.video.play()
248
+
249
+ this.video.onloadedmetadata = async e => {
250
+ var canvas = new OffscreenCanvas(
251
+ this.video!.videoWidth || this.video!.width,
252
+ this.video!.videoHeight || this.video!.height
253
+ )
254
+
255
+ var context = canvas.getContext('2d', {
256
+ willReadFrequently: true
257
+ })
258
+
259
+ const detect = async () => {
260
+ try {
261
+ if (!this.stream?.active) {
262
+ return
263
+ }
264
+
265
+ context!.drawImage(this.video!, 0, 0, canvas.width, canvas.height)
266
+ const imageData = context!.getImageData(0, 0, canvas.width, canvas.height)
267
+ const symbols = await scanImageData(imageData)
268
+ const result = symbols[0]?.decode()
269
+
270
+ if (result) {
271
+ this.stopScan()
272
+
273
+ var input = this.input
274
+ input.focus()
275
+ this.value = input.value = String(result)
276
+
277
+ if (!this.withoutEnter) {
278
+ input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }))
279
+ }
280
+ } else {
281
+ requestAnimationFrame(async () => await detect())
282
+ }
283
+ } catch (e) {
284
+ console.warn(e)
285
+ this.stopScan()
286
+ }
221
287
  }
222
- } else {
223
- /* popup이 비동기 진행 중에 close된 경우라면, stopScan()을 처리하지 못하게 되므로, 다시한번 clear해준다. */
224
- this.stopScan()
288
+
289
+ await detect()
225
290
  }
226
291
  } catch (err) {
227
292
  /*
@@ -229,20 +294,20 @@ export class OxInputBarcode extends OxFormField {
229
294
  * 2. 뒤로가기 등으로 popup이 종료된 경우에도 NotFoundException: Video stream has ended before any code could be detected. 이 발생한다.
230
295
  */
231
296
  console.warn(err)
232
- } finally {
233
- this.popup.close()
234
-
235
- this.stopScan()
236
297
  }
237
298
  }
238
299
 
239
300
  stopScan() {
240
- this.video?.pause()
301
+ if (this.video) {
302
+ this.video.pause()
303
+ this.video.srcObject = null
304
+ }
241
305
 
242
- this.stream?.getTracks().forEach(track => track.stop())
243
- this.reader?.reset()
306
+ if (this.popup) {
307
+ this.popup.close()
308
+ this.popup = null
309
+ }
244
310
 
245
- delete this.stream
246
- delete this.reader
311
+ this.stream?.getTracks().forEach(track => track.stop())
247
312
  }
248
313
  }
@@ -5,8 +5,9 @@
5
5
  import { css, PropertyValues } from 'lit'
6
6
  import { customElement, property } from 'lit/decorators.js'
7
7
 
8
+ import { minimalSetup } from 'codemirror'
8
9
  import { history, historyKeymap, indentWithTab } from '@codemirror/commands'
9
- import { EditorView, highlightActiveLine, keymap } from '@codemirror/view'
10
+ import { EditorView, highlightActiveLine, keymap, lineNumbers } from '@codemirror/view'
10
11
  import { autocompletion, closeBrackets } from '@codemirror/autocomplete'
11
12
  import { bracketMatching, LanguageSupport, syntaxHighlighting } from '@codemirror/language'
12
13
  import { oneDarkHighlightStyle, oneDark } from '@codemirror/theme-one-dark'
@@ -25,7 +26,7 @@ WEB Component for code-mirror code editor.
25
26
 
26
27
  Example:
27
28
 
28
- <ox-input-code .value=${text} tab-size="4" tab-as-space="true" language="javascript">
29
+ <ox-input-code .value=${text} language="javascript" show-line-numbers>
29
30
  </ox-input-code>
30
31
  */
31
32
  @customElement('ox-input-code')
@@ -51,8 +52,7 @@ export class OxInputCode extends OxFormField {
51
52
  * `value`는 에디터에서 작성중인 contents이다.
52
53
  */
53
54
  @property({ type: String }) value: string = ''
54
- @property({ type: Number, attribute: 'tab-size' }) tabSize: number = 2
55
- @property({ type: Boolean, attribute: 'tab-as-space' }) tabAsSpace: boolean = true
55
+ @property({ type: Boolean, attribute: 'show-line-numbers' }) showLineNumbers: boolean = false
56
56
  @property({ type: String }) language?: string = 'javascript'
57
57
 
58
58
  private _self_changing: boolean = false
@@ -88,7 +88,9 @@ export class OxInputCode extends OxFormField {
88
88
  this._editor = new EditorView({
89
89
  doc: this.value,
90
90
  extensions: [
91
+ minimalSetup,
91
92
  ...language,
93
+ ...(this.showLineNumbers ? [lineNumbers()] : []),
92
94
  bracketMatching(),
93
95
  closeBrackets(),
94
96
  history(),
@@ -129,15 +131,6 @@ export class OxInputCode extends OxFormField {
129
131
  this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
130
132
  })
131
133
 
132
- // this._editor.contentDOM.addEventListener('change', async e => {
133
- // this._self_changing = true
134
- // this._changed = true
135
-
136
- // await this.updateComplete
137
-
138
- // this._self_changing = false
139
- // })
140
-
141
134
  return this._editor
142
135
  }
143
136
  }
@@ -2,7 +2,7 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
 
5
- import '@material/mwc-icon'
5
+ import '@material/web/icon/icon.js'
6
6
  import '@operato/popup/ox-popup-list.js'
7
7
 
8
8
  import { css, html, LitElement } from 'lit'
@@ -17,7 +17,7 @@ export class OxInputContainer extends LitElement {
17
17
  render() {
18
18
  return html`
19
19
  <slot> </slot>
20
- <mwc-icon @click=${this.openPopupList.bind(this)}>menu</mwc-icon>
20
+ <md-icon @click=${this.openPopupList.bind(this)}>menu</md-icon>
21
21
 
22
22
  <ox-popup-list></ox-popup-list>
23
23
  `
@@ -2,8 +2,6 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
 
5
- import '@material/mwc-button'
6
-
7
5
  import { css, html, PropertyValues } from 'lit'
8
6
  import { customElement, property, state } from 'lit/decorators.js'
9
7
 
@@ -211,14 +209,12 @@ export class OxInputCrontab extends OxFormField {
211
209
  margin: -0.25rem;
212
210
  }
213
211
 
214
- mwc-button {
215
- background-color: var(--secondary-color);
212
+ button {
216
213
  border-radius: var(--button-border-radius);
217
- --mdc-theme-primary: #fff;
218
214
  margin: 0.25rem;
219
215
  }
220
- mwc-button:hover,
221
- mwc-button:active {
216
+ button:hover,
217
+ button:active {
222
218
  background-color: var(--primary-color);
223
219
  }
224
220
  `
@@ -399,7 +395,7 @@ export class OxInputCrontab extends OxFormField {
399
395
  }
400
396
 
401
397
  get focusableElements(): HTMLElement[] {
402
- return Array.from(this.renderRoot.querySelectorAll('select, input, mwc-button'))
398
+ return Array.from(this.renderRoot.querySelectorAll('select, input, button'))
403
399
  }
404
400
 
405
401
  firstUpdated() {
@@ -38,7 +38,7 @@ export class OxInputData extends OxFormField {
38
38
  font-size: small;
39
39
  }
40
40
 
41
- div[datatype] mwc-icon {
41
+ div[datatype] md-icon {
42
42
  margin-left: auto;
43
43
  }
44
44
 
@@ -88,7 +88,7 @@ export class OxInputData extends OxFormField {
88
88
  />
89
89
  <label for="object">object</label>
90
90
 
91
- <mwc-icon @click=${() => this._clearData()} title="delete">delete_forever</mwc-icon>
91
+ <md-icon @click=${() => this._clearData()} title="delete">delete_forever</md-icon>
92
92
  </div>
93
93
 
94
94
  <ox-input-code
@@ -2,8 +2,6 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
 
5
- import '@material/mwc-button'
6
-
7
5
  import { css, html } from 'lit'
8
6
  import { customElement, property, query } from 'lit/decorators.js'
9
7
 
@@ -28,9 +26,14 @@ export class OxInputDuration extends OxFormField {
28
26
  }
29
27
 
30
28
  form {
31
- width: 100%;
32
- height: 100%;
33
- justify-content: center;
29
+ display: flex;
30
+ flex-direction: row;
31
+
32
+ align-items: center;
33
+ }
34
+
35
+ [padding] {
36
+ min-width: 100px;
34
37
  }
35
38
 
36
39
  input {
@@ -65,18 +68,16 @@ export class OxInputDuration extends OxFormField {
65
68
  border: var(--button-border);
66
69
  border-radius: var(--border-radius);
67
70
  background-color: var(--button-background-color);
68
- padding: var(--padding-narrow) var(--padding-default);
69
71
  min-height: 35px;
70
72
  line-height: 0.8;
71
73
  color: var(--button-color);
72
74
  cursor: pointer;
73
75
  }
76
+
74
77
  button + button {
75
78
  margin-left: -5px;
76
79
  }
77
- button mwc-icon {
78
- font-size: var(--fontsize-default);
79
- }
80
+
80
81
  button:focus,
81
82
  button:hover,
82
83
  button:active {
@@ -100,6 +101,7 @@ export class OxInputDuration extends OxFormField {
100
101
 
101
102
  return html`
102
103
  <form @change=${this.onChange.bind(this)}>
104
+ <div padding></div>
103
105
  <input id="days" type="number" .value=${String(days || 0)} pattern="\\d*" ?disabled=${this.disabled} />
104
106
  <label for="days">${i18next.t('label.days')}</label>
105
107
 
@@ -148,8 +150,9 @@ export class OxInputDuration extends OxFormField {
148
150
  }}
149
151
  ?disabled=${this.disabled}
150
152
  >
151
- <mwc-icon>backspace</mwc-icon>
153
+ <md-icon>backspace</md-icon>
152
154
  </button>
155
+ <div padding></div>
153
156
  </form>
154
157
  `
155
158
  }
@@ -2,7 +2,7 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
 
5
- import '@material/mwc-icon'
5
+ import '@material/web/icon/icon.js'
6
6
 
7
7
  import { css, html, PropertyValues } from 'lit'
8
8
  import { customElement, property, query } from 'lit/decorators.js'
@@ -32,9 +32,10 @@ export class OxInputFile extends OxFormField {
32
32
  font: var(--file-uploader-font) !important;
33
33
  color: var(--file-uploader-color);
34
34
  }
35
- :host > mwc-icon {
35
+
36
+ :host > md-icon {
36
37
  color: var(--file-uploader-icon-color);
37
- --mdc-icon-size: var(--file-uploader-icon-size, 36px);
38
+ --md-icon-size: var(--file-uploader-icon-size, 36px);
38
39
  }
39
40
 
40
41
  :host(.candrop) {
@@ -75,14 +76,14 @@ export class OxInputFile extends OxFormField {
75
76
  border-bottom: var(--file-uploader-li-border-bottom);
76
77
  font: normal 14px var(--theme-font);
77
78
  }
78
- li mwc-icon {
79
+ li md-icon {
79
80
  float: right;
80
81
  cursor: pointer;
81
82
  margin: var(--file-uploader-li-icon-margin);
82
83
  font-size: 1em;
83
84
  }
84
- li mwc-icon:hover,
85
- li mwc-icon:active {
85
+ li md-icon:hover,
86
+ li md-icon:active {
86
87
  color: var(--file-uploader-li-icon-focus-color);
87
88
  }
88
89
  `
@@ -104,7 +105,7 @@ export class OxInputFile extends OxFormField {
104
105
  var files: File[] = this.value || []
105
106
 
106
107
  return html`
107
- <mwc-icon>${this.icon || 'upload'}</mwc-icon>
108
+ <md-icon>${this.icon || 'upload'}</md-icon>
108
109
 
109
110
  <span>${this.description || 'drop files here!'}</span>
110
111
 
@@ -127,7 +128,7 @@ export class OxInputFile extends OxFormField {
127
128
  file => html`
128
129
  <li>
129
130
  - ${file.name}
130
- <mwc-icon
131
+ <md-icon
131
132
  @click=${(e: Event) => {
132
133
  if (this.disabled) {
133
134
  return
@@ -136,7 +137,7 @@ export class OxInputFile extends OxFormField {
136
137
  this.value = [...files]
137
138
  this._notifyChange()
138
139
  }}
139
- >delete_outline</mwc-icon
140
+ >delete_outline</md-icon
140
141
  >
141
142
  </li>
142
143
  `
@@ -2,7 +2,7 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
 
5
- import '@material/mwc-icon'
5
+ import '@material/web/icon/icon.js'
6
6
 
7
7
  import { css, html } from 'lit'
8
8
  import { customElement, property, queryAll } from 'lit/decorators.js'
@@ -35,17 +35,18 @@ export class OxInputI18nLabels extends OxFormField {
35
35
  display: flex;
36
36
  flex-direction: column;
37
37
  overflow: hidden;
38
+ gap: 10px;
38
39
  }
39
40
 
40
41
  [data-record] {
41
42
  display: flex;
42
43
  flex-direction: row;
44
+ align-items: center;
43
45
  gap: 10px;
44
46
  }
45
47
 
46
48
  label {
47
49
  width: 80px;
48
- align-self: center;
49
50
  text-align: end;
50
51
  }
51
52