Skip to content

Commit 4b858cb

Browse files
gerjanvangeesttlouisse
authored andcommitted
feat(overlays): create BottomsheetController
1 parent 1cc92fb commit 4b858cb

File tree

9 files changed

+168
-24
lines changed

9 files changed

+168
-24
lines changed

packages/overlays/docs/GlobalOverlayController.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,17 @@ const myCtrl = overlays.add(
2626
);
2727
```
2828

29+
### BottomsheetController
30+
31+
A specific extension of GlobalOverlayController configured to create accessible dialogs at the bottom of the screen.
32+
33+
```js
34+
import { BottomsheetController } from '@lion/overlays';
35+
```
36+
2937
### ModalDialogController
3038

31-
A specific extension of GlobalOverlayController configured to create accessible modal dialogs.
39+
A specific extension of GlobalOverlayController configured to create accessible modal dialogs placed in the center of the screen.
3240

3341
```js
3442
import { ModalDialogController } from '@lion/overlays';

packages/overlays/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export { DynamicOverlayController } from './src/DynamicOverlayController.js';
22
export { GlobalOverlayController } from './src/GlobalOverlayController.js';
33
export { globalOverlaysStyle } from './src/globalOverlaysStyle.js';
44
export { LocalOverlayController } from './src/LocalOverlayController.js';
5+
export { BottomsheetController } from './src/BottomsheetController.js';
56
export { ModalDialogController } from './src/ModalDialogController.js';
67
export { overlays } from './src/overlays.js';
78
export { OverlaysManager } from './src/OverlaysManager.js';
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { GlobalOverlayController } from './GlobalOverlayController.js';
2+
3+
export class BottomsheetController extends GlobalOverlayController {
4+
constructor(params) {
5+
super({
6+
hasBackdrop: true,
7+
preventsScroll: true,
8+
trapsKeyboardFocus: true,
9+
hidesOnEsc: true,
10+
viewportConfig: {
11+
placement: 'bottom',
12+
},
13+
...params,
14+
});
15+
}
16+
}

packages/overlays/src/globalOverlaysStyle.js

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,67 @@ export const globalOverlaysStyle = css`
44
.global-overlays {
55
position: fixed;
66
z-index: 200;
7-
left: 0;
8-
top: 0;
9-
width: 100vw;
10-
height: 100vh;
11-
pointer-events: none;
127
}
138
149
.global-overlays__overlay,
1510
.global-overlays__overlay--blocking {
1611
pointer-events: auto;
1712
}
1813
14+
.global-overlays__overlay-container {
15+
display: flex;
16+
position: fixed;
17+
top: 0;
18+
left: 0;
19+
width: 100%;
20+
height: 100%;
21+
pointer-events: none;
22+
}
23+
24+
.global-overlays__overlay-container--top-left {
25+
justify-content: flex-start;
26+
align-items: flex-start;
27+
}
28+
29+
.global-overlays__overlay-container--top {
30+
justify-content: center;
31+
align-items: flex-start;
32+
}
33+
34+
.global-overlays__overlay-container--top-right {
35+
justify-content: flex-end;
36+
align-items: flex-start;
37+
}
38+
39+
.global-overlays__overlay-container--right {
40+
justify-content: flex-end;
41+
align-items: center;
42+
}
43+
44+
.global-overlays__overlay-container--bottom-left {
45+
justify-content: flex-start;
46+
align-items: flex-end;
47+
}
48+
49+
.global-overlays__overlay-container--bottom {
50+
justify-content: center;
51+
align-items: flex-end;
52+
}
53+
54+
.global-overlays__overlay-container--bottom-right {
55+
justify-content: flex-end;
56+
align-items: flex-end;
57+
}
58+
.global-overlays__overlay-container--left {
59+
justify-content: flex-start;
60+
align-items: center;
61+
}
62+
63+
.global-overlays__overlay-container--center {
64+
justify-content: center;
65+
align-items: center;
66+
}
67+
1968
.global-overlays.global-overlays--blocking-opened .global-overlays__overlay {
2069
display: none;
2170
}
@@ -30,9 +79,10 @@ export const globalOverlaysStyle = css`
3079
content: '';
3180
position: fixed;
3281
top: 0;
33-
right: 0;
34-
bottom: 0;
3582
left: 0;
83+
width: 100%;
84+
height: 100%;
85+
z-index: -1;
3686
background-color: #333333;
3787
opacity: 0.3;
3888
}
@@ -46,19 +96,6 @@ export const globalOverlaysStyle = css`
4696
opacity: 0;
4797
}
4898
49-
.global-overlays.global-overlays--backdrop-fade-out {
50-
content: '';
51-
position: fixed;
52-
top: 0;
53-
right: 0;
54-
bottom: 0;
55-
left: 0;
56-
background-color: #333333;
57-
opacity: 0;
58-
pointer-events: none;
59-
animation: global-overlays-backdrop-fade-out 300ms;
60-
}
61-
6299
@keyframes global-overlays-backdrop-fade-in {
63100
from {
64101
opacity: 0;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { storiesOf, html } from '@open-wc/demoing-storybook';
2+
3+
import { css } from '@lion/core';
4+
import { overlays, BottomsheetController } from '../index.js';
5+
6+
const bottomsheetDemoStyle = css`
7+
.demo-overlay {
8+
width: 100%;
9+
background-color: white;
10+
border: 1px solid lightgrey;
11+
text-align: center;
12+
height: 800px;
13+
}
14+
`;
15+
16+
storiesOf('Global Overlay System|Bottomsheet', module).add('Default', () => {
17+
const bottomsheetCtrl = overlays.add(
18+
new BottomsheetController({
19+
contentTemplate: () => html`
20+
<div class="demo-overlay">
21+
<p>Bottomsheet</p>
22+
<button @click="${() => bottomsheetCtrl.hide()}">Close</button>
23+
</div>
24+
`,
25+
}),
26+
);
27+
28+
return html`
29+
<style>
30+
${bottomsheetDemoStyle}
31+
</style>
32+
<a href="#">Anchor 1</a>
33+
<button
34+
@click="${event => bottomsheetCtrl.show(event.target)}"
35+
aria-haspopup="dialog"
36+
aria-expanded="false"
37+
>
38+
Open dialog
39+
</button>
40+
<a href="#">Anchor 2</a>
41+
${Array(50).fill(
42+
html`
43+
<p>Lorem ipsum</p>
44+
`,
45+
)}
46+
`;
47+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import './global-overlay.stories.js';
22
import './modal-dialog.stories.js';
3+
import './bottomsheet.stories.js';
34
import './local-overlay.stories.js';
45
import './local-overlay-placement.stories.js';
56
import './dynamic-overlay.stories.js';
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { expect, html } from '@open-wc/testing';
2+
3+
import { GlobalOverlayController } from '../src/GlobalOverlayController.js';
4+
import { BottomsheetController } from '../src/BottomsheetController.js';
5+
6+
describe('BottomsheetController', () => {
7+
let defaultOptions;
8+
9+
before(() => {
10+
defaultOptions = {
11+
contentTemplate: () => html`
12+
<p>my content</p>
13+
`,
14+
};
15+
});
16+
17+
it('extends GlobalOverlayController', () => {
18+
expect(new BottomsheetController(defaultOptions)).to.be.instanceof(GlobalOverlayController);
19+
});
20+
21+
it('has correct defaults', () => {
22+
const controller = new BottomsheetController(defaultOptions);
23+
expect(controller.hasBackdrop).to.equal(true);
24+
expect(controller.isBlocking).to.equal(false);
25+
expect(controller.preventsScroll).to.equal(true);
26+
expect(controller.trapsKeyboardFocus).to.equal(true);
27+
expect(controller.hidesOnEsc).to.equal(true);
28+
expect(controller.overlayContainerPlacementClass).to.equal(
29+
'global-overlays__overlay-container--bottom',
30+
);
31+
});
32+
});

packages/overlays/test/GlobalOverlayController.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ describe('GlobalOverlayController', () => {
349349
});
350350

351351
controller.show();
352-
expect(controller.overlayContainerClass).to.equal(
352+
expect(controller.overlayContainerPlacementClass).to.equal(
353353
'global-overlays__overlay-container--center',
354354
);
355355
});
@@ -377,7 +377,7 @@ describe('GlobalOverlayController', () => {
377377
`,
378378
});
379379
controller.show();
380-
expect(controller.overlayContainerClass).to.equal(
380+
expect(controller.overlayContainerPlacementClass).to.equal(
381381
`global-overlays__overlay-container--${viewportPlacement}`,
382382
);
383383
});

packages/overlays/test/ModalDialogController.test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ describe('ModalDialogController', () => {
2525
expect(ctrl.preventsScroll).to.be.true;
2626
expect(ctrl.trapsKeyboardFocus).to.be.true;
2727
expect(ctrl.hidesOnEsc).to.be.true;
28-
expect(ctrl.overlayContainerClass).to.equal('global-overlays__overlay-container--center');
28+
expect(ctrl.overlayContainerPlacementClass).to.equal(
29+
'global-overlays__overlay-container--center',
30+
);
2931
});
3032
});

0 commit comments

Comments
 (0)