diff --git a/.changeset/popular-plums-mate.md b/.changeset/popular-plums-mate.md
new file mode 100644
index 00000000000..2c1afd0d80a
--- /dev/null
+++ b/.changeset/popular-plums-mate.md
@@ -0,0 +1,6 @@
+---
+"@aws-amplify/ui-react": minor
+"@aws-amplify/ui": minor
+---
+
+feat(button): add `warning` and `destructive` variations to the React Button component
diff --git a/docs/src/data/test/__snapshots__/props-table.test.ts.snap b/docs/src/data/test/__snapshots__/props-table.test.ts.snap
index cd49ea028d7..f905500f805 100644
--- a/docs/src/data/test/__snapshots__/props-table.test.ts.snap
+++ b/docs/src/data/test/__snapshots__/props-table.test.ts.snap
@@ -982,7 +982,7 @@ exports[`Props Table 1`] = `
},
\\"variation\\": {
\\"name\\": \\"variation\\",
- \\"type\\": \\"'primary' | 'link' | 'menu'\\",
+ \\"type\\": \\"| 'primary'\\\\n | 'link'\\\\n | 'menu'\\\\n | 'warning'\\\\n | 'destructive'\\",
\\"description\\": \\"Changes the visual weight of the button.\\",
\\"category\\": \\"ButtonProps\\",
\\"isOptional\\": true
@@ -4432,7 +4432,7 @@ exports[`Props Table 1`] = `
},
\\"variation\\": {
\\"name\\": \\"variation\\",
- \\"type\\": \\"'primary' | 'link' | 'menu'\\",
+ \\"type\\": \\"| 'primary'\\\\n | 'link'\\\\n | 'menu'\\\\n | 'warning'\\\\n | 'destructive'\\",
\\"description\\": \\"Changes the visual weight of the button.\\",
\\"category\\": \\"ButtonProps\\",
\\"isOptional\\": true
@@ -4715,7 +4715,7 @@ exports[`Props Table 1`] = `
},
\\"variation\\": {
\\"name\\": \\"variation\\",
- \\"type\\": \\"'primary' | 'link' | 'menu'\\",
+ \\"type\\": \\"| 'primary'\\\\n | 'link'\\\\n | 'menu'\\\\n | 'warning'\\\\n | 'destructive'\\",
\\"description\\": \\"Changes the visual weight of the button.\\",
\\"category\\": \\"ButtonProps\\",
\\"isOptional\\": true
@@ -11420,7 +11420,7 @@ exports[`Props Table 1`] = `
},
\\"variation\\": {
\\"name\\": \\"variation\\",
- \\"type\\": \\"'primary' | 'link' | 'menu'\\",
+ \\"type\\": \\"| 'primary'\\\\n | 'link'\\\\n | 'menu'\\\\n | 'warning'\\\\n | 'destructive'\\",
\\"description\\": \\"Changes the visual weight of the button.\\",
\\"category\\": \\"ButtonProps\\",
\\"isOptional\\": true
@@ -11724,7 +11724,7 @@ exports[`Props Table 1`] = `
},
\\"variation\\": {
\\"name\\": \\"variation\\",
- \\"type\\": \\"'primary' | 'link' | 'menu'\\",
+ \\"type\\": \\"| 'primary'\\\\n | 'link'\\\\n | 'menu'\\\\n | 'warning'\\\\n | 'destructive'\\",
\\"description\\": \\"Changes the visual weight of the button.\\",
\\"category\\": \\"ButtonProps\\",
\\"isOptional\\": true
diff --git a/docs/src/pages/[platform]/components/button/demo.tsx b/docs/src/pages/[platform]/components/button/demo.tsx
index f97c6dcb54e..46cfd7b40ab 100644
--- a/docs/src/pages/[platform]/components/button/demo.tsx
+++ b/docs/src/pages/[platform]/components/button/demo.tsx
@@ -48,6 +48,8 @@ const PropControls = (props) => {
+
+
+
+
@@ -92,6 +94,8 @@ Use the `variation` prop to change the Button variation. Available options are `
+
+
```
diff --git a/packages/react/src/primitives/Button/__tests__/Button.test.tsx b/packages/react/src/primitives/Button/__tests__/Button.test.tsx
index 75e6ac0c032..026928bf3c9 100644
--- a/packages/react/src/primitives/Button/__tests__/Button.test.tsx
+++ b/packages/react/src/primitives/Button/__tests__/Button.test.tsx
@@ -15,14 +15,29 @@ describe('Button test suite', () => {
+
+
+
);
const primary = await screen.findByTestId('primary');
const link = await screen.findByTestId('link');
+ const menu = await screen.findByTestId('menu');
+ const warning = await screen.findByTestId('warning');
+ const destructive = await screen.findByTestId('destructive');
expect(primary.classList).toContain('amplify-button--primary');
expect(link.classList).toContain('amplify-button--link');
+ expect(menu.classList).toContain('amplify-button--menu');
+ expect(warning.classList).toContain('amplify-button--warning');
+ expect(destructive.classList).toContain('amplify-button--destructive');
});
it('should add the disabled class with the disabled attribute', async () => {
diff --git a/packages/react/src/primitives/types/button.ts b/packages/react/src/primitives/types/button.ts
index 5567d267923..822d0efcbd5 100644
--- a/packages/react/src/primitives/types/button.ts
+++ b/packages/react/src/primitives/types/button.ts
@@ -4,7 +4,12 @@ import { FlexContainerStyleProps } from './flex';
export type ButtonSizes = Sizes;
export type ButtonTypes = 'button' | 'reset' | 'submit';
-export type ButtonVariations = 'primary' | 'link' | 'menu';
+export type ButtonVariations =
+ | 'primary'
+ | 'link'
+ | 'menu'
+ | 'warning'
+ | 'destructive';
export interface ButtonProps extends ViewProps, FlexContainerStyleProps {
/**
diff --git a/packages/ui/src/theme/__tests__/defaultTheme.test.ts b/packages/ui/src/theme/__tests__/defaultTheme.test.ts
index 722836b6151..4ab206315de 100644
--- a/packages/ui/src/theme/__tests__/defaultTheme.test.ts
+++ b/packages/ui/src/theme/__tests__/defaultTheme.test.ts
@@ -182,6 +182,47 @@ describe('@aws-amplify/ui', () => {
--amplify-components-button-link-loading-border-color: transparent;
--amplify-components-button-link-loading-background-color: transparent;
--amplify-components-button-link-loading-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-warning-background-color: transparent;
+ --amplify-components-button-warning-border-color: var(--amplify-colors-red-60);
+ --amplify-components-button-warning-border-width: var(--amplify-border-widths-small);
+ --amplify-components-button-warning-color: var(--amplify-colors-red-60);
+ --amplify-components-button-warning-hover-border-color: var(--amplify-colors-red-80);
+ --amplify-components-button-warning-hover-background-color: var(--amplify-colors-red-10);
+ --amplify-components-button-warning-hover-color: var(--amplify-colors-font-error);
+ --amplify-components-button-warning-focus-border-color: var(--amplify-colors-red-80);
+ --amplify-components-button-warning-focus-background-color: var(--amplify-colors-red-10);
+ --amplify-components-button-warning-focus-color: var(--amplify-colors-red-80);
+ --amplify-components-button-warning-focus-box-shadow: var(--amplify-components-fieldcontrol-error-focus-box-shadow);
+ --amplify-components-button-warning-active-border-color: var(--amplify-colors-red-100);
+ --amplify-components-button-warning-active-background-color: var(--amplify-colors-red-20);
+ --amplify-components-button-warning-active-color: var(--amplify-colors-red-100);
+ --amplify-components-button-warning-disabled-border-color: var(--amplify-colors-border-tertiary);
+ --amplify-components-button-warning-disabled-background-color: transparent;
+ --amplify-components-button-warning-disabled-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-warning-loading-border-color: var(--amplify-colors-border-tertiary);
+ --amplify-components-button-warning-loading-background-color: transparent;
+ --amplify-components-button-warning-loading-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-destructive-border-color: transparent;
+ --amplify-components-button-destructive-border-width: var(--amplify-border-widths-small);
+ --amplify-components-button-destructive-border-style: solid;
+ --amplify-components-button-destructive-background-color: var(--amplify-colors-red-60);
+ --amplify-components-button-destructive-color: var(--amplify-colors-font-inverse);
+ --amplify-components-button-destructive-disabled-border-color: transparent;
+ --amplify-components-button-destructive-disabled-background-color: var(--amplify-colors-background-disabled);
+ --amplify-components-button-destructive-disabled-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-destructive-loading-border-color: transparent;
+ --amplify-components-button-destructive-loading-background-color: var(--amplify-colors-background-disabled);
+ --amplify-components-button-destructive-loading-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-destructive-hover-border-color: transparent;
+ --amplify-components-button-destructive-hover-background-color: var(--amplify-colors-red-80);
+ --amplify-components-button-destructive-hover-color: var(--amplify-colors-font-inverse);
+ --amplify-components-button-destructive-focus-border-color: transparent;
+ --amplify-components-button-destructive-focus-background-color: var(--amplify-colors-red-80);
+ --amplify-components-button-destructive-focus-color: var(--amplify-colors-font-inverse);
+ --amplify-components-button-destructive-focus-box-shadow: var(--amplify-components-fieldcontrol-error-focus-box-shadow);
+ --amplify-components-button-destructive-active-border-color: transparent;
+ --amplify-components-button-destructive-active-background-color: var(--amplify-colors-red-100);
+ --amplify-components-button-destructive-active-color: var(--amplify-colors-font-inverse);
--amplify-components-button-small-font-size: var(--amplify-components-fieldcontrol-small-font-size);
--amplify-components-button-small-padding-block-start: var(--amplify-components-fieldcontrol-small-padding-block-start);
--amplify-components-button-small-padding-block-end: var(--amplify-components-fieldcontrol-small-padding-block-end);
diff --git a/packages/ui/src/theme/__tests__/overrides.test.ts b/packages/ui/src/theme/__tests__/overrides.test.ts
index f46f49594de..2abffc7c99d 100644
--- a/packages/ui/src/theme/__tests__/overrides.test.ts
+++ b/packages/ui/src/theme/__tests__/overrides.test.ts
@@ -216,6 +216,47 @@ describe('@aws-amplify/ui', () => {
--amplify-components-button-link-loading-border-color: transparent;
--amplify-components-button-link-loading-background-color: transparent;
--amplify-components-button-link-loading-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-warning-background-color: transparent;
+ --amplify-components-button-warning-border-color: var(--amplify-colors-red-60);
+ --amplify-components-button-warning-border-width: var(--amplify-border-widths-small);
+ --amplify-components-button-warning-color: var(--amplify-colors-red-60);
+ --amplify-components-button-warning-hover-border-color: var(--amplify-colors-red-80);
+ --amplify-components-button-warning-hover-background-color: var(--amplify-colors-red-10);
+ --amplify-components-button-warning-hover-color: var(--amplify-colors-font-error);
+ --amplify-components-button-warning-focus-border-color: var(--amplify-colors-red-80);
+ --amplify-components-button-warning-focus-background-color: var(--amplify-colors-red-10);
+ --amplify-components-button-warning-focus-color: var(--amplify-colors-red-80);
+ --amplify-components-button-warning-focus-box-shadow: var(--amplify-components-fieldcontrol-error-focus-box-shadow);
+ --amplify-components-button-warning-active-border-color: var(--amplify-colors-red-100);
+ --amplify-components-button-warning-active-background-color: var(--amplify-colors-red-20);
+ --amplify-components-button-warning-active-color: var(--amplify-colors-red-100);
+ --amplify-components-button-warning-disabled-border-color: var(--amplify-colors-border-tertiary);
+ --amplify-components-button-warning-disabled-background-color: transparent;
+ --amplify-components-button-warning-disabled-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-warning-loading-border-color: var(--amplify-colors-border-tertiary);
+ --amplify-components-button-warning-loading-background-color: transparent;
+ --amplify-components-button-warning-loading-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-destructive-border-color: transparent;
+ --amplify-components-button-destructive-border-width: var(--amplify-border-widths-small);
+ --amplify-components-button-destructive-border-style: solid;
+ --amplify-components-button-destructive-background-color: var(--amplify-colors-red-60);
+ --amplify-components-button-destructive-color: var(--amplify-colors-font-inverse);
+ --amplify-components-button-destructive-disabled-border-color: transparent;
+ --amplify-components-button-destructive-disabled-background-color: var(--amplify-colors-background-disabled);
+ --amplify-components-button-destructive-disabled-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-destructive-loading-border-color: transparent;
+ --amplify-components-button-destructive-loading-background-color: var(--amplify-colors-background-disabled);
+ --amplify-components-button-destructive-loading-color: var(--amplify-colors-font-disabled);
+ --amplify-components-button-destructive-hover-border-color: transparent;
+ --amplify-components-button-destructive-hover-background-color: var(--amplify-colors-red-80);
+ --amplify-components-button-destructive-hover-color: var(--amplify-colors-font-inverse);
+ --amplify-components-button-destructive-focus-border-color: transparent;
+ --amplify-components-button-destructive-focus-background-color: var(--amplify-colors-red-80);
+ --amplify-components-button-destructive-focus-color: var(--amplify-colors-font-inverse);
+ --amplify-components-button-destructive-focus-box-shadow: var(--amplify-components-fieldcontrol-error-focus-box-shadow);
+ --amplify-components-button-destructive-active-border-color: transparent;
+ --amplify-components-button-destructive-active-background-color: var(--amplify-colors-red-100);
+ --amplify-components-button-destructive-active-color: var(--amplify-colors-font-inverse);
--amplify-components-button-small-font-size: var(--amplify-components-fieldcontrol-small-font-size);
--amplify-components-button-small-padding-block-start: var(--amplify-components-fieldcontrol-small-padding-block-start);
--amplify-components-button-small-padding-block-end: var(--amplify-components-fieldcontrol-small-padding-block-end);
diff --git a/packages/ui/src/theme/css/component/button.scss b/packages/ui/src/theme/css/component/button.scss
index f0013601e99..d6df024ffe7 100644
--- a/packages/ui/src/theme/css/component/button.scss
+++ b/packages/ui/src/theme/css/component/button.scss
@@ -203,6 +203,112 @@
color: var(--amplify-components-button-link-active-color);
}
}
+
+ &--destructive {
+ border-width: var(--amplify-components-button-destructive-border-width);
+ background-color: var(--amplify-components-button-destructive-background-color);
+ border-color: var(--amplify-components-button-destructive-border-color);
+ color: var(--amplify-components-button-destructive-color);
+
+ &:hover {
+ background-color: var(
+ --amplify-components-button-destructive-hover-background-color
+ );
+ border-color: var(--amplify-components-button-destructive-hover-border-color);
+ color: var(--amplify-components-button-destructive-hover-color);
+ }
+
+ &:focus {
+ background-color: var(
+ --amplify-components-button-destructive-focus-background-color
+ );
+ border-color: var(--amplify-components-button-destructive-focus-border-color);
+ color: var(--amplify-components-button-destructive-focus-color);
+ box-shadow: var(--amplify-components-button-destructive-focus-box-shadow);
+ }
+
+ &:active {
+ background-color: var(
+ --amplify-components-button-destructive-active-background-color
+ );
+ border-color: var(
+ --amplify-components-button-destructive-active-border-color
+ );
+ color: var(--amplify-components-button-destructive-active-color);
+ }
+
+ --amplify-internal-button-disabled-border-color: var(
+ --amplify-components-button-destructive-disabled-border-color
+ );
+ --amplify-internal-button-disabled-background-color: var(
+ --amplify-components-button-destructive-disabled-background-color
+ );
+ --amplify-internal-button-disabled-color: var(
+ --amplify-components-button-destructive-disabled-color
+ );
+ --amplify-internal-button-loading-background-color: var(
+ --amplify-components-button-destructive-loading-background-color
+ );
+ --amplify-internal-button-loading-border-color: var(
+ --amplify-components-button-destructive-loading-border-color
+ );
+ --amplify-internal-button-loading-color: var(
+ --amplify-components-button-destructive-loading-color
+ );
+ }
+
+ &--warning {
+ background-color: var(--amplify-components-button-warning-background-color);
+ border-color: var(--amplify-components-button-warning-border-color);
+ border-width: var(--amplify-components-button-warning-border-width);
+ color: var(--amplify-components-button-warning-color);
+
+ --amplify-internal-button-disabled-text-decoration: none;
+ --amplify-internal-button-disabled-border-color: var(
+ --amplify-components-button-warning-disabled-border-color
+ );
+ --amplify-internal-button-disabled-background-color: var(
+ --amplify-components-button-warning-disabled-background-color
+ );
+ --amplify-internal-button-disabled-color: var(
+ --amplify-components-button-warning-disabled-color
+ );
+ --amplify-internal-button-loading-background-color: var(
+ --amplify-components-button-warning-loading-background-color
+ );
+ --amplify-internal-button-loading-border-color: var(
+ --amplify-components-button-warning-loading-border-color
+ );
+ --amplify-internal-button-loading-color: var(
+ --amplify-components-button-warning-loading-color
+ );
+ --amplify-internal-button-loading-text-decoration: none;
+
+ &:hover {
+ background-color: var(
+ --amplify-components-button-warning-hover-background-color
+ );
+ border-color: var(--amplify-components-button-warning-hover-border-color);
+ color: var(--amplify-components-button-warning-hover-color);
+ }
+
+ &:focus {
+ background-color: var(
+ --amplify-components-button-warning-focus-background-color
+ );
+ border-color: var(--amplify-components-button-warning-focus-border-color);
+ color: var(--amplify-components-button-warning-focus-color);
+ box-shadow: var(--amplify-components-button-warning-focus-box-shadow);
+ }
+
+ &:active {
+ background-color: var(
+ --amplify-components-button-warning-active-background-color
+ );
+ border-color: var(--amplify-components-button-warning-active-border-color);
+ color: var(--amplify-components-button-warning-active-color);
+ }
+ }
&--small {
font-size: var(--amplify-components-button-small-font-size);
diff --git a/packages/ui/src/theme/tokens/components/button.ts b/packages/ui/src/theme/tokens/components/button.ts
index f60a06f59ab..5eabae4f2a2 100644
--- a/packages/ui/src/theme/tokens/components/button.ts
+++ b/packages/ui/src/theme/tokens/components/button.ts
@@ -72,6 +72,8 @@ export type ButtonTokens