@things-factory/reference-app 4.0.4 → 4.0.8

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 (54) hide show
  1. package/Dockerfile +1 -1
  2. package/attachments/03176f83-6c50-4850-ab43-e6765b259afd.png +0 -0
  3. package/attachments/2b963bee-3ca5-4a86-95b7-e557b7eba8eb.html +5695 -0
  4. package/attachments/4880d6fb-7045-4c50-bfb9-daf83ecf6cc1.png +0 -0
  5. package/attachments/5bcde766-32e5-4cdc-ad9b-9e0139c122f4.txt +673 -0
  6. package/attachments/6f9d5fd4-6546-40c6-90c0-0207233ad12f.json +145 -0
  7. package/attachments/a1aaa123-4c8d-485e-9975-5b5b4add6a30.png +0 -0
  8. package/attachments/b2331d78-f55d-4b9e-8aae-34f80c1252b3.jpeg +0 -0
  9. package/attachments/b9a3e2fd-fe83-4394-8fc8-66478443f65e.png +0 -0
  10. package/attachments/be3d2cd7-d236-45af-b512-4f141c8e2cfc.pptx +0 -0
  11. package/attachments/d211b356-1619-4f2b-9b10-ed46b4fd82de.png +0 -0
  12. package/attachments/d445e1a1-a048-49d7-96f2-284ac00fe96a.png +0 -0
  13. package/attachments/d462b12b-d519-4d6c-861a-f56d2494b135.png +0 -0
  14. package/attachments/f63986fb-bef5-4b55-a342-6fd4abf26739.png +0 -0
  15. package/client/bootstrap.js +30 -0
  16. package/client/components/camera-capturer.js +29 -2
  17. package/client/components/ocr-viewpart.js +94 -0
  18. package/client/menu.js +1 -1
  19. package/client/pages/context-menu-page.js +91 -69
  20. package/client/pages/grist-mode-page.js +15 -15
  21. package/client/pages/label-scan-page.js +189 -0
  22. package/client/pages/ocr-page.js +4 -3
  23. package/client/route.js +4 -0
  24. package/config/config.development.js +5 -1
  25. package/db.sqlite +0 -0
  26. package/dist-server/service/reference/lambda-call.js +68 -0
  27. package/dist-server/service/reference/lambda-call.js.map +1 -0
  28. package/dist-server/service/reference/reference-query.js +26 -4
  29. package/dist-server/service/reference/reference-query.js.map +1 -1
  30. package/logs/.08636eb59927f12972f6774f5947c8507b3564c2-audit.json +11 -6
  31. package/logs/.5e5d741d8b7784a2fbad65eedc0fd46946aaf6f2-audit.json +9 -14
  32. package/logs/application-2021-11-29-20.log +21 -0
  33. package/logs/application-2021-11-29-21.log +4 -0
  34. package/logs/application-2021-11-29-23.log +4 -0
  35. package/logs/{connections-2021-11-02-11.log → connections-2021-11-29-20.log} +0 -0
  36. package/logs/{connections-2021-11-03-11.log → connections-2021-11-29-21.log} +0 -0
  37. package/logs/{connections-2021-11-04-14.log → connections-2021-11-29-23.log} +0 -0
  38. package/package.json +43 -42
  39. package/server/service/reference/lambda-call.ts +69 -0
  40. package/server/service/reference/reference-query.ts +35 -7
  41. package/things-factory.config.js +4 -0
  42. package/translations/en.json +3 -2
  43. package/translations/ko.json +3 -2
  44. package/translations/ms.json +3 -2
  45. package/translations/zh.json +3 -2
  46. package/views/auth-page.html +0 -1
  47. package/attachments/69808491-8e6b-45e2-9bf8-dccea1c5b52e.png +0 -0
  48. package/attachments/7927fe8e-2246-453d-9869-7072b983437c.png +0 -0
  49. package/attachments/7d150574-01b8-4439-96a0-d57299f3ffcf.png +0 -0
  50. package/attachments/a1cf142c-f3c2-442c-b8d5-a7f9cc6a59b3.png +0 -0
  51. package/attachments/cb3ac834-ece0-4802-bef0-dfdc0fcd93bd.png +0 -0
  52. package/logs/application-2021-11-04-14.log +0 -4
  53. package/logs/application-2021-11-05-18.log +0 -6
  54. package/logs/connections-2021-11-05-18.log +0 -0
@@ -0,0 +1,145 @@
1
+ [
2
+ {
3
+ "type": "simple-switch",
4
+ "left": 119.16099773242632,
5
+ "top": 38.95691609977326,
6
+ "width": 99.99999999999974,
7
+ "height": 40.00000000000001,
8
+ "thumbnailColor": "#ffffff",
9
+ "onColor": "#2196f3",
10
+ "offColor": "#cccccc",
11
+ "rotation": 0,
12
+ "id": "input1"
13
+ },
14
+ {
15
+ "type": "input-text",
16
+ "top": 91.57596371882084,
17
+ "left": 119.72789115646258,
18
+ "width": 255.64625850340076,
19
+ "height": 30,
20
+ "paddingLeft": 7,
21
+ "paddingRight": 7,
22
+ "fontSize": 14,
23
+ "fillStyle": "white",
24
+ "fontColor": "#585858",
25
+ "strokeStyle": "rgba(0,0,0,.4)",
26
+ "lineWidth": 1,
27
+ "lineDash": "solid",
28
+ "textAlign": "left",
29
+ "rotation": 0,
30
+ "id": "input2",
31
+ "mappings": [
32
+ {
33
+ "rule": "value",
34
+ "target": "(self)",
35
+ "property": "value"
36
+ }
37
+ ]
38
+ },
39
+ {
40
+ "type": "text",
41
+ "left": 7.4829931972789225,
42
+ "top": 43.934240362811806,
43
+ "width": 95.91836734693874,
44
+ "height": 50,
45
+ "text": "Input 1",
46
+ "fillStyle": "#fff",
47
+ "strokeStyle": "#000",
48
+ "alpha": 1,
49
+ "hidden": false,
50
+ "lineWidth": 5,
51
+ "lineDash": "solid",
52
+ "lineCap": "butt",
53
+ "textAlign": "left",
54
+ "textBaseline": "top",
55
+ "textWrap": false,
56
+ "fontFamily": "serif",
57
+ "fontSize": 30,
58
+ "rotation": 0
59
+ },
60
+ {
61
+ "type": "text",
62
+ "left": 7.4829931972789225,
63
+ "top": 94.72789115646262,
64
+ "width": 95.91836734693874,
65
+ "height": 50,
66
+ "text": "Input 2",
67
+ "fillStyle": "#fff",
68
+ "strokeStyle": "#000",
69
+ "alpha": 1,
70
+ "hidden": false,
71
+ "lineWidth": 5,
72
+ "lineDash": "solid",
73
+ "lineCap": "butt",
74
+ "textAlign": "left",
75
+ "textBaseline": "top",
76
+ "textWrap": false,
77
+ "fontFamily": "serif",
78
+ "fontSize": 30,
79
+ "rotation": 0
80
+ },
81
+ {
82
+ "type": "rect",
83
+ "left": 251.70068027210883,
84
+ "top": 252.4943310657596,
85
+ "width": 120.29478458049894,
86
+ "height": 32.42630385487533,
87
+ "fillStyle": "#fff",
88
+ "strokeStyle": "#000",
89
+ "alpha": 1,
90
+ "hidden": false,
91
+ "lineWidth": 1,
92
+ "lineDash": "solid",
93
+ "lineCap": "butt",
94
+ "rotation": 0,
95
+ "text": "OK",
96
+ "shadow": {
97
+ "left": 5,
98
+ "top": 5,
99
+ "blurSize": 5,
100
+ "color": "rgb(217, 13, 75)"
101
+ },
102
+ "event": {
103
+ "tap": {
104
+ "pressed": true,
105
+ "action": "close-scene"
106
+ }
107
+ },
108
+ "data": {
109
+ "result1": true,
110
+ "result2": "성공했습니다."
111
+ }
112
+ },
113
+ {
114
+ "type": "rect",
115
+ "left": 119.72789115646259,
116
+ "top": 252.4943310657596,
117
+ "width": 120.29478458049883,
118
+ "height": 32.42630385487533,
119
+ "fillStyle": "#fff",
120
+ "strokeStyle": "#000",
121
+ "alpha": 1,
122
+ "hidden": false,
123
+ "lineWidth": 1,
124
+ "lineDash": "solid",
125
+ "lineCap": "butt",
126
+ "rotation": 0,
127
+ "text": "NOT OK",
128
+ "shadow": {
129
+ "left": 5,
130
+ "top": 5,
131
+ "blurSize": 5,
132
+ "color": "rgb(5, 61, 55)"
133
+ },
134
+ "event": {
135
+ "tap": {
136
+ "pressed": true,
137
+ "action": "close-scene"
138
+ }
139
+ },
140
+ "data": {
141
+ "result1": false,
142
+ "result2": "실패했습니다."
143
+ }
144
+ }
145
+ ]
@@ -1,6 +1,7 @@
1
1
  import '@things-factory/auth-ui' /* for domain-switch */
2
2
  import '@things-factory/barcode-base' /* for <default-label-printer-setting-let> */
3
3
  import '@things-factory/notification' /* for notification-badge */
4
+ import './components/ocr-viewpart'
4
5
 
5
6
  import { TOOL_POSITION, VIEWPART_POSITION, appendViewpart, toggleOverlay } from '@things-factory/layout-base'
6
7
  import { getEditor, registerEditor, registerRenderer } from '@operato/data-grist'
@@ -134,6 +135,24 @@ export default function bootstrap() {
134
135
  })
135
136
 
136
137
  /* setting app-tools */
138
+ store.dispatch({
139
+ type: APPEND_APP_TOOL,
140
+ tool: {
141
+ name: 'ocr-toggler',
142
+ template: html`
143
+ <mwc-icon
144
+ @click=${e => {
145
+ toggleOverlay('ocr-viewpart', {
146
+ backdrop: false
147
+ })
148
+ }}
149
+ >camera_enhance
150
+ </mwc-icon>
151
+ `,
152
+ position: TOOL_POSITION.REAR
153
+ }
154
+ })
155
+
137
156
  store.dispatch({
138
157
  type: APPEND_APP_TOOL,
139
158
  tool: {
@@ -162,6 +181,17 @@ export default function bootstrap() {
162
181
  position: VIEWPART_POSITION.HEADERBAR
163
182
  })
164
183
 
184
+ appendViewpart({
185
+ name: 'ocr-viewpart',
186
+ viewpart: {
187
+ show: false,
188
+ hovering: false,
189
+ resizable: true,
190
+ template: html` <ocr-viewpart style="min-width: 300px; height: 100%; width: 50vw;"></ocr-viewpart> `
191
+ },
192
+ position: VIEWPART_POSITION.ASIDEBAR
193
+ })
194
+
165
195
  appendViewpart({
166
196
  name: 'notification',
167
197
  viewpart: {
@@ -119,8 +119,16 @@ export class CameraCapturer extends LitElement {
119
119
  - ${file.name}
120
120
  <mwc-icon
121
121
  @click=${e => {
122
- this._files.splice(this._files.indexOf(file), 1)
123
- this.requestUpdate()
122
+ this._files = [...this._files.splice(this._files.indexOf(file), 1)]
123
+ this.dispatchEvent(
124
+ new CustomEvent('files-change', {
125
+ bubbles: true,
126
+ composed: true,
127
+ detail: {
128
+ files: this._files
129
+ }
130
+ })
131
+ )
124
132
  }}
125
133
  >delete_outline</mwc-icon
126
134
  >
@@ -137,6 +145,15 @@ export class CameraCapturer extends LitElement {
137
145
 
138
146
  this.addEventListener('file-drop', e => {
139
147
  this._files = this.multiple ? e.detail : e.detail[0] ? [e.detail[0]] : []
148
+ this.dispatchEvent(
149
+ new CustomEvent('files-change', {
150
+ bubbles: true,
151
+ composed: true,
152
+ detail: {
153
+ files: this._files
154
+ }
155
+ })
156
+ )
140
157
  })
141
158
  }
142
159
 
@@ -151,6 +168,16 @@ export class CameraCapturer extends LitElement {
151
168
  reset() {
152
169
  this.fileInput.value = ''
153
170
  this._files = []
171
+
172
+ this.dispatchEvent(
173
+ new CustomEvent('files-change', {
174
+ bubbles: true,
175
+ composed: true,
176
+ detail: {
177
+ files: this._files
178
+ }
179
+ })
180
+ )
154
181
  }
155
182
  }
156
183
 
@@ -0,0 +1,94 @@
1
+ import './camera-capturer'
2
+ import '@material/mwc-button'
3
+ import '@operato/ocr'
4
+
5
+ import { gql } from 'graphql-tag'
6
+ import { css, html, LitElement } from 'lit-element'
7
+
8
+ import { client } from '@things-factory/shell'
9
+
10
+ var FILES = []
11
+ var RESULT = []
12
+
13
+ class OCRViewPart extends LitElement {
14
+ static get styles() {
15
+ return [
16
+ css`
17
+ :host {
18
+ display: flex;
19
+ flex-direction: column;
20
+ min-width: 240px;
21
+ }
22
+
23
+ ox-ocr-helper {
24
+ flex: 1;
25
+ }
26
+ `
27
+ ]
28
+ }
29
+
30
+ static get properties() {
31
+ return {
32
+ _result: Array,
33
+ _files: Array
34
+ }
35
+ }
36
+
37
+ connectedCallback() {
38
+ super.connectedCallback()
39
+
40
+ this._files = FILES
41
+ this._result = RESULT
42
+ }
43
+
44
+ render() {
45
+ const files = this._files || []
46
+ const index = this.index || 0
47
+ const file = files[index]
48
+ const image = file && URL.createObjectURL(file)
49
+ if (image) {
50
+ requestAnimationFrame(() => URL.revokeObjectURL(image))
51
+ }
52
+
53
+ return html`
54
+ <ox-ocr-helper @attached=${this.upload.bind(this)} .files=${this._files} .result=${this._result}> </ox-ocr-helper>
55
+ `
56
+ }
57
+
58
+ async upload(e) {
59
+ FILES = this._files = e.detail
60
+
61
+ const response = await client.query({
62
+ query: gql`
63
+ query ocrRequest($images: [Upload!]!) {
64
+ ocrRequest(images: $images)
65
+ }
66
+ `,
67
+ variables: {
68
+ images: this._files
69
+ },
70
+ context: { hasUpload: true }
71
+ })
72
+
73
+ if (!response.errors) {
74
+ const helper = this.shadowRoot.querySelector('ox-ocr-helper')
75
+ RESULT = helper.result = response.data.ocrRequest.map(result => {
76
+ return {
77
+ ...result,
78
+ boundaries: JSON.parse(result.boundaries)
79
+ }
80
+ })
81
+ } else {
82
+ document.dispatchEvent(
83
+ new CustomEvent('notify', {
84
+ detail: {
85
+ level: 'error',
86
+ message: response.errors
87
+ }
88
+ })
89
+ )
90
+ }
91
+ }
92
+ }
93
+
94
+ customElements.define('ocr-viewpart', OCRViewPart)
package/client/menu.js CHANGED
@@ -80,7 +80,7 @@ export function getMenuTemplate() {
80
80
  },
81
81
  {
82
82
  name: 'Label Scan',
83
- path: 'bizplace-register'
83
+ path: 'label-scan-page'
84
84
  },
85
85
  {
86
86
  name: 'Ghost Print',
@@ -1,9 +1,10 @@
1
1
  import '@material/mwc-icon'
2
- import '@operato/mini-popup'
2
+ import '@operato/popup'
3
3
 
4
4
  import { css, html } from 'lit-element'
5
5
  import { connect } from 'pwa-helpers/connect-mixin.js'
6
6
 
7
+ import { PopupMenu } from '@operato/popup'
7
8
  import { PageView, store } from '@things-factory/shell'
8
9
 
9
10
  import { referencePageStyles } from './reference-page-styles'
@@ -39,93 +40,114 @@ class ContextMenuPage extends connect(store)(PageView) {
39
40
  페이지내에 엘리먼트를 위치시키고 open method로 활성화 시키는 방법을 예시합니다. 데스크톱 브라우저 페이지 내 어느
40
41
  위치에서든 마우스 우측버튼을 클릭하고, 모바일 디바이스에서는 탭을 오래누르면(longpress) 팝업메뉴가 동작합니다.
41
42
  </p>
43
+ `
44
+ }
42
45
 
43
- <popup-menu>
44
- <popup-menuitem label="article">
45
- <mwc-icon slot="icon">article</mwc-icon>
46
- </popup-menuitem>
47
-
48
- <popup-menuitem label="home">
49
- <mwc-icon slot="icon">home</mwc-icon>
50
- </popup-menuitem>
51
-
52
- <popup-menuitem label="empty"> </popup-menuitem>
53
-
54
- <popup-menuitem
55
- label="click me to toggle"
56
- @click=${function (e) {
57
- const target = e.currentTarget
58
- const icon = target.querySelector('mwc-icon')
59
- icon.innerHTML = icon.innerHTML == 'check' ? '' : 'check'
60
- }}
61
- >
62
- <mwc-icon slot="icon" style="width: 20px;height: 20px;"></mwc-icon>
63
- </popup-menuitem>
64
-
65
- <popup-menuitem label="verified">
66
- <mwc-icon slot="icon">verified</mwc-icon>
67
- <popup-menu>
68
- <popup-menuitem label="article">
46
+ firstUpdated() {
47
+ this.addEventListener('contextmenu', e => {
48
+ e.preventDefault()
49
+
50
+ PopupMenu.open({
51
+ template: html`
52
+ <ox-popup-menuitem
53
+ label="article - click me"
54
+ @selected=${function (e) {
55
+ console.log('first level article selected')
56
+ }}
57
+ >
69
58
  <mwc-icon slot="icon">article</mwc-icon>
70
- </popup-menuitem>
59
+ </ox-popup-menuitem>
71
60
 
72
- <popup-menuitem label="home">
61
+ <ox-popup-menuitem label="home">
73
62
  <mwc-icon slot="icon">home</mwc-icon>
74
- </popup-menuitem>
75
-
76
- <popup-menuitem label="verified">
63
+ </ox-popup-menuitem>
64
+
65
+ <ox-popup-menuitem label="empty"> </ox-popup-menuitem>
66
+
67
+ <ox-popup-menuitem
68
+ label="click me to toggle"
69
+ @selected=${function (e) {
70
+ const icon = this.querySelector('mwc-icon')
71
+ icon.innerHTML = icon.innerHTML == 'check' ? '' : 'check'
72
+ }}
73
+ alive-on-select
74
+ >
75
+ <mwc-icon slot="icon" style="width: 20px;height: 20px;"></mwc-icon>
76
+ </ox-popup-menuitem>
77
+
78
+ <ox-popup-menuitem label="verified" @selected=${e => console.log('selected verified')}>
77
79
  <mwc-icon slot="icon">verified</mwc-icon>
78
- <popup-menu>
79
- <popup-menuitem label="article">
80
+ <ox-popup-menu>
81
+ <ox-popup-menuitem
82
+ label="article"
83
+ @selected=${function (e) {
84
+ console.log('article selected')
85
+ }}
86
+ alive-on-select
87
+ >
80
88
  <mwc-icon slot="icon">article</mwc-icon>
81
- </popup-menuitem>
89
+ </ox-popup-menuitem>
82
90
 
83
- <popup-menuitem label="home">
91
+ <ox-popup-menuitem label="home">
84
92
  <mwc-icon slot="icon">home</mwc-icon>
85
- </popup-menuitem>
93
+ </ox-popup-menuitem>
86
94
 
87
- <popup-menuitem label="verified">
95
+ <ox-popup-menuitem label="verified">
88
96
  <mwc-icon slot="icon">verified</mwc-icon>
89
- </popup-menuitem>
97
+ <ox-popup-menu>
98
+ <ox-popup-menuitem label="article">
99
+ <mwc-icon slot="icon">article</mwc-icon>
100
+ </ox-popup-menuitem>
90
101
 
91
- <popup-menuitem label="checkbox">
92
- <input type="checkbox" slot="icon" />
93
- </popup-menuitem>
94
-
95
- <div separator></div>
96
- </popup-menu>
97
- </popup-menuitem>
102
+ <ox-popup-menuitem label="home">
103
+ <mwc-icon slot="icon">home</mwc-icon>
104
+ </ox-popup-menuitem>
98
105
 
99
- <div separator></div>
106
+ <ox-popup-menuitem label="verified">
107
+ <mwc-icon slot="icon">verified</mwc-icon>
108
+ </ox-popup-menuitem>
100
109
 
101
- <popup-menuitem label="checkbox">
102
- <input type="checkbox" slot="icon" />
103
- </popup-menuitem>
104
- </popup-menu>
105
- </popup-menuitem>
110
+ <ox-popup-menuitem label="checkbox">
111
+ <input type="checkbox" slot="icon" />
112
+ </ox-popup-menuitem>
106
113
 
107
- <popup-menuitem label="checkbox">
108
- <input type="checkbox" slot="icon" />
109
- </popup-menuitem>
114
+ <div separator></div>
115
+ </ox-popup-menu>
116
+ </ox-popup-menuitem>
110
117
 
111
- <div separator></div>
118
+ <div separator></div>
112
119
 
113
- <div menu>Plain DIV</div>
114
- <input type="checkbox" menu />
115
- <input type="text" menu value="Plain text input" />
116
- </popup-menu>
117
- `
118
- }
120
+ <ox-popup-menuitem label="checkbox">
121
+ <input type="checkbox" slot="icon" />
122
+ </ox-popup-menuitem>
123
+ </ox-popup-menu>
124
+ </ox-popup-menuitem>
119
125
 
120
- firstUpdated() {
121
- this.addEventListener('contextmenu', e => {
122
- const popupMenu = this.renderRoot.querySelector('popup-menu')
126
+ <ox-popup-menuitem label="checkbox in icon area" alive-on-select>
127
+ <input type="checkbox" slot="icon" />
128
+ </ox-popup-menuitem>
123
129
 
124
- if (popupMenu) {
125
- e.preventDefault()
130
+ <div separator></div>
126
131
 
127
- popupMenu.open({ left: e.offsetX, top: e.offsetY })
128
- }
132
+ <div menu>Plain Text</div>
133
+
134
+ <div menu alive-on-select>
135
+ <ox-checkbox label="checkbox" slot="icon" checked />checkbox</ox-checkbox>
136
+ </div>
137
+
138
+ <div menu alive-on-select>
139
+ <input id="checkbox-01" type="checkbox" />
140
+ <label for="checkbox-01">custom menu</label>
141
+ </div>
142
+ <div menu alive-on-select>
143
+ <label for="text-01">value</label>
144
+ <input id="text-01" type="text" value="Plain text input" />
145
+ </div>
146
+ `,
147
+ top: e.offsetY,
148
+ left: e.offsetX,
149
+ parent: this.renderRoot
150
+ })
129
151
  })
130
152
  }
131
153
  }
@@ -1,12 +1,10 @@
1
- import '@operato/mini-popup'
1
+ import '@operato/popup'
2
2
  import '@operato/data-grist'
3
3
 
4
4
  import { css, html } from 'lit-element'
5
- import { getEditor, getRenderer } from '@operato/data-grist'
6
- import { i18next, localize } from '@things-factory/i18n-base'
7
5
 
6
+ import { i18next, localize } from '@things-factory/i18n-base'
8
7
  import { PageView } from '@things-factory/shell'
9
- import { isMobileDevice } from '@things-factory/utils'
10
8
 
11
9
  class GristModePage extends localize(i18next)(PageView) {
12
10
  static get styles() {
@@ -113,7 +111,7 @@ class GristModePage extends localize(i18next)(PageView) {
113
111
  <mwc-icon
114
112
  @click=${e => {
115
113
  const target = e.currentTarget
116
- this.renderRoot.querySelector('popup-menu').open({
114
+ this.renderRoot.querySelector('ox-popup-list').open({
117
115
  left: target.offsetLeft,
118
116
  top: target.offsetTop + target.offsetHeight
119
117
  })
@@ -123,7 +121,7 @@ class GristModePage extends localize(i18next)(PageView) {
123
121
  <mwc-icon
124
122
  @click=${e => {
125
123
  const target = e.currentTarget
126
- this.renderRoot.querySelector('popup-menu').open({
124
+ this.renderRoot.querySelector('ox-popup-list').open({
127
125
  left: target.offsetLeft,
128
126
  top: target.offsetTop + target.offsetHeight
129
127
  })
@@ -133,7 +131,7 @@ class GristModePage extends localize(i18next)(PageView) {
133
131
  <mwc-icon
134
132
  @click=${e => {
135
133
  const target = e.currentTarget
136
- this.renderRoot.querySelector('popup-menu').open({
134
+ this.renderRoot.querySelector('ox-popup-list').open({
137
135
  left: target.offsetLeft,
138
136
  top: target.offsetTop + target.offsetHeight
139
137
  })
@@ -141,26 +139,28 @@ class GristModePage extends localize(i18next)(PageView) {
141
139
  >sort</mwc-icon
142
140
  >
143
141
 
144
- <popup-menu>
145
- <popup-menuitem
146
- label="click me to toggle"
142
+ <ox-popup-list alive-on-select>
143
+ <div
144
+ option
147
145
  @click=${function (e) {
148
146
  const icon = e.currentTarget.querySelector('mwc-icon')
149
147
  icon.innerHTML = icon.innerHTML == 'check' ? '' : 'check'
150
148
  }}
151
149
  >
152
150
  <mwc-icon slot="icon" style="width: 20px;height: 20px;"></mwc-icon>
153
- </popup-menuitem>
154
- <popup-menuitem
155
- label="click me to toggle"
151
+ <span>click me to toggle</span>
152
+ </div>
153
+ <div
154
+ option
156
155
  @click=${function (e) {
157
156
  const icon = e.currentTarget.querySelector('mwc-icon')
158
157
  icon.innerHTML = icon.innerHTML == 'check' ? '' : 'check'
159
158
  }}
160
159
  >
161
160
  <mwc-icon slot="icon" style="width: 20px;height: 20px;"></mwc-icon>
162
- </popup-menuitem>
163
- </popup-menu>
161
+ <span>click me to toggle</span>
162
+ </div>
163
+ </ox-popup-list>
164
164
  </div>
165
165
  </div>
166
166
  </ox-grist>