diff options
author | Eric Bailey <git@esb.lol> | 2024-01-08 19:43:56 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-08 19:43:56 -0600 |
commit | a5b474895a27bb36381cca6a580dc19e4c4b10c2 (patch) | |
tree | 8540478dcd85cf095de50b8a8076a86a1ba28369 /src/alf/index.tsx | |
parent | 0ee0554b8632a9d32fa36ffa9fde8d719ab1527e (diff) | |
download | voidsky-a5b474895a27bb36381cca6a580dc19e4c4b10c2.tar.zst |
Application Layout Framework (#1732)
* Initial library setup * Add docblocks * Some cleanup * New storybook * Playing around * Remove silly test, use for...in * Memo * Memo * Add hooks example * Tweak colors, bit of cleanup * Improve macro handling * Add some more examples * Rename for better diff * Cleanup * Add nested context example * Add todo * Less break more perf * Buttons, you get the idea * Fix test * Remove temp colors * Add a few more common macros * Docs * Perf improvements * Alf go brrrr * Update breakpoint handling * I think it'll work * Better naming, better code * Fix typo * Some renaming * More complete pass at Tailwind naming * Build out storybook * Playing around with curves * Revert "Playing around with curves" This reverts commit 6b0e0e5c9d842a2d9af31b53affe2f6291c3fa0d. * Smooth brain * Remove outdated docs * Some docs, fix line-height values, export tokens
Diffstat (limited to 'src/alf/index.tsx')
-rw-r--r-- | src/alf/index.tsx | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/alf/index.tsx b/src/alf/index.tsx new file mode 100644 index 000000000..1daa0bfed --- /dev/null +++ b/src/alf/index.tsx @@ -0,0 +1,92 @@ +import React from 'react' +import {Dimensions} from 'react-native' +import * as themes from '#/alf/themes' + +export * as tokens from '#/alf/tokens' +export {atoms} from '#/alf/atoms' +export * from '#/alf/util/platform' + +type BreakpointName = keyof typeof breakpoints + +/* + * Breakpoints + */ +const breakpoints: { + [key: string]: number +} = { + gtMobile: 800, + gtTablet: 1200, +} +function getActiveBreakpoints({width}: {width: number}) { + const active: (keyof typeof breakpoints)[] = Object.keys(breakpoints).filter( + breakpoint => width >= breakpoints[breakpoint], + ) + + return { + active: active[active.length - 1], + gtMobile: active.includes('gtMobile'), + gtTablet: active.includes('gtTablet'), + } +} + +/* + * Context + */ +export const Context = React.createContext<{ + themeName: themes.ThemeName + theme: themes.Theme + breakpoints: { + active: BreakpointName | undefined + gtMobile: boolean + gtTablet: boolean + } +}>({ + themeName: 'light', + theme: themes.light, + breakpoints: { + active: undefined, + gtMobile: false, + gtTablet: false, + }, +}) + +export function ThemeProvider({ + children, + theme: themeName, +}: React.PropsWithChildren<{theme: themes.ThemeName}>) { + const theme = themes[themeName] + const [breakpoints, setBreakpoints] = React.useState(() => + getActiveBreakpoints({width: Dimensions.get('window').width}), + ) + + React.useEffect(() => { + const listener = Dimensions.addEventListener('change', ({window}) => { + const bp = getActiveBreakpoints({width: window.width}) + if (bp.active !== breakpoints.active) setBreakpoints(bp) + }) + + return listener.remove + }, [breakpoints, setBreakpoints]) + + return ( + <Context.Provider + value={React.useMemo( + () => ({ + themeName: themeName, + theme: theme, + breakpoints, + }), + [theme, themeName, breakpoints], + )}> + {children} + </Context.Provider> + ) +} + +export function useTheme() { + return React.useContext(Context).theme +} + +export function useBreakpoints() { + return React.useContext(Context).breakpoints +} |