diff --git a/src/lib/tabs/TabItem.svelte b/src/lib/tabs/TabItem.svelte index 8b3f0933..214b798e 100644 --- a/src/lib/tabs/TabItem.svelte +++ b/src/lib/tabs/TabItem.svelte @@ -1,28 +1,22 @@ + @@ -44,7 +58,10 @@ ## Props @props: children: Snippet; @props:tabStyle: "full" | "pill" | "underline" | "none" = "none"; +@props:tabSize: "xs" | "sm" | "md" = "md"; @props:ulClass: string; @props:contentClass: string; +@props:inactiveClass: string; +@props:activeClass: string; @props:divider: boolean = true; --> diff --git a/src/lib/tabs/index.ts b/src/lib/tabs/index.ts index c46cacca..68f48bc4 100644 --- a/src/lib/tabs/index.ts +++ b/src/lib/tabs/index.ts @@ -2,13 +2,15 @@ import TabItem from "./TabItem.svelte"; import Tabs from "./Tabs.svelte"; import type { Snippet } from "svelte"; import type { HTMLAttributes, HTMLLiAttributes } from "svelte/elements"; -import { type Writable } from "svelte/store"; import { tabs, tabItem } from "./theme"; interface TabsProps extends HTMLAttributes { children: Snippet; tabStyle?: "full" | "pill" | "underline" | "none"; + tabSize?: "xs" | "sm" | "md"; ulClass?: string; + activeClass?: string; + inactiveClass?: string; contentClass?: string; divider?: boolean; class?: string; @@ -19,18 +21,14 @@ interface TabitemProps extends HTMLLiAttributes { titleSlot?: Snippet; open?: boolean; title?: string; - activeClass?: string; - inactiveClass?: string; class?: string; disabled?: boolean; - tabStyle?: "full" | "pill" | "underline" | "none"; } interface TabCtxType { - activeClass?: string; - inactiveClass?: string; - tabStyle?: "full" | "pill" | "underline" | "none"; - selected: Writable; + activeClass: string; + inactiveClass: string; + selected?: HTMLElement; panelId: string; } diff --git a/src/lib/tabs/theme.ts b/src/lib/tabs/theme.ts index d49bbe37..77dc7590 100644 --- a/src/lib/tabs/theme.ts +++ b/src/lib/tabs/theme.ts @@ -5,14 +5,14 @@ export const tabs = tv({ base: "flex flex-wrap space-x-2 rtl:space-x-reverse", content: "p-4 bg-gray-50 rounded-lg dark:bg-gray-800 mt-4", divider: "h-px bg-gray-200 dark:bg-gray-700", - active: "p-4 text-primary-600 bg-gray-100 rounded-t-lg dark:bg-gray-800 dark:text-primary-500", - inactive: "p-4 text-gray-500 rounded-t-lg hover:text-gray-600 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-300" + active: "text-primary-600 bg-gray-100 rounded-t-lg dark:bg-gray-800 dark:text-primary-500", + inactive: "text-gray-500 rounded-t-lg hover:text-gray-600 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-300" }, variants: { tabStyle: { full: { - active: "p-4 w-full rounded-none group-first:rounded-s-lg group-last:rounded-e-lg text-gray-900 bg-gray-100 focus:ring-4 focus:ring-primary-300 focus:outline-none dark:bg-gray-700 dark:text-white", - inactive: "p-4 w-full rounded-none group-first:rounded-s-lg group-last:rounded-e-lg text-gray-500 dark:text-gray-400 bg-white hover:text-gray-700 hover:bg-gray-50 focus:ring-4 focus:ring-primary-300 focus:outline-none dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700" + active: "w-full rounded-none group-first:rounded-s-lg group-last:rounded-e-lg text-gray-900 bg-gray-100 focus:ring-4 focus:ring-primary-300 focus:outline-none dark:bg-gray-700 dark:text-white", + inactive: "w-full rounded-none group-first:rounded-s-lg group-last:rounded-e-lg text-gray-500 dark:text-gray-400 bg-white hover:text-gray-700 hover:bg-gray-50 focus:ring-4 focus:ring-primary-300 focus:outline-none dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700" }, pill: { active: "py-3 px-4 text-white bg-primary-600 rounded-lg", @@ -20,14 +20,28 @@ export const tabs = tv({ }, underline: { base: "-mb-px", - active: "p-4 text-primary-600 border-b-2 border-primary-600 dark:text-primary-500 dark:border-primary-500 bg-transparent", - inactive: "p-4 border-b-2 border-transparent hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300 text-gray-500 dark:text-gray-400 bg-transparent" + active: "text-primary-600 border-b-2 border-primary-600 dark:text-primary-500 dark:border-primary-500 bg-transparent", + inactive: "border-b-2 border-transparent hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300 text-gray-500 dark:text-gray-400 bg-transparent" }, none: { active: "", inactive: "" } }, + tabSize: { + xs: { + active: "p-1", + inactive: "p-1" + }, + sm: { + active: "p-2", + inactive: "p-2" + }, + md: { + active: "p-4", + inactive: "p-4" + } + }, hasDivider: { true: {} } @@ -43,7 +57,8 @@ export const tabs = tv({ ], defaultVariants: { tabStyle: "none", - hasDivider: true + hasDivider: true, + tabSize: "md" } }); diff --git a/src/routes/components/tabs/+page.svelte b/src/routes/components/tabs/+page.svelte index 19c580cb..fc488ba5 100644 --- a/src/routes/components/tabs/+page.svelte +++ b/src/routes/components/tabs/+page.svelte @@ -37,14 +37,17 @@ let tabStyle: TabsProps["tabStyle"] = $state("none") as NonNullable; const tabStyles = Object.keys(tabs.variants.tabStyle); + let tabSize: TabsProps["tabSize"] = $state("md") as NonNullable; + const tabSizes = Object.keys(tabs.variants.tabSize); // code generator let generatedCode = $derived( (() => { let props = []; - if (tabStyle !== "none") props.push(` style="${tabStyle}"`); + if (tabStyle !== "none") props.push(` tabStyle="${tabStyle}"`); + if (tabSize !== "md") props.push(` tabSize="${tabSize}"`); - return ` + return ` Profile: @@ -111,7 +114,7 @@ Interactive Tab Builder - + {#snippet titleSlot()}Profile{/snippet} @@ -158,6 +161,12 @@ {/if} {/each} + + Size + {#each tabSizes as option} + {option} + {/each} + {#snippet codeblock()} {/snippet}
Profile: @@ -111,7 +114,7 @@
@@ -158,6 +161,12 @@ {/if} {/each} +