Merge pull request #247 from shoelace-style/autoslot

automatically slot tab into tab group; fixes #239
This commit is contained in:
Cory LaViska
2024-11-22 12:29:06 -05:00
committed by GitHub
8 changed files with 88 additions and 86 deletions

View File

@@ -266,9 +266,9 @@
</p>
<wa-tab-group label="How would you like to import this component?">
<wa-tab slot="nav" panel="cdn">CDN</wa-tab>
<wa-tab slot="nav" panel="npm">npm</wa-tab>
<wa-tab slot="nav" panel="react">React</wa-tab>
<wa-tab panel="cdn">CDN</wa-tab>
<wa-tab panel="npm">npm</wa-tab>
<wa-tab panel="react">React</wa-tab>
<wa-tab-panel name="cdn">
<p>
To manually import this component from the CDN, use the following code.

View File

@@ -4,14 +4,14 @@ description: Tab groups organize content into a container that shows one section
layout: component
---
Tab groups make use of [tabs](/docs/components/tab) and [tab panels](/docs/components/tab-panel). Each tab must be slotted into the `nav` slot and its `panel` must refer to a tab panel of the same name.
Tab groups make use of [tabs](/docs/components/tab) and [tab panels](/docs/components/tab-panel). Each panel should have a name that's unique within the tab group, and tabs should have a `panel` attribute that points to the respective panel's name.
```html {.example}
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab slot="nav" panel="advanced">Advanced</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled>Disabled</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>
@@ -28,9 +28,9 @@ To make a tab active, set the `active` attribute to the name of the appropriate
```html {.example}
<wa-tab-group active="advanced">
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab slot="nav" panel="advanced">Advanced</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>
@@ -44,10 +44,10 @@ Tabs can be shown on the bottom by setting `placement` to `bottom`.
```html {.example}
<wa-tab-group placement="bottom">
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab slot="nav" panel="advanced">Advanced</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled>Disabled</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>
@@ -62,10 +62,10 @@ Tabs can be shown on the starting side by setting `placement` to `start`.
```html {.example}
<wa-tab-group placement="start">
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab slot="nav" panel="advanced">Advanced</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled>Disabled</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>
@@ -80,10 +80,10 @@ Tabs can be shown on the ending side by setting `placement` to `end`.
```html {.example}
<wa-tab-group placement="end">
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab slot="nav" panel="advanced">Advanced</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled>Disabled</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>
@@ -98,10 +98,10 @@ You can make a tab closable by adding a close button next to the tab and inside
```html {.example}
<wa-tab-group class="tabs-closable">
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="closable">Closable</wa-tab>
<wa-icon-button slot="nav" tabindex="-1" name="xmark" label="Close the closable tab"></wa-icon-button>
<wa-tab slot="nav" panel="closable-2">Advanced</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="closable">Closable</wa-tab>
<wa-icon-button tabindex="-1" name="xmark" label="Close the closable tab"></wa-icon-button>
<wa-tab panel="closable-2">Advanced</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="closable">This is the closable tab panel.</wa-tab-panel>
@@ -148,26 +148,26 @@ When there are more tabs than horizontal space allows, the nav will be scrollabl
```html {.example}
<wa-tab-group>
<wa-tab slot="nav" panel="tab-1">Tab 1</wa-tab>
<wa-tab slot="nav" panel="tab-2">Tab 2</wa-tab>
<wa-tab slot="nav" panel="tab-3">Tab 3</wa-tab>
<wa-tab slot="nav" panel="tab-4">Tab 4</wa-tab>
<wa-tab slot="nav" panel="tab-5">Tab 5</wa-tab>
<wa-tab slot="nav" panel="tab-6">Tab 6</wa-tab>
<wa-tab slot="nav" panel="tab-7">Tab 7</wa-tab>
<wa-tab slot="nav" panel="tab-8">Tab 8</wa-tab>
<wa-tab slot="nav" panel="tab-9">Tab 9</wa-tab>
<wa-tab slot="nav" panel="tab-10">Tab 10</wa-tab>
<wa-tab slot="nav" panel="tab-11">Tab 11</wa-tab>
<wa-tab slot="nav" panel="tab-12">Tab 12</wa-tab>
<wa-tab slot="nav" panel="tab-13">Tab 13</wa-tab>
<wa-tab slot="nav" panel="tab-14">Tab 14</wa-tab>
<wa-tab slot="nav" panel="tab-15">Tab 15</wa-tab>
<wa-tab slot="nav" panel="tab-16">Tab 16</wa-tab>
<wa-tab slot="nav" panel="tab-17">Tab 17</wa-tab>
<wa-tab slot="nav" panel="tab-18">Tab 18</wa-tab>
<wa-tab slot="nav" panel="tab-19">Tab 19</wa-tab>
<wa-tab slot="nav" panel="tab-20">Tab 20</wa-tab>
<wa-tab panel="tab-1">Tab 1</wa-tab>
<wa-tab panel="tab-2">Tab 2</wa-tab>
<wa-tab panel="tab-3">Tab 3</wa-tab>
<wa-tab panel="tab-4">Tab 4</wa-tab>
<wa-tab panel="tab-5">Tab 5</wa-tab>
<wa-tab panel="tab-6">Tab 6</wa-tab>
<wa-tab panel="tab-7">Tab 7</wa-tab>
<wa-tab panel="tab-8">Tab 8</wa-tab>
<wa-tab panel="tab-9">Tab 9</wa-tab>
<wa-tab panel="tab-10">Tab 10</wa-tab>
<wa-tab panel="tab-11">Tab 11</wa-tab>
<wa-tab panel="tab-12">Tab 12</wa-tab>
<wa-tab panel="tab-13">Tab 13</wa-tab>
<wa-tab panel="tab-14">Tab 14</wa-tab>
<wa-tab panel="tab-15">Tab 15</wa-tab>
<wa-tab panel="tab-16">Tab 16</wa-tab>
<wa-tab panel="tab-17">Tab 17</wa-tab>
<wa-tab panel="tab-18">Tab 18</wa-tab>
<wa-tab panel="tab-19">Tab 19</wa-tab>
<wa-tab panel="tab-20">Tab 20</wa-tab>
<wa-tab-panel name="tab-1">Tab panel 1</wa-tab-panel>
<wa-tab-panel name="tab-2">Tab panel 2</wa-tab-panel>
@@ -198,10 +198,10 @@ When focused, keyboard users can press [[Left]] or [[Right]] to select the desir
```html {.example}
<wa-tab-group activation="manual">
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab slot="nav" panel="advanced">Advanced</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled>Disabled</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>

View File

@@ -6,10 +6,10 @@ layout: component
```html {.example}
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab slot="nav" panel="advanced">Advanced</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled>Disabled</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>

View File

@@ -440,10 +440,10 @@ TODO Page Description
<wa-icon family="brands" name="instagram"></wa-icon>
<wa-icon family="brands" name="x-twitter"></wa-icon>
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab slot="nav" panel="advanced">Advanced</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled>Disabled</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general">
<div></div>

View File

@@ -78,7 +78,7 @@ describe('<wa-tab-group>', () => {
it('renders', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
</wa-tab-group>
`);
@@ -89,7 +89,7 @@ describe('<wa-tab-group>', () => {
it('is accessible', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
</wa-tab-group>
`);
@@ -100,8 +100,8 @@ describe('<wa-tab-group>', () => {
it('displays all tabs', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general" data-testid="general-tab-header">General</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled data-testid="disabled-tab-header">Disabled</wa-tab>
<wa-tab panel="general" data-testid="general-tab-header">General</wa-tab>
<wa-tab panel="disabled" disabled data-testid="disabled-tab-header">Disabled</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="disabled">This is a disabled tab panel.</wa-tab-panel>
</wa-tab-group>
@@ -114,8 +114,8 @@ describe('<wa-tab-group>', () => {
it('shows the first tab to be active by default', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab-panel name="general" data-testid="general-tab-content">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>
</wa-tab-group>
@@ -128,7 +128,7 @@ describe('<wa-tab-group>', () => {
it('shows the header above the tabs by default', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
</wa-tab-group>
`);
@@ -142,7 +142,7 @@ describe('<wa-tab-group>', () => {
it('shows the header below the tabs by setting placement to bottom', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
</wa-tab-group>
`);
@@ -157,7 +157,7 @@ describe('<wa-tab-group>', () => {
it('shows the header left of the tabs by setting placement to start', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
</wa-tab-group>
`);
@@ -172,7 +172,7 @@ describe('<wa-tab-group>', () => {
it('shows the header right of the tabs by setting placement to end', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general">General</wa-tab>
<wa-tab panel="general">General</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
</wa-tab-group>
`);
@@ -190,7 +190,7 @@ describe('<wa-tab-group>', () => {
const result: HTMLTemplateResult[] = [];
for (let i = 0; i < n; i++) {
result.push(
html`<wa-tab slot="nav" panel="tab-${i}">Tab ${i}</wa-tab>
html`<wa-tab panel="tab-${i}">Tab ${i}</wa-tab>
<wa-tab-panel name="tab-${i}">Content of tab ${i}0</wa-tab-panel> `
);
}
@@ -350,8 +350,8 @@ describe('<wa-tab-group>', () => {
it('selects a tab by clicking on it', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general" data-testid="general-header">General</wa-tab>
<wa-tab slot="nav" panel="custom" data-testid="custom-header">Custom</wa-tab>
<wa-tab panel="general" data-testid="general-header">General</wa-tab>
<wa-tab panel="custom" data-testid="custom-header">Custom</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom" data-testid="custom-tab-content">This is the custom tab panel.</wa-tab-panel>
</wa-tab-group>
@@ -364,8 +364,8 @@ describe('<wa-tab-group>', () => {
it('does not change if the active tab is reselected', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general" data-testid="general-header">General</wa-tab>
<wa-tab slot="nav" panel="custom">Custom</wa-tab>
<wa-tab panel="general" data-testid="general-header">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab-panel name="general" data-testid="general-tab-content"
>This is the general tab panel.</wa-tab-panel
>
@@ -380,8 +380,8 @@ describe('<wa-tab-group>', () => {
it('does not change if a disabled tab is clicked', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general" data-testid="general-header">General</wa-tab>
<wa-tab slot="nav" panel="disabled" data-testid="disabled-header" disabled>disabled</wa-tab>
<wa-tab panel="general" data-testid="general-header">General</wa-tab>
<wa-tab panel="disabled" data-testid="disabled-header" disabled>disabled</wa-tab>
<wa-tab-panel name="general" data-testid="general-tab-content"
>This is the general tab panel.</wa-tab-panel
>
@@ -396,8 +396,8 @@ describe('<wa-tab-group>', () => {
it('selects a tab by using the arrow keys', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general" data-testid="general-header">General</wa-tab>
<wa-tab slot="nav" panel="custom" data-testid="custom-header">Custom</wa-tab>
<wa-tab panel="general" data-testid="general-header">General</wa-tab>
<wa-tab panel="custom" data-testid="custom-header">Custom</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom" data-testid="custom-tab-content">This is the custom tab panel.</wa-tab-panel>
</wa-tab-group>
@@ -409,8 +409,8 @@ describe('<wa-tab-group>', () => {
it('selects a tab by using the arrow keys and enter if activation is set to manual', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general" data-testid="general-header">General</wa-tab>
<wa-tab slot="nav" panel="custom" data-testid="custom-header">Custom</wa-tab>
<wa-tab panel="general" data-testid="general-header">General</wa-tab>
<wa-tab panel="custom" data-testid="custom-header">Custom</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom" data-testid="custom-tab-content">This is the custom tab panel.</wa-tab-panel>
</wa-tab-group>
@@ -438,8 +438,8 @@ describe('<wa-tab-group>', () => {
it('does not allow selection of disabled tabs with arrow keys', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general" data-testid="general-header">General</wa-tab>
<wa-tab slot="nav" panel="disabled" disabled>Disabled</wa-tab>
<wa-tab panel="general" data-testid="general-header">General</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general" data-testid="general-tab-content"
>This is the general tab panel.</wa-tab-panel
>
@@ -453,8 +453,8 @@ describe('<wa-tab-group>', () => {
it('selects a tab by using the show function', async () => {
const tabGroup = await fixture<WaTabGroup>(html`
<wa-tab-group>
<wa-tab slot="nav" panel="general" data-testid="general-header">General</wa-tab>
<wa-tab slot="nav" panel="custom" data-testid="custom-header">Custom</wa-tab>
<wa-tab panel="general" data-testid="general-header">General</wa-tab>
<wa-tab panel="custom" data-testid="custom-header">Custom</wa-tab>
<wa-tab-panel name="general">This is the general tab panel.</wa-tab-panel>
<wa-tab-panel name="custom" data-testid="custom-tab-content">This is the custom tab panel.</wa-tab-panel>
</wa-tab-group>

View File

@@ -27,7 +27,8 @@ import type WaTabPanel from '../tab-panel/tab-panel.js';
* @dependency wa-tab-panel
*
* @slot - Used for grouping tab panels in the tab group. Must be `<wa-tab-panel>` elements.
* @slot nav - Used for grouping tabs in the tab group. Must be `<wa-tab>` elements.
* @slot nav - Used for grouping tabs in the tab group. Must be `<wa-tab>` elements. Note that `<wa-tab>` will set this
* slot on itself automatically.
*
* @event {{ name: String }} wa-tab-show - Emitted when a tab is shown.
* @event {{ name: String }} wa-tab-hide - Emitted when a tab is hidden.

View File

@@ -9,7 +9,7 @@ describe('<wa-tab>', () => {
it('passes accessibility test', async () => {
const el = await fixture<WaTab>(html`
<wa-tab-group>
<wa-tab slot="nav">Test</wa-tab>
<wa-tab>Test</wa-tab>
</wa-tab-group>
`);
await expect(el).to.be.accessible();

View File

@@ -26,6 +26,7 @@ let id = 0;
@customElement('wa-tab')
export default class WaTab extends WebAwesomeElement {
static styles: CSSResultGroup = [componentStyles, styles];
public slot = 'nav'; // Auto-slot into nav slot
private readonly attrId = ++id;
private readonly componentId = `wa-tab-${this.attrId}`;