@furystack/shades-common-components 10.0.35 → 11.0.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 +66 -0
- package/esm/components/animations.spec.d.ts +2 -0
- package/esm/components/animations.spec.d.ts.map +1 -0
- package/esm/components/animations.spec.js +201 -0
- package/esm/components/animations.spec.js.map +1 -0
- package/esm/components/app-bar-link.js +21 -20
- package/esm/components/app-bar-link.js.map +1 -1
- package/esm/components/app-bar-link.spec.d.ts +2 -0
- package/esm/components/app-bar-link.spec.d.ts.map +1 -0
- package/esm/components/app-bar-link.spec.js +252 -0
- package/esm/components/app-bar-link.spec.js.map +1 -0
- package/esm/components/app-bar.js +21 -21
- package/esm/components/app-bar.js.map +1 -1
- package/esm/components/app-bar.spec.d.ts +2 -0
- package/esm/components/app-bar.spec.d.ts.map +1 -0
- package/esm/components/app-bar.spec.js +117 -0
- package/esm/components/app-bar.spec.js.map +1 -0
- package/esm/components/avatar.d.ts.map +1 -1
- package/esm/components/avatar.js +15 -19
- package/esm/components/avatar.js.map +1 -1
- package/esm/components/avatar.spec.d.ts +2 -0
- package/esm/components/avatar.spec.d.ts.map +1 -0
- package/esm/components/avatar.spec.js +114 -0
- package/esm/components/avatar.spec.js.map +1 -0
- package/esm/components/button.d.ts.map +1 -1
- package/esm/components/button.js +145 -156
- package/esm/components/button.js.map +1 -1
- package/esm/components/button.spec.d.ts +2 -0
- package/esm/components/button.spec.d.ts.map +1 -0
- package/esm/components/button.spec.js +155 -0
- package/esm/components/button.spec.js.map +1 -0
- package/esm/components/command-palette/command-palette-input.d.ts.map +1 -1
- package/esm/components/command-palette/command-palette-input.js +18 -16
- package/esm/components/command-palette/command-palette-input.js.map +1 -1
- package/esm/components/command-palette/command-palette-input.spec.d.ts +2 -0
- package/esm/components/command-palette/command-palette-input.spec.d.ts.map +1 -0
- package/esm/components/command-palette/command-palette-input.spec.js +233 -0
- package/esm/components/command-palette/command-palette-input.spec.js.map +1 -0
- package/esm/components/command-palette/command-palette-manager.spec.d.ts +2 -0
- package/esm/components/command-palette/command-palette-manager.spec.d.ts.map +1 -0
- package/esm/components/command-palette/command-palette-manager.spec.js +362 -0
- package/esm/components/command-palette/command-palette-manager.spec.js.map +1 -0
- package/esm/components/command-palette/command-palette-suggestion-list.d.ts.map +1 -1
- package/esm/components/command-palette/command-palette-suggestion-list.js +42 -46
- package/esm/components/command-palette/command-palette-suggestion-list.js.map +1 -1
- package/esm/components/command-palette/command-palette-suggestion-list.spec.d.ts +2 -0
- package/esm/components/command-palette/command-palette-suggestion-list.spec.d.ts.map +1 -0
- package/esm/components/command-palette/command-palette-suggestion-list.spec.js +376 -0
- package/esm/components/command-palette/command-palette-suggestion-list.spec.js.map +1 -0
- package/esm/components/command-palette/index.d.ts.map +1 -1
- package/esm/components/command-palette/index.js +100 -110
- package/esm/components/command-palette/index.js.map +1 -1
- package/esm/components/command-palette/index.spec.d.ts +2 -0
- package/esm/components/command-palette/index.spec.d.ts.map +1 -0
- package/esm/components/command-palette/index.spec.js +509 -0
- package/esm/components/command-palette/index.spec.js.map +1 -0
- package/esm/components/data-grid/body.js +1 -1
- package/esm/components/data-grid/body.js.map +1 -1
- package/esm/components/data-grid/body.spec.d.ts +2 -0
- package/esm/components/data-grid/body.spec.d.ts.map +1 -0
- package/esm/components/data-grid/body.spec.js +228 -0
- package/esm/components/data-grid/body.spec.js.map +1 -0
- package/esm/components/data-grid/data-grid-row.d.ts.map +1 -1
- package/esm/components/data-grid/data-grid-row.js +49 -73
- package/esm/components/data-grid/data-grid-row.js.map +1 -1
- package/esm/components/data-grid/data-grid-row.spec.d.ts +2 -0
- package/esm/components/data-grid/data-grid-row.spec.d.ts.map +1 -0
- package/esm/components/data-grid/data-grid-row.spec.js +296 -0
- package/esm/components/data-grid/data-grid-row.spec.js.map +1 -0
- package/esm/components/data-grid/data-grid.d.ts.map +1 -1
- package/esm/components/data-grid/data-grid.js +35 -28
- package/esm/components/data-grid/data-grid.js.map +1 -1
- package/esm/components/data-grid/data-grid.spec.d.ts +2 -0
- package/esm/components/data-grid/data-grid.spec.d.ts.map +1 -0
- package/esm/components/data-grid/data-grid.spec.js +544 -0
- package/esm/components/data-grid/data-grid.spec.js.map +1 -0
- package/esm/components/data-grid/footer.js +21 -15
- package/esm/components/data-grid/footer.js.map +1 -1
- package/esm/components/data-grid/footer.spec.d.ts +2 -0
- package/esm/components/data-grid/footer.spec.d.ts.map +1 -0
- package/esm/components/data-grid/footer.spec.js +264 -0
- package/esm/components/data-grid/footer.spec.js.map +1 -0
- package/esm/components/data-grid/header.d.ts.map +1 -1
- package/esm/components/data-grid/header.js +55 -33
- package/esm/components/data-grid/header.js.map +1 -1
- package/esm/components/data-grid/header.spec.d.ts +2 -0
- package/esm/components/data-grid/header.spec.d.ts.map +1 -0
- package/esm/components/data-grid/header.spec.js +421 -0
- package/esm/components/data-grid/header.spec.js.map +1 -0
- package/esm/components/data-grid/selection-cell.d.ts.map +1 -1
- package/esm/components/data-grid/selection-cell.js +13 -6
- package/esm/components/data-grid/selection-cell.js.map +1 -1
- package/esm/components/data-grid/selection-cell.spec.d.ts +2 -0
- package/esm/components/data-grid/selection-cell.spec.d.ts.map +1 -0
- package/esm/components/data-grid/selection-cell.spec.js +118 -0
- package/esm/components/data-grid/selection-cell.spec.js.map +1 -0
- package/esm/components/fab.d.ts.map +1 -1
- package/esm/components/fab.js +10 -1
- package/esm/components/fab.js.map +1 -1
- package/esm/components/fab.spec.d.ts +2 -0
- package/esm/components/fab.spec.d.ts.map +1 -0
- package/esm/components/fab.spec.js +95 -0
- package/esm/components/fab.spec.js.map +1 -0
- package/esm/components/form.spec.d.ts +2 -0
- package/esm/components/form.spec.d.ts.map +1 -0
- package/esm/components/form.spec.js +314 -0
- package/esm/components/form.spec.js.map +1 -0
- package/esm/components/grid.d.ts.map +1 -1
- package/esm/components/grid.js +40 -37
- package/esm/components/grid.js.map +1 -1
- package/esm/components/grid.spec.d.ts +2 -0
- package/esm/components/grid.spec.d.ts.map +1 -0
- package/esm/components/grid.spec.js +316 -0
- package/esm/components/grid.spec.js.map +1 -0
- package/esm/components/inputs/autocomplete.spec.d.ts +2 -0
- package/esm/components/inputs/autocomplete.spec.d.ts.map +1 -0
- package/esm/components/inputs/autocomplete.spec.js +194 -0
- package/esm/components/inputs/autocomplete.spec.js.map +1 -0
- package/esm/components/inputs/input.d.ts.map +1 -1
- package/esm/components/inputs/input.js +141 -109
- package/esm/components/inputs/input.js.map +1 -1
- package/esm/components/inputs/input.spec.d.ts +2 -0
- package/esm/components/inputs/input.spec.d.ts.map +1 -0
- package/esm/components/inputs/input.spec.js +577 -0
- package/esm/components/inputs/input.spec.js.map +1 -0
- package/esm/components/inputs/text-area.d.ts.map +1 -1
- package/esm/components/inputs/text-area.js +54 -58
- package/esm/components/inputs/text-area.js.map +1 -1
- package/esm/components/inputs/text-area.spec.d.ts +2 -0
- package/esm/components/inputs/text-area.spec.d.ts.map +1 -0
- package/esm/components/inputs/text-area.spec.js +214 -0
- package/esm/components/inputs/text-area.spec.js.map +1 -0
- package/esm/components/loader.js +1 -1
- package/esm/components/loader.js.map +1 -1
- package/esm/components/loader.spec.d.ts +2 -0
- package/esm/components/loader.spec.d.ts.map +1 -0
- package/esm/components/loader.spec.js +251 -0
- package/esm/components/loader.spec.js.map +1 -0
- package/esm/components/modal.d.ts.map +1 -1
- package/esm/components/modal.js +11 -9
- package/esm/components/modal.js.map +1 -1
- package/esm/components/modal.spec.d.ts +2 -0
- package/esm/components/modal.spec.d.ts.map +1 -0
- package/esm/components/modal.spec.js +227 -0
- package/esm/components/modal.spec.js.map +1 -0
- package/esm/components/noty-list.d.ts.map +1 -1
- package/esm/components/noty-list.js +39 -40
- package/esm/components/noty-list.js.map +1 -1
- package/esm/components/noty-list.spec.d.ts +2 -0
- package/esm/components/noty-list.spec.d.ts.map +1 -0
- package/esm/components/noty-list.spec.js +486 -0
- package/esm/components/noty-list.spec.js.map +1 -0
- package/esm/components/paper.d.ts.map +1 -1
- package/esm/components/paper.js +15 -12
- package/esm/components/paper.js.map +1 -1
- package/esm/components/paper.spec.d.ts +2 -0
- package/esm/components/paper.spec.d.ts.map +1 -0
- package/esm/components/paper.spec.js +63 -0
- package/esm/components/paper.spec.js.map +1 -0
- package/esm/components/skeleton.js +1 -1
- package/esm/components/skeleton.js.map +1 -1
- package/esm/components/skeleton.spec.d.ts +2 -0
- package/esm/components/skeleton.spec.d.ts.map +1 -0
- package/esm/components/skeleton.spec.js +159 -0
- package/esm/components/skeleton.spec.js.map +1 -0
- package/esm/components/styles.spec.d.ts +2 -0
- package/esm/components/styles.spec.d.ts.map +1 -0
- package/esm/components/styles.spec.js +56 -0
- package/esm/components/styles.spec.js.map +1 -0
- package/esm/components/suggest/index.d.ts.map +1 -1
- package/esm/components/suggest/index.js +74 -83
- package/esm/components/suggest/index.js.map +1 -1
- package/esm/components/suggest/index.spec.d.ts +2 -0
- package/esm/components/suggest/index.spec.d.ts.map +1 -0
- package/esm/components/suggest/index.spec.js +515 -0
- package/esm/components/suggest/index.spec.js.map +1 -0
- package/esm/components/suggest/suggest-input.d.ts.map +1 -1
- package/esm/components/suggest/suggest-input.js +16 -17
- package/esm/components/suggest/suggest-input.js.map +1 -1
- package/esm/components/suggest/suggest-input.spec.d.ts +2 -0
- package/esm/components/suggest/suggest-input.spec.d.ts.map +1 -0
- package/esm/components/suggest/suggest-input.spec.js +138 -0
- package/esm/components/suggest/suggest-input.spec.js.map +1 -0
- package/esm/components/suggest/suggest-manager.spec.d.ts +2 -0
- package/esm/components/suggest/suggest-manager.spec.d.ts.map +1 -0
- package/esm/components/suggest/suggest-manager.spec.js +308 -0
- package/esm/components/suggest/suggest-manager.spec.js.map +1 -0
- package/esm/components/suggest/suggestion-list.d.ts.map +1 -1
- package/esm/components/suggest/suggestion-list.js +43 -48
- package/esm/components/suggest/suggestion-list.js.map +1 -1
- package/esm/components/suggest/suggestion-list.spec.d.ts +2 -0
- package/esm/components/suggest/suggestion-list.spec.d.ts.map +1 -0
- package/esm/components/suggest/suggestion-list.spec.js +252 -0
- package/esm/components/suggest/suggestion-list.spec.js.map +1 -0
- package/esm/components/tabs.d.ts.map +1 -1
- package/esm/components/tabs.js +32 -18
- package/esm/components/tabs.js.map +1 -1
- package/esm/components/tabs.spec.d.ts +2 -0
- package/esm/components/tabs.spec.d.ts.map +1 -0
- package/esm/components/tabs.spec.js +187 -0
- package/esm/components/tabs.spec.js.map +1 -0
- package/esm/components/wizard/index.d.ts.map +1 -1
- package/esm/components/wizard/index.js +10 -7
- package/esm/components/wizard/index.js.map +1 -1
- package/esm/components/wizard/index.spec.d.ts +2 -0
- package/esm/components/wizard/index.spec.d.ts.map +1 -0
- package/esm/components/wizard/index.spec.js +171 -0
- package/esm/components/wizard/index.spec.js.map +1 -0
- package/esm/services/collection-service.spec.js +391 -2
- package/esm/services/collection-service.spec.js.map +1 -1
- package/esm/services/css-variable-theme.d.ts.map +1 -1
- package/esm/services/css-variable-theme.js +21 -1
- package/esm/services/css-variable-theme.js.map +1 -1
- package/esm/services/css-variable-theme.spec.d.ts +2 -0
- package/esm/services/css-variable-theme.spec.d.ts.map +1 -0
- package/esm/services/css-variable-theme.spec.js +169 -0
- package/esm/services/css-variable-theme.spec.js.map +1 -0
- package/esm/services/default-palette.d.ts +4 -0
- package/esm/services/default-palette.d.ts.map +1 -1
- package/esm/services/default-palette.js +22 -0
- package/esm/services/default-palette.js.map +1 -1
- package/esm/services/theme-provider-service.d.ts +59 -1
- package/esm/services/theme-provider-service.d.ts.map +1 -1
- package/esm/services/theme-provider-service.js.map +1 -1
- package/esm/services/theme-provider-service.spec.d.ts +2 -0
- package/esm/services/theme-provider-service.spec.d.ts.map +1 -0
- package/esm/services/theme-provider-service.spec.js +166 -0
- package/esm/services/theme-provider-service.spec.js.map +1 -0
- package/package.json +2 -2
- package/src/components/animations.spec.ts +299 -0
- package/src/components/app-bar-link.spec.tsx +341 -0
- package/src/components/app-bar-link.tsx +21 -21
- package/src/components/app-bar.spec.tsx +142 -0
- package/src/components/app-bar.tsx +22 -22
- package/src/components/avatar.spec.tsx +146 -0
- package/src/components/avatar.tsx +17 -20
- package/src/components/button.spec.tsx +193 -0
- package/src/components/button.tsx +162 -197
- package/src/components/command-palette/command-palette-input.spec.tsx +320 -0
- package/src/components/command-palette/command-palette-input.tsx +19 -22
- package/src/components/command-palette/command-palette-manager.spec.ts +470 -0
- package/src/components/command-palette/command-palette-suggestion-list.spec.tsx +499 -0
- package/src/components/command-palette/command-palette-suggestion-list.tsx +42 -46
- package/src/components/command-palette/index.spec.tsx +684 -0
- package/src/components/command-palette/index.tsx +107 -136
- package/src/components/data-grid/body.spec.tsx +340 -0
- package/src/components/data-grid/body.tsx +1 -1
- package/src/components/data-grid/data-grid-row.spec.tsx +382 -0
- package/src/components/data-grid/data-grid-row.tsx +50 -82
- package/src/components/data-grid/data-grid.spec.tsx +939 -0
- package/src/components/data-grid/data-grid.tsx +38 -35
- package/src/components/data-grid/footer.spec.tsx +344 -0
- package/src/components/data-grid/footer.tsx +19 -19
- package/src/components/data-grid/header.spec.tsx +563 -0
- package/src/components/data-grid/header.tsx +53 -44
- package/src/components/data-grid/selection-cell.spec.tsx +150 -0
- package/src/components/data-grid/selection-cell.tsx +12 -6
- package/src/components/fab.spec.tsx +108 -0
- package/src/components/fab.tsx +10 -1
- package/src/components/form.spec.tsx +481 -0
- package/src/components/grid.spec.tsx +334 -0
- package/src/components/grid.tsx +57 -63
- package/src/components/inputs/autocomplete.spec.tsx +258 -0
- package/src/components/inputs/input.spec.tsx +808 -0
- package/src/components/inputs/input.tsx +153 -139
- package/src/components/inputs/text-area.spec.tsx +285 -0
- package/src/components/inputs/text-area.tsx +53 -79
- package/src/components/loader.spec.tsx +346 -0
- package/src/components/loader.tsx +1 -1
- package/src/components/modal.spec.tsx +304 -0
- package/src/components/modal.tsx +11 -9
- package/src/components/noty-list.spec.tsx +631 -0
- package/src/components/noty-list.tsx +39 -50
- package/src/components/paper.spec.tsx +72 -0
- package/src/components/paper.tsx +15 -13
- package/src/components/skeleton.spec.tsx +219 -0
- package/src/components/skeleton.tsx +1 -1
- package/src/components/styles.spec.ts +70 -0
- package/src/components/suggest/index.spec.tsx +861 -0
- package/src/components/suggest/index.tsx +74 -101
- package/src/components/suggest/suggest-input.spec.tsx +181 -0
- package/src/components/suggest/suggest-input.tsx +16 -24
- package/src/components/suggest/suggest-manager.spec.ts +409 -0
- package/src/components/suggest/suggestion-list.spec.tsx +334 -0
- package/src/components/suggest/suggestion-list.tsx +43 -48
- package/src/components/tabs.spec.tsx +236 -0
- package/src/components/tabs.tsx +33 -21
- package/src/components/wizard/index.spec.tsx +224 -0
- package/src/components/wizard/index.tsx +10 -9
- package/src/services/collection-service.spec.ts +492 -3
- package/src/services/css-variable-theme.spec.ts +204 -0
- package/src/services/css-variable-theme.ts +21 -1
- package/src/services/default-palette.ts +22 -0
- package/src/services/theme-provider-service.spec.ts +195 -0
- package/src/services/theme-provider-service.ts +60 -2
|
@@ -0,0 +1,684 @@
|
|
|
1
|
+
import { Injector } from '@furystack/inject'
|
|
2
|
+
import { createComponent, initializeShadeRoot } from '@furystack/shades'
|
|
3
|
+
import { sleepAsync, usingAsync } from '@furystack/utils'
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
5
|
+
import type { CommandPaletteSuggestionResult, CommandProvider } from './command-provider.js'
|
|
6
|
+
import { CommandPalette } from './index.js'
|
|
7
|
+
|
|
8
|
+
describe('CommandPalette', () => {
|
|
9
|
+
let originalAnimate: typeof Element.prototype.animate
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
document.body.innerHTML = '<div id="root"></div>'
|
|
13
|
+
|
|
14
|
+
originalAnimate = Element.prototype.animate
|
|
15
|
+
|
|
16
|
+
Element.prototype.animate = vi.fn(() => {
|
|
17
|
+
const mockAnimation = {
|
|
18
|
+
onfinish: null as ((event: AnimationPlaybackEvent) => void) | null,
|
|
19
|
+
oncancel: null as ((event: AnimationPlaybackEvent) => void) | null,
|
|
20
|
+
cancel: vi.fn(),
|
|
21
|
+
play: vi.fn(),
|
|
22
|
+
pause: vi.fn(),
|
|
23
|
+
finish: vi.fn(),
|
|
24
|
+
addEventListener: vi.fn(),
|
|
25
|
+
removeEventListener: vi.fn(),
|
|
26
|
+
}
|
|
27
|
+
return mockAnimation as unknown as Animation
|
|
28
|
+
}) as typeof Element.prototype.animate
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
document.body.innerHTML = ''
|
|
33
|
+
Element.prototype.animate = originalAnimate
|
|
34
|
+
vi.restoreAllMocks()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const createMockProvider = (results: CommandPaletteSuggestionResult[]): CommandProvider => {
|
|
38
|
+
return vi.fn(async () => results)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const createSuggestion = (
|
|
42
|
+
text: string,
|
|
43
|
+
score: number,
|
|
44
|
+
onSelected: (options: { injector: Injector }) => void = vi.fn(),
|
|
45
|
+
): CommandPaletteSuggestionResult => ({
|
|
46
|
+
element: <span>{text}</span>,
|
|
47
|
+
score,
|
|
48
|
+
onSelected,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
describe('rendering', () => {
|
|
52
|
+
it('should render the shade-command-palette custom element', async () => {
|
|
53
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
54
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
55
|
+
|
|
56
|
+
initializeShadeRoot({
|
|
57
|
+
injector,
|
|
58
|
+
rootElement,
|
|
59
|
+
jsxElement: <CommandPalette commandProviders={[]} defaultPrefix=">" />,
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
await sleepAsync(50)
|
|
63
|
+
|
|
64
|
+
const commandPalette = document.querySelector('shade-command-palette')
|
|
65
|
+
expect(commandPalette).not.toBeNull()
|
|
66
|
+
expect(commandPalette?.tagName.toLowerCase()).toBe('shade-command-palette')
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('should render the default prefix', async () => {
|
|
71
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
72
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
73
|
+
|
|
74
|
+
initializeShadeRoot({
|
|
75
|
+
injector,
|
|
76
|
+
rootElement,
|
|
77
|
+
jsxElement: <CommandPalette commandProviders={[]} defaultPrefix=">" />,
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
await sleepAsync(50)
|
|
81
|
+
|
|
82
|
+
expect(document.body.innerHTML).toContain('>')
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('should render input component', async () => {
|
|
87
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
88
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
89
|
+
|
|
90
|
+
initializeShadeRoot({
|
|
91
|
+
injector,
|
|
92
|
+
rootElement,
|
|
93
|
+
jsxElement: <CommandPalette commandProviders={[]} defaultPrefix=">" />,
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
await sleepAsync(50)
|
|
97
|
+
|
|
98
|
+
const input = document.querySelector('shades-command-palette-input')
|
|
99
|
+
expect(input).not.toBeNull()
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('should render suggestion list component', async () => {
|
|
104
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
105
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
106
|
+
|
|
107
|
+
initializeShadeRoot({
|
|
108
|
+
injector,
|
|
109
|
+
rootElement,
|
|
110
|
+
jsxElement: <CommandPalette commandProviders={[]} defaultPrefix=">" />,
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
await sleepAsync(50)
|
|
114
|
+
|
|
115
|
+
const suggestionList = document.querySelector('shade-command-palette-suggestion-list')
|
|
116
|
+
expect(suggestionList).not.toBeNull()
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
describe('keyboard navigation', () => {
|
|
122
|
+
const triggerKeyup = (input: HTMLInputElement, key: string) => {
|
|
123
|
+
const event = new KeyboardEvent('keyup', { key, bubbles: true })
|
|
124
|
+
Object.defineProperty(event, 'target', { value: input, writable: false })
|
|
125
|
+
input.dispatchEvent(event)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const getSuggestionItems = (commandPalette: HTMLElement) => {
|
|
129
|
+
const suggestionList = commandPalette.querySelector('shade-command-palette-suggestion-list') as HTMLElement
|
|
130
|
+
return suggestionList?.querySelectorAll('.suggestion-item') || []
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
it('should navigate down with ArrowDown key', async () => {
|
|
134
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
135
|
+
const provider = createMockProvider([
|
|
136
|
+
createSuggestion('Item 1', 100),
|
|
137
|
+
createSuggestion('Item 2', 90),
|
|
138
|
+
createSuggestion('Item 3', 80),
|
|
139
|
+
])
|
|
140
|
+
|
|
141
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
142
|
+
|
|
143
|
+
initializeShadeRoot({
|
|
144
|
+
injector,
|
|
145
|
+
rootElement,
|
|
146
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
await sleepAsync(50)
|
|
150
|
+
|
|
151
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
152
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
153
|
+
|
|
154
|
+
// Open and trigger suggestions
|
|
155
|
+
input.value = 'test'
|
|
156
|
+
triggerKeyup(input, 'a')
|
|
157
|
+
|
|
158
|
+
await sleepAsync(300)
|
|
159
|
+
|
|
160
|
+
// Press ArrowDown
|
|
161
|
+
triggerKeyup(input, 'ArrowDown')
|
|
162
|
+
await sleepAsync(50)
|
|
163
|
+
|
|
164
|
+
const suggestionItems = getSuggestionItems(commandPalette)
|
|
165
|
+
expect(suggestionItems[1]?.classList.contains('selected')).toBe(true)
|
|
166
|
+
})
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('should navigate up with ArrowUp key', async () => {
|
|
170
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
171
|
+
const provider = createMockProvider([
|
|
172
|
+
createSuggestion('Item 1', 100),
|
|
173
|
+
createSuggestion('Item 2', 90),
|
|
174
|
+
createSuggestion('Item 3', 80),
|
|
175
|
+
])
|
|
176
|
+
|
|
177
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
178
|
+
|
|
179
|
+
initializeShadeRoot({
|
|
180
|
+
injector,
|
|
181
|
+
rootElement,
|
|
182
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
await sleepAsync(50)
|
|
186
|
+
|
|
187
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
188
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
189
|
+
|
|
190
|
+
// Open and trigger suggestions
|
|
191
|
+
input.value = 'test'
|
|
192
|
+
triggerKeyup(input, 'a')
|
|
193
|
+
|
|
194
|
+
await sleepAsync(300)
|
|
195
|
+
|
|
196
|
+
// Navigate down then up
|
|
197
|
+
triggerKeyup(input, 'ArrowDown')
|
|
198
|
+
await sleepAsync(50)
|
|
199
|
+
triggerKeyup(input, 'ArrowUp')
|
|
200
|
+
await sleepAsync(50)
|
|
201
|
+
|
|
202
|
+
const suggestionItems = getSuggestionItems(commandPalette)
|
|
203
|
+
expect(suggestionItems[0]?.classList.contains('selected')).toBe(true)
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it('should not navigate below the last item', async () => {
|
|
208
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
209
|
+
const provider = createMockProvider([createSuggestion('Item 1', 100), createSuggestion('Item 2', 90)])
|
|
210
|
+
|
|
211
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
212
|
+
|
|
213
|
+
initializeShadeRoot({
|
|
214
|
+
injector,
|
|
215
|
+
rootElement,
|
|
216
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
await sleepAsync(50)
|
|
220
|
+
|
|
221
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
222
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
223
|
+
|
|
224
|
+
input.value = 'test'
|
|
225
|
+
triggerKeyup(input, 'a')
|
|
226
|
+
|
|
227
|
+
await sleepAsync(300)
|
|
228
|
+
|
|
229
|
+
// Press ArrowDown multiple times
|
|
230
|
+
triggerKeyup(input, 'ArrowDown')
|
|
231
|
+
triggerKeyup(input, 'ArrowDown')
|
|
232
|
+
triggerKeyup(input, 'ArrowDown')
|
|
233
|
+
await sleepAsync(50)
|
|
234
|
+
|
|
235
|
+
const suggestionItems = getSuggestionItems(commandPalette)
|
|
236
|
+
expect(suggestionItems[1]?.classList.contains('selected')).toBe(true)
|
|
237
|
+
})
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
it('should not navigate above the first item', async () => {
|
|
241
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
242
|
+
const provider = createMockProvider([createSuggestion('Item 1', 100), createSuggestion('Item 2', 90)])
|
|
243
|
+
|
|
244
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
245
|
+
|
|
246
|
+
initializeShadeRoot({
|
|
247
|
+
injector,
|
|
248
|
+
rootElement,
|
|
249
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
await sleepAsync(50)
|
|
253
|
+
|
|
254
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
255
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
256
|
+
|
|
257
|
+
input.value = 'test'
|
|
258
|
+
triggerKeyup(input, 'a')
|
|
259
|
+
|
|
260
|
+
await sleepAsync(300)
|
|
261
|
+
|
|
262
|
+
// Press ArrowUp when already at first item
|
|
263
|
+
triggerKeyup(input, 'ArrowUp')
|
|
264
|
+
await sleepAsync(50)
|
|
265
|
+
|
|
266
|
+
const suggestionItems = getSuggestionItems(commandPalette)
|
|
267
|
+
expect(suggestionItems[0]?.classList.contains('selected')).toBe(true)
|
|
268
|
+
})
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('should select suggestion on Enter key', async () => {
|
|
272
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
273
|
+
const onSelected = vi.fn()
|
|
274
|
+
const provider = createMockProvider([createSuggestion('Item 1', 100, onSelected)])
|
|
275
|
+
|
|
276
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
277
|
+
|
|
278
|
+
initializeShadeRoot({
|
|
279
|
+
injector,
|
|
280
|
+
rootElement,
|
|
281
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
await sleepAsync(50)
|
|
285
|
+
|
|
286
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
287
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
288
|
+
|
|
289
|
+
input.value = 'test'
|
|
290
|
+
triggerKeyup(input, 'a')
|
|
291
|
+
|
|
292
|
+
await sleepAsync(300)
|
|
293
|
+
|
|
294
|
+
// Press Enter
|
|
295
|
+
triggerKeyup(input, 'Enter')
|
|
296
|
+
await sleepAsync(50)
|
|
297
|
+
|
|
298
|
+
expect(onSelected).toHaveBeenCalledTimes(1)
|
|
299
|
+
expect(onSelected).toHaveBeenCalledWith(expect.objectContaining({ injector: expect.any(Injector) as unknown }))
|
|
300
|
+
})
|
|
301
|
+
})
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
describe('selection', () => {
|
|
305
|
+
const triggerKeyup = (input: HTMLInputElement, key: string) => {
|
|
306
|
+
const event = new KeyboardEvent('keyup', { key, bubbles: true })
|
|
307
|
+
Object.defineProperty(event, 'target', { value: input, writable: false })
|
|
308
|
+
input.dispatchEvent(event)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const getSuggestionItems = (commandPalette: HTMLElement) => {
|
|
312
|
+
const suggestionList = commandPalette.querySelector('shade-command-palette-suggestion-list') as HTMLElement
|
|
313
|
+
return suggestionList?.querySelectorAll('.suggestion-item') || []
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
it('should close palette when clicking a suggestion', async () => {
|
|
317
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
318
|
+
const provider = createMockProvider([createSuggestion('Item 1', 100), createSuggestion('Item 2', 90)])
|
|
319
|
+
|
|
320
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
321
|
+
|
|
322
|
+
initializeShadeRoot({
|
|
323
|
+
injector,
|
|
324
|
+
rootElement,
|
|
325
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
await sleepAsync(50)
|
|
329
|
+
|
|
330
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
331
|
+
|
|
332
|
+
// Open palette by clicking prefix
|
|
333
|
+
const termIcon = commandPalette.querySelector('.term-icon') as HTMLElement
|
|
334
|
+
termIcon.click()
|
|
335
|
+
await sleepAsync(100) // Wait longer for the opened state to propagate
|
|
336
|
+
|
|
337
|
+
expect(commandPalette.classList.contains('opened')).toBe(true)
|
|
338
|
+
|
|
339
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
340
|
+
input.value = 'test'
|
|
341
|
+
triggerKeyup(input, 'a')
|
|
342
|
+
|
|
343
|
+
await sleepAsync(300)
|
|
344
|
+
|
|
345
|
+
// Click on first suggestion
|
|
346
|
+
const suggestionItems = getSuggestionItems(commandPalette)
|
|
347
|
+
expect(suggestionItems.length).toBeGreaterThan(0)
|
|
348
|
+
;(suggestionItems[0] as HTMLElement).click()
|
|
349
|
+
await sleepAsync(100)
|
|
350
|
+
|
|
351
|
+
// Clicking a suggestion should close the palette
|
|
352
|
+
expect(commandPalette.classList.contains('opened')).toBe(false)
|
|
353
|
+
})
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
it('should close palette after selection', async () => {
|
|
357
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
358
|
+
const provider = createMockProvider([createSuggestion('Item 1', 100)])
|
|
359
|
+
|
|
360
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
361
|
+
|
|
362
|
+
initializeShadeRoot({
|
|
363
|
+
injector,
|
|
364
|
+
rootElement,
|
|
365
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
await sleepAsync(50)
|
|
369
|
+
|
|
370
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
371
|
+
|
|
372
|
+
// Open palette
|
|
373
|
+
const termIcon = commandPalette.querySelector('.term-icon') as HTMLElement
|
|
374
|
+
termIcon.click()
|
|
375
|
+
await sleepAsync(50)
|
|
376
|
+
|
|
377
|
+
expect(commandPalette.classList.contains('opened')).toBe(true)
|
|
378
|
+
|
|
379
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
380
|
+
input.value = 'test'
|
|
381
|
+
triggerKeyup(input, 'a')
|
|
382
|
+
|
|
383
|
+
await sleepAsync(300)
|
|
384
|
+
|
|
385
|
+
// Select via Enter
|
|
386
|
+
triggerKeyup(input, 'Enter')
|
|
387
|
+
await sleepAsync(50)
|
|
388
|
+
|
|
389
|
+
expect(commandPalette.classList.contains('opened')).toBe(false)
|
|
390
|
+
})
|
|
391
|
+
})
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
describe('command providers', () => {
|
|
395
|
+
const triggerKeyup = (input: HTMLInputElement, key: string) => {
|
|
396
|
+
const event = new KeyboardEvent('keyup', { key, bubbles: true })
|
|
397
|
+
Object.defineProperty(event, 'target', { value: input, writable: false })
|
|
398
|
+
input.dispatchEvent(event)
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const getSuggestionItems = (commandPalette: HTMLElement) => {
|
|
402
|
+
const suggestionList = commandPalette.querySelector('shade-command-palette-suggestion-list') as HTMLElement
|
|
403
|
+
return suggestionList?.querySelectorAll('.suggestion-item') || []
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
it('should call all command providers when searching', async () => {
|
|
407
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
408
|
+
const provider1 = createMockProvider([createSuggestion('Provider 1 Result', 100)])
|
|
409
|
+
const provider2 = createMockProvider([createSuggestion('Provider 2 Result', 90)])
|
|
410
|
+
|
|
411
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
412
|
+
|
|
413
|
+
initializeShadeRoot({
|
|
414
|
+
injector,
|
|
415
|
+
rootElement,
|
|
416
|
+
jsxElement: <CommandPalette commandProviders={[provider1, provider2]} defaultPrefix=">" />,
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
await sleepAsync(50)
|
|
420
|
+
|
|
421
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
422
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
423
|
+
|
|
424
|
+
input.value = 'search'
|
|
425
|
+
triggerKeyup(input, 'h')
|
|
426
|
+
|
|
427
|
+
await sleepAsync(300)
|
|
428
|
+
|
|
429
|
+
expect(provider1).toHaveBeenCalled()
|
|
430
|
+
expect(provider2).toHaveBeenCalled()
|
|
431
|
+
})
|
|
432
|
+
})
|
|
433
|
+
|
|
434
|
+
it('should aggregate results from multiple providers', async () => {
|
|
435
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
436
|
+
const provider1 = createMockProvider([createSuggestion('Provider 1 Result', 100)])
|
|
437
|
+
const provider2 = createMockProvider([createSuggestion('Provider 2 Result', 90)])
|
|
438
|
+
|
|
439
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
440
|
+
|
|
441
|
+
initializeShadeRoot({
|
|
442
|
+
injector,
|
|
443
|
+
rootElement,
|
|
444
|
+
jsxElement: <CommandPalette commandProviders={[provider1, provider2]} defaultPrefix=">" />,
|
|
445
|
+
})
|
|
446
|
+
|
|
447
|
+
await sleepAsync(50)
|
|
448
|
+
|
|
449
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
450
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
451
|
+
|
|
452
|
+
input.value = 'search'
|
|
453
|
+
triggerKeyup(input, 'h')
|
|
454
|
+
|
|
455
|
+
await sleepAsync(300)
|
|
456
|
+
|
|
457
|
+
const suggestionItems = getSuggestionItems(commandPalette)
|
|
458
|
+
expect(suggestionItems.length).toBe(2)
|
|
459
|
+
expect(document.body.innerHTML).toContain('Provider 1 Result')
|
|
460
|
+
expect(document.body.innerHTML).toContain('Provider 2 Result')
|
|
461
|
+
})
|
|
462
|
+
})
|
|
463
|
+
|
|
464
|
+
it('should sort results by score', async () => {
|
|
465
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
466
|
+
const provider = createMockProvider([
|
|
467
|
+
createSuggestion('Low Score', 50),
|
|
468
|
+
createSuggestion('High Score', 100),
|
|
469
|
+
createSuggestion('Medium Score', 75),
|
|
470
|
+
])
|
|
471
|
+
|
|
472
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
473
|
+
|
|
474
|
+
initializeShadeRoot({
|
|
475
|
+
injector,
|
|
476
|
+
rootElement,
|
|
477
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
await sleepAsync(50)
|
|
481
|
+
|
|
482
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
483
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
484
|
+
|
|
485
|
+
input.value = 'search'
|
|
486
|
+
triggerKeyup(input, 'h')
|
|
487
|
+
|
|
488
|
+
await sleepAsync(300)
|
|
489
|
+
|
|
490
|
+
const suggestionItems = getSuggestionItems(commandPalette)
|
|
491
|
+
expect(suggestionItems.length).toBe(3)
|
|
492
|
+
|
|
493
|
+
// Results should be sorted by score ascending (sortBy sorts ascending)
|
|
494
|
+
expect(suggestionItems[0]?.textContent).toContain('Low Score')
|
|
495
|
+
expect(suggestionItems[1]?.textContent).toContain('Medium Score')
|
|
496
|
+
expect(suggestionItems[2]?.textContent).toContain('High Score')
|
|
497
|
+
})
|
|
498
|
+
})
|
|
499
|
+
})
|
|
500
|
+
|
|
501
|
+
describe('opening and closing', () => {
|
|
502
|
+
it('should open when clicking the prefix icon', async () => {
|
|
503
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
504
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
505
|
+
|
|
506
|
+
initializeShadeRoot({
|
|
507
|
+
injector,
|
|
508
|
+
rootElement,
|
|
509
|
+
jsxElement: <CommandPalette commandProviders={[]} defaultPrefix=">" />,
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
await sleepAsync(50)
|
|
513
|
+
|
|
514
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
515
|
+
expect(commandPalette.classList.contains('opened')).toBe(false)
|
|
516
|
+
|
|
517
|
+
const termIcon = commandPalette.querySelector('.term-icon') as HTMLElement
|
|
518
|
+
termIcon.click()
|
|
519
|
+
await sleepAsync(50)
|
|
520
|
+
|
|
521
|
+
expect(commandPalette.classList.contains('opened')).toBe(true)
|
|
522
|
+
})
|
|
523
|
+
})
|
|
524
|
+
|
|
525
|
+
it('should close when clicking the close button', async () => {
|
|
526
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
527
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
528
|
+
|
|
529
|
+
initializeShadeRoot({
|
|
530
|
+
injector,
|
|
531
|
+
rootElement,
|
|
532
|
+
jsxElement: <CommandPalette commandProviders={[]} defaultPrefix=">" />,
|
|
533
|
+
})
|
|
534
|
+
|
|
535
|
+
await sleepAsync(50)
|
|
536
|
+
|
|
537
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
538
|
+
|
|
539
|
+
// Open first
|
|
540
|
+
const termIcon = commandPalette.querySelector('.term-icon') as HTMLElement
|
|
541
|
+
termIcon.click()
|
|
542
|
+
await sleepAsync(50)
|
|
543
|
+
expect(commandPalette.classList.contains('opened')).toBe(true)
|
|
544
|
+
|
|
545
|
+
// Close
|
|
546
|
+
const closeButton = commandPalette.querySelector('.close-suggestions') as HTMLElement
|
|
547
|
+
closeButton.click()
|
|
548
|
+
await sleepAsync(50)
|
|
549
|
+
|
|
550
|
+
expect(commandPalette.classList.contains('opened')).toBe(false)
|
|
551
|
+
})
|
|
552
|
+
})
|
|
553
|
+
|
|
554
|
+
it('should add loading class when fetching suggestions', async () => {
|
|
555
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
556
|
+
const provider = vi.fn(
|
|
557
|
+
() =>
|
|
558
|
+
new Promise<CommandPaletteSuggestionResult[]>((resolve) => {
|
|
559
|
+
setTimeout(() => resolve([createSuggestion('Result', 100)]), 100)
|
|
560
|
+
}),
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
564
|
+
|
|
565
|
+
initializeShadeRoot({
|
|
566
|
+
injector,
|
|
567
|
+
rootElement,
|
|
568
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" />,
|
|
569
|
+
})
|
|
570
|
+
|
|
571
|
+
await sleepAsync(50)
|
|
572
|
+
|
|
573
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
574
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
575
|
+
|
|
576
|
+
input.value = 'test'
|
|
577
|
+
const event = new KeyboardEvent('keyup', { key: 't', bubbles: true })
|
|
578
|
+
Object.defineProperty(event, 'target', { value: input, writable: false })
|
|
579
|
+
input.dispatchEvent(event)
|
|
580
|
+
|
|
581
|
+
await sleepAsync(260) // After debounce but before provider resolves
|
|
582
|
+
|
|
583
|
+
expect(commandPalette.classList.contains('loading')).toBe(true)
|
|
584
|
+
|
|
585
|
+
await sleepAsync(200) // Wait for provider to resolve
|
|
586
|
+
|
|
587
|
+
expect(commandPalette.classList.contains('loading')).toBe(false)
|
|
588
|
+
})
|
|
589
|
+
})
|
|
590
|
+
})
|
|
591
|
+
|
|
592
|
+
describe('click away', () => {
|
|
593
|
+
it('should close when clicking outside the component', async () => {
|
|
594
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
595
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
596
|
+
|
|
597
|
+
initializeShadeRoot({
|
|
598
|
+
injector,
|
|
599
|
+
rootElement,
|
|
600
|
+
jsxElement: (
|
|
601
|
+
<div>
|
|
602
|
+
<div id="outside">Outside element</div>
|
|
603
|
+
<CommandPalette commandProviders={[]} defaultPrefix=">" />
|
|
604
|
+
</div>
|
|
605
|
+
),
|
|
606
|
+
})
|
|
607
|
+
|
|
608
|
+
await sleepAsync(50)
|
|
609
|
+
|
|
610
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
611
|
+
|
|
612
|
+
// Open first
|
|
613
|
+
const termIcon = commandPalette.querySelector('.term-icon') as HTMLElement
|
|
614
|
+
termIcon.click()
|
|
615
|
+
await sleepAsync(50)
|
|
616
|
+
expect(commandPalette.classList.contains('opened')).toBe(true)
|
|
617
|
+
|
|
618
|
+
// Click outside
|
|
619
|
+
const outsideElement = document.getElementById('outside') as HTMLElement
|
|
620
|
+
outsideElement.dispatchEvent(new MouseEvent('click', { bubbles: true }))
|
|
621
|
+
await sleepAsync(50)
|
|
622
|
+
|
|
623
|
+
expect(commandPalette.classList.contains('opened')).toBe(false)
|
|
624
|
+
})
|
|
625
|
+
})
|
|
626
|
+
})
|
|
627
|
+
|
|
628
|
+
describe('styling', () => {
|
|
629
|
+
it('should apply custom style to input container', async () => {
|
|
630
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
631
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
632
|
+
|
|
633
|
+
initializeShadeRoot({
|
|
634
|
+
injector,
|
|
635
|
+
rootElement,
|
|
636
|
+
jsxElement: <CommandPalette commandProviders={[]} defaultPrefix=">" style={{ maxWidth: '500px' }} />,
|
|
637
|
+
})
|
|
638
|
+
|
|
639
|
+
await sleepAsync(50)
|
|
640
|
+
|
|
641
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
642
|
+
const inputContainer = commandPalette.querySelector('.input-container') as HTMLElement
|
|
643
|
+
|
|
644
|
+
expect(inputContainer.style.maxWidth).toBe('500px')
|
|
645
|
+
})
|
|
646
|
+
})
|
|
647
|
+
|
|
648
|
+
it('should pass fullScreenSuggestions to suggestion list', async () => {
|
|
649
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
650
|
+
const provider = createMockProvider([createSuggestion('Item', 100)])
|
|
651
|
+
|
|
652
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
653
|
+
|
|
654
|
+
initializeShadeRoot({
|
|
655
|
+
injector,
|
|
656
|
+
rootElement,
|
|
657
|
+
jsxElement: <CommandPalette commandProviders={[provider]} defaultPrefix=">" fullScreenSuggestions />,
|
|
658
|
+
})
|
|
659
|
+
|
|
660
|
+
await sleepAsync(50)
|
|
661
|
+
|
|
662
|
+
const commandPalette = document.querySelector('shade-command-palette') as HTMLElement
|
|
663
|
+
|
|
664
|
+
// Open and search
|
|
665
|
+
const termIcon = commandPalette.querySelector('.term-icon') as HTMLElement
|
|
666
|
+
termIcon.click()
|
|
667
|
+
await sleepAsync(50)
|
|
668
|
+
|
|
669
|
+
const input = commandPalette.querySelector('input') as HTMLInputElement
|
|
670
|
+
input.value = 'test'
|
|
671
|
+
const event = new KeyboardEvent('keyup', { key: 't', bubbles: true })
|
|
672
|
+
Object.defineProperty(event, 'target', { value: input, writable: false })
|
|
673
|
+
input.dispatchEvent(event)
|
|
674
|
+
|
|
675
|
+
await sleepAsync(300)
|
|
676
|
+
|
|
677
|
+
const suggestionList = commandPalette.querySelector('shade-command-palette-suggestion-list') as HTMLElement
|
|
678
|
+
const suggestionContainer = suggestionList.querySelector('.suggestion-items-container') as HTMLElement
|
|
679
|
+
// fullScreenSuggestions sets left: '0' and specific width
|
|
680
|
+
expect(suggestionContainer.style.left).toBe('0px')
|
|
681
|
+
})
|
|
682
|
+
})
|
|
683
|
+
})
|
|
684
|
+
})
|