diff --git a/apps/www/src/app/examples/scoped-theme/page.tsx b/apps/www/src/app/examples/scoped-theme/page.tsx new file mode 100644 index 000000000..388ddad2a --- /dev/null +++ b/apps/www/src/app/examples/scoped-theme/page.tsx @@ -0,0 +1,131 @@ +'use client'; + +import { + Button, + Callout, + Flex, + IconButton, + Text, + ThemeProvider +} from '@raystack/apsara'; +import { Moon, Sun } from 'lucide-react'; +import { useState } from 'react'; +import { useTheme } from '@/components/theme'; + +type ScopeTheme = 'light' | 'dark'; + +const panelStyle = { + minWidth: 320, + padding: 'var(--rs-space-7)', + borderRadius: 'var(--rs-space-3)', + border: '1px solid var(--rs-color-border-base-primary)', + backgroundColor: 'var(--rs-color-background-base-primary)' +}; + +const Page = () => { + const { theme, setTheme } = useTheme(); + const [scopeTheme, setScopeTheme] = useState('dark'); + const [calloutScopeTheme, setCalloutScopeTheme] = + useState('light'); + const GlobalIcon = theme === 'dark' ? Sun : Moon; + + return ( + + + + Scoped Theming + + + setTheme({ theme: theme === 'dark' ? 'light' : 'dark' }) + } + > + + + + + + + + + Scoped box + + + setScopeTheme(scopeTheme === 'dark' ? 'light' : 'dark') + } + > + {scopeTheme === 'dark' ? : } + + + + This box themes itself via{' '} + data-theme="{scopeTheme}", independent of the + page. + + + + + + + + + + + + + Semantic colors in scope + + + setCalloutScopeTheme( + calloutScopeTheme === 'dark' ? 'light' : 'dark' + ) + } + > + {calloutScopeTheme === 'dark' ? : } + + + + Accent, success, danger, and attention tokens all re-resolve at the + scope. + + Accent — informational message + Success — operation completed + Danger — something went wrong + + Attention — review before continuing + + + + + ); +}; + +export default Page; diff --git a/apps/www/src/app/examples/theme-overrides/page.tsx b/apps/www/src/app/examples/theme-overrides/page.tsx new file mode 100644 index 000000000..33b6892fc --- /dev/null +++ b/apps/www/src/app/examples/theme-overrides/page.tsx @@ -0,0 +1,261 @@ +'use client'; + +import { + Button, + Callout, + Flex, + IconButton, + Text, + ThemeProvider +} from '@raystack/apsara'; +import { Moon, Sun } from 'lucide-react'; +import { useState } from 'react'; +import { useTheme } from '@/components/theme'; + +type Accent = 'indigo' | 'orange' | 'mint'; +type Gray = 'gray' | 'mauve' | 'slate'; +type Style = 'modern' | 'traditional'; +type Scheme = 'light' | 'dark'; + +const ACCENTS: Accent[] = ['indigo', 'orange', 'mint']; +const GRAYS: Gray[] = ['gray', 'mauve', 'slate']; + +const panelStyle = { + padding: 'var(--rs-space-7)', + borderRadius: 'var(--rs-space-3)', + border: '1px solid var(--rs-color-border-base-primary)', + backgroundColor: 'var(--rs-color-background-base-primary)' +}; + +const cycle = (values: T[], current: T): T => + values[(values.indexOf(current) + 1) % values.length]; + +const Page = () => { + const { theme, setTheme } = useTheme(); + const GlobalIcon = theme === 'dark' ? Sun : Moon; + + const [accentScheme, setAccentScheme] = useState('light'); + const [accent, setAccent] = useState('orange'); + + const [grayScheme, setGrayScheme] = useState('light'); + const [gray, setGray] = useState('mauve'); + + const [styleScheme, setStyleScheme] = useState('light'); + const [variant, setVariant] = useState