Modal
A dialog in the middle of the screen. The page behind it cannot be used until it closes.
Basic
Invite a teammate
HTML
<button class="pw-btn pw-btn--primary" data-pw-open="#demo-modal">Open the modal</button>
<div class="pw-modal" id="demo-modal" data-pw-modal hidden>
<div class="pw-modal-box">
<div class="pw-modal-head">
<h2>Invite a teammate</h2>
<button class="pw-close" data-pw-close aria-label="Close"></button>
</div>
<div class="pw-modal-body">
<label class="pw-field">
<span class="pw-label">Email address</span>
<input class="pw-input" type="email" placeholder="name@example.com">
</label>
</div>
<div class="pw-modal-foot">
<button class="pw-btn" data-pw-close>Cancel</button>
<button class="pw-btn pw-btn--primary" data-pw-close>Send invite</button>
</div>
</div>
</div>Sizes and long content
Add pw-modal--sm, pw-modal--lg or pw-modal--full. Long content scrolls inside the box.
Saved
Your changes are saved.
Terms of service
This is sample text to show how a long modal scrolls. The header and the footer stay in place while the middle part moves.
Use short paragraphs. People read dialogs quickly and want to get back to what they were doing.
If you have this much to say, ask yourself whether a full page would be better than a dialog.
The page behind does not scroll while the modal is open, and it does not jump sideways when the scrollbar goes away.
On phones the modal becomes a sheet that slides up from the bottom of the screen.
Pressing Esc closes it. So does a click on the dark area around it.
When it closes, the keyboard focus goes back to the button that opened it.
That is the end of the sample text.
HTML
<button class="pw-btn" data-pw-open="#demo-modal-sm">Small</button>
<button class="pw-btn" data-pw-open="#demo-modal-lg">Large with long text</button>
<div class="pw-modal pw-modal--sm" id="demo-modal-sm" data-pw-modal hidden>
<div class="pw-modal-box">
<div class="pw-modal-head"><h2>Saved</h2><button class="pw-close" data-pw-close aria-label="Close"></button></div>
<div class="pw-modal-body"><p>Your changes are saved.</p></div>
</div>
</div>
<div class="pw-modal pw-modal--lg" id="demo-modal-lg" data-pw-modal hidden>
<div class="pw-modal-box">
<div class="pw-modal-head"><h2>Terms of service</h2><button class="pw-close" data-pw-close aria-label="Close"></button></div>
<div class="pw-modal-body" tabindex="0">
<p>This is sample text to show how a long modal scrolls. The header and the footer stay in place while the middle part moves.</p>
<p>Use short paragraphs. People read dialogs quickly and want to get back to what they were doing.</p>
<p>If you have this much to say, ask yourself whether a full page would be better than a dialog.</p>
<p>The page behind does not scroll while the modal is open, and it does not jump sideways when the scrollbar goes away.</p>
<p>On phones the modal becomes a sheet that slides up from the bottom of the screen.</p>
<p>Pressing Esc closes it. So does a click on the dark area around it.</p>
<p>When it closes, the keyboard focus goes back to the button that opened it.</p>
<p>That is the end of the sample text.</p>
</div>
<div class="pw-modal-foot"><button class="pw-btn pw-btn--primary" data-pw-close>I agree</button></div>
</div>
</div>Must answer
With data-static, a click outside and Esc do not close the modal. The box nudges to show that an answer is needed.
Session about to end
You will be signed out in one minute.
HTML
<button class="pw-btn" data-pw-open="#demo-modal-static">Open</button>
<div class="pw-modal pw-modal--sm" id="demo-modal-static" data-pw-modal data-static hidden>
<div class="pw-modal-box">
<div class="pw-modal-head"><h2>Session about to end</h2></div>
<div class="pw-modal-body"><p>You will be signed out in one minute.</p></div>
<div class="pw-modal-foot">
<button class="pw-btn" data-pw-close>Sign out</button>
<button class="pw-btn pw-btn--primary" data-pw-close>Stay signed in</button>
</div>
</div>
</div>Confirm from a script
Partwise.confirm() builds a small dialog for you and gives back a promise.
HTML
<button class="pw-btn pw-btn--danger" id="demo-delete">Delete project</button>
<p class="demo-out" id="demo-confirm-out"></p>JavaScript
document.getElementById('demo-delete').addEventListener('click', function () {
Partwise.confirm({
title: 'Delete this project?',
text: 'All 12 files in it are deleted too. This cannot be undone.',
ok: 'Delete', danger: true
}).then(function (yes) {
document.getElementById('demo-confirm-out').textContent = yes ? 'You chose Delete.' : 'You chose Cancel.';
});
});Options
Set them as attributes on the element.
| Attribute | Default | What it does |
|---|---|---|
data-static | A click outside and Esc do not close it. | |
data-focus | A selector for the element that gets the focus first, for example #email. Without it, the first field or button that is not a close button. |
Classes
| Class | What it does |
|---|---|
pw-modal--sm | Narrow box, 380px. |
pw-modal--lg | Wide box, 780px. |
pw-modal--full | Fills the screen. |
Events
Listen with addEventListener. Details are in event.detail.
| Event | When |
|---|---|
pw:open | Before it opens. Call preventDefault() to stop it. |
pw:opened | After it opened. |
pw:close | Before it closes, with reason: button, escape, outside or script. Can be stopped. |
pw:closed | After it closed and the focus went back. |
From your script
Partwise.modal.open('#demo-modal');
Partwise.modal.close(); // closes the top one
var m = Partwise.get('#demo-modal', 'modal');
m.open(); m.close(); m.toggle(); m.isOpen;
Partwise.confirm({ title: 'Publish now?', ok: 'Publish' }).then(function (yes) { });Keyboard
| Key | Action |
|---|---|
| Esc | Close |
| Tab | Move through the controls inside. The focus stays in the modal. |
Good to know
- The script adds
role="dialog",aria-modaland the label from the first heading, so you do not have to. - You can open a modal from inside another one. Esc closes the top one first.
- Menus, selects and date pickers work inside a modal.
- Modals you add to the page later need
Partwise.init(element)once.
Files
Everything is in dist/partwise.css and dist/partwise.js. To load only this component, use src/css/00-base.css and src/js/00-core.js plus: css/12-dialog.css, js/12-dialog.js.