@internetarchive/modal-manager 2.0.2 → 2.0.3
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/dist/src/assets/arrow-left-icon.d.ts +2 -0
- package/dist/src/assets/arrow-left-icon.js +15 -0
- package/dist/src/assets/arrow-left-icon.js.map +1 -0
- package/dist/src/modal-config.d.ts +12 -0
- package/dist/src/modal-config.js +5 -3
- package/dist/src/modal-config.js.map +1 -1
- package/dist/src/modal-manager-interface.d.ts +2 -0
- package/dist/src/modal-manager-interface.js.map +1 -1
- package/dist/src/modal-manager.d.ts +15 -0
- package/dist/src/modal-manager.js +16 -0
- package/dist/src/modal-manager.js.map +1 -1
- package/dist/src/modal-template.d.ts +8 -0
- package/dist/src/modal-template.js +53 -0
- package/dist/src/modal-template.js.map +1 -1
- package/dist/test/modal-config.test.js +8 -0
- package/dist/test/modal-config.test.js.map +1 -1
- package/dist/test/modal-manager.test.js +41 -19
- package/dist/test/modal-manager.test.js.map +1 -1
- package/dist/test/modal-template.test.js +84 -12
- package/dist/test/modal-template.test.js.map +1 -1
- package/index.html +18 -0
- package/package.json +1 -1
- package/src/assets/arrow-left-icon.ts +15 -0
- package/src/modal-config.ts +16 -0
- package/src/modal-manager-interface.ts +2 -0
- package/src/modal-manager.ts +25 -0
- package/src/modal-template.ts +56 -0
- package/test/modal-config.test.ts +8 -0
- package/test/modal-manager.test.ts +28 -0
- package/test/modal-template.test.ts +82 -0
package/src/modal-template.ts
CHANGED
|
@@ -6,6 +6,7 @@ import '@internetarchive/icon-close';
|
|
|
6
6
|
|
|
7
7
|
import { ModalConfig } from './modal-config';
|
|
8
8
|
import IALogoIcon from './assets/ia-logo-icon';
|
|
9
|
+
import arrowLeftIcon from './assets/arrow-left-icon';
|
|
9
10
|
|
|
10
11
|
@customElement('modal-template')
|
|
11
12
|
export class ModalTemplate extends LitElement {
|
|
@@ -23,6 +24,9 @@ export class ModalTemplate extends LitElement {
|
|
|
23
24
|
<div class="modal-wrapper">
|
|
24
25
|
<div class="modal-container">
|
|
25
26
|
<header style="background-color: ${this.config.headerColor}">
|
|
27
|
+
${this.config.showLeftNavButton
|
|
28
|
+
? this.leftNavButtonTemplate
|
|
29
|
+
: nothing}
|
|
26
30
|
${this.config.showCloseButton ? this.closeButtonTemplate : ''}
|
|
27
31
|
${this.config.showHeaderLogo
|
|
28
32
|
? html`<div class="logo-icon">${IALogoIcon}</div>`
|
|
@@ -84,6 +88,25 @@ export class ModalTemplate extends LitElement {
|
|
|
84
88
|
this.dispatchEvent(event);
|
|
85
89
|
}
|
|
86
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Dispatch the `leftNavButtonPressed` event to the consumer
|
|
93
|
+
*
|
|
94
|
+
* @private
|
|
95
|
+
* @memberof ModalTemplate
|
|
96
|
+
*/
|
|
97
|
+
private handleLeftNavButtonPressed(e: Event): void {
|
|
98
|
+
e.preventDefault();
|
|
99
|
+
if (
|
|
100
|
+
e.type === 'keydown' &&
|
|
101
|
+
(e as KeyboardEvent).key !== ' ' &&
|
|
102
|
+
(e as KeyboardEvent).key !== 'Enter'
|
|
103
|
+
) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const event = new Event('leftNavButtonPressed');
|
|
107
|
+
this.dispatchEvent(event);
|
|
108
|
+
}
|
|
109
|
+
|
|
87
110
|
/**
|
|
88
111
|
* The close button template
|
|
89
112
|
*
|
|
@@ -105,6 +128,17 @@ export class ModalTemplate extends LitElement {
|
|
|
105
128
|
`;
|
|
106
129
|
}
|
|
107
130
|
|
|
131
|
+
private get leftNavButtonTemplate(): TemplateResult {
|
|
132
|
+
return html`<button
|
|
133
|
+
type="button"
|
|
134
|
+
class="back-button"
|
|
135
|
+
@click=${this.handleLeftNavButtonPressed}
|
|
136
|
+
@keydown=${this.handleLeftNavButtonPressed}
|
|
137
|
+
>
|
|
138
|
+
${arrowLeftIcon} ${this.config.leftNavButtonText ?? ''}
|
|
139
|
+
</button> `;
|
|
140
|
+
}
|
|
141
|
+
|
|
108
142
|
/** @inheritdoc */
|
|
109
143
|
static get styles(): CSSResult {
|
|
110
144
|
const modalLogoSize = css`var(--modalLogoSize, 6.5rem)`;
|
|
@@ -261,6 +295,28 @@ export class ModalTemplate extends LitElement {
|
|
|
261
295
|
0 4px 4px 0 rgba(0, 0, 0, 0.08);
|
|
262
296
|
}
|
|
263
297
|
|
|
298
|
+
.back-button {
|
|
299
|
+
position: absolute;
|
|
300
|
+
left: 1.2rem;
|
|
301
|
+
top: 1.2rem;
|
|
302
|
+
height: 2rem;
|
|
303
|
+
background-color: transparent;
|
|
304
|
+
outline: none;
|
|
305
|
+
border: none;
|
|
306
|
+
padding: 0;
|
|
307
|
+
cursor: pointer;
|
|
308
|
+
color: white;
|
|
309
|
+
font-family: inherit;
|
|
310
|
+
display: flex;
|
|
311
|
+
flex-direction: row;
|
|
312
|
+
align-items: center;
|
|
313
|
+
gap: 0.5rem;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.back-button svg {
|
|
317
|
+
height: 1.5rem;
|
|
318
|
+
}
|
|
319
|
+
|
|
264
320
|
.sr-only {
|
|
265
321
|
position: absolute;
|
|
266
322
|
width: 1px;
|
|
@@ -24,6 +24,8 @@ describe('Modal Config', () => {
|
|
|
24
24
|
const showProcessingIndicator = true;
|
|
25
25
|
const processingImageMode = 'processing';
|
|
26
26
|
const showCloseButton = false;
|
|
27
|
+
const showLeftNavButton = false;
|
|
28
|
+
const leftNavButtonText = 'Previous';
|
|
27
29
|
const showHeaderLogo = false;
|
|
28
30
|
const closeOnBackdropClick = false;
|
|
29
31
|
|
|
@@ -36,6 +38,8 @@ describe('Modal Config', () => {
|
|
|
36
38
|
showProcessingIndicator: showProcessingIndicator,
|
|
37
39
|
processingImageMode: processingImageMode,
|
|
38
40
|
showCloseButton: showCloseButton,
|
|
41
|
+
showLeftNavButton: showLeftNavButton,
|
|
42
|
+
leftNavButtonText: leftNavButtonText,
|
|
39
43
|
showHeaderLogo: showHeaderLogo,
|
|
40
44
|
closeOnBackdropClick: closeOnBackdropClick,
|
|
41
45
|
});
|
|
@@ -49,6 +53,8 @@ describe('Modal Config', () => {
|
|
|
49
53
|
expect(config.showProcessingIndicator).to.equal(showProcessingIndicator);
|
|
50
54
|
expect(config.processingImageMode).to.equal(processingImageMode);
|
|
51
55
|
expect(config.showCloseButton).to.equal(showCloseButton);
|
|
56
|
+
expect(config.showLeftNavButton).to.equal(showLeftNavButton);
|
|
57
|
+
expect(config.leftNavButtonText).to.equal(leftNavButtonText);
|
|
52
58
|
expect(config.showHeaderLogo).to.equal(showHeaderLogo);
|
|
53
59
|
expect(config.closeOnBackdropClick).to.equal(closeOnBackdropClick);
|
|
54
60
|
});
|
|
@@ -63,6 +69,8 @@ describe('Modal Config', () => {
|
|
|
63
69
|
expect(config.showProcessingIndicator).to.equal(false);
|
|
64
70
|
expect(config.processingImageMode).to.equal('complete');
|
|
65
71
|
expect(config.showCloseButton).to.equal(true);
|
|
72
|
+
expect(config.showLeftNavButton).to.equal(false);
|
|
73
|
+
expect(config.leftNavButtonText).to.equal('');
|
|
66
74
|
expect(config.showHeaderLogo).to.equal(true);
|
|
67
75
|
expect(config.closeOnBackdropClick).to.equal(true);
|
|
68
76
|
});
|
|
@@ -151,6 +151,34 @@ describe('Modal Manager', () => {
|
|
|
151
151
|
expect(callbackCalled).to.equal(false);
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
+
it('calls the userPressedLeftNavButtonCallback when the user clicks the left nav button', async () => {
|
|
155
|
+
const el = (await fixture(html`
|
|
156
|
+
<modal-manager></modal-manager>
|
|
157
|
+
`)) as ModalManager;
|
|
158
|
+
|
|
159
|
+
const config = new ModalConfig();
|
|
160
|
+
config.showLeftNavButton = true;
|
|
161
|
+
|
|
162
|
+
let callbackCalled = false;
|
|
163
|
+
const callback = (): void => {
|
|
164
|
+
callbackCalled = true;
|
|
165
|
+
};
|
|
166
|
+
el.showModal({
|
|
167
|
+
config,
|
|
168
|
+
userPressedLeftNavButtonCallback: callback,
|
|
169
|
+
});
|
|
170
|
+
await elementUpdated(el);
|
|
171
|
+
|
|
172
|
+
const modalTemplate = el.shadowRoot?.querySelector('modal-template');
|
|
173
|
+
expect(modalTemplate).to.exist;
|
|
174
|
+
|
|
175
|
+
modalTemplate?.dispatchEvent(new Event('leftNavButtonPressed'));
|
|
176
|
+
|
|
177
|
+
await elementUpdated(el);
|
|
178
|
+
|
|
179
|
+
expect(callbackCalled).to.equal(true);
|
|
180
|
+
});
|
|
181
|
+
|
|
154
182
|
it('mode is set to closed when close button is pressed', async () => {
|
|
155
183
|
const el = (await fixture(html`
|
|
156
184
|
<modal-manager></modal-manager>
|
|
@@ -57,6 +57,40 @@ describe('Modal Template', () => {
|
|
|
57
57
|
expect(response).to.exist;
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
+
it('emits leftNavButtonPressed event when left nav button is pressed', async () => {
|
|
61
|
+
const config = new ModalConfig();
|
|
62
|
+
config.showLeftNavButton = true;
|
|
63
|
+
const el = await fixture(html`
|
|
64
|
+
<modal-template .config=${config}></modal-template>
|
|
65
|
+
`);
|
|
66
|
+
|
|
67
|
+
const leftNavButton = el.shadowRoot?.querySelector('.back-button');
|
|
68
|
+
const clickEvent = new MouseEvent('click');
|
|
69
|
+
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
leftNavButton?.dispatchEvent(clickEvent);
|
|
72
|
+
});
|
|
73
|
+
const response = await oneEvent(el, 'leftNavButtonPressed', false);
|
|
74
|
+
expect(response).to.exist;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('emits leftNavButtonPressed event when left nav button gets spacebar pressed', async () => {
|
|
78
|
+
const config = new ModalConfig();
|
|
79
|
+
config.showLeftNavButton = true;
|
|
80
|
+
const el = await fixture(html`
|
|
81
|
+
<modal-template .config=${config}></modal-template>
|
|
82
|
+
`);
|
|
83
|
+
|
|
84
|
+
const leftNavButton = el.shadowRoot?.querySelector('.back-button');
|
|
85
|
+
const clickEvent = new KeyboardEvent('keydown', { key: ' ' });
|
|
86
|
+
|
|
87
|
+
setTimeout(() => {
|
|
88
|
+
leftNavButton?.dispatchEvent(clickEvent);
|
|
89
|
+
});
|
|
90
|
+
const response = await oneEvent(el, 'leftNavButtonPressed', false);
|
|
91
|
+
expect(response).to.exist;
|
|
92
|
+
});
|
|
93
|
+
|
|
60
94
|
it('shows the processing indicator if configured to', async () => {
|
|
61
95
|
const config = new ModalConfig();
|
|
62
96
|
config.showProcessingIndicator = true;
|
|
@@ -70,6 +104,54 @@ describe('Modal Template', () => {
|
|
|
70
104
|
expect('hidden' in classList).to.equal(false);
|
|
71
105
|
});
|
|
72
106
|
|
|
107
|
+
it('shows the left nav button if configured to', async () => {
|
|
108
|
+
const config = new ModalConfig();
|
|
109
|
+
config.showLeftNavButton = true;
|
|
110
|
+
const el = await fixture(html`
|
|
111
|
+
<modal-template .config=${config}></modal-template>
|
|
112
|
+
`);
|
|
113
|
+
|
|
114
|
+
const leftNavButton = el.shadowRoot?.querySelector('.back-button');
|
|
115
|
+
expect(leftNavButton).to.exist;
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('hides the left nav button if configured to', async () => {
|
|
119
|
+
const config = new ModalConfig();
|
|
120
|
+
config.showCloseButton = false;
|
|
121
|
+
const el = await fixture(html`
|
|
122
|
+
<modal-template .config=${config}></modal-template>
|
|
123
|
+
`);
|
|
124
|
+
|
|
125
|
+
const closeButton = el.shadowRoot?.querySelector('.close-button');
|
|
126
|
+
expect(closeButton).to.not.exist;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('uses custom text for the left nav button if configured to', async () => {
|
|
130
|
+
const config = new ModalConfig();
|
|
131
|
+
config.showLeftNavButton = true;
|
|
132
|
+
config.leftNavButtonText = 'Previous';
|
|
133
|
+
const el = await fixture(html`
|
|
134
|
+
<modal-template .config=${config}></modal-template>
|
|
135
|
+
`);
|
|
136
|
+
|
|
137
|
+
const leftNavButton = el.shadowRoot?.querySelector('.back-button');
|
|
138
|
+
|
|
139
|
+
expect(leftNavButton).to.exist;
|
|
140
|
+
expect(leftNavButton?.innerHTML).to.contain('Previous');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('does not use any text for the left nav button if not configured to', async () => {
|
|
144
|
+
const config = new ModalConfig();
|
|
145
|
+
config.showLeftNavButton = true;
|
|
146
|
+
|
|
147
|
+
const el = await fixture(html`
|
|
148
|
+
<modal-template .config=${config}></modal-template>
|
|
149
|
+
`);
|
|
150
|
+
|
|
151
|
+
const leftNavButton = el.shadowRoot?.querySelector('.back-button');
|
|
152
|
+
expect(leftNavButton?.innerHTML).not.to.contain('Previous');
|
|
153
|
+
});
|
|
154
|
+
|
|
73
155
|
it('shows the close button if configured to', async () => {
|
|
74
156
|
const config = new ModalConfig();
|
|
75
157
|
config.showCloseButton = true;
|