Skip to content

Commit 692046d

Browse files
committed
Fix panels and tabs behaviour
1 parent d5d168d commit 692046d

File tree

5 files changed

+190
-248
lines changed

5 files changed

+190
-248
lines changed

docs/pages/components/panel.md

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,84 @@ around been displayed in a panel.
5555
</zn-panel>
5656
```
5757

58-
### Second Example
58+
### Flush with Tabs
5959

60-
TODO
60+
`flush` panels are designed to be used in a layout where the content of the panel needs to take up the entire width of
61+
the
62+
panel. This can be useful when using other components such as `zn-tabs`.
63+
64+
```html:preview
65+
66+
<zn-panel caption="Example Panel" flush tabbed>
67+
68+
<!-- All the panel actions -->
69+
<zn-chip slot="actions" icon="home">Awesome</zn-chip>
70+
<zn-chip slot="actions" icon="phone" type="info">example</zn-chip>
71+
72+
<!-- Example panel content -->
73+
<zn-tabs flush>
74+
<zn-navbar slot="top">
75+
<li tab>Customer</li>
76+
<li tab="something-else">Something Else</li>
77+
</zn-navbar>
78+
79+
<zn-sp id="" divide>
80+
<zn-description-item style="background: var(--zn-color-red-100);" label="Label 1">This is awesome
81+
</zn-description-item>
82+
<zn-description-item style="background: var(--zn-color-red-100);" label="Label 2">This is awesome
83+
</zn-description-item>
84+
</zn-sp>
85+
86+
<zn-sp id="something-else" divide>
87+
<zn-description-item style="background: var(--zn-color-red-100);" label="Label 3">This is not awesome
88+
</zn-description-item>
89+
<zn-description-item style="background: var(--zn-color-red-100);" label="Label 4">This is not awesome
90+
</zn-description-item>
91+
</zn-sp>
92+
</zn-tabs>
93+
94+
<!-- Panel Footer -->
95+
<span slot="footer">
96+
Some awesome footer information
97+
</span>
98+
</zn-panel>
99+
```
100+
101+
[component-metadata:zn-panel]
102+
103+
### Moving the caption
104+
105+
```html:preview
106+
107+
<zn-panel flush>
108+
109+
<!-- Example panel content -->
110+
<zn-tabs caption="Example Panel">
111+
<zn-navbar slot="top">
112+
<li tab>Customer</li>
113+
<li tab="something-else">Something Else</li>
114+
</zn-navbar>
115+
116+
<zn-sp id="" divide>
117+
<zn-description-item style="background: var(--zn-color-red-100);" label="Label 1">This is awesome
118+
</zn-description-item>
119+
<zn-description-item style="background: var(--zn-color-red-100);" label="Label 2">This is awesome
120+
</zn-description-item>
121+
</zn-sp>
122+
123+
<zn-sp id="something-else" divide>
124+
<zn-description-item style="background: var(--zn-color-red-100);" label="Label 3">This is not awesome
125+
</zn-description-item>
126+
<zn-description-item style="background: var(--zn-color-red-100);" label="Label 4">This is not awesome
127+
</zn-description-item>
128+
</zn-sp>
129+
</zn-tabs>
130+
131+
<!-- Panel Footer -->
132+
<span slot="footer">
133+
Some awesome footer information
134+
</span>
135+
</zn-panel>
136+
```
61137

62138
[component-metadata:zn-panel]

src/components/navbar/navbar.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
}
1010

1111
ul {
12-
padding-top: var(--zn-navbar-padding-top);
1312
padding-left: var(--zn-navbar-padding-left);
1413
padding-right: var(--zn-navbar-padding-right);
1514
}
@@ -125,7 +124,7 @@ ul {
125124

126125
user-select: none;
127126
font-weight: 500;
128-
padding: 10px 0;
127+
padding-bottom: 10px;
129128
position: relative;
130129

131130
display: flex;

src/components/panel/panel.component.ts

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,17 @@ import ZincElement from '../../internal/zinc-element';
44

55
import styles from './panel.scss';
66
import {classMap} from "lit/directives/class-map.js";
7+
import {HasSlotController} from "../../internal/slot";
78

89
/**
910
* @summary Short summary of the component's intended use.
1011
* @documentation https://zinc.style/components/panel
1112
* @status experimental
1213
* @since 1.0
1314
*
14-
* @dependency zn-example
15-
*
16-
* @event zn-event-name - Emitted as an example.
17-
*
1815
* @slot - The default slot.
19-
* @slot example - An example slot.
16+
* @slot actions - The actions slot.
17+
* @slot footer - The footer slot.
2018
*
2119
* @csspart base - The component's base wrapper.
2220
*
@@ -25,17 +23,26 @@ import {classMap} from "lit/directives/class-map.js";
2523
export default class ZnPanel extends ZincElement {
2624
static styles: CSSResultGroup = unsafeCSS(styles);
2725

28-
@property({attribute: 'basis-px', type: Number, reflect: true}) basis: number;
29-
@property({attribute: 'caption', type: String, reflect: true}) caption: string;
30-
@property({attribute: 'rows', type: Number, reflect: true}) rows: number;
31-
@property({attribute: 'tabbed', type: Boolean, reflect: true}) tabbed: boolean;
26+
private readonly hasSlotController = new HasSlotController(this, '[default]', 'actions', 'footer');
27+
28+
@property({type: Number}) basis: number;
29+
30+
@property() caption: string;
31+
32+
@property({type: Boolean}) tabbed: boolean;
33+
3234
@property({type: Boolean}) flush: boolean;
3335

3436

3537
protected firstUpdated(_changedProperties: PropertyValues) {
3638
super.firstUpdated(_changedProperties);
39+
40+
if (this.basis) {
41+
this.style.setProperty('--zn-panel-basis', this.basis.toString());
42+
}
43+
3744
if (!this.tabbed) {
38-
const tabs = this.querySelector('zn-tabs');
45+
const tabs = this.querySelector('zn-tabs')!;
3946
if (tabs) {
4047
tabs.setAttribute('flush-x', '');
4148
const body = this.shadowRoot?.querySelector('.body');
@@ -46,48 +53,37 @@ export default class ZnPanel extends ZincElement {
4653
}
4754
}
4855

49-
protected render(): unknown {
50-
if (this.basis > 0) {
51-
this.style.flexBasis = this.basis + 'px';
52-
}
53-
54-
const footerItems = this.querySelectorAll('[slot="footer"]').length > 0;
55-
const actionItems = this.querySelectorAll('[slot="actions"]').length > 0;
56-
57-
if (this.rows > 0) {
58-
this.style.setProperty('--row-count', this.rows.toString());
59-
}
60-
61-
let header;
62-
if (actionItems || this.caption || this.firstChild?.nodeName == 'ZN-TABS') {
63-
// zn-tabs uses the header as top-padding
64-
header = html`
65-
<div class="header">
66-
<span>${this.caption}</span>
67-
<slot name="actions" class="header__actions"></slot>
68-
</div>
69-
`;
70-
}
7156

72-
let footer;
73-
if (footerItems) {
74-
footer = html`
75-
<div class="footer">
76-
<slot name="footer"></slot>
77-
</div>`;
78-
}
57+
protected render(): unknown {
58+
const hasActionSlot = this.hasSlotController.test('actions');
59+
const hasFooterSlot = this.hasSlotController.test('footer');
60+
const hasHeader = this.caption || hasActionSlot;
7961

8062
return html`
81-
<div class=${classMap({
63+
<div part="base" class=${classMap({
8264
panel: true,
83-
'panel--flush': this.flush || this.tabbed
65+
'panel--flush': this.flush || this.tabbed,
66+
'panel--tabbed': this.tabbed,
67+
'panel--has-actions': hasActionSlot,
68+
'panel--has-footer': hasFooterSlot,
69+
'panel--has-header': hasHeader,
8470
})}>
85-
<div>${header}
86-
<div class="panel__body body">
87-
<slot></slot>
71+
72+
${hasHeader ? html`
73+
<div class="panel__header">
74+
<span class="panel__caption">${this.caption}</span>
75+
${hasActionSlot ? html`
76+
<slot name="actions" class="panel__header__actions"></slot>
77+
` : null}
8878
</div>
89-
${footer}
79+
` : null}
80+
81+
<div class="panel__body">
82+
<slot></slot>
9083
</div>
84+
85+
${hasFooterSlot ? html`
86+
<slot name="footer" class="panel__footer"></slot>` : null}
9187
</div>`;
9288
}
9389
}

0 commit comments

Comments
 (0)