diff --git a/apps/expo/app/ExpoRootLayout.tsx b/apps/expo/app/ExpoRootLayout.tsx index b8bd9f5..42a23fc 100644 --- a/apps/expo/app/ExpoRootLayout.tsx +++ b/apps/expo/app/ExpoRootLayout.tsx @@ -1,12 +1,21 @@ import { Stack } from 'expo-router' import UniversalAppProviders from '@app/core/screens/UniversalAppProviders' import UniversalRootLayout from '@app/core/screens/UniversalRootLayout' +import { NativeWindStyleSheet } from 'nativewind' // -i- Expo Router's layout setup is much simpler than Next.js's layout setup // -i- Since Expo doesn't require a custom document setup or server component root layout // -i- Use this file to apply your Expo specific layout setup: // -i- like rendering our Universal Layout and App Providers +/* --- Settings -------------------------------------------------------------------------------- */ + +NativeWindStyleSheet.setOutput({ + default: 'native', +}) + +/* --- ------------------------------------------------------------------------ */ + export default function ExpoRootLayout() { return ( diff --git a/apps/expo/babel.config.js b/apps/expo/babel.config.js index 4f30874..6fb6b9c 100644 --- a/apps/expo/babel.config.js +++ b/apps/expo/babel.config.js @@ -2,6 +2,7 @@ module.exports = function (api) { api.cache(true) return { - presets: ["babel-preset-expo"], + presets: ['babel-preset-expo'], + plugins: ['nativewind/babel'], } } diff --git a/apps/expo/tailwind.config.js b/apps/expo/tailwind.config.js new file mode 100644 index 0000000..b0e0700 --- /dev/null +++ b/apps/expo/tailwind.config.js @@ -0,0 +1,14 @@ +const { universalTheme } = require('@app/core/tailwind.theme') + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + '../../apps/**/*.tsx', + '../../features/**/*.tsx', + '../../packages/**/*.tsx', + ], + plugins: [], + theme: { + ...universalTheme, + }, +} diff --git a/apps/next/babel.config.js b/apps/next/babel.config.js index 4f30874..7df53e0 100644 --- a/apps/next/babel.config.js +++ b/apps/next/babel.config.js @@ -2,6 +2,7 @@ module.exports = function (api) { api.cache(true) return { - presets: ["babel-preset-expo"], + presets: ['babel-preset-expo'], + plugins: ['nativewind/babel', { mode: 'transformOnly' }], } } diff --git a/apps/next/global.css b/apps/next/global.css index 658fe65..72e135b 100644 --- a/apps/next/global.css +++ b/apps/next/global.css @@ -1,3 +1,8 @@ + +@tailwind base; +@tailwind components; +@tailwind utilities; + /* -i- Upgrade from the CSS reset that came with Expo's default Next.js setup */ /* Follows the setup for react-native-web: */ /* https://necolas.github.io/react-native-web/docs/setup/#root-element */ diff --git a/apps/next/next.config.js b/apps/next/next.config.js index 13d929d..af744a6 100644 --- a/apps/next/next.config.js +++ b/apps/next/next.config.js @@ -8,6 +8,7 @@ const nextConfig = withExpo({ "react-native", "react-native-web", "expo", + "nativewind", // Add more React Native / Expo packages here... ], typescript: { diff --git a/apps/next/package.json b/apps/next/package.json index 1ea911a..65ce7d4 100644 --- a/apps/next/package.json +++ b/apps/next/package.json @@ -5,7 +5,10 @@ "dependencies": { "next": "~14.0.4" }, - "devDependencies": {}, + "devDependencies": { + "autoprefixer": "^10.4.19", + "postcss": "8.4.23" + }, "scripts": { "dev": "next dev", "build": "next build", diff --git a/apps/next/postcss.config.js b/apps/next/postcss.config.js new file mode 100644 index 0000000..fef1b22 --- /dev/null +++ b/apps/next/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/apps/next/tailwind.config.js b/apps/next/tailwind.config.js new file mode 100644 index 0000000..434c6cd --- /dev/null +++ b/apps/next/tailwind.config.js @@ -0,0 +1,15 @@ +const { universalTheme } = require('@app/core/tailwind.theme') + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + '../../apps/**/*.tsx', + '../../features/**/*.tsx', + '../../packages/**/*.tsx', + ], + plugins: [require('nativewind/tailwind/css')], + important: 'html', + theme: { + ...universalTheme, + }, +} diff --git a/features/app-core/components/Image.tsx b/features/app-core/components/Image.tsx index 71bf58f..1b1fe6b 100644 --- a/features/app-core/components/Image.tsx +++ b/features/app-core/components/Image.tsx @@ -1,6 +1,7 @@ import { Image as ExpoImage } from 'expo-image' import { Platform } from 'react-native' import { UniversalImageProps, UniversalImageMethods } from './Image.types' +import { parseNativeWindStyles } from '../utils/parseNativeWindStyles' /* --- -------------------------------------------------------------------------------- */ @@ -39,10 +40,13 @@ const Image = (props: UniversalImageProps): JSX.Element => { responsivePolicy, } = props + // -- Nativewind -- + + const { nativeWindStyles, restStyle } = parseNativeWindStyles(style) + const finalStyle = { width, height, ...nativeWindStyles, ...restStyle } + // -- Overrides -- - // @ts-ignore - const finalStyle = { width, height, ...style } if (fill) finalStyle.height = '100%' if (fill) finalStyle.width = '100%' diff --git a/features/app-core/components/Image.types.tsx b/features/app-core/components/Image.types.tsx index ae5fe5f..839416e 100644 --- a/features/app-core/components/Image.types.tsx +++ b/features/app-core/components/Image.types.tsx @@ -38,6 +38,10 @@ export type UniversalImageProps = { * - Remember that the required width and height props can interact with your styling. If you use styling to modify an image's width, you should also style its height to auto to preserve its intrinsic aspect ratio, or your image will be distorted. */ style?: ExpoImageProps['style'] + /** Universal, will affect both Expo & Next.js + * - Remember that the required width and height props can interact with your styling. If you use styling to modify an image's width, you should also style its height to auto to preserve its intrinsic aspect ratio, or your image will be distorted. */ + className?: string + /** Universal, will affect both Expo & Next.js - Called on an image fetching error. */ onError?: ExpoImageProps['onError'] diff --git a/features/app-core/components/Image.web.tsx b/features/app-core/components/Image.web.tsx index f37b907..6bcc6ee 100644 --- a/features/app-core/components/Image.web.tsx +++ b/features/app-core/components/Image.web.tsx @@ -1,5 +1,6 @@ import NextImage from 'next/image' import { UniversalImageProps, UniversalImageMethods } from './Image.types' +import { parseNativeWindStyles } from '../utils/parseNativeWindStyles' /* --- -------------------------------------------------------------------------------- */ @@ -11,6 +12,7 @@ const Image = (props: UniversalImageProps): JSX.Element => { alt, width, height, + className, style = {}, priority = 'normal', onError, @@ -31,10 +33,13 @@ const Image = (props: UniversalImageProps): JSX.Element => { contentFit, } = props + // -- Nativewind -- + + const { nativeWindStyles, nativeWindClassName, restStyle } = parseNativeWindStyles(style) + const finalStyle = { width, height, ...nativeWindStyles, ...restStyle } as React.CSSProperties + // -- Overrides -- - // @ts-ignore - const finalStyle = { width, height, ...style } if (fill) finalStyle.height = '100%' if (fill) finalStyle.width = '100%' if (fill) finalStyle.objectFit = contentFit || 'cover' @@ -47,7 +52,8 @@ const Image = (props: UniversalImageProps): JSX.Element => { src={src as any} alt={alt || accessibilityLabel} width={width} - height={height} // @ts-ignore + height={height} + className={[className, nativeWindClassName].filter(Boolean).join(' ')} style={finalStyle} priority={priority === 'high'} onError={onError as any} diff --git a/features/app-core/components/styled.tsx b/features/app-core/components/styled.tsx new file mode 100644 index 0000000..4a503f1 --- /dev/null +++ b/features/app-core/components/styled.tsx @@ -0,0 +1,33 @@ +import { styled } from 'nativewind' +import { Text as RNText, View as RNView } from 'react-native' +import { Link as UniversalLink } from '../navigation/Link' +import { Image as UniversalImage } from './Image' + +/* --- Primitives ------------------------------------------------------------------------------ */ + +export const View = styled(RNView, '') +export const Text = styled(RNText, '') +export const Image = styled(UniversalImage, '') + +/* --- Typography ------------------------------------------------------------------------------ */ + +export const H1 = styled(RNText, 'font-bold text-2xl text-primary-500') +export const H2 = styled(RNText, 'font-bold text-xl text-primary-500') +export const H3 = styled(RNText, 'font-bold text-lg text-primary-500') + +export const P = styled(RNText, 'text-base') + +/* --- Fix for Next Link ----------------------------------------------------------------------- */ + +export const Link = styled(UniversalLink, 'text-blue-500 underline') +export const LinkText = styled(RNText, 'text-blue-500 underline') +export const TextLink = (props: Omit, 'className'> & { className?: string }) => { + const { className, style, children, ...universalLinkProps } = props + return ( + + + {children} + + + ) +} diff --git a/features/app-core/navigation/Link.tsx b/features/app-core/navigation/Link.tsx index 6f36026..6efc365 100644 --- a/features/app-core/navigation/Link.tsx +++ b/features/app-core/navigation/Link.tsx @@ -1,5 +1,6 @@ import { Link as ExpoLink } from 'expo-router' import type { UniversalLinkProps } from './Link.types' +import { parseNativeWindStyles } from '../utils/parseNativeWindStyles' /* --- --------------------------------------------------------------------------------- */ @@ -21,12 +22,17 @@ export const Link = (props: UniversalLinkProps) => { maxFontSizeMultiplier } = props + // -- Nativewind -- + + const { nativeWindStyles, restStyle } = parseNativeWindStyles(style) + const finalStyle = { ...nativeWindStyles, ...restStyle } + // -- Render -- return ( --------------------------------------------------------------------------------- */ @@ -9,6 +10,7 @@ export const Link = (props: UniversalLinkProps) => { const { children, href, + className, style, replace, onPress, @@ -21,12 +23,18 @@ export const Link = (props: UniversalLinkProps) => { as, } = props + // -- Nativewind -- + + const { nativeWindStyles, nativeWindClassName, restStyle } = parseNativeWindStyles(style) + const finalStyle = { ...nativeWindStyles, ...restStyle } as React.CSSProperties + // -- Render -- return ( ['style']} + className={[className, nativeWindClassName].filter(Boolean).join(' ')} + style={finalStyle as unknown as ComponentProps['style']} onClick={onPress} target={target} replace={replace} diff --git a/features/app-core/package.json b/features/app-core/package.json index e04b339..9002a7f 100644 --- a/features/app-core/package.json +++ b/features/app-core/package.json @@ -2,8 +2,11 @@ "name": "@app/core", "version": "1.0.0", "private": true, - "dependencies": {}, + "dependencies": { + "nativewind": "^2.0.11" + }, "devDependencies": { + "tailwindcss": "3.3.2", "typescript": "5.3.3" }, "scripts": {} diff --git a/features/app-core/screens/HomeScreen.tsx b/features/app-core/screens/HomeScreen.tsx index 7db3255..fa73032 100644 --- a/features/app-core/screens/HomeScreen.tsx +++ b/features/app-core/screens/HomeScreen.tsx @@ -1,50 +1,27 @@ import React from 'react' -import { StyleSheet, Text, View } from 'react-native' -import { Link } from '../navigation/Link' -import { Image } from '../components/Image' +import { View, Image, H3, P, Link } from '../components/styled' /* --- --------------------------------------------------------------------------- */ const HomeScreen = () => { return ( - - - Expo + Next.js app routing 🚀 - Open HomeScreen.tsx in features/app-core/screens to start working on your app - Test navigation - Test images - Docs + + +

Expo + Next.js app routing 🚀

+

Open HomeScreen.tsx in features/app-core/screens to start working on your app

+ + Test navigation + + + Test images + + + Docs +
) } -/* --- Styles ---------------------------------------------------------------------------------- */ - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - }, - title: { - fontWeight: 'bold', - fontSize: 16, - textAlign: 'center', - }, - subtitle: { - marginTop: 8, - fontSize: 16, - textAlign: 'center', - }, - link: { - marginTop: 16, - fontSize: 16, - color: 'blue', - textAlign: 'center', - textDecorationLine: 'underline', - }, -}) - /* --- Exports --------------------------------------------------------------------------------- */ export default HomeScreen diff --git a/features/app-core/screens/ImagesScreen.tsx b/features/app-core/screens/ImagesScreen.tsx index 81bd68e..06a1e6e 100644 --- a/features/app-core/screens/ImagesScreen.tsx +++ b/features/app-core/screens/ImagesScreen.tsx @@ -1,67 +1,37 @@ import React from 'react' -import { StyleSheet, Text, View } from 'react-native' -import { Link } from '../navigation/Link' -import { Image } from '../components/Image' +import { View, Text, Image, Link } from '../components/styled' /* --- --------------------------------------------------------------------------- */ const ImagesScreen = () => { return ( - + {`< Back`} {/* - 1 - */} - src=static-require | width: 60 | height: 60 + src=static-require | width: 60 | height: 60 {/* - 2 - */} - src=external-url | width: 60 | height: 60 + src=external-url | width: 60 | height: 60 {/* - 3 - */} - + - wrapper=50x80, relative | fill=true + wrapper=50x80, relative | fill=true {/* - 4 - */} - + - wrapper=80x60, relative | fill | contentFit=contain + wrapper=80x60, relative | fill | contentFit=contain ) } -/* --- Styles ---------------------------------------------------------------------------------- */ - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - }, - backButton: { - position: 'absolute', - top: 16, - left: 16, - }, - subtitle: { - marginTop: 8, - marginBottom: 16, - fontSize: 16, - textAlign: 'center', - }, - link: { - marginTop: 16, - fontSize: 16, - color: 'blue', - textAlign: 'center', - textDecorationLine: 'underline', - }, -}) - /* --- Exports --------------------------------------------------------------------------------- */ export default ImagesScreen diff --git a/features/app-core/screens/SlugScreen.tsx b/features/app-core/screens/SlugScreen.tsx index c0184ec..2924afb 100644 --- a/features/app-core/screens/SlugScreen.tsx +++ b/features/app-core/screens/SlugScreen.tsx @@ -1,7 +1,6 @@ import React from 'react' -import { StyleSheet, Text, View } from 'react-native' -import { useRouteParams } from '../navigation/useRouteParams' -import { Link } from '../navigation/Link' +import { useRouteParams } from '@app/core/navigation/useRouteParams' +import { View, Text, H3, Link } from '../components/styled' import { useRouter } from '../navigation/useRouter' /* --- --------------------------------------------------------------------------- */ @@ -17,71 +16,45 @@ const SlugScreen = (props) => { // -- Render -- return ( - + {showBackButton && ( {`< Back`} )} - +

Page slug: {slug} {!!count && ` | count: ${count}`} +

+ + Need a more robust, Fully-Stacked, Full-Product, Universal App Setup? - Need a more robust, Fully-Stacked, Full-Product, Universal App Setup? - + Check out the GREEN Stack Starter - push('/subpages/push')}> + push('/subpages/push')}> {`router.push()`} - navigate('/subpages/navigate')}> + navigate('/subpages/navigate')}> {`router.navigate()`} - replace('/subpages/replace')}> + replace('/subpages/replace')}> {`router.replace()`} - setParams({ count: `${+count + 1}` })}> + setParams({ count: `${+count + 1}` })}> {`router.setParams()`}
) } -/* --- Styles ---------------------------------------------------------------------------------- */ - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - }, - backButton: { - position: 'absolute', - top: 16, - left: 16, - }, - title: { - fontWeight: 'bold', - fontSize: 16, - textAlign: 'center', - }, - subtitle: { - marginTop: 8, - fontSize: 16, - textAlign: 'center', - }, - link: { - marginTop: 16, - fontSize: 16, - color: 'blue', - textAlign: 'center', - textDecorationLine: 'underline', - }, -}) - /* --- Exports --------------------------------------------------------------------------------- */ export default SlugScreen diff --git a/features/app-core/tailwind.config.js b/features/app-core/tailwind.config.js new file mode 100644 index 0000000..03a600b --- /dev/null +++ b/features/app-core/tailwind.config.js @@ -0,0 +1,14 @@ +const { universalTheme } = require('./tailwind.theme') + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + '../../apps/**/*.tsx', + '../../features/**/*.tsx', + '../../packages/**/*.tsx', + ], + plugins: [], + theme: { + ...universalTheme, + }, +} diff --git a/features/app-core/tailwind.theme.js b/features/app-core/tailwind.theme.js new file mode 100644 index 0000000..fdb93f5 --- /dev/null +++ b/features/app-core/tailwind.theme.js @@ -0,0 +1,16 @@ +const colors = require('tailwindcss/colors') + +/** @type {import('tailwindcss').Config['theme']} */ +const universalTheme = { + // -i- Extend default tailwind theme here + // -i- Reference this theme in the tailwind.config.js files in apps/expo, apps/next, features/app-core and other package or feature folders + extend: { + colors: { + primary: colors.green, + }, + } +} + +/* --- Exports --------------------------------------------------------------------------------- */ + +module.exports = { universalTheme } diff --git a/features/app-core/utils/parseNativeWindStyles.ts b/features/app-core/utils/parseNativeWindStyles.ts new file mode 100644 index 0000000..afa1855 --- /dev/null +++ b/features/app-core/utils/parseNativeWindStyles.ts @@ -0,0 +1,31 @@ + +/** --- parseNativeWindStyles() ---------------------------------------------------------------- */ +/** -i- Util to extract Nativewind's style and/or className from a styled() components style prop */ +export const parseNativeWindStyles = (style: any) => { + return Object.entries(style || {}).reduce( + (acc, [key, value]) => { + // If the key is unsupported, ignore it + if (['mask', 'childClassNames'].includes(key)) return acc + // If the key is a number, it's a Nativewind style + if (Number.isInteger(Number(key))) { + const isCSS = !!(value as Record)['$$css'] + if (isCSS) { + // If it's a CSS object, add as a Nativewind className + const { '$$css': _, ...classNameObjects } = value as Record + const className = [acc.nativeWindClassName, ...Object.values(classNameObjects)].filter(Boolean).join(' ') // prettier-ignore + return { ...acc, nativeWindClassName: className } + } else if (Array.isArray(value)) { + // If it's an array, we should merge the arrays + const flattenedStyles = value.reduce((acc, val) => ({ ...acc, ...val }), {}) + return { ...acc, nativeWindStyles: { ...acc.nativeWindStyles, ...flattenedStyles } } // prettier-ignore + } else { + // If it's a React-Native style object, check if we should merge arrays or objects + return { ...acc, nativeWindStyles: { ...acc.nativeWindStyles, ...(value as Record) } } // prettier-ignore + } + } + // If the key is a string, it's a regular style + return { ...acc, restStyle: { ...acc.restStyle, [key]: value } } + }, + { nativeWindStyles: {}, nativeWindClassName: '', restStyle: {} } + ) +} diff --git a/package-lock.json b/package-lock.json index 2f76ce4..5c49033 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,15 +47,33 @@ "dependencies": { "next": "~14.0.4" }, - "devDependencies": {} + "devDependencies": { + "autoprefixer": "^10.4.19", + "postcss": "8.4.23" + } }, "features/app-core": { "name": "@app/core", "version": "1.0.0", + "dependencies": { + "nativewind": "^2.0.11" + }, "devDependencies": { + "tailwindcss": "3.3.2", "typescript": "5.3.3" } }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -2913,6 +2931,33 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/@expo/metro-config/node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/@expo/metro-config/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7116,6 +7161,43 @@ "node": ">= 4.0.0" } }, + "node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -7345,6 +7427,17 @@ "node": ">=0.6" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -7644,6 +7737,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001643", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", @@ -7684,6 +7793,29 @@ "node": "*" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -8078,6 +8210,14 @@ "node": ">=8" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, "node_modules/css-in-js-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", @@ -8086,6 +8226,32 @@ "hyphenate-style-name": "^1.0.3" } }, + "node_modules/css-mediaquery": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz", + "integrity": "sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==" + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -8354,6 +8520,11 @@ "node": ">=0.10" } }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8365,6 +8536,11 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -9152,6 +9328,11 @@ "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.12.1.tgz", "integrity": "sha512-/t3xdbS8KB0prj5KG5w7z+wZPFlPtkgs95BsmrP/E7Q0xHXTcDcQ6Cu2FkFuRM+PKTb17cJDnLkawyS5vDLxMA==" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -9408,6 +9589,19 @@ "node": ">= 6" } }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/freeport-async": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/freeport-async/-/freeport-async-2.0.0.tgz", @@ -10066,6 +10260,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -11133,6 +11338,14 @@ "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz", "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==" }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/joi": { "version": "17.13.3", "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", @@ -11571,6 +11784,14 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -12628,6 +12849,61 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/nativewind": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/nativewind/-/nativewind-2.0.11.tgz", + "integrity": "sha512-qCEXUwKW21RYJ33KRAJl3zXq2bCq82WoI564fI21D/TiqhfmstZOqPN53RF8qK1NDK6PGl56b2xaTxgObEePEg==", + "dependencies": { + "@babel/generator": "^7.18.7", + "@babel/helper-module-imports": "7.18.6", + "@babel/types": "7.19.0", + "css-mediaquery": "^0.1.2", + "css-to-react-native": "^3.0.0", + "micromatch": "^4.0.5", + "postcss": "^8.4.12", + "postcss-calc": "^8.2.4", + "postcss-color-functional-notation": "^4.2.2", + "postcss-css-variables": "^0.18.0", + "postcss-nested": "^5.0.6", + "react-is": "^18.1.0", + "use-sync-external-store": "^1.1.0" + }, + "engines": { + "node": ">=14.18" + }, + "peerDependencies": { + "tailwindcss": "~3" + } + }, + "node_modules/nativewind/node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/nativewind/node_modules/@babel/types": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz", + "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "dependencies": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/nativewind/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, "node_modules/ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", @@ -12814,6 +13090,15 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npm-package-arg": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-7.0.0.tgz", @@ -12873,6 +13158,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", @@ -13310,9 +13603,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", + "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", "funding": [ { "type": "opencollective", @@ -13328,14 +13621,166 @@ } ], "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, "engines": { "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-css-variables": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/postcss-css-variables/-/postcss-css-variables-0.18.0.tgz", + "integrity": "sha512-lYS802gHbzn1GI+lXvy9MYIYDuGnl1WB4FTKoqMQqJ3Mab09A7a/1wZvGTkCEZJTM8mSbIyb1mJYn8f0aPye0Q==", + "dependencies": { + "balanced-match": "^1.0.0", + "escape-string-regexp": "^1.0.3", + "extend": "^3.0.1" + }, + "peerDependencies": { + "postcss": "^8.2.6" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-nested": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "dependencies": { + "postcss-selector-parser": "^6.0.6" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -13906,6 +14351,22 @@ "react": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-cache/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -13920,6 +14381,28 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/readline": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", @@ -15023,6 +15506,78 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwindcss": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz", + "integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.18.2", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tailwindcss/node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -15768,6 +16323,14 @@ "react": ">=16.8" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",