Skip to content

Commit 84aa3ec

Browse files
castastrophecastastrophe
authored andcommitted
fix: pull out rendering for Dialog into individual methods
1 parent e750e05 commit 84aa3ec

File tree

2 files changed

+192
-41
lines changed

2 files changed

+192
-41
lines changed

packages/dialog/src/Dialog.ts

Lines changed: 70 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ governing permissions and limitations under the License.
1313
import {
1414
CSSResultArray,
1515
html,
16+
nothing,
1617
PropertyValues,
1718
SpectrumElement,
1819
TemplateResult,
@@ -118,57 +119,86 @@ export class Dialog extends FocusVisiblePolyfillMixin(
118119
);
119120
}
120121

122+
protected renderHero(): TemplateResult {
123+
return html`
124+
<slot name="hero"></slot>
125+
`;
126+
}
127+
128+
protected renderHeading(): TemplateResult {
129+
return html`
130+
<slot
131+
name="heading"
132+
class=${ifDefined(this.hasHero ? this.hasHero : undefined)}
133+
@slotchange=${this.onHeadingSlotchange}
134+
></slot>
135+
`;
136+
}
137+
138+
protected renderContent(): TemplateResult {
139+
return html`
140+
<div class="content">
141+
<slot @slotchange=${this.onContentSlotChange}></slot>
142+
</div>
143+
`;
144+
}
145+
146+
protected renderFooter(): TemplateResult {
147+
if (!this.hasFooter) return html``;
148+
return html`
149+
<div class="footer">
150+
<slot name="footer"></slot>
151+
</div>
152+
`;
153+
}
154+
155+
protected renderButtons(): TemplateResult {
156+
if (!this.hasButtons) return html``;
157+
return html`
158+
<sp-button-group
159+
class="button-group ${this.hasFooter
160+
? nothing
161+
: 'button-group--noFooter'}"
162+
>
163+
<slot name="button"></slot>
164+
</sp-button-group>
165+
`;
166+
}
167+
168+
protected renderDismiss(): TemplateResult {
169+
if (!this.dismissable) return html``;
170+
return html`
171+
<sp-action-button
172+
class="close-button"
173+
label="Close"
174+
quiet
175+
size="m"
176+
@click=${this.close}
177+
>
178+
<sp-icon-cross500
179+
class="spectrum-UIIcon-Cross500"
180+
slot="icon"
181+
></sp-icon-cross500>
182+
</sp-action-button>
183+
`;
184+
}
185+
121186
protected override render(): TemplateResult {
122187
return html`
123188
<div class="grid">
124-
<slot name="hero"></slot>
125-
<slot
126-
name="heading"
127-
class=${ifDefined(this.hasHero ? this.hasHero : undefined)}
128-
@slotchange=${this.onHeadingSlotchange}
129-
></slot>
189+
${this.renderHero()} ${this.renderHeading()}
130190
${this.error
131191
? html`
132192
<sp-icon-alert class="type-icon"></sp-icon-alert>
133193
`
134-
: html``}
194+
: nothing}
135195
${this.noDivider
136-
? html``
196+
? nothing
137197
: html`
138198
<sp-divider size="m" class="divider"></sp-divider>
139199
`}
140-
<div class="content">
141-
<slot @slotchange=${this.onContentSlotChange}></slot>
142-
</div>
143-
${this.hasFooter
144-
? html`
145-
<div class="footer">
146-
<slot name="footer"></slot>
147-
</div>
148-
`
149-
: html``}
150-
${this.hasButtons
151-
? html`
152-
<sp-button-group
153-
class="button-group ${this.hasFooter
154-
? ''
155-
: 'button-group--noFooter'}"
156-
>
157-
<slot name="button"></slot>
158-
</sp-button-group>
159-
`
160-
: html``}
161-
${this.dismissable
162-
? html`
163-
<sp-close-button
164-
class="close-button"
165-
label="Close"
166-
quiet
167-
size="m"
168-
@click=${this.close}
169-
></sp-close-button>
170-
`
171-
: html``}
200+
${this.renderContent()} ${this.renderFooter()}
201+
${this.renderButtons()} ${this.renderDismiss()}
172202
</div>
173203
`;
174204
}

packages/dialog/test/dialog.test.ts

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag
1010
governing permissions and limitations under the License.
1111
*/
1212

13-
import { elementUpdated, expect, fixture } from '@open-wc/testing';
13+
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
14+
import { TemplateResult } from '@spectrum-web-components/base';
1415

1516
import '@spectrum-web-components/dialog/sp-dialog.js';
1617
import { Dialog } from '@spectrum-web-components/dialog';
@@ -77,4 +78,124 @@ describe('Dialog', () => {
7778
await elementUpdated(el);
7879
expect(closeSpy.calledOnce).to.be.true;
7980
});
81+
it('allows hero override', async () => {
82+
class Override extends Dialog {
83+
renderHero(): TemplateResult {
84+
return html`
85+
<div id="hero-container"></div>
86+
`;
87+
}
88+
}
89+
90+
customElements.define('hero-dialog', Override);
91+
92+
const el = await fixture<Override>(
93+
html`
94+
<hero-dialog></hero-dialog>
95+
`
96+
);
97+
98+
const container = el.shadowRoot.querySelector('#hero-container');
99+
expect(container).to.not.be.null;
100+
});
101+
it('allows heading override', async () => {
102+
class Override extends Dialog {
103+
renderHeading(): TemplateResult {
104+
return html`
105+
<h2 id="heading-container">Test</h2>
106+
`;
107+
}
108+
}
109+
110+
customElements.define('heading-dialog', Override);
111+
112+
const el = await fixture<Override>(
113+
html`
114+
<heading-dialog></heading-dialog>
115+
`
116+
);
117+
118+
const container = el.shadowRoot.querySelector('#heading-container');
119+
expect(container).to.not.be.null;
120+
});
121+
it('allows content override', async () => {
122+
class Override extends Dialog {
123+
renderContent(): TemplateResult {
124+
return html`
125+
<p id="content-container">Test</p>
126+
`;
127+
}
128+
}
129+
130+
customElements.define('content-dialog', Override);
131+
132+
const el = await fixture<Override>(
133+
html`
134+
<content-dialog></content-dialog>
135+
`
136+
);
137+
138+
const container = el.shadowRoot.querySelector('#content-container');
139+
expect(container).to.not.be.null;
140+
});
141+
it('allows footer override', async () => {
142+
class Override extends Dialog {
143+
renderFooter(): TemplateResult {
144+
return html`
145+
<p id="footer-container">Test</p>
146+
`;
147+
}
148+
}
149+
150+
customElements.define('footer-dialog', Override);
151+
152+
const el = await fixture<Override>(
153+
html`
154+
<footer-dialog></footer-dialog>
155+
`
156+
);
157+
158+
const container = el.shadowRoot.querySelector('#footer-container');
159+
expect(container).to.not.be.null;
160+
});
161+
it('allows button override', async () => {
162+
class Override extends Dialog {
163+
renderButtons(): TemplateResult {
164+
return html`
165+
<p id="button-container">Test</p>
166+
`;
167+
}
168+
}
169+
170+
customElements.define('button-dialog', Override);
171+
172+
const el = await fixture<Override>(
173+
html`
174+
<button-dialog></button-dialog>
175+
`
176+
);
177+
178+
const container = el.shadowRoot.querySelector('#button-container');
179+
expect(container).to.not.be.null;
180+
});
181+
it('allows dismiss override', async () => {
182+
class Override extends Dialog {
183+
renderDismiss(): TemplateResult {
184+
return html`
185+
<p id="dismiss-container">Test</p>
186+
`;
187+
}
188+
}
189+
190+
customElements.define('dismiss-dialog', Override);
191+
192+
const el = await fixture<Override>(
193+
html`
194+
<dismiss-dialog></dismiss-dialog>
195+
`
196+
);
197+
198+
const container = el.shadowRoot.querySelector('#dismiss-container');
199+
expect(container).to.not.be.null;
200+
});
80201
});

0 commit comments

Comments
 (0)