mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: resolve <Badge /> incorrect sizes (#22539)
This pull-request makes a few changes to our `<Badge />` component to bring it inline with Figma. * Added all variants to the stories of Figma (they can vary per badge-type, so its better we track everything). * Removed the `border` variant of the component, border variants should be on all `sm` and `md`. * Added a hover effect to the `default` variant (per-design). * Resolved issue with sizings of `xs` and `sm` plus resolved iconography. * Resolved issue with icons not showing at all on `xs` variants.
This commit is contained in:
@@ -1,56 +1,150 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { Settings, TriangleAlert } from "lucide-react";
|
||||
import { Database, Settings, TriangleAlert } from "lucide-react";
|
||||
import { Badges } from "#/components/Badges/Badges";
|
||||
import { Badge } from "./Badge";
|
||||
|
||||
const meta: Meta<typeof Badge> = {
|
||||
title: "components/Badge",
|
||||
component: Badge,
|
||||
args: {
|
||||
children: "Badge",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Badge>;
|
||||
|
||||
export const Default: Story = {};
|
||||
export const Default: Story = {
|
||||
render: () => (
|
||||
<Badges>
|
||||
<Badge size="xs">
|
||||
<Database />
|
||||
Text
|
||||
</Badge>
|
||||
<Badge size="sm">
|
||||
<Database />
|
||||
Text
|
||||
</Badge>
|
||||
<Badge size="md">
|
||||
<Database />
|
||||
Text
|
||||
</Badge>
|
||||
</Badges>
|
||||
),
|
||||
};
|
||||
|
||||
export const Warning: Story = {
|
||||
args: {
|
||||
variant: "warning",
|
||||
},
|
||||
render: () => (
|
||||
<Badges>
|
||||
<Badge variant="warning" size="xs">
|
||||
Warning
|
||||
<TriangleAlert />
|
||||
</Badge>
|
||||
<Badge variant="warning" size="sm">
|
||||
<TriangleAlert />
|
||||
Warning
|
||||
</Badge>
|
||||
<Badge variant="warning" size="md">
|
||||
<TriangleAlert />
|
||||
Warning
|
||||
</Badge>
|
||||
</Badges>
|
||||
),
|
||||
};
|
||||
|
||||
export const Destructive: Story = {
|
||||
args: {
|
||||
variant: "destructive",
|
||||
},
|
||||
render: () => (
|
||||
<Badges>
|
||||
<Badge variant="destructive" size="xs">
|
||||
Destructive
|
||||
<TriangleAlert />
|
||||
</Badge>
|
||||
<Badge variant="destructive" size="sm">
|
||||
<TriangleAlert />
|
||||
Destructive
|
||||
</Badge>
|
||||
<Badge variant="destructive" size="md">
|
||||
<TriangleAlert />
|
||||
Destructive
|
||||
</Badge>
|
||||
</Badges>
|
||||
),
|
||||
};
|
||||
|
||||
export const Info: Story = {
|
||||
args: {
|
||||
variant: "info",
|
||||
},
|
||||
render: () => (
|
||||
<Badges>
|
||||
<Badge variant="info" size="xs">
|
||||
Info
|
||||
</Badge>
|
||||
<Badge variant="info" size="sm">
|
||||
Info
|
||||
</Badge>
|
||||
<Badge variant="info" size="md">
|
||||
Info
|
||||
</Badge>
|
||||
</Badges>
|
||||
),
|
||||
};
|
||||
|
||||
export const Green: Story = {
|
||||
args: {
|
||||
variant: "green",
|
||||
},
|
||||
render: () => (
|
||||
<Badges>
|
||||
<Badge variant="green" size="xs">
|
||||
Green
|
||||
</Badge>
|
||||
<Badge variant="green" size="sm">
|
||||
Green
|
||||
</Badge>
|
||||
<Badge variant="green" size="md">
|
||||
Green
|
||||
</Badge>
|
||||
</Badges>
|
||||
),
|
||||
};
|
||||
|
||||
export const Purple: Story = {
|
||||
render: () => (
|
||||
<Badges>
|
||||
<Badge variant="purple" size="xs">
|
||||
Purple
|
||||
</Badge>
|
||||
<Badge variant="purple" size="sm">
|
||||
Purple
|
||||
</Badge>
|
||||
<Badge variant="purple" size="md">
|
||||
Purple
|
||||
</Badge>
|
||||
</Badges>
|
||||
),
|
||||
};
|
||||
|
||||
export const Magenta: Story = {
|
||||
render: () => (
|
||||
<Badges>
|
||||
<Badge variant="magenta" size="xs">
|
||||
Magenta
|
||||
</Badge>
|
||||
<Badge variant="magenta" size="sm">
|
||||
Magenta
|
||||
</Badge>
|
||||
<Badge variant="magenta" size="md">
|
||||
Magenta
|
||||
</Badge>
|
||||
</Badges>
|
||||
),
|
||||
};
|
||||
|
||||
export const SmallWithIcon: Story = {
|
||||
args: {
|
||||
variant: "default",
|
||||
size: "sm",
|
||||
children: <>{<Settings />} Preset</>,
|
||||
},
|
||||
render: () => (
|
||||
<Badge variant="default" size="sm">
|
||||
<Settings />
|
||||
Preset
|
||||
</Badge>
|
||||
),
|
||||
};
|
||||
|
||||
export const MediumWithIcon: Story = {
|
||||
args: {
|
||||
variant: "warning",
|
||||
size: "md",
|
||||
children: <>{<TriangleAlert />} Immutable</>,
|
||||
},
|
||||
render: () => (
|
||||
<Badge variant="warning" size="md">
|
||||
<TriangleAlert />
|
||||
Immutable
|
||||
</Badge>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copied from shadc/ui on 11/13/2024
|
||||
* Copied from shadcn/ui on 11/13/2024
|
||||
* @see {@link https://ui.shadcn.com/docs/components/badge}
|
||||
*/
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
@@ -8,35 +8,31 @@ import { cn } from "#/utils/cn";
|
||||
|
||||
const badgeVariants = cva(
|
||||
`
|
||||
inline-flex items-center rounded-md border px-2 py-1 text-nowrap
|
||||
transition-colors
|
||||
[&_svg]:pointer-events-none [&_svg]:pr-0.5 [&_svg]:py-0.5 [&_svg]:mr-0.5
|
||||
inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-nowrap
|
||||
transition-colors [&_svg]:py-0.5 border-solid
|
||||
[&_svg]:pointer-events-none
|
||||
`,
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"border-transparent bg-surface-secondary text-content-secondary shadow",
|
||||
"border-surface-secondary bg-surface-secondary text-content-secondary shadow",
|
||||
warning:
|
||||
"border border-solid border-border-warning bg-surface-orange text-content-warning shadow",
|
||||
"border-border-warning bg-surface-orange text-content-warning shadow",
|
||||
destructive:
|
||||
"border border-solid border-border-destructive bg-surface-red text-highlight-red shadow",
|
||||
"border-border-destructive bg-surface-red text-highlight-red shadow",
|
||||
green:
|
||||
"border border-solid border-border-green bg-surface-green text-highlight-green shadow",
|
||||
"border-border-green bg-surface-green text-highlight-green shadow",
|
||||
purple:
|
||||
"border border-solid border-border-purple bg-surface-purple text-highlight-purple shadow",
|
||||
"border-border-purple bg-surface-purple text-highlight-purple shadow",
|
||||
magenta:
|
||||
"border border-solid border-border-magenta bg-surface-magenta text-highlight-magenta shadow",
|
||||
info: "border border-solid border-border-pending bg-surface-sky text-highlight-sky shadow",
|
||||
"border-border-magenta bg-surface-magenta text-highlight-magenta shadow",
|
||||
info: "border-border-pending bg-surface-sky text-highlight-sky shadow",
|
||||
},
|
||||
size: {
|
||||
xs: "text-2xs font-regular h-5 [&_svg]:hidden rounded px-1.5",
|
||||
sm: "text-2xs font-regular h-5.5 [&_svg]:size-icon-xs",
|
||||
md: "text-xs font-medium [&_svg]:size-icon-sm",
|
||||
},
|
||||
border: {
|
||||
none: "border-transparent",
|
||||
solid: "border border-solid",
|
||||
xs: "border-0 text-2xs font-normal h-[18px] [&_svg]:size-icon-xs rounded",
|
||||
sm: "text-2xs font-normal h-5.5 py-1 [&_svg]:size-icon-xs",
|
||||
md: "text-xs font-normal py-1 [&_svg]:size-icon-xs",
|
||||
},
|
||||
hover: {
|
||||
false: null,
|
||||
@@ -58,7 +54,6 @@ const badgeVariants = cva(
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "md",
|
||||
border: "none",
|
||||
hover: false,
|
||||
},
|
||||
},
|
||||
@@ -73,7 +68,6 @@ export const Badge: React.FC<BadgeProps> = ({
|
||||
className,
|
||||
variant,
|
||||
size,
|
||||
border,
|
||||
hover,
|
||||
asChild = false,
|
||||
...props
|
||||
@@ -83,7 +77,7 @@ export const Badge: React.FC<BadgeProps> = ({
|
||||
return (
|
||||
<Comp
|
||||
{...props}
|
||||
className={cn(badgeVariants({ variant, size, border, hover }), className)}
|
||||
className={cn(badgeVariants({ variant, size, hover }), className)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,18 +3,14 @@ import { Stack } from "#/components/Stack/Stack";
|
||||
|
||||
export const EnabledBadge: React.FC = () => {
|
||||
return (
|
||||
<Badge className="option-enabled" variant="green" border="solid">
|
||||
<Badge className="option-enabled" variant="green">
|
||||
Enabled
|
||||
</Badge>
|
||||
);
|
||||
};
|
||||
|
||||
export const EntitledBadge: React.FC = () => {
|
||||
return (
|
||||
<Badge border="solid" variant="green">
|
||||
Entitled
|
||||
</Badge>
|
||||
);
|
||||
return <Badge variant="green">Entitled</Badge>;
|
||||
};
|
||||
|
||||
export const DisabledBadge: React.FC<React.ComponentPropsWithRef<"div">> = ({
|
||||
@@ -28,11 +24,7 @@ export const DisabledBadge: React.FC<React.ComponentPropsWithRef<"div">> = ({
|
||||
};
|
||||
|
||||
export const EnterpriseBadge: React.FC = () => {
|
||||
return (
|
||||
<Badge variant="purple" border="solid">
|
||||
Enterprise
|
||||
</Badge>
|
||||
);
|
||||
return <Badge variant="purple">Enterprise</Badge>;
|
||||
};
|
||||
|
||||
interface PremiumBadgeProps {
|
||||
@@ -42,35 +34,19 @@ interface PremiumBadgeProps {
|
||||
export const PremiumBadge: React.FC<PremiumBadgeProps> = ({
|
||||
children = "Premium",
|
||||
}) => {
|
||||
return (
|
||||
<Badge variant="magenta" border="solid">
|
||||
{children}
|
||||
</Badge>
|
||||
);
|
||||
return <Badge variant="magenta">{children}</Badge>;
|
||||
};
|
||||
|
||||
export const PreviewBadge: React.FC = () => {
|
||||
return (
|
||||
<Badge variant="purple" border="solid">
|
||||
Preview
|
||||
</Badge>
|
||||
);
|
||||
return <Badge variant="purple">Preview</Badge>;
|
||||
};
|
||||
|
||||
export const AlphaBadge: React.FC = () => {
|
||||
return (
|
||||
<Badge variant="purple" border="solid">
|
||||
Alpha
|
||||
</Badge>
|
||||
);
|
||||
return <Badge variant="purple">Alpha</Badge>;
|
||||
};
|
||||
|
||||
export const DeprecatedBadge: React.FC = () => {
|
||||
return (
|
||||
<Badge variant="warning" border="solid">
|
||||
Deprecated
|
||||
</Badge>
|
||||
);
|
||||
return <Badge variant="warning">Deprecated</Badge>;
|
||||
};
|
||||
|
||||
export const Badges: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||
|
||||
@@ -141,7 +141,7 @@ const ParameterLabel: FC<ParameterLabelProps> = ({
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="flex items-center">
|
||||
<Badge size="sm" variant="warning" border="none">
|
||||
<Badge size="sm" variant="warning">
|
||||
<TriangleAlert />
|
||||
Immutable
|
||||
</Badge>
|
||||
@@ -159,7 +159,7 @@ const ParameterLabel: FC<ParameterLabelProps> = ({
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="flex items-center">
|
||||
<Badge size="sm" variant="green" border="none">
|
||||
<Badge size="sm" variant="green">
|
||||
<Hourglass />
|
||||
Ephemeral
|
||||
</Badge>
|
||||
@@ -211,7 +211,7 @@ const ParameterLabel: FC<ParameterLabelProps> = ({
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="flex items-center">
|
||||
<Badge size="sm" variant="destructive" border="none">
|
||||
<Badge size="sm" variant="destructive">
|
||||
Required
|
||||
</Badge>
|
||||
</span>
|
||||
|
||||
@@ -38,11 +38,7 @@ export const ExternalAuthButton: FC<ExternalAuthButtonProps> = ({
|
||||
)}
|
||||
<p className="font-semibold text-sm m-0">{auth.display_name}</p>
|
||||
{!auth.authenticated && !auth.optional && (
|
||||
<Badge
|
||||
size="sm"
|
||||
border="none"
|
||||
variant={error ? "destructive" : "warning"}
|
||||
>
|
||||
<Badge size="sm" variant={error ? "destructive" : "warning"}>
|
||||
Required
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ export const AIGovernanceAddOnCard: FC<AIGovernanceAddOnCardProps> = ({
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Badge variant="magenta" size="sm" border="solid">
|
||||
<Badge variant="magenta" size="sm">
|
||||
AI add-on
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
@@ -116,12 +116,12 @@ const ReviewPanel: FC<ReviewPanelProps> = ({
|
||||
<span className="flex flex-row items-center gap-2">
|
||||
<span className="leading-tight">{workspaceName}</span>
|
||||
{running && (
|
||||
<Badge size="xs" variant="warning" border="none">
|
||||
<Badge size="xs" variant="warning">
|
||||
Running
|
||||
</Badge>
|
||||
)}
|
||||
{transitioning && (
|
||||
<Badge size="xs" variant="warning" border="none">
|
||||
<Badge size="xs" variant="warning">
|
||||
Getting latest status
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user