diff --git a/lib/use-tabs.js b/lib/use-tabs.js index 868628d..47d49ba 100644 --- a/lib/use-tabs.js +++ b/lib/use-tabs.js @@ -6,7 +6,7 @@ import { useHashParam, link } from './use-hash-param'; import { - choose, getName, isValid + choose, collect, getName, isValid } from './utils'; const useTabSelectedEffect = (host, selectedTab) => { @@ -64,7 +64,7 @@ const useTabSelectedEffect = (host, selectedTab) => { return { tabs, selectedTab, - onSlot: useCallback(({ target }) => requestAnimationFrame(() => setTabs(target.assignedElements().filter(el => el.matches('cosmoz-tab')))), []), + onSlot: useCallback(({ target }) => requestAnimationFrame(() => setTabs(collect(target))), []), onSelect: useCallback(e => { if (e.button !== 0 || e.metaKey || e.ctrlKey) { return; diff --git a/lib/utils.js b/lib/utils.js index a7fab0f..aecc778 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -30,11 +30,21 @@ const isValid = tab => !tab.hidden && !tab.disabled, } const selectedTab = tabs.find(tab => getName(tab) === selected); return selectedTab && isValid(selectedTab) ? selectedTab : tabs.find(isValid); - }; + }, + collect = slot => slot.assignedElements().flatMap(el => { + if (el.matches('cosmoz-tab')) { + return [el]; + } + if (el.matches('slot')) { + return collect(el); + } + return []; + }); export { choose, + collect, isValid, getIcon, getIconStyle, diff --git a/test/cosmoz-tabs-slot.test.js b/test/cosmoz-tabs-slot.test.js new file mode 100644 index 0000000..cd3dceb --- /dev/null +++ b/test/cosmoz-tabs-slot.test.js @@ -0,0 +1,34 @@ +import { + assert, html, fixture, nextFrame +} from '@open-wc/testing'; + +import '../cosmoz-tabs.js'; +import { component } from 'haunted'; + +suiteSetup(() => { + if (customElements.get('slot-test')) { + return; + } + customElements.define('slot-test', component(() => html` + + 1 + + +`)); +}); + +suite('cosmoz-tabs slot', () => { + test('collects cosmoz-tabs from slot', async () => { + const el = await fixture(html` + + 2 + 3 + + `), + tabs = el.shadowRoot.querySelector('cosmoz-tabs'); + await nextFrame(); + tabs.selected = 'tab1'; + await nextFrame(); + assert.equal(el.querySelector('cosmoz-tab').getAttribute('is-selected'), ''); + }); +});