From d163c295f533027ad75c3ccdda9d2c5b783ddeea Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 8 May 2025 12:38:00 -0700 Subject: [PATCH 1/3] Setup theme override --- .../kit/src/components/internal/Button.tsx | 14 ++-- packages/kit/src/core/theme.tsx | 70 ++++++++++++++----- packages/kit/src/provider/FlowProvider.tsx | 6 +- 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/packages/kit/src/components/internal/Button.tsx b/packages/kit/src/components/internal/Button.tsx index ded675c0b..a2d020b3b 100644 --- a/packages/kit/src/components/internal/Button.tsx +++ b/packages/kit/src/components/internal/Button.tsx @@ -14,17 +14,19 @@ export const Button: React.FC = ({ ...props }) => { const {colors} = useTheme() + const buttonVariant = colors[variant] const baseStyles = "px-4 py-2 rounded-md font-medium transition-colors" - const variantStyles = { - primary: colors.primary, - secondary: colors.secondary, - outline: colors.outline, - } + const variantClasses = twMerge( + buttonVariant.background, + buttonVariant.text, + buttonVariant.hover, + buttonVariant.border + ) return ( ) diff --git a/packages/kit/src/core/theme.tsx b/packages/kit/src/core/theme.tsx index b41795c79..cf95ca889 100644 --- a/packages/kit/src/core/theme.tsx +++ b/packages/kit/src/core/theme.tsx @@ -1,9 +1,16 @@ import React, {createContext, useContext} from "react" +export type ButtonVariant = { + background: string + text: string + hover: string + border?: string +} + export type ThemeColors = { - primary: string - secondary: string - outline: string + primary: ButtonVariant + secondary: ButtonVariant + outline: ButtonVariant } export type Theme = { @@ -12,31 +19,60 @@ export type Theme = { const defaultTheme: Theme = { colors: { - primary: "bg-slate-900 text-white hover:bg-slate-800", - secondary: "bg-slate-100 text-slate-900 hover:bg-slate-200", - outline: - "bg-transparent border border-slate-200 text-slate-900 hover:bg-slate-100", - }, + primary: { + background: "bg-slate-900", + text: "text-white", + hover: "hover:bg-slate-800", + border: undefined + }, + secondary: { + background: "bg-slate-100", + text: "text-slate-900", + hover: "hover:bg-slate-200", + border: undefined + }, + outline: { + background: "bg-transparent", + text: "text-slate-900", + hover: "hover:bg-slate-100", + border: "border border-slate-200" + } + } } const ThemeContext = createContext(defaultTheme) export const useTheme = () => useContext(ThemeContext) +type DeepPartial = { + [P in keyof T]?: T[P] extends object ? DeepPartial : T[P] +} + type ThemeProviderProps = React.PropsWithChildren<{ - theme?: Partial + theme?: DeepPartial }> +const deepMerge = (target: T, source?: DeepPartial): T => { + if (!source) return target + const result = {...target} + + Object.keys(source).forEach(key => { + const targetValue = target[key as keyof T] + const sourceValue = source[key as keyof DeepPartial] + + if (sourceValue && typeof sourceValue === 'object' && targetValue && typeof targetValue === 'object') { + result[key as keyof T] = deepMerge(targetValue as object, sourceValue as object) as T[keyof T] + } else if (sourceValue !== undefined) { + result[key as keyof T] = sourceValue as T[keyof T] + } + }) + + return result +} + export const ThemeProvider = ({ theme: customTheme, children, }: ThemeProviderProps) => { - const theme = { - ...defaultTheme, - ...customTheme, - colors: { - ...defaultTheme.colors, - ...customTheme?.colors, - }, - } + const theme = deepMerge(defaultTheme, customTheme) return {children} } diff --git a/packages/kit/src/provider/FlowProvider.tsx b/packages/kit/src/provider/FlowProvider.tsx index 6d515fa4a..92221db77 100644 --- a/packages/kit/src/provider/FlowProvider.tsx +++ b/packages/kit/src/provider/FlowProvider.tsx @@ -4,13 +4,14 @@ import {FlowConfig, FlowConfigContext} from "../core/context" import {DefaultOptions, QueryClient} from "@tanstack/react-query" import {FlowQueryClientProvider} from "./FlowQueryClient" import {deepEqual} from "../utils/deepEqual" -import {ThemeProvider} from "../core/theme" +import {ThemeProvider, Theme} from "../core/theme" import tailwindStyles from "../styles/tailwind.css" interface FlowProviderProps { config?: FlowConfig queryClient?: QueryClient flowJson?: Record + theme?: Partial } const mappings: Array<{fcl: string; typed: keyof FlowConfig}> = [ @@ -93,6 +94,7 @@ export function FlowProvider({ config: initialConfig = {}, queryClient: _queryClient, flowJson, + theme: customTheme, children, }: PropsWithChildren) { const [queryClient] = useState( @@ -144,7 +146,7 @@ export function FlowProvider({ - {children} + {children} ) From 57f56054d0a76b233c23829dae96802afd14ab74 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 9 May 2025 09:37:21 -0700 Subject: [PATCH 2/3] Run prettier --- packages/kit/src/core/theme.tsx | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/kit/src/core/theme.tsx b/packages/kit/src/core/theme.tsx index cf95ca889..c8d7de61e 100644 --- a/packages/kit/src/core/theme.tsx +++ b/packages/kit/src/core/theme.tsx @@ -23,21 +23,21 @@ const defaultTheme: Theme = { background: "bg-slate-900", text: "text-white", hover: "hover:bg-slate-800", - border: undefined + border: undefined, }, secondary: { background: "bg-slate-100", text: "text-slate-900", hover: "hover:bg-slate-200", - border: undefined + border: undefined, }, outline: { background: "bg-transparent", text: "text-slate-900", hover: "hover:bg-slate-100", - border: "border border-slate-200" - } - } + border: "border border-slate-200", + }, + }, } const ThemeContext = createContext(defaultTheme) @@ -54,18 +54,26 @@ type ThemeProviderProps = React.PropsWithChildren<{ const deepMerge = (target: T, source?: DeepPartial): T => { if (!source) return target const result = {...target} - + Object.keys(source).forEach(key => { const targetValue = target[key as keyof T] const sourceValue = source[key as keyof DeepPartial] - - if (sourceValue && typeof sourceValue === 'object' && targetValue && typeof targetValue === 'object') { - result[key as keyof T] = deepMerge(targetValue as object, sourceValue as object) as T[keyof T] + + if ( + sourceValue && + typeof sourceValue === "object" && + targetValue && + typeof targetValue === "object" + ) { + result[key as keyof T] = deepMerge( + targetValue as object, + sourceValue as object + ) as T[keyof T] } else if (sourceValue !== undefined) { result[key as keyof T] = sourceValue as T[keyof T] } }) - + return result } From 5700679e902dd59f6aded06f77674afb0991117e Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 10 Jun 2025 16:44:54 -0700 Subject: [PATCH 3/3] Add link theme --- packages/kit/src/core/theme.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/kit/src/core/theme.tsx b/packages/kit/src/core/theme.tsx index c8d7de61e..0fdd72b20 100644 --- a/packages/kit/src/core/theme.tsx +++ b/packages/kit/src/core/theme.tsx @@ -11,6 +11,7 @@ export type ThemeColors = { primary: ButtonVariant secondary: ButtonVariant outline: ButtonVariant + link: ButtonVariant } export type Theme = { @@ -37,6 +38,12 @@ const defaultTheme: Theme = { hover: "hover:bg-slate-100", border: "border border-slate-200", }, + link: { + background: "bg-transparent", + text: "text-slate-900", + hover: "hover:underline", + border: undefined, + }, }, }