Updates
This commit is contained in:
@@ -1,32 +1,50 @@
|
||||
import React, {
|
||||
AnchorHTMLAttributes,
|
||||
ButtonHTMLAttributes,
|
||||
ComponentProps,
|
||||
DetailedHTMLProps,
|
||||
HTMLAttributeAnchorTarget,
|
||||
HTMLAttributes,
|
||||
type AnchorHTMLAttributes,
|
||||
type ButtonHTMLAttributes,
|
||||
type ComponentProps,
|
||||
type DetailedHTMLProps,
|
||||
type HTMLAttributeAnchorTarget,
|
||||
type HTMLAttributes,
|
||||
} from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import Loading from "../elements/Loading";
|
||||
import LucideIcon, { TWUILucideIconName } from "../elements/lucide-icon";
|
||||
import LucideIcon, { type TWUILucideIconName } from "../elements/lucide-icon";
|
||||
import type { LucideProps } from "lucide-react";
|
||||
|
||||
export const TWUIButtonColors = [
|
||||
"primary",
|
||||
"secondary",
|
||||
"text",
|
||||
"white",
|
||||
"accent",
|
||||
"gray",
|
||||
"error",
|
||||
"warning",
|
||||
"success",
|
||||
] as const;
|
||||
|
||||
export const TWUIButtonSizes = [
|
||||
"small",
|
||||
"smaller",
|
||||
"normal",
|
||||
"large",
|
||||
"larger",
|
||||
] as const;
|
||||
|
||||
export const TWUIButtonVariants = ["normal", "ghost", "outlined"] as const;
|
||||
|
||||
export type TWUIButtonColorType = (typeof TWUIButtonColors)[number];
|
||||
export type TWUIButtonSizeType = (typeof TWUIButtonSizes)[number];
|
||||
export type TWUIButtonVariantType = (typeof TWUIButtonVariants)[number];
|
||||
|
||||
export type TWUIButtonProps = DetailedHTMLProps<
|
||||
ButtonHTMLAttributes<HTMLButtonElement>,
|
||||
HTMLButtonElement
|
||||
> & {
|
||||
title: string;
|
||||
variant?: "normal" | "ghost" | "outlined";
|
||||
color?:
|
||||
| "primary"
|
||||
| "secondary"
|
||||
| "text"
|
||||
| "white"
|
||||
| "accent"
|
||||
| "gray"
|
||||
| "error"
|
||||
| "warning"
|
||||
| "success";
|
||||
size?: "small" | "smaller" | "normal" | "large" | "larger";
|
||||
variant?: TWUIButtonVariantType;
|
||||
color?: TWUIButtonColorType;
|
||||
size?: TWUIButtonSizeType;
|
||||
loadingIconSize?: React.ComponentProps<typeof Loading>["size"];
|
||||
href?: string;
|
||||
target?: HTMLAttributeAnchorTarget;
|
||||
@@ -37,6 +55,10 @@ export type TWUIButtonProps = DetailedHTMLProps<
|
||||
>;
|
||||
beforeIcon?: TWUILucideIconName | React.JSX.Element;
|
||||
afterIcon?: TWUILucideIconName | React.JSX.Element;
|
||||
before_icon_name?: TWUILucideIconName;
|
||||
after_icon_name?: TWUILucideIconName;
|
||||
before_icon_props?: LucideProps;
|
||||
after_icon_props?: LucideProps;
|
||||
buttonContentProps?: DetailedHTMLProps<
|
||||
HTMLAttributes<HTMLDivElement>,
|
||||
HTMLDivElement
|
||||
@@ -44,7 +66,7 @@ export type TWUIButtonProps = DetailedHTMLProps<
|
||||
loadingProps?: ComponentProps<typeof Loading>;
|
||||
};
|
||||
|
||||
const buttonClasses: Record<string, Record<string, string>> = {
|
||||
export const ButtonClasses: Record<string, Record<string, string>> = {
|
||||
normal: {
|
||||
primary: twMerge(
|
||||
"bg-primary hover:bg-primary-hover text-white",
|
||||
@@ -96,8 +118,8 @@ const buttonClasses: Record<string, Record<string, string>> = {
|
||||
"twui-button-accent-outlined",
|
||||
),
|
||||
gray: twMerge(
|
||||
"bg-transparent outline outline-1 outline-slate-300",
|
||||
"text-slate-600 dark:text-white/60 dark:outline-white/30",
|
||||
"bg-transparent outline outline-1 outline-gray",
|
||||
"text-dark dark:text-white/60 dark:outline-white/30",
|
||||
"twui-button-gray-outlined",
|
||||
),
|
||||
white: twMerge(
|
||||
@@ -110,6 +132,11 @@ const buttonClasses: Record<string, Record<string, string>> = {
|
||||
"dark:outline-error dark:text-error-dark",
|
||||
"twui-button-error-outlined",
|
||||
),
|
||||
warning: twMerge(
|
||||
"bg-transparent outline outline-1 outline-warning text-warning",
|
||||
"dark:outline-warning dark:text-warning-dark",
|
||||
"twui-button-warning-outlined",
|
||||
),
|
||||
},
|
||||
ghost: {
|
||||
primary: twMerge(
|
||||
@@ -226,9 +253,14 @@ export default function Button({
|
||||
loading,
|
||||
loadingIconSize,
|
||||
loadingProps,
|
||||
before_icon_name,
|
||||
after_icon_name,
|
||||
before_icon_props,
|
||||
after_icon_props,
|
||||
...props
|
||||
}: TWUIButtonProps) {
|
||||
const finalClassName = buttonClasses[variant || "normal"]?.[color || "primary"] ?? "";
|
||||
const finalClassName =
|
||||
ButtonClasses[variant || "normal"]?.[color || "primary"] ?? "";
|
||||
|
||||
const buttonComponent = (
|
||||
<button
|
||||
@@ -246,7 +278,7 @@ export default function Button({
|
||||
? "text-lg twui-button-large"
|
||||
: size == "larger"
|
||||
? "px-5 py-3 text-xl twui-button-larger"
|
||||
: "twui-button-base",
|
||||
: "text-sm twui-button-base",
|
||||
finalClassName,
|
||||
loading ? "pointer-events-none opacity-80" : "",
|
||||
props.className,
|
||||
@@ -262,7 +294,12 @@ export default function Button({
|
||||
buttonContentProps?.className,
|
||||
)}
|
||||
>
|
||||
{beforeIcon ? (
|
||||
{before_icon_name ? (
|
||||
<LucideIcon
|
||||
{...before_icon_props}
|
||||
name={before_icon_name}
|
||||
/>
|
||||
) : beforeIcon ? (
|
||||
typeof beforeIcon == "string" ? (
|
||||
<LucideIcon name={beforeIcon as TWUILucideIconName} />
|
||||
) : (
|
||||
@@ -270,7 +307,9 @@ export default function Button({
|
||||
)
|
||||
) : null}
|
||||
{props.children}
|
||||
{afterIcon ? (
|
||||
{after_icon_name ? (
|
||||
<LucideIcon {...after_icon_props} name={after_icon_name} />
|
||||
) : afterIcon ? (
|
||||
typeof afterIcon == "string" ? (
|
||||
<LucideIcon name={afterIcon as TWUILucideIconName} />
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user