diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8b2ea8a46f..ac876a1833 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -35,6 +35,9 @@ jobs:
- name: 📝 Prettier formatting
run: pnpm lint:formatting
+ - name: 📝 Generate CSS types
+ run: pnpm test:generatecsstypes
+
- name: 💪 Type check
run: pnpm test:typecheck
diff --git a/.gitignore b/.gitignore
index e4512323a2..51a071534f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,5 @@ fly.toml
/playwright-report/
/blob-report/
/playwright/.cache/
+
+*.css.d.ts
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 4e0f7f6a27..fc984f7336 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -2,7 +2,6 @@
"recommendations": [
"ionic.ionic",
"esbenp.prettier-vscode",
- "styled-components.vscode-styled-components", // TODO remove
"github.vscode-github-actions",
"clinyong.vscode-css-modules"
]
diff --git a/package.json b/package.json
index f9c2c43552..bbdc3192a0 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"preview": "vite preview",
"test": "vitest",
"test:e2e": "playwright test",
+ "test:generatecsstypes": "tcm src",
"test:typecheck": "tsc",
"lint": "eslint src --max-warnings=0",
"lint:formatting": "prettier --check .",
@@ -148,6 +149,7 @@
"prettier": "^3.3.3",
"pwa-asset-generator": "^6.4.0",
"release-it": "^17.10.0",
+ "typed-css-modules": "^0.9.1",
"typescript": "^5.6.3",
"typescript-eslint": "^8.14.0",
"vite": "^5.4.11",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index af1d8136d7..7f207ab636 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -314,6 +314,9 @@ importers:
release-it:
specifier: ^17.10.0
version: 17.10.0(typescript@5.6.3)
+ typed-css-modules:
+ specifier: ^0.9.1
+ version: 0.9.1
typescript:
specifier: ^5.6.3
version: 5.6.3
@@ -2052,6 +2055,10 @@ packages:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@@ -2170,6 +2177,10 @@ packages:
resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==}
engines: {node: '>=0.6'}
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
@@ -2350,6 +2361,10 @@ packages:
chevrotain@7.1.1:
resolution: {integrity: sha512-wy3mC1x4ye+O+QkEinVJkPf5u2vsrDIYW9G7ZuwFl6v/Yu0LwUuT2POsb+NUWApebyxfkQq6+yDfRExbnI5rcw==}
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
chokidar@4.0.1:
resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==}
engines: {node: '>= 14.16.0'}
@@ -3510,6 +3525,9 @@ packages:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
+ icss-replace-symbols@1.1.0:
+ resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==}
+
icss-utils@5.1.0:
resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
engines: {node: ^10 || ^12 || >= 14}
@@ -3617,6 +3635,10 @@ packages:
is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
is-boolean-object@1.1.2:
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
engines: {node: '>= 0.4'}
@@ -3798,6 +3820,9 @@ packages:
resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==}
engines: {node: '>=0.10.0'}
+ is-there@4.5.1:
+ resolution: {integrity: sha512-vIZ7HTXAoRoIwYSsTnxb0sg9L6rth+JOulNcavsbskQkCIWoSM2cjFOWZs4wGziGZER+Xgs/HXiCQZgiL8ppxQ==}
+
is-typed-array@1.1.13:
resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
engines: {node: '>= 0.4'}
@@ -4473,6 +4498,11 @@ packages:
engines: {node: '>=10'}
hasBin: true
+ mkdirp@3.0.1:
+ resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==}
+ engines: {node: '>=10'}
+ hasBin: true
+
modern-screenshot@4.5.4:
resolution: {integrity: sha512-4O9hT31e2XqAga5tIuNe8YemB8SnjHYClD1lHu0DqgiZ4Mld6Hf4t3Oz+3RnxQm+95cMatFsmJRI1IIMub13ww==}
@@ -4558,6 +4588,10 @@ packages:
resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==}
engines: {node: '>=10'}
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
npm-run-path@4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
@@ -5087,6 +5121,10 @@ packages:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
readdirp@4.0.2:
resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==}
engines: {node: '>= 14.16.0'}
@@ -5791,6 +5829,11 @@ packages:
resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
engines: {node: '>= 0.4'}
+ typed-css-modules@0.9.1:
+ resolution: {integrity: sha512-W2HWKncdKd+bLWsnuWB2EyuQBzZ7KJ9Byr/67KLiiyGegcN52rOveun9JR8yAvuL5IXunRMxt0eORMtAUj5bmA==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
typedarray-to-buffer@3.1.5:
resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
@@ -8471,6 +8514,11 @@ snapshots:
ansi-styles@6.2.1: {}
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
arg@4.1.3: {}
argparse@2.0.1: {}
@@ -8606,6 +8654,8 @@ snapshots:
big-integer@1.6.52: {}
+ binary-extensions@2.3.0: {}
+
bl@4.1.0:
dependencies:
buffer: 5.7.1
@@ -8795,6 +8845,18 @@ snapshots:
dependencies:
regexp-to-ast: 0.5.0
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
chokidar@4.0.1:
dependencies:
readdirp: 4.0.2
@@ -10217,6 +10279,8 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
+ icss-replace-symbols@1.1.0: {}
+
icss-utils@5.1.0(postcss@8.4.49):
dependencies:
postcss: 8.4.49
@@ -10331,6 +10395,10 @@ snapshots:
dependencies:
has-bigints: 1.0.2
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
is-boolean-object@1.1.2:
dependencies:
call-bind: 1.0.7
@@ -10458,6 +10526,8 @@ snapshots:
dependencies:
text-extensions: 1.9.0
+ is-there@4.5.1: {}
+
is-typed-array@1.1.13:
dependencies:
which-typed-array: 1.1.15
@@ -11304,6 +11374,8 @@ snapshots:
mkdirp@1.0.4: {}
+ mkdirp@3.0.1: {}
+
modern-screenshot@4.5.4: {}
modify-values@1.0.1: {}
@@ -11386,6 +11458,8 @@ snapshots:
semver: 7.6.3
validate-npm-package-license: 3.0.4
+ normalize-path@3.0.0: {}
+
npm-run-path@4.0.1:
dependencies:
path-key: 3.1.1
@@ -11992,6 +12066,10 @@ snapshots:
string_decoder: 1.3.0
util-deprecate: 1.0.2
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.1
+
readdirp@4.0.2:
optional: true
@@ -12797,6 +12875,22 @@ snapshots:
is-typed-array: 1.1.13
possible-typed-array-names: 1.0.0
+ typed-css-modules@0.9.1:
+ dependencies:
+ camelcase: 6.3.0
+ chalk: 4.1.2
+ chokidar: 3.6.0
+ glob: 10.4.5
+ icss-replace-symbols: 1.1.0
+ is-there: 4.5.1
+ mkdirp: 3.0.1
+ postcss: 8.4.49
+ postcss-modules-extract-imports: 3.1.0(postcss@8.4.49)
+ postcss-modules-local-by-default: 4.1.0(postcss@8.4.49)
+ postcss-modules-scope: 3.2.1(postcss@8.4.49)
+ postcss-modules-values: 4.0.0(postcss@8.4.49)
+ yargs: 17.7.2
+
typedarray-to-buffer@3.1.5:
dependencies:
is-typedarray: 1.0.0
diff --git a/src/features/inbox/InboxItem.tsx b/src/features/inbox/InboxItem.tsx
index 56169224d3..08c78d6a7d 100644
--- a/src/features/inbox/InboxItem.tsx
+++ b/src/features/inbox/InboxItem.tsx
@@ -200,7 +200,7 @@ export default function InboxItem({ item }: InboxItemProps) {