Skip to content

Commit

Permalink
Merge pull request #41 from xmimiex/feat/change-theme
Browse files Browse the repository at this point in the history
feat: can change theme from header
  • Loading branch information
jcfauchet authored Jun 1, 2024
2 parents 985b975 + b1efb45 commit 1414ef6
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 21 deletions.
9 changes: 4 additions & 5 deletions src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
$,
ClassList,
Component,
component$,
FunctionComponent,
Expand Down Expand Up @@ -70,7 +69,7 @@ export const Dropdown: FunctionComponent<DropdownProps> = ({ children, label, as
closeWhenSelect={closeWhenSelect}
inline={inline}
size={size}
class={attrs.class}
title={attrs.title}
/>
</div>
)
Expand Down Expand Up @@ -98,10 +97,10 @@ type InnerDropdownProps = {
components: ComponentType[]
inline: boolean
size: DropdownSize
class?: ClassList
title?: string
}

const InnerDropdown = component$<InnerDropdownProps>(({ label, as, closeWhenSelect, components, inline, size }) => {
const InnerDropdown = component$<InnerDropdownProps>(({ label, as, closeWhenSelect, components, inline, size, title }) => {
const { dropdownModalClasses } = useDropdownClasses(
useComputed$(() => size),
useComputed$(() => inline),
Expand All @@ -120,7 +119,7 @@ const InnerDropdown = component$<InnerDropdownProps>(({ label, as, closeWhenSele
useDocumentOuterClick([dropdownRef], toggleVisible, visible)

return (
<div class={['inline-flex relative justify-center']}>
<div class={['inline-flex relative justify-center']} title={title}>
<div ref={dropdownRef}>
{TriggerButtonAs ? (
<TriggerButtonAs
Expand Down
2 changes: 1 addition & 1 deletion src/components/FlowbiteProvider/FlowbiteProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type FlowbiteProviderProps = {
export const FlowbiteProvider = component$<FlowbiteProviderProps>(({ toastPosition, theme }) => {
useContextProvider(toastContext, useStore([]))
useContextProvider(darkModeContext, useSignal(undefined))
useContextProvider(themeContext, theme)
useContextProvider(themeContext, useSignal(theme))

return (
<FlowbiteThemable theme={theme}>
Expand Down
4 changes: 2 additions & 2 deletions src/components/FlowbiteThemable/FlowbiteThemable.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Slot, component$, useContextProvider } from '@builder.io/qwik'
import { Slot, component$, useContextProvider, useSignal } from '@builder.io/qwik'
import { FlowbiteTheme, themeContext } from './composables/use-flowbite-themable'

type FlowbiteChildeProps = {
theme?: FlowbiteTheme
}

export const FlowbiteThemable = component$<FlowbiteChildeProps>(({ theme = 'blue' }) => {
useContextProvider(themeContext, theme)
useContextProvider(themeContext, useSignal(theme))

return <Slot />
})
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createContextId, useComputed$, useContext } from '@builder.io/qwik'
import { $, createContextId, Signal, useComputed$, useContext } from '@builder.io/qwik'

export type FlowbiteTheme = 'blue' | 'green' | 'red' | 'pink' | 'purple'
export const FlowbiteThemeValues = ['blue', 'green', 'red', 'pink', 'purple'] as const
export type FlowbiteTheme = (typeof FlowbiteThemeValues)[number]

type FlowbiteThemeMap = {
background: string
Expand Down Expand Up @@ -58,26 +59,28 @@ const flowbiteThemeClasses: FlowbiteThemes<FlowbiteTheme> = {

export const THEME_CONTEXT = 'FLOWBITE_THEME_CONTEXT'

export const themeContext = createContextId<FlowbiteTheme>(THEME_CONTEXT)
export const themeContext = createContextId<Signal<FlowbiteTheme>>(THEME_CONTEXT)

export function useFlowbiteThemable() {
const theme = useContext<FlowbiteTheme>(themeContext)
const theme = useContext(themeContext)

const themeName = useComputed$(() => theme)
const setThemeName = $((name: FlowbiteTheme) => {
theme.value = name
})

const backgroundClasses = useComputed$(() => (!themeName.value ? '' : flowbiteThemeClasses[themeName.value].background))
const backgroundClasses = useComputed$(() => (!theme.value ? '' : flowbiteThemeClasses[theme.value].background))

const borderClasses = useComputed$(() => (!themeName.value ? '' : flowbiteThemeClasses[themeName.value].border))
const borderClasses = useComputed$(() => (!theme.value ? '' : flowbiteThemeClasses[theme.value].border))

const color = useComputed$(() => theme || undefined)

const disabledClasses = useComputed$(() => (!themeName.value ? '' : flowbiteThemeClasses[themeName.value].disabled))
const disabledClasses = useComputed$(() => (!theme.value ? '' : flowbiteThemeClasses[theme.value].disabled))

const focusClasses = useComputed$(() => (!themeName.value ? '' : flowbiteThemeClasses[themeName.value].focus))
const focusClasses = useComputed$(() => (!theme.value ? '' : flowbiteThemeClasses[theme.value].focus))

const hoverClasses = useComputed$(() => (!themeName.value ? '' : flowbiteThemeClasses[themeName.value].hover))
const hoverClasses = useComputed$(() => (!theme.value ? '' : flowbiteThemeClasses[theme.value].hover))

const textClasses = useComputed$(() => (!themeName.value ? '' : flowbiteThemeClasses[themeName.value].text))
const textClasses = useComputed$(() => (!theme.value ? '' : flowbiteThemeClasses[theme.value].text))

return {
backgroundClasses,
Expand All @@ -87,6 +90,7 @@ export function useFlowbiteThemable() {
focusClasses,
hoverClasses,
textClasses,
themeName,
themeName: theme,
setThemeName,
}
}
35 changes: 34 additions & 1 deletion src/routes/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import { IconGithubSolid, IconMoonOutline, IconSunOutline } from '~/components/I
import { Button } from '~/components/Button/Button'
import { Badge } from '~/components/Badge/Badge'
import pkg from '~/../package.json'
import { Dropdown, DropdownItem } from '~/components/Dropdown/Dropdown'
import { FlowbiteThemeValues, useFlowbiteThemable } from '~/components/FlowbiteThemable/composables/use-flowbite-themable'

export default component$(() => {
const { isDark, setDarkModeValue } = useDark()
const location = useLocation()
const { setThemeName } = useFlowbiteThemable()

return (
<div>
Expand All @@ -32,6 +35,36 @@ export default component$(() => {
>
{isDark.value ? <IconSunOutline class="h-4 w-4" /> : <IconMoonOutline class="h-4 w-4" />}
</Button>
<Dropdown
title="Switch Flowbite theme"
as={
<svg
class="w-6 h-6 text-gray-800 dark:text-white"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M15.907 11.998 10.332 9.23a.9.9 0 0 1-.16-.037l-.018-.007v6.554c0 .017.008.034.01.051l2.388-2.974 3.355-.82Z" />
<path d="m11.463 4.054 5.579 3.323A4.02 4.02 0 0 1 18.525 9c.332.668.47 1.414.398 2.155a3.07 3.07 0 0 1-.745 1.65 3.108 3.108 0 0 1-1.55.951c-.022.007-.045.005-.07.01-.062.03-.126.057-.191.08l-2.72.667-1.992 2.48c-.18.227-.41.409-.67.534.047.034.085.077.137.107a2.05 2.05 0 0 0 1.995.035c.592-.33 2.15-1.201 4.636-2.892l.28-.19c1.328-.895 3.616-2.442 3.967-4.215a9.94 9.94 0 0 0-1.713-4.154 10.027 10.027 0 0 0-3.375-2.989 10.107 10.107 0 0 0-8.802-.418c1.162.287 2.287.704 3.354 1.243Z" />
<path d="M5.382 17.082v-6.457a3.7 3.7 0 0 1 .45-1.761 3.733 3.733 0 0 1 1.238-1.34 3.915 3.915 0 0 1 3.433-.245c.176.03.347.084.508.161l5.753 2.856c.082.05.161.105.236.165a2.128 2.128 0 0 0-.953-1.455l-5.51-3.284c-1.74-.857-3.906-1.523-5.244-1.097a9.96 9.96 0 0 0-2.5 3.496 9.895 9.895 0 0 0 .283 8.368 9.973 9.973 0 0 0 2.73 3.322 17.161 17.161 0 0 1-.424-2.729Z" />
<path d="m19.102 16.163-.272.183c-2.557 1.74-4.169 2.64-4.698 2.935a4.083 4.083 0 0 1-2 .53 3.946 3.946 0 0 1-1.983-.535 3.788 3.788 0 0 1-1.36-1.361 3.752 3.752 0 0 1-.51-1.85 1.812 1.812 0 0 1-.043-.26V9.143c0-.024.009-.046.01-.07-.056.02-.11.043-.162.07a1.796 1.796 0 0 0-.787 1.516v6.377a10.67 10.67 0 0 0 1.113 4.27 10.11 10.11 0 0 0 8.505-.53 10.022 10.022 0 0 0 3.282-2.858 9.936 9.936 0 0 0 1.75-3.97 19.615 19.615 0 0 1-2.845 2.216Z" />
</svg>
}
>
{FlowbiteThemeValues.map((theme) => (
<DropdownItem
key={theme}
onClick$={() => {
setThemeName(theme)
}}
>
{theme}
</DropdownItem>
))}
</Dropdown>
<Badge class="hidden md:block" size="sm" type="dark" content={'v' + pkg.version} />

<NavbarToggle />
Expand All @@ -47,7 +80,7 @@ export default component$(() => {
</NavbarCollapse>
</Navbar>

<main class="pt-[61px]">
<main class="pt-14">
<Slot />
</main>
</div>
Expand Down

0 comments on commit 1414ef6

Please sign in to comment.