diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index af9447f85..7fba05b8d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,11 +26,15 @@ - JavaScriptのランタイム - [Node.js](https://nodejs.org): v22.x - 汎用フレームワーク - - [Svelte](https://svelte.dev/): v5.x。後方互換性を優先しているが、Runes が利用できるように破壊的な変更が含まれる箇所を段階的に移行予定 + - [Svelte](https://svelte.dev/): v5.x。Runes mode で運用中 - [SvelteKit](https://svelte.dev/): v2.x - UIライブラリ - - [Flowbite Svelte](https://flowbite-svelte.com/) + - [Svelte 5 UI lib](https://svelte-5-ui-lib.codewithshin.com/) - Svelte v5.xにおける[Flowbite Svelte](https://flowbite-svelte.com/)の代替ライブラリ。一部の属性名・値などが変更されていることに注意が必要 + - コンポーネントが未実装である場合は、主に[Flowbite](https://flowbite.com/)を暫定的に利用する + - [Embla Carousel](https://github.com/davidjerleke/embla-carousel) - Svelte 5 UI lib ではカルーセルコンポーネントが未実装(2025年2月時点)なため、暫定的に導入している + - Tailwind v4 に未対応(2025年2月時点)のため、[Skeleton](https://github.com/skeletonlabs/skeleton)などへ移行する可能性もある - [STWUI](https://stwui.vercel.app/): 開発が事実上終了した可能性が高いため、使用しているコンポーネントを調べて別のライブラリに移行する + - [Lucide](https://github.com/lucide-icons/lucide) - アイコンライブラリ - テスティングフレームワーク - [Vitest](https://vitest.dev/): 単体テスト (ユーティリティ、コンポーネント) - [Playwright](https://playwright.dev/): e2eテスト @@ -120,18 +124,17 @@ `docker compose exec web pnpm exec playwright install-deps` - `docker compose exec -e DATABASE_URL=postgresql://db_user:db_password@db:5432/test_db web pnpm prisma db push` + `docker compose exec -e DATABASE_URL=postgresql://db_user:db_password@db:5432/test_db?pgbouncer=true&connection_limit=10&connect_timeout=60&statement_timeout=60000 -e DIRECT_URL=postgresql://db_user:db_password@db:5432/test_db web pnpm prisma db push` `docker compose exec web pnpm prisma generate` -- 開発サーバ(port番号: 5173)を起動します。その後、以下のリンクを順番にクリックしてください。 +- 開発サーバ(port番号: 5174)を起動します。その後、以下のリンクを順番にクリックしてください。 - Note: リンクのアドレス・ポート番号は、環境によって変わる可能性もあります。 `docker compose exec web pnpm dev --host` - http://172.18.0.3:5173 - http://127.0.0.1:5173/ + [http://localhost:5174/](http://localhost:5174/) - ホーム画面が起動し、ユーザの登録・ログインができれば、環境構築は完了です。 @@ -166,11 +169,11 @@ - 以下のリンクをクリックしてください。 - + - また、開発サーバの起動と同時に新しいブラウザタブでアプリを開くこともできます。 - `pnpm dev -- --open` + `pnpm dev --open` - 先ほどとは異なるターミナルで以下のコマンドをそれぞれ実行すると、データベースの初期データ投入やローカル環境でのテーブル・サンプルデータが閲覧できます。 @@ -268,6 +271,17 @@ ### トラブルシューティング +- エラー: ローカル環境で開発用サーバを立ち上げても、ブラウザに表示されない + + - 前提条件: Docker Desktop 4.30.0 以上、かつ、VSCode DevContainer で Vite を動かす場合。Windows、macOS で発生する + - 原因: Dockerで、ホストが IPv4 のみを使用している場合でも、`::1` を返すようになったため + - 対処方法: `vite.config` に、server の host を追記する + - 参考資料 + - [Docker の Issues](https://github.com/docker/for-mac/issues/7276) + - [Vite の Issues](https://github.com/vitejs/vite/issues/16522#issuecomment-2432846922) + - [Zenn の記事](https://zenn.dev/onozaty/articles/docker-desktop-portforward-not-working) + - [本プロジェクトでの対処状況](https://github.com/AtCoder-NoviSteps/AtCoderNoviSteps/issues/814#issuecomment-2131173142) + - エラー: Docker Desktop で Vite を利用したときに Segmentation Fault が発生 - 対処方法: Docker Desktopで「Use Visualization Framework」のチェックを外す diff --git a/package.json b/package.json index 108776b70..5fae51d6c 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,6 @@ "eslint": "9.20.0", "eslint-config-prettier": "10.0.1", "eslint-plugin-svelte": "2.46.1", - "flowbite-svelte": "0.47.4", - "flowbite-svelte-icons": "2.0.2", "globals": "15.14.0", "husky": "9.1.7", "jsdom": "26.0.0", @@ -62,6 +60,7 @@ "stwui": "0.21.2-next", "super-sitemap": "1.0.3", "svelte": "5.19.9", + "svelte-5-ui-lib": "0.12.2", "svelte-check": "4.1.4", "svelte-meta-tags": "4.1.0", "sveltekit-superforms": "2.23.1", @@ -82,8 +81,11 @@ "@types/node": "22.13.1", "autoprefixer": "10.4.20", "debug": "4.4.0", + "embla-carousel-autoplay": "8.5.2", + "embla-carousel-svelte": "8.5.2", "flowbite": "2.5.2", "lucia": "2.7.7", + "lucide-svelte": "^0.475.0", "playwright": "1.50.1", "pnpm": "10.2.1", "prisma-erd-generator": "2.0.4", @@ -93,5 +95,5 @@ "vercel": "41.0.3", "xss": "1.0.15" }, - "packageManager": "pnpm@9.15.2" + "packageManager": "pnpm@10.2.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1367dabfc..6e0de5a3e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,12 +35,21 @@ importers: debug: specifier: 4.4.0 version: 4.4.0 + embla-carousel-autoplay: + specifier: 8.5.2 + version: 8.5.2(embla-carousel@8.5.2) + embla-carousel-svelte: + specifier: 8.5.2 + version: 8.5.2(svelte@5.19.9) flowbite: specifier: 2.5.2 version: 2.5.2(rollup@4.34.6) lucia: specifier: 2.7.7 version: 2.7.7 + lucide-svelte: + specifier: ^0.475.0 + version: 0.475.0(svelte@5.19.9) playwright: specifier: 1.50.1 version: 1.50.1 @@ -120,12 +129,6 @@ importers: eslint-plugin-svelte: specifier: 2.46.1 version: 2.46.1(eslint@9.20.0(jiti@1.21.6))(svelte@5.19.9)(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3)) - flowbite-svelte: - specifier: 0.47.4 - version: 0.47.4(rollup@4.34.6)(svelte@5.19.9) - flowbite-svelte-icons: - specifier: 2.0.2 - version: 2.0.2(svelte@5.19.9)(tailwind-merge@2.6.0)(tailwindcss@3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3))) globals: specifier: 15.14.0 version: 15.14.0 @@ -162,6 +165,9 @@ importers: svelte: specifier: 5.19.9 version: 5.19.9 + svelte-5-ui-lib: + specifier: 0.12.2 + version: 0.12.2(svelte@5.19.9)(tailwindcss@3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3))) svelte-check: specifier: 4.1.4 version: 4.1.4(picomatch@4.0.2)(svelte@5.19.9)(typescript@5.6.3) @@ -1769,8 +1775,8 @@ packages: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} - caniuse-lite@1.0.30001649: - resolution: {integrity: sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==} + caniuse-lite@1.0.30001699: + resolution: {integrity: sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==} chai@5.1.2: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} @@ -2251,6 +2257,24 @@ packages: electron-to-chromium@1.5.4: resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==} + embla-carousel-autoplay@8.5.2: + resolution: {integrity: sha512-27emJ0px3q/c0kCHCjwRrEbYcyYUPfGO3g5IBWF1i7714TTzE6L9P81V6PHLoSMAKJ1aHoT2e7YFOsuFKCbyag==} + peerDependencies: + embla-carousel: 8.5.2 + + embla-carousel-reactive-utils@8.5.2: + resolution: {integrity: sha512-QC8/hYSK/pEmqEdU1IO5O+XNc/Ptmmq7uCB44vKplgLKhB/l0+yvYx0+Cv0sF6Ena8Srld5vUErZkT+yTahtDg==} + peerDependencies: + embla-carousel: 8.5.2 + + embla-carousel-svelte@8.5.2: + resolution: {integrity: sha512-tuzX8df2cMBwBtxJtIGPzUbLFBv0ujT4iOx1wMferFfztE7ebbHoYXrE9/JRjjp8ld+Wsc35yR8fWkuSaSxgpQ==} + peerDependencies: + svelte: ^3.49.0 || ^4.0.0 || ^5.0.0 + + embla-carousel@8.5.2: + resolution: {integrity: sha512-xQ9oVLrun/eCG/7ru3R+I5bJ7shsD8fFwLEY7yPe27/+fDHCNj0OT5EoG5ZbFyOxOcG6yTwW8oTz/dWyFnyGpg==} + emoji-regex@10.4.0: resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} @@ -2644,19 +2668,6 @@ packages: flowbite-datepicker@1.3.0: resolution: {integrity: sha512-CLVqzuoE2vkUvWYK/lJ6GzT0be5dlTbH3uuhVwyB67+PjqJWABm2wv68xhBf5BqjpBxvTSQ3mrmLHpPJ2tvrSQ==} - flowbite-svelte-icons@2.0.2: - resolution: {integrity: sha512-Vkmduy2867Rk8R7TziPirsWkixJnToFBEXRaN4ouJabOx62NQjiBbHFe+HTaMOQmdp4FNMI2Nhtk2I2CQ8r3RQ==} - engines: {node: '>=18.0.0', npm: '>=7.0.0'} - peerDependencies: - svelte: ^5.0.0 - tailwind-merge: ^2.3.0 - tailwindcss: ^3.4.3 - - flowbite-svelte@0.47.4: - resolution: {integrity: sha512-8oiY/oeWA7fgkDF91MZKEBo5VmjL8El3wuqTDWAFO1j7p45BHIL6G1VGnnidgCEYlbADDQN9BIGCvyPq4J3g+w==} - peerDependencies: - svelte: ^3.55.1 || ^4.0.0 || ^5.0.0 - flowbite@2.5.2: resolution: {integrity: sha512-kwFD3n8/YW4EG8GlY3Od9IoKND97kitO+/ejISHSqpn3vw2i5K/+ZI8Jm2V+KC4fGdnfi0XZ+TzYqQb4Q1LshA==} @@ -3134,6 +3145,11 @@ packages: lucia@2.7.7: resolution: {integrity: sha512-Hy1nMcLquLl3yDvV9zYA9fSBGUDy/Fw2zEUw2Ia4iGdk/O+hI/TvQ1tAfED/U1WE/c5DT1hEger3m7qIx1qbUg==} + lucide-svelte@0.475.0: + resolution: {integrity: sha512-N5+hFTPHaZe9HhqJDxxxODfYuOmI6v+JIowzERcea/uxytN/JZlehVTcINBNp8wMo7l6ov1Jf5srrDbkI/WsJg==} + peerDependencies: + svelte: ^3 || ^4 || ^5.0.0-next.42 + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -4080,6 +4096,12 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svelte-5-ui-lib@0.12.2: + resolution: {integrity: sha512-94eOQx8891haCCTot+jjEeMLIANvAKpwFl0eS8AWXn/bVpFHtEWvcVgvB7WM+l2El4zDphUGiHEyReQHPdV4mA==} + peerDependencies: + svelte: ^5.0.0 + tailwindcss: ^3.0.0 + svelte-check@4.1.4: resolution: {integrity: sha512-v0j7yLbT29MezzaQJPEDwksybTE2Ups9rUxEXy92T06TiA0cbqcO8wAOwNUVkFW6B0hsYHA+oAX3BS8b/2oHtw==} engines: {node: '>= 18.0.0'} @@ -4150,9 +4172,18 @@ packages: resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} engines: {node: '>=8.0.0'} + tailwind-merge@2.5.4: + resolution: {integrity: sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==} + tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} + tailwind-variants@0.3.1: + resolution: {integrity: sha512-krn67M3FpPwElg4FsZrOQd0U26o7UDH/QOkK8RNaiCCrr052f6YJPBUfNKnPo/s/xRzNPtv1Mldlxsg8Tb46BQ==} + engines: {node: '>=16.x', pnpm: '>=7.x'} + peerDependencies: + tailwindcss: '*' + tailwindcss@3.4.17: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} @@ -5055,7 +5086,7 @@ snapshots: '@floating-ui/dom@1.6.13': dependencies: - '@floating-ui/core': 1.6.2 + '@floating-ui/core': 1.6.9 '@floating-ui/utils': 0.2.9 '@floating-ui/dom@1.6.5': @@ -6342,7 +6373,7 @@ snapshots: autoprefixer@10.4.20(postcss@8.4.49): dependencies: browserslist: 4.23.3 - caniuse-lite: 1.0.30001649 + caniuse-lite: 1.0.30001699 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.1 @@ -6382,7 +6413,7 @@ snapshots: browserslist@4.23.3: dependencies: - caniuse-lite: 1.0.30001649 + caniuse-lite: 1.0.30001699 electron-to-chromium: 1.5.4 node-releases: 2.0.18 update-browserslist-db: 1.1.0(browserslist@4.23.3) @@ -6415,7 +6446,7 @@ snapshots: camelcase@8.0.0: optional: true - caniuse-lite@1.0.30001649: {} + caniuse-lite@1.0.30001699: {} chai@5.1.2: dependencies: @@ -6899,6 +6930,22 @@ snapshots: electron-to-chromium@1.5.4: {} + embla-carousel-autoplay@8.5.2(embla-carousel@8.5.2): + dependencies: + embla-carousel: 8.5.2 + + embla-carousel-reactive-utils@8.5.2(embla-carousel@8.5.2): + dependencies: + embla-carousel: 8.5.2 + + embla-carousel-svelte@8.5.2(svelte@5.19.9): + dependencies: + embla-carousel: 8.5.2 + embla-carousel-reactive-utils: 8.5.2(embla-carousel@8.5.2) + svelte: 5.19.9 + + embla-carousel@8.5.2: {} + emoji-regex@10.4.0: {} emoji-regex@8.0.0: {} @@ -7327,22 +7374,6 @@ snapshots: transitivePeerDependencies: - rollup - flowbite-svelte-icons@2.0.2(svelte@5.19.9)(tailwind-merge@2.6.0)(tailwindcss@3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3))): - dependencies: - svelte: 5.19.9 - tailwind-merge: 2.6.0 - tailwindcss: 3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3)) - - flowbite-svelte@0.47.4(rollup@4.34.6)(svelte@5.19.9): - dependencies: - '@floating-ui/dom': 1.6.13 - apexcharts: 3.54.1 - flowbite: 2.5.2(rollup@4.34.6) - svelte: 5.19.9 - tailwind-merge: 2.6.0 - transitivePeerDependencies: - - rollup - flowbite@2.5.2(rollup@4.34.6): dependencies: '@popperjs/core': 2.11.8 @@ -7851,6 +7882,10 @@ snapshots: lucia@2.7.7: {} + lucide-svelte@0.475.0(svelte@5.19.9): + dependencies: + svelte: 5.19.9 + lz-string@1.5.0: {} magic-string@0.30.17: @@ -8702,6 +8737,16 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svelte-5-ui-lib@0.12.2(svelte@5.19.9)(tailwindcss@3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3))): + dependencies: + '@floating-ui/dom': 1.6.13 + apexcharts: 3.54.1 + clsx: 2.1.1 + svelte: 5.19.9 + tailwind-merge: 2.6.0 + tailwind-variants: 0.3.1(tailwindcss@3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3))) + tailwindcss: 3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3)) + svelte-check@4.1.4(picomatch@4.0.2)(svelte@5.19.9)(typescript@5.6.3): dependencies: '@jridgewell/trace-mapping': 0.3.25 @@ -8815,8 +8860,15 @@ snapshots: typical: 5.2.0 wordwrapjs: 4.0.1 + tailwind-merge@2.5.4: {} + tailwind-merge@2.6.0: {} + tailwind-variants@0.3.1(tailwindcss@3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3))): + dependencies: + tailwind-merge: 2.5.4 + tailwindcss: 3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3)) + tailwindcss@3.4.17(ts-node@10.9.1(@types/node@22.13.1)(typescript@5.6.3)): dependencies: '@alloc/quick-lru': 5.2.0 diff --git a/src/lib/components/AtCoderUserValidationForm.svelte b/src/lib/components/AtCoderUserValidationForm.svelte index 1482bb8e4..e8899df1f 100644 --- a/src/lib/components/AtCoderUserValidationForm.svelte +++ b/src/lib/components/AtCoderUserValidationForm.svelte @@ -1,30 +1,31 @@ - - +
@@ -92,15 +105,15 @@
-
+
@@ -110,16 +123,21 @@

(変更不可。3〜24文字で、半角英数字と_のみ)

+ - + {#snippet left()} + + {/snippet} @@ -143,21 +161,23 @@ bind:value={$form.password} disabled={$submitting || isSubmitting} required + class="ps-10" > - + {#snippet left()} + + {/snippet} diff --git a/src/lib/components/ContainerWrapper.svelte b/src/lib/components/ContainerWrapper.svelte index 007ac2137..58eef531a 100644 --- a/src/lib/components/ContainerWrapper.svelte +++ b/src/lib/components/ContainerWrapper.svelte @@ -1,7 +1,14 @@ -
- +
+ {@render children?.()}
diff --git a/src/lib/components/ExternalLinkIcon.svelte b/src/lib/components/ExternalLinkIcon.svelte index 20c716011..40670a71f 100644 --- a/src/lib/components/ExternalLinkIcon.svelte +++ b/src/lib/components/ExternalLinkIcon.svelte @@ -1,5 +1,9 @@ diff --git a/src/lib/components/ExternalLinkWrapper.svelte b/src/lib/components/ExternalLinkWrapper.svelte index 2bbea4eb3..e48ddcf7b 100644 --- a/src/lib/components/ExternalLinkWrapper.svelte +++ b/src/lib/components/ExternalLinkWrapper.svelte @@ -1,12 +1,23 @@ - import { Footer, FooterCopyright } from 'flowbite-svelte'; + import { Footer, FooterCopyright } from 'svelte-5-ui-lib'; import { PRODUCT_TEAM_URL, PRODUCT_NAME } from '$lib/constants/product-info'; - -