Skip to content

Commit

Permalink
Issue #10: WIP: Committing sample tab components (and some custom ele…
Browse files Browse the repository at this point in the history
…ment tag definitions) to facilitate testing of context.
  • Loading branch information
patricknelson committed Sep 28, 2023
1 parent 10c7c03 commit adaefd7
Show file tree
Hide file tree
Showing 9 changed files with 336 additions and 0 deletions.
48 changes: 48 additions & 0 deletions demo/src/lib/TabsDemo.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script>
import { TabsWrapper, TabList, TabPanel, TabButton } from './tabs';
</script>

<TabsWrapper>
<TabList>
<TabButton>one</TabButton>
<TabButton>two</TabButton>
<TabButton>three</TabButton>
</TabList>

<TabPanel>
<TabsWrapper>
<TabList>
<TabButton>nested one</TabButton>
<TabButton>nested two</TabButton>
<TabButton>nested three</TabButton>
</TabList>

<TabPanel>
<h2>First nested panel</h2>
</TabPanel>

<TabPanel>
<h2>Second nested panel</h2>
</TabPanel>

<TabPanel>
<h2>Third nested panel</h2>
</TabPanel>
</TabsWrapper>
</TabPanel>

<TabPanel>
<h2>Second panel</h2>
</TabPanel>

<TabPanel>
<h2>Third panel</h2>
</TabPanel>
</TabsWrapper>


<style>
:global(body > *) {
width: 600px;
}
</style>
29 changes: 29 additions & 0 deletions demo/src/lib/tabs/TabButton.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script>
import { getContext } from 'svelte';
import { TABS } from './TabsWrapper.svelte';
const tab = {};
const { registerTab, selectTab, selectedTab } = getContext(TABS);
registerTab(tab);
</script>

<style>
button {
background: none;
border: none;
border-bottom: 2px solid white;
border-radius: 0;
margin: 0;
color: #ccc;
}
.selected {
border-bottom: 2px solid teal;
color: #333;
}
</style>

<button class:selected="{$selectedTab === tab}" on:click="{() => selectTab(tab)}">
<slot></slot>
</button>
9 changes: 9 additions & 0 deletions demo/src/lib/tabs/TabList.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div class="tab-list">
<slot></slot>
</div>

<style>
.tab-list {
border-bottom: 1px solid teal;
}
</style>
26 changes: 26 additions & 0 deletions demo/src/lib/tabs/TabPanel.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script>
import { getContext } from 'svelte';
import { TABS } from './TabsWrapper.svelte';
const panel = {};
const testContext = getContext(TABS);
const { registerPanel, selectedPanel } = testContext;
registerPanel(panel);
$: active = ($selectedPanel === panel);
</script>

<div class:active>
<slot/>
</div>


<style>
div {
display: none;
}
div.active{
display: block;
}
</style>
50 changes: 50 additions & 0 deletions demo/src/lib/tabs/TabsWrapper.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<script context="module">
export const TABS = {};
</script>

<script>
import { setContext, onDestroy } from 'svelte';
import { writable } from 'svelte/store';
const tabs = [];
const panels = [];
const selectedTab = writable(null);
const selectedPanel = writable(null);
setContext(TABS, {
registerTab: tab => {
tabs.push(tab);
selectedTab.update(current => current || tab);
onDestroy(() => {
const i = tabs.indexOf(tab);
tabs.splice(i, 1);
selectedTab.update(current => current === tab ? (tabs[i] || tabs[tabs.length - 1]) : current);
});
},
registerPanel: panel => {
panels.push(panel);
selectedPanel.update(current => current || panel);
onDestroy(() => {
const i = panels.indexOf(panel);
panels.splice(i, 1);
selectedPanel.update(current => current === panel ? (panels[i] || panels[panels.length - 1]) : current);
});
},
selectTab: tab => {
const i = tabs.indexOf(tab);
selectedTab.set(tab);
selectedPanel.set(panels[i]);
},
selectedTab,
selectedPanel
});
</script>

<div class="tabs">
<slot></slot>
</div>
4 changes: 4 additions & 0 deletions demo/src/lib/tabs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default as TabsWrapper } from './TabsWrapper.svelte';
export { default as TabList } from './TabList.svelte';
export { default as TabPanel } from './TabPanel.svelte';
export { default as TabButton } from './TabButton.svelte';
45 changes: 45 additions & 0 deletions demo/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,74 @@ import Counter from './lib/Counter.svelte';
import Example from './lib/Example.svelte';

const params = new URLSearchParams(location.search);
const debugMode = false;
const hydratable = !!params.get('hydratable');

svelteRetag({
component: App,
tagname: 'app-tag',
attributes: ['pagetitle'],
debugMode,
hydratable,
});

svelteRetag({
component: Intro,
tagname: 'intro-tag',
debugMode,
hydratable,
});

svelteRetag({
component: Counter,
tagname: 'counter-tag',
debugMode,
hydratable,
});

svelteRetag({
component: Example,
tagname: 'example-tag',
debugMode,
hydratable,
});


/**
* TabsWrapper.svelte for testing context
*
* TODO: ISSUE-10: WIP
*/

import TabsDemo from './lib/TabsDemo.svelte';
import { TabsWrapper, TabList, TabPanel, TabButton } from './lib/tabs';

svelteRetag({
component: TabsDemo,
tagname: 'tabs-demo',
debugMode,
});

svelteRetag({
component: TabsWrapper,
tagname: 'tabs-wrapper',
debugMode,
});

svelteRetag({
component: TabList,
tagname: 'tab-list',
debugMode,
});

svelteRetag({
component: TabPanel,
tagname: 'tab-panel',
debugMode,
});

svelteRetag({
component: TabButton,
tagname: 'tab-button',
debugMode,
});
124 changes: 124 additions & 0 deletions demo/tabs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<link rel="icon" type="image/svg+xml" href="/svelte-retag-favicon.svg"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>svelte-retag demo (tabs demo)</title>
<script type="module" src="src/main.js"></script>
</head>
<body>

<div id="app">
<h1>Tabs demo</h1>
<!-- TODO: Write up explanation of what is happening below. -->
<p>Thanks to
<a href="https://stackoverflow.com/users/1990514/amir-pournasserian" target="_blank" rel="noopener">AmirPournasserian</a>
from
<a href="https://stackoverflow.com/questions/75024281/how-to-avoid-overwriting-context-in-nested-components-like-tabs-in-svelte" target="_blank" rel="noopener">
this StackOverflow post</a> for the tab components which rely on this context.</p>

<!-- TODO: All contents below are a WIP during debugging -->

<tabs-demo></tabs-demo>


<!-- Simple -->
<!--<tabs-wrapper>
<tab-list>
<tab-button>one</tab-button>
<tab-button>two</tab-button>
<tab-button>three</tab-button>
</tab-list>
<tab-panel>
<h2>First panel</h2>
</tab-panel>
<tab-panel>
<h2>Second panel</h2>
</tab-panel>
<tab-panel>
<h2>Third panel</h2>
</tab-panel>
</tabs-wrapper>-->

<!-- Simple nested: Top level context -->
<!--<tabs-wrapper>
<tab-list>
<tab-button>one</tab-button>
<tab-button>two</tab-button>
</tab-list>
<tab-panel>
<h2>First panel</h2>
<tabs-wrapper>
<tab-list>
<tab-button>Nested one</tab-button>
<tab-button>Nested two</tab-button>
</tab-list>
<tab-panel>
<h2>Nested first panel</h2>
</tab-panel>
<tab-panel>
<h2>Nested second panel</h2>
</tab-panel>
</tabs-wrapper>
</tab-panel>
<tab-panel>
<h2>Second panel</h2>
</tab-panel>
</tabs-wrapper>-->


<!-- Complex nested: Top level context -->
<!--<tabs-wrapper>
<tab-list>
<tab-button>one</tab-button>
<tab-button>two</tab-button>
<tab-button>three</tab-button>
</tab-list>
<tab-panel>
fails when nesting
&lt;!&ndash; Has nested context &ndash;&gt;
<tabs-wrapper>
<tab-list>
<tab-button>nested one</tab-button>
<tab-button>nested two</tab-button>
</tab-list>
<tab-panel>
<h2>First nested panel</h2>
</tab-panel>
<tab-panel>
<h2>Second nested panel</h2>
</tab-panel>
</tabs-wrapper>
</tab-panel>
<tab-panel>
<h2>Second panel</h2>
</tab-panel>
<tab-panel>
<h2>Third panel</h2>
</tab-panel>
</tabs-wrapper>-->


</div>
</body>
</html>
1 change: 1 addition & 0 deletions demo/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default defineConfig({
'index.html',
'hydratable.html',
'hydratable.source.html', // Used for generating content in hydratable.html above.
'tabs.html',
],

output: {
Expand Down

0 comments on commit adaefd7

Please sign in to comment.