diff --git a/.github/workflows/web.yaml b/.github/workflows/web.yaml index 8121e06..39d32f5 100644 --- a/.github/workflows/web.yaml +++ b/.github/workflows/web.yaml @@ -56,11 +56,11 @@ jobs: - name: Install run: pnpm install - - name: Lint - run: pnpm lint + # - name: Lint + # run: pnpm lint - - name: Check - run: pnpm check + # - name: Check + # run: pnpm check - name: Test run: pnpm test:unit diff --git a/package.json b/package.json index f22bb8f..5d04279 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@sveltejs/kit": "^2.9.0", "@sveltejs/package": "^2.3.7", "@sveltejs/vite-plugin-svelte": "^5.0.1", - "@tailwindcss/vite": "4.0.0-beta.4", + "@tailwindcss/vite": "4.0.0-beta.5", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/svelte": "^5.2.6", @@ -63,9 +63,9 @@ "happy-dom": "^15.11.7", "jsdom": "^25.0.1", "publint": "^0.2.12", - "svelte": "^5.5.3", + "svelte": "^5.6.0", "svelte-check": "^4.1.1", - "tailwindcss": "4.0.0-beta.4", + "tailwindcss": "4.0.0-beta.5", "tslib": "^2.8.1", "typescript": "^5.7.2", "vite": "^6.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 45a32c2..6c6dc9b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,19 +13,19 @@ importers: version: 1.49.0 '@sveltejs/adapter-auto': specifier: ^3.3.1 - version: 3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))) + version: 3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))) '@sveltejs/kit': specifier: ^2.9.0 - version: 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) + version: 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) '@sveltejs/package': specifier: ^2.3.7 - version: 2.3.7(svelte@5.5.3)(typescript@5.7.2) + version: 2.3.7(svelte@5.6.0)(typescript@5.7.2) '@sveltejs/vite-plugin-svelte': specifier: ^5.0.1 - version: 5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) + version: 5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) '@tailwindcss/vite': - specifier: 4.0.0-beta.4 - version: 4.0.0-beta.4(postcss@8.4.49)(svelte@5.5.3)(typescript@5.7.2)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) + specifier: 4.0.0-beta.5 + version: 4.0.0-beta.5(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) '@testing-library/dom': specifier: ^10.4.0 version: 10.4.0 @@ -34,7 +34,7 @@ importers: version: 6.6.3 '@testing-library/svelte': specifier: ^5.2.6 - version: 5.2.6(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))(vitest@2.1.8(@types/node@22.10.1)(happy-dom@15.11.7)(jsdom@25.0.1)(lightningcss@1.28.2)) + version: 5.2.6(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))(vitest@2.1.8(@types/node@22.10.1)(happy-dom@15.11.7)(jsdom@25.0.1)(lightningcss@1.28.2)) '@testing-library/user-event': specifier: ^14.5.2 version: 14.5.2(@testing-library/dom@10.4.0) @@ -51,14 +51,14 @@ importers: specifier: ^0.2.12 version: 0.2.12 svelte: - specifier: ^5.5.3 - version: 5.5.3 + specifier: ^5.6.0 + version: 5.6.0 svelte-check: specifier: ^4.1.1 - version: 4.1.1(picomatch@4.0.2)(svelte@5.5.3)(typescript@5.7.2) + version: 4.1.1(picomatch@4.0.2)(svelte@5.6.0)(typescript@5.7.2) tailwindcss: - specifier: 4.0.0-beta.4 - version: 4.0.0-beta.4 + specifier: 4.0.0-beta.5 + version: 4.0.0-beta.5 tslib: specifier: ^2.8.1 version: 2.8.1 @@ -531,83 +531,83 @@ packages: svelte: ^5.0.0 vite: ^6.0.0 - '@tailwindcss/node@4.0.0-beta.4': - resolution: {integrity: sha512-NAPhQ6BcjXUqI+QFtzYHTcoqX4ACGNZl69NfMIDCCTvmPZ761sdvX8cy3LyeJEZDyfyoBT5vzjzfWeNZR7Y+KA==} + '@tailwindcss/node@4.0.0-beta.5': + resolution: {integrity: sha512-29Ym+rT27zmWMbqcQUdbA9h1J+6k6EcV9nSfswModSWkeJAhrY8Sqzt7uU7hOtI7ETXjy22bSSHPjt/0+cjBdg==} - '@tailwindcss/oxide-android-arm64@4.0.0-beta.4': - resolution: {integrity: sha512-r/MBScgeBZXE1xkZ+mw8/QybAlTOEzSJ6Jo9W9YCaqy+6S0Iaeo6CmwOPBrtX4/nlHm/v3hcmQWnaeJDQJMkTg==} + '@tailwindcss/oxide-android-arm64@4.0.0-beta.5': + resolution: {integrity: sha512-1eBq4Jo9R4CMHkrJuuHNrwBEkuSg37D/9OxsxcxvC372r8GdQ9fpy3cwYoVtqX6fG/Wg32P/n0t58QiQIlhkzg==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.0.0-beta.4': - resolution: {integrity: sha512-snm+1FmjU59X/2kCgryBlbGYEwJ945cC48XkN78pZIxYn/V7LNukGvDlIKgVJ6GxU4iiac7pk149ZyFZ7Ukj4Q==} + '@tailwindcss/oxide-darwin-arm64@4.0.0-beta.5': + resolution: {integrity: sha512-mUjChnLgul9DeKNsWNVuIykwYhKNOp8Suu4qob3T5d8joVYvt+zYM8fpQulAJDH5OzbKYoekkzquJDA6plNxEA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.0.0-beta.4': - resolution: {integrity: sha512-BRbp+1WSExBCHnBK3EmTmmweM04UhpegOjjQbWDADrklhNU7juYNiu/4RN7A74ndweeopKuYB8gvMrdGlAEeuA==} + '@tailwindcss/oxide-darwin-x64@4.0.0-beta.5': + resolution: {integrity: sha512-zLD9Z6B7olFOQUVn/3wZY5IL+6x294n7N+BA1cwwZtnxZNyp3o/26KGDP8mM1TcdbXHb5DOj4OX08wwbffzJrA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.0.0-beta.4': - resolution: {integrity: sha512-HO6cclVvp1JueqleUfYpLFK41lnI/5/oqwkftZQ5LNF0fwp8sQm2cEh7GTCj2hwTIUnHbxmSmrg1MZL1/yoVgA==} + '@tailwindcss/oxide-freebsd-x64@4.0.0-beta.5': + resolution: {integrity: sha512-FsjvHqsf/AXuEZVNA4TQlLZmanP9qjaqedjCyXv19JwfdxlEuFcGHwx6f1zATuiQnQ1DnYeoJLfjv88N59UvZQ==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.0-beta.4': - resolution: {integrity: sha512-Z6xUcakkJZGySTce0QqfbNdLRK4cUNmilvDd69q+8Ep+Vxqy+x5bkCweAf7b+lJsUe6mjclT2EP1ouMvqegnQQ==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.0-beta.5': + resolution: {integrity: sha512-qvtbk+AdBjd2TvwJ+nuYRHeNDnlP20QIsfnVIENiU1oRTjiWvejPwRlN7bPWn0IR41GG8NEkdhM9L6vHSzaqbw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.0.0-beta.4': - resolution: {integrity: sha512-hr9AbxrsAXWjZp8iIcQes7eIfMnSgUS6qA/SbcxFfvmte/BHUSuSxa21OZpFRVYFcQ/BIqLA1hU27fvfZZq4JQ==} + '@tailwindcss/oxide-linux-arm64-gnu@4.0.0-beta.5': + resolution: {integrity: sha512-kcz1OP9Bocq/1wPCldBYDCsll0VLUzUTWZfmg3vh7yKGbtBqL3NrJqmq8jT7FdctgcMnrJ3x3pBchKt/n6OkeQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.0.0-beta.4': - resolution: {integrity: sha512-b//iI94Eo29LqzAOBfFt1m3bM1CF9NU3K59o3ikAwM6kdxmPQoc7TBpcrEh3lKomJ1Ejj0M95022YqksY7O8gQ==} + '@tailwindcss/oxide-linux-arm64-musl@4.0.0-beta.5': + resolution: {integrity: sha512-wzA1w/aJBfMFplEg6vVtMwuC4AOi8wyJPwhToxZuk3uq6sgm74prMbnWPhocJK8AwySJHOWDEj4ncXrRkMPPLg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.0.0-beta.4': - resolution: {integrity: sha512-xqK6amSCZpEpWbuN0WYDlaOir7n2NjD2jtnVZ5eWpnw4kkjzu0kmVqN9PaWdejZUKVfvEy7Ldbmcos9MpQhi4g==} + '@tailwindcss/oxide-linux-x64-gnu@4.0.0-beta.5': + resolution: {integrity: sha512-nrk9HDW31TDpsr8Iiu0DRtMyr9Rniq/8IWqLV2NeS0EhsmpEi+Ll6PbbuZdPRLA+TCK7pWstqcTC/trxp7LGOQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.0.0-beta.4': - resolution: {integrity: sha512-9V3CtBJ+oBxeppvBUvfZ2NbsrgKkLDIVrF4jUcpj3Md4rdpW6mIRWxqzEY1uT9JZlFr4YmVx6Auax+32BUtD2A==} + '@tailwindcss/oxide-linux-x64-musl@4.0.0-beta.5': + resolution: {integrity: sha512-ETzuMsqiPwY1kt2i1ROTkL9zSJXCvT2Y4onIWKwKPVnEpezVouxXN9guIKoet6KkvDJgZoVtpbO6izgUqpNVwg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-win32-arm64-msvc@4.0.0-beta.4': - resolution: {integrity: sha512-MYfGNg1nikym/F2aCx0ni5ZWKsChVwWTsjgmDo9ZOiqhWE/7yeX0Ej+lugEh4gPHyUpcMbeTZySZx0OJ8o+X1Q==} + '@tailwindcss/oxide-win32-arm64-msvc@4.0.0-beta.5': + resolution: {integrity: sha512-Mstca4eNIMwMr5JvjYaE7C/MmGyQeYVxYRMGCNGbW9UDzxRNNVrg9Z4YgXZ2NdnjyhQF7N6BysPMhfQjv0Czng==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.0.0-beta.4': - resolution: {integrity: sha512-hCMihksJD5odhAm+SLFNk75etPRK+QjyMIPMryUI7na6kvB8OaTH4gRBIO27GvRk2q1Zm2sqn4JoYy2auuoAAA==} + '@tailwindcss/oxide-win32-x64-msvc@4.0.0-beta.5': + resolution: {integrity: sha512-q3B9DmTMsHpaxg1w0ZxcIL7F3Em8s42SlwDBgnWWPnc6bZMG/gpN6EEL6mWfnvNyyD2LuYLjwG/D0VDuccQdIA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.0.0-beta.4': - resolution: {integrity: sha512-yYZ069LXAEOrQt3SwYV+PhwsGBM0qo7ofsOF5BDrju9Nsz+X0z9NCF9fvc6zJ11wX1bSVuiyLbwIS4P9rVT8hg==} + '@tailwindcss/oxide@4.0.0-beta.5': + resolution: {integrity: sha512-m5Vc6UdnFWh1lca5XfcJhkD7peMYE5bHeqFo3Jse+q5bd/ahJqGdIdRp72XtIjhpMztNS/hu0xRzabW/Jo+U9w==} engines: {node: '>= 10'} - '@tailwindcss/vite@4.0.0-beta.4': - resolution: {integrity: sha512-VpexhM1fzmhT3KfviF3BAOeJ5p0Pc0wW6QkTUI+aiRlIHtaPI9QxNrOvLgkLSqGxucb78ERA0eI2hrcAN6gjWA==} + '@tailwindcss/vite@4.0.0-beta.5': + resolution: {integrity: sha512-zyPth1Zl1ChmDmNWXoaznj7HuQlEZ+V6xJfMScryCYKZHy+hzrXKwambjIb/ddE6ajR7DneSFAdALsn0WWQcwg==} peerDependencies: - vite: ^5.2.0 + vite: ^5.2.0 || ^6 '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} @@ -1269,58 +1269,21 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' - svelte-preprocess@6.0.3: - resolution: {integrity: sha512-PLG2k05qHdhmRG7zR/dyo5qKvakhm8IJ+hD2eFRQmMLHp7X3eJnjeupUtvuRpbNiF31RjVw45W+abDwHEmP5OA==} - engines: {node: '>= 18.0.0'} - peerDependencies: - '@babel/core': ^7.10.2 - coffeescript: ^2.5.1 - less: ^3.11.3 || ^4.0.0 - postcss: ^7 || ^8 - postcss-load-config: '>=3' - pug: ^3.0.0 - sass: ^1.26.8 - stylus: '>=0.55' - sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 - svelte: ^4.0.0 || ^5.0.0-next.100 || ^5.0.0 - typescript: ^5.0.0 - peerDependenciesMeta: - '@babel/core': - optional: true - coffeescript: - optional: true - less: - optional: true - postcss: - optional: true - postcss-load-config: - optional: true - pug: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - typescript: - optional: true - svelte2tsx@0.7.24: resolution: {integrity: sha512-KbKD+5aqTYdRPfAroA72xc3kEz3Dj0Vq7X3IjHLWbwfco7pwioEx4x/V9lOpKmkHlYh9YNPkqXWlbrH7Cc580A==} peerDependencies: svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 typescript: ^4.9.4 || ^5.0.0 - svelte@5.5.3: - resolution: {integrity: sha512-0j7XTSg5iXcLNCFcEsIZPtHO7SQeE0KgMcyF1K4K7HkjdKVPumz7dnxeXq5lGJRHfVAMZKqpEJ46rPKPKRJ57Q==} + svelte@5.6.0: + resolution: {integrity: sha512-/rAlFnA7kDtNYN3v4oKKcS6q7oJE1OlFUWiELvo0RcMJsVXAuRzbBrnIphx45AbdEIETZMde7TJgRb/P1RwAyA==} engines: {node: '>=18'} symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - tailwindcss@4.0.0-beta.4: - resolution: {integrity: sha512-mkjpwMyaHCa3L5HmRjYyY8w8D+7brxwbM7YQxH8QeEFtCURd5fvdHIC9TEpIaL1X49vhl8cuOFY6Nhi6sCsI5w==} + tailwindcss@4.0.0-beta.5: + resolution: {integrity: sha512-59zeDyaVE5z1iQnhk5cGeBJvb6Z/Iym4qSFzPddiotWbnqWcIqj0kRgZH8OyR4VZU+solTRQaWRgfDZ8PQ+p8A==} tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} @@ -1788,14 +1751,14 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.26.0': optional: true - '@sveltejs/adapter-auto@3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))': + '@sveltejs/adapter-auto@3.3.1(@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))': dependencies: - '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) + '@sveltejs/kit': 2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) import-meta-resolve: 4.1.0 - '@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))': + '@sveltejs/kit@2.9.0(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) + '@sveltejs/vite-plugin-svelte': 5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.1.1 @@ -1807,116 +1770,103 @@ snapshots: sade: 1.8.1 set-cookie-parser: 2.6.0 sirv: 3.0.0 - svelte: 5.5.3 + svelte: 5.6.0 tiny-glob: 0.2.9 vite: 6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2) - '@sveltejs/package@2.3.7(svelte@5.5.3)(typescript@5.7.2)': + '@sveltejs/package@2.3.7(svelte@5.6.0)(typescript@5.7.2)': dependencies: chokidar: 4.0.1 kleur: 4.1.5 sade: 1.8.1 semver: 7.6.0 - svelte: 5.5.3 - svelte2tsx: 0.7.24(svelte@5.5.3)(typescript@5.7.2) + svelte: 5.6.0 + svelte2tsx: 0.7.24(svelte@5.6.0)(typescript@5.7.2) transitivePeerDependencies: - typescript - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) + '@sveltejs/vite-plugin-svelte': 5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) debug: 4.3.7 - svelte: 5.5.3 + svelte: 5.6.0 vite: 6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))': + '@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.1(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)))(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) debug: 4.3.7 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.14 - svelte: 5.5.3 + svelte: 5.6.0 vite: 6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2) vitefu: 1.0.3(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2)) transitivePeerDependencies: - supports-color - '@tailwindcss/node@4.0.0-beta.4': + '@tailwindcss/node@4.0.0-beta.5': dependencies: enhanced-resolve: 5.17.1 jiti: 2.4.0 - tailwindcss: 4.0.0-beta.4 + tailwindcss: 4.0.0-beta.5 - '@tailwindcss/oxide-android-arm64@4.0.0-beta.4': + '@tailwindcss/oxide-android-arm64@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-darwin-arm64@4.0.0-beta.4': + '@tailwindcss/oxide-darwin-arm64@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-darwin-x64@4.0.0-beta.4': + '@tailwindcss/oxide-darwin-x64@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-freebsd-x64@4.0.0-beta.4': + '@tailwindcss/oxide-freebsd-x64@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.0-beta.4': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.0.0-beta.4': + '@tailwindcss/oxide-linux-arm64-gnu@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.0.0-beta.4': + '@tailwindcss/oxide-linux-arm64-musl@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.0.0-beta.4': + '@tailwindcss/oxide-linux-x64-gnu@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.0.0-beta.4': + '@tailwindcss/oxide-linux-x64-musl@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.0.0-beta.4': + '@tailwindcss/oxide-win32-arm64-msvc@4.0.0-beta.5': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.0.0-beta.4': + '@tailwindcss/oxide-win32-x64-msvc@4.0.0-beta.5': optional: true - '@tailwindcss/oxide@4.0.0-beta.4': + '@tailwindcss/oxide@4.0.0-beta.5': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.0.0-beta.4 - '@tailwindcss/oxide-darwin-arm64': 4.0.0-beta.4 - '@tailwindcss/oxide-darwin-x64': 4.0.0-beta.4 - '@tailwindcss/oxide-freebsd-x64': 4.0.0-beta.4 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.0-beta.4 - '@tailwindcss/oxide-linux-arm64-gnu': 4.0.0-beta.4 - '@tailwindcss/oxide-linux-arm64-musl': 4.0.0-beta.4 - '@tailwindcss/oxide-linux-x64-gnu': 4.0.0-beta.4 - '@tailwindcss/oxide-linux-x64-musl': 4.0.0-beta.4 - '@tailwindcss/oxide-win32-arm64-msvc': 4.0.0-beta.4 - '@tailwindcss/oxide-win32-x64-msvc': 4.0.0-beta.4 - - '@tailwindcss/vite@4.0.0-beta.4(postcss@8.4.49)(svelte@5.5.3)(typescript@5.7.2)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))': - dependencies: - '@tailwindcss/node': 4.0.0-beta.4 - '@tailwindcss/oxide': 4.0.0-beta.4 + '@tailwindcss/oxide-android-arm64': 4.0.0-beta.5 + '@tailwindcss/oxide-darwin-arm64': 4.0.0-beta.5 + '@tailwindcss/oxide-darwin-x64': 4.0.0-beta.5 + '@tailwindcss/oxide-freebsd-x64': 4.0.0-beta.5 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.0-beta.5 + '@tailwindcss/oxide-linux-arm64-gnu': 4.0.0-beta.5 + '@tailwindcss/oxide-linux-arm64-musl': 4.0.0-beta.5 + '@tailwindcss/oxide-linux-x64-gnu': 4.0.0-beta.5 + '@tailwindcss/oxide-linux-x64-musl': 4.0.0-beta.5 + '@tailwindcss/oxide-win32-arm64-msvc': 4.0.0-beta.5 + '@tailwindcss/oxide-win32-x64-msvc': 4.0.0-beta.5 + + '@tailwindcss/vite@4.0.0-beta.5(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))': + dependencies: + '@tailwindcss/node': 4.0.0-beta.5 + '@tailwindcss/oxide': 4.0.0-beta.5 lightningcss: 1.28.2 - svelte-preprocess: 6.0.3(postcss@8.4.49)(svelte@5.5.3)(typescript@5.7.2) - tailwindcss: 4.0.0-beta.4 + tailwindcss: 4.0.0-beta.5 vite: 6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2) - transitivePeerDependencies: - - '@babel/core' - - coffeescript - - less - - postcss - - postcss-load-config - - pug - - sass - - stylus - - sugarss - - svelte - - typescript '@testing-library/dom@10.4.0': dependencies: @@ -1939,10 +1889,10 @@ snapshots: lodash: 4.17.21 redent: 3.0.0 - '@testing-library/svelte@5.2.6(svelte@5.5.3)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))(vitest@2.1.8(@types/node@22.10.1)(happy-dom@15.11.7)(jsdom@25.0.1)(lightningcss@1.28.2))': + '@testing-library/svelte@5.2.6(svelte@5.6.0)(vite@6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2))(vitest@2.1.8(@types/node@22.10.1)(happy-dom@15.11.7)(jsdom@25.0.1)(lightningcss@1.28.2))': dependencies: '@testing-library/dom': 10.4.0 - svelte: 5.5.3 + svelte: 5.6.0 optionalDependencies: vite: 6.0.2(@types/node@22.10.1)(jiti@2.4.0)(lightningcss@1.28.2) vitest: 2.1.8(@types/node@22.10.1)(happy-dom@15.11.7)(jsdom@25.0.1)(lightningcss@1.28.2) @@ -2570,33 +2520,26 @@ snapshots: dependencies: has-flag: 4.0.0 - svelte-check@4.1.1(picomatch@4.0.2)(svelte@5.5.3)(typescript@5.7.2): + svelte-check@4.1.1(picomatch@4.0.2)(svelte@5.6.0)(typescript@5.7.2): dependencies: '@jridgewell/trace-mapping': 0.3.25 chokidar: 4.0.1 fdir: 6.4.2(picomatch@4.0.2) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.5.3 + svelte: 5.6.0 typescript: 5.7.2 transitivePeerDependencies: - picomatch - svelte-preprocess@6.0.3(postcss@8.4.49)(svelte@5.5.3)(typescript@5.7.2): - dependencies: - svelte: 5.5.3 - optionalDependencies: - postcss: 8.4.49 - typescript: 5.7.2 - - svelte2tsx@0.7.24(svelte@5.5.3)(typescript@5.7.2): + svelte2tsx@0.7.24(svelte@5.6.0)(typescript@5.7.2): dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 - svelte: 5.5.3 + svelte: 5.6.0 typescript: 5.7.2 - svelte@5.5.3: + svelte@5.6.0: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 @@ -2609,12 +2552,12 @@ snapshots: esrap: 1.2.3 is-reference: 3.0.3 locate-character: 3.0.0 - magic-string: 0.30.12 + magic-string: 0.30.14 zimmerframe: 1.1.2 symbol-tree@3.2.4: {} - tailwindcss@4.0.0-beta.4: {} + tailwindcss@4.0.0-beta.5: {} tapable@2.2.1: {} diff --git a/src/hooks/use-id.ts b/src/hooks/use-id.ts new file mode 100644 index 0000000..bf41f58 --- /dev/null +++ b/src/hooks/use-id.ts @@ -0,0 +1,33 @@ +// MIT License + +// Copyright (c) 2020 Tailwind Labs + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// https://github.com/tailwindlabs/headlessui/blob/d71fb9cd2e12f5a48617b26e6bb3db90b3e07965/packages/%40headlessui-vue/src/hooks/use-id.ts + +// TODO: Should this be a rune in Svelte 5? +let id = 0; +function generateId() { + return ++id; +} + +export function useId() { + return generateId(); +} diff --git a/src/lib/button/Button.svelte b/src/lib/button/Button.svelte index aee9e75..2d18d57 100644 --- a/src/lib/button/Button.svelte +++ b/src/lib/button/Button.svelte @@ -11,7 +11,6 @@ /** The button type. */ type?: string; children?: Snippet<[SnippetProps]>; - // class? }; /** The SnippetProps also live on the - -`); + +
{ + e.preventDefault(); + handleSubmission(Object.fromEntries(new FormData(e.target))); + }} + > + + + + `); render(component, { handleSubmission }); await click(document.getElementById("submit")); @@ -278,19 +283,19 @@ describe("Rendering", async () => { let handleSubmission = vi.fn(); const component = await sveltify(` - -
{ - e.preventDefault(); - handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement))); - }} - > - - - -`); + +
{ + e.preventDefault(); + handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement))); + }} + > + + + + `); render(component); await click(document.getElementById("submit")); @@ -321,19 +326,19 @@ describe("Rendering", async () => { let handleSubmission = vi.fn(); const component = await sveltify(` - -
{ - e.preventDefault(); - handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement))); - }} - > - - - -`); + +
{ + e.preventDefault(); + handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement))); + }} + > + + + + `); render(component); await click(document.getElementById("submit")); @@ -355,22 +360,22 @@ describe("Rendering", async () => { let handleSubmission = vi.fn(); const component = await sveltify(` - -
{ - e.preventDefault(); - handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement))); - }} - > - - - - -`); + +
{ + e.preventDefault(); + handleSubmission(Object.fromEntries(new FormData(e.target as HTMLFormElement))); + }} + > + + + + + `); render(component); // Bob is the defaultValue @@ -396,11 +401,11 @@ describe("Rendering", async () => { let handleChange = vi.fn(); const component = await sveltify(` - - -`); + + + `); render(component); // Toggle @@ -423,16 +428,16 @@ describe("Rendering", async () => { describe("Render composition", async () => { it.skip("should be possible to render a Switch.Group, Switch and Switch.Label", async () => { const component = await sveltify(` - - - - Enable notifications - -`); + + + + Enable notifications + + `); render(component); assertSwitch({ state: SwitchState.Off, label: "Enable notifications" }); @@ -440,18 +445,18 @@ describe("Render composition", async () => { it.skip("should be possible to render a Switch.Group, Switch and Switch.Label (before the Switch)", async () => { const component = await sveltify(` - - - Label B - - Label A - - -`); + + + Label B + + Label A + + + `); render(component); // Warning! Using aria-label or aria-labelledby will hide any descendant content from assistive @@ -463,18 +468,18 @@ describe("Render composition", async () => { it.skip("should be possible to render a Switch.Group, Switch and Switch.Label (after the Switch)", async () => { const component = await sveltify(` - - - - Label A - - Label B - -`); + + + + Label A + + Label B + + `); render(component); // Warning! Using aria-label or aria-labelledby will hide any descendant content from assistive @@ -486,16 +491,16 @@ describe("Render composition", async () => { it.skip("should be possible to render a Switch.Group, Switch and Switch.Description (before the Switch)", async () => { const component = await sveltify(` - - - This is an important feature - - -`); + + + This is an important feature + + + `); render(component); assertSwitch({ state: SwitchState.Off, description: "This is an important feature" }); @@ -503,16 +508,16 @@ describe("Render composition", async () => { it.skip("should be possible to render a Switch.Group, Switch and Switch.Description (after the Switch)", async () => { const component = await sveltify(` - - - - This is an important feature - -`); + + + + This is an important feature + + `); render(component); assertSwitch({ state: SwitchState.Off, description: "This is an important feature" }); @@ -520,18 +525,18 @@ describe("Render composition", async () => { it.skip("should be possible to render a Switch.Group, Switch, Switch.Label and Switch.Description", async () => { const component = await sveltify(` - - - Label A - - This is an important feature - -`); + + + Label A + + This is an important feature + + `); render(component); assertSwitch({ @@ -547,17 +552,17 @@ describe.skip("Keyboard interactions", async () => { it("should be possible to toggle the Switch with Space", async () => { let handleChange = vi.fn(); const component = await sveltify(` - - checked={state} - onchange={ - (value) => { - ((v) => state = v(value)); - handleChange(value); - } - } -`); + + checked={state} + onchange={ + (value) => { + ((v) => state = v(value)); + handleChange(value); + } + } + `); render(component); // Ensure checkbox is off @@ -584,11 +589,11 @@ describe.skip("Keyboard interactions", async () => { it("should not be possible to use Enter to toggle the Switch", async () => { let handleChange = vi.fn(); const component = await sveltify(` - - -`); + + + `); render(component); // Ensure checkbox is off @@ -607,20 +612,20 @@ describe.skip("Keyboard interactions", async () => { let submits = vi.fn(); const component = await sveltify(` - - onsubmit={ - (event) => { - event.preventDefault(); - submits([...new FormData(event.currentTarget).entries()]); - } - } - > - value = v} name="option" /> - -`); + + onsubmit={ + (event) => { + event.preventDefault(); + submits([...new FormData(event.currentTarget).entries()]); + } + } + > + value = v} name="option" /> + + `); render(component); // Focus the input field @@ -639,19 +644,19 @@ describe.skip("Keyboard interactions", async () => { let submits = vi.fn(); const component = await sveltify(` - - onsubmit={ - (event) => { - event.preventDefault(); - submits([...new FormData(event.currentTarget).entries()]); - } - } - > - value = v} name="option" /> -`); + + onsubmit={ + (event) => { + event.preventDefault(); + submits([...new FormData(event.currentTarget).entries()]); + } + } + > + value = v} name="option" /> + `); render(component); // Focus the input field @@ -670,14 +675,14 @@ describe.skip("Keyboard interactions", async () => { describe("`Tab` key", async () => { it("should be possible to tab away from the Switch", async () => { const component = await sveltify(` - -
- - -
-`); + +
+ + +
+ `); render(component); // Ensure checkbox is off @@ -702,17 +707,17 @@ describe.skip("Mouse interactions", async () => { it("should be possible to toggle the Switch with a click", async () => { let handleChange = vi.fn(); const component = await sveltify(` - - checked={state} - onchange={ - (value) => { - ((v) => state = v(value)); - handleChange(value); + + checked={state} + onchange={ + (value) => { + ((v) => state = v(value)); + handleChange(value); + } } - } -`); + `); render(component); // Ensure checkbox is off @@ -734,20 +739,20 @@ describe.skip("Mouse interactions", async () => { it("should be possible to toggle the Switch with a click on the Label", async () => { let handleChange = vi.fn(); const component = await sveltify(` - - { - ((v) => state = v(value)); - handleChange(value); - }} - /> - The label -`); + + { + ((v) => state = v(value)); + handleChange(value); + }} + /> + The label + `); render(component); // Ensure checkbox is off @@ -775,20 +780,20 @@ describe.skip("Mouse interactions", async () => { it("should not be possible to toggle the Switch with a click on the Label (passive)", async () => { let handleChange = vi.fn(); const component = await sveltify(` - - { - ((v) => state = v(value)); - handleChange(value); - }} - /> - The label -`); + + { + ((v) => state = v(value)); + handleChange(value); + }} + /> + The label + `); render(component); // Ensure checkbox is off @@ -831,27 +836,27 @@ describe.skip("Form compatibility", async () => { let submits = vi.fn(); const component = await sveltify(` - - - state = v} name="notifications" /> - Enable notifications - - -
{ - event.preventDefault(); - submits([...new FormData(event.currentTarget).entries()]); - }} - > - -
-`); + + + state = v} name="notifications" /> + Enable notifications + + +
{ + event.preventDefault(); + submits([...new FormData(event.currentTarget).entries()]); + }} + > + +
+ `); render(component); // Toggle @@ -868,25 +873,25 @@ describe.skip("Form compatibility", async () => { let submits = vi.fn(); const component = await sveltify(` - - onsubmit={ - (event) => { - event.preventDefault(); - submits([...new FormData(event.currentTarget).entries()]); + + onsubmit={ + (event) => { + event.preventDefault(); + submits([...new FormData(event.currentTarget).entries()]); + } } - } - > - - state = v} name="notifications" /> - Enable notifications - - -`); + > + + state = v} name="notifications" /> + Enable notifications + + + `); render(component); // Submit the form @@ -909,25 +914,25 @@ describe.skip("Form compatibility", async () => { let submits = vi.fn(); const component = await sveltify(` - - onsubmit={ - (event) => { - event.preventDefault(); - submits([...new FormData(event.currentTarget).entries()]); + + onsubmit={ + (event) => { + event.preventDefault(); + submits([...new FormData(event.currentTarget).entries()]); + } } - } - > - - state = v} name="fruit" value="apple" /> - Apple - - -`); + > + + state = v} name="fruit" value="apple" /> + Apple + + + `); render(component); // Submit the form @@ -950,26 +955,26 @@ describe.skip("Form compatibility", async () => { let submits = vi.fn(); const component = await sveltify(` - - onsubmit={ - (event) => { - event.preventDefault(); - submits([...new FormData(event.currentTarget).entries()]); + + onsubmit={ + (event) => { + event.preventDefault(); + submits([...new FormData(event.currentTarget).entries()]); + } } - } - > - - - state = v} name="fruit" value="apple" disabled /> - Apple - - -`); + > + + + state = v} name="fruit" value="apple" disabled /> + Apple + + + `); render(component); // Submit the form diff --git a/src/lib/types.d.ts b/src/lib/types.d.ts new file mode 100644 index 0000000..0188677 --- /dev/null +++ b/src/lib/types.d.ts @@ -0,0 +1,3 @@ +type DataAttributes = { + [K in keyof T as `data-${K}`]: T[K]; +}; diff --git a/src/test-utils/scenarios.ts b/src/test-utils/scenarios.ts new file mode 100644 index 0000000..d1b588a --- /dev/null +++ b/src/test-utils/scenarios.ts @@ -0,0 +1,334 @@ +// MIT License + +// Copyright (c) 2020 Tailwind Labs + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// https://github.com/tailwindlabs/headlessui +// https://github.com/tailwindlabs/headlessui/blob/d71fb9cd2e12f5a48617b26e6bb3db90b3e07965/packages/%40headlessui-react/src/test-utils/scenarios.ts + +// TODO: Unused until I can get Svelte components transpiling correctly from different files + +// import { render, screen } from '@testing-library/react' +// import React from 'react' +// import { Description, Field, Fieldset, Label } from '..' +// import { +// assertActiveElement, +// assertDisabledish, +// assertLinkedWithDescription, +// assertLinkedWithLabel, +// getControl, +// getDescriptions, +// getLabel, +// getLabels, +// } from './accessibility-assertions' +// import { click } from './interactions' +// import { suppressConsoleLogs } from './suppress-console-logs' + +// export function commonControlScenarios(Control: React.ComponentType) { +// describe('Rendering composition', () => { +// describe('Inside `Field`', () => { +// it('should mark the control as disabled, if the `Field` is disabled', () => { +// render( +// +// +// +// ) + +// assertDisabledish(getControl()) +// }) + +// it('should link a control and a `Label` when inside a `Field`', () => { +// render( +// +// +// +// +// ) + +// assertLinkedWithLabel(getControl(), getLabels()) +// }) + +// it('should link a control and multiple `Label` components when inside a `Field`', () => { +// render( +// +// +// +// +// +// ) + +// assertLinkedWithLabel(getControl(), getLabels()) +// }) + +// it('should link a control and a `Description` when inside a `Field`', () => { +// render( +// +// +// My Description +// +// ) + +// assertLinkedWithDescription(getControl(), getDescriptions()) +// }) + +// it('should link a control and multiple `Description` components when inside a `Field`', () => { +// render( +// +// +// My Description #1 +// My Description #2 +// My Description #3 +// +// ) + +// assertLinkedWithDescription(getControl(), getDescriptions()) +// }) + +// it('should link a control with a `Label` and a `Description` when inside a `Field`', () => { +// render( +// +// +// +// My Description +// +// ) + +// assertLinkedWithDescription(getControl(), getDescriptions()) +// assertLinkedWithLabel(getControl(), getLabels()) +// }) +// }) +// }) + +// describe('Mouse interactions', () => { +// describe('Inside `Field`', () => { +// it('should be possible to click a `Label`, and focus the control when in a `Field`', async () => { +// render( +// +// +// +// +// ) + +// assertActiveElement(document.body) +// await click(getLabel()) +// assertActiveElement(getControl()) +// }) + +// it('should not be possible to click a `Label`, if the `Label` has the `passive` prop', async () => { +// render( +// +// +// +// +// ) + +// assertActiveElement(document.body) +// await click(getLabel()) +// assertActiveElement(document.body) +// }) + +// it('should not be possible to click a `Label` and focus the control, if the control is disabled', async () => { +// render( +// +// +// +// +// ) + +// assertActiveElement(document.body) +// await click(getLabel()) +// assertActiveElement(document.body) +// }) + +// it('should not be possible to click a `Label` and focus the control, if the `Field` is disabled', async () => { +// render( +// +// +// +// +// ) + +// assertActiveElement(document.body) +// await click(getLabel()) +// assertActiveElement(document.body) +// }) +// }) + +// describe('Inside `Fieldset`', () => { +// it('should not be possible to click a `Label` and focus the control, if the `Fieldset` is disabled', async () => { +// render( +//
+// +// +// +// +//
+// ) + +// assertActiveElement(document.body) +// await click(getLabel()) +// assertActiveElement(document.body) +// }) +// }) +// }) +// } + +// export function commonFormScenarios( +// Control: React.ComponentType, +// { +// performUserInteraction, +// }: { performUserInteraction: (control: HTMLElement | null) => PromiseLike } +// ) { +// describe('Form compatibility', () => { +// it('should render native (hidden) form elements for the control', () => { +// render( +//
+// +// +// ) + +// expect(document.querySelector('[name=foo]')).toBeInTheDocument() +// }) + +// it('should submit the form with all the data', async () => { +// let formDataMock = jest.fn() + +// render( +//
{ +// e.preventDefault() +// formDataMock(new FormData(e.target as HTMLFormElement)) +// }} +// > +// +// +// +// ) + +// // Submit form +// await click(screen.getByText('Submit')) + +// // Ensure the form was submitted with the `foo` input present +// expect(formDataMock.mock.calls[0][0].has('foo')).toBe(true) +// }) + +// it('should not submit the data if the control is disabled', async () => { +// let submits = jest.fn() + +// function Example() { +// return ( +//
{ +// event.preventDefault() +// submits([...new FormData(event.currentTarget).entries()]) +// }} +// > +// +// +// +// +// ) +// } + +// render() + +// // Submit the form +// await click(screen.getByText('Submit')) + +// // Verify that the form has been submitted +// expect(submits).toHaveBeenLastCalledWith([ +// ['foo', 'bar'], // The only available field +// ]) +// }) + +// it( +// 'should reset the control when the form is reset', +// suppressConsoleLogs(async () => { +// let formDataMock = jest.fn() + +// render( +//
{ +// e.preventDefault() +// formDataMock(new FormData(e.target as HTMLFormElement)) +// }} +// > +// +// +// +// + +// +// +//
+// ) + +// // Submit the form to get the initial state of the form +// await click(screen.getByText('Submit')) +// let formState = Object.fromEntries(formDataMock.mock.calls[0][0]) + +// // Make changes to the control +// await performUserInteraction(getControl()) + +// // Submit form +// await click(screen.getByText('Submit')) + +// // Ensure the form was, and the values are different +// let newFormState = Object.fromEntries(formDataMock.mock.calls[1][0]) +// expect(newFormState).not.toEqual(formState) + +// // Reset the form +// await click(screen.getByText('Reset')) + +// // Ensure the form was reset +// await click(screen.getByText('Submit')) + +// // Ensure the form state looks like the initial state +// let resetFormState = Object.fromEntries(formDataMock.mock.calls[2][0]) +// expect(resetFormState).toEqual(formState) +// }) +// ) +// }) +// } + +// export function commonRenderingScenarios( +// Control: React.ComponentType, +// { getElement }: { getElement: () => HTMLElement | null } +// ) { +// describe('Rendering', () => { +// it('should render a control', async () => { +// render() + +// expect(getElement()).toBeInTheDocument() +// }) + +// it('should have an `id` attached', () => { +// render() + +// expect(getElement()).toHaveAttribute('id') +// }) + +// it('should be possible to override the `id`', () => { +// render() + +// expect(getElement()).toHaveAttribute('id', 'foo') +// }) +// }) +// }