@api-client/ui 0.5.39 → 0.5.41
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/build/src/elements/contextual-menu/{internals/ContextualMenu.d.ts → ContextualMenu.d.ts} +11 -6
- package/build/src/elements/contextual-menu/ContextualMenu.d.ts.map +1 -0
- package/build/src/elements/contextual-menu/{internals/ContextualMenu.js → ContextualMenu.js} +25 -3
- package/build/src/elements/contextual-menu/ContextualMenu.js.map +1 -0
- package/build/src/elements/contextual-menu/internals/types.d.ts +16 -7
- package/build/src/elements/contextual-menu/internals/types.d.ts.map +1 -1
- package/build/src/elements/contextual-menu/internals/types.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -0
- package/package.json +1 -1
- package/src/elements/contextual-menu/{internals/ContextualMenu.ts → ContextualMenu.ts} +31 -7
- package/src/elements/contextual-menu/internals/types.ts +17 -7
- package/.aiexclude +0 -3
- package/.cursor/rules/html-and-css-best-practices.mdc +0 -63
- package/.cursor/rules/lit-best-practices.mdc +0 -89
- package/.editorconfig +0 -29
- package/.github/CONTRIBUTING.md +0 -24
- package/.github/instructions/html-and-css-best-practices.instructions.md +0 -70
- package/.github/instructions/lit-best-practices.instructions.md +0 -90
- package/.github/release.yml +0 -14
- package/.github/stale.yml +0 -23
- package/.github/workflows/auto-release.yml +0 -182
- package/.github/workflows/release.yml +0 -82
- package/.prettierrc.js +0 -14
- package/.vscode/settings.json +0 -18
- package/RELEASE.md +0 -163
- package/RELEASE_SETUP.md +0 -235
- package/build/src/demo/DemoPage.d.ts +0 -81
- package/build/src/demo/DemoPage.d.ts.map +0 -1
- package/build/src/demo/DemoPage.js +0 -175
- package/build/src/demo/DemoPage.js.map +0 -1
- package/build/src/demo/DemoStyles.d.ts +0 -3
- package/build/src/demo/DemoStyles.d.ts.map +0 -1
- package/build/src/demo/DemoStyles.js +0 -60
- package/build/src/demo/DemoStyles.js.map +0 -1
- package/build/src/elements/contextual-menu/internals/ContextualMenu.d.ts.map +0 -1
- package/build/src/elements/contextual-menu/internals/ContextualMenu.js.map +0 -1
- package/build/test/elements/navigation/Navigation.test.d.ts +0 -3
- package/build/test/elements/navigation/Navigation.test.d.ts.map +0 -1
- package/build/test/elements/navigation/Navigation.test.js +0 -113
- package/build/test/elements/navigation/Navigation.test.js.map +0 -1
- package/commitlint.config.cjs +0 -2
- package/demo/elements/authorization/AuthPlugin.js +0 -57
- package/demo/elements/authorization/AuthProxy.js +0 -215
- package/demo/elements/authorization/api-key.html +0 -27
- package/demo/elements/authorization/api-key.ts +0 -44
- package/demo/elements/authorization/basic.html +0 -27
- package/demo/elements/authorization/basic.ts +0 -43
- package/demo/elements/authorization/bearer.html +0 -27
- package/demo/elements/authorization/bearer.ts +0 -43
- package/demo/elements/authorization/env.js +0 -8
- package/demo/elements/authorization/index.html +0 -44
- package/demo/elements/authorization/ntlm.html +0 -27
- package/demo/elements/authorization/ntlm.ts +0 -43
- package/demo/elements/authorization/oauth-authorize.html +0 -75
- package/demo/elements/authorization/oauth-authorize.ts +0 -40
- package/demo/elements/authorization/oauth-error.html +0 -18
- package/demo/elements/authorization/oauth-error.ts +0 -10
- package/demo/elements/authorization/oauth-popup.html +0 -36
- package/demo/elements/authorization/oauth2.html +0 -27
- package/demo/elements/authorization/oauth2.ts +0 -100
- package/demo/elements/authorization/oidc.html +0 -27
- package/demo/elements/authorization/oidc.ts +0 -139
- package/demo/elements/authorization/private.crt +0 -31
- package/demo/elements/authorization/private.csr +0 -28
- package/demo/elements/authorization/private.key +0 -51
- package/demo/elements/authorization/private.pem +0 -31
- package/demo/elements/authorization/redirect.html +0 -20
- package/demo/elements/authorization/ssl-commands.sh +0 -30
- package/demo/elements/authorization/ssl.conf +0 -24
- package/demo/elements/autocomplete/index.html +0 -64
- package/demo/elements/autocomplete/index.ts +0 -171
- package/demo/elements/code-editor/CodeEditorDemo.ts +0 -173
- package/demo/elements/code-editor/index.html +0 -19
- package/demo/elements/context-menu/DemoIcons.ts +0 -21
- package/demo/elements/context-menu/basic.html +0 -25
- package/demo/elements/context-menu/basic.ts +0 -119
- package/demo/elements/context-menu/custom-data.html +0 -25
- package/demo/elements/context-menu/custom-data.ts +0 -62
- package/demo/elements/context-menu/demo.css +0 -28
- package/demo/elements/context-menu/enabled-state.html +0 -25
- package/demo/elements/context-menu/enabled-state.ts +0 -73
- package/demo/elements/context-menu/icons.html +0 -25
- package/demo/elements/context-menu/icons.ts +0 -64
- package/demo/elements/context-menu/index.html +0 -43
- package/demo/elements/context-menu/nested.html +0 -25
- package/demo/elements/context-menu/nestedt.ts +0 -152
- package/demo/elements/context-menu/no-execute.html +0 -25
- package/demo/elements/context-menu/no-execute.ts +0 -134
- package/demo/elements/context-menu/radio-menu.html +0 -25
- package/demo/elements/context-menu/radio-menu.ts +0 -83
- package/demo/elements/context-menu/separators.html +0 -25
- package/demo/elements/context-menu/separators.ts +0 -172
- package/demo/elements/currency/index.html +0 -91
- package/demo/elements/currency/index.ts +0 -352
- package/demo/elements/environment/environment-editor.html +0 -20
- package/demo/elements/environment/environment-editor.ts +0 -49
- package/demo/elements/environment/index.html +0 -33
- package/demo/elements/environment/server-editor.html +0 -20
- package/demo/elements/environment/server-editor.ts +0 -67
- package/demo/elements/environment/variables-editor.html +0 -20
- package/demo/elements/environment/variables-editor.ts +0 -94
- package/demo/elements/har/har-viewer.html +0 -20
- package/demo/elements/har/har-viewer.ts +0 -76
- package/demo/elements/har/har1.har +0 -3044
- package/demo/elements/har/har2.json +0 -439
- package/demo/elements/har/index.html +0 -26
- package/demo/elements/highlight/example.md +0 -27
- package/demo/elements/highlight/index.html +0 -31
- package/demo/elements/highlight/marked-highlight.html +0 -132
- package/demo/elements/highlight/marked-highlight.ts +0 -22
- package/demo/elements/highlight/prism-highlight.html +0 -62
- package/demo/elements/highlight/prism-highlight.ts +0 -17
- package/demo/elements/http/body-editor.html +0 -17
- package/demo/elements/http/body-editor.ts +0 -115
- package/demo/elements/http/headers.html +0 -17
- package/demo/elements/http/headers.ts +0 -59
- package/demo/elements/http/http-assertions.html +0 -20
- package/demo/elements/http/http-assertions.ts +0 -89
- package/demo/elements/http/http-flows.html +0 -23
- package/demo/elements/http/http-flows.ts +0 -89
- package/demo/elements/http/index.html +0 -45
- package/demo/elements/http/request-editor.html +0 -26
- package/demo/elements/http/request-editor.ts +0 -197
- package/demo/elements/http/request-log.html +0 -16
- package/demo/elements/http/request-log.ts +0 -136
- package/demo/elements/http/url-editing.html +0 -17
- package/demo/elements/http/url-editing.ts +0 -112
- package/demo/elements/icons/index.html +0 -81
- package/demo/elements/icons/index.ts +0 -52
- package/demo/elements/index.html +0 -72
- package/demo/elements/mention-textarea/index.html +0 -19
- package/demo/elements/mention-textarea/index.ts +0 -205
- package/demo/elements/navigation/navigation-item.html +0 -49
- package/demo/elements/navigation/navigation-item.ts +0 -131
- package/demo/elements/navigation/navigation.html +0 -20
- package/demo/elements/navigation/navigation.ts +0 -45
- package/demo/elements/project/index.html +0 -29
- package/demo/elements/project/project-run-report.html +0 -20
- package/demo/elements/project/project-run-report.ts +0 -132
- package/demo/elements/project/request-editor.html +0 -23
- package/demo/elements/project/request-editor.ts +0 -232
- package/demo/elements/user/user-avatar.html +0 -17
- package/demo/elements/user/user-avatar.ts +0 -60
- package/demo/env.js +0 -4
- package/demo/index.html +0 -34
- package/demo/layout/index.html +0 -94
- package/demo/layout/index.ts +0 -190
- package/demo/md/DemoStyles.ts +0 -61
- package/demo/md/UiDemoPage.ts +0 -6
- package/demo/md/buttons/button.html +0 -121
- package/demo/md/buttons/button.ts +0 -246
- package/demo/md/buttons/group.html +0 -36
- package/demo/md/buttons/group.ts +0 -171
- package/demo/md/checkbox/index.html +0 -39
- package/demo/md/checkbox/index.ts +0 -220
- package/demo/md/chip/chip.html +0 -70
- package/demo/md/chip/chip.ts +0 -219
- package/demo/md/chip/pawel6c9a.jpg +0 -0
- package/demo/md/collapse/CustomDetail.ts +0 -89
- package/demo/md/collapse/collapse.html +0 -21
- package/demo/md/collapse/collapse.ts +0 -78
- package/demo/md/date-picker/date-picker.ts +0 -336
- package/demo/md/date-picker/index.html +0 -171
- package/demo/md/dialog/confirm-dialog.html +0 -49
- package/demo/md/dialog/confirm-dialog.ts +0 -121
- package/demo/md/dialog/dialog.html +0 -25
- package/demo/md/dialog/dialog.ts +0 -468
- package/demo/md/dropdown-list/index.html +0 -31
- package/demo/md/dropdown-list/index.ts +0 -158
- package/demo/md/icon-button/index.html +0 -122
- package/demo/md/icon-button/index.ts +0 -132
- package/demo/md/index.html +0 -73
- package/demo/md/inputs/input.html +0 -73
- package/demo/md/inputs/input.ts +0 -278
- package/demo/md/inputs/radio.html +0 -39
- package/demo/md/inputs/radio.ts +0 -156
- package/demo/md/inputs/switch.html +0 -45
- package/demo/md/inputs/switch.ts +0 -144
- package/demo/md/list/list.html +0 -65
- package/demo/md/list/list.ts +0 -204
- package/demo/md/listbox/listbox.html +0 -31
- package/demo/md/listbox/listbox.ts +0 -27
- package/demo/md/menu/index.html +0 -19
- package/demo/md/menu/index.ts +0 -514
- package/demo/md/notification/snack.html +0 -21
- package/demo/md/notification/snack.ts +0 -70
- package/demo/md/progress/progress.html +0 -46
- package/demo/md/progress/progress.ts +0 -161
- package/demo/md/segmented-button/index.html +0 -21
- package/demo/md/segmented-button/index.ts +0 -55
- package/demo/md/select/index.html +0 -16
- package/demo/md/select/index.ts +0 -217
- package/demo/md/tabs/tabs.html +0 -40
- package/demo/md/tabs/tabs.ts +0 -214
- package/demo/oauth-popup.html +0 -36
- package/demo/page.css +0 -8
- package/demo/resources/calendar-month.png +0 -0
- package/demo/resources/favorite.png +0 -0
- package/demo/resources/fingerprint.png +0 -0
- package/demo/resources/home-work.png +0 -0
- package/demo/resources/mood.png +0 -0
- package/demo/resources/print.png +0 -0
- package/demo/resources/stars.png +0 -0
- package/demo/resources/theaters.png +0 -0
- package/demo/tsconfig.json +0 -4
- package/eslint.config.js +0 -97
- package/scripts/copy-assets.js +0 -21
- package/scripts/release.js +0 -66
- package/src/demo/DemoPage.ts +0 -169
- package/src/demo/DemoStyles.ts +0 -60
- package/test/README.md +0 -375
- package/test/contextual-menu/ContextMenu.test.ts +0 -760
- package/test/contextual-menu/ContextMenuElement.test.ts +0 -569
- package/test/core/activity.spec.ts +0 -413
- package/test/core/activity_manager.spec.ts +0 -544
- package/test/core/application.spec.ts +0 -218
- package/test/core/fragment.spec.ts +0 -565
- package/test/core/fragment_manager.spec.ts +0 -404
- package/test/core/live_data.spec.ts +0 -558
- package/test/core/renderer.spec.ts +0 -113
- package/test/dom-assertions.test.ts +0 -182
- package/test/elements/MonacoSetup.ts +0 -65
- package/test/elements/authorization/basic-method.test.ts +0 -177
- package/test/elements/authorization/bearer-method.test.ts +0 -143
- package/test/elements/authorization/ntlm-method.test.ts +0 -219
- package/test/elements/authorization/oauth2-client-credentials-method.test.ts +0 -334
- package/test/elements/authorization/oauth2-code-method.test.ts +0 -320
- package/test/elements/authorization/oauth2-custom-grant-method.test.ts +0 -255
- package/test/elements/authorization/oauth2-device-code-method.test.ts +0 -371
- package/test/elements/authorization/oauth2-implicit-method.test.ts +0 -407
- package/test/elements/authorization/oauth2-jwt-method.test.ts +0 -217
- package/test/elements/authorization/oauth2-password-method.test.ts +0 -275
- package/test/elements/authorization/openid-method.test.ts +0 -591
- package/test/elements/autocomplete/autocomplete-input.spec.ts +0 -646
- package/test/elements/code-editor/code-editor.accessibility.test.ts +0 -298
- package/test/elements/code-editor/code-editor.test.ts +0 -574
- package/test/elements/currency/CurrencyPicker.accessibility.test.ts +0 -328
- package/test/elements/currency/CurrencyPicker.core.test.ts +0 -318
- package/test/elements/currency/CurrencyPicker.integration.test.ts +0 -482
- package/test/elements/currency/CurrencyPicker.test.ts +0 -486
- package/test/elements/data-table/DataTable.browser.test.ts +0 -649
- package/test/elements/har/HarUtils.test.ts +0 -45
- package/test/elements/har/HarViewerElement.test.ts +0 -687
- package/test/elements/har/test-data/har1.har +0 -3044
- package/test/elements/highlight/MarkedHighlightElement.test.ts +0 -452
- package/test/elements/highlight/PrismHighlightElement.test.ts +0 -79
- package/test/elements/highlight/PrismHighlighter.test.ts +0 -94
- package/test/elements/highlight/remoteSanitization.md +0 -1
- package/test/elements/highlight/test.md +0 -3
- package/test/elements/highlight/test1.md +0 -3
- package/test/elements/highlight/test2.md +0 -1
- package/test/elements/http/BodyFormdataEditorElement.test.ts +0 -482
- package/test/elements/http/BodyMultipartEditorElement.test.ts +0 -658
- package/test/elements/http/BodyRawEditorElement.test.ts +0 -90
- package/test/elements/http/CertificateAdd.test.ts +0 -457
- package/test/elements/http/HttpAssertions.test.ts +0 -994
- package/test/elements/http/HttpFlows.test.ts +0 -502
- package/test/elements/http/UrlEncodeUtils.test.ts +0 -202
- package/test/elements/layout/SplitItem.test.ts +0 -440
- package/test/elements/layout/SplitLayoutManager.test.ts +0 -1501
- package/test/elements/layout/SplitPanel.test.ts +0 -1109
- package/test/elements/mention-textarea/MentionTextArea.basic.test.ts +0 -114
- package/test/elements/mention-textarea/MentionTextArea.test.ts +0 -613
- package/test/elements/navigation/Navigation.test.ts +0 -120
- package/test/env.ts +0 -15
- package/test/events/EventTypes.test.ts +0 -363
- package/test/events/EventsTestHelpers.ts +0 -16
- package/test/helpers/TestUtils.ts +0 -243
- package/test/helpers/UiMock.ts +0 -185
- package/test/lib/Dom.test.ts +0 -231
- package/test/md/button/UiButton.test.ts +0 -347
- package/test/md/button/UiIconButton.test.ts +0 -155
- package/test/md/chip/UiChip.test.ts +0 -219
- package/test/md/collapse/UiCollapse.test.ts +0 -250
- package/test/md/collapse/flex-layout.test.ts +0 -105
- package/test/md/date-time/DateTime.test.ts +0 -348
- package/test/md/dialog/UiConfirmDialog.test.ts +0 -131
- package/test/md/dialog/UiDialog.test.ts +0 -759
- package/test/md/menu/Menu.test.ts +0 -855
- package/test/md/menu/MenuIntegration.test.ts +0 -426
- package/test/md/menu/MenuItem.test.ts +0 -652
- package/test/md/menu/SubMenu.test.ts +0 -410
- package/test/md/progress/UiCircularProgressElement.test.ts +0 -481
- package/test/md/progress/UiProgressElement.test.ts +0 -117
- package/test/md/progress/UiRangeElement.test.ts +0 -156
- package/test/md/select/Select.test.ts +0 -925
- package/test/plugins/takeScreenshotPlugin.js +0 -35
- package/test/setup.test.ts +0 -217
- package/test/setup.ts +0 -117
- package/test/tsconfig.json +0 -7
- package/web-dev-server.config.js +0 -21
- package/web-test-runner.config.js +0 -90
|
@@ -1,569 +0,0 @@
|
|
|
1
|
-
import { html, fixture, assert, nextFrame, aTimeout } from '@open-wc/testing'
|
|
2
|
-
import { setViewport } from '@web/test-runner-commands'
|
|
3
|
-
import sinon from 'sinon'
|
|
4
|
-
import { copy } from '../../demo/elements/context-menu/DemoIcons.js'
|
|
5
|
-
import ContextualMenuElement from '../../src/elements/contextual-menu/internals/ContextualMenuElement.js'
|
|
6
|
-
import { MenuItem } from '../../src/elements/contextual-menu/internals/MenuItem.js'
|
|
7
|
-
import type {
|
|
8
|
-
CheckedMenuOptions,
|
|
9
|
-
ContextMenuCommand,
|
|
10
|
-
CommandExecuteOptions,
|
|
11
|
-
} from '../../src/elements/contextual-menu/internals/types.js'
|
|
12
|
-
import UiListItem from '../../src/md/list/internals/ListItem.js'
|
|
13
|
-
|
|
14
|
-
import '../../src/elements/contextual-menu/contextual-menu.js'
|
|
15
|
-
|
|
16
|
-
describe('ContextualMenuElement', () => {
|
|
17
|
-
const store: object = {}
|
|
18
|
-
const target = document.createElement('div')
|
|
19
|
-
const workspace = document.createElement('div')
|
|
20
|
-
const customData = Object.freeze({})
|
|
21
|
-
|
|
22
|
-
before(() => {
|
|
23
|
-
const link = document.createElement('link')
|
|
24
|
-
link.rel = 'stylesheet'
|
|
25
|
-
link.href = '../../demo/elements/context-menu/demo.css'
|
|
26
|
-
document.head.append(link)
|
|
27
|
-
document.body.classList.add('styled')
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
async function dataFixture<T>(commands: MenuItem<T>[]): Promise<ContextualMenuElement<T>> {
|
|
31
|
-
return fixture(html`
|
|
32
|
-
<contextual-menu
|
|
33
|
-
.commands="${commands}"
|
|
34
|
-
.store="${store}"
|
|
35
|
-
.target="${target}"
|
|
36
|
-
.workspace="${workspace}"
|
|
37
|
-
.customData="${customData}"
|
|
38
|
-
></contextual-menu>
|
|
39
|
-
`)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
describe('Menu rendering', () => {
|
|
43
|
-
let menu: ContextualMenuElement<typeof store>
|
|
44
|
-
const commands: ContextMenuCommand<typeof store>[] = [
|
|
45
|
-
{
|
|
46
|
-
type: 'normal',
|
|
47
|
-
target: 'div',
|
|
48
|
-
label: 'test 1',
|
|
49
|
-
id: 't1',
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
type: 'separator',
|
|
53
|
-
id: 't2',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
target: 'div',
|
|
57
|
-
type: 'normal',
|
|
58
|
-
label: 'test 2',
|
|
59
|
-
icon: copy,
|
|
60
|
-
id: 't3',
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
target: 'div',
|
|
64
|
-
label: 'test 3',
|
|
65
|
-
enabled: false,
|
|
66
|
-
id: 't4',
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
target: 'div',
|
|
70
|
-
label: 'test 4',
|
|
71
|
-
enabled: (): boolean => false,
|
|
72
|
-
id: 't5',
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
target: 'div',
|
|
76
|
-
label: 'test 5',
|
|
77
|
-
visible: false,
|
|
78
|
-
id: 't6',
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
target: 'div',
|
|
82
|
-
label: 'test 6',
|
|
83
|
-
visible: (): boolean => false,
|
|
84
|
-
id: 't7',
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
target: 'div',
|
|
88
|
-
label: 'test 7',
|
|
89
|
-
title: 'test title',
|
|
90
|
-
id: 't8',
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
target: 'div',
|
|
94
|
-
type: 'label',
|
|
95
|
-
label: 'test label',
|
|
96
|
-
id: 't9',
|
|
97
|
-
},
|
|
98
|
-
]
|
|
99
|
-
beforeEach(async () => {
|
|
100
|
-
const cmd = commands.map((item) => new MenuItem(item))
|
|
101
|
-
menu = await dataFixture<typeof store>(cmd)
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('renders an item with a label', () => {
|
|
105
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="t1"]') as HTMLElement
|
|
106
|
-
const iconContainer = item.querySelector('.menu-icon') as HTMLElement
|
|
107
|
-
assert.notOk(iconContainer, 'has no icon container')
|
|
108
|
-
const labelContainer = item.querySelector('.menu-label') as HTMLElement
|
|
109
|
-
assert.ok(labelContainer, 'has the label container')
|
|
110
|
-
assert.equal(labelContainer.innerText.trim(), 'test 1', 'the label container has the value')
|
|
111
|
-
const subContainer = item.querySelector('.sub-menu-icon') as HTMLElement
|
|
112
|
-
assert.notOk(subContainer, 'has no sub-menu icon')
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('renders a divider', () => {
|
|
116
|
-
const item = menu.shadowRoot!.querySelector('ui-divider[data-cmd="t2"]') as HTMLElement
|
|
117
|
-
assert.ok(item, 'has the divider')
|
|
118
|
-
assert.isTrue(item.classList.contains('menu-divider'), 'has the class name')
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('renders a hidden divider', async () => {
|
|
122
|
-
menu.commands![1].visible = false
|
|
123
|
-
menu.requestUpdate()
|
|
124
|
-
await menu.updateComplete
|
|
125
|
-
const item = menu.shadowRoot!.querySelector('ui-divider[data-cmd="t2"]') as HTMLElement
|
|
126
|
-
assert.ok(item, 'has the divider')
|
|
127
|
-
assert.isTrue(item.classList.contains('hidden'), 'has the hidden class name')
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it('renders the icon', () => {
|
|
131
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="t3"]') as HTMLElement
|
|
132
|
-
const iconContainer = item.querySelector('.menu-icon') as HTMLElement
|
|
133
|
-
assert.ok(iconContainer, 'has the icon container')
|
|
134
|
-
assert.include(iconContainer.innerHTML.trim(), '<svg', 'the icon container has content')
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('renders disabled item from the "enabled" property', () => {
|
|
138
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="t4"]') as HTMLElement
|
|
139
|
-
assert.isTrue(item.classList.contains('disabled'), 'has the disabled class name')
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('renders disabled item from the "enabled" function', () => {
|
|
143
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="t5"]') as HTMLElement
|
|
144
|
-
assert.isTrue(item.classList.contains('disabled'), 'has the disabled class name')
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
it('renders hidden item from the "visible" property', () => {
|
|
148
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="t6"]') as HTMLElement
|
|
149
|
-
assert.isTrue(item.classList.contains('hidden'), 'has the hidden class name')
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
it('renders hidden item from the "visible" function', () => {
|
|
153
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="t7"]') as HTMLElement
|
|
154
|
-
assert.isTrue(item.classList.contains('hidden'), 'has the hidden class name')
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it('has the title attribute', () => {
|
|
158
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="t8"]') as HTMLElement
|
|
159
|
-
assert.equal(item.getAttribute('title'), 'test title')
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
it('dispatches the trigger event when selecting an item', async () => {
|
|
163
|
-
const spy = sinon.spy()
|
|
164
|
-
menu.addEventListener('trigger', spy)
|
|
165
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="t8"]') as UiListItem
|
|
166
|
-
item.click()
|
|
167
|
-
await nextFrame()
|
|
168
|
-
assert.isTrue(spy.calledOnce, 'The event is dispatched')
|
|
169
|
-
const { detail } = spy.args[0][0]
|
|
170
|
-
assert.isTrue(detail.command === menu.commands![7], 'has the command')
|
|
171
|
-
assert.equal(detail.item, 7, 'has the index')
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
it('renders section title', () => {
|
|
175
|
-
const item = menu.shadowRoot!.querySelector('div[data-cmd="t9"]') as HTMLElement
|
|
176
|
-
assert.ok(item, 'has the item')
|
|
177
|
-
assert.include(item.innerHTML.trim(), 'test label', 'has the provided label')
|
|
178
|
-
})
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
describe('Nested menus', () => {
|
|
182
|
-
before(async () => {
|
|
183
|
-
await setViewport({ width: 1200, height: 800 })
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
let menu: ContextualMenuElement<typeof store>
|
|
187
|
-
const commands: ContextMenuCommand<typeof store>[] = [
|
|
188
|
-
{
|
|
189
|
-
target: 'root',
|
|
190
|
-
label: 'Font size',
|
|
191
|
-
id: 'font-size',
|
|
192
|
-
children: [
|
|
193
|
-
{
|
|
194
|
-
label: '0.75 rem',
|
|
195
|
-
id: '0.75rem',
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
label: '1 rem',
|
|
199
|
-
id: '1rem',
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
label: '1.25 rem',
|
|
203
|
-
id: '1.25rem',
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
label: '1.5 rem',
|
|
207
|
-
id: '1.5rem',
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
label: '2 rem',
|
|
211
|
-
id: '2rem',
|
|
212
|
-
},
|
|
213
|
-
],
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
target: 'root',
|
|
217
|
-
label: 'Font family',
|
|
218
|
-
id: 'font-family',
|
|
219
|
-
children: [
|
|
220
|
-
{
|
|
221
|
-
label: 'Arial',
|
|
222
|
-
id: 'Arial',
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
label: 'Calibri',
|
|
226
|
-
id: 'Calibri',
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
label: 'Consolas',
|
|
230
|
-
id: 'Consolas',
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
label: 'Courier New',
|
|
234
|
-
id: 'Courier New',
|
|
235
|
-
},
|
|
236
|
-
{
|
|
237
|
-
label: 'Open Sans',
|
|
238
|
-
id: 'Open Sans',
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
label: 'Roboto',
|
|
242
|
-
id: 'Roboto',
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
label: 'Times New Roman',
|
|
246
|
-
id: 'Times New Roman',
|
|
247
|
-
},
|
|
248
|
-
],
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
target: 'root',
|
|
252
|
-
label: 'Copy',
|
|
253
|
-
id: 'copy',
|
|
254
|
-
},
|
|
255
|
-
]
|
|
256
|
-
|
|
257
|
-
beforeEach(async () => {
|
|
258
|
-
const cmd = commands.map((item) => {
|
|
259
|
-
const result = new MenuItem(item)
|
|
260
|
-
if (result.children) {
|
|
261
|
-
result.children = result.children.map((child) => new MenuItem(child))
|
|
262
|
-
}
|
|
263
|
-
return result
|
|
264
|
-
})
|
|
265
|
-
menu = await dataFixture(cmd)
|
|
266
|
-
menu.subMenuTimeout = 0
|
|
267
|
-
menu.style.top = '25px'
|
|
268
|
-
menu.style.left = '25px'
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
async function untilOpened(
|
|
272
|
-
elm: ContextualMenuElement<typeof store>,
|
|
273
|
-
name: string
|
|
274
|
-
): Promise<ContextualMenuElement<typeof store>> {
|
|
275
|
-
// make sure the menu is fully rendered
|
|
276
|
-
await nextFrame()
|
|
277
|
-
const item = elm.shadowRoot!.querySelector(`ui-list-item[data-cmd="${name}"]`) as HTMLElement
|
|
278
|
-
item.dispatchEvent(
|
|
279
|
-
new MouseEvent('mousemove', {
|
|
280
|
-
bubbles: true,
|
|
281
|
-
cancelable: true,
|
|
282
|
-
composed: true,
|
|
283
|
-
clientX: 0,
|
|
284
|
-
clientY: 0,
|
|
285
|
-
})
|
|
286
|
-
)
|
|
287
|
-
// for the menu debouncer
|
|
288
|
-
await aTimeout(1)
|
|
289
|
-
// for the menu to render
|
|
290
|
-
await nextFrame()
|
|
291
|
-
return elm.shadowRoot!.querySelector('contextual-menu')! as ContextualMenuElement<typeof store>
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
it('renders the sub-menu icon', () => {
|
|
295
|
-
const icon = menu.shadowRoot!.querySelector('.sub-menu-icon') as HTMLElement
|
|
296
|
-
assert.ok(icon)
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
it('does not render the sub-menu', () => {
|
|
300
|
-
const sub = menu.shadowRoot!.querySelector('contextual-menu') as HTMLElement
|
|
301
|
-
assert.notOk(sub)
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
it('items have data-nested attribute', () => {
|
|
305
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="font-size"]') as HTMLElement
|
|
306
|
-
assert.equal(item.getAttribute('data-nested'), 'true')
|
|
307
|
-
})
|
|
308
|
-
|
|
309
|
-
it('items have aria-haspopup attribute', () => {
|
|
310
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="font-size"]') as HTMLElement
|
|
311
|
-
assert.equal(item.getAttribute('aria-haspopup'), 'true')
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
it('opens the sub-menu', async () => {
|
|
315
|
-
const sub = await untilOpened(menu, 'font-size')
|
|
316
|
-
assert.ok(sub, 'sub menu is in the dom')
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
it('positions the sub-menu relative to the command', async () => {
|
|
320
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
321
|
-
const item = menu.shadowRoot!.querySelector('ui-list-item[data-cmd="font-family"]') as HTMLElement
|
|
322
|
-
const subBox = sub.getBoundingClientRect()
|
|
323
|
-
const itemBox = item.getBoundingClientRect()
|
|
324
|
-
// assert.isTrue(sub.positionTarget === item, 'position target is set')
|
|
325
|
-
assert.approximately(itemBox.right - 4, subBox.x, 1, 'is positioned relatively x-axis')
|
|
326
|
-
assert.approximately(itemBox.top, subBox.top, 1, 'is positioned to the top')
|
|
327
|
-
})
|
|
328
|
-
|
|
329
|
-
it('sets commands on the sub-menu', async () => {
|
|
330
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
331
|
-
assert.typeOf(sub.commands, 'array')
|
|
332
|
-
assert.lengthOf(sub.commands!, 7)
|
|
333
|
-
})
|
|
334
|
-
|
|
335
|
-
it('passes the store to the sub-menu', async () => {
|
|
336
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
337
|
-
assert.isTrue(sub.store === store)
|
|
338
|
-
})
|
|
339
|
-
|
|
340
|
-
it('passes the target to the sub-menu', async () => {
|
|
341
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
342
|
-
assert.isTrue(sub.target === target)
|
|
343
|
-
})
|
|
344
|
-
|
|
345
|
-
it('passes the workspace to the sub-menu', async () => {
|
|
346
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
347
|
-
assert.isTrue(sub.workspace === workspace)
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
it('passes the customData to the sub-menu', async () => {
|
|
351
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
352
|
-
assert.isTrue(sub.customData === customData)
|
|
353
|
-
})
|
|
354
|
-
|
|
355
|
-
it('sets the parentCommand on the sub-menu', async () => {
|
|
356
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
357
|
-
assert.equal(sub.parentCommand, 'font-family')
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
it('removes the sub-menu when closed', async () => {
|
|
361
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
362
|
-
sub.close()
|
|
363
|
-
const element = menu.shadowRoot!.querySelector('contextual-menu')
|
|
364
|
-
assert.notOk(element)
|
|
365
|
-
})
|
|
366
|
-
|
|
367
|
-
it('dispatches "trigger" event when sub-menu item is selected', async () => {
|
|
368
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
369
|
-
const spy = sinon.spy()
|
|
370
|
-
menu.addEventListener('trigger', spy)
|
|
371
|
-
const item = sub.shadowRoot!.querySelector('ui-list-item') as HTMLElement
|
|
372
|
-
item.click()
|
|
373
|
-
await nextFrame()
|
|
374
|
-
assert.isTrue(spy.calledOnce, 'the event is dispatched')
|
|
375
|
-
const { detail } = spy.args[0][0]
|
|
376
|
-
assert.isTrue(detail.command === sub.commands![0], 'passes the command')
|
|
377
|
-
assert.equal(detail.item, 0, 'passes the item')
|
|
378
|
-
assert.isUndefined(detail.parent, 'parent is not set when parent has no execute function')
|
|
379
|
-
})
|
|
380
|
-
|
|
381
|
-
it('dispatches "trigger" event with "parent"', async () => {
|
|
382
|
-
menu.commands![1].execute = (): void => {
|
|
383
|
-
//
|
|
384
|
-
}
|
|
385
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
386
|
-
const spy = sinon.spy()
|
|
387
|
-
menu.addEventListener('trigger', spy)
|
|
388
|
-
const item = sub.shadowRoot!.querySelector('ui-list-item') as HTMLElement
|
|
389
|
-
item.click()
|
|
390
|
-
await nextFrame()
|
|
391
|
-
const { detail } = spy.args[0][0]
|
|
392
|
-
assert.isTrue(detail.parent === menu.commands![1], 'passes the parent')
|
|
393
|
-
})
|
|
394
|
-
|
|
395
|
-
it('opens another sub-menu and closes previous one', async () => {
|
|
396
|
-
const previous = await untilOpened(menu, 'font-family')
|
|
397
|
-
const current = await untilOpened(menu, 'font-size')
|
|
398
|
-
assert.notOk(previous.parentNode, 'previous menu is removed')
|
|
399
|
-
assert.ok(current.parentNode, 'new menu is rendered')
|
|
400
|
-
})
|
|
401
|
-
|
|
402
|
-
it('closes the sub-menu when hovering another item', async () => {
|
|
403
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
404
|
-
const item = menu.shadowRoot!.querySelector(`ui-list-item[data-cmd="copy"]`) as HTMLElement
|
|
405
|
-
item.dispatchEvent(
|
|
406
|
-
new MouseEvent('mousemove', {
|
|
407
|
-
bubbles: true,
|
|
408
|
-
cancelable: true,
|
|
409
|
-
composed: true,
|
|
410
|
-
clientX: 0,
|
|
411
|
-
clientY: 0,
|
|
412
|
-
})
|
|
413
|
-
)
|
|
414
|
-
await aTimeout(1)
|
|
415
|
-
assert.notOk(sub.parentNode, 'previous menu is removed')
|
|
416
|
-
})
|
|
417
|
-
|
|
418
|
-
it('closes the sub-menu when arrow-left', async () => {
|
|
419
|
-
const sub = await untilOpened(menu, 'font-family')
|
|
420
|
-
const item = sub.shadowRoot!.querySelector(`ui-list-item`)!
|
|
421
|
-
item.dispatchEvent(
|
|
422
|
-
new KeyboardEvent('keydown', {
|
|
423
|
-
bubbles: true,
|
|
424
|
-
cancelable: true,
|
|
425
|
-
composed: true,
|
|
426
|
-
code: 'ArrowLeft',
|
|
427
|
-
})
|
|
428
|
-
)
|
|
429
|
-
assert.notOk(sub.parentNode, 'previous menu is removed')
|
|
430
|
-
})
|
|
431
|
-
|
|
432
|
-
it('opens the sub-menu when arrow-right', async () => {
|
|
433
|
-
await nextFrame()
|
|
434
|
-
menu.focus({ selectFirst: true })
|
|
435
|
-
await menu.updateComplete
|
|
436
|
-
menu.dispatchEvent(
|
|
437
|
-
new KeyboardEvent('keydown', {
|
|
438
|
-
bubbles: true,
|
|
439
|
-
cancelable: true,
|
|
440
|
-
composed: true,
|
|
441
|
-
code: 'ArrowRight',
|
|
442
|
-
})
|
|
443
|
-
)
|
|
444
|
-
await nextFrame()
|
|
445
|
-
const sub = menu.shadowRoot!.querySelector('contextual-menu')
|
|
446
|
-
assert.ok(sub)
|
|
447
|
-
})
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
describe('Radio menus', () => {
|
|
451
|
-
before(async () => {
|
|
452
|
-
await setViewport({ width: 1200, height: 800 })
|
|
453
|
-
})
|
|
454
|
-
|
|
455
|
-
interface StoreItem {
|
|
456
|
-
'font-size': string
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
let menu: ContextualMenuElement<StoreItem>
|
|
460
|
-
const commands: ContextMenuCommand<StoreItem>[] = [
|
|
461
|
-
{
|
|
462
|
-
target: 'all',
|
|
463
|
-
label: 'Font',
|
|
464
|
-
title: 'Select a default font for the UI',
|
|
465
|
-
id: 'font-size',
|
|
466
|
-
execute: (ctx: CommandExecuteOptions<StoreItem>): void => {
|
|
467
|
-
const size = ctx.item.id.replace('font-', '')
|
|
468
|
-
ctx.store['font-size'] = size
|
|
469
|
-
// ctx.store.set('font-size', size)
|
|
470
|
-
},
|
|
471
|
-
children: [
|
|
472
|
-
{
|
|
473
|
-
type: 'radio',
|
|
474
|
-
label: 'Small',
|
|
475
|
-
id: 'font-small',
|
|
476
|
-
checked: (ctx: CheckedMenuOptions<StoreItem>): boolean => {
|
|
477
|
-
const fs = ctx.store['font-size']
|
|
478
|
-
return fs === 'small'
|
|
479
|
-
},
|
|
480
|
-
},
|
|
481
|
-
{
|
|
482
|
-
type: 'radio',
|
|
483
|
-
label: 'Normal',
|
|
484
|
-
id: 'font-normal',
|
|
485
|
-
checked: (ctx: CheckedMenuOptions<StoreItem>): boolean => {
|
|
486
|
-
const fs = ctx.store['font-size']
|
|
487
|
-
return !fs || fs === 'normal'
|
|
488
|
-
},
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
type: 'radio',
|
|
492
|
-
label: 'Large',
|
|
493
|
-
id: 'font-large',
|
|
494
|
-
checked: (ctx: CheckedMenuOptions<StoreItem>): boolean => {
|
|
495
|
-
const fs = ctx.store['font-size']
|
|
496
|
-
return fs === 'large'
|
|
497
|
-
},
|
|
498
|
-
},
|
|
499
|
-
],
|
|
500
|
-
},
|
|
501
|
-
]
|
|
502
|
-
|
|
503
|
-
beforeEach(async () => {
|
|
504
|
-
const cmd = commands.map((item) => {
|
|
505
|
-
const result = new MenuItem(item)
|
|
506
|
-
if (result.children) {
|
|
507
|
-
result.children = result.children.map((child) => new MenuItem(child))
|
|
508
|
-
}
|
|
509
|
-
return result
|
|
510
|
-
})
|
|
511
|
-
menu = await dataFixture(cmd)
|
|
512
|
-
menu.subMenuTimeout = 0
|
|
513
|
-
menu.style.top = '25px'
|
|
514
|
-
menu.style.left = '25px'
|
|
515
|
-
})
|
|
516
|
-
|
|
517
|
-
async function untilOpened<T>(elm: ContextualMenuElement<T>, name: string): Promise<ContextualMenuElement<T>> {
|
|
518
|
-
// make sure the menu is fully rendered
|
|
519
|
-
await nextFrame()
|
|
520
|
-
const item = elm.shadowRoot!.querySelector(`ui-list-item[data-cmd="${name}"]`) as HTMLElement
|
|
521
|
-
item.dispatchEvent(
|
|
522
|
-
new MouseEvent('mousemove', {
|
|
523
|
-
bubbles: true,
|
|
524
|
-
cancelable: true,
|
|
525
|
-
composed: true,
|
|
526
|
-
clientX: 0,
|
|
527
|
-
clientY: 0,
|
|
528
|
-
})
|
|
529
|
-
)
|
|
530
|
-
// for the menu debouncer
|
|
531
|
-
await aTimeout(1)
|
|
532
|
-
// for the menu to render
|
|
533
|
-
await nextFrame()
|
|
534
|
-
return elm.shadowRoot!.querySelector('contextual-menu')! as ContextualMenuElement<T>
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
it('has the selected item', async () => {
|
|
538
|
-
const sub = await untilOpened(menu, 'font-size')
|
|
539
|
-
const item = sub.shadowRoot!.querySelector('ui-list-item[data-cmd="font-normal"]') as HTMLElement
|
|
540
|
-
const checkIcon = item.querySelector('.menu-icon[data-state="checked"]')
|
|
541
|
-
assert.ok(checkIcon)
|
|
542
|
-
})
|
|
543
|
-
|
|
544
|
-
it('has no selection when not set', async () => {
|
|
545
|
-
const sub = await untilOpened(menu, 'font-size')
|
|
546
|
-
const item1 = sub.shadowRoot!.querySelector('ui-list-item[data-cmd="font-small"]') as HTMLElement
|
|
547
|
-
const checkIcon1 = item1.querySelector('.menu-icon[data-state="checked"]')
|
|
548
|
-
assert.notOk(checkIcon1, 'first item has no selection')
|
|
549
|
-
|
|
550
|
-
const item2 = sub.shadowRoot!.querySelector('ui-list-item[data-cmd="font-large"]') as HTMLElement
|
|
551
|
-
const checkIcon2 = item2.querySelector('.menu-icon[data-state="checked"]')
|
|
552
|
-
assert.notOk(checkIcon2, 'third item has no selection')
|
|
553
|
-
})
|
|
554
|
-
|
|
555
|
-
it('has the data-type property', async () => {
|
|
556
|
-
const sub = await untilOpened(menu, 'font-size')
|
|
557
|
-
const item = sub.shadowRoot!.querySelector('ui-list-item[data-cmd="font-normal"]') as HTMLElement
|
|
558
|
-
assert.equal(item.getAttribute('data-type'), 'radio')
|
|
559
|
-
})
|
|
560
|
-
|
|
561
|
-
it('uses the boolean checked value to determine the state', async () => {
|
|
562
|
-
;(menu.commands![0].children![0] as ContextMenuCommand).checked = true
|
|
563
|
-
const sub = await untilOpened(menu, 'font-size')
|
|
564
|
-
const item = sub.shadowRoot!.querySelector('ui-list-item[data-cmd="font-small"]') as HTMLElement
|
|
565
|
-
const checkIcon = item.querySelector('.menu-icon[data-state="checked"]')
|
|
566
|
-
assert.ok(checkIcon)
|
|
567
|
-
})
|
|
568
|
-
})
|
|
569
|
-
})
|