mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 20:19:13 +00:00
remove slot detection from card, dialog, drawer
This commit is contained in:
@@ -328,7 +328,7 @@ wa-select[label="Signet"]::part(form-control-help-text) {
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<wa-dialog id="icon-chooser" label="Browse Icons">
|
||||
<wa-dialog id="icon-chooser" label="Browse Icons" with-header>
|
||||
<div style="display: grid; grid-template-rows: minmax(0, auto) minmax(0, 1fr); height: 100%; gap: 1rem;">
|
||||
<div style="display: flex; gap: 1.25rem;">
|
||||
<wa-input name="icon-search" placeholder="Search Icons" clearable style="flex: 1 1 auto;">
|
||||
|
||||
@@ -5,7 +5,7 @@ layout: ../../../layouts/ComponentLayout.astro
|
||||
---
|
||||
|
||||
```html:preview
|
||||
<wa-card class="card-overview">
|
||||
<wa-card with-image with-footer class="card-overview">
|
||||
<img
|
||||
slot="image"
|
||||
src="https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80"
|
||||
@@ -62,7 +62,7 @@ const css = `
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard className="card-overview">
|
||||
<WaCard with-image with-footer className="card-overview">
|
||||
<img
|
||||
slot="image"
|
||||
src="https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80"
|
||||
@@ -129,7 +129,7 @@ const App = () => (
|
||||
Headers can be used to display titles and more.
|
||||
|
||||
```html:preview
|
||||
<wa-card class="card-header">
|
||||
<wa-card with-header class="card-header">
|
||||
<div slot="header">
|
||||
Header Title
|
||||
<wa-icon-button name="gear" variant="solid" label="Settings"></wa-icon-button>
|
||||
@@ -185,7 +185,7 @@ const css = `
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard className="card-header">
|
||||
<WaCard with-header className="card-header">
|
||||
<div slot="header">
|
||||
Header Title
|
||||
<WaIconButton name="gear" variant="solid"></WaIconButton>
|
||||
@@ -203,7 +203,7 @@ const App = () => (
|
||||
Footers can be used to display actions, summaries, or other relevant content.
|
||||
|
||||
```html:preview
|
||||
<wa-card class="card-footer">
|
||||
<wa-card with-footer class="card-footer">
|
||||
This card has a footer. You can put all sorts of things in it!
|
||||
|
||||
<div slot="footer">
|
||||
@@ -244,7 +244,7 @@ const css = `
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard className="card-footer">
|
||||
<WaCard with-footer className="card-footer">
|
||||
This card has a footer. You can put all sorts of things in it!
|
||||
<div slot="footer">
|
||||
<WaRating></WaRating>
|
||||
@@ -264,7 +264,7 @@ const App = () => (
|
||||
Cards accept an `image` slot. The image is displayed atop the card and stretches to fit.
|
||||
|
||||
```html:preview
|
||||
<wa-card class="card-image">
|
||||
<wa-card with-image class="card-image">
|
||||
<img
|
||||
slot="image"
|
||||
src="https://images.unsplash.com/photo-1547191783-94d5f8f6d8b1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&q=80"
|
||||
@@ -291,7 +291,7 @@ const css = `
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard className="card-image">
|
||||
<WaCard with-image className="card-image">
|
||||
<img
|
||||
slot="image"
|
||||
src="https://images.unsplash.com/photo-1547191783-94d5f8f6d8b1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&q=80"
|
||||
|
||||
@@ -7,7 +7,7 @@ layout: ../../../layouts/ComponentLayout.astro
|
||||
<!-- cspell:dictionaries lorem-ipsum -->
|
||||
|
||||
```html:preview
|
||||
<wa-dialog label="Dialog" class="dialog-overview">
|
||||
<wa-dialog label="Dialog" with-header with-footer class="dialog-overview">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-dialog>
|
||||
@@ -34,7 +34,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
@@ -54,7 +54,7 @@ const App = () => {
|
||||
Use the `--width` custom property to set the dialog's width.
|
||||
|
||||
```html:preview
|
||||
<wa-dialog label="Dialog" class="dialog-width" style="--width: 50vw;">
|
||||
<wa-dialog label="Dialog" with-header with-footer class="dialog-width" style="--width: 50vw;">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-dialog>
|
||||
@@ -81,7 +81,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" open={open} style={{ '--width': '50vw' }} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} style={{ '--width': '50vw' }} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
@@ -99,7 +99,7 @@ const App = () => {
|
||||
By design, a dialog's height will never exceed that of the viewport. As such, dialogs will not scroll with the page ensuring the header and footer are always accessible to the user.
|
||||
|
||||
```html:preview
|
||||
<wa-dialog label="Dialog" class="dialog-scrolling">
|
||||
<wa-dialog label="Dialog" with-header with-footer class="dialog-scrolling">
|
||||
<div style="height: 150vh; border: dashed 2px var(--wa-color-surface-border); padding: 0 1rem;">
|
||||
<p>Scroll down and give it a try! 👇</p>
|
||||
</div>
|
||||
@@ -128,7 +128,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<div
|
||||
style={{
|
||||
height: '150vh',
|
||||
@@ -155,7 +155,7 @@ const App = () => {
|
||||
The header shows a functional close button by default. You can use the `header-actions` slot to add additional [icon buttons](/components/icon-button) if needed.
|
||||
|
||||
```html:preview
|
||||
<wa-dialog label="Dialog" class="dialog-header-actions">
|
||||
<wa-dialog label="Dialog" with-header with-footer class="dialog-header-actions">
|
||||
<wa-icon-button class="new-window" slot="header-actions" name="arrow-up-right-from-square" variant="solid"></wa-icon-button>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
@@ -186,7 +186,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaIconButton
|
||||
class="new-window"
|
||||
slot="header-actions"
|
||||
@@ -214,7 +214,7 @@ To keep the dialog open in such cases, you can cancel the `wa-request-close` eve
|
||||
You can use `event.detail.source` to determine what triggered the request to close. This example prevents the dialog from closing when the overlay is clicked, but allows the close button or [[Escape]] to dismiss it.
|
||||
|
||||
```html:preview
|
||||
<wa-dialog label="Dialog" class="dialog-deny-close">
|
||||
<wa-dialog label="Dialog" with-header with-footer class="dialog-deny-close">
|
||||
This dialog will not close when you click on the overlay.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-dialog>
|
||||
@@ -255,7 +255,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" open={open} onWaRequestClose={handleRequestClose} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaRequestClose={handleRequestClose} onWaAfterHide={() => setOpen(false)}>
|
||||
This dialog will not close when you click on the overlay.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
@@ -273,7 +273,7 @@ const App = () => {
|
||||
By default, the dialog's panel will gain focus when opened. This allows a subsequent tab press to focus on the first tabbable element in the dialog. If you want a different element to have focus, add the `autofocus` attribute to it as shown below.
|
||||
|
||||
```html:preview
|
||||
<wa-dialog label="Dialog" class="dialog-focus">
|
||||
<wa-dialog label="Dialog" with-header with-footer class="dialog-focus">
|
||||
<wa-input autofocus placeholder="I will have focus when the dialog is opened"></wa-input>
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-dialog>
|
||||
@@ -302,7 +302,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaInput autofocus placeholder="I will have focus when the dialog is opened" />
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
|
||||
@@ -7,7 +7,7 @@ layout: ../../../layouts/ComponentLayout.astro
|
||||
<!-- cspell:dictionaries lorem-ipsum -->
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" class="drawer-overview">
|
||||
<wa-drawer label="Drawer" with-header with-footer class="drawer-overview">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-drawer>
|
||||
@@ -34,7 +34,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
@@ -54,7 +54,7 @@ const App = () => {
|
||||
By default, drawers slide in from the end. To make the drawer slide in from the start, set the `placement` attribute to `start`.
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" placement="start" class="drawer-placement-start">
|
||||
<wa-drawer label="Drawer" placement="start" with-header with-footer class="drawer-placement-start">
|
||||
This drawer slides in from the start.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-drawer>
|
||||
@@ -81,7 +81,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" placement="start" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDrawer label="Drawer" placement="start" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
This drawer slides in from the start.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
@@ -99,7 +99,7 @@ const App = () => {
|
||||
To make the drawer slide in from the top, set the `placement` attribute to `top`.
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" placement="top" class="drawer-placement-top">
|
||||
<wa-drawer label="Drawer" placement="top" with-header with-footer class="drawer-placement-top">
|
||||
This drawer slides in from the top.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-drawer>
|
||||
@@ -126,7 +126,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" placement="top" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDrawer label="Drawer" placement="top" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
This drawer slides in from the top.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
@@ -144,7 +144,7 @@ const App = () => {
|
||||
To make the drawer slide in from the bottom, set the `placement` attribute to `bottom`.
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" placement="bottom" class="drawer-placement-bottom">
|
||||
<wa-drawer label="Drawer" placement="bottom" with-header with-footer class="drawer-placement-bottom">
|
||||
This drawer slides in from the bottom.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-drawer>
|
||||
@@ -171,7 +171,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" placement="bottom" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDrawer label="Drawer" placement="bottom" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
This drawer slides in from the bottom.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
@@ -184,84 +184,12 @@ const App = () => {
|
||||
};
|
||||
```
|
||||
|
||||
### Contained to an Element
|
||||
|
||||
By default, drawers slide out of their [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport. To make a drawer slide out of a parent element, add the `contained` attribute to the drawer and apply `position: relative` to its parent.
|
||||
|
||||
Unlike normal drawers, contained drawers are not modal. This means they do not show an overlay, they do not trap focus, and they are not dismissible with [[Escape]]. This is intentional to allow users to interact with elements outside of the drawer.
|
||||
|
||||
```html:preview
|
||||
<div
|
||||
style="position: relative; border: solid 2px var(--wa-color-surface-border); height: 300px; padding: 1rem; margin-bottom: 1rem;"
|
||||
>
|
||||
The drawer will be contained to this box. This content won't shift or be affected in any way when the drawer opens.
|
||||
|
||||
<wa-drawer label="Drawer" contained class="drawer-contained" style="--size: 50%;">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-drawer>
|
||||
</div>
|
||||
|
||||
<wa-button>Toggle Drawer</wa-button>
|
||||
|
||||
<script>
|
||||
const drawer = document.querySelector('.drawer-contained');
|
||||
const openButton = drawer.parentElement.nextElementSibling;
|
||||
const closeButton = drawer.querySelector('wa-button[variant="brand"]');
|
||||
|
||||
openButton.addEventListener('click', () => (drawer.open = !drawer.open));
|
||||
closeButton.addEventListener('click', () => drawer.hide());
|
||||
</script>
|
||||
```
|
||||
|
||||
```jsx:react
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
border: 'solid 2px var(--wa-color-surface-border)',
|
||||
height: '300px',
|
||||
padding: '1rem',
|
||||
marginBottom: '1rem'
|
||||
}}
|
||||
>
|
||||
The drawer will be contained to this box. This content won't shift or be affected in any way when the drawer
|
||||
opens.
|
||||
<WaDrawer
|
||||
label="Drawer"
|
||||
contained
|
||||
no-modal
|
||||
open={open}
|
||||
onWaAfterHide={() => setOpen(false)}
|
||||
style={{ '--size': '50%' }}
|
||||
>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
</div>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### Custom Size
|
||||
|
||||
Use the `--size` custom property to set the drawer's size. This will be applied to the drawer's width or height depending on its `placement`.
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" class="drawer-custom-size" style="--size: 50vw;">
|
||||
<wa-drawer label="Drawer" with-header with-footer class="drawer-custom-size" style="--size: 50vw;">
|
||||
This drawer is always 50% of the viewport.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-drawer>
|
||||
@@ -288,7 +216,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" open={open} onWaAfterHide={() => setOpen(false)} style={{ '--size': '50vw' }}>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)} style={{ '--size': '50vw' }}>
|
||||
This drawer is always 50% of the viewport.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
@@ -306,7 +234,7 @@ const App = () => {
|
||||
By design, a drawer's height will never exceed 100% of its container. As such, drawers will not scroll with the page to ensure the header and footer are always accessible to the user.
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" class="drawer-scrolling">
|
||||
<wa-drawer label="Drawer" with-header with-footer class="drawer-scrolling">
|
||||
<div style="height: 150vh; border: dashed 2px var(--wa-color-surface-border); padding: 0 1rem;">
|
||||
<p>Scroll down and give it a try! 👇</p>
|
||||
</div>
|
||||
@@ -335,7 +263,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<div
|
||||
style={{
|
||||
height: '150vh',
|
||||
@@ -361,7 +289,7 @@ const App = () => {
|
||||
The header shows a functional close button by default. You can use the `header-actions` slot to add additional [icon buttons](/components/icon-button) if needed.
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" class="drawer-header-actions">
|
||||
<wa-drawer label="Drawer" with-header with-footer class="drawer-header-actions">
|
||||
<wa-icon-button class="new-window" slot="header-actions" name="arrow-up-right-from-square" variant="solid"></wa-icon-button>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
@@ -392,7 +320,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaIconButton slot="header-actions" name="arrow-up-right-from-square" onClick={() => window.open(location.href)} />
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
@@ -415,7 +343,7 @@ To keep the drawer open in such cases, you can cancel the `wa-request-close` eve
|
||||
You can use `event.detail.source` to determine what triggered the request to close. This example prevents the drawer from closing when the overlay is clicked, but allows the close button or [[Escape]] to dismiss it.
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" class="drawer-deny-close">
|
||||
<wa-drawer label="Drawer" with-header with-footer class="drawer-deny-close">
|
||||
This drawer will not close when you click on the overlay.
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-drawer>
|
||||
@@ -456,7 +384,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" open={open} onWaRequestClose={handleRequestClose} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaRequestClose={handleRequestClose} onWaAfterHide={() => setOpen(false)}>
|
||||
This drawer will not close when you click on the overlay.
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Save & Close
|
||||
@@ -474,7 +402,7 @@ const App = () => {
|
||||
By default, the drawer's panel will gain focus when opened. This allows a subsequent tab press to focus on the first tabbable element in the drawer. If you want a different element to have focus, add the `autofocus` attribute to it as shown below.
|
||||
|
||||
```html:preview
|
||||
<wa-drawer label="Drawer" class="drawer-focus">
|
||||
<wa-drawer label="Drawer" with-header with-footer class="drawer-focus">
|
||||
<wa-input autofocus placeholder="I will have focus when the drawer is opened"></wa-input>
|
||||
<wa-button slot="footer" variant="brand">Close</wa-button>
|
||||
</wa-drawer>
|
||||
@@ -503,7 +431,7 @@ const App = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaInput autofocus placeholder="I will have focus when the drawer is opened" />
|
||||
<WaButton slot="footer" variant="brand" onClick={() => setOpen(false)}>
|
||||
Close
|
||||
|
||||
@@ -6,7 +6,7 @@ description: TODO
|
||||
## Card
|
||||
|
||||
```html:preview
|
||||
<wa-card class="card-overview">
|
||||
<wa-card with-image class="card-overview">
|
||||
<img
|
||||
slot="image"
|
||||
src="https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80"
|
||||
|
||||
@@ -281,7 +281,7 @@ Internally, each component uses the [BEM methodology](http://getbem.com/) for cl
|
||||
|
||||
### Boolean Props
|
||||
|
||||
Boolean props should _always_ default to `false`, otherwise there's no way for the user to unset them using only attributes. To keep the API as friendly and consistent as possible, use a property such as `noHeader` and a corresponding kebab-case attribute such as `no-header`.
|
||||
Boolean props should _always_ default to `false`, otherwise there's no way for the user to unset them using only attributes. To keep the API as friendly and consistent as possible, use a property such as `noValue` and a corresponding kebab-case attribute such as `no-value`.
|
||||
|
||||
When naming boolean props that hide or disable things, prefix them with `no-`, e.g. `no-spin-buttons` and avoid using other verbs such as `hide-` and `disable-` for consistency.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
fun.
|
||||
</p>
|
||||
|
||||
<wa-dialog id="dialog"> I'm just a lowly dialog. </wa-dialog>
|
||||
<wa-dialog id="dialog" label="Dialog" with-header> I'm just a lowly dialog. </wa-dialog>
|
||||
|
||||
<wa-button>Open Dialog</wa-button>
|
||||
</wa-page>
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
<wa-card class="wa-card--muted" style="--padding: 8px">
|
||||
<wa-card with-header class="wa-card--muted" style="--padding: 8px">
|
||||
<h3 slot="header">Total listening time</h3>
|
||||
|
||||
<p>
|
||||
@@ -146,7 +146,7 @@
|
||||
</p>
|
||||
</wa-card>
|
||||
|
||||
<wa-card class="wa-card--muted" style="--padding: 8px">
|
||||
<wa-card with-header class="wa-card--muted" style="--padding: 8px">
|
||||
<h3 slot="header">Total songs played</h3>
|
||||
|
||||
<p>
|
||||
@@ -160,7 +160,7 @@
|
||||
</p>
|
||||
</wa-card>
|
||||
|
||||
<wa-card class="wa-card--muted" style="--padding: 8px">
|
||||
<wa-card with-header class="wa-card--muted" style="--padding: 8px">
|
||||
<h3 slot="header">Average listening session</h3>
|
||||
|
||||
<p>
|
||||
@@ -174,7 +174,7 @@
|
||||
</p>
|
||||
</wa-card>
|
||||
|
||||
<wa-card class="wa-card--muted" style="--padding: 8px">
|
||||
<wa-card with-header class="wa-card--muted" style="--padding: 8px">
|
||||
<h3 slot="header">Average track listening time</h3>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { HasSlotController } from '../../internal/slot.js';
|
||||
import { html } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './card.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
@@ -34,7 +34,14 @@ import type { CSSResultGroup } from 'lit';
|
||||
export default class WaCard extends WebAwesomeElement {
|
||||
static styles: CSSResultGroup = [componentStyles, styles];
|
||||
|
||||
private readonly hasSlotController = new HasSlotController(this, 'footer', 'header', 'image');
|
||||
/** Renders the card with a header */
|
||||
@property({ attribute: 'with-header', type: Boolean }) withHeader = false;
|
||||
|
||||
/** Renders the card with an image */
|
||||
@property({ attribute: 'with-image', type: Boolean }) withImage = false;
|
||||
|
||||
/** Renders the card with a footer */
|
||||
@property({ attribute: 'with-footer', type: Boolean }) withFooter = false;
|
||||
|
||||
render() {
|
||||
return html`
|
||||
@@ -42,9 +49,9 @@ export default class WaCard extends WebAwesomeElement {
|
||||
part="base"
|
||||
class=${classMap({
|
||||
card: true,
|
||||
'card--has-footer': this.hasSlotController.test('footer'),
|
||||
'card--has-image': this.hasSlotController.test('image'),
|
||||
'card--has-header': this.hasSlotController.test('header')
|
||||
'card--has-footer': this.withFooter,
|
||||
'card--has-image': this.withImage,
|
||||
'card--has-header': this.withHeader
|
||||
})}
|
||||
>
|
||||
<slot name="image" part="image" class="card__image"></slot>
|
||||
|
||||
@@ -37,6 +37,8 @@ export default css`
|
||||
.card__image::slotted(img) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-bottom-left-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
.card:not(.card--has-image) .card__image {
|
||||
|
||||
@@ -29,7 +29,7 @@ describe('<wa-card>', () => {
|
||||
describe('when provided an element in the slot "header" to render a header', () => {
|
||||
before(async () => {
|
||||
el = await fixture<WaCard>(
|
||||
html`<wa-card>
|
||||
html`<wa-card with-header>
|
||||
<div slot="header">Header Title</div>
|
||||
This card has a header. You can put all sorts of things in it!
|
||||
</wa-card>`
|
||||
@@ -65,7 +65,7 @@ describe('<wa-card>', () => {
|
||||
describe('when provided an element in the slot "footer" to render a footer', () => {
|
||||
before(async () => {
|
||||
el = await fixture<WaCard>(
|
||||
html`<wa-card>
|
||||
html`<wa-card with-footer>
|
||||
This card has a footer. You can put all sorts of things in it!
|
||||
|
||||
<div slot="footer">Footer Content</div>
|
||||
@@ -102,7 +102,7 @@ describe('<wa-card>', () => {
|
||||
describe('when provided an element in the slot "image" to render a image', () => {
|
||||
before(async () => {
|
||||
el = await fixture<WaCard>(
|
||||
html`<wa-card>
|
||||
html`<wa-card with-image>
|
||||
<img
|
||||
slot="image"
|
||||
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { animateTo, stopAnimations } from '../../internal/animate.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { getAnimation, setDefaultAnimation } from '../../utilities/animation-registry.js';
|
||||
import { HasSlotController } from '../../internal/slot.js';
|
||||
import { html } from 'lit';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
@@ -71,7 +70,6 @@ export default class WaDialog extends WebAwesomeElement {
|
||||
'wa-icon-button': WaIconButton
|
||||
};
|
||||
|
||||
private readonly hasSlotController = new HasSlotController(this, 'footer');
|
||||
private readonly localize = new LocalizeController(this);
|
||||
private originalTrigger: HTMLElement | null;
|
||||
public modal = new Modal(this);
|
||||
@@ -88,16 +86,16 @@ export default class WaDialog extends WebAwesomeElement {
|
||||
@property({ type: Boolean, reflect: true }) open = false;
|
||||
|
||||
/**
|
||||
* The dialog's label as displayed in the header. You should always include a relevant label even when using
|
||||
* `no-header`, as it is required for proper accessibility. If you need to display HTML, use the `label` slot instead.
|
||||
* The dialog's label as displayed in the header. You should always include a relevant label, as it is required for
|
||||
* proper accessibility. If you need to display HTML, use the `label` slot instead.
|
||||
*/
|
||||
@property({ reflect: true }) label = '';
|
||||
|
||||
/**
|
||||
* Disables the header. This will also remove the default close button, so please ensure you provide an easy,
|
||||
* accessible way for users to dismiss the dialog.
|
||||
*/
|
||||
@property({ attribute: 'no-header', type: Boolean, reflect: true }) noHeader = false;
|
||||
/** Renders the dialog with a header. */
|
||||
@property({ attribute: 'with-header', type: Boolean, reflect: true }) withHeader = false;
|
||||
|
||||
/** Renders the dialog with a footer. */
|
||||
@property({ attribute: 'with-footer', type: Boolean, reflect: true }) withFooter = false;
|
||||
|
||||
firstUpdated() {
|
||||
this.dialog.hidden = !this.open;
|
||||
@@ -272,7 +270,8 @@ export default class WaDialog extends WebAwesomeElement {
|
||||
class=${classMap({
|
||||
dialog: true,
|
||||
'dialog--open': this.open,
|
||||
'dialog--has-footer': this.hasSlotController.test('footer')
|
||||
'dialog--with-header': this.withHeader,
|
||||
'dialog--with-footer': this.withFooter
|
||||
})}
|
||||
>
|
||||
<div part="overlay" class="dialog__overlay" @click=${() => this.requestClose('overlay')} tabindex="-1"></div>
|
||||
@@ -283,11 +282,11 @@ export default class WaDialog extends WebAwesomeElement {
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-hidden=${this.open ? 'false' : 'true'}
|
||||
aria-label=${ifDefined(this.noHeader ? this.label : undefined)}
|
||||
aria-labelledby=${ifDefined(!this.noHeader ? 'title' : undefined)}
|
||||
aria-label=${ifDefined(this.withHeader ? undefined : this.label)}
|
||||
aria-labelledby=${ifDefined(this.withHeader ? 'title' : undefined)}
|
||||
tabindex="-1"
|
||||
>
|
||||
${!this.noHeader
|
||||
${this.withHeader
|
||||
? html`
|
||||
<header part="header" class="dialog__header">
|
||||
<h2 part="title" class="dialog__title" id="title">
|
||||
@@ -314,9 +313,13 @@ export default class WaDialog extends WebAwesomeElement {
|
||||
}
|
||||
<div part="body" class="dialog__body" tabindex="-1"><slot></slot></div>
|
||||
|
||||
<footer part="footer" class="dialog__footer">
|
||||
<slot name="footer"></slot>
|
||||
</footer>
|
||||
${this.withFooter
|
||||
? html`
|
||||
<footer part="footer" class="dialog__footer">
|
||||
<slot name="footer"></slot>
|
||||
</footer>
|
||||
`
|
||||
: ''}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -99,10 +99,6 @@ export default css`
|
||||
margin-inline-start: var(--wa-spacing-xs);
|
||||
}
|
||||
|
||||
.dialog:not(.dialog--has-footer) .dialog__footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dialog__overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
|
||||
@@ -6,10 +6,10 @@ import { sendKeys } from '@web/test-runner-commands';
|
||||
import sinon from 'sinon';
|
||||
import type WaDialog from './dialog.js';
|
||||
|
||||
describe('<wa-dialog>', () => {
|
||||
describe('<wa-dialog with-header>', () => {
|
||||
it('should be visible with the open attribute', async () => {
|
||||
const el = await fixture<WaDialog>(html`
|
||||
<wa-dialog open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
<wa-dialog with-header open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
`);
|
||||
const base = el.shadowRoot!.querySelector<HTMLElement>('[part~="base"]')!;
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('<wa-dialog>', () => {
|
||||
|
||||
it('should not be visible without the open attribute', async () => {
|
||||
const el = await fixture<WaDialog>(html`
|
||||
<wa-dialog>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
<wa-dialog with-header>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
`);
|
||||
const base = el.shadowRoot!.querySelector<HTMLElement>('[part~="base"]')!;
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('<wa-dialog>', () => {
|
||||
|
||||
it('should emit wa-show and wa-after-show when calling show()', async () => {
|
||||
const el = await fixture<WaDialog>(html`
|
||||
<wa-dialog>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
<wa-dialog with-header>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
`);
|
||||
const base = el.shadowRoot!.querySelector<HTMLElement>('[part~="base"]')!;
|
||||
const showHandler = sinon.spy();
|
||||
@@ -47,7 +47,7 @@ describe('<wa-dialog>', () => {
|
||||
|
||||
it('should emit wa-hide and wa-after-hide when calling hide()', async () => {
|
||||
const el = await fixture<WaDialog>(html`
|
||||
<wa-dialog open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
<wa-dialog with-header open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
`);
|
||||
const base = el.shadowRoot!.querySelector<HTMLElement>('[part~="base"]')!;
|
||||
const hideHandler = sinon.spy();
|
||||
@@ -67,7 +67,7 @@ describe('<wa-dialog>', () => {
|
||||
|
||||
it('should emit wa-show and wa-after-show when setting open = true', async () => {
|
||||
const el = await fixture<WaDialog>(html`
|
||||
<wa-dialog>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
<wa-dialog with-header>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
`);
|
||||
const base = el.shadowRoot!.querySelector<HTMLElement>('[part~="base"]')!;
|
||||
const showHandler = sinon.spy();
|
||||
@@ -87,7 +87,7 @@ describe('<wa-dialog>', () => {
|
||||
|
||||
it('should emit wa-hide and wa-after-hide when setting open = false', async () => {
|
||||
const el = await fixture<WaDialog>(html`
|
||||
<wa-dialog open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
<wa-dialog with-header open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
`);
|
||||
const base = el.shadowRoot!.querySelector<HTMLElement>('[part~="base"]')!;
|
||||
const hideHandler = sinon.spy();
|
||||
@@ -107,7 +107,7 @@ describe('<wa-dialog>', () => {
|
||||
|
||||
it('should not close when wa-request-close is prevented', async () => {
|
||||
const el = await fixture<WaDialog>(html`
|
||||
<wa-dialog open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
<wa-dialog with-header open>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</wa-dialog>
|
||||
`);
|
||||
const overlay = el.shadowRoot!.querySelector<HTMLElement>('[part~="overlay"]')!;
|
||||
|
||||
@@ -120,7 +120,7 @@ describe('<wa-dialog>', () => {
|
||||
});
|
||||
|
||||
it('should allow initial focus to be set', async () => {
|
||||
const el = await fixture<WaDialog>(html` <wa-dialog><input /></wa-dialog> `);
|
||||
const el = await fixture<WaDialog>(html` <wa-dialog with-header><input /></wa-dialog> `);
|
||||
const input = el.querySelector('input')!;
|
||||
const initialFocusHandler = sinon.spy((event: Event) => {
|
||||
event.preventDefault();
|
||||
@@ -137,7 +137,7 @@ describe('<wa-dialog>', () => {
|
||||
});
|
||||
|
||||
it('should close when pressing Escape', async () => {
|
||||
const el = await fixture<WaDialog>(html` <wa-dialog open></wa-dialog> `);
|
||||
const el = await fixture<WaDialog>(html` <wa-dialog with-header open></wa-dialog> `);
|
||||
const hideHandler = sinon.spy();
|
||||
|
||||
el.addEventListener('wa-hide', hideHandler);
|
||||
@@ -162,7 +162,7 @@ describe('<wa-dialog>', () => {
|
||||
render() {
|
||||
return html`
|
||||
<h1>Dialog Example</h1>
|
||||
<wa-dialog label="Dialog" class="dialog-overview">
|
||||
<wa-dialog with-header label="Dialog" class="dialog-overview">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<br />
|
||||
<label><input type="checkbox" />A</label>
|
||||
@@ -200,7 +200,7 @@ describe('<wa-dialog>', () => {
|
||||
const dialog = container.shadowRoot?.querySelector('wa-dialog');
|
||||
|
||||
if (!dialog) {
|
||||
throw Error('Could not find <wa-dialog> element.');
|
||||
throw Error('Could not find <wa-dialog with-header> element.');
|
||||
}
|
||||
|
||||
const closeButton = dialog.shadowRoot?.querySelector('wa-icon-button');
|
||||
|
||||
@@ -95,36 +95,27 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
@property({ type: Boolean, reflect: true }) open = false;
|
||||
|
||||
/**
|
||||
* The drawer's label as displayed in the header. You should always include a relevant label even when using
|
||||
* `no-header`, as it is required for proper accessibility. If you need to display HTML, use the `label` slot instead.
|
||||
* The drawer's label as displayed in the header. You should always include a relevant label, as it is required for
|
||||
* proper accessibility. If you need to display HTML, use the `label` slot instead.
|
||||
*/
|
||||
@property({ reflect: true }) label = '';
|
||||
|
||||
/** The direction from which the drawer will open. */
|
||||
@property({ reflect: true }) placement: 'top' | 'end' | 'bottom' | 'start' = 'end';
|
||||
|
||||
/**
|
||||
* By default, the drawer slides out of its containing block (usually the viewport). To make the drawer slide out of
|
||||
* its parent element, set this attribute and add `position: relative` to the parent.
|
||||
*/
|
||||
@property({ type: Boolean, reflect: true }) contained = false;
|
||||
/** Renders the drawer with a header. */
|
||||
@property({ attribute: 'with-header', type: Boolean, reflect: true }) withHeader = false;
|
||||
|
||||
/**
|
||||
* Removes the header. This will also remove the default close button, so please ensure you provide an easy,
|
||||
* accessible way for users to dismiss the drawer.
|
||||
*/
|
||||
@property({ attribute: 'no-header', type: Boolean, reflect: true }) noHeader = false;
|
||||
/** Renders the drawer with a footer. */
|
||||
@property({ attribute: 'with-footer', type: Boolean, reflect: true }) withFooter = false;
|
||||
|
||||
firstUpdated() {
|
||||
this.drawer.hidden = !this.open;
|
||||
|
||||
if (this.open) {
|
||||
this.addOpenListeners();
|
||||
|
||||
if (!this.contained) {
|
||||
this.modal.activate();
|
||||
lockBodyScrolling(this);
|
||||
}
|
||||
this.modal.activate();
|
||||
lockBodyScrolling(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,10 +143,8 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
private addOpenListeners() {
|
||||
if ('CloseWatcher' in window) {
|
||||
this.closeWatcher?.destroy();
|
||||
if (!this.contained) {
|
||||
this.closeWatcher = new CloseWatcher();
|
||||
this.closeWatcher.onclose = () => this.requestClose('keyboard');
|
||||
}
|
||||
this.closeWatcher = new CloseWatcher();
|
||||
this.closeWatcher.onclose = () => this.requestClose('keyboard');
|
||||
} else {
|
||||
document.addEventListener('keydown', this.handleDocumentKeyDown);
|
||||
this.closeWatcher?.destroy();
|
||||
@@ -167,11 +156,6 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
}
|
||||
|
||||
private handleDocumentKeyDown = (event: KeyboardEvent) => {
|
||||
// Contained drawers aren't modal and don't response to the escape key
|
||||
if (this.contained) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.key === 'Escape' && this.modal.isActive() && this.open) {
|
||||
event.stopImmediatePropagation();
|
||||
this.requestClose('keyboard');
|
||||
@@ -185,12 +169,8 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
this.emit('wa-show');
|
||||
this.addOpenListeners();
|
||||
this.originalTrigger = document.activeElement as HTMLElement;
|
||||
|
||||
// Lock body scrolling only if the drawer isn't contained
|
||||
if (!this.contained) {
|
||||
this.modal.activate();
|
||||
lockBodyScrolling(this);
|
||||
}
|
||||
this.modal.activate();
|
||||
lockBodyScrolling(this);
|
||||
|
||||
// When the drawer is shown, Safari will attempt to set focus on whatever element has autofocus. This causes the
|
||||
// drawer's animation to jitter, so we'll temporarily remove the attribute, call `focus({ preventScroll: true })`
|
||||
@@ -239,11 +219,8 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
// Hide
|
||||
this.emit('wa-hide');
|
||||
this.removeOpenListeners();
|
||||
|
||||
if (!this.contained) {
|
||||
this.modal.deactivate();
|
||||
unlockBodyScrolling(this);
|
||||
}
|
||||
this.modal.deactivate();
|
||||
unlockBodyScrolling(this);
|
||||
|
||||
await Promise.all([stopAnimations(this.drawer), stopAnimations(this.overlay)]);
|
||||
const panelAnimation = getAnimation(this, `drawer.hide${uppercaseFirstLetter(this.placement)}`, {
|
||||
@@ -279,19 +256,6 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('contained', { waitUntilFirstUpdate: true })
|
||||
handleNoModalChange() {
|
||||
if (this.open && !this.contained) {
|
||||
this.modal.activate();
|
||||
lockBodyScrolling(this);
|
||||
}
|
||||
|
||||
if (this.open && this.contained) {
|
||||
this.modal.deactivate();
|
||||
unlockBodyScrolling(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** Shows the drawer. */
|
||||
async show() {
|
||||
if (this.open) {
|
||||
@@ -323,10 +287,9 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
'drawer--end': this.placement === 'end',
|
||||
'drawer--bottom': this.placement === 'bottom',
|
||||
'drawer--start': this.placement === 'start',
|
||||
'drawer--contained': this.contained,
|
||||
'drawer--fixed': !this.contained,
|
||||
'drawer--rtl': this.localize.dir() === 'rtl',
|
||||
'drawer--has-footer': this.hasSlotController.test('footer')
|
||||
'drawer--with-header': this.withHeader,
|
||||
'drawer--with-footer': this.withFooter
|
||||
})}
|
||||
>
|
||||
<div part="overlay" class="drawer__overlay" @click=${() => this.requestClose('overlay')} tabindex="-1"></div>
|
||||
@@ -337,11 +300,11 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-hidden=${this.open ? 'false' : 'true'}
|
||||
aria-label=${ifDefined(this.noHeader ? this.label : undefined)}
|
||||
aria-labelledby=${ifDefined(!this.noHeader ? 'title' : undefined)}
|
||||
aria-label=${ifDefined(this.withHeader ? undefined : this.label)}
|
||||
aria-labelledby=${ifDefined(this.withHeader ? 'title' : undefined)}
|
||||
tabindex="0"
|
||||
>
|
||||
${!this.noHeader
|
||||
${this.withHeader
|
||||
? html`
|
||||
<header part="header" class="drawer__header">
|
||||
<h2 part="title" class="drawer__title" id="title">
|
||||
@@ -367,9 +330,13 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
|
||||
<slot part="body" class="drawer__body"></slot>
|
||||
|
||||
<footer part="footer" class="drawer__footer">
|
||||
<slot name="footer"></slot>
|
||||
</footer>
|
||||
${this.withFooter
|
||||
? html`
|
||||
<footer part="footer" class="drawer__footer">
|
||||
<slot name="footer"></slot>
|
||||
</footer>
|
||||
`
|
||||
: ''}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -11,6 +11,8 @@ export default css`
|
||||
}
|
||||
|
||||
.drawer {
|
||||
position: fixed;
|
||||
z-index: var(--wa-z-index-drawer);
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
@@ -19,16 +21,6 @@ export default css`
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.drawer--contained {
|
||||
position: absolute;
|
||||
z-index: initial;
|
||||
}
|
||||
|
||||
.drawer--fixed {
|
||||
position: fixed;
|
||||
z-index: var(--wa-z-index-drawer);
|
||||
}
|
||||
|
||||
.drawer__panel {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
@@ -129,10 +121,6 @@ export default css`
|
||||
margin-inline-end: var(--wa-spacing-xs);
|
||||
}
|
||||
|
||||
.drawer:not(.drawer--has-footer) .drawer__footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.drawer__overlay {
|
||||
display: block;
|
||||
position: fixed;
|
||||
@@ -144,10 +132,6 @@ export default css`
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.drawer--contained .drawer__overlay {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.drawer__panel {
|
||||
border: solid 1px white;
|
||||
|
||||
@@ -147,7 +147,7 @@ it('Should allow tabbing to slotted elements', async () => {
|
||||
|
||||
it('Should account for when focus is changed from outside sources (like clicking)', async () => {
|
||||
const dialog = await fixture(html`
|
||||
<wa-dialog open="" label="Dialog" class="dialog-overview">
|
||||
<wa-dialog open="" label="Dialog" with-header with-footer class="dialog-overview">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<wa-input placeholder="tab to me"></wa-input>
|
||||
<wa-button slot="footer" variant="primary">Close</wa-button>
|
||||
@@ -188,12 +188,12 @@ it('Should respect nested modal instances', async () => {
|
||||
await fixture(html`
|
||||
<div>
|
||||
<wa-button id="open-dialog-1" @click=${() => dialogOne().show()}></wa-button>
|
||||
<wa-dialog id="dialog-1" label="Dialog 1">
|
||||
<wa-dialog id="dialog-1" label="Dialog 1" with-header with-footer>
|
||||
<wa-button @click=${() => dialogTwo().show()} id="open-dialog-2">Open Dialog 2</wa-button>
|
||||
<wa-button slot="footer" variant="primary">Close</wa-button>
|
||||
</wa-dialog>
|
||||
|
||||
<wa-dialog id="dialog-2" label="Dialog 2">
|
||||
<wa-dialog id="dialog-2" label="Dialog 2" with-header with-footer>
|
||||
<wa-input id="focus-1" autofocus="" placeholder="I will have focus when the dialog is opened"></wa-input>
|
||||
<wa-input id="focus-2" placeholder="Second input"></wa-input>
|
||||
<wa-button slot="footer" variant="primary" class="close-2">Close</wa-button>
|
||||
|
||||
Reference in New Issue
Block a user