mirror of https://github.com/sveltejs/svelte
parent
2d1475600d
commit
9cfe0593d4
@ -0,0 +1,17 @@
|
||||
<script>
|
||||
import { getContext, onDestroy } from 'svelte';
|
||||
import { TABS } from './Tabs.html';
|
||||
|
||||
const tab = {};
|
||||
const { registerTab, unregisterTab, selectTab, selectedTab } = getContext(TABS);
|
||||
|
||||
registerTab(tab);
|
||||
|
||||
onDestroy(() => {
|
||||
unregisterTab(tab);
|
||||
});
|
||||
</script>
|
||||
|
||||
<button class:selected={$selectedTab} on:click="{() => selectTab(tab)}">
|
||||
<slot></slot>
|
||||
</button>
|
@ -0,0 +1,3 @@
|
||||
<div class="tab-list">
|
||||
<slot></slot>
|
||||
</div>
|
@ -0,0 +1,16 @@
|
||||
<script>
|
||||
import { getContext, onDestroy } from 'svelte';
|
||||
import { TABS } from './Tabs.html';
|
||||
|
||||
const panel = {};
|
||||
const { registerPanel, unregisterPanel, selectedPanel } = getContext(TABS);
|
||||
registerPanel(panel);
|
||||
|
||||
onDestroy(() => {
|
||||
unregisterPanel(panel);
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if $selected === panel}
|
||||
<slot></slot>
|
||||
{/if}
|
@ -0,0 +1,48 @@
|
||||
|
||||
|
||||
<script context="module">
|
||||
export const TABS = {};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { setContext } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
const tabs = [];
|
||||
const panels = [];
|
||||
const selected = writable(null);
|
||||
|
||||
setContext(TABS, {
|
||||
registerTab: tab => {
|
||||
tabs.push(tab);
|
||||
},
|
||||
|
||||
unregisterTab: tab => {
|
||||
const i = tabs.indexOf(tab);
|
||||
tabs.splice(i, 1);
|
||||
},
|
||||
|
||||
registerPanel: panel => {
|
||||
panels.push(panel);
|
||||
|
||||
// if this is the first panel, select it
|
||||
selected.update(current => current || panel);
|
||||
},
|
||||
|
||||
unregisterPanel: panel => {
|
||||
const i = panels.indexOf(panel);
|
||||
panels.splice(i, 1);
|
||||
},
|
||||
|
||||
selectTab: tab => {
|
||||
const i = tabs.indexOf(tab);
|
||||
selected.set(panels[i]);
|
||||
},
|
||||
|
||||
selected
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="tabs">
|
||||
<slot></slot>
|
||||
</div>
|
@ -0,0 +1,73 @@
|
||||
export default {
|
||||
html: `
|
||||
<div class="tabs">
|
||||
<div class="tab-list">
|
||||
<button class="selected">small</button>
|
||||
<button>large</button>
|
||||
</div>
|
||||
|
||||
<h2>Small panel</h2>
|
||||
</div>
|
||||
`,
|
||||
|
||||
async test({ assert, component, target, window }) {
|
||||
const click = new window.MouseEvent('click');
|
||||
let buttons = target.querySelectorAll('button');
|
||||
|
||||
await buttons[1].dispatchEvent(click);
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div class="tabs">
|
||||
<div class="tab-list">
|
||||
<button>small</button>
|
||||
<button class="selected">large</button>
|
||||
</div>
|
||||
|
||||
<h2>Large panel</h2>
|
||||
</div>
|
||||
`);
|
||||
|
||||
component.show_medium = true;
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div class="tabs">
|
||||
<div class="tab-list">
|
||||
<button>small</button>
|
||||
<button>medium</button>
|
||||
<button class="selected">large</button>
|
||||
</div>
|
||||
|
||||
<h2>Large panel</h2>
|
||||
</div>
|
||||
`);
|
||||
|
||||
buttons = target.querySelectorAll('button');
|
||||
|
||||
await buttons[1].dispatchEvent(click);
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div class="tabs">
|
||||
<div class="tab-list">
|
||||
<button>small</button>
|
||||
<button class="selected">medium</button>
|
||||
<button>large</button>
|
||||
</div>
|
||||
|
||||
<h2>Medium panel</h2>
|
||||
</div>
|
||||
`);
|
||||
|
||||
component.show_medium = false;
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div class="tabs">
|
||||
<div class="tab-list">
|
||||
<button>small</button>
|
||||
<button class="selected">large</button>
|
||||
</div>
|
||||
|
||||
<h2>Large panel</h2>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
<script>
|
||||
import Tabs from './Tabs.html';
|
||||
import TabList from './TabList.html';
|
||||
import Tab from './Tab.html';
|
||||
import TabPanel from './TabPanel.html';
|
||||
|
||||
export let show_medium = false;
|
||||
</script>
|
||||
|
||||
<Tabs>
|
||||
<TabList>
|
||||
<Tab>small</Tab>
|
||||
{#if show_medium}<Tab>medium</Tab>{/if}
|
||||
<Tab>large</Tab>
|
||||
</TabList>
|
||||
|
||||
<TabPanel>
|
||||
<h2>Small panel</h2>
|
||||
</TabPanel>
|
||||
|
||||
{#if show_medium}
|
||||
<TabPanel>
|
||||
<h2>Medium panel</h2>
|
||||
</TabPanel>
|
||||
{/if}
|
||||
|
||||
<TabPanel>
|
||||
<h2>Large panel</h2>
|
||||
</TabPanel>
|
||||
</Tabs>
|
Loading…
Reference in new issue