diff --git a/packages/calcite-components/src/assets/styles/includes.scss b/packages/calcite-components/src/assets/styles/includes.scss
index 1f34b2dff8a..383de896e84 100644
--- a/packages/calcite-components/src/assets/styles/includes.scss
+++ b/packages/calcite-components/src/assets/styles/includes.scss
@@ -106,50 +106,53 @@
}
}
-@mixin x-button() {
- :host([scale="s"]) {
- .x-button {
- inline-size: theme("spacing.4");
- block-size: theme("spacing.4");
- }
- }
-
- :host([scale="m"]) {
- .x-button {
- inline-size: theme("spacing.6");
- block-size: theme("spacing.6");
- }
- }
-
- :host([scale="l"]) {
- .x-button {
- inline-size: theme("spacing.8");
- block-size: theme("spacing.8");
- }
- }
-
+@mixin x-button(
+ $size: "var(--calcite-internal-close-size, 1.5rem)",
+ $padding: "0",
+ $color: "var(--calcite-close-icon-color, var(--calcite-color-text-1))",
+ $background-color: "var(--calcite-close-background-color, var(--calcite-color-transparent))",
+ $background-color-hover: "var(--calcite-close-background-color-hover, var(--calcite-color-transparent-hover))",
+ $background-color-press: "var(--calcite-close-background-color-press, var(--calcite-color-transparent-press))"
+) {
.x-button {
- @apply appearance-none bg-transparent border-2 content-center cursor-pointer flex focus-base items-center justify-center m-0 self-center text-color-3 transition-default;
-
- border-radius: 50%;
- border-color: transparent;
- background-color: var(--calcite-color-foreground-2);
+ @apply transition-default;
+ border-style: none;
+ cursor: pointer;
+ outline-color: transparent;
+ align-items: center;
+ margin: 0;
+ background-color: #{$background-color};
+ -webkit-appearance: none;
+ display: flex;
+ align-content: center;
+ justify-content: center;
+ color: #{$color};
+ block-size: #{$size};
+ inline-size: #{$size};
+ min-block-size: #{$size};
+ min-inline-size: #{$size};
+ padding: #{$padding};
- &:active,
- &:hover {
- @apply text-color-1;
- background-color: var(--calcite-color-foreground-3);
+ &:hover,
+ &:focus {
+ background-color: #{$background-color-hover};
+ }
+ &:focus {
+ @apply focus-inset;
}
&:active {
- @apply border-solid;
- border-color: theme("borderColor.color-brand");
+ background-color: #{$background-color-press};
}
- & calcite-icon {
+ calcite-icon {
color: inherit;
}
}
+
+ .x-button--round {
+ border-radius: 9999px;
+ }
}
@mixin close-button(
diff --git a/packages/calcite-components/src/components/button/button.e2e.ts b/packages/calcite-components/src/components/button/button.e2e.ts
index e22d5988e87..12bef5d60a4 100644
--- a/packages/calcite-components/src/components/button/button.e2e.ts
+++ b/packages/calcite-components/src/components/button/button.e2e.ts
@@ -509,14 +509,11 @@ describe("calcite-button", () => {
Layers
`;
- let page;
- let buttonEl;
- let buttonHoverStyle;
it("should have defined CSS custom properties", async () => {
- page = await newE2EPage({ html: buttonSnippet });
+ const page = await newE2EPage({ html: buttonSnippet });
const buttonStyles = await page.evaluate(() => {
- buttonEl = document.querySelector("calcite-button");
+ const buttonEl = document.querySelector("calcite-button");
buttonEl.style.setProperty("--calcite-color-transparent-hover", "rgba(34, 23, 200, 0.4)");
buttonEl.style.setProperty("--calcite-color-transparent-press", "rgba(1, 20, 44, 0.1");
return {
@@ -530,31 +527,31 @@ describe("calcite-button", () => {
describe("when mode attribute is not provided", () => {
it("should render button pseudo classes with default values tied to light mode", async () => {
- page = await newE2EPage({ html: buttonSnippet });
- buttonEl = await page.find("calcite-button >>> button");
+ const page = await newE2EPage({ html: buttonSnippet });
+ const buttonEl = await page.find("calcite-button >>> button");
await buttonEl.hover();
await page.waitForChanges();
- buttonHoverStyle = await buttonEl.getComputedStyle();
+ const buttonHoverStyle = await buttonEl.getComputedStyle();
expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual("rgba(0, 0, 0, 0.04)");
});
});
describe("when mode attribute is dark", () => {
it("should render button pseudo classes with value tied to dark mode", async () => {
- page = await newE2EPage({
+ const page = await newE2EPage({
html: `
${buttonSnippet}
`,
});
- buttonEl = await page.find("calcite-button >>> button");
+ const buttonEl = await page.find("calcite-button >>> button");
await buttonEl.hover();
await page.waitForChanges();
- buttonHoverStyle = await buttonEl.getComputedStyle();
+ const buttonHoverStyle = await buttonEl.getComputedStyle();
expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual("rgba(255, 255, 255, 0.04)");
});
});
it("should allow the CSS custom property to be overridden", async () => {
const overrideStyle = "rgba(255, 255, 0, 0.9)";
- page = await newE2EPage({
+ const page = await newE2EPage({
html: `
${buttonSnippet}
`,
});
- buttonEl = await page.find("calcite-button >>> button");
+ const buttonEl = await page.find("calcite-button >>> button");
await buttonEl.hover();
await page.waitForChanges();
- buttonHoverStyle = await buttonEl.getComputedStyle();
+ const buttonHoverStyle = await buttonEl.getComputedStyle();
expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual(overrideStyle);
});
});
diff --git a/packages/calcite-components/src/components/button/button.scss b/packages/calcite-components/src/components/button/button.scss
index c101ad48115..de0a7697e3c 100644
--- a/packages/calcite-components/src/components/button/button.scss
+++ b/packages/calcite-components/src/components/button/button.scss
@@ -3,9 +3,10 @@
*
* These properties can be overridden using the component's tag as selector.
*
- * @prop --calcite-button-background-color: Specifies the component's background color when appearance="solid" or appearance="outline-fill".
- * @prop --calcite-button-border-color: Specifies the component's border color when it has appearance="outline" or appearance="outline-fill".
+ * @prop --calcite-button-background-color: Specifies the component's background color.
+ * @prop --calcite-button-border-color: Specifies the component's border color.
* @prop --calcite-button-corner-radius: Specifies the component's corner radius.
+ * @prop --calcite-button-icon-color: Specifies the component's `iconStart` and/or `iconEnd` color.
* @prop --calcite-button-loader-color: Specifies the component's loader color.
* @prop --calcite-button-shadow-color: Specifies the component's box-shadow color.
* @prop --calcite-button-text-color: Specifies the component's text color.
@@ -20,7 +21,7 @@
button {
--calcite-internal-button-content-margin: theme("margin.2");
--calcite-internal-button-padding-x: 7px;
- --calcite-internal-button-padding-y-internal: 3px;
+ --calcite-internal-button-padding-y: 3px;
@apply appearance-none
border-none
@@ -43,13 +44,41 @@
--calcite-button-background-color,
var(--calcite-internal-button-background-color, var(--calcite-color-transparent))
);
- border-color: var(
+ border-block-start-color: var(
--calcite-button-border-color,
- var(--calcite-internal-button-border-color, var(--calcite-color-transparent))
+ var(
+ --calcite-internal-button-border-block-start-color,
+ var(--calcite-internal-button-border-color, var(--calcite-color-transparent))
+ )
);
+ border-block-end-color: var(
+ --calcite-button-border-color,
+ var(
+ --calcite-internal-button-border-block-end-color,
+ var(--calcite-internal-button-border-color, var(--calcite-color-transparent))
+ )
+ );
+ border-inline-start-color: var(
+ --calcite-button-border-color,
+ var(
+ --calcite-internal-button-border-inline-start-color,
+ var(--calcite-internal-button-border-color, var(--calcite-color-transparent))
+ )
+ );
+ border-inline-end-color: var(
+ --calcite-button-border-color,
+ var(
+ --calcite-internal-button-border-inline-end-color,
+ var(--calcite-internal-button-border-color, var(--calcite-color-transparent))
+ )
+ );
+ border-style: solid;
+ border-width: var(--calcite-border-width-sm);
+ box-shadow: inset 0 0 0 0
+ var(--calcite-button-shadow-color, var(--calcite-internal-button-shadow-color, var(--calcite-color-transparent)));
border-radius: var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, 0));
color: var(--calcite-button-text-color, var(--calcite-internal-button-text-color, currentColor));
- padding-block: var(--calcite-internal-button-padding-y-internal);
+ padding-block: var(--calcite-internal-button-padding-y);
padding-inline: var(--calcite-internal-button-padding-x);
// include transition from focus
@@ -72,7 +101,13 @@
}
calcite-loader {
- color: var(--calcite-button-loader-color, var(--calcite-internal-button-loader-color, currentColor));
+ color: var(
+ --calcite-button-loader-color,
+ var(
+ --calcite-internal-button-loader-color,
+ var(--calcite-button-text-color, var(--calcite-internal-button-text-color))
+ )
+ );
}
}
}
@@ -177,14 +212,6 @@
}
}
-.icon {
- @apply relative
- m-0
- inline-flex
- font-normal;
- line-height: inherit;
-}
-
@include disabled();
@keyframes loader-in {
@@ -254,6 +281,7 @@
a {
--calcite-internal-button-text-color: var(--calcite-color-text-inverse);
--calcite-internal-button-background-color: var(--calcite-color-brand);
+ --calcite-internal-button-loader-color: var(--calcite-color-text-inverse);
&:hover {
--calcite-internal-button-background-color: var(--calcite-color-brand-hover);
@@ -268,6 +296,7 @@
a {
--calcite-internal-button-text-color: var(--calcite-color-text-inverse);
--calcite-internal-button-background-color: var(--calcite-color-status-danger);
+ --calcite-internal-button-loader-color: var(--calcite-color-text-inverse);
&:hover {
--calcite-internal-button-background-color: var(--calcite-color-status-danger-hover);
@@ -282,6 +311,7 @@
a {
--calcite-internal-button-text-color: var(--calcite-color-text-1);
--calcite-internal-button-background-color: var(--calcite-color-foreground-3);
+ --calcite-internal-button-loader-color: var(--calcite-color-text-1);
&:hover {
--calcite-internal-button-background-color: var(--calcite-color-foreground-2);
}
@@ -295,6 +325,7 @@
a {
--calcite-internal-button-text-color: var(--calcite-color-text-inverse);
--calcite-internal-button-background-color: var(--calcite-color-inverse);
+ --calcite-internal-button-loader-color: var(--calcite-color-text-inverse);
&:hover {
--calcite-internal-button-background-color: var(--calcite-color-inverse-hover);
}
@@ -323,6 +354,7 @@
a {
--calcite-internal-button-border-color: var(--calcite-color-brand);
--calcite-internal-button-text-color: theme("colors.brand");
+ --calcite-internal-button-loader-color: var(--calcite-color-brand);
&:hover {
--calcite-internal-button-border-color: var(--calcite-color-brand-hover);
@@ -349,6 +381,7 @@
a {
--calcite-internal-button-border-color: var(--calcite-color-status-danger);
--calcite-internal-button-text-color: theme("colors.danger");
+ --calcite-internal-button-loader-color: var(--calcite-color-status-danger);
&:hover {
--calcite-internal-button-border-color: var(--calcite-color-status-danger-hover);
@@ -375,6 +408,7 @@
a {
--calcite-internal-button-border-color: theme("borderColor.color.1");
--calcite-internal-button-text-color: var(--calcite-color-text-1);
+ --calcite-internal-button-loader-color: var(--calcite-color-text-1);
&:hover {
--calcite-internal-button-shadow-color: var(--calcite-color-foreground-3);
@@ -405,6 +439,7 @@
a {
--calcite-internal-button-text-color: var(--calcite-color-text-1);
--calcite-internal-button-border-color: var(--calcite-color-inverse);
+ --calcite-internal-button-loader-color: var(--calcite-color-text-1);
&:hover {
--calcite-internal-button-border-color: var(--calcite-color-inverse-hover);
@@ -441,6 +476,7 @@
a {
--calcite-internal-button-border-color: var(--calcite-color-brand);
--calcite-internal-button-text-color: theme("colors.brand");
+ --calcite-internal-button-loader-color: var(--calcite-color-brand);
&:hover {
--calcite-internal-button-border-color: var(--calcite-color-brand-hover);
@@ -467,6 +503,7 @@
a {
--calcite-internal-button-border-color: var(--calcite-color-status-danger);
--calcite-internal-button-text-color: theme("colors.danger");
+ --calcite-internal-button-loader-color: var(--calcite-color-status-danger);
&:hover {
--calcite-internal-button-border-color: var(--calcite-color-status-danger-hover);
@@ -493,6 +530,7 @@
a {
--calcite-internal-button-text-color: var(--calcite-color-text-1);
--calcite-internal-button-border-color: theme("borderColor.color.1");
+ --calcite-internal-button-loader-color: var(--calcite-color-text-1);
&:hover {
--calcite-internal-button-shadow-color: var(--calcite-color-foreground-3);
@@ -512,6 +550,7 @@
a {
--calcite-internal-button-text-color: var(--calcite-color-text-1);
--calcite-internal-button-border-color: var(--calcite-color-inverse);
+ --calcite-internal-button-loader-color: var(--calcite-color-text-1);
&:hover {
--calcite-internal-button-border-color: var(--calcite-color-inverse-hover);
--calcite-internal-button-shadow-color: var(--calcite-color-inverse-hover);
@@ -540,6 +579,20 @@
}
// transparent
+:host([appearance="transparent"]) {
+ button,
+ a {
+ --calcite-internal-button-background-color: var(--calcite-color-transparent);
+
+ &:hover,
+ &:focus {
+ --calcite-internal-button-background-color: var(--calcite-color-transparent-hover);
+ }
+ &:active {
+ --calcite-internal-button-background-color: var(--calcite-color-transparent-press);
+ }
+ }
+}
:host([appearance="transparent"]:not(.enable-editing-button)) {
button,
a {
@@ -556,6 +609,7 @@
button,
a {
--calcite-internal-button-text-color: theme("colors.brand");
+ --calcite-internal-button-loader-color: var(--calcite-color-brand);
&:hover {
--calcite-internal-button-text-color: theme("colors.brand-hover");
}
@@ -575,6 +629,7 @@
button,
a {
--calcite-internal-button-text-color: theme("colors.danger");
+ --calcite-internal-button-loader-color: var(--calcite-color-status-danger);
&:hover {
--calcite-internal-button-text-color: theme("colors.danger-hover");
}
@@ -601,29 +656,14 @@
:host([appearance="transparent"][kind="neutral"].cancel-editing-button) {
button {
--calcite-internal-button-text-color: var(--calcite-color-text-3);
- @apply text-color-3
- border-t-color-input
- border-b-color-input
- border-t
- border-b;
- border-block-style: solid;
-
- &:not(.content--slotted) {
- --calcite-internal-button-padding-y-internal: 0;
- }
&:hover {
--calcite-internal-button-text-color: var(--calcite-color-text-1);
+ --calcite-internal-button-padding-y: 0;
}
}
}
-:host([appearance="transparent"][kind="neutral"].enable-editing-button) {
- button {
- @apply bg-transparent;
- }
-}
-
:host(.confirm-changes-button),
:host(.cancel-editing-button),
:host(.enable-editing-button) {
@@ -656,7 +696,7 @@
:host([scale="s"]) button,
:host([scale="s"]) a {
- --calcite-internal-button-padding-y-internal: 3px;
+ --calcite-internal-button-padding-y: 3px;
}
:host([scale="m"]) button.content--slotted,
@@ -667,7 +707,7 @@
:host([scale="m"]) button,
:host([scale="m"]) a {
- --calcite-internal-button-padding-y-internal: 7px;
+ --calcite-internal-button-padding-y: 7px;
}
// accommodate for transparent buttons not having borders
:host([scale="m"][appearance="transparent"]) button.content--slotted,
@@ -684,11 +724,11 @@
:host([scale="l"]) {
.button-padding {
--calcite-internal-button-padding-x: theme("padding.4");
- --calcite-internal-button-padding-y-internal: 11px;
+ --calcite-internal-button-padding-y: 11px;
}
//shrink the padding if an icon is present to preserve the height
.button-padding--shrunk {
- --calcite-internal-button-padding-y-internal: 9px;
+ --calcite-internal-button-padding-y: 9px;
}
}
@@ -696,7 +736,7 @@
:host([scale="s"]) button:not(.content--slotted),
:host([scale="s"]) a:not(.content--slotted) {
--calcite-internal-button-padding-x: theme("padding[0.5]");
- --calcite-internal-button-padding-y-internal: 3px;
+ --calcite-internal-button-padding-y: 3px;
@apply text-0h w-6;
min-block-size: theme("height.6");
}
@@ -704,14 +744,14 @@
:host([scale="m"]) button:not(.content--slotted),
:host([scale="m"]) a:not(.content--slotted) {
--calcite-internal-button-padding-x: theme("padding[0.5]");
- --calcite-internal-button-padding-y-internal: 7px;
+ --calcite-internal-button-padding-y: 7px;
@apply text-0h w-8;
min-block-size: theme("height.8");
}
:host([scale="l"]) button:not(.content--slotted),
:host([scale="l"]) a:not(.content--slotted) {
--calcite-internal-button-padding-x: theme("padding[0.5]");
- --calcite-internal-button-padding-y-internal: 9px;
+ --calcite-internal-button-padding-y: 9px;
@apply text-0h w-11;
min-block-size: theme("height.11");
}
@@ -728,7 +768,7 @@
// accommodate for transparent buttons not having borders
:host([scale="l"][appearance="transparent"]) button:not(.content--slotted),
:host([scale="l"][appearance="transparent"]) a:not(.content--slotted) {
- --calcite-internal-button-padding-y-internal: theme("padding[2.5]");
+ --calcite-internal-button-padding-y: theme("padding[2.5]");
}
// generate fab scales (scenario: 2 icons, ie., should not be square)
diff --git a/packages/calcite-components/src/components/color-picker/color-picker.e2e.ts b/packages/calcite-components/src/components/color-picker/color-picker.e2e.ts
index 9999490f114..f23c14aa9d5 100644
--- a/packages/calcite-components/src/components/color-picker/color-picker.e2e.ts
+++ b/packages/calcite-components/src/components/color-picker/color-picker.e2e.ts
@@ -134,7 +134,7 @@ describe("calcite-color-picker", () => {
const buttons = await findAll(page, `calcite-color-picker >>> .${CSS.container} calcite-button`);
- expect(buttons).toHaveLength(2);
+ expect(buttons).toHaveLength(4);
for (const button of buttons) {
expect(await button.getProperty("type")).toBe("button");
diff --git a/packages/calcite-components/src/components/combobox/combobox.scss b/packages/calcite-components/src/components/combobox/combobox.scss
index c47509a8c12..bda08cc4725 100644
--- a/packages/calcite-components/src/components/combobox/combobox.scss
+++ b/packages/calcite-components/src/components/combobox/combobox.scss
@@ -16,15 +16,13 @@
@apply relative block;
}
-@include disabled();
-@include x-button();
-
:host([scale="s"]) {
@apply text-n2;
--calcite-combobox-item-spacing-unit-l: theme("spacing.2");
--calcite-combobox-item-spacing-unit-s: theme("spacing.1");
--calcite-combobox-input-height: theme("spacing.4");
--calcite-internal-combobox-input-margin-block: calc(theme("spacing.1") - theme("borderWidth.DEFAULT"));
+ --calcite-internal-close-size: 1rem;
.x-button {
margin-inline: theme("spacing.2");
@@ -37,6 +35,7 @@
--calcite-combobox-item-spacing-unit-s: theme("spacing.2");
--calcite-combobox-input-height: theme("spacing.4");
--calcite-internal-combobox-input-margin-block: calc(theme("spacing.2") - theme("borderWidth.DEFAULT"));
+ --calcite-internal-close-size: 1.5rem;
.x-button {
margin-inline-end: theme("spacing.3");
@@ -49,12 +48,17 @@
--calcite-combobox-item-spacing-unit-s: theme("spacing.3");
--calcite-combobox-input-height: theme("spacing.6");
--calcite-internal-combobox-input-margin-block: calc(theme("spacing[2.5]") - theme("borderWidth.DEFAULT"));
+ --calcite-internal-close-size: 2rem;
.x-button {
margin-inline-end: theme("spacing.4");
}
}
+.x-button {
+ align-self: center;
+}
+
.wrapper {
@apply focus-base flex border border-solid;
padding-block: calc(var(--calcite-combobox-item-spacing-unit-s) / 4);
@@ -232,6 +236,12 @@ calcite-chip {
@apply block;
}
+@include disabled();
+@include x-button(
+ $background-color: "var(--calcite-close-background-color, var(--calcite-color-foreground-2))",
+ $background-color-hover: "var(--calcite-close-background-color-hover, var(--calcite-color-foreground-3))",
+ $color: "var(--calcite-close-icon-color, var(--calcite-color-text-3))"
+);
@include form-validation-message();
@include hidden-form-input();
@include base-component();
diff --git a/packages/calcite-components/src/components/combobox/combobox.tsx b/packages/calcite-components/src/components/combobox/combobox.tsx
index c51d8481561..1d5a7d085e9 100644
--- a/packages/calcite-components/src/components/combobox/combobox.tsx
+++ b/packages/calcite-components/src/components/combobox/combobox.tsx
@@ -100,6 +100,8 @@ export class Combobox
// #region Private Properties
+ private closeButtonEl = createRef();
+
private allSelectedIndicatorChipEl: Chip["el"];
private chipContainerEl: HTMLDivElement;
@@ -1778,6 +1780,7 @@ export class Combobox
disabled={this.disabled}
key="close-button"
label={this.messages.clear}
+ ref={this.closeButtonEl}
scale={this.scale}
/>
) : null}
diff --git a/packages/calcite-components/src/components/functional/XButton.tsx b/packages/calcite-components/src/components/functional/XButton.tsx
index db5a38f4e1c..72a7d99d188 100644
--- a/packages/calcite-components/src/components/functional/XButton.tsx
+++ b/packages/calcite-components/src/components/functional/XButton.tsx
@@ -3,24 +3,45 @@ import { h, LuminaJsx } from "@arcgis/lumina";
import { Scale } from "../interfaces";
import { getIconScale } from "../../utils/component";
-export interface XButtonProps extends LuminaJsx.CustomAttributes {
+export interface XButtonProps extends LuminaJsx.CustomAttributes {
disabled: boolean;
+ focusable?: boolean;
label: string;
+ round?: boolean;
scale: Scale;
+ title?: string;
onClick?: LuminaJsx.DOMAttributes["onClick"];
}
export const CSS = {
button: "x-button",
+ buttonRound: "x-button--round",
};
-export const XButton = ({ disabled, key, label, scale }: XButtonProps): TemplateResult => (
+export const XButton = ({
+ disabled,
+ focusable,
+ key,
+ label,
+ onClick,
+ ref,
+ round = true,
+ scale,
+ title,
+}: XButtonProps): TemplateResult => (