diff --git a/.github/actions/yarn-install/action.yml b/.github/actions/yarn-install/action.yml deleted file mode 100644 index 0918e772557d..000000000000 --- a/.github/actions/yarn-install/action.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: 'Installing Yarn dependencies' -description: 'Installs the dependencies using Yarn' - -runs: - using: 'composite' - steps: - - uses: actions/cache@v2 - with: - path: | - ./node_modules/ - # Cache key. Whenever the postinstall patches change, the cache needs to be invalidated. - # If just the `yarn.lock` file changes, the most recent cache can be restored though. - # See: https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#example-using-the-cache-action. - key: v4-${{hashFiles('tools/postinstall/apply-patches.js')}}-${{hashFiles('yarn.lock')}} - restore-keys: v4-${{hashFiles('tools/postinstall/apply-patches.js')}}- - - - run: yarn install --frozen-lockfile --non-interactive - shell: bash diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 44f762d99a2d..257d553f73df 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -16,6 +16,6 @@ jobs: - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@fb30926790c6225d553b91a4818cab2fdde4fb4e + - uses: angular/dev-infra/github-actions/branch-manager@e0ec7b60641d7f6369be45d8d02663fd50f320be with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci-privileged.yml b/.github/workflows/ci-privileged.yml index 813840ee71ca..9a6096e29663 100644 --- a/.github/workflows/ci-privileged.yml +++ b/.github/workflows/ci-privileged.yml @@ -26,7 +26,7 @@ jobs: CI_RUNNER_NUMBER: ${{ github.run_id }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ba9b4487ced515e5b4d87edd681a3bd9792444d6 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true # Checking out the pull request commit is intended here as we need to run the changed code tests. @@ -34,7 +34,7 @@ jobs: - name: Install node modules run: yarn install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@ba9b4487ced515e5b4d87edd681a3bd9792444d6 + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Run tests on Saucelabs run: ./scripts/circleci/run-saucelabs-tests.sh @@ -48,7 +48,7 @@ jobs: CI_RUNNER_NUMBER: ${{ github.run_id }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@ba9b4487ced515e5b4d87edd681a3bd9792444d6 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true # Checking out the pull request commit is intended here as we need to run the changed code tests. @@ -56,6 +56,6 @@ jobs: - name: Install node modules run: yarn install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@ba9b4487ced515e5b4d87edd681a3bd9792444d6 + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Run tests on Browserstack run: ./scripts/circleci/run-browserstack-tests.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea37f8960350..3c0fcede5ee2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Install node modules @@ -66,13 +66,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Check API Goldens @@ -87,13 +87,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Run e2e tests @@ -108,13 +108,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Run integration tests @@ -132,13 +132,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Run linker AOT tests @@ -153,13 +153,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Run linker JIT tests @@ -174,13 +174,13 @@ jobs: runs-on: ubuntu-latest-16core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Run tests @@ -195,13 +195,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Run tests @@ -217,13 +217,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Build and Verify Release Output @@ -249,13 +249,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Build and Verify Release Output @@ -275,13 +275,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@9931e1a8d1b62fcd2267e89f9993a494856cc1cd + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Install node modules run: yarn install --frozen-lockfile - name: Build and Verify Release Output diff --git a/.github/workflows/deploy-dev-app-main-push.yml b/.github/workflows/deploy-dev-app-main-push.yml new file mode 100644 index 000000000000..1b0dc434202a --- /dev/null +++ b/.github/workflows/deploy-dev-app-main-push.yml @@ -0,0 +1,59 @@ +name: Deploying dev-app to Firebase [main push]. + +on: + push: + branches: [main] + +permissions: + deployments: write + +env: + PREVIEW_PROJECT: ng-dev-previews + PREVIEW_SITE: ng-comp-devapp + PREVIEW_CHANNEL: live + +jobs: + deploy-material2-dev: + runs-on: ubuntu-latest + steps: + - name: Initialize environment + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be + with: + cache-node-modules: true + - name: Setup Bazel + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be + - name: Setup Bazel RBE + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be + + - name: Building dev-app + run: | + yarn -s bazel build //src/dev-app:web_package --symlink_prefix=dist/ + cp -R dist/bin/src/dev-app/web_package dist/dev-app-web-pkg + + - name: Configure Firebase deploy target + run: | + # We can use `npx` as the Firebase deploy actions uses it too. + npx -y firebase-tools@latest target:clear --project ${{env.PREVIEW_PROJECT}} hosting dev-app + npx -y firebase-tools@latest target:apply --project ${{env.PREVIEW_PROJECT}} hosting dev-app ${{env.PREVIEW_SITE}} + + - uses: FirebaseExtended/action-hosting-deploy@638d3c162747cead0c1c0d3093208ed59dfd8231 # v0 + id: deploy + with: + # Note: No token used here as the action otherwise may attempt to post a comment. + repoToken: '' + firebaseServiceAccount: '${{secrets.FIREBASE_PREVIEW_SERVICE_TOKEN}}' + projectId: '${{env.PREVIEW_PROJECT}}' + entryPoint: './' + channelId: '${{env.PREVIEW_CHANNEL}}' + + - name: Result + run: | + echo "Deployed to: ${{steps.deploy.outputs.details_url}}" + + - name: Deployment Status + uses: zattoo/deploy-status@c8a0267e54a90ea07765fa88f7c7c35171859eec # v1 + with: + token: '${{github.token}}' + environment: 'dev' + environment_url: '${{steps.deploy.outputs.details_url}}' + state: success diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 6e26d0c1b30b..94ed12fb63c8 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -12,13 +12,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2 - - uses: angular/dev-infra/github-actions/commit-message-based-labels@fb30926790c6225d553b91a4818cab2fdde4fb4e + - uses: angular/dev-infra/github-actions/commit-message-based-labels@e0ec7b60641d7f6369be45d8d02663fd50f320be with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: runs-on: ubuntu-latest steps: - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2 - - uses: angular/dev-infra/github-actions/post-approval-changes@fb30926790c6225d553b91a4818cab2fdde4fb4e + - uses: angular/dev-infra/github-actions/post-approval-changes@e0ec7b60641d7f6369be45d8d02663fd50f320be with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/google-internal-tests.yml b/.github/workflows/google-internal-tests.yml index e00505ac7bbf..a8bfc770f29c 100644 --- a/.github/workflows/google-internal-tests.yml +++ b/.github/workflows/google-internal-tests.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0 - - uses: angular/dev-infra/github-actions/google-internal-tests@fb30926790c6225d553b91a4818cab2fdde4fb4e + - uses: angular/dev-infra/github-actions/google-internal-tests@e0ec7b60641d7f6369be45d8d02663fd50f320be with: run-tests-guide-url: http://go/angular-material-presubmit github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build-dev-app.yml b/.github/workflows/preview-build-dev-app.yml similarity index 68% rename from .github/workflows/build-dev-app.yml rename to .github/workflows/preview-build-dev-app.yml index f80a4853b9ac..1ff3e3abfe66 100644 --- a/.github/workflows/build-dev-app.yml +++ b/.github/workflows/preview-build-dev-app.yml @@ -22,19 +22,19 @@ jobs: (github.event.action == 'labeled' && github.event.label.name == 'dev-app preview') || (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'dev-app preview')) steps: - - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # renovate: tag=v2.0.0 - - uses: ./.github/actions/yarn-install - - - uses: angular/dev-infra/github-actions/setup-bazel-remote-exec@fb30926790c6225d553b91a4818cab2fdde4fb4e + - name: Initialize environment + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: - bazelrc: ./.bazelrc.user + cache-node-modules: true + - name: Setup Bazel + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be + - name: Setup Bazel RBE + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - # Build the web package. Note: We run Bazel from a low-resource Github action container, - # so we manually need to instruct Bazel to run more actions concurrently as by default - # the number of concurrent actions is determined based on the host resources. - - run: bazel build //src/dev-app:web_package --symlink_prefix=dist/ --jobs=32 + # Build the web package + - run: bazel build //src/dev-app:web_package --symlink_prefix=dist/ - - uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@fb30926790c6225d553b91a4818cab2fdde4fb4e + - uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@e0ec7b60641d7f6369be45d8d02663fd50f320be with: workflow-artifact-name: 'dev-app' pull-number: '${{github.event.pull_request.number}}' diff --git a/.github/workflows/deploy-dev-app.yml b/.github/workflows/preview-deploy-dev-app.yml similarity index 96% rename from .github/workflows/deploy-dev-app.yml rename to .github/workflows/preview-deploy-dev-app.yml index 7e67ac7b1f48..8c78838cfe5d 100644 --- a/.github/workflows/deploy-dev-app.yml +++ b/.github/workflows/preview-deploy-dev-app.yml @@ -33,7 +33,7 @@ jobs: npx -y firebase-tools@latest target:clear --project ${{env.PREVIEW_PROJECT}} hosting dev-app npx -y firebase-tools@latest target:apply --project ${{env.PREVIEW_PROJECT}} hosting dev-app ${{env.PREVIEW_SITE}} - - uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@fb30926790c6225d553b91a4818cab2fdde4fb4e + - uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@e0ec7b60641d7f6369be45d8d02663fd50f320be with: github-token: '${{secrets.GITHUB_TOKEN}}' workflow-artifact-name: 'dev-app' diff --git a/.github/workflows/scheduled-ci.yml b/.github/workflows/scheduled-ci.yml index 1511336bb7e4..4562fee6d538 100644 --- a/.github/workflows/scheduled-ci.yml +++ b/.github/workflows/scheduled-ci.yml @@ -19,13 +19,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setting up Angular snapshot builds # Angular snapshots must be set up first so that the yarn install properly # updates the yarn.lock as expected with the changes @@ -44,13 +44,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setting up Angular snapshot builds # Angular snapshots must be set up first so that the yarn install properly # updates the yarn.lock as expected with the changes @@ -71,13 +71,13 @@ jobs: runs-on: ubuntu-latest-4core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/setup@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/bazel/configure-remote@e0ec7b60641d7f6369be45d8d02663fd50f320be - name: Setting up Angular snapshot builds # Angular snapshots must be set up first so that the yarn install properly # updates the yarn.lock as expected with the changes @@ -98,7 +98,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fb30926790c6225d553b91a4818cab2fdde4fb4e + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e0ec7b60641d7f6369be45d8d02663fd50f320be with: cache-node-modules: true - name: Install node modules diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b68efd95052..81a39ffd2399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,41 @@ + +# 17.0.0-rc.3 "vandium-vest" (2023-11-06) +### cdk +| Commit | Type | Description | +| -- | -- | -- | +| [c0b38dede](https://github.com/angular/components/commit/c0b38dede8806629a7c9c5319c707aaeedd6812c) | perf | **a11y:** Don't trigger re-layout when detecting fake mousedown ([#28029](https://github.com/angular/components/pull/28029)) | +### material +| Commit | Type | Description | +| -- | -- | -- | +| [157c0e28f](https://github.com/angular/components/commit/157c0e28f7c8170433fafcd57cc70fb63cc57ff4) | fix | **schematics:** asyncPipe not imported but used in the template ([#28055](https://github.com/angular/components/pull/28055)) | + + + + +# 17.0.0-rc.2 "beryllium-brilliance" (2023-11-01) +### cdk +| Commit | Type | Description | +| -- | -- | -- | +| [b361de136b](https://github.com/angular/components/commit/b361de136b40377ce07430f9f2cf8111ffd300ca) | fix | **accordion:** add `CDK_ACCORDION` export ([#27981](https://github.com/angular/components/pull/27981)) | +### material +| Commit | Type | Description | +| -- | -- | -- | +| [fcaa95e695](https://github.com/angular/components/commit/fcaa95e6955d05773037650f48eb50efc445b24c) | fix | **core:** prevent updates to v17 if project uses legacy components ([#28024](https://github.com/angular/components/pull/28024)) | +| [c4a62a884f](https://github.com/angular/components/commit/c4a62a884f9eabeacdfd299a91deccc9003fc34c) | fix | **dialog:** MatDialog: change member _dialog (cdk) from private to protected ([#28019](https://github.com/angular/components/pull/28019)) ([#28020](https://github.com/angular/components/pull/28020)) | +| [7a42a5de98](https://github.com/angular/components/commit/7a42a5de9888fcd2dc459c3887a167860d0726fd) | fix | **schematics:** account for browser-esbuild builder ([#28025](https://github.com/angular/components/pull/28025)) | +| [9fe4fe1f54](https://github.com/angular/components/commit/9fe4fe1f54f8dab72d4291e2dbee96dc8ade62b6) | fix | **schematics:** don't add the preconnect for fonts ([#28026](https://github.com/angular/components/pull/28026)) | + + + + +# 16.2.11 "fabric-fantasy" (2023-11-01) +### cdk +| Commit | Type | Description | +| -- | -- | -- | +| [2f468f1606](https://github.com/angular/components/commit/2f468f160604a50141048afe75c829bc6b8c85b1) | fix | **accordion:** add `CDK_ACCORDION` export ([#27981](https://github.com/angular/components/pull/27981)) | + + + # 16.2.10 "plaster-pineapple" (2023-10-25) ### material diff --git a/guides/creating-a-custom-stepper-using-the-cdk-stepper.md b/guides/creating-a-custom-stepper-using-the-cdk-stepper.md index 615f241950dd..c116bfb92f40 100644 --- a/guides/creating-a-custom-stepper-using-the-cdk-stepper.md +++ b/guides/creating-a-custom-stepper-using-the-cdk-stepper.md @@ -45,14 +45,11 @@ This is the HTML template of our custom stepper component: @@ -117,9 +114,11 @@ If you want to iterate over your steps and use your own custom component you can ```html - - - + @for (step of mySteps; track step) { + + + + } ``` diff --git a/guides/v15-mdc-migration.md b/guides/v15-mdc-migration.md index df3b2f415452..5f4663b1f151 100644 --- a/guides/v15-mdc-migration.md +++ b/guides/v15-mdc-migration.md @@ -1,6 +1,6 @@ # Migrating to MDC-based Angular Material Components -In Angular Material v15, many of the components have been refactored to be based on the official +In Angular Material v15 and later, many of the components have been refactored to be based on the official [Material Design Components for Web (MDC)](https://github.com/material-components/material-components-web). The components from the following imports have been refactored: @@ -81,22 +81,22 @@ practices before migrating. component. Using component harnesses makes your tests easier to understand and more robust to changes in Angular Material -### 1. Update to Angular Material v15 +### 1. Update to Angular Material v16 Angular Material includes a schematic to help migrate applications to use the new MDC-based -components. To get started, upgrade your application to Angular Material 15. +components. To get started, upgrade your application to Angular Material 16. ```shell -ng update @angular/material@15 +ng update @angular/material@16 ``` As part of this update, a schematic will run to automatically move your application to use the "legacy" imports containing the old component implementations. This provides a quick path to getting -your application running on v15 with minimal manual changes. +your application running on v16 with minimal manual changes. ### 2. Run the migration tool -After upgrading to v15, you can run the migration tool to switch from the legacy component +After upgrading to v16, you can run the migration tool to switch from the legacy component implementations to the new MDC-based ones. ```shell diff --git a/package.json b/package.json index 72c9dcdf9c69..639e1971d88e 100644 --- a/package.json +++ b/package.json @@ -57,12 +57,12 @@ }, "version": "17.1.0-next.0", "dependencies": { - "@angular/animations": "^17.0.0-rc.0", - "@angular/common": "^17.0.0-rc.0", - "@angular/compiler": "^17.0.0-rc.0", - "@angular/core": "^17.0.0-rc.0", - "@angular/forms": "^17.0.0-rc.0", - "@angular/platform-browser": "^17.0.0-rc.0", + "@angular/animations": "^17.0.0-rc.2", + "@angular/common": "^17.0.0-rc.2", + "@angular/compiler": "^17.0.0-rc.2", + "@angular/core": "^17.0.0-rc.2", + "@angular/forms": "^17.0.0-rc.2", + "@angular/platform-browser": "^17.0.0-rc.2", "@types/google.maps": "^3.52.4", "@types/youtube": "^0.0.46", "rxjs": "^6.6.7", @@ -71,18 +71,18 @@ "zone.js": "~0.13.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.0.0-rc.0", - "@angular-devkit/core": "^17.0.0-rc.0", - "@angular-devkit/schematics": "^17.0.0-rc.0", + "@angular-devkit/build-angular": "^17.0.0-rc.3", + "@angular-devkit/core": "^17.0.0-rc.3", + "@angular-devkit/schematics": "^17.0.0-rc.3", "@angular/bazel": "https://github.com/angular/bazel-builds.git#bac9c1abe1e6ac1801fbbccb53353a1ed7126469", - "@angular/build-tooling": "https://github.com/angular/dev-infra-private-build-tooling-builds.git#28072768cb6624221b17766a7f571b6d9e5d55e6", - "@angular/cli": "^17.0.0-rc.0", - "@angular/compiler-cli": "^17.0.0-rc.0", - "@angular/localize": "^17.0.0-rc.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#16b9f550b766b52f51dc5580cbac13378a1ab5f4", - "@angular/platform-browser-dynamic": "^17.0.0-rc.0", - "@angular/platform-server": "^17.0.0-rc.0", - "@angular/router": "^17.0.0-rc.0", + "@angular/build-tooling": "https://github.com/angular/dev-infra-private-build-tooling-builds.git#d05af145e0e0effa8ff2d0abb8e2fdb1ede584ab", + "@angular/cli": "^17.0.0-rc.3", + "@angular/compiler-cli": "^17.0.0-rc.2", + "@angular/localize": "^17.0.0-rc.2", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#f10010d0d3d96919644bb97f09d11ba678929e9b", + "@angular/platform-browser-dynamic": "^17.0.0-rc.2", + "@angular/platform-server": "^17.0.0-rc.2", + "@angular/router": "^17.0.0-rc.2", "@babel/core": "^7.16.12", "@babel/helper-explode-assignable-expression": "^7.18.6", "@babel/helper-string-parser": "^7.22.5", @@ -148,7 +148,7 @@ "@octokit/rest": "18.3.5", "@rollup/plugin-commonjs": "^21.0.0", "@rollup/plugin-node-resolve": "^13.1.3", - "@schematics/angular": "^17.0.0-rc.0", + "@schematics/angular": "^17.0.0-rc.3", "@types/babel__core": "^7.1.18", "@types/browser-sync": "^2.26.3", "@types/fs-extra": "^9.0.13", diff --git a/src/cdk-experimental/popover-edit/edit-event-dispatcher.ts b/src/cdk-experimental/popover-edit/edit-event-dispatcher.ts index 76cef0f1915d..cc9999a3bedc 100644 --- a/src/cdk-experimental/popover-edit/edit-event-dispatcher.ts +++ b/src/cdk-experimental/popover-edit/edit-event-dispatcher.ts @@ -35,7 +35,7 @@ const FOCUS_DELAY = 0; * FOCUSABLE - Rendered in the dom and styled for its contents to be focusable but invisible. * ON - Rendered and fully visible. */ -export const enum HoverContentState { +export enum HoverContentState { OFF = 0, FOCUSABLE, ON, diff --git a/src/cdk-experimental/popover-edit/focus-escape-notifier.ts b/src/cdk-experimental/popover-edit/focus-escape-notifier.ts index d03bbf7dd44e..970c79c784d5 100644 --- a/src/cdk-experimental/popover-edit/focus-escape-notifier.ts +++ b/src/cdk-experimental/popover-edit/focus-escape-notifier.ts @@ -12,7 +12,7 @@ import {FocusTrap, InteractivityChecker} from '@angular/cdk/a11y'; import {Observable, Subject} from 'rxjs'; /** Value indicating whether focus left the target area before or after the enclosed elements. */ -export const enum FocusEscapeNotifierDirection { +export enum FocusEscapeNotifierDirection { START, END, } diff --git a/src/cdk-experimental/popover-edit/popover-edit.spec.ts b/src/cdk-experimental/popover-edit/popover-edit.spec.ts index 950c572cc538..7a7b0bd1a605 100644 --- a/src/cdk-experimental/popover-edit/popover-edit.spec.ts +++ b/src/cdk-experimental/popover-edit/popover-edit.spec.ts @@ -194,18 +194,20 @@ abstract class BaseTestComponent { ${WEIGHT_EDIT_TEMPLATE} - - just a cell - - - ${CELL_TEMPLATE} - - - - {{element.weight}} - - + @for (element of elements; track element) { + + just a cell + + + ${CELL_TEMPLATE} + + + + {{element.weight}} + + + } `, }) @@ -220,25 +222,27 @@ class VanillaTableOutOfCell extends BaseTestComponent { @Component({ template: ` - - + @for (element of elements; track element) { + + - + + ${NAME_EDIT_TEMPLATE} + + - - + + ${WEIGHT_EDIT_TEMPLATE} + + + + }
just a cell
just a cell - ${CELL_TEMPLATE} + + ${CELL_TEMPLATE} - - ${NAME_EDIT_TEMPLATE} - - - {{element.weight}} + + {{element.weight}} - - ${WEIGHT_EDIT_TEMPLATE} - -
`, }) diff --git a/src/cdk-experimental/selection/selection.spec.ts b/src/cdk-experimental/selection/selection.spec.ts index 0a15f2bd45d1..757ee64cd85e 100644 --- a/src/cdk-experimental/selection/selection.spec.ts +++ b/src/cdk-experimental/selection/selection.spec.ts @@ -442,15 +442,17 @@ describe('cdkSelectionColumn with multiple = false', () => { -
  • - - {{item}} -
  • + @for (item of data; track item; let i = $index) { +
  • + + {{item}} +
  • + } `, }) class ListWithMultiSelection { @@ -460,7 +462,10 @@ class ListWithMultiSelection { selectionChange?: SelectionChange; - constructor(private readonly _elementRef: ElementRef, private readonly _cdr: ChangeDetectorRef) {} + constructor( + private readonly _elementRef: ElementRef, + private readonly _cdr: ChangeDetectorRef, + ) {} selectAllState(indeterminateState: boolean | null, checkedState: boolean | null): string { if (indeterminateState) { @@ -502,15 +507,17 @@ class ListWithMultiSelection { template: ` `, }) class ListWithSingleSelection { @@ -530,7 +537,10 @@ class ListWithSingleSelection { this._cdr.detectChanges(); } - constructor(private readonly _elementRef: ElementRef, private readonly _cdr: ChangeDetectorRef) {} + constructor( + private readonly _elementRef: ElementRef, + private readonly _cdr: ChangeDetectorRef, + ) {} getSelectionToggle(index: number) { return this._elementRef.nativeElement.querySelectorAll('[cdkselectiontoggle]')[index]; @@ -585,7 +595,10 @@ class MultiSelectTableWithSelectionColumn { this._cdr.detectChanges(); } - constructor(readonly elementRef: ElementRef, private readonly _cdr: ChangeDetectorRef) {} + constructor( + readonly elementRef: ElementRef, + private readonly _cdr: ChangeDetectorRef, + ) {} getSelectAll(): HTMLInputElement { return this.elementRef.nativeElement.querySelector('input[cdkselectall]'); @@ -632,7 +645,10 @@ class SingleSelectTableWithSelectionColumn { this._cdr.detectChanges(); } - constructor(readonly elementRef: ElementRef, private readonly _cdr: ChangeDetectorRef) {} + constructor( + readonly elementRef: ElementRef, + private readonly _cdr: ChangeDetectorRef, + ) {} getSelectionToggle(index: number): HTMLInputElement { return this.elementRef.nativeElement.querySelectorAll('input[cdkselectiontoggle]')[index]; diff --git a/src/cdk-experimental/table-scroll-container/table-scroll-container.spec.ts b/src/cdk-experimental/table-scroll-container/table-scroll-container.spec.ts index 1c152347c069..4fffaff7cfc9 100644 --- a/src/cdk-experimental/table-scroll-container/table-scroll-container.spec.ts +++ b/src/cdk-experimental/table-scroll-container/table-scroll-container.spec.ts @@ -247,13 +247,15 @@ class FakeDataSource extends DataSource { template: `
    - - - - - + @for (column of columns; track column) { + + + + + + } diff --git a/src/cdk/a11y/fake-event-detection.ts b/src/cdk/a11y/fake-event-detection.ts index d4d6e80ae2af..6a2dca02ecc3 100644 --- a/src/cdk/a11y/fake-event-detection.ts +++ b/src/cdk/a11y/fake-event-detection.ts @@ -9,13 +9,11 @@ /** Gets whether an event could be a faked `mousedown` event dispatched by a screen reader. */ export function isFakeMousedownFromScreenReader(event: MouseEvent): boolean { // Some screen readers will dispatch a fake `mousedown` event when pressing enter or space on - // a clickable element. We can distinguish these events when both `offsetX` and `offsetY` are - // zero or `event.buttons` is zero, depending on the browser: + // a clickable element. We can distinguish these events when `event.buttons` is zero, or + // `event.detail` is zero depending on the browser: // - `event.buttons` works on Firefox, but fails on Chrome. - // - `offsetX` and `offsetY` work on Chrome, but fail on Firefox. - // Note that there's an edge case where the user could click the 0x0 spot of the - // screen themselves, but that is unlikely to contain interactive elements. - return event.buttons === 0 || (event.offsetX === 0 && event.offsetY === 0); + // - `detail` works on Chrome, but fails on Firefox. + return event.buttons === 0 || event.detail === 0; } /** Gets whether an event could be a faked `touchstart` event dispatched by a screen reader. */ diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts index 8fc89c9b46d0..b1472a5809f5 100644 --- a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts +++ b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts @@ -168,7 +168,7 @@ describe('FocusMonitor', () => { // Simulate focus via a fake mousedown from a screen reader. dispatchMouseEvent(buttonElement, 'mousedown'); const event = createMouseEvent('mousedown'); - Object.defineProperties(event, {offsetX: {get: () => 0}, offsetY: {get: () => 0}}); + Object.defineProperties(event, {detail: {get: () => 0}}); dispatchEvent(buttonElement, event); buttonElement.focus(); diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.ts b/src/cdk/a11y/focus-monitor/focus-monitor.ts index d1da1c165a11..1c5b5706b71a 100644 --- a/src/cdk/a11y/focus-monitor/focus-monitor.ts +++ b/src/cdk/a11y/focus-monitor/focus-monitor.ts @@ -43,7 +43,7 @@ export interface FocusOptions { } /** Detection mode used for attributing the origin of a focus event. */ -export const enum FocusMonitorDetectionMode { +export enum FocusMonitorDetectionMode { /** * Any mousedown, keydown, or touchstart event that happened in the previous * tick or the current tick will be used to assign a focus event's origin (to @@ -623,7 +623,10 @@ export class CdkMonitorFocus implements AfterViewInit, OnDestroy { @Output() readonly cdkFocusChange = new EventEmitter(); - constructor(private _elementRef: ElementRef, private _focusMonitor: FocusMonitor) {} + constructor( + private _elementRef: ElementRef, + private _focusMonitor: FocusMonitor, + ) {} get focusOrigin(): FocusOrigin { return this._focusOrigin; diff --git a/src/cdk/a11y/focus-trap/focus-trap.spec.ts b/src/cdk/a11y/focus-trap/focus-trap.spec.ts index 7c8bbfe0b76d..6038356b930a 100644 --- a/src/cdk/a11y/focus-trap/focus-trap.spec.ts +++ b/src/cdk/a11y/focus-trap/focus-trap.spec.ts @@ -339,10 +339,12 @@ class SimpleFocusTrap { const AUTO_FOCUS_TEMPLATE = ` -
    - - -
    + @if (showTrappedRegion) { +
    + + +
    + } `; @Component({template: AUTO_FOCUS_TEMPLATE}) @@ -360,11 +362,13 @@ class FocusTrapWithAutoCaptureInShadowDom extends FocusTrapWithAutoCapture {} @Component({ template: ` -
    - - -
    - `, + @if (renderFocusTrap) { +
    + + +
    + } + `, }) class FocusTrapWithBindings { @ViewChild(CdkTrapFocus) focusTrapDirective: CdkTrapFocus; diff --git a/src/cdk/a11y/high-contrast-mode/high-contrast-mode-detector.ts b/src/cdk/a11y/high-contrast-mode/high-contrast-mode-detector.ts index 13d4d0a98e96..238d0ddbc3ea 100644 --- a/src/cdk/a11y/high-contrast-mode/high-contrast-mode-detector.ts +++ b/src/cdk/a11y/high-contrast-mode/high-contrast-mode-detector.ts @@ -13,7 +13,7 @@ import {DOCUMENT} from '@angular/common'; import {Subscription} from 'rxjs'; /** Set of possible high-contrast mode backgrounds. */ -export const enum HighContrastMode { +export enum HighContrastMode { NONE, BLACK_ON_WHITE, WHITE_ON_BLACK, @@ -49,7 +49,10 @@ export class HighContrastModeDetector implements OnDestroy { private _document: Document; private _breakpointSubscription: Subscription; - constructor(private _platform: Platform, @Inject(DOCUMENT) document: any) { + constructor( + private _platform: Platform, + @Inject(DOCUMENT) document: any, + ) { this._document = document; this._breakpointSubscription = inject(BreakpointObserver) diff --git a/src/cdk/a11y/input-modality/input-modality-detector.spec.ts b/src/cdk/a11y/input-modality/input-modality-detector.spec.ts index b403c0d48937..a7dee553b5cf 100644 --- a/src/cdk/a11y/input-modality/input-modality-detector.spec.ts +++ b/src/cdk/a11y/input-modality/input-modality-detector.spec.ts @@ -138,7 +138,7 @@ describe('InputModalityDetector', () => { // Create a fake screen-reader mouse event. const event = createMouseEvent('mousedown'); - Object.defineProperties(event, {offsetX: {get: () => 0}, offsetY: {get: () => 0}}); + Object.defineProperties(event, {detail: {get: () => 0}}); dispatchEvent(document, event); expect(detector.mostRecentModality).toBe('keyboard'); diff --git a/src/cdk/accordion/public-api.ts b/src/cdk/accordion/public-api.ts index 31c56b5d06bd..3e82f36a5b6e 100644 --- a/src/cdk/accordion/public-api.ts +++ b/src/cdk/accordion/public-api.ts @@ -7,5 +7,5 @@ */ export {CdkAccordionItem} from './accordion-item'; -export {CdkAccordion} from './accordion'; +export {CdkAccordion, CDK_ACCORDION} from './accordion'; export * from './accordion-module'; diff --git a/src/cdk/collections/view-repeater.ts b/src/cdk/collections/view-repeater.ts index b380d59deb96..78b3e086cbfa 100644 --- a/src/cdk/collections/view-repeater.ts +++ b/src/cdk/collections/view-repeater.ts @@ -58,7 +58,7 @@ export type _ViewRepeaterItemContextFactory = (record: IterableChangeRecord) => T; /** Indicates how a view was changed by a {@link _ViewRepeater}. */ -export const enum _ViewRepeaterOperation { +export enum _ViewRepeaterOperation { /** The content of an existing view was replaced with another item. */ REPLACED, /** A new view was created with `createEmbeddedView`. */ diff --git a/src/cdk/drag-drop/directives/drag.spec.ts b/src/cdk/drag-drop/directives/drag.spec.ts index b318dd989094..3398aed91e2e 100644 --- a/src/cdk/drag-drop/directives/drag.spec.ts +++ b/src/cdk/drag-drop/directives/drag.spec.ts @@ -6,7 +6,7 @@ import { dispatchMouseEvent, dispatchTouchEvent, dispatchFakeEvent, -} from '../../testing/private'; +} from '@angular/cdk/testing/private'; import { AfterViewInit, ChangeDetectionStrategy, @@ -240,8 +240,8 @@ describe('CdkDrag', () => { const event = createMouseEvent('mousedown', 0, 0); Object.defineProperties(event, { - offsetX: {get: () => 0}, - offsetY: {get: () => 0}, + buttons: {get: () => 0}, + detail: {get: () => 0}, }); expect(dragElement.style.transform).toBeFalsy(); @@ -6725,10 +6725,11 @@ class StandaloneDraggableWithPreDisabledHandle { template: `
    -
    + @if (showHandle) { +
    + }
    `, }) @@ -6806,6 +6807,7 @@ class StandaloneDraggableWithMultipleHandles { @ViewChildren(CdkDragHandle) handles: QueryList; } +// TODO(crisbeto): figure out why switch `*ngFor` with `@for` here causes a test failure. const DROP_ZONE_FIXTURE_TEMPLATE = `
    - -
    {{item.value}}
    -
    + @if (true) { + @for (item of items; track item) { +
    {{item.value}}
    + } + }
    `, }) @@ -6993,12 +6996,13 @@ const HORIZONTAL_FIXTURE_TEMPLATE = ` cdkDropListOrientation="horizontal" [cdkDropListData]="items" (cdkDropListDropped)="droppedSpy($event)"> -
    {{item.value}}
    + @for (item of items; track item) { +
    {{item.value}}
    + } `; @@ -7058,26 +7062,29 @@ class DraggableInScrollableHorizontalDropZone extends DraggableInHorizontalDropZ } } +// TODO(crisbeto): `*ngIf` here can be removed after updating to a version of Angular that includes +// https://github.com/angular/angular/pull/52515 @Component({ template: `
    -
    - {{item}} - - - -
    Custom preview
    -
    -
    -
    + @for (item of items; track item) { +
    + {{item}} + + + +
    Custom preview
    +
    +
    +
    + }
    `, }) @@ -7095,15 +7102,16 @@ class DraggableInDropZoneWithCustomPreview { @Component({ template: `
    -
    - {{item}} - Hello {{item}} -
    + @for (item of items; track item) { +
    + {{item}} + Hello {{item}} +
    + }
    `, }) @@ -7116,16 +7124,15 @@ class DraggableInDropZoneWithCustomTextOnlyPreview { @Component({ template: `
    -
    + @for (item of items; track item) { +
    {{item}} Hello {{item}} -
    +
    + }
    `, }) @@ -7141,16 +7148,17 @@ class DraggableInDropZoneWithCustomMultiNodePreview { cdkDropList (cdkDropListDropped)="droppedSpy($event)" style="width: 100px; background: pink;"> -
    + @for (item of items; track item) { +
    {{item}} - + @if (renderPlaceholder) {
    Custom placeholder
    -
    -
    + } +
    + } `, styles: [ @@ -7172,11 +7180,12 @@ class DraggableInDropZoneWithCustomPlaceholder { @Component({ template: `
    -
    + @for (item of items; track item) { +
    {{item}} Hello {{item}} -
    +
    + }
    `, }) @@ -7188,14 +7197,15 @@ class DraggableInDropZoneWithCustomTextOnlyPlaceholder { @Component({ template: `
    -
    + @for (item of items; track item) { +
    {{item}} Hello {{item}} -
    +
    + }
    `, }) @@ -7229,11 +7239,12 @@ const CONNECTED_DROP_ZONES_TEMPLATE = ` [cdkDropListConnectedTo]="[doneZone]" (cdkDropListDropped)="droppedSpy($event)" (cdkDropListEntered)="enteredSpy($event)"> -
    {{item}}
    + @for (item of todo; track item) { +
    {{item}}
    + }
    -
    {{item}}
    + @for (item of done; track item) { +
    {{item}}
    + }
    -
    {{item}}
    + @for (item of extra; track item) { +
    {{item}}
    + }
    `; @@ -7295,7 +7308,7 @@ class ConnectedDropZones implements AfterViewInit { @Component({ encapsulation: ViewEncapsulation.ShadowDom, styles: CONNECTED_DROP_ZONES_STYLES, - template: `
    ${CONNECTED_DROP_ZONES_TEMPLATE}
    `, + template: `@if (true) {${CONNECTED_DROP_ZONES_TEMPLATE}}`, }) class ConnectedDropZonesInsideShadowRootWithNgIf extends ConnectedDropZones {} @@ -7323,14 +7336,18 @@ class ConnectedDropZonesInsideShadowRootWithNgIf extends ConnectedDropZones {} cdkDropList [cdkDropListData]="todo" (cdkDropListDropped)="droppedSpy($event)"> -
    {{item}}
    + @for (item of todo; track item) { +
    {{item}}
    +}
    -
    {{item}}
    + @for (item of done; track item) { +
    {{item}}
    + }
    `, @@ -7445,10 +7462,12 @@ class DropListOnNgContainer {} changeDetection: ChangeDetectionStrategy.OnPush, template: `
    -
    {{item.value}}
    + @for (item of items; track item) { +
    {{item.value}}
    + }
    `, }) @@ -7503,16 +7522,17 @@ class ConnectedWrappedDropZones { [cdkDropListData]="items" (cdkDropListSorted)="sortedSpy($event)" (cdkDropListDropped)="droppedSpy($event)"> -
    - {{item.value}} - -
    + @for (item of items; track item) { +
    + {{item.value}} + +
    + } `, }) @@ -7546,16 +7566,17 @@ class DraggableWithCanvasInDropZone extends DraggableInDropZone implements After [cdkDropListData]="items" (cdkDropListSorted)="sortedSpy($event)" (cdkDropListDropped)="droppedSpy($event)"> -
    - {{item.value}} - -
    + @for (item of items; track item) { +
    + {{item.value}} + +
    + } `, }) @@ -7576,7 +7597,9 @@ class PassthroughComponent {} selector: 'wrapped-drop-container', template: `
    -
    {{item}}
    + @for (item of items; track item) { +
    {{item}}
    + }
    `, changeDetection: ChangeDetectionStrategy.OnPush, @@ -7695,10 +7718,11 @@ class NestedDragsThroughTemplate { template: `
    -
    {{item}}
    + @for (item of items; track item) { +
    {{item}}
    + }
    `, @@ -7743,13 +7767,14 @@ class PlainStandaloneDropList { ], template: `
    -
    - {{item}} - - -
    {{item}}
    -
    -
    + @for (item of items; track item) { +
    + {{item}} + +
    {{item}}
    +
    +
    + }
    `, }) @@ -7768,11 +7793,12 @@ class DraggableInHorizontalFlexDropZoneWithMatchSizePreview { [cdkDropListConnectedTo]="[doneZone]" (cdkDropListDropped)="droppedSpy($event)" (cdkDropListEntered)="enteredSpy($event)"> -
    {{item}}
    + @for (item of todo; track item) { +
    {{item}}
    + }
    Hello there
    -
    {{item}}
    + @for (item of done; track item) { +
    {{item}}
    + }
    `, @@ -7824,21 +7851,22 @@ class DraggableWithAlternateRootAndSelfHandle { [cdkDropListData]="items" (cdkDropListSorted)="sortedSpy($event)" (cdkDropListDropped)="droppedSpy($event)"> -
    - {{item.value}} - - - -
    + @for (item of items; track item) { +
    + {{item.value}} + + + +
    + } `, }) @@ -7852,13 +7880,14 @@ class DraggableWithInputsInDropZone extends DraggableInDropZone { cdkDropList class="drop-list scroll-container" [cdkDropListData]="items"> -
    - {{item.id}} - -
    + @for (item of items; track item) { +
    + {{item.id}} + +
    + } `, }) diff --git a/src/cdk/drag-drop/drag-drop.md b/src/cdk/drag-drop/drag-drop.md index 0c955660e0e1..bb8438e525d9 100644 --- a/src/cdk/drag-drop/drag-drop.md +++ b/src/cdk/drag-drop/drag-drop.md @@ -46,7 +46,9 @@ will be connected to all other lists automatically. ```html
    -
    + @for (list of lists; track list) { +
    + }
    ``` @@ -58,9 +60,13 @@ or `cdkDropListData`, respectively. Events fired from both directives include th you to easily identify the origin of the drag or drop interaction. ```html -
    -
    -
    +@for (list of lists; track list) { +
    + @for (item of list; track item) { +
    + } +
    +} ``` ### Styling diff --git a/src/cdk/drag-drop/drop-list-ref.ts b/src/cdk/drag-drop/drop-list-ref.ts index e03a07af0186..8717f09fd20a 100644 --- a/src/cdk/drag-drop/drop-list-ref.ts +++ b/src/cdk/drag-drop/drop-list-ref.ts @@ -34,14 +34,14 @@ const DROP_PROXIMITY_THRESHOLD = 0.05; const SCROLL_PROXIMITY_THRESHOLD = 0.05; /** Vertical direction in which we can auto-scroll. */ -const enum AutoScrollVerticalDirection { +enum AutoScrollVerticalDirection { NONE, UP, DOWN, } /** Horizontal direction in which we can auto-scroll. */ -const enum AutoScrollHorizontalDirection { +enum AutoScrollHorizontalDirection { NONE, LEFT, RIGHT, diff --git a/src/cdk/listbox/listbox.spec.ts b/src/cdk/listbox/listbox.spec.ts index 3a75f90bdb2d..a7a2c9837ce1 100644 --- a/src/cdk/listbox/listbox.spec.ts +++ b/src/cdk/listbox/listbox.spec.ts @@ -1004,7 +1004,9 @@ class ListboxWithFormControl { @Component({ template: `
    -
    {{option}}
    + @for (option of options; track option) { +
    {{option}}
    + }
    `, }) @@ -1016,7 +1018,9 @@ class ListboxWithPreselectedFormControl { @Component({ template: `
    -
    {{option}}
    + @for (option of options; track option) { +
    {{option}}
    + }
    `, }) @@ -1071,7 +1075,9 @@ class ListboxWithMultipleBoundValues { @Component({ template: `
    -
    {{fruit.name}}
    + @for (fruit of fruits; track fruit) { +
    {{fruit.name}}
    + }
    `, }) diff --git a/src/cdk/menu/menu-stack.ts b/src/cdk/menu/menu-stack.ts index eabdc5640af9..d38ba4056ba7 100644 --- a/src/cdk/menu/menu-stack.ts +++ b/src/cdk/menu/menu-stack.ts @@ -11,7 +11,7 @@ import {Observable, Subject} from 'rxjs'; import {debounceTime, distinctUntilChanged, startWith} from 'rxjs/operators'; /** The relative item in the inline menu to focus after closing all popup menus. */ -export const enum FocusNext { +export enum FocusNext { nextItem, previousItem, currentItem, diff --git a/src/cdk/menu/pointer-focus-tracker.spec.ts b/src/cdk/menu/pointer-focus-tracker.spec.ts index 0e8c2ca43467..afa8f7ddc3e2 100644 --- a/src/cdk/menu/pointer-focus-tracker.spec.ts +++ b/src/cdk/menu/pointer-focus-tracker.spec.ts @@ -108,7 +108,9 @@ class MockWrapper implements FocusableElement {
    First Second - Third + @if (showThird) { + Third + }
    `, }) diff --git a/src/cdk/platform/features/scrolling.ts b/src/cdk/platform/features/scrolling.ts index 84f3ed729f3f..e20d77dc181c 100644 --- a/src/cdk/platform/features/scrolling.ts +++ b/src/cdk/platform/features/scrolling.ts @@ -7,7 +7,7 @@ */ /** The possible ways the browser may handle the horizontal scroll axis in RTL languages. */ -export const enum RtlScrollAxisType { +export enum RtlScrollAxisType { /** * scrollLeft is 0 when scrolled all the way left and (scrollWidth - clientWidth) when scrolled * all the way right. diff --git a/src/cdk/portal/portal.spec.ts b/src/cdk/portal/portal.spec.ts index 2ac61c3cd067..df20e496453c 100644 --- a/src/cdk/portal/portal.spec.ts +++ b/src/cdk/portal/portal.spec.ts @@ -779,7 +779,10 @@ class ArbitraryViewContainerRefComponent { @ViewChild('template') template: TemplateRef; @ViewChild(SaveParentNodeOnInit) saveParentNodeOnInit: SaveParentNodeOnInit; - constructor(public viewContainerRef: ViewContainerRef, public injector: Injector) {} + constructor( + public viewContainerRef: ViewContainerRef, + public injector: Injector, + ) {} } /** Test-bed component that contains a portal outlet and a couple of template portals. */ @@ -799,7 +802,9 @@ class ArbitraryViewContainerRefComponent {
      -
    • {{fruitName}}
    • + @for (fruitName of fruits; track fruitName) { +
    • {{fruitName}}
    • + }
    @@ -825,7 +830,10 @@ class PortalTestApp { fruits = ['Apple', 'Pineapple', 'Durian']; attachedSpy = jasmine.createSpy('attached spy'); - constructor(public viewContainerRef: ViewContainerRef, public injector: Injector) {} + constructor( + public viewContainerRef: ViewContainerRef, + public injector: Injector, + ) {} get cakePortal() { return this.portals.first; diff --git a/src/cdk/schematics/update-tool/target-version.ts b/src/cdk/schematics/update-tool/target-version.ts index 71d63ee1a92e..73953eccc769 100644 --- a/src/cdk/schematics/update-tool/target-version.ts +++ b/src/cdk/schematics/update-tool/target-version.ts @@ -7,7 +7,7 @@ */ /** Possible versions that can be automatically migrated by `ng update`. */ -// Used in an `Object.keys` call below so it can't be `const enum`. + // tslint:disable-next-line:prefer-const-enum export enum TargetVersion { V17 = 'version 17', diff --git a/src/cdk/schematics/utils/project-targets.ts b/src/cdk/schematics/utils/project-targets.ts index 3d2f4b0f9797..287ed701a768 100644 --- a/src/cdk/schematics/utils/project-targets.ts +++ b/src/cdk/schematics/utils/project-targets.ts @@ -33,7 +33,8 @@ export function getProjectBuildTargets( project, builder => builder === '@angular-devkit/build-angular:application' || - builder === '@angular-devkit/build-angular:browser', + builder === '@angular-devkit/build-angular:browser' || + builder === '@angular-devkit/build-angular:browser-esbuild', ); } diff --git a/src/cdk/scrolling/virtual-scroll-viewport.spec.ts b/src/cdk/scrolling/virtual-scroll-viewport.spec.ts index c61ec400f7d9..0b623dd0e36f 100644 --- a/src/cdk/scrolling/virtual-scroll-viewport.spec.ts +++ b/src/cdk/scrolling/virtual-scroll-viewport.spec.ts @@ -1419,9 +1419,9 @@ class VirtualScrollWithItemInjectingViewContainer { @Component({ template: ` - + @if (renderVirtualFor) {
    {{item}}
    -
    + }
    `, styles: [ diff --git a/src/cdk/stepper/BUILD.bazel b/src/cdk/stepper/BUILD.bazel index 41ab3d3b9ebf..c6ad545fdc85 100644 --- a/src/cdk/stepper/BUILD.bazel +++ b/src/cdk/stepper/BUILD.bazel @@ -12,7 +12,6 @@ ng_module( "//src:dev_mode_types", "//src/cdk/a11y", "//src/cdk/bidi", - "//src/cdk/coercion", "//src/cdk/keycodes", "//src/cdk/platform", "@npm//@angular/core", diff --git a/src/cdk/table/table.spec.ts b/src/cdk/table/table.spec.ts index 798e41234f4f..1ac2f5cb3dce 100644 --- a/src/cdk/table/table.spec.ts +++ b/src/cdk/table/table.spec.ts @@ -2419,13 +2419,15 @@ class StickyPositioningListenerTest implements StickyPositioningListener { @Component({ template: ` - - Header {{column}} - {{column}} - Footer {{column}} - + @for (column of columns; track column) { + + Header {{column}} + {{column}} + Footer {{column}} + + } @@ -2477,13 +2479,15 @@ class StickyFlexLayoutCdkTableApp extends StickyPositioningListenerTest { @Component({ template: `
    Header {{column}} {{column}} Footer {{column}} Header {{column}} {{column}} Footer {{column}}
    - - - - - + @for (column of columns; track column) { + + + + + + } @@ -2532,10 +2536,12 @@ class StickyNativeLayoutCdkTableApp extends StickyPositioningListenerTest { @Component({ template: ` - - {{column}} - {{column}} - + @for (column of dynamicColumns; track column) { + + {{column}} + {{column}} + + } @@ -3007,15 +3013,15 @@ class NativeHtmlTableWithColgroupAndCol { } @Component({ - // Note that we need the `ngSwitch` below in order to surface the issue we're testing for. + // Note that we need the `@if` below in order to surface the issue we're testing for. template: ` - + @if (true) { Column A {{row.a}} - + } diff --git a/src/cdk/testing/testbed/fake-events/event-objects.ts b/src/cdk/testing/testbed/fake-events/event-objects.ts index 4bbc10e03f48..aeee1ec151dc 100644 --- a/src/cdk/testing/testbed/fake-events/event-objects.ts +++ b/src/cdk/testing/testbed/fake-events/event-objects.ts @@ -19,8 +19,8 @@ export function createMouseEvent( type: string, clientX = 0, clientY = 0, - offsetX = 1, - offsetY = 1, + offsetX = 0, + offsetY = 0, button = 0, modifiers: ModifierKeys = {}, ) { @@ -36,7 +36,7 @@ export function createMouseEvent( cancelable: true, composed: true, // Required for shadow DOM events. view: window, - detail: 0, + detail: 1, relatedTarget: null, screenX, screenY, diff --git a/src/cdk/testing/tests/test-main-component.html b/src/cdk/testing/tests/test-main-component.html index 8ec6080aa042..263f6d235b5c 100644 --- a/src/cdk/testing/tests/test-main-component.html +++ b/src/cdk/testing/tests/test-main-component.html @@ -74,7 +74,9 @@

    Main Component

    - +@if (_shadowDomSupported) { + +}
    List of {{title}}
      -
    • {{item}}
    • + @for (item of items; track item) { +
    • {{item}}
    • + }
    `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/cdk/tree/BUILD.bazel b/src/cdk/tree/BUILD.bazel index 4933a9726ab4..2da2df0bb980 100644 --- a/src/cdk/tree/BUILD.bazel +++ b/src/cdk/tree/BUILD.bazel @@ -18,7 +18,6 @@ ng_module( "//src:dev_mode_types", "//src/cdk/a11y", "//src/cdk/bidi", - "//src/cdk/coercion", "//src/cdk/collections", "//src/cdk/keycodes", "@npm//@angular/core", diff --git a/src/cdk/tree/nested-node.ts b/src/cdk/tree/nested-node.ts index bed3fe979a48..d4ced02bb185 100644 --- a/src/cdk/tree/nested-node.ts +++ b/src/cdk/tree/nested-node.ts @@ -30,7 +30,6 @@ import {CdkTree, CdkTreeNode} from './tree'; @Directive({ selector: 'cdk-nested-tree-node', exportAs: 'cdkNestedTreeNode', - inputs: ['role', 'disabled', 'tabIndex'], providers: [ {provide: CdkTreeNode, useExisting: CdkNestedTreeNode}, {provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: CdkNestedTreeNode}, diff --git a/src/cdk/tree/padding.ts b/src/cdk/tree/padding.ts index 54c5c51a0774..ebb3cca25b6e 100644 --- a/src/cdk/tree/padding.ts +++ b/src/cdk/tree/padding.ts @@ -7,8 +7,7 @@ */ import {Directionality} from '@angular/cdk/bidi'; -import {coerceNumberProperty, NumberInput} from '@angular/cdk/coercion'; -import {Directive, ElementRef, Input, OnDestroy, Optional} from '@angular/core'; +import {Directive, ElementRef, Input, numberAttribute, OnDestroy, Optional} from '@angular/core'; import {takeUntil} from 'rxjs/operators'; import {Subject} from 'rxjs'; import {CdkTree, CdkTreeNode} from './tree'; @@ -34,11 +33,11 @@ export class CdkTreeNodePadding implements OnDestroy { indentUnits = 'px'; /** The level of depth of the tree node. The padding will be `level * indent` pixels. */ - @Input('cdkTreeNodePadding') + @Input({alias: 'cdkTreeNodePadding', transform: numberAttribute}) get level(): number { return this._level; } - set level(value: NumberInput) { + set level(value: number) { this._setLevelInput(value); } _level: number; @@ -104,11 +103,11 @@ export class CdkTreeNodePadding implements OnDestroy { * TS 4.0 doesn't allow properties to override accessors or vice-versa. * @docs-private */ - protected _setLevelInput(value: NumberInput) { + protected _setLevelInput(value: number) { // Set to null as the fallback value so that _setPadding can fall back to the node level if the // consumer set the directive as `cdkTreeNodePadding=""`. We still want to take this value if // they set 0 explicitly. - this._level = coerceNumberProperty(value, null)!; + this._level = isNaN(value) ? null! : value; this._setPadding(); } @@ -129,7 +128,7 @@ export class CdkTreeNodePadding implements OnDestroy { } this.indentUnits = units; - this._indent = coerceNumberProperty(value); + this._indent = numberAttribute(value); this._setPadding(); } } diff --git a/src/cdk/tree/toggle.ts b/src/cdk/tree/toggle.ts index 442d6ade7832..697f447c8d57 100644 --- a/src/cdk/tree/toggle.ts +++ b/src/cdk/tree/toggle.ts @@ -6,9 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; -import {Directive, Input} from '@angular/core'; import {ENTER, SPACE} from '@angular/cdk/keycodes'; +import {Directive, Input, booleanAttribute} from '@angular/core'; import {CdkTree, CdkTreeNode} from './tree'; @@ -28,14 +27,8 @@ import {CdkTree, CdkTreeNode} from './tree'; }) export class CdkTreeNodeToggle { /** Whether expand/collapse the node recursively. */ - @Input('cdkTreeNodeToggleRecursive') - get recursive(): boolean { - return this._recursive; - } - set recursive(value: BooleanInput) { - this._recursive = coerceBooleanProperty(value); - } - protected _recursive = false; + @Input({alias: 'cdkTreeNodeToggleRecursive', transform: booleanAttribute}) + recursive: boolean = false; constructor( protected _tree: CdkTree, diff --git a/src/cdk/tree/tree.spec.ts b/src/cdk/tree/tree.spec.ts index 2670e331bf84..0a87b33b112e 100644 --- a/src/cdk/tree/tree.spec.ts +++ b/src/cdk/tree/tree.spec.ts @@ -1501,16 +1501,15 @@ class SimpleCdkTreeApp { @Component({ template: ` - - + + @if (true) { {{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}} - + } `, }) @@ -1626,9 +1625,11 @@ class CdkTreeAppWithToggle { cdkTreeNodeToggle [cdkTreeNodeToggleRecursive]="toggleRecursively"> {{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}} -
    + @if (tree.isExpanded(node)) { +
    +} `, diff --git a/src/cdk/tree/tree.ts b/src/cdk/tree/tree.ts index 275564af4ef1..876b1d73b8e8 100644 --- a/src/cdk/tree/tree.ts +++ b/src/cdk/tree/tree.ts @@ -13,7 +13,6 @@ import { TreeKeyManagerStrategy, } from '@angular/cdk/a11y'; import {Directionality} from '@angular/cdk/bidi'; -import {coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion'; import { CollectionViewer, DataSource, @@ -43,7 +42,9 @@ import { ViewChild, ViewContainerRef, ViewEncapsulation, + booleanAttribute, inject, + numberAttribute, } from '@angular/core'; import { BehaviorSubject, @@ -1119,15 +1120,15 @@ export class CdkTreeNode implements OnDestroy, OnInit, TreeKeyManagerI * If not using `FlatTreeControl`, or if `isExpandable` is not provided to * `NestedTreeControl`, this should be provided for correct node a11y. */ - @Input() + @Input({transform: booleanAttribute}) get isExpandable() { return this._isExpandable(); } - set isExpandable(isExpandable: boolean | '' | null) { - this._inputIsExpandable = coerceBooleanProperty(isExpandable); + set isExpandable(isExpandable: boolean) { + this._inputIsExpandable = isExpandable; } - @Input() + @Input({transform: booleanAttribute}) get isExpanded(): boolean { return this._tree.isExpanded(this._data); } @@ -1143,7 +1144,7 @@ export class CdkTreeNode implements OnDestroy, OnInit, TreeKeyManagerI * Whether or not this node is disabled. If it's disabled, then the user won't be able to focus * or activate this node. */ - @Input() isDisabled?: boolean; + @Input({transform: booleanAttribute}) isDisabled?: boolean; /** This emits when the node has been programatically activated or activated by keyboard. */ @Output() @@ -1323,7 +1324,7 @@ function getParentNodeAriaLevel(nodeElement: HTMLElement): number { return -1; } } else if (parent.classList.contains('cdk-nested-tree-node')) { - return coerceNumberProperty(parent.getAttribute('aria-level')!); + return numberAttribute(parent.getAttribute('aria-level')!); } else { // The ancestor element is the cdk-tree itself return 0; diff --git a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-cell-span-vanilla-table/cdk-popover-edit-cell-span-vanilla-table-example.html b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-cell-span-vanilla-table/cdk-popover-edit-cell-span-vanilla-table-example.html index df7be8b086d4..d2fb0ff05f3b 100644 --- a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-cell-span-vanilla-table/cdk-popover-edit-cell-span-vanilla-table-example.html +++ b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-cell-span-vanilla-table/cdk-popover-edit-cell-span-vanilla-table-example.html @@ -26,45 +26,47 @@
    - +
    - - - - - - - - - + @for (person of persons; track person) { + + + + + + + + + + }
    Header {{column}} {{column}} Footer {{column}} Header {{column}} {{column}} Footer {{column}}
    No. First name Middle name Last name
    {{person.id}} - {{person.firstName}} - - - - - - {{person.middleName}} - - - - - - {{person.lastName}} - - - - -
    {{person.id}} + {{person.firstName}} + + + + + + {{person.middleName}} + + + + + + {{person.lastName}} + + + + +
    diff --git a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-cell-span-vanilla-table/cdk-popover-edit-cell-span-vanilla-table-example.ts b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-cell-span-vanilla-table/cdk-popover-edit-cell-span-vanilla-table-example.ts index f3fa86f5b5a5..d0168c103ca0 100644 --- a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-cell-span-vanilla-table/cdk-popover-edit-cell-span-vanilla-table-example.ts +++ b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-cell-span-vanilla-table/cdk-popover-edit-cell-span-vanilla-table-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {NgForm, FormsModule} from '@angular/forms'; -import {NgFor} from '@angular/common'; import {CdkPopoverEditModule} from '@angular/cdk-experimental/popover-edit'; export interface Person { @@ -30,7 +29,7 @@ const PERSON_DATA: Person[] = [ styleUrls: ['cdk-popover-edit-cell-span-vanilla-table-example.css'], templateUrl: 'cdk-popover-edit-cell-span-vanilla-table-example.html', standalone: true, - imports: [CdkPopoverEditModule, FormsModule, NgFor], + imports: [CdkPopoverEditModule, FormsModule], }) export class CdkPopoverEditCellSpanVanillaTableExample { readonly preservedValues = new WeakMap(); diff --git a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-tab-out-vanilla-table/cdk-popover-edit-tab-out-vanilla-table-example.html b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-tab-out-vanilla-table/cdk-popover-edit-tab-out-vanilla-table-example.html index 13270f0a01f0..dcd780c5a16e 100644 --- a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-tab-out-vanilla-table/cdk-popover-edit-tab-out-vanilla-table-example.html +++ b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-tab-out-vanilla-table/cdk-popover-edit-tab-out-vanilla-table-example.html @@ -15,42 +15,44 @@
    - + No. Name Weight Symbol - - - {{element.position}} - - - {{element.name}} - - - -
    -
    - -
    - -
    -
    -
    - - - {{element.weight}} - + @for (element of elements; track element) { + + {{element.position}} - {{element.symbol}} - + + {{element.name}} + + + +
    +
    + +
    + +
    +
    +
    + + + + {{element.weight}} + + + {{element.symbol}} + + } diff --git a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-tab-out-vanilla-table/cdk-popover-edit-tab-out-vanilla-table-example.ts b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-tab-out-vanilla-table/cdk-popover-edit-tab-out-vanilla-table-example.ts index 322b160cb655..bb3fc4379565 100644 --- a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-tab-out-vanilla-table/cdk-popover-edit-tab-out-vanilla-table-example.ts +++ b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-tab-out-vanilla-table/cdk-popover-edit-tab-out-vanilla-table-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {NgForm, FormsModule} from '@angular/forms'; -import {NgFor} from '@angular/common'; import {CdkPopoverEditModule} from '@angular/cdk-experimental/popover-edit'; export interface PeriodicElement { @@ -41,7 +40,7 @@ const ELEMENT_DATA: PeriodicElement[] = [ styleUrls: ['cdk-popover-edit-tab-out-vanilla-table-example.css'], templateUrl: 'cdk-popover-edit-tab-out-vanilla-table-example.html', standalone: true, - imports: [CdkPopoverEditModule, FormsModule, NgFor], + imports: [CdkPopoverEditModule, FormsModule], }) export class CdkPopoverEditTabOutVanillaTableExample { readonly preservedNameValues = new WeakMap(); diff --git a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-vanilla-table/cdk-popover-edit-vanilla-table-example.html b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-vanilla-table/cdk-popover-edit-vanilla-table-example.html index fe4d4dbd7912..4facc8c21aa5 100644 --- a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-vanilla-table/cdk-popover-edit-vanilla-table-example.html +++ b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-vanilla-table/cdk-popover-edit-vanilla-table-example.html @@ -19,51 +19,53 @@ - + No. Name Weight Symbol - - - {{element.position}} - - - {{element.name}} - - - -
    -
    - Edit a: - -
    - - - -
    -
    -
    - - - - + @for (element of elements; track element) { + + {{element.position}} - - {{element.weight}} - - - - - + + {{element.name}} - {{element.symbol}} - + + +
    +
    + Edit a: + +
    + + + +
    +
    +
    + + + + + + + + {{element.weight}} + + + + + + + {{element.symbol}} + + } diff --git a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-vanilla-table/cdk-popover-edit-vanilla-table-example.ts b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-vanilla-table/cdk-popover-edit-vanilla-table-example.ts index 7309eb186543..0e3c9f5e7cf2 100644 --- a/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-vanilla-table/cdk-popover-edit-vanilla-table-example.ts +++ b/src/components-examples/cdk-experimental/popover-edit/cdk-popover-edit-vanilla-table/cdk-popover-edit-vanilla-table-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {NgForm, FormsModule} from '@angular/forms'; -import {NgFor} from '@angular/common'; import {CdkPopoverEditModule} from '@angular/cdk-experimental/popover-edit'; export interface PeriodicElement { @@ -41,7 +40,7 @@ const ELEMENT_DATA: PeriodicElement[] = [ styleUrls: ['cdk-popover-edit-vanilla-table-example.css'], templateUrl: 'cdk-popover-edit-vanilla-table-example.html', standalone: true, - imports: [CdkPopoverEditModule, FormsModule, NgFor], + imports: [CdkPopoverEditModule, FormsModule], }) export class CdkPopoverEditVanillaTableExample { readonly preservedNameValues = new WeakMap(); diff --git a/src/components-examples/cdk-experimental/selection/cdk-selection-list/cdk-selection-list-example.html b/src/components-examples/cdk-experimental/selection/cdk-selection-list/cdk-selection-list-example.html index 8877ac3e1b25..610b3453d34f 100644 --- a/src/components-examples/cdk-experimental/selection/cdk-selection-list/cdk-selection-list-example.html +++ b/src/components-examples/cdk-experimental/selection/cdk-selection-list/cdk-selection-list-example.html @@ -5,40 +5,48 @@

    native input

    [checked]="allToggler.checked | async" [indeterminate]="allToggler.indeterminate | async" (click)="allToggler.toggle($event)"> -
  • - - {{item}} -
  • + @for (item of data; track item) { +
  • + + {{item}} +
  • + }

    mat-checkbox

    Selected: {{selected2}}
      -
    • - - {{item}} -
    • + @for (item of data; track item) { +
    • + + {{item}} +
    • + }

    Single select with mat-checkbox

    Selected: {{selected3}}
      -
    • - - {{item}} -
    • + @for (item of data; track item) { +
    • + + {{item}} +
    • + }

    with trackBy

    Selected: {{selected4}}
      -
    • - - {{item}} -
    • + @for (item of data; track trackByFn($index)) { +
    • + + {{item}} +
    • + }
    diff --git a/src/components-examples/cdk-experimental/selection/cdk-selection-list/cdk-selection-list-example.ts b/src/components-examples/cdk-experimental/selection/cdk-selection-list/cdk-selection-list-example.ts index ea93bffe5a8a..ab0dedf7f6e6 100644 --- a/src/components-examples/cdk-experimental/selection/cdk-selection-list/cdk-selection-list-example.ts +++ b/src/components-examples/cdk-experimental/selection/cdk-selection-list/cdk-selection-list-example.ts @@ -1,5 +1,5 @@ import {Component} from '@angular/core'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {SelectionChange, CdkSelectionModule} from '@angular/cdk-experimental/selection'; import {MatCheckboxModule} from '@angular/material/checkbox'; @@ -10,7 +10,7 @@ import {MatCheckboxModule} from '@angular/material/checkbox'; selector: 'cdk-selection-list-example', templateUrl: 'cdk-selection-list-example.html', standalone: true, - imports: [CdkSelectionModule, NgFor, MatCheckboxModule, AsyncPipe], + imports: [CdkSelectionModule, MatCheckboxModule, AsyncPipe], }) export class CdkSelectionListExample { data = ELEMENT_NAMES; diff --git a/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.html b/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.html index 0a02078fd51a..984d85a30d29 100644 --- a/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.html +++ b/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.html @@ -1,29 +1,31 @@ - -
    - {{ item }} - - Click to {{ accordionItem.expanded ? 'close' : 'open' }} - -
    -
    - Lorem ipsum dolor, sit amet consectetur adipisicing elit. Perferendis - excepturi incidunt ipsum deleniti labore, tempore non nam doloribus blanditiis - veritatis illo autem iure aliquid ullam rem tenetur deserunt velit culpa? -
    -
    + @for (item of items; track item; let index = $index) { + +
    + {{ item }} + + Click to {{ accordionItem.expanded ? 'close' : 'open' }} + +
    +
    + Lorem ipsum dolor, sit amet consectetur adipisicing elit. Perferendis + excepturi incidunt ipsum deleniti labore, tempore non nam doloribus blanditiis + veritatis illo autem iure aliquid ullam rem tenetur deserunt velit culpa? +
    +
    + }
    diff --git a/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.ts b/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.ts index 8210e1e591a5..2a6f6d75f3af 100644 --- a/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.ts +++ b/src/components-examples/cdk/accordion/cdk-accordion-overview/cdk-accordion-overview-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {CdkAccordionModule} from '@angular/cdk/accordion'; /** @@ -10,7 +9,7 @@ import {CdkAccordionModule} from '@angular/cdk/accordion'; templateUrl: 'cdk-accordion-overview-example.html', styleUrls: ['cdk-accordion-overview-example.css'], standalone: true, - imports: [CdkAccordionModule, NgFor], + imports: [CdkAccordionModule], }) export class CdkAccordionOverviewExample { items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']; diff --git a/src/components-examples/cdk/dialog/cdk-dialog-data/cdk-dialog-data-example-dialog.html b/src/components-examples/cdk/dialog/cdk-dialog-data/cdk-dialog-data-example-dialog.html index 80957156217c..ed8e220bd62f 100644 --- a/src/components-examples/cdk/dialog/cdk-dialog-data/cdk-dialog-data-example-dialog.html +++ b/src/components-examples/cdk/dialog/cdk-dialog-data/cdk-dialog-data-example-dialog.html @@ -3,13 +3,19 @@

    Favorite Animal

    My favorite animal is:
    • - Panda + @if (data.animal === 'panda') { + + } Panda
    • - Unicorn + @if (data.animal === 'unicorn') { + + } Unicorn
    • - Lion + @if (data.animal === 'lion') { + + } Lion
    diff --git a/src/components-examples/cdk/dialog/cdk-dialog-data/cdk-dialog-data-example.ts b/src/components-examples/cdk/dialog/cdk-dialog-data/cdk-dialog-data-example.ts index eae2408e86a5..105ad82c6191 100644 --- a/src/components-examples/cdk/dialog/cdk-dialog-data/cdk-dialog-data-example.ts +++ b/src/components-examples/cdk/dialog/cdk-dialog-data/cdk-dialog-data-example.ts @@ -1,6 +1,5 @@ import {Component, Inject} from '@angular/core'; import {Dialog, DIALOG_DATA, DialogModule} from '@angular/cdk/dialog'; -import {NgIf} from '@angular/common'; export interface DialogData { animal: 'panda' | 'unicorn' | 'lion'; @@ -33,7 +32,6 @@ export class CdkDialogDataExample { templateUrl: 'cdk-dialog-data-example-dialog.html', styleUrls: ['./cdk-dialog-data-example-dialog.css'], standalone: true, - imports: [NgIf], }) export class CdkDialogDataExampleDialog { constructor(@Inject(DIALOG_DATA) public data: DialogData) {} diff --git a/src/components-examples/cdk/dialog/cdk-dialog-overview/cdk-dialog-overview-example.html b/src/components-examples/cdk/dialog/cdk-dialog-overview/cdk-dialog-overview-example.html index 80f3adcbf9e3..8bc87d66ac56 100644 --- a/src/components-examples/cdk/dialog/cdk-dialog-overview/cdk-dialog-overview-example.html +++ b/src/components-examples/cdk/dialog/cdk-dialog-overview/cdk-dialog-overview-example.html @@ -6,7 +6,9 @@
  • -
  • - You chose: {{animal}} -
  • + @if (animal) { +
  • + You chose: {{animal}} +
  • + } diff --git a/src/components-examples/cdk/dialog/cdk-dialog-overview/cdk-dialog-overview-example.ts b/src/components-examples/cdk/dialog/cdk-dialog-overview/cdk-dialog-overview-example.ts index 49828936cdd4..b6cc17829dea 100644 --- a/src/components-examples/cdk/dialog/cdk-dialog-overview/cdk-dialog-overview-example.ts +++ b/src/components-examples/cdk/dialog/cdk-dialog-overview/cdk-dialog-overview-example.ts @@ -1,6 +1,5 @@ import {Component, Inject} from '@angular/core'; import {Dialog, DialogRef, DIALOG_DATA, DialogModule} from '@angular/cdk/dialog'; -import {NgIf} from '@angular/common'; import {FormsModule} from '@angular/forms'; export interface DialogData { @@ -15,7 +14,7 @@ export interface DialogData { selector: 'cdk-dialog-overview-example', templateUrl: 'cdk-dialog-overview-example.html', standalone: true, - imports: [FormsModule, NgIf, DialogModule], + imports: [FormsModule, DialogModule], }) export class CdkDialogOverviewExample { animal: string | undefined; @@ -44,5 +43,8 @@ export class CdkDialogOverviewExample { imports: [FormsModule], }) export class CdkDialogOverviewExampleDialog { - constructor(public dialogRef: DialogRef, @Inject(DIALOG_DATA) public data: DialogData) {} + constructor( + public dialogRef: DialogRef, + @Inject(DIALOG_DATA) public data: DialogData, + ) {} } diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting-group/cdk-drag-drop-connected-sorting-group-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting-group/cdk-drag-drop-connected-sorting-group-example.html index edd8d80438ea..327ae1f986d9 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting-group/cdk-drag-drop-connected-sorting-group-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting-group/cdk-drag-drop-connected-sorting-group-example.html @@ -7,7 +7,9 @@

    To do

    [cdkDropListData]="todo" class="example-list" (cdkDropListDropped)="drop($event)"> -
    {{item}}
    + @for (item of todo; track item) { +
    {{item}}
    + } @@ -19,7 +21,9 @@

    Done

    [cdkDropListData]="done" class="example-list" (cdkDropListDropped)="drop($event)"> -
    {{item}}
    + @for (item of done; track item) { +
    {{item}}
    + } diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting-group/cdk-drag-drop-connected-sorting-group-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting-group/cdk-drag-drop-connected-sorting-group-example.ts index 8b9396684dd6..cae54929724d 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting-group/cdk-drag-drop-connected-sorting-group-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting-group/cdk-drag-drop-connected-sorting-group-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import { CdkDragDrop, CdkDrag, @@ -17,7 +16,7 @@ import { templateUrl: 'cdk-drag-drop-connected-sorting-group-example.html', styleUrls: ['cdk-drag-drop-connected-sorting-group-example.css'], standalone: true, - imports: [CdkDropListGroup, CdkDropList, NgFor, CdkDrag], + imports: [CdkDropListGroup, CdkDropList, CdkDrag], }) export class CdkDragDropConnectedSortingGroupExample { todo = ['Get to work', 'Pick up groceries', 'Go home', 'Fall asleep']; diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting/cdk-drag-drop-connected-sorting-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting/cdk-drag-drop-connected-sorting-example.html index ed67f2935414..44cd97cf460e 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting/cdk-drag-drop-connected-sorting-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting/cdk-drag-drop-connected-sorting-example.html @@ -8,7 +8,9 @@

    To do

    [cdkDropListConnectedTo]="[doneList]" class="example-list" (cdkDropListDropped)="drop($event)"> -
    {{item}}
    + @for (item of todo; track item) { +
    {{item}}
    + } @@ -22,7 +24,9 @@

    Done

    [cdkDropListConnectedTo]="[todoList]" class="example-list" (cdkDropListDropped)="drop($event)"> -
    {{item}}
    + @for (item of done; track item) { +
    {{item}}
    + } diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting/cdk-drag-drop-connected-sorting-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting/cdk-drag-drop-connected-sorting-example.ts index 6287bb5c36a8..00055e1d5d17 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting/cdk-drag-drop-connected-sorting-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-connected-sorting/cdk-drag-drop-connected-sorting-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import { CdkDragDrop, moveItemInArray, @@ -16,7 +15,7 @@ import { templateUrl: 'cdk-drag-drop-connected-sorting-example.html', styleUrls: ['cdk-drag-drop-connected-sorting-example.css'], standalone: true, - imports: [CdkDropList, NgFor, CdkDrag], + imports: [CdkDropList, CdkDrag], }) export class CdkDragDropConnectedSortingExample { todo = ['Get to work', 'Pick up groceries', 'Go home', 'Fall asleep']; diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-placeholder/cdk-drag-drop-custom-placeholder-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-placeholder/cdk-drag-drop-custom-placeholder-example.html index 68994b543234..f0673cd2abe7 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-placeholder/cdk-drag-drop-custom-placeholder-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-placeholder/cdk-drag-drop-custom-placeholder-example.html @@ -1,6 +1,8 @@
    -
    -
    - {{movie}} -
    + @for (movie of movies; track movie) { +
    +
    + {{movie}} +
    + }
    diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-placeholder/cdk-drag-drop-custom-placeholder-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-placeholder/cdk-drag-drop-custom-placeholder-example.ts index 01d0ae213469..6ce72bc70a37 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-placeholder/cdk-drag-drop-custom-placeholder-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-placeholder/cdk-drag-drop-custom-placeholder-example.ts @@ -6,7 +6,6 @@ import { CdkDropList, moveItemInArray, } from '@angular/cdk/drag-drop'; -import {NgFor} from '@angular/common'; /** * @title Drag&Drop custom placeholder @@ -16,7 +15,7 @@ import {NgFor} from '@angular/common'; templateUrl: 'cdk-drag-drop-custom-placeholder-example.html', styleUrls: ['cdk-drag-drop-custom-placeholder-example.css'], standalone: true, - imports: [CdkDropList, NgFor, CdkDrag, CdkDragPlaceholder], + imports: [CdkDropList, CdkDrag, CdkDragPlaceholder], }) export class CdkDragDropCustomPlaceholderExample { movies = [ diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-preview/cdk-drag-drop-custom-preview-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-preview/cdk-drag-drop-custom-preview-example.html index a6a717fb8746..5072331e4076 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-preview/cdk-drag-drop-custom-preview-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-preview/cdk-drag-drop-custom-preview-example.html @@ -1,6 +1,8 @@
    -
    - {{movie.title}} - -
    + @for (movie of movies; track movie) { +
    + {{movie.title}} + +
    + }
    diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-preview/cdk-drag-drop-custom-preview-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-preview/cdk-drag-drop-custom-preview-example.ts index 05c81f1514cd..de89682ba474 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-preview/cdk-drag-drop-custom-preview-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-custom-preview/cdk-drag-drop-custom-preview-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import { CdkDragDrop, CdkDropList, @@ -16,7 +15,7 @@ import { templateUrl: 'cdk-drag-drop-custom-preview-example.html', styleUrls: ['cdk-drag-drop-custom-preview-example.css'], standalone: true, - imports: [CdkDropList, NgFor, CdkDrag, CdkDragPreview], + imports: [CdkDropList, CdkDrag, CdkDragPreview], }) export class CdkDragDropCustomPreviewExample { // tslint:disable:max-line-length diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled-sorting/cdk-drag-drop-disabled-sorting-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled-sorting/cdk-drag-drop-disabled-sorting-example.html index 1e9383b04beb..ee6b133d578b 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled-sorting/cdk-drag-drop-disabled-sorting-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled-sorting/cdk-drag-drop-disabled-sorting-example.html @@ -8,7 +8,9 @@

    Available items

    class="example-list" cdkDropListSortingDisabled (cdkDropListDropped)="drop($event)"> -
    {{item}}
    + @for (item of items; track item) { +
    {{item}}
    + } @@ -20,7 +22,9 @@

    Shopping basket

    [cdkDropListData]="basket" class="example-list" (cdkDropListDropped)="drop($event)"> -
    {{item}}
    + @for (item of basket; track item) { +
    {{item}}
    + } diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled-sorting/cdk-drag-drop-disabled-sorting-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled-sorting/cdk-drag-drop-disabled-sorting-example.ts index 625e2dac3b88..5978eee1d5d0 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled-sorting/cdk-drag-drop-disabled-sorting-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled-sorting/cdk-drag-drop-disabled-sorting-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import { CdkDrag, CdkDragDrop, @@ -17,7 +16,7 @@ import { templateUrl: 'cdk-drag-drop-disabled-sorting-example.html', styleUrls: ['cdk-drag-drop-disabled-sorting-example.css'], standalone: true, - imports: [CdkDropListGroup, CdkDropList, NgFor, CdkDrag], + imports: [CdkDropListGroup, CdkDropList, CdkDrag], }) export class CdkDragDropDisabledSortingExample { items = ['Carrots', 'Tomatoes', 'Onions', 'Apples', 'Avocados']; diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled/cdk-drag-drop-disabled-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled/cdk-drag-drop-disabled-example.html index d258da1b47de..75c0f30f1624 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled/cdk-drag-drop-disabled-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled/cdk-drag-drop-disabled-example.html @@ -1,7 +1,8 @@
    -
    {{item.value}}
    + @for (item of items; track item) { +
    {{item.value}}
    + }
    diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled/cdk-drag-drop-disabled-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled/cdk-drag-drop-disabled-example.ts index 95512519c67e..a9bc78fe7921 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled/cdk-drag-drop-disabled-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-disabled/cdk-drag-drop-disabled-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {CdkDragDrop, CdkDrag, CdkDropList, moveItemInArray} from '@angular/cdk/drag-drop'; -import {NgFor} from '@angular/common'; /** * @title Drag&Drop disabled @@ -10,7 +9,7 @@ import {NgFor} from '@angular/common'; templateUrl: 'cdk-drag-drop-disabled-example.html', styleUrls: ['cdk-drag-drop-disabled-example.css'], standalone: true, - imports: [CdkDropList, NgFor, CdkDrag], + imports: [CdkDropList, CdkDrag], }) export class CdkDragDropDisabledExample { items = [ diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-enter-predicate/cdk-drag-drop-enter-predicate-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-enter-predicate/cdk-drag-drop-enter-predicate-example.html index d8d02e342bb9..258fb3c5d8ce 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-enter-predicate/cdk-drag-drop-enter-predicate-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-enter-predicate/cdk-drag-drop-enter-predicate-example.html @@ -9,11 +9,12 @@

    Available numbers

    class="example-list" (cdkDropListDropped)="drop($event)" [cdkDropListEnterPredicate]="noReturnPredicate"> -
    {{number}}
    + @for (number of all; track number) { +
    {{number}}
    + } @@ -28,11 +29,12 @@

    Even numbers

    class="example-list" (cdkDropListDropped)="drop($event)" [cdkDropListEnterPredicate]="evenPredicate"> -
    {{number}}
    + @for (number of even; track number) { +
    {{number}}
    + } diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-enter-predicate/cdk-drag-drop-enter-predicate-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-enter-predicate/cdk-drag-drop-enter-predicate-example.ts index 0f761795970a..2db8c906b9a2 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-enter-predicate/cdk-drag-drop-enter-predicate-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-enter-predicate/cdk-drag-drop-enter-predicate-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import { CdkDragDrop, moveItemInArray, @@ -16,7 +15,7 @@ import { templateUrl: 'cdk-drag-drop-enter-predicate-example.html', styleUrls: ['cdk-drag-drop-enter-predicate-example.css'], standalone: true, - imports: [CdkDropList, NgFor, CdkDrag], + imports: [CdkDropList, CdkDrag], }) export class CdkDragDropEnterPredicateExample { all = [1, 2, 3, 4, 5, 6, 7, 8, 9]; diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-horizontal-sorting/cdk-drag-drop-horizontal-sorting-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-horizontal-sorting/cdk-drag-drop-horizontal-sorting-example.html index d32505ba1a15..f476de2fa1a2 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-horizontal-sorting/cdk-drag-drop-horizontal-sorting-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-horizontal-sorting/cdk-drag-drop-horizontal-sorting-example.html @@ -1,3 +1,5 @@
    -
    {{timePeriod}}
    + @for (timePeriod of timePeriods; track timePeriod) { +
    {{timePeriod}}
    + }
    diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-horizontal-sorting/cdk-drag-drop-horizontal-sorting-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-horizontal-sorting/cdk-drag-drop-horizontal-sorting-example.ts index 3eb91457a54d..2b6193cba1bf 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-horizontal-sorting/cdk-drag-drop-horizontal-sorting-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-horizontal-sorting/cdk-drag-drop-horizontal-sorting-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {CdkDragDrop, CdkDrag, CdkDropList, moveItemInArray} from '@angular/cdk/drag-drop'; /** @@ -10,7 +9,7 @@ import {CdkDragDrop, CdkDrag, CdkDropList, moveItemInArray} from '@angular/cdk/d templateUrl: 'cdk-drag-drop-horizontal-sorting-example.html', styleUrls: ['cdk-drag-drop-horizontal-sorting-example.css'], standalone: true, - imports: [CdkDropList, NgFor, CdkDrag], + imports: [CdkDropList, CdkDrag], }) export class CdkDragDropHorizontalSortingExample { timePeriods = [ diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-sort-predicate/cdk-drag-drop-sort-predicate-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-sort-predicate/cdk-drag-drop-sort-predicate-example.html index 34c2d6711dc7..1e97c0c37e49 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-sort-predicate/cdk-drag-drop-sort-predicate-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-sort-predicate/cdk-drag-drop-sort-predicate-example.html @@ -3,9 +3,10 @@ class="example-list" (cdkDropListDropped)="drop($event)" [cdkDropListSortPredicate]="sortPredicate"> -
    {{number}}
    + @for (number of numbers; track number) { +
    {{number}}
    + } diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-sort-predicate/cdk-drag-drop-sort-predicate-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-sort-predicate/cdk-drag-drop-sort-predicate-example.ts index 8fa2a25d9692..86f8f2a8edd0 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-sort-predicate/cdk-drag-drop-sort-predicate-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-sort-predicate/cdk-drag-drop-sort-predicate-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {CdkDragDrop, moveItemInArray, CdkDrag, CdkDropList} from '@angular/cdk/drag-drop'; /** @@ -10,7 +9,7 @@ import {CdkDragDrop, moveItemInArray, CdkDrag, CdkDropList} from '@angular/cdk/d templateUrl: 'cdk-drag-drop-sort-predicate-example.html', styleUrls: ['cdk-drag-drop-sort-predicate-example.css'], standalone: true, - imports: [CdkDropList, NgFor, CdkDrag], + imports: [CdkDropList, CdkDrag], }) export class CdkDragDropSortPredicateExample { numbers = [1, 2, 3, 4, 5, 6, 7, 8]; diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-sorting/cdk-drag-drop-sorting-example.html b/src/components-examples/cdk/drag-drop/cdk-drag-drop-sorting/cdk-drag-drop-sorting-example.html index 699c95cf9c7b..d240babbfc3d 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-sorting/cdk-drag-drop-sorting-example.html +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-sorting/cdk-drag-drop-sorting-example.html @@ -1,3 +1,5 @@
    -
    {{movie}}
    + @for (movie of movies; track movie) { +
    {{movie}}
    + }
    diff --git a/src/components-examples/cdk/drag-drop/cdk-drag-drop-sorting/cdk-drag-drop-sorting-example.ts b/src/components-examples/cdk/drag-drop/cdk-drag-drop-sorting/cdk-drag-drop-sorting-example.ts index 35a8e31a51d7..5674fc049ad4 100644 --- a/src/components-examples/cdk/drag-drop/cdk-drag-drop-sorting/cdk-drag-drop-sorting-example.ts +++ b/src/components-examples/cdk/drag-drop/cdk-drag-drop-sorting/cdk-drag-drop-sorting-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {CdkDragDrop, CdkDropList, CdkDrag, moveItemInArray} from '@angular/cdk/drag-drop'; -import {NgFor} from '@angular/common'; /** * @title Drag&Drop sorting @@ -10,7 +9,7 @@ import {NgFor} from '@angular/common'; templateUrl: 'cdk-drag-drop-sorting-example.html', styleUrls: ['cdk-drag-drop-sorting-example.css'], standalone: true, - imports: [CdkDropList, NgFor, CdkDrag], + imports: [CdkDropList, CdkDrag], }) export class CdkDragDropSortingExample { movies = [ diff --git a/src/components-examples/cdk/listbox/cdk-listbox-activedescendant/cdk-listbox-activedescendant-example.html b/src/components-examples/cdk/listbox/cdk-listbox-activedescendant/cdk-listbox-activedescendant-example.html index 26cd1eba7ed9..1cecc7c5f695 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-activedescendant/cdk-listbox-activedescendant-example.html +++ b/src/components-examples/cdk/listbox/cdk-listbox-activedescendant/cdk-listbox-activedescendant-example.html @@ -8,11 +8,9 @@ cdkListboxUseActiveDescendant aria-labelledby="example-spatula-label" class="example-listbox"> -
  • - {{feature}} -
  • + @for (feature of features; track feature) { +
  • {{feature}}
  • + } diff --git a/src/components-examples/cdk/listbox/cdk-listbox-activedescendant/cdk-listbox-activedescendant-example.ts b/src/components-examples/cdk/listbox/cdk-listbox-activedescendant/cdk-listbox-activedescendant-example.ts index 5d1c5f36c88b..5e979318bc79 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-activedescendant/cdk-listbox-activedescendant-example.ts +++ b/src/components-examples/cdk/listbox/cdk-listbox-activedescendant/cdk-listbox-activedescendant-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; /** @title Listbox with aria-activedescendant. */ @@ -9,7 +8,7 @@ import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; templateUrl: 'cdk-listbox-activedescendant-example.html', styleUrls: ['cdk-listbox-activedescendant-example.css'], standalone: true, - imports: [CdkListbox, NgFor, CdkOption], + imports: [CdkListbox, CdkOption], }) export class CdkListboxActivedescendantExample { features = ['Hydrodynamic', 'Port & Starboard Attachments', 'Turbo Drive']; diff --git a/src/components-examples/cdk/listbox/cdk-listbox-compare-with/cdk-listbox-compare-with-example.html b/src/components-examples/cdk/listbox/cdk-listbox-compare-with/cdk-listbox-compare-with-example.html index 088bf43edab2..471dceff9461 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-compare-with/cdk-listbox-compare-with-example.html +++ b/src/components-examples/cdk/listbox/cdk-listbox-compare-with/cdk-listbox-compare-with-example.html @@ -9,14 +9,14 @@ (cdkListboxValueChange)="appointment = $event.value" aria-labelledby="example-appointment-label" class="example-listbox"> -
  • - {{formatTime(time)}} -
  • + @for (time of slots; track time) { +
  • {{formatTime(time)}}
  • + } -

    - Your appointment is scheduled for {{formatAppointment() | json}}  -

    +@if (appointment[0]) { +

    + Your appointment is scheduled for {{formatAppointment() | json}}  +

    +} diff --git a/src/components-examples/cdk/listbox/cdk-listbox-compare-with/cdk-listbox-compare-with-example.ts b/src/components-examples/cdk/listbox/cdk-listbox-compare-with/cdk-listbox-compare-with-example.ts index 9a1e2103c828..fc79ef4ac178 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-compare-with/cdk-listbox-compare-with-example.ts +++ b/src/components-examples/cdk/listbox/cdk-listbox-compare-with/cdk-listbox-compare-with-example.ts @@ -1,5 +1,5 @@ import {Component} from '@angular/core'; -import {NgFor, NgIf, JsonPipe} from '@angular/common'; +import {JsonPipe} from '@angular/common'; import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; const today = new Date(); @@ -19,7 +19,7 @@ const formatter = new Intl.DateTimeFormat(undefined, { templateUrl: 'cdk-listbox-compare-with-example.html', styleUrls: ['cdk-listbox-compare-with-example.css'], standalone: true, - imports: [CdkListbox, NgFor, CdkOption, NgIf, JsonPipe], + imports: [CdkListbox, CdkOption, JsonPipe], }) export class CdkListboxCompareWithExample { slots = [12, 13, 14, 15].map( diff --git a/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.html b/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.html index 5cc648351875..391e26f1a7b2 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.html +++ b/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.html @@ -6,16 +6,18 @@ [formControl]="signCtrl" aria-labelledby="example-zodiac-sign-label" class="example-listbox"> -
  • - {{sign}} -
  • + @for (sign of signs; track sign) { +
  • {{sign}}
  • + } -
    -

    {{error}}

    -
    +@if (invalid | async) { +
    + @for (error of getErrors(); track error) { +

    {{error}}

    + } +
    +}

    Your zodiac sign is: {{signCtrl.value | json}}    diff --git a/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.ts b/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.ts index ff6e9c215d57..a8ca73893fb4 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.ts +++ b/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.ts @@ -2,7 +2,7 @@ import {Component} from '@angular/core'; import {FormControl, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {map} from 'rxjs/operators'; import {Observable} from 'rxjs'; -import {NgFor, NgIf, AsyncPipe, JsonPipe} from '@angular/common'; +import {AsyncPipe, JsonPipe} from '@angular/common'; import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; /** @title Listbox with forms validation. */ @@ -12,16 +12,7 @@ import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; templateUrl: 'cdk-listbox-forms-validation-example.html', styleUrls: ['cdk-listbox-forms-validation-example.css'], standalone: true, - imports: [ - CdkListbox, - FormsModule, - ReactiveFormsModule, - NgFor, - CdkOption, - NgIf, - AsyncPipe, - JsonPipe, - ], + imports: [CdkListbox, FormsModule, ReactiveFormsModule, CdkOption, AsyncPipe, JsonPipe], }) export class CdkListboxFormsValidationExample { signs = [ diff --git a/src/components-examples/cdk/listbox/cdk-listbox-horizontal/cdk-listbox-horizontal-example.html b/src/components-examples/cdk/listbox/cdk-listbox-horizontal/cdk-listbox-horizontal-example.html index 08b362fb333b..5b5e6f19b386 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-horizontal/cdk-listbox-horizontal-example.html +++ b/src/components-examples/cdk/listbox/cdk-listbox-horizontal/cdk-listbox-horizontal-example.html @@ -6,10 +6,8 @@ cdkListboxOrientation="horizontal" aria-labelledby="example-shirt-size-label" class="example-listbox"> -

  • - {{size}} -
  • + @for (size of sizes; track size) { +
  • {{size}}
  • + } diff --git a/src/components-examples/cdk/listbox/cdk-listbox-horizontal/cdk-listbox-horizontal-example.ts b/src/components-examples/cdk/listbox/cdk-listbox-horizontal/cdk-listbox-horizontal-example.ts index d77a424be855..efbdcabce378 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-horizontal/cdk-listbox-horizontal-example.ts +++ b/src/components-examples/cdk/listbox/cdk-listbox-horizontal/cdk-listbox-horizontal-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; /** @title Horizontal listbox */ @@ -9,7 +8,7 @@ import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; templateUrl: 'cdk-listbox-horizontal-example.html', styleUrls: ['cdk-listbox-horizontal-example.css'], standalone: true, - imports: [CdkListbox, NgFor, CdkOption], + imports: [CdkListbox, CdkOption], }) export class CdkListboxHorizontalExample { sizes = ['XS', 'S', 'M', 'L', 'XL']; diff --git a/src/components-examples/cdk/listbox/cdk-listbox-reactive-forms/cdk-listbox-reactive-forms-example.html b/src/components-examples/cdk/listbox/cdk-listbox-reactive-forms/cdk-listbox-reactive-forms-example.html index 49b8588c8ab7..5f102c98f005 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-reactive-forms/cdk-listbox-reactive-forms-example.html +++ b/src/components-examples/cdk/listbox/cdk-listbox-reactive-forms/cdk-listbox-reactive-forms-example.html @@ -7,11 +7,9 @@ [formControl]="languageCtrl" aria-labelledby="example-language-label" class="example-listbox"> -
  • - {{language}} -
  • + @for (language of languages; track language) { +
  • {{language}}
  • + } diff --git a/src/components-examples/cdk/listbox/cdk-listbox-reactive-forms/cdk-listbox-reactive-forms-example.ts b/src/components-examples/cdk/listbox/cdk-listbox-reactive-forms/cdk-listbox-reactive-forms-example.ts index cd39f4c44278..ffa5a9b8d58a 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-reactive-forms/cdk-listbox-reactive-forms-example.ts +++ b/src/components-examples/cdk/listbox/cdk-listbox-reactive-forms/cdk-listbox-reactive-forms-example.ts @@ -1,6 +1,6 @@ import {Component} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgFor, JsonPipe} from '@angular/common'; +import {JsonPipe} from '@angular/common'; import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; /** @title Listbox with reactive forms. */ @@ -10,7 +10,7 @@ import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; templateUrl: 'cdk-listbox-reactive-forms-example.html', styleUrls: ['cdk-listbox-reactive-forms-example.css'], standalone: true, - imports: [CdkListbox, FormsModule, ReactiveFormsModule, NgFor, CdkOption, JsonPipe], + imports: [CdkListbox, FormsModule, ReactiveFormsModule, CdkOption, JsonPipe], }) export class CdkListboxReactiveFormsExample { languages = ['C++', 'Java', 'JavaScript', 'Python', 'TypeScript']; diff --git a/src/components-examples/cdk/listbox/cdk-listbox-template-forms/cdk-listbox-template-forms-example.html b/src/components-examples/cdk/listbox/cdk-listbox-template-forms/cdk-listbox-template-forms-example.html index be65ce12ef62..a342812b74a7 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-template-forms/cdk-listbox-template-forms-example.html +++ b/src/components-examples/cdk/listbox/cdk-listbox-template-forms/cdk-listbox-template-forms-example.html @@ -8,11 +8,9 @@ [(ngModel)]="order" aria-labelledby="example-toppings-label" class="example-listbox"> -
  • - {{topping}} -
  • + @for (topping of toppings; track topping) { +
  • {{topping}}
  • + } diff --git a/src/components-examples/cdk/listbox/cdk-listbox-template-forms/cdk-listbox-template-forms-example.ts b/src/components-examples/cdk/listbox/cdk-listbox-template-forms/cdk-listbox-template-forms-example.ts index 3d429e15272c..d563594683a2 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-template-forms/cdk-listbox-template-forms-example.ts +++ b/src/components-examples/cdk/listbox/cdk-listbox-template-forms/cdk-listbox-template-forms-example.ts @@ -1,5 +1,5 @@ import {Component} from '@angular/core'; -import {NgFor, JsonPipe} from '@angular/common'; +import {JsonPipe} from '@angular/common'; import {FormsModule} from '@angular/forms'; import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; @@ -10,7 +10,7 @@ import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; templateUrl: 'cdk-listbox-template-forms-example.html', styleUrls: ['cdk-listbox-template-forms-example.css'], standalone: true, - imports: [CdkListbox, FormsModule, NgFor, CdkOption, JsonPipe], + imports: [CdkListbox, FormsModule, CdkOption, JsonPipe], }) export class CdkListboxTemplateFormsExample { toppings = ['Extra Cheese', 'Mushrooms', 'Pepperoni', 'Sausage']; diff --git a/src/components-examples/cdk/listbox/cdk-listbox-value-binding/cdk-listbox-value-binding-example.html b/src/components-examples/cdk/listbox/cdk-listbox-value-binding/cdk-listbox-value-binding-example.html index a5ecd604914b..ecc594508f71 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-value-binding/cdk-listbox-value-binding-example.html +++ b/src/components-examples/cdk/listbox/cdk-listbox-value-binding/cdk-listbox-value-binding-example.html @@ -8,11 +8,9 @@ (cdkListboxValueChange)="starter = $event.value" aria-labelledby="example-starter-pokemon-label" class="example-listbox"> -
  • - {{pokemon}} -
  • + @for (pokemon of starters; track pokemon) { +
  • {{pokemon}}
  • + } diff --git a/src/components-examples/cdk/listbox/cdk-listbox-value-binding/cdk-listbox-value-binding-example.ts b/src/components-examples/cdk/listbox/cdk-listbox-value-binding/cdk-listbox-value-binding-example.ts index 3cc0140cf403..df90e254246e 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-value-binding/cdk-listbox-value-binding-example.ts +++ b/src/components-examples/cdk/listbox/cdk-listbox-value-binding/cdk-listbox-value-binding-example.ts @@ -1,5 +1,5 @@ import {Component} from '@angular/core'; -import {NgFor, JsonPipe} from '@angular/common'; +import {JsonPipe} from '@angular/common'; import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; /** @title Listbox with value binding. */ @@ -9,7 +9,7 @@ import {CdkListbox, CdkOption} from '@angular/cdk/listbox'; templateUrl: 'cdk-listbox-value-binding-example.html', styleUrls: ['cdk-listbox-value-binding-example.css'], standalone: true, - imports: [CdkListbox, NgFor, CdkOption, JsonPipe], + imports: [CdkListbox, CdkOption, JsonPipe], }) export class CdkListboxValueBindingExample { starters = ['Sprigatito', 'Fuecoco', 'Quaxly']; diff --git a/src/components-examples/cdk/menu/cdk-menu-standalone-stateful-menu/cdk-menu-standalone-stateful-menu-example.html b/src/components-examples/cdk/menu/cdk-menu-standalone-stateful-menu/cdk-menu-standalone-stateful-menu-example.html index b553bf7a6c1b..5941d6fdf55e 100644 --- a/src/components-examples/cdk/menu/cdk-menu-standalone-stateful-menu/cdk-menu-standalone-stateful-menu-example.html +++ b/src/components-examples/cdk/menu/cdk-menu-standalone-stateful-menu/cdk-menu-standalone-stateful-menu-example.html @@ -21,14 +21,15 @@
    - + @for (size of sizes; track size) { + + }

    diff --git a/src/components-examples/cdk/menu/cdk-menu-standalone-stateful-menu/cdk-menu-standalone-stateful-menu-example.ts b/src/components-examples/cdk/menu/cdk-menu-standalone-stateful-menu/cdk-menu-standalone-stateful-menu-example.ts index e68e5a7baec7..c9ae902bffa7 100644 --- a/src/components-examples/cdk/menu/cdk-menu-standalone-stateful-menu/cdk-menu-standalone-stateful-menu-example.ts +++ b/src/components-examples/cdk/menu/cdk-menu-standalone-stateful-menu/cdk-menu-standalone-stateful-menu-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import { CdkMenu, CdkMenuItem, @@ -20,7 +19,6 @@ import { CdkMenu, CdkMenuItemCheckbox, CdkMenuGroup, - NgFor, CdkMenuItemRadio, CdkMenuItem, ], diff --git a/src/components-examples/cdk/scrolling/cdk-virtual-scroll-window-scrolling/cdk-virtual-scroll-window-scrolling-example.html b/src/components-examples/cdk/scrolling/cdk-virtual-scroll-window-scrolling/cdk-virtual-scroll-window-scrolling-example.html index 0020c02846a5..016b70b3c70d 100644 --- a/src/components-examples/cdk/scrolling/cdk-virtual-scroll-window-scrolling/cdk-virtual-scroll-window-scrolling-example.html +++ b/src/components-examples/cdk/scrolling/cdk-virtual-scroll-window-scrolling/cdk-virtual-scroll-window-scrolling-example.html @@ -1,9 +1,11 @@ - +@if (shouldRun) {
    Content before
    {{item}}
    -
    +} -
    Please open on StackBlitz to see result
    +@if (!shouldRun) { +
    Please open on StackBlitz to see result
    +} diff --git a/src/components-examples/cdk/scrolling/cdk-virtual-scroll-window-scrolling/cdk-virtual-scroll-window-scrolling-example.ts b/src/components-examples/cdk/scrolling/cdk-virtual-scroll-window-scrolling/cdk-virtual-scroll-window-scrolling-example.ts index 85ea301d4074..8b8de163953a 100644 --- a/src/components-examples/cdk/scrolling/cdk-virtual-scroll-window-scrolling/cdk-virtual-scroll-window-scrolling-example.ts +++ b/src/components-examples/cdk/scrolling/cdk-virtual-scroll-window-scrolling/cdk-virtual-scroll-window-scrolling-example.ts @@ -1,5 +1,4 @@ import {ChangeDetectionStrategy, Component, Input} from '@angular/core'; -import {NgIf} from '@angular/common'; import {ScrollingModule} from '@angular/cdk/scrolling'; /** @title Virtual scrolling window */ @@ -9,7 +8,7 @@ import {ScrollingModule} from '@angular/cdk/scrolling'; templateUrl: 'cdk-virtual-scroll-window-scrolling-example.html', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [NgIf, ScrollingModule], + imports: [ScrollingModule], }) export class CdkVirtualScrollWindowScrollingExample { @Input() shouldRun = /(^|.)(stackblitz|webcontainer).(io|com)$/.test(window.location.host); diff --git a/src/components-examples/cdk/stepper/cdk-custom-stepper-without-form/cdk-custom-stepper-without-form-example.ts b/src/components-examples/cdk/stepper/cdk-custom-stepper-without-form/cdk-custom-stepper-without-form-example.ts index d21e092b0381..19d1fb595847 100644 --- a/src/components-examples/cdk/stepper/cdk-custom-stepper-without-form/cdk-custom-stepper-without-form-example.ts +++ b/src/components-examples/cdk/stepper/cdk-custom-stepper-without-form/cdk-custom-stepper-without-form-example.ts @@ -1,6 +1,6 @@ import {Component, forwardRef} from '@angular/core'; import {CdkStepper, CdkStepperModule} from '@angular/cdk/stepper'; -import {NgTemplateOutlet, NgFor} from '@angular/common'; +import {NgTemplateOutlet} from '@angular/common'; /** @title A custom CDK stepper without a form */ @Component({ @@ -19,7 +19,7 @@ export class CdkCustomStepperWithoutFormExample {} styleUrls: ['./example-custom-stepper.css'], providers: [{provide: CdkStepper, useExisting: CustomStepper}], standalone: true, - imports: [NgTemplateOutlet, CdkStepperModule, NgFor], + imports: [NgTemplateOutlet, CdkStepperModule], }) export class CustomStepper extends CdkStepper { selectStepByIndex(index: number): void { diff --git a/src/components-examples/cdk/stepper/cdk-custom-stepper-without-form/example-custom-stepper.html b/src/components-examples/cdk/stepper/cdk-custom-stepper-without-form/example-custom-stepper.html index f3cb23972f5d..625c72b8bf92 100644 --- a/src/components-examples/cdk/stepper/cdk-custom-stepper-without-form/example-custom-stepper.html +++ b/src/components-examples/cdk/stepper/cdk-custom-stepper-without-form/example-custom-stepper.html @@ -7,14 +7,12 @@

    Step {{ selectedIndex + 1 }}/{{ steps.length }}

    - + @for (step of steps; track step; let i = $index) { + + }
    diff --git a/src/components-examples/cdk/stepper/cdk-linear-stepper-with-form/cdk-linear-stepper-with-form-example.ts b/src/components-examples/cdk/stepper/cdk-linear-stepper-with-form/cdk-linear-stepper-with-form-example.ts index 6b422e4a414a..16a8f9a20d04 100644 --- a/src/components-examples/cdk/stepper/cdk-linear-stepper-with-form/cdk-linear-stepper-with-form-example.ts +++ b/src/components-examples/cdk/stepper/cdk-linear-stepper-with-form/cdk-linear-stepper-with-form-example.ts @@ -1,7 +1,7 @@ import {Component, forwardRef} from '@angular/core'; import {CdkStepper, CdkStepperModule} from '@angular/cdk/stepper'; import {FormBuilder, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgTemplateOutlet, NgFor} from '@angular/common'; +import {NgTemplateOutlet} from '@angular/common'; /** @title A custom CDK linear stepper with forms */ @Component({ @@ -39,7 +39,7 @@ export class CdkLinearStepperWithFormExample { styleUrls: ['./example-custom-linear-stepper.css'], providers: [{provide: CdkStepper, useExisting: CustomLinearStepper}], standalone: true, - imports: [NgTemplateOutlet, CdkStepperModule, NgFor], + imports: [NgTemplateOutlet, CdkStepperModule], }) export class CustomLinearStepper extends CdkStepper { selectStepByIndex(index: number): void { diff --git a/src/components-examples/cdk/stepper/cdk-linear-stepper-with-form/example-custom-linear-stepper.html b/src/components-examples/cdk/stepper/cdk-linear-stepper-with-form/example-custom-linear-stepper.html index ec97b13bf0f4..70bc88308cc0 100644 --- a/src/components-examples/cdk/stepper/cdk-linear-stepper-with-form/example-custom-linear-stepper.html +++ b/src/components-examples/cdk/stepper/cdk-linear-stepper-with-form/example-custom-linear-stepper.html @@ -7,14 +7,12 @@

    Step {{selectedIndex + 1}}/{{steps.length}}

    - + @for (step of steps; track step; let i = $index) { + + }
    diff --git a/src/components-examples/cdk/text-field/text-field-autofill-directive/text-field-autofill-directive-example.html b/src/components-examples/cdk/text-field/text-field-autofill-directive/text-field-autofill-directive-example.html index 9942f27a0852..1d2b160fe1ff 100644 --- a/src/components-examples/cdk/text-field/text-field-autofill-directive/text-field-autofill-directive-example.html +++ b/src/components-examples/cdk/text-field/text-field-autofill-directive/text-field-autofill-directive-example.html @@ -2,12 +2,16 @@ First name - Autofilled! + @if (firstNameAutofilled) { + Autofilled! + } Last name - Autofilled! + @if (lastNameAutofilled) { + Autofilled! + } diff --git a/src/components-examples/cdk/text-field/text-field-autofill-directive/text-field-autofill-directive-example.ts b/src/components-examples/cdk/text-field/text-field-autofill-directive/text-field-autofill-directive-example.ts index 73e0fc67cc51..2762b18a9a00 100644 --- a/src/components-examples/cdk/text-field/text-field-autofill-directive/text-field-autofill-directive-example.ts +++ b/src/components-examples/cdk/text-field/text-field-autofill-directive/text-field-autofill-directive-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {MatButtonModule} from '@angular/material/button'; -import {NgIf} from '@angular/common'; import {TextFieldModule} from '@angular/cdk/text-field'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -11,7 +10,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; templateUrl: './text-field-autofill-directive-example.html', styleUrls: ['./text-field-autofill-directive-example.css'], standalone: true, - imports: [MatFormFieldModule, MatInputModule, TextFieldModule, NgIf, MatButtonModule], + imports: [MatFormFieldModule, MatInputModule, TextFieldModule, MatButtonModule], }) export class TextFieldAutofillDirectiveExample { firstNameAutofilled: boolean; diff --git a/src/components-examples/cdk/text-field/text-field-autofill-monitor/text-field-autofill-monitor-example.html b/src/components-examples/cdk/text-field/text-field-autofill-monitor/text-field-autofill-monitor-example.html index e9ae5d687871..22087273e8cd 100644 --- a/src/components-examples/cdk/text-field/text-field-autofill-monitor/text-field-autofill-monitor-example.html +++ b/src/components-examples/cdk/text-field/text-field-autofill-monitor/text-field-autofill-monitor-example.html @@ -2,12 +2,16 @@ First name - Autofilled! + @if (firstNameAutofilled) { + Autofilled! + } Last name - Autofilled! + @if (lastNameAutofilled) { + Autofilled! + } diff --git a/src/components-examples/cdk/text-field/text-field-autofill-monitor/text-field-autofill-monitor-example.ts b/src/components-examples/cdk/text-field/text-field-autofill-monitor/text-field-autofill-monitor-example.ts index 880a0882e534..61026ad8baaa 100644 --- a/src/components-examples/cdk/text-field/text-field-autofill-monitor/text-field-autofill-monitor-example.ts +++ b/src/components-examples/cdk/text-field/text-field-autofill-monitor/text-field-autofill-monitor-example.ts @@ -1,7 +1,6 @@ import {AutofillMonitor} from '@angular/cdk/text-field'; import {AfterViewInit, Component, ElementRef, OnDestroy, ViewChild} from '@angular/core'; import {MatButtonModule} from '@angular/material/button'; -import {NgIf} from '@angular/common'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -11,7 +10,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; templateUrl: './text-field-autofill-monitor-example.html', styleUrls: ['./text-field-autofill-monitor-example.css'], standalone: true, - imports: [MatFormFieldModule, MatInputModule, NgIf, MatButtonModule], + imports: [MatFormFieldModule, MatInputModule, MatButtonModule], }) export class TextFieldAutofillMonitorExample implements AfterViewInit, OnDestroy { @ViewChild('first', {read: ElementRef}) firstName: ElementRef; diff --git a/src/components-examples/material-experimental/popover-edit/popover-edit-mat-table/popover-edit-mat-table-example.html b/src/components-examples/material-experimental/popover-edit/popover-edit-mat-table/popover-edit-mat-table-example.html index 4a4c076025bd..414532d5a1c7 100644 --- a/src/components-examples/material-experimental/popover-edit/popover-edit-mat-table/popover-edit-mat-table-example.html +++ b/src/components-examples/material-experimental/popover-edit/popover-edit-mat-table/popover-edit-mat-table-example.html @@ -70,11 +70,11 @@

    Name

    - + @if (nameEditEnabled) { - + } @@ -99,10 +99,9 @@

    Name

    [ngModel]="[element.type]" (selectionChange)="f.ngSubmit.emit()" aria-label="Element type"> - - {{type}} - + @for (type of TYPES; track type) { + {{type}} + } @@ -155,11 +154,11 @@

    Name

    - - {{fantasyElement}} - + checkboxPosition="before">{{fantasyElement}} + }
    diff --git a/src/components-examples/material-experimental/popover-edit/popover-edit-mat-table/popover-edit-mat-table-example.ts b/src/components-examples/material-experimental/popover-edit/popover-edit-mat-table/popover-edit-mat-table-example.ts index a3aaafd0b58e..1e051a32a336 100644 --- a/src/components-examples/material-experimental/popover-edit/popover-edit-mat-table/popover-edit-mat-table-example.ts +++ b/src/components-examples/material-experimental/popover-edit/popover-edit-mat-table/popover-edit-mat-table-example.ts @@ -5,7 +5,6 @@ import {NgForm, FormsModule} from '@angular/forms'; import {MatSnackBar, MatSnackBarModule} from '@angular/material/snack-bar'; import {BehaviorSubject, Observable} from 'rxjs'; import {MatListModule} from '@angular/material/list'; -import {NgIf, NgFor} from '@angular/common'; import {MatCheckboxModule} from '@angular/material/checkbox'; import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; @@ -218,9 +217,7 @@ const FANTASY_ELEMENTS: readonly FantasyElement[] = [ MatButtonModule, MatIconModule, MatCheckboxModule, - NgIf, MatListModule, - NgFor, MatSnackBarModule, ], }) diff --git a/src/components-examples/material-experimental/selection/mat-selection-list/mat-selection-list-example.html b/src/components-examples/material-experimental/selection/mat-selection-list/mat-selection-list-example.html index bec0b35b1cc5..5c7a9b02ea85 100644 --- a/src/components-examples/material-experimental/selection/mat-selection-list/mat-selection-list-example.html +++ b/src/components-examples/material-experimental/selection/mat-selection-list/mat-selection-list-example.html @@ -5,40 +5,48 @@

    native input

    [checked]="allToggler.checked | async" [indeterminate]="allToggler.indeterminate | async" (click)="allToggler.toggle($event)"> -
  • - - {{item}} -
  • + @for (item of data; track item) { +
  • + + {{item}} +
  • + }

    mat-checkbox

    Selected: {{selected2}}
      -
    • + @for (item of data; track item) { +
    • {{item}}
    • +}

    Single select with mat-checkbox

    Selected: {{selected3}}
      -
    • - - {{item}} -
    • + @for (item of data; track item) { +
    • + + {{item}} +
    • + }

    with trackBy

    Selected: {{selected4}}
      -
    • - - {{item}} -
    • + @for (item of data; track trackByFn(i, item); let i = $index) { +
    • + + {{item}} +
    • + }
    diff --git a/src/components-examples/material-experimental/selection/mat-selection-list/mat-selection-list-example.ts b/src/components-examples/material-experimental/selection/mat-selection-list/mat-selection-list-example.ts index 96c43c5bf9d0..94e9eedb7a3a 100644 --- a/src/components-examples/material-experimental/selection/mat-selection-list/mat-selection-list-example.ts +++ b/src/components-examples/material-experimental/selection/mat-selection-list/mat-selection-list-example.ts @@ -1,7 +1,7 @@ import {SelectionChange} from '@angular/cdk-experimental/selection'; import {Component} from '@angular/core'; import {MatCheckboxModule} from '@angular/material/checkbox'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatSelectionModule} from '@angular/material-experimental/selection'; /** @@ -11,7 +11,7 @@ import {MatSelectionModule} from '@angular/material-experimental/selection'; selector: 'mat-selection-list-example', templateUrl: 'mat-selection-list-example.html', standalone: true, - imports: [MatSelectionModule, NgFor, MatCheckboxModule, AsyncPipe], + imports: [MatSelectionModule, MatCheckboxModule, AsyncPipe], }) export class MatSelectionListExample { data = ELEMENT_NAMES; diff --git a/src/components-examples/material/autocomplete/autocomplete-auto-active-first-option/autocomplete-auto-active-first-option-example.html b/src/components-examples/material/autocomplete/autocomplete-auto-active-first-option/autocomplete-auto-active-first-option-example.html index cfa15480831c..e1abe1ad5a4c 100644 --- a/src/components-examples/material/autocomplete/autocomplete-auto-active-first-option/autocomplete-auto-active-first-option-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-auto-active-first-option/autocomplete-auto-active-first-option-example.html @@ -8,9 +8,9 @@ [formControl]="myControl" [matAutocomplete]="auto"> - - {{option}} - + @for (option of filteredOptions | async; track option) { + {{option}} + } diff --git a/src/components-examples/material/autocomplete/autocomplete-auto-active-first-option/autocomplete-auto-active-first-option-example.ts b/src/components-examples/material/autocomplete/autocomplete-auto-active-first-option/autocomplete-auto-active-first-option-example.ts index a8093b37e76f..8f18898d8903 100644 --- a/src/components-examples/material/autocomplete/autocomplete-auto-active-first-option/autocomplete-auto-active-first-option-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-auto-active-first-option/autocomplete-auto-active-first-option-example.ts @@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Observable} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -21,7 +21,6 @@ import {MatFormFieldModule} from '@angular/material/form-field'; MatInputModule, MatAutocompleteModule, ReactiveFormsModule, - NgFor, AsyncPipe, ], }) diff --git a/src/components-examples/material/autocomplete/autocomplete-display/autocomplete-display-example.html b/src/components-examples/material/autocomplete/autocomplete-display/autocomplete-display-example.html index 455d42ef963b..479304681f7a 100644 --- a/src/components-examples/material/autocomplete/autocomplete-display/autocomplete-display-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-display/autocomplete-display-example.html @@ -3,9 +3,9 @@ Assignee - - {{option.name}} - + @for (option of filteredOptions | async; track option) { + {{option.name}} + } diff --git a/src/components-examples/material/autocomplete/autocomplete-display/autocomplete-display-example.ts b/src/components-examples/material/autocomplete/autocomplete-display/autocomplete-display-example.ts index 5fc1a62c84fe..40394477d82e 100644 --- a/src/components-examples/material/autocomplete/autocomplete-display/autocomplete-display-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-display/autocomplete-display-example.ts @@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Observable} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -25,7 +25,6 @@ export interface User { MatInputModule, MatAutocompleteModule, ReactiveFormsModule, - NgFor, AsyncPipe, ], }) diff --git a/src/components-examples/material/autocomplete/autocomplete-filter/autocomplete-filter-example.html b/src/components-examples/material/autocomplete/autocomplete-filter/autocomplete-filter-example.html index 1562b3c8387b..8ac756c675af 100644 --- a/src/components-examples/material/autocomplete/autocomplete-filter/autocomplete-filter-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-filter/autocomplete-filter-example.html @@ -8,9 +8,9 @@ [formControl]="myControl" [matAutocomplete]="auto"> - - {{option}} - + @for (option of filteredOptions | async; track option) { + {{option}} + } diff --git a/src/components-examples/material/autocomplete/autocomplete-filter/autocomplete-filter-example.ts b/src/components-examples/material/autocomplete/autocomplete-filter/autocomplete-filter-example.ts index 20088741e197..17d9d844e5bf 100644 --- a/src/components-examples/material/autocomplete/autocomplete-filter/autocomplete-filter-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-filter/autocomplete-filter-example.ts @@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Observable} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -21,7 +21,6 @@ import {MatFormFieldModule} from '@angular/material/form-field'; MatInputModule, MatAutocompleteModule, ReactiveFormsModule, - NgFor, AsyncPipe, ], }) diff --git a/src/components-examples/material/autocomplete/autocomplete-harness/autocomplete-harness-example.html b/src/components-examples/material/autocomplete/autocomplete-harness/autocomplete-harness-example.html index 9ec82cd88899..e0af7691b679 100644 --- a/src/components-examples/material/autocomplete/autocomplete-harness/autocomplete-harness-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-harness/autocomplete-harness-example.html @@ -1,5 +1,7 @@ - {{ state.name }} + @for (state of states; track state) { + {{ state.name }} + } diff --git a/src/components-examples/material/autocomplete/autocomplete-harness/autocomplete-harness-example.ts b/src/components-examples/material/autocomplete/autocomplete-harness/autocomplete-harness-example.ts index d3848a54d31b..2dac7916eb30 100644 --- a/src/components-examples/material/autocomplete/autocomplete-harness/autocomplete-harness-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-harness/autocomplete-harness-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; /** @@ -9,7 +8,7 @@ import {MatAutocompleteModule} from '@angular/material/autocomplete'; selector: 'autocomplete-harness-example', templateUrl: 'autocomplete-harness-example.html', standalone: true, - imports: [MatAutocompleteModule, NgFor], + imports: [MatAutocompleteModule], }) export class AutocompleteHarnessExample { states = [ diff --git a/src/components-examples/material/autocomplete/autocomplete-optgroup/autocomplete-optgroup-example.html b/src/components-examples/material/autocomplete/autocomplete-optgroup/autocomplete-optgroup-example.html index 8e0ccdea8130..8181071dec7a 100644 --- a/src/components-examples/material/autocomplete/autocomplete-optgroup/autocomplete-optgroup-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-optgroup/autocomplete-optgroup-example.html @@ -8,11 +8,13 @@ [matAutocomplete]="autoGroup"> - - - {{name}} - - + @for (group of stateGroupOptions | async; track group) { + + @for (name of group.names; track name) { + {{name}} + } + + } diff --git a/src/components-examples/material/autocomplete/autocomplete-optgroup/autocomplete-optgroup-example.ts b/src/components-examples/material/autocomplete/autocomplete-optgroup/autocomplete-optgroup-example.ts index 055013753108..f413f5755fae 100644 --- a/src/components-examples/material/autocomplete/autocomplete-optgroup/autocomplete-optgroup-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-optgroup/autocomplete-optgroup-example.ts @@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core'; import {FormBuilder, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Observable} from 'rxjs'; import {startWith, map} from 'rxjs/operators'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -31,7 +31,6 @@ export const _filter = (opt: string[], value: string): string[] => { MatFormFieldModule, MatInputModule, MatAutocompleteModule, - NgFor, AsyncPipe, ], }) diff --git a/src/components-examples/material/autocomplete/autocomplete-overview/autocomplete-overview-example.html b/src/components-examples/material/autocomplete/autocomplete-overview/autocomplete-overview-example.html index 9a828b98a80f..51c22a153544 100644 --- a/src/components-examples/material/autocomplete/autocomplete-overview/autocomplete-overview-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-overview/autocomplete-overview-example.html @@ -6,11 +6,13 @@ [matAutocomplete]="auto" [formControl]="stateCtrl"> - - - {{state.name}} | - Population: {{state.population}} - + @for (state of filteredStates | async; track state) { + + + {{state.name}} | + Population: {{state.population}} + + } diff --git a/src/components-examples/material/autocomplete/autocomplete-overview/autocomplete-overview-example.ts b/src/components-examples/material/autocomplete/autocomplete-overview/autocomplete-overview-example.ts index e8fefe1dd766..a2ef5ca19243 100644 --- a/src/components-examples/material/autocomplete/autocomplete-overview/autocomplete-overview-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-overview/autocomplete-overview-example.ts @@ -3,7 +3,7 @@ import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Observable} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; import {MatSlideToggleModule} from '@angular/material/slide-toggle'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -28,7 +28,6 @@ export interface State { MatInputModule, MatAutocompleteModule, ReactiveFormsModule, - NgFor, MatSlideToggleModule, AsyncPipe, ], diff --git a/src/components-examples/material/autocomplete/autocomplete-plain-input/autocomplete-plain-input-example.html b/src/components-examples/material/autocomplete/autocomplete-plain-input/autocomplete-plain-input-example.html index 1f94451ba956..d830477d23ca 100644 --- a/src/components-examples/material/autocomplete/autocomplete-plain-input/autocomplete-plain-input-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-plain-input/autocomplete-plain-input-example.html @@ -5,8 +5,8 @@ [matAutocomplete]="auto" class="example-input"> - - {{street}} - + @for (street of filteredStreets | async; track street) { + {{street}} + } diff --git a/src/components-examples/material/autocomplete/autocomplete-plain-input/autocomplete-plain-input-example.ts b/src/components-examples/material/autocomplete/autocomplete-plain-input/autocomplete-plain-input-example.ts index 5e043b281bc4..168a3b18204c 100644 --- a/src/components-examples/material/autocomplete/autocomplete-plain-input/autocomplete-plain-input-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-plain-input/autocomplete-plain-input-example.ts @@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Observable} from 'rxjs'; import {startWith, map} from 'rxjs/operators'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; /** @@ -13,7 +13,7 @@ import {MatAutocompleteModule} from '@angular/material/autocomplete'; templateUrl: 'autocomplete-plain-input-example.html', styleUrls: ['autocomplete-plain-input-example.css'], standalone: true, - imports: [FormsModule, MatAutocompleteModule, ReactiveFormsModule, NgFor, AsyncPipe], + imports: [FormsModule, MatAutocompleteModule, ReactiveFormsModule, AsyncPipe], }) export class AutocompletePlainInputExample implements OnInit { control = new FormControl(''); diff --git a/src/components-examples/material/autocomplete/autocomplete-require-selection/autocomplete-require-selection-example.html b/src/components-examples/material/autocomplete/autocomplete-require-selection/autocomplete-require-selection-example.html index e5c96b37e9d3..e219ae709ab9 100644 --- a/src/components-examples/material/autocomplete/autocomplete-require-selection/autocomplete-require-selection-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-require-selection/autocomplete-require-selection-example.html @@ -12,9 +12,9 @@ (input)="filter()" (focus)="filter()"> - - {{option}} - + @for (option of filteredOptions; track option) { + {{option}} + } diff --git a/src/components-examples/material/autocomplete/autocomplete-require-selection/autocomplete-require-selection-example.ts b/src/components-examples/material/autocomplete/autocomplete-require-selection/autocomplete-require-selection-example.ts index 5da4fc881088..42d322fbfd70 100644 --- a/src/components-examples/material/autocomplete/autocomplete-require-selection/autocomplete-require-selection-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-require-selection/autocomplete-require-selection-example.ts @@ -1,6 +1,6 @@ import {Component, ElementRef, ViewChild} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -19,7 +19,6 @@ import {MatFormFieldModule} from '@angular/material/form-field'; MatInputModule, MatAutocompleteModule, ReactiveFormsModule, - NgFor, AsyncPipe, ], }) diff --git a/src/components-examples/material/autocomplete/autocomplete-simple/autocomplete-simple-example.html b/src/components-examples/material/autocomplete/autocomplete-simple/autocomplete-simple-example.html index a8332e050ee1..c3a57bceb82d 100644 --- a/src/components-examples/material/autocomplete/autocomplete-simple/autocomplete-simple-example.html +++ b/src/components-examples/material/autocomplete/autocomplete-simple/autocomplete-simple-example.html @@ -11,9 +11,9 @@ - - {{option}} - + @for (option of options; track option) { + {{option}} + } diff --git a/src/components-examples/material/autocomplete/autocomplete-simple/autocomplete-simple-example.ts b/src/components-examples/material/autocomplete/autocomplete-simple/autocomplete-simple-example.ts index 18ee25c3dde5..1cd58ba7ceef 100644 --- a/src/components-examples/material/autocomplete/autocomplete-simple/autocomplete-simple-example.ts +++ b/src/components-examples/material/autocomplete/autocomplete-simple/autocomplete-simple-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgFor} from '@angular/common'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -19,7 +18,6 @@ import {MatFormFieldModule} from '@angular/material/form-field'; MatInputModule, MatAutocompleteModule, ReactiveFormsModule, - NgFor, ], }) export class AutocompleteSimpleExample { diff --git a/src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.html b/src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.html index 89f364c1fea8..ff06d1f31192 100644 --- a/src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.html +++ b/src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.html @@ -15,13 +15,15 @@
      -
    • - - {{subtask.name}} - -
    • + @for (subtask of task.subtasks; track subtask) { +
    • + + {{subtask.name}} + +
    • + }
    diff --git a/src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.ts b/src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.ts index 8a9dc89df453..1449ee250f02 100644 --- a/src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.ts +++ b/src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {ThemePalette} from '@angular/material/core'; import {FormsModule} from '@angular/forms'; -import {NgFor} from '@angular/common'; import {MatCheckboxModule} from '@angular/material/checkbox'; export interface Task { @@ -19,7 +18,7 @@ export interface Task { templateUrl: 'checkbox-overview-example.html', styleUrls: ['checkbox-overview-example.css'], standalone: true, - imports: [MatCheckboxModule, NgFor, FormsModule], + imports: [MatCheckboxModule, FormsModule], }) export class CheckboxOverviewExample { task: Task = { diff --git a/src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.html b/src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.html index e8fa8d73bfc3..0e9f4a806f2b 100644 --- a/src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.html +++ b/src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.html @@ -2,21 +2,23 @@ Favorite Fruits - - {{fruit}} - - + @for (fruit of fruits; track fruit) { + + {{fruit}} + + + } - - {{fruit}} - + @for (fruit of filteredFruits | async; track fruit) { + {{fruit}} + } diff --git a/src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.ts b/src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.ts index 9b6a27fad8bb..71b023377968 100644 --- a/src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.ts +++ b/src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.ts @@ -6,7 +6,7 @@ import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips'; import {Observable} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; import {MatIconModule} from '@angular/material/icon'; -import {NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; import {MatFormFieldModule} from '@angular/material/form-field'; import {LiveAnnouncer} from '@angular/cdk/a11y'; @@ -22,7 +22,6 @@ import {LiveAnnouncer} from '@angular/cdk/a11y'; FormsModule, MatFormFieldModule, MatChipsModule, - NgFor, MatIconModule, MatAutocompleteModule, ReactiveFormsModule, diff --git a/src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.html b/src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.html index b695a45e3d31..774899b66afc 100644 --- a/src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.html +++ b/src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.html @@ -1,12 +1,9 @@ - - {{vegetable.name}} - + @for (vegetable of vegetables; track vegetable) { + {{vegetable.name}} + } diff --git a/src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.ts b/src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.ts index 1c5d60a490d0..130f643518cb 100644 --- a/src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.ts +++ b/src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {CdkDragDrop, moveItemInArray, CdkDrag, CdkDropList} from '@angular/cdk/drag-drop'; -import {NgFor} from '@angular/common'; import {MatChipsModule} from '@angular/material/chips'; export interface Vegetable { @@ -15,7 +14,7 @@ export interface Vegetable { templateUrl: 'chips-drag-drop-example.html', styleUrls: ['chips-drag-drop-example.css'], standalone: true, - imports: [MatChipsModule, CdkDropList, NgFor, CdkDrag], + imports: [MatChipsModule, CdkDropList, CdkDrag], }) export class ChipsDragDropExample { vegetables: Vegetable[] = [ diff --git a/src/components-examples/material/chips/chips-form-control/chips-form-control-example.html b/src/components-examples/material/chips/chips-form-control/chips-form-control-example.html index 72631a4b7cd7..d1dfeddd6c2c 100644 --- a/src/components-examples/material/chips/chips-form-control/chips-form-control-example.html +++ b/src/components-examples/material/chips/chips-form-control/chips-form-control-example.html @@ -8,12 +8,14 @@ Video keywords - - {{keyword}} - - + @for (keyword of keywords; track keyword) { + + {{keyword}} + + + } Favorite Fruits - - {{fruit.name}} - - + @for (fruit of fruits; track fruit) { + + {{fruit.name}} + + + } - - {{chip.name}} - - \ No newline at end of file + @for (chip of availableColors; track chip) { + {{chip.name}} + } + diff --git a/src/components-examples/material/chips/chips-stacked/chips-stacked-example.ts b/src/components-examples/material/chips/chips-stacked/chips-stacked-example.ts index 798e825d2c5f..0dde8fe84408 100644 --- a/src/components-examples/material/chips/chips-stacked/chips-stacked-example.ts +++ b/src/components-examples/material/chips/chips-stacked/chips-stacked-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {ThemePalette} from '@angular/material/core'; -import {NgFor} from '@angular/common'; import {MatChipsModule} from '@angular/material/chips'; export interface ChipColor { @@ -16,7 +15,7 @@ export interface ChipColor { templateUrl: 'chips-stacked-example.html', styleUrls: ['chips-stacked-example.css'], standalone: true, - imports: [MatChipsModule, NgFor], + imports: [MatChipsModule], }) export class ChipsStackedExample { availableColors: ChipColor[] = [ diff --git a/src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.html b/src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.html index 34b60d753dee..7d218f08c524 100644 --- a/src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.html +++ b/src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.html @@ -8,8 +8,12 @@ - Invalid start date - Invalid end date + @if (range.controls.start.hasError('matStartDateInvalid')) { + Invalid start date + } + @if (range.controls.end.hasError('matEndDateInvalid')) { + Invalid end date + }

    Selected range: {{range.value | json}}

    diff --git a/src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.ts b/src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.ts index 2074169d3cfa..b1b4d92a3460 100644 --- a/src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.ts +++ b/src/components-examples/material/datepicker/date-range-picker-forms/date-range-picker-forms-example.ts @@ -1,6 +1,6 @@ import {Component} from '@angular/core'; import {FormGroup, FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgIf, JsonPipe} from '@angular/common'; +import {JsonPipe} from '@angular/common'; import {MatDatepickerModule} from '@angular/material/datepicker'; import {MatFormFieldModule} from '@angular/material/form-field'; import {MatNativeDateModule} from '@angular/material/core'; @@ -15,7 +15,6 @@ import {MatNativeDateModule} from '@angular/material/core'; MatDatepickerModule, FormsModule, ReactiveFormsModule, - NgIf, JsonPipe, MatNativeDateModule, ], diff --git a/src/components-examples/material/datepicker/datepicker-events/datepicker-events-example.html b/src/components-examples/material/datepicker/datepicker-events/datepicker-events-example.html index 208548d84935..1dc59fb2450d 100644 --- a/src/components-examples/material/datepicker/datepicker-events/datepicker-events-example.html +++ b/src/components-examples/material/datepicker/datepicker-events/datepicker-events-example.html @@ -8,5 +8,7 @@
    -
    {{e}}
    + @for (e of events; track e) { +
    {{e}}
    + }
    diff --git a/src/components-examples/material/datepicker/datepicker-events/datepicker-events-example.ts b/src/components-examples/material/datepicker/datepicker-events/datepicker-events-example.ts index 55c8a89fe8f3..beed6b8c22ad 100644 --- a/src/components-examples/material/datepicker/datepicker-events/datepicker-events-example.ts +++ b/src/components-examples/material/datepicker/datepicker-events/datepicker-events-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {MatDatepickerInputEvent, MatDatepickerModule} from '@angular/material/datepicker'; -import {NgFor} from '@angular/common'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; import {MatNativeDateModule} from '@angular/material/core'; @@ -11,7 +10,7 @@ import {MatNativeDateModule} from '@angular/material/core'; templateUrl: 'datepicker-events-example.html', styleUrls: ['datepicker-events-example.css'], standalone: true, - imports: [MatFormFieldModule, MatInputModule, MatNativeDateModule, MatDatepickerModule, NgFor], + imports: [MatFormFieldModule, MatInputModule, MatNativeDateModule, MatDatepickerModule], }) export class DatepickerEventsExample { events: string[] = []; diff --git a/src/components-examples/material/dialog/dialog-data/dialog-data-example-dialog.html b/src/components-examples/material/dialog/dialog-data/dialog-data-example-dialog.html index 6d263bacf3c9..25b007c49e65 100644 --- a/src/components-examples/material/dialog/dialog-data/dialog-data-example-dialog.html +++ b/src/components-examples/material/dialog/dialog-data/dialog-data-example-dialog.html @@ -3,13 +3,19 @@

    Favorite Animal

    My favorite animal is:
    • - Panda + @if (data.animal === 'panda') { + + } Panda
    • - Unicorn + @if (data.animal === 'unicorn') { + + } Unicorn
    • - Lion + @if (data.animal === 'lion') { + + } Lion
    diff --git a/src/components-examples/material/dialog/dialog-data/dialog-data-example.ts b/src/components-examples/material/dialog/dialog-data/dialog-data-example.ts index 54a160dc3dea..4b604892a7b2 100644 --- a/src/components-examples/material/dialog/dialog-data/dialog-data-example.ts +++ b/src/components-examples/material/dialog/dialog-data/dialog-data-example.ts @@ -1,6 +1,5 @@ import {Component, Inject} from '@angular/core'; import {MatDialog, MAT_DIALOG_DATA, MatDialogModule} from '@angular/material/dialog'; -import {NgIf} from '@angular/common'; import {MatButtonModule} from '@angular/material/button'; export interface DialogData { @@ -32,7 +31,7 @@ export class DialogDataExample { selector: 'dialog-data-example-dialog', templateUrl: 'dialog-data-example-dialog.html', standalone: true, - imports: [MatDialogModule, NgIf], + imports: [MatDialogModule], }) export class DialogDataExampleDialog { constructor(@Inject(MAT_DIALOG_DATA) public data: DialogData) {} diff --git a/src/components-examples/material/dialog/dialog-overview/dialog-overview-example.html b/src/components-examples/material/dialog/dialog-overview/dialog-overview-example.html index 5e7be5d347ca..c3f033499dad 100644 --- a/src/components-examples/material/dialog/dialog-overview/dialog-overview-example.html +++ b/src/components-examples/material/dialog/dialog-overview/dialog-overview-example.html @@ -8,7 +8,7 @@
  • -
  • - You chose: {{animal}} -
  • + @if (animal) { +
  • You chose: {{animal}}
  • + } diff --git a/src/components-examples/material/dialog/dialog-overview/dialog-overview-example.ts b/src/components-examples/material/dialog/dialog-overview/dialog-overview-example.ts index 218ed8d512fc..84a6739e3ad9 100644 --- a/src/components-examples/material/dialog/dialog-overview/dialog-overview-example.ts +++ b/src/components-examples/material/dialog/dialog-overview/dialog-overview-example.ts @@ -1,6 +1,5 @@ import {Component, Inject} from '@angular/core'; import {MatDialog, MAT_DIALOG_DATA, MatDialogRef, MatDialogModule} from '@angular/material/dialog'; -import {NgIf} from '@angular/common'; import {MatButtonModule} from '@angular/material/button'; import {FormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; @@ -18,14 +17,7 @@ export interface DialogData { selector: 'dialog-overview-example', templateUrl: 'dialog-overview-example.html', standalone: true, - imports: [ - MatFormFieldModule, - MatInputModule, - FormsModule, - MatButtonModule, - NgIf, - MatDialogModule, - ], + imports: [MatFormFieldModule, MatInputModule, FormsModule, MatButtonModule, MatDialogModule], }) export class DialogOverviewExample { animal: string; diff --git a/src/components-examples/material/expansion/expansion-overview/expansion-overview-example.css b/src/components-examples/material/expansion/expansion-overview/expansion-overview-example.css deleted file mode 100644 index 0cf5d9eb3d17..000000000000 --- a/src/components-examples/material/expansion/expansion-overview/expansion-overview-example.css +++ /dev/null @@ -1,3 +0,0 @@ -.mat-mdc-form-field + .mat-mdc-form-field { - margin-left: 8px; -} diff --git a/src/components-examples/material/expansion/expansion-overview/expansion-overview-example.ts b/src/components-examples/material/expansion/expansion-overview/expansion-overview-example.ts index 5903799c42a9..c5acf05bc7be 100644 --- a/src/components-examples/material/expansion/expansion-overview/expansion-overview-example.ts +++ b/src/components-examples/material/expansion/expansion-overview/expansion-overview-example.ts @@ -7,7 +7,6 @@ import {MatExpansionModule} from '@angular/material/expansion'; @Component({ selector: 'expansion-overview-example', templateUrl: 'expansion-overview-example.html', - styleUrls: ['expansion-overview-example.css'], standalone: true, imports: [MatExpansionModule], }) diff --git a/src/components-examples/material/form-field/form-field-error/form-field-error-example.html b/src/components-examples/material/form-field/form-field-error/form-field-error-example.html index 4e19231827fa..56c5be722ebf 100644 --- a/src/components-examples/material/form-field/form-field-error/form-field-error-example.html +++ b/src/components-examples/material/form-field/form-field-error/form-field-error-example.html @@ -2,6 +2,8 @@ Enter your email - {{getErrorMessage()}} + @if (email.invalid) { + {{getErrorMessage()}} + } diff --git a/src/components-examples/material/form-field/form-field-error/form-field-error-example.ts b/src/components-examples/material/form-field/form-field-error/form-field-error-example.ts index 46f771017105..c5a18580672e 100644 --- a/src/components-examples/material/form-field/form-field-error/form-field-error-example.ts +++ b/src/components-examples/material/form-field/form-field-error/form-field-error-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {FormControl, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgIf} from '@angular/common'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -10,7 +9,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; templateUrl: 'form-field-error-example.html', styleUrls: ['form-field-error-example.css'], standalone: true, - imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, NgIf], + imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule], }) export class FormFieldErrorExample { email = new FormControl('', [Validators.required, Validators.email]); diff --git a/src/components-examples/material/grid-list/grid-list-dynamic/grid-list-dynamic-example.html b/src/components-examples/material/grid-list/grid-list-dynamic/grid-list-dynamic-example.html index c79507b49a6f..48eb283308bc 100644 --- a/src/components-examples/material/grid-list/grid-list-dynamic/grid-list-dynamic-example.html +++ b/src/components-examples/material/grid-list/grid-list-dynamic/grid-list-dynamic-example.html @@ -1,9 +1,8 @@ - - {{tile.text}} - + [style.background]="tile.color">{{tile.text}} + } diff --git a/src/components-examples/material/grid-list/grid-list-dynamic/grid-list-dynamic-example.ts b/src/components-examples/material/grid-list/grid-list-dynamic/grid-list-dynamic-example.ts index 6c2c35145277..a48a547a3842 100644 --- a/src/components-examples/material/grid-list/grid-list-dynamic/grid-list-dynamic-example.ts +++ b/src/components-examples/material/grid-list/grid-list-dynamic/grid-list-dynamic-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatGridListModule} from '@angular/material/grid-list'; export interface Tile { @@ -16,7 +15,7 @@ export interface Tile { selector: 'grid-list-dynamic-example', templateUrl: 'grid-list-dynamic-example.html', standalone: true, - imports: [MatGridListModule, NgFor], + imports: [MatGridListModule], }) export class GridListDynamicExample { tiles: Tile[] = [ diff --git a/src/components-examples/material/input/input-clearable/input-clearable-example.html b/src/components-examples/material/input/input-clearable/input-clearable-example.html index 82e3c9fc48cd..3d7d9a985f9d 100644 --- a/src/components-examples/material/input/input-clearable/input-clearable-example.html +++ b/src/components-examples/material/input/input-clearable/input-clearable-example.html @@ -1,7 +1,9 @@ Clearable input - + @if (value) { + + } diff --git a/src/components-examples/material/input/input-clearable/input-clearable-example.ts b/src/components-examples/material/input/input-clearable/input-clearable-example.ts index 326826be3ee7..4daccba02bf0 100644 --- a/src/components-examples/material/input/input-clearable/input-clearable-example.ts +++ b/src/components-examples/material/input/input-clearable/input-clearable-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; -import {NgIf} from '@angular/common'; import {FormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -14,7 +13,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; templateUrl: './input-clearable-example.html', styleUrls: ['./input-clearable-example.css'], standalone: true, - imports: [MatFormFieldModule, MatInputModule, FormsModule, NgIf, MatButtonModule, MatIconModule], + imports: [MatFormFieldModule, MatInputModule, FormsModule, MatButtonModule, MatIconModule], }) export class InputClearableExample { value = 'Clear me'; diff --git a/src/components-examples/material/input/input-error-state-matcher/input-error-state-matcher-example.html b/src/components-examples/material/input/input-error-state-matcher/input-error-state-matcher-example.html index fecd22f0c4bf..a40618bf738d 100644 --- a/src/components-examples/material/input/input-error-state-matcher/input-error-state-matcher-example.html +++ b/src/components-examples/material/input/input-error-state-matcher/input-error-state-matcher-example.html @@ -4,11 +4,11 @@ Errors appear instantly! - - Please enter a valid email address - - - Email is required - + @if (emailFormControl.hasError('email') && !emailFormControl.hasError('required')) { + Please enter a valid email address + } + @if (emailFormControl.hasError('required')) { + Email is required + } diff --git a/src/components-examples/material/input/input-error-state-matcher/input-error-state-matcher-example.ts b/src/components-examples/material/input/input-error-state-matcher/input-error-state-matcher-example.ts index 17d969377565..690a8b6da144 100644 --- a/src/components-examples/material/input/input-error-state-matcher/input-error-state-matcher-example.ts +++ b/src/components-examples/material/input/input-error-state-matcher/input-error-state-matcher-example.ts @@ -8,7 +8,6 @@ import { ReactiveFormsModule, } from '@angular/forms'; import {ErrorStateMatcher} from '@angular/material/core'; -import {NgIf} from '@angular/common'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -26,7 +25,7 @@ export class MyErrorStateMatcher implements ErrorStateMatcher { templateUrl: './input-error-state-matcher-example.html', styleUrls: ['./input-error-state-matcher-example.css'], standalone: true, - imports: [FormsModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule, NgIf], + imports: [FormsModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule], }) export class InputErrorStateMatcherExample { emailFormControl = new FormControl('', [Validators.required, Validators.email]); diff --git a/src/components-examples/material/input/input-errors/input-errors-example.html b/src/components-examples/material/input/input-errors/input-errors-example.html index 12cd2e99961b..bb4afaae5f3e 100644 --- a/src/components-examples/material/input/input-errors/input-errors-example.html +++ b/src/components-examples/material/input/input-errors/input-errors-example.html @@ -2,11 +2,11 @@ Email - - Please enter a valid email address - - - Email is required - + @if (emailFormControl.hasError('email') && !emailFormControl.hasError('required')) { + Please enter a valid email address + } + @if (emailFormControl.hasError('required')) { + Email is required + } diff --git a/src/components-examples/material/input/input-errors/input-errors-example.ts b/src/components-examples/material/input/input-errors/input-errors-example.ts index 6d2a6acfd3a2..c23f6b83ced6 100644 --- a/src/components-examples/material/input/input-errors/input-errors-example.ts +++ b/src/components-examples/material/input/input-errors/input-errors-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {FormControl, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgIf} from '@angular/common'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -12,7 +11,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; templateUrl: 'input-errors-example.html', styleUrls: ['input-errors-example.css'], standalone: true, - imports: [FormsModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule, NgIf], + imports: [FormsModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule], }) export class InputErrorsExample { emailFormControl = new FormControl('', [Validators.required, Validators.email]); diff --git a/src/components-examples/material/list/list-sections/list-sections-example.html b/src/components-examples/material/list/list-sections/list-sections-example.html index 98156571a877..644a37e844d2 100644 --- a/src/components-examples/material/list/list-sections/list-sections-example.html +++ b/src/components-examples/material/list/list-sections/list-sections-example.html @@ -1,15 +1,19 @@
    Folders
    - - folder -
    {{folder.name}}
    -
    {{folder.updated | date}}
    -
    + @for (folder of folders; track folder) { + + folder +
    {{folder.name}}
    +
    {{folder.updated | date}}
    +
    + }
    Notes
    - - note -
    {{note.name}}
    -
    {{note.updated | date}}
    -
    + @for (note of notes; track note) { + + note +
    {{note.name}}
    +
    {{note.updated | date}}
    +
    + }
    diff --git a/src/components-examples/material/list/list-sections/list-sections-example.ts b/src/components-examples/material/list/list-sections/list-sections-example.ts index 0bdbf01af0d6..a6b2bc21ae01 100644 --- a/src/components-examples/material/list/list-sections/list-sections-example.ts +++ b/src/components-examples/material/list/list-sections/list-sections-example.ts @@ -1,7 +1,7 @@ import {Component} from '@angular/core'; import {MatDividerModule} from '@angular/material/divider'; import {MatIconModule} from '@angular/material/icon'; -import {NgFor, DatePipe} from '@angular/common'; +import {DatePipe} from '@angular/common'; import {MatListModule} from '@angular/material/list'; export interface Section { @@ -17,7 +17,7 @@ export interface Section { styleUrls: ['list-sections-example.css'], templateUrl: 'list-sections-example.html', standalone: true, - imports: [MatListModule, NgFor, MatIconModule, MatDividerModule, DatePipe], + imports: [MatListModule, MatIconModule, MatDividerModule, DatePipe], }) export class ListSectionsExample { folders: Section[] = [ diff --git a/src/components-examples/material/list/list-selection/list-selection-example.html b/src/components-examples/material/list/list-selection/list-selection-example.html index d068febecc21..a269256b20a8 100644 --- a/src/components-examples/material/list/list-selection/list-selection-example.html +++ b/src/components-examples/material/list/list-selection/list-selection-example.html @@ -1,7 +1,7 @@ - - {{shoe}} - + @for (shoe of typesOfShoes; track shoe) { + {{shoe}} + }

    diff --git a/src/components-examples/material/list/list-selection/list-selection-example.ts b/src/components-examples/material/list/list-selection/list-selection-example.ts index 2d5c04ecb1a5..2209654a7771 100644 --- a/src/components-examples/material/list/list-selection/list-selection-example.ts +++ b/src/components-examples/material/list/list-selection/list-selection-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatListModule} from '@angular/material/list'; /** @@ -9,7 +8,7 @@ import {MatListModule} from '@angular/material/list'; selector: 'list-selection-example', templateUrl: 'list-selection-example.html', standalone: true, - imports: [MatListModule, NgFor], + imports: [MatListModule], }) export class ListSelectionExample { typesOfShoes: string[] = ['Boots', 'Clogs', 'Loafers', 'Moccasins', 'Sneakers']; diff --git a/src/components-examples/material/list/list-single-selection/list-single-selection-example.html b/src/components-examples/material/list/list-single-selection/list-single-selection-example.html index c08d6106d477..0c653bd3b6da 100644 --- a/src/components-examples/material/list/list-single-selection/list-single-selection-example.html +++ b/src/components-examples/material/list/list-single-selection/list-single-selection-example.html @@ -1,7 +1,7 @@ - - {{shoe}} - + @for (shoe of typesOfShoes; track shoe) { + {{shoe}} + }

    diff --git a/src/components-examples/material/list/list-single-selection/list-single-selection-example.ts b/src/components-examples/material/list/list-single-selection/list-single-selection-example.ts index c9a06a75e45c..c848f921fe8c 100644 --- a/src/components-examples/material/list/list-single-selection/list-single-selection-example.ts +++ b/src/components-examples/material/list/list-single-selection/list-single-selection-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatListModule} from '@angular/material/list'; /** @@ -9,7 +8,7 @@ import {MatListModule} from '@angular/material/list'; selector: 'list-single-selection-example', templateUrl: 'list-single-selection-example.html', standalone: true, - imports: [MatListModule, NgFor], + imports: [MatListModule], }) export class ListSingleSelectionExample { typesOfShoes: string[] = ['Boots', 'Clogs', 'Loafers', 'Moccasins', 'Sneakers']; diff --git a/src/components-examples/material/progress-bar/progress-bar-configurable/progress-bar-configurable-example.html b/src/components-examples/material/progress-bar/progress-bar-configurable/progress-bar-configurable-example.html index 1e658b2cced3..100f7afff8fc 100644 --- a/src/components-examples/material/progress-bar/progress-bar-configurable/progress-bar-configurable-example.html +++ b/src/components-examples/material/progress-bar/progress-bar-configurable/progress-bar-configurable-example.html @@ -35,18 +35,22 @@

    Progress bar configuration

    -
    - - - - -
    -
    - - - - -
    + @if (mode === 'determinate' || mode === 'buffer') { +
    + + + + +
    + } + @if (mode === 'buffer') { +
    + + + + +
    + } diff --git a/src/components-examples/material/progress-bar/progress-bar-configurable/progress-bar-configurable-example.ts b/src/components-examples/material/progress-bar/progress-bar-configurable/progress-bar-configurable-example.ts index 34fccfdc820e..0bf1fb2e69d1 100644 --- a/src/components-examples/material/progress-bar/progress-bar-configurable/progress-bar-configurable-example.ts +++ b/src/components-examples/material/progress-bar/progress-bar-configurable/progress-bar-configurable-example.ts @@ -2,7 +2,6 @@ import {Component} from '@angular/core'; import {ThemePalette} from '@angular/material/core'; import {ProgressBarMode, MatProgressBarModule} from '@angular/material/progress-bar'; import {MatSliderModule} from '@angular/material/slider'; -import {NgIf} from '@angular/common'; import {FormsModule} from '@angular/forms'; import {MatRadioModule} from '@angular/material/radio'; import {MatCardModule} from '@angular/material/card'; @@ -15,14 +14,7 @@ import {MatCardModule} from '@angular/material/card'; templateUrl: 'progress-bar-configurable-example.html', styleUrls: ['progress-bar-configurable-example.css'], standalone: true, - imports: [ - MatCardModule, - MatRadioModule, - FormsModule, - NgIf, - MatSliderModule, - MatProgressBarModule, - ], + imports: [MatCardModule, MatRadioModule, FormsModule, MatSliderModule, MatProgressBarModule], }) export class ProgressBarConfigurableExample { color: ThemePalette = 'primary'; diff --git a/src/components-examples/material/progress-spinner/progress-spinner-configurable/progress-spinner-configurable-example.html b/src/components-examples/material/progress-spinner/progress-spinner-configurable/progress-spinner-configurable-example.html index 8de6e3fdc460..27c9712774d0 100644 --- a/src/components-examples/material/progress-spinner/progress-spinner-configurable/progress-spinner-configurable-example.html +++ b/src/components-examples/material/progress-spinner/progress-spinner-configurable/progress-spinner-configurable-example.html @@ -29,12 +29,14 @@

    Progress spinner configuration

    -
    - - - - -
    + @if (mode === 'determinate') { +
    + + + + +
    + } diff --git a/src/components-examples/material/progress-spinner/progress-spinner-configurable/progress-spinner-configurable-example.ts b/src/components-examples/material/progress-spinner/progress-spinner-configurable/progress-spinner-configurable-example.ts index 9317f7cac678..a6cf3c5a6b6c 100644 --- a/src/components-examples/material/progress-spinner/progress-spinner-configurable/progress-spinner-configurable-example.ts +++ b/src/components-examples/material/progress-spinner/progress-spinner-configurable/progress-spinner-configurable-example.ts @@ -2,7 +2,6 @@ import {Component} from '@angular/core'; import {ThemePalette} from '@angular/material/core'; import {ProgressSpinnerMode, MatProgressSpinnerModule} from '@angular/material/progress-spinner'; import {MatSliderModule} from '@angular/material/slider'; -import {NgIf} from '@angular/common'; import {FormsModule} from '@angular/forms'; import {MatRadioModule} from '@angular/material/radio'; import {MatCardModule} from '@angular/material/card'; @@ -15,14 +14,7 @@ import {MatCardModule} from '@angular/material/card'; templateUrl: 'progress-spinner-configurable-example.html', styleUrls: ['progress-spinner-configurable-example.css'], standalone: true, - imports: [ - MatCardModule, - MatRadioModule, - FormsModule, - NgIf, - MatSliderModule, - MatProgressSpinnerModule, - ], + imports: [MatCardModule, MatRadioModule, FormsModule, MatSliderModule, MatProgressSpinnerModule], }) export class ProgressSpinnerConfigurableExample { color: ThemePalette = 'primary'; diff --git a/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.html b/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.html index 5369faa5589b..2908217637ae 100644 --- a/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.html +++ b/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.html @@ -3,8 +3,8 @@ aria-labelledby="example-radio-group-label" class="example-radio-group" [(ngModel)]="favoriteSeason"> - - {{season}} - + @for (season of seasons; track season) { + {{season}} + }
    Your favorite season is: {{favoriteSeason}}
    diff --git a/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.ts b/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.ts index c2ecf4d85d95..6af67740ee0f 100644 --- a/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.ts +++ b/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {FormsModule} from '@angular/forms'; import {MatRadioModule} from '@angular/material/radio'; @@ -11,7 +10,7 @@ import {MatRadioModule} from '@angular/material/radio'; templateUrl: 'radio-ng-model-example.html', styleUrls: ['radio-ng-model-example.css'], standalone: true, - imports: [MatRadioModule, FormsModule, NgFor], + imports: [MatRadioModule, FormsModule], }) export class RadioNgModelExample { favoriteSeason: string; diff --git a/src/components-examples/material/select/select-custom-trigger/select-custom-trigger-example.html b/src/components-examples/material/select/select-custom-trigger/select-custom-trigger-example.html index e768a8908899..522a6b329b9a 100644 --- a/src/components-examples/material/select/select-custom-trigger/select-custom-trigger-example.html +++ b/src/components-examples/material/select/select-custom-trigger/select-custom-trigger-example.html @@ -3,10 +3,14 @@ {{toppings.value?.[0] || ''}} - - (+{{(toppings.value?.length || 0) - 1}} {{toppings.value?.length === 2 ? 'other' : 'others'}}) - + @if ((toppings.value?.length || 0) > 1) { + + (+{{(toppings.value?.length || 0) - 1}} {{toppings.value?.length === 2 ? 'other' : 'others'}}) + + } - {{topping}} + @for (topping of toppingList; track topping) { + {{topping}} +} diff --git a/src/components-examples/material/select/select-custom-trigger/select-custom-trigger-example.ts b/src/components-examples/material/select/select-custom-trigger/select-custom-trigger-example.ts index 40f94c5e9476..98fbd0cf8f8c 100644 --- a/src/components-examples/material/select/select-custom-trigger/select-custom-trigger-example.ts +++ b/src/components-examples/material/select/select-custom-trigger/select-custom-trigger-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgIf, NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -10,7 +9,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; templateUrl: 'select-custom-trigger-example.html', styleUrls: ['select-custom-trigger-example.css'], standalone: true, - imports: [MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule, NgIf, NgFor], + imports: [MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule], }) export class SelectCustomTriggerExample { toppings = new FormControl(''); diff --git a/src/components-examples/material/select/select-error-state-matcher/select-error-state-matcher-example.html b/src/components-examples/material/select/select-error-state-matcher/select-error-state-matcher-example.html index 9e5f17b1a027..8e4c2143599e 100644 --- a/src/components-examples/material/select/select-error-state-matcher/select-error-state-matcher-example.html +++ b/src/components-examples/material/select/select-error-state-matcher/select-error-state-matcher-example.html @@ -7,10 +7,12 @@

    mat-select

    Invalid option Errors appear instantly! - You must make a selection - - Your selection is invalid - + @if (selected.hasError('required')) { + You must make a selection + } + @if (selected.hasError('pattern') && !selected.hasError('required')) { + Your selection is invalid + }

    native html select

    @@ -21,8 +23,10 @@

    native html select

    - You must make a selection - - Your selection is invalid - + @if (nativeSelectFormControl.hasError('required')) { + You must make a selection + } + @if (nativeSelectFormControl.hasError('pattern') && !nativeSelectFormControl.hasError('required')) { + Your selection is invalid + } diff --git a/src/components-examples/material/select/select-error-state-matcher/select-error-state-matcher-example.ts b/src/components-examples/material/select/select-error-state-matcher/select-error-state-matcher-example.ts index 6b6bdc8e5adb..5d590fc02348 100644 --- a/src/components-examples/material/select/select-error-state-matcher/select-error-state-matcher-example.ts +++ b/src/components-examples/material/select/select-error-state-matcher/select-error-state-matcher-example.ts @@ -9,7 +9,6 @@ import { } from '@angular/forms'; import {ErrorStateMatcher} from '@angular/material/core'; import {MatInputModule} from '@angular/material/input'; -import {NgIf} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -26,14 +25,7 @@ export class MyErrorStateMatcher implements ErrorStateMatcher { selector: 'select-error-state-matcher-example', templateUrl: 'select-error-state-matcher-example.html', standalone: true, - imports: [ - MatFormFieldModule, - MatSelectModule, - FormsModule, - ReactiveFormsModule, - NgIf, - MatInputModule, - ], + imports: [MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule, MatInputModule], }) export class SelectErrorStateMatcherExample { selected = new FormControl('valid', [Validators.required, Validators.pattern('valid')]); diff --git a/src/components-examples/material/select/select-form/select-form-example.html b/src/components-examples/material/select/select-form/select-form-example.html index f2b02b6a4e56..3b04b2847f74 100644 --- a/src/components-examples/material/select/select-form/select-form-example.html +++ b/src/components-examples/material/select/select-form/select-form-example.html @@ -3,9 +3,9 @@

    mat-select

    Favorite food - - {{food.viewValue}} - + @for (food of foods; track food) { + {{food.viewValue}} + }

    Selected food: {{selectedValue}}

    @@ -14,9 +14,9 @@

    native html select

    Favorite car

    Selected car: {{selectedCar}}

    diff --git a/src/components-examples/material/select/select-form/select-form-example.ts b/src/components-examples/material/select/select-form/select-form-example.ts index 5e87a68ea320..e06de0971da4 100644 --- a/src/components-examples/material/select/select-form/select-form-example.ts +++ b/src/components-examples/material/select/select-form/select-form-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {MatInputModule} from '@angular/material/input'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; import {FormsModule} from '@angular/forms'; @@ -22,7 +21,7 @@ interface Car { selector: 'select-form-example', templateUrl: 'select-form-example.html', standalone: true, - imports: [FormsModule, MatFormFieldModule, MatSelectModule, NgFor, MatInputModule], + imports: [FormsModule, MatFormFieldModule, MatSelectModule, MatInputModule], }) export class SelectFormExample { selectedValue: string; diff --git a/src/components-examples/material/select/select-harness/select-harness-example.html b/src/components-examples/material/select/select-harness/select-harness-example.html index e41f610c08d1..687e19334a62 100644 --- a/src/components-examples/material/select/select-harness/select-harness-example.html +++ b/src/components-examples/material/select/select-harness/select-harness-example.html @@ -1,8 +1,8 @@ Favorite food - - {{food.viewValue}} - + @for (food of foods; track food) { + {{food.viewValue}} + } diff --git a/src/components-examples/material/select/select-harness/select-harness-example.ts b/src/components-examples/material/select/select-harness/select-harness-example.ts index 5c7347f61b31..d1ea9f2108fa 100644 --- a/src/components-examples/material/select/select-harness/select-harness-example.ts +++ b/src/components-examples/material/select/select-harness/select-harness-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -10,7 +9,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; selector: 'select-harness-example', templateUrl: 'select-harness-example.html', standalone: true, - imports: [MatFormFieldModule, MatSelectModule, NgFor], + imports: [MatFormFieldModule, MatSelectModule], }) export class SelectHarnessExample { foods = [ diff --git a/src/components-examples/material/select/select-hint-error/select-hint-error-example.html b/src/components-examples/material/select/select-hint-error/select-hint-error-example.html index d10b0d422ea4..75909c429dc0 100644 --- a/src/components-examples/material/select/select-hint-error/select-hint-error-example.html +++ b/src/components-examples/material/select/select-hint-error/select-hint-error-example.html @@ -3,11 +3,13 @@

    mat select

    Favorite animal -- - - {{animal.name}} - + @for (animal of animals; track animal) { + {{animal.name}} + } - Please choose an animal + @if (animalControl.hasError('required')) { + Please choose an animal + } {{animalControl.value?.sound}} @@ -20,9 +22,9 @@

    native html select

    - - This field is required - + @if (selectFormControl.hasError('required')) { + This field is required + } You can pick up your favorite car here diff --git a/src/components-examples/material/select/select-hint-error/select-hint-error-example.ts b/src/components-examples/material/select/select-hint-error/select-hint-error-example.ts index 653d4958ba15..736d88f74557 100644 --- a/src/components-examples/material/select/select-hint-error/select-hint-error-example.ts +++ b/src/components-examples/material/select/select-hint-error/select-hint-error-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {FormControl, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; -import {NgFor, NgIf} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -15,15 +14,7 @@ interface Animal { selector: 'select-hint-error-example', templateUrl: 'select-hint-error-example.html', standalone: true, - imports: [ - MatFormFieldModule, - MatSelectModule, - FormsModule, - ReactiveFormsModule, - NgFor, - NgIf, - MatInputModule, - ], + imports: [MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule, MatInputModule], }) export class SelectHintErrorExample { animalControl = new FormControl(null, Validators.required); diff --git a/src/components-examples/material/select/select-initial-value/select-initial-value-example.html b/src/components-examples/material/select/select-initial-value/select-initial-value-example.html index a1cf4d269b7a..40d617b8346e 100644 --- a/src/components-examples/material/select/select-initial-value/select-initial-value-example.html +++ b/src/components-examples/material/select/select-initial-value/select-initial-value-example.html @@ -3,7 +3,9 @@

    Basic mat-select with initial value

    Favorite Food - {{ option.viewValue }} + @for (option of foods; track option) { + {{ option.viewValue }} + }

    You selected: {{selectedFood}}

    @@ -13,8 +15,10 @@

    Basic native select with initial value

    Favorite Car

    You selected: {{selectedCar}}

    diff --git a/src/components-examples/material/select/select-initial-value/select-initial-value-example.ts b/src/components-examples/material/select/select-initial-value/select-initial-value-example.ts index 0688b7f3539f..dfa6782a0eef 100644 --- a/src/components-examples/material/select/select-initial-value/select-initial-value-example.ts +++ b/src/components-examples/material/select/select-initial-value/select-initial-value-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -22,7 +21,7 @@ interface Car { selector: 'select-initial-value-example', templateUrl: 'select-initial-value-example.html', standalone: true, - imports: [MatFormFieldModule, MatSelectModule, NgFor, MatInputModule, FormsModule], + imports: [MatFormFieldModule, MatSelectModule, MatInputModule, FormsModule], }) export class SelectInitialValueExample { foods: Food[] = [ diff --git a/src/components-examples/material/select/select-multiple/select-multiple-example.html b/src/components-examples/material/select/select-multiple/select-multiple-example.html index 2f617c7221fc..1387a62bd98c 100644 --- a/src/components-examples/material/select/select-multiple/select-multiple-example.html +++ b/src/components-examples/material/select/select-multiple/select-multiple-example.html @@ -1,6 +1,8 @@ Toppings - {{topping}} + @for (topping of toppingList; track topping) { + {{topping}} + } diff --git a/src/components-examples/material/select/select-multiple/select-multiple-example.ts b/src/components-examples/material/select/select-multiple/select-multiple-example.ts index 9d9368ab49ab..e3994c7eeec8 100644 --- a/src/components-examples/material/select/select-multiple/select-multiple-example.ts +++ b/src/components-examples/material/select/select-multiple/select-multiple-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -9,7 +8,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; selector: 'select-multiple-example', templateUrl: 'select-multiple-example.html', standalone: true, - imports: [MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule, NgFor], + imports: [MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule], }) export class SelectMultipleExample { toppings = new FormControl(''); diff --git a/src/components-examples/material/select/select-optgroup/select-optgroup-example.html b/src/components-examples/material/select/select-optgroup/select-optgroup-example.html index 6482720884ee..df813e5aae53 100644 --- a/src/components-examples/material/select/select-optgroup/select-optgroup-example.html +++ b/src/components-examples/material/select/select-optgroup/select-optgroup-example.html @@ -3,12 +3,14 @@

    mat-select

    Pokemon -- None -- - - - {{pokemon.viewValue}} - - + @for (group of pokemonGroups; track group) { + + @for (pokemon of group.pokemon; track pokemon) { + {{pokemon.viewValue}} + } + + } diff --git a/src/components-examples/material/select/select-optgroup/select-optgroup-example.ts b/src/components-examples/material/select/select-optgroup/select-optgroup-example.ts index ee9c68e9a00b..58704a50f630 100644 --- a/src/components-examples/material/select/select-optgroup/select-optgroup-example.ts +++ b/src/components-examples/material/select/select-optgroup/select-optgroup-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -21,14 +20,7 @@ interface PokemonGroup { selector: 'select-optgroup-example', templateUrl: 'select-optgroup-example.html', standalone: true, - imports: [ - MatFormFieldModule, - MatSelectModule, - FormsModule, - ReactiveFormsModule, - NgFor, - MatInputModule, - ], + imports: [MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule, MatInputModule], }) export class SelectOptgroupExample { pokemonControl = new FormControl(''); diff --git a/src/components-examples/material/select/select-overview/select-overview-example.html b/src/components-examples/material/select/select-overview/select-overview-example.html index d7df8280eee0..7c3edf7a3a4a 100644 --- a/src/components-examples/material/select/select-overview/select-overview-example.html +++ b/src/components-examples/material/select/select-overview/select-overview-example.html @@ -2,9 +2,9 @@

    Basic mat-select

    Favorite food - - {{food.viewValue}} - + @for (food of foods; track food) { + {{food.viewValue}} + } diff --git a/src/components-examples/material/select/select-overview/select-overview-example.ts b/src/components-examples/material/select/select-overview/select-overview-example.ts index 99ff745ba3ea..58de4dea6016 100644 --- a/src/components-examples/material/select/select-overview/select-overview-example.ts +++ b/src/components-examples/material/select/select-overview/select-overview-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -17,7 +16,7 @@ interface Food { selector: 'select-overview-example', templateUrl: 'select-overview-example.html', standalone: true, - imports: [MatFormFieldModule, MatSelectModule, NgFor, MatInputModule, FormsModule], + imports: [MatFormFieldModule, MatSelectModule, MatInputModule, FormsModule], }) export class SelectOverviewExample { foods: Food[] = [ diff --git a/src/components-examples/material/select/select-reactive-form/select-reactive-form-example.html b/src/components-examples/material/select/select-reactive-form/select-reactive-form-example.html index cd7458a8e5af..f3b0bd18ceb0 100644 --- a/src/components-examples/material/select/select-reactive-form/select-reactive-form-example.html +++ b/src/components-examples/material/select/select-reactive-form/select-reactive-form-example.html @@ -4,9 +4,9 @@

    mat-select

    Favorite Food None - - {{food.viewValue}} - + @for (food of foods; track food) { + {{food.viewValue}} + }

    Selected: {{foodControl.value}}

    @@ -15,9 +15,9 @@

    Native select

    Favorite Car

    Selected: {{carControl.value}}

    diff --git a/src/components-examples/material/select/select-reactive-form/select-reactive-form-example.ts b/src/components-examples/material/select/select-reactive-form/select-reactive-form-example.ts index 816341b06dff..67f07d8003ba 100644 --- a/src/components-examples/material/select/select-reactive-form/select-reactive-form-example.ts +++ b/src/components-examples/material/select/select-reactive-form/select-reactive-form-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -22,14 +21,7 @@ interface Car { selector: 'select-reactive-form-example', templateUrl: 'select-reactive-form-example.html', standalone: true, - imports: [ - FormsModule, - ReactiveFormsModule, - MatFormFieldModule, - MatSelectModule, - NgFor, - MatInputModule, - ], + imports: [FormsModule, ReactiveFormsModule, MatFormFieldModule, MatSelectModule, MatInputModule], }) export class SelectReactiveFormExample { foods: Food[] = [ diff --git a/src/components-examples/material/select/select-reset/select-reset-example.html b/src/components-examples/material/select/select-reset/select-reset-example.html index e0f734507aab..0b89556937b1 100644 --- a/src/components-examples/material/select/select-reset/select-reset-example.html +++ b/src/components-examples/material/select/select-reset/select-reset-example.html @@ -3,7 +3,9 @@

    mat-select

    State None - {{state}} + @for (state of states; track state) { + {{state}} + } diff --git a/src/components-examples/material/select/select-reset/select-reset-example.ts b/src/components-examples/material/select/select-reset/select-reset-example.ts index 1275ecdad9f2..b1fca8b81469 100644 --- a/src/components-examples/material/select/select-reset/select-reset-example.ts +++ b/src/components-examples/material/select/select-reset/select-reset-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -10,7 +9,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; selector: 'select-reset-example', templateUrl: 'select-reset-example.html', standalone: true, - imports: [MatFormFieldModule, MatSelectModule, NgFor, MatInputModule, FormsModule], + imports: [MatFormFieldModule, MatSelectModule, MatInputModule, FormsModule], }) export class SelectResetExample { states: string[] = [ diff --git a/src/components-examples/material/sidenav/sidenav-autosize/sidenav-autosize-example.html b/src/components-examples/material/sidenav/sidenav-autosize/sidenav-autosize-example.html index f9326a3846f3..98e69a1c2c1d 100644 --- a/src/components-examples/material/sidenav/sidenav-autosize/sidenav-autosize-example.html +++ b/src/components-examples/material/sidenav/sidenav-autosize/sidenav-autosize-example.html @@ -1,7 +1,9 @@

    Auto-resizing sidenav

    -

    Lorem, ipsum dolor sit amet consectetur.

    + @if (showFiller) { +

    Lorem, ipsum dolor sit amet consectetur.

    + } diff --git a/src/components-examples/material/sidenav/sidenav-autosize/sidenav-autosize-example.ts b/src/components-examples/material/sidenav/sidenav-autosize/sidenav-autosize-example.ts index 8d7cc2a368a0..d6eea4d561e3 100644 --- a/src/components-examples/material/sidenav/sidenav-autosize/sidenav-autosize-example.ts +++ b/src/components-examples/material/sidenav/sidenav-autosize/sidenav-autosize-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {MatButtonModule} from '@angular/material/button'; -import {NgIf} from '@angular/common'; import {MatSidenavModule} from '@angular/material/sidenav'; /** @@ -11,7 +10,7 @@ import {MatSidenavModule} from '@angular/material/sidenav'; templateUrl: 'sidenav-autosize-example.html', styleUrls: ['sidenav-autosize-example.css'], standalone: true, - imports: [MatSidenavModule, NgIf, MatButtonModule], + imports: [MatSidenavModule, MatButtonModule], }) export class SidenavAutosizeExample { showFiller = false; diff --git a/src/components-examples/material/sidenav/sidenav-configurable-focus-trap/sidenav-configurable-focus-trap-example.html b/src/components-examples/material/sidenav/sidenav-configurable-focus-trap/sidenav-configurable-focus-trap-example.html index e9542d34307c..e6b0821ca811 100644 --- a/src/components-examples/material/sidenav/sidenav-configurable-focus-trap/sidenav-configurable-focus-trap-example.html +++ b/src/components-examples/material/sidenav/sidenav-configurable-focus-trap/sidenav-configurable-focus-trap-example.html @@ -1,36 +1,39 @@ - - -

    -

    - -

    -
    +@if (shouldRun) { + + +

    +

    + +

    +
    - -

    -

    - - - Over - Side - Push - - - - Default - true - false - - - - Start - End - -

    -

    - -

    -
    -
    + +

    +

    + + + Over + Side + Push + + + + Default + true + false + + + + Start + End + +

    +

    + +

    +
    +
    +} @else { +
    Please open on Stackblitz to see result
    +} -
    Please open on Stackblitz to see result
    diff --git a/src/components-examples/material/sidenav/sidenav-configurable-focus-trap/sidenav-configurable-focus-trap-example.ts b/src/components-examples/material/sidenav/sidenav-configurable-focus-trap/sidenav-configurable-focus-trap-example.ts index f397fcd2d04d..b8361413683c 100644 --- a/src/components-examples/material/sidenav/sidenav-configurable-focus-trap/sidenav-configurable-focus-trap-example.ts +++ b/src/components-examples/material/sidenav/sidenav-configurable-focus-trap/sidenav-configurable-focus-trap-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgIf} from '@angular/common'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MatDrawerMode, MatSidenavModule} from '@angular/material/sidenav'; import {MatRadioModule} from '@angular/material/radio'; @@ -12,14 +11,7 @@ import {ConfigurableFocusTrapFactory, FocusTrapFactory} from '@angular/cdk/a11y' templateUrl: 'sidenav-configurable-focus-trap-example.html', styleUrls: ['sidenav-configurable-focus-trap-example.css'], standalone: true, - imports: [ - NgIf, - MatSidenavModule, - MatButtonModule, - MatRadioModule, - FormsModule, - ReactiveFormsModule, - ], + imports: [MatSidenavModule, MatButtonModule, MatRadioModule, FormsModule, ReactiveFormsModule], providers: [{provide: FocusTrapFactory, useClass: ConfigurableFocusTrapFactory}], }) export class SidenavConfigurableFocusTrapExample { diff --git a/src/components-examples/material/sidenav/sidenav-disable-close/sidenav-disable-close-example.html b/src/components-examples/material/sidenav/sidenav-disable-close/sidenav-disable-close-example.html index 4d861c83410c..fada970cd015 100644 --- a/src/components-examples/material/sidenav/sidenav-disable-close/sidenav-disable-close-example.html +++ b/src/components-examples/material/sidenav/sidenav-disable-close/sidenav-disable-close-example.html @@ -1,13 +1,15 @@ - - -

    -
    +@if (shouldRun) { + + +

    +
    - -

    -

    Closed due to: {{reason}}

    -
    -
    - -
    Please open on Stackblitz to see result
    + +

    +

    Closed due to: {{reason}}

    +
    +
    +} @else { +
    Please open on Stackblitz to see result
    +} diff --git a/src/components-examples/material/sidenav/sidenav-disable-close/sidenav-disable-close-example.ts b/src/components-examples/material/sidenav/sidenav-disable-close/sidenav-disable-close-example.ts index 67361e126f2e..7f21079abbae 100644 --- a/src/components-examples/material/sidenav/sidenav-disable-close/sidenav-disable-close-example.ts +++ b/src/components-examples/material/sidenav/sidenav-disable-close/sidenav-disable-close-example.ts @@ -1,7 +1,6 @@ import {Component, ViewChild} from '@angular/core'; import {MatSidenav, MatSidenavModule} from '@angular/material/sidenav'; import {MatButtonModule} from '@angular/material/button'; -import {NgIf} from '@angular/common'; /** @title Sidenav with custom escape and backdrop click behavior */ @Component({ @@ -9,7 +8,7 @@ import {NgIf} from '@angular/common'; templateUrl: 'sidenav-disable-close-example.html', styleUrls: ['sidenav-disable-close-example.css'], standalone: true, - imports: [NgIf, MatSidenavModule, MatButtonModule], + imports: [MatSidenavModule, MatButtonModule], }) export class SidenavDisableCloseExample { @ViewChild('sidenav') sidenav: MatSidenav; diff --git a/src/components-examples/material/sidenav/sidenav-fixed/sidenav-fixed-example.html b/src/components-examples/material/sidenav/sidenav-fixed/sidenav-fixed-example.html index d43ed7fe251a..9880c28eddb1 100644 --- a/src/components-examples/material/sidenav/sidenav-fixed/sidenav-fixed-example.html +++ b/src/components-examples/material/sidenav/sidenav-fixed/sidenav-fixed-example.html @@ -1,4 +1,4 @@ - +@if (shouldRun) { Header @@ -23,6 +23,6 @@ Footer - - -
    Please open on StackBlitz to see result
    +} @else { +
    Please open on StackBlitz to see result
    +} diff --git a/src/components-examples/material/sidenav/sidenav-fixed/sidenav-fixed-example.ts b/src/components-examples/material/sidenav/sidenav-fixed/sidenav-fixed-example.ts index 893e2080ed17..3ad9ff1e2db2 100644 --- a/src/components-examples/material/sidenav/sidenav-fixed/sidenav-fixed-example.ts +++ b/src/components-examples/material/sidenav/sidenav-fixed/sidenav-fixed-example.ts @@ -6,7 +6,6 @@ import {MatCheckboxModule} from '@angular/material/checkbox'; import {MatSidenavModule} from '@angular/material/sidenav'; import {MatToolbarModule} from '@angular/material/toolbar'; import {MatInputModule} from '@angular/material/input'; -import {NgIf} from '@angular/common'; /** @title Fixed sidenav */ @Component({ @@ -15,7 +14,6 @@ import {NgIf} from '@angular/common'; styleUrls: ['sidenav-fixed-example.css'], standalone: true, imports: [ - NgIf, MatToolbarModule, MatSidenavModule, FormsModule, diff --git a/src/components-examples/material/sidenav/sidenav-mode/sidenav-mode-example.html b/src/components-examples/material/sidenav/sidenav-mode/sidenav-mode-example.html index d26f9dee6fb5..04f8b534ac73 100644 --- a/src/components-examples/material/sidenav/sidenav-mode/sidenav-mode-example.html +++ b/src/components-examples/material/sidenav/sidenav-mode/sidenav-mode-example.html @@ -1,27 +1,30 @@ - - -

    -

    - - - Over - Side - Push - -

    -
    +@if (shouldRun) { + + +

    +

    + + + Over + Side + Push + +

    +
    - -

    -

    - - - Over - Side - Push - -

    -
    -
    + +

    +

    + + + Over + Side + Push + +

    +
    +
    +} @else { +
    Please open on Stackblitz to see result
    +} -
    Please open on Stackblitz to see result
    diff --git a/src/components-examples/material/sidenav/sidenav-mode/sidenav-mode-example.ts b/src/components-examples/material/sidenav/sidenav-mode/sidenav-mode-example.ts index 55412ee2d2df..cd02ec9c7aa2 100644 --- a/src/components-examples/material/sidenav/sidenav-mode/sidenav-mode-example.ts +++ b/src/components-examples/material/sidenav/sidenav-mode/sidenav-mode-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgIf} from '@angular/common'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MatDrawerMode, MatSidenavModule} from '@angular/material/sidenav'; import {MatRadioModule} from '@angular/material/radio'; @@ -11,14 +10,7 @@ import {MatButtonModule} from '@angular/material/button'; templateUrl: 'sidenav-mode-example.html', styleUrls: ['sidenav-mode-example.css'], standalone: true, - imports: [ - NgIf, - MatSidenavModule, - MatButtonModule, - MatRadioModule, - FormsModule, - ReactiveFormsModule, - ], + imports: [MatSidenavModule, MatButtonModule, MatRadioModule, FormsModule, ReactiveFormsModule], }) export class SidenavModeExample { mode = new FormControl('over' as MatDrawerMode); diff --git a/src/components-examples/material/sidenav/sidenav-open-close/sidenav-open-close-example.html b/src/components-examples/material/sidenav/sidenav-open-close/sidenav-open-close-example.html index 82cf9382b03c..f82321e94337 100644 --- a/src/components-examples/material/sidenav/sidenav-open-close/sidenav-open-close-example.html +++ b/src/components-examples/material/sidenav/sidenav-open-close/sidenav-open-close-example.html @@ -1,17 +1,22 @@ - - - Sidenav content - +@if (shouldRun) { + + + Sidenav content + - -

    sidenav.opened

    -

    -

    Events:

    -
    -
    {{e}}
    -
    -
    -
    + +

    sidenav.opened

    +

    +

    Events:

    +
    + @for (e of events; track e) { +
    {{e}}
    + } +
    +
    +
    +} @else { +
    Please open on Stackblitz to see result
    +} -
    Please open on Stackblitz to see result
    diff --git a/src/components-examples/material/sidenav/sidenav-open-close/sidenav-open-close-example.ts b/src/components-examples/material/sidenav/sidenav-open-close/sidenav-open-close-example.ts index b7c095783a7f..c49a7a5521bf 100644 --- a/src/components-examples/material/sidenav/sidenav-open-close/sidenav-open-close-example.ts +++ b/src/components-examples/material/sidenav/sidenav-open-close/sidenav-open-close-example.ts @@ -3,7 +3,6 @@ import {MatButtonModule} from '@angular/material/button'; import {FormsModule} from '@angular/forms'; import {MatCheckboxModule} from '@angular/material/checkbox'; import {MatSidenavModule} from '@angular/material/sidenav'; -import {NgIf, NgFor} from '@angular/common'; /** @title Sidenav open & close behavior */ @Component({ @@ -11,7 +10,7 @@ import {NgIf, NgFor} from '@angular/common'; templateUrl: 'sidenav-open-close-example.html', styleUrls: ['sidenav-open-close-example.css'], standalone: true, - imports: [NgIf, MatSidenavModule, MatCheckboxModule, FormsModule, MatButtonModule, NgFor], + imports: [MatSidenavModule, MatCheckboxModule, FormsModule, MatButtonModule], }) export class SidenavOpenCloseExample { events: string[] = []; diff --git a/src/components-examples/material/sidenav/sidenav-overview/sidenav-overview-example.html b/src/components-examples/material/sidenav/sidenav-overview/sidenav-overview-example.html index bb50d519621e..acbdbe728516 100644 --- a/src/components-examples/material/sidenav/sidenav-overview/sidenav-overview-example.html +++ b/src/components-examples/material/sidenav/sidenav-overview/sidenav-overview-example.html @@ -1,6 +1,8 @@ - - Sidenav content - Main content - - -
    Please open on Stackblitz to see result
    +@if (shouldRun) { + + Sidenav content + Main content + +} @else { +
    Please open on Stackblitz to see result
    +} diff --git a/src/components-examples/material/sidenav/sidenav-overview/sidenav-overview-example.ts b/src/components-examples/material/sidenav/sidenav-overview/sidenav-overview-example.ts index 76bd2bd42a80..b9ee6ac6ac98 100644 --- a/src/components-examples/material/sidenav/sidenav-overview/sidenav-overview-example.ts +++ b/src/components-examples/material/sidenav/sidenav-overview/sidenav-overview-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {MatSidenavModule} from '@angular/material/sidenav'; -import {NgIf} from '@angular/common'; /** @title Basic sidenav */ @Component({ @@ -8,7 +7,7 @@ import {NgIf} from '@angular/common'; templateUrl: 'sidenav-overview-example.html', styleUrls: ['sidenav-overview-example.css'], standalone: true, - imports: [NgIf, MatSidenavModule], + imports: [MatSidenavModule], }) export class SidenavOverviewExample { shouldRun = /(^|.)(stackblitz|webcontainer).(io|com)$/.test(window.location.host); diff --git a/src/components-examples/material/sidenav/sidenav-position/sidenav-position-example.html b/src/components-examples/material/sidenav/sidenav-position/sidenav-position-example.html index d45f0e8cb0a1..3319e1452401 100644 --- a/src/components-examples/material/sidenav/sidenav-position/sidenav-position-example.html +++ b/src/components-examples/material/sidenav/sidenav-position/sidenav-position-example.html @@ -1,7 +1,9 @@ - - Start content - End content - Implicit main content - - -
    Please open on Stackblitz to see result
    +@if (shouldRun) { + + Start content + End content + Implicit main content + +} @else { +
    Please open on Stackblitz to see result
    +} diff --git a/src/components-examples/material/sidenav/sidenav-position/sidenav-position-example.ts b/src/components-examples/material/sidenav/sidenav-position/sidenav-position-example.ts index 3169bcaf54d0..250d7611486b 100644 --- a/src/components-examples/material/sidenav/sidenav-position/sidenav-position-example.ts +++ b/src/components-examples/material/sidenav/sidenav-position/sidenav-position-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {MatSidenavModule} from '@angular/material/sidenav'; -import {NgIf} from '@angular/common'; /** @title Implicit main content with two sidenavs */ @Component({ @@ -8,7 +7,7 @@ import {NgIf} from '@angular/common'; templateUrl: 'sidenav-position-example.html', styleUrls: ['sidenav-position-example.css'], standalone: true, - imports: [NgIf, MatSidenavModule], + imports: [MatSidenavModule], }) export class SidenavPositionExample { shouldRun = /(^|.)(stackblitz|webcontainer).(io|com)$/.test(window.location.host); diff --git a/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.html b/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.html index b12947dfd237..7a51a65fc95f 100644 --- a/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.html +++ b/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.html @@ -1,22 +1,28 @@ -
    - - -

    Responsive App

    -
    +@if (shouldRun) { +
    + + +

    Responsive App

    +
    - - - - {{nav}} - - + + + + @for (nav of fillerNav; track nav) { + {{nav}} + } + + - -

    {{content}}

    -
    -
    -
    - -
    Please open on Stackblitz to see result
    + + @for (content of fillerContent; track content) { +

    {{content}}

    + } +
    + +
    +} @else { +
    Please open on Stackblitz to see result
    +} diff --git a/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.ts b/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.ts index d5953f61b831..89287e19af34 100644 --- a/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.ts +++ b/src/components-examples/material/sidenav/sidenav-responsive/sidenav-responsive-example.ts @@ -5,7 +5,6 @@ import {MatSidenavModule} from '@angular/material/sidenav'; import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; import {MatToolbarModule} from '@angular/material/toolbar'; -import {NgIf, NgFor} from '@angular/common'; /** @title Responsive sidenav */ @Component({ @@ -13,15 +12,7 @@ import {NgIf, NgFor} from '@angular/common'; templateUrl: 'sidenav-responsive-example.html', styleUrls: ['sidenav-responsive-example.css'], standalone: true, - imports: [ - NgIf, - MatToolbarModule, - MatButtonModule, - MatIconModule, - MatSidenavModule, - MatListModule, - NgFor, - ], + imports: [MatToolbarModule, MatButtonModule, MatIconModule, MatSidenavModule, MatListModule], }) export class SidenavResponsiveExample implements OnDestroy { mobileQuery: MediaQueryList; diff --git a/src/components-examples/material/sort/sort-harness/sort-harness-example.html b/src/components-examples/material/sort/sort-harness/sort-harness-example.html index 377a0bc51923..b269a5ea4d65 100644 --- a/src/components-examples/material/sort/sort-harness/sort-harness-example.html +++ b/src/components-examples/material/sort/sort-harness/sort-harness-example.html @@ -7,11 +7,13 @@ Protein - - {{dessert.name}} - {{dessert.calories}} - {{dessert.fat}} - {{dessert.carbs}} - {{dessert.protein}} - + @for (dessert of sortedData; track dessert) { + + {{dessert.name}} + {{dessert.calories}} + {{dessert.fat}} + {{dessert.carbs}} + {{dessert.protein}} + + } diff --git a/src/components-examples/material/sort/sort-harness/sort-harness-example.ts b/src/components-examples/material/sort/sort-harness/sort-harness-example.ts index 10f8833a8ca5..90fad6b82d64 100644 --- a/src/components-examples/material/sort/sort-harness/sort-harness-example.ts +++ b/src/components-examples/material/sort/sort-harness/sort-harness-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {Sort, MatSortModule} from '@angular/material/sort'; -import {NgFor} from '@angular/common'; /** * @title Testing with MatSortHarness @@ -9,7 +8,7 @@ import {NgFor} from '@angular/common'; selector: 'sort-harness-example', templateUrl: 'sort-harness-example.html', standalone: true, - imports: [MatSortModule, NgFor], + imports: [MatSortModule], }) export class SortHarnessExample { disableThirdHeader = false; diff --git a/src/components-examples/material/sort/sort-overview/sort-overview-example.html b/src/components-examples/material/sort/sort-overview/sort-overview-example.html index 2b970af18c6a..94591483711a 100644 --- a/src/components-examples/material/sort/sort-overview/sort-overview-example.html +++ b/src/components-examples/material/sort/sort-overview/sort-overview-example.html @@ -7,11 +7,13 @@ Protein (g) - - {{dessert.name}} - {{dessert.calories}} - {{dessert.fat}} - {{dessert.carbs}} - {{dessert.protein}} - + @for (dessert of sortedData; track dessert) { + + {{dessert.name}} + {{dessert.calories}} + {{dessert.fat}} + {{dessert.carbs}} + {{dessert.protein}} + + } diff --git a/src/components-examples/material/sort/sort-overview/sort-overview-example.ts b/src/components-examples/material/sort/sort-overview/sort-overview-example.ts index f233e5ac556f..4a42ae23586a 100644 --- a/src/components-examples/material/sort/sort-overview/sort-overview-example.ts +++ b/src/components-examples/material/sort/sort-overview/sort-overview-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {Sort, MatSortModule} from '@angular/material/sort'; -import {NgFor} from '@angular/common'; export interface Dessert { calories: number; @@ -18,7 +17,7 @@ export interface Dessert { templateUrl: 'sort-overview-example.html', styleUrls: ['sort-overview-example.css'], standalone: true, - imports: [MatSortModule, NgFor], + imports: [MatSortModule], }) export class SortOverviewExample { desserts: Dessert[] = [ diff --git a/src/components-examples/material/stepper/stepper-intl/stepper-intl-example.html b/src/components-examples/material/stepper/stepper-intl/stepper-intl-example.html index 07bb9f8670a3..c108f1673094 100644 --- a/src/components-examples/material/stepper/stepper-intl/stepper-intl-example.html +++ b/src/components-examples/material/stepper/stepper-intl/stepper-intl-example.html @@ -4,12 +4,11 @@ class="demo-radio-group" [(ngModel)]="optionalLabelText" (ngModelChange)="updateOptionalLabel()"> - - {{optionalLabelTextChoice}} - + @for (optionalLabelTextChoice of optionalLabelTextChoices; track optionalLabelTextChoice) { + {{optionalLabelTextChoice}} + } diff --git a/src/components-examples/material/stepper/stepper-intl/stepper-intl-example.ts b/src/components-examples/material/stepper/stepper-intl/stepper-intl-example.ts index bbaf8c8b4a76..305f4ff45daa 100644 --- a/src/components-examples/material/stepper/stepper-intl/stepper-intl-example.ts +++ b/src/components-examples/material/stepper/stepper-intl/stepper-intl-example.ts @@ -4,7 +4,6 @@ import {MatStepperIntl, MatStepperModule} from '@angular/material/stepper'; import {MatButtonModule} from '@angular/material/button'; import {MatInputModule} from '@angular/material/input'; import {MatFormFieldModule} from '@angular/material/form-field'; -import {NgFor} from '@angular/common'; import {MatRadioModule} from '@angular/material/radio'; @Injectable() @@ -25,7 +24,6 @@ export class StepperIntl extends MatStepperIntl { imports: [ MatRadioModule, FormsModule, - NgFor, MatStepperModule, ReactiveFormsModule, MatFormFieldModule, @@ -43,7 +41,10 @@ export class StepperIntlExample { secondCtrl: ['', Validators.required], }); - constructor(private _formBuilder: FormBuilder, private _matStepperIntl: MatStepperIntl) {} + constructor( + private _formBuilder: FormBuilder, + private _matStepperIntl: MatStepperIntl, + ) {} updateOptionalLabel() { this._matStepperIntl.optionalLabel = this.optionalLabelText; diff --git a/src/components-examples/material/stepper/stepper-responsive/stepper-responsive-example.html b/src/components-examples/material/stepper/stepper-responsive/stepper-responsive-example.html index 3db8423dcf64..cba6751334d8 100644 --- a/src/components-examples/material/stepper/stepper-responsive/stepper-responsive-example.html +++ b/src/components-examples/material/stepper/stepper-responsive/stepper-responsive-example.html @@ -1,7 +1,11 @@ - -
    Make your screen smaller to see a vertical stepper
    -
    Make your screen larger to see a horizontal stepper
    -
    +@switch (stepperOrientation | async) { + @case ('horizontal') { +
    Make your screen smaller to see a vertical stepper
    + } + @case ('vertical') { +
    Make your screen larger to see a horizontal stepper
    + } +} ; - constructor(private _formBuilder: FormBuilder, breakpointObserver: BreakpointObserver) { + constructor( + private _formBuilder: FormBuilder, + breakpointObserver: BreakpointObserver, + ) { this.stepperOrientation = breakpointObserver .observe('(min-width: 800px)') .pipe(map(({matches}) => (matches ? 'horizontal' : 'vertical'))); diff --git a/src/components-examples/material/table/table-dynamic-columns/table-dynamic-columns-example.html b/src/components-examples/material/table/table-dynamic-columns/table-dynamic-columns-example.html index 9d2fcac7ac34..11f1e22047a7 100644 --- a/src/components-examples/material/table/table-dynamic-columns/table-dynamic-columns-example.html +++ b/src/components-examples/material/table/table-dynamic-columns/table-dynamic-columns-example.html @@ -3,10 +3,12 @@ - - - - + @for (column of displayedColumns; track column) { + + + + + } diff --git a/src/components-examples/material/table/table-dynamic-columns/table-dynamic-columns-example.ts b/src/components-examples/material/table/table-dynamic-columns/table-dynamic-columns-example.ts index a89b508d9976..acb4b6dd04d9 100644 --- a/src/components-examples/material/table/table-dynamic-columns/table-dynamic-columns-example.ts +++ b/src/components-examples/material/table/table-dynamic-columns/table-dynamic-columns-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatTableModule} from '@angular/material/table'; import {MatButtonModule} from '@angular/material/button'; @@ -31,7 +30,7 @@ const ELEMENT_DATA: PeriodicElement[] = [ styleUrls: ['table-dynamic-columns-example.css'], templateUrl: 'table-dynamic-columns-example.html', standalone: true, - imports: [MatButtonModule, MatTableModule, NgFor], + imports: [MatButtonModule, MatTableModule], }) export class TableDynamicColumnsExample { displayedColumns: string[] = ['name', 'weight', 'symbol', 'position']; diff --git a/src/components-examples/material/table/table-expandable-rows/table-expandable-rows-example.html b/src/components-examples/material/table/table-expandable-rows/table-expandable-rows-example.html index 132dcd9f3f2f..2b3080096152 100644 --- a/src/components-examples/material/table/table-expandable-rows/table-expandable-rows-example.html +++ b/src/components-examples/material/table/table-expandable-rows/table-expandable-rows-example.html @@ -1,16 +1,21 @@
    {{column}} {{element[column]}} {{column}} {{element[column]}}
    - - - - + @for (column of columnsToDisplay; track column) { + + + + + } diff --git a/src/components-examples/material/table/table-expandable-rows/table-expandable-rows-example.ts b/src/components-examples/material/table/table-expandable-rows/table-expandable-rows-example.ts index 27f8278cc003..3d2ee793e40a 100644 --- a/src/components-examples/material/table/table-expandable-rows/table-expandable-rows-example.ts +++ b/src/components-examples/material/table/table-expandable-rows/table-expandable-rows-example.ts @@ -2,7 +2,6 @@ import {Component} from '@angular/core'; import {animate, state, style, transition, trigger} from '@angular/animations'; import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; -import {NgFor, NgIf} from '@angular/common'; import {MatTableModule} from '@angular/material/table'; /** @@ -20,7 +19,7 @@ import {MatTableModule} from '@angular/material/table'; ]), ], standalone: true, - imports: [MatTableModule, NgFor, MatButtonModule, NgIf, MatIconModule], + imports: [MatTableModule, MatButtonModule, MatIconModule], }) export class TableExpandableRowsExample { dataSource = ELEMENT_DATA; diff --git a/src/components-examples/material/table/table-generated-columns/table-generated-columns-example.html b/src/components-examples/material/table/table-generated-columns/table-generated-columns-example.html index c1b5fa29128f..110b906e2b9f 100644 --- a/src/components-examples/material/table/table-generated-columns/table-generated-columns-example.html +++ b/src/components-examples/material/table/table-generated-columns/table-generated-columns-example.html @@ -1,12 +1,14 @@
    {{column}} {{element[column]}} {{column}} {{element[column]}}  
    - - - - + @for (column of columns; track column) { + + + + + } diff --git a/src/components-examples/material/table/table-generated-columns/table-generated-columns-example.ts b/src/components-examples/material/table/table-generated-columns/table-generated-columns-example.ts index b2916d90fa68..4689722972ac 100644 --- a/src/components-examples/material/table/table-generated-columns/table-generated-columns-example.ts +++ b/src/components-examples/material/table/table-generated-columns/table-generated-columns-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatTableModule} from '@angular/material/table'; export interface PeriodicElement { @@ -23,14 +22,14 @@ const ELEMENT_DATA: PeriodicElement[] = [ ]; /** - * @title Table with columns defined using ngFor instead of statically written in the template. + * @title Table with columns defined using a for loop instead of statically written in the template. */ @Component({ selector: 'table-generated-columns-example', styleUrls: ['table-generated-columns-example.css'], templateUrl: 'table-generated-columns-example.html', standalone: true, - imports: [MatTableModule, NgFor], + imports: [MatTableModule], }) export class TableGeneratedColumnsExample { columns = [ diff --git a/src/components-examples/material/table/table-http/table-http-example.html b/src/components-examples/material/table/table-http/table-http-example.html index 355ae60b0ff2..a30712cafa22 100644 --- a/src/components-examples/material/table/table-http/table-http-example.html +++ b/src/components-examples/material/table/table-http/table-http-example.html @@ -1,11 +1,16 @@
    -
    - -
    - GitHub's API rate limit has been reached. It will be reset in one minute. + @if (isLoadingResults || isRateLimitReached) { +
    + @if (isLoadingResults) { + + } + @if (isRateLimitReached) { +
    + GitHub's API rate limit has been reached. It will be reset in one minute. +
    + }
    -
    + }
    diff --git a/src/components-examples/material/table/table-http/table-http-example.ts b/src/components-examples/material/table/table-http/table-http-example.ts index 168367832c73..daf8dc01f8c0 100644 --- a/src/components-examples/material/table/table-http/table-http-example.ts +++ b/src/components-examples/material/table/table-http/table-http-example.ts @@ -6,7 +6,7 @@ import {merge, Observable, of as observableOf} from 'rxjs'; import {catchError, map, startWith, switchMap} from 'rxjs/operators'; import {MatTableModule} from '@angular/material/table'; import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; -import {NgIf, DatePipe} from '@angular/common'; +import {DatePipe} from '@angular/common'; /** * @title Table retrieving data through HTTP @@ -16,14 +16,7 @@ import {NgIf, DatePipe} from '@angular/common'; styleUrls: ['table-http-example.css'], templateUrl: 'table-http-example.html', standalone: true, - imports: [ - NgIf, - MatProgressSpinnerModule, - MatTableModule, - MatSortModule, - MatPaginatorModule, - DatePipe, - ], + imports: [MatProgressSpinnerModule, MatTableModule, MatSortModule, MatPaginatorModule, DatePipe], }) export class TableHttpExample implements AfterViewInit { displayedColumns: string[] = ['created', 'state', 'number', 'title']; diff --git a/src/components-examples/material/table/table-row-binding/table-row-binding-example.html b/src/components-examples/material/table/table-row-binding/table-row-binding-example.html index d8ecfda58fd4..26e24ab03718 100644 --- a/src/components-examples/material/table/table-row-binding/table-row-binding-example.html +++ b/src/components-examples/material/table/table-row-binding/table-row-binding-example.html @@ -38,12 +38,12 @@

    -
    - Clicked rows will be logged here -
    +@if (!clickedRows.size) { +
    Clicked rows will be logged here
    +}
      -
    • - Clicked on {{clickedRow.name}} -
    • + @for (clickedRow of clickedRows; track clickedRow) { +
    • Clicked on {{clickedRow.name}}
    • + }
    diff --git a/src/components-examples/material/table/table-row-binding/table-row-binding-example.ts b/src/components-examples/material/table/table-row-binding/table-row-binding-example.ts index bf6d22faa22e..4b5f58f6a236 100644 --- a/src/components-examples/material/table/table-row-binding/table-row-binding-example.ts +++ b/src/components-examples/material/table/table-row-binding/table-row-binding-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgIf, NgFor} from '@angular/common'; import {MatTableModule} from '@angular/material/table'; export interface PeriodicElement { @@ -30,7 +29,7 @@ const ELEMENT_DATA: PeriodicElement[] = [ styleUrls: ['table-row-binding-example.css'], templateUrl: 'table-row-binding-example.html', standalone: true, - imports: [MatTableModule, NgIf, NgFor], + imports: [MatTableModule], }) export class TableRowBindingExample { displayedColumns: string[] = ['position', 'name', 'weight', 'symbol']; diff --git a/src/components-examples/material/table/table-sticky-complex-flex/table-sticky-complex-flex-example.html b/src/components-examples/material/table/table-sticky-complex-flex/table-sticky-complex-flex-example.html index 2914a3087f20..c9d1430b595b 100644 --- a/src/components-examples/material/table/table-sticky-complex-flex/table-sticky-complex-flex-example.html +++ b/src/components-examples/material/table/table-sticky-complex-flex/table-sticky-complex-flex-example.html @@ -36,43 +36,45 @@
    - - - Position - {{element.position}} - Position Footer - + @for (table of tables; track table) { + + + Position + {{element.position}} + Position Footer + - - Name - {{element.name}} - Name Footer - + + Name + {{element.name}} + Name Footer + - - Weight - {{element.weight}} - Weight Footer - + + Weight + {{element.weight}} + Weight Footer + - - Symbol - {{element.symbol}} - Symbol Footer - + + Symbol + {{element.symbol}} + Symbol Footer + - - Filler header cell - Filler data cell - Filler footer cell - + + Filler header cell + Filler data cell + Filler footer cell + - - + + - + - - - + + + + }
    diff --git a/src/components-examples/material/table/table-sticky-complex-flex/table-sticky-complex-flex-example.ts b/src/components-examples/material/table/table-sticky-complex-flex/table-sticky-complex-flex-example.ts index b3df9c3a82e7..601b475fefa7 100644 --- a/src/components-examples/material/table/table-sticky-complex-flex/table-sticky-complex-flex-example.ts +++ b/src/components-examples/material/table/table-sticky-complex-flex/table-sticky-complex-flex-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatButtonToggleGroup, MatButtonToggleModule} from '@angular/material/button-toggle'; import {MatTableModule} from '@angular/material/table'; import {MatButtonModule} from '@angular/material/button'; @@ -12,7 +11,7 @@ import {MatButtonModule} from '@angular/material/button'; styleUrls: ['table-sticky-complex-flex-example.css'], templateUrl: 'table-sticky-complex-flex-example.html', standalone: true, - imports: [MatButtonModule, MatButtonToggleModule, NgFor, MatTableModule], + imports: [MatButtonModule, MatButtonToggleModule, MatTableModule], }) export class TableStickyComplexFlexExample { displayedColumns: string[] = []; diff --git a/src/components-examples/material/table/table-sticky-complex/table-sticky-complex-example.html b/src/components-examples/material/table/table-sticky-complex/table-sticky-complex-example.html index 2f5c1e7260f6..3a52339e40b7 100644 --- a/src/components-examples/material/table/table-sticky-complex/table-sticky-complex-example.html +++ b/src/components-examples/material/table/table-sticky-complex/table-sticky-complex-example.html @@ -36,43 +36,45 @@
    -
    - {{column.header}} - - {{column.cell(row)}} - + {{column.header}} + + {{column.cell(row)}} +
    - - - - - + @for (table of tables; track table) { +
    Position {{element.position}} Position Footer
    + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - + + - + - - -
    Position {{element.position}} Position Footer Name {{element.name}} Name Footer Name {{element.name}} Name Footer Weight {{element.weight}} Weight Footer Weight {{element.weight}} Weight Footer Symbol {{element.symbol}} Symbol Footer Symbol {{element.symbol}} Symbol Footer Filler header cell Filler data cell Filler footer cell Filler header cell Filler data cell Filler footer cell
    + + + + } diff --git a/src/components-examples/material/table/table-sticky-complex/table-sticky-complex-example.ts b/src/components-examples/material/table/table-sticky-complex/table-sticky-complex-example.ts index a5a6a92cf984..a1a505fe81db 100644 --- a/src/components-examples/material/table/table-sticky-complex/table-sticky-complex-example.ts +++ b/src/components-examples/material/table/table-sticky-complex/table-sticky-complex-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatButtonToggleGroup, MatButtonToggleModule} from '@angular/material/button-toggle'; import {MatTableModule} from '@angular/material/table'; import {MatButtonModule} from '@angular/material/button'; @@ -12,7 +11,7 @@ import {MatButtonModule} from '@angular/material/button'; styleUrls: ['table-sticky-complex-example.css'], templateUrl: 'table-sticky-complex-example.html', standalone: true, - imports: [MatButtonModule, MatButtonToggleModule, NgFor, MatTableModule], + imports: [MatButtonModule, MatButtonToggleModule, MatTableModule], }) export class TableStickyComplexExample { displayedColumns: string[] = []; diff --git a/src/components-examples/material/tabs/tab-group-async/tab-group-async-example.html b/src/components-examples/material/tabs/tab-group-async/tab-group-async-example.html index c1f93438ca1a..a011ccc70408 100644 --- a/src/components-examples/material/tabs/tab-group-async/tab-group-async-example.html +++ b/src/components-examples/material/tabs/tab-group-async/tab-group-async-example.html @@ -1,10 +1,12 @@ - +@if ((asyncTabs | async) === null) { Loading tabs... - +} - - {{tab.label}} - {{tab.content}} - + @for (tab of asyncTabs | async; track tab) { + + {{tab.label}} + {{tab.content}} + + } diff --git a/src/components-examples/material/tabs/tab-group-async/tab-group-async-example.ts b/src/components-examples/material/tabs/tab-group-async/tab-group-async-example.ts index 1553ccb896d5..77392bddcb67 100644 --- a/src/components-examples/material/tabs/tab-group-async/tab-group-async-example.ts +++ b/src/components-examples/material/tabs/tab-group-async/tab-group-async-example.ts @@ -1,7 +1,7 @@ import {Component} from '@angular/core'; import {Observable, Observer} from 'rxjs'; import {MatTabsModule} from '@angular/material/tabs'; -import {NgIf, NgFor, AsyncPipe} from '@angular/common'; +import {AsyncPipe} from '@angular/common'; export interface ExampleTab { label: string; @@ -15,7 +15,7 @@ export interface ExampleTab { selector: 'tab-group-async-example', templateUrl: 'tab-group-async-example.html', standalone: true, - imports: [NgIf, MatTabsModule, NgFor, AsyncPipe], + imports: [MatTabsModule, AsyncPipe], }) export class TabGroupAsyncExample { asyncTabs: Observable; diff --git a/src/components-examples/material/tabs/tab-group-dynamic/tab-group-dynamic-example.html b/src/components-examples/material/tabs/tab-group-dynamic/tab-group-dynamic-example.html index a4f04d26946b..a50d28597e30 100644 --- a/src/components-examples/material/tabs/tab-group-dynamic/tab-group-dynamic-example.html +++ b/src/components-examples/material/tabs/tab-group-dynamic/tab-group-dynamic-example.html @@ -14,14 +14,16 @@ - - Contents for {{tab}} tab + @for (tab of tabs; track tab; let index = $index) { + + Contents for {{tab}} tab - - + + + } diff --git a/src/components-examples/material/tabs/tab-group-dynamic/tab-group-dynamic-example.ts b/src/components-examples/material/tabs/tab-group-dynamic/tab-group-dynamic-example.ts index b943f47fb7e2..a16bc9159558 100644 --- a/src/components-examples/material/tabs/tab-group-dynamic/tab-group-dynamic-example.ts +++ b/src/components-examples/material/tabs/tab-group-dynamic/tab-group-dynamic-example.ts @@ -1,6 +1,5 @@ import {Component} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {NgFor} from '@angular/common'; import {MatTabsModule} from '@angular/material/tabs'; import {MatCheckboxModule} from '@angular/material/checkbox'; import {MatButtonModule} from '@angular/material/button'; @@ -23,7 +22,6 @@ import {MatFormFieldModule} from '@angular/material/form-field'; MatButtonModule, MatCheckboxModule, MatTabsModule, - NgFor, ], }) export class TabGroupDynamicExample { diff --git a/src/components-examples/material/tabs/tab-group-paginated/tab-group-paginated-example.html b/src/components-examples/material/tabs/tab-group-paginated/tab-group-paginated-example.html index d6cf4166e8f6..fe8f6264d46c 100644 --- a/src/components-examples/material/tabs/tab-group-paginated/tab-group-paginated-example.html +++ b/src/components-examples/material/tabs/tab-group-paginated/tab-group-paginated-example.html @@ -1,3 +1,5 @@ - Content - \ No newline at end of file + @for (tab of lotsOfTabs; track tab) { + Content + } + diff --git a/src/components-examples/material/tabs/tab-group-paginated/tab-group-paginated-example.ts b/src/components-examples/material/tabs/tab-group-paginated/tab-group-paginated-example.ts index 00fc787758e9..48f86b5c6e77 100644 --- a/src/components-examples/material/tabs/tab-group-paginated/tab-group-paginated-example.ts +++ b/src/components-examples/material/tabs/tab-group-paginated/tab-group-paginated-example.ts @@ -1,5 +1,4 @@ import {Component} from '@angular/core'; -import {NgFor} from '@angular/common'; import {MatTabsModule} from '@angular/material/tabs'; /** @@ -9,7 +8,7 @@ import {MatTabsModule} from '@angular/material/tabs'; selector: 'tab-group-paginated-example', templateUrl: 'tab-group-paginated-example.html', standalone: true, - imports: [MatTabsModule, NgFor], + imports: [MatTabsModule], }) export class TabGroupPaginatedExample { lotsOfTabs = new Array(30).fill(0).map((_, index) => `Tab ${index}`); diff --git a/src/components-examples/material/tabs/tab-nav-bar-basic/tab-nav-bar-basic-example.html b/src/components-examples/material/tabs/tab-nav-bar-basic/tab-nav-bar-basic-example.html index ff20e1723701..b3f3d959cac8 100644 --- a/src/components-examples/material/tabs/tab-nav-bar-basic/tab-nav-bar-basic-example.html +++ b/src/components-examples/material/tabs/tab-nav-bar-basic/tab-nav-bar-basic-example.html @@ -1,8 +1,10 @@ diff --git a/src/components-examples/material/tabs/tab-nav-bar-basic/tab-nav-bar-basic-example.ts b/src/components-examples/material/tabs/tab-nav-bar-basic/tab-nav-bar-basic-example.ts index 3efbe1a2a184..244dcc462d89 100644 --- a/src/components-examples/material/tabs/tab-nav-bar-basic/tab-nav-bar-basic-example.ts +++ b/src/components-examples/material/tabs/tab-nav-bar-basic/tab-nav-bar-basic-example.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {ThemePalette} from '@angular/material/core'; import {MatButtonModule} from '@angular/material/button'; -import {NgFor} from '@angular/common'; import {MatTabsModule} from '@angular/material/tabs'; /** @@ -12,7 +11,7 @@ import {MatTabsModule} from '@angular/material/tabs'; templateUrl: 'tab-nav-bar-basic-example.html', styleUrls: ['tab-nav-bar-basic-example.css'], standalone: true, - imports: [MatTabsModule, NgFor, MatButtonModule], + imports: [MatTabsModule, MatButtonModule], }) export class TabNavBarBasicExample { links = ['First', 'Second', 'Third']; diff --git a/src/components-examples/material/tooltip/tooltip-auto-hide/tooltip-auto-hide-example.html b/src/components-examples/material/tooltip/tooltip-auto-hide/tooltip-auto-hide-example.html index 583f84211476..193542e1326c 100644 --- a/src/components-examples/material/tooltip/tooltip-auto-hide/tooltip-auto-hide-example.html +++ b/src/components-examples/material/tooltip/tooltip-auto-hide/tooltip-auto-hide-example.html @@ -1,9 +1,9 @@ Tooltip position - - {{positionOption}} - + @for (positionOption of positionOptions; track positionOption) { + {{positionOption}} + } diff --git a/src/components-examples/material/tooltip/tooltip-auto-hide/tooltip-auto-hide-example.ts b/src/components-examples/material/tooltip/tooltip-auto-hide/tooltip-auto-hide-example.ts index c850de5e80da..404d00b35c06 100644 --- a/src/components-examples/material/tooltip/tooltip-auto-hide/tooltip-auto-hide-example.ts +++ b/src/components-examples/material/tooltip/tooltip-auto-hide/tooltip-auto-hide-example.ts @@ -3,7 +3,6 @@ import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {TooltipPosition, MatTooltipModule} from '@angular/material/tooltip'; import {MatButtonModule} from '@angular/material/button'; import {CdkScrollable} from '@angular/cdk/scrolling'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -20,7 +19,6 @@ import {MatFormFieldModule} from '@angular/material/form-field'; MatSelectModule, FormsModule, ReactiveFormsModule, - NgFor, CdkScrollable, MatButtonModule, MatTooltipModule, diff --git a/src/components-examples/material/tooltip/tooltip-position/tooltip-position-example.html b/src/components-examples/material/tooltip/tooltip-position/tooltip-position-example.html index 09459eb63cea..7c1c1d959729 100644 --- a/src/components-examples/material/tooltip/tooltip-position/tooltip-position-example.html +++ b/src/components-examples/material/tooltip/tooltip-position/tooltip-position-example.html @@ -1,9 +1,9 @@ Tooltip position - - {{positionOption}} - + @for (positionOption of positionOptions; track positionOption) { + {{positionOption}} + } diff --git a/src/components-examples/material/tooltip/tooltip-position/tooltip-position-example.ts b/src/components-examples/material/tooltip/tooltip-position/tooltip-position-example.ts index 9546f66a41da..f4d49df6a117 100644 --- a/src/components-examples/material/tooltip/tooltip-position/tooltip-position-example.ts +++ b/src/components-examples/material/tooltip/tooltip-position/tooltip-position-example.ts @@ -2,7 +2,6 @@ import {Component} from '@angular/core'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {TooltipPosition, MatTooltipModule} from '@angular/material/tooltip'; import {MatButtonModule} from '@angular/material/button'; -import {NgFor} from '@angular/common'; import {MatSelectModule} from '@angular/material/select'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -19,7 +18,6 @@ import {MatFormFieldModule} from '@angular/material/form-field'; MatSelectModule, FormsModule, ReactiveFormsModule, - NgFor, MatButtonModule, MatTooltipModule, ], diff --git a/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.html b/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.html index f06d566ee313..2fc1fdfd654d 100644 --- a/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.html +++ b/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.html @@ -11,8 +11,10 @@ {{node.item}} - + @if (node.isLoading) { + + } diff --git a/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts b/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts index 53b74dc52add..c783ec46ce65 100644 --- a/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts +++ b/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts @@ -4,7 +4,6 @@ import {Component, Injectable} from '@angular/core'; import {BehaviorSubject, merge, Observable} from 'rxjs'; import {map} from 'rxjs/operators'; import {MatProgressBarModule} from '@angular/material/progress-bar'; -import {NgIf} from '@angular/common'; import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; import {MatTreeModule} from '@angular/material/tree'; @@ -142,7 +141,7 @@ export class DynamicDataSource implements DataSource { templateUrl: 'tree-dynamic-example.html', styleUrls: ['tree-dynamic-example.css'], standalone: true, - imports: [MatTreeModule, MatButtonModule, MatIconModule, NgIf, MatProgressBarModule], + imports: [MatTreeModule, MatButtonModule, MatIconModule, MatProgressBarModule], }) export class TreeDynamicExample { constructor(database: DynamicDatabase) { diff --git a/src/components-examples/material/tree/tree-loadmore/tree-loadmore-example.html b/src/components-examples/material/tree/tree-loadmore/tree-loadmore-example.html index 9e7feb6b0e9e..945c0ad32f21 100644 --- a/src/components-examples/material/tree/tree-loadmore/tree-loadmore-example.html +++ b/src/components-examples/material/tree/tree-loadmore/tree-loadmore-example.html @@ -19,7 +19,7 @@ Load more of {{node.parent}}... diff --git a/src/dev-app/autocomplete/autocomplete-demo.html b/src/dev-app/autocomplete/autocomplete-demo.html index 6bbe1e9bec6c..9296652d082f 100644 --- a/src/dev-app/autocomplete/autocomplete-demo.html +++ b/src/dev-app/autocomplete/autocomplete-demo.html @@ -21,11 +21,12 @@ [hideSingleSelectionIndicator]="reactiveHideSingleSelectionIndicator" [autoActiveFirstOption]="reactiveAutoActiveFirstOption" [requireSelection]="reactiveRequireSelection"> - - {{ state.name }} - ({{ state.code }}) - + @for (state of reactiveStates; track state; let index = $index) { + + {{ state.name }} + ({{ state.code }}) + + }

    @@ -66,21 +67,25 @@

    Template-driven value (currentState): {{ currentState }}
    Template-driven dirty: {{ modelDir ? modelDir.dirty : false }}
    - - - State - - - - {{ state.name }} - - - + + @if (true) { + + State + + + @for (state of tdStates; track state) { + + {{ state.name }} + + } + + + }

    @@ -89,9 +94,9 @@ TOGGLE DISABLED

    @@ -141,8 +146,11 @@ - - {{ state.name }} - + @for (group of filteredGroupedStates; track group) { + + @for (state of group.states; track state) { + {{ state.name }} + } + + } diff --git a/src/dev-app/autocomplete/autocomplete-demo.ts b/src/dev-app/autocomplete/autocomplete-demo.ts index 08a9a9df027c..af551041dcde 100644 --- a/src/dev-app/autocomplete/autocomplete-demo.ts +++ b/src/dev-app/autocomplete/autocomplete-demo.ts @@ -224,9 +224,9 @@ export class AutocompleteDemo { T-Shirt Size - - {{size}} - + @for (size of sizes; track size) { + {{size}} + } diff --git a/src/dev-app/badge/badge-demo.html b/src/dev-app/badge/badge-demo.html index f25109539acf..9de265315fa1 100644 --- a/src/dev-app/badge/badge-demo.html +++ b/src/dev-app/badge/badge-demo.html @@ -54,9 +54,9 @@

    Size

    Text

    - - Hello - + @if (visible) { + Hello + } Hello diff --git a/src/dev-app/bottom-sheet/bottom-sheet-demo.html b/src/dev-app/bottom-sheet/bottom-sheet-demo.html index 7201ea582a44..e473b19169b9 100644 --- a/src/dev-app/bottom-sheet/bottom-sheet-demo.html +++ b/src/dev-app/bottom-sheet/bottom-sheet-demo.html @@ -36,10 +36,12 @@

    Options

    - - folder - Action {{ action }} - Description - + @for (action of [1, 2, 3]; track action) { + + folder + Action {{ action }} + Description + + } diff --git a/src/dev-app/bottom-sheet/bottom-sheet-demo.ts b/src/dev-app/bottom-sheet/bottom-sheet-demo.ts index 7e6b58a7d446..6f1e7fe52d97 100644 --- a/src/dev-app/bottom-sheet/bottom-sheet-demo.ts +++ b/src/dev-app/bottom-sheet/bottom-sheet-demo.ts @@ -70,10 +70,12 @@ export class BottomSheetDemo { @Component({ template: ` - - Action {{ action }} - Description - + @for (action of [1, 2, 3]; track action) { + + Action {{ action }} + Description + + } `, standalone: true, diff --git a/src/dev-app/button-toggle/button-toggle-demo.html b/src/dev-app/button-toggle/button-toggle-demo.html index a6db320b7973..b2cfc8186f3e 100644 --- a/src/dev-app/button-toggle/button-toggle-demo.html +++ b/src/dev-app/button-toggle/button-toggle-demo.html @@ -83,9 +83,9 @@

    Single Toggle

    Dynamic Exclusive Selection

    - - {{pie}} - + @for (pie of pieOptions; track pie) { + {{pie}} + }

    Your favorite type of pie is: {{favoritePie}}

    diff --git a/src/dev-app/cdk-menu/cdk-menu-demo.html b/src/dev-app/cdk-menu/cdk-menu-demo.html index ed790605b587..545b4ca0ce6e 100644 --- a/src/dev-app/cdk-menu/cdk-menu-demo.html +++ b/src/dev-app/cdk-menu/cdk-menu-demo.html @@ -145,48 +145,44 @@

    Radio items

    - + (cdkMenuItemTriggered)="selectedSize = size">{{size}} + }
    - + (cdkMenuItemTriggered)="selectedColor = color">{{color}} + }
    - + (cdkMenuItemTriggered)="selectedSize = size">{{size}} + }
    - + (cdkMenuItemTriggered)="selectedColor = color">{{color}} + }
    diff --git a/src/dev-app/checkbox/checkbox-demo.html b/src/dev-app/checkbox/checkbox-demo.html index ce19e105b890..8bd338ef7ae5 100644 --- a/src/dev-app/checkbox/checkbox-demo.html +++ b/src/dev-app/checkbox/checkbox-demo.html @@ -151,7 +151,9 @@
    Click action: check-indeterminate
    [indeterminate]="demoIndeterminate" (change)="demoChecked = $event.checked" (indeterminateChange)="demoIndeterminate = $event"> - Checkbox w/ [checked] & (change) + @if (!demoHideLabel) { + Checkbox w/ [checked] & (change) + } Click action: check-indeterminate [indeterminate]="demoIndeterminate" [(ngModel)]="demoChecked" (indeterminateChange)="demoIndeterminate = $event"> - Checkbox w/ [(ngModel)] + @if (!demoHideLabel) { + Checkbox w/ [(ngModel)] + }
    @@ -187,7 +191,9 @@
    Click action: check
    [indeterminate]="demoIndeterminate" (change)="demoChecked = $event.checked" (indeterminateChange)="demoIndeterminate = $event"> - Checkbox w/ [checked] & (change) + @if (!demoHideLabel) { + Checkbox w/ [checked] & (change) + } Click action: check [indeterminate]="demoIndeterminate" [(ngModel)]="demoChecked" (indeterminateChange)="demoIndeterminate = $event"> - Checkbox w/ [(ngModel)] + @if (!demoHideLabel) { + Checkbox w/ [(ngModel)] + }
    @@ -223,7 +231,9 @@
    Click action: noop
    [indeterminate]="demoIndeterminate" (change)="demoChecked = $event.checked" (indeterminateChange)="demoIndeterminate = $event"> - Checkbox w/ [checked] & (change) + @if (!demoHideLabel) { + Checkbox w/ [checked] & (change) + } Click action: noop [indeterminate]="demoIndeterminate" [(ngModel)]="demoChecked" (indeterminateChange)="demoIndeterminate = $event"> - Checkbox w/ [(ngModel)] + @if (!demoHideLabel) { + Checkbox w/ [(ngModel)] + }
    @@ -259,7 +271,9 @@
    No animations
    [indeterminate]="demoIndeterminate" (change)="demoChecked = $event.checked" (indeterminateChange)="demoIndeterminate = $event"> - Checkbox w/ [checked] & (change) + @if (!demoHideLabel) { + Checkbox w/ [checked] & (change) + } No animations [indeterminate]="demoIndeterminate" [(ngModel)]="demoChecked" (indeterminateChange)="demoIndeterminate = $event"> - Checkbox w/ [(ngModel)] + @if (!demoHideLabel) { + Checkbox w/ [(ngModel)] + }
    diff --git a/src/dev-app/checkbox/nested-checklist.html b/src/dev-app/checkbox/nested-checklist.html index 6a4ab3e617ab..7e41027b7fa7 100644 --- a/src/dev-app/checkbox/nested-checklist.html +++ b/src/dev-app/checkbox/nested-checklist.html @@ -1,18 +1,23 @@

    Tasks

      -
    • - -

      {{task.name}}

      -
      -
        -
      • - - {{subtask.name}} - -
      • -
      -
    • + @for (task of tasks; track task) { +
    • + +

      {{task.name}}

      +
      +
        + @for (subtask of task.subtasks; track subtask) { +
      • + + {{subtask.name}} + +
      • + } +
      +
    • + }
    diff --git a/src/dev-app/chips/chips-demo.html b/src/dev-app/chips/chips-demo.html index 894a2a2c60b1..60b2ded6ec09 100644 --- a/src/dev-app/chips/chips-demo.html +++ b/src/dev-app/chips/chips-demo.html @@ -95,13 +95,15 @@

    With avatar, icons, and color

    With Events

    - - With Events - - + @if (visible) { + + With Events + + + }
    {{message}}
    @@ -122,19 +124,27 @@

    With Events

    Single selection

    - - {{shirtSize.label}} - {{shirtSize.avatar}} - + @for (shirtSize of shirtSizes; track shirtSize) { + + {{shirtSize.label}} + @if (listboxesWithAvatar) { + {{shirtSize.avatar}} + } + + }

    Multi selection

    - - {{hint.avatar}} - {{hint.label}} - + @for (hint of restaurantHints; track hint) { + + @if (listboxesWithAvatar) { + {{hint.avatar}} + } + {{hint.label}} + + } @@ -163,15 +173,17 @@

    Input is last child of chip grid

    New Contributor... - - {{person.name}} - - + @for (person of people; track person) { + + {{person.name}} + + + } Input is next sibling child of chip grid New Contributor... - - {{person.name}} - - + @for (person of people; track person) { + + {{person.name}} + + + } Stacked

    - - {{aColor.name}} - + @for (aColor of availableColors; track aColor) { + {{aColor.name}} + }

    NgModel with multi selection

    - - {{aColor.name}} - + @for (aColor of availableColors; track aColor) { + {{aColor.name}} + } The selected colors are - - {{color}}{{isLast ? '' : ', '}}. + @for (color of selectedColors; track color; let isLast = $last) { + {{color}}{{isLast ? '' : ', '}} + }

    NgModel with single selection

    - - {{aColor.name}} - + @for (aColor of availableColors; track aColor) { + {{aColor.name}} + } The selected color is {{selectedColor}}. @@ -254,21 +266,22 @@

    NgModel with single selection

    Single selection without checkmark selection indicator.

    - - {{aColor.name}} - + @for (aColor of availableColors; track aColor) { + {{aColor.name}} + }

    Single selection with decorative icons.

    - - home - {{aColor.name}} - star - + @for (aColor of availableColors; track aColor) { + + home + {{aColor.name}} + star + + } The selected color is {{selectedColor}}. @@ -276,11 +289,13 @@

    Single selection with decorative icons.

    Single selection with stacked appearance.

    - - {{aColor.name}} - star - + @for (aColor of availableColors; track aColor) { + + {{aColor.name}} + star + + } The selected color is {{selectedColor}}. diff --git a/src/dev-app/connected-overlay/connected-overlay-demo.html b/src/dev-app/connected-overlay/connected-overlay-demo.html index c0d6bee6f8f6..ebdcea4a2014 100644 --- a/src/dev-app/connected-overlay/connected-overlay-demo.html +++ b/src/dev-app/connected-overlay/connected-overlay-demo.html @@ -111,7 +111,11 @@

    Options

    -
    • {{itemText}} {{i}}
    +
      + @for (item of itemArray; track item; let i = $index) { +
    • {{itemText}} {{i}}
    • + } +
    diff --git a/src/dev-app/datepicker/datepicker-demo.html b/src/dev-app/datepicker/datepicker-demo.html index ccbb216015fe..f2132816a6c5 100644 --- a/src/dev-app/datepicker/datepicker-demo.html +++ b/src/dev-app/datepicker/datepicker-demo.html @@ -21,10 +21,12 @@

    Options

    [disabled]="inputDisabled" [max]="maxDate"> - - - - + @if (showActions) { + + + + + }
    @@ -33,10 +35,12 @@

    Options

    [disabled]="inputDisabled" [min]="minDate"> - - - - + @if (showActions) { + + + + + }

    @@ -47,10 +51,12 @@

    Options

    [disabled]="inputDisabled"> - - - - + @if (showActions) { + + + + + }

    @@ -78,17 +84,27 @@

    Result

    [startAt]="startAt" [startView]="yearView ? 'year' : 'month'" [color]="color"> - - - - + @if (showActions) { + + + + + } - - "{{resultPickerModel.getError('matDatepickerParse').text}}" is not a valid date! - - Too early! - Too late! - Date unavailable! + @if (resultPickerModel.hasError('matDatepickerParse')) { + + "{{resultPickerModel.getError('matDatepickerParse').text}}" is not a valid date! + + } + @if (resultPickerModel.hasError('matDatepickerMin')) { + Too early! + } + @if (resultPickerModel.hasError('matDatepickerMax')) { + Too late! + } + @if (resultPickerModel.hasError('matDatepickerFilter')) { + Date unavailable! + }

    Last input: {{lastDateInput}}

    @@ -110,10 +126,12 @@

    Result

    [disabled]="datepickerDisabled" [startAt]="startAt" [startView]="yearView ? 'year' : 'month'"> - - - - + @if (showActions) { + + + + + }

    @@ -217,10 +235,12 @@

    Range picker

    [disabled]="datepickerDisabled" [color]="color" #range1Picker> - - - - + @if (showActions) { + + + + + }
    {{range1.value | json}}
    @@ -247,10 +267,12 @@

    Range picker

    [disabled]="datepickerDisabled" panelClass="demo-custom-range" #range2Picker> - - - - + @if (showActions) { + + + + + }
    {{range2.value | json}}
    @@ -276,10 +298,12 @@

    Range picker

    [touchUi]="touch" [disabled]="datepickerDisabled" #range3Picker> - - - - + @if (showActions) { + + + + + }
    {{range3.value | json}}
    @@ -296,10 +320,12 @@

    Range picker with custom selection strategy

    - - - - + @if (showActions) { + + + + + } diff --git a/src/dev-app/dev-app/dev-app-layout.html b/src/dev-app/dev-app/dev-app-layout.html index b4b7829c0142..56eb8f7a8fa9 100644 --- a/src/dev-app/dev-app/dev-app-layout.html +++ b/src/dev-app/dev-app/dev-app-layout.html @@ -1,15 +1,15 @@ - - {{navItem.name}} - + @for (navItem of navItems; track navItem) { + {{navItem.name}} + } diff --git a/src/dev-app/drag-drop/drag-drop-demo.html b/src/dev-app/drag-drop/drag-drop-demo.html index 035c0125592e..5c011e0a1042 100644 --- a/src/dev-app/drag-drop/drag-drop-demo.html +++ b/src/dev-app/drag-drop/drag-drop-demo.html @@ -5,12 +5,13 @@

    To do

    cdkDropList (cdkDropListDropped)="drop($event)" [cdkDropListLockAxis]="axisLock" - [cdkDropListData]="todo" - > -
    - {{item}} - -
    + [cdkDropListData]="todo"> + @for (item of todo; track item) { +
    + {{item}} + +
    + } @@ -20,12 +21,13 @@

    Done

    cdkDropList (cdkDropListDropped)="drop($event)" [cdkDropListLockAxis]="axisLock" - [cdkDropListData]="done" - > -
    - {{item}} - -
    + [cdkDropListData]="done"> + @for (item of done; track item) { +
    + {{item}} + +
    + } @@ -38,12 +40,13 @@

    Ages

    cdkDropListOrientation="horizontal" (cdkDropListDropped)="drop($event)" [cdkDropListLockAxis]="axisLock" - [cdkDropListData]="ages" - > -
    - {{item}} - -
    + [cdkDropListData]="ages"> + @for (item of ages; track item) { +
    + {{item}} + +
    + } @@ -54,12 +57,13 @@

    Preferred Ages

    cdkDropListOrientation="horizontal" (cdkDropListDropped)="drop($event)" [cdkDropListLockAxis]="axisLock" - [cdkDropListData]="preferredAges" - > -
    - {{item}} - -
    + [cdkDropListData]="preferredAges"> + @for (item of preferredAges; track item) { +
    + {{item}} + +
    + } diff --git a/src/dev-app/example/example-list.ts b/src/dev-app/example/example-list.ts index e7b6d5aa0c67..99b0363efea4 100644 --- a/src/dev-app/example/example-list.ts +++ b/src/dev-app/example/example-list.ts @@ -20,18 +20,20 @@ import {Example} from './example'; imports: [CommonModule, MatExpansionModule, Example], template: ` - - -
    -
    {{_getTitle(id)}}
    -
    <{{id}}>
    -
    -
    + @for (id of ids; track id) { + + +
    +
    {{_getTitle(id)}}
    +
    <{{id}}>
    +
    +
    - - - -
    + + + +
    + }
    `, styles: [ diff --git a/src/dev-app/example/example.ts b/src/dev-app/example/example.ts index 3a1be014cb8f..6bef62e47864 100644 --- a/src/dev-app/example/example.ts +++ b/src/dev-app/example/example.ts @@ -24,14 +24,18 @@ import { standalone: true, imports: [CommonModule], template: ` -
    - {{title}} - <{{id}}> -
    + @if (showLabel) { +
    + {{title}} + <{{id}}> +
    + } -
    - Could not find example {{id}} -
    + @if (!id) { +
    + Could not find example {{id}} +
    + } `, styles: [ ` diff --git a/src/dev-app/expansion/expansion-demo.html b/src/dev-app/expansion/expansion-demo.html index 98b14ca6ada2..8a93eed0ea06 100644 --- a/src/dev-app/expansion/expansion-demo.html +++ b/src/dev-app/expansion/expansion-demo.html @@ -33,7 +33,9 @@

    Single Expansion Panel

    Expansion Panel Animation Events

    -
    {{event}}
    + @for (event of events; track event) { +
    {{event}}
    + }

    matAccordion

    @@ -78,14 +80,18 @@

    matAccordion

    Section 2

    This is the content text that makes sense here.

    - - Section 3 - Reveal Buttons Below - - - - - + @if (showPanel3) { + + Section 3 + Reveal Buttons Below + @if (showButtons.checked) { + + + + + } + + }

    cdkAccordion

    @@ -102,7 +108,9 @@

    cdkAccordion

    -

    I only show if item 1 is expanded

    + @if (item1.expanded) { +

    I only show if item 1 is expanded

    + }

    @@ -110,7 +118,9 @@

    cdkAccordion

    -

    I only show if item 2 is expanded

    + @if (item2.expanded) { +

    I only show if item 2 is expanded

    + }

    @@ -118,7 +128,9 @@

    cdkAccordion

    -

    I only show if item 3 is expanded

    + @if (item3.expanded) { +

    I only show if item 3 is expanded

    + }
    diff --git a/src/dev-app/focus-trap/focus-trap-demo.html b/src/dev-app/focus-trap/focus-trap-demo.html index b4f488d6c79c..6a84b7a10728 100644 --- a/src/dev-app/focus-trap/focus-trap-demo.html +++ b/src/dev-app/focus-trap/focus-trap-demo.html @@ -65,8 +65,8 @@ Shadow DOMs - - + + @if (_supportsShadowDom) { @@ -83,9 +83,10 @@ - - Shadow DOM not supported - + } @else { + Shadow DOM not supported + } + diff --git a/src/dev-app/google-map/google-map-demo.html b/src/dev-app/google-map/google-map-demo.html index 9bb8317d2ab6..610b1141132f 100644 --- a/src/dev-app/google-map/google-map-demo.html +++ b/src/dev-app/google-map/google-map-demo.html @@ -1,174 +1,198 @@ -
    Loading Google Maps API...
    -
    - - - - - - Testing 1 2 3 - - - - - - - - - - - - - - -

    {{display?.lat}}

    -

    {{display?.lng}}

    - -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    +@if (hasLoaded) { +
    + + + + @for (markerPosition of markerPositions; track markerPosition) { + + } + + Testing 1 2 3 + @if (isPolylineDisplayed) { + + } + @if (isPolygonDisplayed) { + + } + @if (isRectangleDisplayed) { + + } + @if (isCircleDisplayed) { + + } + @if (isGroundOverlayDisplayed) { + + } + @if (isKmlLayerDisplayed) { + + } + @if (isTrafficLayerDisplayed) { + + } + @if (isTransitLayerDisplayed) { + + } + @if (isBicyclingLayerDisplayed) { + + } + @if (directionsResult) { + + } + @if (isHeatmapDisplayed) { + + } + + +

    {{display?.lat}}

    +

    {{display?.lng}}

    + +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    +
    +} @else { +
    Loading Google Maps API...
    +} diff --git a/src/dev-app/grid-list/grid-list-demo.html b/src/dev-app/grid-list/grid-list-demo.html index 10d526cf00c2..f467ea7f6a01 100644 --- a/src/dev-app/grid-list/grid-list-demo.html +++ b/src/dev-app/grid-list/grid-list-demo.html @@ -55,10 +55,12 @@ Fixed-height grid list - - {{tile.text}} - + @for (tile of tiles; track tile) { + + {{tile.text}} + + } @@ -72,9 +74,9 @@ Ratio-height grid list - - {{tile.text}} - + @for (tile of tiles; track tile) { + {{tile.text}} + } @@ -87,9 +89,9 @@ - - {{tile.text}} - + @for (tile of tiles; track tile) { + {{tile.text}} + } @@ -102,12 +104,14 @@ Grid list with header - - - info_outline - {{dog.name}} - - + @for (dog of dogs; track dog) { + + + info_outline + {{dog.name}} + + + }
    @@ -116,14 +120,16 @@ Grid list with footer - - - -

    {{dog.name}}

    - Human: {{dog.human}} - star_border -
    -
    + @for (dog of dogs; track dog) { + + + +

    {{dog.name}}

    + Human: {{dog.human}} + star_border +
    +
    + }
    diff --git a/src/dev-app/input/input-demo.html b/src/dev-app/input/input-demo.html index b7b9f5344700..0742fa5c891e 100644 --- a/src/dev-app/input/input-demo.html +++ b/src/dev-app/input/input-demo.html @@ -73,12 +73,12 @@

    Regular

    Email - - This field is required - - - Please enter a valid email address - + @if (emailFormControl.hasError('required')) { + This field is required + } + @if (emailFormControl.hasError('pattern')) { + Please enter a valid email address + }

    @@ -124,7 +124,9 @@

    Text

    Amount - $ + @if (showPrefix) { + $ + } .00 @@ -140,7 +142,9 @@

    Icons

    Amount - calendar_today + @if (showPrefix) { + calendar_today + } mode_edit @@ -148,9 +152,11 @@

    Icon buttons

    Amount - + @if (showPrefix) { + + } @@ -162,9 +168,11 @@

    Text & Icons

    $ .00 - + @if (showPrefix) { + + } @@ -491,21 +499,23 @@

    Textarea

    - - {{i+1}} - - - Value - - - - - - - {{item.value}} - + @for (item of items; track item; let i = $index) { + + {{i+1}} + + + Value + + + + + + + {{item.value}} + + } @@ -730,7 +740,9 @@

    <textarea> with bindable autosize

    - {{option}} + @for (option of options; track option) { + {{option}} + }

    @@ -741,7 +753,9 @@

    <textarea> with bindable autosize

    - {{option}} + @for (option of options; track option) { + {{option}} + }

    @@ -776,7 +790,9 @@

    <textarea> with bindable autosize

    Amount - + @if (showSecondPrefix) { + + } .00 diff --git a/src/dev-app/list/list-demo.html b/src/dev-app/list/list-demo.html index 2be72e3bbba6..5edc6cdfa7d0 100644 --- a/src/dev-app/list/list-demo.html +++ b/src/dev-app/list/list-demo.html @@ -11,45 +11,57 @@

    Normal lists

    Items
    - - {{item}} - + @for (item of items; track item) { + {{item}} + }
    - -
    {{contact.name}}
    -
    extra line
    -
    {{contact.headline}}
    -
    + @for (contact of contacts; track contact) { + +
    {{contact.name}}
    + @if (thirdLine) { +
    extra line
    + } +
    {{contact.headline}}
    +
    + }
    Today
    - - Image of {{message.from}} -
    {{message.from}}
    -
    - {{message.subject}} -- - {{message.message}} -
    - -
    + @for (message of messages; track message) { + + Image of {{message.from}} +
    {{message.from}}
    +
    + {{message.subject}} -- + {{message.message}} +
    + @if (!$last) { + + } +
    + } - -
    {{message.from}}
    -
    {{message.subject}}
    -
    {{message.message}}
    -
    + @for (message of messages; track message) { + +
    {{message.from}}
    +
    {{message.subject}}
    +
    {{message.message}}
    +
    + }
    - - {{ link.name }} - - + @for (link of links; track link) { + + {{ link.name }} + + + } @@ -57,61 +69,71 @@

    Normal lists

    Dense lists

    Items
    - - {{item}} - + @for (item of items; track item) { + {{item}} + }
    - -
    {{contact.name}}
    -
    {{contact.headline}}
    -
    + @for (contact of contacts; track contact) { + +
    {{contact.name}}
    +
    {{contact.headline}}
    +
    + }
    Today
    - - Image of {{message.from}} -
    {{message.from}}
    -
    {{message.subject}}
    -
    {{message.message}}
    -
    + @for (message of messages; track message) { + + Image of {{message.from}} +
    {{message.from}}
    +
    {{message.subject}}
    +
    {{message.message}}
    +
    + }
    - - {{ link.name }} - - + @for (link of links; track link) { + + {{ link.name }} + + + }

    Nav lists

    - - {{ link.name }} - + @for (link of links; track link) { + + {{ link.name }} + + } -
    - More info! -
    + @if (infoClicked) { +
    More info!
    + } - - folder - {{ link.name }} - + @for (link of links; track link; let last = $last) { + + folder + {{ link.name }} + + }

    Action list

    - + @for (link of links; track link) { + + }
    @@ -228,10 +250,12 @@

    Line scenarios

    Line alignment

    - - {{ link.name }} - Unscoped content - + @for (link of links; track link) { + + {{ link.name }} + Unscoped content + + } diff --git a/src/dev-app/menu/menu-demo.html b/src/dev-app/menu/menu-demo.html index 7638e8012d0e..69338bb190e8 100644 --- a/src/dev-app/menu/menu-demo.html +++ b/src/dev-app/menu/menu-demo.html @@ -9,9 +9,11 @@ - + @for (item of items; track item) { + + }
    @@ -24,12 +26,12 @@ - - - - + @for (item of items; track item) { + + @if (!$last) { + + } + }
    @@ -95,9 +97,11 @@ - - {{ item.text }} - + @for (item of items; track item) { + + {{ item.text }} + + }
    @@ -111,10 +115,12 @@ - + @for (item of iconItems; track item) { + + }
    @@ -128,9 +134,9 @@ - + @for (item of items; track item) { + + }
    @@ -146,9 +152,9 @@ - + @for (item of items; track item) { + + }
    @@ -162,10 +168,12 @@ - + @for (item of iconItems; track item) { + + }
    @@ -179,9 +187,9 @@ - + @for (item of items; track item) { + + }
    diff --git a/src/dev-app/performance/performance-demo.html b/src/dev-app/performance/performance-demo.html index 73466ba93973..2cfd68c5f975 100644 --- a/src/dev-app/performance/performance-demo.html +++ b/src/dev-app/performance/performance-demo.html @@ -36,10 +36,14 @@ No. {{ item.index }} - + @if (allSamples.length) { + Average render time - - No data yet + +} + @if (!allSamples.length) { + No data yet +} @@ -65,26 +69,32 @@ > +@if (allSamples.length) { +} - - +@if (show) { + + @for (_ of componentArray; track _) { + Input - - + +} + +} diff --git a/src/dev-app/performance/performance-demo.ts b/src/dev-app/performance/performance-demo.ts index 7e0b17bc4b68..612c2dda3dd6 100644 --- a/src/dev-app/performance/performance-demo.ts +++ b/src/dev-app/performance/performance-demo.ts @@ -64,7 +64,7 @@ export class PerformanceDemo implements AfterViewInit { /** The average plus/minus the stdev. */ computedResults = ''; - /** Used in an ngFor to render the desired number of comonents. */ + /** Used in an `@for` to render the desired number of comonents. */ componentArray = [].constructor(this.componentCount); /** The standard deviation of the recorded samples. */ diff --git a/src/dev-app/platform/platform-demo.html b/src/dev-app/platform/platform-demo.html index 79397500200e..012cfba294d4 100644 --- a/src/dev-app/platform/platform-demo.html +++ b/src/dev-app/platform/platform-demo.html @@ -9,5 +9,7 @@

    Supported input types: - {{type}}, + @for (type of supportedInputTypes; track type) { + {{type}}, + }

    diff --git a/src/dev-app/portal/portal-demo.html b/src/dev-app/portal/portal-demo.html index bdb0e648447c..e6aaefc7b2c8 100644 --- a/src/dev-app/portal/portal-demo.html +++ b/src/dev-app/portal/portal-demo.html @@ -21,7 +21,7 @@

    The portal outlet is here:

    diff --git a/src/dev-app/radio/radio-demo.html b/src/dev-app/radio/radio-demo.html index 2c11becb2327..35a4def520db 100644 --- a/src/dev-app/radio/radio-demo.html +++ b/src/dev-app/radio/radio-demo.html @@ -55,9 +55,11 @@

    Favorite Season Example

    Dynamic Example with two-way data-binding

    - - {{season}} - + @for (season of seasonOptions; track season) { + + {{season}} + + }

    Your favorite season is: {{favoriteSeason}}

    diff --git a/src/dev-app/select/select-demo.html b/src/dev-app/select/select-demo.html index 5eee7a9ee2ce..190d3ed68ff7 100644 --- a/src/dev-app/select/select-demo.html +++ b/src/dev-app/select/select-demo.html @@ -13,10 +13,12 @@ None - - {{ drink.viewValue }} - + @for (drink of drinks; track drink; let index = $index) { + + {{ drink.viewValue }} + + } local_drink Pick a drink! @@ -44,9 +46,9 @@

    @@ -73,9 +75,11 @@ Pokemon - - {{ creature.viewValue }} - + @for (creature of pokemon; track creature) { + + {{ creature.viewValue }} + + }

    Value: {{ currentPokemon }}

    @@ -85,7 +89,9 @@

    @@ -104,9 +110,9 @@ Digimon None - - {{ creature.viewValue }} - + @for (creature of digimon; track creature) { + {{ creature.viewValue }} + } @@ -124,12 +130,13 @@ Pokemon - - - {{ creature.viewValue }} - - + @for (group of pokemonGroups; track group) { + + @for (creature of group.pokemon; track creature) { + {{ creature.viewValue }} + } + + } @@ -145,9 +152,9 @@ [required]="drinkObjectRequired" [compareWith]="compareByValue ? compareDrinkObjectsByValue : compareByReference" #drinkObjectControl="ngModel"> - - {{ drink.viewValue }} - + @for (drink of drinks; track drink) { + {{ drink.viewValue }} + }

    Value: {{ currentDrinkObject | json }}

    @@ -174,9 +181,9 @@ Fill None - - {{ creature.viewValue }} - + @for (creature of digimon; track creature) { + {{ creature.viewValue }} + }

    @@ -186,9 +193,9 @@ Outline None - - {{ creature.viewValue }} - + @for (creature of digimon; track creature) { + {{ creature.viewValue }} + }

    @@ -197,45 +204,52 @@ -
    - - formControl + @if (showSelect) { +
    + + formControl - - - Food I would like to eat - - {{ food.viewValue }} - - -

    Value: {{ foodControl.value }}

    -

    Touched: {{ foodControl.touched }}

    -

    Dirty: {{ foodControl.dirty }}

    -

    Status: {{ foodControl.status }}

    - - - -
    -
    -
    + + + Food I would like to eat + + @for (food of foods; track food) { + {{ food.viewValue }} + } + + +

    Value: {{ foodControl.value }}

    +

    Touched: {{ foodControl.touched }}

    +

    Dirty: {{ foodControl.dirty }}

    +

    Status: {{ foodControl.status }}

    + + + +
    +
    +
    + } -
    - - Change event + @if (showSelect) { +
    + + Change event - - - Starter pokemon - - {{ creature.viewValue }} - - - -

    Change event value: {{ latestChangeEvent?.value }}

    -
    -
    -
    + + + Starter pokemon + + @for (creature of pokemon; track creature) { + {{ creature.viewValue }} + } + + +

    Change event value: {{ latestChangeEvent?.value }}

    +
    +
    +
    + } @@ -342,9 +356,9 @@

    Error message, hint, form sumbit

    - - This field is required - + @if (selectFormControl.hasError('required')) { + This field is required + } You can pick up your favorite car here @@ -357,9 +371,9 @@

    Error message with errorStateMatcher

    - - This field is required - + @if (selectFormControl.hasError('required')) { + This field is required + } You can pick up your favorite car here @@ -375,27 +389,27 @@

    Error message with errorStateMatcher

    Bread - - {{ bread.viewValue }} - + @for (bread of breads; track bread) { + {{ bread.viewValue }} + } Meat - - {{ meat.viewValue }} - + @for (meat of meats; track meat) { + {{ meat.viewValue }} + } Cheese - - {{ cheese.viewValue }} - + @for (cheese of cheeses; track cheese) { + {{ cheese.viewValue }} + }

    @@ -403,4 +417,4 @@

    Error message with errorStateMatcher

    Hide Single-Selection Indicator -
    \ No newline at end of file + diff --git a/src/dev-app/sidenav/sidenav-demo.html b/src/dev-app/sidenav/sidenav-demo.html index 7df77ef46f58..f7d461e9b827 100644 --- a/src/dev-app/sidenav/sidenav-demo.html +++ b/src/dev-app/sidenav/sidenav-demo.html @@ -1,9 +1,8 @@ - - -
    - Header +@if (isLaunched) { +
    + @if (showHeader && !coverHeader) { + Header + } @@ -17,7 +16,9 @@
    Mode: {{start.mode}}

    -
    Filler Content
    + @for (c of fillerContent; track c) { +
    Filler Content
    + }
    -
    Filler Content
    + @for (c of fillerContent; track c) { +
    Filler Content
    + }
    - Header + @if (showHeader && coverHeader) { + Header + }
    -
    Filler Content
    + @for (c of fillerContent; track c) { +
    Filler Content
    + }
    - Footer + @if (showFooter && coverHeader) { + Footer + }
    - Footer + @if (showFooter && !coverHeader) { + Footer + }
    +} @else { + +} diff --git a/src/dev-app/slider/slider-demo.ts b/src/dev-app/slider/slider-demo.ts index 42deace7e2f6..3f74bda5e271 100644 --- a/src/dev-app/slider/slider-demo.ts +++ b/src/dev-app/slider/slider-demo.ts @@ -17,7 +17,7 @@ import {MatButtonModule} from '@angular/material/button'; import {ThemePalette} from '@angular/material/core'; interface DialogData { - color: string; + color: ThemePalette; discrete: boolean; showTickMarks: boolean; } diff --git a/src/dev-app/snack-bar/snack-bar-demo.html b/src/dev-app/snack-bar/snack-bar-demo.html index 080876020a1c..26d54831feb0 100644 --- a/src/dev-app/snack-bar/snack-bar-demo.html +++ b/src/dev-app/snack-bar/snack-bar-demo.html @@ -25,24 +25,30 @@

    SnackBar demo

    -

    Show button on snack bar

    - - Snack bar action label - - + @if (action) { + + Snack bar action label + + + } @else { +

    Show button on snack bar

    + }
    -

    Auto hide after duration

    - - Auto hide duration in ms - - + @if (setAutoHide) { + + Auto hide duration in ms + + + } @else { +

    Auto hide after duration

    + }

    diff --git a/src/dev-app/stepper/stepper-demo.html b/src/dev-app/stepper/stepper-demo.html index 9b6004bb2d8d..1dd2a5e94cda 100644 --- a/src/dev-app/stepper/stepper-demo.html +++ b/src/dev-app/stepper/stepper-demo.html @@ -16,7 +16,9 @@ Theme - {{theme.name}} + @for (theme of availableThemes; track theme) { + {{theme.name}} + }

    @@ -231,17 +233,19 @@

    Horizontal Stepper Demo with Text Label

    Horizontal Stepper Demo with Templated Label

    - - {{step.label}} - - Answer - - -
    - - -
    -
    + @for (step of steps; track step) { + + {{step.label}} + + Answer + + +
    + + +
    +
    + }

    Stepper with autosize textarea

    diff --git a/src/dev-app/table-scroll-container/table-scroll-container-demo.html b/src/dev-app/table-scroll-container/table-scroll-container-demo.html index 21aa8b40398d..69229922693e 100644 --- a/src/dev-app/table-scroll-container/table-scroll-container-demo.html +++ b/src/dev-app/table-scroll-container/table-scroll-container-demo.html @@ -35,46 +35,46 @@ -
    - - - - - - +@for (table of tables; track table) { +
    +
    Position {{element.position}} Position Footer
    + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - + + - + - - -
    Position {{element.position}} Position Footer Name {{element.name}} Name Footer Name {{element.name}} Name Footer Weight {{element.weight}} Weight Footer Weight {{element.weight}} Weight Footer Symbol {{element.symbol}} Symbol Footer Symbol {{element.symbol}} Symbol Footer Filler header cell Filler data cell Filler footer cell Filler header cell Filler data cell Filler footer cell
    -
    + + + + +} diff --git a/src/dev-app/youtube-player/youtube-player-demo.html b/src/dev-app/youtube-player/youtube-player-demo.html index a7ff2eb4c615..5a8a04f8c6c2 100644 --- a/src/dev-app/youtube-player/youtube-player-demo.html +++ b/src/dev-app/youtube-player/youtube-player-demo.html @@ -4,9 +4,9 @@

    Basic Example

    - - {{video.name}} - + @for (video of videos; track video) { + {{video.name}} + } Unset
    diff --git a/src/e2e-app/components/e2e-app/e2e-app.html b/src/e2e-app/components/e2e-app/e2e-app.html index d948ef73a18f..7bfa37644fa5 100644 --- a/src/e2e-app/components/e2e-app/e2e-app.html +++ b/src/e2e-app/components/e2e-app/e2e-app.html @@ -1,9 +1,13 @@
    - - {{link.title}} - + @if (showLinks) { + + @for (link of navLinks; track link) { + {{link.title}} + } + + }
    diff --git a/src/google-maps/README.md b/src/google-maps/README.md index 8cc09375b663..acea33991e30 100644 --- a/src/google-maps/README.md +++ b/src/google-maps/README.md @@ -59,7 +59,7 @@ export class GoogleMapsDemoComponent { apiLoaded: Observable; constructor(httpClient: HttpClient) { - // If you're using the `` directive, you also have to include the `visualization` library + // If you're using the `` directive, you also have to include the `visualization` library // when loading the Google Maps API. To do so, you can add `&libraries=visualization` to the script URL: // https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=visualization @@ -75,9 +75,9 @@ export class GoogleMapsDemoComponent { ```html -
    +@if (apiLoaded | async) { -
    +} ``` ## Components diff --git a/src/google-maps/map-directions-renderer/README.md b/src/google-maps/map-directions-renderer/README.md index d40c54678c31..f0e705d4dd51 100644 --- a/src/google-maps/map-directions-renderer/README.md +++ b/src/google-maps/map-directions-renderer/README.md @@ -51,7 +51,8 @@ export class GoogleMapDemo { width="750px" [center]="center" [zoom]="zoom"> - + @if (directionsResults$ | async; as directionsResults) { + + } ``` diff --git a/src/google-maps/map-info-window/README.md b/src/google-maps/map-info-window/README.md index 4b60ab0ebfdb..046553258ab2 100644 --- a/src/google-maps/map-info-window/README.md +++ b/src/google-maps/map-info-window/README.md @@ -39,10 +39,12 @@ export class GoogleMapDemo { [center]="center" [zoom]="zoom" (mapClick)="addMarker($event)"> - + + @for (position of markerPositions; track position) { + + } Info Window content ``` diff --git a/src/google-maps/map-marker-clusterer/README.md b/src/google-maps/map-marker-clusterer/README.md index 4b73cc8d6a77..1ca18feb31b4 100644 --- a/src/google-maps/map-marker-clusterer/README.md +++ b/src/google-maps/map-marker-clusterer/README.md @@ -43,8 +43,9 @@ export class GoogleMapDemo { [zoom]="zoom" (mapClick)="addMarker($event)"> - + @for (position of markerPositions; track position) { + + } ``` diff --git a/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts b/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts index c4a5e475ee91..ed08e42e22b6 100644 --- a/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts +++ b/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts @@ -325,9 +325,15 @@ describe('MapMarkerClusterer', () => { [options]="options" (clusteringbegin)="onClusteringBegin()" (clusterClick)="onClusterClick()"> - - - + @if (state === 'state1') { + + } + @if (state === 'state1' || state === 'state2') { + + } + @if (state === 'state2') { + + } `, }) diff --git a/src/google-maps/map-marker/README.md b/src/google-maps/map-marker/README.md index 2089aebd9f2d..2360943b2940 100644 --- a/src/google-maps/map-marker/README.md +++ b/src/google-maps/map-marker/README.md @@ -32,8 +32,8 @@ export class GoogleMapDemo { [center]="center" [zoom]="zoom" (mapClick)="addMarker($event)"> - + @for (position of markerPositions; track position) { + + } ``` diff --git a/src/material/autocomplete/autocomplete.md b/src/material/autocomplete/autocomplete.md index 48fdcd9070e4..6bb167e3b029 100644 --- a/src/material/autocomplete/autocomplete.md +++ b/src/material/autocomplete/autocomplete.md @@ -111,7 +111,9 @@ autocomplete is attached to using the `matAutocompleteOrigin` directive together - {{option}} + @for (option of options; track option) { + {{option}} + } ``` diff --git a/src/material/autocomplete/autocomplete.spec.ts b/src/material/autocomplete/autocomplete.spec.ts index 801d808702bd..4723e194cac9 100644 --- a/src/material/autocomplete/autocomplete.spec.ts +++ b/src/material/autocomplete/autocomplete.spec.ts @@ -3758,7 +3758,9 @@ describe('MDC-based MatAutocomplete', () => { const SIMPLE_AUTOCOMPLETE_TEMPLATE = ` - State + @if (hasLabel) { + State + } - - {{ state.code }}: {{ state.name }} - + @for (state of filteredStates; track state) { + + {{ state.code }}: {{ state.name }} + + } `; @@ -3848,14 +3851,18 @@ class SimpleAutocompleteShadowDom extends SimpleAutocomplete {} @Component({ template: ` - + @if (isVisible) { + +} - + @for (option of filteredOptions | async; track option) { + {{option}} +} `, }) @@ -3888,9 +3895,11 @@ class NgIfAutocomplete { - - {{ state }} - + @for (state of filteredStates; track state) { + + {{ state }} + + } `, }) @@ -3915,9 +3924,11 @@ class AutocompleteWithoutForms { - - {{ state }} - + @for (state of filteredStates; track state) { + + {{ state }} + + } `, }) @@ -3944,9 +3955,11 @@ class AutocompleteWithNgModel { - - {{ number }} - + @for (number of numbers; track number) { + + {{ number }} + + } `, }) @@ -3963,7 +3976,9 @@ class AutocompleteWithNumbers { - {{ option }} + @for (option of options; track option) { + {{ option }} + } `, }) @@ -3983,9 +3998,9 @@ class AutocompleteWithOnPushDelay implements OnInit { - - {{option}} - + @for (option of filteredOptions | async; track option) { + {{option}} + } `, }) @@ -4024,11 +4039,15 @@ class AutocompleteWithoutPanel { - - - {{ state }} - - + @for (group of stateGroups; track group) { + + @for (state of group.states; track state) { + + {{ state }} + + } + + } `, }) @@ -4058,13 +4077,17 @@ class AutocompleteWithGroups { - - - - {{ state }} - - - + @if (true) { + @for (group of stateGroups; track group) { + + @for (state of group.states; track state) { + + {{ state }} + + } + + } + } `, }) @@ -4077,9 +4100,11 @@ class AutocompleteWithIndirectGroups extends AutocompleteWithGroups {} - - {{ state }} - + @for (state of states; track state) { + + {{ state }} + + } `, }) @@ -4109,7 +4134,9 @@ class PlainAutocompleteInputWithFormControl { - {{value}} + @for (value of values; track value) { + {{value}} + } `, }) @@ -4139,7 +4166,9 @@ class AutocompleteWithNumberInputAndNgModel { - {{value}} + @for (value of values; track value) { + {{value}} + } `, }) @@ -4173,7 +4202,9 @@ class InputWithoutAutocompleteAndDisabled {} - {{ state }} + @for (state of states; track state) { + {{ state }} + } `, }) @@ -4198,9 +4229,9 @@ class AutocompleteWithActivatedEvent { - - {{food.viewValue}} - + @for (food of foods; track food; let index = $index) { + {{food.viewValue}} + }
    diff --git a/src/material/autocomplete/testing/autocomplete-harness.spec.ts b/src/material/autocomplete/testing/autocomplete-harness.spec.ts index 0c4350e3f371..2948d774bfb8 100644 --- a/src/material/autocomplete/testing/autocomplete-harness.spec.ts +++ b/src/material/autocomplete/testing/autocomplete-harness.spec.ts @@ -156,15 +156,19 @@ describe('MatAutocompleteHarness', () => { @Component({ template: ` - {{ state.name }} + @for (state of states; track state) { + {{ state.name }} + } - - {{ state.name }} - + @for (group of stateGroups; track group) { + + @for (state of group.states; track state) { + {{ state.name }} + } + + } diff --git a/src/material/button-toggle/button-toggle.spec.ts b/src/material/button-toggle/button-toggle.spec.ts index 9b38f86d4669..4217167225bb 100644 --- a/src/material/button-toggle/button-toggle.spec.ts +++ b/src/material/button-toggle/button-toggle.spec.ts @@ -962,7 +962,9 @@ describe('MatButtonToggle without forms', () => { - Test1 + @if (renderFirstToggle) { + Test1 + } Test2 Test3 @@ -981,12 +983,12 @@ class ButtonTogglesInsideButtonToggleGroup { [name]="groupName" [(ngModel)]="modelValue" (change)="lastEvent = $event"> - - {{option.label}} - + @for (option of options; track option) { + {{option.label}} + } `, }) @@ -1064,14 +1066,14 @@ class ButtonToggleGroupWithFormControl { } @Component({ - // We need the `ngSwitch` so that there's a directive between the group and the toggles. + // We need the `@if` so that there's a container between the group and the toggles. template: ` - + @if (true) { Value Red Value Green Value Blue - + } `, }) @@ -1094,9 +1096,9 @@ class ButtonToggleWithAriaLabelledby {} @Component({ template: ` - - {{toggle}} - + @for (toggle of possibleValues; track toggle) { + {{toggle}} + } `, }) @@ -1141,7 +1143,9 @@ class ButtonToggleWithStaticAriaAttributes {} @Component({ template: ` - {{value}} + @for (value of values; track value) { + {{value}} + } `, }) diff --git a/src/material/button/_button-base.scss b/src/material/button/_button-base.scss index 9755ae930317..c2443f93ffe0 100644 --- a/src/material/button/_button-base.scss +++ b/src/material/button/_button-base.scss @@ -1,5 +1,6 @@ @use '@material/touch-target' as mdc-touch-target; +@use '../core/tokens/token-utils'; @use '../core/style/layout-common'; @use '../core/mdc-helpers/mdc-helpers'; @@ -39,11 +40,6 @@ .mat-mdc-button-persistent-ripple::before { content: ''; opacity: 0; - background-color: var(--mat-mdc-button-persistent-ripple-color); - } - - .mat-ripple-element { - background-color: var(--mat-mdc-button-ripple-color); } // The content should appear over the state and ripple layers, otherwise they may adversely affect @@ -62,6 +58,33 @@ } } +@mixin mat-private-button-ripple($prefix, $slots) { + @include token-utils.use-tokens($prefix, $slots) { + .mat-ripple-element { + @include token-utils.create-token-slot(background-color, ripple-color); + } + + .mat-mdc-button-persistent-ripple::before { + @include token-utils.create-token-slot(background-color, state-layer-color); + } + + &:hover .mat-mdc-button-persistent-ripple::before { + @include token-utils.create-token-slot(opacity, hover-state-layer-opacity); + } + + &.cdk-program-focused, + &.cdk-keyboard-focused { + .mat-mdc-button-persistent-ripple::before { + @include token-utils.create-token-slot(opacity, focus-state-layer-opacity); + } + } + + &:active .mat-mdc-button-persistent-ripple::before { + @include token-utils.create-token-slot(opacity, pressed-state-layer-opacity); + } + } +} + // MDC's disabled buttons define a default cursor with pointer-events none. However, they select // :disabled for this, which does not affect anchor tags. // TODO(andrewseguin): Discuss with the MDC team about a mixin we can call for applying this style, @@ -75,6 +98,15 @@ } } +// Hides the touch target on lower densities. +@mixin mat-private-button-touch-target-density($scale) { + @include mdc-helpers.if-touch-targets-unsupported($scale) { + .mat-mdc-button-touch-target { + display: none; + } + } +} + @mixin mat-private-button-touch-target($is-square) { // Element used to ensure that the button has a touch target that meets the required minimum. // Note that we use this, instead of MDC's built-in `mdc-button--touch` class, because the MDC diff --git a/src/material/button/_button-theme-private.scss b/src/material/button/_button-theme-private.scss deleted file mode 100644 index 2926f533c46b..000000000000 --- a/src/material/button/_button-theme-private.scss +++ /dev/null @@ -1,55 +0,0 @@ -@use 'sass:map'; -@use '@material/ripple/ripple-theme' as mdc-ripple-theme; -@use '@material/theme/theme-color' as mdc-theme-color; - -@use '../core/mdc-helpers/mdc-helpers'; -@use '../core/theming/inspection'; - -@mixin _ripple-color($color) { - --mat-mdc-button-persistent-ripple-color: #{$color}; - --mat-mdc-button-ripple-color: #{rgba($color, 0.1)}; -} - -@mixin ripple-theme-styles($theme, $is-filled) { - $opacities: if(inspection.get-theme-type($theme) == dark, - mdc-ripple-theme.$light-ink-opacities, mdc-ripple-theme.$dark-ink-opacities); - - // Ideally these styles would be structural, but MDC bases some of the opacities on the theme. - &:hover .mat-mdc-button-persistent-ripple::before { - opacity: map.get($opacities, hover); - } - - &.cdk-program-focused, - &.cdk-keyboard-focused { - .mat-mdc-button-persistent-ripple::before { - opacity: map.get($opacities, focus); - } - } - - &:active .mat-mdc-button-persistent-ripple::before { - opacity: map.get($opacities, press); - } - - @include _ripple-color(mdc-theme-color.prop-value(on-surface)); - - &.mat-primary { - @include _ripple-color(mdc-theme-color.prop-value(if($is-filled, on-primary, primary))); - } - - &.mat-accent { - @include _ripple-color(mdc-theme-color.prop-value(if($is-filled, on-secondary, secondary))); - } - - &.mat-warn { - @include _ripple-color(mdc-theme-color.prop-value(if($is-filled, on-error, error))); - } -} - -// Hides the touch target on lower densities. -@mixin touch-target-density($scale) { - @include mdc-helpers.if-touch-targets-unsupported($scale) { - .mat-mdc-button-touch-target { - display: none; - } - } -} diff --git a/src/material/button/_button-theme.scss b/src/material/button/_button-theme.scss index 1ccf96e803bf..fe214cad2d67 100644 --- a/src/material/button/_button-theme.scss +++ b/src/material/button/_button-theme.scss @@ -5,118 +5,132 @@ @use '@material/button/button-outlined-theme' as mdc-button-outlined-theme; @use '@material/elevation/elevation-theme' as mdc-elevation-theme; -@use './button-theme-private'; +@use './button-base'; @use '../core/mdc-helpers/mdc-helpers'; @use '../core/theming/theming'; @use '../core/theming/inspection'; +@use '../core/tokens/token-utils'; @use '../core/typography/typography'; @use '../core/tokens/m2/mdc/filled-button' as tokens-mdc-filled-button; +@use '../core/tokens/m2/mat/filled-button' as tokens-mat-filled-button; @use '../core/tokens/m2/mdc/outlined-button' as tokens-mdc-outlined-button; +@use '../core/tokens/m2/mat/outlined-button' as tokens-mat-outlined-button; @use '../core/tokens/m2/mdc/protected-button' as tokens-mdc-protected-button; +@use '../core/tokens/m2/mat/protected-button' as tokens-mat-protected-button; @use '../core/tokens/m2/mdc/text-button' as tokens-mdc-text-button; +@use '../core/tokens/m2/mat/text-button' as tokens-mat-text-button; -@function _on-color($theme, $palette) { - $is-dark: inspection.get-theme-type($theme) == dark; - @return if(mdc-helpers.variable-safe-contrast-tone($palette, $is-dark) == 'dark', #000, #fff); + +@mixin _text-button-variant($theme, $palette) { + $mdc-tokens: if($palette, + tokens-mdc-text-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mdc-text-button.get-color-tokens($theme) + ); + + $mat-tokens: if($palette, + tokens-mat-text-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mat-text-button.get-color-tokens($theme) + ); + + @include mdc-button-text-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mat-text-button.$prefix, $mat-tokens); } -@mixin base($theme) { - // TODO(mmalerba): Move button base tokens here +@mixin _filled-button-variant($theme, $palette) { + $mdc-tokens: if($palette, + tokens-mdc-filled-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mdc-filled-button.get-color-tokens($theme) + ); + + $mat-tokens: if($palette, + tokens-mat-filled-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mat-filled-button.get-color-tokens($theme) + ); + + @include mdc-button-filled-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mat-filled-button.$prefix, $mat-tokens); } -@mixin color($theme) { - $surface: inspection.get-theme-color($theme, background, card); - $primary: inspection.get-theme-color($theme, primary); - $accent: inspection.get-theme-color($theme, accent); - $error: inspection.get-theme-color($theme, warn); +@mixin _protected-button-variant($theme, $palette) { + $mdc-tokens: if($palette, + tokens-mdc-protected-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mdc-protected-button.get-color-tokens($theme) + ); - $on-surface: _on-color($theme, $surface); - $on-primary: _on-color($theme, $primary); - $on-accent: _on-color($theme, $accent); - $on-error: _on-color($theme, $error); + $mat-tokens: if($palette, + tokens-mat-protected-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mat-protected-button.get-color-tokens($theme) + ); - // TODO: remove these when tokenizing the ripples. - @include mdc-helpers.using-mdc-theme($theme) { - // Ripple colors - .mat-mdc-button, .mat-mdc-outlined-button { - @include button-theme-private.ripple-theme-styles($theme, false); - } + @include mdc-button-protected-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mat-protected-button.$prefix, $mat-tokens); +} - .mat-mdc-raised-button, .mat-mdc-unelevated-button { - @include button-theme-private.ripple-theme-styles($theme, true); - } - } +@mixin _outlined-button-variant($theme, $palette) { + $mdc-tokens: if($palette, + tokens-mdc-outlined-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mdc-outlined-button.get-color-tokens($theme) + ); + $mat-tokens: if($palette, + tokens-mat-outlined-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mat-outlined-button.get-color-tokens($theme) + ); + + @include mdc-button-outlined-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mat-outlined-button.$prefix, $mat-tokens); +} + +@mixin base($theme) { + // TODO(mmalerba): Move button base tokens here +} + +@mixin color($theme) { .mat-mdc-button { - @include mdc-button-text-theme.theme(tokens-mdc-text-button.get-color-tokens($theme)); + @include _text-button-variant($theme, null); &.mat-primary { - @include mdc-button-text-theme.theme( - tokens-mdc-text-button.private-get-color-palette-color-tokens($theme, primary)); + @include _text-button-variant($theme, primary); } &.mat-accent { - @include mdc-button-text-theme.theme( - tokens-mdc-text-button.private-get-color-palette-color-tokens($theme, accent)); + @include _text-button-variant($theme, accent); } &.mat-warn { - @include mdc-button-text-theme.theme( - tokens-mdc-text-button.private-get-color-palette-color-tokens($theme, warn)); + @include _text-button-variant($theme, warn); } } .mat-mdc-unelevated-button { - $default-color-tokens: tokens-mdc-filled-button.get-color-tokens($theme, $surface, $on-surface); - $primary-color-tokens: tokens-mdc-filled-button.get-color-tokens($theme, $primary, $on-primary); - $accent-color-tokens: tokens-mdc-filled-button.get-color-tokens($theme, $accent, $on-accent); - $warn-color-tokens: tokens-mdc-filled-button.get-color-tokens($theme, $error, $on-error); - - &.mat-unthemed { - @include mdc-button-filled-theme.theme($default-color-tokens); - } + @include _filled-button-variant($theme, null); &.mat-primary { - @include mdc-button-filled-theme.theme($primary-color-tokens); + @include _filled-button-variant($theme, primary); } &.mat-accent { - @include mdc-button-filled-theme.theme($accent-color-tokens); + @include _filled-button-variant($theme, accent); } &.mat-warn { - @include mdc-button-filled-theme.theme($warn-color-tokens); + @include _filled-button-variant($theme, warn); } } .mat-mdc-raised-button { - $default-color-tokens: tokens-mdc-protected-button.get-color-tokens( - $theme, - $surface, - $on-surface - ); - $primary-color-tokens: tokens-mdc-protected-button.get-color-tokens( - $theme, - $primary, - $on-primary - ); - $accent-color-tokens: tokens-mdc-protected-button.get-color-tokens($theme, $accent, $on-accent); - $warn-color-tokens: tokens-mdc-protected-button.get-color-tokens($theme, $error, $on-error); - - &.mat-unthemed { - @include mdc-button-protected-theme.theme($default-color-tokens); - } + @include _protected-button-variant($theme, null); &.mat-primary { - @include mdc-button-protected-theme.theme($primary-color-tokens); + @include _protected-button-variant($theme, primary); } &.mat-accent { - @include mdc-button-protected-theme.theme($accent-color-tokens); + @include _protected-button-variant($theme, accent); } &.mat-warn { - @include mdc-button-protected-theme.theme($warn-color-tokens); + @include _protected-button-variant($theme, warn); } // TODO(wagnermaciel): Remove this workaround when b/301126527 is resolved @@ -134,33 +148,18 @@ } .mat-mdc-outlined-button { - $default-color-tokens: tokens-mdc-outlined-button.get-color-tokens( - $theme, - $on-surface, - $on-surface - ); - $primary-color-tokens: tokens-mdc-outlined-button.get-color-tokens( - $theme, - $primary, - $on-primary - ); - $accent-color-tokens: tokens-mdc-outlined-button.get-color-tokens($theme, $accent, $on-accent); - $warn-color-tokens: tokens-mdc-outlined-button.get-color-tokens($theme, $error, $on-error); - - &.mat-unthemed { - @include mdc-button-outlined-theme.theme($default-color-tokens); - } + @include _outlined-button-variant($theme, null); &.mat-primary { - @include mdc-button-outlined-theme.theme($primary-color-tokens); + @include _outlined-button-variant($theme, primary); } &.mat-accent { - @include mdc-button-outlined-theme.theme($accent-color-tokens); + @include _outlined-button-variant($theme, accent); } &.mat-warn { - @include mdc-button-outlined-theme.theme($warn-color-tokens); + @include _outlined-button-variant($theme, warn); } } } @@ -177,25 +176,25 @@ .mat-mdc-button { $density-tokens: tokens-mdc-text-button.get-density-tokens($theme); @include mdc-button-text-theme.theme($density-tokens); - @include button-theme-private.touch-target-density($density-scale); + @include button-base.mat-private-button-touch-target-density($density-scale); } .mat-mdc-raised-button { $density-tokens: tokens-mdc-protected-button.get-density-tokens($theme); @include mdc-button-protected-theme.theme($density-tokens); - @include button-theme-private.touch-target-density($density-scale); + @include button-base.mat-private-button-touch-target-density($density-scale); } .mat-mdc-unelevated-button { $density-tokens: tokens-mdc-filled-button.get-density-tokens($theme); @include mdc-button-filled-theme.theme($density-tokens); - @include button-theme-private.touch-target-density($density-scale); + @include button-base.mat-private-button-touch-target-density($density-scale); } .mat-mdc-outlined-button { $density-tokens: tokens-mdc-outlined-button.get-density-tokens($theme); @include mdc-button-outlined-theme.theme($density-tokens); - @include button-theme-private.touch-target-density($density-scale); + @include button-base.mat-private-button-touch-target-density($density-scale); } } diff --git a/src/material/button/_fab-theme.scss b/src/material/button/_fab-theme.scss index 3f667eaf0fd3..4841b30f2142 100644 --- a/src/material/button/_fab-theme.scss +++ b/src/material/button/_fab-theme.scss @@ -2,7 +2,6 @@ @use '@material/fab/fab-theme' as mdc-fab-theme; @use '@material/fab/extended-fab-theme' as mdc-extended-fab-theme; -@use './button-theme-private'; @use '../core/mdc-helpers/mdc-helpers'; @use '../core/style/sass-utils'; @use '../core/theming/theming'; @@ -42,15 +41,8 @@ @include sass-utils.current-selector-or-root() { @include _fab-variant($theme, null); - // TODO(wagnermaciel): The ripple-theme-styles mixin depends heavily on - // being wrapped by using-mdc-theme. This workaround needs to be - // revisited w/ a more holistic solution. .mat-mdc-fab, .mat-mdc-mini-fab { - @include mdc-helpers.using-mdc-theme($theme) { - @include button-theme-private.ripple-theme-styles($theme, true); - } - &.mat-primary { @include _fab-variant($theme, primary); } diff --git a/src/material/button/_icon-button-theme.scss b/src/material/button/_icon-button-theme.scss index b4c55c0edc47..511e9ac55731 100644 --- a/src/material/button/_icon-button-theme.scss +++ b/src/material/button/_icon-button-theme.scss @@ -1,20 +1,15 @@ @use 'sass:math'; @use '@material/density/functions' as mdc-density-functions; @use '@material/icon-button/icon-button-theme' as mdc-icon-button-theme; -@use '../core/style/sass-utils'; @use '../core/tokens/m2/mdc/icon-button' as tokens-mdc-icon-button; +@use '../core/tokens/m2/mat/icon-button' as tokens-mat-icon-button; -@use './button-theme-private'; +@use '../core/style/sass-utils'; +@use './button-base'; +@use '../core/tokens/token-utils'; @use '../core/theming/theming'; @use '../core/theming/inspection'; -$_icon-size: 24px; - -// TODO(crisbeto): move these into tokens -@mixin _ripple-color($color) { - --mat-mdc-button-persistent-ripple-color: #{$color}; - --mat-mdc-button-ripple-color: #{rgba($color, 0.1)}; -} @mixin base($theme) { // Add default values for tokens not related to color, typography, or density. @@ -23,31 +18,35 @@ $_icon-size: 24px; } } -@mixin color($theme) { - $color-tokens: tokens-mdc-icon-button.get-color-tokens($theme); - $is-dark: inspection.get-theme-type($theme) == dark; +@mixin _icon-button-variant($theme, $palette) { + $mdc-tokens: if($palette, + tokens-mdc-icon-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mdc-icon-button.get-color-tokens($theme) + ); + $mat-tokens: if($palette, + tokens-mat-icon-button.private-get-color-palette-color-tokens($theme, $palette), + tokens-mat-icon-button.get-color-tokens($theme) + ); + + @include mdc-icon-button-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mat-icon-button.$prefix, $mat-tokens); +} + +@mixin color($theme) { .mat-mdc-icon-button { - @include button-theme-private.ripple-theme-styles($theme, false); - @include mdc-icon-button-theme.theme($color-tokens); - @include _ripple-color(if($is-dark, #fff, #000)); + @include _icon-button-variant($theme, null); &.mat-primary { - @include _ripple-color(inspection.get-theme-color($theme, primary)); - @include mdc-icon-button-theme.theme( - tokens-mdc-icon-button.private-get-color-palette-color-tokens($theme, primary)); + @include _icon-button-variant($theme, primary); } &.mat-accent { - @include _ripple-color(inspection.get-theme-color($theme, accent)); - @include mdc-icon-button-theme.theme( - tokens-mdc-icon-button.private-get-color-palette-color-tokens($theme, accent)); + @include _icon-button-variant($theme, accent); } &.mat-warn { - @include _ripple-color(inspection.get-theme-color($theme, warn)); - @include mdc-icon-button-theme.theme( - tokens-mdc-icon-button.private-get-color-palette-color-tokens($theme, warn)); + @include _icon-button-variant($theme, warn); } } } @@ -55,6 +54,7 @@ $_icon-size: 24px; @mixin typography($theme) {} @mixin density($theme) { + $icon-size: 24px; $density-scale: inspection.get-theme-density($theme); // Manually apply the expected density theming, and include the padding // as it was applied before @@ -85,9 +85,9 @@ $_icon-size: 24px; // fails validation because the variable is "undefined" in the sass stack. width: var(--mdc-icon-button-state-layer-size); height: var(--mdc-icon-button-state-layer-size); - padding: math.div($calculated-size - $_icon-size, 2); + padding: math.div($calculated-size - $icon-size, 2); - @include button-theme-private.touch-target-density($density-scale); + @include button-base.mat-private-button-touch-target-density($density-scale); } } diff --git a/src/material/button/button.scss b/src/material/button/button.scss index 21c9c6ab9c0e..0f159ce4860e 100644 --- a/src/material/button/button.scss +++ b/src/material/button/button.scss @@ -13,9 +13,13 @@ @use '../core/tokens/token-utils'; @use '../core/focus-indicators/private' as focus-indicators-private; @use '../core/tokens/m2/mdc/filled-button' as tokens-mdc-filled-button; +@use '../core/tokens/m2/mat/filled-button' as tokens-mat-filled-button; @use '../core/tokens/m2/mdc/outlined-button' as tokens-mdc-outlined-button; +@use '../core/tokens/m2/mat/outlined-button' as tokens-mat-outlined-button; @use '../core/tokens/m2/mdc/protected-button' as tokens-mdc-protected-button; +@use '../core/tokens/m2/mat/protected-button' as tokens-mat-protected-button; @use '../core/tokens/m2/mdc/text-button' as tokens-mdc-text-button; +@use '../core/tokens/m2/mat/text-button' as tokens-mat-text-button; @include mdc-helpers.disable-mdc-fallback-declarations { @include mdc-button.static-styles-without-ripple($query: mdc-helpers.$mdc-base-styles-query); @@ -27,6 +31,8 @@ @include mdc-button-text-theme.theme-styles($mdc-text-button-slots); @include mdc-button-text-theme.theme(tokens-mdc-text-button.get-unthemable-tokens()); + @include button-base.mat-private-button-ripple(tokens-mat-text-button.$prefix, + tokens-mat-text-button.get-token-slots()); @include token-utils.use-tokens(tokens-mdc-text-button.$prefix, $mdc-text-button-slots) { // We need to re-apply the disabled tokens since MDC uses @@ -40,11 +46,10 @@ .mat-mdc-unelevated-button { $mdc-filled-button-slots: tokens-mdc-filled-button.get-token-slots(); - // Add the slots for MDC text button. @include mdc-button-filled-theme.theme-styles($mdc-filled-button-slots); - - // Add default values for MDC text button tokens that aren't outputted by the theming API. @include mdc-button-filled-theme.theme(tokens-mdc-filled-button.get-unthemable-tokens()); + @include button-base.mat-private-button-ripple(tokens-mat-filled-button.$prefix, + tokens-mat-filled-button.get-token-slots()); @include token-utils.use-tokens(tokens-mdc-filled-button.$prefix, $mdc-filled-button-slots) { // We need to re-apply the disabled tokens since MDC uses @@ -59,11 +64,10 @@ .mat-mdc-raised-button { $mdc-button-protected-slots: tokens-mdc-protected-button.get-token-slots(); - // Add the slots for MDC text button. @include mdc-button-protected-theme.theme-styles($mdc-button-protected-slots); - - // Add default values for MDC text button tokens that aren't outputted by the theming API. @include mdc-button-protected-theme.theme(tokens-mdc-protected-button.get-unthemable-tokens()); + @include button-base.mat-private-button-ripple(tokens-mat-protected-button.$prefix, + tokens-mat-protected-button.get-token-slots()); @include token-utils.use-tokens( tokens-mdc-protected-button.$prefix, @@ -85,11 +89,10 @@ .mat-mdc-outlined-button { $mdc-outlined-button-slots: tokens-mdc-outlined-button.get-token-slots(); - // Add the slots for MDC text button. @include mdc-button-outlined-theme.theme-styles($mdc-outlined-button-slots); - - // Add default values for MDC text button tokens that aren't outputted by the theming API. @include mdc-button-outlined-theme.theme(tokens-mdc-outlined-button.get-unthemable-tokens()); + @include button-base.mat-private-button-ripple(tokens-mat-outlined-button.$prefix, + tokens-mat-outlined-button.get-token-slots()); @include token-utils.use-tokens( tokens-mdc-outlined-button.$prefix, diff --git a/src/material/button/fab.scss b/src/material/button/fab.scss index 3902c2b50304..8c07e851e388 100644 --- a/src/material/button/fab.scss +++ b/src/material/button/fab.scss @@ -35,6 +35,8 @@ .mat-mdc-fab, .mat-mdc-mini-fab { @include button-base.mat-private-button-interactive(); @include button-base.mat-private-button-touch-target(true); + @include button-base.mat-private-button-ripple(tokens-mat-fab.$prefix, + tokens-mat-fab.get-token-slots()); @include style-private.private-animation-noop(); @include elevation.elevation(6); flex-shrink: 0; // Prevent the button from shrinking since it's always supposed to be a circle. diff --git a/src/material/button/icon-button.scss b/src/material/button/icon-button.scss index 2ba3e1c86b32..383b71e3634a 100644 --- a/src/material/button/icon-button.scss +++ b/src/material/button/icon-button.scss @@ -3,6 +3,7 @@ @use '@material/theme/custom-properties' as mdc-custom-properties; @use '../core/tokens/m2/mdc/icon-button' as tokens-mdc-icon-button; +@use '../core/tokens/m2/mat/icon-button' as tokens-mat-icon-button; @use './button-base'; @use '../core/style/private'; @@ -53,6 +54,8 @@ } @include button-base.mat-private-button-interactive(); + @include button-base.mat-private-button-ripple(tokens-mat-icon-button.$prefix, + tokens-mat-icon-button.get-token-slots()); @include button-base.mat-private-button-touch-target(true); @include private.private-animation-noop(); diff --git a/src/material/card/testing/card-harness.ts b/src/material/card/testing/card-harness.ts index a79c87098582..28627fed744f 100644 --- a/src/material/card/testing/card-harness.ts +++ b/src/material/card/testing/card-harness.ts @@ -14,7 +14,7 @@ import { import {CardHarnessFilters} from './card-harness-filters'; /** Selectors for different sections of the mat-card that can container user content. */ -export const enum MatCardSection { +export enum MatCardSection { HEADER = '.mat-mdc-card-header', CONTENT = '.mat-mdc-card-content', ACTIONS = '.mat-mdc-card-actions', diff --git a/src/material/checkbox/checkbox.ts b/src/material/checkbox/checkbox.ts index 77fdfdc12378..44836988ec23 100644 --- a/src/material/checkbox/checkbox.ts +++ b/src/material/checkbox/checkbox.ts @@ -39,7 +39,7 @@ import { * Represents the different states that require custom transitions between them. * @docs-private */ -export const enum TransitionCheckState { +export enum TransitionCheckState { /** The initial state of the component before any user interaction. */ Init, /** The state representing the component when it's becoming checked. */ diff --git a/src/material/chips/chip-action.ts b/src/material/chips/chip-action.ts index c7b98e36b08a..a791926267c8 100644 --- a/src/material/chips/chip-action.ts +++ b/src/material/chips/chip-action.ts @@ -6,25 +6,23 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; +import { + Directive, + ElementRef, + Inject, + Input, + booleanAttribute, + numberAttribute, +} from '@angular/core'; import {ENTER, SPACE} from '@angular/cdk/keycodes'; -import {Directive, ElementRef, Inject, Input} from '@angular/core'; -import {HasTabIndex, mixinTabIndex} from '@angular/material/core'; import {MAT_CHIP} from './tokens'; -abstract class _MatChipActionBase { - abstract disabled: boolean; -} - -const _MatChipActionMixinBase = mixinTabIndex(_MatChipActionBase, -1); - /** * Section within a chip. * @docs-private */ @Directive({ selector: '[matChipAction]', - inputs: ['disabled', 'tabIndex'], host: { 'class': 'mdc-evolution-chip__action mat-mdc-chip-action', '[class.mdc-evolution-chip__action--primary]': '_isPrimary', @@ -37,7 +35,7 @@ const _MatChipActionMixinBase = mixinTabIndex(_MatChipActionBase, -1); '(keydown)': '_handleKeydown($event)', }, }) -export class MatChipAction extends _MatChipActionMixinBase implements HasTabIndex { +export class MatChipAction { /** Whether the action is interactive. */ @Input() isInteractive = true; @@ -45,15 +43,21 @@ export class MatChipAction extends _MatChipActionMixinBase implements HasTabInde _isPrimary = true; /** Whether the action is disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return this._disabled || this._parentChip.disabled; } - set disabled(value: BooleanInput) { - this._disabled = coerceBooleanProperty(value); + set disabled(value: boolean) { + this._disabled = value; } private _disabled = false; + /** Tab index of the action. */ + @Input({ + transform: (value: unknown) => (value == null ? -1 : numberAttribute(value)), + }) + tabIndex: number = -1; + /** * Private API to allow focusing this chip when it is disabled. */ @@ -88,8 +92,6 @@ export class MatChipAction extends _MatChipActionMixinBase implements HasTabInde _isEditing?: boolean; }, ) { - super(); - if (_elementRef.nativeElement.nodeName === 'BUTTON') { _elementRef.nativeElement.setAttribute('type', 'button'); } diff --git a/src/material/chips/chip-grid.spec.ts b/src/material/chips/chip-grid.spec.ts index 946f017e8122..77790253d94c 100644 --- a/src/material/chips/chip-grid.spec.ts +++ b/src/material/chips/chip-grid.spec.ts @@ -1033,10 +1033,12 @@ describe('MDC-based MatChipGrid', () => { @Component({ template: ` - {{name}} {{i + 1}} +} `, }) @@ -1053,7 +1055,9 @@ class StandardChipGrid { Add a chip - {{chip}} + @for (chip of chips; track chip) { + {{chip}} +} @@ -1076,9 +1080,11 @@ class FormFieldChipGrid { New food... - + @for (food of foods; track food) { + {{ food.viewValue }} +} - + @for (food of foods; track food) { + {{food.viewValue}} +} Please select a chip, or type to add a new chip @@ -1162,7 +1170,9 @@ class ChipGridWithFormErrorMessages { @Component({ template: ` - {{i}} + @for (i of numbers; track i) { + {{i}} +} `, animations: [ @@ -1189,10 +1199,12 @@ class StandardChipGridWithAnimations { template: ` - + @for (i of chips; track i) { + Chip {{i + 1}} Remove +} diff --git a/src/material/chips/chip-grid.ts b/src/material/chips/chip-grid.ts index 01dfc3f1d2bb..0a576e62b7a3 100644 --- a/src/material/chips/chip-grid.ts +++ b/src/material/chips/chip-grid.ts @@ -6,11 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {hasModifierKey, TAB} from '@angular/cdk/keycodes'; import { AfterContentInit, AfterViewInit, + booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -55,8 +55,15 @@ export class MatChipGridChange { /** * Boilerplate for applying mixins to MatChipGrid. + * Important! this class needs to be marked as a component or a directive, because + * leaving it without metadata cuases the framework to execute the host bindings multiple + * times which breaks the keyboard navigation. We can't use `@Directive()` here, because + * `MatChipSet` is a component. We should able to remove this class altogether once + * the error state is moved away from using mixins. * @docs-private */ +// tslint:disable-next-line:validate-decorators +@Component({template: ''}) class MatChipGridBase extends MatChipSet { /** * Emits whenever the component state changes and should cause the parent @@ -96,11 +103,10 @@ const _MatChipGridMixinBase = mixinErrorState(MatChipGridBase); `, styleUrls: ['chip-set.css'], - inputs: ['tabIndex'], host: { 'class': 'mat-mdc-chip-set mat-mdc-chip-grid mdc-evolution-chip-set', '[attr.role]': 'role', - '[tabIndex]': '_chips && _chips.length === 0 ? -1 : tabIndex', + '[attr.tabindex]': '(disabled || (_chips && _chips.length === 0)) ? -1 : tabIndex', '[attr.aria-disabled]': 'disabled.toString()', '[attr.aria-invalid]': 'errorState', '[class.mat-mdc-chip-list-disabled]': 'disabled', @@ -156,12 +162,12 @@ export class MatChipGrid * Implemented as part of MatFormFieldControl. * @docs-private */ - @Input() + @Input({transform: booleanAttribute}) override get disabled(): boolean { return this.ngControl ? !!this.ngControl.disabled : this._disabled; } - override set disabled(value: BooleanInput) { - this._disabled = coerceBooleanProperty(value); + override set disabled(value: boolean) { + this._disabled = value; this._syncChipsState(); } @@ -206,12 +212,12 @@ export class MatChipGrid * Implemented as part of MatFormFieldControl. * @docs-private */ - @Input() + @Input({transform: booleanAttribute}) get required(): boolean { return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false; } - set required(value: BooleanInput) { - this._required = coerceBooleanProperty(value); + set required(value: boolean) { + this._required = value; this.stateChanges.next(); } protected _required: boolean | undefined; diff --git a/src/material/chips/chip-input.ts b/src/material/chips/chip-input.ts index e0a8161c06a6..6938e7ce0545 100644 --- a/src/material/chips/chip-input.ts +++ b/src/material/chips/chip-input.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {BACKSPACE, hasModifierKey} from '@angular/cdk/keycodes'; import { AfterContentInit, @@ -19,6 +18,7 @@ import { OnDestroy, Optional, Output, + booleanAttribute, } from '@angular/core'; import {MatFormField, MAT_FORM_FIELD} from '@angular/material/form-field'; import {MatChipsDefaultOptions, MAT_CHIPS_DEFAULT_OPTIONS} from './tokens'; @@ -92,14 +92,8 @@ export class MatChipInput implements MatChipTextControl, AfterContentInit, OnCha /** * Whether or not the chipEnd event will be emitted when the input is blurred. */ - @Input('matChipInputAddOnBlur') - get addOnBlur(): boolean { - return this._addOnBlur; - } - set addOnBlur(value: BooleanInput) { - this._addOnBlur = coerceBooleanProperty(value); - } - _addOnBlur: boolean = false; + @Input({alias: 'matChipInputAddOnBlur', transform: booleanAttribute}) + addOnBlur: boolean = false; /** * The list of key codes that will trigger a chipEnd event. @@ -120,12 +114,12 @@ export class MatChipInput implements MatChipTextControl, AfterContentInit, OnCha @Input() id: string = `mat-mdc-chip-list-input-${nextUniqueId++}`; /** Whether the input is disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return this._disabled || (this._chipGrid && this._chipGrid.disabled); } - set disabled(value: BooleanInput) { - this._disabled = coerceBooleanProperty(value); + set disabled(value: boolean) { + this._disabled = value; } private _disabled: boolean = false; diff --git a/src/material/chips/chip-listbox.spec.ts b/src/material/chips/chip-listbox.spec.ts index ac964fa2cbda..cd4024edef6a 100644 --- a/src/material/chips/chip-listbox.spec.ts +++ b/src/material/chips/chip-listbox.spec.ts @@ -870,10 +870,11 @@ describe('MDC-based MatChipListbox', () => { @Component({ template: ` - - {{name}} {{i + 1}} - + @for (i of chips; track i) { + + {{name}} {{i + 1}} + + } `, }) class StandardChipListbox { @@ -890,9 +891,11 @@ class StandardChipListbox { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + + {{ food.viewValue }} + + } `, }) @@ -921,9 +924,11 @@ class BasicChipListbox { - - {{ food.viewValue }} - + @for (food of foods; track food) { + + {{ food.viewValue }} + + } `, }) @@ -950,9 +955,9 @@ class MultiSelectionChipListbox { @Component({ template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, }) @@ -968,9 +973,11 @@ class FalsyValueChipListbox { @Component({ template: ` - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, }) @@ -987,9 +994,11 @@ class SelectedChipListbox { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + + {{ food.viewValue }} + + } `, }) diff --git a/src/material/chips/chip-listbox.ts b/src/material/chips/chip-listbox.ts index 542543e17e65..42e1bfdfa60c 100644 --- a/src/material/chips/chip-listbox.ts +++ b/src/material/chips/chip-listbox.ts @@ -6,11 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; -import {MatChipAction} from './chip-action'; -import {TAB} from '@angular/cdk/keycodes'; import { AfterContentInit, + booleanAttribute, ChangeDetectionStrategy, Component, ContentChildren, @@ -26,9 +24,11 @@ import { import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import {Observable} from 'rxjs'; import {startWith, takeUntil} from 'rxjs/operators'; +import {TAB} from '@angular/cdk/keycodes'; import {MatChip, MatChipEvent} from './chip'; import {MatChipOption, MatChipSelectionChange} from './chip-option'; import {MatChipSet} from './chip-set'; +import {MatChipAction} from './chip-action'; import {MAT_CHIPS_DEFAULT_OPTIONS} from './tokens'; /** Change event object that is emitted when the chip listbox value has changed. */ @@ -64,11 +64,10 @@ export const MAT_CHIP_LISTBOX_CONTROL_VALUE_ACCESSOR: any = { `, styleUrls: ['chip-set.css'], - inputs: ['tabIndex'], host: { 'class': 'mdc-evolution-chip-set mat-mdc-chip-listbox', '[attr.role]': 'role', - '[tabIndex]': 'empty ? -1 : tabIndex', + '[tabIndex]': '(disabled || empty) ? -1 : tabIndex', // TODO: replace this binding with use of AriaDescriber '[attr.aria-describedby]': '_ariaDescribedby || null', '[attr.aria-required]': 'role ? required : null', @@ -112,12 +111,12 @@ export class MatChipListbox private _defaultOptions = inject(MAT_CHIPS_DEFAULT_OPTIONS, {optional: true}); /** Whether the user should be allowed to select multiple chips. */ - @Input() + @Input({transform: booleanAttribute}) get multiple(): boolean { return this._multiple; } - set multiple(value: BooleanInput) { - this._multiple = coerceBooleanProperty(value); + set multiple(value: boolean) { + this._multiple = value; this._syncListboxProperties(); } private _multiple: boolean = false; @@ -137,12 +136,12 @@ export class MatChipListbox * When a chip listbox is not selectable, the selected states for all * the chips inside the chip listbox are always ignored. */ - @Input() + @Input({transform: booleanAttribute}) get selectable(): boolean { return this._selectable; } - set selectable(value: BooleanInput) { - this._selectable = coerceBooleanProperty(value); + set selectable(value: boolean) { + this._selectable = value; this._syncListboxProperties(); } protected _selectable: boolean = true; @@ -155,22 +154,16 @@ export class MatChipListbox @Input() compareWith: (o1: any, o2: any) => boolean = (o1: any, o2: any) => o1 === o2; /** Whether this chip listbox is required. */ - @Input() - get required(): boolean { - return this._required; - } - set required(value: BooleanInput) { - this._required = coerceBooleanProperty(value); - } - protected _required: boolean = false; + @Input({transform: booleanAttribute}) + required: boolean = false; /** Whether checkmark indicator for single-selection options is hidden. */ - @Input() + @Input({transform: booleanAttribute}) get hideSingleSelectionIndicator(): boolean { return this._hideSingleSelectionIndicator; } - set hideSingleSelectionIndicator(value: BooleanInput) { - this._hideSingleSelectionIndicator = coerceBooleanProperty(value); + set hideSingleSelectionIndicator(value: boolean) { + this._hideSingleSelectionIndicator = value; this._syncListboxProperties(); } private _hideSingleSelectionIndicator: boolean = diff --git a/src/material/chips/chip-option.spec.ts b/src/material/chips/chip-option.spec.ts index 1897d290ac0f..cc74d3011c32 100644 --- a/src/material/chips/chip-option.spec.ts +++ b/src/material/chips/chip-option.spec.ts @@ -398,16 +398,20 @@ describe('MDC-based Option Chips', () => { @Component({ template: ` -
    - - {{avatarLabel}} - {{name}} - -
    + @if (shouldShow) { +
    + + @if (avatarLabel) { + {{avatarLabel}} + } + {{name}} + +
    + }
    `, }) class SingleChip { diff --git a/src/material/chips/chip-option.ts b/src/material/chips/chip-option.ts index e0abdddacbca..b97331966474 100644 --- a/src/material/chips/chip-option.ts +++ b/src/material/chips/chip-option.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import { ChangeDetectionStrategy, Component, @@ -16,6 +15,7 @@ import { ViewEncapsulation, OnInit, inject, + booleanAttribute, } from '@angular/core'; import {MatChip} from './chip'; import {MAT_CHIP, MAT_CHIPS_DEFAULT_OPTIONS} from './tokens'; @@ -42,7 +42,6 @@ export class MatChipSelectionChange { selector: 'mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]', templateUrl: 'chip-option.html', styleUrls: ['chip.css'], - inputs: ['color', 'disabled', 'disableRipple', 'tabIndex'], host: { 'class': 'mat-mdc-chip mat-mdc-chip-option', '[class.mdc-evolution-chip]': '!_isBasicChip', @@ -99,23 +98,23 @@ export class MatChipOption extends MatChip implements OnInit { * ignored. By default an option chip is selectable, and it becomes * non-selectable if its parent chip list is not selectable. */ - @Input() + @Input({transform: booleanAttribute}) get selectable(): boolean { return this._selectable && this.chipListSelectable; } - set selectable(value: BooleanInput) { - this._selectable = coerceBooleanProperty(value); + set selectable(value: boolean) { + this._selectable = value; this._changeDetectorRef.markForCheck(); } protected _selectable: boolean = true; /** Whether the chip is selected. */ - @Input() + @Input({transform: booleanAttribute}) get selected(): boolean { return this._selected; } - set selected(value: BooleanInput) { - this._setSelectedState(coerceBooleanProperty(value), false, true); + set selected(value: boolean) { + this._setSelectedState(value, false, true); } private _selected = false; diff --git a/src/material/chips/chip-row.spec.ts b/src/material/chips/chip-row.spec.ts index c6c44ee47d5e..695fa085a836 100644 --- a/src/material/chips/chip-row.spec.ts +++ b/src/material/chips/chip-row.spec.ts @@ -384,18 +384,22 @@ describe('MDC-based Row Chips', () => { @Component({ template: ` -
    - - {{name}} - - - - -
    + @if (shouldShow) { +
    + + {{name}} + + @if (useCustomEditInput) { + + } + + +
    + }
    `, }) class SingleChip { diff --git a/src/material/chips/chip-row.ts b/src/material/chips/chip-row.ts index ff20f60b5255..70f87f037225 100644 --- a/src/material/chips/chip-row.ts +++ b/src/material/chips/chip-row.ts @@ -47,7 +47,6 @@ export interface MatChipEditedEvent extends MatChipEvent { selector: 'mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]', templateUrl: 'chip-row.html', styleUrls: ['chip.css'], - inputs: ['color', 'disabled', 'disableRipple', 'tabIndex'], host: { 'class': 'mat-mdc-chip mat-mdc-chip-row mdc-evolution-chip', '[class.mat-mdc-chip-with-avatar]': 'leadingIcon', diff --git a/src/material/chips/chip-set.spec.ts b/src/material/chips/chip-set.spec.ts index a5e6363d034b..89c4fdb2fd7c 100644 --- a/src/material/chips/chip-set.spec.ts +++ b/src/material/chips/chip-set.spec.ts @@ -109,9 +109,9 @@ describe('MDC-based MatChipSet', () => { @Component({ template: ` - - {{name}} {{i + 1}} - + @for (i of chips; track i) { + {{name}} {{i + 1}} + } `, }) @@ -123,11 +123,11 @@ class BasicChipSet { @Component({ template: ` - - - {{name}} {{i + 1}} - - + @if (true) { + @for (i of chips; track i) { + {{name}} {{i + 1}} + } + } `, }) diff --git a/src/material/chips/chip-set.ts b/src/material/chips/chip-set.ts index 45ae22bc0eb4..e202c98389be 100644 --- a/src/material/chips/chip-set.ts +++ b/src/material/chips/chip-set.ts @@ -8,7 +8,6 @@ import {FocusKeyManager} from '@angular/cdk/a11y'; import {Directionality} from '@angular/cdk/bidi'; -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import { AfterViewInit, ChangeDetectionStrategy, @@ -21,23 +20,14 @@ import { Optional, QueryList, ViewEncapsulation, + booleanAttribute, + numberAttribute, } from '@angular/core'; -import {HasTabIndex, mixinTabIndex} from '@angular/material/core'; import {merge, Observable, Subject} from 'rxjs'; import {startWith, switchMap, takeUntil} from 'rxjs/operators'; import {MatChip, MatChipEvent} from './chip'; import {MatChipAction} from './chip-action'; -/** - * Boilerplate for applying mixins to MatChipSet. - * @docs-private - */ -abstract class MatChipSetBase { - abstract disabled: boolean; - constructor(_elementRef: ElementRef) {} -} -const _MatChipSetMixinBase = mixinTabIndex(MatChipSetBase); - /** * Basic container component for the MatChip component. * @@ -59,10 +49,7 @@ const _MatChipSetMixinBase = mixinTabIndex(MatChipSetBase); encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatChipSet - extends _MatChipSetMixinBase - implements AfterViewInit, HasTabIndex, OnDestroy -{ +export class MatChipSet implements AfterViewInit, OnDestroy { /** Index of the last destroyed chip that had focus. */ private _lastDestroyedFocusedChipIndex: number | null = null; @@ -91,12 +78,12 @@ export class MatChipSet } /** Whether the chip set is disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return this._disabled; } - set disabled(value: BooleanInput) { - this._disabled = coerceBooleanProperty(value); + set disabled(value: boolean) { + this._disabled = value; this._syncChipsState(); } protected _disabled: boolean = false; @@ -116,6 +103,12 @@ export class MatChipSet return this.empty ? null : this._defaultRole; } + /** Tabindex of the chip set. */ + @Input({ + transform: (value: unknown) => (value == null ? 0 : numberAttribute(value)), + }) + tabIndex: number = 0; + set role(value: string | null) { this._explicitRole = value; } @@ -141,9 +134,7 @@ export class MatChipSet protected _elementRef: ElementRef, protected _changeDetectorRef: ChangeDetectorRef, @Optional() private _dir: Directionality, - ) { - super(_elementRef); - } + ) {} ngAfterViewInit() { this._setUpFocusManagement(); diff --git a/src/material/chips/chip.spec.ts b/src/material/chips/chip.spec.ts index a5f828a20e61..cb15b4935eb6 100644 --- a/src/material/chips/chip.spec.ts +++ b/src/material/chips/chip.spec.ts @@ -185,14 +185,16 @@ describe('MDC-based MatChip', () => { @Component({ template: ` -
    - - {{name}} - -
    + @if (shouldShow) { +
    + + {{name}} + +
    + }
    `, }) class SingleChip { diff --git a/src/material/chips/chip.ts b/src/material/chips/chip.ts index 9e7038e93bf6..fcc2baaa7e38 100644 --- a/src/material/chips/chip.ts +++ b/src/material/chips/chip.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import { AfterViewInit, @@ -31,19 +30,13 @@ import { OnInit, DoCheck, inject, + booleanAttribute, + numberAttribute, } from '@angular/core'; import {DOCUMENT} from '@angular/common'; import { - CanColor, - CanDisable, - CanDisableRipple, - HasTabIndex, MatRipple, MAT_RIPPLE_GLOBAL_OPTIONS, - mixinColor, - mixinDisableRipple, - mixinTabIndex, - mixinDisabled, RippleGlobalOptions, MatRippleLoader, } from '@angular/material/core'; @@ -63,24 +56,6 @@ export interface MatChipEvent { chip: MatChip; } -/** - * Boilerplate for applying mixins to MatChip. - * @docs-private - */ -const _MatChipMixinBase = mixinTabIndex( - mixinColor( - mixinDisableRipple( - mixinDisabled( - class { - constructor(public _elementRef: ElementRef) {} - }, - ), - ), - 'primary', - ), - -1, -); - /** * Material design styled Chip base component. Used inside the MatChipSet component. * @@ -88,12 +63,12 @@ const _MatChipMixinBase = mixinTabIndex( */ @Component({ selector: 'mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]', - inputs: ['color', 'disabled', 'disableRipple', 'tabIndex'], exportAs: 'matChip', templateUrl: 'chip.html', styleUrls: ['chip.css'], host: { 'class': 'mat-mdc-chip', + '[class]': '"mat-" + (color || "primary")', '[class.mdc-evolution-chip]': '!_isBasicChip', '[class.mdc-evolution-chip--disabled]': 'disabled', '[class.mdc-evolution-chip--with-trailing-action]': '_hasTrailingIcon()', @@ -109,7 +84,7 @@ const _MatChipMixinBase = mixinTabIndex( '[class._mat-animation-noopable]': '_animationsDisabled', '[id]': 'id', '[attr.role]': 'role', - '[attr.tabindex]': 'role ? tabIndex : null', + '[attr.tabindex]': '_getTabIndex()', '[attr.aria-label]': 'ariaLabel', '(keydown)': '_handleKeydown($event)', }, @@ -117,19 +92,7 @@ const _MatChipMixinBase = mixinTabIndex( changeDetection: ChangeDetectionStrategy.OnPush, providers: [{provide: MAT_CHIP, useExisting: MatChip}], }) -export class MatChip - extends _MatChipMixinBase - implements - OnInit, - AfterViewInit, - AfterContentInit, - CanColor, - CanDisableRipple, - CanDisable, - DoCheck, - HasTabIndex, - OnDestroy -{ +export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck, OnDestroy { protected _document: Document; /** Emits when the chip is focused. */ @@ -205,29 +168,35 @@ export class MatChip } protected _value: any; + // TODO: should be typed as `ThemePalette` but internal apps pass in arbitrary strings. + /** Theme color palette of the chip. */ + @Input() color?: string | null; + /** * Determines whether or not the chip displays the remove styling and emits (removed) events. */ - @Input() - get removable(): boolean { - return this._removable; - } - set removable(value: BooleanInput) { - this._removable = coerceBooleanProperty(value); - } - protected _removable: boolean = true; + @Input({transform: booleanAttribute}) + removable: boolean = true; /** * Colors the chip for emphasis as if it were selected. */ - @Input() - get highlighted(): boolean { - return this._highlighted; - } - set highlighted(value: BooleanInput) { - this._highlighted = coerceBooleanProperty(value); - } - protected _highlighted: boolean = false; + @Input({transform: booleanAttribute}) + highlighted: boolean = false; + + /** Whether the ripple effect is disabled or not. */ + @Input({transform: booleanAttribute}) + disableRipple: boolean = false; + + /** Whether the chip is disabled. */ + @Input({transform: booleanAttribute}) + disabled: boolean = false; + + /** Tab index of the chip. */ + @Input({ + transform: (value: unknown) => (value == null ? undefined : numberAttribute(value)), + }) + tabIndex: number = -1; /** Emitted when a chip is to be removed. */ @Output() readonly removed: EventEmitter = new EventEmitter(); @@ -270,7 +239,7 @@ export class MatChip constructor( public _changeDetectorRef: ChangeDetectorRef, - elementRef: ElementRef, + public _elementRef: ElementRef, protected _ngZone: NgZone, private _focusMonitor: FocusMonitor, @Inject(DOCUMENT) _document: any, @@ -280,11 +249,10 @@ export class MatChip private _globalRippleOptions?: RippleGlobalOptions, @Attribute('tabindex') tabIndex?: string, ) { - super(elementRef); this._document = _document; this._animationsDisabled = animationMode === 'NoopAnimations'; if (tabIndex != null) { - this.tabIndex = parseInt(tabIndex) ?? this.defaultTabIndex; + this.tabIndex = parseInt(tabIndex) ?? -1; } this._monitorFocus(); @@ -414,6 +382,14 @@ export class MatChip // Empty here, but is overwritten in child classes. } + /** Gets the tabindex of the chip. */ + _getTabIndex() { + if (!this.role) { + return null; + } + return this.disabled ? -1 : this.tabIndex; + } + /** Starts the focus monitoring process on the chip. */ private _monitorFocus() { this._focusMonitor.monitor(this._elementRef, true).subscribe(origin => { diff --git a/src/material/chips/chips.md b/src/material/chips/chips.md index 8a95c6cb4fbc..f803ff2910ae 100644 --- a/src/material/chips/chips.md +++ b/src/material/chips/chips.md @@ -94,7 +94,7 @@ See the [accessibility](#accessibility) section for best practices on implementi ### Orientation -By default, chips are displayed horizontally. To stack chips vertically, apply the `mat-mdc-chip-set-stacked` class to ``, `` or ``. +By default, chips are displayed horizontally. To stack chips vertically, apply the `mat-mdc-chip-set-stacked` class to ``, `` or ``. @@ -141,14 +141,15 @@ The chips components support 3 user interaction patterns, each with its own cont ```html - - {{filling.name}} - - + aria-label="enter sandwich fillings"> + @for (filling of fillings; track filling) { + + {{filling.name}} + + + } diff --git a/src/material/chips/testing/BUILD.bazel b/src/material/chips/testing/BUILD.bazel index 7fd0738229ba..e6540ffcbbb3 100644 --- a/src/material/chips/testing/BUILD.bazel +++ b/src/material/chips/testing/BUILD.bazel @@ -9,7 +9,6 @@ ts_library( exclude = ["**/*.spec.ts"], ), deps = [ - "//src/cdk/coercion", "//src/cdk/testing", ], ) diff --git a/src/material/chips/testing/chip-listbox-harness.spec.ts b/src/material/chips/testing/chip-listbox-harness.spec.ts index 1843d50a08c8..d513a7c03c42 100644 --- a/src/material/chips/testing/chip-listbox-harness.spec.ts +++ b/src/material/chips/testing/chip-listbox-harness.spec.ts @@ -112,9 +112,11 @@ describe('MatChipListboxHarness', () => { @Component({ template: ` - - {{option.text}} - + @for (option of options; track option) { + + {{option.text}} + + } `, }) diff --git a/src/material/core/_core-theme.scss b/src/material/core/_core-theme.scss index 814c245ab8c6..cf6d1f82bd86 100644 --- a/src/material/core/_core-theme.scss +++ b/src/material/core/_core-theme.scss @@ -54,16 +54,16 @@ @include option-theme.typography($theme); @include optgroup-theme.typography($theme); @include pseudo-checkbox-theme.typography($theme); - // TODO(mmalerba): add typography mixin for this. - // @include ripple-theme.typography($config); + @include ripple-theme.typography($theme); } @mixin density($theme) { @include option-theme.density($theme); @include optgroup-theme.density($theme); + @include ripple-theme.density($theme); + // TODO(mmalerba): add density mixins for these. - // @include ripple-theme.density($density-scale); - // @include pseudo-checkbox-theme.density($density-scale); + // @include pseudo-checkbox-theme.density($theme); } // Mixin that renders all of the core styles that depend on the theme. diff --git a/src/material/core/ripple/_ripple-theme.scss b/src/material/core/ripple/_ripple-theme.scss index 6d2589a218a5..86aa6b53f197 100644 --- a/src/material/core/ripple/_ripple-theme.scss +++ b/src/material/core/ripple/_ripple-theme.scss @@ -1,26 +1,30 @@ -@use 'sass:meta'; +@use '../tokens/m2/mat/ripple' as tokens-mat-ripple; +@use '../tokens/token-utils'; +@use '../style/sass-utils'; + @use '../theming/theming'; @use '../theming/inspection'; -@mixin base($theme) { - // TODO(mmalerba): Move ripple base tokens here -} +@mixin base($theme) {} -// Colors for the ripple elements. @mixin color($theme) { - $foreground-base: inspection.get-theme-color($theme, foreground, base); - $color-opacity: 0.1; + @include sass-utils.current-selector-or-root() { + @include token-utils.create-token-values(tokens-mat-ripple.$prefix, + tokens-mat-ripple.get-color-tokens($theme)); + } +} - .mat-ripple-element { - // If the ripple color is resolves to a color *type*, we can use it directly, otherwise - // (e.g. it resolves to a CSS variable) we fall back to using the color and setting an opacity. - @if (meta.type-of($foreground-base) == color) { - background-color: rgba($foreground-base, $color-opacity); - } - @else { - background-color: $foreground-base; - opacity: $color-opacity; - } +@mixin typography($theme) { + @include sass-utils.current-selector-or-root() { + @include token-utils.create-token-values(tokens-mat-ripple.$prefix, + tokens-mat-ripple.get-typography-tokens($theme)); + } +} + +@mixin density($theme) { + @include sass-utils.current-selector-or-root() { + @include token-utils.create-token-values(tokens-mat-ripple.$prefix, + tokens-mat-ripple.get-density-tokens($theme)); } } @@ -30,5 +34,11 @@ @if inspection.theme-has($theme, color) { @include color($theme); } + @if inspection.theme-has($theme, density) { + @include density($theme); + } + @if inspection.theme-has($theme, typography) { + @include typography($theme); + } } } diff --git a/src/material/core/ripple/_ripple.scss b/src/material/core/ripple/_ripple.scss index ca5b93f709dc..e958e7b6f0e0 100644 --- a/src/material/core/ripple/_ripple.scss +++ b/src/material/core/ripple/_ripple.scss @@ -1,4 +1,6 @@ @use '@angular/cdk'; +@use '../tokens/m2/mat/ripple' as tokens-mat-ripple; +@use '../tokens/token-utils'; @mixin ripple() { // The host element of an mat-ripple directive should always have a position of "absolute" or @@ -35,6 +37,12 @@ // the ripples aren't clipped when inside the shadow DOM (see #24028). transform: scale3d(0, 0, 0); + @include token-utils.use-tokens( + tokens-mat-ripple.$prefix, tokens-mat-ripple.get-token-slots()) { + // We have to emit a fallback value here, because some internal builds depend on it. + background-color: var(#{token-utils.get-token-variable(color)}, rgba(#000, 0.1)); + } + // In high contrast mode the ripple is opaque, causing it to obstruct the content. @include cdk.high-contrast(active, off) { display: none; diff --git a/src/material/core/ripple/ripple-ref.ts b/src/material/core/ripple/ripple-ref.ts index 38887a71a4aa..68964a357780 100644 --- a/src/material/core/ripple/ripple-ref.ts +++ b/src/material/core/ripple/ripple-ref.ts @@ -7,7 +7,7 @@ */ /** Possible states for a ripple element. */ -export const enum RippleState { +export enum RippleState { FADING_IN, VISIBLE, FADING_OUT, diff --git a/src/material/core/ripple/ripple.spec.ts b/src/material/core/ripple/ripple.spec.ts index cc7a31120bcd..cc3ef2a61d99 100644 --- a/src/material/core/ripple/ripple.spec.ts +++ b/src/material/core/ripple/ripple.spec.ts @@ -201,7 +201,7 @@ describe('MatRipple', () => { it('should ignore fake mouse events from screen readers', () => { const event = createMouseEvent('mousedown'); - Object.defineProperties(event, {offsetX: {get: () => 0}, offsetY: {get: () => 0}}); + Object.defineProperties(event, {buttons: {get: () => 0}, detail: {get: () => 0}}); dispatchEvent(rippleTarget, event); @@ -874,7 +874,7 @@ class RippleContainerWithInputBindings { class RippleContainerWithoutBindings {} @Component({ - template: `
    `, + template: `@if (!isDestroyed) {
    }`, }) class RippleContainerWithNgIf { @ViewChild(MatRipple) ripple: MatRipple; @@ -897,9 +897,9 @@ class RippleCssTransitionDurationZero {} @Component({ template: ` -
    - Click to remove this element. -
    + @if (show) { +
    Click to remove this element.
    + } `, }) class RippleWithDomRemovalOnClick { diff --git a/src/material/core/tokens/m2/mat/_fab.scss b/src/material/core/tokens/m2/mat/_fab.scss index 1fa4a4b2ccc0..22da2e566fba 100644 --- a/src/material/core/tokens/m2/mat/_fab.scss +++ b/src/material/core/tokens/m2/mat/_fab.scss @@ -1,6 +1,9 @@ +@use 'sass:map'; +@use '@material/ripple/ripple-theme' as mdc-ripple-theme; @use '../../token-utils'; @use '../../../theming/inspection'; @use '../../../style/sass-utils'; +@use '../../../mdc-helpers/mdc-helpers'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mat, fab); @@ -14,24 +17,51 @@ $prefix: (mat, fab); // Tokens that can be configured through Angular Material's color theming API. @function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $surface: if($is-dark, #fff, #000); + $on-surface: if($is-dark, #fff, #000); + $ripple-opacities: if($is-dark, + mdc-ripple-theme.$light-ink-opacities, + mdc-ripple-theme.$dark-ink-opacities + ); @return ( // Color of icons and text projected into a FAB. foreground-color: inspection.get-theme-color($theme, foreground, base), + // Color of the element that shows the hover, focus and pressed states. + state-layer-color: $on-surface, + + // Color of the ripple element. + ripple-color: rgba($on-surface, 0.1), + + // Opacity of the ripple when the button is hovered. + hover-state-layer-opacity: map.get($ripple-opacities, hover), + + // Opacity of the ripple when the button is focused. + focus-state-layer-opacity: map.get($ripple-opacities, focus), + + // Opacity of the ripple when the button is pressed. + pressed-state-layer-opacity: map.get($ripple-opacities, press), + // MDC doesn't have tokens for disabled FABs so we need to implemented them ourselves. // Background color of the container when the FAB is disabled. - disabled-state-container-color: rgba($surface, 0.12), + disabled-state-container-color: rgba($on-surface, 0.12), + // Color of the icons and projected text when the FAB is disabled. - disabled-state-foreground-color: rgba($surface, if($is-dark, 0.5, 0.38)), + disabled-state-foreground-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), ); } // Generates the mapping for the properties that change based on the FAB palette color. @function private-get-color-palette-color-tokens($theme, $palette-name) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $color: if($contrast-tone == 'dark', #000, #fff); + @return ( - foreground-color: inspection.get-theme-color($theme, $palette-name, default-contrast), + foreground-color: $color, + state-layer-color: $color, + ripple-color: rgba($color, 0.1), ); } diff --git a/src/material/core/tokens/m2/mat/_filled-button.scss b/src/material/core/tokens/m2/mat/_filled-button.scss new file mode 100644 index 000000000000..13cb3fdb3e2a --- /dev/null +++ b/src/material/core/tokens/m2/mat/_filled-button.scss @@ -0,0 +1,76 @@ +@use 'sass:map'; +@use '@material/ripple/ripple-theme' as mdc-ripple-theme; +@use '../../token-utils'; +@use '../../../theming/inspection'; +@use '../../../style/sass-utils'; +@use '../../../mdc-helpers/mdc-helpers'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mat, filled-button); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return (); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($theme) { + $is-dark: inspection.get-theme-type($theme) == dark; + $on-surface: if($is-dark, #fff, #000); + $ripple-opacities: if($is-dark, + mdc-ripple-theme.$light-ink-opacities, + mdc-ripple-theme.$dark-ink-opacities + ); + + @return ( + // Color of the element that shows the hover, focus and pressed states. + state-layer-color: $on-surface, + + // Color of the ripple element. + ripple-color: rgba($on-surface, 0.1), + + // Opacity of the ripple when the button is hovered. + hover-state-layer-opacity: map.get($ripple-opacities, hover), + + // Opacity of the ripple when the button is focused. + focus-state-layer-opacity: map.get($ripple-opacities, focus), + + // Opacity of the ripple when the button is pressed. + pressed-state-layer-opacity: map.get($ripple-opacities, press), + ); +} + +// Generates the mapping for the properties that change based on the button palette color. +@function private-get-color-palette-color-tokens($theme, $palette-name) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $color: if($contrast-tone == 'dark', #000, #fff); + + @return ( + state-layer-color: $color, + ripple-color: rgba($color, 0.1), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($theme) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($theme) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return sass-utils.deep-merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mat/_icon-button.scss b/src/material/core/tokens/m2/mat/_icon-button.scss new file mode 100644 index 000000000000..e28df5673dfc --- /dev/null +++ b/src/material/core/tokens/m2/mat/_icon-button.scss @@ -0,0 +1,73 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use '@material/ripple/ripple-theme' as mdc-ripple-theme; +@use '../../token-utils'; +@use '../../../theming/inspection'; +@use '../../../style/sass-utils'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mat, icon-button); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return (); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($theme) { + $is-dark: inspection.get-theme-type($theme) == dark; + $on-surface: if($is-dark, #fff, #000); + $ripple-opacities: if($is-dark, + mdc-ripple-theme.$light-ink-opacities, + mdc-ripple-theme.$dark-ink-opacities + ); + + @return ( + // Color of the element that shows the hover, focus and pressed states. + state-layer-color: $on-surface, + + // Color of the ripple element. + ripple-color: rgba($on-surface, 0.1), + + // Opacity of the ripple when the button is hovered. + hover-state-layer-opacity: map.get($ripple-opacities, hover), + + // Opacity of the ripple when the button is focused. + focus-state-layer-opacity: map.get($ripple-opacities, focus), + + // Opacity of the ripple when the button is pressed. + pressed-state-layer-opacity: map.get($ripple-opacities, press), + ); +} + +// Generates the mapping for the properties that change based on the button palette color. +@function private-get-color-palette-color-tokens($theme, $palette-name) { + $color: inspection.get-theme-color($theme, $palette-name); + + @return ( + state-layer-color: $color, + ripple-color: if(meta.type-of($color) == color, rgba($color, 0.1), $color), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($theme) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($theme) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return sass-utils.deep-merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mat/_outlined-button.scss b/src/material/core/tokens/m2/mat/_outlined-button.scss new file mode 100644 index 000000000000..fb4ac47888f1 --- /dev/null +++ b/src/material/core/tokens/m2/mat/_outlined-button.scss @@ -0,0 +1,73 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use '@material/ripple/ripple-theme' as mdc-ripple-theme; +@use '../../token-utils'; +@use '../../../theming/inspection'; +@use '../../../style/sass-utils'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mat, outlined-button); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return (); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($theme) { + $is-dark: inspection.get-theme-type($theme) == dark; + $on-surface: if($is-dark, #fff, #000); + $ripple-opacities: if($is-dark, + mdc-ripple-theme.$light-ink-opacities, + mdc-ripple-theme.$dark-ink-opacities + ); + + @return ( + // Color of the element that shows the hover, focus and pressed states. + state-layer-color: $on-surface, + + // Color of the ripple element. + ripple-color: rgba($on-surface, 0.1), + + // Opacity of the ripple when the button is hovered. + hover-state-layer-opacity: map.get($ripple-opacities, hover), + + // Opacity of the ripple when the button is focused. + focus-state-layer-opacity: map.get($ripple-opacities, focus), + + // Opacity of the ripple when the button is pressed. + pressed-state-layer-opacity: map.get($ripple-opacities, press), + ); +} + +// Generates the mapping for the properties that change based on the button palette color. +@function private-get-color-palette-color-tokens($theme, $palette-name) { + $color: inspection.get-theme-color($theme, $palette-name); + + @return ( + state-layer-color: $color, + ripple-color: if(meta.type-of($color) == color, rgba($color, 0.1), $color), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($theme) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($theme) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return sass-utils.deep-merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mat/_protected-button.scss b/src/material/core/tokens/m2/mat/_protected-button.scss new file mode 100644 index 000000000000..f3c6c678c138 --- /dev/null +++ b/src/material/core/tokens/m2/mat/_protected-button.scss @@ -0,0 +1,76 @@ +@use 'sass:map'; +@use '@material/ripple/ripple-theme' as mdc-ripple-theme; +@use '../../token-utils'; +@use '../../../theming/inspection'; +@use '../../../style/sass-utils'; +@use '../../../mdc-helpers/mdc-helpers'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mat, protected-button); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return (); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($theme) { + $is-dark: inspection.get-theme-type($theme) == dark; + $on-surface: if($is-dark, #fff, #000); + $ripple-opacities: if($is-dark, + mdc-ripple-theme.$light-ink-opacities, + mdc-ripple-theme.$dark-ink-opacities + ); + + @return ( + // Color of the element that shows the hover, focus and pressed states. + state-layer-color: $on-surface, + + // Color of the ripple element. + ripple-color: rgba($on-surface, 0.1), + + // Opacity of the ripple when the button is hovered. + hover-state-layer-opacity: map.get($ripple-opacities, hover), + + // Opacity of the ripple when the button is focused. + focus-state-layer-opacity: map.get($ripple-opacities, focus), + + // Opacity of the ripple when the button is pressed. + pressed-state-layer-opacity: map.get($ripple-opacities, press), + ); +} + +// Generates the mapping for the properties that change based on the button palette color. +@function private-get-color-palette-color-tokens($theme, $palette-name) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + $color: if($contrast-tone == 'dark', #000, #fff); + + @return ( + state-layer-color: $color, + ripple-color: rgba($color, 0.1), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($theme) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($theme) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return sass-utils.deep-merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mat/_ripple.scss b/src/material/core/tokens/m2/mat/_ripple.scss new file mode 100644 index 000000000000..fdb31a365a4b --- /dev/null +++ b/src/material/core/tokens/m2/mat/_ripple.scss @@ -0,0 +1,49 @@ +@use 'sass:meta'; +@use '../../token-utils'; +@use '../../../theming/inspection'; +@use '../../../style/sass-utils'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mat, ripple); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return (); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($theme) { + $is-dark: inspection.get-theme-type($theme) == dark; + $base: inspection.get-theme-color($theme, foreground, base); + + // If the base is a color *type* we can use it directly in the `rgba` call below. + // If it's anything else (e.g. a CSS variable) we fall back to using static colors + // since we don't have a way of adjusting the opacity. + $color: if(meta.type-of($base) == color, $base, if($is-dark, #fff, #000)); + + @return ( + color: rgba($color, 0.1), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($theme) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($theme) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return sass-utils.deep-merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mat/_text-button.scss b/src/material/core/tokens/m2/mat/_text-button.scss new file mode 100644 index 000000000000..7a509fa7f612 --- /dev/null +++ b/src/material/core/tokens/m2/mat/_text-button.scss @@ -0,0 +1,73 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use '@material/ripple/ripple-theme' as mdc-ripple-theme; +@use '../../token-utils'; +@use '../../../theming/inspection'; +@use '../../../style/sass-utils'; + +// The prefix used to generate the fully qualified name for tokens in this file. +$prefix: (mat, text-button); + +// Tokens that can't be configured through Angular Material's current theming API, +// but may be in a future version of the theming API. +@function get-unthemable-tokens() { + @return (); +} + +// Tokens that can be configured through Angular Material's color theming API. +@function get-color-tokens($theme) { + $is-dark: inspection.get-theme-type($theme) == dark; + $on-surface: if($is-dark, #fff, #000); + $ripple-opacities: if($is-dark, + mdc-ripple-theme.$light-ink-opacities, + mdc-ripple-theme.$dark-ink-opacities + ); + + @return ( + // Color of the element that shows the hover, focus and pressed states. + state-layer-color: $on-surface, + + // Color of the ripple element. + ripple-color: rgba($on-surface, 0.1), + + // Opacity of the ripple when the button is hovered. + hover-state-layer-opacity: map.get($ripple-opacities, hover), + + // Opacity of the ripple when the button is focused. + focus-state-layer-opacity: map.get($ripple-opacities, focus), + + // Opacity of the ripple when the button is pressed. + pressed-state-layer-opacity: map.get($ripple-opacities, press), + ); +} + +// Generates the mapping for the properties that change based on the button palette color. +@function private-get-color-palette-color-tokens($theme, $palette-name) { + $color: inspection.get-theme-color($theme, $palette-name); + + @return ( + state-layer-color: $color, + ripple-color: if(meta.type-of($color) == color, rgba($color, 0.1), $color), + ); +} + +// Tokens that can be configured through Angular Material's typography theming API. +@function get-typography-tokens($theme) { + @return (); +} + +// Tokens that can be configured through Angular Material's density theming API. +@function get-density-tokens($theme) { + @return (); +} + +// Combines the tokens generated by the above functions into a single map with placeholder values. +// This is used to create token slots. +@function get-token-slots() { + @return sass-utils.deep-merge-all( + get-unthemable-tokens(), + get-color-tokens(token-utils.$placeholder-color-config), + get-typography-tokens(token-utils.$placeholder-typography-config), + get-density-tokens(token-utils.$placeholder-density-config) + ); +} diff --git a/src/material/core/tokens/m2/mdc/_extended-fab.scss b/src/material/core/tokens/m2/mdc/_extended-fab.scss index 45a535ae863a..a82a5e93b311 100644 --- a/src/material/core/tokens/m2/mdc/_extended-fab.scss +++ b/src/material/core/tokens/m2/mdc/_extended-fab.scss @@ -8,6 +8,9 @@ $prefix: (mdc, extended-fab); @function get-unthemable-tokens() { @return ( + // ============================================================================================= + // = TOKENS NOT USED IN ANGULAR MATERIAL = + // ============================================================================================= container-color: null, container-elevation: null, container-height: null, diff --git a/src/material/core/tokens/m2/mdc/_fab.scss b/src/material/core/tokens/m2/mdc/_fab.scss index b74094cea9d4..562bf0c57b6e 100644 --- a/src/material/core/tokens/m2/mdc/_fab.scss +++ b/src/material/core/tokens/m2/mdc/_fab.scss @@ -26,6 +26,9 @@ $ripple-target: '.mdc-fab__ripple'; // We create a custom token for it instead. icon-color: null, + // ============================================================================================= + // = TOKENS NOT USED IN ANGULAR MATERIAL = + // ============================================================================================= container-elevation: null, container-height: null, container-shadow-color: null, diff --git a/src/material/core/tokens/m2/mdc/_filled-button.scss b/src/material/core/tokens/m2/mdc/_filled-button.scss index 548f95b0ef4b..04318a9ce937 100644 --- a/src/material/core/tokens/m2/mdc/_filled-button.scss +++ b/src/material/core/tokens/m2/mdc/_filled-button.scss @@ -1,9 +1,9 @@ @use 'sass:map'; @use '../../token-utils'; -@use '../../../mdc-helpers/mdc-helpers'; @use '../../../style/sass-utils'; @use '../../../theming/inspection'; @use '../../../theming/theming'; +@use '../../../mdc-helpers/mdc-helpers'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mdc, filled-button); @@ -24,6 +24,9 @@ $prefix: (mdc, filled-button); keep-touch-target: false, pressed-container-elevation: 0, + // ============================================================================================= + // = TOKENS NOT USED IN ANGULAR MATERIAL = + // ============================================================================================= focus-ring-color: null, focus-ring-offset: null, focus-state-layer-opacity: null, @@ -43,33 +46,36 @@ $prefix: (mdc, filled-button); with-icon-hover-icon-color: null, with-icon-icon-color: null, with-icon-icon-size: null, - with-icon-pressed-icon-color: null + with-icon-pressed-icon-color: null, + focus-state-layer-color: null, + hover-state-layer-color: null, + pressed-state-layer-color: null, ); } -@function _on-color($theme, $palette) { - @if ($palette) { - $is-dark: inspection.get-theme-type($theme) == dark; - @return if(mdc-helpers.variable-safe-contrast-tone($palette, $is-dark) == 'dark', #000, #fff); - } -} - // Tokens that can be configured through Angular Material's color theming API. -@function get-color-tokens($theme, $color: null, $on-color: null) { +@function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $primary: inspection.get-theme-color($theme, primary); $surface: inspection.get-theme-color($theme, background, card); - $on-primary: _on-color($theme, $primary); - $on-surface: _on-color($theme, $surface); + $on-surface: if($is-dark, #fff, #000); @return ( - container-color: if($color, $color, transparent), + container-color: $surface, + label-text-color: $on-surface, disabled-container-color: rgba($on-surface, 0.12), disabled-label-text-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), - focus-state-layer-color: $on-primary, - hover-state-layer-color: $on-primary, - label-text-color: if($on-color, $on-color, inherit), - pressed-state-layer-color: $on-primary + ); +} + +// Generates the mapping for the properties that change based on the button palette color. +@function private-get-color-palette-color-tokens($theme, $palette-name) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name, default); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + + @return ( + container-color: $container-color, + label-text-color: if($contrast-tone == 'dark', #000, #fff), ); } diff --git a/src/material/core/tokens/m2/mdc/_icon-button.scss b/src/material/core/tokens/m2/mdc/_icon-button.scss index 28cddebe52bd..1fbc989bf3e2 100644 --- a/src/material/core/tokens/m2/mdc/_icon-button.scss +++ b/src/material/core/tokens/m2/mdc/_icon-button.scss @@ -1,4 +1,3 @@ -@use 'sass:map'; @use '../../../style/sass-utils'; @use '../../../theming/inspection'; @use '../../token-utils'; @@ -57,8 +56,6 @@ $prefix: (mdc, icon-button); // Generates the mapping for the properties that change based on the button palette color. @function private-get-color-palette-color-tokens($theme, $palette-name) { - $palette: map.get($theme, $palette-name); - @return ( icon-color: inspection.get-theme-color($theme, $palette-name) ); diff --git a/src/material/core/tokens/m2/mdc/_outlined-button.scss b/src/material/core/tokens/m2/mdc/_outlined-button.scss index 746fa27a5547..f837c3d817a3 100644 --- a/src/material/core/tokens/m2/mdc/_outlined-button.scss +++ b/src/material/core/tokens/m2/mdc/_outlined-button.scss @@ -1,9 +1,9 @@ @use 'sass:map'; @use '../../token-utils'; -@use '../../../mdc-helpers/mdc-helpers'; @use '../../../style/sass-utils'; @use '../../../theming/inspection'; @use '../../../theming/theming'; +@use '../../../mdc-helpers/mdc-helpers'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mdc, outlined-button); @@ -21,6 +21,9 @@ $prefix: (mdc, outlined-button); outline-width: 1px, container-shape: 4px, + // ============================================================================================= + // = TOKENS NOT USED IN ANGULAR MATERIAL = + // ============================================================================================= hover-state-layer-opacity: null, focus-state-layer-opacity: null, pressed-state-layer-opacity: null, @@ -55,27 +58,33 @@ $prefix: (mdc, outlined-button); ); } -@function _on-color($theme, $palette) { - @if ($palette) { - $is-dark: inspection.get-theme-type($theme) == dark; - @return if(mdc-helpers.variable-safe-contrast-tone($palette, $is-dark) == 'dark', #000, #fff); - } -} - // Tokens that can be configured through Angular Material's color theming API. -@function get-color-tokens($theme, $color: null, $on-color: null) { +@function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; $surface: inspection.get-theme-color($theme, background, card); - $on-surface: _on-color($theme, $surface); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($surface, $is-dark); + $on-surface: if($contrast-tone == 'dark', #000, #fff); @return ( disabled-outline-color: rgba($on-surface, 0.12), disabled-label-text-color: rgba($on-surface, if($is-dark, 0.5, 0.38)), - label-text-color: if($color, $color, inherit), + label-text-color: if($is-dark, #fff, #000), outline-color: rgba($on-surface, 0.12) ); } +// Generates the mapping for the properties that change based on the button palette color. +@function private-get-color-palette-color-tokens($theme, $palette-name) { + @return ( + label-text-color: inspection.get-theme-color($theme, $palette-name, default), + + // TODO: we shouldn't have to set this since it's the same as the non-palette version, however + // there are a bunch of tests internally that depend on it. We should remove this and clean + // up the screenshots separately. + outline-color: map.get(get-color-tokens($theme), outline-color), + ); +} + // Tokens that can be configured through Angular Material's typography theming API. @function get-typography-tokens($theme) { @return (); diff --git a/src/material/core/tokens/m2/mdc/_protected-button.scss b/src/material/core/tokens/m2/mdc/_protected-button.scss index 9e456b0e5b03..ba9b0f9b1ae1 100644 --- a/src/material/core/tokens/m2/mdc/_protected-button.scss +++ b/src/material/core/tokens/m2/mdc/_protected-button.scss @@ -1,9 +1,9 @@ @use 'sass:map'; @use '../../token-utils'; -@use '../../../mdc-helpers/mdc-helpers'; @use '../../../style/sass-utils'; @use '../../../theming/inspection'; @use '../../../theming/theming'; +@use '../../../mdc-helpers/mdc-helpers'; // The prefix used to generate the fully qualified name for tokens in this file. $prefix: (mdc, protected-button); @@ -19,6 +19,9 @@ $prefix: (mdc, protected-button); container-shape: 4px, keep-touch-target: false, + // ============================================================================================= + // = TOKENS NOT USED IN ANGULAR MATERIAL = + // ============================================================================================= focus-ring-color: null, focus-ring-offset: null, focus-state-layer-opacity: null, @@ -43,36 +46,38 @@ $prefix: (mdc, protected-button); with-icon-focus-icon-color: null, with-icon-hover-icon-color: null, with-icon-icon-color: null, - with-icon-pressed-icon-color: null + with-icon-pressed-icon-color: null, + focus-state-layer-color: null, + hover-state-layer-color: null, + pressed-state-layer-color: null, ); } -@function _on-color($theme, $palette) { - @if ($palette) { - $is-dark: inspection.get-theme-type($theme) == dark; - @return if(mdc-helpers.variable-safe-contrast-tone($palette, $is-dark) == 'dark', #000, #fff); - } -} - // Tokens that can be configured through Angular Material's color theming API. -@function get-color-tokens($theme, $color: null, $on-color: null) { +@function get-color-tokens($theme) { $is-dark: inspection.get-theme-type($theme) == dark; - $primary: inspection.get-theme-color($theme, primary); - $surface: inspection.get-theme-color($theme, background, card); - $on-primary: _on-color($theme, $primary); - $on-surface: _on-color($theme, $surface); + $on-surface: if($is-dark, #fff, #000); @return ( - container-color: if($color, $color, transparent), - focus-state-layer-color: $on-primary, - hover-state-layer-color: $on-primary, - pressed-state-layer-color: $on-primary, - label-text-color: if($on-color, $on-color, inherit), + container-color: inspection.get-theme-color($theme, background, card), + label-text-color: $on-surface, disabled-container-color: rgba($on-surface, 0.12), disabled-label-text-color: rgba($on-surface, if($is-dark, 0.5, 0.38)) ); } +// Generates the mapping for the properties that change based on the button palette color. +@function private-get-color-palette-color-tokens($theme, $palette-name) { + $is-dark: inspection.get-theme-type($theme) == dark; + $container-color: inspection.get-theme-color($theme, $palette-name, default); + $contrast-tone: mdc-helpers.variable-safe-contrast-tone($container-color, $is-dark); + + @return ( + container-color: $container-color, + label-text-color: if($contrast-tone == 'dark', #000, #fff), + ); +} + // Tokens that can be configured through Angular Material's typography theming API. @function get-typography-tokens($theme) { @return (); diff --git a/src/material/datepicker/date-range-input.ts b/src/material/datepicker/date-range-input.ts index 261f2c34f755..14b39cd7294d 100644 --- a/src/material/datepicker/date-range-input.ts +++ b/src/material/datepicker/date-range-input.ts @@ -21,13 +21,13 @@ import { Inject, OnChanges, SimpleChanges, + booleanAttribute, } from '@angular/core'; import {MatFormFieldControl, MAT_FORM_FIELD} from '@angular/material/form-field'; import {ThemePalette, DateAdapter} from '@angular/material/core'; import {NgControl, ControlContainer, Validators} from '@angular/forms'; import {Subject, merge, Subscription} from 'rxjs'; import {FocusOrigin} from '@angular/cdk/a11y'; -import {coerceBooleanProperty, BooleanInput} from '@angular/cdk/coercion'; import { MatStartDate, MatEndDate, @@ -128,7 +128,7 @@ export class MatDateRangeInput private _rangePicker: MatDatepickerPanel, DateRange, D>; /** Whether the input is required. */ - @Input() + @Input({transform: booleanAttribute}) get required(): boolean { return ( this._required ?? @@ -138,8 +138,8 @@ export class MatDateRangeInput false ); } - set required(value: BooleanInput) { - this._required = coerceBooleanProperty(value); + set required(value: boolean) { + this._required = value; } private _required: boolean | undefined; @@ -196,17 +196,15 @@ export class MatDateRangeInput private _max: D | null; /** Whether the input is disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return this._startInput && this._endInput ? this._startInput.disabled && this._endInput.disabled : this._groupDisabled; } - set disabled(value: BooleanInput) { - const newValue = coerceBooleanProperty(value); - - if (newValue !== this._groupDisabled) { - this._groupDisabled = newValue; + set disabled(value: boolean) { + if (value !== this._groupDisabled) { + this._groupDisabled = value; this.stateChanges.next(undefined); } } diff --git a/src/material/datepicker/datepicker-actions.spec.ts b/src/material/datepicker/datepicker-actions.spec.ts index e4fd8fb34104..6a004e161330 100644 --- a/src/material/datepicker/datepicker-actions.spec.ts +++ b/src/material/datepicker/datepicker-actions.spec.ts @@ -292,10 +292,12 @@ describe('MatDatepickerActions', () => { [formControl]="control" (dateChange)="onDateChange()"> - - - - + @if (renderActions) { + + + + + }
    `, diff --git a/src/material/datepicker/datepicker-base.ts b/src/material/datepicker/datepicker-base.ts index 32d110b1ef18..225b3158f9b2 100644 --- a/src/material/datepicker/datepicker-base.ts +++ b/src/material/datepicker/datepicker-base.ts @@ -7,7 +7,7 @@ */ import {Directionality} from '@angular/cdk/bidi'; -import {BooleanInput, coerceBooleanProperty, coerceStringArray} from '@angular/cdk/coercion'; +import {coerceStringArray} from '@angular/cdk/coercion'; import { DOWN_ARROW, ESCAPE, @@ -50,8 +50,9 @@ import { SimpleChanges, OnInit, inject, + booleanAttribute, } from '@angular/core'; -import {CanColor, DateAdapter, mixinColor, ThemePalette} from '@angular/material/core'; +import {DateAdapter, ThemePalette} from '@angular/material/core'; import {AnimationEvent} from '@angular/animations'; import {merge, Subject, Observable, Subscription} from 'rxjs'; import {filter, take} from 'rxjs/operators'; @@ -99,14 +100,6 @@ export const MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = { useFactory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY, }; -// Boilerplate for applying mixins to MatDatepickerContent. -/** @docs-private */ -const _MatDatepickerContentBase = mixinColor( - class { - constructor(public _elementRef: ElementRef) {} - }, -); - /** * Component used as the content for the datepicker overlay. We use this instead of using * MatCalendar directly as the content so we can control the initial focus. This also gives us a @@ -120,6 +113,7 @@ const _MatDatepickerContentBase = mixinColor( styleUrls: ['datepicker-content.css'], host: { 'class': 'mat-datepicker-content', + '[class]': 'color ? "mat-" + color : ""', '[@transformPanel]': '_animationState', '(@transformPanel.start)': '_handleAnimationEvent($event)', '(@transformPanel.done)': '_handleAnimationEvent($event)', @@ -129,17 +123,18 @@ const _MatDatepickerContentBase = mixinColor( exportAs: 'matDatepickerContent', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, - inputs: ['color'], }) export class MatDatepickerContent> - extends _MatDatepickerContentBase - implements OnInit, AfterViewInit, OnDestroy, CanColor + implements OnInit, AfterViewInit, OnDestroy { private _subscriptions = new Subscription(); private _model: MatDateSelectionModel; /** Reference to the internal calendar component. */ @ViewChild(MatCalendar) _calendar: MatCalendar; + /** Palette color of the internal calendar. */ + @Input() color: ThemePalette; + /** Reference to the datepicker that created the overlay. */ datepicker: MatDatepickerBase; @@ -180,7 +175,7 @@ export class MatDatepickerContent> _dialogLabelId: string | null; constructor( - elementRef: ElementRef, + protected _elementRef: ElementRef, private _changeDetectorRef: ChangeDetectorRef, private _globalModel: MatDateSelectionModel, private _dateAdapter: DateAdapter, @@ -189,7 +184,6 @@ export class MatDatepickerContent> private _rangeSelectionStrategy: MatDateRangeSelectionStrategy, intl: MatDatepickerIntl, ) { - super(elementRef); this._closeButtonText = intl.closeCalendarLabel; } @@ -333,10 +327,11 @@ export interface MatDatepickerPanel< /** Base class for a datepicker. */ @Directive() export abstract class MatDatepickerBase< - C extends MatDatepickerControl, - S, - D = ExtractDateTypeFromSelection, -> implements MatDatepickerPanel, OnDestroy, OnChanges + C extends MatDatepickerControl, + S, + D = ExtractDateTypeFromSelection, + > + implements MatDatepickerPanel, OnDestroy, OnChanges { private _scrollStrategy: () => ScrollStrategy; private _inputStateChanges = Subscription.EMPTY; @@ -376,27 +371,19 @@ export abstract class MatDatepickerBase< * Whether the calendar UI is in touch mode. In touch mode the calendar opens in a dialog rather * than a dropdown and elements have more padding to allow for bigger touch targets. */ - @Input() - get touchUi(): boolean { - return this._touchUi; - } - set touchUi(value: BooleanInput) { - this._touchUi = coerceBooleanProperty(value); - } - private _touchUi = false; + @Input({transform: booleanAttribute}) + touchUi: boolean = false; /** Whether the datepicker pop-up should be disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return this._disabled === undefined && this.datepickerInput ? this.datepickerInput.disabled : !!this._disabled; } - set disabled(value: BooleanInput) { - const newValue = coerceBooleanProperty(value); - - if (newValue !== this._disabled) { - this._disabled = newValue; + set disabled(value: boolean) { + if (value !== this._disabled) { + this._disabled = value; this.stateChanges.next(undefined); } } @@ -415,14 +402,8 @@ export abstract class MatDatepickerBase< * Note that automatic focus restoration is an accessibility feature and it is recommended that * you provide your own equivalent, if you decide to turn it off. */ - @Input() - get restoreFocus(): boolean { - return this._restoreFocus; - } - set restoreFocus(value: BooleanInput) { - this._restoreFocus = coerceBooleanProperty(value); - } - private _restoreFocus = true; + @Input({transform: booleanAttribute}) + restoreFocus: boolean = true; /** * Emits selected year in multiyear view. @@ -466,12 +447,16 @@ export abstract class MatDatepickerBase< private _panelClass: string[]; /** Whether the calendar is open. */ - @Input() + @Input({transform: booleanAttribute}) get opened(): boolean { return this._opened; } - set opened(value: BooleanInput) { - coerceBooleanProperty(value) ? this.open() : this.close(); + set opened(value: boolean) { + if (value) { + this.open(); + } else { + this.close(); + } } private _opened = false; @@ -639,7 +624,7 @@ export abstract class MatDatepickerBase< } const canRestoreFocus = - this._restoreFocus && + this.restoreFocus && this._focusedElementBeforeOpen && typeof this._focusedElementBeforeOpen.focus === 'function'; diff --git a/src/material/datepicker/datepicker-input-base.ts b/src/material/datepicker/datepicker-input-base.ts index 1db7fe3b3dd0..4a566dbc73ee 100644 --- a/src/material/datepicker/datepicker-input-base.ts +++ b/src/material/datepicker/datepicker-input-base.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {DOWN_ARROW, hasModifierKey, ModifierKey} from '@angular/cdk/keycodes'; import { Directive, @@ -20,6 +19,7 @@ import { AfterViewInit, OnChanges, SimpleChanges, + booleanAttribute, } from '@angular/core'; import { AbstractControl, @@ -92,12 +92,12 @@ export abstract class MatDatepickerInputBase | undefined; /** Whether the datepicker-input is disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return !!this._disabled || this._parentDisabled(); } - set disabled(value: BooleanInput) { - const newValue = coerceBooleanProperty(value); + set disabled(value: boolean) { + const newValue = value; const element = this._elementRef.nativeElement; if (this._disabled !== newValue) { diff --git a/src/material/datepicker/datepicker-toggle.ts b/src/material/datepicker/datepicker-toggle.ts index 61913c703be9..9b37af245607 100644 --- a/src/material/datepicker/datepicker-toggle.ts +++ b/src/material/datepicker/datepicker-toggle.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import { AfterContentInit, Attribute, @@ -21,6 +20,7 @@ import { SimpleChanges, ViewEncapsulation, ViewChild, + booleanAttribute, } from '@angular/core'; import {MatButton} from '@angular/material/button'; import {merge, Observable, of as observableOf, Subscription} from 'rxjs'; @@ -67,7 +67,7 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe @Input('aria-label') ariaLabel: string; /** Whether the toggle button is disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { if (this._disabled === undefined && this.datepicker) { return this.datepicker.disabled; @@ -75,8 +75,8 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe return !!this._disabled; } - set disabled(value: BooleanInput) { - this._disabled = coerceBooleanProperty(value); + set disabled(value: boolean) { + this._disabled = value; } private _disabled: boolean; diff --git a/src/material/datepicker/testing/calendar-harness.ts b/src/material/datepicker/testing/calendar-harness.ts index dffe7a0a2f2d..44bfd9d04be3 100644 --- a/src/material/datepicker/testing/calendar-harness.ts +++ b/src/material/datepicker/testing/calendar-harness.ts @@ -11,7 +11,7 @@ import {CalendarHarnessFilters, CalendarCellHarnessFilters} from './datepicker-h import {MatCalendarCellHarness} from './calendar-cell-harness'; /** Possible views of a `MatCalendarHarness`. */ -export const enum CalendarView { +export enum CalendarView { MONTH, YEAR, MULTI_YEAR, diff --git a/src/material/dialog/dialog-ref.ts b/src/material/dialog/dialog-ref.ts index c4280bbc611a..348ab75cdf5d 100644 --- a/src/material/dialog/dialog-ref.ts +++ b/src/material/dialog/dialog-ref.ts @@ -17,7 +17,7 @@ import {ESCAPE, hasModifierKey} from '@angular/cdk/keycodes'; import {GlobalPositionStrategy} from '@angular/cdk/overlay'; import {ComponentRef} from '@angular/core'; -export const enum MatDialogState { +export enum MatDialogState { OPEN, CLOSING, CLOSED, diff --git a/src/material/dialog/dialog.spec.ts b/src/material/dialog/dialog.spec.ts index a43f9dc70940..e8be88bc3231 100644 --- a/src/material/dialog/dialog.spec.ts +++ b/src/material/dialog/dialog.spec.ts @@ -2121,7 +2121,7 @@ class ComponentWithOnPushViewContainer { @Component({ selector: 'arbitrary-component', - template: ``, + template: `@if (showChildView) {}`, }) class ComponentWithChildViewContainer { showChildView = true; @@ -2162,9 +2162,15 @@ class PizzaMsg { @Component({ template: ` -

    This is the first title

    -

    This is the second title

    -

    This is the third title

    + @if (shouldShowTitle('first')) { +

    This is the first title

    + } + @if (shouldShowTitle('second')) { +

    This is the second title

    + } + @if (shouldShowTitle('third')) { +

    This is the third title

    + } Lorem ipsum dolor sit amet. @@ -2189,9 +2195,15 @@ class ContentElementDialog { @Component({ template: ` -

    This is the first title

    -

    This is the second title

    -

    This is the third title

    + @if (shouldShowTitle('first')) { +

    This is the first title

    + } + @if (shouldShowTitle('second')) { +

    This is the second title

    + } + @if (shouldShowTitle('third')) { +

    This is the third title

    + } Lorem ipsum dolor sit amet. @@ -2238,7 +2250,10 @@ class ShadowDomComponent {} @Component({template: ''}) class ModuleBoundDialogParentComponent { - constructor(private _injector: Injector, private _dialog: MatDialog) {} + constructor( + private _injector: Injector, + private _dialog: MatDialog, + ) {} openDialog(): void { const ngModuleRef = createNgModuleRef( diff --git a/src/material/dialog/dialog.ts b/src/material/dialog/dialog.ts index 0c96aa4b579c..f85a26a40055 100644 --- a/src/material/dialog/dialog.ts +++ b/src/material/dialog/dialog.ts @@ -82,7 +82,7 @@ export class MatDialog implements OnDestroy { private readonly _openDialogsAtThisLevel: MatDialogRef[] = []; private readonly _afterAllClosedAtThisLevel = new Subject(); private readonly _afterOpenedAtThisLevel = new Subject>(); - private _dialog: Dialog; + protected _dialog: Dialog; protected dialogConfigClass = MatDialogConfig; private readonly _dialogRefConstructor: Type>; diff --git a/src/material/dialog/testing/dialog-harness.ts b/src/material/dialog/testing/dialog-harness.ts index 08579b772c07..03f4aeeff2bb 100644 --- a/src/material/dialog/testing/dialog-harness.ts +++ b/src/material/dialog/testing/dialog-harness.ts @@ -16,7 +16,7 @@ import {DialogHarnessFilters} from './dialog-harness-filters'; import {DialogRole} from '@angular/material/dialog'; /** Selectors for different sections of the mat-dialog that can contain user content. */ -export const enum MatDialogSection { +export enum MatDialogSection { TITLE = '.mat-mdc-dialog-title', CONTENT = '.mat-mdc-dialog-content', ACTIONS = '.mat-mdc-dialog-actions', diff --git a/src/material/divider/divider.md b/src/material/divider/divider.md index 960ef674945d..6e0094184c3b 100644 --- a/src/material/divider/divider.md +++ b/src/material/divider/divider.md @@ -38,19 +38,25 @@ in a list, because it will overlap with the section divider. ```html

    Folders

    - - folder -

    {{folder.name}}

    -

    {{folder.updated}}

    - -
    + @for (folder of folders; track folder) { + + folder +

    {{folder.name}}

    +

    {{folder.updated}}

    + @if (!$last) { + + } +
    + }

    Notes

    - - note -

    {{note.name}}

    -

    {{note.updated}}

    -
    + @for (note of notes; track node) { + + note +

    {{note.name}}

    +

    {{note.updated}}

    +
    + }
    ``` diff --git a/src/material/expansion/BUILD.bazel b/src/material/expansion/BUILD.bazel index 7b278f14f5d8..7d2dd322c69f 100644 --- a/src/material/expansion/BUILD.bazel +++ b/src/material/expansion/BUILD.bazel @@ -23,7 +23,6 @@ ng_module( deps = [ "//src/cdk/a11y", "//src/cdk/accordion", - "//src/cdk/coercion", "//src/cdk/collections", "//src/cdk/keycodes", "//src/cdk/portal", diff --git a/src/material/expansion/accordion.spec.ts b/src/material/expansion/accordion.spec.ts index 45d441c6f469..e0de275e23ce 100644 --- a/src/material/expansion/accordion.spec.ts +++ b/src/material/expansion/accordion.spec.ts @@ -303,10 +303,12 @@ describe('MatAccordion', () => { @Component({ template: ` - - Summary {{i}} -

    Content

    -
    + @for (i of [0, 1, 2, 3]; track i) { + + Summary {{i}} +

    Content

    +
    + }
    `, }) class SetOfItems { diff --git a/src/material/expansion/accordion.ts b/src/material/expansion/accordion.ts index f654a0063602..1289aca8fc01 100644 --- a/src/material/expansion/accordion.ts +++ b/src/material/expansion/accordion.ts @@ -13,8 +13,8 @@ import { QueryList, AfterContentInit, OnDestroy, + booleanAttribute, } from '@angular/core'; -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {CdkAccordion} from '@angular/cdk/accordion'; import {FocusKeyManager} from '@angular/cdk/a11y'; import {startWith} from 'rxjs/operators'; @@ -60,14 +60,8 @@ export class MatAccordion _headers: QueryList; /** Whether the expansion indicator should be hidden. */ - @Input() - get hideToggle(): boolean { - return this._hideToggle; - } - set hideToggle(show: BooleanInput) { - this._hideToggle = coerceBooleanProperty(show); - } - private _hideToggle: boolean = false; + @Input({transform: booleanAttribute}) + hideToggle: boolean = false; /** * Display mode used for all expansion panels in the accordion. Currently two display diff --git a/src/material/expansion/expansion-panel-header.ts b/src/material/expansion/expansion-panel-header.ts index 93641bf2627e..a4a8a4de9354 100644 --- a/src/material/expansion/expansion-panel-header.ts +++ b/src/material/expansion/expansion-panel-header.ts @@ -19,12 +19,12 @@ import { Host, Inject, Input, + numberAttribute, OnDestroy, Optional, ViewEncapsulation, } from '@angular/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; -import {HasTabIndex, mixinTabIndex} from '@angular/material/core'; import {EMPTY, merge, Subscription} from 'rxjs'; import {filter} from 'rxjs/operators'; import {MatAccordionTogglePosition} from './accordion-base'; @@ -35,13 +35,6 @@ import { MAT_EXPANSION_PANEL_DEFAULT_OPTIONS, } from './expansion-panel'; -// Boilerplate for applying mixins to MatExpansionPanelHeader. -/** @docs-private */ -abstract class MatExpansionPanelHeaderBase { - abstract readonly disabled: boolean; -} -const _MatExpansionPanelHeaderMixinBase = mixinTabIndex(MatExpansionPanelHeaderBase); - /** * Header element of a ``. */ @@ -51,13 +44,12 @@ const _MatExpansionPanelHeaderMixinBase = mixinTabIndex(MatExpansionPanelHeaderB templateUrl: 'expansion-panel-header.html', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, - inputs: ['tabIndex'], animations: [matExpansionAnimations.indicatorRotate], host: { 'class': 'mat-expansion-panel-header mat-focus-indicator', 'role': 'button', '[attr.id]': 'panel._headerId', - '[attr.tabindex]': 'tabIndex', + '[attr.tabindex]': 'disabled ? -1 : tabIndex', '[attr.aria-controls]': '_getPanelId()', '[attr.aria-expanded]': '_isExpanded()', '[attr.aria-disabled]': 'panel.disabled', @@ -70,10 +62,7 @@ const _MatExpansionPanelHeaderMixinBase = mixinTabIndex(MatExpansionPanelHeaderB '(keydown)': '_keydown($event)', }, }) -export class MatExpansionPanelHeader - extends _MatExpansionPanelHeaderMixinBase - implements AfterViewInit, OnDestroy, FocusableOption, HasTabIndex -{ +export class MatExpansionPanelHeader implements AfterViewInit, OnDestroy, FocusableOption { private _parentChangeSubscription = Subscription.EMPTY; constructor( @@ -87,7 +76,6 @@ export class MatExpansionPanelHeader @Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string, @Attribute('tabindex') tabIndex?: string, ) { - super(); const accordionHideToggleChange = panel.accordion ? panel.accordion._stateChanges.pipe( filter(changes => !!(changes['hideToggle'] || changes['togglePosition'])), @@ -125,6 +113,12 @@ export class MatExpansionPanelHeader /** Height of the header while the panel is collapsed. */ @Input() collapsedHeight: string; + /** Tab index of the header. */ + @Input({ + transform: (value: unknown) => (value == null ? 0 : numberAttribute(value)), + }) + tabIndex: number = 0; + /** * Whether the associated panel is disabled. Implemented as a part of `FocusableOption`. * @docs-private diff --git a/src/material/expansion/expansion-panel.ts b/src/material/expansion/expansion-panel.ts index 539366df4f7f..f2c001f9cb69 100644 --- a/src/material/expansion/expansion-panel.ts +++ b/src/material/expansion/expansion-panel.ts @@ -8,7 +8,6 @@ import {AnimationEvent} from '@angular/animations'; import {CdkAccordionItem} from '@angular/cdk/accordion'; -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {UniqueSelectionDispatcher} from '@angular/cdk/collections'; import {TemplatePortal} from '@angular/cdk/portal'; import {DOCUMENT} from '@angular/common'; @@ -33,6 +32,7 @@ import { ViewChild, ViewContainerRef, ViewEncapsulation, + booleanAttribute, } from '@angular/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import {Subject} from 'rxjs'; @@ -102,17 +102,16 @@ export class MatExpansionPanel implements AfterContentInit, OnChanges, OnDestroy { private _document: Document; - private _hideToggle = false; - private _togglePosition: MatAccordionTogglePosition; /** Whether the toggle indicator should be hidden. */ - @Input() + @Input({transform: booleanAttribute}) get hideToggle(): boolean { return this._hideToggle || (this.accordion && this.accordion.hideToggle); } - set hideToggle(value: BooleanInput) { - this._hideToggle = coerceBooleanProperty(value); + set hideToggle(value: boolean) { + this._hideToggle = value; } + private _hideToggle = false; /** The position of the expansion indicator. */ @Input() @@ -122,6 +121,7 @@ export class MatExpansionPanel set togglePosition(value: MatAccordionTogglePosition) { this._togglePosition = value; } + private _togglePosition: MatAccordionTogglePosition; /** An event emitted after the body's expansion animation happens. */ @Output() readonly afterExpand = new EventEmitter(); diff --git a/src/material/expansion/expansion.spec.ts b/src/material/expansion/expansion.spec.ts index ae3fbc004a2c..f79a19e1e965 100644 --- a/src/material/expansion/expansion.spec.ts +++ b/src/material/expansion/expansion.spec.ts @@ -582,11 +582,14 @@ class PanelWithContent { @Component({ template: ` -
    - - Panel Title - -
    `, + @if (expansionShown) { +
    + + Panel Title + +
    + } + `, }) class PanelWithContentInNgIf { expansionShown = true; diff --git a/src/material/expansion/testing/BUILD.bazel b/src/material/expansion/testing/BUILD.bazel index c5542e861fc5..1cb28edb5d0a 100644 --- a/src/material/expansion/testing/BUILD.bazel +++ b/src/material/expansion/testing/BUILD.bazel @@ -9,7 +9,6 @@ ts_library( exclude = ["**/*.spec.ts"], ), deps = [ - "//src/cdk/coercion", "//src/cdk/testing", ], ) diff --git a/src/material/expansion/testing/expansion-harness.ts b/src/material/expansion/testing/expansion-harness.ts index 37e2865516ee..fa80761895c2 100644 --- a/src/material/expansion/testing/expansion-harness.ts +++ b/src/material/expansion/testing/expansion-harness.ts @@ -14,7 +14,7 @@ import { import {ExpansionPanelHarnessFilters} from './expansion-harness-filters'; /** Selectors for the various `mat-expansion-panel` sections that may contain user content. */ -export const enum MatExpansionPanelSection { +export enum MatExpansionPanelSection { HEADER = '.mat-expansion-panel-header', TITLE = '.mat-expansion-panel-header-title', DESCRIPTION = '.mat-expansion-panel-header-description', diff --git a/src/material/form-field/form-field.md b/src/material/form-field/form-field.md index 5ccf3129b13b..a393f128eb24 100644 --- a/src/material/form-field/form-field.md +++ b/src/material/form-field/form-field.md @@ -86,7 +86,7 @@ has interacted with the element or the parent form has been submitted. Since the same space as the hints, the hints are hidden when the errors are shown. If a form field can have more than one error state, it is up to the consumer to toggle which -messages should be displayed. This can be done with CSS, `ngIf` or `ngSwitch`. Multiple error +messages should be displayed. This can be done with CSS, `@if` or `@switch`. Multiple error messages can be shown at the same time if desired, but the `` only reserves enough space to display one error message at a time. Ensuring that enough space is available to display multiple errors is up to the user. diff --git a/src/material/grid-list/grid-list.spec.ts b/src/material/grid-list/grid-list.spec.ts index f6519917c11f..ceca04053d5b 100644 --- a/src/material/grid-list/grid-list.spec.ts +++ b/src/material/grid-list/grid-list.spec.ts @@ -676,10 +676,12 @@ class GridListWithRowspanBinding { template: `
    - - {{tile.text}} - + @for (tile of tiles; track tile) { + + {{tile.text}} + + }
    `, }) @@ -744,10 +746,10 @@ class GridListWithFooterContainingTwoLines {} - + @if (true) {

    First line

    Second line -
    + }
    `, @@ -779,13 +781,13 @@ class GridListWithEmptyDirectionality {} class GridListWithRtl {} @Component({ - // Note the blank `ngSwitch` which we need in order to hit the bug that we're testing. + // Note the blank `@if` which we need in order to hit the bug that we're testing. template: `
    - + @if (true) { - + }
    `, diff --git a/src/material/grid-list/testing/grid-list-harness.spec.ts b/src/material/grid-list/testing/grid-list-harness.spec.ts index 2faf72ab5986..2431235d850e 100644 --- a/src/material/grid-list/testing/grid-list-harness.spec.ts +++ b/src/material/grid-list/testing/grid-list-harness.spec.ts @@ -151,7 +151,9 @@ describe('MatGridListHarness', () => { {{firstTileText}} - Footer + @if (showFooter) { + Footer + } Two diff --git a/src/material/grid-list/testing/grid-tile-harness.ts b/src/material/grid-list/testing/grid-tile-harness.ts index 2d51dc95b343..ac2243008a8c 100644 --- a/src/material/grid-list/testing/grid-tile-harness.ts +++ b/src/material/grid-list/testing/grid-tile-harness.ts @@ -10,7 +10,7 @@ import {ContentContainerComponentHarness, HarnessPredicate} from '@angular/cdk/t import {GridTileHarnessFilters} from './grid-list-harness-filters'; /** Selectors for the various `mat-grid-tile` sections that may contain user content. */ -export const enum MatGridTileSection { +export enum MatGridTileSection { HEADER = '.mat-grid-tile-header', FOOTER = '.mat-grid-tile-footer', } diff --git a/src/material/icon/BUILD.bazel b/src/material/icon/BUILD.bazel index 2d560498f48b..e33c8cef8b78 100644 --- a/src/material/icon/BUILD.bazel +++ b/src/material/icon/BUILD.bazel @@ -19,7 +19,6 @@ ng_module( assets = [":icon.css"] + glob(["**/*.html"]), deps = [ "//src:dev_mode_types", - "//src/cdk/coercion", "//src/material/core", "@npm//@angular/common", "@npm//@angular/core", diff --git a/src/material/icon/icon.spec.ts b/src/material/icon/icon.spec.ts index 3d7e8f18d2c3..2a02df303cf9 100644 --- a/src/material/icon/icon.spec.ts +++ b/src/material/icon/icon.spec.ts @@ -1420,7 +1420,7 @@ class IconFromSvgName { @Component({template: 'face'}) class IconWithAriaHiddenFalse {} -@Component({template: `{{iconName}}`}) +@Component({template: `@if (showIcon) {{{iconName}}}`}) class IconWithBindingAndNgIf { iconName = 'fluffy'; showIcon = true; diff --git a/src/material/icon/icon.ts b/src/material/icon/icon.ts index ce51a3f9f05d..5f902d8575eb 100644 --- a/src/material/icon/icon.ts +++ b/src/material/icon/icon.ts @@ -6,11 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {DOCUMENT} from '@angular/common'; import { AfterViewChecked, Attribute, + booleanAttribute, ChangeDetectionStrategy, Component, ElementRef, @@ -24,20 +24,12 @@ import { Optional, ViewEncapsulation, } from '@angular/core'; -import {CanColor, ThemePalette, mixinColor} from '@angular/material/core'; +import {ThemePalette} from '@angular/material/core'; import {Subscription} from 'rxjs'; import {take} from 'rxjs/operators'; import {MatIconRegistry} from './icon-registry'; -// Boilerplate for applying mixins to MatIcon. -/** @docs-private */ -const _MatIconBase = mixinColor( - class { - constructor(public _elementRef: ElementRef) {} - }, -); - /** Default options for `mat-icon`. */ export interface MatIconDefaultOptions { /** Default color of the icon. */ @@ -140,10 +132,10 @@ const funcIriPattern = /^url\(['"]?#(.*?)['"]?\)$/; selector: 'mat-icon', exportAs: 'matIcon', styleUrls: ['icon.css'], - inputs: ['color'], host: { 'role': 'img', 'class': 'mat-icon notranslate', + '[class]': 'color ? "mat-" + color : ""', '[attr.data-mat-icon-type]': '_usingFontIcon() ? "font" : "svg"', '[attr.data-mat-icon-name]': '_svgName || fontIcon', '[attr.data-mat-icon-namespace]': '_svgNamespace || fontSet', @@ -154,19 +146,25 @@ const funcIriPattern = /^url\(['"]?#(.*?)['"]?\)$/; encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatIcon extends _MatIconBase implements OnInit, AfterViewChecked, CanColor, OnDestroy { +export class MatIcon implements OnInit, AfterViewChecked, OnDestroy { + private _defaultColor: ThemePalette; + + /** Theme palette color of the icon. */ + @Input() + get color() { + return this._color || this._defaultColor; + } + set color(value: string | null | undefined) { + this._color = value; + } + private _color: string | null | undefined; + /** * Whether the icon should be inlined, automatically sizing the icon to match the font size of * the element the icon is contained in. */ - @Input() - get inline(): boolean { - return this._inline; - } - set inline(inline: BooleanInput) { - this._inline = coerceBooleanProperty(inline); - } - private _inline: boolean = false; + @Input({transform: booleanAttribute}) + inline: boolean = false; /** Name of the icon in the SVG icon set. */ @Input() @@ -231,7 +229,7 @@ export class MatIcon extends _MatIconBase implements OnInit, AfterViewChecked, C private _currentIconFetch = Subscription.EMPTY; constructor( - elementRef: ElementRef, + readonly _elementRef: ElementRef, private _iconRegistry: MatIconRegistry, @Attribute('aria-hidden') ariaHidden: string, @Inject(MAT_ICON_LOCATION) private _location: MatIconLocation, @@ -240,11 +238,9 @@ export class MatIcon extends _MatIconBase implements OnInit, AfterViewChecked, C @Inject(MAT_ICON_DEFAULT_OPTIONS) defaults?: MatIconDefaultOptions, ) { - super(elementRef); - if (defaults) { if (defaults.color) { - this.color = this.defaultColor = defaults.color; + this.color = this._defaultColor = defaults.color; } if (defaults.fontSet) { @@ -255,7 +251,7 @@ export class MatIcon extends _MatIconBase implements OnInit, AfterViewChecked, C // If the user has not explicitly set aria-hidden, mark the icon as hidden, as this is // the right thing to do for the majority of icon use-cases. if (!ariaHidden) { - elementRef.nativeElement.setAttribute('aria-hidden', 'true'); + _elementRef.nativeElement.setAttribute('aria-hidden', 'true'); } } diff --git a/src/material/icon/testing/BUILD.bazel b/src/material/icon/testing/BUILD.bazel index 66b4e3d100a9..e06226855b45 100644 --- a/src/material/icon/testing/BUILD.bazel +++ b/src/material/icon/testing/BUILD.bazel @@ -9,7 +9,6 @@ ng_module( exclude = ["**/*.spec.ts"], ), deps = [ - "//src/cdk/coercion", "//src/cdk/testing", "//src/material/icon", "@npm//@angular/common", diff --git a/src/material/icon/testing/icon-harness-filters.ts b/src/material/icon/testing/icon-harness-filters.ts index 849ec9d7f052..913ca10a8a68 100644 --- a/src/material/icon/testing/icon-harness-filters.ts +++ b/src/material/icon/testing/icon-harness-filters.ts @@ -9,7 +9,7 @@ import {BaseHarnessFilters} from '@angular/cdk/testing'; /** Possible types of icons. */ -export const enum IconType { +export enum IconType { SVG, FONT, } diff --git a/src/material/input/input.spec.ts b/src/material/input/input.spec.ts index 0f805aae8033..fef22dd52f7c 100644 --- a/src/material/input/input.spec.ts +++ b/src/material/input/input.spec.ts @@ -1629,7 +1629,9 @@ class MatInputHintLabelTestController { template: ` - Some error + @if (showError) { + Some error + } `, }) class MatInputWithSubscriptAndAriaDescribedBy { @@ -1782,7 +1784,9 @@ class MatInputMissingMatInputTestController {} Please type something - This field is required + @if (renderError) { + This field is required + } `, @@ -1855,7 +1859,9 @@ class MatInputWithPrefixAndSuffix {} @Component({ template: ` - + @if (renderInput) { + + } `, }) diff --git a/src/material/list/list.md b/src/material/list/list.md index 9360406bc586..c1c86b453b30 100644 --- a/src/material/list/list.md +++ b/src/material/list/list.md @@ -62,7 +62,9 @@ Simple navigation lists can use the `mat-list-item` attribute on anchor tag elem ```html - {{ link }} + @for (link of list; track link) { + {{ link }} + } ``` @@ -71,12 +73,14 @@ element in an ``. ```html - - {{ link }} - - + @for (link of links; track link) { + + {{ link }} + + + } ``` @@ -111,22 +115,26 @@ attribute. Whichever heading tag is appropriate for your DOM hierarchy should be ```html - -

    {{message.from}}

    -

    - {{message.subject}} - -- {{message.content}} -

    -
    + @for (message of messages; track message) { + +

    {{message.from}}

    +

    + {{message.subject}} + -- {{message.content}} +

    +
    + }
    - -

    {{message.from}}

    -

    {{message.subject}}

    -

    {{message.content}}

    -
    + @for (message of messages; track message) { + +

    {{message.from}}

    +

    {{message.subject}}

    +

    {{message.content}}

    +
    + }
    ``` @@ -137,14 +145,16 @@ To add an icon to your list item, use the `matListItemIcon` attribute. ```html - - folder -

    {{message.from}}

    -

    - {{message.subject}} - -- {{message.content}} -

    -
    + @for (message of messages; track message) { + + folder +

    {{message.from}}

    +

    + {{message.subject}} + -- {{message.content}} +

    +
    + }
    ``` @@ -154,14 +164,16 @@ To include an avatar image, add an image tag with an `matListItemAvatar` attribu ```html - - ... -

    {{message.from}}

    -

    - {{message.subject}} - -- {{message.content}} -

    -
    + @for (message of messages; track message) { + + ... +

    {{message.from}}

    +

    + {{message.subject}} + -- {{message.content}} +

    +
    + }
    ``` @@ -173,18 +185,22 @@ To add a divider, use ``. ```html

    Folders

    - - folder -

    {{folder.name}}

    -

    {{folder.updated}}

    -
    + @for (folder of folders; track folder) { + + folder +

    {{folder.name}}

    +

    {{folder.updated}}

    +
    + }

    Notes

    - - note -

    {{note.name}}

    -

    {{note.updated}}

    -
    + @for (note of notes; track note) { + + note +

    {{note.name}}

    +

    {{note.updated}}

    +
    + }
    ``` diff --git a/src/material/list/list.spec.ts b/src/material/list/list.spec.ts index 5b97fc9f1460..53214f0a75d5 100644 --- a/src/material/list/list.spec.ts +++ b/src/material/list/list.spec.ts @@ -449,10 +449,12 @@ class NavListWithOneAnchorItem extends BaseTestList { @Component({ template: ` - - {{item.name}} - + @for (item of items; track item; let index = $index) { + + {{item.name}} + + } `, }) class NavListWithActivatedItem extends BaseTestList { @@ -493,9 +495,9 @@ class ActionListWithType extends BaseTestList { @Component({ template: ` - + @for (item of items; track item) { + + } `, }) class ActionListWithDisabledList extends BaseTestList { @@ -528,11 +530,13 @@ class ListWithOneItem extends BaseTestList {} @Component({ template: ` - - -

    {{item.name}}

    -

    {{item.description}}

    -
    + @for (item of items; track item) { + + +

    {{item.name}}

    +

    {{item.description}}

    +
    + }
    `, }) class ListWithTwoLineItem extends BaseTestList {} @@ -540,11 +544,13 @@ class ListWithTwoLineItem extends BaseTestList {} @Component({ template: ` - -

    {{item.name}}

    -

    {{item.description}}

    -

    Some other text

    -
    + @for (item of items; track item) { + +

    {{item.name}}

    +

    {{item.description}}

    +

    Some other text

    +
    + }
    `, }) class ListWithThreeLineItem extends BaseTestList {} @@ -552,12 +558,14 @@ class ListWithThreeLineItem extends BaseTestList {} @Component({ template: ` - -

    Line 1

    -

    Line 2

    -

    Line 3

    -

    Line 4

    -
    + @for (item of items; track item) { + +

    Line 1

    +

    Line 2

    +

    Line 3

    +

    Line 4

    +
    + }
    `, }) class ListWithManyLines extends BaseTestList {} @@ -579,10 +587,12 @@ class ListWithAvatar extends BaseTestList {} @Component({ template: ` - -

    {{item.name}}

    -

    {{item.description}}

    -
    + @for (item of items; track item) { + +

    {{item.name}}

    +

    {{item.description}}

    +
    + }
    `, }) class ListWithItemWithCssClass extends BaseTestList {} @@ -590,11 +600,15 @@ class ListWithItemWithCssClass extends BaseTestList {} @Component({ template: ` - -

    {{item.name}}

    -

    {{item.description}}

    -

    Some other text

    -
    + @for (item of items; track item) { + +

    {{item.name}}

    +

    {{item.description}}

    + @if (showThirdLine) { +

    Some other text

    + } +
    + }
    `, }) class ListWithDynamicNumberOfLines extends BaseTestList {} @@ -602,9 +616,9 @@ class ListWithDynamicNumberOfLines extends BaseTestList {} @Component({ template: ` - - {{item.name}} - + @for (item of items; track item) { + {{item.name}} + } `, }) class ListWithMultipleItems extends BaseTestList {} diff --git a/src/material/list/selection-list.spec.ts b/src/material/list/selection-list.spec.ts index c908b52a24f6..51ec5b0413d0 100644 --- a/src/material/list/selection-list.spec.ts +++ b/src/material/list/selection-list.spec.ts @@ -1725,9 +1725,11 @@ describe('MDC-based MatSelectionList with forms', () => { Archive - - Drafts - + @if (showLastOption) { + + Drafts + + }
    `, }) class SelectionListWithListOptions { @@ -1837,7 +1839,9 @@ class SelectionListWithOnlyOneOption {} [(ngModel)]="selectedOptions" (ngModelChange)="modelChangeSpy()" [multiple]="multiple"> - {{option}} + @for (option of options; track option) { + {{option}} + } `, }) class SelectionListWithModel { @@ -1849,12 +1853,16 @@ class SelectionListWithModel { @Component({ template: ` - - Option 1 - Option 2 - Option 3 - Option 4 - + @if (renderList) { + + Option 1 + Option 2 + Option 3 + @if (renderExtraOption) { + Option 4 + } + + } `, }) class SelectionListWithFormControl { @@ -1889,7 +1897,9 @@ class SelectionListWithPreselectedOptionAndModel { changeDetection: ChangeDetectionStrategy.OnPush, template: ` - {{opt}} + @for (opt of opts; track opt) { + {{opt}} + } `, }) @@ -1901,9 +1911,9 @@ class SelectionListWithPreselectedFormControlOnPush { @Component({ template: ` - - {{option.label}} - + @for (option of options; track option) { + {{option.label}} + } `, }) class SelectionListWithCustomComparator { @@ -1946,13 +1956,13 @@ class SelectionListWithIcon { } @Component({ - // Note the blank `ngSwitch` which we need in order to hit the bug that we're testing. + // Note the blank `@if` which we need in order to hit the bug that we're testing. template: ` - + @if (true) { One Two - + } `, }) class SelectionListWithIndirectChildOptions { diff --git a/src/material/list/testing/list-item-harness-base.ts b/src/material/list/testing/list-item-harness-base.ts index 03f9457b0df8..b89097860419 100644 --- a/src/material/list/testing/list-item-harness-base.ts +++ b/src/material/list/testing/list-item-harness-base.ts @@ -67,12 +67,12 @@ export class MatSubheaderHarness extends ComponentHarness { } /** Selectors for the various list item sections that may contain user content. */ -export const enum MatListItemSection { +export enum MatListItemSection { CONTENT = '.mdc-list-item__content', } /** Enum describing the possible variants of a list item. */ -export const enum MatListItemType { +export enum MatListItemType { ONE_LINE_ITEM, TWO_LINE_ITEM, THREE_LINE_ITEM, diff --git a/src/material/menu/menu.spec.ts b/src/material/menu/menu.spec.ts index 8af757362780..5722baf4819b 100644 --- a/src/material/menu/menu.spec.ts +++ b/src/material/menu/menu.spec.ts @@ -2780,7 +2780,9 @@ const SIMPLE_MENU_TEMPLATE = ` - + @for (item of extraItems; track item) { + + } `; @@ -2889,11 +2891,12 @@ class CustomMenu { [matMenuTriggerFor]="levelOne" #levelOneTrigger="matMenuTrigger">One - + @if (showLazy) { + + } @@ -2962,11 +2965,12 @@ class NestedMenuCustomElevation { template: ` - + @for (item of items; track item) { + + } @@ -3083,10 +3087,9 @@ class MenuWithCheckboxItems { template: ` - + @for (item of items; track item) { + + } `, }) @@ -3105,10 +3108,9 @@ class SimpleMenuWithRepeater { - + @for (item of items; track item) { + + } `, @@ -3173,7 +3175,9 @@ class StaticAriaDescribedbyMenu {} template: ` - + @for (item of items; track item) { + + } `, }) diff --git a/src/material/paginator/BUILD.bazel b/src/material/paginator/BUILD.bazel index 3c5ce18ad133..49fc8994b6c7 100644 --- a/src/material/paginator/BUILD.bazel +++ b/src/material/paginator/BUILD.bazel @@ -18,7 +18,6 @@ ng_module( ), assets = [":paginator.css"] + glob(["**/*.html"]), deps = [ - "//src/cdk/coercion", "//src/material/button", "//src/material/core", "//src/material/select", diff --git a/src/material/paginator/paginator.ts b/src/material/paginator/paginator.ts index 03243053123d..403b080cf89f 100644 --- a/src/material/paginator/paginator.ts +++ b/src/material/paginator/paginator.ts @@ -19,22 +19,12 @@ import { Optional, Output, ViewEncapsulation, + booleanAttribute, + numberAttribute, } from '@angular/core'; import {MatFormFieldAppearance} from '@angular/material/form-field'; -import { - CanDisable, - HasInitialized, - mixinDisabled, - mixinInitialized, - ThemePalette, -} from '@angular/material/core'; +import {HasInitialized, mixinInitialized, ThemePalette} from '@angular/material/core'; import {Subscription} from 'rxjs'; -import { - BooleanInput, - coerceBooleanProperty, - coerceNumberProperty, - NumberInput, -} from '@angular/cdk/coercion'; import {MatPaginatorIntl} from './paginator-intl'; /** The default page size if there is no page size and there are no provided page size options. */ @@ -99,7 +89,7 @@ export const MAT_PAGINATOR_DEFAULT_OPTIONS = new InjectionToken coerceNumberProperty(p)); + this._pageSizeOptions = (value || ([] as number[])).map(p => numberAttribute(p, 0)); this._updateDisplayedPageSizeOptions(); } private _pageSizeOptions: number[] = []; /** Whether to hide the page size selection UI from the user. */ - @Input() - get hidePageSize(): boolean { - return this._hidePageSize; - } - set hidePageSize(value: BooleanInput) { - this._hidePageSize = coerceBooleanProperty(value); - } - private _hidePageSize = false; + @Input({transform: booleanAttribute}) + hidePageSize: boolean = false; /** Whether to show the first/last buttons UI to the user. */ - @Input() - get showFirstLastButtons(): boolean { - return this._showFirstLastButtons; - } - set showFirstLastButtons(value: BooleanInput) { - this._showFirstLastButtons = coerceBooleanProperty(value); - } - private _showFirstLastButtons = false; + @Input({transform: booleanAttribute}) + showFirstLastButtons: boolean = false; /** Used to configure the underlying `MatSelect` inside the paginator. */ @Input() selectConfig: MatPaginatorSelectConfig = {}; + /** Whether the paginator is disabled. */ + @Input({transform: booleanAttribute}) + disabled: boolean = false; + /** Event emitted when the paginator changes the page size or page index. */ @Output() readonly page: EventEmitter = new EventEmitter(); @@ -230,11 +211,11 @@ export class MatPaginator } if (hidePageSize != null) { - this._hidePageSize = hidePageSize; + this.hidePageSize = hidePageSize; } if (showFirstLastButtons != null) { - this._showFirstLastButtons = showFirstLastButtons; + this.showFirstLastButtons = showFirstLastButtons; } } diff --git a/src/material/progress-bar/progress-bar.ts b/src/material/progress-bar/progress-bar.ts index 5e2345807194..33f6c563cc5f 100644 --- a/src/material/progress-bar/progress-bar.ts +++ b/src/material/progress-bar/progress-bar.ts @@ -22,11 +22,11 @@ import { ChangeDetectorRef, InjectionToken, inject, + numberAttribute, } from '@angular/core'; import {DOCUMENT} from '@angular/common'; -import {CanColor, mixinColor, ThemePalette} from '@angular/material/core'; +import {ThemePalette} from '@angular/material/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; -import {coerceNumberProperty, NumberInput} from '@angular/cdk/coercion'; /** Last animation end data. */ export interface ProgressAnimationEnd { @@ -77,15 +77,6 @@ export function MAT_PROGRESS_BAR_LOCATION_FACTORY(): MatProgressBarLocation { }; } -// Boilerplate for applying mixins to MatProgressBar. -/** @docs-private */ -const _MatProgressBarBase = mixinColor( - class { - constructor(public _elementRef: ElementRef) {} - }, - 'primary', -); - export type ProgressBarMode = 'determinate' | 'indeterminate' | 'buffer' | 'query'; @Component({ @@ -101,22 +92,19 @@ export type ProgressBarMode = 'determinate' | 'indeterminate' | 'buffer' | 'quer '[attr.aria-valuenow]': '_isIndeterminate() ? null : value', '[attr.mode]': 'mode', 'class': 'mat-mdc-progress-bar mdc-linear-progress', + '[class]': '"mat-" + color', '[class._mat-animation-noopable]': '_isNoopAnimation', '[class.mdc-linear-progress--animation-ready]': '!_isNoopAnimation', '[class.mdc-linear-progress--indeterminate]': '_isIndeterminate()', }, - inputs: ['color'], templateUrl: 'progress-bar.html', styleUrls: ['progress-bar.css'], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class MatProgressBar - extends _MatProgressBarBase - implements AfterViewInit, OnDestroy, CanColor -{ +export class MatProgressBar implements AfterViewInit, OnDestroy { constructor( - elementRef: ElementRef, + readonly _elementRef: ElementRef, private _ngZone: NgZone, private _changeDetectorRef: ChangeDetectorRef, @Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string, @@ -124,12 +112,11 @@ export class MatProgressBar @Inject(MAT_PROGRESS_BAR_DEFAULT_OPTIONS) defaults?: MatProgressBarDefaultOptions, ) { - super(elementRef); this._isNoopAnimation = _animationMode === 'NoopAnimations'; if (defaults) { if (defaults.color) { - this.color = this.defaultColor = defaults.color; + this.color = this._defaultColor = defaults.color; } this.mode = defaults.mode || this.mode; @@ -139,24 +126,36 @@ export class MatProgressBar /** Flag that indicates whether NoopAnimations mode is set to true. */ _isNoopAnimation = false; - /** Value of the progress bar. Defaults to zero. Mirrored to aria-valuenow. */ + // TODO: should be typed as `ThemePalette` but internal apps pass in arbitrary strings. + /** Theme palette color of the progress bar. */ @Input() + get color() { + return this._color || this._defaultColor; + } + set color(value: string | null | undefined) { + this._color = value; + } + private _color: string | null | undefined; + private _defaultColor: ThemePalette = 'primary'; + + /** Value of the progress bar. Defaults to zero. Mirrored to aria-valuenow. */ + @Input({transform: numberAttribute}) get value(): number { return this._value; } - set value(v: NumberInput) { - this._value = clamp(coerceNumberProperty(v)); + set value(v: number) { + this._value = clamp(v || 0); this._changeDetectorRef.markForCheck(); } private _value = 0; /** Buffer value of the progress bar. Defaults to zero. */ - @Input() + @Input({transform: numberAttribute}) get bufferValue(): number { return this._bufferValue || 0; } - set bufferValue(v: NumberInput) { - this._bufferValue = clamp(coerceNumberProperty(v)); + set bufferValue(v: number) { + this._bufferValue = clamp(v || 0); this._changeDetectorRef.markForCheck(); } private _bufferValue = 0; diff --git a/src/material/progress-spinner/progress-spinner.spec.ts b/src/material/progress-spinner/progress-spinner.spec.ts index c17934f8c29b..6b93ca5d7f5f 100644 --- a/src/material/progress-spinner/progress-spinner.spec.ts +++ b/src/material/progress-spinner/progress-spinner.spec.ts @@ -462,9 +462,11 @@ class IndeterminateSpinnerInShadowDom { @Component({ template: ` -
    - -
    + @if (true) { +
    + +
    + } `, encapsulation: ViewEncapsulation.ShadowDom, }) diff --git a/src/material/progress-spinner/progress-spinner.ts b/src/material/progress-spinner/progress-spinner.ts index 3c9d2774a2cf..4066fb9e04c6 100644 --- a/src/material/progress-spinner/progress-spinner.ts +++ b/src/material/progress-spinner/progress-spinner.ts @@ -16,18 +16,10 @@ import { Optional, ViewChild, ViewEncapsulation, + numberAttribute, } from '@angular/core'; -import {CanColor, mixinColor, ThemePalette} from '@angular/material/core'; +import {ThemePalette} from '@angular/material/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; -import {coerceNumberProperty, NumberInput} from '@angular/cdk/coercion'; - -// Boilerplate for applying mixins to MatProgressBar. -const _MatProgressSpinnerBase = mixinColor( - class { - constructor(public _elementRef: ElementRef) {} - }, - 'primary', -); /** Possible mode for a progress spinner. */ export type ProgressSpinnerMode = 'determinate' | 'indeterminate'; @@ -78,6 +70,7 @@ const BASE_STROKE_WIDTH = 10; // set tab index to -1 so screen readers will read the aria-label // Note: there is a known issue with JAWS that does not read progressbar aria labels on FireFox 'tabindex': '-1', + '[class]': '"mat-" + color', '[class._mat-animation-noopable]': `_noopAnimations`, '[class.mdc-circular-progress--indeterminate]': 'mode === "indeterminate"', '[style.width.px]': 'diameter', @@ -89,32 +82,46 @@ const BASE_STROKE_WIDTH = 10; '[attr.aria-valuenow]': 'mode === "determinate" ? value : null', '[attr.mode]': 'mode', }, - inputs: ['color'], templateUrl: 'progress-spinner.html', styleUrls: ['progress-spinner.css'], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class MatProgressSpinner extends _MatProgressSpinnerBase implements CanColor { +export class MatProgressSpinner { /** Whether the _mat-animation-noopable class should be applied, disabling animations. */ _noopAnimations: boolean; + // TODO: should be typed as `ThemePalette` but internal apps pass in arbitrary strings. + /** Theme palette color of the progress spinner. */ + @Input() + get color() { + return this._color || this._defaultColor; + } + set color(value: string | null | undefined) { + this._color = value; + } + private _color: string | null | undefined; + private _defaultColor: ThemePalette = 'primary'; + /** The element of the determinate spinner. */ @ViewChild('determinateSpinner') _determinateCircle: ElementRef; constructor( - elementRef: ElementRef, + readonly _elementRef: ElementRef, @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode: string, @Inject(MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS) defaults?: MatProgressSpinnerDefaultOptions, ) { - super(elementRef); this._noopAnimations = animationMode === 'NoopAnimations' && !!defaults && !defaults._forceAnimations; + this.mode = + _elementRef.nativeElement.nodeName.toLowerCase() === 'mat-spinner' + ? 'indeterminate' + : 'determinate'; if (defaults) { if (defaults.color) { - this.color = this.defaultColor = defaults.color; + this.color = this._defaultColor = defaults.color; } if (defaults.diameter) { @@ -134,38 +141,35 @@ export class MatProgressSpinner extends _MatProgressSpinnerBase implements CanCo * 'determinate'. * Mirrored to mode attribute. */ - @Input() mode: ProgressSpinnerMode = - this._elementRef.nativeElement.nodeName.toLowerCase() === 'mat-spinner' - ? 'indeterminate' - : 'determinate'; + @Input() mode: ProgressSpinnerMode; /** Value of the progress bar. Defaults to zero. Mirrored to aria-valuenow. */ - @Input() + @Input({transform: numberAttribute}) get value(): number { return this.mode === 'determinate' ? this._value : 0; } - set value(v: NumberInput) { - this._value = Math.max(0, Math.min(100, coerceNumberProperty(v))); + set value(v: number) { + this._value = Math.max(0, Math.min(100, v || 0)); } private _value = 0; /** The diameter of the progress spinner (will set width and height of svg). */ - @Input() + @Input({transform: numberAttribute}) get diameter(): number { return this._diameter; } - set diameter(size: NumberInput) { - this._diameter = coerceNumberProperty(size); + set diameter(size: number) { + this._diameter = size || 0; } private _diameter = BASE_SIZE; /** Stroke width of the progress spinner. */ - @Input() + @Input({transform: numberAttribute}) get strokeWidth(): number { return this._strokeWidth ?? this.diameter / 10; } - set strokeWidth(value: NumberInput) { - this._strokeWidth = coerceNumberProperty(value); + set strokeWidth(value: number) { + this._strokeWidth = value || 0; } private _strokeWidth: number; diff --git a/src/material/radio/BUILD.bazel b/src/material/radio/BUILD.bazel index 8dad77dc6441..35fb284f12b8 100644 --- a/src/material/radio/BUILD.bazel +++ b/src/material/radio/BUILD.bazel @@ -19,7 +19,6 @@ ng_module( assets = [":radio_scss"] + glob(["**/*.html"]), deps = [ "//src/cdk/a11y", - "//src/cdk/coercion", "//src/cdk/collections", "//src/material/core", "@npm//@angular/forms", diff --git a/src/material/radio/radio.spec.ts b/src/material/radio/radio.spec.ts index 1e32fc0f1cad..02b8d1e9ba41 100644 --- a/src/material/radio/radio.spec.ts +++ b/src/material/radio/radio.spec.ts @@ -79,7 +79,7 @@ describe('MDC-based MatRadio', () => { }); it('should coerce the disabled binding on the radio group', () => { - (groupInstance as any).disabled = ''; + (testComponent as any).isGroupDisabled = ''; fixture.detectChanges(); radioLabelElements[0].click(); @@ -1007,10 +1007,12 @@ describe('MatRadioDefaultOverrides', () => { [required]="isGroupRequired" [value]="groupValue" name="test-name"> - - Charmander - + @if (isFirstShown) { + + Charmander + + } Squirtle @@ -1073,9 +1075,9 @@ class StandaloneRadioButtons { @Component({ template: ` - - {{option.label}} - + @for (option of options; track option) { + {{option.label}} + } `, }) @@ -1125,9 +1127,11 @@ class FocusableRadioButton { @Component({ template: ` - - {{option.label}} - + @for (option of options; track option) { + + {{option.label}} + + } `, }) @@ -1176,15 +1180,16 @@ class RadioButtonWithPredefinedAriaAttributes {} // Note that this is somewhat of a contrived template, but it is required to // reproduce the issue. It was taken for a specific user report at #25831. template: ` - + @if (true) { - - + } - + @if (true) { + + } `, }) diff --git a/src/material/radio/radio.ts b/src/material/radio/radio.ts index e97a40d42d20..ebf157565694 100644 --- a/src/material/radio/radio.ts +++ b/src/material/radio/radio.ts @@ -10,6 +10,7 @@ import { AfterContentInit, AfterViewInit, Attribute, + booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -22,6 +23,7 @@ import { Inject, InjectionToken, Input, + numberAttribute, OnDestroy, OnInit, Optional, @@ -30,15 +32,8 @@ import { ViewChild, ViewEncapsulation, } from '@angular/core'; -import { - CanDisableRipple, - HasTabIndex, - mixinDisableRipple, - mixinTabIndex, - ThemePalette, -} from '@angular/material/core'; +import {ThemePalette} from '@angular/material/core'; import {FocusMonitor, FocusOrigin} from '@angular/cdk/a11y'; -import {BooleanInput, coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion'; import {UniqueSelectionDispatcher} from '@angular/cdk/collections'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; @@ -217,22 +212,22 @@ export class MatRadioGroup implements AfterContentInit, OnDestroy, ControlValueA } /** Whether the radio group is disabled */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return this._disabled; } - set disabled(value: BooleanInput) { - this._disabled = coerceBooleanProperty(value); + set disabled(value: boolean) { + this._disabled = value; this._markRadiosForCheck(); } /** Whether the radio group is required */ - @Input() + @Input({transform: booleanAttribute}) get required(): boolean { return this._required; } - set required(value: BooleanInput) { - this._required = coerceBooleanProperty(value); + set required(value: boolean) { + this._required = value; this._markRadiosForCheck(); } @@ -348,18 +343,6 @@ export class MatRadioGroup implements AfterContentInit, OnDestroy, ControlValueA } } -// Boilerplate for applying mixins to MatRadioButton. -/** @docs-private */ -abstract class MatRadioButtonBase { - // Since the disabled property is manually defined for the MatRadioButton and isn't set up in - // the mixin base class. To be able to use the tabindex mixin, a disabled property must be - // defined to properly work. - abstract disabled: boolean; - constructor(public _elementRef: ElementRef) {} -} - -const _MatRadioButtonMixinBase = mixinDisableRipple(mixinTabIndex(MatRadioButtonBase)); - @Component({ selector: 'mat-radio-button', templateUrl: 'radio.html', @@ -382,15 +365,11 @@ const _MatRadioButtonMixinBase = mixinDisableRipple(mixinTabIndex(MatRadioButton // the focus to the native element. '(focus)': '_inputElement.nativeElement.focus()', }, - inputs: ['disableRipple', 'tabIndex'], exportAs: 'matRadioButton', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatRadioButton - extends _MatRadioButtonMixinBase - implements OnInit, AfterViewInit, DoCheck, OnDestroy, CanDisableRipple, HasTabIndex -{ +export class MatRadioButton implements OnInit, AfterViewInit, DoCheck, OnDestroy { private _uniqueId: string = `mat-radio-${++nextUniqueId}`; /** The unique ID for the radio button. */ @@ -408,24 +387,33 @@ export class MatRadioButton /** The 'aria-describedby' attribute is read after the element's label and field type. */ @Input('aria-describedby') ariaDescribedby: string; + /** Whether ripples are disabled inside the radio button */ + @Input({transform: booleanAttribute}) + disableRipple: boolean = false; + + /** Tabindex of the radio button. */ + @Input({ + transform: (value: unknown) => (value == null ? 0 : numberAttribute(value)), + }) + tabIndex: number = 0; + /** Whether this radio button is checked. */ - @Input() + @Input({transform: booleanAttribute}) get checked(): boolean { return this._checked; } - set checked(value: BooleanInput) { - const newCheckedState = coerceBooleanProperty(value); - if (this._checked !== newCheckedState) { - this._checked = newCheckedState; - if (newCheckedState && this.radioGroup && this.radioGroup.value !== this.value) { + set checked(value: boolean) { + if (this._checked !== value) { + this._checked = value; + if (value && this.radioGroup && this.radioGroup.value !== this.value) { this.radioGroup.selected = this; - } else if (!newCheckedState && this.radioGroup && this.radioGroup.value === this.value) { + } else if (!value && this.radioGroup && this.radioGroup.value === this.value) { // When unchecking the selected radio button, update the selected radio // property on the group. this.radioGroup.selected = null; } - if (newCheckedState) { + if (value) { // Notify all radio buttons with the same name to un-check. this._radioDispatcher.notify(this.id, this.name); } @@ -464,21 +452,21 @@ export class MatRadioButton private _labelPosition: 'before' | 'after'; /** Whether the radio button is disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return this._disabled || (this.radioGroup !== null && this.radioGroup.disabled); } - set disabled(value: BooleanInput) { - this._setDisabled(coerceBooleanProperty(value)); + set disabled(value: boolean) { + this._setDisabled(value); } /** Whether the radio button is required. */ - @Input() + @Input({transform: booleanAttribute}) get required(): boolean { return this._required || (this.radioGroup && this.radioGroup.required); } - set required(value: BooleanInput) { - this._required = coerceBooleanProperty(value); + set required(value: boolean) { + this._required = value; } /** Theme color of the radio button. */ @@ -539,7 +527,7 @@ export class MatRadioButton constructor( @Optional() @Inject(MAT_RADIO_GROUP) radioGroup: MatRadioGroup, - elementRef: ElementRef, + protected _elementRef: ElementRef, private _changeDetector: ChangeDetectorRef, private _focusMonitor: FocusMonitor, private _radioDispatcher: UniqueSelectionDispatcher, @@ -549,15 +537,13 @@ export class MatRadioButton private _providerOverride?: MatRadioDefaultOptions, @Attribute('tabindex') tabIndex?: string, ) { - super(elementRef); - // Assertions. Ideally these should be stripped out by the compiler. // TODO(jelbourn): Assert that there's no name binding AND a parent radio group. this.radioGroup = radioGroup; this._noopAnimations = animationMode === 'NoopAnimations'; if (tabIndex) { - this.tabIndex = coerceNumberProperty(tabIndex, 0); + this.tabIndex = numberAttribute(tabIndex, 0); } } diff --git a/src/material/radio/testing/radio-harness.spec.ts b/src/material/radio/testing/radio-harness.spec.ts index fc933aa27787..ad19f356e1e2 100644 --- a/src/material/radio/testing/radio-harness.spec.ts +++ b/src/material/radio/testing/radio-harness.spec.ts @@ -185,18 +185,16 @@ describe('radio harness', () => { }); it('should get label text', async () => { - const [firstRadio, secondRadio, thirdRadio] = await loader.getAllHarnesses( - MatRadioButtonHarness, - ); + const [firstRadio, secondRadio, thirdRadio] = + await loader.getAllHarnesses(MatRadioButtonHarness); expect(await firstRadio.getLabelText()).toBe('Option #1'); expect(await secondRadio.getLabelText()).toBe('Option #2'); expect(await thirdRadio.getLabelText()).toBe('Option #3'); }); it('should get value', async () => { - const [firstRadio, secondRadio, thirdRadio] = await loader.getAllHarnesses( - MatRadioButtonHarness, - ); + const [firstRadio, secondRadio, thirdRadio] = + await loader.getAllHarnesses(MatRadioButtonHarness); expect(await firstRadio.getValue()).toBe('opt1'); expect(await secondRadio.getValue()).toBe('opt2'); expect(await thirdRadio.getValue()).toBe('opt3'); @@ -264,23 +262,25 @@ describe('radio harness', () => { @Component({ template: ` - - Option #{{i + 1}} - + @for (value of values; track value) { + + Option #{{$index + 1}} + + } - - {{value}} - + @for (value of values; track value) { + {{value}} + } diff --git a/src/material/schematics/migration.json b/src/material/schematics/migration.json index 93326441e6c8..81aa9dfe8b23 100644 --- a/src/material/schematics/migration.json +++ b/src/material/schematics/migration.json @@ -3,7 +3,7 @@ "schematics": { "migration-v17": { "version": "17.0.0-0", - "description": "Updates the Angular Material to v17", + "description": "Updates Angular Material to v17", "factory": "./ng-update/index_bundled#updateToV17" } } diff --git a/src/material/schematics/ng-add/fonts/material-fonts.ts b/src/material/schematics/ng-add/fonts/material-fonts.ts index a66f44b561d7..d1eea87ba76c 100644 --- a/src/material/schematics/ng-add/fonts/material-fonts.ts +++ b/src/material/schematics/ng-add/fonts/material-fonts.ts @@ -26,15 +26,12 @@ export function addFontsToIndex(options: Schema): Rule { throw new SchematicsException('No project index HTML file could be found.'); } - const preconnect = ``; const fonts = [ 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap', 'https://fonts.googleapis.com/icon?family=Material+Icons', ]; projectIndexFiles.forEach(indexFilePath => { - appendHtmlElementToHead(host, indexFilePath, preconnect); - fonts.forEach(font => { appendHtmlElementToHead(host, indexFilePath, ``); }); diff --git a/src/material/schematics/ng-add/index.spec.ts b/src/material/schematics/ng-add/index.spec.ts index 79bde664ad05..f4e0f09f89c0 100644 --- a/src/material/schematics/ng-add/index.spec.ts +++ b/src/material/schematics/ng-add/index.spec.ts @@ -162,7 +162,6 @@ describe('ng-add schematic', () => { // Ensure that the indentation has been determined properly. We want to make sure that // the created links properly align with the existing HTML. Default CLI projects use an // indentation of two columns. - expect(htmlContent).toContain(' '); expect(htmlContent).toContain( ' { .toContain('BrowserAnimationsModule'); }); }); + + describe('using browser-esbuild builder', () => { + beforeEach(() => { + const config = { + version: 1, + projects: { + material: { + projectType: 'application', + root: 'projects/material', + sourceRoot: 'projects/material/src', + prefix: 'app', + architect: { + build: { + builder: '@angular-devkit/build-angular:browser-esbuild', + options: { + outputPath: 'dist/material', + index: 'projects/material/src/index.html', + main: 'projects/material/src/main.ts', + styles: ['projects/material/src/styles.css'], + }, + }, + test: { + builder: '@angular-devkit/build-angular:karma', + options: { + outputPath: 'dist/material', + index: 'projects/material/src/index.html', + browser: 'projects/material/src/main.ts', + styles: ['projects/material/src/styles.css'], + }, + }, + }, + }, + }, + }; + + appTree.overwrite('/angular.json', JSON.stringify(config, null, 2)); + }); + + it('should add a theme', async () => { + const tree = await runner.runSchematic('ng-add-setup-project', baseOptions, appTree); + const workspace = await getWorkspace(tree); + const project = getProjectFromWorkspace(workspace, baseOptions.project); + + expectProjectStyleFile(project, '@angular/material/prebuilt-themes/indigo-pink.css'); + }); + + it('should add material app styles', async () => { + const tree = await runner.runSchematic('ng-add-setup-project', baseOptions, appTree); + const workspace = await getWorkspace(tree); + const project = getProjectFromWorkspace(workspace, baseOptions.project); + + const defaultStylesPath = getProjectStyleFile(project)!; + const htmlContent = tree.read(defaultStylesPath)!.toString(); + + expect(htmlContent).toContain('html, body { height: 100%; }'); + expect(htmlContent).toContain( + 'body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }', + ); + }); + + it('should add the BrowserAnimationsModule to the project module', async () => { + const tree = await runner.runSchematic('ng-add-setup-project', baseOptions, appTree); + const fileContent = getFileContent(tree, '/projects/material/src/app/app.module.ts'); + + expect(fileContent) + .withContext('Expected the project app module to import the "BrowserAnimationsModule".') + .toContain('BrowserAnimationsModule'); + }); + }); }); describe('ng-add schematic - library project', () => { diff --git a/src/material/schematics/ng-generate/mdc-migration/rules/components/slider/slider-template.ts b/src/material/schematics/ng-generate/mdc-migration/rules/components/slider/slider-template.ts index 47ac87af2beb..122946862cfe 100644 --- a/src/material/schematics/ng-generate/mdc-migration/rules/components/slider/slider-template.ts +++ b/src/material/schematics/ng-generate/mdc-migration/rules/components/slider/slider-template.ts @@ -24,7 +24,7 @@ interface Binding { } /** Describes the different types of bindings we care about. */ -const enum BindingType { +enum BindingType { INPUT, OUTPUT, ATTRIBUTE, diff --git a/src/material/schematics/ng-generate/navigation/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts.template b/src/material/schematics/ng-generate/navigation/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts.template index 12d6ffa84894..ef92c499263b 100644 --- a/src/material/schematics/ng-generate/navigation/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts.template +++ b/src/material/schematics/ng-generate/navigation/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts.template @@ -7,6 +7,7 @@ import { MatListModule } from '@angular/material/list'; import { MatIconModule } from '@angular/material/icon';<% } %> import { Observable } from 'rxjs'; import { map, shareReplay } from 'rxjs/operators'; +import { AsyncPipe, NgIf } from '@angular/common'; @Component({ selector: '<%= selector %>',<% if(inlineTemplate) { %> @@ -26,7 +27,9 @@ import { map, shareReplay } from 'rxjs/operators'; MatButtonModule, MatSidenavModule, MatListModule, - MatIconModule + MatIconModule, + AsyncPipe, + NgIf ]<% } %> }) export class <%= classify(name) %>Component { diff --git a/src/material/schematics/ng-update/BUILD.bazel b/src/material/schematics/ng-update/BUILD.bazel index ed3caabf009a..7f0c2a4ecbd0 100644 --- a/src/material/schematics/ng-update/BUILD.bazel +++ b/src/material/schematics/ng-update/BUILD.bazel @@ -69,6 +69,7 @@ ts_library( "//src/cdk/schematics", "//src/cdk/schematics/testing", "//src/material/schematics:paths", + "@npm//@angular-devkit/core", "@npm//@angular-devkit/schematics", "@npm//@bazel/runfiles", "@npm//@types/jasmine", diff --git a/src/material/schematics/ng-update/index.ts b/src/material/schematics/ng-update/index.ts index 91d843c39012..f536c5b5473e 100644 --- a/src/material/schematics/ng-update/index.ts +++ b/src/material/schematics/ng-update/index.ts @@ -13,6 +13,7 @@ import { TargetVersion, } from '@angular/cdk/schematics'; +import {legacyImportsError} from './migrations/legacy-imports-error'; import {materialUpgradeData} from './upgrade-data'; import {ThemeBaseMigration} from './migrations/theme-base-v17'; @@ -20,11 +21,16 @@ const materialMigrations: NullableDevkitMigration[] = [ThemeBaseMigration]; /** Entry point for the migration schematics with target of Angular Material v17 */ export function updateToV17(): Rule { - return createMigrationSchematicRule( - TargetVersion.V17, - materialMigrations, - materialUpgradeData, - onMigrationComplete, + // We pass the v17 migration rule as a callback, instead of using `chain()`, because the + // legacy imports error only logs an error message, it doesn't actually interrupt the migration + // process and we don't want to execute migrations if there are leftover legacy imports. + return legacyImportsError( + createMigrationSchematicRule( + TargetVersion.V17, + materialMigrations, + materialUpgradeData, + onMigrationComplete, + ), ); } diff --git a/src/material/schematics/ng-update/migrations/legacy-imports-error.ts b/src/material/schematics/ng-update/migrations/legacy-imports-error.ts new file mode 100644 index 000000000000..719a7fd6fe5d --- /dev/null +++ b/src/material/schematics/ng-update/migrations/legacy-imports-error.ts @@ -0,0 +1,98 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {Rule, SchematicContext, Tree} from '@angular-devkit/schematics'; +import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks'; +import * as ts from 'typescript'; + +/** String with which legacy imports start. */ +const LEGACY_IMPORTS_START = '@angular/material/legacy-'; + +/** Maximum files to print in the error message. */ +const MAX_FILES_TO_PRINT = 50; + +/** + * "Migration" that logs an error and prevents further migrations + * from running if the project is using legacy components. + * @param onSuccess Rule to run if there are no legacy imports. + */ +export function legacyImportsError(onSuccess: Rule): Rule { + return async (tree: Tree, context: SchematicContext) => { + const filesUsingLegacyImports = new Set(); + + tree.visit(path => { + if (!path.endsWith('.ts')) { + return; + } + + const content = tree.readText(path); + const sourceFile = ts.createSourceFile(path, content, ts.ScriptTarget.Latest); + + sourceFile.forEachChild(function walk(node) { + const isImportOrExport = ts.isImportDeclaration(node) || ts.isExportDeclaration(node); + + if ( + isImportOrExport && + node.moduleSpecifier && + ts.isStringLiteralLike(node.moduleSpecifier) && + node.moduleSpecifier.text.startsWith(LEGACY_IMPORTS_START) + ) { + filesUsingLegacyImports.add(path); + } + + node.forEachChild(walk); + }); + }); + + // If there are no legacy imports left, we can continue with the migrations. + if (filesUsingLegacyImports.size === 0) { + return onSuccess; + } + + // At this point the project is already at v17 so we need to downgrade it back + // to v16 and run `npm install` again. Ideally we would also throw an error here + // to interrupt the update process, but that would interrupt `npm install` as well. + if (tree.exists('package.json')) { + let packageJson: Record | null = null; + + try { + packageJson = JSON.parse(tree.readText('package.json')) as Record; + } catch {} + + if (packageJson !== null && packageJson['dependencies']) { + packageJson['dependencies']['@angular/material'] = '^16.2.0'; + tree.overwrite('package.json', JSON.stringify(packageJson, null, 2)); + context.addTask(new NodePackageInstallTask()); + } + } + + context.logger.fatal(formatErrorMessage(filesUsingLegacyImports)); + return; + }; +} + +function formatErrorMessage(filesUsingLegacyImports: Set): string { + const files = Array.from(filesUsingLegacyImports, path => ' - ' + path); + const filesMessage = + files.length > MAX_FILES_TO_PRINT + ? [ + ...files.slice(0, MAX_FILES_TO_PRINT), + `${files.length - MAX_FILES_TO_PRINT} more...`, + `Search your project for "${LEGACY_IMPORTS_START}" to view all usages.`, + ].join('\n') + : files.join('\n'); + + return ( + `Cannot update to Angular Material v17 because the project is using the legacy ` + + `Material components\nthat have been deleted. While Angular Material v16 is compatible with ` + + `Angular v17, it is recommended\nto switch away from the legacy components as soon as possible ` + + `because they no longer receive bug fixes,\naccessibility improvements and new features.\n\n` + + `Read more about migrating away from legacy components: https://material.angular.io/guide/mdc-migration\n\n` + + `Files in the project using legacy Material components:\n${filesMessage}\n` + ); +} diff --git a/src/material/schematics/ng-update/test-cases/legacy-imports-error.spec.ts b/src/material/schematics/ng-update/test-cases/legacy-imports-error.spec.ts new file mode 100644 index 000000000000..534948c147db --- /dev/null +++ b/src/material/schematics/ng-update/test-cases/legacy-imports-error.spec.ts @@ -0,0 +1,83 @@ +import {createTestCaseSetup} from '@angular/cdk/schematics/testing'; +import {UnitTestTree} from '@angular-devkit/schematics/testing'; +import {logging} from '@angular-devkit/core'; +import {MIGRATION_PATH} from '../../paths'; + +describe('legacy imports error', () => { + const PATH = 'projects/material-testing/'; + let runFixers: () => Promise; + let tree: UnitTestTree; + let writeFile: (path: string, content: string) => void; + let fatalLogs: string[]; + + beforeEach(async () => { + const setup = await createTestCaseSetup('migration-v17', MIGRATION_PATH, []); + runFixers = setup.runFixers; + writeFile = setup.writeFile; + tree = setup.appTree; + fatalLogs = []; + setup.runner.logger.subscribe((entry: logging.LogEntry) => { + if (entry.level === 'fatal') { + fatalLogs.push(entry.message); + } + }); + }); + + afterEach(() => { + runFixers = tree = writeFile = fatalLogs = null!; + }); + + it('should log a fatal message if the app imports a legacy import', async () => { + writeFile( + `${PATH}/src/app/app.module.ts`, + ` + import {NgModule} from '@angular/core'; + import {MatLegacyButtonModule} from '@angular/material/legacy-button'; + + @NgModule({ + imports: [MatLegacyButtonModule], + }) + export class AppModule {} + `, + ); + + await runFixers(); + + expect(fatalLogs.length).toBe(1); + expect(fatalLogs[0]).toContain( + 'Cannot update to Angular Material v17 because the ' + + 'project is using the legacy Material components', + ); + }); + + it('should downgrade the app to v16 if it contains legacy imports', async () => { + writeFile( + `${PATH}/package.json`, + `{ + "name": "test", + "version": "0.0.0", + "dependencies": { + "@angular/material": "^17.0.0" + } + }`, + ); + + writeFile( + `${PATH}/src/app/app.module.ts`, + ` + import {NgModule} from '@angular/core'; + import {MatLegacyButtonModule} from '@angular/material/legacy-button'; + + @NgModule({ + imports: [MatLegacyButtonModule], + }) + export class AppModule {} + `, + ); + + await runFixers(); + + const content = JSON.parse(tree.readText('/package.json')) as Record; + expect(content['dependencies']['@angular/material']).toBe('^16.2.0'); + }); +}); diff --git a/src/material/select/BUILD.bazel b/src/material/select/BUILD.bazel index e38ab9126915..84bafc4507b5 100644 --- a/src/material/select/BUILD.bazel +++ b/src/material/select/BUILD.bazel @@ -23,7 +23,6 @@ ng_module( "//src:dev_mode_types", "//src/cdk/a11y", "//src/cdk/bidi", - "//src/cdk/coercion", "//src/cdk/collections", "//src/cdk/keycodes", "//src/cdk/overlay", diff --git a/src/material/select/select.md b/src/material/select/select.md index a26aab612e28..6169c15faec9 100644 --- a/src/material/select/select.md +++ b/src/material/select/select.md @@ -176,15 +176,18 @@ items. This error is thrown if you attempt to bind the `multiple` property on `` to a dynamic value. (e.g. `[multiple]="isMultiple"` where the value of `isMultiple` changes over the course of -the component's lifetime). If you need to change this dynamically, use `ngIf` or `ngSwitch` instead: +the component's lifetime). If you need to change this dynamically, use `@if` or `@switch` instead: ```html - - ... - - - ... - +@if (isMultiple) { + + ... + +} @else { + + ... + +} ``` #### Error: Value must be an array in multiple-selection mode diff --git a/src/material/select/select.spec.ts b/src/material/select/select.spec.ts index 87fe1e9ae4d8..27f32fc633f8 100644 --- a/src/material/select/select.spec.ts +++ b/src/material/select/select.spec.ts @@ -4575,18 +4575,24 @@ describe('MDC-based MatSelect', () => { template: `
    - Select a food + @if (hasLabel) { + Select a food + } - - {{ capitalize ? food.viewValue.toUpperCase() : food.viewValue }} - + @for (food of foods; track food) { + + {{ capitalize ? food.viewValue.toUpperCase() : food.viewValue }} + + } - {{ hint }} + @if (hint) { + {{ hint }} + }
    `, @@ -4627,9 +4633,9 @@ class BasicSelect { template: ` - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -4668,15 +4674,17 @@ class ManySelects {} @Component({ selector: 'ng-if-select', template: ` -
    - - - - {{ food.viewValue }} - - - -
    + @if (isShowing) { +
    + + + @for (food of foods; track food) { + {{ food.viewValue }} + } + + +
    + } `, }) class NgIfSelect { @@ -4696,7 +4704,9 @@ class NgIfSelect { template: ` - {{ food }} + @for (food of foods; track food) { + {{ food }} + } `, @@ -4721,9 +4731,9 @@ class SelectWithChangeEvent { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -4808,9 +4818,9 @@ class ThrowsErrorOnInit implements OnInit { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -4830,9 +4840,9 @@ class BasicSelectOnPush { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -4853,9 +4863,9 @@ class BasicSelectOnPushPreselected { Select a food - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -4879,9 +4889,9 @@ class FloatLabelSelect { - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -4916,7 +4926,9 @@ class SelectWithPlainTabindex {} -
    + @if (select.selected) { +
    + } `, }) class SelectEarlyAccessSibling {} @@ -4969,9 +4981,9 @@ class BasicSelectWithTheming { Select a food - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } None @@ -4995,9 +5007,9 @@ class ResetValuesSelect { template: ` - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -5016,12 +5028,13 @@ class FalsyValueSelect { template: ` - - - {{ pokemon.viewValue }} - - + @for (group of pokemonTypes; track group) { + + @for (pokemon of group.pokemon; track pokemon) { + {{ pokemon.viewValue }} + } + + } Mr. Mime @@ -5073,11 +5086,13 @@ class SelectWithGroups { template: ` - - - {{ pokemon.viewValue }} - - + @for (group of pokemonTypes; track group) { + + @for (pokemon of group.pokemon; track pokemon) { + {{ pokemon.viewValue }} + } + + } `, @@ -5111,9 +5126,9 @@ class InvalidSelectInForm { Food - - {{option.viewValue}} - + @for (option of options; track option) { + {{option.viewValue}} + } This field is required @@ -5138,9 +5153,9 @@ class SelectInsideFormGroup { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -5160,9 +5175,9 @@ class BasicSelectWithoutForms { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -5181,9 +5196,9 @@ class BasicSelectWithoutFormsPreselected { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -5207,9 +5222,9 @@ class BasicSelectWithoutFormsMultiple { {{ select.selected?.viewValue.split('').reverse().join('') }} - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + }
    `, @@ -5228,7 +5243,9 @@ class SelectWithCustomTrigger { - {{ food.viewValue }} + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -5273,9 +5290,9 @@ class NgModelCompareWithSelect { @Component({ template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, }) @@ -5293,9 +5310,9 @@ class CustomErrorBehaviorSelect { template: ` - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -5318,9 +5335,9 @@ class SingleSelectWithPreselectedArrayValues { template: ` - - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } `, @@ -5361,9 +5378,11 @@ class SelectWithFormFieldLabel { template: ` Select something - - One - + @if (showSelect) { + + One + + } `, }) @@ -5375,7 +5394,9 @@ class SelectWithNgIfAndLabel { template: ` - {{item}} + @for (item of items; track item) { + {{item}} + } `, @@ -5416,13 +5437,13 @@ class SelectWithResetOptionAndFormControl { selector: 'select-with-placeholder-in-ngcontainer-with-ngIf', template: ` - + @if (true) { A B C - + } `, }) @@ -5458,17 +5479,23 @@ class SelectInsideDynamicFormGroup { template: `
    - Select a food + @if (hasLabel) { + Select a food + } - - {{ food.viewValue }} - + @for (food of foods; track food) { + + {{ food.viewValue }} + + } - {{ hint }} + @if (hint) { + {{ hint }} + }
    `, @@ -5512,9 +5539,9 @@ class BasicSelectWithFirstAndLastOptionDisabled { Select a food - {{ food.viewValue }} - + @for (food of foods; track food) { + {{ food.viewValue }} + } diff --git a/src/material/select/select.ts b/src/material/select/select.ts index 0f58027cceb2..1fb059e38736 100644 --- a/src/material/select/select.ts +++ b/src/material/select/select.ts @@ -13,12 +13,6 @@ import { removeAriaReferencedId, } from '@angular/cdk/a11y'; import {Directionality} from '@angular/cdk/bidi'; -import { - BooleanInput, - coerceBooleanProperty, - coerceNumberProperty, - NumberInput, -} from '@angular/cdk/coercion'; import {SelectionModel} from '@angular/cdk/collections'; import { A, @@ -64,6 +58,8 @@ import { SimpleChanges, ViewChild, ViewEncapsulation, + booleanAttribute, + numberAttribute, } from '@angular/core'; import { AbstractControl, @@ -74,20 +70,14 @@ import { Validators, } from '@angular/forms'; import { - CanDisable, - CanDisableRipple, CanUpdateErrorState, ErrorStateMatcher, - HasTabIndex, MatOptgroup, MatOption, MatOptionSelectionChange, MAT_OPTGROUP, MAT_OPTION_PARENT_COMPONENT, - mixinDisabled, - mixinDisableRipple, mixinErrorState, - mixinTabIndex, _countGroupLabelsBeforeOption, _getOptionScrollPosition, } from '@angular/material/core'; @@ -173,34 +163,28 @@ export class MatSelectChange { // Boilerplate for applying mixins to MatSelect. /** @docs-private */ -const _MatSelectMixinBase = mixinDisableRipple( - mixinTabIndex( - mixinDisabled( - mixinErrorState( - class { - /** - * Emits whenever the component state changes and should cause the parent - * form-field to update. Implemented as part of `MatFormFieldControl`. - * @docs-private - */ - readonly stateChanges = new Subject(); - - constructor( - public _elementRef: ElementRef, - public _defaultErrorStateMatcher: ErrorStateMatcher, - public _parentForm: NgForm, - public _parentFormGroup: FormGroupDirective, - /** - * Form control bound to the component. - * Implemented as part of `MatFormFieldControl`. - * @docs-private - */ - public ngControl: NgControl, - ) {} - }, - ), - ), - ), +const _MatSelectMixinBase = mixinErrorState( + class { + /** + * Emits whenever the component state changes and should cause the parent + * form-field to update. Implemented as part of `MatFormFieldControl`. + * @docs-private + */ + readonly stateChanges = new Subject(); + + constructor( + public _elementRef: ElementRef, + public _defaultErrorStateMatcher: ErrorStateMatcher, + public _parentForm: NgForm, + public _parentFormGroup: FormGroupDirective, + /** + * Form control bound to the component. + * Implemented as part of `MatFormFieldControl`. + * @docs-private + */ + public ngControl: NgControl, + ) {} + }, ); @Component({ @@ -208,7 +192,6 @@ const _MatSelectMixinBase = mixinDisableRipple( exportAs: 'matSelect', templateUrl: 'select.html', styleUrls: ['select.css'], - inputs: ['disabled', 'disableRipple', 'tabIndex'], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { @@ -217,7 +200,7 @@ const _MatSelectMixinBase = mixinDisableRipple( 'aria-haspopup': 'listbox', 'class': 'mat-mdc-select', '[attr.id]': 'id', - '[attr.tabindex]': 'tabIndex', + '[attr.tabindex]': 'disabled ? -1 : tabIndex', '[attr.aria-controls]': 'panelOpen ? id + "-panel" : null', '[attr.aria-expanded]': 'panelOpen', '[attr.aria-label]': 'ariaLabel || null', @@ -250,11 +233,8 @@ export class MatSelect OnInit, DoCheck, ControlValueAccessor, - CanDisable, - HasTabIndex, MatFormFieldControl, - CanUpdateErrorState, - CanDisableRipple + CanUpdateErrorState { /** All of the defined select options. */ @ContentChildren(MatOption, {descendants: true}) options: QueryList; @@ -418,13 +398,27 @@ export class MatSelect /** Classes to be passed to the select panel. Supports the same syntax as `ngClass`. */ @Input() panelClass: string | string[] | Set | {[key: string]: any}; + /** Whether the select is disabled. */ + @Input({transform: booleanAttribute}) + disabled: boolean = false; + + /** Whether ripples in the select are disabled. */ + @Input({transform: booleanAttribute}) + disableRipple: boolean = false; + + /** Tab index of the select. */ + @Input({ + transform: (value: unknown) => (value == null ? 0 : numberAttribute(value)), + }) + tabIndex: number = 0; + /** Whether checkmark indicator for single-selection options is hidden. */ - @Input() + @Input({transform: booleanAttribute}) get hideSingleSelectionIndicator(): boolean { return this._hideSingleSelectionIndicator; } - set hideSingleSelectionIndicator(value: BooleanInput) { - this._hideSingleSelectionIndicator = coerceBooleanProperty(value); + set hideSingleSelectionIndicator(value: boolean) { + this._hideSingleSelectionIndicator = value; this._syncParentProperties(); } private _hideSingleSelectionIndicator: boolean = @@ -442,39 +436,33 @@ export class MatSelect private _placeholder: string; /** Whether the component is required. */ - @Input() + @Input({transform: booleanAttribute}) get required(): boolean { return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false; } - set required(value: BooleanInput) { - this._required = coerceBooleanProperty(value); + set required(value: boolean) { + this._required = value; this.stateChanges.next(); } private _required: boolean | undefined; /** Whether the user should be allowed to select multiple options. */ - @Input() + @Input({transform: booleanAttribute}) get multiple(): boolean { return this._multiple; } - set multiple(value: BooleanInput) { + set multiple(value: boolean) { if (this._selectionModel && (typeof ngDevMode === 'undefined' || ngDevMode)) { throw getMatSelectDynamicMultipleError(); } - this._multiple = coerceBooleanProperty(value); + this._multiple = value; } private _multiple: boolean = false; /** Whether to center the active option over the trigger. */ - @Input() - get disableOptionCentering(): boolean { - return this._disableOptionCentering; - } - set disableOptionCentering(value: BooleanInput) { - this._disableOptionCentering = coerceBooleanProperty(value); - } - private _disableOptionCentering = this._defaultOptions?.disableOptionCentering ?? false; + @Input({transform: booleanAttribute}) + disableOptionCentering = this._defaultOptions?.disableOptionCentering ?? false; /** * Function to compare the option values with the selected values. The first argument @@ -520,14 +508,8 @@ export class MatSelect @Input() override errorStateMatcher: ErrorStateMatcher; /** Time to wait in milliseconds after the last keystroke before moving focus to an item. */ - @Input() - get typeaheadDebounceInterval(): number { - return this._typeaheadDebounceInterval; - } - set typeaheadDebounceInterval(value: NumberInput) { - this._typeaheadDebounceInterval = coerceNumberProperty(value); - } - private _typeaheadDebounceInterval: number; + @Input({transform: numberAttribute}) + typeaheadDebounceInterval: number; /** * Function used to sort the values in a select in multiple mode. @@ -624,7 +606,7 @@ export class MatSelect // Note that we only want to set this when the defaults pass it in, otherwise it should // stay as `undefined` so that it falls back to the default in the key manager. if (_defaultOptions?.typeaheadDebounceInterval != null) { - this._typeaheadDebounceInterval = _defaultOptions.typeaheadDebounceInterval; + this.typeaheadDebounceInterval = _defaultOptions.typeaheadDebounceInterval; } this._scrollStrategyFactory = scrollStrategyFactory; @@ -707,14 +689,14 @@ export class MatSelect } ngOnChanges(changes: SimpleChanges) { - // Updating the disabled state is handled by `mixinDisabled`, but we need to additionally let + // Updating the disabled state is handled by the input, but we need to additionally let // the parent form field know to run change detection when the disabled state changes. if (changes['disabled'] || changes['userAriaDescribedBy']) { this.stateChanges.next(); } if (changes['typeaheadDebounceInterval'] && this._keyManager) { - this._keyManager.withTypeAhead(this._typeaheadDebounceInterval); + this._keyManager.withTypeAhead(this.typeaheadDebounceInterval); } } @@ -1181,7 +1163,7 @@ export class MatSelect /** Sets up a key manager to listen to keyboard events on the overlay panel. */ private _initKeyManager() { this._keyManager = new ActiveDescendantKeyManager(this.options) - .withTypeAhead(this._typeaheadDebounceInterval) + .withTypeAhead(this.typeaheadDebounceInterval) .withVerticalOrientation() .withHorizontalOrientation(this._isRtl() ? 'rtl' : 'ltr') .withHomeAndEnd() diff --git a/src/material/select/testing/select-harness.spec.ts b/src/material/select/testing/select-harness.spec.ts index 454da02187e4..c2bb067a24d4 100644 --- a/src/material/select/testing/select-harness.spec.ts +++ b/src/material/select/testing/select-harness.spec.ts @@ -270,26 +270,34 @@ describe('MatSelectHarness', () => { template: ` - {{ state.name }} + @for (state of states; track state) { + {{ state.name }} + } - {{ state.name }} + @for (state of states; track state) { + {{ state.name }} +} - - {{ state.name }} - + @for (group of stateGroups; track group) { + + @for (state of group.states; track state) { + {{ state.name }} + } + + } - {{ state.name }} + @for (state of states; track state) { + {{ state.name }} + } `, diff --git a/src/material/sidenav/drawer.spec.ts b/src/material/sidenav/drawer.spec.ts index 3758567e0f39..480d8ac16531 100644 --- a/src/material/sidenav/drawer.spec.ts +++ b/src/material/sidenav/drawer.spec.ts @@ -1284,7 +1284,9 @@ class DrawerWithoutFocusableElements {} @Component({ template: ` - Drawer + @if (showDrawer) { + Drawer + } `, }) @@ -1296,7 +1298,9 @@ class DrawerDelayed { @Component({ template: ` - + @if (renderDrawer) { + + } `, }) class DrawerContainerStateChangesTestApp { @@ -1336,13 +1340,13 @@ class DrawerContainerWithContent { } @Component({ - // Note that we need the `ng-container` with the `ngSwitch` so that - // there's a directive between the container and the drawer. + // Note that we need the `@if` so that there's an embedded + // view between the container and the drawer. template: ` - + @if (true) { Drawer - + } `, }) class IndirectDescendantDrawer { diff --git a/src/material/sidenav/sidenav.spec.ts b/src/material/sidenav/sidenav.spec.ts index d1d5604178c7..ba0b49b5c34e 100644 --- a/src/material/sidenav/sidenav.spec.ts +++ b/src/material/sidenav/sidenav.spec.ts @@ -105,13 +105,13 @@ class SidenavWithFixedPosition { } @Component({ - // Note that we need the `ng-container` with the `ngSwitch` so that - // there's a directive between the container and the sidenav. + // Note that we need the `@if` so that there's an embedded + // view between the container and the sidenav. template: ` - + @if (true) { Sidenav. - + } Some content. `, }) diff --git a/src/material/slider/BUILD.bazel b/src/material/slider/BUILD.bazel index 0d5421ba57ce..16b78db3bfd4 100644 --- a/src/material/slider/BUILD.bazel +++ b/src/material/slider/BUILD.bazel @@ -24,7 +24,6 @@ ng_module( ] + glob(["**/*.html"]), deps = [ "//src/cdk/bidi", - "//src/cdk/coercion", "//src/cdk/platform", "//src/material/core", "@npm//@angular/forms", diff --git a/src/material/slider/slider-input.ts b/src/material/slider/slider-input.ts index 6657a08c3e6e..be47889bc55e 100644 --- a/src/material/slider/slider-input.ts +++ b/src/material/slider/slider-input.ts @@ -7,12 +7,7 @@ */ import { - BooleanInput, - coerceBooleanProperty, - coerceNumberProperty, - NumberInput, -} from '@angular/cdk/coercion'; -import { + booleanAttribute, ChangeDetectorRef, Directive, ElementRef, @@ -22,6 +17,7 @@ import { Inject, Input, NgZone, + numberAttribute, OnDestroy, Output, } from '@angular/core'; @@ -87,20 +83,21 @@ export const MAT_SLIDER_RANGE_THUMB_VALUE_ACCESSOR: any = { ], }) export class MatSliderThumb implements _MatSliderThumb, OnDestroy, ControlValueAccessor { - @Input() + @Input({transform: numberAttribute}) get value(): number { - return coerceNumberProperty(this._hostElement.value); + return numberAttribute(this._hostElement.value, 0); } - set value(v: NumberInput) { - const val = coerceNumberProperty(v).toString(); + set value(value: number) { + value = isNaN(value) ? 0 : value; + const stringValue = value + ''; if (!this._hasSetInitialValue) { - this._initialValue = val; + this._initialValue = stringValue; return; } if (this._isActive) { return; } - this._hostElement.value = val; + this._hostElement.value = stringValue; this._updateThumbUIByValue(); this._slider._onValueChange(this); this._cdr.detectChanges(); @@ -144,36 +141,36 @@ export class MatSliderThumb implements _MatSliderThumb, OnDestroy, ControlValueA /** @docs-private */ get min(): number { - return coerceNumberProperty(this._hostElement.min); + return numberAttribute(this._hostElement.min, 0); } - set min(v: NumberInput) { - this._hostElement.min = coerceNumberProperty(v).toString(); + set min(v: number) { + this._hostElement.min = v + ''; this._cdr.detectChanges(); } /** @docs-private */ get max(): number { - return coerceNumberProperty(this._hostElement.max); + return numberAttribute(this._hostElement.max, 0); } - set max(v: NumberInput) { - this._hostElement.max = coerceNumberProperty(v).toString(); + set max(v: number) { + this._hostElement.max = v + ''; this._cdr.detectChanges(); } get step(): number { - return coerceNumberProperty(this._hostElement.step); + return numberAttribute(this._hostElement.step, 0); } - set step(v: NumberInput) { - this._hostElement.step = coerceNumberProperty(v).toString(); + set step(v: number) { + this._hostElement.step = v + ''; this._cdr.detectChanges(); } /** @docs-private */ get disabled(): boolean { - return coerceBooleanProperty(this._hostElement.disabled); + return booleanAttribute(this._hostElement.disabled); } - set disabled(v: BooleanInput) { - this._hostElement.disabled = coerceBooleanProperty(v); + set disabled(v: boolean) { + this._hostElement.disabled = v; this._cdr.detectChanges(); if (this._slider.disabled !== this.disabled) { diff --git a/src/material/slider/slider-interface.ts b/src/material/slider/slider-interface.ts index c0b037447942..9eb2f4d1e2e0 100644 --- a/src/material/slider/slider-interface.ts +++ b/src/material/slider/slider-interface.ts @@ -13,13 +13,13 @@ import {MatRipple, RippleGlobalOptions} from '@angular/material/core'; * Thumb types: range slider has two thumbs (START, END) whereas single point * slider only has one thumb (END). */ -export const enum _MatThumb { +export enum _MatThumb { START = 1, END = 2, } /** Tick mark enum, for discrete sliders. */ -export const enum _MatTickMark { +export enum _MatTickMark { ACTIVE = 0, INACTIVE = 1, } diff --git a/src/material/slider/slider.e2e.spec.ts b/src/material/slider/slider.e2e.spec.ts index e7d6fcb45ba0..2590734142ef 100644 --- a/src/material/slider/slider.e2e.spec.ts +++ b/src/material/slider/slider.e2e.spec.ts @@ -168,7 +168,7 @@ async function getCoordsForValue(slider: ElementFinder, value: number): Promise< return {x, y}; } -const enum Thumb { +enum Thumb { START = 1, END = 2, } diff --git a/src/material/slider/slider.ts b/src/material/slider/slider.ts index 5f20ad665dbd..df6d23b1244d 100644 --- a/src/material/slider/slider.ts +++ b/src/material/slider/slider.ts @@ -7,15 +7,10 @@ */ import {Directionality} from '@angular/cdk/bidi'; -import { - BooleanInput, - coerceBooleanProperty, - coerceNumberProperty, - NumberInput, -} from '@angular/cdk/coercion'; import {Platform} from '@angular/cdk/platform'; import { AfterViewInit, + booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -26,6 +21,7 @@ import { Inject, Input, NgZone, + numberAttribute, OnDestroy, Optional, QueryList, @@ -33,13 +29,7 @@ import { ViewChildren, ViewEncapsulation, } from '@angular/core'; -import { - CanDisableRipple, - MAT_RIPPLE_GLOBAL_OPTIONS, - mixinColor, - mixinDisableRipple, - RippleGlobalOptions, -} from '@angular/material/core'; +import {MAT_RIPPLE_GLOBAL_OPTIONS, RippleGlobalOptions, ThemePalette} from '@angular/material/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import {Subscription} from 'rxjs'; import { @@ -60,16 +50,6 @@ import { // 2. tab to disable checkbox // 3. without ending drag, disable the slider -// Boilerplate for applying mixins to MatSlider. -const _MatSliderMixinBase = mixinColor( - mixinDisableRipple( - class { - constructor(public _elementRef: ElementRef) {} - }, - ), - 'primary', -); - /** * Allows users to select from a range of values by moving the slider thumb. It is similar in * behavior to the native `` element. @@ -80,6 +60,7 @@ const _MatSliderMixinBase = mixinColor( styleUrls: ['slider.css'], host: { 'class': 'mat-mdc-slider mdc-slider', + '[class]': '"mat-" + (color || "primary")', '[class.mdc-slider--range]': '_isRange', '[class.mdc-slider--disabled]': 'disabled', '[class.mdc-slider--discrete]': 'discrete', @@ -89,13 +70,9 @@ const _MatSliderMixinBase = mixinColor( exportAs: 'matSlider', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, - inputs: ['color', 'disableRipple'], providers: [{provide: MAT_SLIDER, useExisting: MatSlider}], }) -export class MatSlider - extends _MatSliderMixinBase - implements AfterViewInit, CanDisableRipple, OnDestroy, _MatSlider -{ +export class MatSlider implements AfterViewInit, OnDestroy, _MatSlider { /** The active portion of the slider track. */ @ViewChild('trackActive') _trackActive: ElementRef; @@ -110,12 +87,12 @@ export class MatSlider _inputs: QueryList<_MatSliderRangeThumb>; /** Whether the slider is disabled. */ - @Input() + @Input({transform: booleanAttribute}) get disabled(): boolean { return this._disabled; } - set disabled(v: BooleanInput) { - this._disabled = coerceBooleanProperty(v); + set disabled(v: boolean) { + this._disabled = v; const endInput = this._getInput(_MatThumb.END); const startInput = this._getInput(_MatThumb.START); @@ -129,39 +106,41 @@ export class MatSlider private _disabled: boolean = false; /** Whether the slider displays a numeric value label upon pressing the thumb. */ - @Input() + @Input({transform: booleanAttribute}) get discrete(): boolean { return this._discrete; } - set discrete(v: BooleanInput) { - this._discrete = coerceBooleanProperty(v); + set discrete(v: boolean) { + this._discrete = v; this._updateValueIndicatorUIs(); } private _discrete: boolean = false; /** Whether the slider displays tick marks along the slider track. */ - @Input() - get showTickMarks(): boolean { - return this._showTickMarks; - } - set showTickMarks(v: BooleanInput) { - this._showTickMarks = coerceBooleanProperty(v); - } - private _showTickMarks: boolean = false; + @Input({transform: booleanAttribute}) + showTickMarks: boolean = false; /** The minimum value that the slider can have. */ - @Input() + @Input({transform: numberAttribute}) get min(): number { return this._min; } - set min(v: NumberInput) { - const min = coerceNumberProperty(v, this._min); + set min(v: number) { + const min = isNaN(v) ? this._min : v; if (this._min !== min) { this._updateMin(min); } } private _min: number = 0; + /** Palette color of the slider. */ + @Input() + color: ThemePalette; + + /** Whether ripples are disabled in the slider. */ + @Input({transform: booleanAttribute}) + disableRipple: boolean = false; + private _updateMin(min: number): void { const prevMin = this._min; this._min = min; @@ -212,12 +191,12 @@ export class MatSlider } /** The maximum value that the slider can have. */ - @Input() + @Input({transform: numberAttribute}) get max(): number { return this._max; } - set max(v: NumberInput) { - const max = coerceNumberProperty(v, this._max); + set max(v: number) { + const max = isNaN(v) ? this._max : v; if (this._max !== max) { this._updateMax(max); } @@ -274,12 +253,12 @@ export class MatSlider } /** The values at which the thumb will snap. */ - @Input() + @Input({transform: numberAttribute}) get step(): number { return this._step; } - set step(v: NumberInput) { - const step = coerceNumberProperty(v, this._step); + set step(v: number) { + const step = isNaN(v) ? this._step : v; if (this._step !== step) { this._updateStep(step); } @@ -410,14 +389,13 @@ export class MatSlider constructor( readonly _ngZone: NgZone, readonly _cdr: ChangeDetectorRef, - elementRef: ElementRef, + readonly _elementRef: ElementRef, @Optional() readonly _dir: Directionality, @Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) readonly _globalRippleOptions?: RippleGlobalOptions, @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string, ) { - super(elementRef); this._noopAnimations = animationMode === 'NoopAnimations'; this._dirChangeSubscription = this._dir.change.subscribe(() => this._onDirChange()); this._isRtl = this._dir.value === 'rtl'; diff --git a/src/material/slider/testing/slider-harness-filters.ts b/src/material/slider/testing/slider-harness-filters.ts index b652cf56a26e..118a58d9572d 100644 --- a/src/material/slider/testing/slider-harness-filters.ts +++ b/src/material/slider/testing/slider-harness-filters.ts @@ -8,7 +8,7 @@ import {BaseHarnessFilters} from '@angular/cdk/testing'; /** Possible positions of a slider thumb. */ -export const enum ThumbPosition { +export enum ThumbPosition { START, END, } diff --git a/src/material/snack-bar/snack-bar-container.scss b/src/material/snack-bar/snack-bar-container.scss index cadfc349cbc8..9091b929091c 100644 --- a/src/material/snack-bar/snack-bar-container.scss +++ b/src/material/snack-bar/snack-bar-container.scss @@ -3,6 +3,7 @@ @use '@material/theme/custom-properties' as mdc-custom-properties; @use '../core/tokens/m2/mdc/snack-bar' as tokens-mdc-snack-bar; @use '../core/tokens/m2/mat/snack-bar' as tokens-mat-snack-bar; +@use '../core/tokens/m2/mat/text-button' as tokens-mat-text-button; @use '../core/tokens/token-utils'; @use '../core/mdc-helpers/mdc-helpers'; @@ -67,10 +68,12 @@ } // Darken the ripples in the button so they're visible against the dark background. - --mat-mdc-button-persistent-ripple-color: currentColor; + @include token-utils.create-token-values(tokens-mat-text-button.$prefix, ( + state-layer-color: currentColor, + ripple-color: currentColor, + )); .mat-ripple-element { - background-color: currentColor; opacity: 0.1; } } diff --git a/src/material/snack-bar/snack-bar.spec.ts b/src/material/snack-bar/snack-bar.spec.ts index b04988967c32..53fe0e94b9a6 100644 --- a/src/material/snack-bar/snack-bar.spec.ts +++ b/src/material/snack-bar/snack-bar.spec.ts @@ -1091,7 +1091,7 @@ class DirectiveWithViewContainer { @Component({ selector: 'arbitrary-component', - template: ``, + template: `@if (childComponentExists) {}`, }) class ComponentWithChildViewContainer { @ViewChild(DirectiveWithViewContainer) childWithViewContainer: DirectiveWithViewContainer; diff --git a/src/material/sort/BUILD.bazel b/src/material/sort/BUILD.bazel index 7f568f8f51d6..26cc5662a395 100644 --- a/src/material/sort/BUILD.bazel +++ b/src/material/sort/BUILD.bazel @@ -20,7 +20,6 @@ ng_module( deps = [ "//src:dev_mode_types", "//src/cdk/a11y", - "//src/cdk/coercion", "//src/cdk/keycodes", "//src/material/core", "@npm//@angular/animations", diff --git a/src/material/sort/sort-header.ts b/src/material/sort/sort-header.ts index 2e478e122513..d5dcbcb5e3a6 100644 --- a/src/material/sort/sort-header.ts +++ b/src/material/sort/sort-header.ts @@ -7,7 +7,6 @@ */ import {AriaDescriber, FocusMonitor} from '@angular/cdk/a11y'; -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {ENTER, SPACE} from '@angular/cdk/keycodes'; import { AfterViewInit, @@ -21,8 +20,8 @@ import { OnInit, Optional, ViewEncapsulation, + booleanAttribute, } from '@angular/core'; -import {CanDisable, mixinDisabled} from '@angular/material/core'; import {merge, Subscription} from 'rxjs'; import { MAT_SORT_DEFAULT_OPTIONS, @@ -36,10 +35,6 @@ import {SortDirection} from './sort-direction'; import {getSortHeaderNotContainedWithinSortError} from './sort-errors'; import {MatSortHeaderIntl} from './sort-header-intl'; -// Boilerplate for applying mixins to the sort header. -/** @docs-private */ -const _MatSortHeaderBase = mixinDisabled(class {}); - /** * Valid positions for the arrow to be in for its opacity and translation. If the state is a * sort direction, the position of the arrow will be above/below and opacity 0. If the state is @@ -90,7 +85,6 @@ interface MatSortHeaderColumnDef { }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, - inputs: ['disabled'], animations: [ matSortAnimations.indicator, matSortAnimations.leftPointer, @@ -100,10 +94,7 @@ interface MatSortHeaderColumnDef { matSortAnimations.allowChildren, ], }) -export class MatSortHeader - extends _MatSortHeaderBase - implements CanDisable, MatSortable, OnDestroy, OnInit, AfterViewInit -{ +export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewInit { private _rerenderSubscription: Subscription; /** @@ -145,6 +136,10 @@ export class MatSortHeader /** Overrides the sort start value of the containing MatSort for this MatSortable. */ @Input() start: SortDirection; + /** whether the sort header is disabled. */ + @Input({transform: booleanAttribute}) + disabled: boolean = false; + /** * Description applied to MatSortHeader's button element with aria-describedby. This text should * describe the action that will occur when the user clicks the sort header. @@ -162,14 +157,8 @@ export class MatSortHeader private _sortActionDescription: string = 'Sort'; /** Overrides the disable clear value of the containing MatSort for this MatSortable. */ - @Input() - get disableClear(): boolean { - return this._disableClear; - } - set disableClear(v: BooleanInput) { - this._disableClear = coerceBooleanProperty(v); - } - private _disableClear: boolean; + @Input({transform: booleanAttribute}) + disableClear: boolean; constructor( /** @@ -196,8 +185,6 @@ export class MatSortHeader // `material/table` and `cdk/table` and we can't have the CDK depending on Material, // and we want to avoid having the sort header depending on the CDK table because // of this single reference. - super(); - if (!_sort && (typeof ngDevMode === 'undefined' || ngDevMode)) { throw getSortHeaderNotContainedWithinSortError(); } diff --git a/src/material/sort/sort.ts b/src/material/sort/sort.ts index 36f750370b0a..310f25b9d33a 100644 --- a/src/material/sort/sort.ts +++ b/src/material/sort/sort.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import { Directive, EventEmitter, @@ -18,8 +17,9 @@ import { OnInit, Optional, Output, + booleanAttribute, } from '@angular/core'; -import {CanDisable, HasInitialized, mixinDisabled, mixinInitialized} from '@angular/material/core'; +import {HasInitialized, mixinInitialized} from '@angular/material/core'; import {Subject} from 'rxjs'; import {SortDirection} from './sort-direction'; import { @@ -67,7 +67,7 @@ export const MAT_SORT_DEFAULT_OPTIONS = new InjectionToken(); @@ -119,14 +115,12 @@ export class MatSort * Whether to disable the user from clearing the sort by finishing the sort direction cycle. * May be overridden by the MatSortable's disable clear input. */ - @Input('matSortDisableClear') - get disableClear(): boolean { - return this._disableClear; - } - set disableClear(v: BooleanInput) { - this._disableClear = coerceBooleanProperty(v); - } - private _disableClear: boolean; + @Input({alias: 'matSortDisableClear', transform: booleanAttribute}) + disableClear: boolean; + + /** Whether the sortable is disabled. */ + @Input({alias: 'matSortDisabled', transform: booleanAttribute}) + disabled: boolean = false; /** Event emitted when the user changes either the active sort or sort direction. */ @Output('matSortChange') readonly sortChange: EventEmitter = new EventEmitter(); diff --git a/src/material/sort/testing/sort-harness.spec.ts b/src/material/sort/testing/sort-harness.spec.ts index ee34924a2e26..017765e65758 100644 --- a/src/material/sort/testing/sort-harness.spec.ts +++ b/src/material/sort/testing/sort-harness.spec.ts @@ -127,13 +127,15 @@ describe('MatSortHarness', () => { Protein - - {{dessert.name}} - {{dessert.calories}} - {{dessert.fat}} - {{dessert.carbs}} - {{dessert.protein}} - + @for (dessert of sortedData; track dessert) { + + {{dessert.name}} + {{dessert.calories}} + {{dessert.fat}} + {{dessert.carbs}} + {{dessert.protein}} + + } `, }) diff --git a/src/material/stepper/step-header.ts b/src/material/stepper/step-header.ts index 4e58c5a35cfe..c859d9fd9a37 100644 --- a/src/material/stepper/step-header.ts +++ b/src/material/stepper/step-header.ts @@ -23,35 +23,21 @@ import {MatStepLabel} from './step-label'; import {MatStepperIntl} from './stepper-intl'; import {MatStepperIconContext} from './stepper-icon'; import {CdkStepHeader, StepState} from '@angular/cdk/stepper'; -import {mixinColor, CanColor} from '@angular/material/core'; - -// Boilerplate for applying mixins to MatStepHeader. -/** @docs-private */ -const _MatStepHeaderBase = mixinColor( - class MatStepHeaderBase extends CdkStepHeader { - constructor(elementRef: ElementRef) { - super(elementRef); - } - }, - 'primary', -); +import {ThemePalette} from '@angular/material/core'; @Component({ selector: 'mat-step-header', templateUrl: 'step-header.html', styleUrls: ['step-header.css'], - inputs: ['color'], host: { 'class': 'mat-step-header', + '[class]': '"mat-" + (color || "primary")', 'role': 'tab', }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatStepHeader - extends _MatStepHeaderBase - implements AfterViewInit, OnDestroy, CanColor -{ +export class MatStepHeader extends CdkStepHeader implements AfterViewInit, OnDestroy { private _intlSubscription: Subscription; /** State of the given step. */ @@ -81,6 +67,9 @@ export class MatStepHeader /** Whether the ripple should be disabled. */ @Input() disableRipple: boolean; + /** Theme palette color of the step header. */ + @Input() color: ThemePalette; + constructor( public _intl: MatStepperIntl, private _focusMonitor: FocusMonitor, diff --git a/src/material/stepper/stepper.spec.ts b/src/material/stepper/stepper.spec.ts index ac8fcefb6a69..5e33dc892298 100644 --- a/src/material/stepper/stepper.spec.ts +++ b/src/material/stepper/stepper.spec.ts @@ -1894,14 +1894,16 @@ class SimpleMatHorizontalStepperApp {
    - - Step 2 - Content 2 -
    - - -
    -
    + @if (showStepTwo) { + + Step 2 + Content 2 +
    + + +
    +
    + } Content 3
    @@ -1988,10 +1990,9 @@ class SimplePreselectedMatHorizontalStepperApp { @Component({ template: ` - + @for (step of steps; track step) { + + } `, }) @@ -2006,11 +2007,12 @@ class SimpleStepperWithoutStepControl { @Component({ template: ` - + @for (step of steps; track step) { + + } `, }) @@ -2058,13 +2060,13 @@ class IconOverridesStepper { @Component({ template: ` - + @if (true) { Custom edit Custom done {{getRomanNumeral(index + 1)}} - + } Content 1 Content 2 @@ -2103,11 +2105,11 @@ class StepperWithAriaInputs { @Component({ template: ` - + @if (true) { Content 1 Content 2 Content 3 - + } `, }) @@ -2120,9 +2122,11 @@ class StepperWithIndirectDescendantSteps {} Step 1 - - Step 2 - + @if (showStep2) { + + Step 2 + + } `, }) @@ -2187,7 +2191,9 @@ class StepperWithLazyContent { template: ` Content 1 - Content 2 + @if (renderSecondStep) { + Content 2 + } Content 3 `, diff --git a/src/material/stepper/testing/step-harness-filters.ts b/src/material/stepper/testing/step-harness-filters.ts index 7b67c56e8bca..f13034f32c45 100644 --- a/src/material/stepper/testing/step-harness-filters.ts +++ b/src/material/stepper/testing/step-harness-filters.ts @@ -8,7 +8,7 @@ import {BaseHarnessFilters} from '@angular/cdk/testing'; /** Possible orientations for a stepper. */ -export const enum StepperOrientation { +export enum StepperOrientation { HORIZONTAL, VERTICAL, } diff --git a/src/material/tabs/paginated-tab-header.ts b/src/material/tabs/paginated-tab-header.ts index 934d3668028b..f18239dd0786 100644 --- a/src/material/tabs/paginated-tab-header.ts +++ b/src/material/tabs/paginated-tab-header.ts @@ -20,14 +20,10 @@ import { Directive, Inject, Input, + booleanAttribute, + numberAttribute, } from '@angular/core'; import {Direction, Directionality} from '@angular/cdk/bidi'; -import { - BooleanInput, - coerceBooleanProperty, - coerceNumberProperty, - NumberInput, -} from '@angular/cdk/coercion'; import {ViewportRuler} from '@angular/cdk/scrolling'; import {FocusKeyManager, FocusableOption} from '@angular/cdk/a11y'; import {ENTER, SPACE, hasModifierKey} from '@angular/cdk/keycodes'; @@ -128,21 +124,15 @@ export abstract class MatPaginatedTabHeader * Whether pagination should be disabled. This can be used to avoid unnecessary * layout recalculations if it's known that pagination won't be required. */ - @Input() - get disablePagination(): boolean { - return this._disablePagination; - } - set disablePagination(value: BooleanInput) { - this._disablePagination = coerceBooleanProperty(value); - } - private _disablePagination: boolean = false; + @Input({transform: booleanAttribute}) + disablePagination: boolean = false; /** The index of the active tab. */ get selectedIndex(): number { return this._selectedIndex; } - set selectedIndex(value: NumberInput) { - value = coerceNumberProperty(value); + set selectedIndex(v: unknown) { + const value = numberAttribute(v, 0); if (this._selectedIndex != value) { this._selectedIndexChanged = true; diff --git a/src/material/tabs/tab-group.spec.ts b/src/material/tabs/tab-group.spec.ts index 31b468ec456a..a392c10ded1f 100644 --- a/src/material/tabs/tab-group.spec.ts +++ b/src/material/tabs/tab-group.spec.ts @@ -1158,10 +1158,12 @@ class SimpleTabsTestApp { (focusChange)="handleFocus($event)" (selectedTabChange)="handleSelection($event)" [disablePagination]="disablePagination"> - - {{tab.label}} - {{tab.content}} - + @for (tab of tabs; track tab) { + + {{tab.label}} + {{tab.content}} + + } `, }) @@ -1186,9 +1188,9 @@ class SimpleDynamicTabsTestApp { @Component({ template: ` - - {{tab.content}} - + @for (tab of tabs; track tab) { + {{tab.content}} + } `, }) @@ -1234,10 +1236,12 @@ class DisabledTabsTestApp { @Component({ template: ` - - {{ tab.label }} - {{ tab.content }} - + @for (tab of tabs | async; track tab) { + + {{ tab.label }} + {{ tab.content }} + + } `, }) @@ -1327,7 +1331,9 @@ class TabGroupWithAriaInputs { Broccoli, spinach -
    pizza is active
    + @if (pizza.isActive) { +
    pizza is active
    + } `, }) class TabGroupWithIsActiveBinding {} @@ -1345,10 +1351,10 @@ class TabsWithCustomAnimationDuration {} @Component({ template: ` - + @if (true) { Tab one content Tab two content - + } `, }) diff --git a/src/material/tabs/tab-group.ts b/src/material/tabs/tab-group.ts index da919665fbf0..51a0dcad50d3 100644 --- a/src/material/tabs/tab-group.ts +++ b/src/material/tabs/tab-group.ts @@ -23,23 +23,13 @@ import { QueryList, ViewChild, ViewEncapsulation, + booleanAttribute, + numberAttribute, } from '@angular/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import {MAT_TAB_GROUP, MatTab} from './tab'; import {MatTabHeader} from './tab-header'; -import { - BooleanInput, - coerceBooleanProperty, - coerceNumberProperty, - NumberInput, -} from '@angular/cdk/coercion'; -import { - CanColor, - CanDisableRipple, - mixinColor, - mixinDisableRipple, - ThemePalette, -} from '@angular/material/core'; +import {ThemePalette} from '@angular/material/core'; import {merge, Subscription} from 'rxjs'; import {MAT_TABS_CONFIG, MatTabsConfig} from './tab-config'; import {startWith} from 'rxjs/operators'; @@ -48,17 +38,6 @@ import {FocusOrigin} from '@angular/cdk/a11y'; /** Used to generate unique ID's for each tab component */ let nextId = 0; -// Boilerplate for applying mixins to MatTabGroup. -/** @docs-private */ -const _MatTabGroupMixinBase = mixinColor( - mixinDisableRipple( - class { - constructor(public _elementRef: ElementRef) {} - }, - ), - 'primary', -); - /** @docs-private */ export interface MatTabGroupBaseHeader { _alignInkBarToSelectedTab(): void; @@ -82,7 +61,6 @@ export type MatTabHeaderPosition = 'above' | 'below'; encapsulation: ViewEncapsulation.None, // tslint:disable-next-line:validate-decorators changeDetection: ChangeDetectionStrategy.Default, - inputs: ['color', 'disableRipple'], providers: [ { provide: MAT_TAB_GROUP, @@ -92,16 +70,14 @@ export type MatTabHeaderPosition = 'above' | 'below'; host: { 'ngSkipHydration': '', 'class': 'mat-mdc-tab-group', + '[class]': '"mat-" + (color || "primary")', '[class.mat-mdc-tab-group-dynamic-height]': 'dynamicHeight', '[class.mat-mdc-tab-group-inverted-header]': 'headerPosition === "below"', '[class.mat-mdc-tab-group-stretch-tabs]': 'stretchTabs', '[style.--mat-tab-animation-duration]': 'animationDuration', }, }) -export class MatTabGroup - extends _MatTabGroupMixinBase - implements AfterContentInit, AfterContentChecked, OnDestroy, CanColor, CanDisableRipple -{ +export class MatTabGroup implements AfterContentInit, AfterContentChecked, OnDestroy { /** * All tabs inside the tab group. This includes tabs that belong to groups that are nested * inside the current one. We filter out only the tabs that belong to this group in `_tabs`. @@ -128,49 +104,37 @@ export class MatTabGroup /** Subscription to changes in the tab labels. */ private _tabLabelSubscription = Subscription.EMPTY; - /** Whether the ink bar should fit its width to the size of the tab label content. */ + /** Theme color of the tab group. */ @Input() + color: ThemePalette; + + /** Whether the ink bar should fit its width to the size of the tab label content. */ + @Input({transform: booleanAttribute}) get fitInkBarToContent(): boolean { return this._fitInkBarToContent; } - set fitInkBarToContent(v: BooleanInput) { - this._fitInkBarToContent = coerceBooleanProperty(v); + set fitInkBarToContent(value: boolean) { + this._fitInkBarToContent = value; this._changeDetectorRef.markForCheck(); } private _fitInkBarToContent = false; /** Whether tabs should be stretched to fill the header. */ - @Input('mat-stretch-tabs') - get stretchTabs(): boolean { - return this._stretchTabs; - } - set stretchTabs(v: BooleanInput) { - this._stretchTabs = coerceBooleanProperty(v); - } - private _stretchTabs = true; + @Input({alias: 'mat-stretch-tabs', transform: booleanAttribute}) + stretchTabs: boolean = true; /** Whether the tab group should grow to the size of the active tab. */ - @Input() - get dynamicHeight(): boolean { - return this._dynamicHeight; - } - - set dynamicHeight(value: BooleanInput) { - this._dynamicHeight = coerceBooleanProperty(value); - } - - private _dynamicHeight: boolean = false; + @Input({transform: booleanAttribute}) + dynamicHeight: boolean = false; /** The index of the active tab. */ - @Input() + @Input({transform: numberAttribute}) get selectedIndex(): number | null { return this._selectedIndex; } - - set selectedIndex(value: NumberInput) { - this._indexToSelect = coerceNumberProperty(value, null); + set selectedIndex(value: number) { + this._indexToSelect = isNaN(value) ? null : value; } - private _selectedIndex: number | null = null; /** Position of the tab header. */ @@ -181,11 +145,10 @@ export class MatTabGroup get animationDuration(): string { return this._animationDuration; } - - set animationDuration(value: NumberInput) { - this._animationDuration = /^\d+$/.test(value + '') ? value + 'ms' : (value as string); + set animationDuration(value: string | number) { + const stringValue = value + ''; + this._animationDuration = /^\d+$/.test(stringValue) ? value + 'ms' : stringValue; } - private _animationDuration: string; /** @@ -194,13 +157,13 @@ export class MatTabGroup * The `tabindex` will be removed automatically for inactive tabs. * Read more at https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-2/tabs.html */ - @Input() + @Input({transform: numberAttribute}) get contentTabIndex(): number | null { return this._contentTabIndex; } - set contentTabIndex(value: NumberInput) { - this._contentTabIndex = coerceNumberProperty(value, null); + set contentTabIndex(value: number) { + this._contentTabIndex = isNaN(value) ? null : value; } private _contentTabIndex: number | null; @@ -209,32 +172,20 @@ export class MatTabGroup * Whether pagination should be disabled. This can be used to avoid unnecessary * layout recalculations if it's known that pagination won't be required. */ - @Input() - get disablePagination(): boolean { - return this._disablePagination; - } + @Input({transform: booleanAttribute}) + disablePagination: boolean = false; - set disablePagination(value: BooleanInput) { - this._disablePagination = coerceBooleanProperty(value); - } - - private _disablePagination: boolean = false; + /** Whether ripples in the tab group are disabled. */ + @Input({transform: booleanAttribute}) + disableRipple: boolean = false; /** * By default tabs remove their content from the DOM while it's off-screen. * Setting this to `true` will keep it in the DOM which will prevent elements * like iframes and videos from reloading next time it comes back into the view. */ - @Input() - get preserveContent(): boolean { - return this._preserveContent; - } - - set preserveContent(value: BooleanInput) { - this._preserveContent = coerceBooleanProperty(value); - } - - private _preserveContent: boolean = false; + @Input({transform: booleanAttribute}) + preserveContent: boolean = false; /** Background color of the tab group. */ @Input() @@ -273,12 +224,11 @@ export class MatTabGroup private _groupId: number; constructor( - elementRef: ElementRef, + readonly _elementRef: ElementRef, private _changeDetectorRef: ChangeDetectorRef, @Inject(MAT_TABS_CONFIG) @Optional() defaultConfig?: MatTabsConfig, @Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string, ) { - super(elementRef); this._groupId = nextId++; this.animationDuration = defaultConfig && defaultConfig.animationDuration ? defaultConfig.animationDuration : '500ms'; @@ -288,7 +238,9 @@ export class MatTabGroup : false; this.dynamicHeight = defaultConfig && defaultConfig.dynamicHeight != null ? defaultConfig.dynamicHeight : false; - this.contentTabIndex = defaultConfig?.contentTabIndex ?? null; + if (defaultConfig?.contentTabIndex != null) { + this.contentTabIndex = defaultConfig.contentTabIndex; + } this.preserveContent = !!defaultConfig?.preserveContent; this.fitInkBarToContent = defaultConfig && defaultConfig.fitInkBarToContent != null @@ -502,7 +454,7 @@ export class MatTabGroup * height property is true. */ _setTabBodyWrapperHeight(tabHeight: number): void { - if (!this._dynamicHeight || !this._tabBodyWrapperHeight) { + if (!this.dynamicHeight || !this._tabBodyWrapperHeight) { return; } diff --git a/src/material/tabs/tab-header.spec.ts b/src/material/tabs/tab-header.spec.ts index fda6f442ab51..920cb195f12b 100644 --- a/src/material/tabs/tab-header.spec.ts +++ b/src/material/tabs/tab-header.spec.ts @@ -723,12 +723,11 @@ interface Tab { (indexFocused)="focusedIndex = $event" (selectFocusedIndex)="selectedIndex = $event" [disablePagination]="disablePagination"> -
    - {{tab.label}} -
    + (click)="selectedIndex = i">{{tab.label}}
    + } `, diff --git a/src/material/tabs/tab-header.ts b/src/material/tabs/tab-header.ts index 6356af386a21..963a5982b201 100644 --- a/src/material/tabs/tab-header.ts +++ b/src/material/tabs/tab-header.ts @@ -23,6 +23,7 @@ import { QueryList, ViewChild, ViewEncapsulation, + booleanAttribute, } from '@angular/core'; import {ViewportRuler} from '@angular/cdk/scrolling'; import {Platform} from '@angular/cdk/platform'; @@ -31,7 +32,6 @@ import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import {MatTabLabelWrapper} from './tab-label-wrapper'; import {MatInkBar} from './ink-bar'; import {MatPaginatedTabHeader} from './paginated-tab-header'; -import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; /** * The header of the tab group which displays a list of all the tabs in the tab group. Includes @@ -68,16 +68,8 @@ export class MatTabHeader _inkBar: MatInkBar; /** Whether the ripple effect is disabled or not. */ - @Input() - get disableRipple(): boolean { - return this._disableRipple; - } - - set disableRipple(value: BooleanInput) { - this._disableRipple = coerceBooleanProperty(value); - } - - private _disableRipple: boolean = false; + @Input({transform: booleanAttribute}) + disableRipple: boolean = false; constructor( elementRef: ElementRef, diff --git a/src/material/tabs/tab-label-wrapper.ts b/src/material/tabs/tab-label-wrapper.ts index f954e4157402..15e2a778f33f 100644 --- a/src/material/tabs/tab-label-wrapper.ts +++ b/src/material/tabs/tab-label-wrapper.ts @@ -6,18 +6,15 @@ * found in the LICENSE file at https://angular.io/license */ -import {Directive, ElementRef} from '@angular/core'; +import {Directive, ElementRef, Input, booleanAttribute} from '@angular/core'; import {mixinInkBarItem} from './ink-bar'; -import {CanDisable, mixinDisabled} from '@angular/material/core'; // Boilerplate for applying mixins to MatTabLabelWrapper. /** @docs-private */ const _MatTabLabelWrapperMixinBase = mixinInkBarItem( - mixinDisabled( - class { - elementRef: ElementRef; - }, - ), + class { + elementRef: ElementRef; + }, ); /** @@ -26,13 +23,17 @@ const _MatTabLabelWrapperMixinBase = mixinInkBarItem( */ @Directive({ selector: '[matTabLabelWrapper]', - inputs: ['disabled', 'fitInkBarToContent'], + inputs: ['fitInkBarToContent'], host: { '[class.mat-mdc-tab-disabled]': 'disabled', '[attr.aria-disabled]': '!!disabled', }, }) -export class MatTabLabelWrapper extends _MatTabLabelWrapperMixinBase implements CanDisable { +export class MatTabLabelWrapper extends _MatTabLabelWrapperMixinBase { + /** Whether the tab is disabled. */ + @Input({transform: booleanAttribute}) + disabled: boolean = false; + constructor(override elementRef: ElementRef) { super(); } diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts b/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts index df4c41485d37..e1a749f65ad2 100644 --- a/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts +++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts @@ -526,14 +526,13 @@ describe('MatTabNavBar with enabled animations', () => { [disableRipple]="disableRippleOnBar" [fitInkBarToContent]="fitInkBarToContent" [tabPanel]="tabPanel"> - - Tab link {{label}} - + @for (tab of tabs; track tab; let index = $index) { + Tab link {{label}} + } Tab panel `, @@ -555,7 +554,9 @@ class SimpleTabNavBarTestApp { @Component({ template: ` Tab panel `, @@ -567,7 +568,9 @@ class TabLinkWithNgIf { @Component({ template: ` Tab panel `, @@ -579,7 +582,9 @@ class TabBarWithInactiveTabsOnInit { @Component({ template: ` , `, diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts index 4d6274dfb75b..ac597d17ccde 100644 --- a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts +++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts @@ -10,6 +10,7 @@ import { AfterContentInit, AfterViewInit, Attribute, + booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -19,6 +20,7 @@ import { Inject, Input, NgZone, + numberAttribute, OnDestroy, Optional, QueryList, @@ -27,13 +29,7 @@ import { } from '@angular/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import { - CanDisable, - CanDisableRipple, - HasTabIndex, MAT_RIPPLE_GLOBAL_OPTIONS, - mixinDisabled, - mixinDisableRipple, - mixinTabIndex, RippleConfig, RippleGlobalOptions, RippleTarget, @@ -44,7 +40,6 @@ import {Directionality} from '@angular/cdk/bidi'; import {ViewportRuler} from '@angular/cdk/scrolling'; import {Platform} from '@angular/cdk/platform'; import {MatInkBar, mixinInkBarItem} from '../ink-bar'; -import {BooleanInput, coerceBooleanProperty, NumberInput} from '@angular/cdk/coercion'; import {BehaviorSubject, Subject} from 'rxjs'; import {startWith, takeUntil} from 'rxjs/operators'; import {ENTER, SPACE} from '@angular/cdk/keycodes'; @@ -61,7 +56,6 @@ let nextUniqueId = 0; @Component({ selector: '[mat-tab-nav-bar]', exportAs: 'matTabNavBar, matTabNav', - inputs: ['color'], templateUrl: 'tab-nav-bar.html', styleUrls: ['tab-nav-bar.css'], host: { @@ -85,33 +79,28 @@ export class MatTabNav implements AfterContentChecked, AfterContentInit, OnDestroy, AfterViewInit { /** Whether the ink bar should fit its width to the size of the tab label content. */ - @Input() + @Input({transform: booleanAttribute}) get fitInkBarToContent(): boolean { return this._fitInkBarToContent.value; } - set fitInkBarToContent(v: BooleanInput) { - this._fitInkBarToContent.next(coerceBooleanProperty(v)); + set fitInkBarToContent(value: boolean) { + this._fitInkBarToContent.next(value); this._changeDetectorRef.markForCheck(); } _fitInkBarToContent = new BehaviorSubject(false); /** Whether tabs should be stretched to fill the header. */ - @Input('mat-stretch-tabs') - get stretchTabs(): boolean { - return this._stretchTabs; - } - set stretchTabs(v: BooleanInput) { - this._stretchTabs = coerceBooleanProperty(v); - } - private _stretchTabs = true; + @Input({alias: 'mat-stretch-tabs', transform: booleanAttribute}) + stretchTabs: boolean = true; @Input() get animationDuration(): string { return this._animationDuration; } - set animationDuration(value: NumberInput) { - this._animationDuration = /^\d+$/.test(value + '') ? value + 'ms' : (value as string); + set animationDuration(value: string | number) { + const stringValue = value + ''; + this._animationDuration = /^\d+$/.test(stringValue) ? value + 'ms' : stringValue; } private _animationDuration: string; @@ -139,16 +128,8 @@ export class MatTabNav private _backgroundColor: ThemePalette; /** Whether the ripple effect is disabled or not. */ - @Input() - get disableRipple(): boolean { - return this._disableRipple; - } - - set disableRipple(value: BooleanInput) { - this._disableRipple = coerceBooleanProperty(value); - } - - private _disableRipple: boolean = false; + @Input({transform: booleanAttribute}) + disableRipple: boolean = false; /** Theme color of the nav bar. */ @Input() color: ThemePalette = 'primary'; @@ -245,15 +226,9 @@ export class MatTabNav // Boilerplate for applying mixins to MatTabLink. const _MatTabLinkMixinBase = mixinInkBarItem( - mixinTabIndex( - mixinDisableRipple( - mixinDisabled( - class { - elementRef: ElementRef; - }, - ), - ), - ), + class { + elementRef: ElementRef; + }, ); /** @@ -262,7 +237,7 @@ const _MatTabLinkMixinBase = mixinInkBarItem( @Component({ selector: '[mat-tab-link], [matTabLink]', exportAs: 'matTabLink', - inputs: ['disabled', 'disableRipple', 'tabIndex', 'active', 'id'], + inputs: ['active', 'id'], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, templateUrl: 'tab-link.html', @@ -284,14 +259,7 @@ const _MatTabLinkMixinBase = mixinInkBarItem( }) export class MatTabLink extends _MatTabLinkMixinBase - implements - AfterViewInit, - OnDestroy, - CanDisable, - CanDisableRipple, - HasTabIndex, - RippleTarget, - FocusableOption + implements AfterViewInit, OnDestroy, RippleTarget, FocusableOption { private readonly _destroyed = new Subject(); @@ -299,20 +267,31 @@ export class MatTabLink protected _isActive: boolean = false; /** Whether the link is active. */ - @Input() + @Input({transform: booleanAttribute}) get active(): boolean { return this._isActive; } - set active(value: BooleanInput) { - const newValue = coerceBooleanProperty(value); - - if (newValue !== this._isActive) { - this._isActive = newValue; + set active(value: boolean) { + if (value !== this._isActive) { + this._isActive = value; this._tabNavBar.updateActiveLink(); } } + /** Whether the tab link is disabled. */ + @Input({transform: booleanAttribute}) + disabled: boolean = false; + + /** Whether ripples are disabled on the tab link. */ + @Input({transform: booleanAttribute}) + disableRipple: boolean = false; + + @Input({ + transform: (value: unknown) => (value == null ? 0 : numberAttribute(value)), + }) + tabIndex: number = 0; + /** * Ripple configuration for ripples that are launched on pointer down. The ripple config * is set to the global ripple options since we don't have any configurable options for @@ -419,7 +398,7 @@ export class MatTabLink if (this._tabNavBar.tabPanel) { return this._isActive && !this.disabled ? 0 : -1; } else { - return this.tabIndex; + return this.disabled ? -1 : this.tabIndex; } } } diff --git a/src/material/tabs/tab.ts b/src/material/tabs/tab.ts index 020a3f0fa0af..95e292385feb 100644 --- a/src/material/tabs/tab.ts +++ b/src/material/tabs/tab.ts @@ -22,17 +22,13 @@ import { ViewChild, ViewContainerRef, ViewEncapsulation, + booleanAttribute, } from '@angular/core'; import {MatTabContent} from './tab-content'; import {MAT_TAB, MatTabLabel} from './tab-label'; -import {CanDisable, mixinDisabled} from '@angular/material/core'; import {TemplatePortal} from '@angular/cdk/portal'; import {Subject} from 'rxjs'; -// Boilerplate for applying mixins to MatTab. -/** @docs-private */ -const _MatTabMixinBase = mixinDisabled(class {}); - /** * Used to provide a tab group to a tab without causing a circular dependency. * @docs-private @@ -46,16 +42,18 @@ export const MAT_TAB_GROUP = new InjectionToken('MAT_TAB_GROUP'); // the inlined template of `MatTab` isn't duplicated, however the template is small enough // that creating the extra class will generate more code than just duplicating the template. templateUrl: 'tab.html', - inputs: ['disabled'], // tslint:disable-next-line:validate-decorators changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.None, exportAs: 'matTab', providers: [{provide: MAT_TAB, useExisting: MatTab}], }) -export class MatTab extends _MatTabMixinBase implements CanDisable, OnInit, OnChanges, OnDestroy { +export class MatTab implements OnInit, OnChanges, OnDestroy { + /** whether the tab is disabled. */ + @Input({transform: booleanAttribute}) + disabled: boolean = false; + /** Content for the tab label given by ``. */ - private _templateLabel: MatTabLabel; @ContentChild(MatTabLabel) get templateLabel(): MatTabLabel { return this._templateLabel; @@ -63,6 +61,7 @@ export class MatTab extends _MatTabMixinBase implements CanDisable, OnInit, OnCh set templateLabel(value: MatTabLabel) { this._setTemplateLabelInput(value); } + private _templateLabel: MatTabLabel; /** * Template provided in the tab content that will be used if present, used to enable lazy-loading @@ -129,9 +128,7 @@ export class MatTab extends _MatTabMixinBase implements CanDisable, OnInit, OnCh constructor( private _viewContainerRef: ViewContainerRef, @Inject(MAT_TAB_GROUP) @Optional() public _closestTabGroup: any, - ) { - super(); - } + ) {} ngOnChanges(changes: SimpleChanges): void { if (changes.hasOwnProperty('textLabel') || changes.hasOwnProperty('disabled')) { diff --git a/src/material/tabs/testing/BUILD.bazel b/src/material/tabs/testing/BUILD.bazel index 17873ad3f5ab..ce2555520988 100644 --- a/src/material/tabs/testing/BUILD.bazel +++ b/src/material/tabs/testing/BUILD.bazel @@ -9,7 +9,6 @@ ts_library( exclude = ["**/*.spec.ts"], ), deps = [ - "//src/cdk/coercion", "//src/cdk/testing", ], ) diff --git a/src/material/toolbar/testing/toolbar-harness.ts b/src/material/toolbar/testing/toolbar-harness.ts index 597564058f25..1e3c3a5a5948 100644 --- a/src/material/toolbar/testing/toolbar-harness.ts +++ b/src/material/toolbar/testing/toolbar-harness.ts @@ -10,7 +10,7 @@ import {ContentContainerComponentHarness, HarnessPredicate, parallel} from '@ang import {ToolbarHarnessFilters} from './toolbar-harness-filters'; /** Selectors for different sections of the mat-toolbar that contain user content. */ -export const enum MatToolbarSection { +export enum MatToolbarSection { ROW = '.mat-toolbar-row', } diff --git a/src/material/toolbar/toolbar.spec.ts b/src/material/toolbar/toolbar.spec.ts index 524ff148a570..2989dd7fc838 100644 --- a/src/material/toolbar/toolbar.spec.ts +++ b/src/material/toolbar/toolbar.spec.ts @@ -128,7 +128,9 @@ class ToolbarMultipleRows {} template: ` First Row - Second Row + @if (showToolbarRow) { + Second Row + } `, }) @@ -140,10 +142,10 @@ class ToolbarMixedRowModes { // The ng-container is there so we have a node with a directive between the toolbar and the rows. template: ` - + @if (true) { First Row Second Row - + } `, }) diff --git a/src/material/toolbar/toolbar.ts b/src/material/toolbar/toolbar.ts index 21f2ad7be476..9da14b5ea24c 100644 --- a/src/material/toolbar/toolbar.ts +++ b/src/material/toolbar/toolbar.ts @@ -16,18 +16,10 @@ import { Directive, ElementRef, Inject, + Input, QueryList, ViewEncapsulation, } from '@angular/core'; -import {CanColor, mixinColor} from '@angular/material/core'; - -// Boilerplate for applying mixins to MatToolbar. -/** @docs-private */ -const _MatToolbarBase = mixinColor( - class { - constructor(public _elementRef: ElementRef) {} - }, -); @Directive({ selector: 'mat-toolbar-row', @@ -41,28 +33,30 @@ export class MatToolbarRow {} exportAs: 'matToolbar', templateUrl: 'toolbar.html', styleUrls: ['toolbar.css'], - inputs: ['color'], host: { 'class': 'mat-toolbar', + '[class]': 'color ? "mat-" + color : ""', '[class.mat-toolbar-multiple-rows]': '_toolbarRows.length > 0', '[class.mat-toolbar-single-row]': '_toolbarRows.length === 0', }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class MatToolbar extends _MatToolbarBase implements CanColor, AfterViewInit { +export class MatToolbar implements AfterViewInit { + // TODO: should be typed as `ThemePalette` but internal apps pass in arbitrary strings. + /** Palette color of the toolbar. */ + @Input() color?: string | null; + private _document: Document; /** Reference to all toolbar row elements that have been projected. */ @ContentChildren(MatToolbarRow, {descendants: true}) _toolbarRows: QueryList; constructor( - elementRef: ElementRef, + protected _elementRef: ElementRef, private _platform: Platform, @Inject(DOCUMENT) document?: any, ) { - super(elementRef); - // TODO: make the document a required param when doing breaking changes. this._document = document; } diff --git a/src/material/tooltip/tooltip.spec.ts b/src/material/tooltip/tooltip.spec.ts index 12f86924974f..393e841614c9 100644 --- a/src/material/tooltip/tooltip.spec.ts +++ b/src/material/tooltip/tooltip.spec.ts @@ -1533,14 +1533,13 @@ describe('MDC-based MatTooltip', () => { @Component({ selector: 'app', template: ` - `, + @if (showButton) { + + }`, }) class BasicTooltipDemo { position: string = 'below'; @@ -1557,11 +1556,11 @@ class BasicTooltipDemo { template: `
    - + [matTooltipPosition]="position">Button + }
    `, }) class ScrollableTooltipDemo { @@ -1599,10 +1598,10 @@ class OnPushTooltipDemo { @Component({ selector: 'app', template: ` - `, + @for (tooltip of tooltips; track tooltip) { + + } + `, }) class DynamicTooltipsDemo { tooltips: string[] = []; diff --git a/src/material/tree/node.ts b/src/material/tree/node.ts index 6294f6459de0..7648b1a32bdc 100644 --- a/src/material/tree/node.ts +++ b/src/material/tree/node.ts @@ -22,6 +22,8 @@ import { IterableDiffers, OnDestroy, OnInit, + booleanAttribute, + numberAttribute, } from '@angular/core'; import {CanDisable, HasTabIndex} from '@angular/material/core'; import {BooleanInput, coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion'; @@ -42,7 +44,6 @@ function isLegacyTreeKeyManager( @Directive({ selector: 'mat-tree-node', exportAs: 'matTreeNode', - inputs: ['role', 'disabled', 'tabIndex', 'isExpandable', 'isExpanded', 'isDisabled'], outputs: ['activation', 'expandedChange'], providers: [{provide: CdkTreeNode, useExisting: MatTreeNode}], host: { @@ -69,13 +70,10 @@ export class MatTreeNode * an unexpected state. Tabindex to be removed in a future version. * @breaking-change 19.0.0 Remove this attribute. */ - get tabIndex(): number { - return this.isDisabled ? -1 : this._tabIndex; - } - set tabIndex(value: number) { - // If the specified tabIndex value is null or undefined, fall back to the default value. - this._tabIndex = value != null ? coerceNumberProperty(value) : this.defaultTabIndex; - } + @Input({ + transform: (value: unknown) => (value == null ? 0 : numberAttribute(value)), + }) + tabIndex: number; /** * The default tabindex of the tree node. @@ -100,11 +98,12 @@ export class MatTreeNode * @deprecated This is an alias for `isDisabled`. * @breaking-change 19.0.0 Remove this input */ + @Input({transform: booleanAttribute}) get disabled(): boolean { return this.isDisabled ?? false; } - set disabled(value: BooleanInput) { - this.isDisabled = coerceBooleanProperty(value); + set disabled(value: boolean) { + this.isDisabled = value; } constructor( @@ -155,7 +154,6 @@ export class MatTreeNodeDef extends CdkTreeNodeDef { @Directive({ selector: 'mat-nested-tree-node', exportAs: 'matNestedTreeNode', - inputs: ['role', 'disabled', 'tabIndex', 'isExpandable', 'isExpanded', 'isDisabled'], outputs: ['activation', 'expandedChange'], providers: [ {provide: CdkNestedTreeNode, useExisting: MatNestedTreeNode}, @@ -173,7 +171,7 @@ export class MatNestedTreeNode @Input('matNestedTreeNode') node: T; /** - * Whether the component is disabled. + * Whether the node is disabled. * * @deprecated This is an alias for `isDisabled`. * @breaking-change 19.0.0 Remove this input @@ -185,6 +183,17 @@ export class MatNestedTreeNode this.isDisabled = coerceBooleanProperty(value); } + /** Tabindex for the node. */ + @Input() + get tabIndex(): number { + return this.disabled ? -1 : this._tabIndex; + } + set tabIndex(value: number) { + // If the specified tabIndex value is null or undefined, fall back to the default value. + this._tabIndex = value != null ? value : 0; + } + private _tabIndex: number; + constructor( elementRef: ElementRef, tree: CdkTree, diff --git a/src/material/tree/padding.ts b/src/material/tree/padding.ts index 65a98cf6e37c..81aeed52ebc2 100644 --- a/src/material/tree/padding.ts +++ b/src/material/tree/padding.ts @@ -5,9 +5,8 @@ * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -import {NumberInput} from '@angular/cdk/coercion'; import {CdkTreeNodePadding} from '@angular/cdk/tree'; -import {Directive, Input} from '@angular/core'; +import {Directive, Input, numberAttribute} from '@angular/core'; /** * Wrapper for the CdkTree padding with Material design styles. @@ -18,11 +17,11 @@ import {Directive, Input} from '@angular/core'; }) export class MatTreeNodePadding extends CdkTreeNodePadding { /** The level of depth of the tree node. The padding will be `level * indent` pixels. */ - @Input('matTreeNodePadding') + @Input({alias: 'matTreeNodePadding', transform: numberAttribute}) override get level(): number { return this._level; } - override set level(value: NumberInput) { + override set level(value: number) { this._setLevelInput(value); } diff --git a/src/material/tree/tree.spec.ts b/src/material/tree/tree.spec.ts index b0256a1cd2cc..211c978de260 100644 --- a/src/material/tree/tree.spec.ts +++ b/src/material/tree/tree.spec.ts @@ -993,9 +993,11 @@ class NestedMatTreeApp { >>> {{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}} -
    - -
    + @if (isExpanded(node)) { +
    + +
    + }
    `, @@ -1053,9 +1055,11 @@ class MatTreeAppWithToggle { matTreeNodeToggle [matTreeNodeToggleRecursive]="toggleRecursively"> {{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}} -
    - -
    + @if (isExpanded(node)) { +
    + +
    + } `, diff --git a/src/youtube-player/youtube-player.spec.ts b/src/youtube-player/youtube-player.spec.ts index ec3e45d9818c..777be4fb2e20 100644 --- a/src/youtube-player/youtube-player.spec.ts +++ b/src/youtube-player/youtube-player.spec.ts @@ -554,17 +554,19 @@ describe('YoutubePlayer', () => { @Component({ selector: 'test-app', template: ` - - + @if (visible) { + + + } `, }) class TestApp { diff --git a/tools/public_api_guard/cdk/a11y.md b/tools/public_api_guard/cdk/a11y.md index 7cfc74bbcbcc..0194b9b884de 100644 --- a/tools/public_api_guard/cdk/a11y.md +++ b/tools/public_api_guard/cdk/a11y.md @@ -195,7 +195,7 @@ export class FocusMonitor implements OnDestroy { } // @public -export const enum FocusMonitorDetectionMode { +export enum FocusMonitorDetectionMode { EVENTUAL = 1, IMMEDIATE = 0 } @@ -264,7 +264,7 @@ export interface FocusTrapInertStrategy { export function getAriaReferenceIds(el: Element, attr: string): string[]; // @public -export const enum HighContrastMode { +export enum HighContrastMode { // (undocumented) BLACK_ON_WHITE = 1, // (undocumented) diff --git a/tools/public_api_guard/cdk/accordion.md b/tools/public_api_guard/cdk/accordion.md index 4d5148decd78..461b701c096a 100644 --- a/tools/public_api_guard/cdk/accordion.md +++ b/tools/public_api_guard/cdk/accordion.md @@ -14,6 +14,9 @@ import { SimpleChanges } from '@angular/core'; import { Subject } from 'rxjs'; import { UniqueSelectionDispatcher } from '@angular/cdk/collections'; +// @public +export const CDK_ACCORDION: InjectionToken; + // @public export class CdkAccordion implements OnDestroy, OnChanges { closeAll(): void; diff --git a/tools/public_api_guard/cdk/collections.md b/tools/public_api_guard/cdk/collections.md index 5fe8f1feec32..9c29898a18e4 100644 --- a/tools/public_api_guard/cdk/collections.md +++ b/tools/public_api_guard/cdk/collections.md @@ -154,7 +154,7 @@ export interface _ViewRepeaterItemInsertArgs { export type _ViewRepeaterItemValueResolver = (record: IterableChangeRecord) => T; // @public -export const enum _ViewRepeaterOperation { +export enum _ViewRepeaterOperation { INSERTED = 1, MOVED = 2, REMOVED = 3, diff --git a/tools/public_api_guard/cdk/menu.md b/tools/public_api_guard/cdk/menu.md index d640aca085b6..a3e127dcc32a 100644 --- a/tools/public_api_guard/cdk/menu.md +++ b/tools/public_api_guard/cdk/menu.md @@ -275,7 +275,7 @@ export interface FocusableElement { } // @public -export const enum FocusNext { +export enum FocusNext { // (undocumented) currentItem = 2, // (undocumented) diff --git a/tools/public_api_guard/cdk/platform.md b/tools/public_api_guard/cdk/platform.md index 054d150551a0..096ec373aafc 100644 --- a/tools/public_api_guard/cdk/platform.md +++ b/tools/public_api_guard/cdk/platform.md @@ -56,7 +56,7 @@ export class PlatformModule { } // @public -export const enum RtlScrollAxisType { +export enum RtlScrollAxisType { INVERTED = 2, NEGATED = 1, NORMAL = 0 diff --git a/tools/public_api_guard/cdk/tree.md b/tools/public_api_guard/cdk/tree.md index f45a9476244d..4aeca6a64b2e 100644 --- a/tools/public_api_guard/cdk/tree.md +++ b/tools/public_api_guard/cdk/tree.md @@ -7,7 +7,6 @@ import { AfterContentChecked } from '@angular/core'; import { AfterContentInit } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; -import { BooleanInput } from '@angular/cdk/coercion'; import { ChangeDetectorRef } from '@angular/core'; import { CollectionViewer } from '@angular/cdk/collections'; import { DataSource } from '@angular/cdk/collections'; @@ -18,7 +17,6 @@ import * as i0 from '@angular/core'; import { InjectionToken } from '@angular/core'; import { IterableDiffer } from '@angular/core'; import { IterableDiffers } from '@angular/core'; -import { NumberInput } from '@angular/cdk/coercion'; import { Observable } from 'rxjs'; import { OnDestroy } from '@angular/core'; import { OnInit } from '@angular/core'; @@ -72,7 +70,7 @@ export class CdkNestedTreeNode extends CdkTreeNode implements Af nodeOutlet: QueryList; protected updateChildrenNodes(children?: T[]): void; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration, "cdk-nested-tree-node", ["cdkNestedTreeNode"], { "role": { "alias": "role"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; }, {}, ["nodeOutlet"], never, false, never>; + static ɵdir: i0.ɵɵDirectiveDeclaration, "cdk-nested-tree-node", ["cdkNestedTreeNode"], {}, {}, ["nodeOutlet"], never, false, never>; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration, never>; } @@ -177,8 +175,8 @@ export class CdkTreeNode implements OnDestroy, OnInit, TreeKeyManagerI _getPositionInSet(): number; _getSetSize(): number; isDisabled?: boolean; - get isExpandable(): boolean | '' | null; - set isExpandable(isExpandable: boolean | '' | null); + get isExpandable(): boolean; + set isExpandable(isExpandable: boolean); _isExpandable(): boolean; // (undocumented) get isExpanded(): boolean; @@ -187,6 +185,12 @@ export class CdkTreeNode implements OnDestroy, OnInit, TreeKeyManagerI get level(): number; static mostRecentTreeNode: CdkTreeNode | null; // (undocumented) + static ngAcceptInputType_isDisabled: unknown; + // (undocumented) + static ngAcceptInputType_isExpandable: unknown; + // (undocumented) + static ngAcceptInputType_isExpanded: unknown; + // (undocumented) ngOnDestroy(): void; // (undocumented) ngOnInit(): void; @@ -248,14 +252,16 @@ export class CdkTreeNodePadding implements OnDestroy { _indent: number; indentUnits: string; get level(): number; - set level(value: NumberInput); + set level(value: number); // (undocumented) _level: number; // (undocumented) + static ngAcceptInputType_level: unknown; + // (undocumented) ngOnDestroy(): void; _paddingIndent(): string | null; protected _setIndentInput(indent: number | string): void; - protected _setLevelInput(value: NumberInput): void; + protected _setLevelInput(value: number): void; // (undocumented) _setPadding(forceChange?: boolean): void; // (undocumented) @@ -267,10 +273,9 @@ export class CdkTreeNodePadding implements OnDestroy { // @public export class CdkTreeNodeToggle { constructor(_tree: CdkTree, _treeNode: CdkTreeNode); - get recursive(): boolean; - set recursive(value: BooleanInput); // (undocumented) - protected _recursive: boolean; + static ngAcceptInputType_recursive: unknown; + recursive: boolean; // (undocumented) _toggle(event: Event): void; // (undocumented) diff --git a/tools/public_api_guard/material/card-testing.md b/tools/public_api_guard/material/card-testing.md index babc3816028f..b97462c527ef 100644 --- a/tools/public_api_guard/material/card-testing.md +++ b/tools/public_api_guard/material/card-testing.md @@ -26,7 +26,7 @@ export class MatCardHarness extends ContentContainerComponentHarness; export const MAT_CHIPS_DEFAULT_OPTIONS: InjectionToken; // @public -export class MatChip extends _MatChipMixinBase implements OnInit, AfterViewInit, AfterContentInit, CanColor, CanDisableRipple, CanDisable, DoCheck, HasTabIndex, OnDestroy { - constructor(_changeDetectorRef: ChangeDetectorRef, elementRef: ElementRef, _ngZone: NgZone, _focusMonitor: FocusMonitor, _document: any, animationMode?: string, _globalRippleOptions?: RippleGlobalOptions | undefined, tabIndex?: string); +export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck, OnDestroy { + constructor(_changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef, _ngZone: NgZone, _focusMonitor: FocusMonitor, _document: any, animationMode?: string, _globalRippleOptions?: RippleGlobalOptions | undefined, tabIndex?: string); protected _allLeadingIcons: QueryList; protected _allRemoveIcons: QueryList; protected _allTrailingIcons: QueryList; @@ -73,26 +68,39 @@ export class MatChip extends _MatChipMixinBase implements OnInit, AfterViewInit, protected basicChipAttrName: string; // (undocumented) _changeDetectorRef: ChangeDetectorRef; + color?: string | null; readonly destroyed: EventEmitter; + disabled: boolean; + disableRipple: boolean; // (undocumented) protected _document: Document; + // (undocumented) + _elementRef: ElementRef; focus(): void; _getActions(): MatChipAction[]; _getSourceAction(target: Node): MatChipAction | undefined; + _getTabIndex(): number | null; _handleKeydown(event: KeyboardEvent): void; _handlePrimaryActionInteraction(): void; // (undocumented) _hasFocus(): boolean; _hasTrailingIcon(): boolean; - get highlighted(): boolean; - set highlighted(value: BooleanInput); - // (undocumented) - protected _highlighted: boolean; + highlighted: boolean; id: string; _isBasicChip: boolean; _isRippleDisabled(): boolean; leadingIcon: MatChipAvatar; // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_disableRipple: unknown; + // (undocumented) + static ngAcceptInputType_highlighted: unknown; + // (undocumented) + static ngAcceptInputType_removable: unknown; + // (undocumented) + static ngAcceptInputType_tabIndex: unknown; + // (undocumented) ngAfterContentInit(): void; // (undocumented) ngAfterViewInit(): void; @@ -107,10 +115,7 @@ export class MatChip extends _MatChipMixinBase implements OnInit, AfterViewInit, readonly _onBlur: Subject; readonly _onFocus: Subject; primaryAction: MatChipAction; - get removable(): boolean; - set removable(value: BooleanInput); - // (undocumented) - protected _removable: boolean; + removable: boolean; remove(): void; readonly removed: EventEmitter; removeIcon: MatChipRemove; @@ -119,13 +124,14 @@ export class MatChip extends _MatChipMixinBase implements OnInit, AfterViewInit, set ripple(v: MatRipple); _rippleLoader: MatRippleLoader; role: string | null; + tabIndex: number; trailingIcon: MatChipTrailingIcon; get value(): any; set value(value: any); // (undocumented) protected _value: any; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -179,7 +185,7 @@ export class MatChipGrid extends _MatChipGridMixinBase implements AfterContentIn // (undocumented) protected _defaultRole: string; get disabled(): boolean; - set disabled(value: BooleanInput); + set disabled(value: boolean); get empty(): boolean; errorStateMatcher: ErrorStateMatcher; focus(): void; @@ -189,6 +195,10 @@ export class MatChipGrid extends _MatChipGridMixinBase implements AfterContentIn _handleKeydown(event: KeyboardEvent): void; get id(): string; // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_required: unknown; + // (undocumented) ngAfterContentInit(): void; // (undocumented) ngAfterViewInit(): void; @@ -207,7 +217,7 @@ export class MatChipGrid extends _MatChipGridMixinBase implements AfterContentIn registerOnChange(fn: (value: any) => void): void; registerOnTouched(fn: () => void): void; get required(): boolean; - set required(value: BooleanInput); + set required(value: boolean); // (undocumented) protected _required: boolean | undefined; setDescribedByIds(ids: string[]): void; @@ -220,7 +230,7 @@ export class MatChipGrid extends _MatChipGridMixinBase implements AfterContentIn readonly valueChange: EventEmitter; writeValue(value: any): void; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -237,17 +247,14 @@ export class MatChipGridChange { // @public export class MatChipInput implements MatChipTextControl, AfterContentInit, OnChanges, OnDestroy { constructor(_elementRef: ElementRef, defaultOptions: MatChipsDefaultOptions, formField?: MatFormField); - get addOnBlur(): boolean; - set addOnBlur(value: BooleanInput); - // (undocumented) - _addOnBlur: boolean; + addOnBlur: boolean; _blur(): void; readonly chipEnd: EventEmitter; get chipGrid(): MatChipGrid; set chipGrid(value: MatChipGrid); clear(): void; get disabled(): boolean; - set disabled(value: BooleanInput); + set disabled(value: boolean); // (undocumented) protected _elementRef: ElementRef; _emitChipEnd(event?: KeyboardEvent): void; @@ -261,6 +268,10 @@ export class MatChipInput implements MatChipTextControl, AfterContentInit, OnCha _keydown(event?: KeyboardEvent): void; _keyup(event: KeyboardEvent): void; // (undocumented) + static ngAcceptInputType_addOnBlur: unknown; + // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) ngAfterContentInit(): void; // (undocumented) ngOnChanges(): void; @@ -300,23 +311,28 @@ export class MatChipListbox extends MatChipSet implements AfterContentInit, OnDe protected _defaultRole: string; focus(): void; get hideSingleSelectionIndicator(): boolean; - set hideSingleSelectionIndicator(value: BooleanInput); + set hideSingleSelectionIndicator(value: boolean); // (undocumented) _keydown(event: KeyboardEvent): void; get multiple(): boolean; - set multiple(value: BooleanInput); + set multiple(value: boolean); + // (undocumented) + static ngAcceptInputType_hideSingleSelectionIndicator: unknown; + // (undocumented) + static ngAcceptInputType_multiple: unknown; + // (undocumented) + static ngAcceptInputType_required: unknown; + // (undocumented) + static ngAcceptInputType_selectable: unknown; // (undocumented) ngAfterContentInit(): void; _onChange: (value: any) => void; _onTouched: () => void; registerOnChange(fn: (value: any) => void): void; registerOnTouched(fn: () => void): void; - get required(): boolean; - set required(value: BooleanInput); - // (undocumented) - protected _required: boolean; + required: boolean; get selectable(): boolean; - set selectable(value: BooleanInput); + set selectable(value: boolean); // (undocumented) protected _selectable: boolean; get selected(): MatChipOption[] | MatChipOption; @@ -329,7 +345,7 @@ export class MatChipListbox extends MatChipSet implements AfterContentInit, OnDe protected _value: any; writeValue(value: any): void; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -356,21 +372,25 @@ export class MatChipOption extends MatChip implements OnInit { // (undocumented) _hasLeadingGraphic(): boolean; // (undocumented) + static ngAcceptInputType_selectable: unknown; + // (undocumented) + static ngAcceptInputType_selected: unknown; + // (undocumented) ngOnInit(): void; select(): void; get selectable(): boolean; - set selectable(value: BooleanInput); + set selectable(value: boolean); // (undocumented) protected _selectable: boolean; get selected(): boolean; - set selected(value: BooleanInput); + set selected(value: boolean); readonly selectionChange: EventEmitter; selectViaInteraction(): void; // (undocumented) _setSelectedState(isSelected: boolean, isUserInput: boolean, emitEvent: boolean): void; toggleSelected(isUserInput?: boolean): boolean; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -411,7 +431,7 @@ export class MatChipRow extends MatChip implements AfterViewInit { // (undocumented) _isRippleDisabled(): boolean; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -434,7 +454,7 @@ export class MatChipSelectionChange { } // @public -export class MatChipSet extends _MatChipSetMixinBase implements AfterViewInit, HasTabIndex, OnDestroy { +export class MatChipSet implements AfterViewInit, OnDestroy { constructor(_elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, _dir: Directionality); protected _allowFocusEscape(): void; // (undocumented) @@ -447,7 +467,7 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterViewInit, H protected _defaultRole: string; protected _destroyed: Subject; get disabled(): boolean; - set disabled(value: BooleanInput); + set disabled(value: boolean); // (undocumented) protected _disabled: boolean; // (undocumented) @@ -461,6 +481,10 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterViewInit, H protected _isValidIndex(index: number): boolean; protected _keyManager: FocusKeyManager; // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_tabIndex: unknown; + // (undocumented) ngAfterViewInit(): void; // (undocumented) ngOnDestroy(): void; @@ -469,8 +493,9 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterViewInit, H set role(value: string | null); protected _skipPredicate(action: MatChipAction): boolean; protected _syncChipsState(): void; + tabIndex: number; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/tools/public_api_guard/material/core.md b/tools/public_api_guard/material/core.md index a3734ebc1751..6e1d062079b6 100644 --- a/tools/public_api_guard/material/core.md +++ b/tools/public_api_guard/material/core.md @@ -546,7 +546,7 @@ export class RippleRenderer implements EventListenerObject { } // @public -export const enum RippleState { +export enum RippleState { // (undocumented) FADING_IN = 0, // (undocumented) diff --git a/tools/public_api_guard/material/datepicker-testing.md b/tools/public_api_guard/material/datepicker-testing.md index d971eaaf3290..e58538ebf732 100644 --- a/tools/public_api_guard/material/datepicker-testing.md +++ b/tools/public_api_guard/material/datepicker-testing.md @@ -26,7 +26,7 @@ export interface CalendarHarnessFilters extends BaseHarnessFilters { } // @public -export const enum CalendarView { +export enum CalendarView { // (undocumented) MONTH = 0, // (undocumented) diff --git a/tools/public_api_guard/material/datepicker.md b/tools/public_api_guard/material/datepicker.md index 9ce80428a884..80088883bbad 100644 --- a/tools/public_api_guard/material/datepicker.md +++ b/tools/public_api_guard/material/datepicker.md @@ -11,8 +11,6 @@ import { AfterViewChecked } from '@angular/core'; import { AfterViewInit } from '@angular/core'; import { AnimationEvent as AnimationEvent_2 } from '@angular/animations'; import { AnimationTriggerMetadata } from '@angular/animations'; -import { BooleanInput } from '@angular/cdk/coercion'; -import { CanColor } from '@angular/material/core'; import { CanUpdateErrorState } from '@angular/material/core'; import { ChangeDetectorRef } from '@angular/core'; import { ComponentType } from '@angular/cdk/portal'; @@ -372,8 +370,8 @@ export class MatDatepickerCancel { } // @public -export class MatDatepickerContent> extends _MatDatepickerContentBase implements OnInit, AfterViewInit, OnDestroy, CanColor { - constructor(elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, _globalModel: MatDateSelectionModel, _dateAdapter: DateAdapter, _rangeSelectionStrategy: MatDateRangeSelectionStrategy, intl: MatDatepickerIntl); +export class MatDatepickerContent> implements OnInit, AfterViewInit, OnDestroy { + constructor(_elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, _globalModel: MatDateSelectionModel, _dateAdapter: DateAdapter, _rangeSelectionStrategy: MatDateRangeSelectionStrategy, intl: MatDatepickerIntl); _actionsPortal: TemplatePortal | null; readonly _animationDone: Subject; _animationState: 'enter-dropdown' | 'enter-dialog' | 'void'; @@ -382,10 +380,13 @@ export class MatDatepickerContent> extend _calendar: MatCalendar; _closeButtonFocused: boolean; _closeButtonText: string; + color: ThemePalette; comparisonEnd: D | null; comparisonStart: D | null; datepicker: MatDatepickerBase; _dialogLabelId: string | null; + // (undocumented) + protected _elementRef: ElementRef; endDateAccessibleName: string | null; // (undocumented) _getSelected(): D | DateRange | null; @@ -537,11 +538,13 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe _customIcon: MatDatepickerToggleIcon; datepicker: MatDatepickerPanel, D>; get disabled(): boolean; - set disabled(value: BooleanInput); + set disabled(value: boolean); disableRipple: boolean; // (undocumented) _intl: MatDatepickerIntl; // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) ngAfterContentInit(): void; // (undocumented) ngOnChanges(changes: SimpleChanges): void; @@ -574,7 +577,7 @@ export class MatDateRangeInput implements MatFormFieldControl>, get dateFilter(): DateFilterFn; set dateFilter(value: DateFilterFn); get disabled(): boolean; - set disabled(value: BooleanInput); + set disabled(value: boolean); get empty(): boolean; // (undocumented) _endInput: MatEndDate; @@ -599,6 +602,10 @@ export class MatDateRangeInput implements MatFormFieldControl>, get min(): D | null; set min(value: D | null); // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_required: unknown; + // (undocumented) ngAfterContentInit(): void; ngControl: NgControl | null; // (undocumented) @@ -611,7 +618,7 @@ export class MatDateRangeInput implements MatFormFieldControl>, get rangePicker(): MatDatepickerPanel, DateRange, D>; set rangePicker(rangePicker: MatDatepickerPanel, DateRange, D>); get required(): boolean; - set required(value: BooleanInput); + set required(value: boolean); separator: string; setDescribedByIds(ids: string[]): void; _shouldHidePlaceholders(): boolean; diff --git a/tools/public_api_guard/material/dialog-testing.md b/tools/public_api_guard/material/dialog-testing.md index 00c2404ebaaf..317a912fc96a 100644 --- a/tools/public_api_guard/material/dialog-testing.md +++ b/tools/public_api_guard/material/dialog-testing.md @@ -44,7 +44,7 @@ export class MatDialogHarness extends ContentContainerComponentHarness>; closeAll(): void; // (undocumented) + protected _dialog: Dialog; + // (undocumented) protected dialogConfigClass: typeof MatDialogConfig; getDialogById(id: string): MatDialogRef | undefined; // (undocumented) @@ -240,7 +243,7 @@ export class MatDialogRef { } // @public (undocumented) -export const enum MatDialogState { +export enum MatDialogState { // (undocumented) CLOSED = 2, // (undocumented) diff --git a/tools/public_api_guard/material/expansion-testing.md b/tools/public_api_guard/material/expansion-testing.md index e3d7c5f349a5..781338c2b25f 100644 --- a/tools/public_api_guard/material/expansion-testing.md +++ b/tools/public_api_guard/material/expansion-testing.md @@ -60,7 +60,7 @@ export class MatExpansionPanelHarness extends ContentContainerComponentHarness; - get hideToggle(): boolean; - set hideToggle(show: BooleanInput); + hideToggle: boolean; + // (undocumented) + static ngAcceptInputType_hideToggle: unknown; // (undocumented) ngAfterContentInit(): void; // (undocumented) @@ -114,10 +111,12 @@ export class MatExpansionPanel extends CdkAccordionItem implements AfterContentI _hasSpacing(): boolean; _headerId: string; get hideToggle(): boolean; - set hideToggle(value: BooleanInput); + set hideToggle(value: boolean); readonly _inputChanges: Subject; _lazyContent: MatExpansionPanelContent; // (undocumented) + static ngAcceptInputType_hideToggle: unknown; + // (undocumented) ngAfterContentInit(): void; // (undocumented) ngOnChanges(changes: SimpleChanges): void; @@ -171,7 +170,7 @@ export class MatExpansionPanelDescription { } // @public -export class MatExpansionPanelHeader extends _MatExpansionPanelHeaderMixinBase implements AfterViewInit, OnDestroy, FocusableOption, HasTabIndex { +export class MatExpansionPanelHeader implements AfterViewInit, OnDestroy, FocusableOption { constructor(panel: MatExpansionPanel, _element: ElementRef, _focusMonitor: FocusMonitor, _changeDetectorRef: ChangeDetectorRef, defaultOptions?: MatExpansionPanelDefaultOptions, _animationMode?: string | undefined, tabIndex?: string); // (undocumented) _animationMode?: string | undefined; @@ -186,15 +185,18 @@ export class MatExpansionPanelHeader extends _MatExpansionPanelHeaderMixinBase i _isExpanded(): boolean; _keydown(event: KeyboardEvent): void; // (undocumented) + static ngAcceptInputType_tabIndex: unknown; + // (undocumented) ngAfterViewInit(): void; // (undocumented) ngOnDestroy(): void; // (undocumented) panel: MatExpansionPanel; _showToggle(): boolean; + tabIndex: number; _toggle(): void; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/tools/public_api_guard/material/grid-list-testing.md b/tools/public_api_guard/material/grid-list-testing.md index 55cc256bcabf..eeab39079af5 100644 --- a/tools/public_api_guard/material/grid-list-testing.md +++ b/tools/public_api_guard/material/grid-list-testing.md @@ -45,7 +45,7 @@ export class MatGridTileHarness extends ContentContainerComponentHarness; export function MAT_ICON_LOCATION_FACTORY(): MatIconLocation; // @public -export class MatIcon extends _MatIconBase implements OnInit, AfterViewChecked, CanColor, OnDestroy { - constructor(elementRef: ElementRef, _iconRegistry: MatIconRegistry, ariaHidden: string, _location: MatIconLocation, _errorHandler: ErrorHandler, defaults?: MatIconDefaultOptions); +export class MatIcon implements OnInit, AfterViewChecked, OnDestroy { + constructor(_elementRef: ElementRef, _iconRegistry: MatIconRegistry, ariaHidden: string, _location: MatIconLocation, _errorHandler: ErrorHandler, defaults?: MatIconDefaultOptions); + get color(): string | null | undefined; + set color(value: string | null | undefined); + // (undocumented) + readonly _elementRef: ElementRef; get fontIcon(): string; set fontIcon(value: string); get fontSet(): string; set fontSet(value: string); - get inline(): boolean; - set inline(inline: BooleanInput); + inline: boolean; + // (undocumented) + static ngAcceptInputType_inline: unknown; // (undocumented) ngAfterViewChecked(): void; // (undocumented) diff --git a/tools/public_api_guard/material/list-testing.md b/tools/public_api_guard/material/list-testing.md index 8f85468dbc2f..279f855de780 100644 --- a/tools/public_api_guard/material/list-testing.md +++ b/tools/public_api_guard/material/list-testing.md @@ -82,13 +82,13 @@ export class MatListItemHarness extends MatListItemHarnessBase { } // @public -export const enum MatListItemSection { +export enum MatListItemSection { // (undocumented) CONTENT = ".mdc-list-item__content" } // @public -export const enum MatListItemType { +export enum MatListItemType { // (undocumented) ONE_LINE_ITEM = 0, // (undocumented) diff --git a/tools/public_api_guard/material/paginator.md b/tools/public_api_guard/material/paginator.md index ef6fd8b3dc2f..e53d9ae093c1 100644 --- a/tools/public_api_guard/material/paginator.md +++ b/tools/public_api_guard/material/paginator.md @@ -4,11 +4,7 @@ ```ts -import { _AbstractConstructor } from '@angular/material/core'; -import { BooleanInput } from '@angular/cdk/coercion'; -import { CanDisable } from '@angular/material/core'; import { ChangeDetectorRef } from '@angular/core'; -import { _Constructor } from '@angular/material/core'; import { EventEmitter } from '@angular/core'; import { HasInitialized } from '@angular/material/core'; import * as i0 from '@angular/core'; @@ -17,7 +13,6 @@ import * as i3 from '@angular/material/select'; import * as i4 from '@angular/material/tooltip'; import { InjectionToken } from '@angular/core'; import { MatFormFieldAppearance } from '@angular/material/form-field'; -import { NumberInput } from '@angular/cdk/coercion'; import { OnDestroy } from '@angular/core'; import { OnInit } from '@angular/core'; import { Optional } from '@angular/core'; @@ -38,44 +33,55 @@ export const MAT_PAGINATOR_INTL_PROVIDER: { export function MAT_PAGINATOR_INTL_PROVIDER_FACTORY(parentIntl: MatPaginatorIntl): MatPaginatorIntl; // @public -export class MatPaginator extends _MatPaginatorMixinBase implements OnInit, OnDestroy, CanDisable, HasInitialized { +export class MatPaginator extends _MatPaginatorMixinBase implements OnInit, OnDestroy, HasInitialized { constructor(_intl: MatPaginatorIntl, _changeDetectorRef: ChangeDetectorRef, defaults?: MatPaginatorDefaultOptions); _changePageSize(pageSize: number): void; color: ThemePalette; + disabled: boolean; _displayedPageSizeOptions: number[]; firstPage(): void; _formFieldAppearance?: MatFormFieldAppearance; getNumberOfPages(): number; hasNextPage(): boolean; hasPreviousPage(): boolean; - get hidePageSize(): boolean; - set hidePageSize(value: BooleanInput); + hidePageSize: boolean; // (undocumented) _intl: MatPaginatorIntl; lastPage(): void; get length(): number; - set length(value: NumberInput); + set length(value: number); _nextButtonsDisabled(): boolean; nextPage(): void; // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_hidePageSize: unknown; + // (undocumented) + static ngAcceptInputType_length: unknown; + // (undocumented) + static ngAcceptInputType_pageIndex: unknown; + // (undocumented) + static ngAcceptInputType_pageSize: unknown; + // (undocumented) + static ngAcceptInputType_showFirstLastButtons: unknown; + // (undocumented) ngOnDestroy(): void; // (undocumented) ngOnInit(): void; readonly page: EventEmitter; get pageIndex(): number; - set pageIndex(value: NumberInput); + set pageIndex(value: number); get pageSize(): number; - set pageSize(value: NumberInput); + set pageSize(value: number); readonly _pageSizeLabelId: string; get pageSizeOptions(): number[]; set pageSizeOptions(value: number[] | readonly number[]); _previousButtonsDisabled(): boolean; previousPage(): void; selectConfig: MatPaginatorSelectConfig; - get showFirstLastButtons(): boolean; - set showFirstLastButtons(value: BooleanInput); + showFirstLastButtons: boolean; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/tools/public_api_guard/material/progress-bar.md b/tools/public_api_guard/material/progress-bar.md index 1487851aff50..9ebf1bbe1c4c 100644 --- a/tools/public_api_guard/material/progress-bar.md +++ b/tools/public_api_guard/material/progress-bar.md @@ -4,18 +4,14 @@ ```ts -import { _AbstractConstructor } from '@angular/material/core'; import { AfterViewInit } from '@angular/core'; -import { CanColor } from '@angular/material/core'; import { ChangeDetectorRef } from '@angular/core'; -import { _Constructor } from '@angular/material/core'; import { ElementRef } from '@angular/core'; import { EventEmitter } from '@angular/core'; import * as i0 from '@angular/core'; import * as i2 from '@angular/material/core'; import { InjectionToken } from '@angular/core'; import { NgZone } from '@angular/core'; -import { NumberInput } from '@angular/cdk/coercion'; import { OnDestroy } from '@angular/core'; import { ThemePalette } from '@angular/material/core'; @@ -29,13 +25,17 @@ export const MAT_PROGRESS_BAR_LOCATION: InjectionToken; export function MAT_PROGRESS_BAR_LOCATION_FACTORY(): MatProgressBarLocation; // @public (undocumented) -export class MatProgressBar extends _MatProgressBarBase implements AfterViewInit, OnDestroy, CanColor { - constructor(elementRef: ElementRef, _ngZone: NgZone, _changeDetectorRef: ChangeDetectorRef, _animationMode?: string | undefined, defaults?: MatProgressBarDefaultOptions); +export class MatProgressBar implements AfterViewInit, OnDestroy { + constructor(_elementRef: ElementRef, _ngZone: NgZone, _changeDetectorRef: ChangeDetectorRef, _animationMode?: string | undefined, defaults?: MatProgressBarDefaultOptions); readonly animationEnd: EventEmitter; // (undocumented) _animationMode?: string | undefined; get bufferValue(): number; - set bufferValue(v: NumberInput); + set bufferValue(v: number); + get color(): string | null | undefined; + set color(value: string | null | undefined); + // (undocumented) + readonly _elementRef: ElementRef; _getBufferBarFlexBasis(): string; _getPrimaryBarTransform(): string; _isIndeterminate(): boolean; @@ -43,11 +43,15 @@ export class MatProgressBar extends _MatProgressBarBase implements AfterViewInit get mode(): ProgressBarMode; set mode(value: ProgressBarMode); // (undocumented) + static ngAcceptInputType_bufferValue: unknown; + // (undocumented) + static ngAcceptInputType_value: unknown; + // (undocumented) ngAfterViewInit(): void; // (undocumented) ngOnDestroy(): void; get value(): number; - set value(v: NumberInput); + set value(v: number); // (undocumented) static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) diff --git a/tools/public_api_guard/material/progress-spinner.md b/tools/public_api_guard/material/progress-spinner.md index cb0434e17f32..cdceb6897426 100644 --- a/tools/public_api_guard/material/progress-spinner.md +++ b/tools/public_api_guard/material/progress-spinner.md @@ -4,15 +4,11 @@ ```ts -import { _AbstractConstructor } from '@angular/material/core'; -import { CanColor } from '@angular/material/core'; -import { _Constructor } from '@angular/material/core'; import { ElementRef } from '@angular/core'; import * as i0 from '@angular/core'; import * as i2 from '@angular/common'; import * as i3 from '@angular/material/core'; import { InjectionToken } from '@angular/core'; -import { NumberInput } from '@angular/cdk/coercion'; import { ThemePalette } from '@angular/material/core'; // @public @@ -22,21 +18,31 @@ export const MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS: InjectionToken, animationMode: string, defaults?: MatProgressSpinnerDefaultOptions); +export class MatProgressSpinner { + constructor(_elementRef: ElementRef, animationMode: string, defaults?: MatProgressSpinnerDefaultOptions); _circleRadius(): number; _circleStrokeWidth(): number; + get color(): string | null | undefined; + set color(value: string | null | undefined); _determinateCircle: ElementRef; get diameter(): number; - set diameter(size: NumberInput); + set diameter(size: number); + // (undocumented) + readonly _elementRef: ElementRef; mode: ProgressSpinnerMode; + // (undocumented) + static ngAcceptInputType_diameter: unknown; + // (undocumented) + static ngAcceptInputType_strokeWidth: unknown; + // (undocumented) + static ngAcceptInputType_value: unknown; _noopAnimations: boolean; _strokeCircumference(): number; _strokeDashOffset(): number | null; get strokeWidth(): number; - set strokeWidth(value: NumberInput); + set strokeWidth(value: number); get value(): number; - set value(v: NumberInput); + set value(v: number); _viewBox(): string; // (undocumented) static ɵcmp: i0.ɵɵComponentDeclaration; diff --git a/tools/public_api_guard/material/radio.md b/tools/public_api_guard/material/radio.md index d5d1d1060378..6cfc760336ad 100644 --- a/tools/public_api_guard/material/radio.md +++ b/tools/public_api_guard/material/radio.md @@ -4,20 +4,15 @@ ```ts -import { _AbstractConstructor } from '@angular/material/core'; import { AfterContentInit } from '@angular/core'; import { AfterViewInit } from '@angular/core'; -import { BooleanInput } from '@angular/cdk/coercion'; -import { CanDisableRipple } from '@angular/material/core'; import { ChangeDetectorRef } from '@angular/core'; -import { _Constructor } from '@angular/material/core'; import { ControlValueAccessor } from '@angular/forms'; import { DoCheck } from '@angular/core'; import { ElementRef } from '@angular/core'; import { EventEmitter } from '@angular/core'; import { FocusMonitor } from '@angular/cdk/a11y'; import { FocusOrigin } from '@angular/cdk/a11y'; -import { HasTabIndex } from '@angular/material/core'; import * as i0 from '@angular/core'; import * as i2 from '@angular/material/core'; import * as i3 from '@angular/common'; @@ -41,18 +36,21 @@ export const MAT_RADIO_GROUP: InjectionToken; export const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any; // @public (undocumented) -export class MatRadioButton extends _MatRadioButtonMixinBase implements OnInit, AfterViewInit, DoCheck, OnDestroy, CanDisableRipple, HasTabIndex { - constructor(radioGroup: MatRadioGroup, elementRef: ElementRef, _changeDetector: ChangeDetectorRef, _focusMonitor: FocusMonitor, _radioDispatcher: UniqueSelectionDispatcher, animationMode?: string, _providerOverride?: MatRadioDefaultOptions | undefined, tabIndex?: string); +export class MatRadioButton implements OnInit, AfterViewInit, DoCheck, OnDestroy { + constructor(radioGroup: MatRadioGroup, _elementRef: ElementRef, _changeDetector: ChangeDetectorRef, _focusMonitor: FocusMonitor, _radioDispatcher: UniqueSelectionDispatcher, animationMode?: string, _providerOverride?: MatRadioDefaultOptions | undefined, tabIndex?: string); ariaDescribedby: string; ariaLabel: string; ariaLabelledby: string; readonly change: EventEmitter; get checked(): boolean; - set checked(value: BooleanInput); + set checked(value: boolean); get color(): ThemePalette; set color(newValue: ThemePalette); get disabled(): boolean; - set disabled(value: BooleanInput); + set disabled(value: boolean); + disableRipple: boolean; + // (undocumented) + protected _elementRef: ElementRef; focus(options?: FocusOptions, origin?: FocusOrigin): void; id: string; _inputElement: ElementRef; @@ -64,6 +62,16 @@ export class MatRadioButton extends _MatRadioButtonMixinBase implements OnInit, _markForCheck(): void; name: string; // (undocumented) + static ngAcceptInputType_checked: unknown; + // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_disableRipple: unknown; + // (undocumented) + static ngAcceptInputType_required: unknown; + // (undocumented) + static ngAcceptInputType_tabIndex: unknown; + // (undocumented) ngAfterViewInit(): void; // (undocumented) ngDoCheck(): void; @@ -78,12 +86,13 @@ export class MatRadioButton extends _MatRadioButtonMixinBase implements OnInit, _onTouchTargetClick(event: Event): void; radioGroup: MatRadioGroup; get required(): boolean; - set required(value: BooleanInput); + set required(value: boolean); protected _setDisabled(value: boolean): void; + tabIndex: number; get value(): any; set value(value: any); // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -112,7 +121,7 @@ export class MatRadioGroup implements AfterContentInit, OnDestroy, ControlValueA color: ThemePalette; _controlValueAccessorChangeFn: (value: any) => void; get disabled(): boolean; - set disabled(value: BooleanInput); + set disabled(value: boolean); _emitChangeEvent(): void; get labelPosition(): 'before' | 'after'; set labelPosition(v: 'before' | 'after'); @@ -120,6 +129,10 @@ export class MatRadioGroup implements AfterContentInit, OnDestroy, ControlValueA _markRadiosForCheck(): void; get name(): string; set name(value: string); + // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_required: unknown; ngAfterContentInit(): void; // (undocumented) ngOnDestroy(): void; @@ -128,7 +141,7 @@ export class MatRadioGroup implements AfterContentInit, OnDestroy, ControlValueA registerOnChange(fn: (value: any) => void): void; registerOnTouched(fn: any): void; get required(): boolean; - set required(value: BooleanInput); + set required(value: boolean); get selected(): MatRadioButton | null; set selected(selected: MatRadioButton | null); setDisabledState(isDisabled: boolean): void; diff --git a/tools/public_api_guard/material/select.md b/tools/public_api_guard/material/select.md index 7e34dce94f09..17c392c7ce2c 100644 --- a/tools/public_api_guard/material/select.md +++ b/tools/public_api_guard/material/select.md @@ -8,9 +8,6 @@ import { _AbstractConstructor } from '@angular/material/core'; import { ActiveDescendantKeyManager } from '@angular/cdk/a11y'; import { AfterContentInit } from '@angular/core'; import { AnimationTriggerMetadata } from '@angular/animations'; -import { BooleanInput } from '@angular/cdk/coercion'; -import { CanDisable } from '@angular/material/core'; -import { CanDisableRipple } from '@angular/material/core'; import { CanUpdateErrorState } from '@angular/material/core'; import { CdkConnectedOverlay } from '@angular/cdk/overlay'; import { CdkOverlayOrigin } from '@angular/cdk/overlay'; @@ -24,7 +21,6 @@ import { ElementRef } from '@angular/core'; import { ErrorStateMatcher } from '@angular/material/core'; import { EventEmitter } from '@angular/core'; import { FormGroupDirective } from '@angular/forms'; -import { HasTabIndex } from '@angular/material/core'; import * as i0 from '@angular/core'; import * as i2 from '@angular/common'; import * as i3 from '@angular/cdk/overlay'; @@ -41,7 +37,6 @@ import { MatOptionSelectionChange } from '@angular/material/core'; import { NgControl } from '@angular/forms'; import { NgForm } from '@angular/forms'; import { NgZone } from '@angular/core'; -import { NumberInput } from '@angular/cdk/coercion'; import { Observable } from 'rxjs'; import { OnChanges } from '@angular/core'; import { OnDestroy } from '@angular/core'; @@ -74,7 +69,7 @@ export function MAT_SELECT_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay: Overlay): ( export const MAT_SELECT_TRIGGER: InjectionToken; // @public (undocumented) -export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, OnChanges, OnDestroy, OnInit, DoCheck, ControlValueAccessor, CanDisable, HasTabIndex, MatFormFieldControl, CanUpdateErrorState, CanDisableRipple { +export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, OnChanges, OnDestroy, OnInit, DoCheck, ControlValueAccessor, MatFormFieldControl, CanUpdateErrorState { constructor(_viewportRuler: ViewportRuler, _changeDetectorRef: ChangeDetectorRef, _ngZone: NgZone, _defaultErrorStateMatcher: ErrorStateMatcher, elementRef: ElementRef, _dir: Directionality, _parentForm: NgForm, _parentFormGroup: FormGroupDirective, _parentFormField: MatFormField, ngControl: NgControl, tabIndex: string, scrollStrategyFactory: any, _liveAnnouncer: LiveAnnouncer, _defaultOptions?: MatSelectConfig | undefined); ariaLabel: string; ariaLabelledby: string; @@ -90,8 +85,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, // (undocumented) protected _defaultOptions?: MatSelectConfig | undefined; protected readonly _destroy: Subject; - get disableOptionCentering(): boolean; - set disableOptionCentering(value: BooleanInput); + disabled: boolean; + disableOptionCentering: boolean; + disableRipple: boolean; get empty(): boolean; errorStateMatcher: ErrorStateMatcher; focus(options?: FocusOptions): void; @@ -101,13 +97,29 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, _getPanelTheme(): string; _handleKeydown(event: KeyboardEvent): void; get hideSingleSelectionIndicator(): boolean; - set hideSingleSelectionIndicator(value: BooleanInput); + set hideSingleSelectionIndicator(value: boolean); get id(): string; set id(value: string); _isRtl(): boolean; _keyManager: ActiveDescendantKeyManager; get multiple(): boolean; - set multiple(value: BooleanInput); + set multiple(value: boolean); + // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_disableOptionCentering: unknown; + // (undocumented) + static ngAcceptInputType_disableRipple: unknown; + // (undocumented) + static ngAcceptInputType_hideSingleSelectionIndicator: unknown; + // (undocumented) + static ngAcceptInputType_multiple: unknown; + // (undocumented) + static ngAcceptInputType_required: unknown; + // (undocumented) + static ngAcceptInputType_tabIndex: unknown; + // (undocumented) + static ngAcceptInputType_typeaheadDebounceInterval: unknown; // (undocumented) ngAfterContentInit(): void; // (undocumented) @@ -154,7 +166,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, registerOnChange(fn: (value: any) => void): void; registerOnTouched(fn: () => {}): void; get required(): boolean; - set required(value: BooleanInput); + set required(value: boolean); _scrollOptionIntoView(index: number): void; _scrollStrategy: ScrollStrategy; get selected(): MatOption | MatOption[]; @@ -165,11 +177,11 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, get shouldLabelFloat(): boolean; sortComparator: (a: MatOption, b: MatOption, options: MatOption[]) => number; _syncParentProperties(): void; + tabIndex: number; toggle(): void; trigger: ElementRef; get triggerValue(): string; - get typeaheadDebounceInterval(): number; - set typeaheadDebounceInterval(value: NumberInput); + typeaheadDebounceInterval: number; userAriaDescribedBy: string; get value(): any; set value(newValue: any); @@ -179,7 +191,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit, protected _viewportRuler: ViewportRuler; writeValue(value: any): void; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/tools/public_api_guard/material/slider-testing.md b/tools/public_api_guard/material/slider-testing.md index 48e8e41fe714..5183a0eb337e 100644 --- a/tools/public_api_guard/material/slider-testing.md +++ b/tools/public_api_guard/material/slider-testing.md @@ -55,7 +55,7 @@ export interface SliderThumbHarnessFilters extends BaseHarnessFilters { } // @public -export const enum ThumbPosition { +export enum ThumbPosition { // (undocumented) END = 1, // (undocumented) diff --git a/tools/public_api_guard/material/slider.md b/tools/public_api_guard/material/slider.md index b21987e4e7c7..f79cdc91f3d3 100644 --- a/tools/public_api_guard/material/slider.md +++ b/tools/public_api_guard/material/slider.md @@ -4,13 +4,8 @@ ```ts -import { _AbstractConstructor } from '@angular/material/core'; import { AfterViewInit } from '@angular/core'; -import { BooleanInput } from '@angular/cdk/coercion'; -import { CanColor } from '@angular/material/core'; -import { CanDisableRipple } from '@angular/material/core'; import { ChangeDetectorRef } from '@angular/core'; -import { _Constructor } from '@angular/material/core'; import { ControlValueAccessor } from '@angular/forms'; import { Directionality } from '@angular/cdk/bidi'; import { ElementRef } from '@angular/core'; @@ -19,15 +14,15 @@ import * as i0 from '@angular/core'; import * as i4 from '@angular/material/core'; import { MatRipple } from '@angular/material/core'; import { NgZone } from '@angular/core'; -import { NumberInput } from '@angular/cdk/coercion'; import { OnDestroy } from '@angular/core'; import { QueryList } from '@angular/core'; import { RippleGlobalOptions } from '@angular/material/core'; import { Subject } from 'rxjs'; +import { ThemePalette } from '@angular/material/core'; // @public -export class MatSlider extends _MatSliderMixinBase implements AfterViewInit, CanDisableRipple, OnDestroy, _MatSlider { - constructor(_ngZone: NgZone, _cdr: ChangeDetectorRef, elementRef: ElementRef, _dir: Directionality, _globalRippleOptions?: RippleGlobalOptions | undefined, animationMode?: string); +export class MatSlider implements AfterViewInit, OnDestroy, _MatSlider { + constructor(_ngZone: NgZone, _cdr: ChangeDetectorRef, _elementRef: ElementRef, _dir: Directionality, _globalRippleOptions?: RippleGlobalOptions | undefined, animationMode?: string); // (undocumented) _cachedLeft: number; // (undocumented) @@ -35,14 +30,18 @@ export class MatSlider extends _MatSliderMixinBase implements AfterViewInit, Can _calcTickMarkTransform(index: number): string; // (undocumented) readonly _cdr: ChangeDetectorRef; + color: ThemePalette; // (undocumented) readonly _dir: Directionality; get disabled(): boolean; - set disabled(v: BooleanInput); + set disabled(v: boolean); + disableRipple: boolean; get discrete(): boolean; - set discrete(v: BooleanInput); + set discrete(v: boolean); displayWith: (value: number) => string; // (undocumented) + readonly _elementRef: ElementRef; + // (undocumented) _endThumbTransform: string; protected endValueIndicatorText: string; _getInput(thumbPosition: _MatThumb): _MatSliderThumb | _MatSliderRangeThumb | undefined; @@ -63,9 +62,23 @@ export class MatSlider extends _MatSliderMixinBase implements AfterViewInit, Can _isRtl: boolean; _knobRadius: number; get max(): number; - set max(v: NumberInput); + set max(v: number); get min(): number; - set min(v: NumberInput); + set min(v: number); + // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_disableRipple: unknown; + // (undocumented) + static ngAcceptInputType_discrete: unknown; + // (undocumented) + static ngAcceptInputType_max: unknown; + // (undocumented) + static ngAcceptInputType_min: unknown; + // (undocumented) + static ngAcceptInputType_showTickMarks: unknown; + // (undocumented) + static ngAcceptInputType_step: unknown; // (undocumented) ngAfterViewInit(): void; // (undocumented) @@ -93,13 +106,12 @@ export class MatSlider extends _MatSliderMixinBase implements AfterViewInit, Can }): void; // (undocumented) _setTransition(withAnimation: boolean): void; - get showTickMarks(): boolean; - set showTickMarks(v: BooleanInput); + showTickMarks: boolean; // (undocumented) _startThumbTransform: string; protected startValueIndicatorText: string; get step(): number; - set step(v: NumberInput); + set step(v: number); _thumbs: QueryList<_MatSliderVisualThumb>; _tickMarks: _MatTickMark[]; _tickMarkTrackWidth: number; @@ -110,7 +122,7 @@ export class MatSlider extends _MatSliderMixinBase implements AfterViewInit, Can _updateTrackUI(source: _MatSliderThumb): void; _updateValueIndicatorUI(source: _MatSliderThumb): void; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -197,7 +209,7 @@ export class MatSliderThumb implements _MatSliderThumb, OnDestroy, ControlValueA _clamp(v: number): number; protected readonly _destroyed: Subject; get disabled(): boolean; - set disabled(v: BooleanInput); + set disabled(v: boolean); readonly dragEnd: EventEmitter; readonly dragStart: EventEmitter; // (undocumented) @@ -219,9 +231,11 @@ export class MatSliderThumb implements _MatSliderThumb, OnDestroy, ControlValueA _isFocused: boolean; _knobRadius: number; get max(): number; - set max(v: NumberInput); + set max(v: number); get min(): number; - set min(v: NumberInput); + set min(v: number); + // (undocumented) + static ngAcceptInputType_value: unknown; // (undocumented) ngOnDestroy(): void; // (undocumented) @@ -252,7 +266,7 @@ export class MatSliderThumb implements _MatSliderThumb, OnDestroy, ControlValueA protected _slider: _MatSlider; // (undocumented) get step(): number; - set step(v: NumberInput); + set step(v: number); thumbPosition: _MatThumb; get translateX(): number; set translateX(v: number); @@ -272,7 +286,7 @@ export class MatSliderThumb implements _MatSliderThumb, OnDestroy, ControlValueA _updateWidthInactive(): void; // (undocumented) get value(): number; - set value(v: NumberInput); + set value(value: number); readonly valueChange: EventEmitter; _valuetext: string; writeValue(value: any): void; diff --git a/tools/public_api_guard/material/sort.md b/tools/public_api_guard/material/sort.md index 4acf67bd612f..69cac94228c8 100644 --- a/tools/public_api_guard/material/sort.md +++ b/tools/public_api_guard/material/sort.md @@ -4,14 +4,10 @@ ```ts -import { _AbstractConstructor } from '@angular/material/core'; import { AfterViewInit } from '@angular/core'; import { AnimationTriggerMetadata } from '@angular/animations'; import { AriaDescriber } from '@angular/cdk/a11y'; -import { BooleanInput } from '@angular/cdk/coercion'; -import { CanDisable } from '@angular/material/core'; import { ChangeDetectorRef } from '@angular/core'; -import { _Constructor } from '@angular/material/core'; import { ElementRef } from '@angular/core'; import { EventEmitter } from '@angular/core'; import { FocusMonitor } from '@angular/cdk/a11y'; @@ -50,16 +46,20 @@ export const MAT_SORT_HEADER_INTL_PROVIDER: { export function MAT_SORT_HEADER_INTL_PROVIDER_FACTORY(parentIntl: MatSortHeaderIntl): MatSortHeaderIntl; // @public -export class MatSort extends _MatSortBase implements CanDisable, HasInitialized, OnChanges, OnDestroy, OnInit { +export class MatSort extends _MatSortBase implements HasInitialized, OnChanges, OnDestroy, OnInit { constructor(_defaultOptions?: MatSortDefaultOptions | undefined); active: string; deregister(sortable: MatSortable): void; get direction(): SortDirection; set direction(direction: SortDirection); - get disableClear(): boolean; - set disableClear(v: BooleanInput); + disableClear: boolean; + disabled: boolean; getNextSortDirection(sortable: MatSortable): SortDirection; // (undocumented) + static ngAcceptInputType_disableClear: unknown; + // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) ngOnChanges(): void; // (undocumented) ngOnDestroy(): void; @@ -72,7 +72,7 @@ export class MatSort extends _MatSortBase implements CanDisable, HasInitialized, start: SortDirection; readonly _stateChanges: Subject; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration; + static ɵdir: i0.ɵɵDirectiveDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -101,7 +101,7 @@ export interface MatSortDefaultOptions { } // @public -export class MatSortHeader extends _MatSortHeaderBase implements CanDisable, MatSortable, OnDestroy, OnInit, AfterViewInit { +export class MatSortHeader implements MatSortable, OnDestroy, OnInit, AfterViewInit { constructor( _intl: MatSortHeaderIntl, _changeDetectorRef: ChangeDetectorRef, _sort: MatSort, _columnDef: MatSortHeaderColumnDef, _focusMonitor: FocusMonitor, _elementRef: ElementRef, _ariaDescriber?: AriaDescriber | null | undefined, defaultOptions?: MatSortDefaultOptions); @@ -109,8 +109,8 @@ export class MatSortHeader extends _MatSortHeaderBase implements CanDisable, Mat arrowPosition: SortHeaderArrowPosition; // (undocumented) _columnDef: MatSortHeaderColumnDef; - get disableClear(): boolean; - set disableClear(v: BooleanInput); + disableClear: boolean; + disabled: boolean; _disableViewStateAnimation: boolean; _getAriaSortAttribute(): "none" | "ascending" | "descending"; _getArrowDirectionState(): string; @@ -126,6 +126,10 @@ export class MatSortHeader extends _MatSortHeaderBase implements CanDisable, Mat _isDisabled(): boolean; _isSorted(): boolean; // (undocumented) + static ngAcceptInputType_disableClear: unknown; + // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) ngAfterViewInit(): void; // (undocumented) ngOnDestroy(): void; @@ -144,7 +148,7 @@ export class MatSortHeader extends _MatSortHeaderBase implements CanDisable, Mat _updateArrowDirection(): void; _viewState: ArrowViewStateTransition; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/tools/public_api_guard/material/stepper-testing.md b/tools/public_api_guard/material/stepper-testing.md index 0ce427142b12..95f789c6fe1d 100644 --- a/tools/public_api_guard/material/stepper-testing.md +++ b/tools/public_api_guard/material/stepper-testing.md @@ -66,7 +66,7 @@ export interface StepperHarnessFilters extends BaseHarnessFilters { } // @public -export const enum StepperOrientation { +export enum StepperOrientation { // (undocumented) HORIZONTAL = 0, // (undocumented) diff --git a/tools/public_api_guard/material/stepper.md b/tools/public_api_guard/material/stepper.md index 2d006f0b0f8e..a6e498f4ff66 100644 --- a/tools/public_api_guard/material/stepper.md +++ b/tools/public_api_guard/material/stepper.md @@ -4,20 +4,18 @@ ```ts -import { _AbstractConstructor } from '@angular/material/core'; import { AbstractControl } from '@angular/forms'; import { AfterContentInit } from '@angular/core'; import { AfterViewInit } from '@angular/core'; import { AnimationEvent as AnimationEvent_2 } from '@angular/animations'; import { AnimationTriggerMetadata } from '@angular/animations'; -import { CanColor } from '@angular/material/core'; import { CdkStep } from '@angular/cdk/stepper'; +import { CdkStepHeader } from '@angular/cdk/stepper'; import { CdkStepLabel } from '@angular/cdk/stepper'; import { CdkStepper } from '@angular/cdk/stepper'; import { CdkStepperNext } from '@angular/cdk/stepper'; import { CdkStepperPrevious } from '@angular/cdk/stepper'; import { ChangeDetectorRef } from '@angular/core'; -import { _Constructor } from '@angular/material/core'; import { Directionality } from '@angular/cdk/bidi'; import { ElementRef } from '@angular/core'; import { ErrorStateMatcher } from '@angular/material/core'; @@ -84,9 +82,10 @@ export class MatStepContent { } // @public (undocumented) -export class MatStepHeader extends _MatStepHeaderBase implements AfterViewInit, OnDestroy, CanColor { +export class MatStepHeader extends CdkStepHeader implements AfterViewInit, OnDestroy { constructor(_intl: MatStepperIntl, _focusMonitor: FocusMonitor, _elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef); active: boolean; + color: ThemePalette; disableRipple: boolean; errorMessage: string; focus(origin?: FocusOrigin, options?: FocusOptions): void; @@ -111,7 +110,7 @@ export class MatStepHeader extends _MatStepHeaderBase implements AfterViewInit, _stringLabel(): string | null; _templateLabel(): MatStepLabel | null; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/tools/public_api_guard/material/tabs.md b/tools/public_api_guard/material/tabs.md index 7f282bae581f..cf422b53791f 100644 --- a/tools/public_api_guard/material/tabs.md +++ b/tools/public_api_guard/material/tabs.md @@ -4,22 +4,16 @@ ```ts -import { _AbstractConstructor } from '@angular/material/core'; import { AfterContentChecked } from '@angular/core'; import { AfterContentInit } from '@angular/core'; import { AfterViewInit } from '@angular/core'; import { AnimationEvent as AnimationEvent_2 } from '@angular/animations'; import { AnimationTriggerMetadata } from '@angular/animations'; import { BehaviorSubject } from 'rxjs'; -import { BooleanInput } from '@angular/cdk/coercion'; -import { CanColor } from '@angular/material/core'; -import { CanDisable } from '@angular/material/core'; -import { CanDisableRipple } from '@angular/material/core'; import { CdkPortal } from '@angular/cdk/portal'; import { CdkPortalOutlet } from '@angular/cdk/portal'; import { ChangeDetectorRef } from '@angular/core'; import { ComponentFactoryResolver } from '@angular/core'; -import { _Constructor } from '@angular/material/core'; import { Direction } from '@angular/cdk/bidi'; import { Directionality } from '@angular/cdk/bidi'; import { ElementRef } from '@angular/core'; @@ -27,7 +21,6 @@ import { EventEmitter } from '@angular/core'; import { FocusableOption } from '@angular/cdk/a11y'; import { FocusMonitor } from '@angular/cdk/a11y'; import { FocusOrigin } from '@angular/cdk/a11y'; -import { HasTabIndex } from '@angular/material/core'; import * as i0 from '@angular/core'; import * as i10 from '@angular/material/core'; import * as i11 from '@angular/cdk/portal'; @@ -36,7 +29,6 @@ import * as i13 from '@angular/cdk/a11y'; import * as i9 from '@angular/common'; import { InjectionToken } from '@angular/core'; import { NgZone } from '@angular/core'; -import { NumberInput } from '@angular/cdk/coercion'; import { OnChanges } from '@angular/core'; import { OnDestroy } from '@angular/core'; import { OnInit } from '@angular/core'; @@ -101,8 +93,7 @@ export abstract class MatPaginatedTabHeader implements AfterContentChecked, Afte _checkPaginationEnabled(): void; _checkScrollingControls(): void; protected readonly _destroyed: Subject; - get disablePagination(): boolean; - set disablePagination(value: BooleanInput); + disablePagination: boolean; _disableScrollAfter: boolean; _disableScrollBefore: boolean; // (undocumented) @@ -127,6 +118,8 @@ export abstract class MatPaginatedTabHeader implements AfterContentChecked, Afte // (undocumented) abstract _nextPaginator: ElementRef; // (undocumented) + static ngAcceptInputType_disablePagination: unknown; + // (undocumented) ngAfterContentChecked(): void; // (undocumented) ngAfterContentInit(): void; @@ -145,7 +138,7 @@ export abstract class MatPaginatedTabHeader implements AfterContentChecked, Afte }; _scrollToLabel(labelIndex: number): void; get selectedIndex(): number; - set selectedIndex(value: NumberInput); + set selectedIndex(v: unknown); readonly selectFocusedIndex: EventEmitter; _setTabFocus(tabIndex: number): void; _showPaginationControls: boolean; @@ -165,7 +158,7 @@ export abstract class MatPaginatedTabHeader implements AfterContentChecked, Afte } // @public (undocumented) -export class MatTab extends _MatTabMixinBase implements CanDisable, OnInit, OnChanges, OnDestroy { +export class MatTab implements OnInit, OnChanges, OnDestroy { constructor(_viewContainerRef: ViewContainerRef, _closestTabGroup: any); ariaLabel: string; ariaLabelledby: string; @@ -173,10 +166,13 @@ export class MatTab extends _MatTabMixinBase implements CanDisable, OnInit, OnCh // (undocumented) _closestTabGroup: any; get content(): TemplatePortal | null; + disabled: boolean; _implicitContent: TemplateRef; isActive: boolean; labelClass: string | string[]; // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) ngOnChanges(changes: SimpleChanges): void; // (undocumented) ngOnDestroy(): void; @@ -185,7 +181,6 @@ export class MatTab extends _MatTabMixinBase implements CanDisable, OnInit, OnCh origin: number | null; position: number | null; readonly _stateChanges: Subject; - // (undocumented) get templateLabel(): MatTabLabel; set templateLabel(value: MatTabLabel); textLabel: string; @@ -258,24 +253,26 @@ export class MatTabContent { } // @public -export class MatTabGroup extends _MatTabGroupMixinBase implements AfterContentInit, AfterContentChecked, OnDestroy, CanColor, CanDisableRipple { - constructor(elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, defaultConfig?: MatTabsConfig, _animationMode?: string | undefined); +export class MatTabGroup implements AfterContentInit, AfterContentChecked, OnDestroy { + constructor(_elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, defaultConfig?: MatTabsConfig, _animationMode?: string | undefined); _allTabs: QueryList; readonly animationDone: EventEmitter; get animationDuration(): string; - set animationDuration(value: NumberInput); + set animationDuration(value: string | number); // (undocumented) _animationMode?: string | undefined; get backgroundColor(): ThemePalette; set backgroundColor(value: ThemePalette); + color: ThemePalette; get contentTabIndex(): number | null; - set contentTabIndex(value: NumberInput); - get disablePagination(): boolean; - set disablePagination(value: BooleanInput); - get dynamicHeight(): boolean; - set dynamicHeight(value: BooleanInput); + set contentTabIndex(value: number); + disablePagination: boolean; + disableRipple: boolean; + dynamicHeight: boolean; + // (undocumented) + readonly _elementRef: ElementRef; get fitInkBarToContent(): boolean; - set fitInkBarToContent(v: BooleanInput); + set fitInkBarToContent(value: boolean); readonly focusChange: EventEmitter; // (undocumented) _focusChanged(index: number): void; @@ -285,22 +282,36 @@ export class MatTabGroup extends _MatTabGroupMixinBase implements AfterContentIn _getTabLabelId(i: number): string; _handleClick(tab: MatTab, tabHeader: MatTabGroupBaseHeader, index: number): void; headerPosition: MatTabHeaderPosition; + // (undocumented) + static ngAcceptInputType_contentTabIndex: unknown; + // (undocumented) + static ngAcceptInputType_disablePagination: unknown; + // (undocumented) + static ngAcceptInputType_disableRipple: unknown; + // (undocumented) + static ngAcceptInputType_dynamicHeight: unknown; + // (undocumented) + static ngAcceptInputType_fitInkBarToContent: unknown; + // (undocumented) + static ngAcceptInputType_preserveContent: unknown; + // (undocumented) + static ngAcceptInputType_selectedIndex: unknown; + // (undocumented) + static ngAcceptInputType_stretchTabs: unknown; ngAfterContentChecked(): void; // (undocumented) ngAfterContentInit(): void; // (undocumented) ngOnDestroy(): void; - get preserveContent(): boolean; - set preserveContent(value: BooleanInput); + preserveContent: boolean; realignInkBar(): void; _removeTabBodyWrapperHeight(): void; get selectedIndex(): number | null; - set selectedIndex(value: NumberInput); + set selectedIndex(value: number); readonly selectedIndexChange: EventEmitter; readonly selectedTabChange: EventEmitter; _setTabBodyWrapperHeight(tabHeight: number): void; - get stretchTabs(): boolean; - set stretchTabs(v: BooleanInput); + stretchTabs: boolean; // (undocumented) _tabBodyWrapper: ElementRef; _tabFocusChanged(focusOrigin: FocusOrigin, index: number): void; @@ -309,7 +320,7 @@ export class MatTabGroup extends _MatTabGroupMixinBase implements AfterContentIn _tabs: QueryList; updatePagination(): void; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -327,8 +338,7 @@ export interface MatTabGroupBaseHeader { // @public export class MatTabHeader extends MatPaginatedTabHeader implements AfterContentChecked, AfterContentInit, AfterViewInit, OnDestroy { constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, viewportRuler: ViewportRuler, dir: Directionality, ngZone: NgZone, platform: Platform, animationMode?: string); - get disableRipple(): boolean; - set disableRipple(value: BooleanInput); + disableRipple: boolean; // (undocumented) _inkBar: MatInkBar; // (undocumented) @@ -338,6 +348,8 @@ export class MatTabHeader extends MatPaginatedTabHeader implements AfterContentC // (undocumented) _nextPaginator: ElementRef; // (undocumented) + static ngAcceptInputType_disableRipple: unknown; + // (undocumented) ngAfterContentInit(): void; // (undocumented) _previousPaginator: ElementRef; @@ -368,8 +380,9 @@ export class MatTabLabel extends CdkPortal { } // @public -export class MatTabLabelWrapper extends _MatTabLabelWrapperMixinBase implements CanDisable { +export class MatTabLabelWrapper extends _MatTabLabelWrapperMixinBase { constructor(elementRef: ElementRef); + disabled: boolean; // (undocumented) elementRef: ElementRef; focus(): void; @@ -378,17 +391,21 @@ export class MatTabLabelWrapper extends _MatTabLabelWrapperMixinBase implements // (undocumented) getOffsetWidth(): number; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration; + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ɵdir: i0.ɵɵDirectiveDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } // @public -export class MatTabLink extends _MatTabLinkMixinBase implements AfterViewInit, OnDestroy, CanDisable, CanDisableRipple, HasTabIndex, RippleTarget, FocusableOption { +export class MatTabLink extends _MatTabLinkMixinBase implements AfterViewInit, OnDestroy, RippleTarget, FocusableOption { constructor(_tabNavBar: MatTabNav, elementRef: ElementRef, globalRippleOptions: RippleGlobalOptions | null, tabIndex: string, _focusMonitor: FocusMonitor, animationMode?: string); get active(): boolean; - set active(value: BooleanInput); + set active(value: boolean); + disabled: boolean; + disableRipple: boolean; elementRef: ElementRef; focus(): void; // (undocumented) @@ -408,13 +425,23 @@ export class MatTabLink extends _MatTabLinkMixinBase implements AfterViewInit, O id: string; protected _isActive: boolean; // (undocumented) + static ngAcceptInputType_active: unknown; + // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_disableRipple: unknown; + // (undocumented) + static ngAcceptInputType_tabIndex: unknown; + // (undocumented) ngAfterViewInit(): void; // (undocumented) ngOnDestroy(): void; rippleConfig: RippleConfig & RippleGlobalOptions; get rippleDisabled(): boolean; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + tabIndex: number; + // (undocumented) + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -424,14 +451,13 @@ export class MatTabNav extends MatPaginatedTabHeader implements AfterContentChec constructor(elementRef: ElementRef, dir: Directionality, ngZone: NgZone, changeDetectorRef: ChangeDetectorRef, viewportRuler: ViewportRuler, platform: Platform, animationMode?: string, defaultConfig?: MatTabsConfig); // (undocumented) get animationDuration(): string; - set animationDuration(value: NumberInput); + set animationDuration(value: string | number); get backgroundColor(): ThemePalette; set backgroundColor(value: ThemePalette); color: ThemePalette; - get disableRipple(): boolean; - set disableRipple(value: BooleanInput); + disableRipple: boolean; get fitInkBarToContent(): boolean; - set fitInkBarToContent(v: BooleanInput); + set fitInkBarToContent(value: boolean); // (undocumented) _fitInkBarToContent: BehaviorSubject; // (undocumented) @@ -444,13 +470,18 @@ export class MatTabNav extends MatPaginatedTabHeader implements AfterContentChec // (undocumented) _nextPaginator: ElementRef; // (undocumented) + static ngAcceptInputType_disableRipple: unknown; + // (undocumented) + static ngAcceptInputType_fitInkBarToContent: unknown; + // (undocumented) + static ngAcceptInputType_stretchTabs: unknown; + // (undocumented) ngAfterContentInit(): void; // (undocumented) ngAfterViewInit(): void; // (undocumented) _previousPaginator: ElementRef; - get stretchTabs(): boolean; - set stretchTabs(v: BooleanInput); + stretchTabs: boolean; // (undocumented) _tabList: ElementRef; // (undocumented) @@ -460,7 +491,7 @@ export class MatTabNav extends MatPaginatedTabHeader implements AfterContentChec tabPanel?: MatTabNavPanel; updateActiveLink(): void; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/tools/public_api_guard/material/toolbar-testing.md b/tools/public_api_guard/material/toolbar-testing.md index ef7bf7f14a76..8bce42a06557 100644 --- a/tools/public_api_guard/material/toolbar-testing.md +++ b/tools/public_api_guard/material/toolbar-testing.md @@ -18,7 +18,7 @@ export class MatToolbarHarness extends ContentContainerComponentHarness; diff --git a/tools/public_api_guard/material/tree.md b/tools/public_api_guard/material/tree.md index ae35d952fc6c..282b39b0c376 100644 --- a/tools/public_api_guard/material/tree.md +++ b/tools/public_api_guard/material/tree.md @@ -23,7 +23,6 @@ import * as i0 from '@angular/core'; import * as i6 from '@angular/cdk/tree'; import * as i7 from '@angular/material/core'; import { IterableDiffers } from '@angular/core'; -import { NumberInput } from '@angular/cdk/coercion'; import { Observable } from 'rxjs'; import { OnDestroy } from '@angular/core'; import { OnInit } from '@angular/core'; @@ -44,8 +43,10 @@ export class MatNestedTreeNode extends CdkNestedTreeNode impleme ngOnInit(): void; // (undocumented) node: T; + get tabIndex(): number; + set tabIndex(value: number); // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration, "mat-nested-tree-node", ["matNestedTreeNode"], { "role": { "alias": "role"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "isExpandable": { "alias": "isExpandable"; "required": false; }; "isExpanded": { "alias": "isExpanded"; "required": false; }; "isDisabled": { "alias": "isDisabled"; "required": false; }; "node": { "alias": "matNestedTreeNode"; "required": false; }; }, { "activation": "activation"; "expandedChange": "expandedChange"; }, never, never, false, never>; + static ɵdir: i0.ɵɵDirectiveDeclaration, "mat-nested-tree-node", ["matNestedTreeNode"], { "node": { "alias": "matNestedTreeNode"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; }, { "activation": "activation"; "expandedChange": "expandedChange"; }, never, never, false, never>; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration, [null, null, null, { attribute: "tabindex"; }]>; } @@ -119,18 +120,21 @@ export class MatTreeNode extends CdkTreeNode implements CanDisab defaultTabIndex: number; // @deprecated get disabled(): boolean; - set disabled(value: BooleanInput); + set disabled(value: boolean); // (undocumented) protected _getTabindexAttribute(): number; // (undocumented) + static ngAcceptInputType_disabled: unknown; + // (undocumented) + static ngAcceptInputType_tabIndex: unknown; + // (undocumented) ngOnDestroy(): void; // (undocumented) ngOnInit(): void; // @deprecated - get tabIndex(): number; - set tabIndex(value: number); + tabIndex: number; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration, "mat-tree-node", ["matTreeNode"], { "role": { "alias": "role"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "isExpandable": { "alias": "isExpandable"; "required": false; }; "isExpanded": { "alias": "isExpanded"; "required": false; }; "isDisabled": { "alias": "isDisabled"; "required": false; }; }, { "activation": "activation"; "expandedChange": "expandedChange"; }, never, never, false, never>; + static ɵdir: i0.ɵɵDirectiveDeclaration, "mat-tree-node", ["matTreeNode"], { "tabIndex": { "alias": "tabIndex"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "activation": "activation"; "expandedChange": "expandedChange"; }, never, never, false, never>; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration, [null, null, { attribute: "tabindex"; }]>; } @@ -163,7 +167,9 @@ export class MatTreeNodePadding extends CdkTreeNodePadding { get indent(): number | string; set indent(indent: number | string); get level(): number; - set level(value: NumberInput); + set level(value: number); + // (undocumented) + static ngAcceptInputType_level: unknown; // (undocumented) static ɵdir: i0.ɵɵDirectiveDeclaration, "[matTreeNodePadding]", never, { "level": { "alias": "matTreeNodePadding"; "required": false; }; "indent": { "alias": "matTreeNodePaddingIndent"; "required": false; }; }, {}, never, never, false, never>; // (undocumented) diff --git a/tools/tslint-rules/preferConstEnumRule.ts b/tools/tslint-rules/preferPlainEnumRule.ts similarity index 61% rename from tools/tslint-rules/preferConstEnumRule.ts rename to tools/tslint-rules/preferPlainEnumRule.ts index 0e7f7bbfe136..4471d8df62d0 100644 --- a/tools/tslint-rules/preferConstEnumRule.ts +++ b/tools/tslint-rules/preferPlainEnumRule.ts @@ -2,7 +2,7 @@ import ts from 'typescript'; import * as Lint from 'tslint'; /** - * Rule that enforces that we use `const enum` rather than a plain `enum`. + * Rule that enforces that we use plain `enum` rather than `const enum`. */ export class Rule extends Lint.Rules.AbstractRule { apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { @@ -12,8 +12,8 @@ export class Rule extends Lint.Rules.AbstractRule { class Walker extends Lint.RuleWalker { override visitEnumDeclaration(node: ts.EnumDeclaration) { - if (!node.modifiers?.some(({kind}) => kind === ts.SyntaxKind.ConstKeyword)) { - this.addFailureAtNode(node.name, 'Enums should be declared as `const enum`.'); + if (node.modifiers?.some(({kind}) => kind === ts.SyntaxKind.ConstKeyword)) { + this.addFailureAtNode(node.name, 'Const enums are not allowed! Prefer plain `enum` instead.'); } super.visitEnumDeclaration(node); diff --git a/tslint.json b/tslint.json index a4231a4d61f5..30188ce90a60 100644 --- a/tslint.json +++ b/tslint.json @@ -68,7 +68,7 @@ "lifecycle-hook-interface": true, "require-breaking-change-version": true, "no-nested-ternary": true, - "prefer-const-enum": true, + "prefer-plain-enum": true, "no-lifecycle-invocation": [true, "**/!(*.spec).ts"], "lightweight-tokens": [ true, diff --git a/yarn.lock b/yarn.lock index 243018274eea..6b15526b951f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,103 +25,23 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@angular-devkit/architect@0.1700.0-next.6": - version "0.1700.0-next.6" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1700.0-next.6.tgz#8ac2f298f4314bed29cc11da766ea86c4957a339" - integrity sha512-kSC6JwKOpbiOUn9VYdSy/u4gZRGSLl5rNPrVnLBv2A7OSDcNKMGYBzW9k9DxK6y4JW8LGArqBkitwymEoD1MWw== +"@angular-devkit/architect@0.1700.0-rc.3": + version "0.1700.0-rc.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1700.0-rc.3.tgz#f000f5b041aa6811f93af10921d32485d94c29c0" + integrity sha512-bXnqMmZBlRxpQOIsk+HHELGu/kKHRFlhs8JSiJpwvj16jWEDcRCKwXE5yTr6Q1YqVieMpnYzYTkdAVNCtpfk2A== dependencies: - "@angular-devkit/core" "17.0.0-next.6" + "@angular-devkit/core" "17.0.0-rc.3" rxjs "7.8.1" -"@angular-devkit/architect@0.1700.0-rc.0": - version "0.1700.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1700.0-rc.0.tgz#a7d56181ee84d9ffc02236132908b0ebca0c673e" - integrity sha512-vdLd+LBneWqgdE2+MA1Vdg7NyIHcEixYOGCoWjdDQpxjOCAZ7PCnWzDWGc+SxUJ/yAzmbh+nAyFQ8m9TEKaf1A== - dependencies: - "@angular-devkit/core" "17.0.0-rc.0" - rxjs "7.8.1" - -"@angular-devkit/build-angular@17.0.0-next.6": - version "17.0.0-next.6" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.0.0-next.6.tgz#212bf083ca7868a0e539bc689e0292cffe62cbce" - integrity sha512-w7Ofqp4cBtdu94G9MApEzH5N50mrfpv/4na3qGWAv1uQJRzXsL5R13grNevOy88u8XXXh9vR5clSXexmzjskxw== +"@angular-devkit/build-angular@17.0.0-rc.3", "@angular-devkit/build-angular@^17.0.0-rc.3": + version "17.0.0-rc.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.0.0-rc.3.tgz#ca1e32aebe7dad23faf2b9cb17f76bbd1772c5fd" + integrity sha512-XXlS5Gw6G5VpDaTSq+mPao3hdZZNfjQy9yoiFD1KDxHHavstOhIkgacD0v5fU0JGT/KBlqTr68wqBRMX+f+FMA== dependencies: "@ampproject/remapping" "2.2.1" - "@angular-devkit/architect" "0.1700.0-next.6" - "@angular-devkit/build-webpack" "0.1700.0-next.6" - "@angular-devkit/core" "17.0.0-next.6" - "@babel/core" "7.22.17" - "@babel/generator" "7.22.15" - "@babel/helper-annotate-as-pure" "7.22.5" - "@babel/helper-split-export-declaration" "7.22.6" - "@babel/plugin-transform-async-generator-functions" "7.22.15" - "@babel/plugin-transform-async-to-generator" "7.22.5" - "@babel/plugin-transform-runtime" "7.22.15" - "@babel/preset-env" "7.22.15" - "@babel/runtime" "7.22.15" - "@discoveryjs/json-ext" "0.5.7" - "@ngtools/webpack" "17.0.0-next.6" - "@vitejs/plugin-basic-ssl" "1.0.1" - ansi-colors "4.1.3" - autoprefixer "10.4.15" - babel-loader "9.1.3" - babel-plugin-istanbul "6.1.1" - browser-sync "2.29.3" - browserslist "^4.21.5" - chokidar "3.5.3" - copy-webpack-plugin "11.0.0" - critters "0.0.20" - css-loader "6.8.1" - esbuild-wasm "0.19.3" - fast-glob "3.3.1" - http-proxy-middleware "2.0.6" - https-proxy-agent "7.0.2" - inquirer "8.2.6" - jsonc-parser "3.2.0" - karma-source-map-support "1.4.0" - less "4.2.0" - less-loader "11.1.0" - license-webpack-plugin "4.0.2" - loader-utils "3.2.1" - magic-string "0.30.3" - mini-css-extract-plugin "2.7.6" - mrmime "1.0.1" - open "8.4.2" - ora "5.4.1" - parse5-html-rewriting-stream "7.0.0" - picomatch "2.3.1" - piscina "4.1.0" - postcss "8.4.29" - postcss-loader "7.3.3" - resolve-url-loader "5.0.0" - rxjs "7.8.1" - sass "1.67.0" - sass-loader "13.3.2" - semver "7.5.4" - source-map-loader "4.0.1" - source-map-support "0.5.21" - terser "5.19.4" - text-table "0.2.0" - tree-kill "1.2.2" - tslib "2.6.2" - vite "4.4.9" - webpack "5.88.2" - webpack-dev-middleware "6.1.1" - webpack-dev-server "4.15.1" - webpack-merge "5.9.0" - webpack-subresource-integrity "5.1.0" - optionalDependencies: - esbuild "0.19.3" - -"@angular-devkit/build-angular@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.0.0-rc.0.tgz#815b327facf8564145d220413f14e17a15f0b82e" - integrity sha512-mkEtCuv/oULO+jSafdgfU9k9iEK786mxMw3FflfQoUnTYtXm1WJZoMyUn/tFsDAus5PTSqkO0N388sC9N07o2w== - dependencies: - "@ampproject/remapping" "2.2.1" - "@angular-devkit/architect" "0.1700.0-rc.0" - "@angular-devkit/build-webpack" "0.1700.0-rc.0" - "@angular-devkit/core" "17.0.0-rc.0" + "@angular-devkit/architect" "0.1700.0-rc.3" + "@angular-devkit/build-webpack" "0.1700.0-rc.3" + "@angular-devkit/core" "17.0.0-rc.3" "@babel/core" "7.23.2" "@babel/generator" "7.23.0" "@babel/helper-annotate-as-pure" "7.22.5" @@ -132,7 +52,7 @@ "@babel/preset-env" "7.23.2" "@babel/runtime" "7.23.2" "@discoveryjs/json-ext" "0.5.7" - "@ngtools/webpack" "17.0.0-rc.0" + "@ngtools/webpack" "17.0.0-rc.3" "@vitejs/plugin-basic-ssl" "1.0.1" ansi-colors "4.1.3" autoprefixer "10.4.16" @@ -148,7 +68,7 @@ fast-glob "3.3.1" http-proxy-middleware "2.0.6" https-proxy-agent "7.0.2" - inquirer "8.2.6" + inquirer "9.2.11" jsonc-parser "3.2.0" karma-source-map-support "1.4.0" less "4.2.0" @@ -161,21 +81,22 @@ open "8.4.2" ora "5.4.1" parse5-html-rewriting-stream "7.0.0" - picomatch "2.3.1" + picomatch "3.0.1" piscina "4.1.0" postcss "8.4.31" postcss-loader "7.3.3" resolve-url-loader "5.0.0" rxjs "7.8.1" - sass "1.67.0" + sass "1.69.5" sass-loader "13.3.2" semver "7.5.4" source-map-loader "4.0.1" source-map-support "0.5.21" - terser "5.22.0" + terser "5.24.0" text-table "0.2.0" tree-kill "1.2.2" tslib "2.6.2" + undici "5.27.0" vite "4.5.0" webpack "5.89.0" webpack-dev-middleware "6.1.1" @@ -185,61 +106,41 @@ optionalDependencies: esbuild "0.19.5" -"@angular-devkit/build-webpack@0.1700.0-next.6": - version "0.1700.0-next.6" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1700.0-next.6.tgz#b4174ab0e7bf197f6e84135b49d6249fe9e4b1db" - integrity sha512-ik+aZfDZzOW0xxBNRrf1h/0fV+O3FCVHxDlpDdhnrLiecVH78TgOHn1vHKzg2y6chSL3yYyUXeYQ3i0ttr5gtg== - dependencies: - "@angular-devkit/architect" "0.1700.0-next.6" - rxjs "7.8.1" - -"@angular-devkit/build-webpack@0.1700.0-rc.0": - version "0.1700.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1700.0-rc.0.tgz#d8c58d381340056c6e8864e6b0e24a4581fed750" - integrity sha512-U4qK4V9mxPlVRlFQ2LERnUmvhKp1CiP0T1FdJ4llxWP5UXjJBrzchYlcdcrU1lQjydDXBGPxI5cJFR0zsEv6hQ== +"@angular-devkit/build-webpack@0.1700.0-rc.3": + version "0.1700.0-rc.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1700.0-rc.3.tgz#176f212592859a38067b4ef200756b90e85c1d39" + integrity sha512-0xcbhED5LM69oOItTGglxTHKNt7w9UM8ziQ8lKYHLEXV4ZwjhZvHcFSQ8EADqrWVcgXNLfN4x3fVHJQ6Plce3A== dependencies: - "@angular-devkit/architect" "0.1700.0-rc.0" + "@angular-devkit/architect" "0.1700.0-rc.3" rxjs "7.8.1" -"@angular-devkit/core@17.0.0-next.6": - version "17.0.0-next.6" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.0.0-next.6.tgz#e939e86c5b74f5f8b9abbc9cdb16bb6d0998c2de" - integrity sha512-KfuXWSV9BU2dKEEpAwVJFjuvUdlqFzZD1vGqZpbXtaKnRAwqbEChy1nQJNin0E4gJ1XXFDmCv/gcGasDV3r1wg== +"@angular-devkit/core@17.0.0-rc.3", "@angular-devkit/core@^17.0.0-rc.3": + version "17.0.0-rc.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.0.0-rc.3.tgz#b7b95e2d5d72f5285dfbf55c4de1d039b09992dd" + integrity sha512-cPSWBXm7CSpSG+JLR2khKEFLWfkfZKgKsAZVlHdpXgICc3fmtSG/01ZSAD84oq5Ch5l1+6P62P+4fjwex9joZA== dependencies: ajv "8.12.0" ajv-formats "2.1.1" jsonc-parser "3.2.0" - picomatch "2.3.1" + picomatch "3.0.1" rxjs "7.8.1" source-map "0.7.4" -"@angular-devkit/core@17.0.0-rc.0", "@angular-devkit/core@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.0.0-rc.0.tgz#ca0ed9b081ed01642bf0d4244b13025d078b6512" - integrity sha512-xSXwtYHTj12dG9Sd3SzKlwcJNTkADuS5xmlYUzbqtzZXit9BMiJ+wBEvBVVj6wdEUq1xgLmDmK6Ne7xgUmtRiQ== +"@angular-devkit/schematics@17.0.0-rc.3", "@angular-devkit/schematics@^17.0.0-rc.3": + version "17.0.0-rc.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.0.0-rc.3.tgz#b58134dac5e1581f66650878b17386441771dd09" + integrity sha512-QewQ15pdnvWTAvcf3oWvFv+El6DWOYrvaNs+r4lzikx9dYIM4L/NruD32AEYt4xM1livy3ndRxnQQ8A7DM/BrQ== dependencies: - ajv "8.12.0" - ajv-formats "2.1.1" - jsonc-parser "3.2.0" - picomatch "2.3.1" - rxjs "7.8.1" - source-map "0.7.4" - -"@angular-devkit/schematics@17.0.0-rc.0", "@angular-devkit/schematics@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.0.0-rc.0.tgz#c0c5a33eee4f856ad6b086a8c31a408a2fada482" - integrity sha512-RQGevShl5lNa3EXbq2DVZ4yay0ipkeudcRyePxPurLy+ZkR+KRVwXt/MH0UoszXE0g5ulKexW3XXCI8cemu3Vw== - dependencies: - "@angular-devkit/core" "17.0.0-rc.0" + "@angular-devkit/core" "17.0.0-rc.3" jsonc-parser "3.2.0" magic-string "0.30.5" ora "5.4.1" rxjs "7.8.1" -"@angular/animations@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-17.0.0-rc.0.tgz#f94f0535ed3e9776b4518ea5703ee11c9e5cbb71" - integrity sha512-HWYuLoGBMl4sQW8KCK4ursNJecKjvgVPlWezR4jccsWlARzMyP5eGixCd8gYC4uaiMgpe9wrFOtAvuXu/smJWA== +"@angular/animations@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-17.0.0-rc.2.tgz#4f2b14f2ae31bb4e4e29054ca94e1d12629bd7de" + integrity sha512-g6Nzcfls89fYdi6LQcZr1rOZots7667QDUtfbkhlt5UMC8MNbKSuSLjIpl7JwZtRl352HnhwhWM4bMchOQ7VDg== dependencies: tslib "^2.3.0" @@ -260,23 +161,23 @@ "@angular/core" "^13.0.0 || ^14.0.0-0" reflect-metadata "^0.1.13" -"@angular/build-tooling@https://github.com/angular/dev-infra-private-build-tooling-builds.git#28072768cb6624221b17766a7f571b6d9e5d55e6": - version "0.0.0-52c2fa858076a6397ee3d0efb97b22f3870dd2d6" - resolved "https://github.com/angular/dev-infra-private-build-tooling-builds.git#28072768cb6624221b17766a7f571b6d9e5d55e6" +"@angular/build-tooling@https://github.com/angular/dev-infra-private-build-tooling-builds.git#d05af145e0e0effa8ff2d0abb8e2fdb1ede584ab": + version "0.0.0-e0ec7b60641d7f6369be45d8d02663fd50f320be" + resolved "https://github.com/angular/dev-infra-private-build-tooling-builds.git#d05af145e0e0effa8ff2d0abb8e2fdb1ede584ab" dependencies: - "@angular-devkit/build-angular" "17.0.0-next.6" + "@angular-devkit/build-angular" "17.0.0-rc.3" "@angular/benchpress" "0.3.0" "@babel/core" "^7.16.0" "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/plugin-proposal-async-generator-functions" "^7.20.1" - "@bazel/buildifier" "6.1.2" + "@bazel/buildifier" "6.3.3" "@bazel/concatjs" "5.8.1" "@bazel/esbuild" "5.8.1" "@bazel/protractor" "5.8.1" "@bazel/runfiles" "5.8.1" "@bazel/terser" "5.8.1" "@bazel/typescript" "5.8.1" - "@microsoft/api-extractor" "7.38.0" + "@microsoft/api-extractor" "7.38.1" "@types/browser-sync" "^2.26.3" "@types/marked" "^5.0.1" "@types/node" "16.10.9" @@ -284,7 +185,7 @@ "@types/send" "^0.17.1" "@types/tmp" "^0.2.1" "@types/uuid" "^9.0.0" - "@types/ws" "8.5.6" + "@types/ws" "8.5.8" "@types/yargs" "^17.0.0" browser-sync "^2.27.7" clang-format "1.8.0" @@ -293,7 +194,7 @@ preact-render-to-string "^6.2.1" prettier "3.0.3" protractor "^7.0.0" - selenium-webdriver "4.13.0" + selenium-webdriver "4.14.0" send "^0.18.0" source-map "^0.7.4" tmp "^0.2.1" @@ -303,19 +204,19 @@ uuid "^9.0.0" yargs "^17.0.0" -"@angular/cli@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-17.0.0-rc.0.tgz#c8851cc11756c7d6e7a74e17e46b7691a698af6a" - integrity sha512-BM+VW4CNi42a2GC6cs0LN5a5Z2DIdfwoMjEQVJxaxe1vdR7sGcLJEpb4+dyiTEAFGJELGgYoSY9QhSefsb+SKg== +"@angular/cli@^17.0.0-rc.3": + version "17.0.0-rc.3" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-17.0.0-rc.3.tgz#40c2d8e12196db971efdf31fb5d217ba465e208a" + integrity sha512-7R/o1N0YuEWeFpK5w5JzXQTSu4HuAu7EtzOF9aDf1Qay1A/fDtk1QAjpMZDmXpbqg3xYDY7LqWqGuc1CCgaQZg== dependencies: - "@angular-devkit/architect" "0.1700.0-rc.0" - "@angular-devkit/core" "17.0.0-rc.0" - "@angular-devkit/schematics" "17.0.0-rc.0" - "@schematics/angular" "17.0.0-rc.0" + "@angular-devkit/architect" "0.1700.0-rc.3" + "@angular-devkit/core" "17.0.0-rc.3" + "@angular-devkit/schematics" "17.0.0-rc.3" + "@schematics/angular" "17.0.0-rc.3" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.3" ini "4.1.1" - inquirer "8.2.6" + inquirer "9.2.11" jsonc-parser "3.2.0" npm-package-arg "11.0.1" npm-pick-manifest "9.0.0" @@ -327,17 +228,17 @@ symbol-observable "4.0.0" yargs "17.7.2" -"@angular/common@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-17.0.0-rc.0.tgz#5fb4412a57bf81a8b0eb042f7e5177a0066bd8b9" - integrity sha512-Pb1I1qX46WxDxEVhZ5U3AmGjNPS8fg+a1PUzTO7VP78bOK/LhrtBS8RX6BuVAVx4LQwJ0FxAVu9Hukdlq+d6+A== +"@angular/common@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-17.0.0-rc.2.tgz#768645b62defb74839c4fd329a15105af2d8643f" + integrity sha512-q+9LwLvSUJXjI+CYqC1BJLxSSy2NIN1B2k/iyROhLje+V8jPdZyA5MZjRGMwqL8QXeH0qvIh/tetmf0QXahXSA== dependencies: tslib "^2.3.0" -"@angular/compiler-cli@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-17.0.0-rc.0.tgz#8aa7a065effe6d86f9203b62bc79b291892bbaa0" - integrity sha512-t+8nvnptRxORkEiBi+y8yymZQY0ci5VaacWBJEg3vgdVd8Ic0evVKrrzEpiW6Wih9uVIW/ZQzfKEuPIGPsEO0w== +"@angular/compiler-cli@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-17.0.0-rc.2.tgz#e1d65def8ef735ac7c8112272b6be5552b3c1c85" + integrity sha512-PEQxfzi63GzNdyaJcD1p9mAHhguC8mNvmoh53Bl69z6urgnCtIQRVq/AZ3aOYdEbt6LwFC8xOUeQ9Cj8Ti28jA== dependencies: "@babel/core" "7.23.2" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -348,10 +249,10 @@ tslib "^2.3.0" yargs "^17.2.1" -"@angular/compiler@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-17.0.0-rc.0.tgz#79b36b02380b1a60105e5c19c258c820a0ca164f" - integrity sha512-8DF4q7yweTsRkkc1CJ+X6NfXOchHjCHjUiWzK76ekBXczJMNPk83EkkyTdyEphJ7U0F1NJx9bFEtXA0q4xo5MA== +"@angular/compiler@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-17.0.0-rc.2.tgz#c56e6414655307cc9736352ff32315e1a59567b2" + integrity sha512-E8URFYjTReFU1AUOJjomnYfxmF77JcpskfCtgYCl5aKCV7Yick01mnNFn/g7XoSCH1+cKjCbVOAr2JgRfoOIhg== dependencies: tslib "^2.3.0" @@ -362,62 +263,62 @@ dependencies: tslib "^2.3.0" -"@angular/core@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-17.0.0-rc.0.tgz#e8553ee873244b5b56cd629ca36d97d17f28f9f4" - integrity sha512-gzxOE5HTZkLCW/jFRVXgEDQjpCndWIzeaMedAGxo431wdz9Yn33iqgSipmXKwdruLHzKN0p8ZKF1YhgsAgYPwA== +"@angular/core@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-17.0.0-rc.2.tgz#2d76f0f92586e39bbae9a91fe9311f8cb5ed41bd" + integrity sha512-EULe5FUEjtkoUwAAh9j08bRUhpV+vvtF6sCAun5iXl/RR1dO3Tdz4TZG9+zXwpMvyUVuMWUt8RsvCTbv6m2KRw== dependencies: tslib "^2.3.0" -"@angular/forms@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-17.0.0-rc.0.tgz#57002d12e815a15c0b9063b0ee53ef85b2665843" - integrity sha512-1+UUttZI21d3x59QYAsVXOksSSyXR8wEyGMHKOddCAk+VtEMoY9gZXSO+S1YHPjvXcxfqlcHv2f8HKmG63glRA== +"@angular/forms@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-17.0.0-rc.2.tgz#b138c9b78e81e4187e48ee0c162b9fb59e328129" + integrity sha512-X64uuIamPAvqsG/WezCCbEJCQPunOliAegQivwvJbl8fh/L8tYdk5Qt4yBFkgSWAKBFVwTWw0m73OYnTGa4Rsw== dependencies: tslib "^2.3.0" -"@angular/localize@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-17.0.0-rc.0.tgz#8a408a862dacb6e3a503d329bc1e95a4e9421de3" - integrity sha512-fDQ1v8hLgn1CXO5hEPIfNm9VNMdi4YNyqxdyFkXtl4w9cNANohItyPvtYn4QsNCNp8di8rfUrsHmd7SnTnSR1g== +"@angular/localize@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-17.0.0-rc.2.tgz#4fd3e54b4040421e5bf79e650198ba87277aa6da" + integrity sha512-VWPdnk7wosrNxfhG8PVGSdyOdznzKmVz5IwV2pDm4kTGxjFbzbIDTYXQoGeW9VhIUSeWcY6ZzqZTnr17Tdgs2g== dependencies: "@babel/core" "7.23.2" fast-glob "3.3.1" yargs "^17.2.1" -"@angular/ng-dev@https://github.com/angular/dev-infra-private-ng-dev-builds.git#16b9f550b766b52f51dc5580cbac13378a1ab5f4": - version "0.0.0-52c2fa858076a6397ee3d0efb97b22f3870dd2d6" - resolved "https://github.com/angular/dev-infra-private-ng-dev-builds.git#16b9f550b766b52f51dc5580cbac13378a1ab5f4" +"@angular/ng-dev@https://github.com/angular/dev-infra-private-ng-dev-builds.git#f10010d0d3d96919644bb97f09d11ba678929e9b": + version "0.0.0-e0ec7b60641d7f6369be45d8d02663fd50f320be" + resolved "https://github.com/angular/dev-infra-private-ng-dev-builds.git#f10010d0d3d96919644bb97f09d11ba678929e9b" dependencies: "@yarnpkg/lockfile" "^1.1.0" typescript "~4.9.0" -"@angular/platform-browser-dynamic@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.0.0-rc.0.tgz#037f960160d9e0d714cc192b29e04f2b9a6b5c22" - integrity sha512-afnh679vBCec+qhmWLyx+YrgMGBwvVLfdsMCUsEmx1DiczMCa1NpmWCX0yXP78/1WUQusNfEbfCierU9NPwmvA== +"@angular/platform-browser-dynamic@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.0.0-rc.2.tgz#3eaa8de99545c6f584139f90e9113ad162b6a750" + integrity sha512-U3aq/uVp8DeT96uhZWORqR4p+9Z9V1LzqwPXGebmJflSnBXns5iZGAeDK8izuT4LWKljB49Pf45DfPfhcuJJ+w== dependencies: tslib "^2.3.0" -"@angular/platform-browser@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-17.0.0-rc.0.tgz#aacb8367b0ff3dc48a010470fa10eae86c5499b9" - integrity sha512-2KNDqWscM5BheIUt4JckEkkhR4WSboxXL+KPelxapoUtns08/ApjkOjF92W3ihhIVZ+PwJfyIFMw7FcgvQoRaw== +"@angular/platform-browser@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-17.0.0-rc.2.tgz#4e7f66dec7677d420239413d16d520d5d39c5bff" + integrity sha512-eFtHNkkRx3GVLTEd5NlIa8d59BNmbVMejHW8ZWZsG9317wW7HM19REORS0JisvkuBkoUoHurqo5DBliDYeTUzw== dependencies: tslib "^2.3.0" -"@angular/platform-server@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-17.0.0-rc.0.tgz#f958e70e58d08479e47fb59846770b23e3051e36" - integrity sha512-RWQ430esYfBpxUIQXAJc7GnnsnynCPLYKJYTKW0PrA/HyKuHGh9n3NBn0V9p7PxM9Mo4w47HGvFbA68pmkhtkQ== +"@angular/platform-server@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-17.0.0-rc.2.tgz#fdf7b0edea038d7bdf16104ab35591d0249011a7" + integrity sha512-IVo8hrkZY9l1ep68E97yK13JTaCk4QLA29mTAsAHXf1ECHtFjeBERE8/rbh/UujSEnVQm2xQ1ZaHwmIYX+y9Fg== dependencies: tslib "^2.3.0" xhr2 "^0.2.0" -"@angular/router@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-17.0.0-rc.0.tgz#ae913790757182fffb29a189441303dfacaddf5a" - integrity sha512-ljoh/5Rr4Pw0xqonqCkR1cWMsWsEwtFkSy9Ze2ufxSR6l4b+HMj7vKDUPXRwOY5cuIkIw10FMjb6NPqesjI4qA== +"@angular/router@^17.0.0-rc.2": + version "17.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-17.0.0-rc.2.tgz#b5e54602c6d5edafca5208d5ed56b827c418ed1a" + integrity sha512-i2DEIVAd1HHenV6a+SDjzc5hvmPfJlmmKw2ypQgjQz/F4Ca6hlw6wdxFwoJktZ9WW5gBRAo8+UYwFy+Xw8ldAw== dependencies: tslib "^2.3.0" @@ -485,27 +386,6 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== -"@babel/core@7.22.17": - version "7.22.17" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.17.tgz#2f9b0b395985967203514b24ee50f9fd0639c866" - integrity sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.22.15" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.22.17" - "@babel/helpers" "^7.22.15" - "@babel/parser" "^7.22.16" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.22.17" - "@babel/types" "^7.22.17" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - "@babel/core@7.23.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" @@ -548,16 +428,6 @@ json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@7.22.15", "@babel/generator@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.15.tgz#1564189c7ec94cb8f77b5e8a90c4d200d21b2339" - integrity sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA== - dependencies: - "@babel/types" "^7.22.15" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - "@babel/generator@7.23.0", "@babel/generator@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" @@ -707,17 +577,6 @@ regexpu-core "^5.3.1" semver "^6.3.0" -"@babel/helper-define-polyfill-provider@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7" - integrity sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw== - dependencies: - "@babel/helper-compilation-targets" "^7.22.6" - "@babel/helper-plugin-utils" "^7.22.5" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - "@babel/helper-define-polyfill-provider@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba" @@ -860,17 +719,6 @@ "@babel/traverse" "^7.17.3" "@babel/types" "^7.17.0" -"@babel/helper-module-transforms@^7.22.15", "@babel/helper-module-transforms@^7.22.17": - version "7.22.17" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz#7edf129097a51ccc12443adbc6320e90eab76693" - integrity sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.15" - "@babel/helper-module-transforms@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" @@ -885,17 +733,6 @@ "@babel/traverse" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/helper-module-transforms@^7.22.9": - version "7.22.9" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" - integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-module-imports" "^7.22.5" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.5" - "@babel/helper-module-transforms@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" @@ -963,15 +800,6 @@ "@babel/helper-wrap-function" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/helper-remap-async-to-generator@^7.22.9": - version "7.22.17" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.17.tgz#dabaa50622b3b4670bd6546fc8db23eb12d89da0" - integrity sha512-bxH77R5gjH3Nkde6/LuncQoLaP16THYPscurp1S8z7S9ZgezCyV3G8Hc+TZiCmY8pz4fp8CvKSgtJMW0FkLAxA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-wrap-function" "^7.22.17" - "@babel/helper-replace-supers@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz#71bc5fb348856dea9fdc4eafd7e2e49f585145dc" @@ -1097,15 +925,6 @@ "@babel/traverse" "^7.18.9" "@babel/types" "^7.18.9" -"@babel/helper-wrap-function@^7.22.17": - version "7.22.17" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.17.tgz#222ac3ff9cc8f9b617cc1e5db75c0b538e722801" - integrity sha512-nAhoheCMlrqU41tAojw9GpVEKDlTS8r3lzFmF0lP52LwblCPbuFSO7nGIZoIcoU5NIm1ABrna0cJExE4Ay6l2Q== - dependencies: - "@babel/helper-function-name" "^7.22.5" - "@babel/template" "^7.22.15" - "@babel/types" "^7.22.17" - "@babel/helper-wrap-function@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" @@ -1134,15 +953,6 @@ "@babel/traverse" "^7.17.9" "@babel/types" "^7.17.0" -"@babel/helpers@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.15.tgz#f09c3df31e86e3ea0b7ff7556d85cdebd47ea6f1" - integrity sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.22.15" - "@babel/types" "^7.22.15" - "@babel/helpers@^7.23.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" @@ -1198,7 +1008,7 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== -"@babel/parser@^7.22.15", "@babel/parser@^7.22.16": +"@babel/parser@^7.22.15": version "7.22.16" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.16.tgz#180aead7f247305cce6551bea2720934e2fa2c95" integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA== @@ -1378,16 +1188,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-async-generator-functions@7.22.15", "@babel/plugin-transform-async-generator-functions@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz#3b153af4a6b779f340d5b80d3f634f55820aefa3" - integrity sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w== - dependencies: - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-transform-async-generator-functions@7.23.2", "@babel/plugin-transform-async-generator-functions@^7.23.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz#054afe290d64c6f576f371ccc321772c8ea87ebb" @@ -1414,13 +1214,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-block-scoping@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.15.tgz#494eb82b87b5f8b1d8f6f28ea74078ec0a10a841" - integrity sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-block-scoping@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz#8744d02c6c264d82e1a4bc5d2d501fd8aff6f022" @@ -1468,13 +1261,6 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/template" "^7.22.5" -"@babel/plugin-transform-destructuring@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.15.tgz#e7404ea5bb3387073b9754be654eecb578324694" - integrity sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-destructuring@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c" @@ -1567,14 +1353,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-amd@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz#4e045f55dcf98afd00f85691a68fc0780704f526" - integrity sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ== - dependencies: - "@babel/helper-module-transforms" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-modules-amd@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz#05b2bc43373faa6d30ca89214731f76f966f3b88" @@ -1583,15 +1361,6 @@ "@babel/helper-module-transforms" "^7.23.0" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-commonjs@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz#b11810117ed4ee7691b29bd29fd9f3f98276034f" - integrity sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg== - dependencies: - "@babel/helper-module-transforms" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-simple-access" "^7.22.5" - "@babel/plugin-transform-modules-commonjs@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481" @@ -1601,16 +1370,6 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" -"@babel/plugin-transform-modules-systemjs@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz#3386be5875d316493b517207e8f1931d93154bb1" - integrity sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA== - dependencies: - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-module-transforms" "^7.22.9" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.5" - "@babel/plugin-transform-modules-systemjs@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz#77591e126f3ff4132a40595a6cccd00a6b60d160" @@ -1752,18 +1511,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-runtime@7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.15.tgz#3a625c4c05a39e932d7d34f5d4895cdd0172fdc9" - integrity sha512-tEVLhk8NRZSmwQ0DJtxxhTrCht1HVo8VaMzYT4w6lwyKBuHsgoioAUA7/6eT2fRfc5/23fuGdlwIxXhRVgWr4g== - dependencies: - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - babel-plugin-polyfill-corejs2 "^0.4.5" - babel-plugin-polyfill-corejs3 "^0.8.3" - babel-plugin-polyfill-regenerator "^0.5.2" - semver "^6.3.1" - "@babel/plugin-transform-runtime@7.23.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.2.tgz#c956a3f8d1aa50816ff6c30c6288d66635c12990" @@ -1843,92 +1590,6 @@ "@babel/helper-create-regexp-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/preset-env@7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.15.tgz#142716f8e00bc030dae5b2ac6a46fbd8b3e18ff8" - integrity sha512-tZFHr54GBkHk6hQuVA8w4Fmq+MSPsfvMG0vPnOYyTnJpyfMqybL8/MbNCPRT9zc2KBO2pe4tq15g6Uno4Jpoag== - dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.15" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.15" - "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.22.5" - "@babel/plugin-syntax-import-attributes" "^7.22.5" - "@babel/plugin-syntax-import-meta" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.22.5" - "@babel/plugin-transform-async-generator-functions" "^7.22.15" - "@babel/plugin-transform-async-to-generator" "^7.22.5" - "@babel/plugin-transform-block-scoped-functions" "^7.22.5" - "@babel/plugin-transform-block-scoping" "^7.22.15" - "@babel/plugin-transform-class-properties" "^7.22.5" - "@babel/plugin-transform-class-static-block" "^7.22.11" - "@babel/plugin-transform-classes" "^7.22.15" - "@babel/plugin-transform-computed-properties" "^7.22.5" - "@babel/plugin-transform-destructuring" "^7.22.15" - "@babel/plugin-transform-dotall-regex" "^7.22.5" - "@babel/plugin-transform-duplicate-keys" "^7.22.5" - "@babel/plugin-transform-dynamic-import" "^7.22.11" - "@babel/plugin-transform-exponentiation-operator" "^7.22.5" - "@babel/plugin-transform-export-namespace-from" "^7.22.11" - "@babel/plugin-transform-for-of" "^7.22.15" - "@babel/plugin-transform-function-name" "^7.22.5" - "@babel/plugin-transform-json-strings" "^7.22.11" - "@babel/plugin-transform-literals" "^7.22.5" - "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" - "@babel/plugin-transform-member-expression-literals" "^7.22.5" - "@babel/plugin-transform-modules-amd" "^7.22.5" - "@babel/plugin-transform-modules-commonjs" "^7.22.15" - "@babel/plugin-transform-modules-systemjs" "^7.22.11" - "@babel/plugin-transform-modules-umd" "^7.22.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" - "@babel/plugin-transform-new-target" "^7.22.5" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" - "@babel/plugin-transform-numeric-separator" "^7.22.11" - "@babel/plugin-transform-object-rest-spread" "^7.22.15" - "@babel/plugin-transform-object-super" "^7.22.5" - "@babel/plugin-transform-optional-catch-binding" "^7.22.11" - "@babel/plugin-transform-optional-chaining" "^7.22.15" - "@babel/plugin-transform-parameters" "^7.22.15" - "@babel/plugin-transform-private-methods" "^7.22.5" - "@babel/plugin-transform-private-property-in-object" "^7.22.11" - "@babel/plugin-transform-property-literals" "^7.22.5" - "@babel/plugin-transform-regenerator" "^7.22.10" - "@babel/plugin-transform-reserved-words" "^7.22.5" - "@babel/plugin-transform-shorthand-properties" "^7.22.5" - "@babel/plugin-transform-spread" "^7.22.5" - "@babel/plugin-transform-sticky-regex" "^7.22.5" - "@babel/plugin-transform-template-literals" "^7.22.5" - "@babel/plugin-transform-typeof-symbol" "^7.22.5" - "@babel/plugin-transform-unicode-escapes" "^7.22.10" - "@babel/plugin-transform-unicode-property-regex" "^7.22.5" - "@babel/plugin-transform-unicode-regex" "^7.22.5" - "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" - "@babel/preset-modules" "0.1.6-no-external-plugins" - "@babel/types" "^7.22.15" - babel-plugin-polyfill-corejs2 "^0.4.5" - babel-plugin-polyfill-corejs3 "^0.8.3" - babel-plugin-polyfill-regenerator "^0.5.2" - core-js-compat "^3.31.0" - semver "^6.3.1" - "@babel/preset-env@7.23.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.2.tgz#1f22be0ff0e121113260337dbc3e58fafce8d059" @@ -2029,13 +1690,6 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - "@babel/runtime@7.23.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" @@ -2118,22 +1772,6 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.22.15", "@babel/traverse@^7.22.17": - version "7.22.17" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.17.tgz#b23c203ab3707e3be816043081b4a994fcacec44" - integrity sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.22.15" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.22.16" - "@babel/types" "^7.22.17" - debug "^4.1.0" - globals "^11.1.0" - "@babel/traverse@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" @@ -2182,7 +1820,7 @@ "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" -"@babel/types@^7.22.15", "@babel/types@^7.22.17": +"@babel/types@^7.22.15": version "7.22.17" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.17.tgz#f753352c4610ffddf9c8bc6823f9ff03e2303eee" integrity sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg== @@ -2219,6 +1857,11 @@ resolved "https://registry.yarnpkg.com/@bazel/buildifier/-/buildifier-6.1.2.tgz#c151df52d2537937911f8f7802f96611d63a90b7" integrity sha512-psKePmRkP6acwyePOhXP67R/wdwN7BGJxHqp1j5myaO24feMsaXyyiO+oW49x8YAwOpKVSCujVzkTwX2auAc0A== +"@bazel/buildifier@6.3.3": + version "6.3.3" + resolved "https://registry.yarnpkg.com/@bazel/buildifier/-/buildifier-6.3.3.tgz#ff21352ac9f72df6a53cc8ad9b862eb68918c1e9" + integrity sha512-0f5eNWhylZQbiTddfVkIXKkugQadzZdonLw4ur58oK4X+gIHOZ42Xv94sepu8Di9UWKFXNc4zxuuTiWM22hGvw== + "@bazel/concatjs@5.8.1": version "5.8.1" resolved "https://registry.yarnpkg.com/@bazel/concatjs/-/concatjs-5.8.1.tgz#dd20882429e382cae79c08cbd3238dfc680d2d67" @@ -2331,11 +1974,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.19.tgz#8735b552b8e0b9a943460d37fbc976b9d9cd4b4e" integrity sha512-4+jkUFQxZkQfQOOxfGVZB38YUWHMJX2ihZwF+2nh8m7bHdWXpixiurgGRN3c/KMSwlltbYI0/i929jwBRMFzbA== -"@esbuild/android-arm64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.3.tgz#91a3b1b4a68c01ffdd5d8ffffb0a83178a366ae0" - integrity sha512-w+Akc0vv5leog550kjJV9Ru+MXMR2VuMrui3C61mnysim0gkFCPOUTAfzTP0qX+HpN9Syu3YA3p1hf3EPqObRw== - "@esbuild/android-arm64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz#276c5f99604054d3dbb733577e09adae944baa90" @@ -2351,11 +1989,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.19.tgz#efd1f33583a893c0cc57f25b1d081af8cdc6bfd9" integrity sha512-1uOoDurJYh5MNqPqpj3l/TQCI1V25BXgChEldCB7D6iryBYqYKrbZIhYO5AI9fulf66sM8UJpc3UcCly2Tv28w== -"@esbuild/android-arm@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.3.tgz#08bd09f2ebc312422f4e94ae954821f9cf37b39e" - integrity sha512-Lemgw4io4VZl9GHJmjiBGzQ7ONXRfRPHcUEerndjwiSkbxzrpq0Uggku5MxxrXdwJ+pTj1qyw4jwTu7hkPsgIA== - "@esbuild/android-arm@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.5.tgz#4a3cbf14758166abaae8ba9c01a80e68342a4eec" @@ -2371,11 +2004,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.19.tgz#d9f35722701a97a2ef69c7a84f1ee2aef2a306a7" integrity sha512-ae5sHYiP/Ogj2YNrLZbWkBmyHIDOhPgpkGvFnke7XFGQldBDWvc/AyYwSLpNuKw9UNkgnLlB/jPpnBmlF3G9Bg== -"@esbuild/android-x64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.3.tgz#b1dffec99ed5505fc57561e8758b449dba4924fe" - integrity sha512-FKQJKkK5MXcBHoNZMDNUAg1+WcZlV/cuXrWCoGF/TvdRiYS4znA0m5Il5idUwfxrE20bG/vU1Cr5e1AD6IEIjQ== - "@esbuild/android-x64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.5.tgz#21a3d11cd4613d2d3c5ccb9e746c254eb9265b0a" @@ -2391,11 +2019,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.19.tgz#8cb81b971ee5231acc7de07225f6e18562c359e4" integrity sha512-HIpQvNQWFYROmWDANMRL+jZvvTQGOiTuwWBIuAsMaQrnStedM+nEKJBzKQ6bfT9RFKH2wZ+ej+DY7+9xHBTFPg== -"@esbuild/darwin-arm64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.3.tgz#2e0db5ad26313c7f420f2cd76d9d263fc49cb549" - integrity sha512-kw7e3FXU+VsJSSSl2nMKvACYlwtvZB8RUIeVShIEY6PVnuZ3c9+L9lWB2nWeeKWNNYDdtL19foCQ0ZyUL7nqGw== - "@esbuild/darwin-arm64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz#714cb839f467d6a67b151ee8255886498e2b9bf6" @@ -2411,11 +2034,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.19.tgz#81024ab64232dd323f03796d449f018b59f04ca9" integrity sha512-m6JdvXJQt0thNLIcWOeG079h2ivhYH4B5sVCgqb/B29zTcFd7EE8/J1nIUHhdtwGeItdUeqKaqqb4towwxvglQ== -"@esbuild/darwin-x64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.3.tgz#ebe99f35049180023bb37999bddbe306b076a484" - integrity sha512-tPfZiwF9rO0jW6Jh9ipi58N5ZLoSjdxXeSrAYypy4psA2Yl1dAMhM71KxVfmjZhJmxRjSnb29YlRXXhh3GqzYw== - "@esbuild/darwin-x64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz#2c553e97a6d2b4ae76a884e35e6cbab85a990bbf" @@ -2431,11 +2049,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.19.tgz#9fa91e3b08d10c0adfa71b37372a7627b26e9686" integrity sha512-G0p4EFMPZhGn/xVNspUyMQbORH3nlKTV0bFNHPIwLraBuAkTeMyxNviTe0ZXUbIXQrR1lrwniFjNFU4s+x7veQ== -"@esbuild/freebsd-arm64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.3.tgz#cf8b58ba5173440ea6124a3d0278bfe4ce181c20" - integrity sha512-ERDyjOgYeKe0Vrlr1iLrqTByB026YLPzTytDTz1DRCYM+JI92Dw2dbpRHYmdqn6VBnQ9Bor6J8ZlNwdZdxjlSg== - "@esbuild/freebsd-arm64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz#d554f556718adb31917a0da24277bf84b6ee87f3" @@ -2451,11 +2064,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.19.tgz#ef6f5a85c1bb029fb0076da5b223e50b353e615c" integrity sha512-hBxgRlG42+W+j/1/cvlnSa+3+OBKeDCyO7OG2ICya1YJaSCYfSpuG30KfOnQHI7Ytgu4bRqCgrYXxQEzy0zM5Q== -"@esbuild/freebsd-x64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.3.tgz#3f283099810ef1b8468cd1a9400c042e3f12e2a7" - integrity sha512-nXesBZ2Ad1qL+Rm3crN7NmEVJ5uvfLFPLJev3x1j3feCQXfAhoYrojC681RhpdOph8NsvKBBwpYZHR7W0ifTTA== - "@esbuild/freebsd-x64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz#288f7358a3bb15d99e73c65c9adaa3dabb497432" @@ -2471,11 +2079,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.19.tgz#0cef913dcdc1efb1bb04406a8e5f5668b721d89e" integrity sha512-X8g33tczY0GsJq3lhyBrjnFtaKjWVpp1gMq5IlF9BQJ3TUfSK74nQnz9mRIEejmcV+OIYn6bkOJeUaU1Knrljg== -"@esbuild/linux-arm64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.3.tgz#a8b3aa69653ac504a51aa73739fb06de3a04d1ff" - integrity sha512-qXvYKmXj8GcJgWq3aGvxL/JG1ZM3UR272SdPU4QSTzD0eymrM7leiZH77pvY3UetCy0k1xuXZ+VPvoJNdtrsWQ== - "@esbuild/linux-arm64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz#95933ae86325c93cb6b5e8333d22120ecfdc901b" @@ -2491,11 +2094,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.19.tgz#39ea874c8e5177b83903bec1883a43f3c163627a" integrity sha512-qtWyoQskfJlb9MD45mvzCEKeO4uCnDZ7lPFeNqbfaaJHqBiH9qA5Vu2EuckqYZuFMJWy1l4dxTf9NOulCVfUjg== -"@esbuild/linux-arm@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.3.tgz#ff6a2f68d4fc3ab46f614bca667a1a81ed6eea26" - integrity sha512-zr48Cg/8zkzZCzDHNxXO/89bf9e+r4HtzNUPoz4GmgAkF1gFAFmfgOdCbR8zMbzFDGb1FqBBhdXUpcTQRYS1cQ== - "@esbuild/linux-arm@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz#0acef93aa3e0579e46d33b666627bddb06636664" @@ -2511,11 +2109,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.19.tgz#283cd3c3d8380e8fab90583fa86ca1fcc9b9ec57" integrity sha512-SAkRWJgb+KN+gOhmbiE6/wu23D6HRcGQi15cB13IVtBZZgXxygTV5GJlUAKLQ5Gcx0gtlmt+XIxEmSqA6sZTOw== -"@esbuild/linux-ia32@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.3.tgz#5813baf70e406304e8931b200e39d0293b488073" - integrity sha512-7XlCKCA0nWcbvYpusARWkFjRQNWNGlt45S+Q18UeS///K6Aw8bB2FKYe9mhVWy/XLShvCweOLZPrnMswIaDXQA== - "@esbuild/linux-ia32@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz#b6e5c9e80b42131cbd6b1ddaa48c92835f1ed67f" @@ -2531,11 +2124,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.19.tgz#1c69d7928a55b26326398d31d2ac9c82d2297f1b" integrity sha512-YLAslaO8NsB9UOxBchos82AOMRDbIAWChwDKfjlGrHSzS3v1kxce7dGlSTsrb0PJwo1KYccypN3VNjQVLtz7LA== -"@esbuild/linux-loong64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.3.tgz#21110f29b5e31dc865c7253fde8a2003f7e8b6fd" - integrity sha512-qGTgjweER5xqweiWtUIDl9OKz338EQqCwbS9c2Bh5jgEH19xQ1yhgGPNesugmDFq+UUSDtWgZ264st26b3de8A== - "@esbuild/linux-loong64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz#e5f0cf95a180158b01ff5f417da796a1c09dfbea" @@ -2551,11 +2139,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.19.tgz#b25b352e7645885fa1d01182116c506a78fe4733" integrity sha512-vSYFtlYds/oTI8aflEP65xo3MXChMwBOG1eWPGGKs/ev9zkTeXVvciU+nifq8J1JYMz+eQ4J9JDN0O2RKF8+1Q== -"@esbuild/linux-mips64el@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.3.tgz#4530fc416651eadeb1acc27003c00eac769eb8fd" - integrity sha512-gy1bFskwEyxVMFRNYSvBauDIWNggD6pyxUksc0MV9UOBD138dKTzr8XnM2R4mBsHwVzeuIH8X5JhmNs2Pzrx+A== - "@esbuild/linux-mips64el@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz#ae36fb86c7d5f641f3a0c8472e83dcb6ea36a408" @@ -2571,11 +2154,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.19.tgz#568b5a051f47af732c4314e697bb559a14b3d811" integrity sha512-tgG41lRVwlzqO9tv9l7aXYVw35BxKXLtPam1qALScwSqPivI8hjkZLNH0deaaSCYCFT9cBIdB+hUjWFlFFLL9A== -"@esbuild/linux-ppc64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.3.tgz#facf910b0d397e391b37b01a1b4f6e363b04e56b" - integrity sha512-UrYLFu62x1MmmIe85rpR3qou92wB9lEXluwMB/STDzPF9k8mi/9UvNsG07Tt9AqwPQXluMQ6bZbTzYt01+Ue5g== - "@esbuild/linux-ppc64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz#7960cb1666f0340ddd9eef7b26dcea3835d472d0" @@ -2591,11 +2169,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.19.tgz#020729b47ca63321667297d1610bab81cd08a65c" integrity sha512-EgBZFLoN1S5RuB4cCJI31pBPsjE1nZ+3+fHRjguq9Ibrzo29bOLSBcH1KZJvRNh5qtd+fcYIGiIUia8Jw5r1lQ== -"@esbuild/linux-riscv64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.3.tgz#4a67abe97a495430d5867340982f5424a64f2aac" - integrity sha512-9E73TfyMCbE+1AwFOg3glnzZ5fBAFK4aawssvuMgCRqCYzE0ylVxxzjEfut8xjmKkR320BEoMui4o/t9KA96gA== - "@esbuild/linux-riscv64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz#32207df26af60a3a9feea1783fc21b9817bade19" @@ -2611,11 +2184,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.19.tgz#ed5cca8dac130d2f736914f9efad5fa15c238c20" integrity sha512-q1V1rtHRojAzjSigZEqrcLkpfh5K09ShCoIsdTakozVBnM5rgV58PLFticqDp5UJ9uE0HScov9QNbbl8HBo6QQ== -"@esbuild/linux-s390x@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.3.tgz#c5fb47474b9f816d81876c119dbccadf671cc5f6" - integrity sha512-LlmsbuBdm1/D66TJ3HW6URY8wO6IlYHf+ChOUz8SUAjVTuaisfuwCOAgcxo3Zsu3BZGxmI7yt//yGOxV+lHcEA== - "@esbuild/linux-s390x@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz#b38d5681db89a3723862dfa792812397b1510a7d" @@ -2631,11 +2199,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.19.tgz#f8023a38ae02b46c60a134ccbc7ae377b3bec66f" integrity sha512-D0IiYjpZRXxGZLQfsydeAD7ZWqdGyFLBj5f2UshJpy09WPs3qizDCsEr8zyzcym6Woj/UI9ZzMIXwvoXVtyt0A== -"@esbuild/linux-x64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.3.tgz#f22d659969ab78dc422f1df8d9a79bc1e7b12ee3" - integrity sha512-ogV0+GwEmvwg/8ZbsyfkYGaLACBQWDvO0Kkh8LKBGKj9Ru8VM39zssrnu9Sxn1wbapA2qNS6BiLdwJZGouyCwQ== - "@esbuild/linux-x64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz#46feba2ad041a241379d150f415b472fe3885075" @@ -2651,11 +2214,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.19.tgz#8fd667c535db0a5b346afa2d74ff1fb53477427f" integrity sha512-3tt3SOS8L3D54R8oER41UdDshlBIAjYhdWRPiZCTZ1E41+shIZBpTjaW5UaN/jD1ENE/Ok5lkeqhoNMbxstyxw== -"@esbuild/netbsd-x64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.3.tgz#e9b046934996991f46b8c1cadac815aa45f84fd4" - integrity sha512-o1jLNe4uzQv2DKXMlmEzf66Wd8MoIhLNO2nlQBHLtWyh2MitDG7sMpfCO3NTcoTMuqHjfufgUQDFRI5C+xsXQw== - "@esbuild/netbsd-x64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz#3b5c1fb068f26bfc681d31f682adf1bea4ef0702" @@ -2671,11 +2229,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.19.tgz#354d5b54a6bffa381cb513e878880192e07004be" integrity sha512-MxbhcuAYQPlfln1EMc4T26OUoeg/YQc6wNoEV8xvktDKZhLtBxjkoeESSo9BbPaGKhAPzusXYj5n8n5A8iZSrA== -"@esbuild/openbsd-x64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.3.tgz#b287ef4841fc1067bbbd9a60549e8f9cf1b7ee3a" - integrity sha512-AZJCnr5CZgZOdhouLcfRdnk9Zv6HbaBxjcyhq0StNcvAdVZJSKIdOiPB9az2zc06ywl0ePYJz60CjdKsQacp5Q== - "@esbuild/openbsd-x64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz#ca6830316ca68056c5c88a875f103ad3235e00db" @@ -2691,11 +2244,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.19.tgz#e2de98bd961e04f76f6acf5970263efc7051def5" integrity sha512-m0/UOq1wj25JpWqOJxoWBRM9VWc3c32xiNzd+ERlYstUZ6uwx5SZsQUtkiFHaYmcaoj+f6+Tfcl7atuAz3idwQ== -"@esbuild/sunos-x64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.3.tgz#b2b8ba7d27907c7245f6e57dc62f3b88693f84b0" - integrity sha512-Acsujgeqg9InR4glTRvLKGZ+1HMtDm94ehTIHKhJjFpgVzZG9/pIcWW/HA/DoMfEyXmANLDuDZ2sNrWcjq1lxw== - "@esbuild/sunos-x64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz#9efc4eb9539a7be7d5a05ada52ee43cda0d8e2dd" @@ -2711,11 +2259,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.19.tgz#9dca55f0dcbbdb50bf36353d1114f5f71c269275" integrity sha512-L4vb6pcoB1cEcXUHU6EPnUhUc4+/tcz4OqlXTWPcSQWxegfmcOprhmIleKKwmMNQVc4wrx/+jB7tGkjjDmiupg== -"@esbuild/win32-arm64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.3.tgz#1974c8c180c9add4962235662c569fcc4c8f43dd" - integrity sha512-FSrAfjVVy7TifFgYgliiJOyYynhQmqgPj15pzLyJk8BUsnlWNwP/IAy6GAiB1LqtoivowRgidZsfpoYLZH586A== - "@esbuild/win32-arm64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz#29f8184afa7a02a956ebda4ed638099f4b8ff198" @@ -2731,11 +2274,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.19.tgz#db6ea4467e87e6d3fc2177dea35e81f26f7a061d" integrity sha512-rQng7LXSKdrDlNDb7/v0fujob6X0GAazoK/IPd9C3oShr642ri8uIBkgM37/l8B3Rd5sBQcqUXoDdEy75XC/jg== -"@esbuild/win32-ia32@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.3.tgz#b02cc2dd8b6aed042069680f01f45fdfd3de5bc4" - integrity sha512-xTScXYi12xLOWZ/sc5RBmMN99BcXp/eEf7scUC0oeiRoiT5Vvo9AycuqCp+xdpDyAU+LkrCqEpUS9fCSZF8J3Q== - "@esbuild/win32-ia32@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz#f3de07afb292ecad651ae4bb8727789de2d95b05" @@ -2751,16 +2289,16 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.19.tgz#6105755d7097e0d7e22f893c3e62f143d8137bd0" integrity sha512-z69jhyG20Gq4QL5JKPLqUT+eREuqnDAFItLbza4JCmpvUnIlY73YNjd5djlO7kBiiZnvTnJuAbOjIoZIOa1GjA== -"@esbuild/win32-x64@0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.3.tgz#e5036be529f757e58d9a7771f2f1b14782986a74" - integrity sha512-FbUN+0ZRXsypPyWE2IwIkVjDkDnJoMJARWOcFZn4KPPli+QnKqF0z1anvfaYe3ev5HFCpRDLLBDHyOALLppWHw== - "@esbuild/win32-x64@0.19.5": version "0.19.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz#faad84c41ba12e3a0acb52571df9bff37bee75f6" integrity sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw== +"@fastify/busboy@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8" + integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ== + "@firebase/app-types@^0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" @@ -2973,6 +2511,13 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0" integrity sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg== +"@ljharb/through@^2.3.9": + version "2.3.11" + resolved "https://registry.yarnpkg.com/@ljharb/through/-/through-2.3.11.tgz#783600ff12c06f21a76cc26e33abd0b1595092f9" + integrity sha512-ccfcIDlogiXNq5KcbAwbaO7lMh3Tm1i3khMPYpxlK8hH/W53zN81KM9coerRLOnTGu3nfXIniAmQbRI9OxbC0w== + dependencies: + call-bind "^1.0.2" + "@material/animation@15.0.0-canary.a246a4439.0": version "15.0.0-canary.a246a4439.0" resolved "https://registry.yarnpkg.com/@material/animation/-/animation-15.0.0-canary.a246a4439.0.tgz#bb7a8dc450e99be4f3c3ef4ace206b44ee1a9162" @@ -3693,17 +3238,17 @@ "@microsoft/tsdoc-config" "~0.16.1" "@rushstack/node-core-library" "3.61.0" -"@microsoft/api-extractor@7.38.0": - version "7.38.0" - resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.38.0.tgz#e72546d6766b3866578a462b040f71b17779e1c5" - integrity sha512-e1LhZYnfw+JEebuY2bzhw0imDCl1nwjSThTrQqBXl40hrVo6xm3j/1EpUr89QyzgjqmAwek2ZkIVZbrhaR+cqg== +"@microsoft/api-extractor@7.38.1": + version "7.38.1" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.38.1.tgz#1bccfae8b8d95c667d35aee085322c84ae1d2639" + integrity sha512-Hxu/RrVpItQ4dzeMyfwlk4lGQFsXMoMS7bYU9YUrpW16hH04PXLRiTXJz77WhBiSGNtTuufz2xh6hWyXhC9JuQ== dependencies: "@microsoft/api-extractor-model" "7.28.2" "@microsoft/tsdoc" "0.14.2" "@microsoft/tsdoc-config" "~0.16.1" "@rushstack/node-core-library" "3.61.0" "@rushstack/rig-package" "0.5.1" - "@rushstack/ts-command-line" "4.16.1" + "@rushstack/ts-command-line" "4.17.0" colors "~1.2.1" lodash "~4.17.15" resolve "~1.22.1" @@ -3749,15 +3294,10 @@ resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz#c3ec604a0b54b9a9b87e9735dfc59e1a5da6a5fb" integrity sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug== -"@ngtools/webpack@17.0.0-next.6": - version "17.0.0-next.6" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.0.0-next.6.tgz#450f8c1dcc448f6fd8a30e313d0735cd21b803c8" - integrity sha512-xsWk3iwoSvkl3ZSrN8jbLJZPKVPk8Ge7bnD6pzZDokjtl8ApcXatGd0NBqCQDr+lfV+ZdhVGJ5xfBiyGzEeSzw== - -"@ngtools/webpack@17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.0.0-rc.0.tgz#0c07c3c07730fe580509bee8ece7d8818367f3cc" - integrity sha512-VoOZE2YzdqI8934enPPY6d22IhBMASXEmZDFlNT7FD0BCn+P+p4g+0P/YC5kDZQ/+oh+CNgCO5jXy2l5MRp2lQ== +"@ngtools/webpack@17.0.0-rc.3": + version "17.0.0-rc.3" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.0.0-rc.3.tgz#75bfa534307b48f6d67f1e7aeec24127c13902ee" + integrity sha512-jNj1riYrF7Qwq4tD5FqWTVI3SlERWy01iLN8Hmx2i1b7IeSHm6UY6g1DSTgV7PuMesFMumORPtSc9WqCcPAPIg== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -4138,23 +3678,23 @@ colors "~1.2.1" string-argv "~0.3.1" -"@rushstack/ts-command-line@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.16.1.tgz#3537bbc323f77c8646646465c579b992d39feb16" - integrity sha512-+OCsD553GYVLEmz12yiFjMOzuPeCiZ3f8wTiFHL30ZVXexTyPmgjwXEhg2K2P0a2lVf+8YBy7WtPoflB2Fp8/A== +"@rushstack/ts-command-line@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.17.0.tgz#da99fc18b847a060329967228413f010155d98e7" + integrity sha512-1S0sXuEpZlzKTfvUqNs7Rg4leVkeLJc4Dn9cm+pSIn35a0Ztp5GxPN2gabD2G4RrQoQcJLLyVu+twzrJl1C0eA== dependencies: "@types/argparse" "1.0.38" argparse "~1.0.9" colors "~1.2.1" string-argv "~0.3.1" -"@schematics/angular@17.0.0-rc.0", "@schematics/angular@^17.0.0-rc.0": - version "17.0.0-rc.0" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.0.0-rc.0.tgz#806822e9eeae678f6c38660ff0aa939da8206efb" - integrity sha512-6sWQ9UXaR43Q+9/Ogyc3Mt65o7nfmpXj5yjq46VPcpJsIAM3sfWRJG1mdmQ7iBXlP6U38dQaqpKPrqDFu72Ejw== +"@schematics/angular@17.0.0-rc.3", "@schematics/angular@^17.0.0-rc.3": + version "17.0.0-rc.3" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.0.0-rc.3.tgz#13c7e6a6830fd3077850a64d2346a2a1845621da" + integrity sha512-gRafyBMgnzc3QEHUIX+lrGrH6HcnmxwKeNiIXyFPlvoqMr1U5KazFNSqImF9VHg4dboIOVEJFJCHP8sadaejHQ== dependencies: - "@angular-devkit/core" "17.0.0-rc.0" - "@angular-devkit/schematics" "17.0.0-rc.0" + "@angular-devkit/core" "17.0.0-rc.3" + "@angular-devkit/schematics" "17.0.0-rc.3" jsonc-parser "3.2.0" "@sigstore/bundle@^2.1.0": @@ -4741,10 +4281,10 @@ resolved "https://registry.yarnpkg.com/@types/which/-/which-2.0.1.tgz#27ecd67f915b7c3d6ba552135bb1eecd66e63501" integrity sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ== -"@types/ws@8.5.6": - version "8.5.6" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.6.tgz#e9ad51f0ab79b9110c50916c9fcbddc36d373065" - integrity sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg== +"@types/ws@8.5.8": + version "8.5.8" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.8.tgz#13efec7bd439d0bdf2af93030804a94f163b1430" + integrity sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg== dependencies: "@types/node" "*" @@ -5194,7 +4734,7 @@ ansi-escapes@^3.1.0, ansi-escapes@^3.2.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== -ansi-escapes@^4.2.1: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -5491,18 +5031,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@10.4.15: - version "10.4.15" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.15.tgz#a1230f4aeb3636b89120b34a1f513e2f6834d530" - integrity sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew== - dependencies: - browserslist "^4.21.10" - caniuse-lite "^1.0.30001520" - fraction.js "^4.2.0" - normalize-range "^0.1.2" - picocolors "^1.0.0" - postcss-value-parser "^4.2.0" - autoprefixer@10.4.16: version "10.4.16" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.16.tgz#fad1411024d8670880bdece3970aa72e3572feb8" @@ -5563,15 +5091,6 @@ babel-plugin-istanbul@6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-polyfill-corejs2@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c" - integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg== - dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.4.2" - semver "^6.3.1" - babel-plugin-polyfill-corejs2@^0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" @@ -5581,14 +5100,6 @@ babel-plugin-polyfill-corejs2@^0.4.6: "@babel/helper-define-polyfill-provider" "^0.4.3" semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz#b4f719d0ad9bb8e0c23e3e630c0c8ec6dd7a1c52" - integrity sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.2" - core-js-compat "^3.31.0" - babel-plugin-polyfill-corejs3@^0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.5.tgz#a75fa1b0c3fc5bd6837f9ec465c0f48031b8cab1" @@ -5597,13 +5108,6 @@ babel-plugin-polyfill-corejs3@^0.8.5: "@babel/helper-define-polyfill-provider" "^0.4.3" core-js-compat "^3.32.2" -babel-plugin-polyfill-regenerator@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326" - integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.2" - babel-plugin-polyfill-regenerator@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" @@ -6351,6 +5855,15 @@ call-bind@^1.0.0: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-bind@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -6411,11 +5924,6 @@ caniuse-lite@^1.0.30001517: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== -caniuse-lite@^1.0.30001520: - version "1.0.30001534" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz#f24a9b2a6d39630bac5c132b5dff89b39a12e7dd" - integrity sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q== - caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541: version "1.0.30001551" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz#1f2cfa8820bd97c971a57349d7fd8f6e08664a3e" @@ -6523,6 +6031,11 @@ chalk@^5.0.1: resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6" integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w== +chalk@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + change-case@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.0.0.tgz#6c9c8e35f8790870a82b6b0745be8c3cbef9b081" @@ -6701,6 +6214,11 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + cliui@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -7484,6 +7002,15 @@ defer-to-connect@^2.0.0: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" @@ -8207,44 +7734,11 @@ es6-weak-map@^2.0.3: es6-iterator "^2.0.3" es6-symbol "^3.1.1" -esbuild-wasm@0.19.3: - version "0.19.3" - resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.19.3.tgz#9ac844d4b542ad33a81be7cb32ba1d451522cee6" - integrity sha512-Vx94kkrz9CwaYutautk+RhIvwhcpawSRmKD/zz6n3wQqJgBzaMRVZaF9eAuVseXwOmfJexSGmwwgToQ1uAoOjg== - esbuild-wasm@0.19.5: version "0.19.5" resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.19.5.tgz#28f4563d7e3bcbe9462813e376b2fb6024931fd9" integrity sha512-7zmLLn2QCj93XfMmHtzrDJ1UBuOHB2CZz1ghoCEZiRajxjUvHsF40PnbzFIY/pmesqPRaEtEWii0uzsTbnAgrA== -esbuild@0.19.3: - version "0.19.3" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.3.tgz#d9268cd23358eef9d76146f184e0c55ff8da7bb6" - integrity sha512-UlJ1qUUA2jL2nNib1JTSkifQTcYTroFqRjwCFW4QYEKEsixXD5Tik9xML7zh2gTxkYTBKGHNH9y7txMwVyPbjw== - optionalDependencies: - "@esbuild/android-arm" "0.19.3" - "@esbuild/android-arm64" "0.19.3" - "@esbuild/android-x64" "0.19.3" - "@esbuild/darwin-arm64" "0.19.3" - "@esbuild/darwin-x64" "0.19.3" - "@esbuild/freebsd-arm64" "0.19.3" - "@esbuild/freebsd-x64" "0.19.3" - "@esbuild/linux-arm" "0.19.3" - "@esbuild/linux-arm64" "0.19.3" - "@esbuild/linux-ia32" "0.19.3" - "@esbuild/linux-loong64" "0.19.3" - "@esbuild/linux-mips64el" "0.19.3" - "@esbuild/linux-ppc64" "0.19.3" - "@esbuild/linux-riscv64" "0.19.3" - "@esbuild/linux-s390x" "0.19.3" - "@esbuild/linux-x64" "0.19.3" - "@esbuild/netbsd-x64" "0.19.3" - "@esbuild/openbsd-x64" "0.19.3" - "@esbuild/sunos-x64" "0.19.3" - "@esbuild/win32-arm64" "0.19.3" - "@esbuild/win32-ia32" "0.19.3" - "@esbuild/win32-x64" "0.19.3" - esbuild@0.19.5: version "0.19.5" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.5.tgz#53a0e19dfbf61ba6c827d51a80813cf071239a8c" @@ -8354,6 +7848,11 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + escodegen@1.8.x: version "1.8.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" @@ -8672,7 +8171,7 @@ extend@^3.0.0, extend@^3.0.2, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.3: +external-editor@^3.0.3, external-editor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== @@ -8825,6 +8324,14 @@ figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" +figures@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-5.0.0.tgz#126cd055052dea699f8a54e8c9450e6ecfc44d5f" + integrity sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg== + dependencies: + escape-string-regexp "^5.0.0" + is-unicode-supported "^1.2.0" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -9283,6 +8790,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + furi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/furi/-/furi-2.0.0.tgz#13d85826a1af21acc691da6254b3888fc39f0b4a" @@ -9351,6 +8863,16 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -9654,6 +9176,13 @@ google-protobuf@^3.6.1: resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.20.0.tgz#8705ab5fb7e91e9578250a4a8ac533a3cc0bc0bb" integrity sha512-hhXv5IKLDIkb0pEm53G053UZGhRAhw3wM5Jk7ly5sGIQRkO1s63FaDqM9QjlrPHygKEE2awUlLP9fFrG6M9vfQ== +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + got@^11.0.2, got@^11.7.0: version "11.8.3" resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770" @@ -9823,12 +9352,17 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + has-symbol-support-x@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== -has-symbols@^1.0.1: +has-symbols@^1.0.1, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== @@ -9865,6 +9399,13 @@ hash.js@^1.1.7: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + hast-util-from-parse5@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.3.tgz#3089dc0ee2ccf6ec8bc416919b51a54a589e097c" @@ -10331,26 +9872,26 @@ ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -inquirer@8.2.6: - version "8.2.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" - integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== +inquirer@9.2.11: + version "9.2.11" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.2.11.tgz#e9003755c233a414fceda1891c23bd622cad4a95" + integrity sha512-B2LafrnnhbRzCWfAdOXisUzL89Kg8cVJlYmhqoi3flSiV/TveO+nsXwgKr9h9PIo+J1hz7nBSk6gegRIMBBf7g== dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" + "@ljharb/through" "^2.3.9" + ansi-escapes "^4.3.2" + chalk "^5.3.0" cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" + cli-width "^4.1.0" + external-editor "^3.1.0" + figures "^5.0.0" lodash "^4.17.21" - mute-stream "0.0.8" + mute-stream "1.0.0" ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^6.0.1" + run-async "^3.0.0" + rxjs "^7.8.1" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" inquirer@^8.2.0: version "8.2.2" @@ -10717,6 +10258,11 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-unicode-supported@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714" + integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== + is-upper-case@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f" @@ -11822,13 +11368,6 @@ madge@^4.0.0: typescript "^3.9.5" walkdir "^0.4.1" -magic-string@0.30.3: - version "0.30.3" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.3.tgz#403755dfd9d6b398dfa40635d52e96c5ac095b85" - integrity sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw== - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" - magic-string@0.30.5: version "0.30.5" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" @@ -12393,6 +11932,11 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mute-stream@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" + integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== + nan@^2.15.0: version "2.15.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" @@ -13353,7 +12897,12 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@2.3.1, picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: +picomatch@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-3.0.1.tgz#817033161def55ec9638567a2f3bbc876b3e7516" + integrity sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -13519,15 +13068,6 @@ postcss-values-parser@^2.0.1: indexes-of "^1.0.1" uniq "^1.0.1" -postcss@8.4.29, postcss@^8.4.27: - version "8.4.29" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd" - integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - postcss@8.4.31: version "8.4.31" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" @@ -13573,6 +13113,15 @@ postcss@^8.4.23: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.27: + version "8.4.29" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd" + integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + preact-render-to-string@^6.2.1: version "6.2.2" resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-6.2.2.tgz#eb086b6db5d57468ab2c184896884fb0a818245d" @@ -14527,6 +14076,11 @@ run-async@^2.2.0, run-async@^2.4.0: resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-async@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-3.0.0.tgz#42a432f6d76c689522058984384df28be379daad" + integrity sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q== + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -14566,7 +14120,7 @@ rxjs-tslint-rules@^4.34.8: tsutils "^3.0.0" tsutils-etc "^1.2.2" -rxjs@7.8.1: +rxjs@7.8.1, rxjs@^7.8.1: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== @@ -14633,10 +14187,10 @@ sass-lookup@^3.0.0: dependencies: commander "^2.16.0" -sass@1.67.0: - version "1.67.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.67.0.tgz#fed84d74b9cd708db603b1380d6dc1f71bb24f6f" - integrity sha512-SVrO9ZeX/QQyEGtuZYCVxoeAL5vGlYjJ9p4i4HFuekWl8y/LtJ7tJc10Z+ck1c8xOuoBm2MYzcLfTAffD0pl/A== +sass@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.5.tgz#23e18d1c757a35f2e52cc81871060b9ad653dfde" + integrity sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -14726,14 +14280,14 @@ selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1, selenium-webdriver@^3.6.0: tmp "0.0.30" xml2js "^0.4.17" -selenium-webdriver@4.13.0: - version "4.13.0" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.13.0.tgz#1e06bab7adedb308e3635131bc75bd32038261d5" - integrity sha512-8JS0h5E0Sq7gNfbGg8LVaQ+Eqek97tvOONn3Jmy+NiWfb12WYpftz4VTC4D2JT4wakdG6VUzGKpA8cFGg0IjkA== +selenium-webdriver@4.14.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.14.0.tgz#d39917cd7c1bb30f753c1f668158f37d1905fafc" + integrity sha512-637rs8anqMKHbWxcBZpyG3Gcs+rBUtAUiqk0O/knUqH4Paj3MFUZrz88/pVGOLNryEVy2z92fZomT8p1ENl1gA== dependencies: jszip "^3.10.1" tmp "^0.2.1" - ws ">=8.13.0" + ws ">=8.14.2" selfsigned@^2.1.1: version "2.1.1" @@ -14952,6 +14506,16 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + set-immediate-shim@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" @@ -15945,20 +15509,10 @@ terser-webpack-plugin@^5.3.7: serialize-javascript "^6.0.1" terser "^5.16.5" -terser@5.19.4: - version "5.19.4" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.4.tgz#941426fa482bf9b40a0308ab2b3cd0cf7c775ebd" - integrity sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" - commander "^2.20.0" - source-map-support "~0.5.20" - -terser@5.22.0: - version "5.22.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.22.0.tgz#4f18103f84c5c9437aafb7a14918273310a8a49d" - integrity sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw== +terser@5.24.0: + version "5.24.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364" + integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -16425,6 +15979,13 @@ unbzip2-stream@^1.0.9, unbzip2-stream@^1.3.3: buffer "^5.2.1" through "^2.3.8" +undici@5.27.0: + version "5.27.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.27.0.tgz#789f2e40ce982b5507899abc2c2ddeb2712b4554" + integrity sha512-l3ydWhlhOJzMVOYkymLykcRRXqbUaQriERtR70B9LzNkZ4bX52Fc8wbTDneMiwo8T+AemZXvXaTx+9o5ROxrXg== + dependencies: + "@fastify/busboy" "^2.0.0" + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -16810,17 +16371,6 @@ vfile@^3.0.0: unist-util-stringify-position "^1.0.0" vfile-message "^1.0.0" -vite@4.4.9: - version "4.4.9" - resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d" - integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA== - dependencies: - esbuild "^0.18.10" - postcss "^8.4.27" - rollup "^3.27.1" - optionalDependencies: - fsevents "~2.3.2" - vite@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.0.tgz#ec406295b4167ac3bc23e26f9c8ff559287cff26" @@ -17025,14 +16575,6 @@ webpack-merge@5.10.0: flat "^5.0.2" wildcard "^2.0.0" -webpack-merge@5.9.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.9.0.tgz#dc160a1c4cf512ceca515cc231669e9ddb133826" - integrity sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - webpack-sources@^3.0.0, webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" @@ -17045,36 +16587,6 @@ webpack-subresource-integrity@5.1.0: dependencies: typed-assert "^1.0.8" -webpack@5.88.2: - version "5.88.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" - integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "^1.11.5" - "@webassemblyjs/wasm-edit" "^1.11.5" - "@webassemblyjs/wasm-parser" "^1.11.5" - acorn "^8.7.1" - acorn-import-assertions "^1.9.0" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.15.0" - es-module-lexer "^1.2.1" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.2.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - webpack@5.89.0: version "5.89.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" @@ -17228,7 +16740,7 @@ wordwrap@^1.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: +wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== @@ -17269,16 +16781,21 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@>=8.13.0, ws@^8.13.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== +ws@>=8.14.2: + version "8.14.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" + integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== ws@^7.2.3: version "7.5.7" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== +ws@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + ws@~3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"