From 89b7403eaf6382485b440b50ea01c10307c53cca Mon Sep 17 00:00:00 2001 From: Patrick Nelson Date: Wed, 27 Sep 2023 20:31:48 -0700 Subject: [PATCH] Issue #10: WIP: Working on setting context and nested context --- demo/src/lib/TabsDemo.svelte | 48 +++++++++++++++++ demo/src/lib/tabs/TabButton.svelte | 29 +++++++++++ demo/src/lib/tabs/TabList.svelte | 9 ++++ demo/src/lib/tabs/TabPanel.svelte | 27 ++++++++++ demo/src/lib/tabs/TabsWrapper.svelte | 50 ++++++++++++++++++ demo/src/lib/tabs/index.js | 4 ++ demo/src/main.js | 35 +++++++++++++ demo/tabs.html | 77 ++++++++++++++++++++++++++++ demo/vite.config.js | 1 + index.js | 33 +++++++++++- 10 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 demo/src/lib/TabsDemo.svelte create mode 100644 demo/src/lib/tabs/TabButton.svelte create mode 100644 demo/src/lib/tabs/TabList.svelte create mode 100644 demo/src/lib/tabs/TabPanel.svelte create mode 100644 demo/src/lib/tabs/TabsWrapper.svelte create mode 100644 demo/src/lib/tabs/index.js create mode 100644 demo/tabs.html diff --git a/demo/src/lib/TabsDemo.svelte b/demo/src/lib/TabsDemo.svelte new file mode 100644 index 0000000..ddaeb1a --- /dev/null +++ b/demo/src/lib/TabsDemo.svelte @@ -0,0 +1,48 @@ + + + + + one + two + three + + + + + + nested one + nested two + nested three + + + +

First nested panel

+
+ + +

Second nested panel

+
+ + +

Third nested panel

+
+
+
+ + +

Second panel

+
+ + +

Third panel

+
+
+ + + diff --git a/demo/src/lib/tabs/TabButton.svelte b/demo/src/lib/tabs/TabButton.svelte new file mode 100644 index 0000000..86b913e --- /dev/null +++ b/demo/src/lib/tabs/TabButton.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/demo/src/lib/tabs/TabList.svelte b/demo/src/lib/tabs/TabList.svelte new file mode 100644 index 0000000..2f63475 --- /dev/null +++ b/demo/src/lib/tabs/TabList.svelte @@ -0,0 +1,9 @@ +
+ +
+ + diff --git a/demo/src/lib/tabs/TabPanel.svelte b/demo/src/lib/tabs/TabPanel.svelte new file mode 100644 index 0000000..f2922be --- /dev/null +++ b/demo/src/lib/tabs/TabPanel.svelte @@ -0,0 +1,27 @@ + + +
+ +
+ + + diff --git a/demo/src/lib/tabs/TabsWrapper.svelte b/demo/src/lib/tabs/TabsWrapper.svelte new file mode 100644 index 0000000..904461a --- /dev/null +++ b/demo/src/lib/tabs/TabsWrapper.svelte @@ -0,0 +1,50 @@ + + + + +
+ +
diff --git a/demo/src/lib/tabs/index.js b/demo/src/lib/tabs/index.js new file mode 100644 index 0000000..58e1285 --- /dev/null +++ b/demo/src/lib/tabs/index.js @@ -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'; diff --git a/demo/src/main.js b/demo/src/main.js index 8849758..35c9797 100644 --- a/demo/src/main.js +++ b/demo/src/main.js @@ -33,3 +33,38 @@ svelteRetag({ tagname: 'example-tag', hydratable, }); + + +/** + * TabsWrapper.svelte for testing context + * + * TODO: WIP + */ + +import TabsDemo from './lib/TabsDemo.svelte'; +import { TabsWrapper, TabList, TabPanel, TabButton } from './lib/tabs'; + +svelteRetag({ + component: TabsDemo, + tagname: 'tabs-demo', +}); + +svelteRetag({ + component: TabsWrapper, + tagname: 'tabs-wrapper', +}); + +svelteRetag({ + component: TabList, + tagname: 'tab-list', +}); + +svelteRetag({ + component: TabPanel, + tagname: 'tab-panel', +}); + +svelteRetag({ + component: TabButton, + tagname: 'tab-button', +}); diff --git a/demo/tabs.html b/demo/tabs.html new file mode 100644 index 0000000..abeaa9c --- /dev/null +++ b/demo/tabs.html @@ -0,0 +1,77 @@ + + + + + + + svelte-retag demo (tabs demo) + + + + +
+

Tabs demo

+

Setup to demonstrate context. Thanks to + AmirPournasserian + from + + this StackOverflow post for a majority of the tab code (ideal for testing).

+ + + + + + + + + one + two + three + + + + fails when nesting + + + + + +

Second panel

+
+ + +

Third panel

+
+
+ + +
+ + + diff --git a/demo/vite.config.js b/demo/vite.config.js index 64e5fd2..4b0ea47 100644 --- a/demo/vite.config.js +++ b/demo/vite.config.js @@ -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: { diff --git a/index.js b/index.js index 4e3a8df..c52f444 100644 --- a/index.js +++ b/index.js @@ -65,7 +65,9 @@ export default function(opts) { // Temporarily instantiate the component ahead of time just so we can get its available properties (statically // available). Note that we're doing it here in the constructor in case this component has context (so it may // normally only be instantiated from within another component). - const propInstance = new opts.component({ target: document.createElement('div') }); + // TODO: ISSUE-10: Fails since it also needs context. Make this more consistent or find cleaner method. + const context = this._getAncestorContext(); + const propInstance = new opts.component({ target: document.createElement('div'), context }); this.propMap = new Map(); for(let key of Object.keys(propInstance.$$.props)) { this.propMap.set(key.toLowerCase(), key); @@ -276,6 +278,24 @@ export default function(opts) { } } + + /** + * TODO: ISSUE-10: Doc + */ + _getAncestorContext() { + let node = this; + while (node.parentNode) { + if (node?.componentInstance?.$$?.context) { + console.log(this, 'found context in', node); + console.log(node?.componentInstance?.$$?.context); + return node?.componentInstance?.$$?.context; + } + node = node.parentNode; + } + return undefined; + } + + /** * Renders (or rerenders) the Svelte component into this custom element based on the latest properties and slots * (with slots initialized elsewhere). @@ -315,9 +335,18 @@ export default function(opts) { props[this._translateAttribute(attr.name)] = attr.value; } + + // Instantiate component into our root now, which is either the "light DOM" (i.e. directly under this element) or // in the shadow DOM. - this.componentInstance = new opts.component({ target: this._root, props: props }); + const context = this._getAncestorContext(this); + this.componentInstance = new opts.component({ target: this._root, props: props, context }); + + /*let that = this; + this.componentInstance = new opts.component({ target: this._root, props: props, get context() { + return that._getAncestorContext(that._root); + } });*/ + } /**