From 3496060bc0a2d7952ec2de3fb940a4e1a51cca56 Mon Sep 17 00:00:00 2001 From: Mark Lawlor Date: Wed, 27 Apr 2022 17:43:30 +1000 Subject: [PATCH] fix: improvements to platform prefixes --- README.md | 34 ++- .../custom-tailwindcss/platform-prefixes.ts | 80 ++++++ __tests__/tailwindcss/runner.ts | 19 +- plugin.js | 1 + src/babel/tailwind/get-tailwind-config.ts | 11 +- src/babel/tailwind/native-config.ts | 248 ---------------- src/babel/tailwind/native-plugin.ts | 32 --- .../utils/get-import-blocked-components.ts | 3 +- src/context.ts | 9 +- src/plugin/index.ts | 15 + src/plugin/native.ts | 271 ++++++++++++++++++ src/shared/platforms.ts | 21 ++ 12 files changed, 423 insertions(+), 321 deletions(-) create mode 100644 __tests__/custom-tailwindcss/platform-prefixes.ts create mode 100644 plugin.js delete mode 100644 src/babel/tailwind/native-config.ts delete mode 100644 src/babel/tailwind/native-plugin.ts create mode 100644 src/plugin/index.ts create mode 100644 src/plugin/native.ts create mode 100644 src/shared/platforms.ts diff --git a/README.md b/README.md index 2d40951..ed5f57c 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,12 @@ Install the library `npm install tailwindcss-react-native tailwindcss` or `yarn add tailwindcss-react-native tailwindcss` -Create a `tailwind.config.js` and set `content` +Create a `tailwind.config.js` and set `content` and added the `tailwindcss-react-native/plugin` ```js // tailwind.config.js module.exports = { + plugins: [require("tailwindcss-react-native/plugin")], content: [ "./screens/**/*.{js,ts,jsx,tsx}", "./pages/**/*.{js,ts,jsx,tsx}", @@ -200,11 +201,11 @@ function MyAppsProviders ({ children }) { You don't need to provide these props if you are using Babel or spreading the CLI output. -| Prop | Values | Default | Description | -| -------- | ----------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------- | -| platform | `native`, `web`, `ios`, `android`, `windows`, `macos` | Platform.OS | Specifies how the className is transformed. `ios`, `android`, `windows`, `macos` are aliases for `native` | -| style | Compiled style object | | | -| media | Compiled media object | | | +| Prop | Values | Default | Description | +| -------- | ------------------------------------------------------------------- | ----------- | ----------------------------------------- | +| platform | `web`, `native`, `ios`, `android`, `windows`, `macos`, `web-inline` | Platform.OS | Specifies how the styles are transformed. | +| style | Compiled style object | | | +| media | Compiled media object | | | ## Component API @@ -265,17 +266,22 @@ Options can be provided via the babel config ```js // babel.config.js module.exports = { - plugins: [["tailwindcss-react-native/babel", { platform: "native" }]], + plugins: [ + [ + "tailwindcss-react-native/babel", + { tailwindConfig: "./tailwind.native.config.js" }, + ], + ], }; ``` -| Option | Values | Default | Description | -| -------------- | ----------------------------------------------------- | --------------------------------------------- | --------------------------------------------------------------------------------------------------------- | -| platform | `native`, `web`, `ios`, `android`, `windows`, `macos` | `native` | Specifies how the className is transformed. `ios`, `android`, `windows`, `macos` are aliases for `native` | -| hmr | `boolean` | Development: `true`
Production: `false` | Allow fast-refresh of styles | -| tailwindConfig | Path relative to `cwd` | `tailwind.config.js` | Provide a custom `tailwind.config.js`. Useful for setting different settings per platform. | -| allowModules | `*`, `string[]` | `*` | Only transform components from these imported modules. `*` will transform all modules | -| blockModules | `string[]` | `[]` | Do not transform components from these imported modules. | +| Option | Values | Default | Description | +| -------------- | ----------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------ | +| platform | `native`, `web`, `ios`, `android`, `windows`, `macos` | `native` | Specifies how the className is transformed. | +| hmr | `boolean` | Development: `true`
Production: `false` | Allow fast-refresh of styles | +| tailwindConfig | Path relative to `cwd` | `tailwind.config.js` | Provide a custom `tailwind.config.js`. Useful for setting different settings per platform. | +| allowModules | `*`, `string[]` | `*` | Only transform components from these imported modules. `*` will transform all modules | +| blockModules | `string[]` | `[]` | Do not transform components from these imported modules. | ### CLI Options diff --git a/__tests__/custom-tailwindcss/platform-prefixes.ts b/__tests__/custom-tailwindcss/platform-prefixes.ts new file mode 100644 index 0000000..5232bd9 --- /dev/null +++ b/__tests__/custom-tailwindcss/platform-prefixes.ts @@ -0,0 +1,80 @@ +import { tailwindRunner } from "../tailwindcss/runner"; + +tailwindRunner("Platform Prefixes", [ + [ + "ios:w-px", + { + styles: { + "ios_w-px_0": { width: 1 }, + }, + media: { + "ios_w-px": [["ios", 0]], + }, + }, + ], + [ + "android:w-px", + { + styles: { + "android_w-px_0": { width: 1 }, + }, + media: { + "android_w-px": [["android", 0]], + }, + }, + ], + [ + "windows:w-px", + { + styles: { + "windows_w-px_0": { width: 1 }, + }, + media: { + "windows_w-px": [["windows", 0]], + }, + }, + ], + [ + "macos:w-px", + { + styles: { + "macos_w-px_0": { width: 1 }, + }, + media: { + "macos_w-px": [["macos", 0]], + }, + }, + ], + [ + "web:w-px", + { + styles: { + "web_w-px_0": { width: 1 }, + }, + media: { + "web_w-px": [["web-inline", 0]], + }, + }, + ], + [ + "native:w-px", + { + styles: { + "native_w-px_0": { width: 1 }, + "native_w-px_1": { width: 1 }, + "native_w-px_2": { width: 1 }, + "native_w-px_3": { width: 1 }, + "native_w-px_4": { width: 1 }, + }, + media: { + "native_w-px": [ + ["native", 0], + ["android", 1], + ["ios", 2], + ["windows", 3], + ["macos", 4], + ], + }, + }, + ], +]); diff --git a/__tests__/tailwindcss/runner.ts b/__tests__/tailwindcss/runner.ts index 8faccce..9ce1966 100644 --- a/__tests__/tailwindcss/runner.ts +++ b/__tests__/tailwindcss/runner.ts @@ -1,9 +1,9 @@ -import { getNativeTailwindConfig } from "../../src/babel/tailwind/native-config"; import { extractStyles } from "../../src/babel/native-style-extraction"; import { normaliseSelector } from "../../src/shared/selector"; import { MediaRecord, StyleRecord } from "../../src/types/common"; -const nativeConfig = getNativeTailwindConfig(); +import plugin from "../../src/plugin"; +import { nativePlugin } from "../../src/plugin/native"; export type Test = [string, Expected]; @@ -22,23 +22,16 @@ export function tailwindRunner(name: string, testCases: Test[]) { }); } -export function assertStyles( - css: string, - { styles: expectedStyles, media: expectedMedia }: Expected -) { - const { styles, media } = extractStyles({ +export function assertStyles(css: string, { styles, media = {} }: Expected) { + const output = extractStyles({ theme: {}, - ...nativeConfig, + plugins: [plugin, nativePlugin()], // eslint-disable-next-line @typescript-eslint/no-explicit-any content: [{ raw: "", extension: "html" } as any], safelist: [css], }); - expect(styles).toEqual(expectedStyles); - - if (expectedMedia) { - expect(media).toEqual(expectedMedia); - } + expect(output).toEqual({ styles, media }); } /** diff --git a/plugin.js b/plugin.js new file mode 100644 index 0000000..572666d --- /dev/null +++ b/plugin.js @@ -0,0 +1 @@ +module.exports = require("./dist/plugin").default; diff --git a/src/babel/tailwind/get-tailwind-config.ts b/src/babel/tailwind/get-tailwind-config.ts index d741a69..7756130 100644 --- a/src/babel/tailwind/get-tailwind-config.ts +++ b/src/babel/tailwind/get-tailwind-config.ts @@ -4,7 +4,7 @@ import { existsSync } from "node:fs"; import resolveTailwindConfig from "tailwindcss/resolveConfig"; import { TailwindConfig } from "tailwindcss/tailwind-config"; -import { getNativeTailwindConfig } from "./native-config"; +import { nativePlugin } from "../../plugin/native"; export interface GetTailwindConfigOptions { rem?: number; @@ -33,16 +33,9 @@ export function getTailwindConfig( userConfig = {}; } - const nativeConfig = getNativeTailwindConfig(options); - const mergedConfig = { - ...nativeConfig, ...userConfig, - theme: { - ...nativeConfig.theme, - ...userConfig.theme, - }, - plugins: [...(nativeConfig.plugins ?? []), ...(userConfig.plugins ?? [])], + plugins: [nativePlugin(options), ...(userConfig.plugins ?? [])], }; return resolveTailwindConfig(mergedConfig); diff --git a/src/babel/tailwind/native-config.ts b/src/babel/tailwind/native-config.ts deleted file mode 100644 index 907ed6e..0000000 --- a/src/babel/tailwind/native-config.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { TailwindConfig } from "tailwindcss/tailwind-config"; -import { nativePlugin } from "./native-plugin"; - -export interface GetNativeTailwindConfigOptions { - rem?: number; -} - -export function getNativeTailwindConfig({ - rem = 16, -}: GetNativeTailwindConfigOptions = {}) { - const config: Partial = { - plugins: [nativePlugin], - corePlugins: { - accentColor: false, - accessibility: false, - animation: false, - appearance: false, - aspectRatio: false, - backdropBlur: false, - backdropBrightness: false, - backdropContrast: false, - backdropFilter: false, - backdropGrayscale: false, - backdropHueRotate: false, - backdropInvert: false, - backdropOpacity: false, - backdropSaturate: false, - backdropSepia: false, - backgroundAttachment: false, - backgroundBlendMode: false, - backgroundClip: false, - backgroundImage: false, - backgroundOrigin: false, - backgroundPosition: false, - backgroundRepeat: false, - backgroundSize: false, - blur: false, - borderCollapse: false, - boxDecorationBreak: false, - boxShadow: false, - boxSizing: false, - breakAfter: false, - breakBefore: false, - breakInside: false, - brightness: false, - caretColor: false, - clear: false, - columns: false, - content: false, - contrast: false, - cursor: false, - divideColor: false, - divideOpacity: false, - divideStyle: false, - divideWidth: false, - dropShadow: false, - fill: false, - filter: false, - float: false, - fontSmoothing: false, - gap: false, - gradientColorStops: false, - grayscale: false, - gridAutoColumns: false, - gridAutoFlow: false, - gridAutoRows: false, - gridColumn: false, - gridColumnEnd: false, - gridColumnStart: false, - gridRow: false, - gridRowEnd: false, - gridRowStart: false, - gridTemplateColumns: false, - gridTemplateRows: false, - hueRotate: false, - invert: false, - isolation: false, - justifyItems: false, - justifySelf: false, - listStylePosition: false, - listStyleType: false, - mixBlendMode: false, - objectFit: false, - objectPosition: false, - order: false, - overscrollBehavior: false, - placeItems: false, - placeSelf: false, - placeholderColor: false, - placeholderOpacity: false, - preflight: false, - resize: false, - ringColor: false, - ringOffsetColor: false, - ringOffsetWidth: false, - ringOpacity: false, - ringWidth: false, - rotate: false, - saturate: false, - scale: false, - scrollBehavior: false, - scrollMargin: false, - scrollPadding: false, - scrollSnapAlign: false, - scrollSnapStop: false, - scrollSnapType: false, - sepia: false, - skew: false, - space: false, - stroke: false, - strokeWidth: false, - tableLayout: false, - textIndent: false, - textOverflow: false, - touchAction: false, - transform: false, - transformOrigin: false, - transitionDelay: false, - transitionDuration: false, - transitionProperty: false, - transitionTimingFunction: false, - translate: false, - userSelect: false, - verticalAlign: false, - visibility: false, - whitespace: false, - willChange: false, - wordBreak: false, - }, - theme: { - aspectRatio: { - auto: "0", - square: "1", - video: "1.777777778", - }, - letterSpacing: { - tighter: "-0.5px", - tight: "-0.25px", - normal: "0px", - wide: "0.25px", - wider: "0.5px", - widest: "1px", - }, - spacing: { - px: "1px", - 0: "0px", - 0.5: `${rem * 0.125}px`, - 1: `${rem * 0.25}px`, - 1.5: `${rem * 0.375}px`, - 2: `${rem * 0.5}px`, - 2.5: `${rem * 0.625}px`, - 3: `${rem * 0.75}px`, - 3.5: `${rem * 0.875}px`, - 4: `${rem * 1}px`, - 5: `${rem * 1.25}px`, - 6: `${rem * 1.5}px`, - 7: `${rem * 1.75}px`, - 8: `${rem * 2}px`, - 9: `${rem * 2.25}px`, - 10: `${rem * 2.5}px`, - 11: `${rem * 2.75}px`, - 12: `${rem * 3}px`, - 14: `${rem * 3.5}px`, - 16: `${rem * 4}px`, - 20: `${rem * 5}px`, - 24: `${rem * 6}px`, - 28: `${rem * 7}px`, - 32: `${rem * 8}px`, - 36: `${rem * 9}px`, - 40: `${rem * 10}px`, - 44: `${rem * 11}px`, - 48: `${rem * 12}px`, - 52: `${rem * 13}px`, - 56: `${rem * 14}px`, - 60: `${rem * 15}px`, - 64: `${rem * 16}px`, - 72: `${rem * 18}px`, - 80: `${rem * 20}px`, - 96: `${rem * 24}px`, - }, - borderRadius: { - none: "0px", - sm: `${rem * 0.125}px`, - DEFAULT: `${rem * 0.25}px`, - md: `${rem * 0.375}px`, - lg: `${rem * 0.5}px`, - xl: `${rem * 0.75}px`, - "2xl": `${rem * 1}px`, - "3xl": `${rem * 1.5}px`, - full: "9999px", - }, - fontSize: { - xs: [`${rem * 0.75}px`, { lineHeight: `${rem * 1}px` }], - sm: [`${rem * 0.875}px`, { lineHeight: `${rem * 1.25}px` }], - base: [`${rem * 1}px`, { lineHeight: `${rem * 1.5}px` }], - lg: [`${rem * 1.125}px`, { lineHeight: `${rem * 1.75}px` }], - xl: [`${rem * 1.25}px`, { lineHeight: `${rem * 1.75}px` }], - "2xl": [`${rem * 1.5}px`, { lineHeight: `${rem * 2}px` }], - "3xl": [`${rem * 1.875}px`, { lineHeight: `${rem * 2.25}px` }], - "4xl": [`${rem * 2.25}px`, { lineHeight: `${rem * 2.5}px` }], - "5xl": [`${rem * 3}px`, { lineHeight: "1" }], - "6xl": [`${rem * 3.75}px`, { lineHeight: "1" }], - "7xl": [`${rem * 4.5}px`, { lineHeight: "1" }], - "8xl": [`${rem * 6}px`, { lineHeight: "1" }], - "9xl": [`${rem * 8}px`, { lineHeight: "1" }], - }, - lineHeight: { - none: "1", - tight: "1.25", - snug: "1.375", - normal: "1.5", - relaxed: "1.625", - loose: "2", - 3: `${rem * 0.75}px`, - 4: `${rem * 1}px`, - 5: `${rem * 1.25}px`, - 6: `${rem * 1.5}px`, - 7: `${rem * 1.75}px`, - 8: `${rem * 2}px`, - 9: `${rem * 2.25}px`, - 10: `${rem * 2.5}px`, - }, - maxWidth: ({ theme, breakpoints }) => ({ - none: "none", - 0: `${rem * 0}px`, - xs: `${rem * 20}px`, - sm: `${rem * 24}px`, - md: `${rem * 28}px`, - lg: `${rem * 32}px`, - xl: `${rem * 36}px`, - "2xl": `${rem * 42}px`, - "3xl": `${rem * 48}px`, - "4xl": `${rem * 56}px`, - "5xl": `${rem * 64}px`, - "6xl": `${rem * 72}px`, - "7xl": `${rem * 80}px`, - full: "100%", - min: "min-content", - max: "max-content", - fit: "fit-content", - prose: "65ch", - ...breakpoints(theme("screens")), - }), - }, - }; - - return config; -} diff --git a/src/babel/tailwind/native-plugin.ts b/src/babel/tailwind/native-plugin.ts deleted file mode 100644 index 2b29b21..0000000 --- a/src/babel/tailwind/native-plugin.ts +++ /dev/null @@ -1,32 +0,0 @@ -import plugin from "tailwindcss/plugin"; - -export const nativePlugin = plugin(function ({ - addVariant, - matchUtilities, - theme, -}) { - addVariant("native", "@media native"); - addVariant("ios", ""); - addVariant("android", ""); - - matchUtilities( - { - aspect: (value: string) => { - let aspectRatio = value; - - if (value.includes("/")) { - const [left, right] = value.split("/").map((n) => { - return Number.parseInt(n, 10); - }); - - aspectRatio = `${left / right}`; - } - - return { - aspectRatio, - }; - }, - }, - { values: theme("aspectRatio") } - ); -}); diff --git a/src/babel/utils/get-import-blocked-components.ts b/src/babel/utils/get-import-blocked-components.ts index 236698e..82c14df 100644 --- a/src/babel/utils/get-import-blocked-components.ts +++ b/src/babel/utils/get-import-blocked-components.ts @@ -6,9 +6,10 @@ import micromatch from "micromatch"; import { NodePath } from "@babel/core"; import { ImportDeclaration } from "@babel/types"; import { VisitorState } from "../visitor"; +import { platforms } from "../../shared/platforms"; const allowedIndexFiles: string[] = []; -for (const platform of ["android", "ios", "native", "web", "windows"]) { +for (const platform of platforms) { for (const extension of ["js", "jsx", "ts", "tsx"]) { allowedIndexFiles.push(`index.${platform}.${extension}`); } diff --git a/src/context.ts b/src/context.ts index e30881d..608f336 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,6 +1,7 @@ import { createContext } from "react"; -import { Appearance, ColorSchemeName, Platform } from "react-native"; +import { Appearance, ColorSchemeName } from "react-native"; import { MediaRecord, StyleRecord } from "./types/common"; +import { Platform } from "./shared/platforms"; declare global { // eslint-disable-next-line no-var @@ -27,6 +28,6 @@ export const TailwindSetColorSchemeContext = createContext< >(() => { return; }); -export const TailwindPlatformContext = createContext< - typeof Platform.OS | "native" | undefined ->(undefined); +export const TailwindPlatformContext = createContext( + undefined +); diff --git a/src/plugin/index.ts b/src/plugin/index.ts new file mode 100644 index 0000000..3b328a3 --- /dev/null +++ b/src/plugin/index.ts @@ -0,0 +1,15 @@ +import plugin from "tailwindcss/plugin"; +import { platforms, nativePlatforms } from "../shared/platforms"; + +export default plugin(function ({ addVariant }) { + for (const platform of platforms) { + addVariant(platform, `@media ${platform}`); + } + + addVariant( + "native", + nativePlatforms.map((platform) => `@media ${platform}`) + ); + + addVariant("web", "@media web-inline"); +}); diff --git a/src/plugin/native.ts b/src/plugin/native.ts new file mode 100644 index 0000000..6530034 --- /dev/null +++ b/src/plugin/native.ts @@ -0,0 +1,271 @@ +import plugin from "tailwindcss/plugin"; +import { TailwindConfig } from "tailwindcss/tailwind-config"; + +export interface NativePluginOptions { + rem?: number; +} + +export const nativePlugin = plugin.withOptions( + function () { + return ({ matchUtilities, theme }) => { + matchUtilities( + { + aspect: (value: string) => { + let aspectRatio = value; + + if (value.includes("/")) { + const [left, right] = value.split("/").map((n) => { + return Number.parseInt(n, 10); + }); + + aspectRatio = `${left / right}`; + } + + return { + aspectRatio, + }; + }, + }, + { values: theme("aspectRatio") } + ); + }; + }, + function ({ rem = 16 } = {}) { + const config: Partial = { + corePlugins: { + accentColor: false, + accessibility: false, + animation: false, + appearance: false, + aspectRatio: false, + backdropBlur: false, + backdropBrightness: false, + backdropContrast: false, + backdropFilter: false, + backdropGrayscale: false, + backdropHueRotate: false, + backdropInvert: false, + backdropOpacity: false, + backdropSaturate: false, + backdropSepia: false, + backgroundAttachment: false, + backgroundBlendMode: false, + backgroundClip: false, + backgroundImage: false, + backgroundOrigin: false, + backgroundPosition: false, + backgroundRepeat: false, + backgroundSize: false, + blur: false, + borderCollapse: false, + boxDecorationBreak: false, + boxShadow: false, + boxSizing: false, + breakAfter: false, + breakBefore: false, + breakInside: false, + brightness: false, + caretColor: false, + clear: false, + columns: false, + content: false, + contrast: false, + cursor: false, + divideColor: false, + divideOpacity: false, + divideStyle: false, + divideWidth: false, + dropShadow: false, + fill: false, + filter: false, + float: false, + fontSmoothing: false, + gap: false, + gradientColorStops: false, + grayscale: false, + gridAutoColumns: false, + gridAutoFlow: false, + gridAutoRows: false, + gridColumn: false, + gridColumnEnd: false, + gridColumnStart: false, + gridRow: false, + gridRowEnd: false, + gridRowStart: false, + gridTemplateColumns: false, + gridTemplateRows: false, + hueRotate: false, + invert: false, + isolation: false, + justifyItems: false, + justifySelf: false, + listStylePosition: false, + listStyleType: false, + mixBlendMode: false, + objectFit: false, + objectPosition: false, + order: false, + overscrollBehavior: false, + placeItems: false, + placeSelf: false, + placeholderColor: false, + placeholderOpacity: false, + preflight: false, + resize: false, + ringColor: false, + ringOffsetColor: false, + ringOffsetWidth: false, + ringOpacity: false, + ringWidth: false, + rotate: false, + saturate: false, + scale: false, + scrollBehavior: false, + scrollMargin: false, + scrollPadding: false, + scrollSnapAlign: false, + scrollSnapStop: false, + scrollSnapType: false, + sepia: false, + skew: false, + space: false, + stroke: false, + strokeWidth: false, + tableLayout: false, + textIndent: false, + textOverflow: false, + touchAction: false, + transform: false, + transformOrigin: false, + transitionDelay: false, + transitionDuration: false, + transitionProperty: false, + transitionTimingFunction: false, + translate: false, + userSelect: false, + verticalAlign: false, + visibility: false, + whitespace: false, + willChange: false, + wordBreak: false, + }, + theme: { + aspectRatio: { + auto: "0", + square: "1", + video: "1.777777778", + }, + letterSpacing: { + tighter: "-0.5px", + tight: "-0.25px", + normal: "0px", + wide: "0.25px", + wider: "0.5px", + widest: "1px", + }, + spacing: { + px: "1px", + 0: "0px", + 0.5: `${rem * 0.125}px`, + 1: `${rem * 0.25}px`, + 1.5: `${rem * 0.375}px`, + 2: `${rem * 0.5}px`, + 2.5: `${rem * 0.625}px`, + 3: `${rem * 0.75}px`, + 3.5: `${rem * 0.875}px`, + 4: `${rem * 1}px`, + 5: `${rem * 1.25}px`, + 6: `${rem * 1.5}px`, + 7: `${rem * 1.75}px`, + 8: `${rem * 2}px`, + 9: `${rem * 2.25}px`, + 10: `${rem * 2.5}px`, + 11: `${rem * 2.75}px`, + 12: `${rem * 3}px`, + 14: `${rem * 3.5}px`, + 16: `${rem * 4}px`, + 20: `${rem * 5}px`, + 24: `${rem * 6}px`, + 28: `${rem * 7}px`, + 32: `${rem * 8}px`, + 36: `${rem * 9}px`, + 40: `${rem * 10}px`, + 44: `${rem * 11}px`, + 48: `${rem * 12}px`, + 52: `${rem * 13}px`, + 56: `${rem * 14}px`, + 60: `${rem * 15}px`, + 64: `${rem * 16}px`, + 72: `${rem * 18}px`, + 80: `${rem * 20}px`, + 96: `${rem * 24}px`, + }, + borderRadius: { + none: "0px", + sm: `${rem * 0.125}px`, + DEFAULT: `${rem * 0.25}px`, + md: `${rem * 0.375}px`, + lg: `${rem * 0.5}px`, + xl: `${rem * 0.75}px`, + "2xl": `${rem * 1}px`, + "3xl": `${rem * 1.5}px`, + full: "9999px", + }, + fontSize: { + xs: [`${rem * 0.75}px`, { lineHeight: `${rem * 1}px` }], + sm: [`${rem * 0.875}px`, { lineHeight: `${rem * 1.25}px` }], + base: [`${rem * 1}px`, { lineHeight: `${rem * 1.5}px` }], + lg: [`${rem * 1.125}px`, { lineHeight: `${rem * 1.75}px` }], + xl: [`${rem * 1.25}px`, { lineHeight: `${rem * 1.75}px` }], + "2xl": [`${rem * 1.5}px`, { lineHeight: `${rem * 2}px` }], + "3xl": [`${rem * 1.875}px`, { lineHeight: `${rem * 2.25}px` }], + "4xl": [`${rem * 2.25}px`, { lineHeight: `${rem * 2.5}px` }], + "5xl": [`${rem * 3}px`, { lineHeight: "1" }], + "6xl": [`${rem * 3.75}px`, { lineHeight: "1" }], + "7xl": [`${rem * 4.5}px`, { lineHeight: "1" }], + "8xl": [`${rem * 6}px`, { lineHeight: "1" }], + "9xl": [`${rem * 8}px`, { lineHeight: "1" }], + }, + lineHeight: { + none: "1", + tight: "1.25", + snug: "1.375", + normal: "1.5", + relaxed: "1.625", + loose: "2", + 3: `${rem * 0.75}px`, + 4: `${rem * 1}px`, + 5: `${rem * 1.25}px`, + 6: `${rem * 1.5}px`, + 7: `${rem * 1.75}px`, + 8: `${rem * 2}px`, + 9: `${rem * 2.25}px`, + 10: `${rem * 2.5}px`, + }, + maxWidth: ({ theme, breakpoints }) => ({ + none: "none", + 0: `${rem * 0}px`, + xs: `${rem * 20}px`, + sm: `${rem * 24}px`, + md: `${rem * 28}px`, + lg: `${rem * 32}px`, + xl: `${rem * 36}px`, + "2xl": `${rem * 42}px`, + "3xl": `${rem * 48}px`, + "4xl": `${rem * 56}px`, + "5xl": `${rem * 64}px`, + "6xl": `${rem * 72}px`, + "7xl": `${rem * 80}px`, + full: "100%", + min: "min-content", + max: "max-content", + fit: "fit-content", + prose: "65ch", + ...breakpoints(theme("screens")), + }), + }, + }; + + return config; + } +); diff --git a/src/shared/platforms.ts b/src/shared/platforms.ts new file mode 100644 index 0000000..deaa8e7 --- /dev/null +++ b/src/shared/platforms.ts @@ -0,0 +1,21 @@ +import { Platform } from "react-native"; + +export type Platform = typeof Platform.OS | "native" | "web-inline"; + +export const platforms: Platform[] = [ + "android", + "ios", + "web", + "native", + "windows", + "macos", + "web-inline", +]; + +export const nativePlatforms: Platform[] = [ + "native", + "android", + "ios", + "windows", + "macos", +];