@operato/popup 10.15.0 → 10.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/coverage/lcov-report/index.html +27 -27
- package/coverage/lcov.info +1385 -1075
- package/dist/src/ox-prompt.d.ts +16 -0
- package/dist/src/ox-prompt.js +24 -0
- package/dist/src/ox-prompt.js.map +1 -1
- package/dist/test/office-control-height.test.d.ts +2 -1
- package/dist/test/office-control-height.test.js +84 -30
- package/dist/test/office-control-height.test.js.map +1 -1
- package/dist/test/ox-popup-actions.test.js +4 -4
- package/dist/test/ox-popup-actions.test.js.map +1 -1
- package/dist/test/ox-prompt-actions.test.js +33 -2
- package/dist/test/ox-prompt-actions.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/test/office-control-height.test.ts +98 -31
- package/test/ox-popup-actions.test.ts +4 -4
- package/test/ox-prompt-actions.test.ts +39 -2
- package/translations/en.json +6 -1
- package/translations/ja.json +6 -0
- package/translations/ko.json +6 -1
- package/translations/ms.json +6 -0
- package/translations/zh.json +6 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@operato/popup",
|
|
3
3
|
"description": "Webcomponent popup following open-wc recommendations",
|
|
4
4
|
"author": "heartyoh",
|
|
5
|
-
"version": "10.
|
|
5
|
+
"version": "10.16.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/src/index.js",
|
|
8
8
|
"module": "dist/src/index.js",
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@material/web": "^2.0.0",
|
|
74
74
|
"@operato/i18n": "^10.11.0",
|
|
75
|
-
"@operato/styles": "^10.
|
|
76
|
-
"@operato/utils": "^10.
|
|
75
|
+
"@operato/styles": "^10.16.0",
|
|
76
|
+
"@operato/utils": "^10.16.0",
|
|
77
77
|
"lit": "^3.1.2",
|
|
78
78
|
"sortablejs": "^1.15.2"
|
|
79
79
|
},
|
|
@@ -110,5 +110,5 @@
|
|
|
110
110
|
"prettier --write"
|
|
111
111
|
]
|
|
112
112
|
},
|
|
113
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "8a061bd85d68e619b0c6aef699c57c89d3d9052a"
|
|
114
114
|
}
|
|
@@ -1,58 +1,125 @@
|
|
|
1
|
-
import
|
|
1
|
+
import '@material/web/button/filled-button.js'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { expect, fixture } from '@open-wc/testing'
|
|
4
|
+
import { css, html, LitElement } from 'lit'
|
|
4
5
|
|
|
6
|
+
import {
|
|
7
|
+
ACTION_HEIGHT_TOKENS,
|
|
8
|
+
ButtonContainerStyles,
|
|
9
|
+
CommonHeaderStyles,
|
|
10
|
+
CommonPopupStyles
|
|
11
|
+
} from '@operato/styles'
|
|
12
|
+
|
|
13
|
+
import '../src/ox-popup-actions.js'
|
|
5
14
|
import { OxPopupActions } from '../src/ox-popup-actions.js'
|
|
6
15
|
|
|
7
16
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
17
|
+
* Button heights (ADR-0060 decisions 6 and 6-1).
|
|
18
|
+
*
|
|
19
|
+
* The **platform** keeps the heights every application had before the operato standardization, so
|
|
20
|
+
* dssp, fmsim and the rest do not change when they upgrade. The **operato products** are compact: the
|
|
21
|
+
* shell theme opens each token as `var(--suite-<token>, <platform>)` and operato-suite fills the slot.
|
|
10
22
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* Shop-floor popups raise the token themselves (operato-plant checks that on its side).
|
|
23
|
+
* These render both worlds with a mouse (the test browser). The finger branches cannot be emulated,
|
|
24
|
+
* so those are read from the stylesheets.
|
|
14
25
|
*/
|
|
15
26
|
|
|
27
|
+
const PLATFORM_TOKENS = `
|
|
28
|
+
--context-action-height: var(--suite-context-action-height, 32px);
|
|
29
|
+
--popup-action-height: var(--suite-popup-action-height, 30px);
|
|
30
|
+
--form-action-height: var(--suite-form-action-height, 40px);
|
|
31
|
+
`
|
|
32
|
+
const SUITE_SLOTS = `
|
|
33
|
+
--suite-context-action-height: 32px;
|
|
34
|
+
--suite-popup-action-height: 32px;
|
|
35
|
+
--suite-form-action-height: 32px;
|
|
36
|
+
`
|
|
37
|
+
|
|
38
|
+
class StyledRows extends LitElement {
|
|
39
|
+
static styles = [CommonPopupStyles, CommonHeaderStyles, ButtonContainerStyles, css``]
|
|
40
|
+
|
|
41
|
+
render() {
|
|
42
|
+
return html`
|
|
43
|
+
<div class="buttons"><md-filled-button id="popup-md">save</md-filled-button></div>
|
|
44
|
+
<div class="footer"><button id="footer">save</button></div>
|
|
45
|
+
<div class="button-container">
|
|
46
|
+
<button id="bar">export</button>
|
|
47
|
+
<md-filled-button id="bar-md">publish</md-filled-button>
|
|
48
|
+
</div>
|
|
49
|
+
`
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
customElements.define('test-styled-rows', StyledRows)
|
|
53
|
+
|
|
54
|
+
const height = (el: Element | null | undefined) => Math.round(el!.getBoundingClientRect().height)
|
|
16
55
|
const text = (styles: unknown) =>
|
|
17
56
|
(Array.isArray(styles) ? styles : [styles]).map(s => String((s as { cssText?: string }).cssText ?? s)).join('\n')
|
|
57
|
+
const coarse = (cssText: string) => cssText.slice(cssText.indexOf('(pointer: coarse)'))
|
|
18
58
|
|
|
19
|
-
|
|
59
|
+
async function rows(style: string) {
|
|
60
|
+
const host = await fixture<HTMLElement>(html`
|
|
61
|
+
<div style="${style}">
|
|
62
|
+
<test-styled-rows></test-styled-rows>
|
|
63
|
+
<ox-popup-actions>
|
|
64
|
+
<md-filled-button slot="confirm" id="prompt-md">ok</md-filled-button>
|
|
65
|
+
</ox-popup-actions>
|
|
66
|
+
</div>
|
|
67
|
+
`)
|
|
68
|
+
const styled = host.querySelector('test-styled-rows') as StyledRows
|
|
69
|
+
await styled.updateComplete
|
|
70
|
+
const actions = host.querySelector('ox-popup-actions') as OxPopupActions
|
|
71
|
+
await actions.updateComplete
|
|
72
|
+
const buttons = [...Array.from(styled.shadowRoot!.querySelectorAll('md-filled-button')), host.querySelector('#prompt-md')]
|
|
73
|
+
await Promise.all(buttons.map(b => (b as LitElement).updateComplete))
|
|
74
|
+
return { root: styled.shadowRoot!, host }
|
|
75
|
+
}
|
|
20
76
|
|
|
21
77
|
describe('office control height', () => {
|
|
22
|
-
it('the defaults are
|
|
78
|
+
it('the platform defaults are the heights before the standardization', () => {
|
|
23
79
|
expect(ACTION_HEIGHT_TOKENS).to.deep.equal({
|
|
24
80
|
'--context-action-height': 32,
|
|
25
|
-
'--popup-action-height':
|
|
26
|
-
'--form-action-height':
|
|
81
|
+
'--popup-action-height': 30,
|
|
82
|
+
'--form-action-height': 40,
|
|
27
83
|
'--cell-action-height': 26
|
|
28
84
|
})
|
|
29
85
|
})
|
|
30
86
|
|
|
31
|
-
it('
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
expect(
|
|
35
|
-
expect(
|
|
87
|
+
it('★ platform: nothing changes for applications outside the operato suite', async () => {
|
|
88
|
+
const { root, host } = await rows(PLATFORM_TOKENS)
|
|
89
|
+
|
|
90
|
+
expect(height(root.querySelector('#popup-md'))).to.equal(40) // CommonPopupStyles .buttons
|
|
91
|
+
expect(height(root.querySelector('#footer'))).to.be.at.least(30) // older footer
|
|
92
|
+
expect(height(root.querySelector('#bar'))).to.equal(32) // page action bar
|
|
93
|
+
expect(height(root.querySelector('#bar-md'))).to.equal(40) // Material keeps its own in the bar
|
|
94
|
+
expect(height(host.querySelector('#prompt-md'))).to.equal(30) // OxPrompt row, as before
|
|
36
95
|
})
|
|
37
96
|
|
|
38
|
-
it('
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
expect(
|
|
42
|
-
expect(
|
|
97
|
+
it('★ suite: every action button in the operato products is 32px', async () => {
|
|
98
|
+
const { root, host } = await rows(SUITE_SLOTS + PLATFORM_TOKENS)
|
|
99
|
+
|
|
100
|
+
expect(height(root.querySelector('#popup-md'))).to.equal(32)
|
|
101
|
+
expect(height(root.querySelector('#bar'))).to.equal(32)
|
|
102
|
+
expect(height(root.querySelector('#bar-md'))).to.equal(32)
|
|
103
|
+
expect(height(host.querySelector('#prompt-md'))).to.equal(32)
|
|
43
104
|
})
|
|
44
105
|
|
|
45
|
-
it('
|
|
46
|
-
const
|
|
47
|
-
expect(
|
|
48
|
-
|
|
106
|
+
it('a shop-floor screen still raises the popup row above both', async () => {
|
|
107
|
+
const { root } = await rows(SUITE_SLOTS + PLATFORM_TOKENS + '--popup-action-height: 64px;')
|
|
108
|
+
expect(height(root.querySelector('#popup-md'))).to.equal(64)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('finger: the platform keeps 44px for the page bar and a 48px floor for the popup row', () => {
|
|
112
|
+
const bar = coarse(text(ButtonContainerStyles))
|
|
113
|
+
expect(bar).to.contain('var(--suite-context-action-height, 44px)')
|
|
114
|
+
|
|
115
|
+
const popup = coarse(text(CommonPopupStyles))
|
|
116
|
+
expect(popup).to.contain('var(--suite-popup-action-height, 48px)')
|
|
117
|
+
expect(popup).to.contain('var(--popup-action-height, 30px)')
|
|
49
118
|
})
|
|
50
119
|
|
|
51
|
-
it('
|
|
52
|
-
const
|
|
53
|
-
expect(
|
|
54
|
-
expect(
|
|
55
|
-
expect(css).to.not.contain('--context-action-height-touch')
|
|
56
|
-
expect(css).to.not.contain('(pointer: coarse)')
|
|
120
|
+
it('ox-popup-actions has no finger height of its own', () => {
|
|
121
|
+
const cssText = text(OxPopupActions.styles)
|
|
122
|
+
expect(cssText).to.contain('--_height: var(--popup-action-height, 30px)')
|
|
123
|
+
expect(coarse(cssText)).to.not.contain('--_height:')
|
|
57
124
|
})
|
|
58
125
|
})
|
|
@@ -11,7 +11,7 @@ import '../src/ox-popup-actions.js'
|
|
|
11
11
|
* wrong by writing its markup differently. These run with a mouse pointer (the test browser); the
|
|
12
12
|
* finger bar is a media query of the same element.
|
|
13
13
|
*
|
|
14
|
-
* The expected numbers are written out (
|
|
14
|
+
* The expected numbers are written out (30, 68, 999em) rather than read from the stylesheet, so a
|
|
15
15
|
* change to the stylesheet shows up here as a decision, not as a silent follow.
|
|
16
16
|
*/
|
|
17
17
|
|
|
@@ -60,7 +60,7 @@ describe('ox-popup-actions', () => {
|
|
|
60
60
|
expect(Math.round(confirm.getBoundingClientRect().right)).to.equal(Math.round(actions.getBoundingClientRect().right))
|
|
61
61
|
})
|
|
62
62
|
|
|
63
|
-
it('gives Material buttons and plain buttons the same
|
|
63
|
+
it('gives Material buttons and plain buttons the same height (30px, the platform default)', async () => {
|
|
64
64
|
const actions = await row(html`
|
|
65
65
|
<ox-popup-actions>
|
|
66
66
|
<button slot="cancel" id="plain">cancel</button>
|
|
@@ -68,8 +68,8 @@ describe('ox-popup-actions', () => {
|
|
|
68
68
|
</ox-popup-actions>
|
|
69
69
|
`)
|
|
70
70
|
|
|
71
|
-
expect(height(actions.querySelector('#md')!)).to.equal(
|
|
72
|
-
expect(height(actions.querySelector('#plain')!)).to.equal(
|
|
71
|
+
expect(height(actions.querySelector('#md')!)).to.equal(30)
|
|
72
|
+
expect(height(actions.querySelector('#plain')!)).to.equal(30)
|
|
73
73
|
})
|
|
74
74
|
|
|
75
75
|
it('uses pill shapes inside the popup card', async () => {
|
|
@@ -62,8 +62,8 @@ describe('OxPrompt uses the shared action row', () => {
|
|
|
62
62
|
expect(confirm.getAttribute('slot')).to.equal('confirm')
|
|
63
63
|
expect(cancel.getAttribute('slot')).to.equal('cancel')
|
|
64
64
|
expect(cancel.getBoundingClientRect().left).to.be.lessThan(confirm.getBoundingClientRect().left)
|
|
65
|
-
expect(Math.round(confirm.getBoundingClientRect().height)).to.equal(
|
|
66
|
-
expect(Math.round(cancel.getBoundingClientRect().height)).to.equal(
|
|
65
|
+
expect(Math.round(confirm.getBoundingClientRect().height)).to.equal(30)
|
|
66
|
+
expect(Math.round(cancel.getBoundingClientRect().height)).to.equal(30)
|
|
67
67
|
|
|
68
68
|
cancel.click()
|
|
69
69
|
expect(await within(answer)).to.equal(false)
|
|
@@ -97,3 +97,40 @@ describe('OxPrompt uses the shared action row', () => {
|
|
|
97
97
|
expect(await within(answer)).to.equal(false)
|
|
98
98
|
})
|
|
99
99
|
})
|
|
100
|
+
|
|
101
|
+
describe('OxPrompt.confirmDelete', () => {
|
|
102
|
+
afterEach(() => {
|
|
103
|
+
document.body.querySelectorAll('ox-prompt').forEach(p => (p as OxPrompt).close())
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
async function opened(count?: number) {
|
|
107
|
+
const before = document.body.querySelectorAll('ox-prompt').length
|
|
108
|
+
const answer = OxPrompt.confirmDelete({ count })
|
|
109
|
+
for (let i = 0; i < 40 && document.body.querySelectorAll('ox-prompt').length <= before; i++) await settle()
|
|
110
|
+
const prompts = document.body.querySelectorAll('ox-prompt')
|
|
111
|
+
const prompt = prompts[prompts.length - 1] as OxPrompt
|
|
112
|
+
await prompt.updateComplete
|
|
113
|
+
const root = prompt.renderRoot as ShadowRoot
|
|
114
|
+
const confirm = root.querySelector('#confirm') as HTMLElement & { updateComplete: Promise<unknown> }
|
|
115
|
+
await confirm?.updateComplete
|
|
116
|
+
return { answer, prompt, root, confirm }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
it('asks in the shared popup with a destructive delete, and answers true on delete', async () => {
|
|
120
|
+
const { answer, prompt, confirm } = await opened()
|
|
121
|
+
|
|
122
|
+
expect(prompt.titler).to.equal('delete the selected item?')
|
|
123
|
+
expect(confirm.hasAttribute('destructive')).to.equal(true)
|
|
124
|
+
expect(confirm.textContent?.trim()).to.equal('delete')
|
|
125
|
+
|
|
126
|
+
confirm.click()
|
|
127
|
+
expect(await within(answer)).to.equal(true)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('names how many are selected when more than one', async () => {
|
|
131
|
+
const { prompt, root } = await opened(3)
|
|
132
|
+
|
|
133
|
+
expect(prompt.titler).to.equal('delete the 3 selected items?')
|
|
134
|
+
;(root.querySelector('#cancel') as HTMLElement).click()
|
|
135
|
+
})
|
|
136
|
+
})
|
package/translations/en.json
CHANGED
package/translations/ko.json
CHANGED