Skip to content

Commit 93827c2

Browse files
committed
Update dialog and confim
1 parent 152e8e5 commit 93827c2

File tree

13 files changed

+577
-316
lines changed

13 files changed

+577
-316
lines changed

docs/_includes/component.njk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
{# Markdown content #}
4545
{{ content | safe }}
4646

47-
Importing
4847
<h2>Importing</h2>
4948
<p>
5049
If you're using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use

docs/pages/components/dialog.md

Lines changed: 130 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,145 @@
11
---
22
meta:
33
title: Dialog
4-
description:
4+
description: 'Dialogs, also called "modals", appear above the page and require the users immediate attention.'
55
layout: component
66
---
77

8+
## Examples
9+
10+
### Basic Dialog
11+
12+
This is a basic dialog. It has a trigger button that opens the dialog. The dialog has a close button and two buttons in
13+
the footer.
14+
815
```html:preview
9-
<zn-dialog></zn-dialog>
16+
17+
<zn-button id="dialog-trigger">Open Basic dialog</zn-button>
18+
<zn-dialog class="dialog-basic" trigger="dialog-trigger" label="Dialog">
19+
This is the dialog’s body.
20+
21+
<zn-button color="default" slot="footer">Do Something</zn-button>
22+
<zn-button color="secondary" slot="footer" dialog-closer>Close Dialog</zn-button>
23+
</zn-dialog>
1024
```
1125

12-
## Examples
26+
### Dialog Variants
27+
28+
Use the header-icon slot to display an sl-icon to the left of the dialog header (label).
29+
30+
Use this pattern for confirmation dialogs, when asking people to confirm that they want to take an action, and for
31+
informational dialogs.
32+
33+
Set the dialog variant (default or warning) to apply the right color theme to the icon: default for confirmation of
34+
neutral actions (like submitting a form), and warning for confirmation of destructive actions (like canceling or
35+
deleting something).
36+
37+
```html:preview
38+
39+
<zn-button id="dialog-trigger">Open Default Dialog</zn-button>
40+
<zn-dialog class="dialog-basic" trigger="dialog-trigger" label="Dialog">
41+
<zn-icon src="info" slot="header-icon"></zn-icon>
42+
If you need to, you can cancel this request after submitting it. Are you sure you want to submit it now?
43+
44+
<zn-button color="secondary" slot="footer" dialog-closer>Close Dialog</zn-button>
45+
<zn-button color="default" slot="footer" type="submit">Do Something</zn-button>
46+
</zn-dialog>
47+
48+
<zn-button id="dialog-trigger-2">Open Warning Dialog</zn-button>
49+
<zn-dialog class="dialog-basic" trigger="dialog-trigger-2" label="Dialog" variant="warning">
50+
<zn-icon src="info" slot="header-icon"></zn-icon>
51+
If you need to, you can cancel this request after submitting it. Are you sure you want to submit it now?
52+
53+
<zn-button color="secondary" slot="footer" dialog-closer>Close Dialog</zn-button>
54+
<zn-button color="warning" slot="footer">Do Something</zn-button>
55+
</zn-dialog>
56+
57+
<zn-button id="dialog-trigger-3" color="warning">Open Announcement Dialog</zn-button>
58+
<zn-dialog class="dialog-basic" trigger="dialog-trigger-3" label="Meet your new Monthly Numbers dashboard" variant="announcement">
59+
<div slot="announcement-intro">Welcome!</div>
60+
<zn-icon src="info" slot="header-icon"></zn-icon>
61+
If you need to, you can cancel this request after submitting it. Are you sure you want to submit it now?
62+
63+
<zn-button color="secondary" slot="footer" dialog-closer>Close Dialog</zn-button>
64+
<zn-button color="default" slot="footer">Do Something</zn-button>
65+
<div slot="footer-text"><a href="#">Learn more about Monthly Numbers</a></div>
66+
</zn-dialog>
67+
```
68+
69+
### Dialogs as Forms
70+
71+
Use dialogs as forms when you need to collect information from users. This example shows a dialog with a form inside it.
72+
73+
```html:preview
74+
75+
<form method="post" action="#" style="display: inline-block">
76+
<zn-button id="dialog-trigger">Open Form Dialog</zn-button>
77+
<zn-dialog class="dialog-basic" trigger="dialog-trigger" label="Dialog" size="large">
78+
<zn-icon src="info" slot="header-icon"></zn-icon>
79+
80+
<zn-form-group
81+
label="Profile"
82+
label-tooltip="huh"
83+
help-text="This information will be displayed publicly so be careful what you share">
84+
85+
<div class="form-spacing">
86+
<zn-input type="text" name="name" label="Name" required></zn-input>
87+
<zn-select label="Favorite Animal" clearable required>
88+
<zn-option value="birds">Birds</zn-option>
89+
<zn-option value="cats">Cats</zn-option>
90+
<zn-option value="dogs">Dogs</zn-option>
91+
<zn-option value="other">Other</zn-option>
92+
</zn-select>
93+
94+
<zn-textarea name="comment" label="Comment" required></zn-textarea>
95+
96+
<zn-checkbox required>Check me before submitting</zn-checkbox>
97+
98+
<br>
99+
<zn-checkbox-group label="Checkbox group" help-text="Select at least one" label-tooltip="Do you need help?"
100+
required>
101+
<zn-checkbox value="I'm option 1">Option 1</zn-checkbox>
102+
<zn-checkbox value="I'm option 2">Option 2</zn-checkbox>
103+
<zn-checkbox value="I'm option 3">Option 3</zn-checkbox>
104+
</zn-checkbox-group>
105+
</div>
106+
</zn-form-group>
107+
108+
<zn-button color="secondary" slot="footer" dialog-closer>Close Dialog</zn-button>
109+
<zn-button color="default" slot="footer" type="submit">Submit</zn-button>
110+
</zn-dialog>
111+
```
112+
113+
### Dialog Sizes
114+
115+
Dialogs come in three different sizes: `small`, `medium`, and `large`. The default size is `medium`.
116+
117+
```html:preview
13118
14-
### First Example
119+
<zn-button id="dialog-trigger">Open Small Dialog</zn-button>
120+
<zn-dialog class="dialog-basic" trigger="dialog-trigger" label="Dialog" size="small">
121+
<zn-icon src="info" slot="header-icon"></zn-icon>
122+
This is a small dialog.
15123
16-
TODO
124+
<zn-button color="secondary" slot="footer" dialog-closer>Close Dialog</zn-button>
125+
<zn-button color="default" slot="footer">Do Something</zn-button>
126+
</zn-dialog>
17127
18-
### Second Example
128+
<zn-button id="dialog-trigger-2">Open Medium Dialog</zn-button>
129+
<zn-dialog class="dialog-basic" trigger="dialog-trigger-2" label="Dialog">
130+
<zn-icon src="info" slot="header-icon"></zn-icon>
131+
This is a medium dialog.
19132
20-
TODO
133+
<zn-button color="secondary" slot="footer" dialog-closer>Close Dialog</zn-button>
134+
<zn-button color="default" slot="footer">Do Something</zn-button>
135+
</zn-dialog>
21136
137+
<zn-button id="dialog-trigger-3">Open Large Dialog</zn-button>
138+
<zn-dialog class="dialog-basic" trigger="dialog-trigger-3" label="Dialog" size="large">
139+
<zn-icon src="info" slot="header-icon"></zn-icon>
140+
This is a large dialog.
22141
142+
<zn-button color="secondary" slot="footer" dialog-closer>Close Dialog</zn-button>
143+
<zn-button color="default" slot="footer">Do Something</zn-button>
144+
</zn-dialog>
145+
```

scss/themes/_light.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@
396396
/* Font weights */
397397
--zn-font-weight-light: 300;
398398
--zn-font-weight-normal: 400;
399-
--zn-font-weight-semibold: 500;
399+
--zn-font-weight-semibold: 600;
400400
--zn-font-weight-bold: 700;
401401

402402
/* Letter spacings */

src/components/confirm-content/confirm-content.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export default class ZnConfirmContent extends Dialog {
124124

125125
if (form && form.reportValidity()) {
126126
form.requestSubmit();
127-
this.close();
127+
this.hide();
128128
}
129129
}
130130
}
Lines changed: 79 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import {property} from 'lit/decorators.js';
2-
import {type CSSResultGroup, html, PropertyValues, unsafeCSS} from 'lit';
3-
import ZnDialog from "../dialog";
41
import {classMap} from "lit/directives/class-map.js";
5-
import {unsafeHTML} from "lit/directives/unsafe-html.js";
2+
import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from 'lit';
3+
import {ifDefined} from "lit/directives/if-defined.js";
4+
import {property, query} from 'lit/decorators.js';
5+
import ZincElement from "../../internal/zinc-element";
6+
import ZnDialog from "../dialog";
67

78
import styles from './confirm.scss';
89

@@ -23,107 +24,103 @@ import styles from './confirm.scss';
2324
*
2425
* @cssproperty --example - An example CSS custom property.
2526
*/
26-
export default class ZnConfirm extends ZnDialog {
27+
export default class ZnConfirm extends ZincElement {
28+
static styles: CSSResultGroup = unsafeCSS(styles);
29+
static dependencies = {
30+
'zn-dialog': ZnDialog
31+
};
2732

28-
static get styles(): CSSResultGroup {
29-
return [super.styles, unsafeCSS(styles)];
30-
}
33+
/** The dialog's theme variant. */
34+
@property({reflect: true}) color: 'default' | 'warning' | 'announcement' = 'default';
35+
36+
/** The dialog's size. */
37+
@property({reflect: true}) size: 'small' | 'medium' | 'large' = 'medium';
38+
39+
/** The dialogs type, which will determine the icon and color. */
40+
@property() type: 'warning' | 'error' | 'success' | 'info' = 'warning';
41+
42+
/**
43+
* Indicated whether of not the dialog is open. You can toggle this attribute to show and hide the dialog, or you can
44+
* use the `show()` and `hide()` methods and this attribute will reflect the dialog's state.
45+
*/
46+
@property({type: Boolean, reflect: true}) open = false;
3147

3248
@property() caption: string = '';
33-
@property() content: string = '';
49+
3450
@property() action: string = '';
51+
52+
@property() content: string = '';
53+
3554
@property() confirmText: string = "Confirm";
55+
3656
@property() cancelText: string = "Cancel";
57+
3758
@property({type: Boolean, attribute: 'hide-icon'}) hideIcon: boolean = false;
3859

39-
@property() type: 'warning' | 'error' | 'success' | 'info' = 'warning';
40-
@property() size: 'small' | 'medium' | 'large' = 'medium';
60+
/**
61+
* The dialog's trigger element. This is used to open the dialog when clicked. If you do not provide a trigger, you
62+
* will need to manually open the dialog using the `show()` method.
63+
*/
64+
@property({reflect: true}) trigger: string;
4165

42-
private _hasVisibleInput: boolean = false;
66+
/** The Dialogs announcement text. */
67+
@property() announcement: string = '';
4368

44-
getIcon() {
45-
const src = {
46-
'warning': 'priority_high',
47-
'error': 'priority_high',
48-
'success': 'check',
49-
'info': 'help'
50-
};
69+
/** The Dialogs footer text. */
70+
@property({attribute: 'footer-text'}) footerText: string = '';
5171

52-
return html`
53-
<zn-icon slot="primary" color="${this.type}" src="${src[this.type]}" size="24"></zn-icon>
54-
`;
55-
}
56-
57-
connectedCallback() {
58-
this.emit('zn-element-added', {detail: {element: this}});
59-
super.connectedCallback();
60-
}
72+
@query('zn-dialog') dialog: ZnDialog;
6173

6274
protected firstUpdated(_changedProperties: PropertyValues) {
6375
super.firstUpdated(_changedProperties);
76+
if (this.open) {
77+
this.dialog.show();
78+
}
79+
}
6480

65-
const slot = this.shadowRoot?.querySelector('slot');
66-
if (slot) {
67-
const nodes: Node[] = slot.assignedNodes();
68-
const form = nodes.filter((node) => node.nodeName === 'FORM');
69-
70-
const elementNameMap = [
71-
'input', 'select', 'textarea', 'zn-select', 'zn-input', 'zn-textarea'
72-
];
73-
74-
const elements: any[] = [];
75-
if (form[0]) {
76-
elementNameMap.forEach((elementName) => {
77-
elements.push(...(form[0] as HTMLFormElement).querySelectorAll(elementName));
78-
});
79-
}
81+
connectedCallback() {
82+
super.connectedCallback();
8083

81-
// Check if there is an input that isn't hidden
82-
for (let i = 0; i < elements.length; i++) {
83-
if (elements[i].type !== 'hidden') {
84-
this._hasVisibleInput = true;
85-
this.requestUpdate();
86-
break;
87-
}
84+
if (this.trigger) {
85+
const trigger = this.parentElement?.querySelector('#' + this.trigger);
86+
if (trigger) {
87+
trigger.addEventListener('click', () => this.dialog.show());
8888
}
8989
}
9090
}
9191

9292
render() {
93-
const icon = this.getIcon();
93+
const src = {
94+
'warning': 'priority_high',
95+
'error': 'priority_high',
96+
'success': 'check',
97+
'info': 'help'
98+
};
9499

95100
return html`
96-
<dialog class=${classMap({
97-
'dialog': true,
98-
'dialog--small': this.size === 'small',
99-
'dialog--medium': this.size === 'medium',
100-
'dialog--large': this.size === 'large'
101-
})}>
102-
<div id="content"> <!-- default dialog close button -->
103-
${!this.hideIcon ? icon : ''}
104-
<h2 class="title">${unsafeHTML(this.caption)}</h2>
105-
${this.content && html`<p>${unsafeHTML(this.content)}</p>`}
106-
<slot></slot>
107-
<div class="${classMap({
108-
'button-group': true,
109-
'button-group--gap': this._hasVisibleInput
110-
})}">
111-
<zn-button style="flex-grow:1" outline color="${this.type}" dialog-closer modal-closer
112-
@click="${this.closeModal}">
113-
${this.cancelText}
114-
</zn-button>
115-
<zn-button style="flex-grow:1" color="${this.type}" @click="${this.submitDialog}"> ${this.confirmText}
116-
</zn-button>
117-
</div>
118-
</div>
119-
<div class="done">
120-
<zn-icon src="check:success" size="150"></zn-icon>
121-
</div>
122-
</dialog>`;
123-
}
101+
<zn-dialog size="${this.size}" variant="announcement" label=${ifDefined(this.caption)} trigger=${this.trigger}
102+
class=${classMap({
103+
'confirm-dialog': true,
104+
'confirm-dialog--warning': this.type === 'warning',
105+
'confirm-dialog--error': this.type === 'error',
106+
'confirm-dialog--success': this.type === 'success',
107+
'confirm-dialog--info': this.type === 'info'
108+
})}>
109+
110+
<slot name="announcement-intro" slot="announcement-intro">${this.announcement}</slot>
111+
112+
${!this.hideIcon ? html`
113+
<zn-icon slot="header-icon" color="${this.type}" src="${src[this.type]}"></zn-icon>`
114+
: ''}
115+
116+
${this.content ? html`<p class="confirm-dialog__content">${this.content}</p>` : ''}
117+
<slot></slot>
118+
119+
<zn-button outline color="${this.type}" slot="footer" dialog-closer>${this.cancelText}</zn-button>
120+
<zn-button color="${this.type}" slot="footer" @click="${this.submitDialog}"> ${this.confirmText}</zn-button>
124121
125-
closeModal() {
126-
this.emit('zn-close', {detail: {element: this}});
122+
<slot name="footer-text" slot="footer-text">${this.footerText}</slot>
123+
</zn-dialog>`;
127124
}
128125

129126
submitDialog() {
@@ -141,7 +138,7 @@ export default class ZnConfirm extends ZnDialog {
141138

142139
if (form && form.reportValidity()) {
143140
form.requestSubmit();
144-
this.close();
141+
this.dialog.hide();
145142
}
146143
}
147144
}

0 commit comments

Comments
 (0)