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
This commit is contained in:
parent
0ee0554b86
commit
a5b474895a
13 changed files with 1793 additions and 18 deletions
92
src/alf/index.tsx
Normal file
92
src/alf/index.tsx
Normal file
|
@ -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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue