diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml
index b7cd1b7c89f..3b50413e3d8 100644
--- a/.github/ISSUE_TEMPLATE/enhancement.yml
+++ b/.github/ISSUE_TEMPLATE/enhancement.yml
@@ -66,6 +66,7 @@ body:
- label: "@esri/calcite-components"
- label: "@esri/calcite-components-react"
- label: "@esri/calcite-design-tokens"
+ - label: "@esri/calcite-ui-icons"
- label: "@esri/eslint-plugin-calcite-components"
- type: dropdown
id: esri-team
diff --git a/.github/scripts/notifyAboutIconRequest.js b/.github/scripts/notifyAboutIconRequest.js
new file mode 100644
index 00000000000..024bcd8d125
--- /dev/null
+++ b/.github/scripts/notifyAboutIconRequest.js
@@ -0,0 +1,33 @@
+// @ts-check
+
+// If the "calcite-ui-icons" label is added to an issue, generates a notification to the Icons team leads to review
+// The secret is formatted like so: icon-team-member-1, icon-team-member-2, icon-team-member-3
+// Note the script automatically adds the "@" character in to notify the icon team lead(s)
+
+/** @param {import('github-script').AsyncFunctionArguments} AsyncFunctionArguments */
+module.exports = async ({ github, context }) => {
+ const { repo, owner } = context.repo;
+
+ const payload = /** @type {import('@octokit/webhooks-types').IssuesLabeledEvent} */ (context.payload);
+ const {
+ issue: { number },
+ } = payload;
+
+ const { ICONS_TEAM } = process.env;
+
+ // Add a "@" character to notify the user
+ const icon_leads = ICONS_TEAM?.split(",").map((v) => " @" + v.trim());
+
+ if (!icon_leads?.length) {
+ console.error("unable to determine icon leads");
+ process.exit(1);
+ }
+
+ // Add a comment to issues with the 'calcite-ui-icons' label to notify icon team lead(s)
+ await github.rest.issues.createComment({
+ owner,
+ repo,
+ issue_number: number,
+ body: `cc ${icon_leads}`,
+ });
+};
diff --git a/.github/scripts/removeIssuesFromDesignProjects.js b/.github/scripts/removeIssueFromDesignProjects.js
similarity index 93%
rename from .github/scripts/removeIssuesFromDesignProjects.js
rename to .github/scripts/removeIssueFromDesignProjects.js
index 36d7ed65bc3..c9e301a2538 100644
--- a/.github/scripts/removeIssuesFromDesignProjects.js
+++ b/.github/scripts/removeIssueFromDesignProjects.js
@@ -52,7 +52,7 @@ try {
const deleteQuery = `mutation { deleteProjectV2Item(input: {projectId: "${projectItem.project.id}", itemId: "${projectItem.id}"}) { clientMutationId } }`;
runQuery(deleteQuery);
createComment(
- `The issue has been removed from the [${projectItem.project.title}](${projectItem.project.url}) project.`,
+ `This issue has been removed from the [${projectItem.project.title}](${projectItem.project.url}) project.`,
);
console.log("Issue removed from project.");
} else {
diff --git a/.github/workflows/issue-notifications.yaml b/.github/workflows/issue-notifications.yml
similarity index 80%
rename from .github/workflows/issue-notifications.yaml
rename to .github/workflows/issue-notifications.yml
index 24e26fb5f4d..2ce21e74e7b 100644
--- a/.github/workflows/issue-notifications.yaml
+++ b/.github/workflows/issue-notifications.yml
@@ -10,7 +10,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- - name : "Assign for verification"
+ - name: "Assign for verification"
if: github.event.label.name == '3 - installed'
uses: actions/github-script@v7
env:
@@ -51,3 +51,12 @@ jobs:
const action = require('${{ github.workspace }}/.github/scripts/notifyAboutNewComponent.js')
await action({github, context, core})
+ - name: "Icon request notification"
+ if: github.event.label.name == 'calcite-ui-icons'
+ uses: actions/github-script@v7
+ env:
+ ICONS_TEAM: ${{secrets.ICON_LEADS}}
+ with:
+ script: |
+ const action = require('${{ github.workspace }}/.github/scripts/notifyAboutIconRequest.js')
+ await action({github, context, core})
diff --git a/.github/workflows/remove-issue-from-design-projects.yml b/.github/workflows/remove-issue-from-design-projects.yml
index 789ebdb81db..6013684d858 100644
--- a/.github/workflows/remove-issue-from-design-projects.yml
+++ b/.github/workflows/remove-issue-from-design-projects.yml
@@ -1,4 +1,4 @@
-name: Archive Issue in Project
+name: Remove Issue From Project
on:
issues:
@@ -18,7 +18,7 @@ jobs:
with:
node-version-file: package.json
- - name: Archive Issue
+ - name: Remove Issue
env:
GITHUB_TOKEN: ${{ secrets.ADMIN_TOKEN }}
OWNER: ${{ github.repository_owner }}
diff --git a/package-lock.json b/package-lock.json
index 98bcfb7728f..36b7f2ffdee 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -31895,13 +31895,13 @@
},
"packages/calcite-components": {
"name": "@esri/calcite-components",
- "version": "3.0.0-next.105",
+ "version": "3.0.0-next.106",
"license": "SEE LICENSE.md",
"dependencies": {
"@arcgis/components-controllers": "^4.32.0-next.81",
"@arcgis/components-utils": "^4.32.0-next.81",
"@arcgis/lumina": "^4.32.0-next.81",
- "@esri/calcite-ui-icons": "4.0.0-next.9",
+ "@esri/calcite-ui-icons": "4.0.0-next.10",
"@floating-ui/dom": "^1.6.12",
"@floating-ui/utils": "^0.2.8",
"@types/color": "^4.2.0",
@@ -31914,7 +31914,7 @@
"lodash-es": "^4.17.21",
"sortablejs": "^1.15.6",
"timezone-groups": "^0.10.4",
- "type-fest": "4.32.0"
+ "type-fest": "^4.30.1"
},
"devDependencies": {
"@esri/calcite-design-tokens": "3.0.0-next.7",
@@ -31923,10 +31923,10 @@
},
"packages/calcite-components-react": {
"name": "@esri/calcite-components-react",
- "version": "3.0.0-next.105",
+ "version": "3.0.0-next.106",
"license": "SEE LICENSE.md",
"dependencies": {
- "@esri/calcite-components": "3.0.0-next.105",
+ "@esri/calcite-components": "3.0.0-next.106",
"@lit/react": "1.0.7"
},
"peerDependencies": {
@@ -31941,7 +31941,7 @@
},
"packages/calcite-ui-icons": {
"name": "@esri/calcite-ui-icons",
- "version": "4.0.0-next.9",
+ "version": "4.0.0-next.10",
"license": "SEE LICENSE.md",
"bin": {
"spriter": "bin/spriter.js"
diff --git a/packages/calcite-components-react/CHANGELOG.md b/packages/calcite-components-react/CHANGELOG.md
index 6b8faeac828..bafe2674369 100644
--- a/packages/calcite-components-react/CHANGELOG.md
+++ b/packages/calcite-components-react/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [3.0.0-next.106](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@3.0.0-next.105...@esri/calcite-components-react@3.0.0-next.106) (2025-01-22)
+
+**Note:** Version bump only for package @esri/calcite-components-react
+
## [3.0.0-next.105](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@3.0.0-next.104...@esri/calcite-components-react@3.0.0-next.105) (2025-01-17)
**Note:** Version bump only for package @esri/calcite-components-react
diff --git a/packages/calcite-components-react/package.json b/packages/calcite-components-react/package.json
index 3f9d5b4694a..82565e77fb4 100644
--- a/packages/calcite-components-react/package.json
+++ b/packages/calcite-components-react/package.json
@@ -1,6 +1,6 @@
{
"name": "@esri/calcite-components-react",
- "version": "3.0.0-next.105",
+ "version": "3.0.0-next.106",
"description": "A set of React components that wrap calcite components",
"homepage": "https://developers.arcgis.com/calcite-design-system/",
"repository": {
@@ -26,7 +26,7 @@
"tsc": "tsc"
},
"dependencies": {
- "@esri/calcite-components": "3.0.0-next.105",
+ "@esri/calcite-components": "3.0.0-next.106",
"@lit/react": "1.0.7"
},
"peerDependencies": {
diff --git a/packages/calcite-components/CHANGELOG.md b/packages/calcite-components/CHANGELOG.md
index 1f147ed1d15..5eb826aad4a 100644
--- a/packages/calcite-components/CHANGELOG.md
+++ b/packages/calcite-components/CHANGELOG.md
@@ -3,6 +3,19 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [3.0.0-next.106](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@3.0.0-next.105...@esri/calcite-components@3.0.0-next.106) (2025-01-22)
+
+### Features
+
+- **button:** add component tokens ([#10358](https://github.com/Esri/calcite-design-system/issues/10358)) ([a7dc494](https://github.com/Esri/calcite-design-system/commit/a7dc4945bbf9cfabc54a81e8321ac128124ceb8b)), closes [#7180](https://github.com/Esri/calcite-design-system/issues/7180) [#11210](https://github.com/Esri/calcite-design-system/issues/11210)
+- **panel:** control panel header action tokens ([#11300](https://github.com/Esri/calcite-design-system/issues/11300)) ([45f573f](https://github.com/Esri/calcite-design-system/commit/45f573f29d3ed5ffa6eef8420dde3905d16b1c83))
+
+### Bug Fixes
+
+- **color-picker:** fix error caused by initial value with a different format ([#11351](https://github.com/Esri/calcite-design-system/issues/11351)) ([1d187da](https://github.com/Esri/calcite-design-system/commit/1d187daf65e5f0e4f062283e9df10a310e52d3d6)), closes [#10731](https://github.com/Esri/calcite-design-system/issues/10731) [#10310](https://github.com/Esri/calcite-design-system/issues/10310)
+- **combobox, input-time-zone:** fix initial item selection delay ([#11326](https://github.com/Esri/calcite-design-system/issues/11326)) ([59ab243](https://github.com/Esri/calcite-design-system/commit/59ab24368455cc968e990ea2d35f44a6949e4726)), closes [#10731](https://github.com/Esri/calcite-design-system/issues/10731)
+- **tree:** render lines correctly in RTL direction ([#11346](https://github.com/Esri/calcite-design-system/issues/11346)) ([7df1b15](https://github.com/Esri/calcite-design-system/commit/7df1b1555a85eda52e52f6b64457bfbdd25825c7)), closes [#11334](https://github.com/Esri/calcite-design-system/issues/11334)
+
## [3.0.0-next.105](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@3.0.0-next.104...@esri/calcite-components@3.0.0-next.105) (2025-01-17)
**Note:** Version bump only for package @esri/calcite-components
diff --git a/packages/calcite-components/package.json b/packages/calcite-components/package.json
index 4a019c488c1..80c25798cd6 100644
--- a/packages/calcite-components/package.json
+++ b/packages/calcite-components/package.json
@@ -1,6 +1,6 @@
{
"name": "@esri/calcite-components",
- "version": "3.0.0-next.105",
+ "version": "3.0.0-next.106",
"description": "Web Components for Esri's Calcite Design System.",
"homepage": "https://developers.arcgis.com/calcite-design-system/",
"repository": {
@@ -72,7 +72,7 @@
"@arcgis/components-controllers": "^4.32.0-next.81",
"@arcgis/components-utils": "^4.32.0-next.81",
"@arcgis/lumina": "^4.32.0-next.81",
- "@esri/calcite-ui-icons": "4.0.0-next.9",
+ "@esri/calcite-ui-icons": "4.0.0-next.10",
"@floating-ui/dom": "^1.6.12",
"@floating-ui/utils": "^0.2.8",
"@types/color": "^4.2.0",
diff --git a/packages/calcite-components/src/components/action-pad/action-pad.scss b/packages/calcite-components/src/components/action-pad/action-pad.scss
index d5e1a1d3d28..0b400e6db80 100755
--- a/packages/calcite-components/src/components/action-pad/action-pad.scss
+++ b/packages/calcite-components/src/components/action-pad/action-pad.scss
@@ -30,7 +30,7 @@
@apply shadow-2
inline-flex
flex-col
- overflow-y-auto;
+ overflow-hidden;
gap: var(--calcite-action-pad-items-space, 0);
border-radius: calc(var(--calcite-action-pad-corner-radius, 0.125rem) * 2) /* 4px */;
diff --git a/packages/calcite-components/src/components/button/button.e2e.ts b/packages/calcite-components/src/components/button/button.e2e.ts
index b732aa8aae5..5aa148117ff 100644
--- a/packages/calcite-components/src/components/button/button.e2e.ts
+++ b/packages/calcite-components/src/components/button/button.e2e.ts
@@ -1,7 +1,7 @@
// @ts-strict-ignore
import { newE2EPage, E2EElement } from "@arcgis/lumina-compiler/puppeteerTesting";
import { describe, expect, it } from "vitest";
-import { accessible, defaults, disabled, hidden, HYDRATED_ATTR, labelable, t9n } from "../../tests/commonTests";
+import { accessible, defaults, disabled, hidden, HYDRATED_ATTR, labelable, t9n, themed } from "../../tests/commonTests";
import { GlobalTestProps } from "../../tests/utils";
import { html } from "../../../support/formatting";
import { CSS } from "./resources";
@@ -713,4 +713,59 @@ describe("calcite-button", () => {
expect(elementHost).toEqualAttribute("width", "full");
expect(await elementAsButton.getComputedStyle()["width"]).toEqual(await elementHost.getComputedStyle()["width"]);
});
+
+ describe("theme", () => {
+ describe("default", () => {
+ themed("calcite-button", {
+ "--calcite-button-background-color": {
+ shadowSelector: "button",
+ targetProp: "backgroundColor",
+ },
+ "--calcite-button-corner-radius": {
+ shadowSelector: "button",
+ targetProp: "borderRadius",
+ },
+ "--calcite-button-text-color": {
+ shadowSelector: "button",
+ targetProp: "color",
+ },
+ "--calcite-button-border-color": {
+ shadowSelector: "button",
+ targetProp: "borderColor",
+ },
+ });
+ });
+ describe("loading", () => {
+ themed(html``, {
+ "--calcite-button-background-color": {
+ shadowSelector: "button",
+ targetProp: "backgroundColor",
+ },
+ "--calcite-button-corner-radius": {
+ shadowSelector: "button",
+ targetProp: "borderRadius",
+ },
+ "--calcite-button-text-color": {
+ shadowSelector: "button",
+ targetProp: "color",
+ },
+ "--calcite-button-loader-color": {
+ shadowSelector: `.${CSS.loadingIn}`,
+ targetProp: "color",
+ },
+ "--calcite-button-border-color": {
+ shadowSelector: "button",
+ targetProp: "borderColor",
+ },
+ });
+ });
+ describe("outline", () => {
+ themed(html``, {
+ "--calcite-button-border-color": {
+ shadowSelector: "button",
+ targetProp: "borderColor",
+ },
+ });
+ });
+ });
});
diff --git a/packages/calcite-components/src/components/button/button.scss b/packages/calcite-components/src/components/button/button.scss
index 5a01a0740b2..0597fd4d834 100644
--- a/packages/calcite-components/src/components/button/button.scss
+++ b/packages/calcite-components/src/components/button/button.scss
@@ -1,64 +1,89 @@
+/**
+ * CSS Custom Properties
+ *
+ * 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-corner-radius: Specifies the component's corner radius.
+ * @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.
+ */
+
:host {
@apply inline-block w-auto align-middle;
-}
-// fab variants
-:host([round]) {
- border-radius: 50px;
- & a,
- & button {
- border-radius: 50px;
- }
-}
-
-// focus styles
-:host button,
-:host a {
- @apply focus-base;
- &:focus {
- @apply focus-outset;
- }
-}
-// button base
-:host button,
-:host a {
- --calcite-button-content-margin-internal: theme("margin.2");
- --calcite-button-padding-x-internal: 7px;
- --calcite-button-padding-y-internal: 3px;
- padding-block: var(--calcite-button-padding-y-internal);
- padding-inline: var(--calcite-button-padding-x-internal);
- @apply font-inherit
- relative
+ border-radius: var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, 0));
+
+ a,
+ button {
+ --calcite-internal-button-content-margin: theme("margin.2");
+ --calcite-internal-button-padding-x: 7px;
+ --calcite-internal-button-padding-y-internal: 3px;
+
+ @apply appearance-none
+ border-none
box-border
+ cursor-pointer
flex
+ focus-base
+ font-inherit
+ font-normal
h-full
- w-full
- cursor-pointer
- select-none
- appearance-none
items-center
justify-center
- rounded-none
- border-none
+ no-underline
+ relative
+ select-none
text-center
- font-normal
- no-underline;
- // include transition from focus
- transition:
- color var(--calcite-animation-timing) ease-in-out,
- background-color var(--calcite-animation-timing) ease-in-out,
- box-shadow var(--calcite-animation-timing) ease-in-out,
- outline-color var(--calcite-internal-animation-timing-fast) ease-in-out;
- &:hover {
- @apply no-underline;
- }
- & span {
- @apply truncate;
+ w-full;
+
+ background-color: var(
+ --calcite-button-background-color,
+ var(--calcite-internal-button-background-color, var(--calcite-color-transparent))
+ );
+ border-color: var(
+ --calcite-button-border-color,
+ var(--calcite-internal-button-border-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-inline: var(--calcite-internal-button-padding-x);
+
+ // include transition from focus
+ transition:
+ color var(--calcite-animation-timing) ease-in-out,
+ background-color var(--calcite-animation-timing) ease-in-out,
+ box-shadow var(--calcite-animation-timing) ease-in-out,
+ outline-color var(--calcite-internal-animation-timing-fast) ease-in-out;
+
+ &:hover {
+ @apply no-underline;
+ }
+
+ &:focus {
+ @apply focus-outset;
+ }
+
+ span {
+ @apply truncate;
+ }
+
+ calcite-loader {
+ color: var(--calcite-button-loader-color, var(--calcite-internal-button-loader-color, currentColor));
+ }
}
}
+// fab variants
+:host([round]) {
+ --calcite-internal-button-corner-radius: 50px;
+}
+
.content {
- margin-inline: var(--calcite-button-content-margin-internal);
+ margin-inline: var(--calcite-internal-button-content-margin);
}
.icon-start-empty {
@@ -75,13 +100,13 @@
:host([scale="m"]) {
button,
a {
- --calcite-button-content-margin-internal: theme("margin.3");
+ --calcite-internal-button-content-margin: theme("margin.3");
}
}
:host([scale="l"]) {
button,
a {
- --calcite-button-content-margin-internal: theme("margin.4");
+ --calcite-internal-button-content-margin: theme("margin.4");
}
}
@@ -147,7 +172,7 @@
a:not(.content--slotted),
button:not(.content--slotted) {
.icon--start + .icon--end {
- margin-inline-start: var(--calcite-button-content-margin-internal);
+ margin-inline-start: var(--calcite-internal-button-content-margin);
}
}
}
@@ -199,7 +224,7 @@
button.content--slotted,
a.content--slotted {
.calcite-button--loader calcite-loader {
- margin-inline-end: var(--calcite-button-content-margin-internal);
+ margin-inline-end: var(--calcite-internal-button-content-margin);
}
}
// hide icons when loading with no text
@@ -216,271 +241,297 @@
:host([appearance]) {
button,
a {
- @apply border-color-transparent
- border
- border-solid;
+ --calcite-internal-button-border-color: var(--calcite-color-transparent);
+
+ @apply border-solid;
+
+ border-width: var(--calcite-button-border-size, 1px);
}
}
:host([kind="brand"]) {
button,
a {
- @apply text-color-inverse bg-brand;
+ --calcite-internal-button-text-color: var(--calcite-color-text-inverse);
+ --calcite-internal-button-background-color: var(--calcite-color-brand);
+
&:hover,
&:focus {
- @apply bg-brand-hover;
+ --calcite-internal-button-background-color: var(--calcite-color-brand-hover);
}
&:active {
- @apply bg-brand-press;
- }
- calcite-loader {
- @apply text-color-inverse;
+ --calcite-internal-button-background-color: var(--calcite-color-brand-press);
}
}
}
:host([kind="danger"]) {
button,
a {
- @apply text-color-inverse bg-danger;
+ --calcite-internal-button-text-color: var(--calcite-color-text-inverse);
+ --calcite-internal-button-background-color: var(--calcite-color-status-danger);
+
&:hover,
&:focus {
- @apply bg-danger-hover;
+ --calcite-internal-button-background-color: var(--calcite-color-status-danger-hover);
}
&:active {
- @apply bg-danger-press;
- }
- calcite-loader {
- @apply text-color-inverse;
+ --calcite-internal-button-background-color: var(--calcite-color-status-danger-press);
}
}
}
:host([kind="neutral"]) {
button,
a {
- @apply text-color-1 bg-foreground-3;
+ --calcite-internal-button-text-color: var(--calcite-color-text-1);
+ --calcite-internal-button-background-color: var(--calcite-color-foreground-3);
&:hover,
&:focus {
- @apply bg-foreground-2;
+ --calcite-internal-button-background-color: var(--calcite-color-foreground-2);
}
&:active {
- @apply bg-foreground-1;
- }
- calcite-loader {
- @apply text-color-1;
+ --calcite-internal-button-background-color: var(--calcite-color-foreground-1);
}
}
}
:host([kind="inverse"]) {
button,
a {
- @apply text-color-inverse;
- background-color: var(--calcite-color-inverse);
+ --calcite-internal-button-text-color: var(--calcite-color-text-inverse);
+ --calcite-internal-button-background-color: var(--calcite-color-inverse);
&:hover,
&:focus {
- background-color: var(--calcite-color-inverse-hover);
+ --calcite-internal-button-background-color: var(--calcite-color-inverse-hover);
}
&:active {
- background-color: var(--calcite-color-inverse-press);
- }
- calcite-loader {
- @apply text-color-inverse;
+ --calcite-internal-button-background-color: var(--calcite-color-inverse-press);
}
}
}
// outline
+:host([appearance="outline-fill"]),
+:host([appearance="outline"]) {
+ a,
+ button {
+ box-shadow: inset 0 0 0 1px
+ var(--calcite-button-shadow-color, var(--calcite-internal-button-shadow-color, transparent));
+
+ &:hover {
+ box-shadow: inset 0 0 0 1px
+ var(
+ --calcite-button-shadow-color,
+ var(--calcite-internal-button-shadow-color, var(--calcite-color-foreground-3))
+ );
+ }
+ &:focus,
+ &:active {
+ box-shadow: inset 0 0 0 2px
+ var(
+ --calcite-button-shadow-color,
+ var(--calcite-internal-button-shadow-color, var(--calcite-color-foreground-3))
+ );
+ }
+ }
+}
+
:host([appearance="outline-fill"]) {
button,
a {
- @apply bg-foreground-1 border border-solid;
- box-shadow: inset 0 0 0 1px transparent;
+ --calcite-internal-button-background-color: var(--calcite-color-foreground-1);
+ @apply border-solid;
+ border-width: var(--calcite-button-border-size, 1px);
}
}
:host([appearance="outline-fill"][kind="brand"]) {
button,
a {
- @apply border-color-brand bg-foreground-1;
- color: theme("colors.brand");
+ --calcite-internal-button-border-color: var(--calcite-color-brand);
+ --calcite-internal-button-text-color: theme("colors.brand");
+ --calcite-internal-button-background-color: var(--calcite-color-foreground-1);
+
&:hover {
- @apply border-color-brand-hover;
- color: theme("colors.brand-hover");
- box-shadow: inset 0 0 0 1px var(--calcite-color-brand-hover);
+ --calcite-internal-button-border-color: var(--calcite-color-brand-hover);
+ --calcite-internal-button-text-color: theme("colors.brand-hover");
+ --calcite-internal-button-shadow-color: var(--calcite-color-brand-hover);
}
&:focus {
- @apply border-color-brand;
- color: theme("colors.brand");
- box-shadow: inset 0 0 0 2px var(--calcite-color-brand);
+ --calcite-internal-button-border-color: var(--calcite-color-brand);
+ --calcite-internal-button-text-color: theme("colors.brand");
+ --calcite-internal-button-shadow-color: var(--calcite-color-brand);
}
&:active {
- @apply border-color-brand-press;
- color: theme("colors.brand-press");
- box-shadow: inset 0 0 0 2px var(--calcite-color-brand-press);
+ --calcite-internal-button-border-color: var(--calcite-color-brand-press);
+ --calcite-internal-button-text-color: theme("colors.brand-press");
+ --calcite-internal-button-shadow-color: var(--calcite-color-brand-press);
}
calcite-loader {
- color: theme("colors.brand");
+ --calcite-internal-button-loader-color: theme("colors.brand");
}
}
}
:host([appearance="outline-fill"][kind="danger"]) {
button,
a {
- @apply border-color-danger bg-foreground-1;
- color: theme("colors.danger");
+ --calcite-internal-button-border-color: var(--calcite-color-status-danger);
+ --calcite-internal-button-background-color: var(--calcite-color-foreground-1);
+ --calcite-internal-button-text-color: theme("colors.danger");
+
&:hover {
- @apply border-color-danger-hover;
- color: theme("colors.danger-hover");
- box-shadow: inset 0 0 0 1px var(--calcite-color-status-danger-hover);
+ --calcite-internal-button-border-color: var(--calcite-color-status-danger-hover);
+ --calcite-internal-button-text-color: theme("colors.danger-hover");
+ --calcite-internal-button-shadow-color: var(--calcite-color-status-danger-hover);
}
&:focus {
- @apply border-color-danger;
- color: theme("colors.danger");
- box-shadow: inset 0 0 0 2px var(--calcite-color-status-danger);
+ --calcite-internal-button-border-color: var(--calcite-color-status-danger);
+ --calcite-internal-button-text-color: theme("colors.danger");
+ --calcite-internal-button-shadow-color: var(--calcite-color-status-danger);
}
&:active {
- @apply border-color-danger-press;
- color: theme("colors.danger-press");
- box-shadow: inset 0 0 0 2px var(--calcite-color-status-danger-press);
+ --calcite-internal-button-border-color: var(--calcite-color-status-danger-press);
+ --calcite-internal-button-text-color: theme("colors.danger-press");
+ --calcite-internal-button-shadow-color: var(--calcite-color-status-danger-press);
}
calcite-loader {
- color: theme("colors.danger");
+ --calcite-internal-button-loader-color: theme("colors.danger");
}
}
}
:host([appearance="outline-fill"][kind="neutral"]) {
button,
a {
- @apply text-color-1 bg-foreground-1;
- border-color: theme("borderColor.color.1");
+ --calcite-internal-button-border-color: theme("borderColor.color.1");
+ --calcite-internal-button-text-color: var(--calcite-color-text-1);
+ --calcite-internal-button-background-color: var(--calcite-color-foreground-1);
+
&:hover {
- box-shadow: inset 0 0 0 1px var(--calcite-color-foreground-3);
+ --calcite-internal-button-shadow-color: var(--calcite-color-foreground-3);
}
&:focus {
- box-shadow: inset 0 0 0 2px var(--calcite-color-foreground-3);
+ --calcite-internal-button-shadow-color: var(--calcite-color-foreground-3);
}
&:active {
- box-shadow: inset 0 0 0 2px var(--calcite-color-foreground-3);
- }
- calcite-loader {
- @apply text-color-1;
+ --calcite-internal-button-shadow-color: var(--calcite-color-foreground-3);
}
}
}
:host([appearance="outline-fill"][kind="inverse"]) {
button,
a {
- @apply text-color-1 bg-foreground-1;
- border-color: var(--calcite-color-inverse);
+ --calcite-internal-button-text-color: var(--calcite-color-text-1);
+ --calcite-internal-button-background-color: var(--calcite-color-foreground-1);
+ --calcite-internal-button-border-color: var(--calcite-color-inverse);
+
&:hover {
- border-color: var(--calcite-color-inverse-hover);
- box-shadow: inset 0 0 0 1px var(--calcite-color-inverse-hover);
+ --calcite-internal-button-border-color: var(--calcite-color-inverse-hover);
+ --calcite-internal-button-shadow-color: var(--calcite-color-inverse-hover);
}
&:focus {
- border-color: var(--calcite-color-inverse);
- box-shadow: inset 0 0 0 2px var(--calcite-color-inverse);
+ --calcite-internal-button-border-color: var(--calcite-color-inverse);
+ --calcite-internal-button-shadow-color: var(--calcite-color-inverse);
}
&:active {
- border-color: var(--calcite-color-inverse-press);
- box-shadow: inset 0 0 0 2px var(--calcite-color-inverse-press);
- }
- calcite-loader {
- @apply text-color-1;
+ --calcite-internal-button-border-color: var(--calcite-color-inverse-press);
+ --calcite-internal-button-shadow-color: var(--calcite-color-inverse-press);
}
}
}
:host([appearance="outline"]) {
button,
a {
- @apply border border-solid bg-transparent;
- box-shadow: inset 0 0 0 1px transparent;
+ --calcite-internal-button-background-color: var(--calcite-color-transparent);
+
+ @apply border-solid;
+ border-width: var(--calcite-button-border-size, 1px);
}
}
:host([appearance="outline"][kind="brand"]) {
button,
a {
- @apply border-color-brand bg-transparent;
- color: theme("colors.brand");
+ --calcite-internal-button-border-color: var(--calcite-color-brand);
+ --calcite-internal-button-text-color: theme("colors.brand");
+ --calcite-internal-button-background-color: var(--calcite-color-transparent);
+
&:hover {
- @apply border-color-brand-hover;
- color: theme("colors.brand-hover");
- box-shadow: inset 0 0 0 1px var(--calcite-color-brand-hover);
+ --calcite-internal-button-border-color: var(--calcite-color-brand-hover);
+ --calcite-internal-button-text-color: theme("colors.brand-hover");
+ --calcite-internal-button-shadow-color: var(--calcite-color-brand-hover);
}
&:focus {
- @apply border-color-brand;
- color: theme("colors.brand");
- box-shadow: inset 0 0 0 2px var(--calcite-color-brand);
+ --calcite-internal-button-border-color: var(--calcite-color-brand);
+ --calcite-internal-button-text-color: theme("colors.brand");
+ --calcite-internal-button-shadow-color: var(--calcite-color-brand);
}
&:active {
- @apply border-color-brand-press;
- color: theme("colors.brand-press");
- box-shadow: inset 0 0 0 2px var(--calcite-color-brand-press);
+ --calcite-internal-button-border-color: var(--calcite-color-brand-press);
+ --calcite-internal-button-text-color: theme("colors.brand-press");
+ --calcite-internal-button-shadow-color: var(--calcite-color-brand-press);
}
calcite-loader {
- color: theme("colors.brand");
+ --calcite-internal-button-loader-color: theme("colors.brand");
}
}
}
:host([appearance="outline"][kind="danger"]) {
button,
a {
- @apply border-color-danger bg-transparent;
- color: theme("colors.danger");
+ --calcite-internal-button-border-color: var(--calcite-color-status-danger);
+ --calcite-internal-button-text-color: theme("colors.danger");
+ --calcite-internal-button-background-color: var(--calcite-color-transparent);
+
&:hover {
- @apply border-color-danger-hover;
- color: theme("colors.danger-hover");
- box-shadow: inset 0 0 0 1px var(--calcite-color-status-danger-hover);
+ --calcite-internal-button-border-color: var(--calcite-color-status-danger-hover);
+ --calcite-internal-button-text-color: theme("colors.danger-hover");
+ --calcite-internal-button-shadow-color: var(--calcite-color-status-danger-hover);
}
&:focus {
- @apply border-color-danger;
- color: theme("colors.danger");
- box-shadow: inset 0 0 0 2px var(--calcite-color-status-danger);
+ --calcite-internal-button-border-color: var(--calcite-color-status-danger);
+ --calcite-internal-button-text-color: theme("colors.danger");
+ --calcite-internal-button-shadow-color: var(--calcite-color-status-danger);
}
&:active {
- @apply border-color-danger-press;
- color: theme("colors.danger-press");
- box-shadow: inset 0 0 0 2px var(--calcite-color-status-danger-press);
+ --calcite-internal-button-border-color: var(--calcite-color-status-danger-press);
+ --calcite-internal-button-text-color: theme("colors.danger-press");
+ --calcite-internal-button-shadow-color: var(--calcite-color-status-danger-press);
}
calcite-loader {
- color: theme("colors.danger");
+ --calcite-internal-button-loader-color: theme("colors.danger");
}
}
}
:host([appearance="outline"][kind="neutral"]) {
button,
a {
- @apply text-color-1 bg-transparent;
- border-color: theme("borderColor.color.1");
+ --calcite-internal-button-text-color: var(--calcite-color-text-1);
+ --calcite-internal-button-background-color: var(--calcite-color-transparent);
+ --calcite-internal-button-border-color: theme("borderColor.color.1");
+
&:hover {
- box-shadow: inset 0 0 0 1px var(--calcite-color-foreground-3);
+ --calcite-internal-button-shadow-color: var(--calcite-color-foreground-3);
}
&:focus {
- box-shadow: inset 0 0 0 2px var(--calcite-color-foreground-3);
+ --calcite-internal-button-shadow-color: var(--calcite-color-foreground-3);
}
&:active {
- box-shadow: inset 0 0 0 2px var(--calcite-color-foreground-3);
- }
- calcite-loader {
- @apply text-color-1;
+ --calcite-internal-button-shadow-color: var(--calcite-color-foreground-3);
}
}
}
:host([appearance="outline"][kind="inverse"]) {
button,
a {
- @apply text-color-1 bg-transparent;
- border-color: var(--calcite-color-inverse);
+ --calcite-internal-button-text-color: var(--calcite-color-text-1);
+ --calcite-internal-button-background-color: var(--calcite-color-transparent);
+ --calcite-internal-button-border-color: var(--calcite-color-inverse);
&:hover {
- border-color: var(--calcite-color-inverse-hover);
- box-shadow: inset 0 0 0 1px var(--calcite-color-inverse-hover);
+ --calcite-internal-button-border-color: var(--calcite-color-inverse-hover);
+ --calcite-internal-button-shadow-color: var(--calcite-color-inverse-hover);
}
&:focus {
- border-color: var(--calcite-color-inverse);
- box-shadow: inset 0 0 0 2px var(--calcite-color-inverse);
+ --calcite-internal-button-border-color: var(--calcite-color-inverse);
+ --calcite-internal-button-shadow-color: var(--calcite-color-inverse);
}
&:active {
- border-color: var(--calcite-color-inverse-press);
- box-shadow: inset 0 0 0 2px var(--calcite-color-inverse-press);
- }
- calcite-loader {
- @apply text-color-1;
+ --calcite-internal-button-border-color: var(--calcite-color-inverse-press);
+ --calcite-internal-button-shadow-color: var(--calcite-color-inverse-press);
}
}
}
@@ -501,7 +552,7 @@
:host([appearance="transparent"]:not(.enable-editing-button)) {
button,
a {
- @apply bg-transparent;
+ background-color: var(--calcite-color-transparent);
&:hover,
&:focus {
background-color: var(--calcite-color-transparent-hover);
@@ -514,18 +565,18 @@
:host([appearance="transparent"][kind="brand"]) {
button,
a {
- color: theme("colors.brand");
+ --calcite-internal-button-text-color: theme("colors.brand");
&:hover {
- color: theme("colors.brand-hover");
+ --calcite-internal-button-text-color: theme("colors.brand-hover");
}
&:focus {
- color: theme("colors.brand");
+ --calcite-internal-button-text-color: theme("colors.brand");
}
&:active {
- color: theme("colors.brand-press");
+ --calcite-internal-button-text-color: theme("colors.brand-press");
}
calcite-loader {
- color: theme("colors.brand");
+ --calcite-internal-button-loader-color: theme("colors.brand");
}
}
}
@@ -533,18 +584,18 @@
:host([appearance="transparent"][kind="danger"]) {
button,
a {
- color: theme("colors.danger");
+ --calcite-internal-button-text-color: theme("colors.danger");
&:hover {
- color: theme("colors.danger-hover");
+ --calcite-internal-button-text-color: theme("colors.danger-hover");
}
&:focus {
- color: theme("colors.danger");
+ --calcite-internal-button-text-color: theme("colors.danger");
}
&:active {
- color: theme("colors.danger-press");
+ --calcite-internal-button-text-color: theme("colors.danger-press");
}
calcite-loader {
- color: theme("colors.danger");
+ --calcite-internal-button-loader-color: theme("colors.danger");
}
}
}
@@ -553,12 +604,13 @@
button,
a,
calcite-loader {
- @apply text-color-1;
+ --calcite-internal-button-text-color: var(--calcite-color-text-1);
}
}
: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
@@ -567,11 +619,11 @@
border-block-style: solid;
&:not(.content--slotted) {
- --calcite-button-padding-y-internal: 0;
+ --calcite-internal-button-padding-y-internal: 0;
}
&:hover {
- @apply text-color-1;
+ --calcite-internal-button-text-color: var(--calcite-color-text-1);
}
}
}
@@ -596,7 +648,7 @@
button,
a,
calcite-loader {
- @apply text-color-inverse;
+ --calcite-internal-button-text-color: var(--calcite-color-text-inverse);
}
}
@@ -609,67 +661,67 @@
// accommodate for transparent buttons not having borders
:host([scale="s"][appearance="transparent"]) button.content--slotted,
:host([scale="s"][appearance="transparent"]) a.content--slotted {
- --calcite-button-padding-x-internal: theme("padding.2");
+ --calcite-internal-button-padding-x: theme("padding.2");
}
:host([scale="s"]) button,
:host([scale="s"]) a {
- --calcite-button-padding-y-internal: 3px;
+ --calcite-internal-button-padding-y-internal: 3px;
}
:host([scale="m"]) button.content--slotted,
:host([scale="m"]) a.content--slotted {
- --calcite-button-padding-x-internal: 11px;
+ --calcite-internal-button-padding-x: 11px;
@apply text-n1h;
}
:host([scale="m"]) button,
:host([scale="m"]) a {
- --calcite-button-padding-y-internal: 7px;
+ --calcite-internal-button-padding-y-internal: 7px;
}
// accommodate for transparent buttons not having borders
:host([scale="m"][appearance="transparent"]) button.content--slotted,
:host([scale="m"][appearance="transparent"]) a.content--slotted {
- --calcite-button-padding-x-internal: theme("padding.3");
+ --calcite-internal-button-padding-x: theme("padding.3");
}
:host([scale="l"]) button.content--slotted,
:host([scale="l"]) a.content--slotted {
- --calcite-button-padding-x-internal: 15px;
+ --calcite-internal-button-padding-x: 15px;
@apply text-0h;
}
:host([scale="l"]) {
.button-padding {
- --calcite-button-padding-x-internal: theme("padding.4");
- --calcite-button-padding-y-internal: 11px;
+ --calcite-internal-button-padding-x: theme("padding.4");
+ --calcite-internal-button-padding-y-internal: 11px;
}
//shrink the padding if an icon is present to preserve the height
.button-padding--shrunk {
- --calcite-button-padding-y-internal: 9px;
+ --calcite-internal-button-padding-y-internal: 9px;
}
}
// generate fab scales (scenario: 1 icon, ie., should be square)
:host([scale="s"]) button:not(.content--slotted),
:host([scale="s"]) a:not(.content--slotted) {
- --calcite-button-padding-x-internal: theme("padding[0.5]");
- --calcite-button-padding-y-internal: 3px;
+ --calcite-internal-button-padding-x: theme("padding[0.5]");
+ --calcite-internal-button-padding-y-internal: 3px;
@apply text-0h w-6;
min-block-size: theme("height.6");
}
:host([scale="m"]) button:not(.content--slotted),
:host([scale="m"]) a:not(.content--slotted) {
- --calcite-button-padding-x-internal: theme("padding[0.5]");
- --calcite-button-padding-y-internal: 7px;
+ --calcite-internal-button-padding-x: theme("padding[0.5]");
+ --calcite-internal-button-padding-y-internal: 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-button-padding-x-internal: theme("padding[0.5]");
- --calcite-button-padding-y-internal: 9px;
+ --calcite-internal-button-padding-x: theme("padding[0.5]");
+ --calcite-internal-button-padding-y-internal: 9px;
@apply text-0h w-11;
min-block-size: theme("height.11");
}
@@ -686,33 +738,33 @@
// 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-button-padding-y-internal: theme("padding[2.5]");
+ --calcite-internal-button-padding-y-internal: theme("padding[2.5]");
}
// generate fab scales (scenario: 2 icons, ie., should not be square)
:host([scale="s"][icon-start][icon-end]) button:not(.content--slotted),
:host([scale="s"][icon-start][icon-end]) a:not(.content--slotted) {
- --calcite-button-padding-x-internal: 23px;
+ --calcite-internal-button-padding-x: 23px;
@apply text-0h h-6;
}
// accommodate for transparent buttons not having borders
:host([scale="s"][icon-start][icon-end][appearance="transparent"]) button:not(.content--slotted),
:host([scale="s"][icon-start][icon-end][appearance="transparent"]) a:not(.content--slotted) {
- --calcite-button-padding-x-internal: theme("padding.6");
+ --calcite-internal-button-padding-x: theme("padding.6");
}
:host([scale="m"][icon-start][icon-end]) button:not(.content--slotted),
:host([scale="m"][icon-start][icon-end]) a:not(.content--slotted) {
- --calcite-button-padding-x-internal: theme("padding.8");
+ --calcite-internal-button-padding-x: theme("padding.8");
@apply text-0h h-8;
}
// accommodate for transparent buttons not having borders
:host([scale="m"][icon-start][icon-end][appearance="transparent"]) button:not(.content--slotted),
:host([scale="m"][icon-start][icon-end][appearance="transparent"]) a:not(.content--slotted) {
- --calcite-button-padding-x-internal: 33px;
+ --calcite-internal-button-padding-x: 33px;
}
:host([scale="l"][icon-start][icon-end]) button:not(.content--slotted),
:host([scale="l"][icon-start][icon-end]) a:not(.content--slotted) {
- --calcite-button-padding-x-internal: 43px;
+ --calcite-internal-button-padding-x: 43px;
@apply text-0h h-11;
// add space between when only 2 icons
.icon--start + .icon--end {
@@ -722,7 +774,7 @@
// accommodate for transparent buttons not having borders
:host([scale="l"][icon-start][icon-end][appearance="transparent"]) button:not(.content--slotted),
:host([scale="l"][icon-start][icon-end][appearance="transparent"]) a:not(.content--slotted) {
- --calcite-button-padding-x-internal: theme("padding.11");
+ --calcite-internal-button-padding-x: theme("padding.11");
}
@include base-component();
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 c1943a2c195..c97eefcf062 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
@@ -2470,4 +2470,14 @@ describe("calcite-color-picker", () => {
});
});
});
+
+ it("does not throw when initialized with different format value (format='auto')", async () => {
+ async function doTest(): Promise {
+ const page = await newE2EPage();
+ await page.setContent(``);
+ await page.waitForChanges();
+ }
+
+ await expect(doTest()).resolves.toBeUndefined();
+ });
});
diff --git a/packages/calcite-components/src/components/color-picker/color-picker.tsx b/packages/calcite-components/src/components/color-picker/color-picker.tsx
index 3b1b981cea5..ce157eb0d39 100644
--- a/packages/calcite-components/src/components/color-picker/color-picker.tsx
+++ b/packages/calcite-components/src/components/color-picker/color-picker.tsx
@@ -549,7 +549,8 @@ export class ColorPicker extends LitElement implements InteractiveComponent, Loa
if (modeChanged || colorChanged) {
this.internalColorSet(
color,
- this.alphaChannel && !(this.mode.endsWith("a") || this.mode.endsWith("a-css")),
+ (this.alphaChannel && !(this.mode.endsWith("a") || this.mode.endsWith("a-css"))) ||
+ this.internalColorUpdateContext === "internal",
"internal",
);
}
diff --git a/packages/calcite-components/src/components/combobox/combobox.e2e.ts b/packages/calcite-components/src/components/combobox/combobox.e2e.ts
index 364eb1ed1f5..2b38fd91481 100644
--- a/packages/calcite-components/src/components/combobox/combobox.e2e.ts
+++ b/packages/calcite-components/src/components/combobox/combobox.e2e.ts
@@ -1264,7 +1264,7 @@ describe("calcite-combobox", () => {
`,
);
- const eventSpy = await page.spyOnEvent("calciteComboboxChipClose", "window");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChipClose");
const chip = await page.find("calcite-combobox >>> calcite-chip");
@@ -1285,6 +1285,7 @@ describe("calcite-combobox", () => {
`);
const input = await page.find("calcite-combobox >>> input");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
await input.click();
await input.press("K");
@@ -1298,6 +1299,7 @@ describe("calcite-combobox", () => {
expect((await combobox.getProperty("selectedItems")).length).toBe(1);
expect(await item.getProperty("selected")).toBe(true);
+ expect(eventSpy).toHaveReceivedEventTimes(1);
});
it("should replace current value to new custom value in single selection mode", async () => {
@@ -1312,6 +1314,7 @@ describe("calcite-combobox", () => {
await skipAnimations(page);
const combobox = await page.find("calcite-combobox");
const input = await page.find("calcite-combobox >>> input");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
await input.click();
await input.press("K");
@@ -1326,6 +1329,7 @@ describe("calcite-combobox", () => {
expect((await combobox.getProperty("selectedItems")).length).toBe(1);
expect(await customValue.getProperty("selected")).toBe(true);
expect(await item1.getProperty("selected")).toBe(false);
+ expect(eventSpy).toHaveReceivedEventTimes(1);
});
it("should auto-select new custom values in multiple selection mode", async () => {
@@ -1339,6 +1343,7 @@ describe("calcite-combobox", () => {
`);
const combobox = await page.find("calcite-combobox");
const input = await page.find("calcite-combobox >>> input");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
await input.click();
await input.press("K");
@@ -1356,6 +1361,7 @@ describe("calcite-combobox", () => {
expect(await customValue.getProperty("selected")).toBe(true);
expect(await item1.getProperty("selected")).toBe(true);
expect(await item2.getProperty("selected")).toBe(true);
+ expect(eventSpy).toHaveReceivedEventTimes(1);
});
});
@@ -1666,17 +1672,21 @@ describe("calcite-combobox", () => {
});
it("should not throw when typing custom value and pressing ArrowDown", async () => {
- const combobox = await page.find("calcite-combobox");
- combobox.setProperty("allowCustomValues", true);
- await page.waitForChanges();
- const inputEl = await page.find(`#myCombobox >>> input`);
- await inputEl.focus();
- await page.waitForChanges();
- expect(await page.evaluate(() => document.activeElement.id)).toBe("myCombobox");
- await page.keyboard.type("asdf");
- await page.waitForChanges();
- await page.keyboard.press("ArrowDown");
- await page.waitForChanges();
+ async function runTest(): Promise {
+ const combobox = await page.find("calcite-combobox");
+ combobox.setProperty("allowCustomValues", true);
+ await page.waitForChanges();
+ const inputEl = await page.find(`#myCombobox >>> input`);
+ await inputEl.focus();
+ await page.waitForChanges();
+ expect(await page.evaluate(() => document.activeElement.id)).toBe("myCombobox");
+ await page.keyboard.type("asdf");
+ await page.waitForChanges();
+ await page.keyboard.press("ArrowDown");
+ await page.waitForChanges();
+ }
+
+ await expect(runTest()).resolves.toBeUndefined();
});
it(`ArrowDown opens the item group for combobox in focus and jumps to the first item`, async () => {
@@ -1766,7 +1776,7 @@ describe("calcite-combobox", () => {
});
it("should cycle through items on ArrowUp/ArrowDown and toggle selection on/off on Enter", async () => {
- const eventSpy = await page.spyOnEvent("calciteComboboxChange", "window");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
const item1 = await page.find("calcite-combobox-item#one");
const item2 = await page.find("calcite-combobox-item#two");
const item3 = await page.find("calcite-combobox-item#three");
@@ -1988,6 +1998,27 @@ describe("calcite-combobox", () => {
expect(eventSpy).toHaveReceivedEventTimes(1);
expect((await element.getProperty("selectedItems")).length).toBe(2);
});
+
+ it("should not emit calciteComboboxChange event when value attribute is updated", async () => {
+ const page = await newE2EPage();
+ await page.setContent(
+ html`
+
+
+
+ `,
+ );
+ await page.waitForChanges();
+
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
+ const combobox = await page.find("calcite-combobox");
+ expect(await combobox.getProperty("value")).toBe("one");
+
+ combobox.setProperty("value", "two");
+ await page.waitForChanges();
+ expect(eventSpy).toHaveReceivedEventTimes(0);
+ expect(await combobox.getProperty("value")).toBe("two");
+ });
});
describe("calciteComboboxItemChange event correctly updates active item index", () => {
@@ -2063,6 +2094,7 @@ describe("calcite-combobox", () => {
`);
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
let chip = await page.find("calcite-combobox >>> calcite-chip");
expect(chip).toBeNull();
@@ -2071,6 +2103,7 @@ describe("calcite-combobox", () => {
await element.press("K");
await element.press("Enter");
+ expect(eventSpy).toHaveReceivedEventTimes(1);
chip = await page.find("calcite-combobox >>> calcite-chip");
expect(chip).toBeDefined();
@@ -2082,6 +2115,7 @@ describe("calcite-combobox", () => {
await element.press("Enter");
const chips = await page.findAll("calcite-combobox >>> calcite-chip");
expect(chips.length).toBe(1);
+ expect(eventSpy).toHaveReceivedEventTimes(2);
});
it("should fire calciteComboboxChange when entering new unknown tag", async () => {
@@ -2099,6 +2133,7 @@ describe("calcite-combobox", () => {
await input.press("K");
await input.press("Enter");
+ await page.waitForChanges();
expect(eventSpy).toHaveReceivedEventTimes(1);
});
@@ -2113,6 +2148,7 @@ describe("calcite-combobox", () => {
`);
const chip = await page.find("calcite-combobox >>> calcite-chip");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
expect(chip).toBeNull();
const input = await page.find("calcite-combobox >>> input");
@@ -2130,6 +2166,7 @@ describe("calcite-combobox", () => {
let chips = await page.findAll("calcite-combobox >>> calcite-chip");
expect(chips.length).toBe(1);
+ expect(eventSpy).toHaveReceivedEventTimes(1);
await input.press("j");
await page.waitForChanges();
@@ -2142,6 +2179,7 @@ describe("calcite-combobox", () => {
chips = await page.findAll("calcite-combobox >>> calcite-chip");
expect(chips.length).toBe(2);
+ expect(eventSpy).toHaveReceivedEventTimes(2);
});
it("should select known tag when input", async () => {
@@ -2154,6 +2192,7 @@ describe("calcite-combobox", () => {
`);
let chip = await page.find("calcite-combobox >>> calcite-chip");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
expect(chip).toBeNull();
const input = await page.find("calcite-combobox >>> input");
@@ -2169,6 +2208,7 @@ describe("calcite-combobox", () => {
expect(await chip.getProperty("value")).toBe("one");
const item1 = await page.find("calcite-combobox-item#one");
expect(await item1.getProperty("selected")).toBe(true);
+ expect(eventSpy).toHaveReceivedEventTimes(1);
});
});
@@ -2448,8 +2488,9 @@ describe("calcite-combobox", () => {
const page = await newE2EPage();
await page.setContent(html);
await skipAnimations(page);
+ const openEvent = page.waitForEvent("calciteComboboxOpen");
await page.click("calcite-combobox");
- await page.waitForChanges();
+ await openEvent;
const activeItem = await page.find("calcite-combobox-item[active]");
expect(await activeItem.getProperty("value")).toBe(expectedActiveItemValue);
@@ -2557,12 +2598,12 @@ describe("calcite-combobox", () => {
async function assertClickOutside(selectionMode = "multiple", allowCustomValues = false): Promise {
const combobox = await page.find("calcite-combobox");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
combobox.setProperty("selectionMode", selectionMode);
combobox.setProperty("allowCustomValues", allowCustomValues);
+ await page.waitForChanges();
const inputEl = await page.find(`#myCombobox >>> input`);
-
await inputEl.focus();
- await page.waitForChanges();
expect(await page.evaluate(() => document.activeElement.id)).toBe("myCombobox");
const comboboxRect = await page.evaluate(() => {
@@ -2580,6 +2621,7 @@ describe("calcite-combobox", () => {
expect(await page.evaluate(() => document.activeElement.id)).not.toBe("myCombobox");
expect(await inputEl.getProperty("value")).toBe("");
expect(await combobox.getProperty("value")).toBe(allowCustomValues ? "three" : "");
+ expect(eventSpy).toHaveReceivedEventTimes(allowCustomValues ? 1 : 0);
}
selectionModes.forEach((mode) => {
@@ -2608,6 +2650,7 @@ describe("calcite-combobox", () => {
async function clearInputValueOnBlur(selectionMode = "multiple", allowCustomValues = false): Promise {
const combobox = await page.find("calcite-combobox");
+ const eventSpy = await page.spyOnEvent("calciteComboboxChange");
combobox.setProperty("selectionMode", selectionMode);
combobox.setProperty("allowCustomValues", allowCustomValues);
const inputEl = await page.find(`#myCombobox >>> input`);
@@ -2622,6 +2665,7 @@ describe("calcite-combobox", () => {
await page.waitForChanges();
expect(await inputEl.getProperty("value")).toBe("");
expect(await combobox.getProperty("value")).toBe(allowCustomValues ? "three" : "");
+ expect(eventSpy).toHaveReceivedEventTimes(allowCustomValues ? 1 : 0);
}
selectionModes.forEach((mode) => {
@@ -2770,4 +2814,25 @@ describe("calcite-combobox", () => {
expect(await combobox.getProperty("value")).toBe("three");
});
+
+ it("should not emit calciteComboboxItemChange event when selected attribute is toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(
+ html`
+
+
+
+ `,
+ );
+ await page.waitForChanges();
+
+ const eventSpy = await page.spyOnEvent("calciteComboboxItemChange");
+ const two = await page.find("#two");
+ two.setProperty("selected", "true");
+ await page.waitForChanges();
+ expect(eventSpy).toHaveReceivedEventTimes(0);
+
+ const combobox = await page.find("calcite-combobox");
+ expect((await combobox.getProperty("selectedItems")).length).toBe(1);
+ });
});
diff --git a/packages/calcite-components/src/components/combobox/combobox.tsx b/packages/calcite-components/src/components/combobox/combobox.tsx
index 5f294220572..3c32e3a3004 100644
--- a/packages/calcite-components/src/components/combobox/combobox.tsx
+++ b/packages/calcite-components/src/components/combobox/combobox.tsx
@@ -108,10 +108,6 @@ export class Combobox
// #region Private Properties
- private internalComboboxChangeEvent = (): void => {
- this.calciteComboboxChange.emit();
- };
-
private allSelectedIndicatorChipEl: Chip["el"];
private chipContainerEl: HTMLDivElement;
@@ -120,7 +116,9 @@ export class Combobox
defaultValue: Combobox["value"];
- private emitComboboxChange = debounce(this.internalComboboxChangeEvent, 0);
+ private emitComboboxChange(): void {
+ this.calciteComboboxChange.emit();
+ }
private get effectiveFilterProps(): string[] {
if (!this.filterProps) {
@@ -217,6 +215,8 @@ export class Combobox
private groupData: GroupData[];
+ private groupItems: HTMLCalciteComboboxItemGroupElement["el"][] = [];
+
private guid = guid();
private ignoreSelectedEventsFlag = false;
@@ -225,6 +225,8 @@ export class Combobox
private internalValueChangeFlag = false;
+ private items: HTMLCalciteComboboxItemElement["el"][] = [];
+
labelEl: Label["el"];
private listContainerEl: HTMLDivElement;
@@ -279,12 +281,6 @@ export class Combobox
@state() compactSelectionDisplay = false;
- @state() groupItems: HTMLCalciteComboboxItemGroupElement["el"][] = [];
-
- @state() items: HTMLCalciteComboboxItemElement["el"][] = [];
-
- @state() needsIcon: boolean;
-
@state() selectedHiddenChipsCount = 0;
@state() selectedVisibleChipsCount = 0;
@@ -565,7 +561,6 @@ export class Combobox
async load(): Promise {
setUpLoadableComponent(this);
- this.filterItems(this.filterText, false, false);
}
override willUpdate(changes: PropertyValues): void {
@@ -612,16 +607,15 @@ export class Combobox
}
updateHostInteraction(this);
-
- if (!this.hasUpdated) {
- this.refreshSelectionDisplay();
- }
+ this.refreshSelectionDisplay();
}
loaded(): void {
afterConnectDefaultValueSet(this, this.getValue());
connectFloatingUI(this);
setComponentLoaded(this);
+ this.updateItems();
+ this.filterItems(this.filterText, false, false);
}
override disconnectedCallback(): void {
@@ -659,14 +653,10 @@ export class Combobox
private valueHandler(value: string | string[]): void {
if (!this.internalValueChangeFlag) {
- const items = this.getItems();
- if (Array.isArray(value)) {
- items.forEach((item) => (item.selected = value.includes(item.value)));
- } else if (value) {
- items.forEach((item) => (item.selected = value === item.value));
- } else {
- items.forEach((item) => (item.selected = false));
- }
+ this.getItems().forEach((item) => {
+ item.selected = Array.isArray(value) ? value.includes(item.value) : value === item.value;
+ });
+
this.updateItems();
}
}
@@ -719,7 +709,9 @@ export class Combobox
event: CustomEvent,
): void {
event.stopPropagation();
- this.updateItems();
+ if (this.hasUpdated) {
+ this.updateItems();
+ }
}
private clearValue(): void {
@@ -932,6 +924,7 @@ export class Combobox
listContainerEl.style.inlineSize = `${referenceEl.clientWidth}px`;
await this.reposition(true);
}
+
private calciteChipCloseHandler(comboboxItem: HTMLCalciteComboboxItemElement["el"]): void {
this.open = false;
@@ -1230,15 +1223,20 @@ export class Combobox
return this.filterText === "" ? this.items : this.items.filter((item) => !isHidden(item));
}
- private updateItems = debounce((): void => {
+ private updateItems(): void {
this.items = this.getItems();
this.groupItems = this.getGroupItems();
+
this.data = this.getData();
this.groupData = this.getGroupData();
+
+ this.updateItemProps();
+
this.selectedItems = this.getSelectedItems();
this.filteredItems = this.getFilteredItems();
- this.needsIcon = this.getNeedsIcon();
+ }
+ private updateItemProps(): void {
this.items.forEach((item) => {
item.selectionMode = this.selectionMode;
item.scale = this.scale;
@@ -1261,7 +1259,7 @@ export class Combobox
nextGroupItem.afterEmptyGroup = groupItem.children.length === 0;
}
});
- }, DEBOUNCE.nextTick);
+ }
private getData(): ItemData[] {
return this.items.map((item) => ({
@@ -1282,10 +1280,6 @@ export class Combobox
}));
}
- private getNeedsIcon(): boolean {
- return isSingleLike(this.selectionMode) && this.items.some((item) => item.icon);
- }
-
private resetText(): void {
if (this.textInput.value) {
this.textInput.value.value = "";
@@ -1309,9 +1303,6 @@ export class Combobox
if (existingItem) {
this.toggleSelection(existingItem, true);
} else {
- if (!this.isMulti()) {
- this.toggleSelection(this.selectedItems[this.selectedItems.length - 1], false);
- }
const item = document.createElement(
// TODO: [MIGRATION] If this is dynamically creating a web component, please read the docs: https://qawebgis.esri.com/arcgis-components/?path=/docs/lumina-jsx--docs#rendering-jsx-outside-the-component
"calcite-combobox-item",
@@ -1320,14 +1311,11 @@ export class Combobox
item.heading = value;
item.selected = true;
this.el.prepend(item);
- this.resetText();
+ this.toggleSelection(item, true);
+ this.open = true;
if (focus) {
this.setFocus();
}
- this.updateItems();
- this.filterItems("");
- this.open = true;
- this.emitComboboxChange();
}
}
diff --git a/packages/calcite-components/src/components/panel/panel.scss b/packages/calcite-components/src/components/panel/panel.scss
index 3cb4518df30..2ab0af241e3 100644
--- a/packages/calcite-components/src/components/panel/panel.scss
+++ b/packages/calcite-components/src/components/panel/panel.scss
@@ -7,25 +7,27 @@
* @prop --calcite-panel-heading-text-color: Specifies the text color of the component's `heading`.
* @prop --calcite-panel-description-text-color: Specifies the text color of the component's `description`.
* @prop --calcite-panel-border-color: Specifies the component's border color.
-
* @prop --calcite-panel-background-color: Specifies the component's background color.
* @prop --calcite-panel-header-background-color: Specifies the background color of the component's header.
* @prop --calcite-panel-footer-background-color: Specifies the background color of the component's footer.
-
* @prop --calcite-panel-space: Specifies the padding of the component's `"unnamed (default)"` slot.
* @prop --calcite-panel-header-content-space: Specifies the padding of the `"header-content"` slot.
* @prop --calcite-panel-footer-space: Specifies the padding of the component's footer.
-
* @prop --calcite-action-background-color: Specifies the background color of the component's `closable`, `collapsible`, and `back` `calcite-action`s. Applies to any slotted `calcite-action`s.
* @prop --calcite-action-background-color-hover: Specifies the background color of the component's `closable`, `collapsible`, and `back` `calcite-action`s when hovered. Applies to any slotted `calcite-action`s.
* @prop --calcite-action-background-color-pressed: Specifies the background color of the component's `closable`, `collapsible`, and `back` `calcite-action`s when pressed. Applies to any slotted `calcite-action`s.
* @prop --calcite-action-text-color-hover: Specifies the text and icon color of the component's `closable`, `collapsible`, and `back` `calcite-action`s when hovered. Applies to any slotted `calcite-action`s.
* @prop --calcite-action-text-color-pressed: Specifies the text and icon color of the component's `closable`, `collapsible`, and `back` `calcite-action`s when pressed. Applies to any slotted `calcite-action`s.
* @prop --calcite-popover-border-color: Specifies the border color of the component's internally rendered `calcite-popover`, which is rendered within a `calcite-action` menu when slotted `calcite-action`s are present in the `header-actions-end` slot. Applies to any slotted `calcite-popover`s.
-
* @prop --calcite-panel-content-space: [Deprecated] Use `--calcite-panel-space` instead. Specifies the padding of the component's content.
* @prop --calcite-panel-footer-padding: [Deprecated] Use `--calcite-panel-footer-space` instead. Specifies the padding of the component's footer.
* @prop --calcite-panel-header-border-block-end: [Deprecated] Use `--calcite-panel-border-color` instead. Specifies the component header's block end border.
+ * @prop --calcite-panel-header-action-background-color-hover: Specifies the background color of the component's `calcite-action` items in the panel header when hovered.
+ * @prop --calcite-panel-header-action-background-color-press: Specifies the background color of the component's `calcite-action` items in the panel header when pressed.
+ * @prop --calcite-panel-header-action-background-color: Specifies the background color of the component's `calcite-action` items in the panel header.
+ * @prop --calcite-panel-header-action-indicator-color: Specifies the color of the component's `calcite-action` items' indicator in the panel header.
+ * @prop --calcite-panel-header-action-text-color-press: Specifies the text color of the component's `calcite-action` items in the panel header when pressed.
+ * @prop --calcite-panel-header-action-text-color: Specifies the text color of the component's `calcite-action` items in the panel header.
*/
:host {
@@ -147,6 +149,15 @@
margin-inline-end: auto;
justify-content: center;
+ .header-actions {
+ --calcite-action-background-color-hover: var(--calcite-panel-header-action-background-color-hover);
+ --calcite-action-background-color-press: var(--calcite-panel-header-action-background-color-press);
+ --calcite-action-background-color: var(--calcite-panel-header-action-background-color);
+ --calcite-action-indicator-color: var(--calcite-panel-header-action-indicator-color);
+ --calcite-action-text-color-press: var(--calcite-panel-header-action-text-color-press);
+ --calcite-action-text-color: var(--calcite-panel-header-action-text-color);
+ }
+
.heading,
.description {
@apply block
diff --git a/packages/calcite-components/src/components/table/table.tsx b/packages/calcite-components/src/components/table/table.tsx
index bf6b8fb1c02..e44a4571072 100644
--- a/packages/calcite-components/src/components/table/table.tsx
+++ b/packages/calcite-components/src/components/table/table.tsx
@@ -70,9 +70,6 @@ export class Table extends LitElement implements LoadableComponent {
@state() pageStartRow = 1;
- /* Workaround for Safari https://bugs.webkit.org/show_bug.cgi?id=258430 https://bugs.webkit.org/show_bug.cgi?id=239478 */
-
- // ⚠️ browser-sniffing is not a best practice and should be avoided ⚠️
@state() readCellContentsToAT: boolean;
@state() selectedCount = 0;
@@ -179,7 +176,11 @@ export class Table extends LitElement implements LoadableComponent {
async load(): Promise {
setUpLoadableComponent(this);
+
+ /* Workaround for Safari https://bugs.webkit.org/show_bug.cgi?id=258430 https://bugs.webkit.org/show_bug.cgi?id=239478 */
+ // ⚠️ browser-sniffing is not a best practice and should be avoided ⚠️
this.readCellContentsToAT = /safari/i.test(getUserAgentString());
+
this.listenOn(this.el.shadowRoot, "slotchange", this.handleSlotChange);
}
diff --git a/packages/calcite-components/src/components/tree-item/tree-item.scss b/packages/calcite-components/src/components/tree-item/tree-item.scss
index 3880270c15a..a33efbd7cee 100644
--- a/packages/calcite-components/src/components/tree-item/tree-item.scss
+++ b/packages/calcite-components/src/components/tree-item/tree-item.scss
@@ -59,7 +59,7 @@
z-default;
// ensure lines don't overlap focus outline
block-size: 100%;
- left: var(--calcite-internal-tree-item-line-left-position);
+ inset-inline-start: var(--calcite-internal-tree-item-line-left-position);
content: "";
background-color: var(--calcite-color-border-2);
}
diff --git a/packages/calcite-components/src/components/tree/tree.stories.ts b/packages/calcite-components/src/components/tree/tree.stories.ts
index 149bd33b16f..b0e9916dda0 100644
--- a/packages/calcite-components/src/components/tree/tree.stories.ts
+++ b/packages/calcite-components/src/components/tree/tree.stories.ts
@@ -141,13 +141,17 @@ const iconStartLargeActionsEnd = (scale: string) => html`
`;
export const singleSelectionMode = (): string => html` ${treeItems()} `;
-
singleSelectionMode.decorators = [allScaleTreeBuilder];
+singleSelectionMode.args = { selectionMode: "single" };
export const selectionModeNone = (): string => html`${treeItems()}`;
selectionModeNone.decorators = [allScaleTreeBuilder];
selectionModeNone.args = { selectionMode: "none" };
+export const linesRTL = (): string => html`${treeItems()}
`;
+linesRTL.decorators = [allScaleTreeBuilder];
+linesRTL.args = { lines: true, selectionMode: "single" };
+
export const multipleSelectionModeWithLines_TestOnly = (): string => html` ${treeItems()} `;
multipleSelectionModeWithLines_TestOnly.decorators = [allScaleTreeBuilder];
@@ -164,8 +168,8 @@ singlePersistSelectionModeWithLines_TestOnly.decorators = [allScaleTreeBuilder];
singlePersistSelectionModeWithLines_TestOnly.args = { lines: true, selectionMode: "single-persist" };
export const iconStartAndActionsEnd = (scale: string): string => html` ${iconStartLargeActionsEnd(scale)} `;
-
iconStartAndActionsEnd.decorators = [allScaleTreeBuilder];
+iconStartAndActionsEnd.args = { selectionMode: "single" };
export const treeItemTextContentWraps_TestOnly = (): string => html`
@@ -207,8 +211,9 @@ export const treeItemContentIsNotClipped_TestOnly = (): string => html`
`;
-export const darkModeRTL_TestOnly = (): string => html` ${treeItems()} `;
+export const darkModeRTL_TestOnly = (): string => html`${treeItems()}
`;
darkModeRTL_TestOnly.parameters = { themes: modesDarkDefault };
+darkModeRTL_TestOnly.args = { selectionMode: "single" };
darkModeRTL_TestOnly.decorators = [allScaleTreeBuilder];
export const OverflowingSubtree = (): string =>
diff --git a/packages/calcite-components/src/utils/loadable.ts b/packages/calcite-components/src/utils/loadable.ts
index 3f072448caf..c6f7f56e8e9 100644
--- a/packages/calcite-components/src/utils/loadable.ts
+++ b/packages/calcite-components/src/utils/loadable.ts
@@ -56,6 +56,7 @@ export interface LoadableComponent {}
*
* @param _component
*/
+// eslint-disable-next-line @typescript-eslint/no-unused-vars -- this method is deprecated, and we allow it to be empty for incremental migration
export function setUpLoadableComponent(_component: LoadableComponent): void {
// intentionally empty
}
@@ -74,6 +75,7 @@ export function setUpLoadableComponent(_component: LoadableComponent): void {
*
* @param _component
*/
+// eslint-disable-next-line @typescript-eslint/no-unused-vars -- this method is deprecated, and we allow it to be empty for incremental migration
export function setComponentLoaded(_component: LoadableComponent): void {
// intentionally empty
}
diff --git a/packages/calcite-ui-icons/CHANGELOG.md b/packages/calcite-ui-icons/CHANGELOG.md
index 32ae894d226..f45e0386ce2 100644
--- a/packages/calcite-ui-icons/CHANGELOG.md
+++ b/packages/calcite-ui-icons/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [4.0.0-next.10](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-ui-icons@4.0.0-next.9...@esri/calcite-ui-icons@4.0.0-next.10) (2025-01-22)
+
+**Note:** Version bump only for package @esri/calcite-ui-icons
+
## [4.0.0-next.9](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-ui-icons@4.0.0-next.8...@esri/calcite-ui-icons@4.0.0-next.9) (2025-01-17)
### Features
diff --git a/packages/calcite-ui-icons/package.json b/packages/calcite-ui-icons/package.json
index 60c509bb11d..6242da74d83 100644
--- a/packages/calcite-ui-icons/package.json
+++ b/packages/calcite-ui-icons/package.json
@@ -1,6 +1,6 @@
{
"name": "@esri/calcite-ui-icons",
- "version": "4.0.0-next.9",
+ "version": "4.0.0-next.10",
"private": false,
"description": "A collection of UI SVG icons created by Esri for applications.",
"keywords": [