diff --git a/.changeset/young-clouds-taste.md b/.changeset/young-clouds-taste.md
new file mode 100644
index 00000000..43e9264c
--- /dev/null
+++ b/.changeset/young-clouds-taste.md
@@ -0,0 +1,5 @@
+---
+"@easypost/easy-ui": minor
+---
+
+feat(Bage): new colors
diff --git a/easy-ui-react/src/Badge/Badge.mdx b/easy-ui-react/src/Badge/Badge.mdx
index 845a309e..dfdbc2e2 100644
--- a/easy-ui-react/src/Badge/Badge.mdx
+++ b/easy-ui-react/src/Badge/Badge.mdx
@@ -13,12 +13,6 @@ A `` can be a simple label.
-## Simple Icon
-
-A `` can be a single icon using the `icon` property. The `icon` property accepts any icon symbol from `@easypost/easy-ui-icons`.
-
-
-
## Detailed Icon
A `` can contain an icon and supporting label.
diff --git a/easy-ui-react/src/Badge/Badge.module.scss b/easy-ui-react/src/Badge/Badge.module.scss
index 29aaad16..410133d5 100644
--- a/easy-ui-react/src/Badge/Badge.module.scss
+++ b/easy-ui-react/src/Badge/Badge.module.scss
@@ -1,7 +1,7 @@
@use "../styles/common" as *;
.root {
- @include font-style("small-button");
+ @include font-style("subtitle2");
border-radius: design-token("shape.border_radius.lg");
display: inline-flex;
// Ensures the background colors do not bleed out of the border radius edges
@@ -31,11 +31,17 @@
}
// prettier-ignore
-.variantPrimary {
- @include component-token("badge", "primary.color.background", design-token("color.primary.600"));
- @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+.variantPrimary.hasIconOrSecondaryLabel {
@include component-token("badge", "secondary.color.background", design-token("color.primary.100"));
@include component-token("badge", "secondary.color.text", design-token("color.primary.800"));
+ @include component-token("badge", "primary.color.background", design-token("color.primary.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantPrimary:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.primary.700"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
}
// prettier-ignore
@@ -93,3 +99,255 @@
@include component-token("badge", "secondary.color.background", design-token("color.negative.100"));
@include component-token("badge", "secondary.color.text", design-token("color.primary.800"));
}
+
+// prettier-ignore
+.variantPrimary\.100.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.primary.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.primary.100"));
+ @include component-token("badge", "secondary.color.text", design-token("color.primary.900"));
+}
+
+// prettier-ignore
+.variantPrimary\.100:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.primary.100"));
+ @include component-token("badge", "primary.color.text", design-token("color.primary.900"));
+}
+
+// prettier-ignore
+.variantPrimary\.500.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.primary.800"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.primary.500"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantPrimary\.500:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.primary.500"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantPrimary\.700.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.primary.900"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.primary.700"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantPrimary\.700:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.primary.700"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantSecondary\.100.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.secondary.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.secondary.100"));
+ @include component-token("badge", "secondary.color.text", design-token("color.secondary.900"));
+}
+
+// prettier-ignore
+.variantSecondary\.100:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.secondary.100"));
+ @include component-token("badge", "primary.color.text", design-token("color.secondary.900"));
+}
+
+// prettier-ignore
+.variantSecondary\.500.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.secondary.800"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.secondary.500"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantSecondary\.500:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.secondary.500"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantSecondary\.700.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.secondary.900"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.secondary.700"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantSecondary\.700:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.secondary.700"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantPositive\.100.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.positive.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.positive.100"));
+ @include component-token("badge", "secondary.color.text", design-token("color.positive.900"));
+}
+
+// prettier-ignore
+.variantPositive\.100:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.positive.100"));
+ @include component-token("badge", "primary.color.text", design-token("color.positive.900"));
+}
+
+// prettier-ignore
+.variantPositive\.600.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.positive.800"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.positive.600"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantPositive\.600:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.positive.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantPositive\.700.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.positive.900"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.positive.700"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantPositive\.700:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.positive.700"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantNegative\.100.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.negative.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.negative.100"));
+ @include component-token("badge", "secondary.color.text", design-token("color.negative.900"));
+}
+
+// prettier-ignore
+.variantNegative\.100:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.negative.100"));
+ @include component-token("badge", "primary.color.text", design-token("color.negative.900"));
+}
+
+// prettier-ignore
+.variantNegative\.400.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.negative.700"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.negative.400"));
+ @include component-token("badge", "secondary.color.text", design-token("color.negative.900"));
+}
+
+// prettier-ignore
+.variantNegative\.400:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.negative.400"));
+ @include component-token("badge", "primary.color.text", design-token("color.negative.900"));
+}
+
+// prettier-ignore
+.variantNegative\.600.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.negative.800"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.negative.600"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantNegative\.600:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.negative.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantWarning\.100.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.warning.500"));
+ @include component-token("badge", "primary.color.text", design-token("color.warning.900"));
+ @include component-token("badge", "secondary.color.background", design-token("color.warning.100"));
+ @include component-token("badge", "secondary.color.text", design-token("color.warning.900"));
+}
+
+// prettier-ignore
+.variantWarning\.100:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.warning.100"));
+ @include component-token("badge", "primary.color.text", design-token("color.warning.900"));
+}
+
+// prettier-ignore
+.variantWarning\.500.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.warning.700"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.warning.500"));
+ @include component-token("badge", "secondary.color.text", design-token("color.warning.900"));
+}
+
+// prettier-ignore
+.variantWarning\.500:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.warning.500"));
+ @include component-token("badge", "primary.color.text", design-token("color.warning.900"));
+}
+
+// prettier-ignore
+.variantWarning\.600.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.warning.800"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.warning.600"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantWarning\.600:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.warning.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantNeutral\.050.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.neutral.500"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.neutral.050"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.900"));
+}
+
+// prettier-ignore
+.variantNeutral\.050:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.neutral.050"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.900"));
+}
+
+// prettier-ignore
+.variantNeutral\.500.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.neutral.700"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.neutral.500"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantNeutral\.500:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.neutral.500"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantNeutral\.600.hasIconOrSecondaryLabel {
+ @include component-token("badge", "primary.color.background", design-token("color.neutral.800"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+ @include component-token("badge", "secondary.color.background", design-token("color.neutral.600"));
+ @include component-token("badge", "secondary.color.text", design-token("color.neutral.000"));
+}
+
+// prettier-ignore
+.variantNeutral\.600:not(.hasIconOrSecondaryLabel) {
+ @include component-token("badge", "primary.color.background", design-token("color.neutral.600"));
+ @include component-token("badge", "primary.color.text", design-token("color.neutral.000"));
+}
diff --git a/easy-ui-react/src/Badge/Badge.stories.tsx b/easy-ui-react/src/Badge/Badge.stories.tsx
index 5ee6bfb7..9b5a9ae9 100644
--- a/easy-ui-react/src/Badge/Badge.stories.tsx
+++ b/easy-ui-react/src/Badge/Badge.stories.tsx
@@ -48,19 +48,6 @@ export const SimpleText: Story = {
},
};
-export const SimpleIcon: Story = {
- render: Template.bind({}),
- args: {
- icon: AnchorIcon,
- accessibilityLabel: "Text to describe badge",
- },
- parameters: {
- controls: {
- include: ["accessibilityLabel", "icon", "variant"],
- },
- },
-};
-
export const DetailedIcon: Story = {
render: Template.bind({}),
args: {
@@ -98,6 +85,24 @@ export const ColorVariants: Story = {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
>
),
args: {
diff --git a/easy-ui-react/src/Badge/Badge.test.tsx b/easy-ui-react/src/Badge/Badge.test.tsx
index a4b061a1..e4135125 100644
--- a/easy-ui-react/src/Badge/Badge.test.tsx
+++ b/easy-ui-react/src/Badge/Badge.test.tsx
@@ -22,11 +22,6 @@ describe("", () => {
expect(screen.getByText("Badge text")).toBeInTheDocument();
});
- it("should render simple icon", () => {
- render();
- expect(screen.getByText(/intent of badge/i)).toBeInTheDocument();
- });
-
it("should render detailed icon", () => {
render(Badge text);
expect(screen.getByRole("img", { hidden: true })).toBeInTheDocument();
@@ -47,17 +42,11 @@ describe("", () => {
);
});
- it("should warn on missing children or icon", () => {
+ it("should warn on missing children", () => {
+ // @ts-expect-error warning check
render();
expect(consoleWarnSpy).toBeCalledWith(
- expect.stringMatching(/requires one of children or icon/),
- );
- });
-
- it("should warn with no accessibility label on icon", () => {
- render();
- expect(consoleWarnSpy).toBeCalledWith(
- expect.stringMatching(/must have accessibilityLabel/),
+ expect.stringMatching(/requires children/),
);
});
@@ -67,7 +56,9 @@ describe("", () => {
accessibilityLabel="Intent of badge"
secondaryLabel="Secondary text"
icon={Anchor}
- />,
+ >
+ Badge text
+ ,
);
expect(consoleWarnSpy).toBeCalledWith(
expect.stringMatching(/secondaryLabel is not supported/),
diff --git a/easy-ui-react/src/Badge/Badge.tsx b/easy-ui-react/src/Badge/Badge.tsx
index 7866804e..c1ad1f22 100644
--- a/easy-ui-react/src/Badge/Badge.tsx
+++ b/easy-ui-react/src/Badge/Badge.tsx
@@ -16,17 +16,34 @@ export type BadgeVariant =
| "gray"
| "success"
| "warning"
- | "danger";
+ | "danger"
+ | "primary.100"
+ | "primary.500"
+ | "primary.700"
+ | "secondary.100"
+ | "secondary.500"
+ | "secondary.700"
+ | "positive.100"
+ | "positive.600"
+ | "positive.700"
+ | "negative.100"
+ | "negative.400"
+ | "negative.600"
+ | "warning.100"
+ | "warning.500"
+ | "warning.600"
+ | "neutral.050"
+ | "neutral.500"
+ | "neutral.600";
export type BadgeProps = {
/**
- * Accessible label for the badge if it differs from its content. Required
- * for icon badges.
+ * Accessible label for the badge if it differs from its content.
*/
accessibilityLabel?: string;
/** Primary badge label. */
- children?: ReactNode;
+ children: ReactNode;
/** Badge icon */
icon?: IconSymbol;
@@ -57,12 +74,6 @@ export type BadgeProps = {
* ```
*
* @example
- * _Simple icon:_
- * ```tsx
- *
- * ```
- *
- * @example
* _Detailed text:_
* ```tsx
*
@@ -88,39 +99,35 @@ export function Badge(props: BadgeProps) {
const className = classNames(
styles.root,
styles[variationName("variant", variant)],
+ (icon || secondaryLabel) && styles.hasIconOrSecondaryLabel,
);
// Ideally the below conditions could use discriminated type unions to enforce
// constraints statically but as of now it makes for too rigorous of an API.
// Can consider revisiting in the future.
- if (!icon && !children) {
- console.warn("Badge requires one of children or icon");
+ if (!children) {
+ console.warn("Badge requires children");
}
if (secondaryLabel && icon) {
console.warn("secondaryLabel is not supported on a Badge with icon");
}
- if (icon && !children && !accessibilityLabel) {
- console.warn("Badge with only icon must have accessibilityLabel");
- }
-
return (
{accessibilityLabel && {accessibilityLabel}}
-
- {icon ? (
+ {icon && (
+
- ) : (
- {children}
- )}
+
+ )}
+
+ {children}
- {children && (icon || secondaryLabel) && (
+ {secondaryLabel && (
-
- {icon ? <>{children}> : <>{secondaryLabel}>}
-
+ {secondaryLabel}
)}