antd5 自定义主题

import React, { useState } from "react";

import { ConfigProvider, Space, Tooltip } from 'antd';

import { ThemeConfig } from "antd/es/config-provider";

import { ThemeType } from '@/interfaces/interfaces';

import {

    CheckOutlined,

} from '@ant-design/icons';

import store from '@/store';

//主题色组件接口接参类型类型

export interface ThemeSelectionProps {

    themeColor: string,

    colorName: string,

    data?: ThemeType

}

//主题色组件 (该组件在使用时需在使用处最外层限定高度)

export function ThemeSelection(c: ThemeSelectionProps[]) {

    const [selection, setSelection] = useState<string>(c[0].colorName)

    return (

        <>

            <Space>

                {

                    c.map((item: ThemeSelectionProps) => {

                        return (

                            <Tooltip key={item.themeColor} title={item.colorName}>

                                <div

                                    style={{

                                        backgroundColor: item.themeColor,

                                        textAlign: "center",

                                        width: "20px",

                                        height: "20px",

                                        cursor: "pointer",

                                    }}

                                    onClick={() => {

                                        setSelection(item.colorName)

                                        //采用了状态共享(https://www.npmjs.com/package/rekv)

                                        store.setState({ colorData: item.data })

                                    }}>

                                    {item.colorName == selection &&

                                        <CheckOutlined style={{ color: "white" }} />

                                    }

                                </div>

                            </Tooltip>

                        )

                    })

                }

            </Space>

        </>

    )

}

//自定义ui组件主题接口接类型

interface ComponentTokenProps {

    name: string,

    componentToken: ThemeConfig

}

//主题色包裹 (原理:将需要换肤的组件传入,借助高阶组件优势,使其在传入组件外套一层ConfigProvider 借助antd5中的token属性实现样式控制)

//参数t有三种情况

//1.不传参数时组件采用 defaultTheme 值  使用场景:全局组件和局部组件的主题统一不冲突的情况。  

//2.传参 string时(不能传空字符串,使用空字符串则会直接使用 defaultTheme 值),需要先在themeData 中定义组件名字(优先采用antd组件名称)和需要用到的ThemeConfig属性 使用场景:多个组件样式不统一的情况下

//3.直接传参 具有ThemeConfig 属性的值

export function ThemeControl(jsx: JSX.Element, t?: ThemeConfig | string) {

    //采用了状态共享(https://www.npmjs.com/package/rekv)

    const { colorData } = store.useState('colorData');

    const defaultTheme: ThemeConfig = {

        token: {

            colorPrimary: "#ffffff",

            colorBgContainer: colorData.sidebarOnebg,

            colorText: colorData.modulehrbj,

            motionDurationSlow: "0.3s",

            controlItemBgActive: colorData.themebg,

            colorBgElevated: colorData.sidebarTwobg,

        }

    }

    const themeData: ComponentTokenProps[] = [

        {

            name: "Menu",

            componentToken: {

                token: {

                    colorPrimary: "#ffffff",

                    colorBgContainer: colorData.sidebarOnebg,

                    colorText: colorData.modulehrbj,

                    motionDurationSlow: "0.3s",

                    controlItemBgActive: colorData.themebg,

                    colorBgElevated: colorData.sidebarTwobg,

                },

                components: {

                    Menu: {

                        subMenuItemBg: colorData.sidebarTwobg,

                        itemSelectedBg: colorData.topbg,

                        popupBg: colorData.sidebarTwobg,

                        itemHoverBg: colorData.topbg,

                        collapsedWidth: 56,

                        iconSize: 18,

                        collapsedIconSize: 18,

                    }

                }

            }

        },

        {

            name: "Modal",

            componentToken: {

                components: {

                    Modal: {

                        titleColor: colorData.themebg

                    }

                }

            }

        }

    ]

    const ComponentTheme = (data: ComponentTokenProps[], token?: ThemeConfig | string) => {

        switch (typeof (token)) {

            case "string":

                return data.find((item: ComponentTokenProps) => {

                    return item.name === token ? item : ""

                })?.componentToken

            case "object":

                return token

            default:

                return defaultTheme

        }

    }

    return <>

        <ConfigProvider

            theme={ComponentTheme(themeData, t) || defaultTheme}

        >

            {jsx}

        </ConfigProvider>

    </>

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值