From b5eb8924050f08f64ff45678f0b5a3b94b9a761d Mon Sep 17 00:00:00 2001 From: sra1kumar-NULL Date: Mon, 25 Nov 2024 19:08:55 +0530 Subject: [PATCH 1/9] feat: nativewind 4.1 compatibility added --- next/app/layout.tsx | 6 +- next/app/registry.tsx | 20 +- next/components/ui/accordion/index.tsx | 97 +- next/components/ui/actionsheet/index.tsx | 79 +- next/components/ui/alert-dialog/index.tsx | 22 +- next/components/ui/alert/index.tsx | 62 +- next/components/ui/avatar/index.tsx | 12 +- next/components/ui/badge/index.tsx | 63 +- next/components/ui/button/index.tsx | 563 ++- next/components/ui/checkbox/index.tsx | 74 +- next/components/ui/divider/index.tsx | 16 +- next/components/ui/drawer/index.tsx | 336 ++ next/components/ui/fab/index.tsx | 66 +- next/components/ui/form-control/index.tsx | 57 +- .../ui/gluestack-ui-provider/config.js | 304 -- .../ui/gluestack-ui-provider/config.ts | 539 ++- .../ui/gluestack-ui-provider/index.tsx | 30 +- .../ui/gluestack-ui-provider/index.web.tsx | 98 +- .../ui/gluestack-ui-provider/script.ts | 19 + next/components/ui/grid/index.tsx | 83 +- next/components/ui/heading/index.tsx | 15 +- next/components/ui/icon/index.tsx | 86 +- next/components/ui/icon/index.web.tsx | 104 +- next/components/ui/image/index.tsx | 8 +- next/components/ui/input/index.tsx | 99 +- next/components/ui/link/index.tsx | 11 +- next/components/ui/menu/index.tsx | 8 +- next/components/ui/modal/index.tsx | 25 +- next/components/ui/popover/index.tsx | 58 +- next/components/ui/pressable/index.tsx | 11 +- next/components/ui/progress/index.tsx | 87 +- next/components/ui/radio/index.tsx | 118 +- next/components/ui/select/index.tsx | 80 +- .../ui/select/select-actionsheet.tsx | 70 +- next/components/ui/slider/index.tsx | 36 +- next/components/ui/spinner/index.tsx | 44 +- next/components/ui/switch/index.tsx | 18 +- next/components/ui/table/index.tsx | 19 +- next/components/ui/table/index.web.tsx | 12 +- next/components/ui/textarea/index.tsx | 24 +- next/components/ui/toast/index.tsx | 54 +- next/components/ui/tooltip/index.tsx | 18 +- .../ui/utils/use-break-point-value.ts | 101 + next/gluestack-ui.config.json | 10 + next/next.config.js | 64 +- next/package.json | 75 +- next/tailwind.config.js | 327 +- next/tsconfig.json | 3 + next/yarn.lock | 3718 ++++------------- 49 files changed, 2542 insertions(+), 5307 deletions(-) create mode 100644 next/components/ui/drawer/index.tsx delete mode 100644 next/components/ui/gluestack-ui-provider/config.js create mode 100644 next/components/ui/gluestack-ui-provider/script.ts create mode 100644 next/components/ui/utils/use-break-point-value.ts create mode 100644 next/gluestack-ui.config.json diff --git a/next/app/layout.tsx b/next/app/layout.tsx index 1f9d0cfd..2c23ae19 100644 --- a/next/app/layout.tsx +++ b/next/app/layout.tsx @@ -1,6 +1,6 @@ -"use client"; - +"use client";; import { Inter } from "next/font/google"; +import "@/styles/global.css"; import StyledJsxRegistry from "./registry"; import { GluestackUIProvider } from "@/components/ui/gluestack-ui-provider"; @@ -14,7 +14,7 @@ export default function RootLayout({ - {children} + {children} diff --git a/next/app/registry.tsx b/next/app/registry.tsx index 470bc580..53996dce 100644 --- a/next/app/registry.tsx +++ b/next/app/registry.tsx @@ -1,14 +1,12 @@ -"use client"; +'use client'; -import "../styles/global.css"; -import React, { useRef, useState } from "react"; -import { useServerInsertedHTML } from "next/navigation"; -import { StyleRegistry, createStyleRegistry } from "styled-jsx"; -// eslint-disable-next-line @next/next/no-document-import-in-page -import { Main } from "next/document"; -import { flush } from "@gluestack-ui/nativewind-utils/flush"; +import React, { useRef, useState } from 'react'; +import { useServerInsertedHTML } from 'next/navigation'; +import { StyleRegistry, createStyleRegistry } from 'styled-jsx'; +import { Main } from 'next/document'; // @ts-ignore -import { AppRegistry } from "react-native-web"; +import { AppRegistry } from 'react-native-web'; +import { flush } from '@gluestack-ui/nativewind-utils/flush'; export default function StyledJsxRegistry({ children, @@ -21,8 +19,8 @@ export default function StyledJsxRegistry({ const isServerInserted = useRef(false); useServerInsertedHTML(() => { - AppRegistry.registerComponent("Main", () => Main); - const { getStyleElement } = AppRegistry.getApplication("Main"); + AppRegistry.registerComponent('Main', () => Main); + const { getStyleElement } = AppRegistry.getApplication('Main'); if (!isServerInserted.current) { isServerInserted.current = true; const styles = [getStyleElement(), jsxStyleRegistry.styles(), flush()]; diff --git a/next/components/ui/accordion/index.tsx b/next/components/ui/accordion/index.tsx index ca4711a7..fa58903f 100644 --- a/next/components/ui/accordion/index.tsx +++ b/next/components/ui/accordion/index.tsx @@ -1,7 +1,6 @@ 'use client'; -import React, { useMemo } from 'react'; +import React from 'react'; import { createAccordion } from '@gluestack-ui/accordion'; -import { Svg } from 'react-native-svg'; import { View, Pressable, Text, Platform, TextProps } from 'react-native'; import { tva } from '@gluestack-ui/nativewind-utils/tva'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; @@ -9,9 +8,9 @@ import { withStyleContext, useStyleContext, } from '@gluestack-ui/nativewind-utils/withStyleContext'; -import { withStyleContextAndStates } from '@gluestack-ui/nativewind-utils/withStyleContextAndStates'; import { H3 } from '@expo/html-elements'; import { cssInterop } from 'nativewind'; +import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon'; const SCOPE = 'ACCORDION'; /** Styles */ @@ -30,7 +29,9 @@ const accordionStyle = tva({ }, }, }); + const accordionItemStyle = tva({ + base: 'py-3 px-4', parentVariants: { variant: { filled: 'bg-background-0', @@ -65,7 +66,7 @@ const accordionContentTextStyle = tva({ base: 'text-typography-700 font-normal', parentVariants: { size: { - sm: 'text-sm ', + sm: 'text-sm', md: 'text-base', lg: 'text-lg', }, @@ -75,79 +76,13 @@ const accordionHeaderStyle = tva({ base: 'mx-0 my-0', }); const accordionContentStyle = tva({ - base: 'px-5 mt-2 pb-5', + base: 'mt-4', }); const accordionTriggerStyle = tva({ - base: 'w-full py-5 px-5 flex-row justify-between items-center web:outline-none focus:outline-none data-[disabled=true]:opacity-40 data-[disabled=true]:cursor-not-allowed data-[focus-visible=true]:bg-background-50', + base: 'w-full flex-row justify-between items-center web:outline-none focus:outline-none data-[disabled=true]:opacity-40 data-[disabled=true]:cursor-not-allowed data-[focus-visible=true]:bg-background-50', }); -type IPrimitiveIcon = { - height?: number | string; - width?: number | string; - fill?: string; - color?: string; - size?: number | string; - stroke?: string; - as?: React.ElementType; - className?: string; -}; - -const PrimitiveIcon = React.forwardRef< - React.ElementRef, - IPrimitiveIcon & React.ComponentPropsWithoutRef ->( - ( - { - height, - width, - fill, - color, - size, - stroke = 'currentColor', - as: AsComp, - ...props - }, - ref - ) => { - const sizeProps = useMemo(() => { - if (size) return { size }; - if (height && width) return { height, width }; - if (height) return { height }; - if (width) return { width }; - return {}; - }, [size, height, width]); - - const colorProps = - stroke === 'currentColor' && color !== undefined ? color : stroke; - - if (AsComp) { - return ( - - ); - } - return ( - - ); - } -); - -const Root = - Platform.OS === 'web' - ? withStyleContext(View, SCOPE) - : withStyleContextAndStates(View, SCOPE); +const Root = withStyleContext(View, SCOPE); const Header = ( Platform.OS === 'web' ? H3 : View @@ -159,30 +94,20 @@ const UIAccordion = createAccordion({ Item: View, Header: Header, Trigger: Pressable, - Icon: PrimitiveIcon, + Icon: UIIcon, TitleText: Text, ContentText: Text, Content: View, }); -cssInterop(UIAccordion, { className: 'style' }); -cssInterop(UIAccordion.Item, { className: 'style' }); -cssInterop(UIAccordion.Header, { className: 'style' }); -cssInterop(UIAccordion.Trigger, { className: 'style' }); -cssInterop(UIAccordion.Icon, { className: 'style' }); -cssInterop(UIAccordion.TitleText, { className: 'style' }); -cssInterop(UIAccordion.Content, { className: 'style' }); -cssInterop(UIAccordion.ContentText, { className: 'style' }); -// @ts-ignore -cssInterop(UIAccordion.Icon, { +cssInterop(PrimitiveIcon, { className: { target: 'style', nativeStyleToProp: { height: true, width: true, - // @ts-ignore fill: true, - color: true, + color: 'classNameColor', stroke: true, }, }, diff --git a/next/components/ui/actionsheet/index.tsx b/next/components/ui/actionsheet/index.tsx index e80735b9..0dc14763 100644 --- a/next/components/ui/actionsheet/index.tsx +++ b/next/components/ui/actionsheet/index.tsx @@ -1,7 +1,6 @@ 'use client'; -import React, { useMemo } from 'react'; +import React from 'react'; import { H4 } from '@expo/html-elements'; -import { Svg } from 'react-native-svg'; import { createActionsheet } from '@gluestack-ui/actionsheet'; import { Pressable, @@ -11,13 +10,11 @@ import { VirtualizedList, FlatList, SectionList, - Platform, PressableProps, } from 'react-native'; - +import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon'; import { tva } from '@gluestack-ui/nativewind-utils/tva'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; -import { withStates } from '@gluestack-ui/nativewind-utils/withStates'; import { cssInterop } from 'nativewind'; import { Motion, @@ -25,68 +22,6 @@ import { createMotionAnimatedComponent, } from '@legendapp/motion'; -type IPrimitiveIcon = { - height?: number | string; - width?: number | string; - fill?: string; - color?: string; - size?: number | string; - stroke?: string; - as?: React.ElementType; - className?: string; -}; -const PrimitiveIcon = React.forwardRef< - React.ElementRef, - IPrimitiveIcon & React.ComponentPropsWithoutRef ->( - ( - { - height, - width, - fill, - color, - size, - stroke = 'currentColor', - as: AsComp, - ...props - }, - ref - ) => { - const sizeProps = useMemo(() => { - if (size) return { size }; - if (height && width) return { height, width }; - if (height) return { height }; - if (width) return { width }; - return {}; - }, [size, height, width]); - - const colorProps = - stroke === 'currentColor' && color !== undefined ? color : stroke; - - if (AsComp) { - return ( - - ); - } - return ( - - ); - } -); - const ItemWrapper = React.forwardRef< React.ElementRef, PressableProps @@ -99,7 +34,7 @@ const AnimatedPressable = createMotionAnimatedComponent(Pressable); export const UIActionsheet = createActionsheet({ Root: View, Content: Motion.View, - Item: Platform.OS === 'web' ? ItemWrapper : withStates(ItemWrapper), + Item: ItemWrapper, ItemText: Text, DragIndicator: View, IndicatorWrapper: View, @@ -109,7 +44,7 @@ export const UIActionsheet = createActionsheet({ FlatList: FlatList, SectionList: SectionList, SectionHeaderText: H4, - Icon: PrimitiveIcon, + Icon: UIIcon, AnimatePresence: AnimatePresence, }); @@ -142,15 +77,15 @@ cssInterop(UIActionsheet.FlatList, { }); cssInterop(UIActionsheet.SectionList, { className: 'style' }); cssInterop(UIActionsheet.SectionHeaderText, { className: 'style' }); -cssInterop(UIActionsheet.Icon, { + +cssInterop(PrimitiveIcon, { className: { target: 'style', nativeStyleToProp: { height: true, width: true, - // @ts-ignore fill: true, - color: true, + color: 'classNameColor', stroke: true, }, }, diff --git a/next/components/ui/alert-dialog/index.tsx b/next/components/ui/alert-dialog/index.tsx index 457db9c6..2bd63535 100644 --- a/next/components/ui/alert-dialog/index.tsx +++ b/next/components/ui/alert-dialog/index.tsx @@ -6,7 +6,7 @@ import { withStyleContext, useStyleContext, } from '@gluestack-ui/nativewind-utils/withStyleContext'; -import { withStyleContextAndStates } from '@gluestack-ui/nativewind-utils/withStyleContextAndStates'; + import { cssInterop } from 'nativewind'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; import { @@ -14,17 +14,14 @@ import { AnimatePresence, createMotionAnimatedComponent, } from '@legendapp/motion'; -import { View, Pressable, ScrollView, Platform } from 'react-native'; +import { View, Pressable, ScrollView } from 'react-native'; const AnimatedPressable = createMotionAnimatedComponent(Pressable); const SCOPE = 'ALERT_DIALOG'; const UIAccessibleAlertDialog = createAlertDialog({ - Root: - Platform.OS === 'web' - ? withStyleContext(View, SCOPE) - : withStyleContextAndStates(View, SCOPE), + Root: withStyleContext(View, SCOPE), Body: ScrollView, Content: Motion.View, CloseButton: Pressable, @@ -34,17 +31,8 @@ const UIAccessibleAlertDialog = createAlertDialog({ AnimatePresence: AnimatePresence, }); -cssInterop(UIAccessibleAlertDialog, { className: 'style' }); -cssInterop(UIAccessibleAlertDialog.Content, { className: 'style' }); -cssInterop(UIAccessibleAlertDialog.CloseButton, { className: 'style' }); -cssInterop(UIAccessibleAlertDialog.Header, { className: 'style' }); -cssInterop(UIAccessibleAlertDialog.Footer, { className: 'style' }); -cssInterop(UIAccessibleAlertDialog.Body, { - className: 'style', - contentContainerClassName: 'contentContainerStyle', - indicatorClassName: 'indicatorStyle', -}); -cssInterop(UIAccessibleAlertDialog.Backdrop, { className: 'style' }); +cssInterop(Motion.View, { className: 'style' }); +cssInterop(AnimatedPressable, { className: 'style' }); const alertDialogStyle = tva({ base: 'group/modal w-full h-full justify-center items-center web:pointer-events-none', diff --git a/next/components/ui/alert/index.tsx b/next/components/ui/alert/index.tsx index f98aceb9..a1036335 100644 --- a/next/components/ui/alert/index.tsx +++ b/next/components/ui/alert/index.tsx @@ -6,10 +6,10 @@ import { withStyleContext, useStyleContext, } from '@gluestack-ui/nativewind-utils/withStyleContext'; -import React, { useMemo } from 'react'; -import { Svg } from 'react-native-svg'; +import React from 'react'; import { cssInterop } from 'nativewind'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; +import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon'; const SCOPE = 'ALERT'; @@ -105,72 +105,20 @@ const alertIconStyle = tva({ }, }); -type IPrimitiveIcon = React.ComponentPropsWithoutRef & { - height?: number | string; - width?: number | string; - fill?: string; - color?: string; - size?: number | string; - stroke?: string; - as?: React.ElementType; - className?: string; -}; - -const PrimitiveIcon = React.forwardRef< - React.ElementRef, - IPrimitiveIcon ->(({ height, width, fill, color, size, stroke, as: AsComp, ...props }, ref) => { - const sizeProps = useMemo(() => { - if (size) return { size }; - if (height && width) return { height, width }; - if (height) return { height }; - if (width) return { width }; - return {}; - }, [size, height, width]); - - let colorProps = {}; - if (color) { - colorProps = { ...colorProps, color: color }; - } - if (stroke) { - colorProps = { ...colorProps, stroke: stroke }; - } - if (fill) { - colorProps = { ...colorProps, fill: fill }; - } - if (AsComp) { - return ; - } - return ( - - ); -}); - -const IconWrapper = React.forwardRef< - React.ElementRef, - IPrimitiveIcon ->(({ ...props }, ref) => { - return ; -}); - export const UIAlert = createAlert({ Root: withStyleContext(View, SCOPE), Text: Text, - Icon: IconWrapper, + Icon: UIIcon, }); -cssInterop(UIAlert, { className: 'style' }); -//@ts-ignore -cssInterop(UIAlert.Text, { className: 'style' }); -cssInterop(IconWrapper, { +cssInterop(PrimitiveIcon, { className: { target: 'style', nativeStyleToProp: { height: true, width: true, - // @ts-ignore fill: true, - color: true, + color: 'classNameColor', stroke: true, }, }, diff --git a/next/components/ui/avatar/index.tsx b/next/components/ui/avatar/index.tsx index 31fcbdd1..b6863aa1 100644 --- a/next/components/ui/avatar/index.tsx +++ b/next/components/ui/avatar/index.tsx @@ -9,7 +9,6 @@ import { withStyleContext, useStyleContext, } from '@gluestack-ui/nativewind-utils/withStyleContext'; -import { cssInterop } from 'nativewind'; const SCOPE = 'AVATAR'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; @@ -21,12 +20,6 @@ const UIAvatar = createAvatar({ FallbackText: Text, }); -cssInterop(UIAvatar, { className: 'style' }); -cssInterop(UIAvatar.Badge, { className: 'style' }); -cssInterop(UIAvatar.Group, { className: 'style' }); -cssInterop(UIAvatar.Image, { className: 'style' }); -cssInterop(UIAvatar.FallbackText, { className: 'style' }); - const avatarStyle = tva({ base: 'rounded-full justify-center items-center relative bg-primary-600 group-[.avatar-group]/avatar-group:-ml-2.5', variants: { @@ -161,10 +154,11 @@ export const AvatarImage = React.forwardRef< className={avatarImageStyle({ class: className, })} - // @ts-ignore + // @ts-expect-error style={ Platform.OS === 'web' - ? { height: 'revert-layer', width: 'revert-layer' } + ? // eslint-disable-next-line react-native/no-inline-styles + { height: 'revert-layer', width: 'revert-layer' } : undefined } /> diff --git a/next/components/ui/badge/index.tsx b/next/components/ui/badge/index.tsx index 42bf6016..7c0c64d6 100644 --- a/next/components/ui/badge/index.tsx +++ b/next/components/ui/badge/index.tsx @@ -1,7 +1,7 @@ 'use client'; -import React, { useMemo } from 'react'; +import React from 'react'; import { Text, View } from 'react-native'; -import { Svg } from 'react-native-svg'; +import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon'; import { tva } from '@gluestack-ui/nativewind-utils/tva'; import { withStyleContext, @@ -93,58 +93,17 @@ const badgeIconStyle = tva({ }, }); -type IPrimitiveIcon = React.ComponentPropsWithoutRef & { - height?: number | string; - width?: number | string; - fill?: string; - color?: string; - size?: number | string; - stroke?: string; - as?: React.ElementType; - className?: string; -}; - -const PrimitiveIcon = React.forwardRef< - React.ElementRef, - IPrimitiveIcon ->(({ height, width, fill, color, size, stroke, as: AsComp, ...props }, ref) => { - const sizeProps = useMemo(() => { - if (size) return { size }; - if (height && width) return { height, width }; - if (height) return { height }; - if (width) return { width }; - return {}; - }, [size, height, width]); - - let colorProps = {}; - if (color) { - colorProps = { ...colorProps, color: color }; - } - if (stroke) { - colorProps = { ...colorProps, stroke: stroke }; - } - if (fill) { - colorProps = { ...colorProps, fill: fill }; - } - if (AsComp) { - return ; - } - return ( - - ); -}); - const ContextView = withStyleContext(View, SCOPE); -cssInterop(ContextView, { className: 'style' }); + cssInterop(PrimitiveIcon, { className: { target: 'style', nativeStyleToProp: { height: true, width: true, - // @ts-ignore + //@ts-expect-error fill: true, - color: true, + color: 'classNameColor', stroke: true, }, }, @@ -154,7 +113,7 @@ type IBadgeProps = React.ComponentPropsWithoutRef & VariantProps; const Badge = ({ children, - action = 'info', + action = 'muted', variant = 'solid', size = 'md', className, @@ -205,14 +164,14 @@ type IBadgeIconProps = React.ComponentPropsWithoutRef & VariantProps; const BadgeIcon = React.forwardRef< - React.ElementRef, + React.ElementRef, IBadgeIconProps >(({ className, size, ...props }, ref) => { const { size: parentSize, action: parentAction } = useStyleContext(SCOPE); if (typeof size === 'number') { return ( - ); } else if ( - (props.height !== undefined || props.width !== undefined) && + (props?.height !== undefined || props?.width !== undefined) && size === undefined ) { return ( - { - const sizeProps = useMemo(() => { - return size ? { size } : { height, width }; - }, [size, height, width]); +const SCOPE = "BUTTON"; - if (AsComp) { - return ( - - ); - } - return ( - - ); - } -); - -const SCOPE = 'BUTTON'; -const Root = - Platform.OS === 'web' - ? withStyleContext(Pressable, SCOPE) - : withStyleContextAndStates(Pressable, SCOPE); +const Root = withStyleContext(Pressable, SCOPE); const UIButton = createButton({ Root: Root, Text, Group: View, Spinner: ActivityIndicator, - Icon: PrimitiveIcon, + Icon: UIIcon, }); -cssInterop(UIButton, { className: 'style' }); -cssInterop(UIButton.Text, { className: 'style' }); -cssInterop(UIButton.Group, { className: 'style' }); -cssInterop(UIButton.Spinner, { className: 'style' }); -cssInterop(UIButton.Icon, { +cssInterop(PrimitiveIcon, { className: { - target: 'style', + target: "style", nativeStyleToProp: { - height: 'height', - width: 'width', - //@ts-ignore - fill: 'fill', - color: 'color', + height: true, + width: true, + fill: true, + color: "classNameColor", + stroke: true, }, }, }); const buttonStyle = tva({ - base: 'group/button rounded bg-primary-500 flex-row items-center justify-center data-[focus-visible=true]:web:outline-none data-[focus-visible=true]:web:ring-2 data-[disabled=true]:opacity-40', + base: "group/button rounded bg-primary-500 flex-row items-center justify-center data-[focus-visible=true]:web:outline-none data-[focus-visible=true]:web:ring-2 data-[disabled=true]:opacity-40 gap-2", variants: { action: { primary: - 'bg-primary-500 hover:bg-primary-600 active:bg-primary-700 border-primary-300 hover:border-primary-400 active:border-primary-500 data-[focus-visible=true]:web:ring-primary-300', + "bg-primary-500 data-[hover=true]:bg-primary-600 data-[active=true]:bg-primary-700 border-primary-300 data-[hover=true]:border-primary-400 data-[active=true]:border-primary-500 data-[focus-visible=true]:web:ring-indicator-info", secondary: - 'bg-secondary-500 border-secondary-300 hover:bg-secondary-600 hover:border-secondary-400 active:bg-secondary-700 active:border-secondary-500 data-[focus-visible=true]:web:ring-secondary-300', + "bg-secondary-500 border-secondary-300 data-[hover=true]:bg-secondary-600 data-[hover=true]:border-secondary-400 data-[active=true]:bg-secondary-700 data-[active=true]:border-secondary-500 data-[focus-visible=true]:web:ring-indicator-info", positive: - 'bg-success-500 border-success-300 hover:bg-success-600 hover:border-success-400 active:bg-success-700 active:border-success-500 data-[focus-visible=true]:web:ring-success-300', + "bg-success-500 border-success-300 data-[hover=true]:bg-success-600 data-[hover=true]:border-success-400 data-[active=true]:bg-success-700 data-[active=true]:border-success-500 data-[focus-visible=true]:web:ring-indicator-info", negative: - 'bg-error-500 border-error-300 hover:bg-error-600 hover:border-error-400 active:bg-error-700 active:border-error-500 data-[focus-visible=true]:web:ring-error-300', - default: 'bg-transparent hover:bg-background-50 active:bg-transparent', + "bg-error-500 border-error-300 data-[hover=true]:bg-error-600 data-[hover=true]:border-error-400 data-[active=true]:bg-error-700 data-[active=true]:border-error-500 data-[focus-visible=true]:web:ring-indicator-info", + default: + "bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent", }, variant: { - link: 'px-0', + link: "px-0", outline: - 'bg-transparent border hover:bg-background-50 active:bg-transparent', - solid: '', + "bg-transparent border data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent", + solid: "", }, size: { - xs: 'px-3.5 h-8', - sm: 'px-4 h-9', - md: 'px-5 h-10', - lg: 'px-6 h-11', + xs: "px-3.5 h-8", + sm: "px-4 h-9", + md: "px-5 h-10", + lg: "px-6 h-11", + xl: "px-7 h-12", }, }, compoundVariants: [ { - action: 'primary', - variant: 'link', - class: 'px-0 bg-transparent hover:bg-transparent active:bg-transparent', + action: "primary", + variant: "link", + class: + "px-0 bg-transparent data-[hover=true]:bg-transparent data-[active=true]:bg-transparent", }, { - action: 'secondary', - variant: 'link', - class: 'px-0 bg-transparent hover:bg-transparent active:bg-transparent', + action: "secondary", + variant: "link", + class: + "px-0 bg-transparent data-[hover=true]:bg-transparent data-[active=true]:bg-transparent", }, { - action: 'positive', - variant: 'link', - class: 'px-0 bg-transparent hover:bg-transparent active:bg-transparent', + action: "positive", + variant: "link", + class: + "px-0 bg-transparent data-[hover=true]:bg-transparent data-[active=true]:bg-transparent", }, { - action: 'negative', - variant: 'link', - class: 'px-0 bg-transparent hover:bg-transparent active:bg-transparent', + action: "negative", + variant: "link", + class: + "px-0 bg-transparent data-[hover=true]:bg-transparent data-[active=true]:bg-transparent", }, { - action: 'primary', - variant: 'outline', - class: 'bg-transparent hover:bg-background-50 active:bg-transparent', + action: "primary", + variant: "outline", + class: + "bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent", }, { - action: 'secondary', - variant: 'outline', - class: 'bg-transparent hover:bg-background-50 active:bg-transparent', + action: "secondary", + variant: "outline", + class: + "bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent", }, { - action: 'positive', - variant: 'outline', - class: 'bg-transparent hover:bg-background-50 active:bg-transparent', + action: "positive", + variant: "outline", + class: + "bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent", }, { - action: 'negative', - variant: 'outline', - class: 'bg-transparent hover:bg-background-50 active:bg-transparent', + action: "negative", + variant: "outline", + class: + "bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent", }, ], }); const buttonTextStyle = tva({ - base: 'text-typography-0 font-semibold web:select-none', + base: "text-typography-0 font-semibold web:select-none", parentVariants: { action: { primary: - 'text-primary-600 group-hover/button:text-primary-600 group-active/button:text-primary-700', + "text-primary-600 data-[hover=true]:text-primary-600 data-[active=true]:text-primary-700", secondary: - 'text-secondary-600 group-hover/button:text-secondary-600 group-active/button:text-secondary-700', + "text-secondary-600 data-[hover=true]:text-secondary-600 data-[active=true]:text-secondary-700", positive: - 'text-success-600 group-hover/button:text-success-600 group-active/button:text-success-700', + "text-success-600 data-[hover=true]:text-success-600 data-[active=true]:text-success-700", negative: - 'text-error-600 group-hover/button:text-error-600 group-active/button:text-error-700', + "text-error-600 data-[hover=true]:text-error-600 data-[active=true]:text-error-700", }, variant: { - link: 'group-hover/button:underline group-active/button:underline', - outline: '', + link: "data-[hover=true]:underline data-[active=true]:underline", + outline: "", solid: - 'text-typography-0 group-hover/button:text-typography-0 group-active/button:text-typography-0', + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", }, size: { - xs: 'text-xs', - sm: 'text-sm', - md: 'text-base', - lg: 'text-lg', + xs: "text-xs", + sm: "text-sm", + md: "text-base", + lg: "text-lg", + xl: "text-xl", }, }, parentCompoundVariants: [ { - variant: 'solid', - action: 'primary', + variant: "solid", + action: "primary", class: - 'text-typography-0 group-hover/button:text-typography-0 group-active/button:text-typography-0', + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", }, { - variant: 'solid', - action: 'secondary', + variant: "solid", + action: "secondary", class: - 'text-typography-0 group-hover/button:text-typography-0 group-active/button:text-typography-0', + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", }, { - variant: 'solid', - action: 'positive', + variant: "solid", + action: "positive", class: - 'text-typography-0 group-hover/button:text-typography-0 group-active/button:text-typography-0', + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", }, { - variant: 'solid', - action: 'negative', + variant: "solid", + action: "negative", class: - 'text-typography-0 group-hover/button:text-typography-0 group-active/button:text-typography-0', + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", + }, + { + variant: "outline", + action: "primary", + class: + "text-primary-500 data-[hover=true]:text-primary-500 data-[active=true]:text-primary-500", + }, + { + variant: "outline", + action: "secondary", + class: + "text-primary-500 data-[hover=true]:text-primary-500 data-[active=true]:text-primary-500", + }, + { + variant: "outline", + action: "positive", + class: + "text-primary-500 data-[hover=true]:text-primary-500 data-[active=true]:text-primary-500", + }, + { + variant: "outline", + action: "negative", + class: + "text-primary-500 data-[hover=true]:text-primary-500 data-[active=true]:text-primary-500", }, ], }); const buttonIconStyle = tva({ + base: "fill-none", parentVariants: { variant: { - link: 'group-hover/button:underline group-active/button:underline', - outline: '', - solid: '', + link: "data-[hover=true]:underline data-[active=true]:underline", + outline: "", + solid: + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", }, size: { - '2xs': 'h-3 w-3', - 'xs': 'h-3.5 w-3.5', - 'sm': 'h-4 w-4', - 'md': 'h-[18px] w-[18px]', - 'lg': 'h-5 w-5', - 'xl': 'h-6 w-6', + xs: "h-3.5 w-3.5", + sm: "h-4 w-4", + md: "h-[18px] w-[18px]", + lg: "h-[18px] w-[18px]", + xl: "h-5 w-5", + }, + action: { + primary: + "text-primary-600 data-[hover=true]:text-primary-600 data-[active=true]:text-primary-700", + secondary: + "text-secondary-600 data-[hover=true]:text-secondary-600 data-[active=true]:text-secondary-700", + positive: + "text-success-600 data-[hover=true]:text-success-600 data-[active=true]:text-success-700", + + negative: + "text-error-600 data-[hover=true]:text-error-600 data-[active=true]:text-error-700", }, }, + parentCompoundVariants: [ + { + variant: "solid", + action: "primary", + class: + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", + }, + { + variant: "solid", + action: "secondary", + class: + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", + }, + { + variant: "solid", + action: "positive", + class: + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", + }, + { + variant: "solid", + action: "negative", + class: + "text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0", + }, + ], }); const buttonGroupStyle = tva({ - base: '', + base: "", variants: { space: { - 'xs': 'gap-1', - 'sm': 'gap-2', - 'md': 'gap-3', - 'lg': 'gap-4', - 'xl': 'gap-5', - '2xl': 'gap-6', - '3xl': 'gap-7', - '4xl': 'gap-8', + xs: "gap-1", + sm: "gap-2", + md: "gap-3", + lg: "gap-4", + xl: "gap-5", + "2xl": "gap-6", + "3xl": "gap-7", + "4xl": "gap-8", }, isAttached: { - true: 'gap-0', + true: "gap-0", }, }, }); -type IButtonProps = Omit, 'context'> & - VariantProps; -const Button = React.forwardRef( +type IButtonProps = Omit< + React.ComponentPropsWithoutRef, + "context" +> & + VariantProps & { className?: string }; + +const Button = React.forwardRef< + React.ElementRef, + IButtonProps +>( ( - { - className, - variant = 'solid', - size = 'md', - action = 'primary', - ...props - }: { className?: string } & IButtonProps, - ref?: any + { className, variant = "solid", size = "md", action = "primary", ...props }, + ref ) => { return ( & - VariantProps; -const ButtonText = React.forwardRef( - ( - { - className, - variant, - size, - action, - ...props - }: { className?: string } & IButtonTextProps, - ref?: any - ) => { - const { - variant: parentVariant, - size: parentSize, - action: parentAction, - } = useStyleContext(SCOPE); +type IButtonTextProps = React.ComponentPropsWithoutRef & + VariantProps & { className?: string }; - return ( - - ); - } -); +const ButtonText = React.forwardRef< + React.ElementRef, + IButtonTextProps +>(({ className, variant, size, action, ...props }, ref) => { + const { + variant: parentVariant, + size: parentSize, + action: parentAction, + } = useStyleContext(SCOPE); + + return ( + + ); +}); const ButtonSpinner = UIButton.Spinner; -interface DefaultColors { - primary: string; - secondary: string; - positive: string; - negative: string; -} -const defaultColors: DefaultColors = { - primary: '#292929', - secondary: '#515252', - positive: '#2A7948', - negative: '#DC2626', -}; -type IButtonIcon = React.ComponentProps & - VariantProps; -const ButtonIcon = React.forwardRef( - ( - { - className, - size, - ...props - }: IButtonIcon & { - className?: any; - fill?: string; - color?: string; - as?: any; - }, - ref?: any - ) => { - const { - variant: parentVariant, - size: parentSize, - action: parentAction, - } = useStyleContext(SCOPE); +type IButtonIcon = React.ComponentPropsWithoutRef & + VariantProps & { + className?: string | undefined; + as?: React.ElementType; + }; - let localColor; - if (parentVariant !== 'solid') { - localColor = defaultColors[parentAction as keyof DefaultColors]; - } else { - localColor = 'gray'; - } - const { color = localColor } = props; +const ButtonIcon = React.forwardRef< + React.ElementRef, + IButtonIcon +>(({ className, size, ...props }, ref) => { + const { + variant: parentVariant, + size: parentSize, + action: parentAction, + } = useStyleContext(SCOPE); - if (typeof size === 'number') { - return ( - - ); - } else if ( - (props.height !== undefined || props.width !== undefined) && - size === undefined - ) { - return ( - - ); - } + if (typeof size === "number") { return ( ); - } -); - -type IButtonGroupProps = React.ComponentProps & - VariantProps; -const ButtonGroup = React.forwardRef( - ( - { - className, - space = 'md', - isAttached = false, - ...props - }: { className?: string } & IButtonGroupProps, - ref?: any - ) => { + } else if ( + (props?.height !== undefined || props?.width !== undefined) && + size === undefined + ) { return ( - ); } -); + return ( + + ); +}); + +type IButtonGroupProps = React.ComponentPropsWithoutRef & + VariantProps; + +const ButtonGroup = React.forwardRef< + React.ElementRef, + IButtonGroupProps +>(({ className, space = "md", isAttached = false, ...props }, ref) => { + return ( + + ); +}); -Button.displayName = 'Button'; -ButtonText.displayName = 'ButtonText'; -ButtonSpinner.displayName = 'ButtonSpinner'; -ButtonIcon.displayName = 'ButtonIcon'; -ButtonGroup.displayName = 'ButtonGroup'; +Button.displayName = "Button"; +ButtonText.displayName = "ButtonText"; +ButtonSpinner.displayName = "ButtonSpinner"; +ButtonIcon.displayName = "ButtonIcon"; +ButtonGroup.displayName = "ButtonGroup"; export { Button, ButtonText, ButtonSpinner, ButtonIcon, ButtonGroup }; diff --git a/next/components/ui/checkbox/index.tsx b/next/components/ui/checkbox/index.tsx index aaaa8f01..4e85cace 100644 --- a/next/components/ui/checkbox/index.tsx +++ b/next/components/ui/checkbox/index.tsx @@ -1,19 +1,16 @@ 'use client'; -import React, { useMemo } from 'react'; +import React from 'react'; import { createCheckbox } from '@gluestack-ui/checkbox'; -import { View, Pressable, Text } from 'react-native'; +import { View, Pressable, Text, Platform } from 'react-native'; import type { TextProps, ViewProps } from 'react-native'; import { tva } from '@gluestack-ui/nativewind-utils/tva'; -import { Svg } from 'react-native-svg'; +import { PrimitiveIcon, IPrimitiveIcon, UIIcon } from '@gluestack-ui/icon'; import { withStyleContext, useStyleContext, } from '@gluestack-ui/nativewind-utils/withStyleContext'; -import { withStyleContextAndStates } from '@gluestack-ui/nativewind-utils/withStyleContextAndStates'; import { cssInterop } from 'nativewind'; -import { withStates } from '@gluestack-ui/nativewind-utils/withStates'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; -import { Platform } from 'react-native'; const IndicatorWrapper = React.forwardRef< React.ElementRef, @@ -28,81 +25,34 @@ const LabelWrapper = React.forwardRef, TextProps>( } ); -type IPrimitiveIcon = React.ComponentPropsWithoutRef & { - height?: number | string; - width?: number | string; - fill?: string; - color?: string; - size?: number | string; - stroke?: string; - as?: React.ElementType; - className?: string; -}; - const IconWrapper = React.forwardRef< React.ElementRef, IPrimitiveIcon >(({ ...props }, ref) => { - return ; -}); - -const PrimitiveIcon = React.forwardRef< - React.ElementRef, - IPrimitiveIcon ->(({ height, width, fill, color, size, stroke, as: AsComp, ...props }, ref) => { - const sizeProps = useMemo(() => { - if (size) return { size }; - if (height && width) return { height, width }; - if (height) return { height }; - if (width) return { width }; - return {}; - }, [size, height, width]); - - let colorProps = {}; - if (color) { - colorProps = { ...colorProps, color: color }; - } - if (stroke) { - colorProps = { ...colorProps, stroke: stroke }; - } - if (fill) { - colorProps = { ...colorProps, fill: fill }; - } - if (AsComp) { - return ; - } - return ( - - ); + return ; }); const SCOPE = 'CHECKBOX'; const UICheckbox = createCheckbox({ - // @ts-ignore + // @ts-expect-error Root: Platform.OS === 'web' ? withStyleContext(View, SCOPE) - : withStyleContextAndStates(Pressable, SCOPE), - Group: Platform.OS === 'web' ? View : withStates(View), - Icon: Platform.OS === 'web' ? IconWrapper : withStates(IconWrapper), - Label: Platform.OS === 'web' ? LabelWrapper : withStates(LabelWrapper), - Indicator: - Platform.OS === 'web' ? IndicatorWrapper : withStates(IndicatorWrapper), + : withStyleContext(Pressable, SCOPE), + Group: View, + Icon: IconWrapper, + Label: LabelWrapper, + Indicator: IndicatorWrapper, }); -cssInterop(UICheckbox, { className: 'style' }); -cssInterop(UICheckbox.Group, { className: 'style' }); -cssInterop(LabelWrapper, { className: 'style' }); -cssInterop(IndicatorWrapper, { className: 'style' }); -cssInterop(IconWrapper, { +cssInterop(PrimitiveIcon, { className: { target: 'style', nativeStyleToProp: { height: true, width: true, - // @ts-ignore fill: true, - color: true, + color: 'classNameColor', stroke: true, }, }, diff --git a/next/components/ui/divider/index.tsx b/next/components/ui/divider/index.tsx index 61404a4b..e9b663a6 100644 --- a/next/components/ui/divider/index.tsx +++ b/next/components/ui/divider/index.tsx @@ -1,9 +1,7 @@ 'use client'; import React from 'react'; -import { createDivider } from '@gluestack-ui/divider'; import { tva } from '@gluestack-ui/nativewind-utils/tva'; -import { View } from 'react-native'; -import { cssInterop } from 'nativewind'; +import { Platform, View } from 'react-native'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; const dividerStyle = tva({ @@ -16,21 +14,19 @@ const dividerStyle = tva({ }, }); -const UIDivider = createDivider({ Root: View }); - -cssInterop(UIDivider, { className: 'style' }); - -type IUIDividerProps = React.ComponentPropsWithoutRef & +type IUIDividerProps = React.ComponentPropsWithoutRef & VariantProps; const Divider = React.forwardRef< - React.ElementRef, + React.ElementRef, IUIDividerProps >(({ className, orientation = 'horizontal', ...props }, ref) => { return ( - & + VariantProps & { className?: string }; + +type IDrawerBackdropProps = React.ComponentProps & + VariantProps & { className?: string }; + +type IDrawerContentProps = React.ComponentProps & + VariantProps & { className?: string }; + +type IDrawerHeaderProps = React.ComponentProps & + VariantProps & { className?: string }; + +type IDrawerBodyProps = React.ComponentProps & + VariantProps & { className?: string }; + +type IDrawerFooterProps = React.ComponentProps & + VariantProps & { className?: string }; + +type IDrawerCloseButtonProps = React.ComponentProps< + typeof UIDrawer.CloseButton +> & + VariantProps & { className?: string }; + +const Drawer = React.forwardRef< + React.ElementRef, + IDrawerProps +>(({ className, size = 'sm', anchor = 'left', ...props }, ref) => { + return ( + + ); +}); + +const DrawerBackdrop = React.forwardRef< + React.ElementRef, + IDrawerBackdropProps +>(({ className, ...props }, ref) => { + return ( + + ); +}); + +const DrawerContent = React.forwardRef< + React.ElementRef, + IDrawerContentProps +>(({ className, ...props }, ref) => { + const { size: parentSize, anchor: parentAnchor } = useStyleContext(SCOPE); + + const drawerHeight = screenHeight * (sizes[parentSize] || sizes.md); + const drawerWidth = screenWidth * (sizes[parentSize] || sizes.md); + + const isHorizontal = parentAnchor === 'left' || parentAnchor === 'right'; + + const initialObj = isHorizontal + ? { x: parentAnchor === 'left' ? -drawerWidth : drawerWidth } + : { y: parentAnchor === 'top' ? -drawerHeight : drawerHeight }; + + const animateObj = isHorizontal ? { x: 0 } : { y: 0 }; + + const exitObj = isHorizontal + ? { x: parentAnchor === 'left' ? -drawerWidth : drawerWidth } + : { y: parentAnchor === 'top' ? -drawerHeight : drawerHeight }; + + const customClass = isHorizontal + ? `top-0 ${parentAnchor === 'left' ? 'left-0' : 'right-0'}` + : `left-0 ${parentAnchor === 'top' ? 'top-0' : 'bottom-0'}`; + + return ( + + ); +}); + +const DrawerHeader = React.forwardRef< + React.ElementRef, + IDrawerHeaderProps +>(({ className, ...props }, ref) => { + return ( + + ); +}); + +const DrawerBody = React.forwardRef< + React.ElementRef, + IDrawerBodyProps +>(({ className, ...props }, ref) => { + return ( + + ); +}); + +const DrawerFooter = React.forwardRef< + React.ElementRef, + IDrawerFooterProps +>(({ className, ...props }, ref) => { + return ( + + ); +}); + +const DrawerCloseButton = React.forwardRef< + React.ElementRef, + IDrawerCloseButtonProps +>(({ className, ...props }, ref) => { + return ( + + ); +}); + +Drawer.displayName = 'Drawer'; +DrawerBackdrop.displayName = 'DrawerBackdrop'; +DrawerContent.displayName = 'DrawerContent'; +DrawerHeader.displayName = 'DrawerHeader'; +DrawerBody.displayName = 'DrawerBody'; +DrawerFooter.displayName = 'DrawerFooter'; +DrawerCloseButton.displayName = 'DrawerCloseButton'; + +export { + Drawer, + DrawerBackdrop, + DrawerContent, + DrawerCloseButton, + DrawerHeader, + DrawerBody, + DrawerFooter, +}; diff --git a/next/components/ui/fab/index.tsx b/next/components/ui/fab/index.tsx index f1544824..98840f89 100644 --- a/next/components/ui/fab/index.tsx +++ b/next/components/ui/fab/index.tsx @@ -1,80 +1,32 @@ 'use client'; -import React, { useMemo } from 'react'; +import React from 'react'; import { createFab } from '@gluestack-ui/fab'; -import { Platform, Text } from 'react-native'; -import { Pressable } from 'react-native'; -import { Svg } from 'react-native-svg'; +import { Pressable, Text } from 'react-native'; import { tva } from '@gluestack-ui/nativewind-utils/tva'; import { withStyleContext, useStyleContext, } from '@gluestack-ui/nativewind-utils/withStyleContext'; -import { withStyleContextAndStates } from '@gluestack-ui/nativewind-utils/withStyleContextAndStates'; import { cssInterop } from 'nativewind'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; - -type IPrimitiveIcon = React.ComponentPropsWithoutRef & { - height?: number | string; - width?: number | string; - fill?: string; - color?: string; - size?: number | string; - stroke?: string; - as?: React.ElementType; - className?: string; -}; - -const PrimitiveIcon = React.forwardRef< - React.ElementRef, - IPrimitiveIcon ->(({ height, width, fill, color, size, stroke, as: AsComp, ...props }, ref) => { - const sizeProps = useMemo(() => { - if (size) return { size }; - if (height && width) return { height, width }; - if (height) return { height }; - if (width) return { width }; - return {}; - }, [size, height, width]); - - let colorProps = {}; - if (color) { - colorProps = { ...colorProps, color: color }; - } - if (stroke) { - colorProps = { ...colorProps, stroke: stroke }; - } - if (fill) { - colorProps = { ...colorProps, fill: fill }; - } - if (AsComp) { - return ; - } - return ( - - ); -}); +import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon'; const SCOPE = 'FAB'; +const Root = withStyleContext(Pressable, SCOPE); const UIFab = createFab({ - Root: - Platform.OS === 'web' - ? withStyleContext(Pressable, SCOPE) - : withStyleContextAndStates(Pressable, SCOPE), + Root: Root, Label: Text, - Icon: PrimitiveIcon, + Icon: UIIcon, }); -cssInterop(UIFab, { className: 'style' }); -cssInterop(UIFab.Label, { className: 'style' }); -cssInterop(UIFab.Icon, { +cssInterop(PrimitiveIcon, { className: { target: 'style', nativeStyleToProp: { height: true, width: true, - // @ts-ignore fill: true, - color: true, + color: 'classNameColor', stroke: true, }, }, @@ -147,7 +99,7 @@ const fabLabelStyle = tva({ }); const fabIconStyle = tva({ - base: 'text-typography-50 hover:text-typography-0 active:text-typography-0 fill-none', + base: 'text-typography-50 fill-none', variants: { size: { '2xs': 'h-3 w-3', diff --git a/next/components/ui/form-control/index.tsx b/next/components/ui/form-control/index.tsx index fcdf8cc1..895b207a 100644 --- a/next/components/ui/form-control/index.tsx +++ b/next/components/ui/form-control/index.tsx @@ -1,7 +1,6 @@ 'use client'; import { Text, View } from 'react-native'; -import React, { useMemo } from 'react'; -import { Svg } from 'react-native-svg'; +import React from 'react'; import { createFormControl } from '@gluestack-ui/form-control'; import { tva } from '@gluestack-ui/nativewind-utils/tva'; import { @@ -10,50 +9,10 @@ import { } from '@gluestack-ui/nativewind-utils/withStyleContext'; import { cssInterop } from 'nativewind'; import type { VariantProps } from '@gluestack-ui/nativewind-utils'; +import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon'; const SCOPE = 'FORM_CONTROL'; -type IPrimitiveIcon = React.ComponentPropsWithoutRef & { - height?: number | string; - width?: number | string; - fill?: string; - color?: string; - size?: number | string; - stroke?: string; - as?: React.ElementType; - className?: string; -}; - -const PrimitiveIcon = React.forwardRef< - React.ElementRef, - IPrimitiveIcon ->(({ height, width, fill, color, size, stroke, as: AsComp, ...props }, ref) => { - const sizeProps = useMemo(() => { - if (size) return { size }; - if (height && width) return { height, width }; - if (height) return { height }; - if (width) return { width }; - return {}; - }, [size, height, width]); - - let colorProps = {}; - if (color) { - colorProps = { ...colorProps, color: color }; - } - if (stroke) { - colorProps = { ...colorProps, stroke: stroke }; - } - if (fill) { - colorProps = { ...colorProps, fill: fill }; - } - if (AsComp) { - return ; - } - return ( - - ); -}); - const formControlStyle = tva({ base: 'flex flex-col', variants: { @@ -278,7 +237,7 @@ export const UIFormControl = createFormControl({ Root: withStyleContext(View, SCOPE), Error: View, ErrorText: Text, - ErrorIcon: PrimitiveIcon, + ErrorIcon: UIIcon, Label: View, LabelText: Text, LabelAstrick: FormControlLabelAstrick, @@ -286,20 +245,12 @@ export const UIFormControl = createFormControl({ HelperText: Text, }); -cssInterop(UIFormControl, { className: 'style' }); -cssInterop(UIFormControl.Error, { className: 'style' }); -cssInterop(UIFormControl.Error.Text, { className: 'style' }); -cssInterop(UIFormControl.Label, { className: 'style' }); -cssInterop(UIFormControl.Label.Text, { className: 'style' }); -cssInterop(UIFormControl.Helper, { className: 'style' }); -cssInterop(UIFormControl.Helper.Text, { className: 'style' }); -cssInterop(UIFormControl.Error.Icon, { +cssInterop(PrimitiveIcon, { className: { target: 'style', nativeStyleToProp: { height: true, width: true, - // @ts-ignore fill: true, color: true, stroke: true, diff --git a/next/components/ui/gluestack-ui-provider/config.js b/next/components/ui/gluestack-ui-provider/config.js deleted file mode 100644 index 0a06501d..00000000 --- a/next/components/ui/gluestack-ui-provider/config.js +++ /dev/null @@ -1,304 +0,0 @@ -"use client"; -import { vars } from "nativewind"; -export const config = { - light: vars({ - "--color-primary-0": "#B3B3B3", - "--color-primary-50": "#999999", - "--color-primary-100": "#808080", - "--color-primary-200": "#737373", - "--color-primary-300": "#666666", - "--color-primary-400": "#525252", - "--color-primary-500": "#333333", - "--color-primary-600": "#292929", - "--color-primary-700": "#1F1F1F", - "--color-primary-800": "#0D0D0D", - "--color-primary-900": "#0A0A0A", - "--color-primary-950": "#080808", - /* Secondary */ - "--color-secondary-0": "#FEFFFF", - "--color-secondary-50": "#F1F2F2", - "--color-secondary-100": "#E7E8E8", - "--color-secondary-200": "#DBDBDB", - "--color-secondary-300": "#AFB0B0", - "--color-secondary-400": "#727373", - "--color-secondary-500": "#5E5F5F", - "--color-secondary-600": "#515252", - "--color-secondary-700": "#3F4040", - "--color-secondary-800": "#272626", - "--color-secondary-900": "#181717", - "--color-secondary-950": "#0B0C0C", - /* Tertiary */ - "--color-tertiary-0": "#FFFAF5", - "--color-tertiary-50": "#FFF2E5", - "--color-tertiary-100": "#FFE9D5", - "--color-tertiary-200": "#FED1AA", - "--color-tertiary-300": "#FDB474", - "--color-tertiary-400": "#FB9D4B", - "--color-tertiary-500": "#E78128", - "--color-tertiary-600": "#D7751F", - "--color-tertiary-700": "#B4621A", - "--color-tertiary-800": "#824917", - "--color-tertiary-900": "#6C3D13", - "--color-tertiary-950": "#543112", - /* Error */ - "--color-error-0": "#FEE9E9", - "--color-error-50": "#FEE2E2", - "--color-error-100": "#FECACA", - "--color-error-200": "#FCA5A5", - "--color-error-300": "#F87171", - "--color-error-400": "#EF4444", - "--color-error-500": "#E63535", - "--color-error-600": "#DC2626", - "--color-error-700": "#B91C1C", - "--color-error-800": "#991B1B", - "--color-error-900": "#7F1D1D", - "--color-error-950": "#531313", - /* Success */ - "--color-success-0": "#E4FFF4", - "--color-success-50": "#CAFFE8", - "--color-success-100": "#A2F1C0", - "--color-success-200": "#84D3A2", - "--color-success-300": "#66B584", - "--color-success-400": "#489766", - "--color-success-500": "#348352", - "--color-success-600": "#2A7948", - "--color-success-700": "#206F3E", - "--color-success-800": "#166534", - "--color-success-900": "#14532D", - "--color-success-950": "#1B3224", - /* Warning */ - "--color-warning-0": "#FFFDFB", - "--color-warning-50": "#FFF9F5", - "--color-warning-100": "#FFE7D5", - "--color-warning-200": "#FECDAA", - "--color-warning-300": "#FDAD74", - "--color-warning-400": "#FB954B", - "--color-warning-500": "#E77828", - "--color-warning-600": "#D76C1F", - "--color-warning-700": "#B45A1A", - "--color-warning-800": "#824417", - "--color-warning-900": "#6C3813", - "--color-warning-950": "#542D12", - /* Info */ - "--color-info-0": "#ECF8FE", - "--color-info-50": "#C7EBFC", - "--color-info-100": "#A2DDFA", - "--color-info-200": "#7CCFF8", - "--color-info-300": "#57C2F6", - "--color-info-400": "#32B4F4", - "--color-info-500": "#0DA6F2", - "--color-info-600": "#0B8DCD", - "--color-info-700": "#0973A8", - "--color-info-800": "#075A83", - "--color-info-900": "#05405D", - "--color-info-950": "#032638", - /* Typography */ - "--color-typography-0": "#FEFEFF", - "--color-typography-50": "#F5F5F5", - "--color-typography-100": "#E5E5E5", - "--color-typography-200": "#DBDBDC", - "--color-typography-300": "#D4D4D4", - "--color-typography-400": "#A3A3A3", - "--color-typography-500": "#8C8C8C", - "--color-typography-600": "#737373", - "--color-typography-700": "#525252", - "--color-typography-800": "#404040", - "--color-typography-900": "#262627", - "--color-typography-950": "#171717", - /* Outline */ - "--color-outline-0": "#FDFEFE", - "--color-outline-50": "#F3F3F3", - "--color-outline-100": "#E6E6E6", - "--color-outline-200": "#DDDCDB", - "--color-outline-300": "#D3D3D3", - "--color-outline-400": "#A5A3A3", - "--color-outline-500": "#8C8D8D", - "--color-outline-600": "#737474", - "--color-outline-700": "#535252", - "--color-outline-800": "#414141", - "--color-outline-900": "#272624", - "--color-outline-950": "#1A1717", - /* Background */ - "--color-background-0": "#FFFFFF", - "--color-background-50": "#F6F6F6", - "--color-background-100": "#F2F1F1", - "--color-background-200": "#DCDBDB", - "--color-background-300": "#D5D4D4", - "--color-background-400": "#A2A3A3", - "--color-background-500": "#8E8E8E", - "--color-background-600": "#747474", - "--color-background-700": "#535252", - "--color-background-800": "#414040", - "--color-background-900": "#272625", - "--color-background-950": "#181718", - /* Background Special */ - "--color-background-error": "#FEF1F1", - "--color-background-warning": "#FFF4EB", - "--color-background-success": "#EDFCF2", - "--color-background-muted": "#F6F6F7", - "--color-background-info": "#EBF8FE", - /* Border */ - "--color-border-0": "#FDFEFE", - "--color-border-50": "#F3F3F3", - "--color-border-100": "#E6E6E6", - "--color-border-200": "#DDDCDB", - "--color-border-300": "#D3D3D3", - "--color-border-400": "#A5A3A3", - "--color-border-500": "#8C8D8D", - "--color-border-600": "#737474", - "--color-border-700": "#535252", - "--color-border-800": "#414141", - "--color-border-900": "#272624", - "--color-border-950": "#1A1717", - }), - dark: vars({ - "--color-primary-0": "#828282", - "--color-primary-50": "#949494", - "--color-primary-100": "#9E9E9E", - "--color-primary-200": "#B3B3B3", - "--color-primary-300": "#C7C7C7", - "--color-primary-400": "#E6E6E6", - "--color-primary-500": "#F0F0F0", - "--color-primary-600": "#FAFAFA", - "--color-primary-700": "#FCFCFC", - "--color-primary-800": "#FDFDFD", - "--color-primary-900": "#FDFCFC", - "--color-primary-950": "#FDFCFC", - /* Secondary */ - "--color-secondary-0": "#0B0C0C", - "--color-secondary-50": "#181717", - "--color-secondary-100": "#272626", - "--color-secondary-200": "#3F4040", - "--color-secondary-300": "#515252", - "--color-secondary-400": "#5E5F5F", - "--color-secondary-500": "#727373", - "--color-secondary-600": "#AFB0B0", - "--color-secondary-700": "#DBDBDB", - "--color-secondary-800": "#E7E8E8", - "--color-secondary-900": "#F1F2F2", - "--color-secondary-950": "#FEFFFF", - /* Tertiary */ - "--color-tertiary-0": "#543112", - "--color-tertiary-50": "#6C3D13", - "--color-tertiary-100": "#824917", - "--color-tertiary-200": "#B4621A", - "--color-tertiary-300": "#D7751F", - "--color-tertiary-400": "#E78128", - "--color-tertiary-500": "#FB9D4B", - "--color-tertiary-600": "#FDB474", - "--color-tertiary-700": "#FED1AA", - "--color-tertiary-800": "#FFE9D5", - "--color-tertiary-900": "#FFF2E5", - "--color-tertiary-950": "#FFFAF5", - /* Error */ - "--color-error-0": "#531313", - "--color-error-50": "#7F1D1D", - "--color-error-100": "#991B1B", - "--color-error-200": "#B91C1C", - "--color-error-300": "#DC2626", - "--color-error-400": "#E63535", - "--color-error-500": "#EF4444", - "--color-error-600": "#F87171", - "--color-error-700": "#E63534", - "--color-error-800": "#FECACA", - "--color-error-900": "#FEE2E2", - "--color-error-950": "#FEE9E9", - /* Success */ - "--color-success-0": "#1B3224", - "--color-success-50": "#14532D", - "--color-success-100": "#166534", - "--color-success-200": "#206F3E", - "--color-success-300": "#2A7948", - "--color-success-400": "#348352", - "--color-success-500": "#489766", - "--color-success-600": "#66B584", - "--color-success-700": "#84D3A2", - "--color-success-800": "#A2F1C0", - "--color-success-900": "#CAFFE8", - "--color-success-950": "#E4FFF4", - /* Warning */ - "--color-warning-0": "#542D12", - "--color-warning-50": "#6C3813", - "--color-warning-100": "#824417", - "--color-warning-200": "#B45A1A", - "--color-warning-300": "#D76C1F", - "--color-warning-400": "#E77828", - "--color-warning-500": "#FB954B", - "--color-warning-600": "#FDAD74", - "--color-warning-700": "#FECDAA", - "--color-warning-800": "#FFE7D5", - "--color-warning-900": "#FFF9F5", - "--color-warning-950": "#FFFDFB", - /* Info */ - "--color-info-0": "#032638", - "--color-info-50": "#05405D", - "--color-info-100": "#075A83", - "--color-info-200": "#0973A8", - "--color-info-300": "#0B8DCD", - "--color-info-400": "#0DA6F2", - "--color-info-500": "#32B4F4", - "--color-info-600": "#57C2F6", - "--color-info-700": "#7CCFF8", - "--color-info-800": "#A2DDFA", - "--color-info-900": "#C7EBFC", - "--color-info-950": "#ECF8FE", - /* Typography */ - "--color-typography-0": "#171717", - "--color-typography-50": "#262627", - "--color-typography-100": "#404040", - "--color-typography-200": "#525252", - "--color-typography-300": "#737373", - "--color-typography-400": "#8C8C8C", - "--color-typography-500": "#A3A3A3", - "--color-typography-600": "#D4D4D4", - "--color-typography-700": "#DBDBDC", - "--color-typography-800": "#E5E5E5", - "--color-typography-900": "#F5F5F5", - "--color-typography-950": "#FEFEFF", - /* Outline */ - "--color-outline-0": "#1A1717", - "--color-outline-50": "#272624", - "--color-outline-100": "#414141", - "--color-outline-200": "#535252", - "--color-outline-300": "#737474", - "--color-outline-400": "#8C8D8D", - "--color-outline-500": "#A5A3A3", - "--color-outline-600": "#D3D3D3", - "--color-outline-700": "#DDDCDB", - "--color-outline-800": "#E6E6E6", - "--color-outline-900": "#F3F3F3", - "--color-outline-950": "#FDFEFE", - /* Background */ - "--color-background-0": "#121212", - "--color-background-50": "#272625", - "--color-background-100": "#414040", - "--color-background-200": "#535252", - "--color-background-300": "#747474", - "--color-background-400": "#8E8E8E", - "--color-background-500": "#A2A3A3", - "--color-background-600": "#D5D4D4", - "--color-background-700": "#DCDBDB", - "--color-background-800": "#F2F1F1", - "--color-background-900": "#F6F6F6", - "--color-background-950": "#FEFEFE", - /* Background Special */ - "--color-background-error": "#422B2B", - "--color-background-warning": "#412F23", - "--color-background-success": "#1C2B21", - "--color-background-muted": "#252526", - "--color-background-info": "#1A282E", - /* Border */ - "--color-border-0": "#1A1717", - "--color-border-50": "#272624", - "--color-border-100": "#414141", - "--color-border-200": "#535252", - "--color-border-300": "#737474", - "--color-border-400": "#8C8D8D", - "--color-border-500": "#A5A3A3", - "--color-border-600": "#D3D3D3", - "--color-border-700": "#DDDCDB", - "--color-border-800": "#E6E6E6", - "--color-border-900": "#F3F3F3", - "--color-border-950": "#FDFEFE", - }), -}; diff --git a/next/components/ui/gluestack-ui-provider/config.ts b/next/components/ui/gluestack-ui-provider/config.ts index 3b42a91a..f388cc6e 100644 --- a/next/components/ui/gluestack-ui-provider/config.ts +++ b/next/components/ui/gluestack-ui-provider/config.ts @@ -1,326 +1,309 @@ -"use client"; -import { vars } from "nativewind"; +'use client'; +import { vars } from 'nativewind'; export const config = { light: vars({ - "--color-primary-0": "#B3B3B3", - "--color-primary-50": "#999999", - "--color-primary-100": "#808080", - "--color-primary-200": "#737373", - "--color-primary-300": "#666666", - "--color-primary-400": "#525252", - "--color-primary-500": "#333333", - "--color-primary-600": "#292929", - "--color-primary-700": "#1F1F1F", - "--color-primary-800": "#0D0D0D", - "--color-primary-900": "#0A0A0A", - "--color-primary-950": "#080808", + '--color-primary-0': '179 179 179', + '--color-primary-50': '153 153 153', + '--color-primary-100': '128 128 128', + '--color-primary-200': '115 115 115', + '--color-primary-300': '102 102 102', + '--color-primary-400': '82 82 82', + '--color-primary-500': '51 51 51', + '--color-primary-600': '41 41 41', + '--color-primary-700': '31 31 31', + '--color-primary-800': '13 13 13', + '--color-primary-900': '10 10 10', + '--color-primary-950': '8 8 8', /* Secondary */ - "--color-secondary-0": "#FEFFFF", - "--color-secondary-50": "#F1F2F2", - "--color-secondary-100": "#E7E8E8", - "--color-secondary-200": "#DBDBDB", - "--color-secondary-300": "#AFB0B0", - "--color-secondary-400": "#727373", - "--color-secondary-500": "#5E5F5F", - "--color-secondary-600": "#515252", - "--color-secondary-700": "#3F4040", - "--color-secondary-800": "#272626", - "--color-secondary-900": "#181717", - "--color-secondary-950": "#0B0C0C", + '--color-secondary-0': '253 253 253', + '--color-secondary-50': '251 251 251', + '--color-secondary-100': '246 246 246', + '--color-secondary-200': '242 242 242', + '--color-secondary-300': '237 237 237', + '--color-secondary-400': '230 230 231', + '--color-secondary-500': '217 217 219', + '--color-secondary-600': '198 199 199', + '--color-secondary-700': '189 189 189', + '--color-secondary-800': '177 177 177', + '--color-secondary-900': '165 164 164', + '--color-secondary-950': '157 157 157', /* Tertiary */ - "--color-tertiary-0": "#FFFAF5", - "--color-tertiary-50": "#FFF2E5", - "--color-tertiary-100": "#FFE9D5", - "--color-tertiary-200": "#FED1AA", - "--color-tertiary-300": "#FDB474", - "--color-tertiary-400": "#FB9D4B", - "--color-tertiary-500": "#E78128", - "--color-tertiary-600": "#D7751F", - "--color-tertiary-700": "#B4621A", - "--color-tertiary-800": "#824917", - "--color-tertiary-900": "#6C3D13", - "--color-tertiary-950": "#543112", + '--color-tertiary-0': '255 250 245', + '--color-tertiary-50': '255 242 229', + '--color-tertiary-100': '255 233 213', + '--color-tertiary-200': '254 209 170', + '--color-tertiary-300': '253 180 116', + '--color-tertiary-400': '251 157 75', + '--color-tertiary-500': '231 129 40', + '--color-tertiary-600': '215 117 31', + '--color-tertiary-700': '180 98 26', + '--color-tertiary-800': '130 73 23', + '--color-tertiary-900': '108 61 19', + '--color-tertiary-950': '84 49 18', /* Error */ - "--color-error-0": "#FEE9E9", - "--color-error-50": "#FEE2E2", - "--color-error-100": "#FECACA", - "--color-error-200": "#FCA5A5", - "--color-error-300": "#F87171", - "--color-error-400": "#EF4444", - "--color-error-500": "#E63535", - "--color-error-600": "#DC2626", - "--color-error-700": "#B91C1C", - "--color-error-800": "#991B1B", - "--color-error-900": "#7F1D1D", - "--color-error-950": "#531313", + '--color-error-0': '254 233 233', + '--color-error-50': '254 226 226', + '--color-error-100': '254 202 202', + '--color-error-200': '252 165 165', + '--color-error-300': '248 113 113', + '--color-error-400': '239 68 68', + '--color-error-500': '230 53 53', + '--color-error-600': '220 38 38', + '--color-error-700': '185 28 28', + '--color-error-800': '153 27 27', + '--color-error-900': '127 29 29', + '--color-error-950': '83 19 19', /* Success */ - "--color-success-0": "#E4FFF4", - "--color-success-50": "#CAFFE8", - "--color-success-100": "#A2F1C0", - "--color-success-200": "#84D3A2", - "--color-success-300": "#66B584", - "--color-success-400": "#489766", - "--color-success-500": "#348352", - "--color-success-600": "#2A7948", - "--color-success-700": "#206F3E", - "--color-success-800": "#166534", - "--color-success-900": "#14532D", - "--color-success-950": "#1B3224", + '--color-success-0': '228 255 244', + '--color-success-50': '202 255 232', + '--color-success-100': '162 241 192', + '--color-success-200': '132 211 162', + '--color-success-300': '102 181 132', + '--color-success-400': '72 151 102', + '--color-success-500': '52 131 82', + '--color-success-600': '42 121 72', + '--color-success-700': '32 111 62', + '--color-success-800': '22 101 52', + '--color-success-900': '20 83 45', + '--color-success-950': '27 50 36', /* Warning */ - "--color-warning-0": "#FFFDFB", - "--color-warning-50": "#FFF9F5", - "--color-warning-100": "#FFE7D5", - "--color-warning-200": "#FECDAA", - "--color-warning-300": "#FDAD74", - "--color-warning-400": "#FB954B", - "--color-warning-500": "#E77828", - "--color-warning-600": "#D76C1F", - "--color-warning-700": "#B45A1A", - "--color-warning-800": "#824417", - "--color-warning-900": "#6C3813", - "--color-warning-950": "#542D12", + '--color-warning-0': '255 249 245', + '--color-warning-50': '255 244 236', + '--color-warning-100': '255 231 213', + '--color-warning-200': '254 205 170', + '--color-warning-300': '253 173 116', + '--color-warning-400': '251 149 75', + '--color-warning-500': '231 120 40', + '--color-warning-600': '215 108 31', + '--color-warning-700': '180 90 26', + '--color-warning-800': '130 68 23', + '--color-warning-900': '108 56 19', + '--color-warning-950': '84 45 18', /* Info */ - "--color-info-0": "#ECF8FE", - "--color-info-50": "#C7EBFC", - "--color-info-100": "#A2DDFA", - "--color-info-200": "#7CCFF8", - "--color-info-300": "#57C2F6", - "--color-info-400": "#32B4F4", - "--color-info-500": "#0DA6F2", - "--color-info-600": "#0B8DCD", - "--color-info-700": "#0973A8", - "--color-info-800": "#075A83", - "--color-info-900": "#05405D", - "--color-info-950": "#032638", + '--color-info-0': '236 248 254', + '--color-info-50': '199 235 252', + '--color-info-100': '162 221 250', + '--color-info-200': '124 207 248', + '--color-info-300': '87 194 246', + '--color-info-400': '50 180 244', + '--color-info-500': '13 166 242', + '--color-info-600': '11 141 205', + '--color-info-700': '9 115 168', + '--color-info-800': '7 90 131', + '--color-info-900': '5 64 93', + '--color-info-950': '3 38 56', /* Typography */ - "--color-typography-0": "#FEFEFF", - "--color-typography-50": "#F5F5F5", - "--color-typography-100": "#E5E5E5", - "--color-typography-200": "#DBDBDC", - "--color-typography-300": "#D4D4D4", - "--color-typography-400": "#A3A3A3", - "--color-typography-500": "#8C8C8C", - "--color-typography-600": "#737373", - "--color-typography-700": "#525252", - "--color-typography-800": "#404040", - "--color-typography-900": "#262627", - "--color-typography-950": "#171717", + '--color-typography-0': '254 254 255', + '--color-typography-50': '245 245 245', + '--color-typography-100': '229 229 229', + '--color-typography-200': '219 219 220', + '--color-typography-300': '212 212 212', + '--color-typography-400': '163 163 163', + '--color-typography-500': '140 140 140', + '--color-typography-600': '115 115 115', + '--color-typography-700': '82 82 82', + '--color-typography-800': '64 64 64', + '--color-typography-900': '38 38 39', + '--color-typography-950': '23 23 23', /* Outline */ - "--color-outline-0": "#FDFEFE", - "--color-outline-50": "#F3F3F3", - "--color-outline-100": "#E6E6E6", - "--color-outline-200": "#DDDCDB", - "--color-outline-300": "#D3D3D3", - "--color-outline-400": "#A5A3A3", - "--color-outline-500": "#8C8D8D", - "--color-outline-600": "#737474", - "--color-outline-700": "#535252", - "--color-outline-800": "#414141", - "--color-outline-900": "#272624", - "--color-outline-950": "#1A1717", + '--color-outline-0': '253 254 254', + '--color-outline-50': '243 243 243', + '--color-outline-100': '230 230 230', + '--color-outline-200': '221 220 219', + '--color-outline-300': '211 211 211', + '--color-outline-400': '165 163 163', + '--color-outline-500': '140 141 141', + '--color-outline-600': '115 116 116', + '--color-outline-700': '83 82 82', + '--color-outline-800': '65 65 65', + '--color-outline-900': '39 38 36', + '--color-outline-950': '26 23 23', + /* Background */ - "--color-background-0": "#FFFFFF", - "--color-background-50": "#F6F6F6", - "--color-background-100": "#F2F1F1", - "--color-background-200": "#DCDBDB", - "--color-background-300": "#D5D4D4", - "--color-background-400": "#A2A3A3", - "--color-background-500": "#8E8E8E", - "--color-background-600": "#747474", - "--color-background-700": "#535252", - "--color-background-800": "#414040", - "--color-background-900": "#272625", - "--color-background-950": "#181718", + '--color-background-0': '255 255 255', + '--color-background-50': '246 246 246', + '--color-background-100': '242 241 241', + '--color-background-200': '220 219 219', + '--color-background-300': '213 212 212', + '--color-background-400': '162 163 163', + '--color-background-500': '142 142 142', + '--color-background-600': '116 116 116', + '--color-background-700': '83 82 82', + '--color-background-800': '65 64 64', + '--color-background-900': '39 38 37', + '--color-background-950': '18 18 18', /* Background Special */ - "--color-background-error": "#FEF1F1", - "--color-background-warning": "#FFF4EB", - "--color-background-success": "#EDFCF2", - "--color-background-muted": "#F6F6F7", - "--color-background-info": "#EBF8FE", + '--color-background-error': '254 241 241', + '--color-background-warning': '255 243 234', + '--color-background-success': '237 252 242', + '--color-background-muted': '247 248 247', + '--color-background-info': '235 248 254', - /* Border */ - "--color-border-0": "#FDFEFE", - "--color-border-50": "#F3F3F3", - "--color-border-100": "#E6E6E6", - "--color-border-200": "#DDDCDB", - "--color-border-300": "#D3D3D3", - "--color-border-400": "#A5A3A3", - "--color-border-500": "#8C8D8D", - "--color-border-600": "#737474", - "--color-border-700": "#535252", - "--color-border-800": "#414141", - "--color-border-900": "#272624", - "--color-border-950": "#1A1717", + /* Focus Ring Indicator */ + '--color-indicator-primary': '55 55 55', + '--color-indicator-info': '83 153 236', + '--color-indicator-error': '185 28 28', }), dark: vars({ - "--color-primary-0": "#828282", - "--color-primary-50": "#949494", - "--color-primary-100": "#9E9E9E", - "--color-primary-200": "#B3B3B3", - "--color-primary-300": "#C7C7C7", - "--color-primary-400": "#E6E6E6", - "--color-primary-500": "#F0F0F0", - "--color-primary-600": "#FAFAFA", - "--color-primary-700": "#FCFCFC", - "--color-primary-800": "#FDFDFD", - "--color-primary-900": "#FDFCFC", - "--color-primary-950": "#FDFCFC", + '--color-primary-0': '166 166 166', + '--color-primary-50': '175 175 175', + '--color-primary-100': '186 186 186', + '--color-primary-200': '197 197 197', + '--color-primary-300': '212 212 212', + '--color-primary-400': '221 221 221', + '--color-primary-500': '230 230 230', + '--color-primary-600': '240 240 240', + '--color-primary-700': '250 250 250', + '--color-primary-800': '253 253 253', + '--color-primary-900': '254 249 249', + '--color-primary-950': '253 252 252', /* Secondary */ - "--color-secondary-0": "#0B0C0C", - "--color-secondary-50": "#181717", - "--color-secondary-100": "#272626", - "--color-secondary-200": "#3F4040", - "--color-secondary-300": "#515252", - "--color-secondary-400": "#5E5F5F", - "--color-secondary-500": "#727373", - "--color-secondary-600": "#AFB0B0", - "--color-secondary-700": "#DBDBDB", - "--color-secondary-800": "#E7E8E8", - "--color-secondary-900": "#F1F2F2", - "--color-secondary-950": "#FEFFFF", + '--color-secondary-0': '20 20 20', + '--color-secondary-50': '23 23 23', + '--color-secondary-100': '31 31 31', + '--color-secondary-200': '39 39 39', + '--color-secondary-300': '44 44 44', + '--color-secondary-400': '56 57 57', + '--color-secondary-500': '63 64 64', + '--color-secondary-600': '86 86 86', + '--color-secondary-700': '110 110 110', + '--color-secondary-800': '135 135 135', + '--color-secondary-900': '150 150 150', + '--color-secondary-950': '164 164 164', /* Tertiary */ - "--color-tertiary-0": "#543112", - "--color-tertiary-50": "#6C3D13", - "--color-tertiary-100": "#824917", - "--color-tertiary-200": "#B4621A", - "--color-tertiary-300": "#D7751F", - "--color-tertiary-400": "#E78128", - "--color-tertiary-500": "#FB9D4B", - "--color-tertiary-600": "#FDB474", - "--color-tertiary-700": "#FED1AA", - "--color-tertiary-800": "#FFE9D5", - "--color-tertiary-900": "#FFF2E5", - "--color-tertiary-950": "#FFFAF5", + '--color-tertiary-0': '84 49 18', + '--color-tertiary-50': '108 61 19', + '--color-tertiary-100': '130 73 23', + '--color-tertiary-200': '180 98 26', + '--color-tertiary-300': '215 117 31', + '--color-tertiary-400': '231 129 40', + '--color-tertiary-500': '251 157 75', + '--color-tertiary-600': '253 180 116', + '--color-tertiary-700': '254 209 170', + '--color-tertiary-800': '255 233 213', + '--color-tertiary-900': '255 242 229', + '--color-tertiary-950': '255 250 245', /* Error */ - "--color-error-0": "#531313", - "--color-error-50": "#7F1D1D", - "--color-error-100": "#991B1B", - "--color-error-200": "#B91C1C", - "--color-error-300": "#DC2626", - "--color-error-400": "#E63535", - "--color-error-500": "#EF4444", - "--color-error-600": "#F87171", - "--color-error-700": "#E63534", - "--color-error-800": "#FECACA", - "--color-error-900": "#FEE2E2", - "--color-error-950": "#FEE9E9", + '--color-error-0': '83 19 19', + '--color-error-50': '127 29 29', + '--color-error-100': '153 27 27', + '--color-error-200': '185 28 28', + '--color-error-300': '220 38 38', + '--color-error-400': '230 53 53', + '--color-error-500': '239 68 68', + '--color-error-600': '249 97 96', + '--color-error-700': '229 91 90', + '--color-error-800': '254 202 202', + '--color-error-900': '254 226 226', + '--color-error-950': '254 233 233', /* Success */ - "--color-success-0": "#1B3224", - "--color-success-50": "#14532D", - "--color-success-100": "#166534", - "--color-success-200": "#206F3E", - "--color-success-300": "#2A7948", - "--color-success-400": "#348352", - "--color-success-500": "#489766", - "--color-success-600": "#66B584", - "--color-success-700": "#84D3A2", - "--color-success-800": "#A2F1C0", - "--color-success-900": "#CAFFE8", - "--color-success-950": "#E4FFF4", + '--color-success-0': '27 50 36', + '--color-success-50': '20 83 45', + '--color-success-100': '22 101 52', + '--color-success-200': '32 111 62', + '--color-success-300': '42 121 72', + '--color-success-400': '52 131 82', + '--color-success-500': '72 151 102', + '--color-success-600': '102 181 132', + '--color-success-700': '132 211 162', + '--color-success-800': '162 241 192', + '--color-success-900': '202 255 232', + '--color-success-950': '228 255 244', /* Warning */ - "--color-warning-0": "#542D12", - "--color-warning-50": "#6C3813", - "--color-warning-100": "#824417", - "--color-warning-200": "#B45A1A", - "--color-warning-300": "#D76C1F", - "--color-warning-400": "#E77828", - "--color-warning-500": "#FB954B", - "--color-warning-600": "#FDAD74", - "--color-warning-700": "#FECDAA", - "--color-warning-800": "#FFE7D5", - "--color-warning-900": "#FFF9F5", - "--color-warning-950": "#FFFDFB", + '--color-warning-0': '84 45 18', + '--color-warning-50': '108 56 19', + '--color-warning-100': '130 68 23', + '--color-warning-200': '180 90 26', + '--color-warning-300': '215 108 31', + '--color-warning-400': '231 120 40', + '--color-warning-500': '251 149 75', + '--color-warning-600': '253 173 116', + '--color-warning-700': '254 205 170', + '--color-warning-800': '255 231 213', + '--color-warning-900': '255 244 237', + '--color-warning-950': '255 249 245', /* Info */ - "--color-info-0": "#032638", - "--color-info-50": "#05405D", - "--color-info-100": "#075A83", - "--color-info-200": "#0973A8", - "--color-info-300": "#0B8DCD", - "--color-info-400": "#0DA6F2", - "--color-info-500": "#32B4F4", - "--color-info-600": "#57C2F6", - "--color-info-700": "#7CCFF8", - "--color-info-800": "#A2DDFA", - "--color-info-900": "#C7EBFC", - "--color-info-950": "#ECF8FE", + '--color-info-0': '3 38 56', + '--color-info-50': '5 64 93', + '--color-info-100': '7 90 131', + '--color-info-200': '9 115 168', + '--color-info-300': '11 141 205', + '--color-info-400': '13 166 242', + '--color-info-500': '50 180 244', + '--color-info-600': '87 194 246', + '--color-info-700': '124 207 248', + '--color-info-800': '162 221 250', + '--color-info-900': '199 235 252', + '--color-info-950': '236 248 254', /* Typography */ - "--color-typography-0": "#171717", - "--color-typography-50": "#262627", - "--color-typography-100": "#404040", - "--color-typography-200": "#525252", - "--color-typography-300": "#737373", - "--color-typography-400": "#8C8C8C", - "--color-typography-500": "#A3A3A3", - "--color-typography-600": "#D4D4D4", - "--color-typography-700": "#DBDBDC", - "--color-typography-800": "#E5E5E5", - "--color-typography-900": "#F5F5F5", - "--color-typography-950": "#FEFEFF", + '--color-typography-0': '23 23 23', + '--color-typography-50': '38 38 39', + '--color-typography-100': '64 64 64', + '--color-typography-200': '82 82 82', + '--color-typography-300': '115 115 115', + '--color-typography-400': '140 140 140', + '--color-typography-500': '163 163 163', + '--color-typography-600': '212 212 212', + '--color-typography-700': '219 219 220', + '--color-typography-800': '229 229 229', + '--color-typography-900': '245 245 245', + '--color-typography-950': '254 254 255', /* Outline */ - "--color-outline-0": "#1A1717", - "--color-outline-50": "#272624", - "--color-outline-100": "#414141", - "--color-outline-200": "#535252", - "--color-outline-300": "#737474", - "--color-outline-400": "#8C8D8D", - "--color-outline-500": "#A5A3A3", - "--color-outline-600": "#D3D3D3", - "--color-outline-700": "#DDDCDB", - "--color-outline-800": "#E6E6E6", - "--color-outline-900": "#F3F3F3", - "--color-outline-950": "#FDFEFE", + '--color-outline-0': '26 23 23', + '--color-outline-50': '39 38 36', + '--color-outline-100': '65 65 65', + '--color-outline-200': '83 82 82', + '--color-outline-300': '115 116 116', + '--color-outline-400': '140 141 141', + '--color-outline-500': '165 163 163', + '--color-outline-600': '211 211 211', + '--color-outline-700': '221 220 219', + '--color-outline-800': '230 230 230', + '--color-outline-900': '243 243 243', + '--color-outline-950': '253 254 254', /* Background */ - "--color-background-0": "#121212", - "--color-background-50": "#272625", - "--color-background-100": "#414040", - "--color-background-200": "#535252", - "--color-background-300": "#747474", - "--color-background-400": "#8E8E8E", - "--color-background-500": "#A2A3A3", - "--color-background-600": "#D5D4D4", - "--color-background-700": "#DCDBDB", - "--color-background-800": "#F2F1F1", - "--color-background-900": "#F6F6F6", - "--color-background-950": "#FEFEFE", + '--color-background-0': '18 18 18', + '--color-background-50': '39 38 37', + '--color-background-100': '65 64 64', + '--color-background-200': '83 82 82', + '--color-background-300': '116 116 116', + '--color-background-400': '142 142 142', + '--color-background-500': '162 163 163', + '--color-background-600': '213 212 212', + '--color-background-700': '229 228 228', + '--color-background-800': '242 241 241', + '--color-background-900': '246 246 246', + '--color-background-950': '255 255 255', /* Background Special */ - "--color-background-error": "#422B2B", - "--color-background-warning": "#412F23", - "--color-background-success": "#1C2B21", - "--color-background-muted": "#252526", - "--color-background-info": "#1A282E", + '--color-background-error': '66 43 43', + '--color-background-warning': '65 47 35', + '--color-background-success': '28 43 33', + '--color-background-muted': '51 51 51', + '--color-background-info': '26 40 46', - /* Border */ - "--color-border-0": "#1A1717", - "--color-border-50": "#272624", - "--color-border-100": "#414141", - "--color-border-200": "#535252", - "--color-border-300": "#737474", - "--color-border-400": "#8C8D8D", - "--color-border-500": "#A5A3A3", - "--color-border-600": "#D3D3D3", - "--color-border-700": "#DDDCDB", - "--color-border-800": "#E6E6E6", - "--color-border-900": "#F3F3F3", - "--color-border-950": "#FDFEFE", + /* Focus Ring Indicator */ + '--color-indicator-primary': '247 247 247', + '--color-indicator-info': '161 199 245', + '--color-indicator-error': '232 70 69', }), }; diff --git a/next/components/ui/gluestack-ui-provider/index.tsx b/next/components/ui/gluestack-ui-provider/index.tsx index 4dc2cfe6..4855e434 100644 --- a/next/components/ui/gluestack-ui-provider/index.tsx +++ b/next/components/ui/gluestack-ui-provider/index.tsx @@ -1,22 +1,42 @@ import React from 'react'; import { config } from './config'; -import { View } from 'react-native'; +import { ColorSchemeName, useColorScheme, View, ViewProps } from 'react-native'; import { OverlayProvider } from '@gluestack-ui/overlay'; import { ToastProvider } from '@gluestack-ui/toast'; +import { colorScheme as colorSchemeNW } from 'nativewind'; + +type ModeType = 'light' | 'dark' | 'system'; + +const getColorSchemeName = ( + colorScheme: ColorSchemeName, + mode: ModeType +): 'light' | 'dark' => { + if (mode === 'system') { + return colorScheme ?? 'light'; + } + return mode; +}; export function GluestackUIProvider({ mode = 'light', ...props }: { - mode?: 'light' | 'dark'; - children?: any; + mode?: 'light' | 'dark' | 'system'; + children?: React.ReactNode; + style?: ViewProps['style']; }) { + const colorScheme = useColorScheme(); + + const colorSchemeName = getColorSchemeName(colorScheme, mode); + + colorSchemeNW.set(mode); + return ( diff --git a/next/components/ui/gluestack-ui-provider/index.web.tsx b/next/components/ui/gluestack-ui-provider/index.web.tsx index 086a7295..30cadaaa 100644 --- a/next/components/ui/gluestack-ui-provider/index.web.tsx +++ b/next/components/ui/gluestack-ui-provider/index.web.tsx @@ -1,36 +1,94 @@ 'use client'; -import React from 'react'; +import React, { useEffect, useLayoutEffect } from 'react'; import { config } from './config'; import { OverlayProvider } from '@gluestack-ui/overlay'; import { ToastProvider } from '@gluestack-ui/toast'; import { setFlushStyles } from '@gluestack-ui/nativewind-utils/flush'; +import { script } from './script'; + +const variableStyleTagId = 'nativewind-style'; +const createStyle = (styleTagId: string) => { + const style = document.createElement('style'); + style.id = styleTagId; + style.appendChild(document.createTextNode('')); + return style; +}; + +export const useSafeLayoutEffect = + typeof window !== 'undefined' ? useLayoutEffect : useEffect; export function GluestackUIProvider({ mode = 'light', ...props }: { - mode?: 'light' | 'dark'; - children?: any; + mode?: 'light' | 'dark' | 'system'; + children?: React.ReactNode; }) { - const stringcssvars = Object.keys(config[mode]).reduce((acc, cur) => { - acc += `${cur}:${config[mode][cur]};`; - return acc; - }, ''); - setFlushStyles(`:root {${stringcssvars}} `); - - if (config[mode] && typeof document !== 'undefined') { - const element = document.documentElement; - if (element) { - const head = element.querySelector('head'); - const style = document.createElement('style'); - style.innerHTML = `:root {${stringcssvars}} `; - if (head) head.appendChild(style); + let cssVariablesWithMode = ``; + Object.keys(config).forEach((configKey) => { + cssVariablesWithMode += + configKey === 'dark' ? `\n .dark {\n ` : `\n:root {\n`; + const cssVariables = Object.keys( + config[configKey as keyof typeof config] + ).reduce((acc: string, curr: string) => { + acc += `${curr}:${config[configKey as keyof typeof config][curr]}; `; + return acc; + }, ''); + cssVariablesWithMode += `${cssVariables} \n}`; + }); + + setFlushStyles(cssVariablesWithMode); + + const handleMediaQuery = React.useCallback((e: MediaQueryListEvent) => { + script(e.matches ? 'dark' : 'light'); + }, []); + + useSafeLayoutEffect(() => { + if (mode !== 'system') { + const documentElement = document.documentElement; + if (documentElement) { + documentElement.classList.add(mode); + documentElement.classList.remove(mode === 'light' ? 'dark' : 'light'); + documentElement.style.colorScheme = mode; + } + } + }, [mode]); + + useSafeLayoutEffect(() => { + if (mode !== 'system') return; + const media = window.matchMedia('(prefers-color-scheme: dark)'); + + media.addListener(handleMediaQuery); + + return () => media.removeListener(handleMediaQuery); + }, [handleMediaQuery]); + + useSafeLayoutEffect(() => { + if (typeof window !== 'undefined') { + const documentElement = document.documentElement; + if (documentElement) { + const head = documentElement.querySelector('head'); + let style = head?.querySelector(`[id='${variableStyleTagId}']`); + if (!style) { + style = createStyle(variableStyleTagId); + style.innerHTML = cssVariablesWithMode; + if (head) head.appendChild(style); + } + } } - } + }, []); return ( - - {props.children} - + <> +