元素在 Tailwind Play 中运行良好,但在实际页面中运行不佳

问题描述 投票:0回答:1

我正在尝试为可能有图标和标签的按钮创建可重用的组件。我在我的项目中使用 React+Next 和 Tailwind。默认/空闲状态是正确的,但悬停状态则不正确。当我将鼠标悬停在它上面时,它只改变了按钮的背景颜色,而不是图标和标签。然而,当我在 Tailwind Play 中尝试时,效果很好。

这是通用按钮的类:

按钮方案.tsx:

'use client'
export type HexColor = `#${string}`;

export enum ButtonType {
    PRIMARY,
    SECONDARY,
    PRIMARY_ICON,
}

export enum ButtonWidth {
    FIT = 'w-fit',
    REG = 'w-[115px]'
}

export enum ButtonHeight {
    FIT = 'h-fit',
    MINI = 'h-[20px]',
    REG = 'h-[40px]'
}

export enum FontSize {
    SMALL = 'text-sm',
    BASE = 'text-base'
}

export interface ButtonColors {
    bgColorIdle: HexColor
    bgColorHover: HexColor
    bgColorDisable: HexColor
    labelColorIdle: HexColor
    labelColorHover: HexColor
    labelColorDisable: HexColor
}

export interface ButtonSizes {
    width: ButtonWidth
    height: ButtonHeight
    fontSize: FontSize
}

export const buttonSizeSchemes: { [type: string]: ButtonSizes; } = {
    [ButtonType.PRIMARY]: {
        width: ButtonWidth.REG,
        height: ButtonHeight.REG,
        fontSize: FontSize.BASE
    },
    [ButtonType.SECONDARY]: {
        width: ButtonWidth.REG,
        height: ButtonHeight.REG,
        fontSize: FontSize.BASE
    },
    [ButtonType.PRIMARY_ICON]: {
        width: ButtonWidth.FIT,
        height: ButtonHeight.REG,
        fontSize: FontSize.BASE
    },
}

export const buttonColorSchemes: { [type: string]: ButtonColors; } = {
    [ButtonType.PRIMARY]: {
        bgColorIdle: '#FA8A0A',
        bgColorHover: '#E37900',
        bgColorDisable: '#EEF0F3',
        labelColorIdle: '#FFFFFF',
        labelColorHover: '#FFFFFF',
        labelColorDisable: '#CDD2DB'
    },
    [ButtonType.SECONDARY]: {
        bgColorIdle: '#F3F6F9',
        bgColorHover: '#DDE1E7',
        bgColorDisable: '#EEF0F3',
        labelColorIdle: '#333333',
        labelColorHover: '#333333',
        labelColorDisable: '#CDD2DB'
    },
    [ButtonType.PRIMARY_ICON]: {
        bgColorIdle: '#F3F6F9',
        bgColorHover: '#576887',
        bgColorDisable: '#EEF0F3',
        labelColorIdle: '#576887',
        labelColorHover: '#FFFFFF',
        labelColorDisable: '#CDD2DB'
    },
}

button-general.tsx:

'use client'
import React, { SVGProps } from "react"
import { ButtonType, ButtonWidth, ButtonHeight, ButtonColors, buttonColorSchemes, buttonSizeSchemes } from "./button-schemes"

export interface ButtonGeneralProperties {
    type: ButtonType
    title?: string
    icon?: any
    onClick?: () => void
    disableWhen?: () => boolean
}

export const ButtonGeneral = (props: ButtonGeneralProperties) => {
    const { type, title, icon, onClick, disableWhen } = props

    const { bgColorIdle, bgColorHover, bgColorDisable, labelColorIdle, labelColorHover, labelColorDisable } = buttonColorSchemes[type]
    const { width, height, fontSize } = buttonSizeSchemes[type]

    return (
        <button
            className={`group ${width ? width : 'w-fit'} ${height ? height : 'h-fit'} p-[15px] bg-[${bgColorIdle}] hover:bg-[${bgColorHover}] disabled:bg-[${bgColorDisable}] rounded-3xl justify-center items-center gap-2.5 flex`}
            onClick={onClick}
            disabled={disableWhen && disableWhen()}
        >
            {icon ? icon : ''}
            <div className={`text-[${labelColorIdle}] group-hover:text-[${labelColorHover}] disabled:text-[${labelColorDisable}] ${fontSize} font-semibold leading-none tracking-wide`}>
                {title}
            </div>
        </button>
    )
}

图标方案.tsx:

import { HexColor } from "../buttons/button-schemes";

export enum IconType {
    PRIMARY,
    SECONDARY,
    TERTIARY,
}

export interface IconColors {
    fillColor: HexColor
    hoverColor: HexColor
}

export interface SvgIconProperties {
    name: string;
    type: IconType;
    size?: string | number;
}

export const iconColorSchemes: { [type: string]: IconColors; } = {
    [IconType.PRIMARY]: {
        fillColor: '#576887',
        hoverColor: '#F89D1D'
    },
}

编辑图标.tsx:

import { SvgIconProperties, iconColorSchemes } from "./icon-schemes";

const EditIcon = (props: SvgIconProperties) => {
    const { name, type, size } = props
    const colors = iconColorSchemes[type]

    return (
        <svg
            width={size ?? '18'}
            height={size ?? '18'}
            viewBox={`0 0 ${size} ${size}`}
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
        >
            <path
                className={`fill-[${colors.fillColor}] group-hover:fill-[${colors.hoverColor}]`}
                d="M16 0C16.5304 0 17.0391 0.210714 17.4142 0.585786C17.7893 0.960859 18 1.46957 18 2V16C18 17.11 17.1 18 16 18H2C1.46957 18 0.960859 17.7893 0.585786 17.4142C0.210714 17.0391 0 16.5304 0 16V2C0 1.46957 0.210714 0.960859 0.585786 0.585786C0.960859 0.210714 1.46957 0 2 0H16ZM13.7 6.35C13.92 6.14 13.92 5.79 13.7 5.58L12.42 4.3C12.21 4.08 11.86 4.08 11.65 4.3L10.65 5.3L12.7 7.35L13.7 6.35ZM4 11.94V14H6.06L12.12 7.94L10.06 5.88L4 11.94Z"
            />
        </svg>
    )
}

export default EditIcon

这就是我的使用方式:

            <ButtonGeneral
                type={ButtonType.PRIMARY_ICON}
                title='Edit User'
                icon={<EditIcon
                  name='Edit'
                  type={IconType.PRIMARY}
                  size='18'
                />}
                onClick={() =>
                  router.push(
                    `/admin-center/user-management/${userDetail?.user_id}/edit`
                  )
                }
              />

这是浏览器中经过检查的元素,在 Tailwind Play 中完美运行:

<button class="group flex h-[40px] w-fit items-center justify-center gap-2.5 rounded-3xl bg-[#F3F6F9] p-[15px] hover:bg-[#576887] disabled:bg-[#EEF0F3]">
  <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path class="fill-[#576887] group-hover:fill-[#F89D1D]" d="M16 0C16.5304 0 17.0391 0.210714 17.4142 0.585786C17.7893 0.960859 18 1.46957 18 2V16C18 17.11 17.1 18 16 18H2C1.46957 18 0.960859 17.7893 0.585786 17.4142C0.210714 17.0391 0 16.5304 0 16V2C0 1.46957 0.210714 0.960859 0.585786 0.585786C0.960859 0.210714 1.46957 0 2 0H16ZM13.7 6.35C13.92 6.14 13.92 5.79 13.7 5.58L12.42 4.3C12.21 4.08 11.86 4.08 11.65 4.3L10.65 5.3L12.7 7.35L13.7 6.35ZM4 11.94V14H6.06L12.12 7.94L10.06 5.88L4 11.94Z"></path>
  </svg>
  <div class="text-base font-semibold leading-none tracking-wide text-[#576887] disabled:text-[#CDD2DB] group-hover:text-[#FFFFFF]">
    Edit User
  </div>
</button>

有人可以帮助我吗?谢谢。

编辑:忘了提及这一点。当我使用没有任何图标的 ButtonType.PRIMARY 和 ButtonType.SECONDARY 时,它工作得很好。

reactjs next.js tailwind-css
1个回答
0
投票

根据文档

Tailwind 如何提取类名的最重要含义是,它只会查找源文件中以完整不间断的字符串形式存在的类。

如果您使用字符串插值或将部分类名连接在一起,Tailwind 将找不到它们,因此不会生成相应的 CSS:

不要动态构造类名

<div class="text-{{ error ? 'red' : 'green' }}-600"></div>

在上面的示例中,字符串

text-red-600
text-green-600
不存在,因此 Tailwind 不会生成这些类。 相反,请确保您使用的任何类名完整存在:

始终使用完整的类名

<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>

你可以:

  • 将整个类包含在您传递给
    className
    的变量中,例如
    export const buttonColorSchemes: { [type: string]: ButtonColors; } = {
      [ButtonType.PRIMARY]: {
        bgColorIdle: 'bg-[#FA8A0A]',
        bgColorHover: 'hover:bg-[#E37900]',
        bgColorDisable: 'disabled:bg-[#EEF0F3]',
        labelColorIdle: 'text-[#FFFFFF]',
        labelColorHover: 'group-hover:text-[#FFFFFF]',
        labelColorDisable: 'disabled:text-[#CDD2DB]'
    
    <button
      className={`… ${bgColorIdle} ${bgColorHover} ${bgColorDisable} …`}
      …
    >
      {icon ? icon : ''}
      <div className={`${labelColorIdle} ${labelColorHover} ${labelColorDisable} …`}>
        {title}
    
    export const iconColorSchemes: { [type: string]: IconColors; } = {
      [IconType.PRIMARY]: {
        fillColor: 'fill-[#576887]',
        hoverColor: 'group-hover:fill-[#F89D1D]'
      },
    }
    
    <path
      className={`${colors.fillColor} ${colors.hoverColor} …`}
    
    确保
    button-general.tsx
    button-schemes.tsx
    content
    文件团覆盖。
  • 使用
    style
    属性:
    <button
      className={`… bg-[--idle] hover:bg-[--hover] disabled:bg-[--disable] …`}
      style={{
        '--idle': bgColorIdle,
        '--hover': bgColorHover,
        '--disable': bgColorDisable,
      }}
      …
    >
      {icon ? icon : ''}
      <div
        className={`text-[--idle] group-hover:text-[--hover] disabled:text-[--disable] …`}
        style={{
          '--idle': labelColorIdle,
          '--hover': labelColorHover,
          '--disable': labelColorDisable,
        }}
      >
        {title}
    
    <path
      className="fill-[--fill] group-hover:fill-[--hover] …"
      style={{
        '--fill': colors.fillColor,
        '--hover': colors.hoverColor,
      }}
    
  • safelist
    ,如果您的已知颜色数量有限:
    module.exports = {
      safelist: [
        'bg-[#F3F6F9]',
        'hover:bg-[#576887]',
        'disabled:bg-[#EEF0F3]',
        // …
      ],
      // …
    ];
    
© www.soinside.com 2019 - 2024. All rights reserved.