From d7ebf06c0ff41bd88ea7797a07eaaf9f27ee2428 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 4 Dec 2024 16:03:57 +0100 Subject: [PATCH 1/5] [examples] Fix vite example --- examples/pigment-css-vite-ts/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/pigment-css-vite-ts/package.json b/examples/pigment-css-vite-ts/package.json index b5a49e55..683fa579 100644 --- a/examples/pigment-css-vite-ts/package.json +++ b/examples/pigment-css-vite-ts/package.json @@ -12,7 +12,8 @@ "@pigment-css/react": "latest", "prop-types": "latest", "react": "latest", - "react-dom": "latest" + "react-dom": "latest", + "react-is": "latest" }, "devDependencies": { "@eslint/js": "latest", From a768502f1b74437a01ab7255e4ead2022143e5d8 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 4 Dec 2024 16:45:31 +0100 Subject: [PATCH 2/5] add dark mode support --- examples/pigment-css-vite-ts/src/App.tsx | 296 ++++++++++-------- examples/pigment-css-vite-ts/src/augment.d.ts | 11 + .../src/components/ColorSchemeProvider.tsx | 62 ++++ examples/pigment-css-vite-ts/src/globals.css | 6 - examples/pigment-css-vite-ts/vite.config.ts | 3 + 5 files changed, 248 insertions(+), 130 deletions(-) create mode 100644 examples/pigment-css-vite-ts/src/components/ColorSchemeProvider.tsx diff --git a/examples/pigment-css-vite-ts/src/App.tsx b/examples/pigment-css-vite-ts/src/App.tsx index 6d506d7d..8232236a 100644 --- a/examples/pigment-css-vite-ts/src/App.tsx +++ b/examples/pigment-css-vite-ts/src/App.tsx @@ -1,4 +1,5 @@ import { styled, css, keyframes } from '@pigment-css/react'; +import { ColorSchemeProvider, useColorScheme } from './components/ColorSchemeProvider'; const scale = keyframes({ to: { scale: 'var(--s2)' }, @@ -58,139 +59,186 @@ function generateBubbleVars() { `; } -export default function Home() { +const IconButton = styled('button')({ + background: 'transparent', + border: 'none', + cursor: 'pointer', + padding: '0', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +}); + +function ColorSchemeToggleButton() { + const { colorScheme, setColorScheme } = useColorScheme(); + + const toggleColorScheme = () => { + setColorScheme(colorScheme === 'dark' ? 'light' : 'dark'); + }; + return ( -
-

({ - fontFamily: 'system-ui, sans-serif', - fontSize: '4rem', - fontWeight: 500, - textAlign: 'center', - position: 'relative', - display: 'flex', - alignItems: 'center', - color: '#888', - marginBottom: '1rem', - ...theme.applyStyles('dark', { color: '#fff' }), - }))}`} - > - Pigment CSS - ({ - position: 'absolute', - inset: '0', - background: 'white', - mixBlendMode: 'color-burn', - overflow: 'hidden', - pointerEvents: 'none', - ...theme.applyStyles('dark', { - mixBlendMode: 'darken', - filter: 'brightness(2)', - }), - }))} - > - - - - - - - - - - - -

-
- CSS-in-JS library with static extraction -
+
+ + {colorScheme === 'light' ? '🌙' : '🔆'} + +
+ ); +} + +function getCookie(name: string) { + return document.cookie + .split('; ') + .find((row) => row.startsWith(`${name}=`)) + ?.split('=')[1]; +} + +function Home() { + const { colorScheme } = useColorScheme(); + + return ( +
- +

({ + fontFamily: 'system-ui, sans-serif', + fontSize: '4rem', + fontWeight: 500, + textAlign: 'center', + position: 'relative', + display: 'flex', + alignItems: 'center', + color: '#888', + marginBottom: '1rem', + ...theme.applyStyles('dark', { color: '#fff' }), + }))}`} + > + Pigment CSS + ({ + position: 'absolute', + inset: '0', + background: 'white', + mixBlendMode: 'color-burn', + overflow: 'hidden', + pointerEvents: 'none', + ...theme.applyStyles('dark', { + mixBlendMode: 'darken', + filter: 'brightness(2)', + }), + }))} + > + + + + + + + + + + + +

+
- Documentation - - +
- Roadmap - + + Documentation + + + Roadmap + +
); } +export default function App() { + const colorScheme = getCookie('colorScheme') || 'light'; + + return ( + + + + ); +} diff --git a/examples/pigment-css-vite-ts/src/augment.d.ts b/examples/pigment-css-vite-ts/src/augment.d.ts index d10b46e0..aed8e0c6 100644 --- a/examples/pigment-css-vite-ts/src/augment.d.ts +++ b/examples/pigment-css-vite-ts/src/augment.d.ts @@ -17,3 +17,14 @@ declare module '@pigment-css/react/theme' { }>; } } + +declare global { + namespace React { + interface HTMLAttributes { + sx?: SxProps; + } + interface SVGProps { + sx?: SxProps; + } + } +} diff --git a/examples/pigment-css-vite-ts/src/components/ColorSchemeProvider.tsx b/examples/pigment-css-vite-ts/src/components/ColorSchemeProvider.tsx new file mode 100644 index 00000000..85bc4453 --- /dev/null +++ b/examples/pigment-css-vite-ts/src/components/ColorSchemeProvider.tsx @@ -0,0 +1,62 @@ +import * as React from 'react'; + +const ColorSchemeContext = React.createContext<{ + colorScheme: string; + setColorScheme: React.Dispatch>; +}>({ + colorScheme: 'light', + setColorScheme: () => '', +}); + +function setCookie(name: string, value: string, days: number = 100) { + let expires = ''; + if (days) { + const date = new Date(); + date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); + expires = `; expires=${date.toUTCString()}`; + } + document.cookie = `${name}=${value || ''}${expires}; path=/`; +} + +export function ColorSchemeProvider({ + colorScheme: initialColorScheme, + children, +}: React.PropsWithChildren<{ colorScheme: string }>) { + const [colorScheme, setColorScheme] = React.useState(initialColorScheme); + + const contextValue = React.useMemo( + () => ({ colorScheme, setColorScheme }), + [colorScheme, setColorScheme], + ); + + // Set the colorScheme in localStorage + React.useEffect(() => { + setCookie('colorScheme', colorScheme); + localStorage.setItem('colorScheme', colorScheme); + }, [colorScheme]); + + // Handle when localStorage has changed + React.useEffect(() => { + const handleStorage = (event: StorageEvent) => { + const value = event.newValue; + if ( + typeof event.key === 'string' && + event.key === 'colorScheme' && + typeof value === 'string' + ) { + setColorScheme(value); + } + }; + // For syncing color-scheme changes between iframes + window.addEventListener('storage', handleStorage); + return () => { + window.removeEventListener('storage', handleStorage); + }; + }, [setColorScheme]); + + return {children}; +} + +export const useColorScheme = () => { + return React.useContext(ColorSchemeContext); +}; diff --git a/examples/pigment-css-vite-ts/src/globals.css b/examples/pigment-css-vite-ts/src/globals.css index a1e5313f..3dd82369 100644 --- a/examples/pigment-css-vite-ts/src/globals.css +++ b/examples/pigment-css-vite-ts/src/globals.css @@ -8,9 +8,3 @@ a { color: inherit; text-decoration: none; } - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } -} diff --git a/examples/pigment-css-vite-ts/vite.config.ts b/examples/pigment-css-vite-ts/vite.config.ts index a4e005fa..d336e83b 100644 --- a/examples/pigment-css-vite-ts/vite.config.ts +++ b/examples/pigment-css-vite-ts/vite.config.ts @@ -22,6 +22,9 @@ const theme = extendTheme({ }, }, }, + getSelector: (colorScheme: string) => { + return `.${colorScheme}`; + }, }); // https://vite.dev/config/ From 5c78634bbcc8e13545e1c53a5b4c967bb40d0287 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 4 Dec 2024 16:55:36 +0100 Subject: [PATCH 3/5] exclude sx from react unknown property in the examples directory --- examples/.eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/.eslintrc.js b/examples/.eslintrc.js index a5dcccaf..ac58b5b8 100644 --- a/examples/.eslintrc.js +++ b/examples/.eslintrc.js @@ -12,6 +12,7 @@ module.exports = { // create-vite generates .jsx 'react/jsx-filename-extension': 'off', 'react/react-in-jsx-scope': 'off', + "react/no-unknown-property": ["error", { "ignore": ["sx"] }], }, overrides: [ { From 10def0839f62d0cc823a3f07b1d13b6bb67baa32 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 4 Dec 2024 17:10:13 +0100 Subject: [PATCH 4/5] prettier --- examples/.eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/.eslintrc.js b/examples/.eslintrc.js index ac58b5b8..51584473 100644 --- a/examples/.eslintrc.js +++ b/examples/.eslintrc.js @@ -12,7 +12,7 @@ module.exports = { // create-vite generates .jsx 'react/jsx-filename-extension': 'off', 'react/react-in-jsx-scope': 'off', - "react/no-unknown-property": ["error", { "ignore": ["sx"] }], + 'react/no-unknown-property': ['error', { ignore: ['sx'] }], }, overrides: [ { From 31b324bf629236a7213bc17a4ff9036326fdfc45 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 4 Dec 2024 21:06:23 +0100 Subject: [PATCH 5/5] Remove cookie logic --- examples/pigment-css-vite-ts/src/App.tsx | 14 ++++---------- .../src/components/ColorSchemeProvider.tsx | 11 ----------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/examples/pigment-css-vite-ts/src/App.tsx b/examples/pigment-css-vite-ts/src/App.tsx index 8232236a..fb90708f 100644 --- a/examples/pigment-css-vite-ts/src/App.tsx +++ b/examples/pigment-css-vite-ts/src/App.tsx @@ -85,13 +85,6 @@ function ColorSchemeToggleButton() { ); } -function getCookie(name: string) { - return document.cookie - .split('; ') - .find((row) => row.startsWith(`${name}=`)) - ?.split('=')[1]; -} - function Home() { const { colorScheme } = useColorScheme(); @@ -233,11 +226,12 @@ function Home() {
); } -export default function App() { - const colorScheme = getCookie('colorScheme') || 'light'; +const defaultColorScheme = localStorage.getItem('colorScheme') ?? 'light'; + +export default function App() { return ( - + ); diff --git a/examples/pigment-css-vite-ts/src/components/ColorSchemeProvider.tsx b/examples/pigment-css-vite-ts/src/components/ColorSchemeProvider.tsx index 85bc4453..d4c81bef 100644 --- a/examples/pigment-css-vite-ts/src/components/ColorSchemeProvider.tsx +++ b/examples/pigment-css-vite-ts/src/components/ColorSchemeProvider.tsx @@ -8,16 +8,6 @@ const ColorSchemeContext = React.createContext<{ setColorScheme: () => '', }); -function setCookie(name: string, value: string, days: number = 100) { - let expires = ''; - if (days) { - const date = new Date(); - date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); - expires = `; expires=${date.toUTCString()}`; - } - document.cookie = `${name}=${value || ''}${expires}; path=/`; -} - export function ColorSchemeProvider({ colorScheme: initialColorScheme, children, @@ -31,7 +21,6 @@ export function ColorSchemeProvider({ // Set the colorScheme in localStorage React.useEffect(() => { - setCookie('colorScheme', colorScheme); localStorage.setItem('colorScheme', colorScheme); }, [colorScheme]);