forked from github/plane
dev: badge component added in planu ui package (#2876)
This commit is contained in:
parent
a3ea7c8f10
commit
5c6a59ba35
64
packages/ui/src/badge/badge.tsx
Normal file
64
packages/ui/src/badge/badge.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getIconStyling,
|
||||||
|
getBadgeStyling,
|
||||||
|
TBadgeVariant,
|
||||||
|
TBadgeSizes,
|
||||||
|
} from "./helper";
|
||||||
|
|
||||||
|
export interface BadgeProps
|
||||||
|
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
|
variant?: TBadgeVariant;
|
||||||
|
size?: TBadgeSizes;
|
||||||
|
className?: string;
|
||||||
|
loading?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
appendIcon?: any;
|
||||||
|
prependIcon?: any;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Badge = React.forwardRef<HTMLButtonElement, BadgeProps>((props, ref) => {
|
||||||
|
const {
|
||||||
|
variant = "primary",
|
||||||
|
size = "md",
|
||||||
|
className = "",
|
||||||
|
type = "button",
|
||||||
|
loading = false,
|
||||||
|
disabled = false,
|
||||||
|
prependIcon = null,
|
||||||
|
appendIcon = null,
|
||||||
|
children,
|
||||||
|
...rest
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const buttonStyle = getBadgeStyling(variant, size, disabled || loading);
|
||||||
|
const buttonIconStyle = getIconStyling(size);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
ref={ref}
|
||||||
|
type={type}
|
||||||
|
className={`${buttonStyle} ${className}`}
|
||||||
|
disabled={disabled || loading}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{prependIcon && (
|
||||||
|
<div className={buttonIconStyle}>
|
||||||
|
{React.cloneElement(prependIcon, { strokeWidth: 2 })}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{children}
|
||||||
|
{appendIcon && (
|
||||||
|
<div className={buttonIconStyle}>
|
||||||
|
{React.cloneElement(appendIcon, { strokeWidth: 2 })}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Badge.displayName = "plane-ui-badge";
|
||||||
|
|
||||||
|
export { Badge };
|
145
packages/ui/src/badge/helper.tsx
Normal file
145
packages/ui/src/badge/helper.tsx
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
export type TBadgeVariant =
|
||||||
|
| "primary"
|
||||||
|
| "accent-primary"
|
||||||
|
| "outline-primary"
|
||||||
|
| "neutral"
|
||||||
|
| "accent-neutral"
|
||||||
|
| "outline-neutral"
|
||||||
|
| "success"
|
||||||
|
| "accent-success"
|
||||||
|
| "outline-success"
|
||||||
|
| "warning"
|
||||||
|
| "accent-warning"
|
||||||
|
| "outline-warning"
|
||||||
|
| "destructive"
|
||||||
|
| "accent-destructive"
|
||||||
|
| "outline-destructive";
|
||||||
|
|
||||||
|
export type TBadgeSizes = "sm" | "md" | "lg" | "xl";
|
||||||
|
|
||||||
|
export interface IBadgeStyling {
|
||||||
|
[key: string]: {
|
||||||
|
default: string;
|
||||||
|
hover: string;
|
||||||
|
disabled: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
enum badgeSizeStyling {
|
||||||
|
sm = `px-2.5 py-1 font-medium text-xs rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||||
|
md = `px-4 py-1.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||||
|
lg = `px-4 py-2 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||||
|
xl = `px-5 py-3 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum badgeIconStyling {
|
||||||
|
sm = "h-3 w-3 flex justify-center items-center overflow-hidden flex-shrink-0",
|
||||||
|
md = "h-3.5 w-3.5 flex justify-center items-center overflow-hidden flex-shrink-0",
|
||||||
|
lg = "h-4 w-4 flex justify-center items-center overflow-hidden flex-shrink-0",
|
||||||
|
xl = "h-4 w-4 flex justify-center items-center overflow-hidden flex-shrink-0",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const badgeStyling: IBadgeStyling = {
|
||||||
|
primary: {
|
||||||
|
default: `text-white bg-custom-primary-100`,
|
||||||
|
hover: `hover:bg-custom-primary-200`,
|
||||||
|
disabled: `cursor-not-allowed !bg-custom-primary-60 hover:bg-custom-primary-60`,
|
||||||
|
},
|
||||||
|
"accent-primary": {
|
||||||
|
default: `bg-custom-primary-10 text-custom-primary-100`,
|
||||||
|
hover: `hover:bg-custom-primary-20 hover:text-custom-primary-200`,
|
||||||
|
disabled: `cursor-not-allowed !text-custom-primary-60`,
|
||||||
|
},
|
||||||
|
"outline-primary": {
|
||||||
|
default: `text-custom-primary-100 bg-custom-background-100 border border-custom-primary-100`,
|
||||||
|
hover: `hover:border-custom-primary-80 hover:bg-custom-primary-10`,
|
||||||
|
disabled: `cursor-not-allowed !text-custom-primary-60 !border-custom-primary-60 `,
|
||||||
|
},
|
||||||
|
|
||||||
|
neutral: {
|
||||||
|
default: `text-custom-background-100 bg-custom-text-100 border border-custom-border-200`,
|
||||||
|
hover: `hover:bg-custom-text-200`,
|
||||||
|
disabled: `cursor-not-allowed bg-custom-border-200 !text-custom-text-400`,
|
||||||
|
},
|
||||||
|
"accent-neutral": {
|
||||||
|
default: `text-custom-text-200 bg-custom-background-80`,
|
||||||
|
hover: `hover:bg-custom-border-200 hover:text-custom-text-100`,
|
||||||
|
disabled: `cursor-not-allowed !text-custom-text-400`,
|
||||||
|
},
|
||||||
|
"outline-neutral": {
|
||||||
|
default: `text-custom-text-200 bg-custom-background-100 border border-custom-border-200`,
|
||||||
|
hover: `hover:text-custom-text-100 hover:bg-custom-border-200`,
|
||||||
|
disabled: `cursor-not-allowed !text-custom-text-400`,
|
||||||
|
},
|
||||||
|
|
||||||
|
success: {
|
||||||
|
default: `text-white bg-green-500`,
|
||||||
|
hover: `hover:bg-green-600`,
|
||||||
|
disabled: `cursor-not-allowed !bg-green-300`,
|
||||||
|
},
|
||||||
|
"accent-success": {
|
||||||
|
default: `text-green-500 bg-green-50`,
|
||||||
|
hover: `hover:bg-green-100 hover:text-green-600`,
|
||||||
|
disabled: `cursor-not-allowed !text-green-300`,
|
||||||
|
},
|
||||||
|
"outline-success": {
|
||||||
|
default: `text-green-500 bg-custom-background-100 border border-green-500`,
|
||||||
|
hover: `hover:text-green-600 hover:bg-green-50`,
|
||||||
|
disabled: `cursor-not-allowed !text-green-300 border-green-300`,
|
||||||
|
},
|
||||||
|
|
||||||
|
warning: {
|
||||||
|
default: `text-white bg-amber-500`,
|
||||||
|
hover: `hover:bg-amber-600`,
|
||||||
|
disabled: `cursor-not-allowed !bg-amber-300`,
|
||||||
|
},
|
||||||
|
"accent-warning": {
|
||||||
|
default: `text-amber-500 bg-amber-50`,
|
||||||
|
hover: `hover:bg-amber-100 hover:text-amber-600`,
|
||||||
|
disabled: `cursor-not-allowed !text-amber-300`,
|
||||||
|
},
|
||||||
|
"outline-warning": {
|
||||||
|
default: `text-amber-500 bg-custom-background-100 border border-amber-500`,
|
||||||
|
hover: `hover:text-amber-600 hover:bg-amber-50`,
|
||||||
|
disabled: `cursor-not-allowed !text-amber-300 border-amber-300`,
|
||||||
|
},
|
||||||
|
|
||||||
|
destructive: {
|
||||||
|
default: `text-white bg-red-500`,
|
||||||
|
hover: `hover:bg-red-600`,
|
||||||
|
disabled: `cursor-not-allowed !bg-red-300`,
|
||||||
|
},
|
||||||
|
"accent-destructive": {
|
||||||
|
default: `text-red-500 bg-red-50`,
|
||||||
|
hover: `hover:bg-red-100 hover:text-red-600`,
|
||||||
|
disabled: `cursor-not-allowed !text-red-300`,
|
||||||
|
},
|
||||||
|
"outline-destructive": {
|
||||||
|
default: `text-red-500 bg-custom-background-100 border border-red-500`,
|
||||||
|
hover: `hover:text-red-600 hover:bg-red-50`,
|
||||||
|
disabled: `cursor-not-allowed !text-red-300 border-red-300`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getBadgeStyling = (
|
||||||
|
variant: TBadgeVariant,
|
||||||
|
size: TBadgeSizes,
|
||||||
|
disabled: boolean = false
|
||||||
|
): string => {
|
||||||
|
let _variant: string = ``;
|
||||||
|
const currentVariant = badgeStyling[variant];
|
||||||
|
|
||||||
|
_variant = `${currentVariant.default} ${
|
||||||
|
disabled ? currentVariant.disabled : currentVariant.hover
|
||||||
|
}`;
|
||||||
|
|
||||||
|
let _size: string = ``;
|
||||||
|
if (size) _size = badgeSizeStyling[size];
|
||||||
|
return `${_variant} ${_size}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getIconStyling = (size: TBadgeSizes): string => {
|
||||||
|
let icon: string = ``;
|
||||||
|
if (size) icon = badgeIconStyling[size];
|
||||||
|
return icon;
|
||||||
|
};
|
1
packages/ui/src/badge/index.ts
Normal file
1
packages/ui/src/badge/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./badge";
|
@ -1,5 +1,6 @@
|
|||||||
export * from "./avatar";
|
export * from "./avatar";
|
||||||
export * from "./breadcrumbs";
|
export * from "./breadcrumbs";
|
||||||
|
export * from "./badge";
|
||||||
export * from "./button";
|
export * from "./button";
|
||||||
export * from "./dropdowns";
|
export * from "./dropdowns";
|
||||||
export * from "./form-fields";
|
export * from "./form-fields";
|
||||||
|
Loading…
Reference in New Issue
Block a user