diff --git a/.cspell.json b/.cspell.json index a0f99167dd00..cfbdc7d7445f 100644 --- a/.cspell.json +++ b/.cspell.json @@ -3,7 +3,7 @@ "import": ["@taiga-ui/cspell-config/cspell.config.js"], "files": ["*/*.*"], "ignorePaths": ["**/projects/i18n/languages/**", "**/addon-commerce/utils/get-currency-symbol.ts"], - "ignoreWords": ["Wachovia", "bottomsheet", "appbar", "qwertypgj_", "antialiasing"], + "ignoreWords": ["Wachovia", "bottomsheet", "appbar", "qwertypgj_", "antialiasing", "xxxs"], "ignoreRegExpList": ["\\(https?://.*?\\)", "\\/{1}.+\\/{1}", "\\%2F.+", "\\%2C.+", "\\ɵ.+", "\\ыва.+"], "overrides": [ { diff --git a/.github/renovate.json b/.github/renovate.json index bf23f4917dc4..b1307bfddcec 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,4 +1,10 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["github>taiga-family/renovate-config"] + "extends": ["github>taiga-family/renovate-config"], + "packageRules": [ + { + "matchPackageNames": ["/^@nx.*/", "/^nx$/"], + "enabled": false + } + ] } diff --git a/.github/workflows/assign-author.yml b/.github/workflows/assign-author.yml index a8b138d6a794..621ccd0f6ec3 100644 --- a/.github/workflows/assign-author.yml +++ b/.github/workflows/assign-author.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 - uses: toshimaru/auto-author-assign@v2.1.1 continue-on-error: true diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index 5cf33c6668b7..d9dbea744a23 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -13,7 +13,7 @@ jobs: matrix: ${{ steps.matrix.outputs.value }} steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 - id: matrix if: env.IS_TAIGA_FAMILY_BOT_PR_AUTHOR == 'true' run: | @@ -31,7 +31,7 @@ jobs: matrix: value: ${{ fromJSON(needs.setup.outputs.matrix) }} steps: - - uses: taiga-family/ci/actions/run/wait-job@v1.101.0 + - uses: taiga-family/ci/actions/run/wait-job@v1.102.0 with: token: ${{ secrets.GITHUB_TOKEN }} job: ${{ matrix.value }} @@ -41,13 +41,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/auto/approve/double@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/auto/approve/double@v1.102.0 if: env.IS_TAIGA_FAMILY_BOT_PR_AUTHOR == 'true' with: token1: ${{ secrets.GITHUB_TOKEN }} token2: ${{ secrets.TAIGA_FAMILY_APPROVE_BOT_PAT }} - - uses: taiga-family/ci/actions/run/merge@v1.101.0 + - uses: taiga-family/ci/actions/run/merge@v1.102.0 if: env.IS_TAIGA_FAMILY_BOT_PR_AUTHOR == 'true' with: token: ${{ secrets.TAIGA_FAMILY_BOT_PAT }} diff --git a/.github/workflows/auto-update-icons.yml b/.github/workflows/auto-update-icons.yml index 3569d237fc3c..f8b471ac2760 100644 --- a/.github/workflows/auto-update-icons.yml +++ b/.github/workflows/auto-update-icons.yml @@ -11,8 +11,8 @@ jobs: - uses: actions/checkout@v4.2.2 with: persist-credentials: false - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - name: Lucide icons run: | npx nx prebuild icons @@ -31,7 +31,7 @@ jobs: npx eslint ./projects/demo/used-icons.ts --fix || echo "no file matching" npx prettier ./projects/demo/used-icons.ts --write || echo "no file matching" npx prettier ./projects/cdk/constants/used-icons.ts --write || echo "no file matching" - - uses: taiga-family/ci/actions/auto/push@v1.101.0 + - uses: taiga-family/ci/actions/auto/push@v1.102.0 if: env.SUPPORT_AUTO_PUSH with: message: icons have changed diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8969b96352f5..3f6b94969c1d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,8 +11,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - run: npm run run-many:build:libs - run: npx ts-node ./scripts/check-dist.ts @@ -22,8 +22,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - run: npx nx prerender demo - run: npx --yes bundlemon --config .github/.bundlemonrc.json continue-on-error: true diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 6a823a8b540b..012ccfb44be6 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -24,8 +24,8 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.TAIGA_FAMILY_BOT_PAT }} - - uses: taiga-family/ci/actions/setup/node@v1.101.0 - - uses: taiga-family/ci/actions/setup/config/git@v1.101.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 + - uses: taiga-family/ci/actions/setup/config/git@v1.102.0 with: token: ${{ secrets.TAIGA_FAMILY_BOT_PAT }} diff --git a/.github/workflows/deploy-gh-pages.yml b/.github/workflows/deploy-gh-pages.yml index ca4ca4bc5256..0f23a79bf854 100644 --- a/.github/workflows/deploy-gh-pages.yml +++ b/.github/workflows/deploy-gh-pages.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 - name: Prepare demo before deploy from snapshots run: | diff --git a/.github/workflows/deploy-preview.yml b/.github/workflows/deploy-preview.yml index f0328bafb451..34199a151439 100644 --- a/.github/workflows/deploy-preview.yml +++ b/.github/workflows/deploy-preview.yml @@ -8,8 +8,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - run: npx nx build demo - name: Debug output run: tree dist/demo/browser -P '*.html' diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 1101f5327184..9c804482bb36 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -14,10 +14,10 @@ jobs: - uses: actions/checkout@v4.2.2 with: fetch-depth: 10 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/run/rebase@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/run/rebase@v1.102.0 continue-on-error: true - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - run: npx nx type-check demo-playwright - name: Building demo-app of git-branch without cache @@ -41,8 +41,8 @@ jobs: - uses: actions/checkout@v4.2.2 with: ref: ${{ github.base_ref }} - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - name: Run tests for baseline state run: npx nx component-test demo-cypress @@ -57,8 +57,8 @@ jobs: retention-days: 1 - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - name: Download Cypress Baseline Snapshots uses: actions/download-artifact@v4.1.8 @@ -111,8 +111,8 @@ jobs: runs-on: ${{ matrix.shard.os }} steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - name: Get installed Playwright version id: playwright-version @@ -138,7 +138,7 @@ jobs: path: dist/demo key: ${{ env.CACHE_DIST_KEY }} - - uses: taiga-family/ci/actions/run/serve@v1.101.0 + - uses: taiga-family/ci/actions/run/serve@v1.102.0 with: port: ${{ env.NG_SERVER_PORT }} directory: ${{ env.DIST }} @@ -151,12 +151,12 @@ jobs: --project=${{ matrix.shard.project }} \ --shard=${{ matrix.shard.index }}/${{ matrix.shard.total }} - - uses: taiga-family/ci/actions/run/clone@v1.101.0 + - uses: taiga-family/ci/actions/run/clone@v1.102.0 with: branch: snapshots/demo/next/${{ github.base_ref }} destination: ${{ env.DIST_NEXT }} - - uses: taiga-family/ci/actions/run/serve@v1.101.0 + - uses: taiga-family/ci/actions/run/serve@v1.102.0 with: port: ${{ env.NG_SERVER_PORT }} directory: ${{ env.DIST_NEXT }} @@ -216,8 +216,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - name: Download artifacts for Playwright continue-on-error: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 15a44d006e24..c3871926c8e0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,8 +13,8 @@ jobs: - uses: actions/checkout@v4.2.2 with: persist-credentials: false - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - run: npm run typecheck - run: npm run cspell - run: | @@ -27,7 +27,7 @@ jobs: npm run prettier -- --check npm run lint fi - - uses: taiga-family/ci/actions/auto/push@v1.101.0 + - uses: taiga-family/ci/actions/auto/push@v1.102.0 with: token: ${{ secrets.TAIGA_FAMILY_BOT_PAT }} diff --git a/.github/workflows/publish-canary.yml b/.github/workflows/publish-canary.yml index 472a87dbccab..eb2c120a1429 100644 --- a/.github/workflows/publish-canary.yml +++ b/.github/workflows/publish-canary.yml @@ -10,9 +10,9 @@ jobs: name: Publish canary steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 - - uses: taiga-family/ci/actions/setup/config/npm@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 + - uses: taiga-family/ci/actions/setup/config/npm@v1.102.0 with: token: ${{ secrets.TAIGA_UI_SCOPE_NPM_TOKEN }} - run: npx ts-node ./scripts/publish-canary.ts diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 054210a4e0f6..113f057b661f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,19 +11,19 @@ jobs: - uses: actions/checkout@v4.2.2 with: fetch-depth: 0 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 - - uses: taiga-family/ci/actions/setup/config/npm@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 + - uses: taiga-family/ci/actions/setup/config/npm@v1.102.0 with: token: ${{ secrets.TAIGA_UI_SCOPE_NPM_TOKEN }} - run: npx nx run-many -t publish - - uses: taiga-family/ci/actions/run/read-package-json@v1.101.0 + - uses: taiga-family/ci/actions/run/read-package-json@v1.102.0 id: info - name: Announce to Time messenger - uses: taiga-family/ci/actions/messenger/time/announce@v1.101.0 + uses: taiga-family/ci/actions/messenger/time/announce@v1.102.0 if: ${{ !contains(steps.info.outputs.version, 'rc') }} with: url: ${{ secrets.ANNOUNCE_WEBHOOK }} @@ -31,7 +31,7 @@ jobs: version: v${{ steps.info.outputs.version }} - name: Announce to Telegram messenger - uses: taiga-family/ci/actions/messenger/telegram/announce@v1.101.0 + uses: taiga-family/ci/actions/messenger/telegram/announce@v1.102.0 if: ${{ !contains(steps.info.outputs.version, 'rc') }} with: chatId: ${{ secrets.TAIGA_TELEGRAM_CHAT_ID }} diff --git a/.github/workflows/ready-to-merge.yml b/.github/workflows/ready-to-merge.yml index 0e91911d03a4..a4a035973cc5 100644 --- a/.github/workflows/ready-to-merge.yml +++ b/.github/workflows/ready-to-merge.yml @@ -10,8 +10,8 @@ jobs: if: github.event.review.state == 'approved' steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/auto/label-when-approved@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/auto/label-when-approved@v1.102.0 with: approvals: 2 token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/schematic.yml b/.github/workflows/schematic.yml index e02bfd128b3c..afa2f0c41251 100644 --- a/.github/workflows/schematic.yml +++ b/.github/workflows/schematic.yml @@ -8,8 +8,8 @@ jobs: name: Run the latest migration steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 - - uses: taiga-family/ci/actions/run/node-info@v1.101.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 + - uses: taiga-family/ci/actions/run/node-info@v1.102.0 id: info - run: npx nx run cdk:schematics --v=${{ steps.info.outputs.root-package-major-version }} diff --git a/.github/workflows/snapshots.yml b/.github/workflows/snapshots.yml index 5ce4f7298659..07559b6ae312 100644 --- a/.github/workflows/snapshots.yml +++ b/.github/workflows/snapshots.yml @@ -16,8 +16,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - run: npx nx build demo # Don't use prerender please, because it's flaky for e2e - run: tree ${{ env.DIST }} -P '*.html' @@ -35,8 +35,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 id: nodejs-workspace - run: npx nx prerender demo diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 68f3eb01b7ba..efc2e0accf95 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,11 +12,13 @@ jobs: name: Unit tests steps: - uses: actions/checkout@v4.2.2 - - uses: taiga-family/ci/actions/setup/variables@v1.101.0 - - uses: taiga-family/ci/actions/setup/node@v1.101.0 + - uses: taiga-family/ci/actions/setup/variables@v1.102.0 + - uses: taiga-family/ci/actions/setup/node@v1.102.0 - run: npm test - run: tree -L 2 ./coverage -P 'lcov.info' - uses: codecov/codecov-action@v5.1.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: directory: ./coverage/ flags: summary diff --git a/package-lock.json b/package-lock.json index d9012cb18d3d..2fee9e2c8093 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,16 +28,16 @@ "@nx/jest": "20.1.4", "@nx/workspace": "20.1.4", "@schematics/angular": "16.2.16", - "@taiga-ui/browserslist-config": "0.235.1", - "@taiga-ui/commitlint-config": "0.235.1", - "@taiga-ui/cspell-config": "0.235.1", + "@taiga-ui/browserslist-config": "0.235.2", + "@taiga-ui/commitlint-config": "0.235.2", + "@taiga-ui/cspell-config": "0.235.2", "@taiga-ui/design-tokens": "0.154.0", - "@taiga-ui/eslint-plugin-experience": "0.235.1", + "@taiga-ui/eslint-plugin-experience": "0.235.2", "@taiga-ui/event-plugins": "4.3.1", - "@taiga-ui/jest-config": "0.235.1", - "@taiga-ui/prettier-config": "0.235.1", - "@taiga-ui/stylelint-config": "0.235.1", - "@taiga-ui/tsconfig": "0.235.1", + "@taiga-ui/jest-config": "0.235.2", + "@taiga-ui/prettier-config": "0.235.2", + "@taiga-ui/stylelint-config": "0.235.2", + "@taiga-ui/tsconfig": "0.235.2", "@types/glob": "8.1.0", "@types/loader-utils": "2.0.6", "@types/node": "22.10.1", @@ -3660,9 +3660,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.3.tgz", - "integrity": "sha512-yTmc8J+Sj8yLzwr4PD5Xb/WF3bOYu2C2OoSZPzbuqRm4n98XirsbzaX+GloeO376UnSYIYJ4NCanwV5/ugZkwA==", + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", "dev": true, "license": "MIT", "dependencies": { @@ -4506,9 +4506,9 @@ "peer": true }, "node_modules/@cspell/dict-npm": { - "version": "5.1.14", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.1.14.tgz", - "integrity": "sha512-7VV/rrRlxOwy5j0bpw6/Uci+nx/rwSgx45FJdeKq++nHsBx/nEXMFNODknm4Mi6i7t7uOVHExpifrR6w6xTWww==", + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.1.15.tgz", + "integrity": "sha512-95D3A8rs9SYlUQUkK48J0F1W3jOsc63dY/vlzuNHE4nuGU2OM4jtoWvLk0ovhBMHwZikaNNTHaHoJyr+VKu+Yg==", "dev": true, "license": "MIT", "peer": true @@ -4538,9 +4538,9 @@ "peer": true }, "node_modules/@cspell/dict-python": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.12.tgz", - "integrity": "sha512-U25eOFu+RE0aEcF2AsxZmq3Lic7y9zspJ9SzjrC0mfJz+yr3YmSCw4E0blMD3mZoNcf7H/vMshuKIY5AY36U+Q==", + "version": "4.2.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.13.tgz", + "integrity": "sha512-mZIcmo9qif8LkJ6N/lqTZawcOk2kVTcuWIUOSbMcjyomO0XZ7iWz15TfONyr03Ea/l7o5ULV+MZ4vx76bAUb7w==", "dev": true, "license": "MIT", "peer": true, @@ -4597,9 +4597,9 @@ "peer": true }, "node_modules/@cspell/dict-software-terms": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-4.1.17.tgz", - "integrity": "sha512-QORIk1R5DV8oOQ+oAlUWE7UomaJwUucqu2srrc2+PmkoI6R1fJwwg2uHCPBWlIb4PGDNEdXLv9BAD13H+0wytQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-4.1.18.tgz", + "integrity": "sha512-QhOQ3qVFr2Y+uDw2SH15klVNU2S07ecFhG+2gpTO/K4Kuaui3INbVrzHOKW41ofP3ghv9y2TkUUtOP5KfddP8A==", "dev": true, "license": "MIT", "peer": true @@ -6466,9 +6466,9 @@ } }, "node_modules/@jsonjoy.com/json-pack": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", - "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -8791,9 +8791,9 @@ } }, "node_modules/@nx/webpack/node_modules/memfs": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.14.1.tgz", - "integrity": "sha512-Fq5CMEth+2iprLJ5mNizRcWuiwRZYjNkUD0zKk224jZunE9CRacTRDK8QLALbMBlNX2y3nY6lKZbesCwDwacig==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.0.tgz", + "integrity": "sha512-q9MmZXd2rRWHS6GU3WEm3HyiXZyyoA1DqdOhEq0lxPBmKb5S7IAOwX0RgUCwJfqjelDCySa5h8ujOy24LqsWcw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -9203,13 +9203,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz", - "integrity": "sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.49.0" + "playwright": "1.49.1" }, "bin": { "playwright": "cli.js" @@ -9608,9 +9608,9 @@ "license": "MIT" }, "node_modules/@stylistic/eslint-plugin": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.11.0.tgz", - "integrity": "sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.12.0.tgz", + "integrity": "sha512-IvD2WXbOoSp0zNpyYbjdSyEjZtut78RYfj2WIlbChE7HFuposTK5X1hc5+4AyqYcjLXYdD5oo/sJtqMGFNRb1w==", "dev": true, "license": "MIT", "peer": true, @@ -9629,9 +9629,9 @@ } }, "node_modules/@stylistic/eslint-plugin-js": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.11.0.tgz", - "integrity": "sha512-btchD0P3iij6cIk5RR5QMdEhtCCV0+L6cNheGhGCd//jaHILZMTi/EOqgEDAf1s4ZoViyExoToM+S2Iwa3U9DA==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.12.0.tgz", + "integrity": "sha512-HMA+qhlDLmLiYC0nyLPEJT4CBq3BP9ri51WECRKmEjO6RZm41MVZCJl+IfUcp2sUvGSl3/FSK5gzgBKcVv8S3w==", "dev": true, "license": "MIT", "peer": true, @@ -9661,9 +9661,9 @@ } }, "node_modules/@stylistic/eslint-plugin-plus": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.11.0.tgz", - "integrity": "sha512-m8dkgJWdLMdVyZRo7+AlZ6sBPhoxn9N3I3QftfODLHkCOpF9o2K7rN0J2yX2e1lbmFKnSb/SaLrNsiqm6l4HAw==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.12.0.tgz", + "integrity": "sha512-90X/B58m7TMotKFW/+UE1ETULAT5ja3XyVyMcIt5p+T5tYcZw1HtM6dJc78lEdPLewiMJ0894EURpITldpgRJw==", "dev": true, "license": "MIT", "peer": true, @@ -9672,9 +9672,9 @@ } }, "node_modules/@stylistic/eslint-plugin-ts": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.11.0.tgz", - "integrity": "sha512-ZBxnfSjzxUiwCibbVCeYCYwZw+P5xaQw+pNA8B8uR42fdMQIOhUstXjJuS2nTHoW5CF4+vGSxbL4gklI8WxhyA==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.12.0.tgz", + "integrity": "sha512-JqoHGQCeW0dC3LN/7+ZRwTOCs3kBum2b4k7ovx+0RXeaDIINs5F+/Mp/NvTCPqDzUlBkd1HOaviKyaEWpKA7Yw==", "dev": true, "license": "MIT", "peer": true, @@ -9794,9 +9794,9 @@ "link": true }, "node_modules/@taiga-ui/browserslist-config": { - "version": "0.235.1", - "resolved": "https://registry.npmjs.org/@taiga-ui/browserslist-config/-/browserslist-config-0.235.1.tgz", - "integrity": "sha512-hU5TeUEp3jEBmuTvG/IlD6LTFoxcrKSAueuLN1RmQKu3IL7qrKxwVZFGevNgFS8dnhH3iV9hV96TrbM0jEUuww==", + "version": "0.235.2", + "resolved": "https://registry.npmjs.org/@taiga-ui/browserslist-config/-/browserslist-config-0.235.2.tgz", + "integrity": "sha512-DRHUlJyWOzi91Uyu+7q9QfoZR5/JvqwIsGBD7kw4XwCT21hpUTdidDP0wUYmz6hrUyp7cZ6572o65nOWU0WAGA==", "dev": true, "license": "Apache-2.0" }, @@ -9805,9 +9805,9 @@ "link": true }, "node_modules/@taiga-ui/commitlint-config": { - "version": "0.235.1", - "resolved": "https://registry.npmjs.org/@taiga-ui/commitlint-config/-/commitlint-config-0.235.1.tgz", - "integrity": "sha512-v32i8uwLimlflBp/cnydfCxJf7WdZFL64LmWt9sr++UDTFoIs2aYtd4P1cmKrFGIUF2LJMHYsgxK9awFdSRqvg==", + "version": "0.235.2", + "resolved": "https://registry.npmjs.org/@taiga-ui/commitlint-config/-/commitlint-config-0.235.2.tgz", + "integrity": "sha512-4rpBnFD0XWDPt4I/VgY9mTYwCcEEZ3l2k5+N1Kq6Dunf6cySJPxRRzTZMvcRbkCNrE0LjaYvpZWO7Vd/6XHrew==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -9820,9 +9820,9 @@ "link": true }, "node_modules/@taiga-ui/cspell-config": { - "version": "0.235.1", - "resolved": "https://registry.npmjs.org/@taiga-ui/cspell-config/-/cspell-config-0.235.1.tgz", - "integrity": "sha512-kTQz3zGT5tNRx8moignjio/LNKTrbsiGOqouTkjgAF28fkK5Y3n70cWyYqglhZeCETqitbQjKym3UF3E3qkEOA==", + "version": "0.235.2", + "resolved": "https://registry.npmjs.org/@taiga-ui/cspell-config/-/cspell-config-0.235.2.tgz", + "integrity": "sha512-clnHVDtJgrD5r8Z3D0Dn6rafjckG2TLrUFSWzXWZ/+Lllbr4mAuSQhFV5qPDv/uFZnCBevS+7EKdpGS8QPMHCQ==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -9872,9 +9872,9 @@ } }, "node_modules/@taiga-ui/eslint-plugin-experience": { - "version": "0.235.1", - "resolved": "https://registry.npmjs.org/@taiga-ui/eslint-plugin-experience/-/eslint-plugin-experience-0.235.1.tgz", - "integrity": "sha512-h7VeN6b4K5PU0rWA0gk9j5aJ7XTHCIXofTBDWvGB7KjIgv2pQ8TGLGrNKsmQcuST61VevklEXecrVZPx9SbWPw==", + "version": "0.235.2", + "resolved": "https://registry.npmjs.org/@taiga-ui/eslint-plugin-experience/-/eslint-plugin-experience-0.235.2.tgz", + "integrity": "sha512-bJUilnEyyHKjJCLz6LuXqJ2ycYqcOIz7O9AM8ca1a6qN6+qwPLxzUQyAdFjz98khMkS1ticaMwIdP4wWQ1q00A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -9886,19 +9886,19 @@ "@angular-eslint/template-parser": "^18.4.0", "@babel/eslint-parser": "^7.25.9", "@babel/eslint-plugin": "^7.25.9", - "@stylistic/eslint-plugin": "^2.11.0", - "@stylistic/eslint-plugin-js": "^2.11.0", - "@stylistic/eslint-plugin-plus": "^2.11.0", - "@stylistic/eslint-plugin-ts": "^2.11.0", - "@typescript-eslint/eslint-plugin": "^8.16.0", - "@typescript-eslint/parser": "^8.16.0", - "@typescript-eslint/types": "^8.16.0", - "@typescript-eslint/typescript-estree": "^8.16.0", - "@typescript-eslint/utils": "^8.16.0", + "@stylistic/eslint-plugin": "^2.12.0", + "@stylistic/eslint-plugin-js": "^2.12.0", + "@stylistic/eslint-plugin-plus": "^2.12.0", + "@stylistic/eslint-plugin-ts": "^2.12.0", + "@typescript-eslint/eslint-plugin": "^8.17.0", + "@typescript-eslint/parser": "^8.17.0", + "@typescript-eslint/types": "^8.17.0", + "@typescript-eslint/typescript-estree": "^8.17.0", + "@typescript-eslint/utils": "^8.17.0", "eslint": "^8.57.1 || ^9.0.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^9.1.0", - "eslint-import-resolver-typescript": "^3.6.3", + "eslint-import-resolver-typescript": "^3.7.0", "eslint-import-resolver-webpack": "^0.13.9", "eslint-plugin-cypress": "^3.6.0", "eslint-plugin-decorator-position": "^5.0.2", @@ -10038,15 +10038,15 @@ "link": true }, "node_modules/@taiga-ui/jest-config": { - "version": "0.235.1", - "resolved": "https://registry.npmjs.org/@taiga-ui/jest-config/-/jest-config-0.235.1.tgz", - "integrity": "sha512-u/TJMot0aN7Ksp/wt7M0NDTP4RFx99tWexcO981wOpGAbWwMkF9wQVYj4eOzusubA47WTfK2sp2NtvR49lwu6A==", + "version": "0.235.2", + "resolved": "https://registry.npmjs.org/@taiga-ui/jest-config/-/jest-config-0.235.2.tgz", + "integrity": "sha512-TaXqM46jzdSQeUWDsaDLdf6eXj7gSyNYea+E7xMBRPqkDgh0nFi5+pm2BWXRZH8TIx1P+Plg/PC05wnSJDz09A==", "dev": true, "license": "Apache-2.0", "dependencies": { "@types/jest": "29.5.14", "jest": "29.7.0", - "jest-preset-angular": "14.4.1", + "jest-preset-angular": "14.4.2", "ts-jest": "29.2.5" } }, @@ -10077,14 +10077,14 @@ } }, "node_modules/@taiga-ui/prettier-config": { - "version": "0.235.1", - "resolved": "https://registry.npmjs.org/@taiga-ui/prettier-config/-/prettier-config-0.235.1.tgz", - "integrity": "sha512-za9hM1TOzKVaPdqopdV+XOjwVR+TjEsqmt3CDSRILDbqIEfXcmUV8HBnPQX3O9bYrhuEXRmEz8Q2IYC5jLwzTA==", + "version": "0.235.2", + "resolved": "https://registry.npmjs.org/@taiga-ui/prettier-config/-/prettier-config-0.235.2.tgz", + "integrity": "sha512-tqcOCncKvlh39rQyCdLrtwPqN8Z2DjqiSFrOCcbGN50BmZ/ngu6109OB+zfEsELKavBuvuEgy/iwO00dnoRW+Q==", "dev": true, "license": "Apache-2.0", "peerDependencies": { "@prettier/plugin-xml": "^3.4.1", - "prettier": "^3.4.1", + "prettier": "^3.4.2", "prettier-package-json": "^2.8.0", "prettier-plugin-organize-attributes": "^1.0.0", "sort-package-json": "^2.12.0", @@ -10092,9 +10092,9 @@ } }, "node_modules/@taiga-ui/stylelint-config": { - "version": "0.235.1", - "resolved": "https://registry.npmjs.org/@taiga-ui/stylelint-config/-/stylelint-config-0.235.1.tgz", - "integrity": "sha512-aHX658fEsV23PwwisbDxtw2PMrK1LeDfIy4IQ5tVJZTh467bBU2dPvsweNzV3WO1AWP1NPhsaz1LH3TAxUG15Q==", + "version": "0.235.2", + "resolved": "https://registry.npmjs.org/@taiga-ui/stylelint-config/-/stylelint-config-0.235.2.tgz", + "integrity": "sha512-3Y26KNn40QZanMzb6nyZ3LdiI1wr4oN43GCw0lWiyDtk5WnFiShpXTgVKIVTl5RwTA+yCsqJrghMiU3YlzYnow==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -10118,9 +10118,9 @@ "link": true }, "node_modules/@taiga-ui/tsconfig": { - "version": "0.235.1", - "resolved": "https://registry.npmjs.org/@taiga-ui/tsconfig/-/tsconfig-0.235.1.tgz", - "integrity": "sha512-LIz4OxIomWBIdeOhlh/YjtRhG9b8HneaALbfRFe2WxnFfbnn3xeEEZUwGsRtpq1OTRmVaF9fOIfQtvDSNKprAA==", + "version": "0.235.2", + "resolved": "https://registry.npmjs.org/@taiga-ui/tsconfig/-/tsconfig-0.235.2.tgz", + "integrity": "sha512-5vWdX7vuf4TaTbyOsJ9lALtI7pvBu9tRxV6k8vezeVFusBxz2cE3+9TI/jqrqGPp+UnwTmEyXq+aKNsBuV6ViQ==", "dev": true, "license": "Apache-2.0" }, @@ -11347,9 +11347,9 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", "dev": true, "license": "ISC", "peer": true @@ -13889,17 +13889,16 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -13908,6 +13907,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -13960,9 +13973,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001686", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz", - "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==", + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", "dev": true, "funding": [ { @@ -16474,14 +16487,14 @@ } }, "node_modules/css-tree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.0.1.tgz", - "integrity": "sha512-8Fxxv+tGhORlshCdCwnNJytvlvq46sOLSYEx2ZIGurahWvMucSRnyjPA3AmrMq4VPRYbHVpWj5VkiVasrM2H4Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "mdn-data": "2.12.1", + "mdn-data": "2.12.2", "source-map-js": "^1.0.1" }, "engines": { @@ -16975,9 +16988,9 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "license": "MIT", "dependencies": { @@ -17630,6 +17643,21 @@ "node": ">=4" } }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -17749,9 +17777,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.70", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.70.tgz", - "integrity": "sha512-P6FPqAWIZrC3sHDAwBitJBs7N7IF58m39XVny7DFseQXK2eiMn7nNQizFf63mWDDUnFvaqsM8FI0+ZZfLkdUGA==", + "version": "1.5.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", + "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==", "dev": true, "license": "ISC" }, @@ -17874,6 +17902,24 @@ "xmlhttprequest-ssl": "~2.1.1" } }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/engine.io-client/node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -17916,6 +17962,24 @@ "node": ">= 0.6" } }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/engine.io/node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -18094,14 +18158,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -22226,17 +22287,20 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.5.tgz", + "integrity": "sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -23054,13 +23118,14 @@ } }, "node_modules/has-proto": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.1.0.tgz", - "integrity": "sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.7" + "dunder-proto": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -25977,9 +26042,9 @@ } }, "node_modules/jest-preset-angular": { - "version": "14.4.1", - "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-14.4.1.tgz", - "integrity": "sha512-6QBP9SN+VVilghc5hjWzJ4ZBrBB4Djl2fO5uyjJhIWEq/r9255fAyDNHfoigdUbx3l4MRVwwyiTMXRsFAZE4XQ==", + "version": "14.4.2", + "resolved": "https://registry.npmjs.org/jest-preset-angular/-/jest-preset-angular-14.4.2.tgz", + "integrity": "sha512-BYYv0FaTDfBNh8WyA9mpOV3krfw20kurBGK8INZUnv7KZDAWZuQtCET4TwTWxSNQ9jS1OX1+a5weCm/bTDDM1A==", "dev": true, "license": "MIT", "dependencies": { @@ -27402,6 +27467,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lint-staged/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/lint-staged/node_modules/emoji-regex": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", @@ -28303,9 +28386,9 @@ } }, "node_modules/lucide-static": { - "version": "0.465.0", - "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-0.465.0.tgz", - "integrity": "sha512-CtNyC1KleoEIGYNVjMpLmiy5rFadlW7nWNozIRddoyPPNXEV5SthpwfACvm1a1vsNwmMWhtHUTnHUzkmWjQGLg==", + "version": "0.468.0", + "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-0.468.0.tgz", + "integrity": "sha512-JvpWui2umxRyEVMoETfMzb+qKqibV/sdoqJbKmW1JLdkuhXluJKoO6NqCbvCK/vAbUuH5bTEFD4T6uECsrNcnA==", "dev": true, "license": "ISC" }, @@ -28649,9 +28732,9 @@ } }, "node_modules/mdn-data": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.1.tgz", - "integrity": "sha512-rsfnCbOHjqrhWxwt5/wtSLzpoKTzW7OXdT5lLOIH1OTYhWu9rRJveGq0sKvDZODABH7RX+uoR+DYcpFnq4Tf6Q==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true, "license": "CC0-1.0", "peer": true @@ -31803,13 +31886,13 @@ "license": "MIT" }, "node_modules/playwright": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz", - "integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.49.0" + "playwright-core": "1.49.1" }, "bin": { "playwright": "cli.js" @@ -31822,9 +31905,9 @@ } }, "node_modules/playwright-core": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz", - "integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -33196,32 +33279,28 @@ } }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", "dev": true, "license": "MIT", "peer": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", + "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "scheduler": "^0.25.0" }, "peerDependencies": { - "react": "^18.3.1" + "react": "^19.0.0" } }, "node_modules/react-is": { @@ -33543,20 +33622,21 @@ "license": "Apache-2.0" }, "node_modules/reflect.getprototypeof": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.7.tgz", - "integrity": "sha512-bMvFGIUKlc/eSfXNX+aZ+EL95/EgZzuwA0OBPTbZZDEJw/0AkentjMuM1oiRfwHrshqk4RzdgiTg5CcDalXN5g==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz", + "integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", + "dunder-proto": "^1.0.0", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "which-builtin-type": "^1.1.4" + "gopd": "^1.2.0", + "which-builtin-type": "^1.2.0" }, "engines": { "node": ">= 0.4" @@ -34335,15 +34415,12 @@ } }, "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0" - } + "peer": true }, "node_modules/schema-utils": { "version": "4.2.0", @@ -35134,6 +35211,24 @@ "ws": "~8.17.1" } }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/socket.io-adapter/node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -35172,6 +35267,24 @@ "node": ">=10.0.0" } }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/socket.io-parser": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", @@ -35186,6 +35299,42 @@ "node": ">=10.0.0" } }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -37331,22 +37480,22 @@ } }, "node_modules/tldts": { - "version": "6.1.65", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.65.tgz", - "integrity": "sha512-xU9gLTfAGsADQ2PcWee6Hg8RFAv0DnjMGVJmDnUmI8a9+nYmapMQix4afwrdaCtT+AqP4MaxEzu7cCrYmBPbzQ==", + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.66.tgz", + "integrity": "sha512-l3ciXsYFel/jSRfESbyKYud1nOw7WfhrBEF9I3UiarYk/qEaOOwu3qXNECHw4fHGHGTEOuhf/VdKgoDX5M/dhQ==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.65" + "tldts-core": "^6.1.66" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.65", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.65.tgz", - "integrity": "sha512-Uq5t0N0Oj4nQSbU8wFN1YYENvMthvwU13MQrMJRspYCGLSAZjAfoBOJki5IQpnBM/WFskxxC/gIOTwaedmHaSg==", + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.66.tgz", + "integrity": "sha512-s07jJruSwndD2X8bVjwioPfqpIc1pDTzszPe9pL1Skbh4bjytL85KNQ3tolqLbCvpQHawIsGfFi9dgerWjqW4g==", "dev": true, "license": "MIT" }, @@ -39797,7 +39946,7 @@ "projects/demo-playwright": { "name": "@taiga-ui/demo-playwright", "devDependencies": { - "@playwright/test": "1.49.0" + "@playwright/test": "1.49.1" } }, "projects/demo/node_modules/@types/express": { @@ -39843,7 +39992,7 @@ "version": "4.17.0", "license": "Apache-2.0", "devDependencies": { - "lucide-static": "0.465.0" + "lucide-static": "0.468.0" } }, "projects/icons-fontawesome": { @@ -39945,32 +40094,6 @@ "@taiga-ui/cdk": "^4.17.0", "tslib": ">=2.8.1" } - }, - "projects/testing/node_modules/jest-preset-angular": { - "version": "14.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "^0.2.6", - "esbuild-wasm": ">=0.15.13", - "jest-environment-jsdom": "^29.0.0", - "jest-util": "^29.0.0", - "pretty-format": "^29.0.0", - "ts-jest": "^29.0.0" - }, - "engines": { - "node": "^14.15.0 || >=16.10.0" - }, - "optionalDependencies": { - "esbuild": ">=0.15.13" - }, - "peerDependencies": { - "@angular/compiler-cli": ">=15.0.0 <20.0.0", - "@angular/core": ">=15.0.0 <20.0.0", - "@angular/platform-browser-dynamic": ">=15.0.0 <20.0.0", - "jest": "^29.0.0", - "typescript": ">=4.8" - } } } } diff --git a/package.json b/package.json index 0801bb6aa99a..560614ec67cc 100644 --- a/package.json +++ b/package.json @@ -158,16 +158,16 @@ "@nx/jest": "20.1.4", "@nx/workspace": "20.1.4", "@schematics/angular": "16.2.16", - "@taiga-ui/browserslist-config": "0.235.1", - "@taiga-ui/commitlint-config": "0.235.1", - "@taiga-ui/cspell-config": "0.235.1", + "@taiga-ui/browserslist-config": "0.235.2", + "@taiga-ui/commitlint-config": "0.235.2", + "@taiga-ui/cspell-config": "0.235.2", "@taiga-ui/design-tokens": "0.154.0", - "@taiga-ui/eslint-plugin-experience": "0.235.1", + "@taiga-ui/eslint-plugin-experience": "0.235.2", "@taiga-ui/event-plugins": "4.3.1", - "@taiga-ui/jest-config": "0.235.1", - "@taiga-ui/prettier-config": "0.235.1", - "@taiga-ui/stylelint-config": "0.235.1", - "@taiga-ui/tsconfig": "0.235.1", + "@taiga-ui/jest-config": "0.235.2", + "@taiga-ui/prettier-config": "0.235.2", + "@taiga-ui/stylelint-config": "0.235.2", + "@taiga-ui/tsconfig": "0.235.2", "@types/glob": "8.1.0", "@types/loader-utils": "2.0.6", "@types/node": "22.10.1", diff --git a/projects/addon-table/components/table/directives/direction-order.directive.ts b/projects/addon-table/components/table/directives/direction-order.directive.ts index ca6de78c4314..3db803d9e07c 100644 --- a/projects/addon-table/components/table/directives/direction-order.directive.ts +++ b/projects/addon-table/components/table/directives/direction-order.directive.ts @@ -1,6 +1,7 @@ import {Directive, inject, Input, Output} from '@angular/core'; import {map} from 'rxjs'; +import {TuiSortDirection} from '../table.options'; import {TuiTableDirective} from './table.directive'; @Directive({ @@ -17,6 +18,7 @@ export class TuiTableDirectionOrder { @Input() public set directionOrder(order: 'asc' | 'desc') { - this.table.direction = order === 'asc' ? 1 : -1; + this.table.direction = + order === 'asc' ? TuiSortDirection.Asc : TuiSortDirection.Desc; } } diff --git a/projects/addon-table/components/table/directives/table.directive.ts b/projects/addon-table/components/table/directives/table.directive.ts index 73d1c95d7257..71051fc19c92 100644 --- a/projects/addon-table/components/table/directives/table.directive.ts +++ b/projects/addon-table/components/table/directives/table.directive.ts @@ -23,7 +23,7 @@ import {tuiChipOptionsProvider} from '@taiga-ui/kit/components/chip'; import {tuiProgressOptionsProvider} from '@taiga-ui/kit/components/progress'; import {Subject} from 'rxjs'; -import {TUI_TABLE_OPTIONS} from '../table.options'; +import {TUI_TABLE_OPTIONS, TuiSortDirection} from '../table.options'; import {TuiStuck} from './stuck.directive'; @Component({ @@ -72,7 +72,7 @@ export class TuiTableDirective>> public direction = this.options.direction; @Output() - public readonly directionChange = new EventEmitter<-1 | 1>(); + public readonly directionChange = new EventEmitter(); @Output() public readonly sorterChange = new EventEmitter | null>(); @@ -94,7 +94,11 @@ export class TuiTableDirective>> public updateSorterAndDirection(sorter: TuiComparator | null): void { if (this.sorter === sorter) { - this.updateDirection(this.direction === 1 ? -1 : 1); + this.updateDirection( + this.direction === TuiSortDirection.Asc + ? TuiSortDirection.Desc + : TuiSortDirection.Asc, + ); } else { this.updateSorter(sorter); this.updateDirection(1); @@ -115,7 +119,7 @@ export class TuiTableDirective>> this.change$.next(); } - private updateDirection(direction: -1 | 1): void { + private updateDirection(direction: TuiSortDirection): void { this.direction = direction; this.directionChange.emit(this.direction); this.change$.next(); diff --git a/projects/addon-table/components/table/directives/test/direction-order.directive.spec.ts b/projects/addon-table/components/table/directives/test/direction-order.directive.spec.ts index cf2cff5b7a77..369998da2baf 100644 --- a/projects/addon-table/components/table/directives/test/direction-order.directive.spec.ts +++ b/projects/addon-table/components/table/directives/test/direction-order.directive.spec.ts @@ -1,7 +1,7 @@ import {ChangeDetectionStrategy, Component, ViewChild} from '@angular/core'; import type {ComponentFixture} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing'; -import {TuiTable, TuiTableDirective} from '@taiga-ui/addon-table'; +import {TuiSortDirection, TuiTable, TuiTableDirective} from '@taiga-ui/addon-table'; describe('TuiDirectionOrder directive', () => { @Component({ @@ -44,31 +44,31 @@ describe('TuiDirectionOrder directive', () => { it('sets the sort direction of table to ascending', () => { fixture.detectChanges(); - expect(testComponent.table.direction).toBe(1); + expect(testComponent.table.direction).toBe(TuiSortDirection.Asc); }); it('sets the sort direction of table to descending', () => { testComponent.directionOrder = 'desc'; fixture.detectChanges(); - expect(testComponent.table.direction).toBe(-1); + expect(testComponent.table.direction).toBe(TuiSortDirection.Desc); }); describe('when table emits direction change', () => { it('emits ascending directionOrder', () => { - testComponent.table.directionChange.emit(1); + testComponent.table.directionChange.emit(TuiSortDirection.Asc); expect(testComponent.directionOrderChange).toHaveBeenCalledWith('asc'); }); it('emits descending directionOrder', () => { - testComponent.table.directionChange.emit(-1); + testComponent.table.directionChange.emit(TuiSortDirection.Desc); expect(testComponent.directionOrderChange).toHaveBeenCalledWith('desc'); }); it('should not emit directionChange when updating sorter programmatically', () => { - testComponent.table.updateSorter(() => -1); + testComponent.table.updateSorter(() => TuiSortDirection.Desc); expect(testComponent.directionOrderChange).not.toHaveBeenCalled(); }); diff --git a/projects/addon-table/components/table/pipes/table-sort.pipe.ts b/projects/addon-table/components/table/pipes/table-sort.pipe.ts index f52441b492f4..2e1c5b59e402 100644 --- a/projects/addon-table/components/table/pipes/table-sort.pipe.ts +++ b/projects/addon-table/components/table/pipes/table-sort.pipe.ts @@ -4,6 +4,7 @@ import type {TuiComparator} from '@taiga-ui/addon-table/types'; import {tuiPure} from '@taiga-ui/cdk/utils/miscellaneous'; import {TuiTableDirective} from '../directives/table.directive'; +import type {TuiSortDirection} from '../table.options'; @Pipe({ standalone: true, @@ -21,7 +22,7 @@ export class TuiTableSortPipe>> implements PipeTran private sort( data: readonly T[], sorter: TuiComparator, - direction: -1 | 1, + direction: TuiSortDirection, ): readonly T[] { return [...data].sort((a, b) => direction * sorter(a, b)); } diff --git a/projects/addon-table/components/table/table.options.ts b/projects/addon-table/components/table/table.options.ts index 293de4867962..1f67be1001d5 100644 --- a/projects/addon-table/components/table/table.options.ts +++ b/projects/addon-table/components/table/table.options.ts @@ -2,8 +2,14 @@ import type {Provider} from '@angular/core'; import {tuiCreateToken, tuiProvideOptions} from '@taiga-ui/cdk/utils/miscellaneous'; import type {TuiSizeL, TuiSizeS} from '@taiga-ui/core/types'; +export const TuiSortDirection = { + Asc: 1, + Desc: -1, +} as const; +export type TuiSortDirection = (typeof TuiSortDirection)[keyof typeof TuiSortDirection]; + export interface TuiTableOptions { - readonly direction: -1 | 1; + readonly direction: TuiSortDirection; readonly requiredSort: boolean; readonly open: boolean; readonly resizable: boolean; @@ -21,7 +27,7 @@ export const TUI_TABLE_DEFAULT_OPTIONS: TuiTableOptions = { resizable: false, open: true, size: 'm', - direction: 1, + direction: TuiSortDirection.Asc, requiredSort: false, sortIcons: { asc: '@tui.chevron-up', diff --git a/projects/addon-table/components/table/th/th.component.ts b/projects/addon-table/components/table/th/th.component.ts index b8be54bab86e..3b6046f03514 100644 --- a/projects/addon-table/components/table/th/th.component.ts +++ b/projects/addon-table/components/table/th/th.component.ts @@ -14,7 +14,7 @@ import {TuiIcon} from '@taiga-ui/core/components/icon'; import {TuiTableHead} from '../directives/head.directive'; import {TuiTableResized} from '../directives/resized.directive'; import {TuiTableDirective} from '../directives/table.directive'; -import {TUI_TABLE_OPTIONS} from '../table.options'; +import {TUI_TABLE_OPTIONS, TuiSortDirection} from '../table.options'; @Component({ standalone: true, @@ -70,9 +70,9 @@ export class TuiTableTh>> { protected get icon(): string { if (this.isCurrent) { - return this.table?.direction === 1 - ? this.options.sortIcons.desc - : this.options.sortIcons.asc; + return this.table?.direction === TuiSortDirection.Asc + ? this.options.sortIcons.asc + : this.options.sortIcons.desc; } return this.options.sortIcons.off; @@ -82,7 +82,7 @@ export class TuiTableTh>> { const sorter = this.requiredSort ? this.sorter : null; this.table?.updateSorterAndDirection( - this.isCurrentAndAscDirection ? sorter : this.sorter, + this.isCurrentAndDescDirection ? sorter : this.sorter, ); } @@ -90,8 +90,11 @@ export class TuiTableTh>> { this.width = width; } - private get isCurrentAndAscDirection(): boolean { - return this.sorter === this.table?.sorter && this.table?.direction === -1; + private get isCurrentAndDescDirection(): boolean { + return ( + this.sorter === this.table?.sorter && + this.table?.direction === TuiSortDirection.Desc + ); } } diff --git a/projects/cdk/utils/di/create-options.ts b/projects/cdk/utils/di/create-options.ts index d2f84baa356f..86525cefc7d9 100644 --- a/projects/cdk/utils/di/create-options.ts +++ b/projects/cdk/utils/di/create-options.ts @@ -1,9 +1,12 @@ -import type {FactoryProvider, InjectionToken} from '@angular/core'; +import type {FactoryProvider, InjectionToken, ProviderToken} from '@angular/core'; import {tuiCreateToken, tuiProvideOptions} from '@taiga-ui/cdk/utils/miscellaneous'; export function tuiCreateOptions( defaults: T, -): [token: InjectionToken, provider: (item: Partial) => FactoryProvider] { +): [ + token: InjectionToken, + provider: (item: Partial | ProviderToken>) => FactoryProvider, +] { const token = tuiCreateToken(defaults); return [token, (options) => tuiProvideOptions(token, options, defaults)]; diff --git a/projects/cdk/utils/miscellaneous/provide-options.ts b/projects/cdk/utils/miscellaneous/provide-options.ts index 9dd009236edf..32c7d3493c49 100644 --- a/projects/cdk/utils/miscellaneous/provide-options.ts +++ b/projects/cdk/utils/miscellaneous/provide-options.ts @@ -1,16 +1,16 @@ -import type {FactoryProvider, InjectionToken} from '@angular/core'; +import type {FactoryProvider, InjectionToken, ProviderToken} from '@angular/core'; import {inject} from '@angular/core'; export function tuiProvideOptions( provide: InjectionToken, - options: Partial, + options: Partial | ProviderToken>, fallback: T, ): FactoryProvider { return { provide, useFactory: (): T => ({ ...(inject(provide, {optional: true, skipSelf: true}) || fallback), - ...options, + ...(inject(options as any, {optional: true}) || options), }), }; } diff --git a/projects/core/components/button/button.options.ts b/projects/core/components/button/button.options.ts index 2d390e343baf..3a18fa46fd19 100644 --- a/projects/core/components/button/button.options.ts +++ b/projects/core/components/button/button.options.ts @@ -1,5 +1,4 @@ -import type {FactoryProvider} from '@angular/core'; -import {tuiCreateToken, tuiProvideOptions} from '@taiga-ui/cdk/utils/miscellaneous'; +import {tuiCreateOptions} from '@taiga-ui/cdk/utils/di'; import type {TuiAppearanceOptions} from '@taiga-ui/core/directives/appearance'; import type {TuiSizeXL, TuiSizeXS} from '@taiga-ui/core/types'; @@ -12,10 +11,6 @@ export const TUI_BUTTON_DEFAULT_OPTIONS: TuiButtonOptions = { size: 'l', }; -export const TUI_BUTTON_OPTIONS = tuiCreateToken(TUI_BUTTON_DEFAULT_OPTIONS); - -export function tuiButtonOptionsProvider( - options: Partial, -): FactoryProvider { - return tuiProvideOptions(TUI_BUTTON_OPTIONS, options, TUI_BUTTON_DEFAULT_OPTIONS); -} +export const [TUI_BUTTON_OPTIONS, tuiButtonOptionsProvider] = tuiCreateOptions( + TUI_BUTTON_DEFAULT_OPTIONS, +); diff --git a/projects/core/components/notification/notification.options.ts b/projects/core/components/notification/notification.options.ts index 16a6364d4725..53c94c4add50 100644 --- a/projects/core/components/notification/notification.options.ts +++ b/projects/core/components/notification/notification.options.ts @@ -1,6 +1,5 @@ -import type {Provider} from '@angular/core'; import type {TuiStringHandler} from '@taiga-ui/cdk/types'; -import {tuiCreateToken, tuiProvideOptions} from '@taiga-ui/cdk/utils/miscellaneous'; +import {tuiCreateOptions} from '@taiga-ui/cdk/utils/di'; import type {TuiAppearanceOptions} from '@taiga-ui/core/directives/appearance'; import type {TuiSizeL, TuiSizeS} from '@taiga-ui/core/types'; @@ -31,14 +30,5 @@ export const TUI_NOTIFICATION_DEFAULT_OPTIONS: TuiNotificationOptions = { /** * Default parameters for notification alert component */ -export const TUI_NOTIFICATION_OPTIONS = tuiCreateToken(TUI_NOTIFICATION_DEFAULT_OPTIONS); - -export function tuiNotificationOptionsProvider( - options: Partial, -): Provider { - return tuiProvideOptions( - TUI_NOTIFICATION_OPTIONS, - options, - TUI_NOTIFICATION_DEFAULT_OPTIONS, - ); -} +export const [TUI_NOTIFICATION_OPTIONS, tuiNotificationOptionsProvider] = + tuiCreateOptions(TUI_NOTIFICATION_DEFAULT_OPTIONS); diff --git a/projects/demo-playwright/package.json b/projects/demo-playwright/package.json index 1f5011b614fc..9a98aa73ed09 100644 --- a/projects/demo-playwright/package.json +++ b/projects/demo-playwright/package.json @@ -2,6 +2,6 @@ "name": "@taiga-ui/demo-playwright", "private": true, "devDependencies": { - "@playwright/test": "1.49.0" + "@playwright/test": "1.49.1" } } diff --git a/projects/demo-playwright/tests/core/breakpoint-service/breakpoint-service.pw.spec.ts b/projects/demo-playwright/tests/core/breakpoint-service/breakpoint-service.pw.spec.ts index fe209d6d194a..868fe07d0028 100644 --- a/projects/demo-playwright/tests/core/breakpoint-service/breakpoint-service.pw.spec.ts +++ b/projects/demo-playwright/tests/core/breakpoint-service/breakpoint-service.pw.spec.ts @@ -22,7 +22,7 @@ test.describe('Breakpoint service', () => { await tuiGoto(page, DemoRoute.BreakpointService); const example = new TuiDocumentationPagePO(page).getExample('#basic'); - await expect(example).toHaveScreenshot(`breakpoint_${width}x${height}.png`); + await expect(example).toHaveScreenshot(`breakpoint-${width}x${height}.png`); }); }); }); diff --git a/projects/demo-playwright/tests/core/dialogs/dialogs.pw.spec.ts b/projects/demo-playwright/tests/core/dialogs/dialogs.pw.spec.ts index 769f773b6b0b..96ba9cbaf029 100644 --- a/projects/demo-playwright/tests/core/dialogs/dialogs.pw.spec.ts +++ b/projects/demo-playwright/tests/core/dialogs/dialogs.pw.spec.ts @@ -21,7 +21,7 @@ test.describe('Dialogs', () => { await documentationPagePO.apiPageExample.locator('button').click(); await documentationPagePO.prepareBeforeScreenshot(); - await expect(page).toHaveScreenshot(`01-prompt_${width}x${height}.png`); + await expect(page).toHaveScreenshot(`01-prompt-${width}x${height}.png`); }); test.describe(`${width}x${height}`, () => { @@ -39,13 +39,13 @@ test.describe('Dialogs', () => { await documentationPagePO.prepareBeforeScreenshot(); await expect(page).toHaveScreenshot( - `02-dialogs-level-1_${width}x${height}.png`, + `02-dialogs-level-1-${width}x${height}.png`, ); await page.locator('tui-dialog button').nth(1).click(); await expect(page).toHaveScreenshot( - `02-dialogs-level-2_${width}x${height}.png`, + `02-dialogs-level-2-${width}x${height}.png`, ); }); @@ -58,7 +58,7 @@ test.describe('Dialogs', () => { await documentationPagePO.prepareBeforeScreenshot(); await expect(page).toHaveScreenshot( - `03-mobile-dialog_${width}x${height}.png`, + `03-mobile-dialog-${width}x${height}.png`, ); }); @@ -71,7 +71,7 @@ test.describe('Dialogs', () => { await documentationPagePO.prepareBeforeScreenshot(); await expect(page).toHaveScreenshot( - `04-dialogs-dialog-directive_${width}x${height}.png`, + `04-dialogs-dialog-directive-${width}x${height}.png`, ); }); @@ -84,7 +84,7 @@ test.describe('Dialogs', () => { await documentationPagePO.prepareBeforeScreenshot(); await expect(page).toHaveScreenshot( - `05-default-button_${width}x${height}.png`, + `05-default-button-${width}x${height}.png`, ); }); @@ -97,7 +97,7 @@ test.describe('Dialogs', () => { await documentationPagePO.prepareBeforeScreenshot(); await expect(page).toHaveScreenshot( - `06-custom-button_${width}x${height}.png`, + `06-custom-button-${width}x${height}.png`, ); }); @@ -113,7 +113,7 @@ test.describe('Dialogs', () => { test('Prompt', async ({page}) => { await expect(page).toHaveScreenshot( - `07-prompt_${width}x${height}.png`, + `07-prompt-${width}x${height}.png`, ); }); @@ -128,7 +128,7 @@ test.describe('Dialogs', () => { await page.locator('tui-dialog .t-close').click(); await expect(page).toHaveScreenshot( - `08-prompt-confirm_${width}x${height}.png`, + `08-prompt-confirm-${width}x${height}.png`, ); }); diff --git a/projects/demo-playwright/tests/core/hint/hint.pw.spec.ts b/projects/demo-playwright/tests/core/hint/hint.pw.spec.ts index 1cb585dfb07f..7c6cb215183d 100644 --- a/projects/demo-playwright/tests/core/hint/hint.pw.spec.ts +++ b/projects/demo-playwright/tests/core/hint/hint.pw.spec.ts @@ -43,7 +43,7 @@ test.describe('TuiHint', () => { await new TuiDocumentationPagePO(page).prepareBeforeScreenshot(); await expect(page).toHaveScreenshot( - `02-hint-manual-direction-${directionIndex}__${direction}-and-width__${width}.png`, + `02-hint-manual-direction-${directionIndex}-${direction}-and-width-${width}.png`, ); }); }); @@ -80,19 +80,19 @@ test.describe('TuiHint', () => { await example.apiPageExample.locator('span').hover(); await expect(page).toHaveScreenshot( - `03-hint-mode-${mode}-tuiHintShowDelay-1000__wait-0.png`, + `03-hint-mode-${mode}-tuiHintShowDelay-1000-wait-0.png`, ); await page.waitForTimeout(500); await expect(page).toHaveScreenshot( - `03-hint-mode-${mode}-tuiHintShowDelay-1000_wait-500.png`, + `03-hint-mode-${mode}-tuiHintShowDelay-1000-wait-500.png`, ); await page.waitForTimeout(500); await expect(page).toHaveScreenshot( - `03-hint-mode-${mode}-tuiHintShowDelay-1000_wait-1000.png`, + `03-hint-mode-${mode}-tuiHintShowDelay-1000-wait-1000.png`, ); }); }); @@ -126,11 +126,11 @@ test.describe('TuiHint', () => { await new TuiDocumentationPagePO(page).prepareBeforeScreenshot(); - await expect(page).toHaveScreenshot('06-hint-direction__bottom.png'); + await expect(page).toHaveScreenshot('06-hint-direction-bottom.png'); await page.setViewportSize({width: 1280, height: 150}); - await expect(page).toHaveScreenshot('06-hint-direction__left.png'); + await expect(page).toHaveScreenshot('06-hint-direction-left.png'); }); test('TuiHint customizing works', async ({page}) => { diff --git a/projects/demo-playwright/tests/deep/deep-select.pw.spec.ts b/projects/demo-playwright/tests/deep/deep-select.pw.spec.ts index 0a17b80707e9..b0e93f8334a1 100644 --- a/projects/demo-playwright/tests/deep/deep-select.pw.spec.ts +++ b/projects/demo-playwright/tests/deep/deep-select.pw.spec.ts @@ -47,7 +47,7 @@ test.describe('Deep / Select', () => { await page.waitForTimeout(100); await expect(api.apiPageExample).toHaveScreenshot( - `deep-${path}__${name}-select-option-${index}.png`, + `deep-${path}-${name}-select-option-${index}.png`, ); await select.click(); diff --git a/projects/demo-playwright/tests/deep/deep-toggle.pw.spec.ts b/projects/demo-playwright/tests/deep/deep-toggle.pw.spec.ts index 3ef4a500bc49..2194b182bf4a 100644 --- a/projects/demo-playwright/tests/deep/deep-toggle.pw.spec.ts +++ b/projects/demo-playwright/tests/deep/deep-toggle.pw.spec.ts @@ -34,7 +34,7 @@ test.describe('Deep / Toggle', () => { await page.waitForTimeout(100); await expect(api.apiPageExample).toHaveScreenshot( - `deep-${path}__${name}-toggled.png`, + `deep-${path}-${name}-toggled.png`, ); await toggle.click(); diff --git a/projects/demo-playwright/tests/kit/calendar-range/calendar-range.pw.spec.ts b/projects/demo-playwright/tests/kit/calendar-range/calendar-range.pw.spec.ts index 6265f6656dc5..44b5dc501d72 100644 --- a/projects/demo-playwright/tests/kit/calendar-range/calendar-range.pw.spec.ts +++ b/projects/demo-playwright/tests/kit/calendar-range/calendar-range.pw.spec.ts @@ -36,7 +36,7 @@ test.describe('CalendarRange', () => { example.locator('p button[data-appearance="action"]'); await expect(example).toHaveScreenshot( - '05-calendar-range-correct-display-defaults-items-and-values_1.png', + '05-calendar-range-correct-display-defaults-items-and-values-1.png', ); await calendarRange.selectItem(1); @@ -61,7 +61,7 @@ test.describe('CalendarRange', () => { await getRangeSwitcher().click(); await expect(example).toHaveScreenshot( - '05-calendar-range-correct-display-defaults-items-and-values_2.png', + '05-calendar-range-correct-display-defaults-items-and-values-2.png', ); }); diff --git a/projects/demo-playwright/tests/kit/input-table/input-table.pw.spec.ts b/projects/demo-playwright/tests/kit/input-table/input-table.pw.spec.ts index 951c2f03b2dd..2b430d40c009 100644 --- a/projects/demo-playwright/tests/kit/input-table/input-table.pw.spec.ts +++ b/projects/demo-playwright/tests/kit/input-table/input-table.pw.spec.ts @@ -21,11 +21,11 @@ test.describe('InputTable', () => { await page.waitForTimeout(300); - await expect(example).toHaveScreenshot(`01-input_table__${index}_1.png`); + await expect(example).toHaveScreenshot(`01-input-table-${index}-1.png`); await example.locator('th').nth(index).click(); - await expect(example).toHaveScreenshot(`01-input_table__${index}_2.png`); + await expect(example).toHaveScreenshot(`01-input-table-${index}-2.png`); // eslint-disable-next-line playwright/no-conditional-in-test if (index > 0) { @@ -40,7 +40,7 @@ test.describe('InputTable', () => { await page.waitForTimeout(300); // eslint-disable-next-line playwright/no-conditional-expect - await expect(example).toHaveScreenshot(`01-input_table__${index}_3.png`); + await expect(example).toHaveScreenshot(`01-input-table-${index}-3.png`); } } }); diff --git a/projects/demo-playwright/tests/kit/line-clamp/line-clamp.pw.spec.ts b/projects/demo-playwright/tests/kit/line-clamp/line-clamp.pw.spec.ts index 967919b4e17d..f53e340c7b9f 100644 --- a/projects/demo-playwright/tests/kit/line-clamp/line-clamp.pw.spec.ts +++ b/projects/demo-playwright/tests/kit/line-clamp/line-clamp.pw.spec.ts @@ -91,11 +91,11 @@ test.describe('LineClamp', () => { ); await pagePO.prepareBeforeScreenshot(); - await expect(page).toHaveScreenshot(`05-1-line-clamp__${index}.png`); + await expect(page).toHaveScreenshot(`05-1-line-clamp-${index}.png`); await pagePO.apiPageExample.locator('tui-line-clamp').hover(); - await expect(page).toHaveScreenshot(`05-2-line-clamp__${index}.png`); + await expect(page).toHaveScreenshot(`05-2-line-clamp-${index}.png`); }); }); }); diff --git a/projects/demo-playwright/tests/kit/range/range.pw.spec.ts b/projects/demo-playwright/tests/kit/range/range.pw.spec.ts index 5b7bad380dc4..607b7f47f10b 100644 --- a/projects/demo-playwright/tests/kit/range/range.pw.spec.ts +++ b/projects/demo-playwright/tests/kit/range/range.pw.spec.ts @@ -234,56 +234,48 @@ test.describe('TuiRange', () => { await range.right.focus(); await expect(output).toContainText('[ 0, 100000 ]'); - await expect(example).toHaveScreenshot('09-range-0-100_000.png'); + await expect(example).toHaveScreenshot('09-range-0-100000.png'); await page.keyboard.down('ArrowUp'); await expect(output).toContainText('[ 0, 300000 ]'); - await expect(example).toHaveScreenshot('09-range-0-300_000.png'); + await expect(example).toHaveScreenshot('09-range-0-300000.png'); await page.keyboard.down('ArrowUp'); await expect(output).toContainText('[ 0, 500000 ]'); - await expect(example).toHaveScreenshot('09-range-0-500_000.png'); + await expect(example).toHaveScreenshot('09-range-0-500000.png'); await page.keyboard.down('ArrowUp'); await expect(output).toContainText('[ 0, 750000 ]'); - await expect(example).toHaveScreenshot('09-range-0-750_000.png'); + await expect(example).toHaveScreenshot('09-range-0-750000.png'); await page.keyboard.down('ArrowUp'); await expect(output).toContainText('[ 0, 1000000 ]'); - await expect(example).toHaveScreenshot('09-range-0-1_000_000.png'); + await expect(example).toHaveScreenshot('09-range-0-1_000000.png'); await range.left.focus(); await page.keyboard.down('ArrowUp'); await expect(output).toContainText('[ 5000, 1000000 ]'); - await expect(example).toHaveScreenshot( - '09-range-5_000-1_000_000.png', - ); + await expect(example).toHaveScreenshot('09-range-5-000-1-000000.png'); await page.keyboard.down('ArrowUp'); await expect(output).toContainText('[ 10000, 1000000 ]'); - await expect(example).toHaveScreenshot( - '09-range-10_000-1_000_000.png', - ); + await expect(example).toHaveScreenshot('09-range-10000-1000000.png'); await page.keyboard.down('ArrowUp'); await expect(output).toContainText('[ 55000, 1000000 ]'); - await expect(example).toHaveScreenshot( - '09-range-55_000-1_000_000.png', - ); + await expect(example).toHaveScreenshot('09-range-55000-1000000.png'); await page.keyboard.down('ArrowUp'); await expect(output).toContainText('[ 100000, 1000000 ]'); - await expect(example).toHaveScreenshot( - '09-range-100_000-1_000_000.png', - ); + await expect(example).toHaveScreenshot('09-range-100000-1000000.png'); }); test('ArrowDown decreases value of the focused slider', async ({ @@ -293,17 +285,17 @@ test.describe('TuiRange', () => { await page.keyboard.down('ArrowDown'); await expect(output).toContainText('[ 0, 55000 ]'); - await expect(example).toHaveScreenshot('10-range-0-55_000.png'); + await expect(example).toHaveScreenshot('10-range-0-55000.png'); await page.keyboard.down('ArrowDown'); await expect(output).toContainText('[ 0, 10000 ]'); - await expect(example).toHaveScreenshot('10-range-0-10_000.png'); + await expect(example).toHaveScreenshot('10-range-0-10000.png'); await page.keyboard.down('ArrowDown'); await expect(output).toContainText('[ 0, 5000 ]'); - await expect(example).toHaveScreenshot('10-range-0-5_000.png'); + await expect(example).toHaveScreenshot('10-range-0-5000.png'); }); test('cannot set position of the LEFT slider MORE THAN position of the RIGHT slider (by ArrowUp)', async ({ diff --git a/projects/demo-playwright/tests/kit/slider/slider.pw.spec.ts b/projects/demo-playwright/tests/kit/slider/slider.pw.spec.ts index 24f1f6f69668..72d4872b5a6f 100644 --- a/projects/demo-playwright/tests/kit/slider/slider.pw.spec.ts +++ b/projects/demo-playwright/tests/kit/slider/slider.pw.spec.ts @@ -67,7 +67,7 @@ test.describe('Slider', () => { const {apiPageExample} = new TuiDocumentationPagePO(page); await expect(apiPageExample).toHaveScreenshot( - '03-min_1__max_10__value_1__segments_9.png', + '03-min-1-max-10-value-1-segments-9.png', ); }); @@ -77,7 +77,7 @@ test.describe('Slider', () => { const {apiPageExample} = new TuiDocumentationPagePO(page); await expect(apiPageExample).toHaveScreenshot( - '04-min_-5__max_5__value_1__segments_5.png', + '04-min--5-max-5-value-1-segments_5.png', ); }); diff --git a/projects/demo-playwright/tests/legacy/input-date-range/input-date-range.pw.spec.ts b/projects/demo-playwright/tests/legacy/input-date-range/input-date-range.pw.spec.ts index 116a663964d9..a9694c2556e4 100644 --- a/projects/demo-playwright/tests/legacy/input-date-range/input-date-range.pw.spec.ts +++ b/projects/demo-playwright/tests/legacy/input-date-range/input-date-range.pw.spec.ts @@ -291,5 +291,38 @@ test.describe('InputDateRange', () => { '08-calendar-correct-selected-period-after-close-open.png', ); }); + + test.describe('with `input[tuiTextfieldLegacy]` inside', () => { + test('filler has no change detection problems', async () => { + const example = documentationPage.getExample('#base'); + const inputDateRange = new TuiInputDateRangePO( + example.locator('tui-input-date-range'), + ); + + /** + * To ensure that example is not changed and + * still contains InputDateRange with projected + */ + await expect( + inputDateRange.host.locator('input[tuiTextfieldLegacy]'), + ).toBeAttached(); + + await inputDateRange.textfield.focus(); + + await expect(inputDateRange.host).toHaveScreenshot( + '12-backspace-pressed-0-times.png', + ); + + for (let i = 1; i <= 16; i++) { + await inputDateRange.textfield.press('Backspace'); + + await expect(inputDateRange.host).toHaveScreenshot( + `12-backspace-pressed-${i}-times.png`, + ); + } + + await expect(inputDateRange.textfield).toHaveValue(''); + }); + }); }); }); diff --git a/projects/demo-playwright/tests/legacy/input-date-time/input-date-time.pw.spec.ts b/projects/demo-playwright/tests/legacy/input-date-time/input-date-time.pw.spec.ts index 5cee26a4346f..7bc36f70be59 100644 --- a/projects/demo-playwright/tests/legacy/input-date-time/input-date-time.pw.spec.ts +++ b/projects/demo-playwright/tests/legacy/input-date-time/input-date-time.pw.spec.ts @@ -312,24 +312,17 @@ test.describe('InputDateTime', () => { }); test.describe('Examples', () => { - let example!: Locator; let documentationPage!: TuiDocumentationPagePO; - let inputDateTime!: TuiInputDateTimePO; test.beforeEach(async ({page}) => { await tuiGoto(page, DemoRoute.InputDateTime); documentationPage = new TuiDocumentationPagePO(page); - example = documentationPage.apiPageExample; - - inputDateTime = new TuiInputDateTimePO( - example.locator('tui-input-date-time'), - ); }); test('With validator: enter incomplete date -> validator error', async () => { - example = documentationPage.getExample('#with-validator'); - inputDateTime = new TuiInputDateTimePO( + const example = documentationPage.getExample('#with-validator'); + const inputDateTime = new TuiInputDateTimePO( example.locator('tui-input-date-time'), ); @@ -343,5 +336,38 @@ test.describe('InputDateTime', () => { {animations: 'allow'}, ); }); + + test.describe('with `input[tuiTextfieldLegacy]` inside', () => { + test('filler has no change detection problems', async () => { + const example = documentationPage.getExample('#base'); + const inputDateTime = new TuiInputDateTimePO( + example.locator('tui-input-date-time'), + ); + + /** + * To ensure that example is not changed and + * still contains InputDateTime with projected + */ + await expect( + inputDateTime.host.locator('input[tuiTextfieldLegacy]'), + ).toBeAttached(); + + await inputDateTime.textfield.focus(); + + await expect(inputDateTime.host).toHaveScreenshot( + '05-backspace-pressed-0-times.png', + ); + + for (let i = 1; i <= 8; i++) { + await inputDateTime.textfield.press('Backspace'); + + await expect(inputDateTime.host).toHaveScreenshot( + `05-backspace-pressed-${i}-times.png`, + ); + } + + await expect(inputDateTime.textfield).toHaveValue(''); + }); + }); }); }); diff --git a/projects/demo-playwright/tests/legacy/input-date/input-date.pw.spec.ts b/projects/demo-playwright/tests/legacy/input-date/input-date.pw.spec.ts index 7be105ec7b6d..53ffa86804a1 100644 --- a/projects/demo-playwright/tests/legacy/input-date/input-date.pw.spec.ts +++ b/projects/demo-playwright/tests/legacy/input-date/input-date.pw.spec.ts @@ -12,6 +12,8 @@ import {TUI_PLAYWRIGHT_MOBILE_USER_AGENT} from '../../../playwright.options'; test.describe('InputDate', () => { test.describe('Examples', () => { + let documentationPage!: TuiDocumentationPagePO; + test.use({ viewport: { width: 450, @@ -19,13 +21,16 @@ test.describe('InputDate', () => { }, }); - test('correct filler display for size', async ({page}) => { + test.beforeEach(async ({page}) => { await tuiGoto(page, DemoRoute.InputDate); - const api = new TuiDocumentationPagePO(page); - const example = api.getExample('#sizes'); + documentationPage = new TuiDocumentationPagePO(page); + }); - await api.prepareBeforeScreenshot(); + test('correct filler display for size', async ({page}) => { + const example = documentationPage.getExample('#sizes'); + + await documentationPage.prepareBeforeScreenshot(); for (const size of ['s', 'm', 'l']) { const input = example @@ -52,6 +57,37 @@ test.describe('InputDate', () => { await expect(page).toHaveScreenshot(`01-04-input-date-${size}.png`); } }); + + test.describe('with `input[tuiTextfieldLegacy]` inside', () => { + test('filler has no change detection problems', async () => { + const example = documentationPage.getExample('#date-localization'); + const inputDate = new TuiInputDatePO(example.locator('tui-input-date')); + + /** + * To ensure that example is not changed and + * still contains InputDate with projected + */ + await expect( + inputDate.host.locator('input[tuiTextfieldLegacy]'), + ).toBeAttached(); + + await inputDate.textfield.focus(); + + await expect(inputDate.host).toHaveScreenshot( + '14-backspace-pressed-0-times.png', + ); + + for (let i = 1; i <= 8; i++) { + await inputDate.textfield.press('Backspace'); + + await expect(inputDate.host).toHaveScreenshot( + `14-backspace-pressed-${i}-times.png`, + ); + } + + await expect(inputDate.textfield).toHaveValue(''); + }); + }); }); test.describe('API', () => { diff --git a/projects/demo-playwright/tests/legacy/input-time/input-time.pw.spec.ts b/projects/demo-playwright/tests/legacy/input-time/input-time.pw.spec.ts index 19824fde16fc..723d9240ea29 100644 --- a/projects/demo-playwright/tests/legacy/input-time/input-time.pw.spec.ts +++ b/projects/demo-playwright/tests/legacy/input-time/input-time.pw.spec.ts @@ -67,7 +67,7 @@ test.describe('InputTime', () => { await inputTime.textfield.click(); - await expect(apiPageExample).toHaveScreenshot(`time_mode_${mode}.png`); + await expect(apiPageExample).toHaveScreenshot(`time-mode-${mode}.png`); }); }); diff --git a/projects/demo-playwright/utils/page-objects/input-date-range.po.ts b/projects/demo-playwright/utils/page-objects/input-date-range.po.ts index 865ac46cbd87..d83b22a35f7a 100644 --- a/projects/demo-playwright/utils/page-objects/input-date-range.po.ts +++ b/projects/demo-playwright/utils/page-objects/input-date-range.po.ts @@ -15,7 +15,7 @@ export class TuiInputDateRangePO { '[automation-id="tui-calendar-range__menu"]', ); - constructor(private readonly host: Locator) {} + constructor(public readonly host: Locator) {} public async getItems(): Promise { const dataList = this.calendar.locator( diff --git a/projects/demo-playwright/utils/page-objects/input-date.po.ts b/projects/demo-playwright/utils/page-objects/input-date.po.ts index df59f891c556..f49a49b6ce0e 100644 --- a/projects/demo-playwright/utils/page-objects/input-date.po.ts +++ b/projects/demo-playwright/utils/page-objects/input-date.po.ts @@ -4,5 +4,5 @@ export class TuiInputDatePO { public readonly textfield: Locator = this.host.getByRole('textbox'); public readonly calendar: Locator = this.host.page().locator('tui-calendar'); - constructor(private readonly host: Locator) {} + constructor(public readonly host: Locator) {} } diff --git a/projects/demo/src/modules/app/app.routes.ts b/projects/demo/src/modules/app/app.routes.ts index 389bcf09f238..e07ad4f1c191 100644 --- a/projects/demo/src/modules/app/app.routes.ts +++ b/projects/demo/src/modules/app/app.routes.ts @@ -324,6 +324,11 @@ export const ROUTES: Routes = [ loadComponent: async () => import('../components/input-color'), title: 'InputColor', }), + route({ + path: DemoRoute.FormLayout, + loadComponent: async () => import('../components/form'), + title: 'Form', + }), route({ path: DemoRoute.Group, loadComponent: async () => import('../components/group'), @@ -746,7 +751,7 @@ export const ROUTES: Routes = [ route({ path: DemoRoute.Form, loadComponent: async () => import('../markup/form'), - title: 'Form', + title: 'Form ', }), route({ path: DemoRoute.Lists, diff --git a/projects/demo/src/modules/app/demo-routes.ts b/projects/demo/src/modules/app/demo-routes.ts index 37daefbb4124..e056dd65fac4 100644 --- a/projects/demo/src/modules/app/demo-routes.ts +++ b/projects/demo/src/modules/app/demo-routes.ts @@ -59,6 +59,7 @@ export const DemoRoute = { Expand: '/components/expand', ElasticContainer: '/components/elastic-container', FieldError: '/pipes/field-error', + FormLayout: '/components/form', InputFiles: '/components/input-files', InputColor: '/components/input-color', Group: '/components/group', diff --git a/projects/demo/src/modules/app/pages.ts b/projects/demo/src/modules/app/pages.ts index 8e67d539d559..d978607349e5 100644 --- a/projects/demo/src/modules/app/pages.ts +++ b/projects/demo/src/modules/app/pages.ts @@ -421,6 +421,12 @@ export const pages: DocRoutePages = [ keywords: 'фильтр, filters', route: DemoRoute.Filter, }, + { + section: 'Components', + title: 'Form', + keywords: 'форма, поле, кнопка, группировка, группа', + route: DemoRoute.FormLayout, + }, { section: 'Components', title: 'Group', diff --git a/projects/demo/src/modules/components/form/examples/1/index.html b/projects/demo/src/modules/components/form/examples/1/index.html new file mode 100644 index 000000000000..797ebade1f2f --- /dev/null +++ b/projects/demo/src/modules/components/form/examples/1/index.html @@ -0,0 +1,87 @@ +
+
+

+ Registration form + Tell us about yourself +

+ + + + + + +
+ +

+ Authenticity required + Please be honest and use your real data +

+
+ + + + + + + + + + + + +
+ + +
+ diff --git a/projects/demo/src/modules/components/form/examples/1/index.ts b/projects/demo/src/modules/components/form/examples/1/index.ts new file mode 100644 index 000000000000..40db010e17c5 --- /dev/null +++ b/projects/demo/src/modules/components/form/examples/1/index.ts @@ -0,0 +1,50 @@ +import {AsyncPipe, NgIf} from '@angular/common'; +import {Component} from '@angular/core'; +import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {encapsulation} from '@demo/emulate/encapsulation'; +import { + TuiAppearance, + TuiButton, + TuiError, + TuiIcon, + TuiNotification, + TuiTextfield, + TuiTitle, +} from '@taiga-ui/core'; +import {TuiFieldErrorPipe, TuiSegmented, TuiSwitch, TuiTooltip} from '@taiga-ui/kit'; +import {TuiCardLarge, TuiForm, TuiHeader} from '@taiga-ui/layout'; + +@Component({ + standalone: true, + imports: [ + AsyncPipe, + NgIf, + ReactiveFormsModule, + TuiAppearance, + TuiButton, + TuiCardLarge, + TuiError, + TuiFieldErrorPipe, + TuiForm, + TuiHeader, + TuiIcon, + TuiNotification, + TuiSegmented, + TuiSwitch, + TuiTextfield, + TuiTitle, + TuiTooltip, + ], + templateUrl: './index.html', + encapsulation, + changeDetection, +}) +export default class Example { + protected readonly form = new FormGroup({ + name: new FormControl('', Validators.required), + email: new FormControl(''), + subscribe: new FormControl(false), + basic: new FormControl(true), + }); +} diff --git a/projects/demo/src/modules/components/form/examples/import/import.md b/projects/demo/src/modules/components/form/examples/import/import.md new file mode 100644 index 000000000000..dd65e0b7cd0c --- /dev/null +++ b/projects/demo/src/modules/components/form/examples/import/import.md @@ -0,0 +1,18 @@ +```ts +import {TuiAppearance} from '@taiga-ui/core'; +import {TuiCardLarge, TuiForm} from '@taiga-ui/layout'; + +// ... + +@Component({ + standalone: true, + imports: [ + // ... + TuiCardLarge, + TuiAppearance, + TuiForm, + ], + // ... +}) +export class Example {} +``` diff --git a/projects/demo/src/modules/components/form/examples/import/template.md b/projects/demo/src/modules/components/form/examples/import/template.md new file mode 100644 index 000000000000..b2a7f6fb927c --- /dev/null +++ b/projects/demo/src/modules/components/form/examples/import/template.md @@ -0,0 +1,9 @@ +```html +
+ +
+``` diff --git a/projects/demo/src/modules/components/form/index.html b/projects/demo/src/modules/components/form/index.html new file mode 100644 index 000000000000..6bddac439cfe --- /dev/null +++ b/projects/demo/src/modules/components/form/index.html @@ -0,0 +1,24 @@ + + + Size sets DI options, therefore it only works for static values like + tuiForm="m" + . If you need dynamic binding for the size, you would have to set it for buttons, segmented control and header + manually as well. + + + + + + + diff --git a/projects/demo/src/modules/components/form/index.less b/projects/demo/src/modules/components/form/index.less new file mode 100644 index 000000000000..b7cd891b0b2b --- /dev/null +++ b/projects/demo/src/modules/components/form/index.less @@ -0,0 +1,3 @@ +.bar { + block-size: 6.25rem; +} diff --git a/projects/demo/src/modules/components/form/index.ts b/projects/demo/src/modules/components/form/index.ts new file mode 100644 index 000000000000..8d7fbeb20e2c --- /dev/null +++ b/projects/demo/src/modules/components/form/index.ts @@ -0,0 +1,14 @@ +import {Component} from '@angular/core'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {TuiDemo} from '@demo/utils'; + +@Component({ + standalone: true, + imports: [TuiDemo], + templateUrl: './index.html', + styleUrls: ['./index.less'], + changeDetection, +}) +export default class Page { + protected readonly examples = ['Basic']; +} diff --git a/projects/demo/src/modules/components/multi-select/examples/1/index.ts b/projects/demo/src/modules/components/multi-select/examples/1/index.ts index 765b7ce03464..788e4f048e48 100644 --- a/projects/demo/src/modules/components/multi-select/examples/1/index.ts +++ b/projects/demo/src/modules/components/multi-select/examples/1/index.ts @@ -9,7 +9,7 @@ import {TuiDataListWrapper} from '@taiga-ui/kit'; import {TuiMultiSelectModule, TuiTextfieldControllerModule} from '@taiga-ui/legacy'; const ITEMS: readonly string[] = [ - 'Luke Skywalker', + 'Luke Skywalker and a long time ago in a galaxy far, far away..', 'Leia Organa Solo', 'Darth Vader', 'Han Solo', diff --git a/projects/demo/src/modules/components/navigation/examples/1/index.html b/projects/demo/src/modules/components/navigation/examples/1/index.html index fcc07b263026..febbb7ceee88 100644 --- a/projects/demo/src/modules/components/navigation/examples/1/index.html +++ b/projects/demo/src/modules/components/navigation/examples/1/index.html @@ -299,16 +299,54 @@ Primary -
-

- Some random content - A subtitle -

-
+ +
+
+

+ Registration form + Tell us about yourself +

+
+ + + + +
+ + +
+
+
+

+ Sidebar content + Use CSS grid to position +

+
+
diff --git a/projects/demo/src/modules/components/navigation/examples/1/index.ts b/projects/demo/src/modules/components/navigation/examples/1/index.ts index bb67455a4743..2a1d486ef0fa 100644 --- a/projects/demo/src/modules/components/navigation/examples/1/index.ts +++ b/projects/demo/src/modules/components/navigation/examples/1/index.ts @@ -13,6 +13,7 @@ import { TuiDropdown, TuiDropdownService, TuiIcon, + TuiTextfield, TuiTitle, } from '@taiga-ui/core'; import { @@ -25,7 +26,7 @@ import { TuiSwitch, TuiTabs, } from '@taiga-ui/kit'; -import {TuiCardLarge, TuiHeader, TuiNavigation} from '@taiga-ui/layout'; +import {TuiCardLarge, TuiForm, TuiHeader, TuiNavigation} from '@taiga-ui/layout'; const ICON = "data:image/svg+xml,%0A%3Csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='32' height='32' rx='8' fill='url(%23paint0_linear_2036_35276)'/%3E%3Cmask id='mask0_2036_35276' style='mask-type:alpha' maskUnits='userSpaceOnUse' x='6' y='5' width='20' height='21'%3E%3Cpath d='M18.2399 9.36607C21.1347 10.1198 24.1992 9.8808 26 7.4922C26 7.4922 21.5645 5 16.4267 5C11.2888 5 5.36726 8.69838 6.05472 16.6053C6.38707 20.4279 6.65839 23.7948 6.65839 23.7948C8.53323 22.1406 9.03427 19.4433 8.97983 16.9435C8.93228 14.7598 9.55448 12.1668 12.1847 10.4112C14.376 8.94865 16.4651 8.90397 18.2399 9.36607Z' fill='url(%23paint1_linear_2036_35276)'/%3E%3Cpath d='M11.3171 20.2647C9.8683 17.1579 10.7756 11.0789 16.4267 11.0789C20.4829 11.0789 23.1891 12.8651 22.9447 18.9072C22.9177 19.575 22.9904 20.2455 23.2203 20.873C23.7584 22.3414 24.7159 24.8946 24.7159 24.8946C23.6673 24.5452 22.8325 23.7408 22.4445 22.7058L21.4002 19.921L21.2662 19.3848C21.0202 18.4008 20.136 17.7104 19.1217 17.7104H17.5319L17.6659 18.2466C17.9119 19.2306 18.7961 19.921 19.8104 19.921L22.0258 26H10.4754C10.7774 24.7006 12.0788 23.2368 11.3171 20.2647Z' fill='url(%23paint2_linear_2036_35276)'/%3E%3C/mask%3E%3Cg mask='url(%23mask0_2036_35276)'%3E%3Crect x='4' y='4' width='24' height='24' fill='white'/%3E%3C/g%3E%3Cdefs%3E%3ClinearGradient id='paint0_linear_2036_35276' x1='0' y1='0' x2='32' y2='32' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23A681D4'/%3E%3Cstop offset='1' stop-color='%237D31D4'/%3E%3C/linearGradient%3E%3ClinearGradient id='paint1_linear_2036_35276' x1='6.0545' y1='24.3421' x2='28.8119' y2='3.82775' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0.0001' stop-opacity='0.996458'/%3E%3Cstop offset='0.317708'/%3E%3Cstop offset='1' stop-opacity='0.32'/%3E%3C/linearGradient%3E%3ClinearGradient id='paint2_linear_2036_35276' x1='6.0545' y1='24.3421' x2='28.8119' y2='3.82775' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0.0001' stop-opacity='0.996458'/%3E%3Cstop offset='0.317708'/%3E%3Cstop offset='1' stop-opacity='0.32'/%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E%0A"; @@ -49,12 +50,14 @@ const ICON = TuiDataListDropdownManager, TuiDropdown, TuiFade, + TuiForm, TuiHeader, TuiIcon, TuiNavigation, TuiRepeatTimes, TuiSwitch, TuiTabs, + TuiTextfield, TuiTitle, ], templateUrl: './index.html', diff --git a/projects/demo/src/modules/components/sheet-dialog/examples/4/index.less b/projects/demo/src/modules/components/sheet-dialog/examples/4/index.less index 8b36f169de63..722e81c8b345 100644 --- a/projects/demo/src/modules/components/sheet-dialog/examples/4/index.less +++ b/projects/demo/src/modules/components/sheet-dialog/examples/4/index.less @@ -20,7 +20,7 @@ .footer { position: sticky; - bottom: 0; + bottom: 0.5rem; display: flex; flex-direction: column; gap: 1rem; diff --git a/projects/demo/src/modules/components/sheet-dialog/examples/4/index.ts b/projects/demo/src/modules/components/sheet-dialog/examples/4/index.ts index 5fdabf8459e7..dae151d98d02 100644 --- a/projects/demo/src/modules/components/sheet-dialog/examples/4/index.ts +++ b/projects/demo/src/modules/components/sheet-dialog/examples/4/index.ts @@ -76,7 +76,7 @@ export default class Example { ); protected readonly height$ = this.size$.pipe( - map(({height}) => `calc(${height - this.offset}px - 14rem`), + map(({height}) => `calc(${height - this.offset}px - 14.5rem`), ); protected toggle(open: boolean): void { diff --git a/projects/demo/src/modules/pipes/filter-by-input/examples/3/index.ts b/projects/demo/src/modules/pipes/filter-by-input/examples/3/index.ts index da7870f42fbf..4a98dc18983f 100644 --- a/projects/demo/src/modules/pipes/filter-by-input/examples/3/index.ts +++ b/projects/demo/src/modules/pipes/filter-by-input/examples/3/index.ts @@ -20,7 +20,7 @@ import {TuiMultiSelectModule, TuiTextfieldControllerModule} from '@taiga-ui/lega }) export default class Example { protected readonly items = [ - 'Luke Skywalker', + 'Luke Skywalker and a long time ago in a galaxy far, far away..', 'Leia Organa Solo', 'Darth Vader', 'Han Solo', diff --git a/projects/icons/package.json b/projects/icons/package.json index 44f00c44a848..1d99656d257c 100644 --- a/projects/icons/package.json +++ b/projects/icons/package.json @@ -12,6 +12,6 @@ "repository": "https://github.com/taiga-family/taiga-ui", "license": "Apache-2.0", "devDependencies": { - "lucide-static": "0.465.0" + "lucide-static": "0.468.0" } } diff --git a/projects/icons/src/bell-dot-filled.svg b/projects/icons/src/bell-dot-filled.svg index efd79316aecd..4d2406aad36d 100644 --- a/projects/icons/src/bell-dot-filled.svg +++ b/projects/icons/src/bell-dot-filled.svg @@ -9,10 +9,10 @@ stroke-linecap="round" stroke-linejoin="round" > + - diff --git a/projects/icons/src/bell-dot.svg b/projects/icons/src/bell-dot.svg index 1d0c1be0f835..66fe9e1f0a31 100644 --- a/projects/icons/src/bell-dot.svg +++ b/projects/icons/src/bell-dot.svg @@ -9,10 +9,10 @@ stroke-linecap="round" stroke-linejoin="round" > + - diff --git a/projects/icons/src/bell-filled.svg b/projects/icons/src/bell-filled.svg index 34d2f81e82a9..35e77a4781d6 100644 --- a/projects/icons/src/bell-filled.svg +++ b/projects/icons/src/bell-filled.svg @@ -9,6 +9,9 @@ stroke-linecap="round" stroke-linejoin="round" > - - + + diff --git a/projects/icons/src/bell-minus-filled.svg b/projects/icons/src/bell-minus-filled.svg index 51ec0c21b86d..416798bae622 100644 --- a/projects/icons/src/bell-minus-filled.svg +++ b/projects/icons/src/bell-minus-filled.svg @@ -9,10 +9,10 @@ stroke-linecap="round" stroke-linejoin="round" > + + - - diff --git a/projects/icons/src/bell-minus.svg b/projects/icons/src/bell-minus.svg index 32d4e4e59355..1ace4a3b20d0 100644 --- a/projects/icons/src/bell-minus.svg +++ b/projects/icons/src/bell-minus.svg @@ -9,10 +9,10 @@ stroke-linecap="round" stroke-linejoin="round" > + + - - diff --git a/projects/icons/src/bell-off-filled.svg b/projects/icons/src/bell-off-filled.svg index cd2f2bda4c58..5d6f1a129fe5 100644 --- a/projects/icons/src/bell-off-filled.svg +++ b/projects/icons/src/bell-off-filled.svg @@ -9,8 +9,11 @@ stroke-linecap="round" stroke-linejoin="round" > - - - + + + diff --git a/projects/icons/src/bell-off.svg b/projects/icons/src/bell-off.svg index 25b1b2054917..2ac9da4ae03d 100644 --- a/projects/icons/src/bell-off.svg +++ b/projects/icons/src/bell-off.svg @@ -9,8 +9,11 @@ stroke-linecap="round" stroke-linejoin="round" > - - - + + + diff --git a/projects/icons/src/bell-plus-filled.svg b/projects/icons/src/bell-plus-filled.svg index 5ec67095a84f..bd78caa7c49a 100644 --- a/projects/icons/src/bell-plus-filled.svg +++ b/projects/icons/src/bell-plus-filled.svg @@ -9,11 +9,11 @@ stroke-linecap="round" stroke-linejoin="round" > + + + - - - diff --git a/projects/icons/src/bell-plus.svg b/projects/icons/src/bell-plus.svg index 67bdc274119a..1f3d7e9d68b4 100644 --- a/projects/icons/src/bell-plus.svg +++ b/projects/icons/src/bell-plus.svg @@ -9,11 +9,11 @@ stroke-linecap="round" stroke-linejoin="round" > + + + - - - diff --git a/projects/icons/src/bell-ring-filled.svg b/projects/icons/src/bell-ring-filled.svg index d5f737be9509..e2c21f7e03fc 100644 --- a/projects/icons/src/bell-ring-filled.svg +++ b/projects/icons/src/bell-ring-filled.svg @@ -9,8 +9,11 @@ stroke-linecap="round" stroke-linejoin="round" > - - - + + + diff --git a/projects/icons/src/bell-ring.svg b/projects/icons/src/bell-ring.svg index 973fc508010f..e0e846b0c497 100644 --- a/projects/icons/src/bell-ring.svg +++ b/projects/icons/src/bell-ring.svg @@ -9,8 +9,11 @@ stroke-linecap="round" stroke-linejoin="round" > - - - + + + diff --git a/projects/icons/src/bell.svg b/projects/icons/src/bell.svg index 714580ffa791..93b337676b35 100644 --- a/projects/icons/src/bell.svg +++ b/projects/icons/src/bell.svg @@ -9,6 +9,9 @@ stroke-linecap="round" stroke-linejoin="round" > - - + + diff --git a/projects/icons/src/book-dashed-filled.svg b/projects/icons/src/book-dashed-filled.svg index 24ca4b4dd8cb..4edd54fde6c3 100644 --- a/projects/icons/src/book-dashed-filled.svg +++ b/projects/icons/src/book-dashed-filled.svg @@ -9,15 +9,15 @@ stroke-linecap="round" stroke-linejoin="round" > - - - - - - - - - - + + + + + + + + + + diff --git a/projects/icons/src/book-dashed.svg b/projects/icons/src/book-dashed.svg index 004fb821022b..363fed7c9f48 100644 --- a/projects/icons/src/book-dashed.svg +++ b/projects/icons/src/book-dashed.svg @@ -9,15 +9,15 @@ stroke-linecap="round" stroke-linejoin="round" > - - - - - - - - - - + + + + + + + + + + diff --git a/projects/icons/src/list-filter-plus-filled.svg b/projects/icons/src/list-filter-plus-filled.svg new file mode 100644 index 000000000000..d8224e5dc05b --- /dev/null +++ b/projects/icons/src/list-filter-plus-filled.svg @@ -0,0 +1,17 @@ + + + + + + + diff --git a/projects/icons/src/list-filter-plus.svg b/projects/icons/src/list-filter-plus.svg new file mode 100644 index 000000000000..349fb98413fb --- /dev/null +++ b/projects/icons/src/list-filter-plus.svg @@ -0,0 +1,17 @@ + + + + + + + diff --git a/projects/icons/src/scan-heart-filled.svg b/projects/icons/src/scan-heart-filled.svg new file mode 100644 index 000000000000..f5a382cc3fb5 --- /dev/null +++ b/projects/icons/src/scan-heart-filled.svg @@ -0,0 +1,20 @@ + + + + + + + diff --git a/projects/icons/src/scan-heart.svg b/projects/icons/src/scan-heart.svg new file mode 100644 index 000000000000..682d743a537b --- /dev/null +++ b/projects/icons/src/scan-heart.svg @@ -0,0 +1,20 @@ + + + + + + + diff --git a/projects/icons/src/waves-ladder-filled.svg b/projects/icons/src/waves-ladder-filled.svg new file mode 100644 index 000000000000..aa8c59cd868e --- /dev/null +++ b/projects/icons/src/waves-ladder-filled.svg @@ -0,0 +1,20 @@ + + + + + + + diff --git a/projects/icons/src/waves-ladder.svg b/projects/icons/src/waves-ladder.svg new file mode 100644 index 000000000000..de8206f1686b --- /dev/null +++ b/projects/icons/src/waves-ladder.svg @@ -0,0 +1,20 @@ + + + + + + + diff --git a/projects/kit/components/segmented/segmented.component.ts b/projects/kit/components/segmented/segmented.component.ts index 9302e6a9c990..d05d8b76f055 100644 --- a/projects/kit/components/segmented/segmented.component.ts +++ b/projects/kit/components/segmented/segmented.component.ts @@ -11,6 +11,7 @@ import { import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; import {ResizeObserverService} from '@ng-web-apis/resize-observer'; import {tuiZonefree} from '@taiga-ui/cdk/observables'; +import {tuiCreateOptions} from '@taiga-ui/cdk/utils/di'; import {tuiInjectElement, tuiIsHTMLElement} from '@taiga-ui/cdk/utils/dom'; import {tuiPx} from '@taiga-ui/cdk/utils/miscellaneous'; import type {TuiSizeL, TuiSizeS} from '@taiga-ui/core/types'; @@ -18,6 +19,10 @@ import {tuiBadgeNotificationOptionsProvider} from '@taiga-ui/kit/components/badg import {TuiSegmentedDirective} from './segmented.directive'; +export const [TUI_SEGMENTED_OPTIONS, tuiSegmentedOptionsProvider] = tuiCreateOptions({ + size: 's' as TuiSizeL | TuiSizeS, +}); + @Component({ standalone: true, selector: 'tui-segmented', @@ -39,7 +44,7 @@ export class TuiSegmented implements OnChanges { .subscribe(() => this.refresh()); @Input() - public size: TuiSizeL | TuiSizeS = 's'; + public size: TuiSizeL | TuiSizeS = inject(TUI_SEGMENTED_OPTIONS).size; @Input() public activeItemIndex = 0; diff --git a/projects/kit/components/tree/misc/tree.service.ts b/projects/kit/components/tree/misc/tree.service.ts index 213ea2e10041..d0192a419778 100644 --- a/projects/kit/components/tree/misc/tree.service.ts +++ b/projects/kit/components/tree/misc/tree.service.ts @@ -1,5 +1,5 @@ import {inject, Injectable} from '@angular/core'; -import {map, startWith, Subject, switchMap, tap} from 'rxjs'; +import {map, mergeMap, startWith, Subject, tap} from 'rxjs'; import type {TuiTreeLoader} from './tree.interfaces'; import {TUI_TREE_LOADER, TUI_TREE_LOADING, TUI_TREE_START} from './tree.tokens'; @@ -13,7 +13,7 @@ export class TuiTreeService { private readonly load$ = new Subject(); public readonly data$ = this.load$.pipe( - switchMap((item) => + mergeMap((item) => this.loader.loadChildren(item).pipe( tap((children) => this.map.set(item, children)), map((children) => diff --git a/projects/layout/components/card/card.styles.less b/projects/layout/components/card/card.styles.less index b55c5176a060..9df6c5272e1d 100644 --- a/projects/layout/components/card/card.styles.less +++ b/projects/layout/components/card/card.styles.less @@ -73,7 +73,7 @@ --t-space: 1.25rem; } - &:not([tuiCell], [tuiHeader]) { + &:not([tuiCell], [tuiHeader], [tuiForm]) { flex-direction: column; gap: var(--t-space); align-items: stretch; diff --git a/projects/layout/components/form/form.directive.ts b/projects/layout/components/form/form.directive.ts new file mode 100644 index 000000000000..ed777416db99 --- /dev/null +++ b/projects/layout/components/form/form.directive.ts @@ -0,0 +1,81 @@ +import type {InjectionToken, Provider} from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + Directive, + inject, + Input, + ViewEncapsulation, +} from '@angular/core'; +import type {TuiStringHandler} from '@taiga-ui/cdk/types'; +import {tuiWithStyles} from '@taiga-ui/cdk/utils/miscellaneous'; +import {tuiButtonOptionsProvider} from '@taiga-ui/core/components/button'; +import {tuiNotificationOptionsProvider} from '@taiga-ui/core/components/notification'; +import {TuiTextfieldOptionsDirective} from '@taiga-ui/core/components/textfield'; +import type {TuiSizeL, TuiSizeS} from '@taiga-ui/core/types'; +import {TUI_SEGMENTED_OPTIONS} from '@taiga-ui/kit/components/segmented'; +import {TUI_SWITCH_OPTIONS} from '@taiga-ui/kit/components/switch'; +import {TUI_HEADER_OPTIONS} from '@taiga-ui/layout/components/header'; + +const HEADER_SIZE: Record = { + s: 'xxxs', + m: 'xs', + l: 's', +}; + +@Component({ + standalone: true, + template: '', + styleUrls: ['./form.styles.less'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'tui-form', + }, +}) +class TuiFormStyles {} + +@Directive({ + standalone: true, + selector: '[tuiForm]', + providers: [ + tuiButtonOptionsProvider(TuiForm), + tuiNotificationOptionsProvider(TuiForm), + projectSize(TUI_HEADER_OPTIONS, (size) => HEADER_SIZE[size]!), + projectSize(TUI_SWITCH_OPTIONS, (size) => (size === 'l' ? 'm' : 's')), + projectSize(TUI_SEGMENTED_OPTIONS, (size) => (size === 'l' ? 'm' : 's')), + ], + hostDirectives: [ + { + directive: TuiTextfieldOptionsDirective, + inputs: [ + 'tuiTextfieldSize: tuiForm', + 'tuiTextfieldAppearance', + 'tuiTextfieldCleaner', + ], + }, + ], + host: { + tuiForm: '', + '[attr.data-size]': 'size', + }, +}) +export class TuiForm { + protected readonly nothing = tuiWithStyles(TuiFormStyles); + + @Input('tuiForm') + public size: TuiSizeL | TuiSizeS = 'l'; +} + +function projectSize( + provide: InjectionToken, + project: TuiStringHandler, +): Provider { + return { + provide, + useFactory: () => ({ + ...inject(provide, {skipSelf: true}), + size: project(inject(TuiForm).size), + }), + }; +} diff --git a/projects/layout/components/form/form.styles.less b/projects/layout/components/form/form.styles.less new file mode 100644 index 000000000000..ad50c74cee7e --- /dev/null +++ b/projects/layout/components/form/form.styles.less @@ -0,0 +1,63 @@ +@import '@taiga-ui/core/styles/taiga-ui-local'; + +[tuiForm] { + display: flex; + flex-direction: column; + align-items: stretch; + + &[data-size='s'] { + gap: 0.75rem; + font: var(--tui-font-text-s); + + tui-error { + margin-top: -0.75rem; + } + + [tuiHeader] { + padding-bottom: 0.5rem; + + [tuiSubtitle] { + font: var(--tui-font-text-ui-s); + } + } + } + + &[data-size='m'] { + gap: 1rem; + font: var(--tui-font-text-s); + + tui-error { + margin-top: -1rem; + } + } + + &[data-size='l'] { + gap: 1.25rem; + font: var(--tui-font-text-m); + + tui-error { + margin-top: -1.25rem; + } + } + + [tuiHeader] { + padding-bottom: 0.25rem; + } + + footer { + display: flex; + gap: 0.75rem; + margin-top: 0.25rem; + } + + [tuiLabel]:not([data-orientation='vertical']) { + font: inherit; + } + + &[data-size='s'], + &[data-size='m'] { + [tuiLabel]:not([data-orientation='vertical']) [tuiTooltip] { + block-size: 1.25rem; + } + } +} diff --git a/projects/layout/components/form/index.ts b/projects/layout/components/form/index.ts new file mode 100644 index 000000000000..0e186e8f6cea --- /dev/null +++ b/projects/layout/components/form/index.ts @@ -0,0 +1 @@ +export * from './form.directive'; diff --git a/projects/layout/components/form/ng-package.json b/projects/layout/components/form/ng-package.json new file mode 100644 index 000000000000..bebf62dcb5e5 --- /dev/null +++ b/projects/layout/components/form/ng-package.json @@ -0,0 +1,5 @@ +{ + "lib": { + "entryFile": "index.ts" + } +} diff --git a/projects/layout/components/header/header.directive.ts b/projects/layout/components/header/header.directive.ts index bb743e8badc5..a94f8884e4f8 100644 --- a/projects/layout/components/header/header.directive.ts +++ b/projects/layout/components/header/header.directive.ts @@ -2,15 +2,21 @@ import { ChangeDetectionStrategy, Component, Directive, + inject, Input, ViewEncapsulation, } from '@angular/core'; +import {tuiCreateOptions} from '@taiga-ui/cdk/utils/di'; import {tuiWithStyles} from '@taiga-ui/cdk/utils/miscellaneous'; import {tuiButtonOptionsProvider} from '@taiga-ui/core/components/button'; import type {TuiSizeXXL, TuiSizeXXS} from '@taiga-ui/core/types'; import {tuiAvatarOptionsProvider} from '@taiga-ui/kit/components/avatar'; import {tuiBadgeOptionsProvider} from '@taiga-ui/kit/components/badge'; +export const [TUI_HEADER_OPTIONS, tuiHeaderOptionsProvider] = tuiCreateOptions({ + size: 's' as TuiSizeXXL | TuiSizeXXS, +}); + @Component({ standalone: true, template: '', @@ -33,12 +39,13 @@ class TuiHeaderStyles {} ], host: { tuiHeader: '', - '[attr.data-size]': 'size || "s"', + '[attr.data-size]': 'size || options.size', }, }) export class TuiHeader { + protected readonly options = inject(TUI_HEADER_OPTIONS); protected readonly nothing = tuiWithStyles(TuiHeaderStyles); @Input('tuiHeader') - public size: TuiSizeXXL | TuiSizeXXS | '' = 's'; + public size: TuiSizeXXL | TuiSizeXXS | '' = ''; } diff --git a/projects/layout/components/index.ts b/projects/layout/components/index.ts index 63939d44f0a5..274f45e66e9e 100644 --- a/projects/layout/components/index.ts +++ b/projects/layout/components/index.ts @@ -3,6 +3,7 @@ export * from '@taiga-ui/layout/components/block-details'; export * from '@taiga-ui/layout/components/block-status'; export * from '@taiga-ui/layout/components/card'; export * from '@taiga-ui/layout/components/cell'; +export * from '@taiga-ui/layout/components/form'; export * from '@taiga-ui/layout/components/header'; export * from '@taiga-ui/layout/components/navigation'; export * from '@taiga-ui/layout/components/search'; diff --git a/projects/layout/components/navigation/main.style.less b/projects/layout/components/navigation/main.style.less index 8902ef048f1b..0f2a8532a0a3 100644 --- a/projects/layout/components/navigation/main.style.less +++ b/projects/layout/components/navigation/main.style.less @@ -5,6 +5,7 @@ main[tuiNavigationMain] { display: grid; grid-template-columns: repeat(12, minmax(0, 8.5625rem)); + align-items: start; gap: 0 1rem; justify-content: center; flex: 1; diff --git a/projects/legacy/components/input-date-range/input-date-range.component.ts b/projects/legacy/components/input-date-range/input-date-range.component.ts index 386d3568e5a2..582e9d067221 100644 --- a/projects/legacy/components/input-date-range/input-date-range.component.ts +++ b/projects/legacy/components/input-date-range/input-date-range.component.ts @@ -3,6 +3,7 @@ import { Component, inject, Input, + signal, ViewChild, } from '@angular/core'; import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; @@ -86,6 +87,7 @@ export class TuiInputDateRangeComponent private readonly mobileCalendar = inject(TUI_MOBILE_CALENDAR, {optional: true}); private readonly options = inject(TUI_INPUT_DATE_OPTIONS); private readonly textfieldSize = inject(TUI_TEXTFIELD_SIZE); + private readonly nativeValue = signal(''); protected readonly dateTexts$ = inject(TUI_DATE_TEXTS); protected override readonly valueTransformer = inject( @@ -160,7 +162,7 @@ export class TuiInputDateRangeComponent return value ? value.getFormattedDayRange(this.dateFormat.mode, this.dateFormat.separator) - : nativeValue; + : nativeValue(); } public get size(): TuiSizeL | TuiSizeS { @@ -174,6 +176,8 @@ export class TuiInputDateRangeComponent } public onValueChange(value: string): void { + this.nativeValue.set(value); + if (this.control) { this.control.updateValueAndValidity({emitEvent: false}); } @@ -183,7 +187,7 @@ export class TuiInputDateRangeComponent } if (this.activePeriod) { - this.nativeValue = ''; + this.nativeValue.set(''); } this.value = @@ -201,7 +205,7 @@ export class TuiInputDateRangeComponent this.focusInput(); if (!range) { - this.nativeValue = ''; + this.nativeValue.set(''); } this.value = range; @@ -209,7 +213,7 @@ export class TuiInputDateRangeComponent public override writeValue(value: TuiDayRange | null): void { super.writeValue(value); - this.nativeValue = value ? this.computedValue : ''; + this.nativeValue.set(value ? this.computedValue : ''); } protected get computedMobile(): boolean { @@ -269,16 +273,6 @@ export class TuiInputDateRangeComponent return null; } - protected get nativeValue(): string { - return this.nativeFocusableElement?.value || ''; - } - - protected set nativeValue(value: string) { - if (this.nativeFocusableElement) { - this.nativeFocusableElement.value = value; - } - } - protected getComputedRangeFiller(dateFiller: string): string { return this.activePeriod ? '' : this.getDateRangeFiller(dateFiller); } @@ -299,12 +293,12 @@ export class TuiInputDateRangeComponent if ( !focused && !this.itemSelected && - (this.nativeValue.length === DATE_FILLER_LENGTH || - this.nativeValue.length === + (this.nativeValue().length === DATE_FILLER_LENGTH || + this.nativeValue().length === DATE_FILLER_LENGTH + RANGE_SEPARATOR_CHAR.length) ) { this.value = TuiDayRange.normalizeParse( - this.nativeValue, + this.nativeValue(), this.dateFormat.mode, ); } @@ -318,7 +312,7 @@ export class TuiInputDateRangeComponent } private get itemSelected(): boolean { - return this.items.findIndex((item) => String(item) === this.nativeValue) !== -1; + return this.items.findIndex((item) => String(item) === this.nativeValue()) !== -1; } @tuiPure diff --git a/projects/legacy/components/input-date-range/test/input-date-range.component.spec.ts b/projects/legacy/components/input-date-range/test/input-date-range.component.spec.ts index fbafe21464c3..48b149df4c9c 100644 --- a/projects/legacy/components/input-date-range/test/input-date-range.component.spec.ts +++ b/projects/legacy/components/input-date-range/test/input-date-range.component.spec.ts @@ -212,12 +212,6 @@ describe('InputDateRangeComponent', () => { }); describe('With items', () => { - beforeAll(() => { - jest.useFakeTimers({advanceTimers: true}).setSystemTime( - new Date('2024-01-15'), - ); - }); - beforeEach(() => { testComponent.items = tuiCreateDefaultDayRangePeriods(); }); @@ -306,7 +300,17 @@ describe('InputDateRangeComponent', () => { }); it('correctly sets stringify selected range via calendar', async () => { - inputPO.sendTextAndBlur('12/01/2021-02/14/2022'); + inputPO.sendText('12/01/2021-02/14/2022'); + /** + * TODO + * Uncomment me to see [TypeError: Cannot read properties of undefined (reading 'addEventListener')] + * ___ + * Stacktrace says that error happens inside `TUI_ACTIVE_ELEMENT`. + * Utility `tuiGetDocumentOrShadowRoot` returns `undefined`. + */ + // inputPO.blur(); + + await fixture.whenStable(); clickOnTextfield(); @@ -541,17 +545,19 @@ describe('InputDateRangeComponent', () => { expect(inputPO.value).toBe('12.09.2021 – 18.10.2021'); }); - it('transforms value which was programmatically patched', () => { - testComponent.control.patchValue([ - new Date(1922, 11, 30), - new Date(1991, 11, 26), - ]); + it('transforms value which was programmatically patched', async () => { + const newDateRange = [new Date(1922, 11, 30), new Date(1991, 11, 26)] as [ + Date, + Date, + ]; + + testComponent.control.patchValue(newDateRange); + + fixture.detectChanges(); + await fixture.whenStable(); expect(inputPO.value).toBe('30.12.1922 – 26.12.1991'); - expect(testComponent.control.value).toEqual([ - new Date(1922, 11, 30), - new Date(1991, 11, 26), - ]); + expect(testComponent.control.value).toEqual(newDateRange); }); }); diff --git a/projects/legacy/components/input-date-time/input-date-time.component.ts b/projects/legacy/components/input-date-time/input-date-time.component.ts index a432b5cf89ef..810f20f71c06 100644 --- a/projects/legacy/components/input-date-time/input-date-time.component.ts +++ b/projects/legacy/components/input-date-time/input-date-time.component.ts @@ -3,6 +3,7 @@ import { Component, inject, Input, + signal, ViewChild, } from '@angular/core'; import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; @@ -79,6 +80,7 @@ export class TuiInputDateTimeComponent private readonly textfieldSize = inject(TUI_TEXTFIELD_SIZE); private month: TuiMonth | null = null; private readonly timeMode$ = new BehaviorSubject('HH:MM'); + private readonly nativeValue = signal(''); protected readonly timeTexts$ = inject(TUI_TIME_TEXTS); protected readonly dateTexts$ = inject(TUI_DATE_TEXTS); @@ -147,10 +149,10 @@ export class TuiInputDateTimeComponent public get computedValue(): string { const {value, nativeValue, timeMode} = this; const [date, time] = value; - const hasTimeInputChars = nativeValue.length > DATE_FILLER_LENGTH; + const hasTimeInputChars = nativeValue().length > DATE_FILLER_LENGTH; if (!date || (!time && hasTimeInputChars)) { - return nativeValue; + return nativeValue(); } return this.getDateTimeString(date, time, timeMode); @@ -164,11 +166,14 @@ export class TuiInputDateTimeComponent public override writeValue(value: [TuiDay | null, TuiTime | null] | null): void { super.writeValue(value); - this.nativeValue = - this.value && (this.value[0] || this.value[1]) ? this.computedValue : ''; + this.nativeValue.set( + this.value && (this.value[0] || this.value[1]) ? this.computedValue : '', + ); } public onValueChange(value: string): void { + this.nativeValue.set(value); + if (this.control) { this.control.updateValueAndValidity({emitEvent: false}); } @@ -258,18 +263,6 @@ export class TuiInputDateTimeComponent ); } - protected get nativeValue(): string { - return this.nativeFocusableElement?.value || ''; - } - - protected set nativeValue(value: string) { - if (!this.nativeFocusableElement) { - return; - } - - this.nativeFocusableElement.value = value; - } - protected onClick(): void { this.open = !this.open; } @@ -279,8 +272,12 @@ export class TuiInputDateTimeComponent const newCaretIndex = DATE_FILLER_LENGTH + DATE_TIME_SEPARATOR.length; this.value = [day, modifiedTime]; - this.updateNativeValue(day); - this.nativeFocusableElement?.setSelectionRange(newCaretIndex, newCaretIndex); + this.nativeValue.update((x) => + this.getDateTimeString(day, x.split(DATE_TIME_SEPARATOR)[1] || ''), + ); + setTimeout(() => + this.nativeFocusableElement?.setSelectionRange(newCaretIndex, newCaretIndex), + ); this.open = false; } @@ -302,19 +299,19 @@ export class TuiInputDateTimeComponent timer(0) .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe(() => { - this.nativeValue = this.trimTrailingSeparator(this.nativeValue); + this.nativeValue.update((x) => this.trimTrailingSeparator(x)); }); if ( this.value[0] === null || this.value[1] !== null || - this.nativeValue.length === this.fillerLength || + this.nativeValue().length === this.fillerLength || this.timeMode === 'HH:MM' ) { return; } - const [, time] = this.nativeValue.split(DATE_TIME_SEPARATOR); + const [, time] = this.nativeValue().split(DATE_TIME_SEPARATOR); if (!time) { return; @@ -391,12 +388,6 @@ export class TuiInputDateTimeComponent : dateString; } - private updateNativeValue(day: TuiDay): void { - const time = this.nativeValue.split(DATE_TIME_SEPARATOR)[1] || ''; - - this.nativeValue = this.getDateTimeString(day, time); - } - private clampTime(time: TuiTime, day: TuiDay): TuiTime { const {computedMin, computedMax} = this; diff --git a/projects/legacy/components/input-date-time/test/input-date-time.component.spec.ts b/projects/legacy/components/input-date-time/test/input-date-time.component.spec.ts index ad6908ab82b5..67b026ac5f9e 100644 --- a/projects/legacy/components/input-date-time/test/input-date-time.component.spec.ts +++ b/projects/legacy/components/input-date-time/test/input-date-time.component.spec.ts @@ -421,9 +421,11 @@ describe('InputDateTime', () => { expect(inputPO.value).toBe('17.03.2022, 12:11'); }); - it('transforms value which was programmatically patched', () => { + it('transforms value which was programmatically patched', async () => { component.control.patchValue('09.05.1945, 00:43'); + await fixture.whenStable(); + expect(inputPO.value).toBe('09.05.1945, 00:43'); expect(component.control.value).toBe('09.05.1945, 00:43'); }); diff --git a/projects/legacy/components/input-date/input-date.component.ts b/projects/legacy/components/input-date/input-date.component.ts index 5e59f8224de8..11ad73c07490 100644 --- a/projects/legacy/components/input-date/input-date.component.ts +++ b/projects/legacy/components/input-date/input-date.component.ts @@ -4,6 +4,7 @@ import { Component, inject, Input, + signal, ViewChild, } from '@angular/core'; import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; @@ -83,6 +84,7 @@ export class TuiInputDateComponent private readonly textfieldSize = inject(TUI_TEXTFIELD_SIZE); private readonly mobileCalendar = inject(TUI_MOBILE_CALENDAR, {optional: true}); private month: TuiMonth | null = null; + private readonly nativeValue = signal(''); @Input() public min: TuiDay | null = this.options.min; @@ -142,16 +144,6 @@ export class TuiInputDateComponent return !!this.textfield?.focused; } - public get nativeValue(): string { - return this.nativeFocusableElement?.value || ''; - } - - public set nativeValue(value: string) { - if (this.nativeFocusableElement) { - this.nativeFocusableElement.value = value; - } - } - public get computedValue(): string { const {value, nativeValue, activeItem} = this; @@ -161,10 +153,12 @@ export class TuiInputDateComponent return value ? value.toString(this.dateFormat.mode, this.dateFormat.separator) - : nativeValue; + : nativeValue(); } public onValueChange(value: string): void { + this.nativeValue.set(value); + if (this.control) { this.control.updateValueAndValidity({emitEvent: false}); } @@ -174,7 +168,7 @@ export class TuiInputDateComponent } if (this.activeItem) { - this.nativeValue = ''; + this.nativeValue.set(''); } this.value = @@ -190,7 +184,7 @@ export class TuiInputDateComponent public override writeValue(value: TuiDay | null): void { super.writeValue(value); - this.nativeValue = value ? this.computedValue : ''; + this.nativeValue.set(value ? this.computedValue : ''); } protected get size(): TuiSizeL | TuiSizeS { diff --git a/projects/legacy/components/input-date/input-date.directive.ts b/projects/legacy/components/input-date/input-date.directive.ts index 1e2403b0d57c..6d1509b278ef 100644 --- a/projects/legacy/components/input-date/input-date.directive.ts +++ b/projects/legacy/components/input-date/input-date.directive.ts @@ -29,10 +29,6 @@ export class TuiInputDateDirective extends AbstractTuiTextfieldHost { changeDetection: ChangeDetectionStrategy.OnPush, }) class Test { + @Input() + public value: TuiDay | null = new TuiDay(2017, 2, 1); + @ViewChild(TuiInputDateComponent) public readonly component!: TuiInputDateComponent; @@ -62,8 +65,6 @@ describe('InputDate', () => { public items: TuiNamedDay[] = []; - public value: TuiDay | null = new TuiDay(2017, 2, 1); - public size: TuiSizeL | TuiSizeS = 'm'; public hintContent: string | null = 'prompt'; @@ -192,10 +193,10 @@ describe('InputDate', () => { }); describe('With items', () => { - beforeEach(() => { + beforeEach(async () => { testComponent.items = [ new TuiNamedDay( - new TuiDay(2017, 2, 1), + new TuiDay(2017, 2, 5), 'Current', TuiDay.currentLocal(), ), @@ -205,11 +206,13 @@ describe('InputDate', () => { TuiDay.currentLocal(), ), ]; + + fixture.detectChanges(); + await fixture.whenStable(); }); it('when entering item date, input shows named date', async () => { - inputPO.sendText('01.02.2017'); - + inputPO.sendText('05.03.2017'); await fixture.whenStable(); expect(inputPO.value).toBe('Current'); @@ -225,7 +228,7 @@ describe('InputDate', () => { }); it('when ngModel value updated with item date, input shows named date', async () => { - testComponent.value = TUI_LAST_DAY.append({year: -1}); + fixture.componentRef.setInput('value', TUI_LAST_DAY.append({year: -1})); fixture.detectChanges(); await fixture.whenStable(); @@ -238,7 +241,7 @@ describe('InputDate', () => { expect(getCalendar()).not.toBeNull(); - const calendarCell = getCalendarCell(1); + const calendarCell = getCalendarCell(5); calendarCell?.nativeElement.click(); @@ -479,9 +482,12 @@ describe('InputDate', () => { expect(testComponent.control.value).toEqual(new Date(2022, 0, 20)); }); - it('transforms value which was programmatically patched', () => { + it('transforms value which was programmatically patched', async () => { testComponent.control.patchValue(new Date(1991, 11, 26)); + fixture.detectChanges(); + await fixture.whenStable(); + expect(inputPO.value).toBe('26.12.1991'); expect(testComponent.control.value).toEqual(new Date(1991, 11, 26)); }); diff --git a/projects/legacy/components/input-tag/input-tag.style.less b/projects/legacy/components/input-tag/input-tag.style.less index 1344aa97bad1..28c0632a13cf 100644 --- a/projects/legacy/components/input-tag/input-tag.style.less +++ b/projects/legacy/components/input-tag/input-tag.style.less @@ -82,6 +82,10 @@ :host[data-size='l']:not(._label-outside) & { padding: 0; } + + tui-tag:last-of-type { + max-inline-size: 80%; + } } .t-content { diff --git a/projects/testing/setup-jest/index.ts b/projects/testing/setup-jest/index.ts index 91d12ff012dc..c3c55aae657f 100644 --- a/projects/testing/setup-jest/index.ts +++ b/projects/testing/setup-jest/index.ts @@ -143,6 +143,14 @@ class TransferMockEvent { global.DragEvent = TransferMockEvent as unknown as typeof DragEvent; global.ClipboardEvent = TransferMockEvent as unknown as typeof ClipboardEvent; +// Need before initialize any static methods +global.Date = class extends Date { + constructor(...args: DateConstructor[]) { + // @ts-ignore + super(...(args.length === 0 ? ['2023-02-15T00:00:00Z'] : args)); + } +} as unknown as DateConstructor; + /** * in our jest setupFilesAfterEnv file, * however when running with ng test those diff --git a/tsconfig.json b/tsconfig.json index dc64e982d487..c857bbef5896 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,8 +13,8 @@ "@demo/emulate/ng-zone-options": ["projects/demo/src/emulate/ng-zone-options.ts"], "@demo/environments/*": ["projects/demo/src/environments/*"], "@demo/root-package": ["package.json"], - "@demo/utils": ["projects/demo/src/utils/index"], "@demo/routes": ["projects/demo/src/modules/app/demo-routes"], + "@demo/utils": ["projects/demo/src/utils/index"], "@taiga-ui/addon-charts": ["projects/addon-charts/index"], "@taiga-ui/addon-charts/*": ["projects/addon-charts/*"], "@taiga-ui/addon-commerce": ["projects/addon-commerce/index"], @@ -38,10 +38,10 @@ "@taiga-ui/kit/*": ["projects/kit/*"], "@taiga-ui/layout": ["projects/layout/index"], "@taiga-ui/layout/*": ["projects/layout/*"], - "@taiga-ui/testing": ["projects/testing/index"], - "@taiga-ui/testing/*": ["projects/testing/*"], "@taiga-ui/legacy": ["projects/legacy/index"], - "@taiga-ui/legacy/*": ["projects/legacy/*"] + "@taiga-ui/legacy/*": ["projects/legacy/*"], + "@taiga-ui/testing": ["projects/testing/index"], + "@taiga-ui/testing/*": ["projects/testing/*"] } } }