From 7514937ccd5806fdbc184bd075164627562370e2 Mon Sep 17 00:00:00 2001 From: Stephanie Zeng Date: Tue, 10 Dec 2024 10:42:17 -0500 Subject: [PATCH] feat: update demo app with theme provider --- apps/demo/src/App.tsx | 27 ++++++++------- apps/demo/src/ThemeProvider.tsx | 59 +++++++++++++++++++++++++++++++++ apps/demo/src/index.css | 8 +++++ apps/demo/src/main.tsx | 5 ++- 4 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 apps/demo/src/ThemeProvider.tsx diff --git a/apps/demo/src/App.tsx b/apps/demo/src/App.tsx index 0549545..ba0c0d7 100644 --- a/apps/demo/src/App.tsx +++ b/apps/demo/src/App.tsx @@ -1,7 +1,7 @@ import './App.css' import { Button } from '@repo/ui' import "@repo/foundations/styles"; -import { useState } from 'react'; +import { useTheme } from './ThemeProvider'; const LightModeIcon = () => ( ) @@ -18,28 +18,31 @@ const SecondaryBrandIcon = () => (('light'); - const [breakpoint, setBreakpoint] = useState('desktop'); - const density = 'default'; + const { + brand, + mode, + breakpoint, + setBrand, + setMode, + setBreakpoint + } = useTheme(); - const bodyClasses = [brand, mode, density, breakpoint].join(" "); return ( -
+
Radius Token Tango demo

Kitchen Sink

-
- - -
@@ -47,7 +50,7 @@ function App() {
- + ) } diff --git a/apps/demo/src/ThemeProvider.tsx b/apps/demo/src/ThemeProvider.tsx new file mode 100644 index 0000000..0ee7f11 --- /dev/null +++ b/apps/demo/src/ThemeProvider.tsx @@ -0,0 +1,59 @@ +import React, { createContext, useState, ReactNode, useEffect, useContext } from 'react'; + +type Brand = 'brand-1' | 'hot-brand'; +type Mode = 'light' | 'dark'; +type Breakpoint = 'desktop' | 'mobile'; +type Density = 'default' | 'compact'; + +interface ThemeContextType { + brand: Brand; + mode: Mode; + breakpoint: Breakpoint; + density: Density; + setBrand: (brand: Brand) => void; + setMode: (mode: Mode) => void; + setBreakpoint: (breakpoint: Breakpoint) => void; + setDensity: (density: Density) => void; + bodyClasses: string; +} + +const ThemeContext = createContext(undefined); + +export const ThemeProvider: React.FC<{ children: ReactNode }> = ({ children }) => { + const [brand, setBrand] = useState('brand-1'); + const [mode, setMode] = useState('light'); + const [breakpoint, setBreakpoint] = useState('desktop'); + const [density, setDensity] = useState('default'); + + const bodyClasses = [brand, mode, density, breakpoint].join(" "); + + useEffect(() => { + document.body.className = bodyClasses; + }, [bodyClasses]); + + const contextValue: ThemeContextType = { + brand, + mode, + breakpoint, + density, + setBrand, + setMode, + setBreakpoint, + setDensity, + bodyClasses + }; + + return ( + + {children} + + ); +}; + +export const useTheme = () => { + const context = useContext(ThemeContext); + if (context === undefined) { + throw new Error('useTheme must be used within a ThemeProvider'); + } + return context; + }; \ No newline at end of file diff --git a/apps/demo/src/index.css b/apps/demo/src/index.css index 6119ad9..d63e73c 100644 --- a/apps/demo/src/index.css +++ b/apps/demo/src/index.css @@ -28,11 +28,14 @@ body { place-items: center; min-width: 320px; min-height: 100vh; + background-color: var(--semantic-static-background-color-default); + color: var(--semantic-static-text-color-default); } h1 { font-size: 3.2em; line-height: 1.1; + color: var(--semantic-static-text-color-default); } button { @@ -54,6 +57,11 @@ button:focus-visible { outline: 4px auto -webkit-focus-ring-color; } +.control { + display: flex; + justify-content: center; + gap: 0.5em; +} @media (prefers-color-scheme: light) { :root { color: #213547; diff --git a/apps/demo/src/main.tsx b/apps/demo/src/main.tsx index 6f4ac9b..b6fb529 100644 --- a/apps/demo/src/main.tsx +++ b/apps/demo/src/main.tsx @@ -2,9 +2,12 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import App from './App.tsx' import './index.css' +import { ThemeProvider } from './ThemeProvider.tsx' createRoot(document.getElementById('root')!).render( - + + + , )