8000 refactor: match StatusIndicator component with the new designs by BrunoQuaresma · Pull Request #16458 · coder/coder · GitHub
[go: up one dir, main page]

Skip to content

refactor: match StatusIndicator component with the new designs #16458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Refactor status indicator
  • Loading branch information
BrunoQuaresma committed Feb 5, 2025
commit 170a73186627186c09256d432dad1084e502d0b0
50 changes: 21 additions & 29 deletions site/src/components/StatusIndicator/StatusIndicator.stories.tsx
10000
Original file line number Diff line number Diff line change
@@ -1,63 +1,55 @@
import type { Meta, StoryObj } from "@storybook/react";
import { StatusIndicator } from "./StatusIndicator";
import { StatusIndicator, StatusIndicatorDot } from "./StatusIndicator";

const meta: Meta<typeof StatusIndicator> = {
title: "components/StatusIndicator",
component: StatusIndicator,
args: {},
args: {
children: (
<>
<StatusIndicatorDot />
Status
</>
),
},
};

export default meta;
type Story = StoryObj<typeof StatusIndicator>;

export const Success: Story = {
args: {
color: "success",
},
};

export const SuccessOutline: Story = {
args: {
color: "success",
variant: "outlined",
variant: "success",
},
};

export const Warning: Story = {
args: {
color: "warning",
},
};

export const WarningOutline: Story = {
export const Failed: Story = {
args: {
color: "warning",
variant: "outlined",
variant: "failed",
},
};

export const Danger: Story = {
export const Stopped: Story = {
args: {
color: "danger",
variant: "stopped",
},
};

export const DangerOutline: Story = {
export const Warning: Story = {
args: {
color: "danger",
variant: "outlined",
variant: "warning",
},
};

export const Inactive: Story = {
export const Starting: Story = {
args: {
color: "inactive",
variant: "starting",
},
};

export const InactiveOutline: Story = {
export const Small: Story = {
args: {
color: "inactive",
variant: "outlined",
variant: "success",
size: "sm",
},
};
101 changes: 76 additions & 25 deletions site/src/components/StatusIndicator/StatusIndicator.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,84 @@
import { useTheme } from "@emotion/react";
import type { FC } from "react";
import type { ThemeRole } from "theme/roles";
import { cva, type VariantProps } from "class-variance-authority";
import { createContext, useContext, type FC } from "react";
import { cn } from "utils/cn";

interface StatusIndicatorProps {
color: ThemeRole;
variant?: "solid" | "outlined";
}
const statusIndicatorVariants = cva(
"font-medium inline-flex items-center gap-2",
{
variants: {
variant: {
success: "text-content-success",
failed: "text-content-destructive",
stopped: "text-highlight-grey",
warning: "text-content-warning",
starting: "text-highlight-sky",
},
size: {
sm: "text-xs",
md: "text-sm",
},
},
defaultVariants: {
variant: "success",
size: "md",
},
},
);

type StatusIndicatorContextValue = VariantProps<typeof statusIndicatorVariants>;

const StatusIndicatorContext = createContext<StatusIndicatorContextValue>({});

export interface StatusIndicatorProps
extends React.HTMLAttributes<HTMLDivElement>,
StatusIndicatorContextValue {}

export const StatusIndicator: FC<StatusIndicatorProps> = ({
color,
variant = "solid",
size,
variant,
className,
...props
}) => {
return (
<StatusIndicatorContext.Provider value={{ size, variant }}>
<div
className={cn(statusIndicatorVariants({ variant, size }), className)}
{...props}
/>
</StatusIndicatorContext.Provider>
);
};

const dotVariants = cva("rounded-full inline-block border-4 border-solid", {
variants: {
variant: {
success: "bg-content-success border-surface-green",
failed: "bg-content-destructive border-surface-destructive",
stopped: "bg-highlight-grey border-surface-grey",
warning: "bg-content-warning border-surface-orange",
starting: "bg-highlight-sky border-surface-sky",
},
size: {
sm: "size-3 border-4",
md: "size-4 border-4",
},
},
defaultVariants: {
variant: "success",
size: "md",
},
});

export interface StatusIndicatorDotProps
extends React.HTMLAttributes<HTMLDivElement> {}

export const StatusIndicatorDot: FC<StatusIndicatorDotProps> = ({
className,
...props
}) => {
const theme = useTheme();
const { size, variant } = useContext(StatusIndicatorContext);

return (
<div
css={[
{
height: 8,
width: 8,
borderRadius: 4,
},
variant === "solid" && {
backgroundColor: theme.roles[color].fill.solid,
},
variant === "outlined" && {
border: `1px solid ${theme.roles[color].outline}`,
},
]}
/>
<div className={cn(dotVariants({ variant, size }), className)} {...props} />
);
};
16 changes: 15 additions & 1 deletion site/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,27 @@
--content-success: 142 72% 29%;
--content-danger: 0 84% 60%;
--content-warning: 27 96% 61%;
--content-destructive: 0 84% 60%;
--surface-primary: 0 0% 98%;
--surface-secondary: 240 5% 96%;
--surface-tertiary: 240 6% 90%;
--surface-quaternary: 240 5% 84%;
--surface-invert-primary: 240 4% 16%;
--surface-invert-secondary: 240 5% 26%;
--surface-destructive: 0 93% 94%;
--surface-green: 141 79% 85%;
--surface-grey: 240 5% 96%;
--surface-orange: 34 100% 92%;
--surface-sky: 201 94% 86%;
--border-default: 240 6% 90%;
--border-success: 142 76% 36%;
--border-destructive: 0 84% 60%;
--overlay-default: 240 5% 84% / 80%;
--radius: 0.5rem;
--highlight-purple: 262 83% 58%;
--highlight-green: 143 64% 24%;
--highlight-grey: 240 5% 65%;
--highlight-sky: 201 90% 27%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 10% 3.9%;
Expand All @@ -46,20 +53,27 @@
--content-disabled: 240 5% 26%;
--content-success: 142 76% 36%;
--content-danger: 0 91% 71%;
--content-warning: 27 96% 61%;
--content-warning: 31 97% 72%;
--content-destructive: 0 91% 71%;
--surface-primary: 240 10% 4%;
--surface-secondary: 240 6% 10%;
--surface-tertiary: 240 4% 16%;
--surface-quaternary: 240 5% 26%;
--surface-invert-primary: 240 6% 90%;
--surface-invert-secondary: 240 5% 65%;
--surface-destructive: 0 75% 15%;
--surface-green: 145 80% 10%;
--surface-grey: 240 6% 10%;
--surface-orange: 13 81% 15%;
--surface-sky: 204 80% 16%;
--border-default: 240 4% 16%;
--border-success: 142 76% 36%;
--border-destructive: 0 91% 71%;
--overlay-default: 240 10% 4% / 80%;
--highlight-purple: 252 95% 85%;
--highlight-green: 141 79% 85%;
--highlight-grey: 240 4% 46%;
--highlight-sky: 198 93% 60%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
Expand Down
8 changes: 8 additions & 0 deletions site/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ module.exports = {
success: "hsl(var(--content-success))",
danger: "hsl(var(--content-danger))",
link: "hsl(var(--content-link))",
destructive: "hsl(var(--content-destructive))",
warning: "hsl(var(--content-warning))",
},
surface: {
primary: "hsl(var(--surface-primary))",
Expand All @@ -44,6 +46,10 @@ module.exports = {
secondary: "hsl(var(--surface-invert-secondary))",
},
destructive: "hsl(var(--surface-destructive))",
green: "hsl(var(--surface-green))",
grey: "hsl(var(--surface-grey))",
orange: "hsl(var(--surface-orange))",
sky: "hsl(var(--surface-sky))",
},
border: {
DEFAULT: "hsl(var(--border-default))",
Expand All @@ -55,6 +61,8 @@ module.exports = {
highlight: {
purple: "hsl(var(--highlight-purple))",
green: "hsl(var(--highlight-green))",
grey: "hsl(var(--highlight-grey))",
sky: "hsl(var(--highlight-sky))",
},
},
keyframes: {
Expand Down
0