feat(overlays): create BottomsheetController
This commit is contained in:
parent
1cc92fbd6e
commit
4b858cbea7
9 changed files with 168 additions and 24 deletions
|
|
@ -26,9 +26,17 @@ const myCtrl = overlays.add(
|
|||
);
|
||||
```
|
||||
|
||||
### BottomsheetController
|
||||
|
||||
A specific extension of GlobalOverlayController configured to create accessible dialogs at the bottom of the screen.
|
||||
|
||||
```js
|
||||
import { BottomsheetController } from '@lion/overlays';
|
||||
```
|
||||
|
||||
### ModalDialogController
|
||||
|
||||
A specific extension of GlobalOverlayController configured to create accessible modal dialogs.
|
||||
A specific extension of GlobalOverlayController configured to create accessible modal dialogs placed in the center of the screen.
|
||||
|
||||
```js
|
||||
import { ModalDialogController } from '@lion/overlays';
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ export { DynamicOverlayController } from './src/DynamicOverlayController.js';
|
|||
export { GlobalOverlayController } from './src/GlobalOverlayController.js';
|
||||
export { globalOverlaysStyle } from './src/globalOverlaysStyle.js';
|
||||
export { LocalOverlayController } from './src/LocalOverlayController.js';
|
||||
export { BottomsheetController } from './src/BottomsheetController.js';
|
||||
export { ModalDialogController } from './src/ModalDialogController.js';
|
||||
export { overlays } from './src/overlays.js';
|
||||
export { OverlaysManager } from './src/OverlaysManager.js';
|
||||
|
|
|
|||
16
packages/overlays/src/BottomsheetController.js
Normal file
16
packages/overlays/src/BottomsheetController.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { GlobalOverlayController } from './GlobalOverlayController.js';
|
||||
|
||||
export class BottomsheetController extends GlobalOverlayController {
|
||||
constructor(params) {
|
||||
super({
|
||||
hasBackdrop: true,
|
||||
preventsScroll: true,
|
||||
trapsKeyboardFocus: true,
|
||||
hidesOnEsc: true,
|
||||
viewportConfig: {
|
||||
placement: 'bottom',
|
||||
},
|
||||
...params,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -4,11 +4,6 @@ export const globalOverlaysStyle = css`
|
|||
.global-overlays {
|
||||
position: fixed;
|
||||
z-index: 200;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.global-overlays__overlay,
|
||||
|
|
@ -16,6 +11,60 @@ export const globalOverlaysStyle = css`
|
|||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container--top-left {
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container--top {
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container--top-right {
|
||||
justify-content: flex-end;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container--right {
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container--bottom-left {
|
||||
justify-content: flex-start;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container--bottom {
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container--bottom-right {
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
}
|
||||
.global-overlays__overlay-container--left {
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.global-overlays__overlay-container--center {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.global-overlays.global-overlays--blocking-opened .global-overlays__overlay {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -30,9 +79,10 @@ export const globalOverlaysStyle = css`
|
|||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
background-color: #333333;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
|
@ -46,19 +96,6 @@ export const globalOverlaysStyle = css`
|
|||
opacity: 0;
|
||||
}
|
||||
|
||||
.global-overlays.global-overlays--backdrop-fade-out {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #333333;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
animation: global-overlays-backdrop-fade-out 300ms;
|
||||
}
|
||||
|
||||
@keyframes global-overlays-backdrop-fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
|
|
|
|||
47
packages/overlays/stories/bottomsheet.stories.js
Normal file
47
packages/overlays/stories/bottomsheet.stories.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { storiesOf, html } from '@open-wc/demoing-storybook';
|
||||
|
||||
import { css } from '@lion/core';
|
||||
import { overlays, BottomsheetController } from '../index.js';
|
||||
|
||||
const bottomsheetDemoStyle = css`
|
||||
.demo-overlay {
|
||||
width: 100%;
|
||||
background-color: white;
|
||||
border: 1px solid lightgrey;
|
||||
text-align: center;
|
||||
height: 800px;
|
||||
}
|
||||
`;
|
||||
|
||||
storiesOf('Global Overlay System|Bottomsheet', module).add('Default', () => {
|
||||
const bottomsheetCtrl = overlays.add(
|
||||
new BottomsheetController({
|
||||
contentTemplate: () => html`
|
||||
<div class="demo-overlay">
|
||||
<p>Bottomsheet</p>
|
||||
<button @click="${() => bottomsheetCtrl.hide()}">Close</button>
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
);
|
||||
|
||||
return html`
|
||||
<style>
|
||||
${bottomsheetDemoStyle}
|
||||
</style>
|
||||
<a href="#">Anchor 1</a>
|
||||
<button
|
||||
@click="${event => bottomsheetCtrl.show(event.target)}"
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Open dialog
|
||||
</button>
|
||||
<a href="#">Anchor 2</a>
|
||||
${Array(50).fill(
|
||||
html`
|
||||
<p>Lorem ipsum</p>
|
||||
`,
|
||||
)}
|
||||
`;
|
||||
});
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import './global-overlay.stories.js';
|
||||
import './modal-dialog.stories.js';
|
||||
import './bottomsheet.stories.js';
|
||||
import './local-overlay.stories.js';
|
||||
import './local-overlay-placement.stories.js';
|
||||
import './dynamic-overlay.stories.js';
|
||||
|
|
|
|||
32
packages/overlays/test/BottomsheetController.test.js
Normal file
32
packages/overlays/test/BottomsheetController.test.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { expect, html } from '@open-wc/testing';
|
||||
|
||||
import { GlobalOverlayController } from '../src/GlobalOverlayController.js';
|
||||
import { BottomsheetController } from '../src/BottomsheetController.js';
|
||||
|
||||
describe('BottomsheetController', () => {
|
||||
let defaultOptions;
|
||||
|
||||
before(() => {
|
||||
defaultOptions = {
|
||||
contentTemplate: () => html`
|
||||
<p>my content</p>
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
it('extends GlobalOverlayController', () => {
|
||||
expect(new BottomsheetController(defaultOptions)).to.be.instanceof(GlobalOverlayController);
|
||||
});
|
||||
|
||||
it('has correct defaults', () => {
|
||||
const controller = new BottomsheetController(defaultOptions);
|
||||
expect(controller.hasBackdrop).to.equal(true);
|
||||
expect(controller.isBlocking).to.equal(false);
|
||||
expect(controller.preventsScroll).to.equal(true);
|
||||
expect(controller.trapsKeyboardFocus).to.equal(true);
|
||||
expect(controller.hidesOnEsc).to.equal(true);
|
||||
expect(controller.overlayContainerPlacementClass).to.equal(
|
||||
'global-overlays__overlay-container--bottom',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -349,7 +349,7 @@ describe('GlobalOverlayController', () => {
|
|||
});
|
||||
|
||||
controller.show();
|
||||
expect(controller.overlayContainerClass).to.equal(
|
||||
expect(controller.overlayContainerPlacementClass).to.equal(
|
||||
'global-overlays__overlay-container--center',
|
||||
);
|
||||
});
|
||||
|
|
@ -377,7 +377,7 @@ describe('GlobalOverlayController', () => {
|
|||
`,
|
||||
});
|
||||
controller.show();
|
||||
expect(controller.overlayContainerClass).to.equal(
|
||||
expect(controller.overlayContainerPlacementClass).to.equal(
|
||||
`global-overlays__overlay-container--${viewportPlacement}`,
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ describe('ModalDialogController', () => {
|
|||
expect(ctrl.preventsScroll).to.be.true;
|
||||
expect(ctrl.trapsKeyboardFocus).to.be.true;
|
||||
expect(ctrl.hidesOnEsc).to.be.true;
|
||||
expect(ctrl.overlayContainerClass).to.equal('global-overlays__overlay-container--center');
|
||||
expect(ctrl.overlayContainerPlacementClass).to.equal(
|
||||
'global-overlays__overlay-container--center',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue