diff --git a/.renovaterc.json b/.renovaterc.json index 65dae772e20..55b6593129e 100644 --- a/.renovaterc.json +++ b/.renovaterc.json @@ -27,7 +27,7 @@ { "groupName": "ArcGIS", "matchPackageNames": ["@arcgis/**"], - "followTag": "next" + "rangeStrategy": "bump" }, { "groupName": "ESLint", diff --git a/LICENSE.md b/LICENSE.md index 1235786306c..37d072da0e3 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # Licensing -COPYRIGHT © 2024 Esri +COPYRIGHT © 2025 Esri All rights reserved under the copyright laws of the United States and applicable international laws, treaties, and conventions. diff --git a/package-lock.json b/package-lock.json index a5978c45dff..08f671335a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "patch-package": "8.0.0" }, "devDependencies": { - "@arcgis/lumina-compiler": "4.32.0-next.68", + "@arcgis/lumina-compiler": "^4.32.0-next.72", "@cspell/eslint-plugin": "8.17.1", "@eslint/compat": "1.2.4", "@eslint/eslintrc": "3.2.0", @@ -58,7 +58,7 @@ "@typescript-eslint/rule-tester": "8.19.0", "@typescript-eslint/utils": "8.19.0", "@vitest/coverage-v8": "2.1.8", - "@vitest/eslint-plugin": "1.1.23", + "@vitest/eslint-plugin": "1.1.24", "@whitespace/storybook-addon-html": "6.1.1", "autoprefixer": "10.4.20", "axe-core": "4.10.2", @@ -216,21 +216,21 @@ } }, "node_modules/@arcgis/api-extractor": { - "version": "4.32.0-next.68", - "resolved": "https://registry.npmjs.org/@arcgis/api-extractor/-/api-extractor-4.32.0-next.68.tgz", - "integrity": "sha512-ZojHF66EIF5fCwcJmmTSWTsRqUbHoatD/xT9PfyVMAlZGXiY/v+amAeILd/emmw6dkWkYFWxs4G9NABfSkGElQ==", + "version": "4.32.0-next.75", + "resolved": "https://registry.npmjs.org/@arcgis/api-extractor/-/api-extractor-4.32.0-next.75.tgz", + "integrity": "sha512-ia8GG6LEfBPEMPn0fDIKK6sZrE7y4o3mEpkA2UFzR++CO6OGJAltrs+ikI13ZAzZ8f6EATjj3tczq5ORO1+32g==", "dev": true, "dependencies": { - "@arcgis/components-build-utils": "4.32.0-next.68", - "@arcgis/components-utils": "4.32.0-next.68", + "@arcgis/components-build-utils": "4.32.0-next.75", + "@arcgis/components-utils": "4.32.0-next.75", "tslib": "^2.7.0", "typescript": "~5.6.3" } }, "node_modules/@arcgis/components-build-utils": { - "version": "4.32.0-next.68", - "resolved": "https://registry.npmjs.org/@arcgis/components-build-utils/-/components-build-utils-4.32.0-next.68.tgz", - "integrity": "sha512-e0q1lMF7BmaaTtNJ74ro5swPp0jbCDRIIP/+cAymxhjGoxLUjL7EPKyw+qyzo/phD4cf3QxP+FYgeou1q4T22g==", + "version": "4.32.0-next.75", + "resolved": "https://registry.npmjs.org/@arcgis/components-build-utils/-/components-build-utils-4.32.0-next.75.tgz", + "integrity": "sha512-kKgUsahHVvlIPfapfp0LitnM2PXTm6EefXVo0CaiVEL/wJ73trdW6LDsWcY0QNyKDgmWpFJSqabHJPJ9HAhc+A==", "dev": true, "dependencies": { "@commander-js/extra-typings": "^11.1.0", @@ -245,29 +245,29 @@ } }, "node_modules/@arcgis/components-controllers": { - "version": "4.32.0-next.68", - "resolved": "https://registry.npmjs.org/@arcgis/components-controllers/-/components-controllers-4.32.0-next.68.tgz", - "integrity": "sha512-TKHjH/dmlJPQgwcKJ8wLmCdTPhniuAhB3y1w3SIPxkYr7w6FRjMoy200KO9KpYqBrSCojkjwJ9z6trigRobYmQ==", + "version": "4.32.0-next.75", + "resolved": "https://registry.npmjs.org/@arcgis/components-controllers/-/components-controllers-4.32.0-next.75.tgz", + "integrity": "sha512-k+W7vgAGDqEayA4PvcCCqhaXQ+pwZHogVv4g6vRcWcmug8Q44Nl4O1cGfzG0piHphauy0zn9rwBv3zzpcV0Cmg==", "dependencies": { - "@arcgis/components-utils": "4.32.0-next.68", + "@arcgis/components-utils": "4.32.0-next.75", "tslib": "^2.7.0" } }, "node_modules/@arcgis/components-utils": { - "version": "4.32.0-next.68", - "resolved": "https://registry.npmjs.org/@arcgis/components-utils/-/components-utils-4.32.0-next.68.tgz", - "integrity": "sha512-U6IWRqvFKMCqBkXv2FMthYTM9Qk+Gw89BXQ5gVKdYnW3Mb8+lJTxu6lSRQT7dtJp3Jgwb8Yo4l/P4H/ssRM37Q==", + "version": "4.32.0-next.75", + "resolved": "https://registry.npmjs.org/@arcgis/components-utils/-/components-utils-4.32.0-next.75.tgz", + "integrity": "sha512-aOWBQcMxernyg6I3124Aa77w6KJocXINNX6WSC/02ISWDZ9BSlPEPODYbgdTTPmSM6Uux/4z4oNitl7PgJQGKA==", "dependencies": { "tslib": "^2.7.0" } }, "node_modules/@arcgis/lumina": { - "version": "4.32.0-next.68", - "resolved": "https://registry.npmjs.org/@arcgis/lumina/-/lumina-4.32.0-next.68.tgz", - "integrity": "sha512-Qf4N7J1g9+z5NftUOWzcasmlBm50GPLYCg0e+qmglxG/TtuFwWfPftBW3b1CpOlbTm/sKNHRAjvPpsz1now7SQ==", + "version": "4.32.0-next.75", + "resolved": "https://registry.npmjs.org/@arcgis/lumina/-/lumina-4.32.0-next.75.tgz", + "integrity": "sha512-Xt/skGurXrhcjfocZHnGhIxLpDapNVdSU3J/w+IGAerdcMxIAEYbyhtOX1Yu5TXVV/EgfJ2+h6lWNqpezDGJVg==", "dependencies": { - "@arcgis/components-controllers": "4.32.0-next.68", - "@arcgis/components-utils": "4.32.0-next.68", + "@arcgis/components-controllers": "4.32.0-next.75", + "@arcgis/components-utils": "4.32.0-next.75", "@lit-labs/ssr": "^3.2.2", "@lit-labs/ssr-client": "^1.1.7", "@lit/context": "^1.1.3", @@ -277,14 +277,14 @@ } }, "node_modules/@arcgis/lumina-compiler": { - "version": "4.32.0-next.68", - "resolved": "https://registry.npmjs.org/@arcgis/lumina-compiler/-/lumina-compiler-4.32.0-next.68.tgz", - "integrity": "sha512-rKU/2oUELs14mv+AYGrAIiwQV/ScBAvDek+ffomymLOipCE/za8m9O4bohLW99+cqkdmRP/iA3Pp3sXUYmn43w==", + "version": "4.32.0-next.75", + "resolved": "https://registry.npmjs.org/@arcgis/lumina-compiler/-/lumina-compiler-4.32.0-next.75.tgz", + "integrity": "sha512-GB+GrRrUNvc3lX/3u0ZRDHmmXM6RSpBg/wczBO4EttJdVVg7nkPnPXztYOtTo23UNk3CkN63gRv209loBbis0Q==", "dev": true, "dependencies": { - "@arcgis/api-extractor": "4.32.0-next.68", - "@arcgis/components-build-utils": "4.32.0-next.68", - "@arcgis/components-utils": "4.32.0-next.68", + "@arcgis/api-extractor": "4.32.0-next.75", + "@arcgis/components-build-utils": "4.32.0-next.75", + "@arcgis/components-utils": "4.32.0-next.75", "chalk": "^5.3.0", "esbuild": "^0.24.0", "js-beautify": "^1.15.1", @@ -300,7 +300,7 @@ "vitest-fail-on-console": "^0.7.1" }, "peerDependencies": { - "@arcgis/lumina": "~4.32.0-next.68" + "@arcgis/lumina": "~4.32.0-next.75" } }, "node_modules/@babel/code-frame": { @@ -8235,9 +8235,9 @@ } }, "node_modules/@vitest/eslint-plugin": { - "version": "1.1.23", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.23.tgz", - "integrity": "sha512-tH8nPAKYdH8jXo/ZJ7SpYTjW9Djoc6t1/EIJicI/ouDwYJQh/U6vhOAOU2nzQgjjfjU26ukvB6iu8MEI9oJmPg==", + "version": "1.1.24", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.24.tgz", + "integrity": "sha512-7IaENe4NNy33g0iuuy5bHY69JYYRjpv4lMx6H5Wp30W7ez2baLHwxsXF5TM4wa8JDYZt8ut99Ytoj7GiDO01hw==", "dev": true, "peerDependencies": { "@typescript-eslint/utils": ">= 8.0", @@ -34970,13 +34970,13 @@ }, "packages/calcite-components": { "name": "@esri/calcite-components", - "version": "3.0.0-next.87", + "version": "3.0.0-next.92", "license": "SEE LICENSE.md", "dependencies": { - "@arcgis/components-controllers": "4.32.0-next.68", - "@arcgis/components-utils": "4.32.0-next.68", - "@arcgis/lumina": "4.32.0-next.68", - "@esri/calcite-ui-icons": "4.0.0-next.5", + "@arcgis/components-controllers": "^4.32.0-next.72", + "@arcgis/components-utils": "^4.32.0-next.72", + "@arcgis/lumina": "^4.32.0-next.72", + "@esri/calcite-ui-icons": "4.0.0-next.7", "@floating-ui/dom": "^1.6.12", "@floating-ui/utils": "^0.2.8", "@types/color": "^4.2.0", @@ -34992,17 +34992,17 @@ "type-fest": "^4.30.1" }, "devDependencies": { - "@esri/calcite-design-tokens": "3.0.0-next.4", - "@esri/eslint-plugin-calcite-components": "2.0.0-next.3", + "@esri/calcite-design-tokens": "3.0.0-next.5", + "@esri/eslint-plugin-calcite-components": "2.0.0-next.4", "vitest": "2.1.8" } }, "packages/calcite-components-react": { "name": "@esri/calcite-components-react", - "version": "3.0.0-next.87", + "version": "3.0.0-next.92", "license": "SEE LICENSE.md", "dependencies": { - "@esri/calcite-components": "3.0.0-next.87", + "@esri/calcite-components": "3.0.0-next.92", "@lit/react": "1.0.6" }, "peerDependencies": { @@ -35012,7 +35012,7 @@ }, "packages/calcite-design-tokens": { "name": "@esri/calcite-design-tokens", - "version": "3.0.0-next.4", + "version": "3.0.0-next.5", "license": "SEE LICENSE.md", "devDependencies": { "ts-jest-resolver": "2.0.1", @@ -35021,7 +35021,7 @@ }, "packages/calcite-ui-icons": { "name": "@esri/calcite-ui-icons", - "version": "4.0.0-next.5", + "version": "4.0.0-next.7", "license": "SEE LICENSE.md", "bin": { "spriter": "bin/spriter.js" @@ -35073,7 +35073,7 @@ }, "packages/eslint-plugin-calcite-components": { "name": "@esri/eslint-plugin-calcite-components", - "version": "2.0.0-next.3", + "version": "2.0.0-next.4", "license": "SEE LICENSE.md", "devDependencies": { "ts-node": "10.9.2" diff --git a/package.json b/package.json index b7f80523b88..3f5adba5b9b 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "util:sync-linked-package-versions": "tsx support/syncLinkedPackageVersions.ts" }, "devDependencies": { - "@arcgis/lumina-compiler": "4.32.0-next.68", + "@arcgis/lumina-compiler": "^4.32.0-next.72", "@cspell/eslint-plugin": "8.17.1", "@eslint/compat": "1.2.4", "@eslint/eslintrc": "3.2.0", @@ -76,7 +76,7 @@ "@typescript-eslint/rule-tester": "8.19.0", "@typescript-eslint/utils": "8.19.0", "@vitest/coverage-v8": "2.1.8", - "@vitest/eslint-plugin": "1.1.23", + "@vitest/eslint-plugin": "1.1.24", "@whitespace/storybook-addon-html": "6.1.1", "autoprefixer": "10.4.20", "axe-core": "4.10.2", diff --git a/packages/calcite-components-react/CHANGELOG.md b/packages/calcite-components-react/CHANGELOG.md index 8a4f58b4fa1..f7cb509d5c1 100644 --- a/packages/calcite-components-react/CHANGELOG.md +++ b/packages/calcite-components-react/CHANGELOG.md @@ -3,6 +3,26 @@ 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.92](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@3.0.0-next.91...@esri/calcite-components-react@3.0.0-next.92) (2025-01-08) + +**Note:** Version bump only for package @esri/calcite-components-react + +## [3.0.0-next.91](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@3.0.0-next.90...@esri/calcite-components-react@3.0.0-next.91) (2025-01-07) + +**Note:** Version bump only for package @esri/calcite-components-react + +## [3.0.0-next.90](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@3.0.0-next.89...@esri/calcite-components-react@3.0.0-next.90) (2025-01-06) + +**Note:** Version bump only for package @esri/calcite-components-react + +## [3.0.0-next.89](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@3.0.0-next.88...@esri/calcite-components-react@3.0.0-next.89) (2025-01-04) + +**Note:** Version bump only for package @esri/calcite-components-react + +## [3.0.0-next.88](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@3.0.0-next.87...@esri/calcite-components-react@3.0.0-next.88) (2025-01-03) + +**Note:** Version bump only for package @esri/calcite-components-react + ## [3.0.0-next.87](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@3.0.0-next.86...@esri/calcite-components-react@3.0.0-next.87) (2025-01-02) **Note:** Version bump only for package @esri/calcite-components-react diff --git a/packages/calcite-components-react/LICENSE.md b/packages/calcite-components-react/LICENSE.md index 1235786306c..37d072da0e3 100644 --- a/packages/calcite-components-react/LICENSE.md +++ b/packages/calcite-components-react/LICENSE.md @@ -1,6 +1,6 @@ # Licensing -COPYRIGHT © 2024 Esri +COPYRIGHT © 2025 Esri All rights reserved under the copyright laws of the United States and applicable international laws, treaties, and conventions. diff --git a/packages/calcite-components-react/package.json b/packages/calcite-components-react/package.json index 86c02acb111..2e4f3e8fab2 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.87", + "version": "3.0.0-next.92", "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.87", + "@esri/calcite-components": "3.0.0-next.92", "@lit/react": "1.0.6" }, "peerDependencies": { diff --git a/packages/calcite-components/CHANGELOG.md b/packages/calcite-components/CHANGELOG.md index bc2ac2c94c4..6cb02de70e9 100644 --- a/packages/calcite-components/CHANGELOG.md +++ b/packages/calcite-components/CHANGELOG.md @@ -3,6 +3,53 @@ 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.92](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@3.0.0-next.91...@esri/calcite-components@3.0.0-next.92) (2025-01-08) + +### Features + +- **menu-item:** add component tokens ([#10654](https://github.com/Esri/calcite-design-system/issues/10654)) ([9dc1262](https://github.com/Esri/calcite-design-system/commit/9dc12626331dbf9252ee4f15fc42dab3358029f1)), closes [#7180](https://github.com/Esri/calcite-design-system/issues/7180) +- **rating:** add component tokens ([#11150](https://github.com/Esri/calcite-design-system/issues/11150)) ([6dbb559](https://github.com/Esri/calcite-design-system/commit/6dbb55946597559e37ce7c1747386a3a69533025)), closes [#7180](https://github.com/Esri/calcite-design-system/issues/7180) + +### Bug Fixes + +- **docs:** add docs package export ([#11221](https://github.com/Esri/calcite-design-system/issues/11221)) ([4b0d804](https://github.com/Esri/calcite-design-system/commit/4b0d8043ddcd2d05451253256a6812d5427a69eb)), closes [#10731](https://github.com/Esri/calcite-design-system/issues/10731) +- **docs:** use updated translation bundle paths to generate `translations.json` ([#11219](https://github.com/Esri/calcite-design-system/issues/11219)) ([dce5635](https://github.com/Esri/calcite-design-system/commit/dce56356568f606004f9210ab21cbbcf7dcb94af)), closes [#10731](https://github.com/Esri/calcite-design-system/issues/10731) +- **tile:** wrap overflowing text content ([#11213](https://github.com/Esri/calcite-design-system/issues/11213)) ([732933a](https://github.com/Esri/calcite-design-system/commit/732933a8ed6e0da21edef9d6b8d6b59b363d7292)), closes [#11170](https://github.com/Esri/calcite-design-system/issues/11170) + +## [3.0.0-next.91](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@3.0.0-next.90...@esri/calcite-components@3.0.0-next.91) (2025-01-07) + +### Bug Fixes + +- **text-area:** make `readOnly` prop writable ([#11218](https://github.com/Esri/calcite-design-system/issues/11218)) ([0cbf766](https://github.com/Esri/calcite-design-system/commit/0cbf766156e3b0ec7a662571606af62895e23f59)), closes [#11217](https://github.com/Esri/calcite-design-system/issues/11217) [#10731](https://github.com/Esri/calcite-design-system/issues/10731) [#10310](https://github.com/Esri/calcite-design-system/issues/10310) + +## [3.0.0-next.90](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@3.0.0-next.89...@esri/calcite-components@3.0.0-next.90) (2025-01-06) + +### Features + +- **notice:** add component tokens ([#11042](https://github.com/Esri/calcite-design-system/issues/11042)) ([a61c15a](https://github.com/Esri/calcite-design-system/commit/a61c15af46e772956a58fcc71f873b910897097e)), closes [#7180](https://github.com/Esri/calcite-design-system/issues/7180) + +### Bug Fixes + +- **input:** correctly apply placeholder styles ([#11107](https://github.com/Esri/calcite-design-system/issues/11107)) ([7fa1eea](https://github.com/Esri/calcite-design-system/commit/7fa1eeaeaf090b1cf4e835a6e3bcd678c3918173)), closes [#8967](https://github.com/Esri/calcite-design-system/issues/8967) +- **time-picker:** display correct localized hour based on hour-format when no value is set ([#11200](https://github.com/Esri/calcite-design-system/issues/11200)) ([a938192](https://github.com/Esri/calcite-design-system/commit/a938192b510a5c57fa7613bbea7e965d540243c7)), closes [#11198](https://github.com/Esri/calcite-design-system/issues/11198) + +## [3.0.0-next.89](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@3.0.0-next.88...@esri/calcite-components@3.0.0-next.89) (2025-01-04) + +### Features + +- **combobox, input-time-zone:** highlight text matches consistently ([#11193](https://github.com/Esri/calcite-design-system/issues/11193)) ([75f54de](https://github.com/Esri/calcite-design-system/commit/75f54de466fa2938af9a333cb9c3e4b8ed00460b)), closes [#11173](https://github.com/Esri/calcite-design-system/issues/11173) + +## [3.0.0-next.88](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@3.0.0-next.87...@esri/calcite-components@3.0.0-next.88) (2025-01-03) + +### Features + +- **combobox:** add `filterProps` ([#11180](https://github.com/Esri/calcite-design-system/issues/11180)) ([09d5a27](https://github.com/Esri/calcite-design-system/commit/09d5a2777ebe3c915a3284efca02768cf5c2823a)), closes [#8043](https://github.com/Esri/calcite-design-system/issues/8043) + +### Bug Fixes + +- **autocomplete:** fix item key functionality ([#11191](https://github.com/Esri/calcite-design-system/issues/11191)) ([d2ced69](https://github.com/Esri/calcite-design-system/commit/d2ced69f4967f17bddb39a2a9e0256ec59c5a0bf)), closes [#11154](https://github.com/Esri/calcite-design-system/issues/11154) +- **list:** include groups in filtering ([#10664](https://github.com/Esri/calcite-design-system/issues/10664)) ([904623b](https://github.com/Esri/calcite-design-system/commit/904623be3cff426e71d51001a29df188a72ea00b)), closes [#7702](https://github.com/Esri/calcite-design-system/issues/7702) + ## [3.0.0-next.87](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@3.0.0-next.86...@esri/calcite-components@3.0.0-next.87) (2025-01-02) **Note:** Version bump only for package @esri/calcite-components diff --git a/packages/calcite-components/LICENSE.md b/packages/calcite-components/LICENSE.md index 1235786306c..37d072da0e3 100644 --- a/packages/calcite-components/LICENSE.md +++ b/packages/calcite-components/LICENSE.md @@ -1,6 +1,6 @@ # Licensing -COPYRIGHT © 2024 Esri +COPYRIGHT © 2025 Esri All rights reserved under the copyright laws of the United States and applicable international laws, treaties, and conventions. diff --git a/packages/calcite-components/package.json b/packages/calcite-components/package.json index 00d5e4bb280..959dc2ec482 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.87", + "version": "3.0.0-next.92", "description": "Web Components for Esri's Calcite Design System.", "homepage": "https://developers.arcgis.com/calcite-design-system/", "repository": { @@ -19,6 +19,7 @@ "./types/*": "./dist/types/*.d.ts", "./hydrate": "./hydrate/index.js", "./calcite/calcite.css": "./dist/calcite/calcite.css", + "./docs/*": "./dist/docs/*", "./dist/calcite/calcite.css": "./dist/calcite/calcite.css", "./dist/loader": "./dist/loader.js", "./dist/components": "./dist/index.js", @@ -68,10 +69,10 @@ "util:test-types": "! grep -rnw 'dist/types' -e ' { defaultValue: undefined, }, { - propertyName: "overlayPositioning", - defaultValue: "absolute", + propertyName: "filterProps", + defaultValue: undefined, }, { - propertyName: "flipPlacements", - defaultValue: undefined, + propertyName: "overlayPositioning", + defaultValue: "absolute", }, { propertyName: "scale", @@ -674,6 +674,61 @@ describe("calcite-combobox", () => { expect(await input.getProperty("value")).toBe("anm"); expect(input).not.toHaveClass(`${CSS.inputHidden}`); }); + + it("supports filterProps", async () => { + const page = await newE2EPage(); + await page.setContent(html` + + + + + + + + `); + + await page.waitForChanges(); + const combobox = await page.find("calcite-combobox"); + combobox.setProperty("filterProps", ["textLabel", "description"]); + await page.waitForChanges(); + await page.waitForTimeout(DEBOUNCE.filter); + + expect(await combobox.getProperty("filteredItems")).toHaveLength(2); + + const visibleItems = await page.findAll("calcite-combobox-item:not([hidden])"); + + expect(visibleItems.map((item) => item.id)).toEqual(["text-label-match", "description-match"]); + }) }); it("should control max items displayed", async () => { diff --git a/packages/calcite-components/src/components/combobox/combobox.tsx b/packages/calcite-components/src/components/combobox/combobox.tsx index 4ad24882113..3e3651c8a1b 100644 --- a/packages/calcite-components/src/components/combobox/combobox.tsx +++ b/packages/calcite-components/src/components/combobox/combobox.tsx @@ -121,17 +121,20 @@ export class Combobox private emitComboboxChange = debounce(this.internalComboboxChangeEvent, 0); + private get effectiveFilterProps(): string[] { + if (!this.filterProps) { + return ["description", "label", "metadata", "shortHeading", "textLabel"]; + } + + return this.filterProps.filter((prop) => prop !== "el"); + } + private filterItems = (() => { const find = (item: ComboboxChildElement, filteredData: ItemData[]) => item && filteredData.some(({ el }) => item === el); return debounce((text: string, setOpenToEmptyState = false, emit = true): void => { - const filteredData = filter([...this.data, ...this.groupData], text, [ - "description", - "label", - "metadata", - "shortHeading", - ]); + const filteredData = filter([...this.data, ...this.groupData], text, this.effectiveFilterProps); const itemsAndGroups = this.getItemsAndGroups(); const matchAll = text === ""; @@ -308,6 +311,9 @@ export class Combobox } } + /** Specifies the properties to match against when filtering. If not set, all properties will be matched (label, description, metadata, value). */ + @property() filterProps: string[]; + /** * Specifies the component's filtered items. * @@ -1264,9 +1270,10 @@ export class Combobox return this.items.map((item) => ({ description: item.description, filterDisabled: item.filterDisabled, - label: item.heading || item.textLabel, + label: item.heading, metadata: item.metadata, shortHeading: item.shortHeading, + textLabel: item.textLabel, el: item, // used for matching items to data })); } diff --git a/packages/calcite-components/src/components/combobox/interfaces.ts b/packages/calcite-components/src/components/combobox/interfaces.ts index 26ff89cfd48..ad98fd15ef9 100644 --- a/packages/calcite-components/src/components/combobox/interfaces.ts +++ b/packages/calcite-components/src/components/combobox/interfaces.ts @@ -8,6 +8,7 @@ export interface ItemData extends BaseData { description: string; metadata: Record; shortHeading: string; + textLabel: string; el: ComboboxItem["el"] | ComboboxItemGroup["el"]; } diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx index edf08b94be1..eedff655fd7 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.tsx @@ -87,7 +87,6 @@ export class DatePickerMonthHeader extends LitElement { * Made into a prop for testing purposes only. * * @private - * @readonly */ @property() messages: DatePicker["messages"]["_overrides"]; diff --git a/packages/calcite-components/src/components/handle/handle.tsx b/packages/calcite-components/src/components/handle/handle.tsx index 14a10a057fd..711a69073fe 100644 --- a/packages/calcite-components/src/components/handle/handle.tsx +++ b/packages/calcite-components/src/components/handle/handle.tsx @@ -66,7 +66,6 @@ export class Handle extends LitElement implements LoadableComponent, Interactive * Made into a prop for testing purposes only. * * @private - * @readonly */ messages = useT9n({ blocking: true }); diff --git a/packages/calcite-components/src/components/input/input.scss b/packages/calcite-components/src/components/input/input.scss index bc0b2dea19a..99d8ea27249 100755 --- a/packages/calcite-components/src/components/input/input.scss +++ b/packages/calcite-components/src/components/input/input.scss @@ -33,6 +33,11 @@ * */ +@mixin input-placeholder-styles { + @apply font-normal; + color: var(--calcite-input-placeholder-text-color, var(--calcite-color-text-3)); +} + :host { @apply block; } @@ -155,17 +160,27 @@ input { block-size 0, outline-offset 0s; -webkit-appearance: none; - &::placeholder, - &:-ms-input-placeholder, - &::-ms-input-placeholder { - @apply font-normal; - color: var(--calcite-input-placeholder-text-color, var(--calcite-color-text-3)); - } + &:placeholder-shown { @apply text-ellipsis; } } +// Placeholder styles +// Do not combine these style rules. The browser interprets the rule as one. When combined, properties like -ms can not be found in non-Microsoft browsers and thus the whole selector is invalidated and is ignored. +:-ms-input-placeholder { + @include input-placeholder-styles; +} + +::-ms-input-placeholder { + @include input-placeholder-styles; +} + +::placeholder { + @include input-placeholder-styles; +} +// End Placeholder styles + textarea { border-radius: var(--calcite-input-corner-radius, var(--calcite-corner-radius-sharp)); } diff --git a/packages/calcite-components/src/components/list/list.e2e.ts b/packages/calcite-components/src/components/list/list.e2e.ts index f5f753fe878..7eb67190a77 100755 --- a/packages/calcite-components/src/components/list/list.e2e.ts +++ b/packages/calcite-components/src/components/list/list.e2e.ts @@ -767,7 +767,7 @@ describe("calcite-list", () => { expect(visibleItems.map((item) => item.id)).toEqual(["label-match", "description-match"]); }); - it("filters initially with filterProps", async () => { + it("supports filterProps", async () => { const page = await newE2EPage(); await page.setContent(html` diff --git a/packages/calcite-components/src/components/menu-item/interfaces.ts b/packages/calcite-components/src/components/menu-item/interfaces.ts index a25275470c7..8c862aa3064 100644 --- a/packages/calcite-components/src/components/menu-item/interfaces.ts +++ b/packages/calcite-components/src/components/menu-item/interfaces.ts @@ -5,3 +5,5 @@ export interface MenuItemCustomEvent { children?: MenuItem["el"][]; isSubmenuOpen?: boolean; } + +export type Layout = "horizontal" | "vertical"; diff --git a/packages/calcite-components/src/components/menu-item/menu-item.e2e.ts b/packages/calcite-components/src/components/menu-item/menu-item.e2e.ts index 9794ef22e23..fa900686bdf 100644 --- a/packages/calcite-components/src/components/menu-item/menu-item.e2e.ts +++ b/packages/calcite-components/src/components/menu-item/menu-item.e2e.ts @@ -1,8 +1,11 @@ import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; import { describe, expect, it } from "vitest"; import { html } from "../../../support/formatting"; -import { accessible, focusable, hidden, reflects, renders, t9n } from "../../tests/commonTests"; +import { accessible, focusable, hidden, reflects, renders, t9n, themed } from "../../tests/commonTests"; import { getFocusedElementProp } from "../../tests/utils"; +import { ComponentTestTokens } from "../../tests/commonTests/themed"; +import { CSS } from "../../../src/components/menu-item/resources"; +import { Layout } from "./interfaces"; describe("calcite-menu-item", () => { describe("renders", () => { @@ -116,4 +119,174 @@ describe("calcite-menu-item", () => { expect(await getFocusedElementProp(page, "id")).toBe("Nature"); expect(eventSpy).toHaveReceivedEventTimes(2); }); + + describe("theme", () => { + const menuWithSlottedSubmenuHTML = (layout: Layout): string => html` + + + + + + + `; + describe("slotted submenu", () => { + const tokens = (layout: Layout): ComponentTestTokens => { + return { + "--calcite-menu-background-color": [{ + selector: "calcite-menu-item", + shadowSelector: `calcite-action`, + targetProp: "--calcite-action-background-color-press", + state: { press: { attribute: "class", value: "dropdown-action" } }, + }, { + selector: "calcite-menu-item", + shadowSelector: `calcite-action`, + targetProp: "--calcite-action-background-color", + }], + "--calcite-menu-text-color": { + selector: "calcite-menu-item", + shadowSelector: `calcite-action`, + targetProp: "--calcite-action-text-color", + }, + "--calcite-menu-item-sub-menu-corner-radius": { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.dropdownMenuItems}`, + targetProp: "borderRadius", + }, + "--calcite-menu-item-sub-menu-border-color": { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.dropdownMenuItems}`, + targetProp: layout === "horizontal" ? "borderColor" : "borderBlockColor", + } + }; + } + + describe("horizontal layout", () => { + themed(menuWithSlottedSubmenuHTML("horizontal"), tokens("horizontal")); + }); + + describe("vertical layout", () => { + themed(menuWithSlottedSubmenuHTML("vertical"), tokens("vertical")); + }); + }); + + describe("default", () => { + const menuHTML = (layout: Layout): string => html` + + + + `; + const tokens: ComponentTestTokens = { + "--calcite-menu-text-color": [ + { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.content}`, + targetProp: "color", + }, + { + selector: "calcite-menu-item", + shadowSelector: ` .${CSS.content} `, + targetProp: "color", + state: { press: { attribute: "role", value: `menuitem` } }, + } + ], + "--calcite-menu-background-color": [ + { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.content}`, + targetProp: "backgroundColor", + }, + { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.content}`, + targetProp: "backgroundColor", + state: { press: { attribute: "role", value: `menuitem` } }, + }], + } + + describe("horizontal layout", () => { + themed(menuHTML("horizontal"), { + ...tokens, "--calcite-menu-item-accent-color": { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.content}`, + targetProp: "borderBlockEndColor", + state: "hover", + }, + }); + }) + + describe("vertical layout", () => { + themed(menuHTML("vertical"), tokens); + }); + }) + + describe("active", () => { + const activeMenuItemHTML = (layout: Layout): string => html` + + + + `; + const tokens = (layout: Layout): ComponentTestTokens => { + const targetBorderProp = layout === "horizontal" ? "borderBlockEndColor" : "borderInlineEndColor"; + return { + "--calcite-menu-item-accent-color": [{ + selector: "calcite-menu-item", + shadowSelector: `.${CSS.content}`, + targetProp: targetBorderProp + }, + { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.content}`, + targetProp: targetBorderProp, + state: "hover", + },] + } + }; + describe("horizontal layout", () => { + themed(activeMenuItemHTML("horizontal"), tokens("horizontal")); + }) + + describe("vertical layout", () => { + themed(activeMenuItemHTML("vertical"), tokens("vertical")); + }) + }); + + describe("icons", () => { + const iconMenuItemHTML: string = html` + + + + `; + + const tokens: ComponentTestTokens = { + "--calcite-menu-text-color": [ + { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.iconStart}`, + targetProp: "color", + }, + { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.iconEnd}`, + targetProp: "color", + }, + { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.iconBreadcrumb}`, + targetProp: "color", + }, + { + selector: "calcite-menu-item", + shadowSelector: `.${CSS.iconDropdown}`, + targetProp: "color", + }, + ], + }; + themed(iconMenuItemHTML, tokens); + }); + }); }); diff --git a/packages/calcite-components/src/components/menu-item/menu-item.scss b/packages/calcite-components/src/components/menu-item/menu-item.scss index 5b2602ea3c0..12fea8c2a5d 100644 --- a/packages/calcite-components/src/components/menu-item/menu-item.scss +++ b/packages/calcite-components/src/components/menu-item/menu-item.scss @@ -1,3 +1,15 @@ +/** + * CSS Custom Properties + * + * These properties can be overridden using the component's tag as selector. + * + * @prop --calcite-menu-item-accent-color: Specifies the border color of the component when `active`. + * @prop --calcite-menu-background-color: Specifies the background color of the component. + * @prop --calcite-menu-item-sub-menu-border-color: Specifies the border color of sub-menu. + * @prop --calcite-menu-item-sub-menu-corner-radius: Specifies the border radius of sub-menu. + * @prop --calcite-menu-text-color: Specifies the text color of the component. + */ + :host { @apply flex items-center @@ -32,46 +44,66 @@ cursor-pointer outline-none text-0 - text-color-2 box-border - bg-foreground-1 px-4 h-full w-full; text-decoration: none; - border-block-end: theme("spacing[0.5]") solid transparent; padding-block-start: theme("spacing[0.5]"); + border-block-end: theme("spacing[0.5]") solid var(--calcite-color-transparent); + + background-color: var( + --calcite-menu-background-color, + var(--calcite-internal-menu-background-color, var(--calcite-color-foreground-1)) + ); + color: var(--calcite-menu-text-color, var(--calcite-internal-menu-text-color, var(--calcite-color-text-2))); + &:hover { - @apply text-color-2 border-b-color-2; + border-block-end-color: var(--calcite-menu-item-accent-color, var(--calcite-color-border-2)); } + &:focus { - @apply text-color-2 focus-inset border-b-4; + @apply focus-inset border-b-4; padding-block-start: theme("spacing.1"); border-block-end-width: theme("spacing.1"); } + &:active { - @apply bg-foreground-3 text-color-1; + --calcite-internal-menu-background-color: var(--calcite-color-foreground-3); + --calcite-internal-menu-text-color: var(--calcite-color-text-1); } + & span { display: inline-flex; } + &.layout--vertical { @apply flex w-full justify-start; padding-block: 1rem; border-block-end: 0; - border-inline-end: theme("spacing.1") solid transparent; + border-inline-end: theme("spacing.1") solid var(--calcite-color-transparent); } } -:host([active]) .content { - @apply text-color-1; - border-color: var(--calcite-color-brand); +:host([layout="vertical"]) .content { + @apply px-3; +} + +:host([active]) { + .content { + --calcite-internal-menu-text-color: var(--calcite-color-text-1); + border-color: var(--calcite-menu-item-accent-color, var(--calcite-color-brand)); + } .icon { - --calcite-icon-color: var(--calcite-color-brand); + --calcite-internal-menu-item-icon-color: var(--calcite-color-brand); } } -:host([layout="vertical"]) .content { - @apply px-3; + +.icon { + color: var( + --calcite-menu-text-color, + var(--calcite-icon-color, var(--calcite-internal-menu-item-icon-color, var(--calcite-color-text-3))) + ); } .icon--start { @@ -88,7 +120,6 @@ .icon--dropdown { @apply ms-auto me-0 ps-2 relative; - --calcite-icon-color: var(--calcite-color-text-3); } :host([layout="vertical"]) .icon--end ~ .icon--dropdown { @@ -108,7 +139,6 @@ .icon--breadcrumb { @apply ps-2 me-0; - --calcite-icon-color: var(--calcite-color-text-3); } :host([layout="vertical"]) .icon--breadcrumb { @@ -130,32 +160,41 @@ calcite-action { @apply relative h-auto; border-inline-start: 1px solid var(--calcite-color-foreground-1); + --calcite-action-background-color: var(--calcite-menu-background-color); + --calcite-action-text-color: var(--calcite-menu-text-color); + &::after { @apply block w-px absolute -start-px; content: ""; inset-block: theme("spacing.3"); background-color: var(--calcite-color-border-3); } + &:hover::after { @apply h-full; inset-block: 0; } + + &:active { + --calcite-action-background-color-press: var(--calcite-menu-background-color); + } } +// extends the broder block of calcite action when hovered on content .content:focus ~ calcite-action, .content:hover ~ calcite-action { - @apply text-color-1; - border-inline-start: 1px solid var(--calcite-color-border-3); -} + --calcite-action-text-color: var(--calcite-menu-text-color, var(--calcite-color-text-1)); -.container:hover .dropdown-action { - @apply bg-foreground-2; + &::after { + @apply h-full; + inset-block: 0; + } } .dropdown-menu-items { @apply absolute h-auto flex-col hidden overflow-visible min-w-full; - border: 1px solid var(--calcite-color-border-3); - background: var(--calcite-color-foreground-1); + border: 1px solid var(--calcite-menu-item-sub-menu-border-color, var(--calcite-color-border-3)); + border-radius: var(--calcite-menu-item-sub-menu-corner-radius, var(--calcite-corner-radius)); inset-block-start: 100%; z-index: theme("zIndex.dropdown"); &.open { @@ -173,7 +212,7 @@ calcite-action { } .dropdown--vertical.dropdown-menu-items { - @apply relative rounded-none; + @apply relative; box-shadow: none; inset-block-start: 0; transform: none; diff --git a/packages/calcite-components/src/components/menu-item/menu-item.tsx b/packages/calcite-components/src/components/menu-item/menu-item.tsx index 8052d1422f3..6609f266a34 100644 --- a/packages/calcite-components/src/components/menu-item/menu-item.tsx +++ b/packages/calcite-components/src/components/menu-item/menu-item.tsx @@ -10,7 +10,7 @@ import { state, JsxNode, } from "@arcgis/lumina"; -import { FlipContext } from "../interfaces"; +import { FlipContext, Layout } from "../interfaces"; import { Direction, getElementDir, slotChangeGetAssignedElements } from "../../utils/dom"; import { componentFocusable, @@ -33,8 +33,6 @@ declare global { } } -type Layout = "horizontal" | "vertical"; - /** @slot submenu-item - A slot for adding `calcite-menu-item`s in a submenu. */ export class MenuItem extends LitElement implements LoadableComponent { // #region Static Members diff --git a/packages/calcite-components/src/components/notice/notice.e2e.ts b/packages/calcite-components/src/components/notice/notice.e2e.ts index 13131e95ed9..b60c223a3a8 100644 --- a/packages/calcite-components/src/components/notice/notice.e2e.ts +++ b/packages/calcite-components/src/components/notice/notice.e2e.ts @@ -1,6 +1,6 @@ import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; import { describe, expect, it } from "vitest"; -import { accessible, focusable, renders, slots, hidden, t9n } from "../../tests/commonTests"; +import { accessible, focusable, renders, slots, hidden, themed, t9n } from "../../tests/commonTests"; import { html } from "../../../support/formatting"; import { openClose } from "../../tests/commonTests"; import { CSS, SLOTS } from "./resources"; @@ -129,4 +129,57 @@ describe("calcite-notice", () => { describe("translation support", () => { t9n("calcite-notice"); }); + + describe("theme", () => { + describe("default", () => { + themed( + html` + +
Title
+
Message
+ Retry +
+ `, + { + "--calcite-notice-background-color": { + shadowSelector: `.${CSS.container}`, + targetProp: "backgroundColor", + }, + "--calcite-notice-close-text-color": { + shadowSelector: `.${CSS.close}`, + targetProp: "color", + }, + "--calcite-notice-close-text-color-hover": [ + { + shadowSelector: `.${CSS.close}`, + targetProp: "color", + state: "focus", + }, + { + shadowSelector: `.${CSS.close}`, + targetProp: "color", + state: "hover", + }, + ], + "--calcite-notice-close-background-color-focus": [ + { + shadowSelector: `.${CSS.close}`, + targetProp: "backgroundColor", + state: "focus", + }, + { + shadowSelector: `.${CSS.close}`, + targetProp: "backgroundColor", + state: "hover", + }, + ], + "--calcite-notice-close-background-color-press": { + shadowSelector: `.${CSS.close}`, + targetProp: "backgroundColor", + state: { press: { attribute: "class", value: CSS.close } }, + }, + }, + ); + }); + }); }); diff --git a/packages/calcite-components/src/components/notice/notice.scss b/packages/calcite-components/src/components/notice/notice.scss index 6343992b784..8b22267bdff 100644 --- a/packages/calcite-components/src/components/notice/notice.scss +++ b/packages/calcite-components/src/components/notice/notice.scss @@ -3,7 +3,13 @@ * * These properties can be overridden using the component's tag as selector. * - * @prop --calcite-notice-width: The width of the component. + * @prop --calcite-notice-background-color: Specifies the component's background color. + * @prop --calcite-notice-close-background-color-focus: Specifies the component's background color when focused. + * @prop --calcite-notice-close-background-color-press: Specifies the component's background color when active. + * @prop --calcite-notice-close-text-color-hover: Specifies the background color of the component's close button when hovered. + * @prop --calcite-notice-close-text-color: Specifies the text color of the component's close button. + * @prop --calcite-notice-content-text-color: Specifies the component's content text color. + * @prop --calcite-notice-width: [Deprecated] Specifies the component's width. */ // scale variables @@ -71,13 +77,13 @@ } .container { - @apply bg-foreground-1 - pointer-events-none + @apply pointer-events-none my-0 box-border flex w-full opacity-0; + overflow: hidden; max-block-size: 0; transition-property: opacity, max-block-size; @@ -85,6 +91,7 @@ text-align: start; border-inline-start: var(--calcite-border-width-md) solid; box-shadow: 0 0 0 0 transparent; + background-color: var(--calcite-notice-background-color, var(--calcite-color-foreground-1)); } // focus styles @@ -109,12 +116,16 @@ } @include slotted("title", "*", ".container") { - @apply text-color-1 m-0 font-medium; + @apply m-0 font-medium; + + color: var(--calcite-notice-close-text-color-hover, var(--calcite-color-text-1)); } @include slotted("message", "*", ".container") { - @apply text-color-2 m-0 inline font-normal; + @apply m-0 inline font-normal; + margin-inline-end: var(--calcite-notice-spacing-token-small); + color: var(--calcite-notice-content-text-color, var(--calcite-color-text-2)); } @mixin notice-element-base() { @@ -146,17 +157,20 @@ } .notice-close { - @apply text-color-3 flex cursor-pointer items-center self-stretch border-none bg-transparent outline-none; + @apply flex cursor-pointer items-center self-stretch border-none bg-transparent outline-none; @include notice-element-base; -webkit-appearance: none; + color: var(--calcite-notice-close-text-color, var(--calcite-color-text-3)); + &:hover, &:focus { - @apply bg-foreground-2 text-color-1; + background-color: var(--calcite-notice-close-background-color-focus, var(--calcite-color-foreground-2)); + color: var(--calcite-notice-close-text-color-hover, var(--calcite-color-text-1)); } &:active { - @apply bg-foreground-3; + background-color: var(--calcite-notice-close-background-color-press, var(--calcite-color-foreground-3)); } } diff --git a/packages/calcite-components/src/components/rating/rating.e2e.ts b/packages/calcite-components/src/components/rating/rating.e2e.ts index 1695fdaa6c9..8ee5602953c 100644 --- a/packages/calcite-components/src/components/rating/rating.e2e.ts +++ b/packages/calcite-components/src/components/rating/rating.e2e.ts @@ -11,8 +11,11 @@ import { reflects, renders, t9n, + themed, } from "../../tests/commonTests"; +import { html } from "../../../support/formatting"; import { isElementFocused } from "../../tests/utils"; +import { CSS } from "./resources"; describe("calcite-rating", () => { describe("common tests", () => { @@ -795,4 +798,56 @@ describe("calcite-rating", () => { expect(element).toEqualAttribute("value", "2"); }); }); + + describe("theme", () => { + describe("default", () => { + themed(html``, { + "--calcite-rating-spacing": { + shadowSelector: `.${CSS.fieldSet}`, + targetProp: "gap", + }, + "--calcite-rating-color": { + shadowSelector: `.${CSS.star}`, + targetProp: "color", + }, + }); + }); + describe("selected", () => { + themed(html``, { + "--calcite-rating-color-hover": [ + { + shadowSelector: `.${CSS.star}`, + targetProp: "color", + state: { hover: { attribute: "class", value: CSS.hovered } }, + }, + { + shadowSelector: `.${CSS.selected}`, + targetProp: "color", + }, + ], + }); + }); + describe("average", () => { + themed(html``, { + "--calcite-rating-average-color": [ + { + shadowSelector: `.${CSS.average}`, + targetProp: "color", + }, + { + shadowSelector: `.${CSS.fraction}`, + targetProp: "color", + }, + ], + "--calcite-rating-average-text-color": { + shadowSelector: `.${CSS.numberAverage}`, + targetProp: "color", + }, + "--calcite-rating-count-text-color": { + shadowSelector: `.${CSS.numberCount}`, + targetProp: "color", + }, + }); + }); + }); }); diff --git a/packages/calcite-components/src/components/rating/rating.scss b/packages/calcite-components/src/components/rating/rating.scss index 63a0139f899..65cf389d639 100644 --- a/packages/calcite-components/src/components/rating/rating.scss +++ b/packages/calcite-components/src/components/rating/rating.scss @@ -3,7 +3,13 @@ * * These properties can be overridden using the component's tag as selector. * - * @prop --calcite-rating-spacing-unit: The amount of left and right margin spacing between each rating star. + * @prop --calcite-rating-spacing-unit: [Deprecated] Use `--calcite-rating-spacing`. Specifies the amount of left and right margin spacing between each item. + * @prop --calcite-rating-spacing: Specifies the amount of left and right margin spacing between each item. + * @prop --calcite-rating-color-hover: Specifies the component's item color when hovered or selected. + * @prop --calcite-rating-color: Specifies the component's item color. + * @prop --calcite-rating-average-color: Specifies the component's item color when average is set. + * @prop --calcite-rating-average-text-color: Specifies the component's average text color. + * @prop --calcite-rating-count-text-color: Specifies the component's count text color. */ :host { @@ -15,17 +21,17 @@ :host([scale="s"]) { @apply h-6; - --calcite-rating-spacing-unit: theme("spacing.1"); + --calcite-internal-rating-spacing: theme("spacing.1"); } :host([scale="m"]) { @apply h-8; - --calcite-rating-spacing-unit: theme("spacing.2"); + --calcite-internal-rating-spacing: theme("spacing.2"); } :host([scale="l"]) { @apply h-11; - --calcite-rating-spacing-unit: theme("spacing.3"); + --calcite-internal-rating-spacing: theme("spacing.3"); } :host([read-only]) { @@ -38,7 +44,7 @@ border-width: 0; padding: 0; align-items: center; - gap: var(--calcite-rating-spacing-unit); + gap: var(--calcite-rating-spacing, var(--calcite-internal-rating-spacing)); } .wrapper { @@ -51,7 +57,7 @@ display: flex; flex-direction: column; cursor: pointer; - color: theme("borderColor.color.input"); + color: var(--calcite-rating-color, theme("borderColor.color.input")); &:focus { @apply focus-outset; } @@ -59,12 +65,12 @@ .average, .fraction { - color: theme("colors.warning"); + color: var(--calcite-rating-average-color, theme("colors.warning")); } .hovered, .selected { - color: theme("colors.brand"); + color: var(--calcite-rating-color-hover, theme("colors.brand")); } .fraction { @@ -84,13 +90,14 @@ calcite-chip { .number--average { font-weight: bold; + color: var(--calcite-rating-average-text-color); } .number--count { - color: var(--calcite-color-text-2); + color: var(--calcite-rating-count-text-color, var(--calcite-color-text-2)); font-style: italic; &:not(:first-child) { - margin-inline-start: var(--calcite-rating-spacing-unit); + margin-inline-start: var(--calcite-rating-spacing, var(--calcite-internal-rating-spacing)); } } diff --git a/packages/calcite-components/src/components/rating/resources.ts b/packages/calcite-components/src/components/rating/resources.ts index 3fbf623b870..ad8ee9ebab2 100644 --- a/packages/calcite-components/src/components/rating/resources.ts +++ b/packages/calcite-components/src/components/rating/resources.ts @@ -1,3 +1,14 @@ +export const CSS = { + fieldSet: "fieldset", + star: "star", + hovered: "hovered", + selected: "selected", + average: "average", + fraction: "fraction", + numberAverage: "number--average", + numberCount: "number--count", +}; + export const IDS = { validationMessage: "validationMessage", }; diff --git a/packages/calcite-components/src/components/sort-handle/sort-handle.tsx b/packages/calcite-components/src/components/sort-handle/sort-handle.tsx index 300f5e1fc5a..0e438eb3e62 100644 --- a/packages/calcite-components/src/components/sort-handle/sort-handle.tsx +++ b/packages/calcite-components/src/components/sort-handle/sort-handle.tsx @@ -63,7 +63,6 @@ export class SortHandle extends LitElement implements LoadableComponent, Interac * Made into a prop for testing purposes only. * * @private - * @readonly */ @property() messages = useT9n({ blocking: true }); diff --git a/packages/calcite-components/src/components/text-area/text-area.tsx b/packages/calcite-components/src/components/text-area/text-area.tsx index deeb4224247..e3708d630f6 100644 --- a/packages/calcite-components/src/components/text-area/text-area.tsx +++ b/packages/calcite-components/src/components/text-area/text-area.tsx @@ -205,7 +205,6 @@ export class TextArea /** * When `true`, the component's `value` can be read, but cannot be modified. * - * @readonly * @mdn [readOnly](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly) */ @property({ reflect: true }) readOnly = false; diff --git a/packages/calcite-components/src/components/tile/tile.scss b/packages/calcite-components/src/components/tile/tile.scss index e56c32a880e..43280e0cc3a 100644 --- a/packages/calcite-components/src/components/tile/tile.scss +++ b/packages/calcite-components/src/components/tile/tile.scss @@ -68,6 +68,7 @@ calcite-link { .content-container { flex-direction: column; +@include word-break(); } .text-content-container { diff --git a/packages/calcite-components/src/components/time-picker/time-picker.e2e.ts b/packages/calcite-components/src/components/time-picker/time-picker.e2e.ts index ec6fba99e19..91712f48885 100644 --- a/packages/calcite-components/src/components/time-picker/time-picker.e2e.ts +++ b/packages/calcite-components/src/components/time-picker/time-picker.e2e.ts @@ -58,12 +58,25 @@ describe("calcite-time-picker", () => { describe("defaults", () => { defaults("calcite-time-picker", [ + { propertyName: "hourFormat", defaultValue: "user" }, { propertyName: "scale", defaultValue: "m" }, { propertyName: "step", defaultValue: 60 }, ]); }); describe("focusing", () => { + describe("should focus the first focusable element when setFocus is called (ltr)", () => { + focusable(`calcite-time-picker`, { + shadowFocusTargetSelector: `.${CSS.input}.${CSS.hour}`, + }); + }); + + describe("should focus the first focusable element when setFocus is called (rtl)", () => { + focusable(``, { + shadowFocusTargetSelector: `.${CSS.input}.${CSS.hour}`, + }); + }); + it("should focus input when corresponding nudge up button is clicked", async () => { const page = await newE2EPage(); await page.setContent(``); @@ -161,50 +174,7 @@ describe("calcite-time-picker", () => { expect(await getFocusedElementProp(page, "ariaLabel", { shadow: true })).toEqual(hourElAriaLabel); }); - }); - - describe("should focus the first focusable element when setFocus is called (ltr)", () => { - focusable(`calcite-time-picker`, { - shadowFocusTargetSelector: `.${CSS.input}.${CSS.hour}`, - }); - }); - - describe("should focus the first focusable element when setFocus is called (rtl)", () => { - focusable(``, { - shadowFocusTargetSelector: `.${CSS.input}.${CSS.hour}`, - }); - }); - - it("value displays correctly when value is programmatically changed", async () => { - const originalValue = "11:00:00"; - const newValue = "14:30:40"; - const page = await newE2EPage({ - html: ``, - }); - - const timePicker = await page.find("calcite-time-picker"); - const hourEl = await page.find(`calcite-time-picker >>> .${CSS.hour}`); - const minuteEl = await page.find(`calcite-time-picker >>> .${CSS.minute}`); - const secondEl = await page.find(`calcite-time-picker >>> .${CSS.second}`); - const meridiemEl = await page.find(`calcite-time-picker >>> .${CSS.meridiem}`); - - expect(await timePicker.getProperty("value")).toBe(originalValue); - expect(hourEl.textContent).toBe("11"); - expect(minuteEl.textContent).toBe("00"); - expect(secondEl.textContent).toBe("00"); - expect(meridiemEl.textContent).toBe("AM"); - - timePicker.setProperty("value", newValue); - await page.waitForChanges(); - - expect(await timePicker.getProperty("value")).toBe(newValue); - expect(hourEl.textContent).toBe("02"); - expect(minuteEl.textContent).toBe("30"); - expect(secondEl.textContent).toBe("40"); - expect(meridiemEl.textContent).toBe("PM"); - }); - describe("keyboard accessibility", () => { it("tabbing focuses each input in the correct sequence", async () => { const page = await newE2EPage({ html: ``, @@ -337,80 +307,38 @@ describe("calcite-time-picker", () => { ), ).toBe(true); }); + }); - it("ArrowUp key increments hour property and display hour correctly for fr lang (24-hour)", async () => { - const page = await newE2EPage({ - html: ``, - }); - const hour = await page.find(`calcite-time-picker >>> .${CSS.hour}`); - - await hour.click(); - - for (let i = 1; i < 24; i++) { - await page.keyboard.press("ArrowUp"); - await page.waitForChanges(); - - expect(hour.textContent).toBe(formatTimePart(i)); - } - - await page.keyboard.press("ArrowUp"); - await page.waitForChanges(); - - expect(hour.textContent).toBe("00"); - }); - - it("ArrowDown key decrements hour property and display hour correctly for fr lang (24-hour)", async () => { - const page = await newE2EPage({ - html: ``, - }); - const hour = await page.find(`calcite-time-picker >>> .${CSS.hour}`); - - await hour.click(); - await page.keyboard.press("ArrowDown"); - - for (let i = 23; i > 0; i--) { - await page.keyboard.press("ArrowDown"); - await page.waitForChanges(); - - expect(hour.textContent).toBe(formatTimePart(i)); - } - }); - - it("ArrowUp key increments hour property and display hour correctly for en lang (12-hour)", async () => { - const page = await newE2EPage({ - html: ``, - }); - const hour = await page.find(`calcite-time-picker >>> .${CSS.hour}`); - - await hour.click(); - - for (let i = 1; i < 24; i++) { - await page.keyboard.press("ArrowUp"); - await page.waitForChanges(); - - expect(hour.textContent).toBe(i > 12 ? formatTimePart(i - 12) : formatTimePart(i)); - } - - await page.keyboard.press("ArrowUp"); + it("value displays correctly when value is programmatically changed", async () => { + const originalValue = "11:00:00"; + const newValue = "14:30:40"; + const page = await newE2EPage({ + html: ``, }); - it("ArrowDown key decrements hour property and display hour correctly for en lang (12-hour)", async () => { - const page = await newE2EPage({ - html: ``, - }); - const hour = await page.find(`calcite-time-picker >>> .${CSS.hour}`); + const timePicker = await page.find("calcite-time-picker"); + const hourEl = await page.find(`calcite-time-picker >>> .${CSS.hour}`); + const minuteEl = await page.find(`calcite-time-picker >>> .${CSS.minute}`); + const secondEl = await page.find(`calcite-time-picker >>> .${CSS.second}`); + const meridiemEl = await page.find(`calcite-time-picker >>> .${CSS.meridiem}`); - await hour.click(); - await page.keyboard.press("ArrowDown"); + expect(await timePicker.getProperty("value")).toBe(originalValue); + expect(hourEl.textContent).toBe("11"); + expect(minuteEl.textContent).toBe("00"); + expect(secondEl.textContent).toBe("00"); + expect(meridiemEl.textContent).toBe("AM"); - for (let i = 23; i > 0; i--) { - await page.keyboard.press("ArrowDown"); - await page.waitForChanges(); + timePicker.setProperty("value", newValue); + await page.waitForChanges(); - expect(hour.textContent).toBe(i > 12 ? formatTimePart(i - 12) : formatTimePart(i)); - } - }); + expect(await timePicker.getProperty("value")).toBe(newValue); + expect(hourEl.textContent).toBe("02"); + expect(minuteEl.textContent).toBe("30"); + expect(secondEl.textContent).toBe("40"); + expect(meridiemEl.textContent).toBe("PM"); + }); + describe("keyboard accessibility", () => { it("ArrowUp key increments minute property correctly", async () => { const page = await newE2EPage({ html: ``, @@ -669,7 +597,7 @@ describe("calcite-time-picker", () => { it("restricts typing to valid hour values for 12-hour format", async () => { const page = await newE2EPage({ - html: ``, + html: ``, }); const hour = await page.find(`calcite-time-picker >>> .${CSS.hour}`); @@ -698,7 +626,7 @@ describe("calcite-time-picker", () => { it("restricts typing to valid hour values for 24-hour format", async () => { const page = await newE2EPage({ - html: ``, + html: ``, }); const hour = await page.find(`calcite-time-picker >>> .${CSS.hour}`); @@ -1252,129 +1180,233 @@ describe("calcite-time-picker", () => { describe("l10n", () => { supportedLocales.forEach((locale) => { + if (locale !== "en") { + return; + } const localeHourFormat = getLocaleHourFormat(locale); describe(`${locale} (${localeHourFormat}-hour)`, () => { - it(`uses the locale's preferred setting when hour-format="user"`, async () => { - const initialDelocalizedValue = "14:02:30.001"; - const page = await newE2EPage(); - await page.setContent(html` - - `); - - const meridiemEl = await page.find(`calcite-time-picker >>> .${CSS.meridiem}`); - - if (localeHourFormat === "12") { - expect(meridiemEl).toBeDefined(); - } else { - expect(meridiemEl).toBeNull(); - } + describe(`hour-format="user"`, () => { + it(`displays initial localized value in the locale's preferred hour format`, async () => { + const initialDelocalizedValue = "14:02:30.001"; + const page = await newE2EPage(); + await page.setContent(html` + + `); + + const { + localizedHour: expectedLocalizedHour, + localizedHourSuffix: expectedLocalizedHourSuffix, + localizedMinute: expectedLocalizedMinute, + localizedMinuteSuffix: expectedLocalizedMinuteSuffix, + localizedSecond: expectedLocalizedSecond, + localizedSecondSuffix: expectedLocalizedSecondSuffix, + localizedDecimalSeparator: expectedLocalizedDecimalSeparator, + localizedFractionalSecond: expectedLocalizedFractionalSecond, + localizedMeridiem: expectedLocalizedMeridiem, + } = localizeTimeStringToParts({ + value: initialDelocalizedValue, + locale, + }); + + const hourEl = await page.find(`calcite-time-picker >>> .${CSS.hour}`); + const hourSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.hourSuffix}`); + const minuteEl = await page.find(`calcite-time-picker >>> .${CSS.minute}`); + const minuteSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.minuteSuffix}`); + const secondEl = await page.find(`calcite-time-picker >>> .${CSS.second}`); + const decimalSeparatorEl = await page.find(`calcite-time-picker >>> .${CSS.decimalSeparator}`); + const fractionalSecondEl = await page.find(`calcite-time-picker >>> .${CSS.fractionalSecond}`); + const secondSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.secondSuffix}`); + const meridiemEl = await page.find(`calcite-time-picker >>> .${CSS.meridiem}`); + + expect(hourEl).toEqualText(expectedLocalizedHour); + expect(hourSuffixEl).toEqualText(expectedLocalizedHourSuffix); + expect(minuteEl).toEqualText(expectedLocalizedMinute); + expect(minuteSuffixEl).toEqualText(expectedLocalizedMinuteSuffix); + expect(secondEl).toEqualText(expectedLocalizedSecond); + expect(decimalSeparatorEl).toEqualText(expectedLocalizedDecimalSeparator); + expect(fractionalSecondEl).toEqualText(expectedLocalizedFractionalSecond); + if (secondSuffixEl) { + // Bulgarian is the only locale Calcite supports that has a known suffix after the seconds. + // Esri i18n prefers this character be removed for short time formats, which is the only format currently that time-picker supports. + // We're leaving this conditional check here in case a new locale is added in the future that might need to test the second suffix. + expect(secondSuffixEl).toEqualText(expectedLocalizedSecondSuffix); + } + + if (localeHourFormat === "12") { + expect(meridiemEl).toEqualText(expectedLocalizedMeridiem); + } else { + expect(meridiemEl).toBeNull(); + } + }); }); - it("supports localized 12-hour format", async () => { - const initialDelocalizedValue = "14:02:30.001"; - const page = await newE2EPage(); - await page.setContent(html` - - `); - - const { - localizedHour: expectedLocalizedHour, - localizedHourSuffix: expectedLocalizedHourSuffix, - localizedMinute: expectedLocalizedMinute, - localizedMinuteSuffix: expectedLocalizedMinuteSuffix, - localizedSecond: expectedLocalizedSecond, - localizedSecondSuffix: expectedLocalizedSecondSuffix, - localizedDecimalSeparator: expectedLocalizedDecimalSeparator, - localizedFractionalSecond: expectedLocalizedFractionalSecond, - localizedMeridiem: expectedLocalizedMeridiem, - } = localizeTimeStringToParts({ - hour12: true, - value: initialDelocalizedValue, - locale, + describe(`hour-format="12"`, () => { + it("displays initial localized value correctly", async () => { + const initialDelocalizedValue = "14:02:30.001"; + const page = await newE2EPage(); + await page.setContent(html` + + `); + + const { + localizedHour: expectedLocalizedHour, + localizedHourSuffix: expectedLocalizedHourSuffix, + localizedMinute: expectedLocalizedMinute, + localizedMinuteSuffix: expectedLocalizedMinuteSuffix, + localizedSecond: expectedLocalizedSecond, + localizedSecondSuffix: expectedLocalizedSecondSuffix, + localizedDecimalSeparator: expectedLocalizedDecimalSeparator, + localizedFractionalSecond: expectedLocalizedFractionalSecond, + localizedMeridiem: expectedLocalizedMeridiem, + } = localizeTimeStringToParts({ + hour12: true, + value: initialDelocalizedValue, + locale, + }); + + const hourEl = await page.find(`calcite-time-picker >>> .${CSS.hour}`); + const hourSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.hourSuffix}`); + const minuteEl = await page.find(`calcite-time-picker >>> .${CSS.minute}`); + const minuteSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.minuteSuffix}`); + const secondEl = await page.find(`calcite-time-picker >>> .${CSS.second}`); + const decimalSeparatorEl = await page.find(`calcite-time-picker >>> .${CSS.decimalSeparator}`); + const fractionalSecondEl = await page.find(`calcite-time-picker >>> .${CSS.fractionalSecond}`); + const secondSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.secondSuffix}`); + const meridiemEl = await page.find(`calcite-time-picker >>> .${CSS.meridiem}`); + + expect(hourEl).toEqualText(expectedLocalizedHour); + expect(hourSuffixEl).toEqualText(expectedLocalizedHourSuffix); + expect(minuteEl).toEqualText(expectedLocalizedMinute); + expect(minuteSuffixEl).toEqualText(expectedLocalizedMinuteSuffix); + expect(secondEl).toEqualText(expectedLocalizedSecond); + expect(decimalSeparatorEl).toEqualText(expectedLocalizedDecimalSeparator); + expect(fractionalSecondEl).toEqualText(expectedLocalizedFractionalSecond); + if (secondSuffixEl) { + // Bulgarian is the only locale Calcite supports that has a known suffix after the seconds. + // Esri i18n prefers this character be removed for short time formats, which is the only format currently that time-picker supports. + // We're leaving this conditional check here in case a new locale is added in the future that might need to test the second suffix. + expect(secondSuffixEl).toEqualText(expectedLocalizedSecondSuffix); + } + expect(meridiemEl).toEqualText(expectedLocalizedMeridiem); }); - const hourEl = await page.find(`calcite-time-picker >>> .${CSS.hour}`); - const hourSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.hourSuffix}`); - const minuteEl = await page.find(`calcite-time-picker >>> .${CSS.minute}`); - const minuteSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.minuteSuffix}`); - const secondEl = await page.find(`calcite-time-picker >>> .${CSS.second}`); - const decimalSeparatorEl = await page.find(`calcite-time-picker >>> .${CSS.decimalSeparator}`); - const fractionalSecondEl = await page.find(`calcite-time-picker >>> .${CSS.fractionalSecond}`); - const secondSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.secondSuffix}`); - const meridiemEl = await page.find(`calcite-time-picker >>> .${CSS.meridiem}`); - - expect(hourEl).toEqualText(expectedLocalizedHour); - expect(hourSuffixEl).toEqualText(expectedLocalizedHourSuffix); - expect(minuteEl).toEqualText(expectedLocalizedMinute); - expect(minuteSuffixEl).toEqualText(expectedLocalizedMinuteSuffix); - expect(secondEl).toEqualText(expectedLocalizedSecond); - expect(decimalSeparatorEl).toEqualText(expectedLocalizedDecimalSeparator); - expect(fractionalSecondEl).toEqualText(expectedLocalizedFractionalSecond); - if (secondSuffixEl) { - // Bulgarian is the only locale Calcite supports that has a known suffix after the seconds. - // Esri i18n prefers this character be removed for short time formats, which is the only format currently that time-picker supports. - // We're leaving this conditional check here in case a new locale is added in the future that might need to test the second suffix. - expect(secondSuffixEl).toEqualText(expectedLocalizedSecondSuffix); - } - expect(meridiemEl).toEqualText(expectedLocalizedMeridiem); + it("always displays hour in 12 hour format when nudging and no value is set", async () => { + const page = await newE2EPage({ + html: ``, + }); + const hour = await page.find(`calcite-time-picker >>> .${CSS.hour}`); + + await hour.click(); + + for (let i = 1; i < 24; i++) { + await page.keyboard.press("ArrowUp"); + await page.waitForChanges(); + + expect(hour).toEqualText(i > 12 ? formatTimePart(i - 12) : formatTimePart(i)); + } + + await page.keyboard.press("Delete"); + await page.waitForChanges(); + await page.keyboard.press("ArrowDown"); + + for (let i = 23; i > 0; i--) { + await page.keyboard.press("ArrowDown"); + await page.waitForChanges(); + + expect(hour).toEqualText(i > 12 ? formatTimePart(i - 12) : formatTimePart(i)); + } + }); }); - it("supports localized 24-hour format", async () => { - const initialDelocalizedValue = "14:02:30.001"; - const page = await newE2EPage(); - await page.setContent(html` - - `); - - const { - localizedHour: expectedLocalizedHour, - localizedHourSuffix: expectedLocalizedHourSuffix, - localizedMinute: expectedLocalizedMinute, - localizedMinuteSuffix: expectedLocalizedMinuteSuffix, - localizedSecond: expectedLocalizedSecond, - localizedSecondSuffix: expectedLocalizedSecondSuffix, - localizedDecimalSeparator: expectedLocalizedDecimalSeparator, - localizedFractionalSecond: expectedLocalizedFractionalSecond, - } = localizeTimeStringToParts({ - hour12: false, - value: initialDelocalizedValue, - locale, + describe(`hour-format="24"`, () => { + it("displays initial localized value correctly", async () => { + const initialDelocalizedValue = "14:02:30.001"; + const page = await newE2EPage(); + await page.setContent(html` + + `); + + const { + localizedHour: expectedLocalizedHour, + localizedHourSuffix: expectedLocalizedHourSuffix, + localizedMinute: expectedLocalizedMinute, + localizedMinuteSuffix: expectedLocalizedMinuteSuffix, + localizedSecond: expectedLocalizedSecond, + localizedSecondSuffix: expectedLocalizedSecondSuffix, + localizedDecimalSeparator: expectedLocalizedDecimalSeparator, + localizedFractionalSecond: expectedLocalizedFractionalSecond, + } = localizeTimeStringToParts({ + hour12: false, + value: initialDelocalizedValue, + locale, + }); + + const hourEl = await page.find(`calcite-time-picker >>> .${CSS.hour}`); + const hourSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.hourSuffix}`); + const minuteEl = await page.find(`calcite-time-picker >>> .${CSS.minute}`); + const minuteSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.minuteSuffix}`); + const secondEl = await page.find(`calcite-time-picker >>> .${CSS.second}`); + const decimalSeparatorEl = await page.find(`calcite-time-picker >>> .${CSS.decimalSeparator}`); + const fractionalSecondEl = await page.find(`calcite-time-picker >>> .${CSS.fractionalSecond}`); + const secondSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.secondSuffix}`); + const meridiemEl = await page.find(`calcite-time-picker >>> .${CSS.meridiem}`); + + expect(hourEl).toEqualText(expectedLocalizedHour); + expect(hourSuffixEl).toEqualText(expectedLocalizedHourSuffix); + expect(minuteEl).toEqualText(expectedLocalizedMinute); + expect(minuteSuffixEl).toEqualText(expectedLocalizedMinuteSuffix); + expect(secondEl).toEqualText(expectedLocalizedSecond); + expect(decimalSeparatorEl).toEqualText(expectedLocalizedDecimalSeparator); + expect(fractionalSecondEl).toEqualText(expectedLocalizedFractionalSecond); + if (secondSuffixEl) { + // Bulgarian is the only locale Calcite supports that has a known suffix after the seconds. + // Esri i18n prefers this character be removed for short time formats, which is the only format currently that time-picker supports. + // We're leaving this conditional check here in case a new locale is added in the future that might need to test the second suffix. + expect(secondSuffixEl).toEqualText(expectedLocalizedSecondSuffix); + } + expect(meridiemEl).toBeNull(); }); - const hourEl = await page.find(`calcite-time-picker >>> .${CSS.hour}`); - const hourSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.hourSuffix}`); - const minuteEl = await page.find(`calcite-time-picker >>> .${CSS.minute}`); - const minuteSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.minuteSuffix}`); - const secondEl = await page.find(`calcite-time-picker >>> .${CSS.second}`); - const decimalSeparatorEl = await page.find(`calcite-time-picker >>> .${CSS.decimalSeparator}`); - const fractionalSecondEl = await page.find(`calcite-time-picker >>> .${CSS.fractionalSecond}`); - const secondSuffixEl = await page.find(`calcite-time-picker >>> .${CSS.secondSuffix}`); - const meridiemEl = await page.find(`calcite-time-picker >>> .${CSS.meridiem}`); - - expect(hourEl).toEqualText(expectedLocalizedHour); - expect(hourSuffixEl).toEqualText(expectedLocalizedHourSuffix); - expect(minuteEl).toEqualText(expectedLocalizedMinute); - expect(minuteSuffixEl).toEqualText(expectedLocalizedMinuteSuffix); - expect(secondEl).toEqualText(expectedLocalizedSecond); - expect(decimalSeparatorEl).toEqualText(expectedLocalizedDecimalSeparator); - expect(fractionalSecondEl).toEqualText(expectedLocalizedFractionalSecond); - if (secondSuffixEl) { - // Bulgarian is the only locale Calcite supports that has a known suffix after the seconds. - // Esri i18n prefers this character be removed for short time formats, which is the only format currently that time-picker supports. - // We're leaving this conditional check here in case a new locale is added in the future that might need to test the second suffix. - expect(secondSuffixEl).toEqualText(expectedLocalizedSecondSuffix); - } - expect(meridiemEl).toBeNull(); + it("always displays hour in 24 hour format when nudging and no value is set", async () => { + const page = await newE2EPage({ + html: ``, + }); + const hour = await page.find(`calcite-time-picker >>> .${CSS.hour}`); + + await hour.click(); + + for (let i = 1; i < 24; i++) { + await page.keyboard.press("ArrowUp"); + await page.waitForChanges(); + + expect(hour).toEqualText(formatTimePart(i)); + } + + await page.keyboard.press("Delete"); + await page.waitForChanges(); + await page.keyboard.press("ArrowDown"); + + for (let i = 23; i > 0; i--) { + await page.keyboard.press("ArrowDown"); + await page.waitForChanges(); + + expect(hour).toEqualText(formatTimePart(i)); + } + }); }); }); }); diff --git a/packages/calcite-components/src/components/time-picker/time-picker.tsx b/packages/calcite-components/src/components/time-picker/time-picker.tsx index 910f40fec3d..0861ca6a8e6 100644 --- a/packages/calcite-components/src/components/time-picker/time-picker.tsx +++ b/packages/calcite-components/src/components/time-picker/time-picker.tsx @@ -777,6 +777,7 @@ export class TimePicker extends LitElement implements LoadableComponent { messages: { _lang: locale }, numberingSystem, } = this; + const hour12 = effectiveHourFormat === "12"; if (key === "meridiem") { this.meridiem = value as Meridiem; if (isValidNumber(this.hour)) { @@ -798,6 +799,7 @@ export class TimePicker extends LitElement implements LoadableComponent { part: "hour", locale, numberingSystem, + hour12, }); } } else if (key === "fractionalSecond") { @@ -813,6 +815,7 @@ export class TimePicker extends LitElement implements LoadableComponent { part: "fractionalSecond", locale, numberingSystem, + hour12, }); } else { this[key] = typeof value === "number" ? formatTimePart(value) : value; @@ -821,6 +824,7 @@ export class TimePicker extends LitElement implements LoadableComponent { part: key, locale, numberingSystem, + hour12, }); } let emit = false; @@ -842,7 +846,7 @@ export class TimePicker extends LitElement implements LoadableComponent { this.value = newValue; this.localizedMeridiem = this.value ? localizeTimeStringToParts({ - hour12: effectiveHourFormat === "12", + hour12, locale, numberingSystem, value: this.value, diff --git a/packages/calcite-components/src/custom-theme.stories.ts b/packages/calcite-components/src/custom-theme.stories.ts index 46a7dafa728..5b39ffafb7e 100644 --- a/packages/calcite-components/src/custom-theme.stories.ts +++ b/packages/calcite-components/src/custom-theme.stories.ts @@ -33,11 +33,12 @@ import { label, labelTokens } from "./custom-theme/label"; import { link, linkTokens } from "./custom-theme/link"; import { list, listTokens } from "./custom-theme/list"; import { loader, loaderTokens } from "./custom-theme/loader"; -import { notices } from "./custom-theme/notice"; +import { notice, noticeTokens } from "./custom-theme/notice"; import { pagination } from "./custom-theme/pagination"; import { popover, popoverTokens } from "./custom-theme/popover"; import { progress, progressTokens } from "./custom-theme/progress"; import { segmentedControl } from "./custom-theme/segmented-control"; +import { rating, ratingTokens } from "./custom-theme/rating"; import { slider, sliderTokens } from "./custom-theme/slider"; import { switchTokens } from "./custom-theme/switch"; import { tabs, tabsBordered, tabsTokens } from "./custom-theme/tabs"; @@ -48,6 +49,7 @@ import { navigationLogoTokens, navigationLogos } from "./custom-theme/navigation import { navigationUserTokens, navigationUsers } from "./custom-theme/navigation-user"; import { tileTokens, tile } from "./custom-theme/tile"; import { navigationTokens, navigation } from "./custom-theme/navigation"; +import { menuItem, menuItemTokens } from "./custom-theme/menu-item"; const globalTokens = { calciteColorBrand: "#007ac2", @@ -113,7 +115,7 @@ const kitchenSink = (args: Record, useTestValues = false) =>
- ${accordion} ${actionBar} ${autocomplete} ${notices} ${segmentedControl} + ${accordion} ${actionBar} ${autocomplete} ${notice} ${segmentedControl}
${actionPad}
${actionMenu}
@@ -133,8 +135,11 @@ const kitchenSink = (args: Record, useTestValues = false) => ${avatarInitials} ${avatarThumbnail} ${progress} ${handle} ${textArea} ${popover} ${tile} ${tooltip} ${comboboxItem}
-
${navigation} ${navigationLogos} ${navigationUsers} ${blockSection} ${block}
+
+ ${navigation} ${navigationLogos} ${navigationUsers} ${blockSection} ${block} ${rating} +
${alert}
+
${menuItem}
`; @@ -164,14 +169,17 @@ const componentTokens = { ...navigationLogoTokens, ...navigationTokens, ...navigationUserTokens, + ...noticeTokens, ...popoverTokens, ...progressTokens, + ...ratingTokens, ...sliderTokens, ...switchTokens, ...tabsTokens, ...textAreaTokens, ...tileTokens, ...tooltipTokens, + ...menuItemTokens, }; export default { diff --git a/packages/calcite-components/src/custom-theme/menu-item.ts b/packages/calcite-components/src/custom-theme/menu-item.ts new file mode 100644 index 00000000000..f7a5990f7fd --- /dev/null +++ b/packages/calcite-components/src/custom-theme/menu-item.ts @@ -0,0 +1,45 @@ +import { html } from "../../support/formatting"; + +export const menuItemTokens = { + calciteMenuItemAccentColor: "", + calciteMenuBackgroundColor: "", + calciteMenuItemSubMenuBorderColor: "", + calciteMenuItemSubMenuCornerRadius: "", + calciteMenuTextColor: "", +}; + +const menuHTML = (layout: string) => html` + + + + + + + + + + `; + +export const menuItem = html` ${menuHTML("horizontal")} ${menuHTML("vertical")} `; diff --git a/packages/calcite-components/src/custom-theme/notice.ts b/packages/calcite-components/src/custom-theme/notice.ts index e59eb3f3810..17bc1e56f7d 100644 --- a/packages/calcite-components/src/custom-theme/notice.ts +++ b/packages/calcite-components/src/custom-theme/notice.ts @@ -1,19 +1,15 @@ import { html } from "../../support/formatting"; -export const notice = ({ kind, message, title }: { kind: string; message: string; title: string }): string => - html` -
${title}
-
${message}
- ${kind === "danger" ? html`Retry` : null} -
`; +export const noticeTokens = { + calciteNoticeBackgroundColor: "", + calciteNoticeCloseBackgroundColorFocus: "", + calciteNoticeCloseBackgroundColorPress: "", + calciteNoticeCloseTextColorHover: "", + calciteNoticeCloseTextColor: "", + calciteNoticeContentTextColor: "", +}; -export const notices = html`${notice({ - kind: "danger", - message: "There was an error while performing the task.", - title: "Something failed", -})} -${notice({ - kind: "success", - message: "That thing you wanted to do worked as expected", - title: "Something worked", -})}`; +export const notice = html` +
Something worked
+
That thing you wanted to do worked as expected
+
`; diff --git a/packages/calcite-components/src/custom-theme/rating.ts b/packages/calcite-components/src/custom-theme/rating.ts new file mode 100644 index 00000000000..656c2eb2c83 --- /dev/null +++ b/packages/calcite-components/src/custom-theme/rating.ts @@ -0,0 +1,12 @@ +import { html } from "../../support/formatting"; + +export const ratingTokens = { + calciteRatingSpacing: "", + calciteRatingColorHover: "", + calciteRatingColor: "", + calciteRatingAverageColor: "", + calciteRatingAverageTextColor: "", + calciteRatingCountTextColor: "", +}; + +export const rating = html``; diff --git a/packages/calcite-components/src/tests/commonTests/themed.ts b/packages/calcite-components/src/tests/commonTests/themed.ts index b9823e7f2cb..05ad1c14519 100644 --- a/packages/calcite-components/src/tests/commonTests/themed.ts +++ b/packages/calcite-components/src/tests/commonTests/themed.ts @@ -4,7 +4,7 @@ import type { RequireExactlyOne } from "type-fest"; import { E2EPage, E2EElement } from "@arcgis/lumina-compiler/puppeteerTesting"; import { expect, it } from "vitest"; import { getTokenValue } from "../utils/cssTokenValues"; -import { toElementHandle } from "../utils"; +import { skipAnimations, toElementHandle } from "../utils"; import type { ComponentTestSetup } from "./interfaces"; import { getTagAndPage } from "./utils"; @@ -75,6 +75,7 @@ export type ComponentTestTokens = Record { const { page, tag } = await getTagAndPage(componentTestSetup); + await skipAnimations(page); await page.evaluate(() => { // we block all clicks to prevent triggering behavior as mouse states are activated between assertions document.addEventListener( @@ -274,29 +275,29 @@ async function assertThemedProps(page: E2EPage, options: TestTarget): Promise { const searchInShadowDom = (node: Node): HTMLElement | SVGElement | Node | undefined => { - const { attribute, value } = context as { + const { attribute, value: valueToMatch } = context as { attribute: string; value: string; }; - if (node.nodeType === 1) { - const attr = (node as Element).getAttribute(attribute); - if (typeof value === "string" && attr === value) { - return node; - } - if (attr === value) { - return node; - } - if ((node as Element) && !attribute && !value) { - return node; + if (node.nodeType === 1) { + const el = node as Element; + const attrValue = el.getAttribute(attribute); + + if ( + (attribute === "class" && el.classList.contains(valueToMatch)) || + (attrValue === valueToMatch) || + (!attribute && !valueToMatch) + ) { + return el; } - } - if (node.nodeType === 1 && (node as Element).shadowRoot) { - for (const child of (node as Element).shadowRoot.children) { - const result = searchInShadowDom(child); - if (result) { - return result; + if (el.shadowRoot) { + for (const child of el.shadowRoot.children) { + const result = searchInShadowDom(child); + if (result) { + return result; + } } } } @@ -308,6 +309,7 @@ async function assertThemedProps(page: E2EPage, options: TestTarget): Promise((resolve) => { requestAnimationFrame(() => { const foundNode = diff --git a/packages/calcite-components/src/tests/utils/cssTokenValues.ts b/packages/calcite-components/src/tests/utils/cssTokenValues.ts index 42d3990fc7e..10b23f944d1 100644 --- a/packages/calcite-components/src/tests/utils/cssTokenValues.ts +++ b/packages/calcite-components/src/tests/utils/cssTokenValues.ts @@ -7,6 +7,7 @@ */ export function getTokenValue(token: string): string { const tokenValueMap = { + spacing: "42px", // granular patterns for the same token must be listed first to match correctly background$: "rgb(252, 244, 52)", "text-color$": "rgb(239, 118, 39)", diff --git a/packages/calcite-components/src/utils/text.tsx b/packages/calcite-components/src/utils/text.tsx index 111c4bf5a7b..e53081816a3 100644 --- a/packages/calcite-components/src/utils/text.tsx +++ b/packages/calcite-components/src/utils/text.tsx @@ -1,5 +1,17 @@ import { h, JsxNode } from "@arcgis/lumina"; +const CSS = { + textMatch: "text-match", +}; + +/** + * Highlight text based on a search pattern. + * + * Items using this in their rendering should include the `text-highlight-item` mixin from `includes.scss` in their styles. + * + * @param text + * @param pattern + */ export function highlightText({ text, pattern, @@ -15,7 +27,7 @@ export function highlightText({ if (parts.length > 1) { // we only highlight the first match - parts[1] = {parts[1]}; + parts[1] = {parts[1]}; } return parts; diff --git a/packages/calcite-components/src/utils/time.ts b/packages/calcite-components/src/utils/time.ts index 80c15c012f5..907ceef7fc5 100644 --- a/packages/calcite-components/src/utils/time.ts +++ b/packages/calcite-components/src/utils/time.ts @@ -310,6 +310,7 @@ interface LocalizeTimePartParameters { part: TimePart; locale: SupportedLocale; numberingSystem?: NumberingSystem; + hour12?: boolean; } export function localizeTimePart({ @@ -317,6 +318,7 @@ export function localizeTimePart({ part, locale, numberingSystem = "latn", + hour12, }: LocalizeTimePartParameters): string { if (part === "fractionalSecond") { const localizedDecimalSeparator = getLocalizedDecimalSeparator(locale, numberingSystem); @@ -358,7 +360,7 @@ export function localizeTimePart({ if (!date) { return; } - const formatter = createLocaleDateTimeFormatter({ locale, numberingSystem }); + const formatter = createLocaleDateTimeFormatter({ hour12, locale, numberingSystem }); const parts = formatter.formatToParts(date); return getLocalizedTimePart(part, parts); } diff --git a/packages/calcite-components/support/generateT9nDocsJSON.ts b/packages/calcite-components/support/generateT9nDocsJSON.ts index 0a75052b505..9427cb7ec13 100755 --- a/packages/calcite-components/support/generateT9nDocsJSON.ts +++ b/packages/calcite-components/support/generateT9nDocsJSON.ts @@ -24,7 +24,7 @@ Object.keys(messagesFileMain).forEach((key) => (data[component][key] = {})); const messagesFilenames = (await readdir(t9nPath, { withFileTypes: true })).map((dirent) => dirent.name); - const messagesFilenameRegex = new RegExp(`${component}\\.t9n\\.(.*)\\.json`); + const messagesFilenameRegex = new RegExp(`messages\\.(.*)\\.json`); for (const messagesFilename of messagesFilenames) { const messagesFilenameMatch = messagesFilename.match(messagesFilenameRegex); diff --git a/packages/calcite-design-tokens/CHANGELOG.md b/packages/calcite-design-tokens/CHANGELOG.md index b9ef32afc1f..7a61de4a67a 100644 --- a/packages/calcite-design-tokens/CHANGELOG.md +++ b/packages/calcite-design-tokens/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.5](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-design-tokens@3.0.0-next.4...@esri/calcite-design-tokens@3.0.0-next.5) (2025-01-04) + +**Note:** Version bump only for package @esri/calcite-design-tokens + ## [3.0.0-next.4](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-design-tokens@3.0.0-next.3...@esri/calcite-design-tokens@3.0.0-next.4) (2025-01-01) **Note:** Version bump only for package @esri/calcite-design-tokens diff --git a/packages/calcite-design-tokens/LICENSE.md b/packages/calcite-design-tokens/LICENSE.md index 1235786306c..37d072da0e3 100644 --- a/packages/calcite-design-tokens/LICENSE.md +++ b/packages/calcite-design-tokens/LICENSE.md @@ -1,6 +1,6 @@ # Licensing -COPYRIGHT © 2024 Esri +COPYRIGHT © 2025 Esri All rights reserved under the copyright laws of the United States and applicable international laws, treaties, and conventions. diff --git a/packages/calcite-design-tokens/package.json b/packages/calcite-design-tokens/package.json index c2b928e6ed6..d9bb729eec0 100644 --- a/packages/calcite-design-tokens/package.json +++ b/packages/calcite-design-tokens/package.json @@ -1,6 +1,6 @@ { "name": "@esri/calcite-design-tokens", - "version": "3.0.0-next.4", + "version": "3.0.0-next.5", "description": "Esri's Calcite Design System Tokens", "keywords": [ "Calcite", diff --git a/packages/calcite-ui-icons/CHANGELOG.md b/packages/calcite-ui-icons/CHANGELOG.md index 7bcc7199b9b..5e6adc07766 100644 --- a/packages/calcite-ui-icons/CHANGELOG.md +++ b/packages/calcite-ui-icons/CHANGELOG.md @@ -3,6 +3,16 @@ 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.7](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-ui-icons@4.0.0-next.6...@esri/calcite-ui-icons@4.0.0-next.7) (2025-01-04) + +**Note:** Version bump only for package @esri/calcite-ui-icons + +## [4.0.0-next.6](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-ui-icons@4.0.0-next.5...@esri/calcite-ui-icons@4.0.0-next.6) (2025-01-03) + +### Performance Improvements + +- speed up build-fonts script ([#11196](https://github.com/Esri/calcite-design-system/issues/11196)) ([c7e3071](https://github.com/Esri/calcite-design-system/commit/c7e30714c9a7943be105d5e88fcac6443629fd12)) + ## [4.0.0-next.5](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-ui-icons@4.0.0-next.4...@esri/calcite-ui-icons@4.0.0-next.5) (2025-01-02) ### Features diff --git a/packages/calcite-ui-icons/LICENSE.md b/packages/calcite-ui-icons/LICENSE.md index 1235786306c..37d072da0e3 100644 --- a/packages/calcite-ui-icons/LICENSE.md +++ b/packages/calcite-ui-icons/LICENSE.md @@ -1,6 +1,6 @@ # Licensing -COPYRIGHT © 2024 Esri +COPYRIGHT © 2025 Esri All rights reserved under the copyright laws of the United States and applicable international laws, treaties, and conventions. diff --git a/packages/calcite-ui-icons/bin/build-fonts.js b/packages/calcite-ui-icons/bin/build-fonts.js new file mode 100755 index 00000000000..46b551eef06 --- /dev/null +++ b/packages/calcite-ui-icons/bin/build-fonts.js @@ -0,0 +1,78 @@ +#!/usr/bin/env node +const { execSync } = require('child_process'); +const { + readdirSync, + mkdirSync, + rmSync, + existsSync, + lstatSync, + symlinkSync, + unlinkSync, + readFileSync, + writeFileSync, + } = require('fs'); +const { join, basename } = require('path'); +const prettier = require('@prettier/sync'); + +const SCRIPT_DIR = __dirname; +const PACKAGE_ROOT = join(SCRIPT_DIR, '..'); +const fontsDir = join(PACKAGE_ROOT, 'fonts/icons'); +const iconsDir = join(PACKAGE_ROOT, 'icons'); + +const sizes = [16, 24, 32]; +const ensureDir = (dir) => mkdirSync(dir, { recursive: true }); +const clearAndPrepareDirs = () => { + if (existsSync(fontsDir)) { + rmSync(fontsDir, { recursive: true, force: true }); + } + sizes.forEach((size) => ensureDir(join(fontsDir, size.toString()))); +}; + +const filterIcons = () => + readdirSync(iconsDir).filter((file) => { + const filePath = join(iconsDir, file); + return file.endsWith('.svg') && !readFileSync(filePath, 'utf8').includes('opacity'); + }); + +const createLinks = (icons) => { + icons.forEach((icon) => { + const src = join(iconsDir, icon); + const dest = join(fontsDir, basename(icon)); + symlinkSync(src, dest); + }); +}; + +const organizeIconsBySize = (size) => { + const sizeDir = join(fontsDir, size.toString()); + readdirSync(fontsDir).forEach((file) => { + if (file.includes(`-${size}`)) { + const src = join(fontsDir, file); + const dest = join(sizeDir, file.replace(`-${size}`, '')); + if (lstatSync(src).isSymbolicLink()) { + if (existsSync(dest)) unlinkSync(dest); + symlinkSync(src, dest); + } + } + }); +}; + +const generateFonts = (size) => + execSync(`fantasticon fonts/icons/${size}/ -n calcite-ui-icons-${size} --normalize true -t ttf -g json -o fonts/`, { + stdio: 'inherit', + }); + +const updateConfig = () => { + const codepoints = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'fonts/calcite-ui-icons-16.json'), 'utf8')); + const config = prettier.format(JSON.stringify({ codepoints }), { parser: 'json' }); + writeFileSync(join(PACKAGE_ROOT, 'fantasticonrc.json'), config); +}; + +const main = () => { + clearAndPrepareDirs(); + createLinks(filterIcons()); + sizes.forEach(organizeIconsBySize); + sizes.forEach(generateFonts); + updateConfig(); +}; + +main(); diff --git a/packages/calcite-ui-icons/bin/build-fonts.sh b/packages/calcite-ui-icons/bin/build-fonts.sh deleted file mode 100755 index 134cfa1fa73..00000000000 --- a/packages/calcite-ui-icons/bin/build-fonts.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -# find the directory this script lives in and cd to its parent (the package root) -SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) -cd "$(dirname "$SCRIPT_DIR")" || exit - -# remove and remake the intermediary font icons directories -rm -rf fonts/icons/ -mkdir -p fonts/icons/{16,24,32}/ - -# filter out icons with opacity and create hardlinks in the intermediary directory -grep -LF opacity icons/*.svg | xargs -I{} ln {} fonts/icons/ - -cd fonts/icons || exit - -# separate the icons into subdirectories by size and remove the size from the filenames -for file in ./*-16{-f,}.svg; do mv "$file" "16/${file/-16/}"; done -for file in ./*-24{-f,}.svg; do mv "$file" "24/${file/-24/}"; done -for file in ./*-32{-f,}.svg; do mv "$file" "32/${file/-32/}"; done - -cd ../.. || exit - -# create a separate font file for each icon size -fantasticon fonts/icons/16/ -n calcite-ui-icons-16 --normalize true -t ttf -g json -o fonts/ -fantasticon fonts/icons/24/ -n calcite-ui-icons-24 --normalize true -t ttf -g json -o fonts/ -fantasticon fonts/icons/32/ -n calcite-ui-icons-32 --normalize true -t ttf -g json -o fonts/ - -# sync the generated codepoints back to the config file (only changes when adding new icons) -# -# NOTE: assumes `codepoints` is the only field used in the config file. If that changes, -# migrate to a Node script to parse the JSON and replace the `codepoints` value -prettier --parser json --write >./fantasticonrc.json <<<"{\"codepoints\": $( - # the codepoints are the same for all sizes (picked 16 arbitrarily) - cat fonts/calcite-ui-icons-16.json -)}" diff --git a/packages/calcite-ui-icons/fantasticonrc.json b/packages/calcite-ui-icons/fantasticonrc.json index 6452ff8548d..c7dfd1a98d8 100644 --- a/packages/calcite-ui-icons/fantasticonrc.json +++ b/packages/calcite-ui-icons/fantasticonrc.json @@ -1156,6 +1156,37 @@ "tree": 60289, "water-drop": 60290, "white-cursor-selection": 60291, - "wind": 60292 + "wind": 60292, + "uncollapse-relationships": 61697, + "uncollapse-entities": 61698, + "single-timeline": 61699, + "show-link-chart-root-nodes": 61700, + "show-link-chart-nonspatial-data": 61701, + "show-data": 61702, + "select-root-chart-nodes": 61703, + "select-nonspatial-data": 61704, + "plug-connection": 61705, + "multi-timeline": 61706, + "link-chart-tools": 61707, + "link-chart-sync-selection": 61708, + "link-chart-select-between": 61709, + "link-chart-find-between": 61710, + "link-chart-connect": 61711, + "link-chart-connect-from": 61712, + "link-chart-connect-between": 61713, + "link-chart-collapse-ends": 61714, + "link-chart-centrality": 61715, + "link-chart-apply-to": 61716, + "hide-link-chart-root-nodes": 61717, + "hide-link-chart-nonspatial-data": 61718, + "hide-data": 61719, + "find-add-path": 61720, + "filtered-find-add-path": 61721, + "editing-trim-to-length": 61722, + "community-detection": 61723, + "collapse-relationships": 61724, + "collapse-entities": 61725, + "cluster-radius": 61726, + "add-link-chart-root-nodes": 61727 } } diff --git a/packages/calcite-ui-icons/package.json b/packages/calcite-ui-icons/package.json index 6597a177063..fde28c1711d 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.5", + "version": "4.0.0-next.7", "private": false, "description": "A collection of UI SVG icons created by Esri for applications.", "keywords": [ @@ -42,7 +42,7 @@ "scripts": { "build": "node bin/cli.js", "postbuild": "npm run build:sprite && npm run build:fonts", - "build:fonts": "bin/build-fonts.sh || true", + "build:fonts": "bin/build-fonts.js || true", "build:sprite": "concurrently npm:build:sprite-*", "build:sprite-16": "svgstore -o sprite-16.svg icons/*-16*.svg", "build:sprite-24": "svgstore -o sprite-24.svg icons/*-24*.svg", diff --git a/packages/eslint-plugin-calcite-components/CHANGELOG.md b/packages/eslint-plugin-calcite-components/CHANGELOG.md index 5ea8ec73e6a..645afe6034c 100644 --- a/packages/eslint-plugin-calcite-components/CHANGELOG.md +++ b/packages/eslint-plugin-calcite-components/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. +## [2.0.0-next.4](https://github.com/Esri/calcite-design-system/compare/@esri/eslint-plugin-calcite-components@2.0.0-next.3...@esri/eslint-plugin-calcite-components@2.0.0-next.4) (2025-01-04) + +**Note:** Version bump only for package @esri/eslint-plugin-calcite-components + ## [2.0.0-next.3](https://github.com/Esri/calcite-design-system/compare/@esri/eslint-plugin-calcite-components@2.0.0-next.2...@esri/eslint-plugin-calcite-components@2.0.0-next.3) (2025-01-01) **Note:** Version bump only for package @esri/eslint-plugin-calcite-components diff --git a/packages/eslint-plugin-calcite-components/LICENSE.md b/packages/eslint-plugin-calcite-components/LICENSE.md index 1235786306c..37d072da0e3 100644 --- a/packages/eslint-plugin-calcite-components/LICENSE.md +++ b/packages/eslint-plugin-calcite-components/LICENSE.md @@ -1,6 +1,6 @@ # Licensing -COPYRIGHT © 2024 Esri +COPYRIGHT © 2025 Esri All rights reserved under the copyright laws of the United States and applicable international laws, treaties, and conventions. diff --git a/packages/eslint-plugin-calcite-components/README.md b/packages/eslint-plugin-calcite-components/README.md index 71390be35af..3d515c79e07 100644 --- a/packages/eslint-plugin-calcite-components/README.md +++ b/packages/eslint-plugin-calcite-components/README.md @@ -59,7 +59,7 @@ We welcome contributions to this project. See [CONTRIBUTING.md](./CONTRIBUTING.m ## License -COPYRIGHT © 2024 Esri +COPYRIGHT © 2025 Esri All rights reserved under the copyright laws of the United States and applicable international laws, treaties, and conventions. diff --git a/packages/eslint-plugin-calcite-components/package.json b/packages/eslint-plugin-calcite-components/package.json index 3cb33d23a2c..66242e1bdb8 100644 --- a/packages/eslint-plugin-calcite-components/package.json +++ b/packages/eslint-plugin-calcite-components/package.json @@ -1,6 +1,6 @@ { "name": "@esri/eslint-plugin-calcite-components", - "version": "2.0.0-next.3", + "version": "2.0.0-next.4", "description": "ESLint rules for @esri/calcite-components", "repository": { "type": "git", diff --git a/readme.md b/readme.md index 006a5b076ba..c6dd6403ac5 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,7 @@ We welcome contributions to this project. See [CONTRIBUTING.md](./CONTRIBUTING.m ## License -COPYRIGHT © 2024 Esri +COPYRIGHT © 2025 Esri All rights reserved under the copyright laws of the United States and applicable international laws, treaties, and conventions.