diff --git a/src/lib/accordion/Accordion.svelte b/src/lib/accordion/Accordion.svelte index 7d7d2b1d88..0f3ac9c3fa 100644 --- a/src/lib/accordion/Accordion.svelte +++ b/src/lib/accordion/Accordion.svelte @@ -9,7 +9,7 @@ let { children, flush, activeClass, inactiveClass, multiple = false, class: className, transitionType, ...restProps }: AccordionProps = $props(); - const theme = getTheme("accordion"); + const theme = $derived(getTheme("accordion")); // Simple reactive state object const reactiveCtx: AccordionContextType = { diff --git a/src/lib/accordion/AccordionItem.svelte b/src/lib/accordion/AccordionItem.svelte index 025681f95b..54af84767a 100644 --- a/src/lib/accordion/AccordionItem.svelte +++ b/src/lib/accordion/AccordionItem.svelte @@ -50,7 +50,7 @@ const useTransition = $derived(transitionType === "none" ? false : ctxTransitionType === "none" ? false : true); // Theme context - const theme = getTheme("accordionItem"); + const theme = $derived(getTheme("accordionItem")); // single selection const self = Symbol("accordion-item"); diff --git a/src/lib/alert/Alert.svelte b/src/lib/alert/Alert.svelte index 8c1b234421..781cbc4170 100644 --- a/src/lib/alert/Alert.svelte +++ b/src/lib/alert/Alert.svelte @@ -23,7 +23,7 @@ }: AlertProps = $props(); // Theme context - const theme = getTheme("alert"); + const theme = $derived(getTheme("alert")); let divCls = $derived( alert({ diff --git a/src/lib/avatar/Avatar.svelte b/src/lib/avatar/Avatar.svelte index 40280d8f2b..9e8fb45efa 100644 --- a/src/lib/avatar/Avatar.svelte +++ b/src/lib/avatar/Avatar.svelte @@ -8,7 +8,7 @@ let { children, indicator, src, href, target, cornerStyle = "circular", border = false, stacked = false, dot, class: className, alt, size = "md", onclick, ...restProps }: AvatarProps = $props(); // Theme context - const theme = getTheme("avatar"); + const theme = $derived(getTheme("avatar")); let dotProps = $derived(dot ? { placement: "top-right" as const, color: "gray" as const, size: "lg" as const, ...dot } : undefined); diff --git a/src/lib/badge/Badge.svelte b/src/lib/badge/Badge.svelte index 4bd473e07d..a36560517b 100644 --- a/src/lib/badge/Badge.svelte +++ b/src/lib/badge/Badge.svelte @@ -36,7 +36,7 @@ const styling = $derived(classes ?? { linkClass: aClass }); // Theme context - const theme = getTheme("badge"); + const theme = $derived(getTheme("badge")); const { base, linkClass } = $derived(badge({ color, size: large ? "large" : "small", rounded, border })); diff --git a/src/lib/banner/Banner.svelte b/src/lib/banner/Banner.svelte index c2ded91527..d0507ef1a6 100644 --- a/src/lib/banner/Banner.svelte +++ b/src/lib/banner/Banner.svelte @@ -34,7 +34,7 @@ const styling = $derived(classes ?? { insideDiv: innerClass, dismissable: closeClass }); // Theme context - const theme = getTheme("banner"); + const theme = $derived(getTheme("banner")); const { base, insideDiv, dismissable: dismissableClass } = $derived(banner({ type, color })); diff --git a/src/lib/bottom-navigation/BottomNav.svelte b/src/lib/bottom-navigation/BottomNav.svelte index e2334b33e9..1cbd08cf6d 100644 --- a/src/lib/bottom-navigation/BottomNav.svelte +++ b/src/lib/bottom-navigation/BottomNav.svelte @@ -18,7 +18,7 @@ const styling = $derived(classes ?? { inner: innerClass }); // Theme context - const theme = getTheme("bottomNav"); + const theme = $derived(getTheme("bottomNav")); const activeCls = $derived(cn("text-primary-700 dark:text-primary-700 hover:text-primary-900 dark:hover:text-primary-900", activeClass)); diff --git a/src/lib/bottom-navigation/BottomNavHeader.svelte b/src/lib/bottom-navigation/BottomNavHeader.svelte index 467743b9f7..bda2fcccb5 100644 --- a/src/lib/bottom-navigation/BottomNavHeader.svelte +++ b/src/lib/bottom-navigation/BottomNavHeader.svelte @@ -16,7 +16,7 @@ const styling = $derived(classes ?? { innerDiv: innerClass }); // Theme context - const theme = getTheme("bottomNavHeader"); + const theme = $derived(getTheme("bottomNavHeader")); const { innerDiv, base } = $derived(bottomNavHeader()); diff --git a/src/lib/bottom-navigation/BottomNavHeaderItem.svelte b/src/lib/bottom-navigation/BottomNavHeaderItem.svelte index 506be7f7e7..32be9694bc 100644 --- a/src/lib/bottom-navigation/BottomNavHeaderItem.svelte +++ b/src/lib/bottom-navigation/BottomNavHeaderItem.svelte @@ -7,7 +7,7 @@ let { itemName, active, class: className, ...restProps }: BottomNavHeaderItemProps = $props(); // Theme context - const theme = getTheme("bottomNavHeaderItem"); + const theme = $derived(getTheme("bottomNavHeaderItem")); let base = $derived(bottomNavHeaderItem({ active, class: clsx(theme, className) })); diff --git a/src/lib/bottom-navigation/BottomNavItem.svelte b/src/lib/bottom-navigation/BottomNavItem.svelte index b9c896fb1f..c0d4b31824 100644 --- a/src/lib/bottom-navigation/BottomNavItem.svelte +++ b/src/lib/bottom-navigation/BottomNavItem.svelte @@ -18,7 +18,7 @@ const styling = $derived(classes ?? { span: spanClass }); // Theme context - const theme = getTheme("bottomNavItem"); + const theme = $derived(getTheme("bottomNavItem")); const context = getBottomNavContext(); diff --git a/src/lib/breadcrumb/Breadcrumb.svelte b/src/lib/breadcrumb/Breadcrumb.svelte index b0b3984d8b..2d86acc68a 100644 --- a/src/lib/breadcrumb/Breadcrumb.svelte +++ b/src/lib/breadcrumb/Breadcrumb.svelte @@ -15,7 +15,7 @@ const styling = $derived(classes ?? { list: olClass }); - const theme = getTheme("breadcrumb"); + const theme = $derived(getTheme("breadcrumb")); const { base, list } = $derived(breadcrumb({ solid })); let classNav = $derived(base({ class: clsx(theme?.base, className) })); diff --git a/src/lib/breadcrumb/BreadcrumbItem.svelte b/src/lib/breadcrumb/BreadcrumbItem.svelte index 61b8c56410..4fa8845d79 100644 --- a/src/lib/breadcrumb/BreadcrumbItem.svelte +++ b/src/lib/breadcrumb/BreadcrumbItem.svelte @@ -8,7 +8,7 @@ const styling = $derived(classes ?? {}); - const theme = getTheme("breadcrumbItem"); + const theme = $derived(getTheme("breadcrumbItem")); const { base, separator } = $derived( breadcrumbItem({ diff --git a/src/lib/button-group/ButtonGroup.svelte b/src/lib/button-group/ButtonGroup.svelte index 1f613eba90..e1e05a66c4 100644 --- a/src/lib/button-group/ButtonGroup.svelte +++ b/src/lib/button-group/ButtonGroup.svelte @@ -7,7 +7,7 @@ let { children, size = "md", disabled, class: className, ...restProps }: ButtonGroupProps = $props(); - const theme = getTheme("buttonGroup"); + const theme = $derived(getTheme("buttonGroup")); let groupClass = $derived(buttonGroup({ size, class: clsx(theme, className) })); diff --git a/src/lib/buttons/Button.svelte b/src/lib/buttons/Button.svelte index 6c8d66b35b..16145359af 100644 --- a/src/lib/buttons/Button.svelte +++ b/src/lib/buttons/Button.svelte @@ -25,7 +25,7 @@ ...restProps }: ButtonProps = $props(); - const theme = getTheme("button"); + const theme = $derived(getTheme("button")); let actualSize = $derived(group ? "sm" : size); let actualColor = $derived(color ?? (group ? (outline ? "dark" : "alternative") : "primary")); diff --git a/src/lib/buttons/GradientButton.svelte b/src/lib/buttons/GradientButton.svelte index 4d90e081b0..d9aa828ee4 100644 --- a/src/lib/buttons/GradientButton.svelte +++ b/src/lib/buttons/GradientButton.svelte @@ -10,7 +10,7 @@ let { children, outline, pill, color = "blue", shadow, class: className, href, disabled, size, btnClass, ...restProps }: GradientButtonProps = $props(); - const theme = getTheme("gradientButton"); + const theme = $derived(getTheme("gradientButton")); const { base, outlineWrapper } = $derived(gradientButton({ color, outline, pill, shadow, disabled, size, group: !!group })); diff --git a/src/lib/card/Card.svelte b/src/lib/card/Card.svelte index 1cfad24dd5..a46f9bde78 100644 --- a/src/lib/card/Card.svelte +++ b/src/lib/card/Card.svelte @@ -15,7 +15,7 @@ const styling = $derived(classes ?? { image: imgClass }); - const theme = getTheme("card"); + const theme = $derived(getTheme("card")); const { base, image } = $derived( card({ diff --git a/src/lib/carousel/Carousel.svelte b/src/lib/carousel/Carousel.svelte index b2c6e7124d..1514651d3f 100644 --- a/src/lib/carousel/Carousel.svelte +++ b/src/lib/carousel/Carousel.svelte @@ -39,7 +39,7 @@ const styling = $derived(classes ?? { slide: imgClass }); // Theme context - const theme = getTheme("carousel"); + const theme = $derived(getTheme("carousel")); let { base, slide: slideCls } = $derived(carousel()); diff --git a/src/lib/carousel/CarouselIndicators.svelte b/src/lib/carousel/CarouselIndicators.svelte index 72ae4b3245..6294c2782e 100644 --- a/src/lib/carousel/CarouselIndicators.svelte +++ b/src/lib/carousel/CarouselIndicators.svelte @@ -8,7 +8,7 @@ let { children, activeClass, inactiveClass, position = "bottom", class: className, ...restProps }: IndicatorsProps = $props(); - const theme = getTheme("carouselIndicators"); + const theme = $derived(getTheme("carouselIndicators")); const _state = getCarouselContext(); const { base, indicator } = $derived(carouselIndicators({ position })); diff --git a/src/lib/carousel/ControlButton.svelte b/src/lib/carousel/ControlButton.svelte index 22d7d2e39f..c0bfa4f503 100644 --- a/src/lib/carousel/ControlButton.svelte +++ b/src/lib/carousel/ControlButton.svelte @@ -8,7 +8,7 @@ const { base, span } = $derived(controlButton({ forward })); - const theme = getTheme("controlButton"); + const theme = $derived(getTheme("controlButton")); + {/each} + + + +
+

Button Width:

+
+ {#each widthOptions as width} + + {/each} +
+
+ + +
+

+ Current State: +
+ Color: + {selectedColor} +
+ Button Width: + {buttonWidth} +

+
+ + +
+
+

Themed Button:

+ +
+ +
+

Themed Card:

+ +
Reactive Theme Card
+

+ This card's background should change reactively when you select different color themes above. The button should also update its color and width based on your selections. +

+

If you see the colors and sizes changing instantly, the ThemeProvider reactivity is working correctly! 🎉

+
+
+
+
+ diff --git a/src/routes/docs/pages/theme-provider.md b/src/routes/docs/pages/theme-provider.md index 75d985fb00..718f8cc20b 100644 --- a/src/routes/docs/pages/theme-provider.md +++ b/src/routes/docs/pages/theme-provider.md @@ -12,6 +12,10 @@ description: The ThemeProvider component allows you to customize the styling of import { A, Img, P } from '$lib'; +## How It Works + +ThemeProvider uses Svelte's context API to pass theme configurations to child components. The theme is reactive - when you change the `theme` prop, all child components automatically re-render with the new theme values. + ## Basic Usage Wrap your components with ThemeProvider and pass a theme configuration object: @@ -170,14 +174,52 @@ Component classes, when defined directly on a component, will always take preced This allows for granular control over theming in different parts of your component tree. +## Reactive Theme + +```svelte example +{#include ThemeReactive.svelte} +``` + ## Notes -- If no theme is provided, the component will log a message to the console but won't break functionality. - The theme configuration is passed through Svelte's context system, making it available to all child components. - Each component will fall back to its default styling if no theme is provided for that specific component. - Theme configurations are merged with default component styles, allowing for partial customization. - Use nested ThemeProviders for section-specific styling while maintaining global themes. +## Dynamic Theme Switching + +Theme changes are reactive. Simply update the `theme` prop and components will automatically re-render: + +```svelte + + + + + + + Themed Card + +``` + +Components inside ThemeProvider will automatically update when `currentTheme` changes. + ## LLM Link \ No newline at end of file