diff --git a/src/lib/holocene/tabs-primitive/context.ts b/src/lib/holocene/tabs-primitive/context.ts new file mode 100644 index 0000000000..f4cf4e6b73 --- /dev/null +++ b/src/lib/holocene/tabs-primitive/context.ts @@ -0,0 +1,21 @@ +import { createContext } from 'svelte'; + +export interface TabsContextType { + selectedTab: T; + tabs: T[]; + getButtonIdForTab: (tab: string) => string; + getPanelIdForTab: (tab: string) => string; + setSelectedTab: (tab: string) => void; +} + +const [getCtx, setCtx] = createContext(); + +export function getTabsContext(): TabsContextType { + return getCtx() as TabsContextType; +} + +export function setTabsContext( + ctx: TabsContextType, +): void { + setCtx(ctx); +} diff --git a/src/lib/holocene/tabs-primitive/tab-button-list.svelte b/src/lib/holocene/tabs-primitive/tab-button-list.svelte new file mode 100644 index 0000000000..ed9cad26ba --- /dev/null +++ b/src/lib/holocene/tabs-primitive/tab-button-list.svelte @@ -0,0 +1,192 @@ + + +
+ {#each context.tabs as tab (tab)} + {@const isSelected = context.selectedTab === tab} + {@render tabButtonSnippet?.( + (overrides) => getTabButtonProps(tab, isSelected, overrides), + { tab, isSelected, setSelectedTab: context.setSelectedTab }, + )} + {/each} +
diff --git a/src/lib/holocene/tabs-primitive/tab-panels.svelte b/src/lib/holocene/tabs-primitive/tab-panels.svelte new file mode 100644 index 0000000000..df8fe37b6d --- /dev/null +++ b/src/lib/holocene/tabs-primitive/tab-panels.svelte @@ -0,0 +1,47 @@ + + +{#each context.tabs as tab (tab)} + {@const isSelected = context.selectedTab === tab} + {@render tabPanelSnippet?.( + (overrides) => getTabPanelProps(tab, isSelected, overrides), + { tab, isSelected, setSelectedTab: context.setSelectedTab }, + )} +{/each} diff --git a/src/lib/holocene/tabs-primitive/tabs.stories.svelte b/src/lib/holocene/tabs-primitive/tabs.stories.svelte new file mode 100644 index 0000000000..c6aa5659a2 --- /dev/null +++ b/src/lib/holocene/tabs-primitive/tabs.stories.svelte @@ -0,0 +1,84 @@ + + + + + + +{#snippet example( + orientation: 'horizontal' | 'vertical', + activation: 'automatic' | 'manual', +)} + + + {#snippet tabButtonSnippet(getAttributes, { tab, isSelected })} + + {/snippet} + + + {#snippet tabPanelSnippet(getAttributes, { tab })} +
+ {tab} content +
+ {/snippet} +
+
+{/snippet} + + + {#snippet template()} + {@render example('horizontal', 'automatic')} + {/snippet} + + + + {#snippet template()} + {@render example('vertical', 'automatic')} + {/snippet} + + + + {#snippet template()} + {@render example('horizontal', 'manual')} + {/snippet} + diff --git a/src/lib/holocene/tabs-primitive/tabs.svelte b/src/lib/holocene/tabs-primitive/tabs.svelte new file mode 100644 index 0000000000..a68644c029 --- /dev/null +++ b/src/lib/holocene/tabs-primitive/tabs.svelte @@ -0,0 +1,46 @@ + + +{@render children?.()}