reactjs 如何风格脉轮用户界面吐司-与颜色-与脉轮用户界面/React2.4.2和下一个v13

r1wp621o  于 2022-12-29  发布在  React
关注(0)|答案(3)|浏览(127)
    • bounty将在5天后过期**。回答此问题可获得+100声望奖励。Mel希望引起更多人对此问题的关注:我试图找到一种方法来风格脉轮用户界面烤面包与品牌颜色。文档似乎是不正确的。

我正在尝试弄清楚如何添加颜色和backgroundColor样式到我的脉轮UI吐司。
我有一个祝酒词部分:

import type { UseToastOptions } from "@chakra-ui/react"
import { useToast as useChakraToast } from "@chakra-ui/react"

export function useToast() {
  const toast = useChakraToast()
  const handleToast = (props: UseToastOptions) => {
    toast({
      position: "bottom-right",
      isClosable: true,
      status: "success",

      ...props,
    })
  }
  return handleToast
}

我也尝试过使用它,效果很好,但我无法添加颜色样式:

import { useApolloClient } from "@apollo/client"
import { useRouter } from "next/router"

import { useToast } from "./useToast"

export const useLogout = () => {
  const client = useApolloClient()
  const router = useRouter()
  const toast = useToast()
  const handleLogout = async () => {
    await router.replace("/logout")
    await fetch("/api/logout", { method: "post" })
    await client.resetStore()
    toast({ description: "Successfully logged out!" } )
  }
  return handleLogout
}

I'd like to find a way to make success equal color: "brand.white" and bg: "brand.green" in the useToast component - but it wont accept those values. I also cant add them in the logout toast.
我能把它们放在哪里?
我尝试向theme. tsx添加属性,如下所示:

components: {
    Button,
    Input,
    Select,
    Textarea,
    // I tried Alert and ToastOptions instead of Toast, but it doesn't make any difference 
    Toast: {
      baseStyle: {},
      defaultProps: {},
      variants: {
        // I tried sprinkling this everywhere - it doesn't make any difference
        background: "unset",
        solid: {
        background: "unset",
        success: {
          background: "unset",
          bg: "brand.green",
          color: "brand.white",
        },
        error: {
          bg: "brand.red",
          color: "brand.white",
        },
        info: {
          bg: "brand.blue",
          color: "brand.white",
        }

      },
      },
    },

但toast组件没有观察到它们。我还尝试将组件头从Toast更改为Alert和ToastOptions,但这两种尝试都不起作用。
注意到this page of the chakra UI docs,我尝试为警报样式创建一个定制组件,如下所示:

import { alertAnatomy } from '@chakra-ui/anatomy'
import { createMultiStyleConfigHelpers } from '@chakra-ui/react'

const { definePartsStyle, defineMultiStyleConfig } =
  createMultiStyleConfigHelpers(alertAnatomy.keys)

const baseStyle = definePartsStyle({
  // define the part you're going to style
        variants: {
            solid: {
            background: "unset",
            success: {
                background: "unset",
                bg: "brand.green",
                color: "brand.white",
            },
            error: {
                background: "unset",
                bg: "brand.tomato",
                color: "brand.white",
            },
            info: {
                background: "unset",
                bg: "brand.blue",
                color: "brand.sludge",
            }
        }  
      

  },
})

export const alertTheme = defineMultiStyleConfig({ baseStyle })

VSCode告诉我:
模块"@chakra-ui/react "没有导出的成员" createMultiStyleConfigHelpers "
我用的是"@chakra-ui/react ":"2.4.4",并且不能让脉轮ui docs中显示的方法起作用。

    • 下次尝试:**

我看到this post报告了下一个v13的问题。我试着固定到v2.4.4和2.4.2。目前,我在2.4.2上(似乎有一个与2.4.4的兼容性问题)。
当我尝试创建一个alert. ts文件时,绿色背景表示成功,红色背景表示错误(在extendTheme中定义为品牌颜色),如下所示:

import { alertAnatomy } from '@chakra-ui/anatomy';
import {
  createMultiStyleConfigHelpers,
} from '@chakra-ui/react';

const { definePartsStyle, defineMultiStyleConfig } =
  createMultiStyleConfigHelpers(alertAnatomy.keys);

// 👇 Defining styles for the first custom variant
const customSuccess = definePartsStyle({
  container: {
    border: '1px solid',
    borderColor: 'brand.green',
    background: 'brand.green',
    
    _dark: {
      borderColor: 'brand.green',
      background: 'brand.green',
      
    },
  },
  title: {
    color: 'brand.white',
    _dark: {
      color: 'brand.white',
    },
  },
  description: {
    color: 'brand.white',
    _dark: {
      color: 'brand.white',
    },
  },
});

// 👇 Defining styles for the second custom variant
const customError = definePartsStyle({
  container: {
    border: '1px solid',
    borderColor: 'brand.tomato',
    background: 'brand.tomato',
    _dark: {
      borderColor: 'brand.tomato',
      background: 'brand.tomato',
    },
  },
  title: {
    color: 'brand.white',
    _dark: {
      color: 'brand.white',
    },
  },
  description: {
    color: 'brand.white',
    _dark: {
      color: 'brand.white',
    },
  },
});

const alertTheme = defineMultiStyleConfig({
  variants: { customSuccess, customError },
});

export default alertTheme

然后,我将其导入到extendTheme中,并尝试在toast中使用它,如下所示:

{
            onSuccess: async () => {
              await fetch("api/issue", { method: "delete" }),
                toast({
                  title: "deleted",
                  description: "Your entry has been deleted",
                  status: "success",
                  variant: "customSuccess"
                })
    
              refetchAllIssueGroups()
            },
          },

当我尝试这个的时候,我得到的是白色背景和黑色文字。不管成功还是失败,我得到的都是同样的黑白。
查克拉能够在警报中使用品牌颜色吗?
我的useToastOptions. ts文件具有:

import { AlertProps, AlertStatus } from '@chakra-ui/alert';
import { SystemStyleObject, ThemingProps, StyleProps, useChakra, ColorMode } from '@chakra-ui/system';
import * as react from 'react';
import { Variants } from 'framer-motion';
import { PortalProps } from '@chakra-ui/portal';

declare type LogicalToastPosition = "top-start" | "top-end" | "bottom-start" | "bottom-end";
declare type ToastPositionWithLogical = LogicalToastPosition | "top" | "top-left" | "top-right" | "bottom" | "bottom-left" | "bottom-right";
declare type ToastPosition = Exclude<ToastPositionWithLogical, LogicalToastPosition>;
declare function getToastPlacement(position: ToastPosition | undefined, dir: "ltr" | "rtl"): ToastPosition | undefined;

interface RenderProps extends UseToastOptions {
    /**
     * Function to close the toast
     */
    onClose(): void;
}
declare type ToastMessage = (props: RenderProps) => React.ReactNode;
declare type ToastId = string | number;
interface ToastOptions {
    /**
     * The element or component type to render.
     * The component will be passed `id` and `onClose`
     */
    message: ToastMessage;
    /**
     * The toast's id
     */
    id: ToastId;
    /**
     * The duration of the toast
     */
    duration: number | null;
    /**
     * The status of the toast's alert component.
     */
    status: Status;
    /**
     * Function that removes the toast from manager's state.
     */
    onRequestRemove(): void;
    /**
     * The position of the toast
     */
    position: ToastPosition;
    /**
     * Callback function to run side effects after the toast has closed.
     */
    onCloseComplete?(): void;
    /**
     * Internally used to queue closing a toast. Should probably not be used by
     * anyone else, but documented regardless.
     */
    requestClose?: boolean;
    /**
     * Optional style overrides for the toast component.
     */
    containerStyle?: SystemStyleObject;
}
declare type ToastState = {
    [K in ToastPosition]: ToastOptions[];
};
declare type Status = "default" | "success" | "error" | "warning" | "info" | "loading";
declare type UpdateFn = (state: ToastState) => void;
declare type CloseAllToastsOptions = {
    positions?: ToastPosition[];
};

interface ToastProps extends UseToastOptions, Omit<AlertProps, keyof UseToastOptions> {
    onClose?: () => void;
}
/**
 * The `Toast` component is used to give feedback to users after an action has taken place.
 *
 * @see Docs https://chakra-ui.com/docs/components/toast
 */
declare const Toast: React.FC<ToastProps>;
declare function createRenderToast(options?: UseToastOptions & {
    toastComponent?: React.FC<ToastProps>;
}): react.FC<RenderProps>;
declare type UseToastPromiseOption = Omit<UseToastOptions, "status">;
declare function createToastFn(dir: "ltr" | "rtl", defaultOptions?: UseToastOptions): {
    (options?: UseToastOptions): ToastId;
    update(id: ToastId, options: Omit<UseToastOptions, "id">): void;
    promise<Result extends unknown, Err extends Error = Error>(promise: Promise<Result>, options: {
        success: MaybeFunction<UseToastPromiseOption, [Result]>;
        error: MaybeFunction<UseToastPromiseOption, [Err]>;
        loading: UseToastPromiseOption;
    }): void;
    closeAll: (options?: CloseAllToastsOptions | undefined) => void;
    close: (id: ToastId) => void;
    isActive: (id: ToastId) => boolean;
};
declare type CreateToastFnReturn = ReturnType<typeof createToastFn>;
declare type MaybeFunction<T, Args extends unknown[] = []> = T | ((...args: Args) => T);

interface UseToastOptions extends ThemingProps<"Alert"> {
    /**
     * The placement of the toast
     *
     * @default "bottom"
     */
    position?: ToastPosition;
    /**
     * The delay before the toast hides (in milliseconds)
     * If set to `null`, toast will never dismiss.
     *
     * @default 5000 ( = 5000ms )
     */
    duration?: ToastOptions["duration"];
    /**
     * Render a component toast component.
     * Any component passed will receive 2 props: `id` and `onClose`.
     */
    render?(props: RenderProps): React.ReactNode;
    /**
     * The title of the toast
     */
    title?: React.ReactNode;
    /**
     * The description of the toast
     */
    description?: React.ReactNode;
    /**
     * If `true`, toast will show a close button
     */
    isClosable?: boolean;
    /**
     * The status of the toast.
     */
    status?: AlertStatus;
    /**
     * A custom icon that will be displayed by the toast.
     */
    icon?: React.ReactNode;
    /**
     * The `id` of the toast.
     *
     * Mostly used when you need to prevent duplicate.
     * By default, we generate a unique `id` for each toast
     */
    id?: ToastId;
    /**
     * Callback function to run side effects after the toast has closed.
     */
    onCloseComplete?: () => void;
    /**
     * Optional style overrides for the container wrapping the toast component.
     */
    containerStyle?: StyleProps;
}
/**
 * React hook used to create a function that can be used
 * to show toasts in an application.
 */
declare function useToast(defaultOptions?: UseToastOptions): CreateToastFnReturn;

interface ToastComponentProps extends ToastOptions, Pick<ToastProviderProps, "motionVariants" | "toastSpacing"> {
}

interface ToastMethods {
    /**
     * Function to actually create a toast and add it
     * to state at the specified position
     */
    notify: (message: ToastMessage, options?: CreateToastOptions) => ToastId;
    /**
     * Close all toasts at once.
     * If given positions, will only close those.
     */
    closeAll: (options?: CloseAllToastsOptions) => void;
    /**
     * Requests to close a toast based on its id and position
     */
    close: (id: ToastId) => void;
    /**
     * Update a specific toast with new options based on the
     * passed `id`
     */
    update: (id: ToastId, options: Omit<UseToastOptions, "id">) => void;
    isActive: (id: ToastId) => boolean;
}
declare type CreateToastOptions = Partial<Pick<ToastOptions, "status" | "duration" | "position" | "id" | "onCloseComplete" | "containerStyle">>;
declare type ToastProviderProps = React.PropsWithChildren<{
    /**
     * Default options for `useToast(options)`
     *
     * @example
     * <ToastProvider defaultOptions={{ duration: 10_000, isClosable: true }} />
     */
    defaultOptions?: UseToastOptions;
    /**
     * Customize the default motion config to animate the toasts your way
     *
     * @example
     * const motionVariants =
     * <ToastProvider motionVariants={motionVariants} />
     */
    motionVariants?: Variants;
    /**
     * Are you looking for a way to style the toast? Use a custom `Alert` variant in the theme.
     * This property overrides the default ToastComponent with your own implementation.
     *
     * @example
     * const CustomToastComponent = (props: ToastComponentProps) => ...
     * <ToastProvider component={CustomToastComponent} />
     *
     * @default ToastComponent
     */
    component?: React.FC<ToastComponentProps>;
    /**
     * Define the margin between toasts
     *
     * @default 0.5rem
     */
    toastSpacing?: string | number;
    /**
     * Props to be forwarded to the portal component
     */
    portalProps?: Pick<PortalProps, "appendToParentPortal" | "containerRef">;
}>;
/**
 * Manages the creation, and removal of toasts
 * across all corners ("top", "bottom", etc.)
 */
declare const ToastProvider: (props: ToastProviderProps) => JSX.Element;

interface CreateStandAloneToastParam extends Partial<ReturnType<typeof useChakra> & {
    setColorMode: (value: ColorMode) => void;
    defaultOptions: UseToastOptions;
}>, Omit<ToastProviderProps, "children"> {
}
declare const defaultStandaloneParam: CreateStandAloneToastParam & Required<Omit<CreateStandAloneToastParam, keyof ToastProviderProps>>;
declare type CreateStandaloneToastReturn = {
    ToastContainer: () => JSX.Element;
    toast: CreateToastFnReturn;
};
/**
 * Create a toast
 */
declare function createStandaloneToast({ theme, colorMode, toggleColorMode, setColorMode, defaultOptions, motionVariants, toastSpacing, component, forced, }?: CreateStandAloneToastParam): CreateStandaloneToastReturn;

export { CloseAllToastsOptions, CreateStandAloneToastParam, CreateStandaloneToastReturn, CreateToastFnReturn, CreateToastOptions, LogicalToastPosition, RenderProps, Status, Toast, ToastId, ToastMessage, ToastMethods, ToastOptions, ToastPosition, ToastPositionWithLogical, ToastProps, ToastProvider, ToastProviderProps, ToastState, UpdateFn, UseToastOptions, createRenderToast, createStandaloneToast, createToastFn, defaultStandaloneParam, getToastPlacement, useToast };
wfveoks0

wfveoks01#

我在设计Alert组件的样式时也遇到了同样的问题,经过一番研究,我设法在theme.js中更改组件样式,如下所示:

//_app.js
import { theme } from 'theme';

<ChakraProvider theme={theme}>
//... 
</ChakraProvider >

//theme.js

import { extendTheme } from '@chakra-ui/react';

const textStyles = {...}
const colors = {...}

const components = {
  Alert: {
    variants: {
      solid: {
        container: {
          bg: '#fff',
          ...
        },
        title: {
          color: 'brand',
        },
        description: {
          ...
        },
        icon: {
          ...
        },
      },
    },
  },
};

export const theme = extendTheme({ colors, components, textStyles });
sxpgvts3

sxpgvts32#

在chakra-ui中使用自定义烤面包更有用。

const toast = useToast()
toast({
      duration: 4000,
      isClosable: true,
      render: () => (
        <CustomToast
          description="Your Description"
          status="success" // "info" | "error"
        />
      ),
    })

和自定义toast组件可能会使用chakra的Alert组件。

<Alert status={status}> {description} </ Alert>
5w9g7ksd

5w9g7ksd3#

根据脉轮UI document,一个基本的解决方案是为Alert创建自定义变量,它由Toast内部使用,因此Toast可以通过使用变量来设置样式。
当在新安装的脉轮用户界面环境中使用基本设置进行测试时,导入createMultiStyleConfigHelpers似乎没有发生错误。
下面是一个简单的现场演示,用于测试:stackblitz.
首先在theme中定义自定义变量的样式:

// '@chakra-ui/anatomy' may need to be installed

import { alertAnatomy } from '@chakra-ui/anatomy';
import {
  ChakraProvider,
  extendTheme,
  createMultiStyleConfigHelpers,
} from '@chakra-ui/react';

const { definePartsStyle, defineMultiStyleConfig } =
  createMultiStyleConfigHelpers(alertAnatomy.keys);

// 👇 Defining styles for the first custom variant
const customSuccess = definePartsStyle({
  container: {
    border: '1px solid',
    borderColor: 'teal.200',
    background: 'teal.500',
    _dark: {
      borderColor: 'teal.600',
      background: 'teal.800',
    },
  },
  title: {
    color: 'pink.200',
    _dark: {
      color: 'pink.200',
    },
  },
});

// 👇 Defining styles for the second custom variant
const customError = definePartsStyle({
  container: {
    border: '1px solid',
    borderColor: 'pink.200',
    background: 'pink.400',
    _dark: {
      borderColor: 'pink.600',
      background: 'pink.800',
    },
  },
  title: {
    color: 'teal.200',
    _dark: {
      color: 'teal.300',
    },
  },
});

const alertTheme = defineMultiStyleConfig({
  variants: { customSuccess, customError },
});

export const theme = extendTheme({
  components: {
    Alert: alertTheme,
  },
});

然后应用于useToast,其variant属性使用为Alert设置的相同变体:
x一个一个一个一个x一个一个二个x

相关问题