···11+# Bluesky's "Application Layout Framework" AKA "ALF"
22+33+No docs for u.
+8
demo/.expo/README.md
···11+> Why do I have a folder named ".expo" in my project?
22+The ".expo" folder is created when an Expo project is started using "expo start" command.
33+> What do the files contain?
44+- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
55+- "settings.json": contains the server configuration that is used to serve the application manifest.
66+> Should I commit the ".expo" folder?
77+No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
88+Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
···11+import { registerRootComponent } from 'expo';
22+33+import App from './App';
44+55+// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
66+// It also ensures that whether you load the app in Expo Go or in a native build,
77+// the environment is set up appropriately
88+registerRootComponent(App);
···11+import {type Platform} from 'react-native'
22+33+export const isIOS = false
44+export const isAndroid = false
55+export const isNative = false
66+export const isWeb = true
77+// @ts-ignore
88+export const isFabric = Boolean(global?.nativeFabricUIManager)
99+1010+/**
1111+ * Identity function on web. Returns nothing on other platforms.
1212+ *
1313+ * Note: Platform splitting does not tree-shake away the other platforms,
1414+ * so don't do stuff like e.g. rely on platform-specific imports. Use
1515+ * platform-split files instead.
1616+ */
1717+export const web = (value: any) => (isWeb ? value : undefined)
1818+1919+/**
2020+ * Identity function on iOS. Returns nothing on other platforms.
2121+ *
2222+ * Note: Platform splitting does not tree-shake away the other platforms,
2323+ * so don't do stuff like e.g. rely on platform-specific imports. Use
2424+ * platform-split files instead.
2525+ */
2626+export const ios = (value: any) => (isIOS ? value : undefined)
2727+2828+/**
2929+ * Identity function on Android. Returns nothing on other platforms..
3030+ *
3131+ * Note: Platform splitting does not tree-shake away the other platforms,
3232+ * so don't do stuff like e.g. rely on platform-specific imports. Use
3333+ * platform-split files instead.
3434+ */
3535+export const android = (value: any) => (isAndroid ? value : undefined)
3636+3737+/**
3838+ * Identity function on iOS and Android. Returns nothing on web.
3939+ *
4040+ * Note: Platform splitting does not tree-shake away the other platforms,
4141+ * so don't do stuff like e.g. rely on platform-specific imports. Use
4242+ * platform-split files instead.
4343+ */
4444+export const native = (value: any) => (isNative ? value : undefined)
4545+4646+/**
4747+ * Note: Platform splitting does not tree-shake away the other platforms,
4848+ * so don't do stuff like e.g. rely on platform-specific imports. Use
4949+ * platform-split files instead.
5050+ */
5151+export const platform = (specifics => {
5252+ // @ts-ignore
5353+ return specifics.web || specifics.default
5454+}) as Platform['select']
···11+export * from './alpha'
22+export * from './leading'
33+export * from './flatten'
44+export * from './select'
+27
src/utils/leading.ts
···11+import {type TextStyle} from 'react-native'
22+33+import {isWeb} from '../platform'
44+import * as tokens from '../tokens'
55+66+/**
77+ * Util to calculate lineHeight from a text size atom and a leading atom (which
88+ * are unitless). On native, this will evaluate to a rounded pixel value. On
99+ * web, it will be a unitless string.
1010+ *
1111+ * Example:
1212+ * `leading(atoms.text_sm, atoms.leading_snug)` // => 17
1313+ */
1414+export function leading(textStyle: TextStyle): Pick<TextStyle, 'lineHeight'> {
1515+ const lineHeight = textStyle?.lineHeight || tokens.lineHeight.snug
1616+1717+ if (isWeb) {
1818+ return {
1919+ lineHeight: String(lineHeight) as unknown as TextStyle['lineHeight'],
2020+ }
2121+ } else {
2222+ const size = textStyle?.fontSize || tokens.fontSize.sm
2323+ return {
2424+ lineHeight: Math.round(size * lineHeight),
2525+ }
2626+ }
2727+}
+19
src/utils/select.ts
···11+import {type ThemeName} from '../themes'
22+33+export function select<T>(
44+ name: ThemeName,
55+ options:
66+ | (Record<ThemeName, T> & {default?: undefined})
77+ | (Partial<Record<ThemeName, T>> & {default: T}),
88+): T {
99+ switch (name) {
1010+ case 'light':
1111+ return options.light as T
1212+ case 'dark':
1313+ return options.dark as T
1414+ case 'dim':
1515+ return options.dim as T
1616+ default:
1717+ return options.default as T
1818+ }
1919+}