From e3f94ff3d94bd2097916966bdfaf6e0fc19ca1fa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 00:02:01 +0000 Subject: [PATCH 01/48] fix(deps): update all non-major dependencies --- .github/actions/metrics-report/package.json | 4 +- .github/actions/metrics-report/yarn.lock | 534 ++++++++++---------- package.json | 12 +- yarn.lock | 285 ++++++++--- 4 files changed, 482 insertions(+), 353 deletions(-) diff --git a/.github/actions/metrics-report/package.json b/.github/actions/metrics-report/package.json index dc700ace..3a115711 100644 --- a/.github/actions/metrics-report/package.json +++ b/.github/actions/metrics-report/package.json @@ -11,7 +11,7 @@ "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", "@octokit/types": "^13.6.2", - "esbuild": "^0.24.0", - "rollup": "^4.28.1" + "esbuild": "^0.24.2", + "rollup": "^4.29.1" } } diff --git a/.github/actions/metrics-report/yarn.lock b/.github/actions/metrics-report/yarn.lock index 8870302a..2a42c9af 100644 --- a/.github/actions/metrics-report/yarn.lock +++ b/.github/actions/metrics-report/yarn.lock @@ -40,125 +40,130 @@ resolved "https://registry.yarnpkg.com/@actions/io/-/io-1.1.3.tgz#4cdb6254da7962b07473ff5c335f3da485d94d71" integrity sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q== -"@esbuild/aix-ppc64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" - integrity sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw== - -"@esbuild/android-arm64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" - integrity sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w== - -"@esbuild/android-arm@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" - integrity sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew== - -"@esbuild/android-x64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" - integrity sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ== - -"@esbuild/darwin-arm64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz#2d0d9414f2acbffd2d86e98253914fca603a53dd" - integrity sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw== - -"@esbuild/darwin-x64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" - integrity sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA== - -"@esbuild/freebsd-arm64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" - integrity sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA== - -"@esbuild/freebsd-x64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" - integrity sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ== - -"@esbuild/linux-arm64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" - integrity sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g== - -"@esbuild/linux-arm@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" - integrity sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw== - -"@esbuild/linux-ia32@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" - integrity sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA== - -"@esbuild/linux-loong64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" - integrity sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g== - -"@esbuild/linux-mips64el@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" - integrity sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA== - -"@esbuild/linux-ppc64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" - integrity sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ== - -"@esbuild/linux-riscv64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" - integrity sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw== - -"@esbuild/linux-s390x@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" - integrity sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g== - -"@esbuild/linux-x64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" - integrity sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA== - -"@esbuild/netbsd-x64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" - integrity sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg== - -"@esbuild/openbsd-arm64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz#5d904a4f5158c89859fd902c427f96d6a9e632e2" - integrity sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg== - -"@esbuild/openbsd-x64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" - integrity sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q== - -"@esbuild/sunos-x64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" - integrity sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA== - -"@esbuild/win32-arm64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" - integrity sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA== - -"@esbuild/win32-ia32@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" - integrity sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw== - -"@esbuild/win32-x64@0.24.0": - version "0.24.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" - integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== +"@esbuild/aix-ppc64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz#38848d3e25afe842a7943643cbcd387cc6e13461" + integrity sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA== + +"@esbuild/android-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz#f592957ae8b5643129fa889c79e69cd8669bb894" + integrity sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg== + +"@esbuild/android-arm@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz#72d8a2063aa630308af486a7e5cbcd1e134335b3" + integrity sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q== + +"@esbuild/android-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz#9a7713504d5f04792f33be9c197a882b2d88febb" + integrity sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw== + +"@esbuild/darwin-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz#02ae04ad8ebffd6e2ea096181b3366816b2b5936" + integrity sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA== + +"@esbuild/darwin-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz#9ec312bc29c60e1b6cecadc82bd504d8adaa19e9" + integrity sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA== + +"@esbuild/freebsd-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz#5e82f44cb4906d6aebf24497d6a068cfc152fa00" + integrity sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg== + +"@esbuild/freebsd-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz#3fb1ce92f276168b75074b4e51aa0d8141ecce7f" + integrity sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q== + +"@esbuild/linux-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz#856b632d79eb80aec0864381efd29de8fd0b1f43" + integrity sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg== + +"@esbuild/linux-arm@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz#c846b4694dc5a75d1444f52257ccc5659021b736" + integrity sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA== + +"@esbuild/linux-ia32@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz#f8a16615a78826ccbb6566fab9a9606cfd4a37d5" + integrity sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw== + +"@esbuild/linux-loong64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz#1c451538c765bf14913512c76ed8a351e18b09fc" + integrity sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ== + +"@esbuild/linux-mips64el@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz#0846edeefbc3d8d50645c51869cc64401d9239cb" + integrity sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw== + +"@esbuild/linux-ppc64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz#8e3fc54505671d193337a36dfd4c1a23b8a41412" + integrity sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw== + +"@esbuild/linux-riscv64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz#6a1e92096d5e68f7bb10a0d64bb5b6d1daf9a694" + integrity sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q== + +"@esbuild/linux-s390x@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz#ab18e56e66f7a3c49cb97d337cd0a6fea28a8577" + integrity sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw== + +"@esbuild/linux-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz#8140c9b40da634d380b0b29c837a0b4267aff38f" + integrity sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q== + +"@esbuild/netbsd-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz#65f19161432bafb3981f5f20a7ff45abb2e708e6" + integrity sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw== + +"@esbuild/netbsd-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz#7a3a97d77abfd11765a72f1c6f9b18f5396bcc40" + integrity sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw== + +"@esbuild/openbsd-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz#58b00238dd8f123bfff68d3acc53a6ee369af89f" + integrity sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A== + +"@esbuild/openbsd-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz#0ac843fda0feb85a93e288842936c21a00a8a205" + integrity sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA== + +"@esbuild/sunos-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz#8b7aa895e07828d36c422a4404cc2ecf27fb15c6" + integrity sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig== + +"@esbuild/win32-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz#c023afb647cabf0c3ed13f0eddfc4f1d61c66a85" + integrity sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ== + +"@esbuild/win32-ia32@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz#96c356132d2dda990098c8b8b951209c3cd743c2" + integrity sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA== + +"@esbuild/win32-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz#34aa0b52d0fbb1a654b596acfa595f0c7b77a77b" + integrity sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg== "@fastify/busboy@^2.0.0": version "2.1.1" @@ -264,100 +269,100 @@ dependencies: "@octokit/openapi-types" "^22.2.0" -"@rollup/rollup-android-arm-eabi@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz#7f4c4d8cd5ccab6e95d6750dbe00321c1f30791e" - integrity sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ== - -"@rollup/rollup-android-arm64@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz#17ea71695fb1518c2c324badbe431a0bd1879f2d" - integrity sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA== - -"@rollup/rollup-darwin-arm64@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz#dac0f0d0cfa73e7d5225ae6d303c13c8979e7999" - integrity sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ== - -"@rollup/rollup-darwin-x64@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz#8f63baa1d31784904a380d2e293fa1ddf53dd4a2" - integrity sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ== - -"@rollup/rollup-freebsd-arm64@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz#30ed247e0df6e8858cdc6ae4090e12dbeb8ce946" - integrity sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA== - -"@rollup/rollup-freebsd-x64@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz#57846f382fddbb508412ae07855b8a04c8f56282" - integrity sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ== - -"@rollup/rollup-linux-arm-gnueabihf@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz#378ca666c9dae5e6f94d1d351e7497c176e9b6df" - integrity sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA== - -"@rollup/rollup-linux-arm-musleabihf@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz#a692eff3bab330d5c33a5d5813a090c15374cddb" - integrity sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg== - -"@rollup/rollup-linux-arm64-gnu@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz#6b1719b76088da5ac1ae1feccf48c5926b9e3db9" - integrity sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA== - -"@rollup/rollup-linux-arm64-musl@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz#865baf5b6f5ff67acb32e5a359508828e8dc5788" - integrity sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A== - -"@rollup/rollup-linux-loongarch64-gnu@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz#23c6609ba0f7fa7a7f2038b6b6a08555a5055a87" - integrity sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA== - -"@rollup/rollup-linux-powerpc64le-gnu@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz#652ef0d9334a9f25b9daf85731242801cb0fc41c" - integrity sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A== - -"@rollup/rollup-linux-riscv64-gnu@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz#1eb6651839ee6ebca64d6cc64febbd299e95e6bd" - integrity sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA== - -"@rollup/rollup-linux-s390x-gnu@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz#015c52293afb3ff2a293cf0936b1d43975c1e9cd" - integrity sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg== - -"@rollup/rollup-linux-x64-gnu@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz#b83001b5abed2bcb5e2dbeec6a7e69b194235c1e" - integrity sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw== - -"@rollup/rollup-linux-x64-musl@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz#6cc7c84cd4563737f8593e66f33b57d8e228805b" - integrity sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g== - -"@rollup/rollup-win32-arm64-msvc@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz#631ffeee094d71279fcd1fe8072bdcf25311bc11" - integrity sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A== - -"@rollup/rollup-win32-ia32-msvc@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz#06d1d60d5b9f718e8a6c4a43f82e3f9e3254587f" - integrity sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA== - -"@rollup/rollup-win32-x64-msvc@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz#4dff5c4259ebe6c5b4a8f2c5bc3829b7a8447ff0" - integrity sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA== +"@rollup/rollup-android-arm-eabi@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz#9bd38df6a29afb7f0336d988bc8112af0c8816c0" + integrity sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw== + +"@rollup/rollup-android-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz#bd1a98390e15b76eeef907175a37c5f0f9e4d214" + integrity sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew== + +"@rollup/rollup-darwin-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz#bc6fa8a2cc77b5f367424e5e994e3537524e6879" + integrity sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw== + +"@rollup/rollup-darwin-x64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz#76059c91f06b17406347b127df10f065283b2e61" + integrity sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng== + +"@rollup/rollup-freebsd-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz#83178315c0be4b4c8c1fd835e1952d2dc1eb4e6e" + integrity sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw== + +"@rollup/rollup-freebsd-x64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz#1ef24fa0576bf7899a0a0a649156606dbd7a0d46" + integrity sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w== + +"@rollup/rollup-linux-arm-gnueabihf@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz#443a6f5681bf4611caae42988994a6d8ee676216" + integrity sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A== + +"@rollup/rollup-linux-arm-musleabihf@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz#9738b27184102228637a683e5f35b22ea352394f" + integrity sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ== + +"@rollup/rollup-linux-arm64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz#b5e9d5e30ff36a19bedd29c715ba18a1889ff269" + integrity sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA== + +"@rollup/rollup-linux-arm64-musl@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz#1d8f68f0829b57f746ec03432ad046f1af014a98" + integrity sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA== + +"@rollup/rollup-linux-loongarch64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz#07027feb883408e74a3002c8e50caaedd288ae38" + integrity sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw== + +"@rollup/rollup-linux-powerpc64le-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz#544ce1b0847a9c1240425e86f33daceac7ec4e12" + integrity sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w== + +"@rollup/rollup-linux-riscv64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz#64be13d51852ec1e2dfbd25d997ed5f42f35ea6d" + integrity sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ== + +"@rollup/rollup-linux-s390x-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz#31f51e1e05c6264552d03875d9e2e673f0fd86e3" + integrity sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g== + +"@rollup/rollup-linux-x64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz#f4c95b26f4ad69ebdb64b42f0ae4da2a0f617958" + integrity sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ== + +"@rollup/rollup-linux-x64-musl@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz#ab7be89192f72beb9ea6e2386186fefde4f69d82" + integrity sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA== + +"@rollup/rollup-win32-arm64-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz#7f12efb8240b238346951559998802722944421e" + integrity sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig== + +"@rollup/rollup-win32-ia32-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz#353d14d6eee943004d129796e4feddd3aa260921" + integrity sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng== + +"@rollup/rollup-win32-x64-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz#c82f04a09ba481e13857d6f2516e072aaa51b7f4" + integrity sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg== "@types/estree@1.0.6": version "1.0.6" @@ -374,35 +379,36 @@ deprecation@^2.0.0: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -esbuild@^0.24.0: - version "0.24.0" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.0.tgz#f2d470596885fcb2e91c21eb3da3b3c89c0b55e7" - integrity sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ== +esbuild@^0.24.2: + version "0.24.2" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.2.tgz#b5b55bee7de017bff5fb8a4e3e44f2ebe2c3567d" + integrity sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA== optionalDependencies: - "@esbuild/aix-ppc64" "0.24.0" - "@esbuild/android-arm" "0.24.0" - "@esbuild/android-arm64" "0.24.0" - "@esbuild/android-x64" "0.24.0" - "@esbuild/darwin-arm64" "0.24.0" - "@esbuild/darwin-x64" "0.24.0" - "@esbuild/freebsd-arm64" "0.24.0" - "@esbuild/freebsd-x64" "0.24.0" - "@esbuild/linux-arm" "0.24.0" - "@esbuild/linux-arm64" "0.24.0" - "@esbuild/linux-ia32" "0.24.0" - "@esbuild/linux-loong64" "0.24.0" - "@esbuild/linux-mips64el" "0.24.0" - "@esbuild/linux-ppc64" "0.24.0" - "@esbuild/linux-riscv64" "0.24.0" - "@esbuild/linux-s390x" "0.24.0" - "@esbuild/linux-x64" "0.24.0" - "@esbuild/netbsd-x64" "0.24.0" - "@esbuild/openbsd-arm64" "0.24.0" - "@esbuild/openbsd-x64" "0.24.0" - "@esbuild/sunos-x64" "0.24.0" - "@esbuild/win32-arm64" "0.24.0" - "@esbuild/win32-ia32" "0.24.0" - "@esbuild/win32-x64" "0.24.0" + "@esbuild/aix-ppc64" "0.24.2" + "@esbuild/android-arm" "0.24.2" + "@esbuild/android-arm64" "0.24.2" + "@esbuild/android-x64" "0.24.2" + "@esbuild/darwin-arm64" "0.24.2" + "@esbuild/darwin-x64" "0.24.2" + "@esbuild/freebsd-arm64" "0.24.2" + "@esbuild/freebsd-x64" "0.24.2" + "@esbuild/linux-arm" "0.24.2" + "@esbuild/linux-arm64" "0.24.2" + "@esbuild/linux-ia32" "0.24.2" + "@esbuild/linux-loong64" "0.24.2" + "@esbuild/linux-mips64el" "0.24.2" + "@esbuild/linux-ppc64" "0.24.2" + "@esbuild/linux-riscv64" "0.24.2" + "@esbuild/linux-s390x" "0.24.2" + "@esbuild/linux-x64" "0.24.2" + "@esbuild/netbsd-arm64" "0.24.2" + "@esbuild/netbsd-x64" "0.24.2" + "@esbuild/openbsd-arm64" "0.24.2" + "@esbuild/openbsd-x64" "0.24.2" + "@esbuild/sunos-x64" "0.24.2" + "@esbuild/win32-arm64" "0.24.2" + "@esbuild/win32-ia32" "0.24.2" + "@esbuild/win32-x64" "0.24.2" fsevents@~2.3.2: version "2.3.3" @@ -416,32 +422,32 @@ once@^1.4.0: dependencies: wrappy "1" -rollup@^4.28.1: - version "4.28.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.28.1.tgz#7718ba34d62b449dfc49adbfd2f312b4fe0df4de" - integrity sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg== +rollup@^4.29.1: + version "4.29.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.29.1.tgz#a9aaaece817e5f778489e5bf82e379cc8a5c05bc" + integrity sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw== dependencies: "@types/estree" "1.0.6" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.28.1" - "@rollup/rollup-android-arm64" "4.28.1" - "@rollup/rollup-darwin-arm64" "4.28.1" - "@rollup/rollup-darwin-x64" "4.28.1" - "@rollup/rollup-freebsd-arm64" "4.28.1" - "@rollup/rollup-freebsd-x64" "4.28.1" - "@rollup/rollup-linux-arm-gnueabihf" "4.28.1" - "@rollup/rollup-linux-arm-musleabihf" "4.28.1" - "@rollup/rollup-linux-arm64-gnu" "4.28.1" - "@rollup/rollup-linux-arm64-musl" "4.28.1" - "@rollup/rollup-linux-loongarch64-gnu" "4.28.1" - "@rollup/rollup-linux-powerpc64le-gnu" "4.28.1" - "@rollup/rollup-linux-riscv64-gnu" "4.28.1" - "@rollup/rollup-linux-s390x-gnu" "4.28.1" - "@rollup/rollup-linux-x64-gnu" "4.28.1" - "@rollup/rollup-linux-x64-musl" "4.28.1" - "@rollup/rollup-win32-arm64-msvc" "4.28.1" - "@rollup/rollup-win32-ia32-msvc" "4.28.1" - "@rollup/rollup-win32-x64-msvc" "4.28.1" + "@rollup/rollup-android-arm-eabi" "4.29.1" + "@rollup/rollup-android-arm64" "4.29.1" + "@rollup/rollup-darwin-arm64" "4.29.1" + "@rollup/rollup-darwin-x64" "4.29.1" + "@rollup/rollup-freebsd-arm64" "4.29.1" + "@rollup/rollup-freebsd-x64" "4.29.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.29.1" + "@rollup/rollup-linux-arm-musleabihf" "4.29.1" + "@rollup/rollup-linux-arm64-gnu" "4.29.1" + "@rollup/rollup-linux-arm64-musl" "4.29.1" + "@rollup/rollup-linux-loongarch64-gnu" "4.29.1" + "@rollup/rollup-linux-powerpc64le-gnu" "4.29.1" + "@rollup/rollup-linux-riscv64-gnu" "4.29.1" + "@rollup/rollup-linux-s390x-gnu" "4.29.1" + "@rollup/rollup-linux-x64-gnu" "4.29.1" + "@rollup/rollup-linux-x64-musl" "4.29.1" + "@rollup/rollup-win32-arm64-msvc" "4.29.1" + "@rollup/rollup-win32-ia32-msvc" "4.29.1" + "@rollup/rollup-win32-x64-msvc" "4.29.1" fsevents "~2.3.2" tunnel@^0.0.6: diff --git a/package.json b/package.json index 58a356e6..597ea308 100644 --- a/package.json +++ b/package.json @@ -67,23 +67,23 @@ "@codspeed/vitest-plugin": "^4.0.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-node-resolve": "^16.0.0", - "@rollup/plugin-typescript": "^12.1.1", + "@rollup/plugin-typescript": "^12.1.2", "@vitest/coverage-v8": "^2.1.8", - "@vitest/eslint-plugin": "^1.1.14", + "@vitest/eslint-plugin": "^1.1.22", "babel-plugin-annotate-pure-calls": "^0.4.0", "babel-plugin-polyfill-regenerator": "^0.6.3", - "eslint": "^9.16.0", + "eslint": "^9.17.0", "eslint-plugin-import": "^2.31.0", "globby": "^11.1.0", "prettier": "^3.4.2", - "rollup": "^4.28.1", + "rollup": "^4.29.1", "rollup-plugin-delete": "^2.1.0", "rollup-plugin-dts": "^6.1.1", "tslib": "^2.8.1", "typescript": "^5.7.2", - "typescript-eslint": "^8.17.0", + "typescript-eslint": "^8.19.0", "vitest": "^2.1.8", - "zx": "^8.2.4" + "zx": "^8.3.0" }, "publishConfig": { "provenance": true diff --git a/yarn.lock b/yarn.lock index a3372a61..1806449a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -968,10 +968,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.16.0": - version "9.16.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.16.0.tgz#3df2b2dd3b9163056616886c86e4082f45dbf3f4" - integrity sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg== +"@eslint/js@9.17.0": + version "9.17.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.17.0.tgz#1523e586791f80376a6f8398a3964455ecc651ec" + integrity sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w== "@eslint/object-schema@^2.1.5": version "2.1.5" @@ -1107,10 +1107,10 @@ is-module "^1.0.0" resolve "^1.22.1" -"@rollup/plugin-typescript@^12.1.1": - version "12.1.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-12.1.1.tgz#008d16b8283a422650c463f99ae0c610cf6c9727" - integrity sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ== +"@rollup/plugin-typescript@^12.1.2": + version "12.1.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz#ebaeec2e7376faa889030ccd7cb485a649e63118" + integrity sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg== dependencies: "@rollup/pluginutils" "^5.1.0" resolve "^1.22.1" @@ -1129,96 +1129,191 @@ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz#7f4c4d8cd5ccab6e95d6750dbe00321c1f30791e" integrity sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ== +"@rollup/rollup-android-arm-eabi@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz#9bd38df6a29afb7f0336d988bc8112af0c8816c0" + integrity sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw== + "@rollup/rollup-android-arm64@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz#17ea71695fb1518c2c324badbe431a0bd1879f2d" integrity sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA== +"@rollup/rollup-android-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz#bd1a98390e15b76eeef907175a37c5f0f9e4d214" + integrity sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew== + "@rollup/rollup-darwin-arm64@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz#dac0f0d0cfa73e7d5225ae6d303c13c8979e7999" integrity sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ== +"@rollup/rollup-darwin-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz#bc6fa8a2cc77b5f367424e5e994e3537524e6879" + integrity sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw== + "@rollup/rollup-darwin-x64@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz#8f63baa1d31784904a380d2e293fa1ddf53dd4a2" integrity sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ== +"@rollup/rollup-darwin-x64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz#76059c91f06b17406347b127df10f065283b2e61" + integrity sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng== + "@rollup/rollup-freebsd-arm64@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz#30ed247e0df6e8858cdc6ae4090e12dbeb8ce946" integrity sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA== +"@rollup/rollup-freebsd-arm64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz#83178315c0be4b4c8c1fd835e1952d2dc1eb4e6e" + integrity sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw== + "@rollup/rollup-freebsd-x64@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz#57846f382fddbb508412ae07855b8a04c8f56282" integrity sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ== +"@rollup/rollup-freebsd-x64@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz#1ef24fa0576bf7899a0a0a649156606dbd7a0d46" + integrity sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w== + "@rollup/rollup-linux-arm-gnueabihf@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz#378ca666c9dae5e6f94d1d351e7497c176e9b6df" integrity sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA== +"@rollup/rollup-linux-arm-gnueabihf@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz#443a6f5681bf4611caae42988994a6d8ee676216" + integrity sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A== + "@rollup/rollup-linux-arm-musleabihf@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz#a692eff3bab330d5c33a5d5813a090c15374cddb" integrity sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg== +"@rollup/rollup-linux-arm-musleabihf@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz#9738b27184102228637a683e5f35b22ea352394f" + integrity sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ== + "@rollup/rollup-linux-arm64-gnu@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz#6b1719b76088da5ac1ae1feccf48c5926b9e3db9" integrity sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA== +"@rollup/rollup-linux-arm64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz#b5e9d5e30ff36a19bedd29c715ba18a1889ff269" + integrity sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA== + "@rollup/rollup-linux-arm64-musl@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz#865baf5b6f5ff67acb32e5a359508828e8dc5788" integrity sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A== +"@rollup/rollup-linux-arm64-musl@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz#1d8f68f0829b57f746ec03432ad046f1af014a98" + integrity sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA== + "@rollup/rollup-linux-loongarch64-gnu@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz#23c6609ba0f7fa7a7f2038b6b6a08555a5055a87" integrity sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA== +"@rollup/rollup-linux-loongarch64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz#07027feb883408e74a3002c8e50caaedd288ae38" + integrity sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw== + "@rollup/rollup-linux-powerpc64le-gnu@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz#652ef0d9334a9f25b9daf85731242801cb0fc41c" integrity sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A== +"@rollup/rollup-linux-powerpc64le-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz#544ce1b0847a9c1240425e86f33daceac7ec4e12" + integrity sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w== + "@rollup/rollup-linux-riscv64-gnu@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz#1eb6651839ee6ebca64d6cc64febbd299e95e6bd" integrity sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA== +"@rollup/rollup-linux-riscv64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz#64be13d51852ec1e2dfbd25d997ed5f42f35ea6d" + integrity sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ== + "@rollup/rollup-linux-s390x-gnu@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz#015c52293afb3ff2a293cf0936b1d43975c1e9cd" integrity sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg== +"@rollup/rollup-linux-s390x-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz#31f51e1e05c6264552d03875d9e2e673f0fd86e3" + integrity sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g== + "@rollup/rollup-linux-x64-gnu@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz#b83001b5abed2bcb5e2dbeec6a7e69b194235c1e" integrity sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw== +"@rollup/rollup-linux-x64-gnu@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz#f4c95b26f4ad69ebdb64b42f0ae4da2a0f617958" + integrity sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ== + "@rollup/rollup-linux-x64-musl@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz#6cc7c84cd4563737f8593e66f33b57d8e228805b" integrity sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g== +"@rollup/rollup-linux-x64-musl@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz#ab7be89192f72beb9ea6e2386186fefde4f69d82" + integrity sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA== + "@rollup/rollup-win32-arm64-msvc@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz#631ffeee094d71279fcd1fe8072bdcf25311bc11" integrity sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A== +"@rollup/rollup-win32-arm64-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz#7f12efb8240b238346951559998802722944421e" + integrity sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig== + "@rollup/rollup-win32-ia32-msvc@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz#06d1d60d5b9f718e8a6c4a43f82e3f9e3254587f" integrity sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA== +"@rollup/rollup-win32-ia32-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz#353d14d6eee943004d129796e4feddd3aa260921" + integrity sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng== + "@rollup/rollup-win32-x64-msvc@4.28.1": version "4.28.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz#4dff5c4259ebe6c5b4a8f2c5bc3829b7a8447ff0" integrity sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA== +"@rollup/rollup-win32-x64-msvc@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz#c82f04a09ba481e13857d6f2516e072aaa51b7f4" + integrity sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg== + "@rtsao/scc@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" @@ -1279,62 +1374,62 @@ resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== -"@typescript-eslint/eslint-plugin@8.17.0": - version "8.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.17.0.tgz#2ee073c421f4e81e02d10e731241664b6253b23c" - integrity sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w== +"@typescript-eslint/eslint-plugin@8.19.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.19.0.tgz#2b1e1b791e21d5fc27ddc93884db066444f597b5" + integrity sha512-NggSaEZCdSrFddbctrVjkVZvFC6KGfKfNK0CU7mNK/iKHGKbzT4Wmgm08dKpcZECBu9f5FypndoMyRHkdqfT1Q== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.17.0" - "@typescript-eslint/type-utils" "8.17.0" - "@typescript-eslint/utils" "8.17.0" - "@typescript-eslint/visitor-keys" "8.17.0" + "@typescript-eslint/scope-manager" "8.19.0" + "@typescript-eslint/type-utils" "8.19.0" + "@typescript-eslint/utils" "8.19.0" + "@typescript-eslint/visitor-keys" "8.19.0" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@8.17.0": - version "8.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.17.0.tgz#2ee972bb12fa69ac625b85813dc8d9a5a053ff52" - integrity sha512-Drp39TXuUlD49F7ilHHCG7TTg8IkA+hxCuULdmzWYICxGXvDXmDmWEjJYZQYgf6l/TFfYNE167m7isnc3xlIEg== +"@typescript-eslint/parser@8.19.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.19.0.tgz#f1512e6e5c491b03aabb2718b95becde22b15292" + integrity sha512-6M8taKyOETY1TKHp0x8ndycipTVgmp4xtg5QpEZzXxDhNvvHOJi5rLRkLr8SK3jTgD5l4fTlvBiRdfsuWydxBw== dependencies: - "@typescript-eslint/scope-manager" "8.17.0" - "@typescript-eslint/types" "8.17.0" - "@typescript-eslint/typescript-estree" "8.17.0" - "@typescript-eslint/visitor-keys" "8.17.0" + "@typescript-eslint/scope-manager" "8.19.0" + "@typescript-eslint/types" "8.19.0" + "@typescript-eslint/typescript-estree" "8.19.0" + "@typescript-eslint/visitor-keys" "8.19.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@8.17.0": - version "8.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.17.0.tgz#a3f49bf3d4d27ff8d6b2ea099ba465ef4dbcaa3a" - integrity sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg== +"@typescript-eslint/scope-manager@8.19.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.19.0.tgz#28fa413a334f70e8b506a968531e0a7c9c3076dc" + integrity sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA== dependencies: - "@typescript-eslint/types" "8.17.0" - "@typescript-eslint/visitor-keys" "8.17.0" + "@typescript-eslint/types" "8.19.0" + "@typescript-eslint/visitor-keys" "8.19.0" -"@typescript-eslint/type-utils@8.17.0": - version "8.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.17.0.tgz#d326569f498cdd0edf58d5bb6030b4ad914e63d3" - integrity sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw== +"@typescript-eslint/type-utils@8.19.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.19.0.tgz#41abd7d2e4cf93b6854b1fe6cbf416fab5abf89f" + integrity sha512-TZs0I0OSbd5Aza4qAMpp1cdCYVnER94IziudE3JU328YUHgWu9gwiwhag+fuLeJ2LkWLXI+F/182TbG+JaBdTg== dependencies: - "@typescript-eslint/typescript-estree" "8.17.0" - "@typescript-eslint/utils" "8.17.0" + "@typescript-eslint/typescript-estree" "8.19.0" + "@typescript-eslint/utils" "8.19.0" debug "^4.3.4" ts-api-utils "^1.3.0" -"@typescript-eslint/types@8.17.0": - version "8.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.17.0.tgz#ef84c709ef8324e766878834970bea9a7e3b72cf" - integrity sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA== +"@typescript-eslint/types@8.19.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.19.0.tgz#a190a25c5484a42b81eaad06989579fdeb478cbb" + integrity sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA== -"@typescript-eslint/typescript-estree@8.17.0": - version "8.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.17.0.tgz#40b5903bc929b1e8dd9c77db3cb52cfb199a2a34" - integrity sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw== +"@typescript-eslint/typescript-estree@8.19.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.0.tgz#6b4f48f98ffad6597379951b115710f4d68c9ccb" + integrity sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw== dependencies: - "@typescript-eslint/types" "8.17.0" - "@typescript-eslint/visitor-keys" "8.17.0" + "@typescript-eslint/types" "8.19.0" + "@typescript-eslint/visitor-keys" "8.19.0" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -1342,22 +1437,22 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@8.17.0": - version "8.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.17.0.tgz#41c05105a2b6ab7592f513d2eeb2c2c0236d8908" - integrity sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w== +"@typescript-eslint/utils@8.19.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.19.0.tgz#33824310e1fccc17f27fbd1030fd8bbd9a674684" + integrity sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "8.17.0" - "@typescript-eslint/types" "8.17.0" - "@typescript-eslint/typescript-estree" "8.17.0" + "@typescript-eslint/scope-manager" "8.19.0" + "@typescript-eslint/types" "8.19.0" + "@typescript-eslint/typescript-estree" "8.19.0" -"@typescript-eslint/visitor-keys@8.17.0": - version "8.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.17.0.tgz#4dbcd0e28b9bf951f4293805bf34f98df45e1aa8" - integrity sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg== +"@typescript-eslint/visitor-keys@8.19.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.0.tgz#dc313f735e64c4979c9073f51ffcefb6d9be5c77" + integrity sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w== dependencies: - "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/types" "8.19.0" eslint-visitor-keys "^4.2.0" "@vitest/coverage-v8@^2.1.8": @@ -1378,10 +1473,10 @@ test-exclude "^7.0.1" tinyrainbow "^1.2.0" -"@vitest/eslint-plugin@^1.1.14": - version "1.1.14" - resolved "https://registry.yarnpkg.com/@vitest/eslint-plugin/-/eslint-plugin-1.1.14.tgz#dc3bb332461282cfab213b76e5e42bd2dad5929b" - integrity sha512-ej0cT5rUt7uvwxuu7Qxkm7fI+eaOq8vD34qGpuRoXCdvOybOlE5GDqtgvVCYbxLANkcRJfm5VDU1TnJmQRHi9g== +"@vitest/eslint-plugin@^1.1.22": + version "1.1.22" + resolved "https://registry.yarnpkg.com/@vitest/eslint-plugin/-/eslint-plugin-1.1.22.tgz#5f8c32de034a37765f91d1b9c05b94bff4f3722c" + integrity sha512-ztvy2+thiCMmKnywvKGhH3AcKgEMGd4BsFK2QC9/EXqlyjXDp7Pg96PonbLx8bDvNCAjq4hfCw5YuZSAz1EDIg== "@vitest/expect@2.1.8": version "2.1.8" @@ -1751,7 +1846,7 @@ core-js-compat@^3.38.0, core-js-compat@^3.38.1: dependencies: browserslist "^4.24.2" -cross-spawn@^7.0.0, cross-spawn@^7.0.5: +cross-spawn@^7.0.0, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -2086,17 +2181,17 @@ eslint-visitor-keys@^4.2.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== -eslint@^9.16.0: - version "9.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.16.0.tgz#66832e66258922ac0a626f803a9273e37747f2a6" - integrity sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA== +eslint@^9.17.0: + version "9.17.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.17.0.tgz#faa1facb5dd042172fdc520106984b5c2421bb0c" + integrity sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.12.1" "@eslint/config-array" "^0.19.0" "@eslint/core" "^0.9.0" "@eslint/eslintrc" "^3.2.0" - "@eslint/js" "9.16.0" + "@eslint/js" "9.17.0" "@eslint/plugin-kit" "^0.2.3" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" @@ -2105,7 +2200,7 @@ eslint@^9.16.0: "@types/json-schema" "^7.0.15" ajv "^6.12.4" chalk "^4.0.0" - cross-spawn "^7.0.5" + cross-spawn "^7.0.6" debug "^4.3.2" escape-string-regexp "^4.0.0" eslint-scope "^8.2.0" @@ -3231,7 +3326,7 @@ rollup-plugin-dts@^6.1.1: optionalDependencies: "@babel/code-frame" "^7.24.2" -rollup@^4.20.0, rollup@^4.28.1: +rollup@^4.20.0: version "4.28.1" resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.28.1.tgz#7718ba34d62b449dfc49adbfd2f312b4fe0df4de" integrity sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg== @@ -3259,6 +3354,34 @@ rollup@^4.20.0, rollup@^4.28.1: "@rollup/rollup-win32-x64-msvc" "4.28.1" fsevents "~2.3.2" +rollup@^4.29.1: + version "4.29.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.29.1.tgz#a9aaaece817e5f778489e5bf82e379cc8a5c05bc" + integrity sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw== + dependencies: + "@types/estree" "1.0.6" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.29.1" + "@rollup/rollup-android-arm64" "4.29.1" + "@rollup/rollup-darwin-arm64" "4.29.1" + "@rollup/rollup-darwin-x64" "4.29.1" + "@rollup/rollup-freebsd-arm64" "4.29.1" + "@rollup/rollup-freebsd-x64" "4.29.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.29.1" + "@rollup/rollup-linux-arm-musleabihf" "4.29.1" + "@rollup/rollup-linux-arm64-gnu" "4.29.1" + "@rollup/rollup-linux-arm64-musl" "4.29.1" + "@rollup/rollup-linux-loongarch64-gnu" "4.29.1" + "@rollup/rollup-linux-powerpc64le-gnu" "4.29.1" + "@rollup/rollup-linux-riscv64-gnu" "4.29.1" + "@rollup/rollup-linux-s390x-gnu" "4.29.1" + "@rollup/rollup-linux-x64-gnu" "4.29.1" + "@rollup/rollup-linux-x64-musl" "4.29.1" + "@rollup/rollup-win32-arm64-msvc" "4.29.1" + "@rollup/rollup-win32-ia32-msvc" "4.29.1" + "@rollup/rollup-win32-x64-msvc" "4.29.1" + fsevents "~2.3.2" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -3580,14 +3703,14 @@ typed-array-length@^1.0.6: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" -typescript-eslint@^8.17.0: - version "8.17.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.17.0.tgz#fa4033c26b3b40f778287bc12918d985481b220b" - integrity sha512-409VXvFd/f1br1DCbuKNFqQpXICoTB+V51afcwG1pn1a3Cp92MqAUges3YjwEdQ0cMUoCIodjVDAYzyD8h3SYA== +typescript-eslint@^8.19.0: + version "8.19.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.19.0.tgz#e4ff06b19f2f9807a2c26147a0199a109944d9e0" + integrity sha512-Ni8sUkVWYK4KAcTtPjQ/UTiRk6jcsuDhPpxULapUDi8A/l8TSBk+t1GtJA1RsCzIJg0q6+J7bf35AwQigENWRQ== dependencies: - "@typescript-eslint/eslint-plugin" "8.17.0" - "@typescript-eslint/parser" "8.17.0" - "@typescript-eslint/utils" "8.17.0" + "@typescript-eslint/eslint-plugin" "8.19.0" + "@typescript-eslint/parser" "8.19.0" + "@typescript-eslint/utils" "8.19.0" typescript@^5.7.2: version "5.7.2" @@ -3775,10 +3898,10 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110" integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g== -zx@^8.2.4: - version "8.2.4" - resolved "https://registry.yarnpkg.com/zx/-/zx-8.2.4.tgz#28bc6a5c37d623b63a3a1c40198e0aaf9d2d136a" - integrity sha512-g9wVU+5+M+zVen/3IyAZfsZFmeqb6vDfjqFggakviz5uLK7OAejOirX+jeTOkyvAh/OYRlCgw+SdqzN7F61QVQ== +zx@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/zx/-/zx-8.3.0.tgz#5a4750662041c5990fad1abd02743208c6555b6b" + integrity sha512-L8mY3yfJwo3a8ZDD6f9jZzAcRWJZYcV8GauZmBxLB/aSTwaMzMIEVpPp2Kyx+7yF0gdvuxKnMxAZRft9UCawiw== optionalDependencies: "@types/fs-extra" ">=11" "@types/node" ">=20" From e95606534be62dca13effa647bbff39fef25bf4e Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Tue, 21 Jan 2025 22:01:15 +0100 Subject: [PATCH 02/48] make label name easier to configure --- .github/workflows/label.yml | 115 ++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 57 deletions(-) diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index eaeef183..a87abd6c 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -1,68 +1,69 @@ name: Auto Label New Issues, PRs, and Discussions on: - issues: - types: [opened] - pull_request_target: - types: [opened] - discussion: - types: [created] + issues: + types: [opened] + pull_request_target: + types: [opened] + discussion: + types: [created] jobs: - add-label: - runs-on: ubuntu-latest + add-label: + runs-on: ubuntu-latest - permissions: - issues: write - discussions: write - pull-requests: write + permissions: + issues: write + discussions: write + pull-requests: write - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - REPO_OWNER: ${{ github.repository_owner }} - REPO_NAME: ${{ github.event.repository.name }} - - steps: - - name: Checkout repository - uses: actions/checkout@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO_OWNER: ${{ github.repository_owner }} + REPO_NAME: ${{ github.event.repository.name }} + LABEL_NAME: context-v2 - - name: Add context-v2 label to new issue - if: github.event_name == 'issues' - run: | - ISSUE_NUMBER=${{ github.event.issue.number }} - gh issue edit "$ISSUE_NUMBER" --add-label "context-v2" + steps: + - name: Checkout repository + uses: actions/checkout@v4 - - name: Add context-v2 label to new PR - if: github.event_name == 'pull_request_target' - run: | - PR_NUMBER=${{ github.event.pull_request.number }} - gh pr edit "$PR_NUMBER" --add-label "context-v2" + - name: Add label to new issue + if: github.event_name == 'issues' + run: | + ISSUE_NUMBER=${{ github.event.issue.number }} + gh issue edit "$ISSUE_NUMBER" --add-label "$LABEL_NAME" - - name: Get label id for discussion - id: label-data - if: github.event_name == 'discussion' - run: | - res="$(gh api \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/$REPO_OWNER/$REPO_NAME/labels/context-v2 --jq '.node_id')" - echo "label_id=$res" >> $GITHUB_OUTPUT + - name: Add label to new PR + if: github.event_name == 'pull_request_target' + run: | + PR_NUMBER=${{ github.event.pull_request.number }} + gh pr edit "$PR_NUMBER" --add-label "$LABEL_NAME" - - name: Add context-v2 label to new discussion - uses: octokit/graphql-action@v2.x - if: github.event_name == 'discussion' - env: - DISCUSSION_ID: ${{ github.event.discussion.node_id }} - LABEL_ID: ${{ steps.label-data.outputs.label_id }} - with: - query: | - mutation { - addLabelsToLabelable( - input:{ - labelableId: "${{env.DISCUSSION_ID}}" - labelIds: ["${{ env.LABEL_ID}}"] - } - ) { - clientMutationId - } - } + - name: Get label id for discussion + id: label-data + if: github.event_name == 'discussion' + run: | + res="$(gh api \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/$REPO_OWNER/$REPO_NAME/labels/$LABEL_NAME --jq '.node_id')" + echo "label_id=$res" >> $GITHUB_OUTPUT + + - name: Add label to new discussion + uses: octokit/graphql-action@v2.x + if: github.event_name == 'discussion' + env: + DISCUSSION_ID: ${{ github.event.discussion.node_id }} + LABEL_ID: ${{ steps.label-data.outputs.label_id }} + with: + query: | + mutation { + addLabelsToLabelable( + input:{ + labelableId: "${{env.DISCUSSION_ID}}" + labelIds: ["${{ env.LABEL_ID}}"] + } + ) { + clientMutationId + } + } From 99f3ca4b381597c520c5c23da9315088a208b9d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:04:11 +0000 Subject: [PATCH 03/48] Bump vite from 5.4.6 to 5.4.14 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.6 to 5.4.14. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v5.4.14/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.4.14/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1806449a..07246732 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3782,9 +3782,9 @@ vite-node@2.1.8: vite "^5.0.0" vite@^5.0.0: - version "5.4.6" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.6.tgz#85a93a1228a7fb5a723ca1743e337a2588ed008f" - integrity sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q== + version "5.4.14" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.14.tgz#ff8255edb02134df180dcfca1916c37a6abe8408" + integrity sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA== dependencies: esbuild "^0.21.3" postcss "^8.4.43" From faf70ccde1e74be8598ac5d1d20fda4d63b1c038 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jan 2025 00:02:11 +0000 Subject: [PATCH 04/48] Bump undici from 5.28.4 to 5.28.5 in /.github/actions/metrics-report Bumps [undici](https://github.com/nodejs/undici) from 5.28.4 to 5.28.5. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5) --- updated-dependencies: - dependency-name: undici dependency-type: indirect ... Signed-off-by: dependabot[bot] --- .github/actions/metrics-report/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/metrics-report/yarn.lock b/.github/actions/metrics-report/yarn.lock index 2a42c9af..c3d15e36 100644 --- a/.github/actions/metrics-report/yarn.lock +++ b/.github/actions/metrics-report/yarn.lock @@ -456,9 +456,9 @@ tunnel@^0.0.6: integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== undici@^5.25.4: - version "5.28.4" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" - integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== + version "5.28.5" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.5.tgz#b2b94b6bf8f1d919bc5a6f31f2c01deb02e54d4b" + integrity sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA== dependencies: "@fastify/busboy" "^2.0.0" From 8aa7a8239d3db7960b3a1d1e224faa32b63779c1 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:33:52 +0100 Subject: [PATCH 05/48] add support for transform-style --- src/lib/default-config.ts | 5 +++++ src/lib/types.ts | 1 + tests/class-map.test.ts | 2 +- tests/tailwind-css-versions.test.ts | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 2c9d2536..0e4dbee4 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -1508,6 +1508,11 @@ export const getDefaultConfig = () => { ], }, ], + /** + * Transform Style + * @see https://tailwindcss.com/docs/transform-style + */ + 'transform-style': [{ transform: ['3d', 'flat'] }], // Interactivity /** * Accent Color diff --git a/src/lib/types.ts b/src/lib/types.ts index 2fc5e420..6ce9c5ed 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -467,6 +467,7 @@ export type DefaultClassGroupIds = | 'touch' | 'tracking' | 'transform-origin' + | 'transform-style' | 'transform' | 'transition' | 'translate-x' diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index 152e54c5..b605ca68 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -264,7 +264,7 @@ test('class map has correct class groups at first part', () => { top: ['top'], touch: ['touch', 'touch-pz', 'touch-x', 'touch-y'], tracking: ['tracking'], - transform: ['transform'], + transform: ['transform', 'transform-style'], transition: ['transition'], translate: ['translate-x', 'translate-y'], truncate: ['text-overflow'], diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index 2ac802fc..f3fd5017 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -57,3 +57,7 @@ test('supports Tailwind CSS v3.4 features', () => { expect(twMerge('float-start float-end clear-start clear-end')).toBe('float-end clear-end') expect(twMerge('*:p-10 *:p-20 hover:*:p-10 hover:*:p-20')).toBe('*:p-20 hover:*:p-20') }) + +test('supports Tailwind CSS v4.0 features', () => { + expect(twMerge('transform-3d transform-flat')).toBe('transform-flat') +}) From 070683c708de49a2eacbf61e411000ca8c2b976a Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:55:49 +0100 Subject: [PATCH 06/48] add support for new rotate utilities --- src/lib/default-config.ts | 18 +++++++++++++++++- src/lib/types.ts | 3 +++ tests/class-map.test.ts | 2 +- tests/tailwind-css-versions.test.ts | 3 +++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 0e4dbee4..30d5dee0 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -87,6 +87,7 @@ export const getDefaultConfig = () => { const getBreaks = () => ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const const getNumberAndArbitrary = () => [isNumber, isArbitraryValue] + const getRotate = () => ['none', isInteger, isArbitraryValue] return { cacheSize: 500, @@ -1467,7 +1468,22 @@ export const getDefaultConfig = () => { * Rotate * @see https://tailwindcss.com/docs/rotate */ - rotate: [{ rotate: [isInteger, isArbitraryValue] }], + rotate: [{ rotate: getRotate() }], + /** + * Rotate X + * @see https://tailwindcss.com/docs/rotate + */ + 'rotate-x': [{ 'rotate-x': getRotate() }], + /** + * Rotate Y + * @see https://tailwindcss.com/docs/rotate + */ + 'rotate-y': [{ 'rotate-y': getRotate() }], + /** + * Rotate Z + * @see https://tailwindcss.com/docs/rotate + */ + 'rotate-z': [{ 'rotate-z': getRotate() }], /** * Translate X * @see https://tailwindcss.com/docs/translate diff --git a/src/lib/types.ts b/src/lib/types.ts index 6ce9c5ed..f7f3ce06 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -387,6 +387,9 @@ export type DefaultClassGroupIds = | 'ring-opacity' | 'ring-w-inset' | 'ring-w' + | 'rotate-x' + | 'rotate-y' + | 'rotate-z' | 'rotate' | 'rounded-b' | 'rounded-bl' diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index b605ca68..94b162f5 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -191,7 +191,7 @@ test('class map has correct class groups at first part', () => { 'ring-w', 'ring-w-inset', ], - rotate: ['rotate'], + rotate: ['rotate', 'rotate-x', 'rotate-y', 'rotate-z'], rounded: [ 'rounded', 'rounded-b', diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index f3fd5017..3e2c0436 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -60,4 +60,7 @@ test('supports Tailwind CSS v3.4 features', () => { test('supports Tailwind CSS v4.0 features', () => { expect(twMerge('transform-3d transform-flat')).toBe('transform-flat') + expect(twMerge('rotate-12 rotate-x-2 rotate-none rotate-y-3')).toBe( + 'rotate-x-2 rotate-none rotate-y-3', + ) }) From 793601334ecffcfe66f9898e6ca11a7203f48b2e Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:04:03 +0100 Subject: [PATCH 07/48] add perspective utilities --- src/lib/default-config.ts | 19 ++++++++++++++++++- src/lib/types.ts | 1 + tests/class-map.test.ts | 1 + tests/tailwind-css-versions.test.ts | 6 ++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 30d5dee0..146f3fb3 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -1406,7 +1406,7 @@ export const getDefaultConfig = () => { caption: [{ caption: ['top', 'bottom'] }], // Transitions and Animation /** - * Tranisition Property + * Transition Property * @see https://tailwindcss.com/docs/transition-property */ transition: [ @@ -1444,6 +1444,23 @@ export const getDefaultConfig = () => { */ animate: [{ animate: ['none', 'spin', 'ping', 'pulse', 'bounce', isArbitraryValue] }], // Transforms + /** + * Perspective + * @see https://tailwindcss.com/docs/perspective + */ + perspective: [ + { + perspective: [ + 'dramatic', + 'near', + 'normal', + 'midrange', + 'distant', + 'none', + isArbitraryValue, + ], + }, + ], /** * Transform * @see https://tailwindcss.com/docs/transform diff --git a/src/lib/types.ts b/src/lib/types.ts index f7f3ce06..b22660b8 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -366,6 +366,7 @@ export type DefaultClassGroupIds = | 'p' | 'pb' | 'pe' + | 'perspective' | 'pl' | 'place-content' | 'place-items' diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index 94b162f5..6a0ead77 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -170,6 +170,7 @@ test('class map has correct class groups at first part', () => { p: ['p'], pb: ['pb'], pe: ['pe'], + perspective: ['perspective'], pl: ['pl'], place: ['place-content', 'place-items', 'place-self'], placeholder: ['placeholder-color', 'placeholder-opacity'], diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index 3e2c0436..04da4c21 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -63,4 +63,10 @@ test('supports Tailwind CSS v4.0 features', () => { expect(twMerge('rotate-12 rotate-x-2 rotate-none rotate-y-3')).toBe( 'rotate-x-2 rotate-none rotate-y-3', ) + expect(twMerge('perspective-dramatic perspective-none perspective-midrange')).toBe( + 'perspective-midrange', + ) + + // TODO: Remove proto + expect(twMerge('')).toBe('') }) From 742e3bcd29263276432cb0faafef423ccdebc546 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:07:49 +0100 Subject: [PATCH 08/48] add perspective-origin utilities --- src/lib/default-config.ts | 20 ++++++++++++++++++++ src/lib/types.ts | 1 + tests/class-map.test.ts | 2 +- tests/tailwind-css-versions.test.ts | 3 +++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 146f3fb3..9b41c111 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -1461,6 +1461,26 @@ export const getDefaultConfig = () => { ], }, ], + /** + * Perspective Origin + * @see https://tailwindcss.com/docs/perspective-origin + */ + 'perspective-origin': [ + { + 'perspective-origin': [ + 'center', + 'top', + 'top-right', + 'right', + 'bottom-right', + 'bottom', + 'bottom-left', + 'left', + 'top-left', + isArbitraryValue, + ], + }, + ], /** * Transform * @see https://tailwindcss.com/docs/transform diff --git a/src/lib/types.ts b/src/lib/types.ts index b22660b8..3d45b9de 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -367,6 +367,7 @@ export type DefaultClassGroupIds = | 'pb' | 'pe' | 'perspective' + | 'perspective-origin' | 'pl' | 'place-content' | 'place-items' diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index 6a0ead77..5ac73a0b 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -170,7 +170,7 @@ test('class map has correct class groups at first part', () => { p: ['p'], pb: ['pb'], pe: ['pe'], - perspective: ['perspective'], + perspective: ['perspective', 'perspective-origin'], pl: ['pl'], place: ['place-content', 'place-items', 'place-self'], placeholder: ['placeholder-color', 'placeholder-opacity'], diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index 04da4c21..5de89e88 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -66,6 +66,9 @@ test('supports Tailwind CSS v4.0 features', () => { expect(twMerge('perspective-dramatic perspective-none perspective-midrange')).toBe( 'perspective-midrange', ) + expect(twMerge('perspective-origin-center perspective-origin-top-left')).toBe( + 'perspective-origin-top-left', + ) // TODO: Remove proto expect(twMerge('')).toBe('') From af4b4c90d207ca48d56f614eea84d4e0c8640c93 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:35:55 +0100 Subject: [PATCH 09/48] breaking: add linear gradient angles --- src/lib/default-config.ts | 7 ++++++- tests/arbitrary-values.test.ts | 4 ++-- tests/tailwind-css-versions.test.ts | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 9b41c111..62f67283 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -943,7 +943,12 @@ export const getDefaultConfig = () => { { bg: [ 'none', - { 'gradient-to': ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl'] }, + { + linear: [ + { to: ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl'] }, + isInteger, + ], + }, isArbitraryImage, ], }, diff --git a/tests/arbitrary-values.test.ts b/tests/arbitrary-values.test.ts index aa64955c..e317f6ee 100644 --- a/tests/arbitrary-values.test.ts +++ b/tests/arbitrary-values.test.ts @@ -72,7 +72,7 @@ test('handles ambiguous arbitrary values correctly', () => { ) expect( twMerge( - 'bg-none bg-[url(.)] bg-[image:.] bg-[url:.] bg-[linear-gradient(.)] bg-gradient-to-r', + 'bg-none bg-[url(.)] bg-[image:.] bg-[url:.] bg-[linear-gradient(.)] bg-linear-to-r', ), - ).toBe('bg-gradient-to-r') + ).toBe('bg-linear-to-r') }) diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index 5de89e88..36dfd749 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -69,6 +69,7 @@ test('supports Tailwind CSS v4.0 features', () => { expect(twMerge('perspective-origin-center perspective-origin-top-left')).toBe( 'perspective-origin-top-left', ) + expect(twMerge('bg-linear-to-r bg-linear-45')).toBe('bg-linear-45') // TODO: Remove proto expect(twMerge('')).toBe('') From cf570544724698bd2136b3593da6646037cb922d Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:08:09 +0100 Subject: [PATCH 10/48] add radial and conic gradients --- src/lib/default-config.ts | 3 +++ tests/tailwind-css-versions.test.ts | 1 + 2 files changed, 4 insertions(+) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 62f67283..aab38cc9 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -947,7 +947,10 @@ export const getDefaultConfig = () => { linear: [ { to: ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl'] }, isInteger, + isArbitraryValue, ], + radial: ['', isArbitraryValue], + conic: [isInteger, isArbitraryValue], }, isArbitraryImage, ], diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index 36dfd749..659fdb6c 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -70,6 +70,7 @@ test('supports Tailwind CSS v4.0 features', () => { 'perspective-origin-top-left', ) expect(twMerge('bg-linear-to-r bg-linear-45')).toBe('bg-linear-45') + expect(twMerge('bg-linear-to-r bg-radial-[something] bg-conic-10')).toBe('bg-conic-10') // TODO: Remove proto expect(twMerge('')).toBe('') From 0c46ce921f0e53d8f761985dffce282e4555e12a Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 21:05:52 +0100 Subject: [PATCH 11/48] add inset-shadow and inset-ring utilities --- src/lib/default-config.ts | 61 +++++++++++++++++++---------- src/lib/types.ts | 7 +++- tests/class-map.test.ts | 19 ++++----- tests/tailwind-css-versions.test.ts | 3 ++ 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index aab38cc9..438e0ad0 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -47,7 +47,7 @@ export const getDefaultConfig = () => { const getOverflow = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const const getSpacingWithAutoAndArbitrary = () => ['auto', isArbitraryValue, spacing] as const const getSpacingWithArbitrary = () => [isArbitraryValue, spacing] as const - const getLengthWithEmptyAndArbitrary = () => ['', isLength, isArbitraryLength] as const + const getNumberWithEmptyAndArbitrary = () => ['', isNumber, isArbitraryLength] as const const getNumberWithAutoAndArbitrary = () => ['auto', isNumber, isArbitraryValue] as const const getPositions = () => [ @@ -100,7 +100,7 @@ export const getDefaultConfig = () => { borderColor: [colors], borderRadius: ['none', '', 'full', isTshirtSize, isArbitraryValue], borderSpacing: getSpacingWithArbitrary(), - borderWidth: getLengthWithEmptyAndArbitrary(), + borderWidth: getNumberWithEmptyAndArbitrary(), contrast: getNumberAndArbitrary(), grayscale: getZeroAndEmpty(), hueRotate: getNumberAndArbitrary(), @@ -1222,47 +1222,68 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/outline-color */ 'outline-color': [{ outline: [colors] }], + // Effects + /** + * Box Shadow + * @see https://tailwindcss.com/docs/box-shadow + */ + shadow: [{ shadow: ['none', isTshirtSize, isArbitraryShadow] }], + /** + * Box Shadow Color + * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color + */ + 'shadow-color': [{ shadow: [isAny] }], + /** + * Inset Box Shadow + * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow + */ + 'inset-shadow': [{ 'inset-shadow': ['none', isTshirtSize, isArbitraryShadow] }], + /** + * Inset Box Shadow Color + * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color + */ + 'inset-shadow-color': [{ 'inset-shadow': [isAny] }], /** * Ring Width - * @see https://tailwindcss.com/docs/ring-width + * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring */ - 'ring-w': [{ ring: getLengthWithEmptyAndArbitrary() }], + 'ring-w': [{ ring: getNumberWithEmptyAndArbitrary() }], /** * Ring Width Inset - * @see https://tailwindcss.com/docs/ring-width + * @see https://v3.tailwindcss.com/docs/ring-width#inset-rings + * @deprecated since Tailwind CSS v4.0.0 + * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ 'ring-w-inset': ['ring-inset'], /** * Ring Color - * @see https://tailwindcss.com/docs/ring-color + * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color */ 'ring-color': [{ ring: [colors] }], - /** - * Ring Opacity - * @see https://tailwindcss.com/docs/ring-opacity - */ - 'ring-opacity': [{ 'ring-opacity': [opacity] }], /** * Ring Offset Width - * @see https://tailwindcss.com/docs/ring-offset-width + * @see https://v3.tailwindcss.com/docs/ring-offset-width + * @deprecated since Tailwind CSS v4.0.0 + * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ 'ring-offset-w': [{ 'ring-offset': [isLength, isArbitraryLength] }], /** * Ring Offset Color - * @see https://tailwindcss.com/docs/ring-offset-color + * @see https://v3.tailwindcss.com/docs/ring-offset-color + * @deprecated since Tailwind CSS v4.0.0 + * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ 'ring-offset-color': [{ 'ring-offset': [colors] }], - // Effects /** - * Box Shadow - * @see https://tailwindcss.com/docs/box-shadow + * Inset Ring Width + * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring */ - shadow: [{ shadow: ['', 'inner', 'none', isTshirtSize, isArbitraryShadow] }], + 'inset-ring-w': [{ 'inset-ring': getNumberWithEmptyAndArbitrary() }], /** - * Box Shadow Color - * @see https://tailwindcss.com/docs/box-shadow-color + * Inset Ring Color + * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color */ - 'shadow-color': [{ shadow: [isAny] }], + 'inset-ring-color': [{ 'inset-ring': [colors] }], /** * Opacity * @see https://tailwindcss.com/docs/opacity diff --git a/src/lib/types.ts b/src/lib/types.ts index 3d45b9de..efc2db65 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -321,6 +321,10 @@ export type DefaultClassGroupIds = | 'hue-rotate' | 'hyphens' | 'indent' + | 'inset-ring-color' + | 'inset-ring-w' + | 'inset-shadow' + | 'inset-shadow-color' | 'inset-x' | 'inset-y' | 'inset' @@ -366,8 +370,8 @@ export type DefaultClassGroupIds = | 'p' | 'pb' | 'pe' - | 'perspective' | 'perspective-origin' + | 'perspective' | 'pl' | 'place-content' | 'place-items' @@ -386,7 +390,6 @@ export type DefaultClassGroupIds = | 'ring-color' | 'ring-offset-color' | 'ring-offset-w' - | 'ring-opacity' | 'ring-w-inset' | 'ring-w' | 'rotate-x' diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index 5ac73a0b..24e59d13 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -128,7 +128,15 @@ test('class map has correct class groups at first part', () => { hyphens: ['hyphens'], indent: ['indent'], inline: ['display'], - inset: ['inset', 'inset-x', 'inset-y'], + inset: [ + 'inset', + 'inset-ring-color', + 'inset-ring-w', + 'inset-shadow', + 'inset-shadow-color', + 'inset-x', + 'inset-y', + ], invert: ['invert'], invisible: ['visibility'], isolate: ['isolation'], @@ -184,14 +192,7 @@ test('class map has correct class groups at first part', () => { relative: ['position'], resize: ['resize'], right: ['right'], - ring: [ - 'ring-color', - 'ring-offset-color', - 'ring-offset-w', - 'ring-opacity', - 'ring-w', - 'ring-w-inset', - ], + ring: ['ring-color', 'ring-offset-color', 'ring-offset-w', 'ring-w', 'ring-w-inset'], rotate: ['rotate', 'rotate-x', 'rotate-y', 'rotate-z'], rounded: [ 'rounded', diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index 659fdb6c..add49648 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -71,6 +71,9 @@ test('supports Tailwind CSS v4.0 features', () => { ) expect(twMerge('bg-linear-to-r bg-linear-45')).toBe('bg-linear-45') expect(twMerge('bg-linear-to-r bg-radial-[something] bg-conic-10')).toBe('bg-conic-10') + expect(twMerge('ring-4 ring-orange inset-ring inset-ring-3 inset-ring-blue')).toBe( + 'ring-4 ring-orange inset-ring-3 inset-ring-blue', + ) // TODO: Remove proto expect(twMerge('')).toBe('') From 1134b3e36d07cb5a03073479c95115621fba82a0 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 21:15:45 +0100 Subject: [PATCH 12/48] add field-sizing utilities --- src/lib/default-config.ts | 5 +++++ src/lib/types.ts | 3 ++- tests/class-map.test.ts | 1 + tests/tailwind-css-versions.test.ts | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 438e0ad0..68fb031e 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -1658,6 +1658,11 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities */ 'caret-color': [{ caret: [colors] }], + /** + * Field Sizing + * @see https://tailwindcss.com/docs/field-sizing + */ + 'field-sizing': [{ 'field-sizing': ['fixed', 'content'] }], /** * Pointer Events * @see https://tailwindcss.com/docs/pointer-events diff --git a/src/lib/types.ts b/src/lib/types.ts index efc2db65..c58346b0 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -285,6 +285,7 @@ export type DefaultClassGroupIds = | 'duration' | 'ease' | 'end' + | 'field-sizing' | 'fill' | 'filter' | 'flex-direction' @@ -323,8 +324,8 @@ export type DefaultClassGroupIds = | 'indent' | 'inset-ring-color' | 'inset-ring-w' - | 'inset-shadow' | 'inset-shadow-color' + | 'inset-shadow' | 'inset-x' | 'inset-y' | 'inset' diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index 24e59d13..19f57449 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -109,6 +109,7 @@ test('class map has correct class groups at first part', () => { duration: ['duration'], ease: ['ease'], end: ['end'], + field: ['field-sizing'], fill: ['fill'], filter: ['filter'], fixed: ['position'], diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index add49648..63a34498 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -74,6 +74,7 @@ test('supports Tailwind CSS v4.0 features', () => { expect(twMerge('ring-4 ring-orange inset-ring inset-ring-3 inset-ring-blue')).toBe( 'ring-4 ring-orange inset-ring-3 inset-ring-blue', ) + expect(twMerge('field-sizing-content field-sizing-fixed')).toBe('field-sizing-fixed') // TODO: Remove proto expect(twMerge('')).toBe('') From 0dba016aa641e924df8270bcfbf4159eb6b792b7 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 21:19:28 +0100 Subject: [PATCH 13/48] add color-scheme utilities --- src/lib/default-config.ts | 17 ++++++++++++----- src/lib/types.ts | 1 + tests/class-map.test.ts | 1 + tests/tailwind-css-versions.test.ts | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 68fb031e..bfaa2751 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -1606,6 +1606,18 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/appearance */ appearance: [{ appearance: ['none', 'auto'] }], + /** + * Caret Color + * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities + */ + 'caret-color': [{ caret: [colors] }], + /** + * Color Scheme + * @see https://tailwindcss.com/docs/color-scheme + */ + 'color-scheme': [ + { scheme: ['normal', 'dark', 'light', 'light-dark', 'only-dark', 'only-light'] }, + ], /** * Cursor * @see https://tailwindcss.com/docs/cursor @@ -1653,11 +1665,6 @@ export const getDefaultConfig = () => { ], }, ], - /** - * Caret Color - * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities - */ - 'caret-color': [{ caret: [colors] }], /** * Field Sizing * @see https://tailwindcss.com/docs/field-sizing diff --git a/src/lib/types.ts b/src/lib/types.ts index c58346b0..27c841ec 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -267,6 +267,7 @@ export type DefaultClassGroupIds = | 'col-end' | 'col-start-end' | 'col-start' + | 'color-scheme' | 'columns' | 'container' | 'content' diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index 19f57449..4b94fb58 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -215,6 +215,7 @@ test('class map has correct class groups at first part', () => { row: ['row-end', 'row-start', 'row-start-end'], saturate: ['saturate'], scale: ['scale', 'scale-x', 'scale-y'], + scheme: ['color-scheme'], scroll: [ 'scroll-behavior', 'scroll-m', diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index 63a34498..218e6075 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -75,6 +75,7 @@ test('supports Tailwind CSS v4.0 features', () => { 'ring-4 ring-orange inset-ring-3 inset-ring-blue', ) expect(twMerge('field-sizing-content field-sizing-fixed')).toBe('field-sizing-fixed') + expect(twMerge('scheme-normal scheme-dark')).toBe('scheme-dark') // TODO: Remove proto expect(twMerge('')).toBe('') From bfc7a421ee93d6a5280c52edbeb9aa0de0b7229e Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 21:25:42 +0100 Subject: [PATCH 14/48] add font-stretch utilities --- src/lib/default-config.ts | 21 +++++++++++++++++++++ src/lib/types.ts | 1 + tests/class-map.test.ts | 2 +- tests/tailwind-css-versions.test.ts | 3 +++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index bfaa2751..b9ffc4d0 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -694,6 +694,27 @@ export const getDefaultConfig = () => { ], }, ], + /** + * Font Stretch + * @see https://tailwindcss.com/docs/font-stretch + */ + 'font-stretch': [ + { + 'font-stretch': [ + 'ultra-condensed', + 'extra-condensed', + 'condensed', + 'semi-condensed', + 'normal', + 'semi-expanded', + 'expanded', + 'extra-expanded', + 'ultra-expanded', + isPercent, + isArbitraryValue, + ], + }, + ], /** * Font Family * @see https://tailwindcss.com/docs/font-family diff --git a/src/lib/types.ts b/src/lib/types.ts index 27c841ec..14ebd749 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -295,6 +295,7 @@ export type DefaultClassGroupIds = | 'float' | 'font-family' | 'font-size' + | 'font-stretch' | 'font-smoothing' | 'font-style' | 'font-weight' diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index 4b94fb58..a77f9998 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -116,7 +116,7 @@ test('class map has correct class groups at first part', () => { flex: ['display', 'flex', 'flex-direction', 'flex-wrap'], float: ['float'], flow: ['display'], - font: ['font-family', 'font-weight'], + font: ['font-family', 'font-stretch', 'font-weight'], forced: ['forced-color-adjust'], from: ['gradient-from', 'gradient-from-pos'], gap: ['gap', 'gap-x', 'gap-y'], diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index 218e6075..cf36a10a 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -76,6 +76,9 @@ test('supports Tailwind CSS v4.0 features', () => { ) expect(twMerge('field-sizing-content field-sizing-fixed')).toBe('field-sizing-fixed') expect(twMerge('scheme-normal scheme-dark')).toBe('scheme-dark') + expect(twMerge('font-stretch-expanded font-stretch-[66.66%] font-stretch-50%')).toBe( + 'font-stretch-50%', + ) // TODO: Remove proto expect(twMerge('')).toBe('') From 465b1a7165688cccc6243a9f15d890a844ac2862 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 21:45:09 +0100 Subject: [PATCH 15/48] remove deprecated opacity utilities --- src/lib/default-config.ts | 26 -------------------------- src/lib/types.ts | 5 ----- tests/arbitrary-properties.test.ts | 4 ++-- tests/class-map.test.ts | 14 ++------------ 4 files changed, 4 insertions(+), 45 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index b9ffc4d0..7e081db0 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -811,11 +811,6 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/placeholder-color */ 'placeholder-color': [{ placeholder: [colors] }], - /** - * Placeholder Opacity - * @see https://tailwindcss.com/docs/placeholder-opacity - */ - 'placeholder-opacity': [{ 'placeholder-opacity': [opacity] }], /** * Text Alignment * @see https://tailwindcss.com/docs/text-align @@ -826,11 +821,6 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/text-color */ 'text-color': [{ text: [colors] }], - /** - * Text Opacity - * @see https://tailwindcss.com/docs/text-opacity - */ - 'text-opacity': [{ 'text-opacity': [opacity] }], /** * Text Decoration * @see https://tailwindcss.com/docs/text-decoration @@ -930,12 +920,6 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/background-clip */ 'bg-clip': [{ 'bg-clip': ['border', 'padding', 'content', 'text'] }], - /** - * Background Opacity - * @deprecated since Tailwind CSS v3.0.0 - * @see https://tailwindcss.com/docs/background-opacity - */ - 'bg-opacity': [{ 'bg-opacity': [opacity] }], /** * Background Origin * @see https://tailwindcss.com/docs/background-origin @@ -1133,11 +1117,6 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/border-width */ 'border-w-l': [{ 'border-l': [borderWidth] }], - /** - * Border Opacity - * @see https://tailwindcss.com/docs/border-opacity - */ - 'border-opacity': [{ 'border-opacity': [opacity] }], /** * Border Style * @see https://tailwindcss.com/docs/border-style @@ -1163,11 +1142,6 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/divide-width */ 'divide-y-reverse': ['divide-y-reverse'], - /** - * Divide Opacity - * @see https://tailwindcss.com/docs/divide-opacity - */ - 'divide-opacity': [{ 'divide-opacity': [opacity] }], /** * Divide Style * @see https://tailwindcss.com/docs/divide-style diff --git a/src/lib/types.ts b/src/lib/types.ts index 14ebd749..102ac2ab 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -223,7 +223,6 @@ export type DefaultClassGroupIds = | 'bg-clip' | 'bg-color' | 'bg-image' - | 'bg-opacity' | 'bg-origin' | 'bg-position' | 'bg-repeat' @@ -239,7 +238,6 @@ export type DefaultClassGroupIds = | 'border-color-x' | 'border-color-y' | 'border-color' - | 'border-opacity' | 'border-spacing-x' | 'border-spacing-y' | 'border-spacing' @@ -276,7 +274,6 @@ export type DefaultClassGroupIds = | 'delay' | 'display' | 'divide-color' - | 'divide-opacity' | 'divide-style' | 'divide-x-reverse' | 'divide-x' @@ -380,7 +377,6 @@ export type DefaultClassGroupIds = | 'place-items' | 'place-self' | 'placeholder-color' - | 'placeholder-opacity' | 'pointer-events' | 'position' | 'pr' @@ -467,7 +463,6 @@ export type DefaultClassGroupIds = | 'text-decoration-style' | 'text-decoration-thickness' | 'text-decoration' - | 'text-opacity' | 'text-overflow' | 'text-transform' | 'text-wrap' diff --git a/tests/arbitrary-properties.test.ts b/tests/arbitrary-properties.test.ts index af933bcc..e8507dd8 100644 --- a/tests/arbitrary-properties.test.ts +++ b/tests/arbitrary-properties.test.ts @@ -22,8 +22,8 @@ test('handles arbitrary property conflicts with modifiers correctly', () => { expect( twMerge('[paint-order:markers] [paint-order:normal] [--my-var:2rem] lg:[--my-var:4px]'), ).toBe('[paint-order:normal] [--my-var:2rem] lg:[--my-var:4px]') - expect(twMerge('bg-[#B91C1C] bg-opacity-[0.56] bg-opacity-[48%]')).toBe( - 'bg-[#B91C1C] bg-opacity-[48%]', + expect(twMerge('bg-[#B91C1C] bg-radial-[at_50%_75%] bg-radial-[at_25%_25%]')).toBe( + 'bg-[#B91C1C] bg-radial-[at_25%_25%]', ) }) diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index a77f9998..ae51acaa 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -43,7 +43,6 @@ test('class map has correct class groups at first part', () => { 'bg-clip', 'bg-color', 'bg-image', - 'bg-opacity', 'bg-origin', 'bg-position', 'bg-repeat', @@ -62,7 +61,6 @@ test('class map has correct class groups at first part', () => { 'border-color-t', 'border-color-x', 'border-color-y', - 'border-opacity', 'border-spacing', 'border-spacing-x', 'border-spacing-y', @@ -98,7 +96,6 @@ test('class map has correct class groups at first part', () => { diagonal: ['fvn-fraction'], divide: [ 'divide-color', - 'divide-opacity', 'divide-style', 'divide-x', 'divide-x-reverse', @@ -182,7 +179,7 @@ test('class map has correct class groups at first part', () => { perspective: ['perspective', 'perspective-origin'], pl: ['pl'], place: ['place-content', 'place-items', 'place-self'], - placeholder: ['placeholder-color', 'placeholder-opacity'], + placeholder: ['placeholder-color'], pointer: ['pointer-events'], pr: ['pr'], proportional: ['fvn-spacing'], @@ -256,14 +253,7 @@ test('class map has correct class groups at first part', () => { subpixel: ['font-smoothing'], table: ['display', 'table-layout'], tabular: ['fvn-spacing'], - text: [ - 'font-size', - 'text-alignment', - 'text-color', - 'text-opacity', - 'text-overflow', - 'text-wrap', - ], + text: ['font-size', 'text-alignment', 'text-color', 'text-overflow', 'text-wrap'], to: ['gradient-to', 'gradient-to-pos'], top: ['top'], touch: ['touch', 'touch-pz', 'touch-x', 'touch-y'], From 8992454ec24adfaba7d7216388b9ed65f58b0997 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Fri, 24 Jan 2025 22:13:59 +0100 Subject: [PATCH 16/48] add renamed utilities and mark deprecated but still supported classes --- src/lib/default-config.ts | 43 ++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 7e081db0..4f3f6350 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -95,10 +95,23 @@ export const getDefaultConfig = () => { theme: { colors: [isAny], spacing: [isLength, isArbitraryLength], - blur: ['none', '', isTshirtSize, isArbitraryValue], + blur: [ + 'none', + // Deprecated since Tailwind CSS v4.0.0 + '', + isTshirtSize, + isArbitraryValue, + ], brightness: getNumberAndArbitrary(), borderColor: [colors], - borderRadius: ['none', '', 'full', isTshirtSize, isArbitraryValue], + borderRadius: [ + 'none', + // Deprecated since Tailwind CSS v4.0.0 + '', + 'full', + isTshirtSize, + isArbitraryValue, + ], borderSpacing: getSpacingWithArbitrary(), borderWidth: getNumberWithEmptyAndArbitrary(), contrast: getNumberAndArbitrary(), @@ -1201,7 +1214,7 @@ export const getDefaultConfig = () => { * Outline Style * @see https://tailwindcss.com/docs/outline-style */ - 'outline-style': [{ outline: ['', ...getLineStyles()] }], + 'outline-style': [{ outline: ['', 'hidden', ...getLineStyles()] }], /** * Outline Offset * @see https://tailwindcss.com/docs/outline-offset @@ -1222,7 +1235,17 @@ export const getDefaultConfig = () => { * Box Shadow * @see https://tailwindcss.com/docs/box-shadow */ - shadow: [{ shadow: ['none', isTshirtSize, isArbitraryShadow] }], + shadow: [ + { + shadow: [ + // Deprecated since Tailwind CSS v4.0.0 + '', + 'none', + isTshirtSize, + isArbitraryShadow, + ], + }, + ], /** * Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color @@ -1320,7 +1343,17 @@ export const getDefaultConfig = () => { * Drop Shadow * @see https://tailwindcss.com/docs/drop-shadow */ - 'drop-shadow': [{ 'drop-shadow': ['', 'none', isTshirtSize, isArbitraryValue] }], + 'drop-shadow': [ + { + 'drop-shadow': [ + // Deprecated since Tailwind CSS v4.0.0 + '', + 'none', + isTshirtSize, + isArbitraryValue, + ], + }, + ], /** * Grayscale * @see https://tailwindcss.com/docs/grayscale From ddc6ae856d04537bc766c4ff9c796cc490a3e44c Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 13:09:55 +0100 Subject: [PATCH 17/48] add support for arbitrary custom properties (CSS variables) and re-architect tailwind-merge config --- src/lib/default-config.ts | 1178 ++++++++++++++++++-------------- src/lib/parse-class-name.ts | 7 +- src/lib/types.ts | 49 +- src/lib/validators.ts | 113 ++- tests/arbitrary-values.test.ts | 13 +- tests/class-map.test.ts | 9 +- tests/public-api.test.ts | 19 +- tests/theme.test.ts | 6 +- tests/validators.test.ts | 323 +++++---- 9 files changed, 1015 insertions(+), 702 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 4f3f6350..da8a1977 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -2,6 +2,7 @@ import { fromTheme } from './from-theme' import { Config, DefaultClassGroupIds, DefaultThemeGroupIds } from './types' import { isAny, + isAnyNonArbitrary, isArbitraryImage, isArbitraryLength, isArbitraryNumber, @@ -9,47 +10,47 @@ import { isArbitraryShadow, isArbitrarySize, isArbitraryValue, + isArbitraryVariable, + isArbitraryVariableFamilyName, + isArbitraryVariableImage, + isArbitraryVariableLength, + isArbitraryVariablePosition, + isArbitraryVariableShadow, + isArbitraryVariableSize, + isFraction, isInteger, - isLength, isNumber, isPercent, isTshirtSize, } from './validators' export const getDefaultConfig = () => { - const colors = fromTheme('colors') + // Theme getters for theme variable namespaces: https://tailwindcss.com/docs/theme#theme-variable-namespaces + + const color = fromTheme('color') + const font = fromTheme('font') + const text = fromTheme('text') + const fontWeight = fromTheme('font-weight') + const tracking = fromTheme('tracking') + const leading = fromTheme('leading') + const breakpoint = fromTheme('breakpoint') + const container = fromTheme('container') const spacing = fromTheme('spacing') + const radius = fromTheme('radius') + const shadow = fromTheme('shadow') + const insetShadow = fromTheme('inset-shadow') + const dropShadow = fromTheme('drop-shadow') const blur = fromTheme('blur') - const brightness = fromTheme('brightness') - const borderColor = fromTheme('borderColor') - const borderRadius = fromTheme('borderRadius') - const borderSpacing = fromTheme('borderSpacing') - const borderWidth = fromTheme('borderWidth') - const contrast = fromTheme('contrast') - const grayscale = fromTheme('grayscale') - const hueRotate = fromTheme('hueRotate') - const invert = fromTheme('invert') - const gap = fromTheme('gap') - const gradientColorStops = fromTheme('gradientColorStops') - const gradientColorStopPositions = fromTheme('gradientColorStopPositions') - const inset = fromTheme('inset') - const margin = fromTheme('margin') - const opacity = fromTheme('opacity') - const padding = fromTheme('padding') - const saturate = fromTheme('saturate') - const scale = fromTheme('scale') - const sepia = fromTheme('sepia') - const skew = fromTheme('skew') - const space = fromTheme('space') - const translate = fromTheme('translate') + const perspective = fromTheme('perspective') + const aspect = fromTheme('aspect') + const ease = fromTheme('ease') + const animate = fromTheme('animate') + + // Helpers to avoid repeating the same values - const getOverscroll = () => ['auto', 'contain', 'none'] as const - const getOverflow = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const - const getSpacingWithAutoAndArbitrary = () => ['auto', isArbitraryValue, spacing] as const - const getSpacingWithArbitrary = () => [isArbitraryValue, spacing] as const - const getNumberWithEmptyAndArbitrary = () => ['', isNumber, isArbitraryLength] as const - const getNumberWithAutoAndArbitrary = () => ['auto', isNumber, isArbitraryValue] as const - const getPositions = () => + const getBreakScale = () => + ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const + const getPositionScale = () => [ 'bottom', 'center', @@ -61,8 +62,54 @@ export const getDefaultConfig = () => { 'right-top', 'top', ] as const - const getLineStyles = () => ['solid', 'dashed', 'dotted', 'double', 'none'] as const - const getBlendModes = () => + const getOverflowScale = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const + const getOverscrollScale = () => ['auto', 'contain', 'none'] as const + const getInsetScale = () => + [isFraction, 'px', 'full', 'auto', isArbitraryVariable, isArbitraryValue, spacing] as const + const getGridTemplateColsRowsScale = () => + [isInteger, 'none', 'subgrid', isArbitraryVariable, isArbitraryValue] as const + const getGridColRowStartAndEndScale = () => + [ + 'auto', + { span: ['full', isInteger, isArbitraryVariable, isArbitraryValue] }, + isArbitraryVariable, + isArbitraryValue, + ] as const + const getGridColRowStartOrEndScale = () => + [isInteger, 'auto', isArbitraryVariable, isArbitraryValue] as const + const getGridAutoColsRowsScale = () => + ['auto', 'min', 'max', 'fr', isArbitraryVariable, isArbitraryValue] as const + const getGapScale = () => [isArbitraryVariable, isArbitraryValue, spacing] as const + const getAlignPrimaryAxisScale = () => + ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch', 'baseline'] as const + const getAlignSecondaryAxisScale = () => ['start', 'end', 'center', 'stretch'] as const + const getUnambiguousSpacingScale = () => + [isArbitraryVariable, isArbitraryValue, spacing] as const + const getMarginScale = () => ['auto', ...getUnambiguousSpacingScale()] as const + const getSizingScale = () => + [ + isFraction, + 'auto', + 'px', + 'full', + 'dvw', + 'dvh', + 'lvw', + 'lvh', + 'svw', + 'svh', + 'min', + 'max', + 'fit', + isArbitraryVariable, + isArbitraryValue, + spacing, + ] as const + const getGradientStopPositionScale = () => [isPercent, isArbitraryLength] as const + const getBorderWidthScale = () => + ['', isNumber, isArbitraryVariableLength, isArbitraryLength] as const + const getLineStyleScale = () => ['solid', 'dashed', 'dotted', 'double'] as const + const getBlendModeScale = () => [ 'normal', 'multiply', @@ -81,84 +128,123 @@ export const getDefaultConfig = () => { 'color', 'luminosity', ] as const - const getAlign = () => - ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch'] as const - const getZeroAndEmpty = () => ['', '0', isArbitraryValue] as const - const getBreaks = () => - ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const - const getNumberAndArbitrary = () => [isNumber, isArbitraryValue] - const getRotate = () => ['none', isInteger, isArbitraryValue] + const getOriginScale = () => + [ + 'center', + 'top', + 'top-right', + 'right', + 'bottom-right', + 'bottom', + 'bottom-left', + 'left', + 'top-left', + isArbitraryVariable, + isArbitraryValue, + ] as const + const getRotateScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const + const getScaleScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const + const getSkewScale = () => [isNumber, isArbitraryVariable, isArbitraryValue] as const + const getTranslateScale = () => + [isFraction, 'full', 'px', isArbitraryVariable, isArbitraryValue, spacing] as const return { cacheSize: 500, separator: ':', theme: { - colors: [isAny], - spacing: [isLength, isArbitraryLength], - blur: [ - 'none', + color: [isAny], + font: [isAnyNonArbitrary, isArbitraryVariableFamilyName, isArbitraryValue], + text: ['base', isTshirtSize, isArbitraryVariableLength, isArbitraryLength], + 'font-weight': [ + 'thin', + 'extralight', + 'light', + 'normal', + 'medium', + 'semibold', + 'bold', + 'extrabold', + 'black', + ], + tracking: ['tighter', 'tight', 'normal', 'wide', 'wider', 'widest'], + leading: ['none', 'tight', 'snug', 'normal', 'relaxed', 'loose'], + breakpoint: [isTshirtSize], + container: [isTshirtSize], + spacing: [isNumber, isArbitraryVariableLength, isArbitraryLength], + radius: [ // Deprecated since Tailwind CSS v4.0.0 '', isTshirtSize, + 'none', + 'full', + isArbitraryVariable, isArbitraryValue, ], - brightness: getNumberAndArbitrary(), - borderColor: [colors], - borderRadius: [ + shadow: [isTshirtSize, 'none', isArbitraryVariableShadow, isArbitraryShadow], + 'inset-shadow': [isTshirtSize], + 'drop-shadow': [ + // Deprecated since Tailwind CSS v4.0.0 + '', + isTshirtSize, 'none', + isArbitraryVariable, + isArbitraryValue, + ], + blur: [ // Deprecated since Tailwind CSS v4.0.0 '', - 'full', isTshirtSize, + 'none', + isArbitraryVariable, isArbitraryValue, ], - borderSpacing: getSpacingWithArbitrary(), - borderWidth: getNumberWithEmptyAndArbitrary(), - contrast: getNumberAndArbitrary(), - grayscale: getZeroAndEmpty(), - hueRotate: getNumberAndArbitrary(), - invert: getZeroAndEmpty(), - gap: getSpacingWithArbitrary(), - gradientColorStops: [colors], - gradientColorStopPositions: [isPercent, isArbitraryLength], - inset: getSpacingWithAutoAndArbitrary(), - margin: getSpacingWithAutoAndArbitrary(), - opacity: getNumberAndArbitrary(), - padding: getSpacingWithArbitrary(), - saturate: getNumberAndArbitrary(), - scale: getNumberAndArbitrary(), - sepia: getZeroAndEmpty(), - skew: getNumberAndArbitrary(), - space: getSpacingWithArbitrary(), - translate: getSpacingWithArbitrary(), + perspective: ['dramatic', 'near', 'normal', 'midrange', 'distant', 'none'], + aspect: ['video'], + ease: ['in', 'out', 'in-out'], + animate: ['spin', 'ping', 'pulse', 'bounce'], }, classGroups: { - // Layout + // -------------- + // --- Layout --- + // -------------- + /** * Aspect Ratio * @see https://tailwindcss.com/docs/aspect-ratio */ - aspect: [{ aspect: ['auto', 'square', 'video', isArbitraryValue] }], + aspect: [ + { + aspect: [ + 'auto', + 'square', + isFraction, + isArbitraryValue, + isArbitraryVariable, + aspect, + ], + }, + ], /** * Container * @see https://tailwindcss.com/docs/container + * @deprecated since Tailwind CSS v4.0.0 */ container: ['container'], /** * Columns * @see https://tailwindcss.com/docs/columns */ - columns: [{ columns: [isTshirtSize] }], + columns: [{ columns: [isNumber, isArbitraryValue, isArbitraryVariable, container] }], /** * Break After * @see https://tailwindcss.com/docs/break-after */ - 'break-after': [{ 'break-after': getBreaks() }], + 'break-after': [{ 'break-after': getBreakScale() }], /** * Break Before * @see https://tailwindcss.com/docs/break-before */ - 'break-before': [{ 'break-before': getBreaks() }], + 'break-before': [{ 'break-before': getBreakScale() }], /** * Break Inside * @see https://tailwindcss.com/docs/break-inside @@ -201,6 +287,11 @@ export const getDefaultConfig = () => { 'list-item', 'hidden', ], + /** + * Screen Reader Only + * @see https://tailwindcss.com/docs/display#screen-reader-only + */ + sr: ['sr-only', 'not-sr-only'], /** * Floats * @see https://tailwindcss.com/docs/float @@ -225,37 +316,39 @@ export const getDefaultConfig = () => { * Object Position * @see https://tailwindcss.com/docs/object-position */ - 'object-position': [{ object: [...getPositions(), isArbitraryValue] }], + 'object-position': [ + { object: [...getPositionScale(), isArbitraryValue, isArbitraryVariable] }, + ], /** * Overflow * @see https://tailwindcss.com/docs/overflow */ - overflow: [{ overflow: getOverflow() }], + overflow: [{ overflow: getOverflowScale() }], /** * Overflow X * @see https://tailwindcss.com/docs/overflow */ - 'overflow-x': [{ 'overflow-x': getOverflow() }], + 'overflow-x': [{ 'overflow-x': getOverflowScale() }], /** * Overflow Y * @see https://tailwindcss.com/docs/overflow */ - 'overflow-y': [{ 'overflow-y': getOverflow() }], + 'overflow-y': [{ 'overflow-y': getOverflowScale() }], /** * Overscroll Behavior * @see https://tailwindcss.com/docs/overscroll-behavior */ - overscroll: [{ overscroll: getOverscroll() }], + overscroll: [{ overscroll: getOverscrollScale() }], /** * Overscroll Behavior X * @see https://tailwindcss.com/docs/overscroll-behavior */ - 'overscroll-x': [{ 'overscroll-x': getOverscroll() }], + 'overscroll-x': [{ 'overscroll-x': getOverscrollScale() }], /** * Overscroll Behavior Y * @see https://tailwindcss.com/docs/overscroll-behavior */ - 'overscroll-y': [{ 'overscroll-y': getOverscroll() }], + 'overscroll-y': [{ 'overscroll-y': getOverscrollScale() }], /** * Position * @see https://tailwindcss.com/docs/position @@ -265,47 +358,47 @@ export const getDefaultConfig = () => { * Top / Right / Bottom / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - inset: [{ inset: [inset] }], + inset: [{ inset: getInsetScale() }], /** * Right / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - 'inset-x': [{ 'inset-x': [inset] }], + 'inset-x': [{ 'inset-x': getInsetScale() }], /** * Top / Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ - 'inset-y': [{ 'inset-y': [inset] }], + 'inset-y': [{ 'inset-y': getInsetScale() }], /** * Start * @see https://tailwindcss.com/docs/top-right-bottom-left */ - start: [{ start: [inset] }], + start: [{ start: getInsetScale() }], /** * End * @see https://tailwindcss.com/docs/top-right-bottom-left */ - end: [{ end: [inset] }], + end: [{ end: getInsetScale() }], /** * Top * @see https://tailwindcss.com/docs/top-right-bottom-left */ - top: [{ top: [inset] }], + top: [{ top: getInsetScale() }], /** * Right * @see https://tailwindcss.com/docs/top-right-bottom-left */ - right: [{ right: [inset] }], + right: [{ right: getInsetScale() }], /** * Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ - bottom: [{ bottom: [inset] }], + bottom: [{ bottom: getInsetScale() }], /** * Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - left: [{ left: [inset] }], + left: [{ left: getInsetScale() }], /** * Visibility * @see https://tailwindcss.com/docs/visibility @@ -315,13 +408,29 @@ export const getDefaultConfig = () => { * Z-Index * @see https://tailwindcss.com/docs/z-index */ - z: [{ z: ['auto', isInteger, isArbitraryValue] }], - // Flexbox and Grid + z: [{ z: [isInteger, 'auto', isArbitraryVariable, isArbitraryValue] }], + + // ------------------------ + // --- Flexbox and Grid --- + // ------------------------ + /** * Flex Basis * @see https://tailwindcss.com/docs/flex-basis */ - basis: [{ basis: getSpacingWithAutoAndArbitrary() }], + basis: [ + { + basis: [ + isFraction, + 'full', + 'auto', + isArbitraryVariable, + isArbitraryValue, + container, + spacing, + ], + }, + ], /** * Flex Direction * @see https://tailwindcss.com/docs/flex-direction @@ -331,77 +440,78 @@ export const getDefaultConfig = () => { * Flex Wrap * @see https://tailwindcss.com/docs/flex-wrap */ - 'flex-wrap': [{ flex: ['wrap', 'wrap-reverse', 'nowrap'] }], + 'flex-wrap': [{ flex: ['nowrap', 'wrap', 'wrap-reverse'] }], /** * Flex * @see https://tailwindcss.com/docs/flex */ - flex: [{ flex: ['1', 'auto', 'initial', 'none', isArbitraryValue] }], + flex: [{ flex: [isNumber, isFraction, 'auto', 'initial', 'none', isArbitraryValue] }], /** * Flex Grow * @see https://tailwindcss.com/docs/flex-grow */ - grow: [{ grow: getZeroAndEmpty() }], + grow: [{ grow: ['', isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Flex Shrink * @see https://tailwindcss.com/docs/flex-shrink */ - shrink: [{ shrink: getZeroAndEmpty() }], + shrink: [{ shrink: ['', isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Order * @see https://tailwindcss.com/docs/order */ - order: [{ order: ['first', 'last', 'none', isInteger, isArbitraryValue] }], + order: [ + { + order: [ + isInteger, + 'first', + 'last', + 'none', + isArbitraryVariable, + isArbitraryValue, + ], + }, + ], /** * Grid Template Columns * @see https://tailwindcss.com/docs/grid-template-columns */ - 'grid-cols': [{ 'grid-cols': [isAny] }], + 'grid-cols': [{ 'grid-cols': getGridTemplateColsRowsScale() }], /** * Grid Column Start / End * @see https://tailwindcss.com/docs/grid-column */ - 'col-start-end': [ - { - col: [ - 'auto', - { span: ['full', isInteger, isArbitraryValue] }, - isArbitraryValue, - ], - }, - ], + 'col-start-end': [{ col: getGridColRowStartAndEndScale() }], /** * Grid Column Start * @see https://tailwindcss.com/docs/grid-column */ - 'col-start': [{ 'col-start': getNumberWithAutoAndArbitrary() }], + 'col-start': [{ 'col-start': getGridColRowStartOrEndScale() }], /** * Grid Column End * @see https://tailwindcss.com/docs/grid-column */ - 'col-end': [{ 'col-end': getNumberWithAutoAndArbitrary() }], + 'col-end': [{ 'col-end': getGridColRowStartOrEndScale() }], /** * Grid Template Rows * @see https://tailwindcss.com/docs/grid-template-rows */ - 'grid-rows': [{ 'grid-rows': [isAny] }], + 'grid-rows': [{ 'grid-rows': getGridTemplateColsRowsScale() }], /** * Grid Row Start / End * @see https://tailwindcss.com/docs/grid-row */ - 'row-start-end': [ - { row: ['auto', { span: [isInteger, isArbitraryValue] }, isArbitraryValue] }, - ], + 'row-start-end': [{ row: getGridColRowStartAndEndScale() }], /** * Grid Row Start * @see https://tailwindcss.com/docs/grid-row */ - 'row-start': [{ 'row-start': getNumberWithAutoAndArbitrary() }], + 'row-start': [{ 'row-start': getGridColRowStartOrEndScale() }], /** * Grid Row End * @see https://tailwindcss.com/docs/grid-row */ - 'row-end': [{ 'row-end': getNumberWithAutoAndArbitrary() }], + 'row-end': [{ 'row-end': getGridColRowStartOrEndScale() }], /** * Grid Auto Flow * @see https://tailwindcss.com/docs/grid-auto-flow @@ -411,208 +521,203 @@ export const getDefaultConfig = () => { * Grid Auto Columns * @see https://tailwindcss.com/docs/grid-auto-columns */ - 'auto-cols': [{ 'auto-cols': ['auto', 'min', 'max', 'fr', isArbitraryValue] }], + 'auto-cols': [{ 'auto-cols': getGridAutoColsRowsScale() }], /** * Grid Auto Rows * @see https://tailwindcss.com/docs/grid-auto-rows */ - 'auto-rows': [{ 'auto-rows': ['auto', 'min', 'max', 'fr', isArbitraryValue] }], + 'auto-rows': [{ 'auto-rows': getGridAutoColsRowsScale() }], /** * Gap * @see https://tailwindcss.com/docs/gap */ - gap: [{ gap: [gap] }], + gap: [{ gap: getGapScale() }], /** * Gap X * @see https://tailwindcss.com/docs/gap */ - 'gap-x': [{ 'gap-x': [gap] }], + 'gap-x': [{ 'gap-x': getGapScale() }], /** * Gap Y * @see https://tailwindcss.com/docs/gap */ - 'gap-y': [{ 'gap-y': [gap] }], + 'gap-y': [{ 'gap-y': getGapScale() }], /** * Justify Content * @see https://tailwindcss.com/docs/justify-content */ - 'justify-content': [{ justify: ['normal', ...getAlign()] }], + 'justify-content': [{ justify: [...getAlignPrimaryAxisScale(), 'normal'] }], /** * Justify Items * @see https://tailwindcss.com/docs/justify-items */ - 'justify-items': [{ 'justify-items': ['start', 'end', 'center', 'stretch'] }], + 'justify-items': [{ 'justify-items': [...getAlignSecondaryAxisScale(), 'normal'] }], /** * Justify Self * @see https://tailwindcss.com/docs/justify-self */ - 'justify-self': [{ 'justify-self': ['auto', 'start', 'end', 'center', 'stretch'] }], + 'justify-self': [{ 'justify-self': ['auto', ...getAlignSecondaryAxisScale()] }], /** * Align Content * @see https://tailwindcss.com/docs/align-content */ - 'align-content': [{ content: ['normal', ...getAlign(), 'baseline'] }], + 'align-content': [{ content: ['normal', ...getAlignPrimaryAxisScale()] }], /** * Align Items * @see https://tailwindcss.com/docs/align-items */ - 'align-items': [{ items: ['start', 'end', 'center', 'baseline', 'stretch'] }], + 'align-items': [{ items: [...getAlignSecondaryAxisScale(), 'baseline'] }], /** * Align Self * @see https://tailwindcss.com/docs/align-self */ - 'align-self': [{ self: ['auto', 'start', 'end', 'center', 'stretch', 'baseline'] }], + 'align-self': [{ self: ['auto', ...getAlignSecondaryAxisScale(), 'baseline'] }], /** * Place Content * @see https://tailwindcss.com/docs/place-content */ - 'place-content': [{ 'place-content': [...getAlign(), 'baseline'] }], + 'place-content': [{ 'place-content': getAlignPrimaryAxisScale() }], /** * Place Items * @see https://tailwindcss.com/docs/place-items */ - 'place-items': [{ 'place-items': ['start', 'end', 'center', 'baseline', 'stretch'] }], + 'place-items': [{ 'place-items': [...getAlignSecondaryAxisScale(), 'baseline'] }], /** * Place Self * @see https://tailwindcss.com/docs/place-self */ - 'place-self': [{ 'place-self': ['auto', 'start', 'end', 'center', 'stretch'] }], + 'place-self': [{ 'place-self': ['auto', ...getAlignSecondaryAxisScale()] }], // Spacing /** * Padding * @see https://tailwindcss.com/docs/padding */ - p: [{ p: [padding] }], + p: [{ p: getUnambiguousSpacingScale() }], /** * Padding X * @see https://tailwindcss.com/docs/padding */ - px: [{ px: [padding] }], + px: [{ px: getUnambiguousSpacingScale() }], /** * Padding Y * @see https://tailwindcss.com/docs/padding */ - py: [{ py: [padding] }], + py: [{ py: getUnambiguousSpacingScale() }], /** * Padding Start * @see https://tailwindcss.com/docs/padding */ - ps: [{ ps: [padding] }], + ps: [{ ps: getUnambiguousSpacingScale() }], /** * Padding End * @see https://tailwindcss.com/docs/padding */ - pe: [{ pe: [padding] }], + pe: [{ pe: getUnambiguousSpacingScale() }], /** * Padding Top * @see https://tailwindcss.com/docs/padding */ - pt: [{ pt: [padding] }], + pt: [{ pt: getUnambiguousSpacingScale() }], /** * Padding Right * @see https://tailwindcss.com/docs/padding */ - pr: [{ pr: [padding] }], + pr: [{ pr: getUnambiguousSpacingScale() }], /** * Padding Bottom * @see https://tailwindcss.com/docs/padding */ - pb: [{ pb: [padding] }], + pb: [{ pb: getUnambiguousSpacingScale() }], /** * Padding Left * @see https://tailwindcss.com/docs/padding */ - pl: [{ pl: [padding] }], + pl: [{ pl: getUnambiguousSpacingScale() }], /** * Margin * @see https://tailwindcss.com/docs/margin */ - m: [{ m: [margin] }], + m: [{ m: getMarginScale() }], /** * Margin X * @see https://tailwindcss.com/docs/margin */ - mx: [{ mx: [margin] }], + mx: [{ mx: getMarginScale() }], /** * Margin Y * @see https://tailwindcss.com/docs/margin */ - my: [{ my: [margin] }], + my: [{ my: getMarginScale() }], /** * Margin Start * @see https://tailwindcss.com/docs/margin */ - ms: [{ ms: [margin] }], + ms: [{ ms: getMarginScale() }], /** * Margin End * @see https://tailwindcss.com/docs/margin */ - me: [{ me: [margin] }], + me: [{ me: getMarginScale() }], /** * Margin Top * @see https://tailwindcss.com/docs/margin */ - mt: [{ mt: [margin] }], + mt: [{ mt: getMarginScale() }], /** * Margin Right * @see https://tailwindcss.com/docs/margin */ - mr: [{ mr: [margin] }], + mr: [{ mr: getMarginScale() }], /** * Margin Bottom * @see https://tailwindcss.com/docs/margin */ - mb: [{ mb: [margin] }], + mb: [{ mb: getMarginScale() }], /** * Margin Left * @see https://tailwindcss.com/docs/margin */ - ml: [{ ml: [margin] }], + ml: [{ ml: getMarginScale() }], /** * Space Between X - * @see https://tailwindcss.com/docs/space + * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ - 'space-x': [{ 'space-x': [space] }], + 'space-x': [{ 'space-x': getUnambiguousSpacingScale() }], /** * Space Between X Reverse - * @see https://tailwindcss.com/docs/space + * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ 'space-x-reverse': ['space-x-reverse'], /** * Space Between Y - * @see https://tailwindcss.com/docs/space + * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ - 'space-y': [{ 'space-y': [space] }], + 'space-y': [{ 'space-y': getUnambiguousSpacingScale() }], /** * Space Between Y Reverse - * @see https://tailwindcss.com/docs/space + * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ 'space-y-reverse': ['space-y-reverse'], - // Sizing + + // -------------- + // --- Sizing --- + // -------------- + /** * Width * @see https://tailwindcss.com/docs/width */ - w: [ - { - w: [ - 'auto', - 'min', - 'max', - 'fit', - 'svw', - 'lvw', - 'dvw', - isArbitraryValue, - spacing, - ], - }, - ], + /** + * Size + * @see https://tailwindcss.com/docs/width#setting-both-width-and-height + */ + size: [{ size: getSizingScale() }], + w: [{ w: [container, 'screen', ...getSizingScale()] }], /** * Min-Width * @see https://tailwindcss.com/docs/min-width */ - 'min-w': [{ 'min-w': [isArbitraryValue, spacing, 'min', 'max', 'fit'] }], + 'min-w': [{ 'min-w': [container, 'screen', 'none', ...getSizingScale()] }], /** * Max-Width * @see https://tailwindcss.com/docs/max-width @@ -620,16 +725,12 @@ export const getDefaultConfig = () => { 'max-w': [ { 'max-w': [ - isArbitraryValue, - spacing, + container, + 'screen', 'none', - 'full', - 'min', - 'max', - 'fit', 'prose', - { screen: [isTshirtSize] }, - isTshirtSize, + { screen: [breakpoint] }, + ...getSizingScale(), ], }, ], @@ -637,46 +738,27 @@ export const getDefaultConfig = () => { * Height * @see https://tailwindcss.com/docs/height */ - h: [ - { - h: [ - isArbitraryValue, - spacing, - 'auto', - 'min', - 'max', - 'fit', - 'svh', - 'lvh', - 'dvh', - ], - }, - ], + h: [{ h: ['screen', ...getSizingScale()] }], /** * Min-Height * @see https://tailwindcss.com/docs/min-height */ - 'min-h': [ - { 'min-h': [isArbitraryValue, spacing, 'min', 'max', 'fit', 'svh', 'lvh', 'dvh'] }, - ], + 'min-h': [{ 'min-h': ['screen', 'none', ...getSizingScale()] }], /** * Max-Height * @see https://tailwindcss.com/docs/max-height */ - 'max-h': [ - { 'max-h': [isArbitraryValue, spacing, 'min', 'max', 'fit', 'svh', 'lvh', 'dvh'] }, - ], - /** - * Size - * @see https://tailwindcss.com/docs/size - */ - size: [{ size: [isArbitraryValue, spacing, 'auto', 'min', 'max', 'fit'] }], - // Typography + 'max-h': [{ 'max-h': ['screen', ...getSizingScale()] }], + + // ------------------ + // --- Typography --- + // ------------------ + /** * Font Size * @see https://tailwindcss.com/docs/font-size */ - 'font-size': [{ text: ['base', isTshirtSize, isArbitraryLength] }], + 'font-size': [{ text: [text] }], /** * Font Smoothing * @see https://tailwindcss.com/docs/font-smoothing @@ -691,22 +773,7 @@ export const getDefaultConfig = () => { * Font Weight * @see https://tailwindcss.com/docs/font-weight */ - 'font-weight': [ - { - font: [ - 'thin', - 'extralight', - 'light', - 'normal', - 'medium', - 'semibold', - 'bold', - 'extrabold', - 'black', - isArbitraryNumber, - ], - }, - ], + 'font-weight': [{ font: [fontWeight, isArbitraryVariable, isArbitraryNumber] }], /** * Font Stretch * @see https://tailwindcss.com/docs/font-stretch @@ -732,7 +799,7 @@ export const getDefaultConfig = () => { * Font Family * @see https://tailwindcss.com/docs/font-family */ - 'font-family': [{ font: [isAny] }], + 'font-family': [{ font: [font] }], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font-variant-numeric @@ -767,73 +834,52 @@ export const getDefaultConfig = () => { * Letter Spacing * @see https://tailwindcss.com/docs/letter-spacing */ - tracking: [ - { - tracking: [ - 'tighter', - 'tight', - 'normal', - 'wide', - 'wider', - 'widest', - isArbitraryValue, - ], - }, - ], + tracking: [{ tracking: [tracking, isArbitraryVariable, isArbitraryValue] }], /** * Line Clamp * @see https://tailwindcss.com/docs/line-clamp */ - 'line-clamp': [{ 'line-clamp': ['none', isNumber, isArbitraryNumber] }], + 'line-clamp': [ + { 'line-clamp': [isNumber, 'none', isArbitraryVariable, isArbitraryNumber] }, + ], /** * Line Height * @see https://tailwindcss.com/docs/line-height */ - leading: [ - { - leading: [ - 'none', - 'tight', - 'snug', - 'normal', - 'relaxed', - 'loose', - isLength, - isArbitraryValue, - ], - }, - ], + leading: [{ leading: [isArbitraryVariable, isArbitraryValue, leading, spacing] }], /** * List Style Image * @see https://tailwindcss.com/docs/list-style-image */ - 'list-image': [{ 'list-image': ['none', isArbitraryValue] }], - /** - * List Style Type - * @see https://tailwindcss.com/docs/list-style-type - */ - 'list-style-type': [{ list: ['none', 'disc', 'decimal', isArbitraryValue] }], + 'list-image': [{ 'list-image': ['none', isArbitraryVariable, isArbitraryValue] }], /** * List Style Position * @see https://tailwindcss.com/docs/list-style-position */ 'list-style-position': [{ list: ['inside', 'outside'] }], /** - * Placeholder Color - * @deprecated since Tailwind CSS v3.0.0 - * @see https://tailwindcss.com/docs/placeholder-color + * List Style Type + * @see https://tailwindcss.com/docs/list-style-type */ - 'placeholder-color': [{ placeholder: [colors] }], + 'list-style-type': [ + { list: ['disc', 'decimal', 'none', isArbitraryVariable, isArbitraryValue] }, + ], /** * Text Alignment * @see https://tailwindcss.com/docs/text-align */ 'text-alignment': [{ text: ['left', 'center', 'right', 'justify', 'start', 'end'] }], + /** + * Placeholder Color + * @deprecated since Tailwind CSS v3.0.0 + * @see https://v3.tailwindcss.com/docs/placeholder-color + */ + 'placeholder-color': [{ placeholder: [color] }], /** * Text Color * @see https://tailwindcss.com/docs/text-color */ - 'text-color': [{ text: [colors] }], + 'text-color': [{ text: [color] }], /** * Text Decoration * @see https://tailwindcss.com/docs/text-decoration @@ -843,24 +889,34 @@ export const getDefaultConfig = () => { * Text Decoration Style * @see https://tailwindcss.com/docs/text-decoration-style */ - 'text-decoration-style': [{ decoration: [...getLineStyles(), 'wavy'] }], + 'text-decoration-style': [{ decoration: [...getLineStyleScale(), 'wavy'] }], /** * Text Decoration Thickness * @see https://tailwindcss.com/docs/text-decoration-thickness */ 'text-decoration-thickness': [ - { decoration: ['auto', 'from-font', isLength, isArbitraryLength] }, + { + decoration: [ + isNumber, + 'from-font', + 'auto', + isArbitraryVariable, + isArbitraryLength, + ], + }, ], - /** - * Text Underline Offset - * @see https://tailwindcss.com/docs/text-underline-offset - */ - 'underline-offset': [{ 'underline-offset': ['auto', isLength, isArbitraryValue] }], /** * Text Decoration Color * @see https://tailwindcss.com/docs/text-decoration-color */ - 'text-decoration-color': [{ decoration: [colors] }], + 'text-decoration-color': [{ decoration: [color] }], + /** + * Text Underline Offset + * @see https://tailwindcss.com/docs/text-underline-offset + */ + 'underline-offset': [ + { 'underline-offset': [isNumber, 'auto', isArbitraryVariable, isArbitraryValue] }, + ], /** * Text Transform * @see https://tailwindcss.com/docs/text-transform @@ -880,7 +936,7 @@ export const getDefaultConfig = () => { * Text Indent * @see https://tailwindcss.com/docs/text-indent */ - indent: [{ indent: getSpacingWithArbitrary() }], + indent: [{ indent: ['px', ...getUnambiguousSpacingScale()] }], /** * Vertical Alignment * @see https://tailwindcss.com/docs/vertical-align @@ -896,6 +952,7 @@ export const getDefaultConfig = () => { 'text-bottom', 'sub', 'super', + isArbitraryVariable, isArbitraryValue, ], }, @@ -921,8 +978,12 @@ export const getDefaultConfig = () => { * Content * @see https://tailwindcss.com/docs/content */ - content: [{ content: ['none', isArbitraryValue] }], - // Backgrounds + content: [{ content: ['none', isArbitraryVariable, isArbitraryValue] }], + + // ------------------- + // --- Backgrounds --- + // ------------------- + /** * Background Attachment * @see https://tailwindcss.com/docs/background-attachment @@ -942,17 +1003,21 @@ export const getDefaultConfig = () => { * Background Position * @see https://tailwindcss.com/docs/background-position */ - 'bg-position': [{ bg: [...getPositions(), isArbitraryPosition] }], + 'bg-position': [ + { bg: [...getPositionScale(), isArbitraryVariablePosition, isArbitraryPosition] }, + ], /** * Background Repeat * @see https://tailwindcss.com/docs/background-repeat */ - 'bg-repeat': [{ bg: ['no-repeat', { repeat: ['', 'x', 'y', 'round', 'space'] }] }], + 'bg-repeat': [{ bg: ['no-repeat', { repeat: ['', 'x', 'y', 'space', 'round'] }] }], /** * Background Size * @see https://tailwindcss.com/docs/background-size */ - 'bg-size': [{ bg: ['auto', 'cover', 'contain', isArbitrarySize] }], + 'bg-size': [ + { bg: ['auto', 'cover', 'contain', isArbitraryVariableSize, isArbitrarySize] }, + ], /** * Background Image * @see https://tailwindcss.com/docs/background-image @@ -965,11 +1030,13 @@ export const getDefaultConfig = () => { linear: [ { to: ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl'] }, isInteger, + isArbitraryVariable, isArbitraryValue, ], - radial: ['', isArbitraryValue], - conic: [isInteger, isArbitraryValue], + radial: ['', isArbitraryVariable, isArbitraryValue], + conic: [isInteger, isArbitraryVariable, isArbitraryValue], }, + isArbitraryVariableImage, isArbitraryImage, ], }, @@ -978,259 +1045,271 @@ export const getDefaultConfig = () => { * Background Color * @see https://tailwindcss.com/docs/background-color */ - 'bg-color': [{ bg: [colors] }], + 'bg-color': [{ bg: [color] }], /** * Gradient Color Stops From Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from-pos': [{ from: [gradientColorStopPositions] }], + 'gradient-from-pos': [{ from: getGradientStopPositionScale() }], /** * Gradient Color Stops Via Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via-pos': [{ via: [gradientColorStopPositions] }], + 'gradient-via-pos': [{ via: getGradientStopPositionScale() }], /** * Gradient Color Stops To Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to-pos': [{ to: [gradientColorStopPositions] }], + 'gradient-to-pos': [{ to: getGradientStopPositionScale() }], /** * Gradient Color Stops From * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from': [{ from: [gradientColorStops] }], + 'gradient-from': [{ from: [color] }], /** * Gradient Color Stops Via * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via': [{ via: [gradientColorStops] }], + 'gradient-via': [{ via: [color] }], /** * Gradient Color Stops To * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to': [{ to: [gradientColorStops] }], - // Borders + 'gradient-to': [{ to: [color] }], + + // --------------- + // --- Borders --- + // --------------- + /** * Border Radius * @see https://tailwindcss.com/docs/border-radius */ - rounded: [{ rounded: [borderRadius] }], + rounded: [{ rounded: [radius] }], /** * Border Radius Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-s': [{ 'rounded-s': [borderRadius] }], + 'rounded-s': [{ 'rounded-s': [radius] }], /** * Border Radius End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-e': [{ 'rounded-e': [borderRadius] }], + 'rounded-e': [{ 'rounded-e': [radius] }], /** * Border Radius Top * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-t': [{ 'rounded-t': [borderRadius] }], + 'rounded-t': [{ 'rounded-t': [radius] }], /** * Border Radius Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-r': [{ 'rounded-r': [borderRadius] }], + 'rounded-r': [{ 'rounded-r': [radius] }], /** * Border Radius Bottom * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-b': [{ 'rounded-b': [borderRadius] }], + 'rounded-b': [{ 'rounded-b': [radius] }], /** * Border Radius Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-l': [{ 'rounded-l': [borderRadius] }], + 'rounded-l': [{ 'rounded-l': [radius] }], /** * Border Radius Start Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ss': [{ 'rounded-ss': [borderRadius] }], + 'rounded-ss': [{ 'rounded-ss': [radius] }], /** * Border Radius Start End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-se': [{ 'rounded-se': [borderRadius] }], + 'rounded-se': [{ 'rounded-se': [radius] }], /** * Border Radius End End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ee': [{ 'rounded-ee': [borderRadius] }], + 'rounded-ee': [{ 'rounded-ee': [radius] }], /** * Border Radius End Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-es': [{ 'rounded-es': [borderRadius] }], + 'rounded-es': [{ 'rounded-es': [radius] }], /** * Border Radius Top Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tl': [{ 'rounded-tl': [borderRadius] }], + 'rounded-tl': [{ 'rounded-tl': [radius] }], /** * Border Radius Top Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tr': [{ 'rounded-tr': [borderRadius] }], + 'rounded-tr': [{ 'rounded-tr': [radius] }], /** * Border Radius Bottom Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-br': [{ 'rounded-br': [borderRadius] }], + 'rounded-br': [{ 'rounded-br': [radius] }], /** * Border Radius Bottom Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-bl': [{ 'rounded-bl': [borderRadius] }], + 'rounded-bl': [{ 'rounded-bl': [radius] }], /** * Border Width * @see https://tailwindcss.com/docs/border-width */ - 'border-w': [{ border: [borderWidth] }], + 'border-w': [{ border: getBorderWidthScale() }], /** * Border Width X * @see https://tailwindcss.com/docs/border-width */ - 'border-w-x': [{ 'border-x': [borderWidth] }], + 'border-w-x': [{ 'border-x': getBorderWidthScale() }], /** * Border Width Y * @see https://tailwindcss.com/docs/border-width */ - 'border-w-y': [{ 'border-y': [borderWidth] }], + 'border-w-y': [{ 'border-y': getBorderWidthScale() }], /** * Border Width Start * @see https://tailwindcss.com/docs/border-width */ - 'border-w-s': [{ 'border-s': [borderWidth] }], + 'border-w-s': [{ 'border-s': getBorderWidthScale() }], /** * Border Width End * @see https://tailwindcss.com/docs/border-width */ - 'border-w-e': [{ 'border-e': [borderWidth] }], + 'border-w-e': [{ 'border-e': getBorderWidthScale() }], /** * Border Width Top * @see https://tailwindcss.com/docs/border-width */ - 'border-w-t': [{ 'border-t': [borderWidth] }], + 'border-w-t': [{ 'border-t': getBorderWidthScale() }], /** * Border Width Right * @see https://tailwindcss.com/docs/border-width */ - 'border-w-r': [{ 'border-r': [borderWidth] }], + 'border-w-r': [{ 'border-r': getBorderWidthScale() }], /** * Border Width Bottom * @see https://tailwindcss.com/docs/border-width */ - 'border-w-b': [{ 'border-b': [borderWidth] }], + 'border-w-b': [{ 'border-b': getBorderWidthScale() }], /** * Border Width Left * @see https://tailwindcss.com/docs/border-width */ - 'border-w-l': [{ 'border-l': [borderWidth] }], - /** - * Border Style - * @see https://tailwindcss.com/docs/border-style - */ - 'border-style': [{ border: [...getLineStyles(), 'hidden'] }], + 'border-w-l': [{ 'border-l': getBorderWidthScale() }], /** * Divide Width X - * @see https://tailwindcss.com/docs/divide-width + * @see https://tailwindcss.com/docs/border-width#between-children */ - 'divide-x': [{ 'divide-x': [borderWidth] }], + 'divide-x': [{ 'divide-x': getBorderWidthScale() }], /** * Divide Width X Reverse - * @see https://tailwindcss.com/docs/divide-width + * @see https://tailwindcss.com/docs/border-width#between-children */ 'divide-x-reverse': ['divide-x-reverse'], /** * Divide Width Y - * @see https://tailwindcss.com/docs/divide-width + * @see https://tailwindcss.com/docs/border-width#between-children */ - 'divide-y': [{ 'divide-y': [borderWidth] }], + 'divide-y': [{ 'divide-y': getBorderWidthScale() }], /** * Divide Width Y Reverse - * @see https://tailwindcss.com/docs/divide-width + * @see https://tailwindcss.com/docs/border-width#between-children */ 'divide-y-reverse': ['divide-y-reverse'], + /** + * Border Style + * @see https://tailwindcss.com/docs/border-style + */ + 'border-style': [{ border: [...getLineStyleScale(), 'hidden', 'none'] }], /** * Divide Style - * @see https://tailwindcss.com/docs/divide-style + * @see https://tailwindcss.com/docs/border-style#setting-the-divider-style */ - 'divide-style': [{ divide: getLineStyles() }], + 'divide-style': [{ divide: [...getLineStyleScale(), 'hidden', 'none'] }], /** * Border Color * @see https://tailwindcss.com/docs/border-color */ - 'border-color': [{ border: [borderColor] }], + 'border-color': [{ border: [color] }], /** * Border Color X * @see https://tailwindcss.com/docs/border-color */ - 'border-color-x': [{ 'border-x': [borderColor] }], + 'border-color-x': [{ 'border-x': [color] }], /** * Border Color Y * @see https://tailwindcss.com/docs/border-color */ - 'border-color-y': [{ 'border-y': [borderColor] }], + 'border-color-y': [{ 'border-y': [color] }], /** * Border Color S * @see https://tailwindcss.com/docs/border-color */ - 'border-color-s': [{ 'border-s': [borderColor] }], + 'border-color-s': [{ 'border-s': [color] }], /** * Border Color E * @see https://tailwindcss.com/docs/border-color */ - 'border-color-e': [{ 'border-e': [borderColor] }], + 'border-color-e': [{ 'border-e': [color] }], /** * Border Color Top * @see https://tailwindcss.com/docs/border-color */ - 'border-color-t': [{ 'border-t': [borderColor] }], + 'border-color-t': [{ 'border-t': [color] }], /** * Border Color Right * @see https://tailwindcss.com/docs/border-color */ - 'border-color-r': [{ 'border-r': [borderColor] }], + 'border-color-r': [{ 'border-r': [color] }], /** * Border Color Bottom * @see https://tailwindcss.com/docs/border-color */ - 'border-color-b': [{ 'border-b': [borderColor] }], + 'border-color-b': [{ 'border-b': [color] }], /** * Border Color Left * @see https://tailwindcss.com/docs/border-color */ - 'border-color-l': [{ 'border-l': [borderColor] }], + 'border-color-l': [{ 'border-l': [color] }], /** * Divide Color * @see https://tailwindcss.com/docs/divide-color */ - 'divide-color': [{ divide: [borderColor] }], + 'divide-color': [{ divide: [color] }], /** * Outline Style * @see https://tailwindcss.com/docs/outline-style */ - 'outline-style': [{ outline: ['', 'hidden', ...getLineStyles()] }], + 'outline-style': [{ outline: [...getLineStyleScale(), 'none', 'hidden'] }], /** * Outline Offset * @see https://tailwindcss.com/docs/outline-offset */ - 'outline-offset': [{ 'outline-offset': [isLength, isArbitraryValue] }], + 'outline-offset': [ + { 'outline-offset': [isNumber, isArbitraryVariable, isArbitraryValue] }, + ], /** * Outline Width * @see https://tailwindcss.com/docs/outline-width */ - 'outline-w': [{ outline: [isLength, isArbitraryLength] }], + 'outline-w': [ + { outline: ['', isNumber, isArbitraryVariableLength, isArbitraryLength] }, + ], /** * Outline Color * @see https://tailwindcss.com/docs/outline-color */ - 'outline-color': [{ outline: [colors] }], - // Effects + 'outline-color': [{ outline: [color] }], + + // --------------- + // --- Effects --- + // --------------- + /** * Box Shadow * @see https://tailwindcss.com/docs/box-shadow @@ -1240,9 +1319,7 @@ export const getDefaultConfig = () => { shadow: [ // Deprecated since Tailwind CSS v4.0.0 '', - 'none', - isTshirtSize, - isArbitraryShadow, + shadow, ], }, ], @@ -1250,22 +1327,24 @@ export const getDefaultConfig = () => { * Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color */ - 'shadow-color': [{ shadow: [isAny] }], + 'shadow-color': [{ shadow: [color] }], /** * Inset Box Shadow * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow */ - 'inset-shadow': [{ 'inset-shadow': ['none', isTshirtSize, isArbitraryShadow] }], + 'inset-shadow': [ + { 'inset-shadow': ['none', isArbitraryVariable, isArbitraryValue, insetShadow] }, + ], /** * Inset Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color */ - 'inset-shadow-color': [{ 'inset-shadow': [isAny] }], + 'inset-shadow-color': [{ 'inset-shadow': [color] }], /** * Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring */ - 'ring-w': [{ ring: getNumberWithEmptyAndArbitrary() }], + 'ring-w': [{ ring: getBorderWidthScale() }], /** * Ring Width Inset * @see https://v3.tailwindcss.com/docs/ring-width#inset-rings @@ -1277,53 +1356,66 @@ export const getDefaultConfig = () => { * Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color */ - 'ring-color': [{ ring: [colors] }], + 'ring-color': [{ ring: [color] }], /** * Ring Offset Width * @see https://v3.tailwindcss.com/docs/ring-offset-width * @deprecated since Tailwind CSS v4.0.0 * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ - 'ring-offset-w': [{ 'ring-offset': [isLength, isArbitraryLength] }], + 'ring-offset-w': [{ 'ring-offset': [isNumber, isArbitraryLength] }], /** * Ring Offset Color * @see https://v3.tailwindcss.com/docs/ring-offset-color * @deprecated since Tailwind CSS v4.0.0 * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ - 'ring-offset-color': [{ 'ring-offset': [colors] }], + 'ring-offset-color': [{ 'ring-offset': [color] }], /** * Inset Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring */ - 'inset-ring-w': [{ 'inset-ring': getNumberWithEmptyAndArbitrary() }], + 'inset-ring-w': [{ 'inset-ring': getBorderWidthScale() }], /** * Inset Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color */ - 'inset-ring-color': [{ 'inset-ring': [colors] }], + 'inset-ring-color': [{ 'inset-ring': [color] }], /** * Opacity * @see https://tailwindcss.com/docs/opacity */ - opacity: [{ opacity: [opacity] }], + opacity: [{ opacity: [isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Mix Blend Mode * @see https://tailwindcss.com/docs/mix-blend-mode */ - 'mix-blend': [{ 'mix-blend': [...getBlendModes(), 'plus-lighter', 'plus-darker'] }], + 'mix-blend': [{ 'mix-blend': [...getBlendModeScale(), 'plus-darker', 'plus-lighter'] }], /** * Background Blend Mode * @see https://tailwindcss.com/docs/background-blend-mode */ - 'bg-blend': [{ 'bg-blend': getBlendModes() }], - // Filters + 'bg-blend': [{ 'bg-blend': getBlendModeScale() }], + + // --------------- + // --- Filters --- + // --------------- + /** * Filter - * @deprecated since Tailwind CSS v3.0.0 * @see https://tailwindcss.com/docs/filter */ - filter: [{ filter: ['', 'none'] }], + filter: [ + { + filter: [ + // Deprecated since Tailwind CSS v3.0.0 + '', + 'none', + isArbitraryVariable, + isArbitraryValue, + ], + }, + ], /** * Blur * @see https://tailwindcss.com/docs/blur @@ -1333,58 +1425,57 @@ export const getDefaultConfig = () => { * Brightness * @see https://tailwindcss.com/docs/brightness */ - brightness: [{ brightness: [brightness] }], + brightness: [{ brightness: [isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Contrast * @see https://tailwindcss.com/docs/contrast */ - contrast: [{ contrast: [contrast] }], + contrast: [{ contrast: [isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Drop Shadow * @see https://tailwindcss.com/docs/drop-shadow */ - 'drop-shadow': [ - { - 'drop-shadow': [ - // Deprecated since Tailwind CSS v4.0.0 - '', - 'none', - isTshirtSize, - isArbitraryValue, - ], - }, - ], + 'drop-shadow': [{ 'drop-shadow': [dropShadow] }], /** * Grayscale * @see https://tailwindcss.com/docs/grayscale */ - grayscale: [{ grayscale: [grayscale] }], + grayscale: [{ grayscale: ['', isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Hue Rotate * @see https://tailwindcss.com/docs/hue-rotate */ - 'hue-rotate': [{ 'hue-rotate': [hueRotate] }], + 'hue-rotate': [{ 'hue-rotate': [isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Invert * @see https://tailwindcss.com/docs/invert */ - invert: [{ invert: [invert] }], + invert: [{ invert: ['', isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Saturate * @see https://tailwindcss.com/docs/saturate */ - saturate: [{ saturate: [saturate] }], + saturate: [{ saturate: [isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Sepia * @see https://tailwindcss.com/docs/sepia */ - sepia: [{ sepia: [sepia] }], + sepia: [{ sepia: ['', isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Backdrop Filter - * @deprecated since Tailwind CSS v3.0.0 * @see https://tailwindcss.com/docs/backdrop-filter */ - 'backdrop-filter': [{ 'backdrop-filter': ['', 'none'] }], + 'backdrop-filter': [ + { + 'backdrop-filter': [ + // Deprecated since Tailwind CSS v3.0.0 + '', + 'none', + isArbitraryVariable, + isArbitraryValue, + ], + }, + ], /** * Backdrop Blur * @see https://tailwindcss.com/docs/backdrop-blur @@ -1394,43 +1485,63 @@ export const getDefaultConfig = () => { * Backdrop Brightness * @see https://tailwindcss.com/docs/backdrop-brightness */ - 'backdrop-brightness': [{ 'backdrop-brightness': [brightness] }], + 'backdrop-brightness': [ + { 'backdrop-brightness': [isNumber, isArbitraryVariable, isArbitraryValue] }, + ], /** * Backdrop Contrast * @see https://tailwindcss.com/docs/backdrop-contrast */ - 'backdrop-contrast': [{ 'backdrop-contrast': [contrast] }], + 'backdrop-contrast': [ + { 'backdrop-contrast': [isNumber, isArbitraryVariable, isArbitraryValue] }, + ], /** * Backdrop Grayscale * @see https://tailwindcss.com/docs/backdrop-grayscale */ - 'backdrop-grayscale': [{ 'backdrop-grayscale': [grayscale] }], + 'backdrop-grayscale': [ + { 'backdrop-grayscale': ['', isNumber, isArbitraryVariable, isArbitraryValue] }, + ], /** * Backdrop Hue Rotate * @see https://tailwindcss.com/docs/backdrop-hue-rotate */ - 'backdrop-hue-rotate': [{ 'backdrop-hue-rotate': [hueRotate] }], + 'backdrop-hue-rotate': [ + { 'backdrop-hue-rotate': [isNumber, isArbitraryVariable, isArbitraryValue] }, + ], /** * Backdrop Invert * @see https://tailwindcss.com/docs/backdrop-invert */ - 'backdrop-invert': [{ 'backdrop-invert': [invert] }], + 'backdrop-invert': [ + { 'backdrop-invert': ['', isNumber, isArbitraryVariable, isArbitraryValue] }, + ], /** * Backdrop Opacity * @see https://tailwindcss.com/docs/backdrop-opacity */ - 'backdrop-opacity': [{ 'backdrop-opacity': [opacity] }], + 'backdrop-opacity': [ + { 'backdrop-opacity': [isNumber, isArbitraryVariable, isArbitraryValue] }, + ], /** * Backdrop Saturate * @see https://tailwindcss.com/docs/backdrop-saturate */ - 'backdrop-saturate': [{ 'backdrop-saturate': [saturate] }], + 'backdrop-saturate': [ + { 'backdrop-saturate': [isNumber, isArbitraryVariable, isArbitraryValue] }, + ], /** * Backdrop Sepia * @see https://tailwindcss.com/docs/backdrop-sepia */ - 'backdrop-sepia': [{ 'backdrop-sepia': [sepia] }], - // Tables + 'backdrop-sepia': [ + { 'backdrop-sepia': ['', isNumber, isArbitraryVariable, isArbitraryValue] }, + ], + + // -------------- + // --- Tables --- + // -------------- + /** * Border Collapse * @see https://tailwindcss.com/docs/border-collapse @@ -1440,17 +1551,17 @@ export const getDefaultConfig = () => { * Border Spacing * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing': [{ 'border-spacing': [borderSpacing] }], + 'border-spacing': [{ 'border-spacing': getUnambiguousSpacingScale() }], /** * Border Spacing X * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing-x': [{ 'border-spacing-x': [borderSpacing] }], + 'border-spacing-x': [{ 'border-spacing-x': getUnambiguousSpacingScale() }], /** * Border Spacing Y * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing-y': [{ 'border-spacing-y': [borderSpacing] }], + 'border-spacing-y': [{ 'border-spacing-y': getUnambiguousSpacingScale() }], /** * Table Layout * @see https://tailwindcss.com/docs/table-layout @@ -1461,7 +1572,11 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/caption-side */ caption: [{ caption: ['top', 'bottom'] }], - // Transitions and Animation + + // --------------------------------- + // --- Transitions and Animation --- + // --------------------------------- + /** * Transition Property * @see https://tailwindcss.com/docs/transition-property @@ -1469,166 +1584,175 @@ export const getDefaultConfig = () => { transition: [ { transition: [ - 'none', - 'all', '', + 'all', 'colors', 'opacity', 'shadow', 'transform', + 'none', + isArbitraryVariable, isArbitraryValue, ], }, ], + /** + * Transition Behavior + * @see https://tailwindcss.com/docs/transition-behavior + */ + 'transition-behavior': [{ transition: ['normal', 'discrete'] }], /** * Transition Duration * @see https://tailwindcss.com/docs/transition-duration */ - duration: [{ duration: getNumberAndArbitrary() }], + duration: [{ duration: [isNumber, 'initial', isArbitraryVariable, isArbitraryValue] }], /** * Transition Timing Function * @see https://tailwindcss.com/docs/transition-timing-function */ - ease: [{ ease: ['linear', 'in', 'out', 'in-out', isArbitraryValue] }], + ease: [{ ease: ['linear', 'initial', isArbitraryVariable, isArbitraryValue, ease] }], /** * Transition Delay * @see https://tailwindcss.com/docs/transition-delay */ - delay: [{ delay: getNumberAndArbitrary() }], + delay: [{ delay: [isNumber, isArbitraryVariable, isArbitraryValue] }], /** * Animation * @see https://tailwindcss.com/docs/animation */ - animate: [{ animate: ['none', 'spin', 'ping', 'pulse', 'bounce', isArbitraryValue] }], - // Transforms + animate: [{ animate: ['none', isArbitraryVariable, isArbitraryValue, animate] }], + + // ------------------ + // --- Transforms --- + // ------------------ + + /** + * Backface Visibility + * @see https://tailwindcss.com/docs/backface-visibility + */ + backface: [{ backface: ['hidden', 'visible'] }], /** * Perspective * @see https://tailwindcss.com/docs/perspective */ - perspective: [ - { - perspective: [ - 'dramatic', - 'near', - 'normal', - 'midrange', - 'distant', - 'none', - isArbitraryValue, - ], - }, - ], + perspective: [{ perspective: [perspective, isArbitraryVariable, isArbitraryValue] }], /** * Perspective Origin * @see https://tailwindcss.com/docs/perspective-origin */ - 'perspective-origin': [ - { - 'perspective-origin': [ - 'center', - 'top', - 'top-right', - 'right', - 'bottom-right', - 'bottom', - 'bottom-left', - 'left', - 'top-left', - isArbitraryValue, - ], - }, - ], - /** - * Transform - * @see https://tailwindcss.com/docs/transform - */ - transform: [{ transform: ['', 'gpu', 'none'] }], - /** - * Scale - * @see https://tailwindcss.com/docs/scale - */ - scale: [{ scale: [scale] }], - /** - * Scale X - * @see https://tailwindcss.com/docs/scale - */ - 'scale-x': [{ 'scale-x': [scale] }], - /** - * Scale Y - * @see https://tailwindcss.com/docs/scale - */ - 'scale-y': [{ 'scale-y': [scale] }], + 'perspective-origin': [{ 'perspective-origin': getOriginScale() }], /** * Rotate * @see https://tailwindcss.com/docs/rotate */ - rotate: [{ rotate: getRotate() }], + rotate: [{ rotate: getRotateScale() }], /** * Rotate X * @see https://tailwindcss.com/docs/rotate */ - 'rotate-x': [{ 'rotate-x': getRotate() }], + 'rotate-x': [{ 'rotate-x': getRotateScale() }], /** * Rotate Y * @see https://tailwindcss.com/docs/rotate */ - 'rotate-y': [{ 'rotate-y': getRotate() }], + 'rotate-y': [{ 'rotate-y': getRotateScale() }], /** * Rotate Z * @see https://tailwindcss.com/docs/rotate */ - 'rotate-z': [{ 'rotate-z': getRotate() }], + 'rotate-z': [{ 'rotate-z': getRotateScale() }], /** - * Translate X - * @see https://tailwindcss.com/docs/translate + * Scale + * @see https://tailwindcss.com/docs/scale */ - 'translate-x': [{ 'translate-x': [translate] }], + scale: [{ scale: getScaleScale() }], /** - * Translate Y - * @see https://tailwindcss.com/docs/translate + * Scale X + * @see https://tailwindcss.com/docs/scale + */ + 'scale-x': [{ 'scale-x': getScaleScale() }], + /** + * Scale Y + * @see https://tailwindcss.com/docs/scale + */ + 'scale-y': [{ 'scale-y': getScaleScale() }], + /** + * Scale Z + * @see https://tailwindcss.com/docs/scale + */ + 'scale-z': [{ 'scale-z': getScaleScale() }], + /** + * Scale 3D + * @see https://tailwindcss.com/docs/scale + */ + 'scale-3d': ['scale-3d'], + /** + * Skew + * @see https://tailwindcss.com/docs/skew */ - 'translate-y': [{ 'translate-y': [translate] }], + skew: [{ skew: getSkewScale() }], /** * Skew X * @see https://tailwindcss.com/docs/skew */ - 'skew-x': [{ 'skew-x': [skew] }], + 'skew-x': [{ 'skew-x': getSkewScale() }], /** * Skew Y * @see https://tailwindcss.com/docs/skew */ - 'skew-y': [{ 'skew-y': [skew] }], + 'skew-y': [{ 'skew-y': getSkewScale() }], + /** + * Transform + * @see https://tailwindcss.com/docs/transform + */ + transform: [ + { transform: [isArbitraryVariable, isArbitraryValue, '', 'none', 'gpu', 'cpu'] }, + ], /** * Transform Origin * @see https://tailwindcss.com/docs/transform-origin */ - 'transform-origin': [ - { - origin: [ - 'center', - 'top', - 'top-right', - 'right', - 'bottom-right', - 'bottom', - 'bottom-left', - 'left', - 'top-left', - isArbitraryValue, - ], - }, - ], + 'transform-origin': [{ origin: getOriginScale() }], /** * Transform Style * @see https://tailwindcss.com/docs/transform-style */ 'transform-style': [{ transform: ['3d', 'flat'] }], - // Interactivity + /** + * Translate + * @see https://tailwindcss.com/docs/translate + */ + translate: [{ translate: getTranslateScale() }], + /** + * Translate X + * @see https://tailwindcss.com/docs/translate + */ + 'translate-x': [{ 'translate-x': getTranslateScale() }], + /** + * Translate Y + * @see https://tailwindcss.com/docs/translate + */ + 'translate-y': [{ 'translate-y': getTranslateScale() }], + /** + * Translate Z + * @see https://tailwindcss.com/docs/translate + */ + 'translate-z': [{ 'translate-z': getTranslateScale() }], + /** + * Translate None + * @see https://tailwindcss.com/docs/translate + */ + 'translate-none': ['translate-none'], + + // --------------------- + // --- Interactivity --- + // --------------------- + /** * Accent Color * @see https://tailwindcss.com/docs/accent-color */ - accent: [{ accent: ['auto', colors] }], + accent: [{ accent: [color] }], /** * Appearance * @see https://tailwindcss.com/docs/appearance @@ -1638,7 +1762,7 @@ export const getDefaultConfig = () => { * Caret Color * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities */ - 'caret-color': [{ caret: [colors] }], + 'caret-color': [{ caret: [color] }], /** * Color Scheme * @see https://tailwindcss.com/docs/color-scheme @@ -1689,6 +1813,7 @@ export const getDefaultConfig = () => { 'nwse-resize', 'zoom-in', 'zoom-out', + isArbitraryVariable, isArbitraryValue, ], }, @@ -1702,12 +1827,12 @@ export const getDefaultConfig = () => { * Pointer Events * @see https://tailwindcss.com/docs/pointer-events */ - 'pointer-events': [{ 'pointer-events': ['none', 'auto'] }], + 'pointer-events': [{ 'pointer-events': ['auto', 'none'] }], /** * Resize * @see https://tailwindcss.com/docs/resize */ - resize: [{ resize: ['none', 'y', 'x', ''] }], + resize: [{ resize: ['none', '', 'y', 'x'] }], /** * Scroll Behavior * @see https://tailwindcss.com/docs/scroll-behavior @@ -1717,92 +1842,92 @@ export const getDefaultConfig = () => { * Scroll Margin * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-m': [{ 'scroll-m': getSpacingWithArbitrary() }], + 'scroll-m': [{ 'scroll-m': getUnambiguousSpacingScale() }], /** * Scroll Margin X * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mx': [{ 'scroll-mx': getSpacingWithArbitrary() }], + 'scroll-mx': [{ 'scroll-mx': getUnambiguousSpacingScale() }], /** * Scroll Margin Y * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-my': [{ 'scroll-my': getSpacingWithArbitrary() }], + 'scroll-my': [{ 'scroll-my': getUnambiguousSpacingScale() }], /** * Scroll Margin Start * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-ms': [{ 'scroll-ms': getSpacingWithArbitrary() }], + 'scroll-ms': [{ 'scroll-ms': getUnambiguousSpacingScale() }], /** * Scroll Margin End * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-me': [{ 'scroll-me': getSpacingWithArbitrary() }], + 'scroll-me': [{ 'scroll-me': getUnambiguousSpacingScale() }], /** * Scroll Margin Top * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mt': [{ 'scroll-mt': getSpacingWithArbitrary() }], + 'scroll-mt': [{ 'scroll-mt': getUnambiguousSpacingScale() }], /** * Scroll Margin Right * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mr': [{ 'scroll-mr': getSpacingWithArbitrary() }], + 'scroll-mr': [{ 'scroll-mr': getUnambiguousSpacingScale() }], /** * Scroll Margin Bottom * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mb': [{ 'scroll-mb': getSpacingWithArbitrary() }], + 'scroll-mb': [{ 'scroll-mb': getUnambiguousSpacingScale() }], /** * Scroll Margin Left * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-ml': [{ 'scroll-ml': getSpacingWithArbitrary() }], + 'scroll-ml': [{ 'scroll-ml': getUnambiguousSpacingScale() }], /** * Scroll Padding * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-p': [{ 'scroll-p': getSpacingWithArbitrary() }], + 'scroll-p': [{ 'scroll-p': getUnambiguousSpacingScale() }], /** * Scroll Padding X * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-px': [{ 'scroll-px': getSpacingWithArbitrary() }], + 'scroll-px': [{ 'scroll-px': getUnambiguousSpacingScale() }], /** * Scroll Padding Y * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-py': [{ 'scroll-py': getSpacingWithArbitrary() }], + 'scroll-py': [{ 'scroll-py': getUnambiguousSpacingScale() }], /** * Scroll Padding Start * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-ps': [{ 'scroll-ps': getSpacingWithArbitrary() }], + 'scroll-ps': [{ 'scroll-ps': getUnambiguousSpacingScale() }], /** * Scroll Padding End * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pe': [{ 'scroll-pe': getSpacingWithArbitrary() }], + 'scroll-pe': [{ 'scroll-pe': getUnambiguousSpacingScale() }], /** * Scroll Padding Top * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pt': [{ 'scroll-pt': getSpacingWithArbitrary() }], + 'scroll-pt': [{ 'scroll-pt': getUnambiguousSpacingScale() }], /** * Scroll Padding Right * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pr': [{ 'scroll-pr': getSpacingWithArbitrary() }], + 'scroll-pr': [{ 'scroll-pr': getUnambiguousSpacingScale() }], /** * Scroll Padding Bottom * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pb': [{ 'scroll-pb': getSpacingWithArbitrary() }], + 'scroll-pb': [{ 'scroll-pb': getUnambiguousSpacingScale() }], /** * Scroll Padding Left * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pl': [{ 'scroll-pl': getSpacingWithArbitrary() }], + 'scroll-pl': [{ 'scroll-pl': getUnambiguousSpacingScale() }], /** * Scroll Snap Align * @see https://tailwindcss.com/docs/scroll-snap-align @@ -1827,29 +1952,17 @@ export const getDefaultConfig = () => { * Touch Action * @see https://tailwindcss.com/docs/touch-action */ - touch: [ - { - touch: ['auto', 'none', 'manipulation'], - }, - ], + touch: [{ touch: ['auto', 'none', 'manipulation'] }], /** * Touch Action X * @see https://tailwindcss.com/docs/touch-action */ - 'touch-x': [ - { - 'touch-pan': ['x', 'left', 'right'], - }, - ], + 'touch-x': [{ 'touch-pan': ['x', 'left', 'right'] }], /** * Touch Action Y * @see https://tailwindcss.com/docs/touch-action */ - 'touch-y': [ - { - 'touch-pan': ['y', 'up', 'down'], - }, - ], + 'touch-y': [{ 'touch-pan': ['y', 'up', 'down'] }], /** * Touch Action Pinch Zoom * @see https://tailwindcss.com/docs/touch-action @@ -1865,30 +1978,51 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/will-change */ 'will-change': [ - { 'will-change': ['auto', 'scroll', 'contents', 'transform', isArbitraryValue] }, + { + 'will-change': [ + 'auto', + 'scroll', + 'contents', + 'transform', + isArbitraryVariable, + isArbitraryValue, + ], + }, ], - // SVG + + // ----------- + // --- SVG --- + // ----------- + /** * Fill * @see https://tailwindcss.com/docs/fill */ - fill: [{ fill: [colors, 'none'] }], + fill: [{ fill: ['none', color] }], /** * Stroke Width * @see https://tailwindcss.com/docs/stroke-width */ - 'stroke-w': [{ stroke: [isLength, isArbitraryLength, isArbitraryNumber] }], + 'stroke-w': [ + { + stroke: [ + isNumber, + isArbitraryVariableLength, + isArbitraryLength, + isArbitraryNumber, + ], + }, + ], /** * Stroke * @see https://tailwindcss.com/docs/stroke */ - stroke: [{ stroke: [colors, 'none'] }], - // Accessibility - /** - * Screen Readers - * @see https://tailwindcss.com/docs/screen-readers - */ - sr: ['sr-only', 'not-sr-only'], + stroke: [{ stroke: ['none', color] }], + + // --------------------- + // --- Accessibility --- + // --------------------- + /** * Forced Color Adjust * @see https://tailwindcss.com/docs/forced-color-adjust @@ -1967,6 +2101,8 @@ export const getDefaultConfig = () => { ], 'border-color-x': ['border-color-r', 'border-color-l'], 'border-color-y': ['border-color-t', 'border-color-b'], + translate: ['translate-x', 'translate-y', 'translate-none'], + 'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'], 'scroll-m': [ 'scroll-mx', 'scroll-my', diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index 9fd428ea..aee93c55 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -13,13 +13,14 @@ export const createParseClassName = (config: AnyConfig) => { const modifiers = [] let bracketDepth = 0 + let parenDepth = 0 let modifierStart = 0 let postfixModifierPosition: number | undefined for (let index = 0; index < className.length; index++) { let currentCharacter = className[index] - if (bracketDepth === 0) { + if (bracketDepth === 0 && parenDepth === 0) { if ( currentCharacter === firstSeparatorCharacter && (isSeparatorSingleCharacter || @@ -40,6 +41,10 @@ export const createParseClassName = (config: AnyConfig) => { bracketDepth++ } else if (currentCharacter === ']') { bracketDepth-- + } else if (currentCharacter === '(') { + parenDepth++ + } else if (currentCharacter === ')') { + parenDepth-- } } diff --git a/src/lib/types.ts b/src/lib/types.ts index 102ac2ab..cc248cd0 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -168,31 +168,24 @@ export type NoInfer = [T][T extends any ? 0 : never] * (the list of supported keys may vary between `tailwind-merge` versions) */ export type DefaultThemeGroupIds = + | 'animate' + | 'aspect' | 'blur' - | 'borderColor' - | 'borderRadius' - | 'borderSpacing' - | 'borderWidth' - | 'brightness' - | 'colors' - | 'contrast' - | 'gap' - | 'gradientColorStopPositions' - | 'gradientColorStops' - | 'grayscale' - | 'hueRotate' - | 'inset' - | 'invert' - | 'margin' - | 'opacity' - | 'padding' - | 'saturate' - | 'scale' - | 'sepia' - | 'skew' - | 'space' + | 'breakpoint' + | 'color' + | 'container' + | 'drop-shadow' + | 'ease' + | 'font-weight' + | 'font' + | 'inset-shadow' + | 'leading' + | 'perspective' + | 'radius' + | 'shadow' | 'spacing' - | 'translate' + | 'text' + | 'tracking' /** * Class group IDs included in the default configuration of tailwind-merge. @@ -217,6 +210,7 @@ export type DefaultClassGroupIds = | 'backdrop-opacity' | 'backdrop-saturate' | 'backdrop-sepia' + | 'backface' | 'basis' | 'bg-attachment' | 'bg-blend' @@ -292,8 +286,8 @@ export type DefaultClassGroupIds = | 'float' | 'font-family' | 'font-size' - | 'font-stretch' | 'font-smoothing' + | 'font-stretch' | 'font-style' | 'font-weight' | 'forced-color-adjust' @@ -414,8 +408,10 @@ export type DefaultClassGroupIds = | 'row-start-end' | 'row-start' | 'saturate' + | 'scale-3d' | 'scale-x' | 'scale-y' + | 'scale-z' | 'scale' | 'scroll-behavior' | 'scroll-m' @@ -444,6 +440,7 @@ export type DefaultClassGroupIds = | 'size' | 'skew-x' | 'skew-y' + | 'skew' | 'snap-align' | 'snap-stop' | 'snap-strictness' @@ -475,9 +472,13 @@ export type DefaultClassGroupIds = | 'transform-origin' | 'transform-style' | 'transform' + | 'transition-behavior' | 'transition' + | 'translate-none' | 'translate-x' | 'translate-y' + | 'translate-z' + | 'translate' | 'underline-offset' | 'vertical-align' | 'visibility' diff --git a/src/lib/validators.ts b/src/lib/validators.ts index 08ed9c51..5e9b427c 100644 --- a/src/lib/validators.ts +++ b/src/lib/validators.ts @@ -1,6 +1,6 @@ -const arbitraryValueRegex = /^\[(?:([a-z-]+):)?(.+)\]$/i +const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i +const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i const fractionRegex = /^\d+\/\d+$/ -const stringLengths = new Set(['px', 'full', 'screen']) const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/ const lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/ @@ -10,49 +10,81 @@ const shadowRegex = /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z] const imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/ -export const isLength = (value: string) => - isNumber(value) || stringLengths.has(value) || fractionRegex.test(value) - -export const isArbitraryLength = (value: string) => - getIsArbitraryValue(value, 'length', isLengthOnly) +export const isFraction = (value: string) => fractionRegex.test(value) export const isNumber = (value: string) => Boolean(value) && !Number.isNaN(Number(value)) -export const isArbitraryNumber = (value: string) => getIsArbitraryValue(value, 'number', isNumber) - export const isInteger = (value: string) => Boolean(value) && Number.isInteger(Number(value)) export const isPercent = (value: string) => value.endsWith('%') && isNumber(value.slice(0, -1)) -export const isArbitraryValue = (value: string) => arbitraryValueRegex.test(value) - export const isTshirtSize = (value: string) => tshirtUnitRegex.test(value) -const sizeLabels = new Set(['length', 'size', 'percentage']) +export const isAny = () => true + +const isLengthOnly = (value: string) => + // `colorFunctionRegex` check is necessary because color functions can have percentages in them which which would be incorrectly classified as lengths. + // For example, `hsl(0 0% 0%)` would be classified as a length without this check. + // I could also use lookbehind assertion in `lengthUnitRegex` but that isn't supported widely enough. + lengthUnitRegex.test(value) && !colorFunctionRegex.test(value) + +const isNever = () => false -export const isArbitrarySize = (value: string) => getIsArbitraryValue(value, sizeLabels, isNever) +const isShadow = (value: string) => shadowRegex.test(value) + +const isImage = (value: string) => imageRegex.test(value) + +export const isAnyNonArbitrary = (value: string) => + !isArbitraryValue(value) && !isArbitraryVariable(value) + +export const isArbitrarySize = (value: string) => getIsArbitraryValue(value, isLabelSize, isNever) + +export const isArbitraryValue = (value: string) => arbitraryValueRegex.test(value) + +export const isArbitraryLength = (value: string) => + getIsArbitraryValue(value, isLabelLength, isLengthOnly) + +export const isArbitraryNumber = (value: string) => + getIsArbitraryValue(value, isLabelNumber, isNumber) export const isArbitraryPosition = (value: string) => - getIsArbitraryValue(value, 'position', isNever) + getIsArbitraryValue(value, isLabelPosition, isNever) -const imageLabels = new Set(['image', 'url']) +export const isArbitraryImage = (value: string) => getIsArbitraryValue(value, isLabelImage, isImage) -export const isArbitraryImage = (value: string) => getIsArbitraryValue(value, imageLabels, isImage) +export const isArbitraryShadow = (value: string) => getIsArbitraryValue(value, isNever, isShadow) -export const isArbitraryShadow = (value: string) => getIsArbitraryValue(value, '', isShadow) +export const isArbitraryVariable = (value: string) => arbitraryVariableRegex.test(value) -export const isAny = () => true +export const isArbitraryVariableLength = (value: string) => + getIsArbitraryVariable(value, isLabelLength) + +export const isArbitraryVariableFamilyName = (value: string) => + getIsArbitraryVariable(value, isLabelFamilyName) + +export const isArbitraryVariablePosition = (value: string) => + getIsArbitraryVariable(value, isLabelPosition) + +export const isArbitraryVariableSize = (value: string) => getIsArbitraryVariable(value, isLabelSize) + +export const isArbitraryVariableImage = (value: string) => + getIsArbitraryVariable(value, isLabelImage) + +export const isArbitraryVariableShadow = (value: string) => + getIsArbitraryVariable(value, isLabelShadow, true) + +// Helpers const getIsArbitraryValue = ( value: string, - label: string | Set, + testLabel: (label: string) => boolean, testValue: (value: string) => boolean, ) => { const result = arbitraryValueRegex.exec(value) if (result) { if (result[1]) { - return typeof label === 'string' ? result[1] === label : label.has(result[1]) + return testLabel(result[1]) } return testValue(result[2]!) @@ -61,14 +93,39 @@ const getIsArbitraryValue = ( return false } -const isLengthOnly = (value: string) => - // `colorFunctionRegex` check is necessary because color functions can have percentages in them which which would be incorrectly classified as lengths. - // For example, `hsl(0 0% 0%)` would be classified as a length without this check. - // I could also use lookbehind assertion in `lengthUnitRegex` but that isn't supported widely enough. - lengthUnitRegex.test(value) && !colorFunctionRegex.test(value) +const getIsArbitraryVariable = ( + value: string, + testLabel: (label: string) => boolean, + shouldMatchNoLabel = false, +) => { + const result = arbitraryVariableRegex.exec(value) -const isNever = () => false + if (result) { + if (result[1]) { + return testLabel(result[1]) + } + return shouldMatchNoLabel + } -const isShadow = (value: string) => shadowRegex.test(value) + return false +} -const isImage = (value: string) => imageRegex.test(value) +// Labels + +const isLabelPosition = (label: string) => label === 'position' + +const imageLabels = new Set(['image', 'url']) + +const isLabelImage = (label: string) => imageLabels.has(label) + +const sizeLabels = new Set(['length', 'size', 'percentage']) + +const isLabelSize = (label: string) => sizeLabels.has(label) + +const isLabelLength = (label: string) => label === 'length' + +const isLabelNumber = (label: string) => label === 'number' + +const isLabelFamilyName = (label: string) => label === 'family-name' + +const isLabelShadow = (label: string) => label === 'shadow' diff --git a/tests/arbitrary-values.test.ts b/tests/arbitrary-values.test.ts index e317f6ee..9f8e0818 100644 --- a/tests/arbitrary-values.test.ts +++ b/tests/arbitrary-values.test.ts @@ -26,7 +26,7 @@ test('handles simple conflicts with arbitrary values correctly', () => { // Handling of value `0` expect(twMerge('min-h-[0.5px] min-h-[0]')).toBe('min-h-[0]') expect(twMerge('text-[0.5px] text-[color:0]')).toBe('text-[0.5px] text-[color:0]') - expect(twMerge('text-[0.5px] text-[--my-0]')).toBe('text-[0.5px] text-[--my-0]') + expect(twMerge('text-[0.5px] text-(--my-0)')).toBe('text-[0.5px] text-(--my-0)') }) test('handles arbitrary length conflicts with labels and modifiers correctly', () => { @@ -76,3 +76,14 @@ test('handles ambiguous arbitrary values correctly', () => { ), ).toBe('bg-linear-to-r') }) + +test('handles arbitrary custom properties correctly', () => { + expect(twMerge('bg-red bg-(--other-red) bg-bottom bg-(position:-my-pos)')).toBe( + 'bg-(--other-red) bg-(position:-my-pos)', + ) + expect( + twMerge( + 'shadow-xs shadow-(shadow:--something) shadow-red shadow-(--some-other-shadow) shadow-(color:--some-color)', + ), + ).toBe('shadow-(--some-other-shadow) shadow-(color:--some-color)') +}) diff --git a/tests/class-map.test.ts b/tests/class-map.test.ts index ae51acaa..7d81fae1 100644 --- a/tests/class-map.test.ts +++ b/tests/class-map.test.ts @@ -36,6 +36,7 @@ test('class map has correct class groups at first part', () => { 'backdrop-saturate', 'backdrop-sepia', ], + backface: ['backface'], basis: ['basis'], bg: [ 'bg-attachment', @@ -211,7 +212,7 @@ test('class map has correct class groups at first part', () => { ], row: ['row-end', 'row-start', 'row-start-end'], saturate: ['saturate'], - scale: ['scale', 'scale-x', 'scale-y'], + scale: ['scale', 'scale-3d', 'scale-x', 'scale-y', 'scale-z'], scheme: ['color-scheme'], scroll: [ 'scroll-behavior', @@ -240,7 +241,7 @@ test('class map has correct class groups at first part', () => { shadow: ['shadow', 'shadow-color'], shrink: ['shrink'], size: ['size'], - skew: ['skew-x', 'skew-y'], + skew: ['skew', 'skew-x', 'skew-y'], slashed: ['fvn-slashed-zero'], snap: ['snap-align', 'snap-stop', 'snap-strictness', 'snap-type'], space: ['space-x', 'space-x-reverse', 'space-y', 'space-y-reverse'], @@ -259,8 +260,8 @@ test('class map has correct class groups at first part', () => { touch: ['touch', 'touch-pz', 'touch-x', 'touch-y'], tracking: ['tracking'], transform: ['transform', 'transform-style'], - transition: ['transition'], - translate: ['translate-x', 'translate-y'], + transition: ['transition', 'transition-behavior'], + translate: ['translate', 'translate-none', 'translate-x', 'translate-y', 'translate-z'], truncate: ['text-overflow'], underline: ['text-decoration', 'underline-offset'], uppercase: ['text-transform'], diff --git a/tests/public-api.test.ts b/tests/public-api.test.ts index 06fa4200..916b3682 100644 --- a/tests/public-api.test.ts +++ b/tests/public-api.test.ts @@ -23,20 +23,28 @@ test('has correct export types', () => { expect(getDefaultConfig).toStrictEqual(expect.any(Function)) expect(validators).toMatchObject({ isAny: expect.any(Function), + isAnyNonArbitrary: expect.any(Function), + isArbitraryImage: expect.any(Function), isArbitraryLength: expect.any(Function), isArbitraryNumber: expect.any(Function), isArbitraryPosition: expect.any(Function), isArbitraryShadow: expect.any(Function), isArbitrarySize: expect.any(Function), - isArbitraryImage: expect.any(Function), isArbitraryValue: expect.any(Function), + isArbitraryVariable: expect.any(Function), + isArbitraryVariableFamilyName: expect.any(Function), + isArbitraryVariableImage: expect.any(Function), + isArbitraryVariableLength: expect.any(Function), + isArbitraryVariablePosition: expect.any(Function), + isArbitraryVariableShadow: expect.any(Function), + isArbitraryVariableSize: expect.any(Function), + isFraction: expect.any(Function), isInteger: expect.any(Function), - isLength: expect.any(Function), - isPercent: expect.any(Function), isNumber: expect.any(Function), + isPercent: expect.any(Function), isTshirtSize: expect.any(Function), }) - expect(Object.keys(validators)).toHaveLength(13) + expect(Object.keys(validators)).toHaveLength(21) expect(mergeConfigs).toStrictEqual(expect.any(Function)) expect(extendTailwindMerge).toStrictEqual(expect.any(Function)) expect(twJoin).toStrictEqual(expect.any(Function)) @@ -151,10 +159,11 @@ test('createTailwindMerge() has correct inputs and outputs', () => { }) test('validators have correct inputs and outputs', () => { - expect(validators.isLength('')).toEqual(expect.any(Boolean)) + expect(validators.isFraction('')).toEqual(expect.any(Boolean)) expect(validators.isArbitraryLength('')).toEqual(expect.any(Boolean)) expect(validators.isInteger('')).toEqual(expect.any(Boolean)) expect(validators.isArbitraryValue('')).toEqual(expect.any(Boolean)) + expect(validators.isArbitraryVariable('')).toEqual(expect.any(Boolean)) expect(validators.isAny()).toEqual(expect.any(Boolean)) expect(validators.isTshirtSize('')).toEqual(expect.any(Boolean)) expect(validators.isArbitrarySize('')).toEqual(expect.any(Boolean)) diff --git a/tests/theme.test.ts b/tests/theme.test.ts index a05997c4..86140d75 100644 --- a/tests/theme.test.ts +++ b/tests/theme.test.ts @@ -7,13 +7,15 @@ test('theme scale can be extended', () => { extend: { theme: { spacing: ['my-space'], - margin: ['my-margin'], + leading: ['my-leading'], }, }, }) expect(tailwindMerge('p-3 p-my-space p-my-margin')).toBe('p-my-space p-my-margin') - expect(tailwindMerge('m-3 m-my-space m-my-margin')).toBe('m-my-margin') + expect(tailwindMerge('leading-3 leading-my-space leading-my-leading')).toBe( + 'leading-my-leading', + ) }) test('theme object can be extended', () => { diff --git a/tests/validators.test.ts b/tests/validators.test.ts index a7d71512..9fdd96d4 100644 --- a/tests/validators.test.ts +++ b/tests/validators.test.ts @@ -3,42 +3,63 @@ import { expect, test } from 'vitest' import { validators } from '../src' const { - isLength, - isPercent, - isArbitraryLength, - isInteger, - isArbitraryValue, isAny, - isTshirtSize, - isArbitrarySize, - isArbitraryPosition, + isAnyNonArbitrary, isArbitraryImage, + isArbitraryLength, isArbitraryNumber, + isArbitraryPosition, isArbitraryShadow, + isArbitrarySize, + isArbitraryValue, + isArbitraryVariable, + isArbitraryVariableFamilyName, + isArbitraryVariableImage, + isArbitraryVariableLength, + isArbitraryVariablePosition, + isArbitraryVariableShadow, + isArbitraryVariableSize, + isFraction, + isInteger, + isNumber, + isPercent, + isTshirtSize, } = validators -test('isLength', () => { - expect(isLength('1')).toBe(true) - expect(isLength('1023713')).toBe(true) - expect(isLength('1.5')).toBe(true) - expect(isLength('1231.503761')).toBe(true) - expect(isLength('px')).toBe(true) - expect(isLength('full')).toBe(true) - expect(isLength('screen')).toBe(true) - expect(isLength('1/2')).toBe(true) - expect(isLength('123/345')).toBe(true) - - expect(isLength('[3.7%]')).toBe(false) - expect(isLength('[481px]')).toBe(false) - expect(isLength('[19.1rem]')).toBe(false) - expect(isLength('[50vw]')).toBe(false) - expect(isLength('[56vh]')).toBe(false) - expect(isLength('[length:var(--arbitrary)]')).toBe(false) - expect(isLength('1d5')).toBe(false) - expect(isLength('[1]')).toBe(false) - expect(isLength('[12px')).toBe(false) - expect(isLength('12px]')).toBe(false) - expect(isLength('one')).toBe(false) +test('isAny', () => { + expect(isAny()).toBe(true) + // @ts-expect-error + expect(isAny('')).toBe(true) + // @ts-expect-error + expect(isAny('something')).toBe(true) +}) + +test('isAnyNonArbitrary', () => { + expect(isAnyNonArbitrary('test')).toBe(true) + expect(isAnyNonArbitrary('1234-hello-world')).toBe(true) + expect(isAnyNonArbitrary('[hello')).toBe(true) + expect(isAnyNonArbitrary('hello]')).toBe(true) + expect(isAnyNonArbitrary('[)')).toBe(true) + expect(isAnyNonArbitrary('(hello]')).toBe(true) + + expect(isAnyNonArbitrary('[test]')).toBe(false) + expect(isAnyNonArbitrary('[label:test]')).toBe(false) + expect(isAnyNonArbitrary('(test)')).toBe(false) + expect(isAnyNonArbitrary('(label:test)')).toBe(false) +}) + +test('isArbitraryImage', () => { + expect(isArbitraryImage('[url:var(--my-url)]')).toBe(true) + expect(isArbitraryImage('[url(something)]')).toBe(true) + expect(isArbitraryImage('[url:bla]')).toBe(true) + expect(isArbitraryImage('[image:bla]')).toBe(true) + expect(isArbitraryImage('[linear-gradient(something)]')).toBe(true) + expect(isArbitraryImage('[repeating-conic-gradient(something)]')).toBe(true) + + expect(isArbitraryImage('[var(--my-url)]')).toBe(false) + expect(isArbitraryImage('[bla]')).toBe(false) + expect(isArbitraryImage('url:2px')).toBe(false) + expect(isArbitraryImage('url(2px)')).toBe(false) }) test('isArbitraryLength', () => { @@ -58,22 +79,52 @@ test('isArbitraryLength', () => { expect(isArbitraryLength('one')).toBe(false) }) -test('isInteger', () => { - expect(isInteger('1')).toBe(true) - expect(isInteger('123')).toBe(true) - expect(isInteger('8312')).toBe(true) +test('isArbitraryNumber', () => { + expect(isArbitraryNumber('[number:black]')).toBe(true) + expect(isArbitraryNumber('[number:bla]')).toBe(true) + expect(isArbitraryNumber('[number:230]')).toBe(true) + expect(isArbitraryNumber('[450]')).toBe(true) - expect(isInteger('[8312]')).toBe(false) - expect(isInteger('[2]')).toBe(false) - expect(isInteger('[8312px]')).toBe(false) - expect(isInteger('[8312%]')).toBe(false) - expect(isInteger('[8312rem]')).toBe(false) - expect(isInteger('8312.2')).toBe(false) - expect(isInteger('1.2')).toBe(false) - expect(isInteger('one')).toBe(false) - expect(isInteger('1/2')).toBe(false) - expect(isInteger('1%')).toBe(false) - expect(isInteger('1px')).toBe(false) + expect(isArbitraryNumber('[2px]')).toBe(false) + expect(isArbitraryNumber('[bla]')).toBe(false) + expect(isArbitraryNumber('[black]')).toBe(false) + expect(isArbitraryNumber('black')).toBe(false) + expect(isArbitraryNumber('450')).toBe(false) +}) + +test('isArbitraryPosition', () => { + expect(isArbitraryPosition('[position:2px]')).toBe(true) + expect(isArbitraryPosition('[position:bla]')).toBe(true) + + expect(isArbitraryPosition('[2px]')).toBe(false) + expect(isArbitraryPosition('[bla]')).toBe(false) + expect(isArbitraryPosition('position:2px')).toBe(false) +}) + +test('isArbitraryShadow', () => { + expect(isArbitraryShadow('[0_35px_60px_-15px_rgba(0,0,0,0.3)]')).toBe(true) + expect(isArbitraryShadow('[inset_0_1px_0,inset_0_-1px_0]')).toBe(true) + expect(isArbitraryShadow('[0_0_#00f]')).toBe(true) + expect(isArbitraryShadow('[.5rem_0_rgba(5,5,5,5)]')).toBe(true) + expect(isArbitraryShadow('[-.5rem_0_#123456]')).toBe(true) + expect(isArbitraryShadow('[0.5rem_-0_#123456]')).toBe(true) + expect(isArbitraryShadow('[0.5rem_-0.005vh_#123456]')).toBe(true) + expect(isArbitraryShadow('[0.5rem_-0.005vh]')).toBe(true) + + expect(isArbitraryShadow('[rgba(5,5,5,5)]')).toBe(false) + expect(isArbitraryShadow('[#00f]')).toBe(false) + expect(isArbitraryShadow('[something-else]')).toBe(false) +}) + +test('isArbitrarySize', () => { + expect(isArbitrarySize('[size:2px]')).toBe(true) + expect(isArbitrarySize('[size:bla]')).toBe(true) + expect(isArbitrarySize('[length:bla]')).toBe(true) + expect(isArbitrarySize('[percentage:bla]')).toBe(true) + + expect(isArbitrarySize('[2px]')).toBe(false) + expect(isArbitrarySize('[bla]')).toBe(false) + expect(isArbitrarySize('size:2px')).toBe(false) }) test('isArbitraryValue', () => { @@ -90,95 +141,114 @@ test('isArbitraryValue', () => { expect(isArbitraryValue('o[n]e')).toBe(false) }) -test('isAny', () => { - expect(isAny()).toBe(true) - // @ts-expect-error - expect(isAny('')).toBe(true) - // @ts-expect-error - expect(isAny('something')).toBe(true) +test('isArbitraryVariable', () => { + expect(isArbitraryVariable('(1)')).toBe(true) + expect(isArbitraryVariable('(bla)')).toBe(true) + expect(isArbitraryVariable('(not-an-arbitrary-value?)')).toBe(true) + expect(isArbitraryVariable('(--my-arbitrary-variable)')).toBe(true) + expect(isArbitraryVariable('(label:--my-arbitrary-variable)')).toBe(true) + + expect(isArbitraryVariable('()')).toBe(false) + expect(isArbitraryVariable('(1')).toBe(false) + expect(isArbitraryVariable('1)')).toBe(false) + expect(isArbitraryVariable('1')).toBe(false) + expect(isArbitraryVariable('one')).toBe(false) + expect(isArbitraryVariable('o(n)e')).toBe(false) }) -test('isTshirtSize', () => { - expect(isTshirtSize('xs')).toBe(true) - expect(isTshirtSize('sm')).toBe(true) - expect(isTshirtSize('md')).toBe(true) - expect(isTshirtSize('lg')).toBe(true) - expect(isTshirtSize('xl')).toBe(true) - expect(isTshirtSize('2xl')).toBe(true) - expect(isTshirtSize('2.5xl')).toBe(true) - expect(isTshirtSize('10xl')).toBe(true) - expect(isTshirtSize('2xs')).toBe(true) - expect(isTshirtSize('2lg')).toBe(true) +test('isArbitraryVariableFamilyName', () => { + expect(isArbitraryVariableFamilyName('(family-name:test)')).toBe(true) - expect(isTshirtSize('')).toBe(false) - expect(isTshirtSize('hello')).toBe(false) - expect(isTshirtSize('1')).toBe(false) - expect(isTshirtSize('xl3')).toBe(false) - expect(isTshirtSize('2xl3')).toBe(false) - expect(isTshirtSize('-xl')).toBe(false) - expect(isTshirtSize('[sm]')).toBe(false) + expect(isArbitraryVariableFamilyName('(other:test)')).toBe(false) + expect(isArbitraryVariableFamilyName('(test)')).toBe(false) + expect(isArbitraryVariableFamilyName('family-name:test')).toBe(false) }) -test('isArbitrarySize', () => { - expect(isArbitrarySize('[size:2px]')).toBe(true) - expect(isArbitrarySize('[size:bla]')).toBe(true) - expect(isArbitrarySize('[length:bla]')).toBe(true) - expect(isArbitrarySize('[percentage:bla]')).toBe(true) +test('isArbitraryVariableImage', () => { + expect(isArbitraryVariableImage('(image:test)')).toBe(true) + expect(isArbitraryVariableImage('(url:test)')).toBe(true) - expect(isArbitrarySize('[2px]')).toBe(false) - expect(isArbitrarySize('[bla]')).toBe(false) - expect(isArbitrarySize('size:2px')).toBe(false) + expect(isArbitraryVariableImage('(other:test)')).toBe(false) + expect(isArbitraryVariableImage('(test)')).toBe(false) + expect(isArbitraryVariableImage('image:test')).toBe(false) }) -test('isArbitraryPosition', () => { - expect(isArbitraryPosition('[position:2px]')).toBe(true) - expect(isArbitraryPosition('[position:bla]')).toBe(true) +test('isArbitraryVariableLength', () => { + expect(isArbitraryVariableLength('(length:test)')).toBe(true) - expect(isArbitraryPosition('[2px]')).toBe(false) - expect(isArbitraryPosition('[bla]')).toBe(false) - expect(isArbitraryPosition('position:2px')).toBe(false) + expect(isArbitraryVariableLength('(other:test)')).toBe(false) + expect(isArbitraryVariableLength('(test)')).toBe(false) + expect(isArbitraryVariableLength('length:test')).toBe(false) }) -test('isArbitraryImage', () => { - expect(isArbitraryImage('[url:var(--my-url)]')).toBe(true) - expect(isArbitraryImage('[url(something)]')).toBe(true) - expect(isArbitraryImage('[url:bla]')).toBe(true) - expect(isArbitraryImage('[image:bla]')).toBe(true) - expect(isArbitraryImage('[linear-gradient(something)]')).toBe(true) - expect(isArbitraryImage('[repeating-conic-gradient(something)]')).toBe(true) +test('isArbitraryVariablePosition', () => { + expect(isArbitraryVariablePosition('(position:test)')).toBe(true) - expect(isArbitraryImage('[var(--my-url)]')).toBe(false) - expect(isArbitraryImage('[bla]')).toBe(false) - expect(isArbitraryImage('url:2px')).toBe(false) - expect(isArbitraryImage('url(2px)')).toBe(false) + expect(isArbitraryVariablePosition('(other:test)')).toBe(false) + expect(isArbitraryVariablePosition('(test)')).toBe(false) + expect(isArbitraryVariablePosition('position:test')).toBe(false) }) -test('isArbitraryNumber', () => { - expect(isArbitraryNumber('[number:black]')).toBe(true) - expect(isArbitraryNumber('[number:bla]')).toBe(true) - expect(isArbitraryNumber('[number:230]')).toBe(true) - expect(isArbitraryNumber('[450]')).toBe(true) +test('isArbitraryVariableShadow', () => { + expect(isArbitraryVariableShadow('(shadow:test)')).toBe(true) + expect(isArbitraryVariableShadow('(test)')).toBe(true) - expect(isArbitraryNumber('[2px]')).toBe(false) - expect(isArbitraryNumber('[bla]')).toBe(false) - expect(isArbitraryNumber('[black]')).toBe(false) - expect(isArbitraryNumber('black')).toBe(false) - expect(isArbitraryNumber('450')).toBe(false) + expect(isArbitraryVariableShadow('(other:test)')).toBe(false) + expect(isArbitraryVariableShadow('shadow:test')).toBe(false) }) -test('isArbitraryShadow', () => { - expect(isArbitraryShadow('[0_35px_60px_-15px_rgba(0,0,0,0.3)]')).toBe(true) - expect(isArbitraryShadow('[inset_0_1px_0,inset_0_-1px_0]')).toBe(true) - expect(isArbitraryShadow('[0_0_#00f]')).toBe(true) - expect(isArbitraryShadow('[.5rem_0_rgba(5,5,5,5)]')).toBe(true) - expect(isArbitraryShadow('[-.5rem_0_#123456]')).toBe(true) - expect(isArbitraryShadow('[0.5rem_-0_#123456]')).toBe(true) - expect(isArbitraryShadow('[0.5rem_-0.005vh_#123456]')).toBe(true) - expect(isArbitraryShadow('[0.5rem_-0.005vh]')).toBe(true) +test('isArbitraryVariableSize', () => { + expect(isArbitraryVariableSize('(size:test)')).toBe(true) + expect(isArbitraryVariableSize('(length:test)')).toBe(true) + expect(isArbitraryVariableSize('(percentage:test)')).toBe(true) - expect(isArbitraryShadow('[rgba(5,5,5,5)]')).toBe(false) - expect(isArbitraryShadow('[#00f]')).toBe(false) - expect(isArbitraryShadow('[something-else]')).toBe(false) + expect(isArbitraryVariableSize('(other:test)')).toBe(false) + expect(isArbitraryVariableSize('(test)')).toBe(false) + expect(isArbitraryVariableSize('size:test')).toBe(false) +}) + +test('isFraction', () => { + expect(isFraction('1/2')).toBe(true) + expect(isFraction('123/209')).toBe(true) + expect(isFraction('1')).toBe(false) + expect(isFraction('1/2/3')).toBe(false) + expect(isFraction('[1/2]')).toBe(false) +}) + +test('isInteger', () => { + expect(isInteger('1')).toBe(true) + expect(isInteger('123')).toBe(true) + expect(isInteger('8312')).toBe(true) + + expect(isInteger('[8312]')).toBe(false) + expect(isInteger('[2]')).toBe(false) + expect(isInteger('[8312px]')).toBe(false) + expect(isInteger('[8312%]')).toBe(false) + expect(isInteger('[8312rem]')).toBe(false) + expect(isInteger('8312.2')).toBe(false) + expect(isInteger('1.2')).toBe(false) + expect(isInteger('one')).toBe(false) + expect(isInteger('1/2')).toBe(false) + expect(isInteger('1%')).toBe(false) + expect(isInteger('1px')).toBe(false) +}) + +test('isNumber', () => { + expect(isNumber('1')).toBe(true) + expect(isNumber('123')).toBe(true) + expect(isNumber('8312')).toBe(true) + expect(isNumber('8312.2')).toBe(true) + expect(isNumber('1.2')).toBe(true) + + expect(isNumber('[8312]')).toBe(false) + expect(isNumber('[2]')).toBe(false) + expect(isNumber('[8312px]')).toBe(false) + expect(isNumber('[8312%]')).toBe(false) + expect(isNumber('[8312rem]')).toBe(false) + expect(isNumber('one')).toBe(false) + expect(isNumber('1/2')).toBe(false) + expect(isNumber('1%')).toBe(false) + expect(isNumber('1px')).toBe(false) }) test('isPercent', () => { @@ -190,3 +260,24 @@ test('isPercent', () => { expect(isPercent('0')).toBe(false) expect(isPercent('one%')).toBe(false) }) + +test('isTshirtSize', () => { + expect(isTshirtSize('xs')).toBe(true) + expect(isTshirtSize('sm')).toBe(true) + expect(isTshirtSize('md')).toBe(true) + expect(isTshirtSize('lg')).toBe(true) + expect(isTshirtSize('xl')).toBe(true) + expect(isTshirtSize('2xl')).toBe(true) + expect(isTshirtSize('2.5xl')).toBe(true) + expect(isTshirtSize('10xl')).toBe(true) + expect(isTshirtSize('2xs')).toBe(true) + expect(isTshirtSize('2lg')).toBe(true) + + expect(isTshirtSize('')).toBe(false) + expect(isTshirtSize('hello')).toBe(false) + expect(isTshirtSize('1')).toBe(false) + expect(isTshirtSize('xl3')).toBe(false) + expect(isTshirtSize('2xl3')).toBe(false) + expect(isTshirtSize('-xl')).toBe(false) + expect(isTshirtSize('[sm]')).toBe(false) +}) From 323870803145faaae85fd6ce2b2b4ba17a7a9608 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 13:28:51 +0100 Subject: [PATCH 18/48] attempt: group theme getters and scale helpers into objects --- src/lib/default-config.ts | 670 ++++++++++++++++++++------------------ 1 file changed, 358 insertions(+), 312 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index da8a1977..7921e50d 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -1,5 +1,5 @@ import { fromTheme } from './from-theme' -import { Config, DefaultClassGroupIds, DefaultThemeGroupIds } from './types' +import { ClassGroup, Config, DefaultClassGroupIds, DefaultThemeGroupIds } from './types' import { isAny, isAnyNonArbitrary, @@ -25,128 +25,157 @@ import { } from './validators' export const getDefaultConfig = () => { - // Theme getters for theme variable namespaces: https://tailwindcss.com/docs/theme#theme-variable-namespaces + /** + * Theme getters for theme variable namespaces + * @see https://tailwindcss.com/docs/theme#theme-variable-namespaces + */ + const theme = { + color: fromTheme('color'), + font: fromTheme('font'), + text: fromTheme('text'), + fontWeight: fromTheme('font-weight'), + tracking: fromTheme('tracking'), + leading: fromTheme('leading'), + breakpoint: fromTheme('breakpoint'), + container: fromTheme('container'), + spacing: fromTheme('spacing'), + radius: fromTheme('radius'), + shadow: fromTheme('shadow'), + insetShadow: fromTheme('inset-shadow'), + dropShadow: fromTheme('drop-shadow'), + blur: fromTheme('blur'), + perspective: fromTheme('perspective'), + aspect: fromTheme('aspect'), + ease: fromTheme('ease'), + animate: fromTheme('animate'), + } satisfies Record> - const color = fromTheme('color') - const font = fromTheme('font') - const text = fromTheme('text') - const fontWeight = fromTheme('font-weight') - const tracking = fromTheme('tracking') - const leading = fromTheme('leading') - const breakpoint = fromTheme('breakpoint') - const container = fromTheme('container') - const spacing = fromTheme('spacing') - const radius = fromTheme('radius') - const shadow = fromTheme('shadow') - const insetShadow = fromTheme('inset-shadow') - const dropShadow = fromTheme('drop-shadow') - const blur = fromTheme('blur') - const perspective = fromTheme('perspective') - const aspect = fromTheme('aspect') - const ease = fromTheme('ease') - const animate = fromTheme('animate') - - // Helpers to avoid repeating the same values - - const getBreakScale = () => - ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const - const getPositionScale = () => - [ - 'bottom', - 'center', - 'left', - 'left-bottom', - 'left-top', - 'right', - 'right-bottom', - 'right-top', - 'top', - ] as const - const getOverflowScale = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const - const getOverscrollScale = () => ['auto', 'contain', 'none'] as const - const getInsetScale = () => - [isFraction, 'px', 'full', 'auto', isArbitraryVariable, isArbitraryValue, spacing] as const - const getGridTemplateColsRowsScale = () => - [isInteger, 'none', 'subgrid', isArbitraryVariable, isArbitraryValue] as const - const getGridColRowStartAndEndScale = () => - [ - 'auto', - { span: ['full', isInteger, isArbitraryVariable, isArbitraryValue] }, - isArbitraryVariable, - isArbitraryValue, - ] as const - const getGridColRowStartOrEndScale = () => - [isInteger, 'auto', isArbitraryVariable, isArbitraryValue] as const - const getGridAutoColsRowsScale = () => - ['auto', 'min', 'max', 'fr', isArbitraryVariable, isArbitraryValue] as const - const getGapScale = () => [isArbitraryVariable, isArbitraryValue, spacing] as const - const getAlignPrimaryAxisScale = () => - ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch', 'baseline'] as const - const getAlignSecondaryAxisScale = () => ['start', 'end', 'center', 'stretch'] as const - const getUnambiguousSpacingScale = () => - [isArbitraryVariable, isArbitraryValue, spacing] as const - const getMarginScale = () => ['auto', ...getUnambiguousSpacingScale()] as const - const getSizingScale = () => - [ - isFraction, - 'auto', - 'px', - 'full', - 'dvw', - 'dvh', - 'lvw', - 'lvh', - 'svw', - 'svh', - 'min', - 'max', - 'fit', - isArbitraryVariable, - isArbitraryValue, - spacing, - ] as const - const getGradientStopPositionScale = () => [isPercent, isArbitraryLength] as const - const getBorderWidthScale = () => - ['', isNumber, isArbitraryVariableLength, isArbitraryLength] as const - const getLineStyleScale = () => ['solid', 'dashed', 'dotted', 'double'] as const - const getBlendModeScale = () => - [ - 'normal', - 'multiply', - 'screen', - 'overlay', - 'darken', - 'lighten', - 'color-dodge', - 'color-burn', - 'hard-light', - 'soft-light', - 'difference', - 'exclusion', - 'hue', - 'saturation', - 'color', - 'luminosity', - ] as const - const getOriginScale = () => - [ - 'center', - 'top', - 'top-right', - 'right', - 'bottom-right', - 'bottom', - 'bottom-left', - 'left', - 'top-left', - isArbitraryVariable, - isArbitraryValue, - ] as const - const getRotateScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const - const getScaleScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const - const getSkewScale = () => [isNumber, isArbitraryVariable, isArbitraryValue] as const - const getTranslateScale = () => - [isFraction, 'full', 'px', isArbitraryVariable, isArbitraryValue, spacing] as const + /** + * Helpers to avoid repeating the same scales + */ + const scale = { + break: () => + ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const, + position: () => + [ + 'bottom', + 'center', + 'left', + 'left-bottom', + 'left-top', + 'right', + 'right-bottom', + 'right-top', + 'top', + ] as const, + overflow: () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const, + overscroll: () => ['auto', 'contain', 'none'] as const, + inset: () => + [ + isFraction, + 'px', + 'full', + 'auto', + isArbitraryVariable, + isArbitraryValue, + theme.spacing, + ] as const, + gridTemplateColsRows: () => + [isInteger, 'none', 'subgrid', isArbitraryVariable, isArbitraryValue] as const, + gridColRowStartAndEnd: () => + [ + 'auto', + { span: ['full', isInteger, isArbitraryVariable, isArbitraryValue] }, + isArbitraryVariable, + isArbitraryValue, + ] as const, + gridColRowStartOrEnd: () => + [isInteger, 'auto', isArbitraryVariable, isArbitraryValue] as const, + gridAutoColsRows: () => + ['auto', 'min', 'max', 'fr', isArbitraryVariable, isArbitraryValue] as const, + gap: () => [isArbitraryVariable, isArbitraryValue, theme.spacing] as const, + alignPrimaryAxis: () => + [ + 'start', + 'end', + 'center', + 'between', + 'around', + 'evenly', + 'stretch', + 'baseline', + ] as const, + alignSecondaryAxis: () => ['start', 'end', 'center', 'stretch'] as const, + unambiguousSpacing: () => [isArbitraryVariable, isArbitraryValue, theme.spacing] as const, + margin: () => ['auto', isArbitraryVariable, isArbitraryValue, theme.spacing] as const, + sizing: () => + [ + isFraction, + 'auto', + 'px', + 'full', + 'dvw', + 'dvh', + 'lvw', + 'lvh', + 'svw', + 'svh', + 'min', + 'max', + 'fit', + isArbitraryVariable, + isArbitraryValue, + theme.spacing, + ] as const, + gradientStopPosition: () => [isPercent, isArbitraryLength] as const, + borderWidth: () => ['', isNumber, isArbitraryVariableLength, isArbitraryLength] as const, + lineStyle: () => ['solid', 'dashed', 'dotted', 'double'] as const, + blendMode: () => + [ + 'normal', + 'multiply', + 'screen', + 'overlay', + 'darken', + 'lighten', + 'color-dodge', + 'color-burn', + 'hard-light', + 'soft-light', + 'difference', + 'exclusion', + 'hue', + 'saturation', + 'color', + 'luminosity', + ] as const, + origin: () => + [ + 'center', + 'top', + 'top-right', + 'right', + 'bottom-right', + 'bottom', + 'bottom-left', + 'left', + 'top-left', + isArbitraryVariable, + isArbitraryValue, + ] as const, + rotate: () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const, + scale: () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const, + skew: () => [isNumber, isArbitraryVariable, isArbitraryValue] as const, + translate: () => + [ + isFraction, + 'full', + 'px', + isArbitraryVariable, + isArbitraryValue, + theme.spacing, + ] as const, + } satisfies Record ClassGroup> return { cacheSize: 500, @@ -220,7 +249,7 @@ export const getDefaultConfig = () => { isFraction, isArbitraryValue, isArbitraryVariable, - aspect, + theme.aspect, ], }, ], @@ -234,17 +263,19 @@ export const getDefaultConfig = () => { * Columns * @see https://tailwindcss.com/docs/columns */ - columns: [{ columns: [isNumber, isArbitraryValue, isArbitraryVariable, container] }], + columns: [ + { columns: [isNumber, isArbitraryValue, isArbitraryVariable, theme.container] }, + ], /** * Break After * @see https://tailwindcss.com/docs/break-after */ - 'break-after': [{ 'break-after': getBreakScale() }], + 'break-after': [{ 'break-after': scale.break() }], /** * Break Before * @see https://tailwindcss.com/docs/break-before */ - 'break-before': [{ 'break-before': getBreakScale() }], + 'break-before': [{ 'break-before': scale.break() }], /** * Break Inside * @see https://tailwindcss.com/docs/break-inside @@ -317,38 +348,38 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/object-position */ 'object-position': [ - { object: [...getPositionScale(), isArbitraryValue, isArbitraryVariable] }, + { object: [...scale.position(), isArbitraryValue, isArbitraryVariable] }, ], /** * Overflow * @see https://tailwindcss.com/docs/overflow */ - overflow: [{ overflow: getOverflowScale() }], + overflow: [{ overflow: scale.overflow() }], /** * Overflow X * @see https://tailwindcss.com/docs/overflow */ - 'overflow-x': [{ 'overflow-x': getOverflowScale() }], + 'overflow-x': [{ 'overflow-x': scale.overflow() }], /** * Overflow Y * @see https://tailwindcss.com/docs/overflow */ - 'overflow-y': [{ 'overflow-y': getOverflowScale() }], + 'overflow-y': [{ 'overflow-y': scale.overflow() }], /** * Overscroll Behavior * @see https://tailwindcss.com/docs/overscroll-behavior */ - overscroll: [{ overscroll: getOverscrollScale() }], + overscroll: [{ overscroll: scale.overscroll() }], /** * Overscroll Behavior X * @see https://tailwindcss.com/docs/overscroll-behavior */ - 'overscroll-x': [{ 'overscroll-x': getOverscrollScale() }], + 'overscroll-x': [{ 'overscroll-x': scale.overscroll() }], /** * Overscroll Behavior Y * @see https://tailwindcss.com/docs/overscroll-behavior */ - 'overscroll-y': [{ 'overscroll-y': getOverscrollScale() }], + 'overscroll-y': [{ 'overscroll-y': scale.overscroll() }], /** * Position * @see https://tailwindcss.com/docs/position @@ -358,47 +389,47 @@ export const getDefaultConfig = () => { * Top / Right / Bottom / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - inset: [{ inset: getInsetScale() }], + inset: [{ inset: scale.inset() }], /** * Right / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - 'inset-x': [{ 'inset-x': getInsetScale() }], + 'inset-x': [{ 'inset-x': scale.inset() }], /** * Top / Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ - 'inset-y': [{ 'inset-y': getInsetScale() }], + 'inset-y': [{ 'inset-y': scale.inset() }], /** * Start * @see https://tailwindcss.com/docs/top-right-bottom-left */ - start: [{ start: getInsetScale() }], + start: [{ start: scale.inset() }], /** * End * @see https://tailwindcss.com/docs/top-right-bottom-left */ - end: [{ end: getInsetScale() }], + end: [{ end: scale.inset() }], /** * Top * @see https://tailwindcss.com/docs/top-right-bottom-left */ - top: [{ top: getInsetScale() }], + top: [{ top: scale.inset() }], /** * Right * @see https://tailwindcss.com/docs/top-right-bottom-left */ - right: [{ right: getInsetScale() }], + right: [{ right: scale.inset() }], /** * Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ - bottom: [{ bottom: getInsetScale() }], + bottom: [{ bottom: scale.inset() }], /** * Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - left: [{ left: getInsetScale() }], + left: [{ left: scale.inset() }], /** * Visibility * @see https://tailwindcss.com/docs/visibility @@ -426,8 +457,8 @@ export const getDefaultConfig = () => { 'auto', isArbitraryVariable, isArbitraryValue, - container, - spacing, + theme.container, + theme.spacing, ], }, ], @@ -476,42 +507,42 @@ export const getDefaultConfig = () => { * Grid Template Columns * @see https://tailwindcss.com/docs/grid-template-columns */ - 'grid-cols': [{ 'grid-cols': getGridTemplateColsRowsScale() }], + 'grid-cols': [{ 'grid-cols': scale.gridTemplateColsRows() }], /** * Grid Column Start / End * @see https://tailwindcss.com/docs/grid-column */ - 'col-start-end': [{ col: getGridColRowStartAndEndScale() }], + 'col-start-end': [{ col: scale.gridColRowStartAndEnd() }], /** * Grid Column Start * @see https://tailwindcss.com/docs/grid-column */ - 'col-start': [{ 'col-start': getGridColRowStartOrEndScale() }], + 'col-start': [{ 'col-start': scale.gridColRowStartOrEnd() }], /** * Grid Column End * @see https://tailwindcss.com/docs/grid-column */ - 'col-end': [{ 'col-end': getGridColRowStartOrEndScale() }], + 'col-end': [{ 'col-end': scale.gridColRowStartOrEnd() }], /** * Grid Template Rows * @see https://tailwindcss.com/docs/grid-template-rows */ - 'grid-rows': [{ 'grid-rows': getGridTemplateColsRowsScale() }], + 'grid-rows': [{ 'grid-rows': scale.gridTemplateColsRows() }], /** * Grid Row Start / End * @see https://tailwindcss.com/docs/grid-row */ - 'row-start-end': [{ row: getGridColRowStartAndEndScale() }], + 'row-start-end': [{ row: scale.gridColRowStartAndEnd() }], /** * Grid Row Start * @see https://tailwindcss.com/docs/grid-row */ - 'row-start': [{ 'row-start': getGridColRowStartOrEndScale() }], + 'row-start': [{ 'row-start': scale.gridColRowStartOrEnd() }], /** * Grid Row End * @see https://tailwindcss.com/docs/grid-row */ - 'row-end': [{ 'row-end': getGridColRowStartOrEndScale() }], + 'row-end': [{ 'row-end': scale.gridColRowStartOrEnd() }], /** * Grid Auto Flow * @see https://tailwindcss.com/docs/grid-auto-flow @@ -521,168 +552,168 @@ export const getDefaultConfig = () => { * Grid Auto Columns * @see https://tailwindcss.com/docs/grid-auto-columns */ - 'auto-cols': [{ 'auto-cols': getGridAutoColsRowsScale() }], + 'auto-cols': [{ 'auto-cols': scale.gridAutoColsRows() }], /** * Grid Auto Rows * @see https://tailwindcss.com/docs/grid-auto-rows */ - 'auto-rows': [{ 'auto-rows': getGridAutoColsRowsScale() }], + 'auto-rows': [{ 'auto-rows': scale.gridAutoColsRows() }], /** * Gap * @see https://tailwindcss.com/docs/gap */ - gap: [{ gap: getGapScale() }], + gap: [{ gap: scale.gap() }], /** * Gap X * @see https://tailwindcss.com/docs/gap */ - 'gap-x': [{ 'gap-x': getGapScale() }], + 'gap-x': [{ 'gap-x': scale.gap() }], /** * Gap Y * @see https://tailwindcss.com/docs/gap */ - 'gap-y': [{ 'gap-y': getGapScale() }], + 'gap-y': [{ 'gap-y': scale.gap() }], /** * Justify Content * @see https://tailwindcss.com/docs/justify-content */ - 'justify-content': [{ justify: [...getAlignPrimaryAxisScale(), 'normal'] }], + 'justify-content': [{ justify: [...scale.alignPrimaryAxis(), 'normal'] }], /** * Justify Items * @see https://tailwindcss.com/docs/justify-items */ - 'justify-items': [{ 'justify-items': [...getAlignSecondaryAxisScale(), 'normal'] }], + 'justify-items': [{ 'justify-items': [...scale.alignSecondaryAxis(), 'normal'] }], /** * Justify Self * @see https://tailwindcss.com/docs/justify-self */ - 'justify-self': [{ 'justify-self': ['auto', ...getAlignSecondaryAxisScale()] }], + 'justify-self': [{ 'justify-self': ['auto', ...scale.alignSecondaryAxis()] }], /** * Align Content * @see https://tailwindcss.com/docs/align-content */ - 'align-content': [{ content: ['normal', ...getAlignPrimaryAxisScale()] }], + 'align-content': [{ content: ['normal', ...scale.alignPrimaryAxis()] }], /** * Align Items * @see https://tailwindcss.com/docs/align-items */ - 'align-items': [{ items: [...getAlignSecondaryAxisScale(), 'baseline'] }], + 'align-items': [{ items: [...scale.alignSecondaryAxis(), 'baseline'] }], /** * Align Self * @see https://tailwindcss.com/docs/align-self */ - 'align-self': [{ self: ['auto', ...getAlignSecondaryAxisScale(), 'baseline'] }], + 'align-self': [{ self: ['auto', ...scale.alignSecondaryAxis(), 'baseline'] }], /** * Place Content * @see https://tailwindcss.com/docs/place-content */ - 'place-content': [{ 'place-content': getAlignPrimaryAxisScale() }], + 'place-content': [{ 'place-content': scale.alignPrimaryAxis() }], /** * Place Items * @see https://tailwindcss.com/docs/place-items */ - 'place-items': [{ 'place-items': [...getAlignSecondaryAxisScale(), 'baseline'] }], + 'place-items': [{ 'place-items': [...scale.alignSecondaryAxis(), 'baseline'] }], /** * Place Self * @see https://tailwindcss.com/docs/place-self */ - 'place-self': [{ 'place-self': ['auto', ...getAlignSecondaryAxisScale()] }], + 'place-self': [{ 'place-self': ['auto', ...scale.alignSecondaryAxis()] }], // Spacing /** * Padding * @see https://tailwindcss.com/docs/padding */ - p: [{ p: getUnambiguousSpacingScale() }], + p: [{ p: scale.unambiguousSpacing() }], /** * Padding X * @see https://tailwindcss.com/docs/padding */ - px: [{ px: getUnambiguousSpacingScale() }], + px: [{ px: scale.unambiguousSpacing() }], /** * Padding Y * @see https://tailwindcss.com/docs/padding */ - py: [{ py: getUnambiguousSpacingScale() }], + py: [{ py: scale.unambiguousSpacing() }], /** * Padding Start * @see https://tailwindcss.com/docs/padding */ - ps: [{ ps: getUnambiguousSpacingScale() }], + ps: [{ ps: scale.unambiguousSpacing() }], /** * Padding End * @see https://tailwindcss.com/docs/padding */ - pe: [{ pe: getUnambiguousSpacingScale() }], + pe: [{ pe: scale.unambiguousSpacing() }], /** * Padding Top * @see https://tailwindcss.com/docs/padding */ - pt: [{ pt: getUnambiguousSpacingScale() }], + pt: [{ pt: scale.unambiguousSpacing() }], /** * Padding Right * @see https://tailwindcss.com/docs/padding */ - pr: [{ pr: getUnambiguousSpacingScale() }], + pr: [{ pr: scale.unambiguousSpacing() }], /** * Padding Bottom * @see https://tailwindcss.com/docs/padding */ - pb: [{ pb: getUnambiguousSpacingScale() }], + pb: [{ pb: scale.unambiguousSpacing() }], /** * Padding Left * @see https://tailwindcss.com/docs/padding */ - pl: [{ pl: getUnambiguousSpacingScale() }], + pl: [{ pl: scale.unambiguousSpacing() }], /** * Margin * @see https://tailwindcss.com/docs/margin */ - m: [{ m: getMarginScale() }], + m: [{ m: scale.margin() }], /** * Margin X * @see https://tailwindcss.com/docs/margin */ - mx: [{ mx: getMarginScale() }], + mx: [{ mx: scale.margin() }], /** * Margin Y * @see https://tailwindcss.com/docs/margin */ - my: [{ my: getMarginScale() }], + my: [{ my: scale.margin() }], /** * Margin Start * @see https://tailwindcss.com/docs/margin */ - ms: [{ ms: getMarginScale() }], + ms: [{ ms: scale.margin() }], /** * Margin End * @see https://tailwindcss.com/docs/margin */ - me: [{ me: getMarginScale() }], + me: [{ me: scale.margin() }], /** * Margin Top * @see https://tailwindcss.com/docs/margin */ - mt: [{ mt: getMarginScale() }], + mt: [{ mt: scale.margin() }], /** * Margin Right * @see https://tailwindcss.com/docs/margin */ - mr: [{ mr: getMarginScale() }], + mr: [{ mr: scale.margin() }], /** * Margin Bottom * @see https://tailwindcss.com/docs/margin */ - mb: [{ mb: getMarginScale() }], + mb: [{ mb: scale.margin() }], /** * Margin Left * @see https://tailwindcss.com/docs/margin */ - ml: [{ ml: getMarginScale() }], + ml: [{ ml: scale.margin() }], /** * Space Between X * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ - 'space-x': [{ 'space-x': getUnambiguousSpacingScale() }], + 'space-x': [{ 'space-x': scale.unambiguousSpacing() }], /** * Space Between X Reverse * @see https://tailwindcss.com/docs/margin#adding-space-between-children @@ -692,7 +723,7 @@ export const getDefaultConfig = () => { * Space Between Y * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ - 'space-y': [{ 'space-y': getUnambiguousSpacingScale() }], + 'space-y': [{ 'space-y': scale.unambiguousSpacing() }], /** * Space Between Y Reverse * @see https://tailwindcss.com/docs/margin#adding-space-between-children @@ -711,13 +742,13 @@ export const getDefaultConfig = () => { * Size * @see https://tailwindcss.com/docs/width#setting-both-width-and-height */ - size: [{ size: getSizingScale() }], - w: [{ w: [container, 'screen', ...getSizingScale()] }], + size: [{ size: scale.sizing() }], + w: [{ w: [theme.container, 'screen', ...scale.sizing()] }], /** * Min-Width * @see https://tailwindcss.com/docs/min-width */ - 'min-w': [{ 'min-w': [container, 'screen', 'none', ...getSizingScale()] }], + 'min-w': [{ 'min-w': [theme.container, 'screen', 'none', ...scale.sizing()] }], /** * Max-Width * @see https://tailwindcss.com/docs/max-width @@ -725,12 +756,12 @@ export const getDefaultConfig = () => { 'max-w': [ { 'max-w': [ - container, + theme.container, 'screen', 'none', 'prose', - { screen: [breakpoint] }, - ...getSizingScale(), + { screen: [theme.breakpoint] }, + ...scale.sizing(), ], }, ], @@ -738,17 +769,17 @@ export const getDefaultConfig = () => { * Height * @see https://tailwindcss.com/docs/height */ - h: [{ h: ['screen', ...getSizingScale()] }], + h: [{ h: ['screen', ...scale.sizing()] }], /** * Min-Height * @see https://tailwindcss.com/docs/min-height */ - 'min-h': [{ 'min-h': ['screen', 'none', ...getSizingScale()] }], + 'min-h': [{ 'min-h': ['screen', 'none', ...scale.sizing()] }], /** * Max-Height * @see https://tailwindcss.com/docs/max-height */ - 'max-h': [{ 'max-h': ['screen', ...getSizingScale()] }], + 'max-h': [{ 'max-h': ['screen', ...scale.sizing()] }], // ------------------ // --- Typography --- @@ -758,7 +789,7 @@ export const getDefaultConfig = () => { * Font Size * @see https://tailwindcss.com/docs/font-size */ - 'font-size': [{ text: [text] }], + 'font-size': [{ text: [theme.text] }], /** * Font Smoothing * @see https://tailwindcss.com/docs/font-smoothing @@ -773,7 +804,7 @@ export const getDefaultConfig = () => { * Font Weight * @see https://tailwindcss.com/docs/font-weight */ - 'font-weight': [{ font: [fontWeight, isArbitraryVariable, isArbitraryNumber] }], + 'font-weight': [{ font: [theme.fontWeight, isArbitraryVariable, isArbitraryNumber] }], /** * Font Stretch * @see https://tailwindcss.com/docs/font-stretch @@ -799,7 +830,7 @@ export const getDefaultConfig = () => { * Font Family * @see https://tailwindcss.com/docs/font-family */ - 'font-family': [{ font: [font] }], + 'font-family': [{ font: [theme.font] }], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font-variant-numeric @@ -834,7 +865,7 @@ export const getDefaultConfig = () => { * Letter Spacing * @see https://tailwindcss.com/docs/letter-spacing */ - tracking: [{ tracking: [tracking, isArbitraryVariable, isArbitraryValue] }], + tracking: [{ tracking: [theme.tracking, isArbitraryVariable, isArbitraryValue] }], /** * Line Clamp * @see https://tailwindcss.com/docs/line-clamp @@ -846,7 +877,9 @@ export const getDefaultConfig = () => { * Line Height * @see https://tailwindcss.com/docs/line-height */ - leading: [{ leading: [isArbitraryVariable, isArbitraryValue, leading, spacing] }], + leading: [ + { leading: [isArbitraryVariable, isArbitraryValue, theme.leading, theme.spacing] }, + ], /** * List Style Image * @see https://tailwindcss.com/docs/list-style-image @@ -874,12 +907,12 @@ export const getDefaultConfig = () => { * @deprecated since Tailwind CSS v3.0.0 * @see https://v3.tailwindcss.com/docs/placeholder-color */ - 'placeholder-color': [{ placeholder: [color] }], + 'placeholder-color': [{ placeholder: [theme.color] }], /** * Text Color * @see https://tailwindcss.com/docs/text-color */ - 'text-color': [{ text: [color] }], + 'text-color': [{ text: [theme.color] }], /** * Text Decoration * @see https://tailwindcss.com/docs/text-decoration @@ -889,7 +922,7 @@ export const getDefaultConfig = () => { * Text Decoration Style * @see https://tailwindcss.com/docs/text-decoration-style */ - 'text-decoration-style': [{ decoration: [...getLineStyleScale(), 'wavy'] }], + 'text-decoration-style': [{ decoration: [...scale.lineStyle(), 'wavy'] }], /** * Text Decoration Thickness * @see https://tailwindcss.com/docs/text-decoration-thickness @@ -909,7 +942,7 @@ export const getDefaultConfig = () => { * Text Decoration Color * @see https://tailwindcss.com/docs/text-decoration-color */ - 'text-decoration-color': [{ decoration: [color] }], + 'text-decoration-color': [{ decoration: [theme.color] }], /** * Text Underline Offset * @see https://tailwindcss.com/docs/text-underline-offset @@ -936,7 +969,7 @@ export const getDefaultConfig = () => { * Text Indent * @see https://tailwindcss.com/docs/text-indent */ - indent: [{ indent: ['px', ...getUnambiguousSpacingScale()] }], + indent: [{ indent: ['px', ...scale.unambiguousSpacing()] }], /** * Vertical Alignment * @see https://tailwindcss.com/docs/vertical-align @@ -1004,7 +1037,9 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/background-position */ 'bg-position': [ - { bg: [...getPositionScale(), isArbitraryVariablePosition, isArbitraryPosition] }, + { + bg: [...scale.position(), isArbitraryVariablePosition, isArbitraryPosition], + }, ], /** * Background Repeat @@ -1045,37 +1080,37 @@ export const getDefaultConfig = () => { * Background Color * @see https://tailwindcss.com/docs/background-color */ - 'bg-color': [{ bg: [color] }], + 'bg-color': [{ bg: [theme.color] }], /** * Gradient Color Stops From Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from-pos': [{ from: getGradientStopPositionScale() }], + 'gradient-from-pos': [{ from: scale.gradientStopPosition() }], /** * Gradient Color Stops Via Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via-pos': [{ via: getGradientStopPositionScale() }], + 'gradient-via-pos': [{ via: scale.gradientStopPosition() }], /** * Gradient Color Stops To Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to-pos': [{ to: getGradientStopPositionScale() }], + 'gradient-to-pos': [{ to: scale.gradientStopPosition() }], /** * Gradient Color Stops From * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from': [{ from: [color] }], + 'gradient-from': [{ from: [theme.color] }], /** * Gradient Color Stops Via * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via': [{ via: [color] }], + 'gradient-via': [{ via: [theme.color] }], /** * Gradient Color Stops To * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to': [{ to: [color] }], + 'gradient-to': [{ to: [theme.color] }], // --------------- // --- Borders --- @@ -1085,127 +1120,127 @@ export const getDefaultConfig = () => { * Border Radius * @see https://tailwindcss.com/docs/border-radius */ - rounded: [{ rounded: [radius] }], + rounded: [{ rounded: [theme.radius] }], /** * Border Radius Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-s': [{ 'rounded-s': [radius] }], + 'rounded-s': [{ 'rounded-s': [theme.radius] }], /** * Border Radius End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-e': [{ 'rounded-e': [radius] }], + 'rounded-e': [{ 'rounded-e': [theme.radius] }], /** * Border Radius Top * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-t': [{ 'rounded-t': [radius] }], + 'rounded-t': [{ 'rounded-t': [theme.radius] }], /** * Border Radius Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-r': [{ 'rounded-r': [radius] }], + 'rounded-r': [{ 'rounded-r': [theme.radius] }], /** * Border Radius Bottom * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-b': [{ 'rounded-b': [radius] }], + 'rounded-b': [{ 'rounded-b': [theme.radius] }], /** * Border Radius Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-l': [{ 'rounded-l': [radius] }], + 'rounded-l': [{ 'rounded-l': [theme.radius] }], /** * Border Radius Start Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ss': [{ 'rounded-ss': [radius] }], + 'rounded-ss': [{ 'rounded-ss': [theme.radius] }], /** * Border Radius Start End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-se': [{ 'rounded-se': [radius] }], + 'rounded-se': [{ 'rounded-se': [theme.radius] }], /** * Border Radius End End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ee': [{ 'rounded-ee': [radius] }], + 'rounded-ee': [{ 'rounded-ee': [theme.radius] }], /** * Border Radius End Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-es': [{ 'rounded-es': [radius] }], + 'rounded-es': [{ 'rounded-es': [theme.radius] }], /** * Border Radius Top Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tl': [{ 'rounded-tl': [radius] }], + 'rounded-tl': [{ 'rounded-tl': [theme.radius] }], /** * Border Radius Top Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tr': [{ 'rounded-tr': [radius] }], + 'rounded-tr': [{ 'rounded-tr': [theme.radius] }], /** * Border Radius Bottom Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-br': [{ 'rounded-br': [radius] }], + 'rounded-br': [{ 'rounded-br': [theme.radius] }], /** * Border Radius Bottom Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-bl': [{ 'rounded-bl': [radius] }], + 'rounded-bl': [{ 'rounded-bl': [theme.radius] }], /** * Border Width * @see https://tailwindcss.com/docs/border-width */ - 'border-w': [{ border: getBorderWidthScale() }], + 'border-w': [{ border: scale.borderWidth() }], /** * Border Width X * @see https://tailwindcss.com/docs/border-width */ - 'border-w-x': [{ 'border-x': getBorderWidthScale() }], + 'border-w-x': [{ 'border-x': scale.borderWidth() }], /** * Border Width Y * @see https://tailwindcss.com/docs/border-width */ - 'border-w-y': [{ 'border-y': getBorderWidthScale() }], + 'border-w-y': [{ 'border-y': scale.borderWidth() }], /** * Border Width Start * @see https://tailwindcss.com/docs/border-width */ - 'border-w-s': [{ 'border-s': getBorderWidthScale() }], + 'border-w-s': [{ 'border-s': scale.borderWidth() }], /** * Border Width End * @see https://tailwindcss.com/docs/border-width */ - 'border-w-e': [{ 'border-e': getBorderWidthScale() }], + 'border-w-e': [{ 'border-e': scale.borderWidth() }], /** * Border Width Top * @see https://tailwindcss.com/docs/border-width */ - 'border-w-t': [{ 'border-t': getBorderWidthScale() }], + 'border-w-t': [{ 'border-t': scale.borderWidth() }], /** * Border Width Right * @see https://tailwindcss.com/docs/border-width */ - 'border-w-r': [{ 'border-r': getBorderWidthScale() }], + 'border-w-r': [{ 'border-r': scale.borderWidth() }], /** * Border Width Bottom * @see https://tailwindcss.com/docs/border-width */ - 'border-w-b': [{ 'border-b': getBorderWidthScale() }], + 'border-w-b': [{ 'border-b': scale.borderWidth() }], /** * Border Width Left * @see https://tailwindcss.com/docs/border-width */ - 'border-w-l': [{ 'border-l': getBorderWidthScale() }], + 'border-w-l': [{ 'border-l': scale.borderWidth() }], /** * Divide Width X * @see https://tailwindcss.com/docs/border-width#between-children */ - 'divide-x': [{ 'divide-x': getBorderWidthScale() }], + 'divide-x': [{ 'divide-x': scale.borderWidth() }], /** * Divide Width X Reverse * @see https://tailwindcss.com/docs/border-width#between-children @@ -1215,7 +1250,7 @@ export const getDefaultConfig = () => { * Divide Width Y * @see https://tailwindcss.com/docs/border-width#between-children */ - 'divide-y': [{ 'divide-y': getBorderWidthScale() }], + 'divide-y': [{ 'divide-y': scale.borderWidth() }], /** * Divide Width Y Reverse * @see https://tailwindcss.com/docs/border-width#between-children @@ -1225,67 +1260,67 @@ export const getDefaultConfig = () => { * Border Style * @see https://tailwindcss.com/docs/border-style */ - 'border-style': [{ border: [...getLineStyleScale(), 'hidden', 'none'] }], + 'border-style': [{ border: [...scale.lineStyle(), 'hidden', 'none'] }], /** * Divide Style * @see https://tailwindcss.com/docs/border-style#setting-the-divider-style */ - 'divide-style': [{ divide: [...getLineStyleScale(), 'hidden', 'none'] }], + 'divide-style': [{ divide: [...scale.lineStyle(), 'hidden', 'none'] }], /** * Border Color * @see https://tailwindcss.com/docs/border-color */ - 'border-color': [{ border: [color] }], + 'border-color': [{ border: [theme.color] }], /** * Border Color X * @see https://tailwindcss.com/docs/border-color */ - 'border-color-x': [{ 'border-x': [color] }], + 'border-color-x': [{ 'border-x': [theme.color] }], /** * Border Color Y * @see https://tailwindcss.com/docs/border-color */ - 'border-color-y': [{ 'border-y': [color] }], + 'border-color-y': [{ 'border-y': [theme.color] }], /** * Border Color S * @see https://tailwindcss.com/docs/border-color */ - 'border-color-s': [{ 'border-s': [color] }], + 'border-color-s': [{ 'border-s': [theme.color] }], /** * Border Color E * @see https://tailwindcss.com/docs/border-color */ - 'border-color-e': [{ 'border-e': [color] }], + 'border-color-e': [{ 'border-e': [theme.color] }], /** * Border Color Top * @see https://tailwindcss.com/docs/border-color */ - 'border-color-t': [{ 'border-t': [color] }], + 'border-color-t': [{ 'border-t': [theme.color] }], /** * Border Color Right * @see https://tailwindcss.com/docs/border-color */ - 'border-color-r': [{ 'border-r': [color] }], + 'border-color-r': [{ 'border-r': [theme.color] }], /** * Border Color Bottom * @see https://tailwindcss.com/docs/border-color */ - 'border-color-b': [{ 'border-b': [color] }], + 'border-color-b': [{ 'border-b': [theme.color] }], /** * Border Color Left * @see https://tailwindcss.com/docs/border-color */ - 'border-color-l': [{ 'border-l': [color] }], + 'border-color-l': [{ 'border-l': [theme.color] }], /** * Divide Color * @see https://tailwindcss.com/docs/divide-color */ - 'divide-color': [{ divide: [color] }], + 'divide-color': [{ divide: [theme.color] }], /** * Outline Style * @see https://tailwindcss.com/docs/outline-style */ - 'outline-style': [{ outline: [...getLineStyleScale(), 'none', 'hidden'] }], + 'outline-style': [{ outline: [...scale.lineStyle(), 'none', 'hidden'] }], /** * Outline Offset * @see https://tailwindcss.com/docs/outline-offset @@ -1304,7 +1339,7 @@ export const getDefaultConfig = () => { * Outline Color * @see https://tailwindcss.com/docs/outline-color */ - 'outline-color': [{ outline: [color] }], + 'outline-color': [{ outline: [theme.color] }], // --------------- // --- Effects --- @@ -1319,7 +1354,7 @@ export const getDefaultConfig = () => { shadow: [ // Deprecated since Tailwind CSS v4.0.0 '', - shadow, + theme.shadow, ], }, ], @@ -1327,24 +1362,31 @@ export const getDefaultConfig = () => { * Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color */ - 'shadow-color': [{ shadow: [color] }], + 'shadow-color': [{ shadow: [theme.color] }], /** * Inset Box Shadow * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow */ 'inset-shadow': [ - { 'inset-shadow': ['none', isArbitraryVariable, isArbitraryValue, insetShadow] }, + { + 'inset-shadow': [ + 'none', + isArbitraryVariable, + isArbitraryValue, + theme.insetShadow, + ], + }, ], /** * Inset Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color */ - 'inset-shadow-color': [{ 'inset-shadow': [color] }], + 'inset-shadow-color': [{ 'inset-shadow': [theme.color] }], /** * Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring */ - 'ring-w': [{ ring: getBorderWidthScale() }], + 'ring-w': [{ ring: scale.borderWidth() }], /** * Ring Width Inset * @see https://v3.tailwindcss.com/docs/ring-width#inset-rings @@ -1356,7 +1398,7 @@ export const getDefaultConfig = () => { * Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color */ - 'ring-color': [{ ring: [color] }], + 'ring-color': [{ ring: [theme.color] }], /** * Ring Offset Width * @see https://v3.tailwindcss.com/docs/ring-offset-width @@ -1370,17 +1412,17 @@ export const getDefaultConfig = () => { * @deprecated since Tailwind CSS v4.0.0 * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ - 'ring-offset-color': [{ 'ring-offset': [color] }], + 'ring-offset-color': [{ 'ring-offset': [theme.color] }], /** * Inset Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring */ - 'inset-ring-w': [{ 'inset-ring': getBorderWidthScale() }], + 'inset-ring-w': [{ 'inset-ring': scale.borderWidth() }], /** * Inset Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color */ - 'inset-ring-color': [{ 'inset-ring': [color] }], + 'inset-ring-color': [{ 'inset-ring': [theme.color] }], /** * Opacity * @see https://tailwindcss.com/docs/opacity @@ -1390,12 +1432,12 @@ export const getDefaultConfig = () => { * Mix Blend Mode * @see https://tailwindcss.com/docs/mix-blend-mode */ - 'mix-blend': [{ 'mix-blend': [...getBlendModeScale(), 'plus-darker', 'plus-lighter'] }], + 'mix-blend': [{ 'mix-blend': [...scale.blendMode(), 'plus-darker', 'plus-lighter'] }], /** * Background Blend Mode * @see https://tailwindcss.com/docs/background-blend-mode */ - 'bg-blend': [{ 'bg-blend': getBlendModeScale() }], + 'bg-blend': [{ 'bg-blend': scale.blendMode() }], // --------------- // --- Filters --- @@ -1420,7 +1462,7 @@ export const getDefaultConfig = () => { * Blur * @see https://tailwindcss.com/docs/blur */ - blur: [{ blur: [blur] }], + blur: [{ blur: [theme.blur] }], /** * Brightness * @see https://tailwindcss.com/docs/brightness @@ -1435,7 +1477,7 @@ export const getDefaultConfig = () => { * Drop Shadow * @see https://tailwindcss.com/docs/drop-shadow */ - 'drop-shadow': [{ 'drop-shadow': [dropShadow] }], + 'drop-shadow': [{ 'drop-shadow': [theme.dropShadow] }], /** * Grayscale * @see https://tailwindcss.com/docs/grayscale @@ -1480,7 +1522,7 @@ export const getDefaultConfig = () => { * Backdrop Blur * @see https://tailwindcss.com/docs/backdrop-blur */ - 'backdrop-blur': [{ 'backdrop-blur': [blur] }], + 'backdrop-blur': [{ 'backdrop-blur': [theme.blur] }], /** * Backdrop Brightness * @see https://tailwindcss.com/docs/backdrop-brightness @@ -1551,17 +1593,17 @@ export const getDefaultConfig = () => { * Border Spacing * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing': [{ 'border-spacing': getUnambiguousSpacingScale() }], + 'border-spacing': [{ 'border-spacing': scale.unambiguousSpacing() }], /** * Border Spacing X * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing-x': [{ 'border-spacing-x': getUnambiguousSpacingScale() }], + 'border-spacing-x': [{ 'border-spacing-x': scale.unambiguousSpacing() }], /** * Border Spacing Y * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing-y': [{ 'border-spacing-y': getUnambiguousSpacingScale() }], + 'border-spacing-y': [{ 'border-spacing-y': scale.unambiguousSpacing() }], /** * Table Layout * @see https://tailwindcss.com/docs/table-layout @@ -1610,7 +1652,9 @@ export const getDefaultConfig = () => { * Transition Timing Function * @see https://tailwindcss.com/docs/transition-timing-function */ - ease: [{ ease: ['linear', 'initial', isArbitraryVariable, isArbitraryValue, ease] }], + ease: [ + { ease: ['linear', 'initial', isArbitraryVariable, isArbitraryValue, theme.ease] }, + ], /** * Transition Delay * @see https://tailwindcss.com/docs/transition-delay @@ -1620,7 +1664,7 @@ export const getDefaultConfig = () => { * Animation * @see https://tailwindcss.com/docs/animation */ - animate: [{ animate: ['none', isArbitraryVariable, isArbitraryValue, animate] }], + animate: [{ animate: ['none', isArbitraryVariable, isArbitraryValue, theme.animate] }], // ------------------ // --- Transforms --- @@ -1635,52 +1679,54 @@ export const getDefaultConfig = () => { * Perspective * @see https://tailwindcss.com/docs/perspective */ - perspective: [{ perspective: [perspective, isArbitraryVariable, isArbitraryValue] }], + perspective: [ + { perspective: [theme.perspective, isArbitraryVariable, isArbitraryValue] }, + ], /** * Perspective Origin * @see https://tailwindcss.com/docs/perspective-origin */ - 'perspective-origin': [{ 'perspective-origin': getOriginScale() }], + 'perspective-origin': [{ 'perspective-origin': scale.origin() }], /** * Rotate * @see https://tailwindcss.com/docs/rotate */ - rotate: [{ rotate: getRotateScale() }], + rotate: [{ rotate: scale.rotate() }], /** * Rotate X * @see https://tailwindcss.com/docs/rotate */ - 'rotate-x': [{ 'rotate-x': getRotateScale() }], + 'rotate-x': [{ 'rotate-x': scale.rotate() }], /** * Rotate Y * @see https://tailwindcss.com/docs/rotate */ - 'rotate-y': [{ 'rotate-y': getRotateScale() }], + 'rotate-y': [{ 'rotate-y': scale.rotate() }], /** * Rotate Z * @see https://tailwindcss.com/docs/rotate */ - 'rotate-z': [{ 'rotate-z': getRotateScale() }], + 'rotate-z': [{ 'rotate-z': scale.rotate() }], /** * Scale * @see https://tailwindcss.com/docs/scale */ - scale: [{ scale: getScaleScale() }], + scale: [{ scale: scale.scale() }], /** * Scale X * @see https://tailwindcss.com/docs/scale */ - 'scale-x': [{ 'scale-x': getScaleScale() }], + 'scale-x': [{ 'scale-x': scale.scale() }], /** * Scale Y * @see https://tailwindcss.com/docs/scale */ - 'scale-y': [{ 'scale-y': getScaleScale() }], + 'scale-y': [{ 'scale-y': scale.scale() }], /** * Scale Z * @see https://tailwindcss.com/docs/scale */ - 'scale-z': [{ 'scale-z': getScaleScale() }], + 'scale-z': [{ 'scale-z': scale.scale() }], /** * Scale 3D * @see https://tailwindcss.com/docs/scale @@ -1690,17 +1736,17 @@ export const getDefaultConfig = () => { * Skew * @see https://tailwindcss.com/docs/skew */ - skew: [{ skew: getSkewScale() }], + skew: [{ skew: scale.skew() }], /** * Skew X * @see https://tailwindcss.com/docs/skew */ - 'skew-x': [{ 'skew-x': getSkewScale() }], + 'skew-x': [{ 'skew-x': scale.skew() }], /** * Skew Y * @see https://tailwindcss.com/docs/skew */ - 'skew-y': [{ 'skew-y': getSkewScale() }], + 'skew-y': [{ 'skew-y': scale.skew() }], /** * Transform * @see https://tailwindcss.com/docs/transform @@ -1712,7 +1758,7 @@ export const getDefaultConfig = () => { * Transform Origin * @see https://tailwindcss.com/docs/transform-origin */ - 'transform-origin': [{ origin: getOriginScale() }], + 'transform-origin': [{ origin: scale.origin() }], /** * Transform Style * @see https://tailwindcss.com/docs/transform-style @@ -1722,22 +1768,22 @@ export const getDefaultConfig = () => { * Translate * @see https://tailwindcss.com/docs/translate */ - translate: [{ translate: getTranslateScale() }], + translate: [{ translate: scale.translate() }], /** * Translate X * @see https://tailwindcss.com/docs/translate */ - 'translate-x': [{ 'translate-x': getTranslateScale() }], + 'translate-x': [{ 'translate-x': scale.translate() }], /** * Translate Y * @see https://tailwindcss.com/docs/translate */ - 'translate-y': [{ 'translate-y': getTranslateScale() }], + 'translate-y': [{ 'translate-y': scale.translate() }], /** * Translate Z * @see https://tailwindcss.com/docs/translate */ - 'translate-z': [{ 'translate-z': getTranslateScale() }], + 'translate-z': [{ 'translate-z': scale.translate() }], /** * Translate None * @see https://tailwindcss.com/docs/translate @@ -1752,7 +1798,7 @@ export const getDefaultConfig = () => { * Accent Color * @see https://tailwindcss.com/docs/accent-color */ - accent: [{ accent: [color] }], + accent: [{ accent: [theme.color] }], /** * Appearance * @see https://tailwindcss.com/docs/appearance @@ -1762,7 +1808,7 @@ export const getDefaultConfig = () => { * Caret Color * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities */ - 'caret-color': [{ caret: [color] }], + 'caret-color': [{ caret: [theme.color] }], /** * Color Scheme * @see https://tailwindcss.com/docs/color-scheme @@ -1842,92 +1888,92 @@ export const getDefaultConfig = () => { * Scroll Margin * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-m': [{ 'scroll-m': getUnambiguousSpacingScale() }], + 'scroll-m': [{ 'scroll-m': scale.unambiguousSpacing() }], /** * Scroll Margin X * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mx': [{ 'scroll-mx': getUnambiguousSpacingScale() }], + 'scroll-mx': [{ 'scroll-mx': scale.unambiguousSpacing() }], /** * Scroll Margin Y * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-my': [{ 'scroll-my': getUnambiguousSpacingScale() }], + 'scroll-my': [{ 'scroll-my': scale.unambiguousSpacing() }], /** * Scroll Margin Start * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-ms': [{ 'scroll-ms': getUnambiguousSpacingScale() }], + 'scroll-ms': [{ 'scroll-ms': scale.unambiguousSpacing() }], /** * Scroll Margin End * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-me': [{ 'scroll-me': getUnambiguousSpacingScale() }], + 'scroll-me': [{ 'scroll-me': scale.unambiguousSpacing() }], /** * Scroll Margin Top * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mt': [{ 'scroll-mt': getUnambiguousSpacingScale() }], + 'scroll-mt': [{ 'scroll-mt': scale.unambiguousSpacing() }], /** * Scroll Margin Right * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mr': [{ 'scroll-mr': getUnambiguousSpacingScale() }], + 'scroll-mr': [{ 'scroll-mr': scale.unambiguousSpacing() }], /** * Scroll Margin Bottom * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mb': [{ 'scroll-mb': getUnambiguousSpacingScale() }], + 'scroll-mb': [{ 'scroll-mb': scale.unambiguousSpacing() }], /** * Scroll Margin Left * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-ml': [{ 'scroll-ml': getUnambiguousSpacingScale() }], + 'scroll-ml': [{ 'scroll-ml': scale.unambiguousSpacing() }], /** * Scroll Padding * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-p': [{ 'scroll-p': getUnambiguousSpacingScale() }], + 'scroll-p': [{ 'scroll-p': scale.unambiguousSpacing() }], /** * Scroll Padding X * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-px': [{ 'scroll-px': getUnambiguousSpacingScale() }], + 'scroll-px': [{ 'scroll-px': scale.unambiguousSpacing() }], /** * Scroll Padding Y * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-py': [{ 'scroll-py': getUnambiguousSpacingScale() }], + 'scroll-py': [{ 'scroll-py': scale.unambiguousSpacing() }], /** * Scroll Padding Start * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-ps': [{ 'scroll-ps': getUnambiguousSpacingScale() }], + 'scroll-ps': [{ 'scroll-ps': scale.unambiguousSpacing() }], /** * Scroll Padding End * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pe': [{ 'scroll-pe': getUnambiguousSpacingScale() }], + 'scroll-pe': [{ 'scroll-pe': scale.unambiguousSpacing() }], /** * Scroll Padding Top * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pt': [{ 'scroll-pt': getUnambiguousSpacingScale() }], + 'scroll-pt': [{ 'scroll-pt': scale.unambiguousSpacing() }], /** * Scroll Padding Right * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pr': [{ 'scroll-pr': getUnambiguousSpacingScale() }], + 'scroll-pr': [{ 'scroll-pr': scale.unambiguousSpacing() }], /** * Scroll Padding Bottom * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pb': [{ 'scroll-pb': getUnambiguousSpacingScale() }], + 'scroll-pb': [{ 'scroll-pb': scale.unambiguousSpacing() }], /** * Scroll Padding Left * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pl': [{ 'scroll-pl': getUnambiguousSpacingScale() }], + 'scroll-pl': [{ 'scroll-pl': scale.unambiguousSpacing() }], /** * Scroll Snap Align * @see https://tailwindcss.com/docs/scroll-snap-align @@ -1998,7 +2044,7 @@ export const getDefaultConfig = () => { * Fill * @see https://tailwindcss.com/docs/fill */ - fill: [{ fill: ['none', color] }], + fill: [{ fill: ['none', theme.color] }], /** * Stroke Width * @see https://tailwindcss.com/docs/stroke-width @@ -2017,7 +2063,7 @@ export const getDefaultConfig = () => { * Stroke * @see https://tailwindcss.com/docs/stroke */ - stroke: [{ stroke: ['none', color] }], + stroke: [{ stroke: ['none', theme.color] }], // --------------------- // --- Accessibility --- From 1f1f572991e25369180b6470cfbf30440619a612 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 13:30:06 +0100 Subject: [PATCH 19/48] Revert "attempt: group theme getters and scale helpers into objects" Bundle size of twMerge increased from +5.6% to +9.4% due to this. This reverts commit 323870803145faaae85fd6ce2b2b4ba17a7a9608. --- src/lib/default-config.ts | 670 ++++++++++++++++++-------------------- 1 file changed, 312 insertions(+), 358 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 7921e50d..da8a1977 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -1,5 +1,5 @@ import { fromTheme } from './from-theme' -import { ClassGroup, Config, DefaultClassGroupIds, DefaultThemeGroupIds } from './types' +import { Config, DefaultClassGroupIds, DefaultThemeGroupIds } from './types' import { isAny, isAnyNonArbitrary, @@ -25,157 +25,128 @@ import { } from './validators' export const getDefaultConfig = () => { - /** - * Theme getters for theme variable namespaces - * @see https://tailwindcss.com/docs/theme#theme-variable-namespaces - */ - const theme = { - color: fromTheme('color'), - font: fromTheme('font'), - text: fromTheme('text'), - fontWeight: fromTheme('font-weight'), - tracking: fromTheme('tracking'), - leading: fromTheme('leading'), - breakpoint: fromTheme('breakpoint'), - container: fromTheme('container'), - spacing: fromTheme('spacing'), - radius: fromTheme('radius'), - shadow: fromTheme('shadow'), - insetShadow: fromTheme('inset-shadow'), - dropShadow: fromTheme('drop-shadow'), - blur: fromTheme('blur'), - perspective: fromTheme('perspective'), - aspect: fromTheme('aspect'), - ease: fromTheme('ease'), - animate: fromTheme('animate'), - } satisfies Record> + // Theme getters for theme variable namespaces: https://tailwindcss.com/docs/theme#theme-variable-namespaces - /** - * Helpers to avoid repeating the same scales - */ - const scale = { - break: () => - ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const, - position: () => - [ - 'bottom', - 'center', - 'left', - 'left-bottom', - 'left-top', - 'right', - 'right-bottom', - 'right-top', - 'top', - ] as const, - overflow: () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const, - overscroll: () => ['auto', 'contain', 'none'] as const, - inset: () => - [ - isFraction, - 'px', - 'full', - 'auto', - isArbitraryVariable, - isArbitraryValue, - theme.spacing, - ] as const, - gridTemplateColsRows: () => - [isInteger, 'none', 'subgrid', isArbitraryVariable, isArbitraryValue] as const, - gridColRowStartAndEnd: () => - [ - 'auto', - { span: ['full', isInteger, isArbitraryVariable, isArbitraryValue] }, - isArbitraryVariable, - isArbitraryValue, - ] as const, - gridColRowStartOrEnd: () => - [isInteger, 'auto', isArbitraryVariable, isArbitraryValue] as const, - gridAutoColsRows: () => - ['auto', 'min', 'max', 'fr', isArbitraryVariable, isArbitraryValue] as const, - gap: () => [isArbitraryVariable, isArbitraryValue, theme.spacing] as const, - alignPrimaryAxis: () => - [ - 'start', - 'end', - 'center', - 'between', - 'around', - 'evenly', - 'stretch', - 'baseline', - ] as const, - alignSecondaryAxis: () => ['start', 'end', 'center', 'stretch'] as const, - unambiguousSpacing: () => [isArbitraryVariable, isArbitraryValue, theme.spacing] as const, - margin: () => ['auto', isArbitraryVariable, isArbitraryValue, theme.spacing] as const, - sizing: () => - [ - isFraction, - 'auto', - 'px', - 'full', - 'dvw', - 'dvh', - 'lvw', - 'lvh', - 'svw', - 'svh', - 'min', - 'max', - 'fit', - isArbitraryVariable, - isArbitraryValue, - theme.spacing, - ] as const, - gradientStopPosition: () => [isPercent, isArbitraryLength] as const, - borderWidth: () => ['', isNumber, isArbitraryVariableLength, isArbitraryLength] as const, - lineStyle: () => ['solid', 'dashed', 'dotted', 'double'] as const, - blendMode: () => - [ - 'normal', - 'multiply', - 'screen', - 'overlay', - 'darken', - 'lighten', - 'color-dodge', - 'color-burn', - 'hard-light', - 'soft-light', - 'difference', - 'exclusion', - 'hue', - 'saturation', - 'color', - 'luminosity', - ] as const, - origin: () => - [ - 'center', - 'top', - 'top-right', - 'right', - 'bottom-right', - 'bottom', - 'bottom-left', - 'left', - 'top-left', - isArbitraryVariable, - isArbitraryValue, - ] as const, - rotate: () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const, - scale: () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const, - skew: () => [isNumber, isArbitraryVariable, isArbitraryValue] as const, - translate: () => - [ - isFraction, - 'full', - 'px', - isArbitraryVariable, - isArbitraryValue, - theme.spacing, - ] as const, - } satisfies Record ClassGroup> + const color = fromTheme('color') + const font = fromTheme('font') + const text = fromTheme('text') + const fontWeight = fromTheme('font-weight') + const tracking = fromTheme('tracking') + const leading = fromTheme('leading') + const breakpoint = fromTheme('breakpoint') + const container = fromTheme('container') + const spacing = fromTheme('spacing') + const radius = fromTheme('radius') + const shadow = fromTheme('shadow') + const insetShadow = fromTheme('inset-shadow') + const dropShadow = fromTheme('drop-shadow') + const blur = fromTheme('blur') + const perspective = fromTheme('perspective') + const aspect = fromTheme('aspect') + const ease = fromTheme('ease') + const animate = fromTheme('animate') + + // Helpers to avoid repeating the same values + + const getBreakScale = () => + ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const + const getPositionScale = () => + [ + 'bottom', + 'center', + 'left', + 'left-bottom', + 'left-top', + 'right', + 'right-bottom', + 'right-top', + 'top', + ] as const + const getOverflowScale = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const + const getOverscrollScale = () => ['auto', 'contain', 'none'] as const + const getInsetScale = () => + [isFraction, 'px', 'full', 'auto', isArbitraryVariable, isArbitraryValue, spacing] as const + const getGridTemplateColsRowsScale = () => + [isInteger, 'none', 'subgrid', isArbitraryVariable, isArbitraryValue] as const + const getGridColRowStartAndEndScale = () => + [ + 'auto', + { span: ['full', isInteger, isArbitraryVariable, isArbitraryValue] }, + isArbitraryVariable, + isArbitraryValue, + ] as const + const getGridColRowStartOrEndScale = () => + [isInteger, 'auto', isArbitraryVariable, isArbitraryValue] as const + const getGridAutoColsRowsScale = () => + ['auto', 'min', 'max', 'fr', isArbitraryVariable, isArbitraryValue] as const + const getGapScale = () => [isArbitraryVariable, isArbitraryValue, spacing] as const + const getAlignPrimaryAxisScale = () => + ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch', 'baseline'] as const + const getAlignSecondaryAxisScale = () => ['start', 'end', 'center', 'stretch'] as const + const getUnambiguousSpacingScale = () => + [isArbitraryVariable, isArbitraryValue, spacing] as const + const getMarginScale = () => ['auto', ...getUnambiguousSpacingScale()] as const + const getSizingScale = () => + [ + isFraction, + 'auto', + 'px', + 'full', + 'dvw', + 'dvh', + 'lvw', + 'lvh', + 'svw', + 'svh', + 'min', + 'max', + 'fit', + isArbitraryVariable, + isArbitraryValue, + spacing, + ] as const + const getGradientStopPositionScale = () => [isPercent, isArbitraryLength] as const + const getBorderWidthScale = () => + ['', isNumber, isArbitraryVariableLength, isArbitraryLength] as const + const getLineStyleScale = () => ['solid', 'dashed', 'dotted', 'double'] as const + const getBlendModeScale = () => + [ + 'normal', + 'multiply', + 'screen', + 'overlay', + 'darken', + 'lighten', + 'color-dodge', + 'color-burn', + 'hard-light', + 'soft-light', + 'difference', + 'exclusion', + 'hue', + 'saturation', + 'color', + 'luminosity', + ] as const + const getOriginScale = () => + [ + 'center', + 'top', + 'top-right', + 'right', + 'bottom-right', + 'bottom', + 'bottom-left', + 'left', + 'top-left', + isArbitraryVariable, + isArbitraryValue, + ] as const + const getRotateScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const + const getScaleScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const + const getSkewScale = () => [isNumber, isArbitraryVariable, isArbitraryValue] as const + const getTranslateScale = () => + [isFraction, 'full', 'px', isArbitraryVariable, isArbitraryValue, spacing] as const return { cacheSize: 500, @@ -249,7 +220,7 @@ export const getDefaultConfig = () => { isFraction, isArbitraryValue, isArbitraryVariable, - theme.aspect, + aspect, ], }, ], @@ -263,19 +234,17 @@ export const getDefaultConfig = () => { * Columns * @see https://tailwindcss.com/docs/columns */ - columns: [ - { columns: [isNumber, isArbitraryValue, isArbitraryVariable, theme.container] }, - ], + columns: [{ columns: [isNumber, isArbitraryValue, isArbitraryVariable, container] }], /** * Break After * @see https://tailwindcss.com/docs/break-after */ - 'break-after': [{ 'break-after': scale.break() }], + 'break-after': [{ 'break-after': getBreakScale() }], /** * Break Before * @see https://tailwindcss.com/docs/break-before */ - 'break-before': [{ 'break-before': scale.break() }], + 'break-before': [{ 'break-before': getBreakScale() }], /** * Break Inside * @see https://tailwindcss.com/docs/break-inside @@ -348,38 +317,38 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/object-position */ 'object-position': [ - { object: [...scale.position(), isArbitraryValue, isArbitraryVariable] }, + { object: [...getPositionScale(), isArbitraryValue, isArbitraryVariable] }, ], /** * Overflow * @see https://tailwindcss.com/docs/overflow */ - overflow: [{ overflow: scale.overflow() }], + overflow: [{ overflow: getOverflowScale() }], /** * Overflow X * @see https://tailwindcss.com/docs/overflow */ - 'overflow-x': [{ 'overflow-x': scale.overflow() }], + 'overflow-x': [{ 'overflow-x': getOverflowScale() }], /** * Overflow Y * @see https://tailwindcss.com/docs/overflow */ - 'overflow-y': [{ 'overflow-y': scale.overflow() }], + 'overflow-y': [{ 'overflow-y': getOverflowScale() }], /** * Overscroll Behavior * @see https://tailwindcss.com/docs/overscroll-behavior */ - overscroll: [{ overscroll: scale.overscroll() }], + overscroll: [{ overscroll: getOverscrollScale() }], /** * Overscroll Behavior X * @see https://tailwindcss.com/docs/overscroll-behavior */ - 'overscroll-x': [{ 'overscroll-x': scale.overscroll() }], + 'overscroll-x': [{ 'overscroll-x': getOverscrollScale() }], /** * Overscroll Behavior Y * @see https://tailwindcss.com/docs/overscroll-behavior */ - 'overscroll-y': [{ 'overscroll-y': scale.overscroll() }], + 'overscroll-y': [{ 'overscroll-y': getOverscrollScale() }], /** * Position * @see https://tailwindcss.com/docs/position @@ -389,47 +358,47 @@ export const getDefaultConfig = () => { * Top / Right / Bottom / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - inset: [{ inset: scale.inset() }], + inset: [{ inset: getInsetScale() }], /** * Right / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - 'inset-x': [{ 'inset-x': scale.inset() }], + 'inset-x': [{ 'inset-x': getInsetScale() }], /** * Top / Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ - 'inset-y': [{ 'inset-y': scale.inset() }], + 'inset-y': [{ 'inset-y': getInsetScale() }], /** * Start * @see https://tailwindcss.com/docs/top-right-bottom-left */ - start: [{ start: scale.inset() }], + start: [{ start: getInsetScale() }], /** * End * @see https://tailwindcss.com/docs/top-right-bottom-left */ - end: [{ end: scale.inset() }], + end: [{ end: getInsetScale() }], /** * Top * @see https://tailwindcss.com/docs/top-right-bottom-left */ - top: [{ top: scale.inset() }], + top: [{ top: getInsetScale() }], /** * Right * @see https://tailwindcss.com/docs/top-right-bottom-left */ - right: [{ right: scale.inset() }], + right: [{ right: getInsetScale() }], /** * Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ - bottom: [{ bottom: scale.inset() }], + bottom: [{ bottom: getInsetScale() }], /** * Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - left: [{ left: scale.inset() }], + left: [{ left: getInsetScale() }], /** * Visibility * @see https://tailwindcss.com/docs/visibility @@ -457,8 +426,8 @@ export const getDefaultConfig = () => { 'auto', isArbitraryVariable, isArbitraryValue, - theme.container, - theme.spacing, + container, + spacing, ], }, ], @@ -507,42 +476,42 @@ export const getDefaultConfig = () => { * Grid Template Columns * @see https://tailwindcss.com/docs/grid-template-columns */ - 'grid-cols': [{ 'grid-cols': scale.gridTemplateColsRows() }], + 'grid-cols': [{ 'grid-cols': getGridTemplateColsRowsScale() }], /** * Grid Column Start / End * @see https://tailwindcss.com/docs/grid-column */ - 'col-start-end': [{ col: scale.gridColRowStartAndEnd() }], + 'col-start-end': [{ col: getGridColRowStartAndEndScale() }], /** * Grid Column Start * @see https://tailwindcss.com/docs/grid-column */ - 'col-start': [{ 'col-start': scale.gridColRowStartOrEnd() }], + 'col-start': [{ 'col-start': getGridColRowStartOrEndScale() }], /** * Grid Column End * @see https://tailwindcss.com/docs/grid-column */ - 'col-end': [{ 'col-end': scale.gridColRowStartOrEnd() }], + 'col-end': [{ 'col-end': getGridColRowStartOrEndScale() }], /** * Grid Template Rows * @see https://tailwindcss.com/docs/grid-template-rows */ - 'grid-rows': [{ 'grid-rows': scale.gridTemplateColsRows() }], + 'grid-rows': [{ 'grid-rows': getGridTemplateColsRowsScale() }], /** * Grid Row Start / End * @see https://tailwindcss.com/docs/grid-row */ - 'row-start-end': [{ row: scale.gridColRowStartAndEnd() }], + 'row-start-end': [{ row: getGridColRowStartAndEndScale() }], /** * Grid Row Start * @see https://tailwindcss.com/docs/grid-row */ - 'row-start': [{ 'row-start': scale.gridColRowStartOrEnd() }], + 'row-start': [{ 'row-start': getGridColRowStartOrEndScale() }], /** * Grid Row End * @see https://tailwindcss.com/docs/grid-row */ - 'row-end': [{ 'row-end': scale.gridColRowStartOrEnd() }], + 'row-end': [{ 'row-end': getGridColRowStartOrEndScale() }], /** * Grid Auto Flow * @see https://tailwindcss.com/docs/grid-auto-flow @@ -552,168 +521,168 @@ export const getDefaultConfig = () => { * Grid Auto Columns * @see https://tailwindcss.com/docs/grid-auto-columns */ - 'auto-cols': [{ 'auto-cols': scale.gridAutoColsRows() }], + 'auto-cols': [{ 'auto-cols': getGridAutoColsRowsScale() }], /** * Grid Auto Rows * @see https://tailwindcss.com/docs/grid-auto-rows */ - 'auto-rows': [{ 'auto-rows': scale.gridAutoColsRows() }], + 'auto-rows': [{ 'auto-rows': getGridAutoColsRowsScale() }], /** * Gap * @see https://tailwindcss.com/docs/gap */ - gap: [{ gap: scale.gap() }], + gap: [{ gap: getGapScale() }], /** * Gap X * @see https://tailwindcss.com/docs/gap */ - 'gap-x': [{ 'gap-x': scale.gap() }], + 'gap-x': [{ 'gap-x': getGapScale() }], /** * Gap Y * @see https://tailwindcss.com/docs/gap */ - 'gap-y': [{ 'gap-y': scale.gap() }], + 'gap-y': [{ 'gap-y': getGapScale() }], /** * Justify Content * @see https://tailwindcss.com/docs/justify-content */ - 'justify-content': [{ justify: [...scale.alignPrimaryAxis(), 'normal'] }], + 'justify-content': [{ justify: [...getAlignPrimaryAxisScale(), 'normal'] }], /** * Justify Items * @see https://tailwindcss.com/docs/justify-items */ - 'justify-items': [{ 'justify-items': [...scale.alignSecondaryAxis(), 'normal'] }], + 'justify-items': [{ 'justify-items': [...getAlignSecondaryAxisScale(), 'normal'] }], /** * Justify Self * @see https://tailwindcss.com/docs/justify-self */ - 'justify-self': [{ 'justify-self': ['auto', ...scale.alignSecondaryAxis()] }], + 'justify-self': [{ 'justify-self': ['auto', ...getAlignSecondaryAxisScale()] }], /** * Align Content * @see https://tailwindcss.com/docs/align-content */ - 'align-content': [{ content: ['normal', ...scale.alignPrimaryAxis()] }], + 'align-content': [{ content: ['normal', ...getAlignPrimaryAxisScale()] }], /** * Align Items * @see https://tailwindcss.com/docs/align-items */ - 'align-items': [{ items: [...scale.alignSecondaryAxis(), 'baseline'] }], + 'align-items': [{ items: [...getAlignSecondaryAxisScale(), 'baseline'] }], /** * Align Self * @see https://tailwindcss.com/docs/align-self */ - 'align-self': [{ self: ['auto', ...scale.alignSecondaryAxis(), 'baseline'] }], + 'align-self': [{ self: ['auto', ...getAlignSecondaryAxisScale(), 'baseline'] }], /** * Place Content * @see https://tailwindcss.com/docs/place-content */ - 'place-content': [{ 'place-content': scale.alignPrimaryAxis() }], + 'place-content': [{ 'place-content': getAlignPrimaryAxisScale() }], /** * Place Items * @see https://tailwindcss.com/docs/place-items */ - 'place-items': [{ 'place-items': [...scale.alignSecondaryAxis(), 'baseline'] }], + 'place-items': [{ 'place-items': [...getAlignSecondaryAxisScale(), 'baseline'] }], /** * Place Self * @see https://tailwindcss.com/docs/place-self */ - 'place-self': [{ 'place-self': ['auto', ...scale.alignSecondaryAxis()] }], + 'place-self': [{ 'place-self': ['auto', ...getAlignSecondaryAxisScale()] }], // Spacing /** * Padding * @see https://tailwindcss.com/docs/padding */ - p: [{ p: scale.unambiguousSpacing() }], + p: [{ p: getUnambiguousSpacingScale() }], /** * Padding X * @see https://tailwindcss.com/docs/padding */ - px: [{ px: scale.unambiguousSpacing() }], + px: [{ px: getUnambiguousSpacingScale() }], /** * Padding Y * @see https://tailwindcss.com/docs/padding */ - py: [{ py: scale.unambiguousSpacing() }], + py: [{ py: getUnambiguousSpacingScale() }], /** * Padding Start * @see https://tailwindcss.com/docs/padding */ - ps: [{ ps: scale.unambiguousSpacing() }], + ps: [{ ps: getUnambiguousSpacingScale() }], /** * Padding End * @see https://tailwindcss.com/docs/padding */ - pe: [{ pe: scale.unambiguousSpacing() }], + pe: [{ pe: getUnambiguousSpacingScale() }], /** * Padding Top * @see https://tailwindcss.com/docs/padding */ - pt: [{ pt: scale.unambiguousSpacing() }], + pt: [{ pt: getUnambiguousSpacingScale() }], /** * Padding Right * @see https://tailwindcss.com/docs/padding */ - pr: [{ pr: scale.unambiguousSpacing() }], + pr: [{ pr: getUnambiguousSpacingScale() }], /** * Padding Bottom * @see https://tailwindcss.com/docs/padding */ - pb: [{ pb: scale.unambiguousSpacing() }], + pb: [{ pb: getUnambiguousSpacingScale() }], /** * Padding Left * @see https://tailwindcss.com/docs/padding */ - pl: [{ pl: scale.unambiguousSpacing() }], + pl: [{ pl: getUnambiguousSpacingScale() }], /** * Margin * @see https://tailwindcss.com/docs/margin */ - m: [{ m: scale.margin() }], + m: [{ m: getMarginScale() }], /** * Margin X * @see https://tailwindcss.com/docs/margin */ - mx: [{ mx: scale.margin() }], + mx: [{ mx: getMarginScale() }], /** * Margin Y * @see https://tailwindcss.com/docs/margin */ - my: [{ my: scale.margin() }], + my: [{ my: getMarginScale() }], /** * Margin Start * @see https://tailwindcss.com/docs/margin */ - ms: [{ ms: scale.margin() }], + ms: [{ ms: getMarginScale() }], /** * Margin End * @see https://tailwindcss.com/docs/margin */ - me: [{ me: scale.margin() }], + me: [{ me: getMarginScale() }], /** * Margin Top * @see https://tailwindcss.com/docs/margin */ - mt: [{ mt: scale.margin() }], + mt: [{ mt: getMarginScale() }], /** * Margin Right * @see https://tailwindcss.com/docs/margin */ - mr: [{ mr: scale.margin() }], + mr: [{ mr: getMarginScale() }], /** * Margin Bottom * @see https://tailwindcss.com/docs/margin */ - mb: [{ mb: scale.margin() }], + mb: [{ mb: getMarginScale() }], /** * Margin Left * @see https://tailwindcss.com/docs/margin */ - ml: [{ ml: scale.margin() }], + ml: [{ ml: getMarginScale() }], /** * Space Between X * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ - 'space-x': [{ 'space-x': scale.unambiguousSpacing() }], + 'space-x': [{ 'space-x': getUnambiguousSpacingScale() }], /** * Space Between X Reverse * @see https://tailwindcss.com/docs/margin#adding-space-between-children @@ -723,7 +692,7 @@ export const getDefaultConfig = () => { * Space Between Y * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ - 'space-y': [{ 'space-y': scale.unambiguousSpacing() }], + 'space-y': [{ 'space-y': getUnambiguousSpacingScale() }], /** * Space Between Y Reverse * @see https://tailwindcss.com/docs/margin#adding-space-between-children @@ -742,13 +711,13 @@ export const getDefaultConfig = () => { * Size * @see https://tailwindcss.com/docs/width#setting-both-width-and-height */ - size: [{ size: scale.sizing() }], - w: [{ w: [theme.container, 'screen', ...scale.sizing()] }], + size: [{ size: getSizingScale() }], + w: [{ w: [container, 'screen', ...getSizingScale()] }], /** * Min-Width * @see https://tailwindcss.com/docs/min-width */ - 'min-w': [{ 'min-w': [theme.container, 'screen', 'none', ...scale.sizing()] }], + 'min-w': [{ 'min-w': [container, 'screen', 'none', ...getSizingScale()] }], /** * Max-Width * @see https://tailwindcss.com/docs/max-width @@ -756,12 +725,12 @@ export const getDefaultConfig = () => { 'max-w': [ { 'max-w': [ - theme.container, + container, 'screen', 'none', 'prose', - { screen: [theme.breakpoint] }, - ...scale.sizing(), + { screen: [breakpoint] }, + ...getSizingScale(), ], }, ], @@ -769,17 +738,17 @@ export const getDefaultConfig = () => { * Height * @see https://tailwindcss.com/docs/height */ - h: [{ h: ['screen', ...scale.sizing()] }], + h: [{ h: ['screen', ...getSizingScale()] }], /** * Min-Height * @see https://tailwindcss.com/docs/min-height */ - 'min-h': [{ 'min-h': ['screen', 'none', ...scale.sizing()] }], + 'min-h': [{ 'min-h': ['screen', 'none', ...getSizingScale()] }], /** * Max-Height * @see https://tailwindcss.com/docs/max-height */ - 'max-h': [{ 'max-h': ['screen', ...scale.sizing()] }], + 'max-h': [{ 'max-h': ['screen', ...getSizingScale()] }], // ------------------ // --- Typography --- @@ -789,7 +758,7 @@ export const getDefaultConfig = () => { * Font Size * @see https://tailwindcss.com/docs/font-size */ - 'font-size': [{ text: [theme.text] }], + 'font-size': [{ text: [text] }], /** * Font Smoothing * @see https://tailwindcss.com/docs/font-smoothing @@ -804,7 +773,7 @@ export const getDefaultConfig = () => { * Font Weight * @see https://tailwindcss.com/docs/font-weight */ - 'font-weight': [{ font: [theme.fontWeight, isArbitraryVariable, isArbitraryNumber] }], + 'font-weight': [{ font: [fontWeight, isArbitraryVariable, isArbitraryNumber] }], /** * Font Stretch * @see https://tailwindcss.com/docs/font-stretch @@ -830,7 +799,7 @@ export const getDefaultConfig = () => { * Font Family * @see https://tailwindcss.com/docs/font-family */ - 'font-family': [{ font: [theme.font] }], + 'font-family': [{ font: [font] }], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font-variant-numeric @@ -865,7 +834,7 @@ export const getDefaultConfig = () => { * Letter Spacing * @see https://tailwindcss.com/docs/letter-spacing */ - tracking: [{ tracking: [theme.tracking, isArbitraryVariable, isArbitraryValue] }], + tracking: [{ tracking: [tracking, isArbitraryVariable, isArbitraryValue] }], /** * Line Clamp * @see https://tailwindcss.com/docs/line-clamp @@ -877,9 +846,7 @@ export const getDefaultConfig = () => { * Line Height * @see https://tailwindcss.com/docs/line-height */ - leading: [ - { leading: [isArbitraryVariable, isArbitraryValue, theme.leading, theme.spacing] }, - ], + leading: [{ leading: [isArbitraryVariable, isArbitraryValue, leading, spacing] }], /** * List Style Image * @see https://tailwindcss.com/docs/list-style-image @@ -907,12 +874,12 @@ export const getDefaultConfig = () => { * @deprecated since Tailwind CSS v3.0.0 * @see https://v3.tailwindcss.com/docs/placeholder-color */ - 'placeholder-color': [{ placeholder: [theme.color] }], + 'placeholder-color': [{ placeholder: [color] }], /** * Text Color * @see https://tailwindcss.com/docs/text-color */ - 'text-color': [{ text: [theme.color] }], + 'text-color': [{ text: [color] }], /** * Text Decoration * @see https://tailwindcss.com/docs/text-decoration @@ -922,7 +889,7 @@ export const getDefaultConfig = () => { * Text Decoration Style * @see https://tailwindcss.com/docs/text-decoration-style */ - 'text-decoration-style': [{ decoration: [...scale.lineStyle(), 'wavy'] }], + 'text-decoration-style': [{ decoration: [...getLineStyleScale(), 'wavy'] }], /** * Text Decoration Thickness * @see https://tailwindcss.com/docs/text-decoration-thickness @@ -942,7 +909,7 @@ export const getDefaultConfig = () => { * Text Decoration Color * @see https://tailwindcss.com/docs/text-decoration-color */ - 'text-decoration-color': [{ decoration: [theme.color] }], + 'text-decoration-color': [{ decoration: [color] }], /** * Text Underline Offset * @see https://tailwindcss.com/docs/text-underline-offset @@ -969,7 +936,7 @@ export const getDefaultConfig = () => { * Text Indent * @see https://tailwindcss.com/docs/text-indent */ - indent: [{ indent: ['px', ...scale.unambiguousSpacing()] }], + indent: [{ indent: ['px', ...getUnambiguousSpacingScale()] }], /** * Vertical Alignment * @see https://tailwindcss.com/docs/vertical-align @@ -1037,9 +1004,7 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/background-position */ 'bg-position': [ - { - bg: [...scale.position(), isArbitraryVariablePosition, isArbitraryPosition], - }, + { bg: [...getPositionScale(), isArbitraryVariablePosition, isArbitraryPosition] }, ], /** * Background Repeat @@ -1080,37 +1045,37 @@ export const getDefaultConfig = () => { * Background Color * @see https://tailwindcss.com/docs/background-color */ - 'bg-color': [{ bg: [theme.color] }], + 'bg-color': [{ bg: [color] }], /** * Gradient Color Stops From Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from-pos': [{ from: scale.gradientStopPosition() }], + 'gradient-from-pos': [{ from: getGradientStopPositionScale() }], /** * Gradient Color Stops Via Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via-pos': [{ via: scale.gradientStopPosition() }], + 'gradient-via-pos': [{ via: getGradientStopPositionScale() }], /** * Gradient Color Stops To Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to-pos': [{ to: scale.gradientStopPosition() }], + 'gradient-to-pos': [{ to: getGradientStopPositionScale() }], /** * Gradient Color Stops From * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from': [{ from: [theme.color] }], + 'gradient-from': [{ from: [color] }], /** * Gradient Color Stops Via * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via': [{ via: [theme.color] }], + 'gradient-via': [{ via: [color] }], /** * Gradient Color Stops To * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to': [{ to: [theme.color] }], + 'gradient-to': [{ to: [color] }], // --------------- // --- Borders --- @@ -1120,127 +1085,127 @@ export const getDefaultConfig = () => { * Border Radius * @see https://tailwindcss.com/docs/border-radius */ - rounded: [{ rounded: [theme.radius] }], + rounded: [{ rounded: [radius] }], /** * Border Radius Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-s': [{ 'rounded-s': [theme.radius] }], + 'rounded-s': [{ 'rounded-s': [radius] }], /** * Border Radius End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-e': [{ 'rounded-e': [theme.radius] }], + 'rounded-e': [{ 'rounded-e': [radius] }], /** * Border Radius Top * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-t': [{ 'rounded-t': [theme.radius] }], + 'rounded-t': [{ 'rounded-t': [radius] }], /** * Border Radius Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-r': [{ 'rounded-r': [theme.radius] }], + 'rounded-r': [{ 'rounded-r': [radius] }], /** * Border Radius Bottom * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-b': [{ 'rounded-b': [theme.radius] }], + 'rounded-b': [{ 'rounded-b': [radius] }], /** * Border Radius Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-l': [{ 'rounded-l': [theme.radius] }], + 'rounded-l': [{ 'rounded-l': [radius] }], /** * Border Radius Start Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ss': [{ 'rounded-ss': [theme.radius] }], + 'rounded-ss': [{ 'rounded-ss': [radius] }], /** * Border Radius Start End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-se': [{ 'rounded-se': [theme.radius] }], + 'rounded-se': [{ 'rounded-se': [radius] }], /** * Border Radius End End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ee': [{ 'rounded-ee': [theme.radius] }], + 'rounded-ee': [{ 'rounded-ee': [radius] }], /** * Border Radius End Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-es': [{ 'rounded-es': [theme.radius] }], + 'rounded-es': [{ 'rounded-es': [radius] }], /** * Border Radius Top Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tl': [{ 'rounded-tl': [theme.radius] }], + 'rounded-tl': [{ 'rounded-tl': [radius] }], /** * Border Radius Top Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tr': [{ 'rounded-tr': [theme.radius] }], + 'rounded-tr': [{ 'rounded-tr': [radius] }], /** * Border Radius Bottom Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-br': [{ 'rounded-br': [theme.radius] }], + 'rounded-br': [{ 'rounded-br': [radius] }], /** * Border Radius Bottom Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-bl': [{ 'rounded-bl': [theme.radius] }], + 'rounded-bl': [{ 'rounded-bl': [radius] }], /** * Border Width * @see https://tailwindcss.com/docs/border-width */ - 'border-w': [{ border: scale.borderWidth() }], + 'border-w': [{ border: getBorderWidthScale() }], /** * Border Width X * @see https://tailwindcss.com/docs/border-width */ - 'border-w-x': [{ 'border-x': scale.borderWidth() }], + 'border-w-x': [{ 'border-x': getBorderWidthScale() }], /** * Border Width Y * @see https://tailwindcss.com/docs/border-width */ - 'border-w-y': [{ 'border-y': scale.borderWidth() }], + 'border-w-y': [{ 'border-y': getBorderWidthScale() }], /** * Border Width Start * @see https://tailwindcss.com/docs/border-width */ - 'border-w-s': [{ 'border-s': scale.borderWidth() }], + 'border-w-s': [{ 'border-s': getBorderWidthScale() }], /** * Border Width End * @see https://tailwindcss.com/docs/border-width */ - 'border-w-e': [{ 'border-e': scale.borderWidth() }], + 'border-w-e': [{ 'border-e': getBorderWidthScale() }], /** * Border Width Top * @see https://tailwindcss.com/docs/border-width */ - 'border-w-t': [{ 'border-t': scale.borderWidth() }], + 'border-w-t': [{ 'border-t': getBorderWidthScale() }], /** * Border Width Right * @see https://tailwindcss.com/docs/border-width */ - 'border-w-r': [{ 'border-r': scale.borderWidth() }], + 'border-w-r': [{ 'border-r': getBorderWidthScale() }], /** * Border Width Bottom * @see https://tailwindcss.com/docs/border-width */ - 'border-w-b': [{ 'border-b': scale.borderWidth() }], + 'border-w-b': [{ 'border-b': getBorderWidthScale() }], /** * Border Width Left * @see https://tailwindcss.com/docs/border-width */ - 'border-w-l': [{ 'border-l': scale.borderWidth() }], + 'border-w-l': [{ 'border-l': getBorderWidthScale() }], /** * Divide Width X * @see https://tailwindcss.com/docs/border-width#between-children */ - 'divide-x': [{ 'divide-x': scale.borderWidth() }], + 'divide-x': [{ 'divide-x': getBorderWidthScale() }], /** * Divide Width X Reverse * @see https://tailwindcss.com/docs/border-width#between-children @@ -1250,7 +1215,7 @@ export const getDefaultConfig = () => { * Divide Width Y * @see https://tailwindcss.com/docs/border-width#between-children */ - 'divide-y': [{ 'divide-y': scale.borderWidth() }], + 'divide-y': [{ 'divide-y': getBorderWidthScale() }], /** * Divide Width Y Reverse * @see https://tailwindcss.com/docs/border-width#between-children @@ -1260,67 +1225,67 @@ export const getDefaultConfig = () => { * Border Style * @see https://tailwindcss.com/docs/border-style */ - 'border-style': [{ border: [...scale.lineStyle(), 'hidden', 'none'] }], + 'border-style': [{ border: [...getLineStyleScale(), 'hidden', 'none'] }], /** * Divide Style * @see https://tailwindcss.com/docs/border-style#setting-the-divider-style */ - 'divide-style': [{ divide: [...scale.lineStyle(), 'hidden', 'none'] }], + 'divide-style': [{ divide: [...getLineStyleScale(), 'hidden', 'none'] }], /** * Border Color * @see https://tailwindcss.com/docs/border-color */ - 'border-color': [{ border: [theme.color] }], + 'border-color': [{ border: [color] }], /** * Border Color X * @see https://tailwindcss.com/docs/border-color */ - 'border-color-x': [{ 'border-x': [theme.color] }], + 'border-color-x': [{ 'border-x': [color] }], /** * Border Color Y * @see https://tailwindcss.com/docs/border-color */ - 'border-color-y': [{ 'border-y': [theme.color] }], + 'border-color-y': [{ 'border-y': [color] }], /** * Border Color S * @see https://tailwindcss.com/docs/border-color */ - 'border-color-s': [{ 'border-s': [theme.color] }], + 'border-color-s': [{ 'border-s': [color] }], /** * Border Color E * @see https://tailwindcss.com/docs/border-color */ - 'border-color-e': [{ 'border-e': [theme.color] }], + 'border-color-e': [{ 'border-e': [color] }], /** * Border Color Top * @see https://tailwindcss.com/docs/border-color */ - 'border-color-t': [{ 'border-t': [theme.color] }], + 'border-color-t': [{ 'border-t': [color] }], /** * Border Color Right * @see https://tailwindcss.com/docs/border-color */ - 'border-color-r': [{ 'border-r': [theme.color] }], + 'border-color-r': [{ 'border-r': [color] }], /** * Border Color Bottom * @see https://tailwindcss.com/docs/border-color */ - 'border-color-b': [{ 'border-b': [theme.color] }], + 'border-color-b': [{ 'border-b': [color] }], /** * Border Color Left * @see https://tailwindcss.com/docs/border-color */ - 'border-color-l': [{ 'border-l': [theme.color] }], + 'border-color-l': [{ 'border-l': [color] }], /** * Divide Color * @see https://tailwindcss.com/docs/divide-color */ - 'divide-color': [{ divide: [theme.color] }], + 'divide-color': [{ divide: [color] }], /** * Outline Style * @see https://tailwindcss.com/docs/outline-style */ - 'outline-style': [{ outline: [...scale.lineStyle(), 'none', 'hidden'] }], + 'outline-style': [{ outline: [...getLineStyleScale(), 'none', 'hidden'] }], /** * Outline Offset * @see https://tailwindcss.com/docs/outline-offset @@ -1339,7 +1304,7 @@ export const getDefaultConfig = () => { * Outline Color * @see https://tailwindcss.com/docs/outline-color */ - 'outline-color': [{ outline: [theme.color] }], + 'outline-color': [{ outline: [color] }], // --------------- // --- Effects --- @@ -1354,7 +1319,7 @@ export const getDefaultConfig = () => { shadow: [ // Deprecated since Tailwind CSS v4.0.0 '', - theme.shadow, + shadow, ], }, ], @@ -1362,31 +1327,24 @@ export const getDefaultConfig = () => { * Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color */ - 'shadow-color': [{ shadow: [theme.color] }], + 'shadow-color': [{ shadow: [color] }], /** * Inset Box Shadow * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow */ 'inset-shadow': [ - { - 'inset-shadow': [ - 'none', - isArbitraryVariable, - isArbitraryValue, - theme.insetShadow, - ], - }, + { 'inset-shadow': ['none', isArbitraryVariable, isArbitraryValue, insetShadow] }, ], /** * Inset Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color */ - 'inset-shadow-color': [{ 'inset-shadow': [theme.color] }], + 'inset-shadow-color': [{ 'inset-shadow': [color] }], /** * Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring */ - 'ring-w': [{ ring: scale.borderWidth() }], + 'ring-w': [{ ring: getBorderWidthScale() }], /** * Ring Width Inset * @see https://v3.tailwindcss.com/docs/ring-width#inset-rings @@ -1398,7 +1356,7 @@ export const getDefaultConfig = () => { * Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color */ - 'ring-color': [{ ring: [theme.color] }], + 'ring-color': [{ ring: [color] }], /** * Ring Offset Width * @see https://v3.tailwindcss.com/docs/ring-offset-width @@ -1412,17 +1370,17 @@ export const getDefaultConfig = () => { * @deprecated since Tailwind CSS v4.0.0 * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ - 'ring-offset-color': [{ 'ring-offset': [theme.color] }], + 'ring-offset-color': [{ 'ring-offset': [color] }], /** * Inset Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring */ - 'inset-ring-w': [{ 'inset-ring': scale.borderWidth() }], + 'inset-ring-w': [{ 'inset-ring': getBorderWidthScale() }], /** * Inset Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color */ - 'inset-ring-color': [{ 'inset-ring': [theme.color] }], + 'inset-ring-color': [{ 'inset-ring': [color] }], /** * Opacity * @see https://tailwindcss.com/docs/opacity @@ -1432,12 +1390,12 @@ export const getDefaultConfig = () => { * Mix Blend Mode * @see https://tailwindcss.com/docs/mix-blend-mode */ - 'mix-blend': [{ 'mix-blend': [...scale.blendMode(), 'plus-darker', 'plus-lighter'] }], + 'mix-blend': [{ 'mix-blend': [...getBlendModeScale(), 'plus-darker', 'plus-lighter'] }], /** * Background Blend Mode * @see https://tailwindcss.com/docs/background-blend-mode */ - 'bg-blend': [{ 'bg-blend': scale.blendMode() }], + 'bg-blend': [{ 'bg-blend': getBlendModeScale() }], // --------------- // --- Filters --- @@ -1462,7 +1420,7 @@ export const getDefaultConfig = () => { * Blur * @see https://tailwindcss.com/docs/blur */ - blur: [{ blur: [theme.blur] }], + blur: [{ blur: [blur] }], /** * Brightness * @see https://tailwindcss.com/docs/brightness @@ -1477,7 +1435,7 @@ export const getDefaultConfig = () => { * Drop Shadow * @see https://tailwindcss.com/docs/drop-shadow */ - 'drop-shadow': [{ 'drop-shadow': [theme.dropShadow] }], + 'drop-shadow': [{ 'drop-shadow': [dropShadow] }], /** * Grayscale * @see https://tailwindcss.com/docs/grayscale @@ -1522,7 +1480,7 @@ export const getDefaultConfig = () => { * Backdrop Blur * @see https://tailwindcss.com/docs/backdrop-blur */ - 'backdrop-blur': [{ 'backdrop-blur': [theme.blur] }], + 'backdrop-blur': [{ 'backdrop-blur': [blur] }], /** * Backdrop Brightness * @see https://tailwindcss.com/docs/backdrop-brightness @@ -1593,17 +1551,17 @@ export const getDefaultConfig = () => { * Border Spacing * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing': [{ 'border-spacing': scale.unambiguousSpacing() }], + 'border-spacing': [{ 'border-spacing': getUnambiguousSpacingScale() }], /** * Border Spacing X * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing-x': [{ 'border-spacing-x': scale.unambiguousSpacing() }], + 'border-spacing-x': [{ 'border-spacing-x': getUnambiguousSpacingScale() }], /** * Border Spacing Y * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing-y': [{ 'border-spacing-y': scale.unambiguousSpacing() }], + 'border-spacing-y': [{ 'border-spacing-y': getUnambiguousSpacingScale() }], /** * Table Layout * @see https://tailwindcss.com/docs/table-layout @@ -1652,9 +1610,7 @@ export const getDefaultConfig = () => { * Transition Timing Function * @see https://tailwindcss.com/docs/transition-timing-function */ - ease: [ - { ease: ['linear', 'initial', isArbitraryVariable, isArbitraryValue, theme.ease] }, - ], + ease: [{ ease: ['linear', 'initial', isArbitraryVariable, isArbitraryValue, ease] }], /** * Transition Delay * @see https://tailwindcss.com/docs/transition-delay @@ -1664,7 +1620,7 @@ export const getDefaultConfig = () => { * Animation * @see https://tailwindcss.com/docs/animation */ - animate: [{ animate: ['none', isArbitraryVariable, isArbitraryValue, theme.animate] }], + animate: [{ animate: ['none', isArbitraryVariable, isArbitraryValue, animate] }], // ------------------ // --- Transforms --- @@ -1679,54 +1635,52 @@ export const getDefaultConfig = () => { * Perspective * @see https://tailwindcss.com/docs/perspective */ - perspective: [ - { perspective: [theme.perspective, isArbitraryVariable, isArbitraryValue] }, - ], + perspective: [{ perspective: [perspective, isArbitraryVariable, isArbitraryValue] }], /** * Perspective Origin * @see https://tailwindcss.com/docs/perspective-origin */ - 'perspective-origin': [{ 'perspective-origin': scale.origin() }], + 'perspective-origin': [{ 'perspective-origin': getOriginScale() }], /** * Rotate * @see https://tailwindcss.com/docs/rotate */ - rotate: [{ rotate: scale.rotate() }], + rotate: [{ rotate: getRotateScale() }], /** * Rotate X * @see https://tailwindcss.com/docs/rotate */ - 'rotate-x': [{ 'rotate-x': scale.rotate() }], + 'rotate-x': [{ 'rotate-x': getRotateScale() }], /** * Rotate Y * @see https://tailwindcss.com/docs/rotate */ - 'rotate-y': [{ 'rotate-y': scale.rotate() }], + 'rotate-y': [{ 'rotate-y': getRotateScale() }], /** * Rotate Z * @see https://tailwindcss.com/docs/rotate */ - 'rotate-z': [{ 'rotate-z': scale.rotate() }], + 'rotate-z': [{ 'rotate-z': getRotateScale() }], /** * Scale * @see https://tailwindcss.com/docs/scale */ - scale: [{ scale: scale.scale() }], + scale: [{ scale: getScaleScale() }], /** * Scale X * @see https://tailwindcss.com/docs/scale */ - 'scale-x': [{ 'scale-x': scale.scale() }], + 'scale-x': [{ 'scale-x': getScaleScale() }], /** * Scale Y * @see https://tailwindcss.com/docs/scale */ - 'scale-y': [{ 'scale-y': scale.scale() }], + 'scale-y': [{ 'scale-y': getScaleScale() }], /** * Scale Z * @see https://tailwindcss.com/docs/scale */ - 'scale-z': [{ 'scale-z': scale.scale() }], + 'scale-z': [{ 'scale-z': getScaleScale() }], /** * Scale 3D * @see https://tailwindcss.com/docs/scale @@ -1736,17 +1690,17 @@ export const getDefaultConfig = () => { * Skew * @see https://tailwindcss.com/docs/skew */ - skew: [{ skew: scale.skew() }], + skew: [{ skew: getSkewScale() }], /** * Skew X * @see https://tailwindcss.com/docs/skew */ - 'skew-x': [{ 'skew-x': scale.skew() }], + 'skew-x': [{ 'skew-x': getSkewScale() }], /** * Skew Y * @see https://tailwindcss.com/docs/skew */ - 'skew-y': [{ 'skew-y': scale.skew() }], + 'skew-y': [{ 'skew-y': getSkewScale() }], /** * Transform * @see https://tailwindcss.com/docs/transform @@ -1758,7 +1712,7 @@ export const getDefaultConfig = () => { * Transform Origin * @see https://tailwindcss.com/docs/transform-origin */ - 'transform-origin': [{ origin: scale.origin() }], + 'transform-origin': [{ origin: getOriginScale() }], /** * Transform Style * @see https://tailwindcss.com/docs/transform-style @@ -1768,22 +1722,22 @@ export const getDefaultConfig = () => { * Translate * @see https://tailwindcss.com/docs/translate */ - translate: [{ translate: scale.translate() }], + translate: [{ translate: getTranslateScale() }], /** * Translate X * @see https://tailwindcss.com/docs/translate */ - 'translate-x': [{ 'translate-x': scale.translate() }], + 'translate-x': [{ 'translate-x': getTranslateScale() }], /** * Translate Y * @see https://tailwindcss.com/docs/translate */ - 'translate-y': [{ 'translate-y': scale.translate() }], + 'translate-y': [{ 'translate-y': getTranslateScale() }], /** * Translate Z * @see https://tailwindcss.com/docs/translate */ - 'translate-z': [{ 'translate-z': scale.translate() }], + 'translate-z': [{ 'translate-z': getTranslateScale() }], /** * Translate None * @see https://tailwindcss.com/docs/translate @@ -1798,7 +1752,7 @@ export const getDefaultConfig = () => { * Accent Color * @see https://tailwindcss.com/docs/accent-color */ - accent: [{ accent: [theme.color] }], + accent: [{ accent: [color] }], /** * Appearance * @see https://tailwindcss.com/docs/appearance @@ -1808,7 +1762,7 @@ export const getDefaultConfig = () => { * Caret Color * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities */ - 'caret-color': [{ caret: [theme.color] }], + 'caret-color': [{ caret: [color] }], /** * Color Scheme * @see https://tailwindcss.com/docs/color-scheme @@ -1888,92 +1842,92 @@ export const getDefaultConfig = () => { * Scroll Margin * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-m': [{ 'scroll-m': scale.unambiguousSpacing() }], + 'scroll-m': [{ 'scroll-m': getUnambiguousSpacingScale() }], /** * Scroll Margin X * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mx': [{ 'scroll-mx': scale.unambiguousSpacing() }], + 'scroll-mx': [{ 'scroll-mx': getUnambiguousSpacingScale() }], /** * Scroll Margin Y * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-my': [{ 'scroll-my': scale.unambiguousSpacing() }], + 'scroll-my': [{ 'scroll-my': getUnambiguousSpacingScale() }], /** * Scroll Margin Start * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-ms': [{ 'scroll-ms': scale.unambiguousSpacing() }], + 'scroll-ms': [{ 'scroll-ms': getUnambiguousSpacingScale() }], /** * Scroll Margin End * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-me': [{ 'scroll-me': scale.unambiguousSpacing() }], + 'scroll-me': [{ 'scroll-me': getUnambiguousSpacingScale() }], /** * Scroll Margin Top * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mt': [{ 'scroll-mt': scale.unambiguousSpacing() }], + 'scroll-mt': [{ 'scroll-mt': getUnambiguousSpacingScale() }], /** * Scroll Margin Right * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mr': [{ 'scroll-mr': scale.unambiguousSpacing() }], + 'scroll-mr': [{ 'scroll-mr': getUnambiguousSpacingScale() }], /** * Scroll Margin Bottom * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mb': [{ 'scroll-mb': scale.unambiguousSpacing() }], + 'scroll-mb': [{ 'scroll-mb': getUnambiguousSpacingScale() }], /** * Scroll Margin Left * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-ml': [{ 'scroll-ml': scale.unambiguousSpacing() }], + 'scroll-ml': [{ 'scroll-ml': getUnambiguousSpacingScale() }], /** * Scroll Padding * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-p': [{ 'scroll-p': scale.unambiguousSpacing() }], + 'scroll-p': [{ 'scroll-p': getUnambiguousSpacingScale() }], /** * Scroll Padding X * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-px': [{ 'scroll-px': scale.unambiguousSpacing() }], + 'scroll-px': [{ 'scroll-px': getUnambiguousSpacingScale() }], /** * Scroll Padding Y * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-py': [{ 'scroll-py': scale.unambiguousSpacing() }], + 'scroll-py': [{ 'scroll-py': getUnambiguousSpacingScale() }], /** * Scroll Padding Start * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-ps': [{ 'scroll-ps': scale.unambiguousSpacing() }], + 'scroll-ps': [{ 'scroll-ps': getUnambiguousSpacingScale() }], /** * Scroll Padding End * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pe': [{ 'scroll-pe': scale.unambiguousSpacing() }], + 'scroll-pe': [{ 'scroll-pe': getUnambiguousSpacingScale() }], /** * Scroll Padding Top * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pt': [{ 'scroll-pt': scale.unambiguousSpacing() }], + 'scroll-pt': [{ 'scroll-pt': getUnambiguousSpacingScale() }], /** * Scroll Padding Right * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pr': [{ 'scroll-pr': scale.unambiguousSpacing() }], + 'scroll-pr': [{ 'scroll-pr': getUnambiguousSpacingScale() }], /** * Scroll Padding Bottom * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pb': [{ 'scroll-pb': scale.unambiguousSpacing() }], + 'scroll-pb': [{ 'scroll-pb': getUnambiguousSpacingScale() }], /** * Scroll Padding Left * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pl': [{ 'scroll-pl': scale.unambiguousSpacing() }], + 'scroll-pl': [{ 'scroll-pl': getUnambiguousSpacingScale() }], /** * Scroll Snap Align * @see https://tailwindcss.com/docs/scroll-snap-align @@ -2044,7 +1998,7 @@ export const getDefaultConfig = () => { * Fill * @see https://tailwindcss.com/docs/fill */ - fill: [{ fill: ['none', theme.color] }], + fill: [{ fill: ['none', color] }], /** * Stroke Width * @see https://tailwindcss.com/docs/stroke-width @@ -2063,7 +2017,7 @@ export const getDefaultConfig = () => { * Stroke * @see https://tailwindcss.com/docs/stroke */ - stroke: [{ stroke: ['none', theme.color] }], + stroke: [{ stroke: ['none', color] }], // --------------------- // --- Accessibility --- From e7e5a081cbfa55902416cadd292692992e07651d Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 13:41:32 +0100 Subject: [PATCH 20/48] use better naming for variables inside getDefaultConfig --- src/lib/default-config.ts | 509 ++++++++++++++++++++------------------ 1 file changed, 271 insertions(+), 238 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index da8a1977..6cdc0ebc 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -25,32 +25,42 @@ import { } from './validators' export const getDefaultConfig = () => { - // Theme getters for theme variable namespaces: https://tailwindcss.com/docs/theme#theme-variable-namespaces + /** + * Theme getters for theme variable namespaces + * @see https://tailwindcss.com/docs/theme#theme-variable-namespaces + */ + /***/ - const color = fromTheme('color') - const font = fromTheme('font') - const text = fromTheme('text') - const fontWeight = fromTheme('font-weight') - const tracking = fromTheme('tracking') - const leading = fromTheme('leading') - const breakpoint = fromTheme('breakpoint') - const container = fromTheme('container') - const spacing = fromTheme('spacing') - const radius = fromTheme('radius') - const shadow = fromTheme('shadow') - const insetShadow = fromTheme('inset-shadow') - const dropShadow = fromTheme('drop-shadow') - const blur = fromTheme('blur') - const perspective = fromTheme('perspective') - const aspect = fromTheme('aspect') - const ease = fromTheme('ease') - const animate = fromTheme('animate') + const themeColor = fromTheme('color') + const themeFont = fromTheme('font') + const themeText = fromTheme('text') + const themeFontWeight = fromTheme('font-weight') + const themeTracking = fromTheme('tracking') + const themeLeading = fromTheme('leading') + const themeBreakpoint = fromTheme('breakpoint') + const themeContainer = fromTheme('container') + const themeSpacing = fromTheme('spacing') + const themeRadius = fromTheme('radius') + const themeShadow = fromTheme('shadow') + const themeInsetShadow = fromTheme('inset-shadow') + const themeDropShadow = fromTheme('drop-shadow') + const themeBlur = fromTheme('blur') + const themePerspective = fromTheme('perspective') + const themeAspect = fromTheme('aspect') + const themeEase = fromTheme('ease') + const themeAnimate = fromTheme('animate') - // Helpers to avoid repeating the same values + /** + * Helpers to avoid repeating the same scales + * + * We use functions that create a new array every time they're called instead of static arrays. + * This ensures that users who modify any scale by mutating the array (e.g. with `array.push(element)`) don't accidentally mutate arrays in other parts of the config. + */ + /***/ - const getBreakScale = () => + const scaleBreak = () => ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'] as const - const getPositionScale = () => + const scalePosition = () => [ 'bottom', 'center', @@ -62,31 +72,39 @@ export const getDefaultConfig = () => { 'right-top', 'top', ] as const - const getOverflowScale = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const - const getOverscrollScale = () => ['auto', 'contain', 'none'] as const - const getInsetScale = () => - [isFraction, 'px', 'full', 'auto', isArbitraryVariable, isArbitraryValue, spacing] as const - const getGridTemplateColsRowsScale = () => + const scaleOverflow = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'] as const + const scaleOverscroll = () => ['auto', 'contain', 'none'] as const + const scaleInset = () => + [ + isFraction, + 'px', + 'full', + 'auto', + isArbitraryVariable, + isArbitraryValue, + themeSpacing, + ] as const + const scaleGridTemplateColsRows = () => [isInteger, 'none', 'subgrid', isArbitraryVariable, isArbitraryValue] as const - const getGridColRowStartAndEndScale = () => + const scaleGridColRowStartAndEnd = () => [ 'auto', { span: ['full', isInteger, isArbitraryVariable, isArbitraryValue] }, isArbitraryVariable, isArbitraryValue, ] as const - const getGridColRowStartOrEndScale = () => + const scaleGridColRowStartOrEnd = () => [isInteger, 'auto', isArbitraryVariable, isArbitraryValue] as const - const getGridAutoColsRowsScale = () => + const scaleGridAutoColsRows = () => ['auto', 'min', 'max', 'fr', isArbitraryVariable, isArbitraryValue] as const - const getGapScale = () => [isArbitraryVariable, isArbitraryValue, spacing] as const - const getAlignPrimaryAxisScale = () => + const scaleGap = () => [isArbitraryVariable, isArbitraryValue, themeSpacing] as const + const scaleAlignPrimaryAxis = () => ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch', 'baseline'] as const - const getAlignSecondaryAxisScale = () => ['start', 'end', 'center', 'stretch'] as const - const getUnambiguousSpacingScale = () => - [isArbitraryVariable, isArbitraryValue, spacing] as const - const getMarginScale = () => ['auto', ...getUnambiguousSpacingScale()] as const - const getSizingScale = () => + const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch'] as const + const scaleUnambiguousSpacing = () => + [isArbitraryVariable, isArbitraryValue, themeSpacing] as const + const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()] as const + const scaleSizing = () => [ isFraction, 'auto', @@ -103,13 +121,13 @@ export const getDefaultConfig = () => { 'fit', isArbitraryVariable, isArbitraryValue, - spacing, + themeSpacing, ] as const - const getGradientStopPositionScale = () => [isPercent, isArbitraryLength] as const - const getBorderWidthScale = () => + const scaleGradientStopPosition = () => [isPercent, isArbitraryLength] as const + const scaleBorderWidth = () => ['', isNumber, isArbitraryVariableLength, isArbitraryLength] as const - const getLineStyleScale = () => ['solid', 'dashed', 'dotted', 'double'] as const - const getBlendModeScale = () => + const scaleLineStyle = () => ['solid', 'dashed', 'dotted', 'double'] as const + const scaleBlendMode = () => [ 'normal', 'multiply', @@ -128,7 +146,7 @@ export const getDefaultConfig = () => { 'color', 'luminosity', ] as const - const getOriginScale = () => + const scaleOrigin = () => [ 'center', 'top', @@ -142,11 +160,11 @@ export const getDefaultConfig = () => { isArbitraryVariable, isArbitraryValue, ] as const - const getRotateScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const - const getScaleScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const - const getSkewScale = () => [isNumber, isArbitraryVariable, isArbitraryValue] as const - const getTranslateScale = () => - [isFraction, 'full', 'px', isArbitraryVariable, isArbitraryValue, spacing] as const + const scaleRotate = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const + const scaleScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue] as const + const scaleSkew = () => [isNumber, isArbitraryVariable, isArbitraryValue] as const + const scaleTranslate = () => + [isFraction, 'full', 'px', isArbitraryVariable, isArbitraryValue, themeSpacing] as const return { cacheSize: 500, @@ -220,7 +238,7 @@ export const getDefaultConfig = () => { isFraction, isArbitraryValue, isArbitraryVariable, - aspect, + themeAspect, ], }, ], @@ -234,17 +252,19 @@ export const getDefaultConfig = () => { * Columns * @see https://tailwindcss.com/docs/columns */ - columns: [{ columns: [isNumber, isArbitraryValue, isArbitraryVariable, container] }], + columns: [ + { columns: [isNumber, isArbitraryValue, isArbitraryVariable, themeContainer] }, + ], /** * Break After * @see https://tailwindcss.com/docs/break-after */ - 'break-after': [{ 'break-after': getBreakScale() }], + 'break-after': [{ 'break-after': scaleBreak() }], /** * Break Before * @see https://tailwindcss.com/docs/break-before */ - 'break-before': [{ 'break-before': getBreakScale() }], + 'break-before': [{ 'break-before': scaleBreak() }], /** * Break Inside * @see https://tailwindcss.com/docs/break-inside @@ -317,38 +337,38 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/object-position */ 'object-position': [ - { object: [...getPositionScale(), isArbitraryValue, isArbitraryVariable] }, + { object: [...scalePosition(), isArbitraryValue, isArbitraryVariable] }, ], /** * Overflow * @see https://tailwindcss.com/docs/overflow */ - overflow: [{ overflow: getOverflowScale() }], + overflow: [{ overflow: scaleOverflow() }], /** * Overflow X * @see https://tailwindcss.com/docs/overflow */ - 'overflow-x': [{ 'overflow-x': getOverflowScale() }], + 'overflow-x': [{ 'overflow-x': scaleOverflow() }], /** * Overflow Y * @see https://tailwindcss.com/docs/overflow */ - 'overflow-y': [{ 'overflow-y': getOverflowScale() }], + 'overflow-y': [{ 'overflow-y': scaleOverflow() }], /** * Overscroll Behavior * @see https://tailwindcss.com/docs/overscroll-behavior */ - overscroll: [{ overscroll: getOverscrollScale() }], + overscroll: [{ overscroll: scaleOverscroll() }], /** * Overscroll Behavior X * @see https://tailwindcss.com/docs/overscroll-behavior */ - 'overscroll-x': [{ 'overscroll-x': getOverscrollScale() }], + 'overscroll-x': [{ 'overscroll-x': scaleOverscroll() }], /** * Overscroll Behavior Y * @see https://tailwindcss.com/docs/overscroll-behavior */ - 'overscroll-y': [{ 'overscroll-y': getOverscrollScale() }], + 'overscroll-y': [{ 'overscroll-y': scaleOverscroll() }], /** * Position * @see https://tailwindcss.com/docs/position @@ -358,47 +378,47 @@ export const getDefaultConfig = () => { * Top / Right / Bottom / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - inset: [{ inset: getInsetScale() }], + inset: [{ inset: scaleInset() }], /** * Right / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - 'inset-x': [{ 'inset-x': getInsetScale() }], + 'inset-x': [{ 'inset-x': scaleInset() }], /** * Top / Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ - 'inset-y': [{ 'inset-y': getInsetScale() }], + 'inset-y': [{ 'inset-y': scaleInset() }], /** * Start * @see https://tailwindcss.com/docs/top-right-bottom-left */ - start: [{ start: getInsetScale() }], + start: [{ start: scaleInset() }], /** * End * @see https://tailwindcss.com/docs/top-right-bottom-left */ - end: [{ end: getInsetScale() }], + end: [{ end: scaleInset() }], /** * Top * @see https://tailwindcss.com/docs/top-right-bottom-left */ - top: [{ top: getInsetScale() }], + top: [{ top: scaleInset() }], /** * Right * @see https://tailwindcss.com/docs/top-right-bottom-left */ - right: [{ right: getInsetScale() }], + right: [{ right: scaleInset() }], /** * Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ - bottom: [{ bottom: getInsetScale() }], + bottom: [{ bottom: scaleInset() }], /** * Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ - left: [{ left: getInsetScale() }], + left: [{ left: scaleInset() }], /** * Visibility * @see https://tailwindcss.com/docs/visibility @@ -426,8 +446,8 @@ export const getDefaultConfig = () => { 'auto', isArbitraryVariable, isArbitraryValue, - container, - spacing, + themeContainer, + themeSpacing, ], }, ], @@ -476,42 +496,42 @@ export const getDefaultConfig = () => { * Grid Template Columns * @see https://tailwindcss.com/docs/grid-template-columns */ - 'grid-cols': [{ 'grid-cols': getGridTemplateColsRowsScale() }], + 'grid-cols': [{ 'grid-cols': scaleGridTemplateColsRows() }], /** * Grid Column Start / End * @see https://tailwindcss.com/docs/grid-column */ - 'col-start-end': [{ col: getGridColRowStartAndEndScale() }], + 'col-start-end': [{ col: scaleGridColRowStartAndEnd() }], /** * Grid Column Start * @see https://tailwindcss.com/docs/grid-column */ - 'col-start': [{ 'col-start': getGridColRowStartOrEndScale() }], + 'col-start': [{ 'col-start': scaleGridColRowStartOrEnd() }], /** * Grid Column End * @see https://tailwindcss.com/docs/grid-column */ - 'col-end': [{ 'col-end': getGridColRowStartOrEndScale() }], + 'col-end': [{ 'col-end': scaleGridColRowStartOrEnd() }], /** * Grid Template Rows * @see https://tailwindcss.com/docs/grid-template-rows */ - 'grid-rows': [{ 'grid-rows': getGridTemplateColsRowsScale() }], + 'grid-rows': [{ 'grid-rows': scaleGridTemplateColsRows() }], /** * Grid Row Start / End * @see https://tailwindcss.com/docs/grid-row */ - 'row-start-end': [{ row: getGridColRowStartAndEndScale() }], + 'row-start-end': [{ row: scaleGridColRowStartAndEnd() }], /** * Grid Row Start * @see https://tailwindcss.com/docs/grid-row */ - 'row-start': [{ 'row-start': getGridColRowStartOrEndScale() }], + 'row-start': [{ 'row-start': scaleGridColRowStartOrEnd() }], /** * Grid Row End * @see https://tailwindcss.com/docs/grid-row */ - 'row-end': [{ 'row-end': getGridColRowStartOrEndScale() }], + 'row-end': [{ 'row-end': scaleGridColRowStartOrEnd() }], /** * Grid Auto Flow * @see https://tailwindcss.com/docs/grid-auto-flow @@ -521,168 +541,168 @@ export const getDefaultConfig = () => { * Grid Auto Columns * @see https://tailwindcss.com/docs/grid-auto-columns */ - 'auto-cols': [{ 'auto-cols': getGridAutoColsRowsScale() }], + 'auto-cols': [{ 'auto-cols': scaleGridAutoColsRows() }], /** * Grid Auto Rows * @see https://tailwindcss.com/docs/grid-auto-rows */ - 'auto-rows': [{ 'auto-rows': getGridAutoColsRowsScale() }], + 'auto-rows': [{ 'auto-rows': scaleGridAutoColsRows() }], /** * Gap * @see https://tailwindcss.com/docs/gap */ - gap: [{ gap: getGapScale() }], + gap: [{ gap: scaleGap() }], /** * Gap X * @see https://tailwindcss.com/docs/gap */ - 'gap-x': [{ 'gap-x': getGapScale() }], + 'gap-x': [{ 'gap-x': scaleGap() }], /** * Gap Y * @see https://tailwindcss.com/docs/gap */ - 'gap-y': [{ 'gap-y': getGapScale() }], + 'gap-y': [{ 'gap-y': scaleGap() }], /** * Justify Content * @see https://tailwindcss.com/docs/justify-content */ - 'justify-content': [{ justify: [...getAlignPrimaryAxisScale(), 'normal'] }], + 'justify-content': [{ justify: [...scaleAlignPrimaryAxis(), 'normal'] }], /** * Justify Items * @see https://tailwindcss.com/docs/justify-items */ - 'justify-items': [{ 'justify-items': [...getAlignSecondaryAxisScale(), 'normal'] }], + 'justify-items': [{ 'justify-items': [...scaleAlignSecondaryAxis(), 'normal'] }], /** * Justify Self * @see https://tailwindcss.com/docs/justify-self */ - 'justify-self': [{ 'justify-self': ['auto', ...getAlignSecondaryAxisScale()] }], + 'justify-self': [{ 'justify-self': ['auto', ...scaleAlignSecondaryAxis()] }], /** * Align Content * @see https://tailwindcss.com/docs/align-content */ - 'align-content': [{ content: ['normal', ...getAlignPrimaryAxisScale()] }], + 'align-content': [{ content: ['normal', ...scaleAlignPrimaryAxis()] }], /** * Align Items * @see https://tailwindcss.com/docs/align-items */ - 'align-items': [{ items: [...getAlignSecondaryAxisScale(), 'baseline'] }], + 'align-items': [{ items: [...scaleAlignSecondaryAxis(), 'baseline'] }], /** * Align Self * @see https://tailwindcss.com/docs/align-self */ - 'align-self': [{ self: ['auto', ...getAlignSecondaryAxisScale(), 'baseline'] }], + 'align-self': [{ self: ['auto', ...scaleAlignSecondaryAxis(), 'baseline'] }], /** * Place Content * @see https://tailwindcss.com/docs/place-content */ - 'place-content': [{ 'place-content': getAlignPrimaryAxisScale() }], + 'place-content': [{ 'place-content': scaleAlignPrimaryAxis() }], /** * Place Items * @see https://tailwindcss.com/docs/place-items */ - 'place-items': [{ 'place-items': [...getAlignSecondaryAxisScale(), 'baseline'] }], + 'place-items': [{ 'place-items': [...scaleAlignSecondaryAxis(), 'baseline'] }], /** * Place Self * @see https://tailwindcss.com/docs/place-self */ - 'place-self': [{ 'place-self': ['auto', ...getAlignSecondaryAxisScale()] }], + 'place-self': [{ 'place-self': ['auto', ...scaleAlignSecondaryAxis()] }], // Spacing /** * Padding * @see https://tailwindcss.com/docs/padding */ - p: [{ p: getUnambiguousSpacingScale() }], + p: [{ p: scaleUnambiguousSpacing() }], /** * Padding X * @see https://tailwindcss.com/docs/padding */ - px: [{ px: getUnambiguousSpacingScale() }], + px: [{ px: scaleUnambiguousSpacing() }], /** * Padding Y * @see https://tailwindcss.com/docs/padding */ - py: [{ py: getUnambiguousSpacingScale() }], + py: [{ py: scaleUnambiguousSpacing() }], /** * Padding Start * @see https://tailwindcss.com/docs/padding */ - ps: [{ ps: getUnambiguousSpacingScale() }], + ps: [{ ps: scaleUnambiguousSpacing() }], /** * Padding End * @see https://tailwindcss.com/docs/padding */ - pe: [{ pe: getUnambiguousSpacingScale() }], + pe: [{ pe: scaleUnambiguousSpacing() }], /** * Padding Top * @see https://tailwindcss.com/docs/padding */ - pt: [{ pt: getUnambiguousSpacingScale() }], + pt: [{ pt: scaleUnambiguousSpacing() }], /** * Padding Right * @see https://tailwindcss.com/docs/padding */ - pr: [{ pr: getUnambiguousSpacingScale() }], + pr: [{ pr: scaleUnambiguousSpacing() }], /** * Padding Bottom * @see https://tailwindcss.com/docs/padding */ - pb: [{ pb: getUnambiguousSpacingScale() }], + pb: [{ pb: scaleUnambiguousSpacing() }], /** * Padding Left * @see https://tailwindcss.com/docs/padding */ - pl: [{ pl: getUnambiguousSpacingScale() }], + pl: [{ pl: scaleUnambiguousSpacing() }], /** * Margin * @see https://tailwindcss.com/docs/margin */ - m: [{ m: getMarginScale() }], + m: [{ m: scaleMargin() }], /** * Margin X * @see https://tailwindcss.com/docs/margin */ - mx: [{ mx: getMarginScale() }], + mx: [{ mx: scaleMargin() }], /** * Margin Y * @see https://tailwindcss.com/docs/margin */ - my: [{ my: getMarginScale() }], + my: [{ my: scaleMargin() }], /** * Margin Start * @see https://tailwindcss.com/docs/margin */ - ms: [{ ms: getMarginScale() }], + ms: [{ ms: scaleMargin() }], /** * Margin End * @see https://tailwindcss.com/docs/margin */ - me: [{ me: getMarginScale() }], + me: [{ me: scaleMargin() }], /** * Margin Top * @see https://tailwindcss.com/docs/margin */ - mt: [{ mt: getMarginScale() }], + mt: [{ mt: scaleMargin() }], /** * Margin Right * @see https://tailwindcss.com/docs/margin */ - mr: [{ mr: getMarginScale() }], + mr: [{ mr: scaleMargin() }], /** * Margin Bottom * @see https://tailwindcss.com/docs/margin */ - mb: [{ mb: getMarginScale() }], + mb: [{ mb: scaleMargin() }], /** * Margin Left * @see https://tailwindcss.com/docs/margin */ - ml: [{ ml: getMarginScale() }], + ml: [{ ml: scaleMargin() }], /** * Space Between X * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ - 'space-x': [{ 'space-x': getUnambiguousSpacingScale() }], + 'space-x': [{ 'space-x': scaleUnambiguousSpacing() }], /** * Space Between X Reverse * @see https://tailwindcss.com/docs/margin#adding-space-between-children @@ -692,7 +712,7 @@ export const getDefaultConfig = () => { * Space Between Y * @see https://tailwindcss.com/docs/margin#adding-space-between-children */ - 'space-y': [{ 'space-y': getUnambiguousSpacingScale() }], + 'space-y': [{ 'space-y': scaleUnambiguousSpacing() }], /** * Space Between Y Reverse * @see https://tailwindcss.com/docs/margin#adding-space-between-children @@ -711,13 +731,13 @@ export const getDefaultConfig = () => { * Size * @see https://tailwindcss.com/docs/width#setting-both-width-and-height */ - size: [{ size: getSizingScale() }], - w: [{ w: [container, 'screen', ...getSizingScale()] }], + size: [{ size: scaleSizing() }], + w: [{ w: [themeContainer, 'screen', ...scaleSizing()] }], /** * Min-Width * @see https://tailwindcss.com/docs/min-width */ - 'min-w': [{ 'min-w': [container, 'screen', 'none', ...getSizingScale()] }], + 'min-w': [{ 'min-w': [themeContainer, 'screen', 'none', ...scaleSizing()] }], /** * Max-Width * @see https://tailwindcss.com/docs/max-width @@ -725,12 +745,12 @@ export const getDefaultConfig = () => { 'max-w': [ { 'max-w': [ - container, + themeContainer, 'screen', 'none', 'prose', - { screen: [breakpoint] }, - ...getSizingScale(), + { screen: [themeBreakpoint] }, + ...scaleSizing(), ], }, ], @@ -738,17 +758,17 @@ export const getDefaultConfig = () => { * Height * @see https://tailwindcss.com/docs/height */ - h: [{ h: ['screen', ...getSizingScale()] }], + h: [{ h: ['screen', ...scaleSizing()] }], /** * Min-Height * @see https://tailwindcss.com/docs/min-height */ - 'min-h': [{ 'min-h': ['screen', 'none', ...getSizingScale()] }], + 'min-h': [{ 'min-h': ['screen', 'none', ...scaleSizing()] }], /** * Max-Height * @see https://tailwindcss.com/docs/max-height */ - 'max-h': [{ 'max-h': ['screen', ...getSizingScale()] }], + 'max-h': [{ 'max-h': ['screen', ...scaleSizing()] }], // ------------------ // --- Typography --- @@ -758,7 +778,7 @@ export const getDefaultConfig = () => { * Font Size * @see https://tailwindcss.com/docs/font-size */ - 'font-size': [{ text: [text] }], + 'font-size': [{ text: [themeText] }], /** * Font Smoothing * @see https://tailwindcss.com/docs/font-smoothing @@ -773,7 +793,7 @@ export const getDefaultConfig = () => { * Font Weight * @see https://tailwindcss.com/docs/font-weight */ - 'font-weight': [{ font: [fontWeight, isArbitraryVariable, isArbitraryNumber] }], + 'font-weight': [{ font: [themeFontWeight, isArbitraryVariable, isArbitraryNumber] }], /** * Font Stretch * @see https://tailwindcss.com/docs/font-stretch @@ -799,7 +819,7 @@ export const getDefaultConfig = () => { * Font Family * @see https://tailwindcss.com/docs/font-family */ - 'font-family': [{ font: [font] }], + 'font-family': [{ font: [themeFont] }], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font-variant-numeric @@ -834,7 +854,7 @@ export const getDefaultConfig = () => { * Letter Spacing * @see https://tailwindcss.com/docs/letter-spacing */ - tracking: [{ tracking: [tracking, isArbitraryVariable, isArbitraryValue] }], + tracking: [{ tracking: [themeTracking, isArbitraryVariable, isArbitraryValue] }], /** * Line Clamp * @see https://tailwindcss.com/docs/line-clamp @@ -846,7 +866,9 @@ export const getDefaultConfig = () => { * Line Height * @see https://tailwindcss.com/docs/line-height */ - leading: [{ leading: [isArbitraryVariable, isArbitraryValue, leading, spacing] }], + leading: [ + { leading: [isArbitraryVariable, isArbitraryValue, themeLeading, themeSpacing] }, + ], /** * List Style Image * @see https://tailwindcss.com/docs/list-style-image @@ -874,12 +896,12 @@ export const getDefaultConfig = () => { * @deprecated since Tailwind CSS v3.0.0 * @see https://v3.tailwindcss.com/docs/placeholder-color */ - 'placeholder-color': [{ placeholder: [color] }], + 'placeholder-color': [{ placeholder: [themeColor] }], /** * Text Color * @see https://tailwindcss.com/docs/text-color */ - 'text-color': [{ text: [color] }], + 'text-color': [{ text: [themeColor] }], /** * Text Decoration * @see https://tailwindcss.com/docs/text-decoration @@ -889,7 +911,7 @@ export const getDefaultConfig = () => { * Text Decoration Style * @see https://tailwindcss.com/docs/text-decoration-style */ - 'text-decoration-style': [{ decoration: [...getLineStyleScale(), 'wavy'] }], + 'text-decoration-style': [{ decoration: [...scaleLineStyle(), 'wavy'] }], /** * Text Decoration Thickness * @see https://tailwindcss.com/docs/text-decoration-thickness @@ -909,7 +931,7 @@ export const getDefaultConfig = () => { * Text Decoration Color * @see https://tailwindcss.com/docs/text-decoration-color */ - 'text-decoration-color': [{ decoration: [color] }], + 'text-decoration-color': [{ decoration: [themeColor] }], /** * Text Underline Offset * @see https://tailwindcss.com/docs/text-underline-offset @@ -936,7 +958,7 @@ export const getDefaultConfig = () => { * Text Indent * @see https://tailwindcss.com/docs/text-indent */ - indent: [{ indent: ['px', ...getUnambiguousSpacingScale()] }], + indent: [{ indent: ['px', ...scaleUnambiguousSpacing()] }], /** * Vertical Alignment * @see https://tailwindcss.com/docs/vertical-align @@ -1004,7 +1026,7 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/background-position */ 'bg-position': [ - { bg: [...getPositionScale(), isArbitraryVariablePosition, isArbitraryPosition] }, + { bg: [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition] }, ], /** * Background Repeat @@ -1045,37 +1067,37 @@ export const getDefaultConfig = () => { * Background Color * @see https://tailwindcss.com/docs/background-color */ - 'bg-color': [{ bg: [color] }], + 'bg-color': [{ bg: [themeColor] }], /** * Gradient Color Stops From Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from-pos': [{ from: getGradientStopPositionScale() }], + 'gradient-from-pos': [{ from: scaleGradientStopPosition() }], /** * Gradient Color Stops Via Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via-pos': [{ via: getGradientStopPositionScale() }], + 'gradient-via-pos': [{ via: scaleGradientStopPosition() }], /** * Gradient Color Stops To Position * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to-pos': [{ to: getGradientStopPositionScale() }], + 'gradient-to-pos': [{ to: scaleGradientStopPosition() }], /** * Gradient Color Stops From * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from': [{ from: [color] }], + 'gradient-from': [{ from: [themeColor] }], /** * Gradient Color Stops Via * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via': [{ via: [color] }], + 'gradient-via': [{ via: [themeColor] }], /** * Gradient Color Stops To * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to': [{ to: [color] }], + 'gradient-to': [{ to: [themeColor] }], // --------------- // --- Borders --- @@ -1085,127 +1107,127 @@ export const getDefaultConfig = () => { * Border Radius * @see https://tailwindcss.com/docs/border-radius */ - rounded: [{ rounded: [radius] }], + rounded: [{ rounded: [themeRadius] }], /** * Border Radius Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-s': [{ 'rounded-s': [radius] }], + 'rounded-s': [{ 'rounded-s': [themeRadius] }], /** * Border Radius End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-e': [{ 'rounded-e': [radius] }], + 'rounded-e': [{ 'rounded-e': [themeRadius] }], /** * Border Radius Top * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-t': [{ 'rounded-t': [radius] }], + 'rounded-t': [{ 'rounded-t': [themeRadius] }], /** * Border Radius Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-r': [{ 'rounded-r': [radius] }], + 'rounded-r': [{ 'rounded-r': [themeRadius] }], /** * Border Radius Bottom * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-b': [{ 'rounded-b': [radius] }], + 'rounded-b': [{ 'rounded-b': [themeRadius] }], /** * Border Radius Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-l': [{ 'rounded-l': [radius] }], + 'rounded-l': [{ 'rounded-l': [themeRadius] }], /** * Border Radius Start Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ss': [{ 'rounded-ss': [radius] }], + 'rounded-ss': [{ 'rounded-ss': [themeRadius] }], /** * Border Radius Start End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-se': [{ 'rounded-se': [radius] }], + 'rounded-se': [{ 'rounded-se': [themeRadius] }], /** * Border Radius End End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ee': [{ 'rounded-ee': [radius] }], + 'rounded-ee': [{ 'rounded-ee': [themeRadius] }], /** * Border Radius End Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-es': [{ 'rounded-es': [radius] }], + 'rounded-es': [{ 'rounded-es': [themeRadius] }], /** * Border Radius Top Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tl': [{ 'rounded-tl': [radius] }], + 'rounded-tl': [{ 'rounded-tl': [themeRadius] }], /** * Border Radius Top Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tr': [{ 'rounded-tr': [radius] }], + 'rounded-tr': [{ 'rounded-tr': [themeRadius] }], /** * Border Radius Bottom Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-br': [{ 'rounded-br': [radius] }], + 'rounded-br': [{ 'rounded-br': [themeRadius] }], /** * Border Radius Bottom Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-bl': [{ 'rounded-bl': [radius] }], + 'rounded-bl': [{ 'rounded-bl': [themeRadius] }], /** * Border Width * @see https://tailwindcss.com/docs/border-width */ - 'border-w': [{ border: getBorderWidthScale() }], + 'border-w': [{ border: scaleBorderWidth() }], /** * Border Width X * @see https://tailwindcss.com/docs/border-width */ - 'border-w-x': [{ 'border-x': getBorderWidthScale() }], + 'border-w-x': [{ 'border-x': scaleBorderWidth() }], /** * Border Width Y * @see https://tailwindcss.com/docs/border-width */ - 'border-w-y': [{ 'border-y': getBorderWidthScale() }], + 'border-w-y': [{ 'border-y': scaleBorderWidth() }], /** * Border Width Start * @see https://tailwindcss.com/docs/border-width */ - 'border-w-s': [{ 'border-s': getBorderWidthScale() }], + 'border-w-s': [{ 'border-s': scaleBorderWidth() }], /** * Border Width End * @see https://tailwindcss.com/docs/border-width */ - 'border-w-e': [{ 'border-e': getBorderWidthScale() }], + 'border-w-e': [{ 'border-e': scaleBorderWidth() }], /** * Border Width Top * @see https://tailwindcss.com/docs/border-width */ - 'border-w-t': [{ 'border-t': getBorderWidthScale() }], + 'border-w-t': [{ 'border-t': scaleBorderWidth() }], /** * Border Width Right * @see https://tailwindcss.com/docs/border-width */ - 'border-w-r': [{ 'border-r': getBorderWidthScale() }], + 'border-w-r': [{ 'border-r': scaleBorderWidth() }], /** * Border Width Bottom * @see https://tailwindcss.com/docs/border-width */ - 'border-w-b': [{ 'border-b': getBorderWidthScale() }], + 'border-w-b': [{ 'border-b': scaleBorderWidth() }], /** * Border Width Left * @see https://tailwindcss.com/docs/border-width */ - 'border-w-l': [{ 'border-l': getBorderWidthScale() }], + 'border-w-l': [{ 'border-l': scaleBorderWidth() }], /** * Divide Width X * @see https://tailwindcss.com/docs/border-width#between-children */ - 'divide-x': [{ 'divide-x': getBorderWidthScale() }], + 'divide-x': [{ 'divide-x': scaleBorderWidth() }], /** * Divide Width X Reverse * @see https://tailwindcss.com/docs/border-width#between-children @@ -1215,7 +1237,7 @@ export const getDefaultConfig = () => { * Divide Width Y * @see https://tailwindcss.com/docs/border-width#between-children */ - 'divide-y': [{ 'divide-y': getBorderWidthScale() }], + 'divide-y': [{ 'divide-y': scaleBorderWidth() }], /** * Divide Width Y Reverse * @see https://tailwindcss.com/docs/border-width#between-children @@ -1225,67 +1247,67 @@ export const getDefaultConfig = () => { * Border Style * @see https://tailwindcss.com/docs/border-style */ - 'border-style': [{ border: [...getLineStyleScale(), 'hidden', 'none'] }], + 'border-style': [{ border: [...scaleLineStyle(), 'hidden', 'none'] }], /** * Divide Style * @see https://tailwindcss.com/docs/border-style#setting-the-divider-style */ - 'divide-style': [{ divide: [...getLineStyleScale(), 'hidden', 'none'] }], + 'divide-style': [{ divide: [...scaleLineStyle(), 'hidden', 'none'] }], /** * Border Color * @see https://tailwindcss.com/docs/border-color */ - 'border-color': [{ border: [color] }], + 'border-color': [{ border: [themeColor] }], /** * Border Color X * @see https://tailwindcss.com/docs/border-color */ - 'border-color-x': [{ 'border-x': [color] }], + 'border-color-x': [{ 'border-x': [themeColor] }], /** * Border Color Y * @see https://tailwindcss.com/docs/border-color */ - 'border-color-y': [{ 'border-y': [color] }], + 'border-color-y': [{ 'border-y': [themeColor] }], /** * Border Color S * @see https://tailwindcss.com/docs/border-color */ - 'border-color-s': [{ 'border-s': [color] }], + 'border-color-s': [{ 'border-s': [themeColor] }], /** * Border Color E * @see https://tailwindcss.com/docs/border-color */ - 'border-color-e': [{ 'border-e': [color] }], + 'border-color-e': [{ 'border-e': [themeColor] }], /** * Border Color Top * @see https://tailwindcss.com/docs/border-color */ - 'border-color-t': [{ 'border-t': [color] }], + 'border-color-t': [{ 'border-t': [themeColor] }], /** * Border Color Right * @see https://tailwindcss.com/docs/border-color */ - 'border-color-r': [{ 'border-r': [color] }], + 'border-color-r': [{ 'border-r': [themeColor] }], /** * Border Color Bottom * @see https://tailwindcss.com/docs/border-color */ - 'border-color-b': [{ 'border-b': [color] }], + 'border-color-b': [{ 'border-b': [themeColor] }], /** * Border Color Left * @see https://tailwindcss.com/docs/border-color */ - 'border-color-l': [{ 'border-l': [color] }], + 'border-color-l': [{ 'border-l': [themeColor] }], /** * Divide Color * @see https://tailwindcss.com/docs/divide-color */ - 'divide-color': [{ divide: [color] }], + 'divide-color': [{ divide: [themeColor] }], /** * Outline Style * @see https://tailwindcss.com/docs/outline-style */ - 'outline-style': [{ outline: [...getLineStyleScale(), 'none', 'hidden'] }], + 'outline-style': [{ outline: [...scaleLineStyle(), 'none', 'hidden'] }], /** * Outline Offset * @see https://tailwindcss.com/docs/outline-offset @@ -1304,7 +1326,7 @@ export const getDefaultConfig = () => { * Outline Color * @see https://tailwindcss.com/docs/outline-color */ - 'outline-color': [{ outline: [color] }], + 'outline-color': [{ outline: [themeColor] }], // --------------- // --- Effects --- @@ -1319,7 +1341,7 @@ export const getDefaultConfig = () => { shadow: [ // Deprecated since Tailwind CSS v4.0.0 '', - shadow, + themeShadow, ], }, ], @@ -1327,24 +1349,31 @@ export const getDefaultConfig = () => { * Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color */ - 'shadow-color': [{ shadow: [color] }], + 'shadow-color': [{ shadow: [themeColor] }], /** * Inset Box Shadow * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow */ 'inset-shadow': [ - { 'inset-shadow': ['none', isArbitraryVariable, isArbitraryValue, insetShadow] }, + { + 'inset-shadow': [ + 'none', + isArbitraryVariable, + isArbitraryValue, + themeInsetShadow, + ], + }, ], /** * Inset Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color */ - 'inset-shadow-color': [{ 'inset-shadow': [color] }], + 'inset-shadow-color': [{ 'inset-shadow': [themeColor] }], /** * Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring */ - 'ring-w': [{ ring: getBorderWidthScale() }], + 'ring-w': [{ ring: scaleBorderWidth() }], /** * Ring Width Inset * @see https://v3.tailwindcss.com/docs/ring-width#inset-rings @@ -1356,7 +1385,7 @@ export const getDefaultConfig = () => { * Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color */ - 'ring-color': [{ ring: [color] }], + 'ring-color': [{ ring: [themeColor] }], /** * Ring Offset Width * @see https://v3.tailwindcss.com/docs/ring-offset-width @@ -1370,17 +1399,17 @@ export const getDefaultConfig = () => { * @deprecated since Tailwind CSS v4.0.0 * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ - 'ring-offset-color': [{ 'ring-offset': [color] }], + 'ring-offset-color': [{ 'ring-offset': [themeColor] }], /** * Inset Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring */ - 'inset-ring-w': [{ 'inset-ring': getBorderWidthScale() }], + 'inset-ring-w': [{ 'inset-ring': scaleBorderWidth() }], /** * Inset Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color */ - 'inset-ring-color': [{ 'inset-ring': [color] }], + 'inset-ring-color': [{ 'inset-ring': [themeColor] }], /** * Opacity * @see https://tailwindcss.com/docs/opacity @@ -1390,12 +1419,12 @@ export const getDefaultConfig = () => { * Mix Blend Mode * @see https://tailwindcss.com/docs/mix-blend-mode */ - 'mix-blend': [{ 'mix-blend': [...getBlendModeScale(), 'plus-darker', 'plus-lighter'] }], + 'mix-blend': [{ 'mix-blend': [...scaleBlendMode(), 'plus-darker', 'plus-lighter'] }], /** * Background Blend Mode * @see https://tailwindcss.com/docs/background-blend-mode */ - 'bg-blend': [{ 'bg-blend': getBlendModeScale() }], + 'bg-blend': [{ 'bg-blend': scaleBlendMode() }], // --------------- // --- Filters --- @@ -1420,7 +1449,7 @@ export const getDefaultConfig = () => { * Blur * @see https://tailwindcss.com/docs/blur */ - blur: [{ blur: [blur] }], + blur: [{ blur: [themeBlur] }], /** * Brightness * @see https://tailwindcss.com/docs/brightness @@ -1435,7 +1464,7 @@ export const getDefaultConfig = () => { * Drop Shadow * @see https://tailwindcss.com/docs/drop-shadow */ - 'drop-shadow': [{ 'drop-shadow': [dropShadow] }], + 'drop-shadow': [{ 'drop-shadow': [themeDropShadow] }], /** * Grayscale * @see https://tailwindcss.com/docs/grayscale @@ -1480,7 +1509,7 @@ export const getDefaultConfig = () => { * Backdrop Blur * @see https://tailwindcss.com/docs/backdrop-blur */ - 'backdrop-blur': [{ 'backdrop-blur': [blur] }], + 'backdrop-blur': [{ 'backdrop-blur': [themeBlur] }], /** * Backdrop Brightness * @see https://tailwindcss.com/docs/backdrop-brightness @@ -1551,17 +1580,17 @@ export const getDefaultConfig = () => { * Border Spacing * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing': [{ 'border-spacing': getUnambiguousSpacingScale() }], + 'border-spacing': [{ 'border-spacing': scaleUnambiguousSpacing() }], /** * Border Spacing X * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing-x': [{ 'border-spacing-x': getUnambiguousSpacingScale() }], + 'border-spacing-x': [{ 'border-spacing-x': scaleUnambiguousSpacing() }], /** * Border Spacing Y * @see https://tailwindcss.com/docs/border-spacing */ - 'border-spacing-y': [{ 'border-spacing-y': getUnambiguousSpacingScale() }], + 'border-spacing-y': [{ 'border-spacing-y': scaleUnambiguousSpacing() }], /** * Table Layout * @see https://tailwindcss.com/docs/table-layout @@ -1610,7 +1639,9 @@ export const getDefaultConfig = () => { * Transition Timing Function * @see https://tailwindcss.com/docs/transition-timing-function */ - ease: [{ ease: ['linear', 'initial', isArbitraryVariable, isArbitraryValue, ease] }], + ease: [ + { ease: ['linear', 'initial', isArbitraryVariable, isArbitraryValue, themeEase] }, + ], /** * Transition Delay * @see https://tailwindcss.com/docs/transition-delay @@ -1620,7 +1651,7 @@ export const getDefaultConfig = () => { * Animation * @see https://tailwindcss.com/docs/animation */ - animate: [{ animate: ['none', isArbitraryVariable, isArbitraryValue, animate] }], + animate: [{ animate: ['none', isArbitraryVariable, isArbitraryValue, themeAnimate] }], // ------------------ // --- Transforms --- @@ -1635,52 +1666,54 @@ export const getDefaultConfig = () => { * Perspective * @see https://tailwindcss.com/docs/perspective */ - perspective: [{ perspective: [perspective, isArbitraryVariable, isArbitraryValue] }], + perspective: [ + { perspective: [themePerspective, isArbitraryVariable, isArbitraryValue] }, + ], /** * Perspective Origin * @see https://tailwindcss.com/docs/perspective-origin */ - 'perspective-origin': [{ 'perspective-origin': getOriginScale() }], + 'perspective-origin': [{ 'perspective-origin': scaleOrigin() }], /** * Rotate * @see https://tailwindcss.com/docs/rotate */ - rotate: [{ rotate: getRotateScale() }], + rotate: [{ rotate: scaleRotate() }], /** * Rotate X * @see https://tailwindcss.com/docs/rotate */ - 'rotate-x': [{ 'rotate-x': getRotateScale() }], + 'rotate-x': [{ 'rotate-x': scaleRotate() }], /** * Rotate Y * @see https://tailwindcss.com/docs/rotate */ - 'rotate-y': [{ 'rotate-y': getRotateScale() }], + 'rotate-y': [{ 'rotate-y': scaleRotate() }], /** * Rotate Z * @see https://tailwindcss.com/docs/rotate */ - 'rotate-z': [{ 'rotate-z': getRotateScale() }], + 'rotate-z': [{ 'rotate-z': scaleRotate() }], /** * Scale * @see https://tailwindcss.com/docs/scale */ - scale: [{ scale: getScaleScale() }], + scale: [{ scale: scaleScale() }], /** * Scale X * @see https://tailwindcss.com/docs/scale */ - 'scale-x': [{ 'scale-x': getScaleScale() }], + 'scale-x': [{ 'scale-x': scaleScale() }], /** * Scale Y * @see https://tailwindcss.com/docs/scale */ - 'scale-y': [{ 'scale-y': getScaleScale() }], + 'scale-y': [{ 'scale-y': scaleScale() }], /** * Scale Z * @see https://tailwindcss.com/docs/scale */ - 'scale-z': [{ 'scale-z': getScaleScale() }], + 'scale-z': [{ 'scale-z': scaleScale() }], /** * Scale 3D * @see https://tailwindcss.com/docs/scale @@ -1690,17 +1723,17 @@ export const getDefaultConfig = () => { * Skew * @see https://tailwindcss.com/docs/skew */ - skew: [{ skew: getSkewScale() }], + skew: [{ skew: scaleSkew() }], /** * Skew X * @see https://tailwindcss.com/docs/skew */ - 'skew-x': [{ 'skew-x': getSkewScale() }], + 'skew-x': [{ 'skew-x': scaleSkew() }], /** * Skew Y * @see https://tailwindcss.com/docs/skew */ - 'skew-y': [{ 'skew-y': getSkewScale() }], + 'skew-y': [{ 'skew-y': scaleSkew() }], /** * Transform * @see https://tailwindcss.com/docs/transform @@ -1712,7 +1745,7 @@ export const getDefaultConfig = () => { * Transform Origin * @see https://tailwindcss.com/docs/transform-origin */ - 'transform-origin': [{ origin: getOriginScale() }], + 'transform-origin': [{ origin: scaleOrigin() }], /** * Transform Style * @see https://tailwindcss.com/docs/transform-style @@ -1722,22 +1755,22 @@ export const getDefaultConfig = () => { * Translate * @see https://tailwindcss.com/docs/translate */ - translate: [{ translate: getTranslateScale() }], + translate: [{ translate: scaleTranslate() }], /** * Translate X * @see https://tailwindcss.com/docs/translate */ - 'translate-x': [{ 'translate-x': getTranslateScale() }], + 'translate-x': [{ 'translate-x': scaleTranslate() }], /** * Translate Y * @see https://tailwindcss.com/docs/translate */ - 'translate-y': [{ 'translate-y': getTranslateScale() }], + 'translate-y': [{ 'translate-y': scaleTranslate() }], /** * Translate Z * @see https://tailwindcss.com/docs/translate */ - 'translate-z': [{ 'translate-z': getTranslateScale() }], + 'translate-z': [{ 'translate-z': scaleTranslate() }], /** * Translate None * @see https://tailwindcss.com/docs/translate @@ -1752,7 +1785,7 @@ export const getDefaultConfig = () => { * Accent Color * @see https://tailwindcss.com/docs/accent-color */ - accent: [{ accent: [color] }], + accent: [{ accent: [themeColor] }], /** * Appearance * @see https://tailwindcss.com/docs/appearance @@ -1762,7 +1795,7 @@ export const getDefaultConfig = () => { * Caret Color * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities */ - 'caret-color': [{ caret: [color] }], + 'caret-color': [{ caret: [themeColor] }], /** * Color Scheme * @see https://tailwindcss.com/docs/color-scheme @@ -1842,92 +1875,92 @@ export const getDefaultConfig = () => { * Scroll Margin * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-m': [{ 'scroll-m': getUnambiguousSpacingScale() }], + 'scroll-m': [{ 'scroll-m': scaleUnambiguousSpacing() }], /** * Scroll Margin X * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mx': [{ 'scroll-mx': getUnambiguousSpacingScale() }], + 'scroll-mx': [{ 'scroll-mx': scaleUnambiguousSpacing() }], /** * Scroll Margin Y * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-my': [{ 'scroll-my': getUnambiguousSpacingScale() }], + 'scroll-my': [{ 'scroll-my': scaleUnambiguousSpacing() }], /** * Scroll Margin Start * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-ms': [{ 'scroll-ms': getUnambiguousSpacingScale() }], + 'scroll-ms': [{ 'scroll-ms': scaleUnambiguousSpacing() }], /** * Scroll Margin End * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-me': [{ 'scroll-me': getUnambiguousSpacingScale() }], + 'scroll-me': [{ 'scroll-me': scaleUnambiguousSpacing() }], /** * Scroll Margin Top * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mt': [{ 'scroll-mt': getUnambiguousSpacingScale() }], + 'scroll-mt': [{ 'scroll-mt': scaleUnambiguousSpacing() }], /** * Scroll Margin Right * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mr': [{ 'scroll-mr': getUnambiguousSpacingScale() }], + 'scroll-mr': [{ 'scroll-mr': scaleUnambiguousSpacing() }], /** * Scroll Margin Bottom * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-mb': [{ 'scroll-mb': getUnambiguousSpacingScale() }], + 'scroll-mb': [{ 'scroll-mb': scaleUnambiguousSpacing() }], /** * Scroll Margin Left * @see https://tailwindcss.com/docs/scroll-margin */ - 'scroll-ml': [{ 'scroll-ml': getUnambiguousSpacingScale() }], + 'scroll-ml': [{ 'scroll-ml': scaleUnambiguousSpacing() }], /** * Scroll Padding * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-p': [{ 'scroll-p': getUnambiguousSpacingScale() }], + 'scroll-p': [{ 'scroll-p': scaleUnambiguousSpacing() }], /** * Scroll Padding X * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-px': [{ 'scroll-px': getUnambiguousSpacingScale() }], + 'scroll-px': [{ 'scroll-px': scaleUnambiguousSpacing() }], /** * Scroll Padding Y * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-py': [{ 'scroll-py': getUnambiguousSpacingScale() }], + 'scroll-py': [{ 'scroll-py': scaleUnambiguousSpacing() }], /** * Scroll Padding Start * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-ps': [{ 'scroll-ps': getUnambiguousSpacingScale() }], + 'scroll-ps': [{ 'scroll-ps': scaleUnambiguousSpacing() }], /** * Scroll Padding End * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pe': [{ 'scroll-pe': getUnambiguousSpacingScale() }], + 'scroll-pe': [{ 'scroll-pe': scaleUnambiguousSpacing() }], /** * Scroll Padding Top * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pt': [{ 'scroll-pt': getUnambiguousSpacingScale() }], + 'scroll-pt': [{ 'scroll-pt': scaleUnambiguousSpacing() }], /** * Scroll Padding Right * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pr': [{ 'scroll-pr': getUnambiguousSpacingScale() }], + 'scroll-pr': [{ 'scroll-pr': scaleUnambiguousSpacing() }], /** * Scroll Padding Bottom * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pb': [{ 'scroll-pb': getUnambiguousSpacingScale() }], + 'scroll-pb': [{ 'scroll-pb': scaleUnambiguousSpacing() }], /** * Scroll Padding Left * @see https://tailwindcss.com/docs/scroll-padding */ - 'scroll-pl': [{ 'scroll-pl': getUnambiguousSpacingScale() }], + 'scroll-pl': [{ 'scroll-pl': scaleUnambiguousSpacing() }], /** * Scroll Snap Align * @see https://tailwindcss.com/docs/scroll-snap-align @@ -1998,7 +2031,7 @@ export const getDefaultConfig = () => { * Fill * @see https://tailwindcss.com/docs/fill */ - fill: [{ fill: ['none', color] }], + fill: [{ fill: ['none', themeColor] }], /** * Stroke Width * @see https://tailwindcss.com/docs/stroke-width @@ -2017,7 +2050,7 @@ export const getDefaultConfig = () => { * Stroke * @see https://tailwindcss.com/docs/stroke */ - stroke: [{ stroke: ['none', color] }], + stroke: [{ stroke: ['none', themeColor] }], // --------------------- // --- Accessibility --- From bd2e7b314145eb84042ee54b54966b5a600e06a0 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 14:07:48 +0100 Subject: [PATCH 21/48] move arbitrary validators out of theme scales to class groups directly --- src/lib/default-config.ts | 182 ++++++++++++++++++++------------------ 1 file changed, 98 insertions(+), 84 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 6cdc0ebc..4f8ae8e6 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -123,7 +123,18 @@ export const getDefaultConfig = () => { isArbitraryValue, themeSpacing, ] as const + const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue] as const const scaleGradientStopPosition = () => [isPercent, isArbitraryLength] as const + const scaleRadius = () => + [ + // Deprecated since Tailwind CSS v4.0.0 + '', + 'none', + 'full', + themeRadius, + isArbitraryVariable, + isArbitraryValue, + ] as const const scaleBorderWidth = () => ['', isNumber, isArbitraryVariableLength, isArbitraryLength] as const const scaleLineStyle = () => ['solid', 'dashed', 'dotted', 'double'] as const @@ -146,6 +157,15 @@ export const getDefaultConfig = () => { 'color', 'luminosity', ] as const + const scaleBlur = () => + [ + // Deprecated since Tailwind CSS v4.0.0 + '', + 'none', + themeBlur, + isArbitraryVariable, + isArbitraryValue, + ] as const const scaleOrigin = () => [ 'center', @@ -170,9 +190,15 @@ export const getDefaultConfig = () => { cacheSize: 500, separator: ':', theme: { + animate: ['spin', 'ping', 'pulse', 'bounce'], + aspect: ['video'], + blur: [isTshirtSize], + breakpoint: [isTshirtSize], color: [isAny], - font: [isAnyNonArbitrary, isArbitraryVariableFamilyName, isArbitraryValue], - text: ['base', isTshirtSize, isArbitraryVariableLength, isArbitraryLength], + container: [isTshirtSize], + 'drop-shadow': [isTshirtSize], + ease: ['in', 'out', 'in-out'], + font: [isAnyNonArbitrary], 'font-weight': [ 'thin', 'extralight', @@ -184,42 +210,14 @@ export const getDefaultConfig = () => { 'extrabold', 'black', ], - tracking: ['tighter', 'tight', 'normal', 'wide', 'wider', 'widest'], - leading: ['none', 'tight', 'snug', 'normal', 'relaxed', 'loose'], - breakpoint: [isTshirtSize], - container: [isTshirtSize], - spacing: [isNumber, isArbitraryVariableLength, isArbitraryLength], - radius: [ - // Deprecated since Tailwind CSS v4.0.0 - '', - isTshirtSize, - 'none', - 'full', - isArbitraryVariable, - isArbitraryValue, - ], - shadow: [isTshirtSize, 'none', isArbitraryVariableShadow, isArbitraryShadow], 'inset-shadow': [isTshirtSize], - 'drop-shadow': [ - // Deprecated since Tailwind CSS v4.0.0 - '', - isTshirtSize, - 'none', - isArbitraryVariable, - isArbitraryValue, - ], - blur: [ - // Deprecated since Tailwind CSS v4.0.0 - '', - isTshirtSize, - 'none', - isArbitraryVariable, - isArbitraryValue, - ], + leading: ['none', 'tight', 'snug', 'normal', 'relaxed', 'loose'], perspective: ['dramatic', 'near', 'normal', 'midrange', 'distant', 'none'], - aspect: ['video'], - ease: ['in', 'out', 'in-out'], - animate: ['spin', 'ping', 'pulse', 'bounce'], + radius: [isTshirtSize], + shadow: [isTshirtSize], + spacing: [isNumber], + text: [isTshirtSize], + tracking: ['tighter', 'tight', 'normal', 'wide', 'wider', 'widest'], }, classGroups: { // -------------- @@ -778,7 +776,9 @@ export const getDefaultConfig = () => { * Font Size * @see https://tailwindcss.com/docs/font-size */ - 'font-size': [{ text: [themeText] }], + 'font-size': [ + { text: ['base', themeText, isArbitraryVariableLength, isArbitraryLength] }, + ], /** * Font Smoothing * @see https://tailwindcss.com/docs/font-smoothing @@ -819,7 +819,7 @@ export const getDefaultConfig = () => { * Font Family * @see https://tailwindcss.com/docs/font-family */ - 'font-family': [{ font: [themeFont] }], + 'font-family': [{ font: [isArbitraryVariableFamilyName, isArbitraryValue, themeFont] }], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font-variant-numeric @@ -896,12 +896,12 @@ export const getDefaultConfig = () => { * @deprecated since Tailwind CSS v3.0.0 * @see https://v3.tailwindcss.com/docs/placeholder-color */ - 'placeholder-color': [{ placeholder: [themeColor] }], + 'placeholder-color': [{ placeholder: scaleColor() }], /** * Text Color * @see https://tailwindcss.com/docs/text-color */ - 'text-color': [{ text: [themeColor] }], + 'text-color': [{ text: scaleColor() }], /** * Text Decoration * @see https://tailwindcss.com/docs/text-decoration @@ -931,7 +931,7 @@ export const getDefaultConfig = () => { * Text Decoration Color * @see https://tailwindcss.com/docs/text-decoration-color */ - 'text-decoration-color': [{ decoration: [themeColor] }], + 'text-decoration-color': [{ decoration: scaleColor() }], /** * Text Underline Offset * @see https://tailwindcss.com/docs/text-underline-offset @@ -1067,7 +1067,7 @@ export const getDefaultConfig = () => { * Background Color * @see https://tailwindcss.com/docs/background-color */ - 'bg-color': [{ bg: [themeColor] }], + 'bg-color': [{ bg: scaleColor() }], /** * Gradient Color Stops From Position * @see https://tailwindcss.com/docs/gradient-color-stops @@ -1087,17 +1087,17 @@ export const getDefaultConfig = () => { * Gradient Color Stops From * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-from': [{ from: [themeColor] }], + 'gradient-from': [{ from: scaleColor() }], /** * Gradient Color Stops Via * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-via': [{ via: [themeColor] }], + 'gradient-via': [{ via: scaleColor() }], /** * Gradient Color Stops To * @see https://tailwindcss.com/docs/gradient-color-stops */ - 'gradient-to': [{ to: [themeColor] }], + 'gradient-to': [{ to: scaleColor() }], // --------------- // --- Borders --- @@ -1107,77 +1107,77 @@ export const getDefaultConfig = () => { * Border Radius * @see https://tailwindcss.com/docs/border-radius */ - rounded: [{ rounded: [themeRadius] }], + rounded: [{ rounded: scaleRadius() }], /** * Border Radius Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-s': [{ 'rounded-s': [themeRadius] }], + 'rounded-s': [{ 'rounded-s': scaleRadius() }], /** * Border Radius End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-e': [{ 'rounded-e': [themeRadius] }], + 'rounded-e': [{ 'rounded-e': scaleRadius() }], /** * Border Radius Top * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-t': [{ 'rounded-t': [themeRadius] }], + 'rounded-t': [{ 'rounded-t': scaleRadius() }], /** * Border Radius Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-r': [{ 'rounded-r': [themeRadius] }], + 'rounded-r': [{ 'rounded-r': scaleRadius() }], /** * Border Radius Bottom * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-b': [{ 'rounded-b': [themeRadius] }], + 'rounded-b': [{ 'rounded-b': scaleRadius() }], /** * Border Radius Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-l': [{ 'rounded-l': [themeRadius] }], + 'rounded-l': [{ 'rounded-l': scaleRadius() }], /** * Border Radius Start Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ss': [{ 'rounded-ss': [themeRadius] }], + 'rounded-ss': [{ 'rounded-ss': scaleRadius() }], /** * Border Radius Start End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-se': [{ 'rounded-se': [themeRadius] }], + 'rounded-se': [{ 'rounded-se': scaleRadius() }], /** * Border Radius End End * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-ee': [{ 'rounded-ee': [themeRadius] }], + 'rounded-ee': [{ 'rounded-ee': scaleRadius() }], /** * Border Radius End Start * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-es': [{ 'rounded-es': [themeRadius] }], + 'rounded-es': [{ 'rounded-es': scaleRadius() }], /** * Border Radius Top Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tl': [{ 'rounded-tl': [themeRadius] }], + 'rounded-tl': [{ 'rounded-tl': scaleRadius() }], /** * Border Radius Top Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-tr': [{ 'rounded-tr': [themeRadius] }], + 'rounded-tr': [{ 'rounded-tr': scaleRadius() }], /** * Border Radius Bottom Right * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-br': [{ 'rounded-br': [themeRadius] }], + 'rounded-br': [{ 'rounded-br': scaleRadius() }], /** * Border Radius Bottom Left * @see https://tailwindcss.com/docs/border-radius */ - 'rounded-bl': [{ 'rounded-bl': [themeRadius] }], + 'rounded-bl': [{ 'rounded-bl': scaleRadius() }], /** * Border Width * @see https://tailwindcss.com/docs/border-width @@ -1257,52 +1257,52 @@ export const getDefaultConfig = () => { * Border Color * @see https://tailwindcss.com/docs/border-color */ - 'border-color': [{ border: [themeColor] }], + 'border-color': [{ border: scaleColor() }], /** * Border Color X * @see https://tailwindcss.com/docs/border-color */ - 'border-color-x': [{ 'border-x': [themeColor] }], + 'border-color-x': [{ 'border-x': scaleColor() }], /** * Border Color Y * @see https://tailwindcss.com/docs/border-color */ - 'border-color-y': [{ 'border-y': [themeColor] }], + 'border-color-y': [{ 'border-y': scaleColor() }], /** * Border Color S * @see https://tailwindcss.com/docs/border-color */ - 'border-color-s': [{ 'border-s': [themeColor] }], + 'border-color-s': [{ 'border-s': scaleColor() }], /** * Border Color E * @see https://tailwindcss.com/docs/border-color */ - 'border-color-e': [{ 'border-e': [themeColor] }], + 'border-color-e': [{ 'border-e': scaleColor() }], /** * Border Color Top * @see https://tailwindcss.com/docs/border-color */ - 'border-color-t': [{ 'border-t': [themeColor] }], + 'border-color-t': [{ 'border-t': scaleColor() }], /** * Border Color Right * @see https://tailwindcss.com/docs/border-color */ - 'border-color-r': [{ 'border-r': [themeColor] }], + 'border-color-r': [{ 'border-r': scaleColor() }], /** * Border Color Bottom * @see https://tailwindcss.com/docs/border-color */ - 'border-color-b': [{ 'border-b': [themeColor] }], + 'border-color-b': [{ 'border-b': scaleColor() }], /** * Border Color Left * @see https://tailwindcss.com/docs/border-color */ - 'border-color-l': [{ 'border-l': [themeColor] }], + 'border-color-l': [{ 'border-l': scaleColor() }], /** * Divide Color * @see https://tailwindcss.com/docs/divide-color */ - 'divide-color': [{ divide: [themeColor] }], + 'divide-color': [{ divide: scaleColor() }], /** * Outline Style * @see https://tailwindcss.com/docs/outline-style @@ -1341,7 +1341,10 @@ export const getDefaultConfig = () => { shadow: [ // Deprecated since Tailwind CSS v4.0.0 '', + 'none', themeShadow, + isArbitraryVariableShadow, + isArbitraryShadow, ], }, ], @@ -1349,7 +1352,7 @@ export const getDefaultConfig = () => { * Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color */ - 'shadow-color': [{ shadow: [themeColor] }], + 'shadow-color': [{ shadow: scaleColor() }], /** * Inset Box Shadow * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow @@ -1368,7 +1371,7 @@ export const getDefaultConfig = () => { * Inset Box Shadow Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color */ - 'inset-shadow-color': [{ 'inset-shadow': [themeColor] }], + 'inset-shadow-color': [{ 'inset-shadow': scaleColor() }], /** * Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring @@ -1385,7 +1388,7 @@ export const getDefaultConfig = () => { * Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color */ - 'ring-color': [{ ring: [themeColor] }], + 'ring-color': [{ ring: scaleColor() }], /** * Ring Offset Width * @see https://v3.tailwindcss.com/docs/ring-offset-width @@ -1399,7 +1402,7 @@ export const getDefaultConfig = () => { * @deprecated since Tailwind CSS v4.0.0 * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158 */ - 'ring-offset-color': [{ 'ring-offset': [themeColor] }], + 'ring-offset-color': [{ 'ring-offset': scaleColor() }], /** * Inset Ring Width * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring @@ -1409,7 +1412,7 @@ export const getDefaultConfig = () => { * Inset Ring Color * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color */ - 'inset-ring-color': [{ 'inset-ring': [themeColor] }], + 'inset-ring-color': [{ 'inset-ring': scaleColor() }], /** * Opacity * @see https://tailwindcss.com/docs/opacity @@ -1449,7 +1452,7 @@ export const getDefaultConfig = () => { * Blur * @see https://tailwindcss.com/docs/blur */ - blur: [{ blur: [themeBlur] }], + blur: [{ blur: scaleBlur() }], /** * Brightness * @see https://tailwindcss.com/docs/brightness @@ -1464,7 +1467,18 @@ export const getDefaultConfig = () => { * Drop Shadow * @see https://tailwindcss.com/docs/drop-shadow */ - 'drop-shadow': [{ 'drop-shadow': [themeDropShadow] }], + 'drop-shadow': [ + { + 'drop-shadow': [ + // Deprecated since Tailwind CSS v4.0.0 + '', + 'none', + themeDropShadow, + isArbitraryVariable, + isArbitraryValue, + ], + }, + ], /** * Grayscale * @see https://tailwindcss.com/docs/grayscale @@ -1509,7 +1523,7 @@ export const getDefaultConfig = () => { * Backdrop Blur * @see https://tailwindcss.com/docs/backdrop-blur */ - 'backdrop-blur': [{ 'backdrop-blur': [themeBlur] }], + 'backdrop-blur': [{ 'backdrop-blur': scaleBlur() }], /** * Backdrop Brightness * @see https://tailwindcss.com/docs/backdrop-brightness @@ -1640,7 +1654,7 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/transition-timing-function */ ease: [ - { ease: ['linear', 'initial', isArbitraryVariable, isArbitraryValue, themeEase] }, + { ease: ['linear', 'initial', themeEase, isArbitraryVariable, isArbitraryValue] }, ], /** * Transition Delay @@ -1651,7 +1665,7 @@ export const getDefaultConfig = () => { * Animation * @see https://tailwindcss.com/docs/animation */ - animate: [{ animate: ['none', isArbitraryVariable, isArbitraryValue, themeAnimate] }], + animate: [{ animate: ['none', themeAnimate, isArbitraryVariable, isArbitraryValue] }], // ------------------ // --- Transforms --- @@ -1785,7 +1799,7 @@ export const getDefaultConfig = () => { * Accent Color * @see https://tailwindcss.com/docs/accent-color */ - accent: [{ accent: [themeColor] }], + accent: [{ accent: scaleColor() }], /** * Appearance * @see https://tailwindcss.com/docs/appearance @@ -1795,7 +1809,7 @@ export const getDefaultConfig = () => { * Caret Color * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities */ - 'caret-color': [{ caret: [themeColor] }], + 'caret-color': [{ caret: scaleColor() }], /** * Color Scheme * @see https://tailwindcss.com/docs/color-scheme @@ -2031,7 +2045,7 @@ export const getDefaultConfig = () => { * Fill * @see https://tailwindcss.com/docs/fill */ - fill: [{ fill: ['none', themeColor] }], + fill: [{ fill: ['none', ...scaleColor()] }], /** * Stroke Width * @see https://tailwindcss.com/docs/stroke-width @@ -2050,7 +2064,7 @@ export const getDefaultConfig = () => { * Stroke * @see https://tailwindcss.com/docs/stroke */ - stroke: [{ stroke: ['none', themeColor] }], + stroke: [{ stroke: ['none', ...scaleColor()] }], // --------------------- // --- Accessibility --- From 94e9e2697c7bc82f188602b5a895065e5a85a261 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 17:29:18 +0100 Subject: [PATCH 22/48] add support for important modifier at the end of base class name --- docs/features.md | 4 ++-- docs/when-and-how-to-use-it.md | 4 ++-- src/lib/parse-class-name.ts | 24 ++++++++++++++++++------ tests/important-modifier.test.ts | 11 +++++++++++ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/docs/features.md b/docs/features.md index 9e9f886b..09050c5f 100644 --- a/docs/features.md +++ b/docs/features.md @@ -82,8 +82,8 @@ The order of standard modifiers before and after an arbitrary variant in isolati ### Supports important modifier ```ts -twMerge('!p-3 !p-4 p-5') // → '!p-4 p-5' -twMerge('!right-2 !-inset-x-1') // → '!-inset-x-1' +twMerge('p-3! p-4! p-5') // → 'p-4! p-5' +twMerge('right-2! -inset-x-1!') // → '-inset-x-1!' ``` ### Supports postfix modifiers diff --git a/docs/when-and-how-to-use-it.md b/docs/when-and-how-to-use-it.md index 6935f60c..ca5e30aa 100644 --- a/docs/when-and-how-to-use-it.md +++ b/docs/when-and-how-to-use-it.md @@ -144,7 +144,7 @@ function MyComponent() { return ( <> - + ) } @@ -158,7 +158,7 @@ function join(...args) { } ``` -The main downside of this approach is that it only works one level deep (you can't override the `!bg-red-500` class in the example above). But if you don't need to be able to override styles through multiple levels of composition, this might be the most lightweight approach possible. +The main downside of this approach is that it only works one level deep (you can't override the `bg-red-500!` class in the example above). But if you don't need to be able to override styles through multiple levels of composition, this might be the most lightweight approach possible. --- diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index aee93c55..7776af96 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -50,12 +50,8 @@ export const createParseClassName = (config: AnyConfig) => { const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.substring(modifierStart) - const hasImportantModifier = - baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER) - const baseClassName = hasImportantModifier - ? baseClassNameWithImportantModifier.substring(1) - : baseClassNameWithImportantModifier - + const baseClassName = stripImportantModifier(baseClassNameWithImportantModifier) + const hasImportantModifier = baseClassName !== baseClassNameWithImportantModifier const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart @@ -104,3 +100,19 @@ export const sortModifiers = (modifiers: string[]) => { return sortedModifiers } + +const stripImportantModifier = (baseClassName: string) => { + if (baseClassName.endsWith(IMPORTANT_MODIFIER)) { + return baseClassName.substring(0, baseClassName.length - 1) + } + + /** + * In Tailwind CSS v3 the important modifier was at the start of the base class name. This is still supported for legacy reasons. + * @see https://github.com/dcastil/tailwind-merge/issues/513#issuecomment-2614029864 + */ + if (baseClassName.startsWith(IMPORTANT_MODIFIER)) { + return baseClassName.substring(1) + } + + return baseClassName +} diff --git a/tests/important-modifier.test.ts b/tests/important-modifier.test.ts index c5cdfe7d..b3520d7d 100644 --- a/tests/important-modifier.test.ts +++ b/tests/important-modifier.test.ts @@ -3,8 +3,19 @@ import { expect, test } from 'vitest' import { twMerge } from '../src' test('merges tailwind classes with important modifier correctly', () => { + expect(twMerge('font-medium! font-bold!')).toBe('font-bold!') + expect(twMerge('font-medium! font-bold! font-thin')).toBe('font-bold! font-thin') + expect(twMerge('right-2! -inset-x-px!')).toBe('-inset-x-px!') + expect(twMerge('focus:inline! focus:block!')).toBe('focus:block!') + expect(twMerge('[--my-var:20px]! [--my-var:30px]!')).toBe('[--my-var:30px]!') + + // Tailwind CSS v3 legacy syntax + + expect(twMerge('font-medium! !font-bold')).toBe('!font-bold') + expect(twMerge('!font-medium !font-bold')).toBe('!font-bold') expect(twMerge('!font-medium !font-bold font-thin')).toBe('!font-bold font-thin') expect(twMerge('!right-2 !-inset-x-px')).toBe('!-inset-x-px') expect(twMerge('focus:!inline focus:!block')).toBe('focus:!block') + expect(twMerge('![--my-var:20px] ![--my-var:30px]')).toBe('![--my-var:30px]') }) From 380c977f9af68e76af114ca77791f01ee4be5e8f Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 19:15:30 +0100 Subject: [PATCH 23/48] add support for new prefix syntax --- docs/api-reference.md | 28 ++++++++--------- docs/configuration.md | 60 ++++++++++++++++++------------------ src/index.ts | 2 +- src/lib/class-group-utils.ts | 40 +++--------------------- src/lib/merge-classlist.ts | 16 ++++++++-- src/lib/parse-class-name.ts | 32 ++++++++++++++++--- src/lib/types.ts | 12 ++++++-- tests/merge-configs.test.ts | 4 +-- tests/prefixes.test.ts | 13 ++++---- tests/type-generics.test.ts | 2 +- 10 files changed, 107 insertions(+), 102 deletions(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 394a5c0f..8687b4cc 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -123,7 +123,7 @@ const customTwMerge = extendTailwindMerge { * Exported for testing only */ export const createClassMap = (config: Config) => { - const { theme, prefix } = config + const { theme, classGroups } = config const classMap: ClassPartObject = { nextPart: new Map(), validators: [], } - const prefixedClassGroupEntries = getPrefixedClassGroupEntries( - Object.entries(config.classGroups), - prefix, - ) - - prefixedClassGroupEntries.forEach(([classGroupId, classGroup]) => { - processClassesRecursively(classGroup, classMap, classGroupId, theme) - }) + for (const classGroupId in classGroups) { + processClassesRecursively(classGroups[classGroupId]!, classMap, classGroupId, theme) + } return classMap } @@ -185,30 +180,3 @@ const getPart = (classPartObject: ClassPartObject, path: string) => { const isThemeGetter = (func: ClassValidator | ThemeGetter): func is ThemeGetter => (func as ThemeGetter).isThemeGetter - -const getPrefixedClassGroupEntries = ( - classGroupEntries: Array<[classGroupId: string, classGroup: ClassGroup]>, - prefix: string | undefined, -): Array<[classGroupId: string, classGroup: ClassGroup]> => { - if (!prefix) { - return classGroupEntries - } - - return classGroupEntries.map(([classGroupId, classGroup]) => { - const prefixedClassGroup = classGroup.map((classDefinition) => { - if (typeof classDefinition === 'string') { - return prefix + classDefinition - } - - if (typeof classDefinition === 'object') { - return Object.fromEntries( - Object.entries(classDefinition).map(([key, value]) => [prefix + key, value]), - ) - } - - return classDefinition - }) - - return [classGroupId, prefixedClassGroup] - }) -} diff --git a/src/lib/merge-classlist.ts b/src/lib/merge-classlist.ts index 0d77e3a0..b53e14ff 100644 --- a/src/lib/merge-classlist.ts +++ b/src/lib/merge-classlist.ts @@ -21,10 +21,20 @@ export const mergeClassList = (classList: string, configUtils: ConfigUtils) => { for (let index = classNames.length - 1; index >= 0; index -= 1) { const originalClassName = classNames[index]! - const { modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition } = - parseClassName(originalClassName) + const { + isExternal, + modifiers, + hasImportantModifier, + baseClassName, + maybePostfixModifierPosition, + } = parseClassName(originalClassName) + + if (isExternal) { + result = originalClassName + (result.length > 0 ? ' ' + result : result) + continue + } - let hasPostfixModifier = Boolean(maybePostfixModifierPosition) + let hasPostfixModifier = !!maybePostfixModifierPosition let classGroupId = getClassGroupId( hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index 7776af96..ef9b6087 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -1,15 +1,20 @@ -import { AnyConfig } from './types' +import { AnyConfig, ParsedClassName } from './types' export const IMPORTANT_MODIFIER = '!' export const createParseClassName = (config: AnyConfig) => { - const { separator, experimentalParseClassName } = config + const { prefix, separator, experimentalParseClassName } = config const isSeparatorSingleCharacter = separator.length === 1 const firstSeparatorCharacter = separator[0] const separatorLength = separator.length - // parseClassName inspired by https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js - const parseClassName = (className: string) => { + /** + * Parse class name into parts. + * + * Inspired by `splitAtTopLevelOnly` used in Tailwind CSS + * @see https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js + */ + let parseClassName = (className: string): ParsedClassName => { const modifiers = [] let bracketDepth = 0 @@ -65,8 +70,25 @@ export const createParseClassName = (config: AnyConfig) => { } } + if (prefix) { + const fullPrefix = prefix + separator + const parseClassNameOriginal = parseClassName + parseClassName = (className: string) => + className.startsWith(fullPrefix) + ? parseClassNameOriginal(className.substring(fullPrefix.length)) + : { + isExternal: true, + modifiers: [], + hasImportantModifier: false, + baseClassName: className, + maybePostfixModifierPosition: undefined, + } + } + if (experimentalParseClassName) { - return (className: string) => experimentalParseClassName({ className, parseClassName }) + const parseClassNameOriginal = parseClassName + parseClassName = (className: string) => + experimentalParseClassName({ className, parseClassName: parseClassNameOriginal }) } return parseClassName diff --git a/src/lib/types.ts b/src/lib/types.ts index cc248cd0..a1f9450e 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -31,7 +31,7 @@ interface ConfigStaticPart { * * This is an experimental feature and may introduce breaking changes in any minor version update. */ - experimentalParseClassName?(param: ExperimentalParseClassNameParam): ExperimentalParsedClassName + experimentalParseClassName?(param: ExperimentalParseClassNameParam): ParsedClassName } /** @@ -41,7 +41,7 @@ interface ConfigStaticPart { */ export interface ExperimentalParseClassNameParam { className: string - parseClassName(className: string): ExperimentalParsedClassName + parseClassName(className: string): ParsedClassName } /** @@ -49,7 +49,13 @@ export interface ExperimentalParseClassNameParam { * * This is an experimental feature and may introduce breaking changes in any minor version update. */ -export interface ExperimentalParsedClassName { +export interface ParsedClassName { + /** + * Whether the class is external and merging logic should be sipped. + * + * If this is `true`, the class will be treated as if it wasn't a Tailwind class and will be passed through as is. + */ + isExternal?: boolean /** * Modifiers of the class in the order they appear in the class. * diff --git a/tests/merge-configs.test.ts b/tests/merge-configs.test.ts index 6fa86c67..7024a6c1 100644 --- a/tests/merge-configs.test.ts +++ b/tests/merge-configs.test.ts @@ -7,7 +7,7 @@ test('mergeConfigs has correct behavior', () => { mergeConfigs( { cacheSize: 50, - prefix: 'tw-', + prefix: 'tw', separator: ':', theme: { hi: ['ho'], @@ -64,7 +64,7 @@ test('mergeConfigs has correct behavior', () => { ), ).toEqual({ cacheSize: 50, - prefix: 'tw-', + prefix: 'tw', separator: '-', theme: { hi: ['ho'], diff --git a/tests/prefixes.test.ts b/tests/prefixes.test.ts index cf17f0b7..cde63dd8 100644 --- a/tests/prefixes.test.ts +++ b/tests/prefixes.test.ts @@ -4,18 +4,17 @@ import { extendTailwindMerge } from '../src' test('prefix working correctly', () => { const twMerge = extendTailwindMerge({ - prefix: 'tw-', + prefix: 'tw', }) - - expect(twMerge('tw-block tw-hidden')).toBe('tw-hidden') + expect(twMerge('tw:block tw:hidden')).toBe('tw:hidden') expect(twMerge('block hidden')).toBe('block hidden') - expect(twMerge('tw-p-3 tw-p-2')).toBe('tw-p-2') + expect(twMerge('tw:p-3 tw:p-2')).toBe('tw:p-2') expect(twMerge('p-3 p-2')).toBe('p-3 p-2') - expect(twMerge('!tw-right-0 !tw-inset-0')).toBe('!tw-inset-0') + expect(twMerge('tw:right-0! tw:inset-0!')).toBe('tw:inset-0!') - expect(twMerge('hover:focus:!tw-right-0 focus:hover:!tw-inset-0')).toBe( - 'focus:hover:!tw-inset-0', + expect(twMerge('tw:hover:focus:right-0! tw:focus:hover:inset-0!')).toBe( + 'tw:focus:hover:inset-0!', ) }) diff --git a/tests/type-generics.test.ts b/tests/type-generics.test.ts index f2da063d..647cc8e0 100644 --- a/tests/type-generics.test.ts +++ b/tests/type-generics.test.ts @@ -100,7 +100,7 @@ test('mergeConfigs type generics work correctly', () => { const config1 = mergeConfigs<'foo' | 'bar', 'baz'>( { cacheSize: 50, - prefix: 'tw-', + prefix: 'tw', separator: ':', theme: { hi: ['ho'], From e8531f89d2179a4050e724f36312064f643b7f57 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 19:29:06 +0100 Subject: [PATCH 24/48] remove unnecessary type annotation --- src/lib/parse-class-name.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index ef9b6087..2bff1317 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -73,7 +73,7 @@ export const createParseClassName = (config: AnyConfig) => { if (prefix) { const fullPrefix = prefix + separator const parseClassNameOriginal = parseClassName - parseClassName = (className: string) => + parseClassName = (className) => className.startsWith(fullPrefix) ? parseClassNameOriginal(className.substring(fullPrefix.length)) : { @@ -87,7 +87,7 @@ export const createParseClassName = (config: AnyConfig) => { if (experimentalParseClassName) { const parseClassNameOriginal = parseClassName - parseClassName = (className: string) => + parseClassName = (className) => experimentalParseClassName({ className, parseClassName: parseClassNameOriginal }) } From bc461530b742eda596d4f12a04607fa1f7e35566 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 19:36:11 +0100 Subject: [PATCH 25/48] add test case for arbitrary variant without `&` symbol --- tests/arbitrary-variants.test.ts | 1 + tests/tailwind-css-versions.test.ts | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/arbitrary-variants.test.ts b/tests/arbitrary-variants.test.ts index a3414a4c..a5dc56d8 100644 --- a/tests/arbitrary-variants.test.ts +++ b/tests/arbitrary-variants.test.ts @@ -3,6 +3,7 @@ import { expect, test } from 'vitest' import { twMerge } from '../src' test('basic arbitrary variants', () => { + expect(twMerge('[p]:underline [p]:line-through')).toBe('[p]:line-through') expect(twMerge('[&>*]:underline [&>*]:line-through')).toBe('[&>*]:line-through') expect(twMerge('[&>*]:underline [&>*]:line-through [&_div]:line-through')).toBe( '[&>*]:line-through [&_div]:line-through', diff --git a/tests/tailwind-css-versions.test.ts b/tests/tailwind-css-versions.test.ts index cf36a10a..0b10d3b4 100644 --- a/tests/tailwind-css-versions.test.ts +++ b/tests/tailwind-css-versions.test.ts @@ -79,7 +79,4 @@ test('supports Tailwind CSS v4.0 features', () => { expect(twMerge('font-stretch-expanded font-stretch-[66.66%] font-stretch-50%')).toBe( 'font-stretch-50%', ) - - // TODO: Remove proto - expect(twMerge('')).toBe('') }) From be17bc6bf97b733e453ff7ca5e69b4081e88977b Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Sun, 26 Jan 2025 20:06:06 +0100 Subject: [PATCH 26/48] adjust configuration documentation to new theme scales --- docs/api-reference.md | 14 ++++---- docs/configuration.md | 75 +++++++++++++++++++++++++------------------ docs/recipes.md | 16 ++++++--- 3 files changed, 62 insertions(+), 43 deletions(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 8687b4cc..d7d5f1bd 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -118,7 +118,7 @@ When using TypeScript and you use custom class group IDs or theme group IDs, you type AdditionalClassGroupIds = 'aspect-w' | 'aspect-h' | 'aspect-reset' type AdditionalThemeGroupIds = never -const customTwMerge = extendTailwindMerge({ +const twMerge = extendTailwindMerge({ // ↓ Optional cache size // Here we're disabling the cache cacheSize: 0, @@ -202,13 +202,13 @@ const customTwMerge = extendTailwindMerge { +// `twMerge` gets called the first time. +const twMerge = createTailwindMerge(() => { const defaultConfig = getDefaultConfig() return { @@ -255,7 +255,7 @@ const customTwMerge = createTailwindMerge(() => { Same as in [`extendTailwindMerge`](#extendtailwindmerge) you can use multiple `createConfig` functions which is convenient if you want to combine your config with third-party plugins. Just keep in mind that the first `createConfig` function does not get passed any arguments, whereas the subsequent functions get each passed the config from the previous function. ```ts -const customTwMerge = createTailwindMerge(getDefaultConfig, withSomePlugin, (config) => ({ +const twMerge = createTailwindMerge(getDefaultConfig, withSomePlugin, (config) => ({ // ↓ Config returned by `withSomePlugin` ...config, classGroups: { @@ -281,7 +281,7 @@ Helper function to merge multiple tailwind-merge configs. Properties with the va When using TypeScript, you need to pass a union of all class group IDs and theme group IDs used in `configExtension` as generic arguments to `mergeConfigs` or pass `string` to both arguments to allow any IDs. ```ts -const customTwMerge = createTailwindMerge(getDefaultConfig, (config) => +const twMerge = createTailwindMerge(getDefaultConfig, (config) => mergeConfigs<'shadow' | 'animate' | 'prose'>(config, { override: { classGroups: { diff --git a/docs/configuration.md b/docs/configuration.md index f2211843..c386fd37 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -138,35 +138,46 @@ const conflictingClassGroupModifiers = { ### Theme -In the Tailwind config you can modify theme scales. tailwind-merge follows the same keys for the theme scales, but doesn't support all of them. tailwind-merge only supports theme scales which are used in multiple class groups to save bundle size (more info to that in [PR 55](https://github.com/dcastil/tailwind-merge/pull/55)). At the moment these are: - -- `colors` -- `spacing` -- `blur` -- `brightness` -- `borderColor` -- `borderRadius` -- `borderSpacing` -- `borderWidth` -- `contrast` -- `grayscale` -- `hueRotate` -- `invert` -- `gap` -- `gradientColorStops` -- `gradientColorStopPositions` -- `inset` -- `margin` -- `opacity` -- `padding` -- `saturate` -- `scale` -- `sepia` -- `skew` -- `space` -- `translate` - -If you modified one of these theme scales in your Tailwind config, you can add all your keys right here and tailwind-merge will take care of the rest. If you modified other theme scales, you need to figure out the class group to modify in the [default config](./api-reference.md#getdefaultconfig). +In the Tailwind config you can modify your theme variable namespace to add classes with custom values. tailwind-merge follows the same naming scheme as Tailwind CSS for its theme scales: + +| Tailwind CSS namespace | tailwind-merge theme key | +| ---------------------- | ------------------------ | +| `--color-*` | `color` | +| `--font-*` | `font` | +| `--text-*` | `text` | +| `--font-weight-*` | `font-weight` | +| `--tracking-*` | `tracking` | +| `--leading-*` | `leading` | +| `--breakpoint-*` | `breakpoint` | +| `--container-*` | `container` | +| `--spacing-*` | `spacing` | +| `--radius-*` | `radius` | +| `--shadow-*` | `shadow` | +| `--inset-shadow-*` | `inset-shadow` | +| `--drop-shadow-*` | `drop-shadow` | +| `--blur-*` | `blur` | +| `--perspective-*` | `perspective` | +| `--aspect-*` | `aspect` | +| `--ease-*` | `ease` | +| `--animate-*` | `animate` | + +If you modified one of the theme namespaces in your Tailwind config, you need to add the variable names to the `theme` object in tailwind-merge as well so that tailwind-merge knows about them. + +E.g. let's say you added the variable `--text-huge-af: 100px` to your Tailwind config which enables classes like `text-huge-af`. To make sure that tailwind-merge merges these classes correctly, you need to configure tailwind-merge like this: + +```ts +import { extendTailwindMerge } from 'tailwind-merge' + +const twMerge = extendTailwindMerge({ + extend: { + theme: { + // ↓ `text` is the key of the namespace `--text-*` + // ↓ `huge-af` is the variable name in the namespace + text: ['huge-af'], + }, + }, +}) +``` ### Extending the tailwind-merge config @@ -175,7 +186,7 @@ If you only need to slightly modify the default tailwind-merge config, [`extendT ```ts import { extendTailwindMerge } from 'tailwind-merge' -const customTwMerge = extendTailwindMerge<'foo' | 'bar' | 'baz'>({ +const twMerge = extendTailwindMerge<'foo' | 'bar' | 'baz'>({ // ↓ Override elements from the default config // It has the same shape as the `extend` object, so we're going to skip it here. override: {}, @@ -263,7 +274,7 @@ The function takes a callback which returns the config you want to use and retur ```ts import { createTailwindMerge } from 'tailwind-merge' -const customTwMerge = createTailwindMerge(() => ({ +const twMerge = createTailwindMerge(() => ({ cacheSize: 500, theme: {}, classGroups: { @@ -283,7 +294,7 @@ const customTwMerge = createTailwindMerge(() => ({ > [!Note] > The function `createTailwindMerge` computes a large data structure based on the config passed to it. I recommend to call it only once and store the result in a top-level variable instead of calling it inline within another repeatedly called function. -The callback passed to `createTailwindMerge` will be called when `customTwMerge` is called the first time, so you don't need to worry about the computations in it affecting app startup performance in case you aren't using tailwind-merge at app startup. +The callback passed to `createTailwindMerge` will be called when `twMerge` is called the first time, so you don't need to worry about the computations in it affecting app startup performance in case you aren't using tailwind-merge at app startup. ### Using tailwind-merge plugins diff --git a/docs/recipes.md b/docs/recipes.md index 6478b1ac..ca3888f1 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -13,7 +13,9 @@ First, we need to know whether we want to override or extend the default scale. Then we check whether our particular theme scale is included in tailwind-merge's theme config object [here](./configuration.md#theme). In the hypothetical case that tailwind-merge supported Tailwind's `boxShadow` theme scale, we could add it to the tailwind-merge config like this: ```js -const customTwMerge = extendTailwindMerge({ +import { extendTailwindMerge } from 'tailwind-merge' + +const twMerge = extendTailwindMerge({ extend: { theme: { // The `boxShadow` key isn't actually supported @@ -26,7 +28,9 @@ const customTwMerge = extendTailwindMerge({ In the case of the `boxShadow` scale, tailwind-merge doesn't include it in the theme object. Instead, we need to check out the [default config of tailwind-merge](../src/lib/default-config.ts) and search for the class group ID of the box shadow scale. After a quick search we find that tailwind-merge is using the key `shadow` for that group. We can add our custom classes to that group like this: ```js -const customTwMerge = extendTailwindMerge({ +import { extendTailwindMerge } from 'tailwind-merge' + +const twMerge = extendTailwindMerge({ extend: { classGroups: { shadow: [{ shadow: ['100', '200', '300'] }], @@ -56,6 +60,8 @@ Instead of creating custom CSS classes, I recommend keeping the collection of Ta ```jsx // React components with JSX syntax used in this example +import { twMerge } from 'tailwind-merge' + const BTN_PRIMARY_CLASSNAMES = 'py-2 px-4 bg-blue-500 text-white rounded-lg hover:bg-blue-700' function ButtonPrimary(props) { @@ -70,9 +76,11 @@ function ButtonPrimary(props) { You can wrap `twMerge` in another function which can modify the inputs and/or output. ```js -function customTwMerge(...inputs) { +import { twMerge as twMergeOriginal } from 'tailwind-merge' + +function twMerge(...inputs) { const modifiedInputs = modifyInputs(inputs) - return twMerge(modifiedInputs) + return twMergeOriginal(modifiedInputs) } ``` From 9b63e89f5372456d4472d7b1cdea0210d2ccd8c7 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Tue, 28 Jan 2025 20:23:47 +0100 Subject: [PATCH 27/48] update documentation to new validators and theme scale --- docs/api-reference.md | 54 +++++++++++++++++++++++++++---------------- docs/configuration.md | 1 - 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index d7d5f1bd..6cbaf235 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -131,7 +131,6 @@ const twMerge = extendTailwindMerge ```ts interface Validators { - isLength(value: string): boolean + isAny(value: string): boolean + isAnyNonArbitrary(value: string): boolean + isArbitraryImage(value: string): boolean isArbitraryLength(value: string): boolean - isNumber(value: string): boolean + isArbitraryNumber(value: string): boolean + isArbitraryPosition(value: string): boolean + isArbitraryShadow(value: string): boolean + isArbitrarySize(value: string): boolean + isArbitraryValue(value: string): boolean + isArbitraryVariable(value: string): boolean + isArbitraryVariableFamilyName(value: string): boolean + isArbitraryVariableImage(value: string): boolean + isArbitraryVariableLength(value: string): boolean + isArbitraryVariablePosition(value: string): boolean + isArbitraryVariableShadow(value: string): boolean + isArbitraryVariableSize(value: string): boolean + isFraction(value: string): boolean isInteger(value: string): boolean + isNumber(value: string): boolean isPercent(value: string): boolean - isArbitraryValue(value: string): boolean isTshirtSize(value: string): boolean - isArbitrarySize(value: string): boolean - isArbitraryPosition(value: string): boolean - isArbitraryImage(value: string): boolean - isArbitraryNumber(value: string): boolean - isArbitraryShadow(value: string): boolean - isAny(value: string): boolean } ``` An object containing all the validators used in tailwind-merge. They are useful if you want to use a custom config with [`extendTailwindMerge`](#extendtailwindmerge) or [`createTailwindMerge`](#createtailwindmerge). E.g. the `classGroup` for padding is defined as ```ts -const paddingClassGroup = [{ p: [validators.isLength] }] +const paddingClassGroup = [{ p: [validators.isNumber] }] ``` A brief summary for each validator: -- `isLength` checks whether a class part is a number (`3`, `1.5`), a fraction (`3/4`), or one of the strings `px`, `full` or `screen`. +- `isAny` always returns true. Be careful with this validator as it might match unwanted classes. I use it primarily to match colors or when I'm certain there are no other class groups in a namespace. +- `isAnyNonArbitrary` checks if the class part is not an arbitrary value or arbitrary variable. +- `isArbitraryImage` checks whether class part is an arbitrary value which is an iamge, e.g. by starting with `image:`, `url:`, `linear-gradient(` or `url(` (`[url('/path-to-image.png')]`, `image:var(--maybe-an-image-at-runtime)]`) which is necessary for background-image classNames. - `isArbitraryLength` checks for arbitrary length values (`[3%]`, `[4px]`, `[length:var(--my-var)]`). -- `isNumber` checks for numbers (`3`, `1.5`) - `isArbitraryNumber` checks whether class part is an arbitrary value which starts with `number:` or is a number (`[number:var(--value)]`, `[450]`) which is necessary for font-weight and stroke-width classNames. +- `isArbitraryPosition` checks whether class part is an arbitrary value which starts with `position:` (`[position:200px_100px]`) which is necessary for background-position classNames. +- `isArbitraryShadow` checks whether class part is an arbitrary value which starts with the same pattern as a shadow value (`[0_35px_60px_-15px_rgba(0,0,0,0.3)]`), namely with two lengths separated by a underscore, optionally prepended by `inset`. +- `isArbitrarySize` checks whether class part is an arbitrary value which starts with `size:` (`[size:200px_100px]`) which is necessary for background-size classNames. +- `isArbitraryValue` checks whether the class part is enclosed in brackets (`[something]`) +- `isArbitraryVariable` checks whether the class part is an arbitrary variable (`(--my-var)`) +- `isArbitraryVariableFamilyName` checks whether class part is an arbitrary variable with the `family-name` label (`(family-name:--my-font)`) +- `isArbitraryVariableImage` checks whether class part is an arbitrary variable with the `image` or `url` label (`(image:--my-image)`) +- `isArbitraryVariableLength` checks whether class part is an arbitrary variable with the `length` label (`(length:--my-length)`) +- `isArbitraryVariablePosition` checks whether class part is an arbitrary variable with the `position` label (`(position:--my-position)`) +- `isArbitraryVariableShadow` checks whether class part is an arbitrary variable with the `shadow` label or not label at all (`(shadow:--my-shadow)`, `(--my-shadow)`) +- `isArbitraryVariableSize` checks whether class part is an arbitrary variable with the `size`, `length` or `percentage` label (`(size:--my-size)`) +- `isFraction` checks whether class part is a fraction of two numbers (`1/2`, `127/256`) - `isInteger` checks for integer values (`3`). +- `isNumber` checks for numbers (`3`, `1.5`) - `isPercent` checks for percent values (`12.5%`) which is used for color stop positions. -- `isArbitraryValue` checks whether the class part is enclosed in brackets (`[something]`) - `isTshirtSize`checks whether class part is a T-shirt size (`sm`, `xl`), optionally with a preceding number (`2xl`). -- `isArbitrarySize` checks whether class part is an arbitrary value which starts with `size:` (`[size:200px_100px]`) which is necessary for background-size classNames. -- `isArbitraryPosition` checks whether class part is an arbitrary value which starts with `position:` (`[position:200px_100px]`) which is necessary for background-position classNames. -- `isArbitraryImage` checks whether class part is an arbitrary value which is an iamge, e.g. by starting with `image:`, `url:`, `linear-gradient(` or `url(` (`[url('/path-to-image.png')]`, `image:var(--maybe-an-image-at-runtime)]`) which is necessary for background-image classNames. -- `isArbitraryShadow` checks whether class part is an arbitrary value which starts with the same pattern as a shadow value (`[0_35px_60px_-15px_rgba(0,0,0,0.3)]`), namely with two lengths separated by a underscore, optionally prepended by `inset`. -- `isAny` always returns true. Be careful with this validator as it might match unwanted classes. I use it primarily to match colors or when I'm certain there are no other class groups in a namespace. ## `Config` diff --git a/docs/configuration.md b/docs/configuration.md index c386fd37..f3b559dd 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -44,7 +44,6 @@ const tailwindMergeConfig = { separator: '_', theme: { // Theme scales are defined here - // This is not the theme object from your Tailwind config }, classGroups: { // Class groups are defined here From 4072d8ab6953ddf07f6065969f0520a581bada1e Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 13:07:34 +0100 Subject: [PATCH 28/48] adjust default config based on https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 --- src/lib/default-config.ts | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 4f8ae8e6..326f7d56 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -103,7 +103,8 @@ export const getDefaultConfig = () => { const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch'] as const const scaleUnambiguousSpacing = () => [isArbitraryVariable, isArbitraryValue, themeSpacing] as const - const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()] as const + const scalePadding = () => ['px', ...scaleUnambiguousSpacing()] + const scaleMargin = () => ['px', 'auto', ...scaleUnambiguousSpacing()] as const const scaleSizing = () => [ isFraction, @@ -610,47 +611,47 @@ export const getDefaultConfig = () => { * Padding * @see https://tailwindcss.com/docs/padding */ - p: [{ p: scaleUnambiguousSpacing() }], + p: [{ p: scalePadding() }], /** * Padding X * @see https://tailwindcss.com/docs/padding */ - px: [{ px: scaleUnambiguousSpacing() }], + px: [{ px: scalePadding() }], /** * Padding Y * @see https://tailwindcss.com/docs/padding */ - py: [{ py: scaleUnambiguousSpacing() }], + py: [{ py: scalePadding() }], /** * Padding Start * @see https://tailwindcss.com/docs/padding */ - ps: [{ ps: scaleUnambiguousSpacing() }], + ps: [{ ps: scalePadding() }], /** * Padding End * @see https://tailwindcss.com/docs/padding */ - pe: [{ pe: scaleUnambiguousSpacing() }], + pe: [{ pe: scalePadding() }], /** * Padding Top * @see https://tailwindcss.com/docs/padding */ - pt: [{ pt: scaleUnambiguousSpacing() }], + pt: [{ pt: scalePadding() }], /** * Padding Right * @see https://tailwindcss.com/docs/padding */ - pr: [{ pr: scaleUnambiguousSpacing() }], + pr: [{ pr: scalePadding() }], /** * Padding Bottom * @see https://tailwindcss.com/docs/padding */ - pb: [{ pb: scaleUnambiguousSpacing() }], + pb: [{ pb: scalePadding() }], /** * Padding Left * @see https://tailwindcss.com/docs/padding */ - pl: [{ pl: scaleUnambiguousSpacing() }], + pl: [{ pl: scalePadding() }], /** * Margin * @see https://tailwindcss.com/docs/margin @@ -735,7 +736,17 @@ export const getDefaultConfig = () => { * Min-Width * @see https://tailwindcss.com/docs/min-width */ - 'min-w': [{ 'min-w': [themeContainer, 'screen', 'none', ...scaleSizing()] }], + 'min-w': [ + { + 'min-w': [ + themeContainer, + 'screen', + /** Deprecated. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */ + 'none', + ...scaleSizing(), + ], + }, + ], /** * Max-Width * @see https://tailwindcss.com/docs/max-width @@ -746,7 +757,9 @@ export const getDefaultConfig = () => { themeContainer, 'screen', 'none', + /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */ 'prose', + /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */ { screen: [themeBreakpoint] }, ...scaleSizing(), ], @@ -867,7 +880,15 @@ export const getDefaultConfig = () => { * @see https://tailwindcss.com/docs/line-height */ leading: [ - { leading: [isArbitraryVariable, isArbitraryValue, themeLeading, themeSpacing] }, + { + leading: [ + isArbitraryVariable, + isArbitraryValue, + /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */ + themeLeading, + themeSpacing, + ], + }, ], /** * List Style Image From 3fe7d3e3ecaae6f8c182df44cdce67cdc272ea61 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:06:56 +0100 Subject: [PATCH 29/48] test: add hardcoded list of position-sensitive modifiers to test perf of that --- src/lib/parse-class-name.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index 2bff1317..547a9d3d 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -94,6 +94,20 @@ export const createParseClassName = (config: AnyConfig) => { return parseClassName } +const positionSensitiveModifiers = new Set([ + 'before', + 'after', + 'placeholder', + 'file', + 'marker', + 'selection', + 'first-line', + 'first-letter', + 'backdrop', + '*', + '**', +]) + /** * Sorts modifiers according to following schema: * - Predefined modifiers are sorted alphabetically @@ -108,9 +122,9 @@ export const sortModifiers = (modifiers: string[]) => { let unsortedModifiers: string[] = [] modifiers.forEach((modifier) => { - const isArbitraryVariant = modifier[0] === '[' + const isPositionSensitive = modifier[0] === '[' || positionSensitiveModifiers.has(modifier) - if (isArbitraryVariant) { + if (isPositionSensitive) { sortedModifiers.push(...unsortedModifiers.sort(), modifier) unsortedModifiers = [] } else { From 5a0a7374860e6bf2c4a5de434bcf5c3d11a657d2 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:09:36 +0100 Subject: [PATCH 30/48] change `positionSensitiveModifiers` to array --- src/lib/parse-class-name.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index 547a9d3d..37783118 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -94,7 +94,7 @@ export const createParseClassName = (config: AnyConfig) => { return parseClassName } -const positionSensitiveModifiers = new Set([ +const positionSensitiveModifiers = [ 'before', 'after', 'placeholder', @@ -106,7 +106,7 @@ const positionSensitiveModifiers = new Set([ 'backdrop', '*', '**', -]) +] /** * Sorts modifiers according to following schema: @@ -122,7 +122,8 @@ export const sortModifiers = (modifiers: string[]) => { let unsortedModifiers: string[] = [] modifiers.forEach((modifier) => { - const isPositionSensitive = modifier[0] === '[' || positionSensitiveModifiers.has(modifier) + const isPositionSensitive = + modifier[0] === '[' || positionSensitiveModifiers.includes(modifier) if (isPositionSensitive) { sortedModifiers.push(...unsortedModifiers.sort(), modifier) From 16de04e30a4a8fa5e1922ed6bf2cf618c078ca50 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:13:10 +0100 Subject: [PATCH 31/48] change to object --- src/lib/parse-class-name.ts | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index 37783118..5a069ffe 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -94,19 +94,19 @@ export const createParseClassName = (config: AnyConfig) => { return parseClassName } -const positionSensitiveModifiers = [ - 'before', - 'after', - 'placeholder', - 'file', - 'marker', - 'selection', - 'first-line', - 'first-letter', - 'backdrop', - '*', - '**', -] +const positionSensitiveModifiers: Record = { + before: true, + after: true, + placeholder: true, + file: true, + marker: true, + selection: true, + 'first-line': true, + 'first-letter': true, + backdrop: true, + '*': true, + '**': true, +} /** * Sorts modifiers according to following schema: @@ -122,8 +122,7 @@ export const sortModifiers = (modifiers: string[]) => { let unsortedModifiers: string[] = [] modifiers.forEach((modifier) => { - const isPositionSensitive = - modifier[0] === '[' || positionSensitiveModifiers.includes(modifier) + const isPositionSensitive = modifier[0] === '[' || positionSensitiveModifiers[modifier] if (isPositionSensitive) { sortedModifiers.push(...unsortedModifiers.sort(), modifier) From 6ed3bedebdfaf1916806bc899383a01283968d71 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:25:56 +0100 Subject: [PATCH 32/48] remove modifier sorting to check perf --- src/lib/merge-classlist.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/merge-classlist.ts b/src/lib/merge-classlist.ts index b53e14ff..ce701d7c 100644 --- a/src/lib/merge-classlist.ts +++ b/src/lib/merge-classlist.ts @@ -1,5 +1,5 @@ import { ConfigUtils } from './config-utils' -import { IMPORTANT_MODIFIER, sortModifiers } from './parse-class-name' +import { IMPORTANT_MODIFIER } from './parse-class-name' const SPLIT_CLASSES_REGEX = /\s+/ @@ -59,7 +59,8 @@ export const mergeClassList = (classList: string, configUtils: ConfigUtils) => { hasPostfixModifier = false } - const variantModifier = sortModifiers(modifiers).join(':') + // TODO: Add back sorting modifiers. Just disabled temporarily. + const variantModifier = modifiers.join(':') const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER From 74b8951cf37dd037033577f402cd3632cba8a1bb Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:54:47 +0100 Subject: [PATCH 33/48] add configurable orderSensitiveModifiers to tailwind-merge --- src/lib/config-utils.ts | 2 ++ src/lib/default-config.ts | 13 ++++++++++ src/lib/merge-classlist.ts | 6 ++--- src/lib/merge-configs.ts | 48 +++++++++++++++++++++++-------------- src/lib/parse-class-name.ts | 43 --------------------------------- src/lib/sort-modifiers.ts | 38 +++++++++++++++++++++++++++++ src/lib/types.ts | 12 +++++++++- tests/merge-configs.test.ts | 4 ++++ 8 files changed, 101 insertions(+), 65 deletions(-) create mode 100644 src/lib/sort-modifiers.ts diff --git a/src/lib/config-utils.ts b/src/lib/config-utils.ts index a31c0923..a5eb08ed 100644 --- a/src/lib/config-utils.ts +++ b/src/lib/config-utils.ts @@ -1,6 +1,7 @@ import { createClassGroupUtils } from './class-group-utils' import { createLruCache } from './lru-cache' import { createParseClassName } from './parse-class-name' +import { createSortModifiers } from './sort-modifiers' import { AnyConfig } from './types' export type ConfigUtils = ReturnType @@ -8,5 +9,6 @@ export type ConfigUtils = ReturnType export const createConfigUtils = (config: AnyConfig) => ({ cache: createLruCache(config.cacheSize), parseClassName: createParseClassName(config), + sortModifiers: createSortModifiers(config), ...createClassGroupUtils(config), }) diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index 326f7d56..fced1b6d 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -2203,5 +2203,18 @@ export const getDefaultConfig = () => { conflictingClassGroupModifiers: { 'font-size': ['leading'], }, + orderSensitiveModifiers: [ + 'before', + 'after', + 'placeholder', + 'file', + 'marker', + 'selection', + 'first-line', + 'first-letter', + 'backdrop', + '*', + '**', + ], } as const satisfies Config } diff --git a/src/lib/merge-classlist.ts b/src/lib/merge-classlist.ts index ce701d7c..12c94ae5 100644 --- a/src/lib/merge-classlist.ts +++ b/src/lib/merge-classlist.ts @@ -4,7 +4,8 @@ import { IMPORTANT_MODIFIER } from './parse-class-name' const SPLIT_CLASSES_REGEX = /\s+/ export const mergeClassList = (classList: string, configUtils: ConfigUtils) => { - const { parseClassName, getClassGroupId, getConflictingClassGroupIds } = configUtils + const { parseClassName, getClassGroupId, getConflictingClassGroupIds, sortModifiers } = + configUtils /** * Set of classGroupIds in following format: @@ -59,8 +60,7 @@ export const mergeClassList = (classList: string, configUtils: ConfigUtils) => { hasPostfixModifier = false } - // TODO: Add back sorting modifiers. Just disabled temporarily. - const variantModifier = modifiers.join(':') + const variantModifier = sortModifiers(modifiers).join(':') const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER diff --git a/src/lib/merge-configs.ts b/src/lib/merge-configs.ts index dd28c889..3b15eea5 100644 --- a/src/lib/merge-configs.ts +++ b/src/lib/merge-configs.ts @@ -1,4 +1,4 @@ -import { AnyConfig, ConfigExtension } from './types' +import { AnyConfig, ConfigExtension, NoInfer } from './types' /** * @param baseConfig Config where other config will be merged into. This object will be mutated. @@ -20,19 +20,23 @@ export const mergeConfigs = { if (mergeObject) { for (const key in mergeObject) { - const mergeValue = mergeObject[key] - - if (mergeValue !== undefined) { - baseObject[key] = (baseObject[key] || []).concat(mergeValue) - } + mergeArrayProperties(baseObject, mergeObject, key) } } } + +const mergeArrayProperties = ( + baseObject: Partial, readonly unknown[]>>, + mergeObject: Partial, readonly unknown[]>>, + key: Key, +) => { + const mergeValue = mergeObject[key] + + if (mergeValue !== undefined) { + baseObject[key] = baseObject[key] ? baseObject[key].concat(mergeValue) : mergeValue + } +} diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index 5a069ffe..3b41c316 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -94,49 +94,6 @@ export const createParseClassName = (config: AnyConfig) => { return parseClassName } -const positionSensitiveModifiers: Record = { - before: true, - after: true, - placeholder: true, - file: true, - marker: true, - selection: true, - 'first-line': true, - 'first-letter': true, - backdrop: true, - '*': true, - '**': true, -} - -/** - * Sorts modifiers according to following schema: - * - Predefined modifiers are sorted alphabetically - * - When an arbitrary variant appears, it must be preserved which modifiers are before and after it - */ -export const sortModifiers = (modifiers: string[]) => { - if (modifiers.length <= 1) { - return modifiers - } - - const sortedModifiers: string[] = [] - let unsortedModifiers: string[] = [] - - modifiers.forEach((modifier) => { - const isPositionSensitive = modifier[0] === '[' || positionSensitiveModifiers[modifier] - - if (isPositionSensitive) { - sortedModifiers.push(...unsortedModifiers.sort(), modifier) - unsortedModifiers = [] - } else { - unsortedModifiers.push(modifier) - } - }) - - sortedModifiers.push(...unsortedModifiers.sort()) - - return sortedModifiers -} - const stripImportantModifier = (baseClassName: string) => { if (baseClassName.endsWith(IMPORTANT_MODIFIER)) { return baseClassName.substring(0, baseClassName.length - 1) diff --git a/src/lib/sort-modifiers.ts b/src/lib/sort-modifiers.ts new file mode 100644 index 00000000..dd34b631 --- /dev/null +++ b/src/lib/sort-modifiers.ts @@ -0,0 +1,38 @@ +import { AnyConfig } from './types' + +/** + * Sorts modifiers according to following schema: + * - Predefined modifiers are sorted alphabetically + * - When an arbitrary variant appears, it must be preserved which modifiers are before and after it + */ +export const createSortModifiers = (config: AnyConfig) => { + const orderSensitiveModifiers = Object.fromEntries( + config.orderSensitiveModifiers.map((modifier) => [modifier, true]), + ) + + const sortModifiers = (modifiers: string[]) => { + if (modifiers.length <= 1) { + return modifiers + } + + const sortedModifiers: string[] = [] + let unsortedModifiers: string[] = [] + + modifiers.forEach((modifier) => { + const isPositionSensitive = modifier[0] === '[' || orderSensitiveModifiers[modifier] + + if (isPositionSensitive) { + sortedModifiers.push(...unsortedModifiers.sort(), modifier) + unsortedModifiers = [] + } else { + unsortedModifiers.push(modifier) + } + }) + + sortedModifiers.push(...unsortedModifiers.sort()) + + return sortedModifiers + } + + return sortModifiers +} diff --git a/src/lib/types.ts b/src/lib/types.ts index a1f9450e..6e09f59f 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -93,11 +93,13 @@ export interface ParsedClassName { interface ConfigGroupsPart { /** * Theme scales used in classGroups. + * * The keys are the same as in the Tailwind config but the values are sometimes defined more broadly. */ theme: NoInfer> /** * Object with groups of classes. + * * @example * { * // Creates group of classes `group`, `of` and `classes` @@ -109,6 +111,7 @@ interface ConfigGroupsPart>> /** * Conflicting classes across groups. + * * The key is ID of class group which creates conflict, values are IDs of class groups which receive a conflict. * A class group ID is the key of a class group in classGroups object. * @example { gap: ['gap-x', 'gap-y'] } @@ -116,12 +119,19 @@ interface ConfigGroupsPart>> /** * Postfix modifiers conflicting with other class groups. + * * A class group ID is the key of a class group in classGroups object. * @example { 'font-size': ['leading'] } */ conflictingClassGroupModifiers: NoInfer< Partial> > + /** + * Modifiers whose order among multiple modifiers should be preserved because their order changes which element gets targeted. + * + * tailwind-merge makes sure that classes with these modifiers are not overwritten by classes with the same modifiers with order-sensitive modifiers being in a different position. + */ + orderSensitiveModifiers: string[] } /** @@ -134,7 +144,7 @@ export interface ConfigExtension = { - [P in keyof T]?: Partial + [P in keyof T]?: T[P] extends any[] ? T[P] : Partial } export type ThemeObject = Record< diff --git a/tests/merge-configs.test.ts b/tests/merge-configs.test.ts index 7024a6c1..724ea6d6 100644 --- a/tests/merge-configs.test.ts +++ b/tests/merge-configs.test.ts @@ -26,6 +26,7 @@ test('mergeConfigs has correct behavior', () => { hello: ['world'], toOverride: ['groupToOverride-2'], }, + orderSensitiveModifiers: ['order-1'], }, { separator: '-', @@ -44,6 +45,7 @@ test('mergeConfigs has correct behavior', () => { conflictingClassGroupModifiers: { toOverride: ['overridden-2'], }, + orderSensitiveModifiers: ['order-2'], }, extend: { classGroups: { @@ -59,6 +61,7 @@ test('mergeConfigs has correct behavior', () => { conflictingClassGroupModifiers: { hello: ['world2'], }, + orderSensitiveModifiers: ['order-3'], }, }, ), @@ -87,5 +90,6 @@ test('mergeConfigs has correct behavior', () => { hello: ['world', 'world2'], toOverride: ['overridden-2'], }, + orderSensitiveModifiers: ['order-2', 'order-3'], }) }) From 0ce3055b0bf1ed7f2f5ddb7abdef627d08c514b2 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:11:48 +0100 Subject: [PATCH 34/48] fix tests and add test for modifiers order --- tests/create-tailwind-merge.test.ts | 2 ++ tests/modifiers.test.ts | 20 ++++++++++++++++++++ tests/public-api.test.ts | 3 +++ 3 files changed, 25 insertions(+) diff --git a/tests/create-tailwind-merge.test.ts b/tests/create-tailwind-merge.test.ts index 613d6f8c..7c60844e 100644 --- a/tests/create-tailwind-merge.test.ts +++ b/tests/create-tailwind-merge.test.ts @@ -17,6 +17,7 @@ test('createTailwindMerge works with single config function', () => { otherKey: ['fooKey', 'fooKey2'], }, conflictingClassGroupModifiers: {}, + orderSensitiveModifiers: [], })) expect(tailwindMerge('')).toBe('') @@ -58,6 +59,7 @@ test('createTailwindMerge works with multiple config functions', () => { otherKey: ['fooKey', 'fooKey2'], }, conflictingClassGroupModifiers: {}, + orderSensitiveModifiers: [], }), (config) => ({ ...config, diff --git a/tests/modifiers.test.ts b/tests/modifiers.test.ts index df948ba2..15f8624f 100644 --- a/tests/modifiers.test.ts +++ b/tests/modifiers.test.ts @@ -30,6 +30,7 @@ test('conflicts across postfix modifiers', () => { conflictingClassGroupModifiers: { baz: ['bar'], }, + orderSensitiveModifiers: [], })) expect(customTwMerge('foo-1/2 foo-2/3')).toBe('foo-2/3') @@ -39,3 +40,22 @@ test('conflicts across postfix modifiers', () => { expect(customTwMerge('bar-2 bar-1/2')).toBe('bar-1/2') expect(customTwMerge('bar-1 baz-1/2')).toBe('baz-1/2') }) + +test('sorts modifiers correctly', () => { + const customTwMerge = createTailwindMerge(() => ({ + cacheSize: 10, + separator: ':', + theme: {}, + classGroups: { + foo: ['foo-1', 'foo-2'], + }, + conflictingClassGroups: {}, + conflictingClassGroupModifiers: {}, + orderSensitiveModifiers: ['a', 'b'], + })) + + expect(customTwMerge('c:d:e:foo-1 d:c:e:foo-2')).toBe('d:c:e:foo-2') + expect(customTwMerge('a:b:foo-1 a:b:foo-2')).toBe('a:b:foo-2') + expect(customTwMerge('a:b:foo-1 b:a:foo-2')).toBe('a:b:foo-1 b:a:foo-2') + expect(customTwMerge('x:y:a:z:foo-1 y:x:a:z:foo-2')).toBe('y:x:a:z:foo-2') +}) diff --git a/tests/public-api.test.ts b/tests/public-api.test.ts index 916b3682..db032c46 100644 --- a/tests/public-api.test.ts +++ b/tests/public-api.test.ts @@ -106,6 +106,7 @@ test('createTailwindMerge() has correct inputs and outputs', () => { classGroups: {}, conflictingClassGroups: {}, conflictingClassGroupModifiers: {}, + orderSensitiveModifiers: [], })), ).toStrictEqual(expect.any(Function)) @@ -123,6 +124,7 @@ test('createTailwindMerge() has correct inputs and outputs', () => { otherKey: ['fooKey', 'fooKey2'], }, conflictingClassGroupModifiers: {}, + orderSensitiveModifiers: [], })) expect(tailwindMerge).toStrictEqual(expect.any(Function)) @@ -186,6 +188,7 @@ test('mergeConfigs has correct inputs and outputs', () => { }, conflictingClassGroups: {}, conflictingClassGroupModifiers: {}, + orderSensitiveModifiers: [], }, {}, ), From 8e32663f61c87d6359d72d9dc847c115aacdea78 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:17:07 +0100 Subject: [PATCH 35/48] add test for modifiers order of twMerge --- tests/modifiers.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/modifiers.test.ts b/tests/modifiers.test.ts index 15f8624f..93e16b87 100644 --- a/tests/modifiers.test.ts +++ b/tests/modifiers.test.ts @@ -42,6 +42,13 @@ test('conflicts across postfix modifiers', () => { }) test('sorts modifiers correctly', () => { + expect(twMerge('c:d:e:block d:c:e:inline')).toBe('d:c:e:inline') + expect(twMerge('*:before:block *:before:inline')).toBe('*:before:inline') + expect(twMerge('*:before:block before:*:inline')).toBe('*:before:block before:*:inline') + expect(twMerge('x:y:*:z:block y:x:*:z:inline')).toBe('y:x:*:z:inline') +}) + +test('sorts modifiers correctly according to orderSensitiveModifiers', () => { const customTwMerge = createTailwindMerge(() => ({ cacheSize: 10, separator: ':', From e7f9b599374fa744cf0370496d2157e6c485df91 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 20:32:52 +0100 Subject: [PATCH 36/48] add `orderSensitiveModifiers` and Tailwind CSS v4 features to docs --- docs/api-reference.md | 7 +++++++ docs/configuration.md | 17 +++++++++++++++++ docs/features.md | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 6cbaf235..0dc147f8 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -155,6 +155,9 @@ const twMerge = extendTailwindMerge { ...defaultConfig.conflictingClassGroupModifiers, baz: ['bar'], }, + orderSensitiveModifiers: [...defaultConfig.orderSensitiveModifiers, 'before'], } }) ``` diff --git a/docs/configuration.md b/docs/configuration.md index f3b559dd..eaa8267b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -54,6 +54,10 @@ const tailwindMergeConfig = { conflictingClassGroupModifiers: { // Conflicts between postfix modifier of a class group and another class group are defined here }, + orderSensitiveModifiers: [ + // Modifiers whose order among multiple modifiers should be preserved because their order + // changes which element gets targeted. + ], } ``` @@ -135,6 +139,16 @@ const conflictingClassGroupModifiers = { } ``` +### Order-sensitive modifiers + +In Tailwind CSS, not all modifiers behave the same when you stack them. + +In most cases the order of modifiers doesn't matter. E.g. `hover:focus:bg-red-500` and `focus:hover:bg-red-500` behave the same and in the context of tailwind-merge, you'd want them both to override each other. tailwind-merge sorts the modifiers internally to be able to override classes with the same modifiers, even if they are in a different order. + +However, there are some modifiers where the order matters, e.g. the direct children modifier `*`. The class `*:hover:text-red-500` modifies the text color of a child if that child is hovered, but the class `hover:*:text-red-500` modifies the text color of all direct children if the parent is hovered. In this case, you would want tailwind-merge to preserve both classes although they have the same modifiers, just in a different order. + +To know which modifiers are order-sensitive, tailwind-merge has the `orderSensitiveModifiers` property in its config. `twMerge` is pre-configured with all the order-sensitive modifiers that Tailwind CSS has by default. You'll only need to configure this property if you add your own order-sensitive modifiers or change the meaning of the default order-sensitive modifiers. + ### Theme In the Tailwind config you can modify your theme variable namespace to add classes with custom values. tailwind-merge follows the same naming scheme as Tailwind CSS for its theme scales: @@ -209,6 +223,8 @@ const twMerge = extendTailwindMerge<'foo' | 'bar' | 'baz'>({ conflictingClassGroupModifiers: { baz: ['bar'], }, + // ↓ Define order-sensitive modifiers + orderSensitiveModifiers: ['my-order-sensitive-modifier'], }, }) ``` @@ -287,6 +303,7 @@ const twMerge = createTailwindMerge(() => ({ conflictingClassGroupModifiers: { baz: ['bar'], }, + orderSensitiveModifiers: [], })) ``` diff --git a/docs/features.md b/docs/features.md index 09050c5f..41be44be 100644 --- a/docs/features.md +++ b/docs/features.md @@ -38,7 +38,8 @@ The order of standard modifiers does not matter for tailwind-merge. ### Supports arbitrary values ```ts -twMerge('bg-black bg-[color:var(--mystery-var)]') // → 'bg-[color:var(--mystery-var)]' +twMerge('bg-black bg-(--my-color) bg-[color:var(--mystery-var)]') +// → 'bg-[color:var(--mystery-var)]' twMerge('grid-cols-[1fr,auto] grid-cols-2') // → 'grid-cols-2' ``` From 360a05828b47cd2e8d6d4f928125b807fd62a224 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 20:35:05 +0100 Subject: [PATCH 37/48] formatting update in changelogs --- docs/changelog/v0-changelog.md | 102 ++++++------- docs/changelog/v0-to-v1-migration.md | 20 +-- docs/changelog/v1-changelog.md | 208 +++++++++++++-------------- docs/changelog/v1-to-v2-migration.md | 50 +++---- 4 files changed, 190 insertions(+), 190 deletions(-) diff --git a/docs/changelog/v0-changelog.md b/docs/changelog/v0-changelog.md index bdbb3f99..4b30f362 100644 --- a/docs/changelog/v0-changelog.md +++ b/docs/changelog/v0-changelog.md @@ -4,8 +4,8 @@ ### New Features -- Mimic theme from Tailwind config in tailwind-merge config by [@dcastil](https://github.com/dcastil) in [#55](https://github.com/dcastil/tailwind-merge/pull/55) - - Adds support for some theme properties like `spacing`, `borderRadius`, etc. More on that in the [theme docs](https://github.com/dcastil/tailwind-merge/tree/v0.9.0#theme). +- Mimic theme from Tailwind config in tailwind-merge config by [@dcastil](https://github.com/dcastil) in [#55](https://github.com/dcastil/tailwind-merge/pull/55) + - Adds support for some theme properties like `spacing`, `borderRadius`, etc. More on that in the [theme docs](https://github.com/dcastil/tailwind-merge/tree/v0.9.0#theme). **Full Changelog**: [`v0.8.2...v0.9.0`](https://github.com/dcastil/tailwind-merge/compare/v0.8.2...v0.9.0) @@ -13,7 +13,7 @@ ### Bug Fixes -- Fix custom values for list-style-type missing in default config by [@dcastil](https://github.com/dcastil) in [#53](https://github.com/dcastil/tailwind-merge/pull/53) +- Fix custom values for list-style-type missing in default config by [@dcastil](https://github.com/dcastil) in [#53](https://github.com/dcastil/tailwind-merge/pull/53) **Full Changelog**: [`v0.8.1...v0.8.2`](https://github.com/dcastil/tailwind-merge/compare/v0.8.1...v0.8.2) @@ -21,8 +21,8 @@ ### Bug Fixes -- Fix missing support for custom values in some class groups in default config by [@dcastil](https://github.com/dcastil) in [#52](https://github.com/dcastil/tailwind-merge/pull/52) - - Adds missing support for custom values in following class groups: Grid Auto Columns, Grid Auto Rows, Max-Width, Transition Property, Transition Timing Function, Animation, Fill, Stroke +- Fix missing support for custom values in some class groups in default config by [@dcastil](https://github.com/dcastil) in [#52](https://github.com/dcastil/tailwind-merge/pull/52) + - Adds missing support for custom values in following class groups: Grid Auto Columns, Grid Auto Rows, Max-Width, Transition Property, Transition Timing Function, Animation, Fill, Stroke **Full Changelog**: [`v0.8.0...v0.8.1`](https://github.com/dcastil/tailwind-merge/compare/v0.8.0...v0.8.1) @@ -34,26 +34,26 @@ This is a big release with breaking changes. These were necessary to improve the ### Breaking Changes -- Previously there was a list of prefixes in the tailwind-merge config which was used to match Tailwind prefixes. I removed those and match all prefixes as valid Tailwind prefixes. This is only a breaking change if you use non-Tailwind classes with `:` in them which look like Tailwind classes after the prefix. tailwind-merge will treat those as Tailwind classes and resolve conflicts incorrectly. [#50](https://github.com/dcastil/tailwind-merge/pull/50)) -- `createTailwindMerge` - - If you added custom prefixes to your tailwind-merge config, you can remove them now. If you use TypeScript, you need to remove them. ([#50](https://github.com/dcastil/tailwind-merge/pull/50)) - - Doesn't get passed the `getDefaultConfig` callback anymore. You need to call the exported function [`getDefaultConfig`](https://github.com/dcastil/tailwind-merge/tree/v0.8.0#getdefaultconfig) instead to get the default config. ([#42](https://github.com/dcastil/tailwind-merge/pull/42)) - - You probably don't need `createTailwindMerge` anyway. Use the new and much simpler to use [`extendTailwindMerge`](https://github.com/dcastil/tailwind-merge/tree/v0.8.0#extendtailwindmerge) instead. ([#49](https://github.com/dcastil/tailwind-merge/pull/49)) +- Previously there was a list of prefixes in the tailwind-merge config which was used to match Tailwind prefixes. I removed those and match all prefixes as valid Tailwind prefixes. This is only a breaking change if you use non-Tailwind classes with `:` in them which look like Tailwind classes after the prefix. tailwind-merge will treat those as Tailwind classes and resolve conflicts incorrectly. [#50](https://github.com/dcastil/tailwind-merge/pull/50)) +- `createTailwindMerge` + - If you added custom prefixes to your tailwind-merge config, you can remove them now. If you use TypeScript, you need to remove them. ([#50](https://github.com/dcastil/tailwind-merge/pull/50)) + - Doesn't get passed the `getDefaultConfig` callback anymore. You need to call the exported function [`getDefaultConfig`](https://github.com/dcastil/tailwind-merge/tree/v0.8.0#getdefaultconfig) instead to get the default config. ([#42](https://github.com/dcastil/tailwind-merge/pull/42)) + - You probably don't need `createTailwindMerge` anyway. Use the new and much simpler to use [`extendTailwindMerge`](https://github.com/dcastil/tailwind-merge/tree/v0.8.0#extendtailwindmerge) instead. ([#49](https://github.com/dcastil/tailwind-merge/pull/49)) ### New Features -- Add plugin documentation by [@dcastil](https://github.com/dcastil) in [#51](https://github.com/dcastil/tailwind-merge/pull/51) -- (Breaking change) Consider all prefixes as valid Tailwind prefixes by [@dcastil](https://github.com/dcastil) in [#50](https://github.com/dcastil/tailwind-merge/pull/50) -- Add `extendTailwindMerge` function by [@dcastil](https://github.com/dcastil) in [#49](https://github.com/dcastil/tailwind-merge/pull/49) -- Add `mergeConfigs` function by [@dcastil](https://github.com/dcastil) in [#45](https://github.com/dcastil/tailwind-merge/pull/45) -- (Breaking change) Code-split default config out by [@dcastil](https://github.com/dcastil) in [#42](https://github.com/dcastil/tailwind-merge/pull/42) -- Enable multiple `createConfig` functions by [@dcastil](https://github.com/dcastil) in [#40](https://github.com/dcastil/tailwind-merge/pull/40) -- Add validators to package exports by [@dcastil](https://github.com/dcastil) in [#38](https://github.com/dcastil/tailwind-merge/pull/38) +- Add plugin documentation by [@dcastil](https://github.com/dcastil) in [#51](https://github.com/dcastil/tailwind-merge/pull/51) +- (Breaking change) Consider all prefixes as valid Tailwind prefixes by [@dcastil](https://github.com/dcastil) in [#50](https://github.com/dcastil/tailwind-merge/pull/50) +- Add `extendTailwindMerge` function by [@dcastil](https://github.com/dcastil) in [#49](https://github.com/dcastil/tailwind-merge/pull/49) +- Add `mergeConfigs` function by [@dcastil](https://github.com/dcastil) in [#45](https://github.com/dcastil/tailwind-merge/pull/45) +- (Breaking change) Code-split default config out by [@dcastil](https://github.com/dcastil) in [#42](https://github.com/dcastil/tailwind-merge/pull/42) +- Enable multiple `createConfig` functions by [@dcastil](https://github.com/dcastil) in [#40](https://github.com/dcastil/tailwind-merge/pull/40) +- Add validators to package exports by [@dcastil](https://github.com/dcastil) in [#38](https://github.com/dcastil/tailwind-merge/pull/38) ### Bug Fixes -- Remove unwated side effects when mutating default config by [@dcastil](https://github.com/dcastil) in [#43](https://github.com/dcastil/tailwind-merge/pull/43) - - Also added the `Config` type to the package exports +- Remove unwated side effects when mutating default config by [@dcastil](https://github.com/dcastil) in [#43](https://github.com/dcastil/tailwind-merge/pull/43) + - Also added the `Config` type to the package exports **Full Changelog**: [`v0.7.1...v0.8.0`](https://github.com/dcastil/tailwind-merge/compare/v0.7.1...v0.8.0) @@ -61,7 +61,7 @@ This is a big release with breaking changes. These were necessary to improve the ### Bug Fixes -- Fix CommonJS imports not working by [@navin-moorthy](https://github.com/navin-moorthy) and [@dcastil](https://github.com/dcastil) in [#31](https://github.com/dcastil/tailwind-merge/pull/31) +- Fix CommonJS imports not working by [@navin-moorthy](https://github.com/navin-moorthy) and [@dcastil](https://github.com/dcastil) in [#31](https://github.com/dcastil/tailwind-merge/pull/31) **Full Changelog**: [`v0.7.0...v0.7.1`](https://github.com/dcastil/tailwind-merge/compare/v0.7.0...v0.7.1) @@ -69,7 +69,7 @@ This is a big release with breaking changes. These were necessary to improve the ### New Features -- Allow passing `false` to `twMerge` by [@dcastil](https://github.com/dcastil) in [#25](https://github.com/dcastil/tailwind-merge/pull/25) +- Allow passing `false` to `twMerge` by [@dcastil](https://github.com/dcastil) in [#25](https://github.com/dcastil/tailwind-merge/pull/25) **Full Changelog**: [`v0.6.0...v0.7.0`](https://github.com/dcastil/tailwind-merge/compare/v0.6.0...v0.7.0) @@ -77,11 +77,11 @@ This is a big release with breaking changes. These were necessary to improve the ### New Features -- Allow passing `null` as argument to `twMerge` by [@dcastil](https://github.com/dcastil) in [#20](https://github.com/dcastil/tailwind-merge/pull/20) +- Allow passing `null` as argument to `twMerge` by [@dcastil](https://github.com/dcastil) in [#20](https://github.com/dcastil/tailwind-merge/pull/20) ### Bug Fixes -- Fix merges with important modifier not working when using prefixed classes by [@dcastil](https://github.com/dcastil) in [#22](https://github.com/dcastil/tailwind-merge/pull/22) +- Fix merges with important modifier not working when using prefixed classes by [@dcastil](https://github.com/dcastil) in [#22](https://github.com/dcastil/tailwind-merge/pull/22) **Full Changelog**: [`v0.5.2...v0.6.0`](https://github.com/dcastil/tailwind-merge/compare/v0.5.2...v0.6.0) @@ -89,8 +89,8 @@ This is a big release with breaking changes. These were necessary to improve the ### Bug Fixes -- Add support for custom classes like `cursor-[grab]` by [@dcastil](https://github.com/dcastil) in [#19](https://github.com/dcastil/tailwind-merge/pull/19) -- Fix incorrect conflicts in Font Variant Numeric classes by [@dcastil](https://github.com/dcastil) in [#18](https://github.com/dcastil/tailwind-merge/pull/18) +- Add support for custom classes like `cursor-[grab]` by [@dcastil](https://github.com/dcastil) in [#19](https://github.com/dcastil/tailwind-merge/pull/19) +- Fix incorrect conflicts in Font Variant Numeric classes by [@dcastil](https://github.com/dcastil) in [#18](https://github.com/dcastil/tailwind-merge/pull/18) **Full Changelog**: [`v0.5.1...v0.5.2`](https://github.com/dcastil/tailwind-merge/compare/v0.5.1...v0.5.2) @@ -98,12 +98,12 @@ This is a big release with breaking changes. These were necessary to improve the ### Bug Fixes -- Fix incorrect conflict between ring and shadow by [@dcastil](https://github.com/dcastil) in [#15](https://github.com/dcastil/tailwind-merge/pull/15) -- Fix not all JIT-enabled pseudo variants working by [@dcastil](https://github.com/dcastil) in [#14](https://github.com/dcastil/tailwind-merge/pull/14) +- Fix incorrect conflict between ring and shadow by [@dcastil](https://github.com/dcastil) in [#15](https://github.com/dcastil/tailwind-merge/pull/15) +- Fix not all JIT-enabled pseudo variants working by [@dcastil](https://github.com/dcastil) in [#14](https://github.com/dcastil/tailwind-merge/pull/14) ### Other -- Add CodeQL security analysis to repo by [@dcastil](https://github.com/dcastil) in [#10](https://github.com/dcastil/tailwind-merge/pull/10) +- Add CodeQL security analysis to repo by [@dcastil](https://github.com/dcastil) in [#10](https://github.com/dcastil/tailwind-merge/pull/10) **Full Changelog**: [`v0.5.0...v0.5.1`](https://github.com/dcastil/tailwind-merge/compare/v0.5.0...v0.5.1) @@ -111,12 +111,12 @@ This is a big release with breaking changes. These were necessary to improve the ### New Features -- Add support for Tailwind CSS v2.2.6 by [@dcastil](https://github.com/dcastil) in [#8](https://github.com/dcastil/tailwind-merge/pull/8) -- Delay `twMerge` initialization until first call by [@dcastil](https://github.com/dcastil) in [#7](https://github.com/dcastil/tailwind-merge/pull/7) +- Add support for Tailwind CSS v2.2.6 by [@dcastil](https://github.com/dcastil) in [#8](https://github.com/dcastil/tailwind-merge/pull/8) +- Delay `twMerge` initialization until first call by [@dcastil](https://github.com/dcastil) in [#7](https://github.com/dcastil/tailwind-merge/pull/7) ### Other -- Make logo in README version-specific by [@dcastil](https://github.com/dcastil) in [#6](https://github.com/dcastil/tailwind-merge/pull/6) +- Make logo in README version-specific by [@dcastil](https://github.com/dcastil) in [#6](https://github.com/dcastil/tailwind-merge/pull/6) **Full Changelog**: [`v0.4.0...v0.5.0`](https://github.com/dcastil/tailwind-merge/compare/v0.4.0...v0.5.0) @@ -124,20 +124,20 @@ This is a big release with breaking changes. These were necessary to improve the ### Breaking Changes -- `createTailwindMerge` - - Config type changed and returned object from `getDefaultConfig` changed. ([#3](https://github.com/dcastil/tailwind-merge/pull/3)) - - `dynamicClasses` and `standaloneClasses` were merged into `classGroups` - - `conflictingGroups` were renamed to `conflictingClassGroups` - - Class group IDs are keys of `classGroups` object instead of full path to class group. E.g. `dynamicClasses.foo.0` → `foo`. +- `createTailwindMerge` + - Config type changed and returned object from `getDefaultConfig` changed. ([#3](https://github.com/dcastil/tailwind-merge/pull/3)) + - `dynamicClasses` and `standaloneClasses` were merged into `classGroups` + - `conflictingGroups` were renamed to `conflictingClassGroups` + - Class group IDs are keys of `classGroups` object instead of full path to class group. E.g. `dynamicClasses.foo.0` → `foo`. ### New Features -- (Breaking change) Simplify config by [@dcastil](https://github.com/dcastil) in [#3](https://github.com/dcastil/tailwind-merge/pull/3) -- Add support for Tailwind v2.2.5 by [@dcastil](https://github.com/dcastil) in [#2](https://github.com/dcastil/tailwind-merge/pull/2) +- (Breaking change) Simplify config by [@dcastil](https://github.com/dcastil) in [#3](https://github.com/dcastil/tailwind-merge/pull/3) +- Add support for Tailwind v2.2.5 by [@dcastil](https://github.com/dcastil) in [#2](https://github.com/dcastil/tailwind-merge/pull/2) ### Bug Fixes -- Fix non-conflicting border classes being merged incorrectly by [@dcastil](https://github.com/dcastil) in [#5](https://github.com/dcastil/tailwind-merge/pull/5) +- Fix non-conflicting border classes being merged incorrectly by [@dcastil](https://github.com/dcastil) in [#5](https://github.com/dcastil/tailwind-merge/pull/5) **Full Changelog**: [`v0.3.0...v0.4.0`](https://github.com/dcastil/tailwind-merge/compare/v0.3.0...v0.4.0) @@ -145,16 +145,16 @@ This is a big release with breaking changes. These were necessary to improve the ### New Features -- Enable named class group collections by [@dcastil](https://github.com/dcastil) in [`16a3175`](https://github.com/dcastil/tailwind-merge/commit/16a31751fdfd87c39683fb4506dec6a0bf118772) - - Class group collections in config can be an object, so you can use group references like `dynamicClasses.flex.direction` instead of just index-based ones like `dynamicClasses.flex.0`. More info on this in the [`createTailwindMerge()` API reference](https://github.com/dcastil/tailwind-merge/tree/v0.3.0#createtailwindmerge). +- Enable named class group collections by [@dcastil](https://github.com/dcastil) in [`16a3175`](https://github.com/dcastil/tailwind-merge/commit/16a31751fdfd87c39683fb4506dec6a0bf118772) + - Class group collections in config can be an object, so you can use group references like `dynamicClasses.flex.direction` instead of just index-based ones like `dynamicClasses.flex.0`. More info on this in the [`createTailwindMerge()` API reference](https://github.com/dcastil/tailwind-merge/tree/v0.3.0#createtailwindmerge). ### Bug Fixes -- Fix small typos in README by [@KeKs0r](https://github.com/KeKs0r) in [#1](https://github.com/dcastil/tailwind-merge/pull/1) +- Fix small typos in README by [@KeKs0r](https://github.com/KeKs0r) in [#1](https://github.com/dcastil/tailwind-merge/pull/1) ### Other -- tailwind-merge now has a logo by [@dcastil](https://github.com/dcastil) in [`9402c8e`](https://github.com/dcastil/tailwind-merge/commit/9402c8ec1b19714bb8ecb158eb124b89a8c1ba64), [`b969979`](https://github.com/dcastil/tailwind-merge/commit/b96997942d4e92e045c9b08e7314843305b41fe2), [`dae2aaa`](https://github.com/dcastil/tailwind-merge/commit/dae2aaabf8c00b0d5086aff744aa2c53513daf33), [`e9e8806`](https://github.com/dcastil/tailwind-merge/commit/e9e88060578483a3ed4728430f7b188e51aaef49), [`4e2d9f1`](https://github.com/dcastil/tailwind-merge/commit/4e2d9f160dae00e18ebcbecf54f4dd33dc4264bb)

tailwind-merge +- tailwind-merge now has a logo by [@dcastil](https://github.com/dcastil) in [`9402c8e`](https://github.com/dcastil/tailwind-merge/commit/9402c8ec1b19714bb8ecb158eb124b89a8c1ba64), [`b969979`](https://github.com/dcastil/tailwind-merge/commit/b96997942d4e92e045c9b08e7314843305b41fe2), [`dae2aaa`](https://github.com/dcastil/tailwind-merge/commit/dae2aaabf8c00b0d5086aff744aa2c53513daf33), [`e9e8806`](https://github.com/dcastil/tailwind-merge/commit/e9e88060578483a3ed4728430f7b188e51aaef49), [`4e2d9f1`](https://github.com/dcastil/tailwind-merge/commit/4e2d9f160dae00e18ebcbecf54f4dd33dc4264bb)

tailwind-merge **Full Changelog**: [`v0.2.0...v0.3.0`](https://github.com/dcastil/tailwind-merge/compare/v0.2.0...v0.3.0) @@ -162,16 +162,16 @@ This is a big release with breaking changes. These were necessary to improve the ### New Features -- Add support for important modifier by [@dcastil](https://github.com/dcastil) in [`17a9e9d`](https://github.com/dcastil/tailwind-merge/commit/17a9e9d9d805ba585372e01a9eefae1dba89368b) -- Add support for per-side border colors by [@dcastil](https://github.com/dcastil) in [`6cd9ee2`](https://github.com/dcastil/tailwind-merge/commit/6cd9ee255e1a6fb42e5262b7835f876e2ce8e3ae) -- Add support for content utiltites by [@dcastil](https://github.com/dcastil) in [`fd097c6`](https://github.com/dcastil/tailwind-merge/commit/fd097c611b5fa02ff6142b66f5ad96d596feed42) -- Add support for caret color by [@dcastil](https://github.com/dcastil) in [`fd097c6`](https://github.com/dcastil/tailwind-merge/commit/fd097c611b5fa02ff6142b66f5ad96d596feed42) -- Add support for JIT-only prefixes by [@dcastil](https://github.com/dcastil) in [`fd097c6`](https://github.com/dcastil/tailwind-merge/commit/fd097c611b5fa02ff6142b66f5ad96d596feed42) -- Mark package as side effect-free by [@dcastil](https://github.com/dcastil) in [`6d00af3`](https://github.com/dcastil/tailwind-merge/commit/6d00af33049c3c7171bce3f1affd561986cc6bfe) +- Add support for important modifier by [@dcastil](https://github.com/dcastil) in [`17a9e9d`](https://github.com/dcastil/tailwind-merge/commit/17a9e9d9d805ba585372e01a9eefae1dba89368b) +- Add support for per-side border colors by [@dcastil](https://github.com/dcastil) in [`6cd9ee2`](https://github.com/dcastil/tailwind-merge/commit/6cd9ee255e1a6fb42e5262b7835f876e2ce8e3ae) +- Add support for content utiltites by [@dcastil](https://github.com/dcastil) in [`fd097c6`](https://github.com/dcastil/tailwind-merge/commit/fd097c611b5fa02ff6142b66f5ad96d596feed42) +- Add support for caret color by [@dcastil](https://github.com/dcastil) in [`fd097c6`](https://github.com/dcastil/tailwind-merge/commit/fd097c611b5fa02ff6142b66f5ad96d596feed42) +- Add support for JIT-only prefixes by [@dcastil](https://github.com/dcastil) in [`fd097c6`](https://github.com/dcastil/tailwind-merge/commit/fd097c611b5fa02ff6142b66f5ad96d596feed42) +- Mark package as side effect-free by [@dcastil](https://github.com/dcastil) in [`6d00af3`](https://github.com/dcastil/tailwind-merge/commit/6d00af33049c3c7171bce3f1affd561986cc6bfe) ### Bug Fixes -- Fix classes like `bottom-auto` not being detected as Tailwind classesby [@dcastil](https://github.com/dcastil) in [`ec65b84`](https://github.com/dcastil/tailwind-merge/commit/ec65b84f0aab57d1305019e4a143772d675798a2) +- Fix classes like `bottom-auto` not being detected as Tailwind classesby [@dcastil](https://github.com/dcastil) in [`ec65b84`](https://github.com/dcastil/tailwind-merge/commit/ec65b84f0aab57d1305019e4a143772d675798a2) **Full Changelog**: [`v0.1.2...v0.2.0`](https://github.com/dcastil/tailwind-merge/compare/v0.1.2...v0.2.0) @@ -179,7 +179,7 @@ This is a big release with breaking changes. These were necessary to improve the ### Bug Fixes -- Fix errors when importing tailwind-merge as third party dependency. by [@dcastil](https://github.com/dcastil) in [`3335956`](https://github.com/dcastil/tailwind-merge/commit/3335956da15fdcc484904976864816413fad68f6) +- Fix errors when importing tailwind-merge as third party dependency. by [@dcastil](https://github.com/dcastil) in [`3335956`](https://github.com/dcastil/tailwind-merge/commit/3335956da15fdcc484904976864816413fad68f6) **Full Changelog**: [`v0.1.1...v0.1.2`](https://github.com/dcastil/tailwind-merge/compare/v0.1.1...v0.1.2) diff --git a/docs/changelog/v0-to-v1-migration.md b/docs/changelog/v0-to-v1-migration.md index f3552ea6..d29662ae 100644 --- a/docs/changelog/v0-to-v1-migration.md +++ b/docs/changelog/v0-to-v1-migration.md @@ -1,4 +1,4 @@ -# Guide to migrate from v0 to v1 +# Guide to migrate from tailwind-merge v0 to v1 This document is only about breaking changes between v0 and v1. For a full list of changes, see the [v1.0.0 release](./v1-changelog.md#v100). @@ -12,21 +12,21 @@ There are no breaking changes in the tailwind-merge types and some breaking chan ### `twMerge` and `extendTailwindMerge` -- Outline utilities from Tailwind v2 don't get merged anymore since they were replaced by outline width, outline style, outline offset and outline color in Tailwind v3 ([`55ab167`](https://github.com/dcastil/tailwind-merge/commit/55ab167b7167519873c5dd4d258dc62212d1659a), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) -- The classes `overflow-ellipsis` and `overflow-clip` will not get merged with class `truncate` anymore, but the new Tailwind v3 classes `text-ellipsis` and `text-clip` will. ([`65b03e4`](https://github.com/dcastil/tailwind-merge/commit/65b03e48914ac5d7d52eea9ec178b204d30609c9), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) -- The classes `decoration-slice` and `decoration-clone` won't get merged anymore and `box-decoration-slide` nad `box-decoration-clone` will ([`bfe2cc9`](https://github.com/dcastil/tailwind-merge/commit/bfe2cc9bb221107fa0bf363cc325ddbb04677f43), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- Outline utilities from Tailwind v2 don't get merged anymore since they were replaced by outline width, outline style, outline offset and outline color in Tailwind v3 ([`55ab167`](https://github.com/dcastil/tailwind-merge/commit/55ab167b7167519873c5dd4d258dc62212d1659a), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- The classes `overflow-ellipsis` and `overflow-clip` will not get merged with class `truncate` anymore, but the new Tailwind v3 classes `text-ellipsis` and `text-clip` will. ([`65b03e4`](https://github.com/dcastil/tailwind-merge/commit/65b03e48914ac5d7d52eea9ec178b204d30609c9), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- The classes `decoration-slice` and `decoration-clone` won't get merged anymore and `box-decoration-slide` nad `box-decoration-clone` will ([`bfe2cc9`](https://github.com/dcastil/tailwind-merge/commit/bfe2cc9bb221107fa0bf363cc325ddbb04677f43), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) ### `getDefaultConfig` -- Removed class group `outline` since it was removed in Tailwind v3 ([`55ab167`](https://github.com/dcastil/tailwind-merge/commit/55ab167b7167519873c5dd4d258dc62212d1659a), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) -- Renamed class group `vertival-alignment` (yes, the typo was in the code) to `vertical-align` ([`1269ce6`](https://github.com/dcastil/tailwind-merge/commit/1269ce68ae39807ceadbecc98c0929fdfdb446d0), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) -- Renamed class groups `flex-basis`, `flex-grow` and `flex-shrink` to `basis`, `grow` and `shrink` to stay consistent with Tailwind v3 ([`e6d8912`](https://github.com/dcastil/tailwind-merge/commit/e6d8912e47bf9a89346b9b0cc822fb2bff2af172), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- Removed class group `outline` since it was removed in Tailwind v3 ([`55ab167`](https://github.com/dcastil/tailwind-merge/commit/55ab167b7167519873c5dd4d258dc62212d1659a), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- Renamed class group `vertival-alignment` (yes, the typo was in the code) to `vertical-align` ([`1269ce6`](https://github.com/dcastil/tailwind-merge/commit/1269ce68ae39807ceadbecc98c0929fdfdb446d0), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- Renamed class groups `flex-basis`, `flex-grow` and `flex-shrink` to `basis`, `grow` and `shrink` to stay consistent with Tailwind v3 ([`e6d8912`](https://github.com/dcastil/tailwind-merge/commit/e6d8912e47bf9a89346b9b0cc822fb2bff2af172), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) ### `validators` -- `isCustomLength` and `isCustomValue` were renamed to `isArbitraryLength` and `isArbitraryValue` to be consistent with naming in Tailwind v3 documentation ([`adc3c02`](https://github.com/dcastil/tailwind-merge/commit/adc3c02c7f035069beec1c62777ec008172587ab), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- `isCustomLength` and `isCustomValue` were renamed to `isArbitraryLength` and `isArbitraryValue` to be consistent with naming in Tailwind v3 documentation ([`adc3c02`](https://github.com/dcastil/tailwind-merge/commit/adc3c02c7f035069beec1c62777ec008172587ab), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) ## Steps to upgrade -- Upgrade to Tailwind CSS v3 -- Upgrade to tailwind-merge v1 +- Upgrade to Tailwind CSS v3 +- Upgrade to tailwind-merge v1 diff --git a/docs/changelog/v1-changelog.md b/docs/changelog/v1-changelog.md index ee6eb52d..4b0b1686 100644 --- a/docs/changelog/v1-changelog.md +++ b/docs/changelog/v1-changelog.md @@ -4,20 +4,20 @@ ### New Features -- Improve support for arbitrary values by [@dcastil](https://github.com/dcastil) in [#263](https://github.com/dcastil/tailwind-merge/pull/263) - - Previously, tailwind-merge checked the content of the arbitrary value portion of a class in most cases to understand whether the type of the arbitrary value is correct (e.g. it checked for number followed by length unit for the length type). That lead to the issue that a class like `mt-[calc(theme(fontSize.4xl)/1.125)]` would not be recognized correctly because no length unit is present in the arbitrary value. - - I changed the check of the arbitrary value to also pass when a `calc()`, `min()`, `max()` and `clamp()` function is used in the arbitrary value. - - In ambiguous cases, you can use data type labels to mark the type of a class. [Read more](https://github.com/dcastil/tailwind-merge/blob/v1.14.0/docs/features.md#supports-arbitrary-values) - - Moreover, I removed the check where the type of the arbitrary value is unambiguous. In the class `mt-[…]` the arbitrary value can only be a length, so I don't check for it. A consequence of this is that if you use non-Tailwind classes like `mt-[this-is-totally-not-tailwind]`, tailwind-merge will recognize it as a Tailwind class from now on. **Please don't use classes that look like Tailwind classes with arbitrary value but aren't Tailwind classes with tailwind-merge (in default config) to prevent incorrect merging behavior**. +- Improve support for arbitrary values by [@dcastil](https://github.com/dcastil) in [#263](https://github.com/dcastil/tailwind-merge/pull/263) + - Previously, tailwind-merge checked the content of the arbitrary value portion of a class in most cases to understand whether the type of the arbitrary value is correct (e.g. it checked for number followed by length unit for the length type). That lead to the issue that a class like `mt-[calc(theme(fontSize.4xl)/1.125)]` would not be recognized correctly because no length unit is present in the arbitrary value. + - I changed the check of the arbitrary value to also pass when a `calc()`, `min()`, `max()` and `clamp()` function is used in the arbitrary value. + - In ambiguous cases, you can use data type labels to mark the type of a class. [Read more](https://github.com/dcastil/tailwind-merge/blob/v1.14.0/docs/features.md#supports-arbitrary-values) + - Moreover, I removed the check where the type of the arbitrary value is unambiguous. In the class `mt-[…]` the arbitrary value can only be a length, so I don't check for it. A consequence of this is that if you use non-Tailwind classes like `mt-[this-is-totally-not-tailwind]`, tailwind-merge will recognize it as a Tailwind class from now on. **Please don't use classes that look like Tailwind classes with arbitrary value but aren't Tailwind classes with tailwind-merge (in default config) to prevent incorrect merging behavior**. ### Bug Fixes -- Fix `col-span-full` class missing in default config by [@dcastil](https://github.com/dcastil) in [#267](https://github.com/dcastil/tailwind-merge/pull/267) -- Fix arbitrary value with no present length unit not being recognized by [@dcastil](https://github.com/dcastil) in [#263](https://github.com/dcastil/tailwind-merge/pull/263) +- Fix `col-span-full` class missing in default config by [@dcastil](https://github.com/dcastil) in [#267](https://github.com/dcastil/tailwind-merge/pull/267) +- Fix arbitrary value with no present length unit not being recognized by [@dcastil](https://github.com/dcastil) in [#263](https://github.com/dcastil/tailwind-merge/pull/263) ### Documentation -- Add missing info about where to call config functions to docs by [@dcastil](https://github.com/dcastil) in [#264](https://github.com/dcastil/tailwind-merge/pull/264) +- Add missing info about where to call config functions to docs by [@dcastil](https://github.com/dcastil) in [#264](https://github.com/dcastil/tailwind-merge/pull/264) **Full Changelog**: [`v1.13.2...v1.14.0`](https://github.com/dcastil/tailwind-merge/compare/v1.13.2...v1.14.0) @@ -25,12 +25,12 @@ ### Bug Fixes -- Fix TypeScript issue when using `moduleResolution: node16` by [@LiamMartens](https://github.com/LiamMartens) in [#245](https://github.com/dcastil/tailwind-merge/pull/245) +- Fix TypeScript issue when using `moduleResolution: node16` by [@LiamMartens](https://github.com/LiamMartens) in [#245](https://github.com/dcastil/tailwind-merge/pull/245) ### Documentation -- Fix grammar and typos in docs by [@jmmarco](https://github.com/jmmarco) in [#249](https://github.com/dcastil/tailwind-merge/pull/249) -- Add tailwind-merge-php to similar packages in docs by [@JamesHemery](https://github.com/JamesHemery) in [#246](https://github.com/dcastil/tailwind-merge/pull/246) +- Fix grammar and typos in docs by [@jmmarco](https://github.com/jmmarco) in [#249](https://github.com/dcastil/tailwind-merge/pull/249) +- Add tailwind-merge-php to similar packages in docs by [@JamesHemery](https://github.com/JamesHemery) in [#246](https://github.com/dcastil/tailwind-merge/pull/246) **Full Changelog**: [`v1.13.1...v1.13.2`](https://github.com/dcastil/tailwind-merge/compare/v1.13.1...v1.13.2) @@ -40,7 +40,7 @@ Thanks to [@bluetch](https://github.com/bluetch) for sponsoring tailwind-merge! ### Bug Fixes -- Fix `basis-auto` and `basis-full` not being merged correctly by [@lukasz-kapica](https://github.com/lukasz-kapica) in [#242](https://github.com/dcastil/tailwind-merge/pull/242) +- Fix `basis-auto` and `basis-full` not being merged correctly by [@lukasz-kapica](https://github.com/lukasz-kapica) in [#242](https://github.com/dcastil/tailwind-merge/pull/242) **Full Changelog**: [`v1.13.0...v1.13.1`](https://github.com/dcastil/tailwind-merge/compare/v1.13.0...v1.13.1) @@ -50,21 +50,21 @@ This release focuses on improvements to the docs. ### Bug Fixes -- Fix arbitrary length `0` without unit not being recognized by [@dcastil](https://github.com/dcastil) in [#237](https://github.com/dcastil/tailwind-merge/pull/237) -- Fix typo in comment in default-config.ts by [@CrutchTheClutch](https://github.com/CrutchTheClutch) in [#227](https://github.com/dcastil/tailwind-merge/pull/227) +- Fix arbitrary length `0` without unit not being recognized by [@dcastil](https://github.com/dcastil) in [#237](https://github.com/dcastil/tailwind-merge/pull/237) +- Fix typo in comment in default-config.ts by [@CrutchTheClutch](https://github.com/CrutchTheClutch) in [#227](https://github.com/dcastil/tailwind-merge/pull/227) ### Documentation -- Add intro video from Simon Vrachliotis to docs by [@dcastil](https://github.com/dcastil) in [#239](https://github.com/dcastil/tailwind-merge/pull/239) - - [@simonswiss](https://github.com/simonswiss) made an intro video to tailwind-merge which I added to the docs. Check it out [here](https://github.com/dcastil/tailwind-merge/blob/v1.13.0/docs/what-is-it-for.md#video-introduction)! -- Add docs about when to use tailwind-merge by [@dcastil](https://github.com/dcastil) in [#230](https://github.com/dcastil/tailwind-merge/pull/230) - - I added a new page to the docs about [when and how to use tailwind-merge](https://github.com/dcastil/tailwind-merge/blob/v1.13.0/docs/when-and-how-to-use-it.md) which should help you to decide whether you should use it and what alternative approaches exist. -- Make it clearer in docs that tailwind-merge supports composition of class strings by [@dcastil](https://github.com/dcastil) in [#229](https://github.com/dcastil/tailwind-merge/pull/229) +- Add intro video from Simon Vrachliotis to docs by [@dcastil](https://github.com/dcastil) in [#239](https://github.com/dcastil/tailwind-merge/pull/239) + - [@simonswiss](https://github.com/simonswiss) made an intro video to tailwind-merge which I added to the docs. Check it out [here](https://github.com/dcastil/tailwind-merge/blob/v1.13.0/docs/what-is-it-for.md#video-introduction)! +- Add docs about when to use tailwind-merge by [@dcastil](https://github.com/dcastil) in [#230](https://github.com/dcastil/tailwind-merge/pull/230) + - I added a new page to the docs about [when and how to use tailwind-merge](https://github.com/dcastil/tailwind-merge/blob/v1.13.0/docs/when-and-how-to-use-it.md) which should help you to decide whether you should use it and what alternative approaches exist. +- Make it clearer in docs that tailwind-merge supports composition of class strings by [@dcastil](https://github.com/dcastil) in [#229](https://github.com/dcastil/tailwind-merge/pull/229) ### Other -- Add npm package provenance by [@dcastil](https://github.com/dcastil) in [#219](https://github.com/dcastil/tailwind-merge/pull/219) - - GitHub introduced a new security feature to verify which source commit and build file were used for a specific npm package version. tailwind-merge now publishes provenance signatures alongside all releases on npm. [Read more on the GitHub blog.](https://github.blog/2023-04-19-introducing-npm-package-provenance/) +- Add npm package provenance by [@dcastil](https://github.com/dcastil) in [#219](https://github.com/dcastil/tailwind-merge/pull/219) + - GitHub introduced a new security feature to verify which source commit and build file were used for a specific npm package version. tailwind-merge now publishes provenance signatures alongside all releases on npm. [Read more on the GitHub blog.](https://github.blog/2023-04-19-introducing-npm-package-provenance/) **Full Changelog**: [`v1.12.0...v1.13.0`](https://github.com/dcastil/tailwind-merge/compare/v1.12.0...v1.13.0) @@ -74,11 +74,11 @@ With this release tailwind-merge supports all features introduced in [Tailwind C ### New Features -- Add support for postfix modifier by [@dcastil](https://github.com/dcastil) in [#214](https://github.com/dcastil/tailwind-merge/pull/214) - - This adds support for `line-height` modifiers in `font-size` utilities like `text-lg/7` and more potential postfix modifiers in the future ([learn more](https://github.com/dcastil/tailwind-merge/blob/v1.12.0/docs/features.md#supports-postfix-modifiers)). - - All classes are checked for postfix modifiers since there will be more in the future and they'll be configurable with plugins. - - tailwind-merge can't know from the class syntax alone whether something is a modifier or not. E.g. there is `w-1/2` which doesn't contain a modifier. So tailwind-merge always checks whether class without potential modifier exists and if it doesn't it checks for full class. This behavior might get reversed in the next major version as a breaking change ([learn more](https://github.com/dcastil/tailwind-merge/issues/215)). - - Added `conflictingClassGroupModifiers` object to tailwind-merge config ([learn more](https://github.com/dcastil/tailwind-merge/blob/v1.12.0/docs/configuration.md#postfix-modifiers-conflicting-with-class-groups)). +- Add support for postfix modifier by [@dcastil](https://github.com/dcastil) in [#214](https://github.com/dcastil/tailwind-merge/pull/214) + - This adds support for `line-height` modifiers in `font-size` utilities like `text-lg/7` and more potential postfix modifiers in the future ([learn more](https://github.com/dcastil/tailwind-merge/blob/v1.12.0/docs/features.md#supports-postfix-modifiers)). + - All classes are checked for postfix modifiers since there will be more in the future and they'll be configurable with plugins. + - tailwind-merge can't know from the class syntax alone whether something is a modifier or not. E.g. there is `w-1/2` which doesn't contain a modifier. So tailwind-merge always checks whether class without potential modifier exists and if it doesn't it checks for full class. This behavior might get reversed in the next major version as a breaking change ([learn more](https://github.com/dcastil/tailwind-merge/issues/215)). + - Added `conflictingClassGroupModifiers` object to tailwind-merge config ([learn more](https://github.com/dcastil/tailwind-merge/blob/v1.12.0/docs/configuration.md#postfix-modifiers-conflicting-with-class-groups)). **Full Changelog**: [`v1.11.0...v1.12.0`](https://github.com/dcastil/tailwind-merge/compare/v1.11.0...v1.12.0) @@ -86,13 +86,13 @@ With this release tailwind-merge supports all features introduced in [Tailwind C ### New Features -- Add support for Tailwind CSS v3.3 except line-height shorthand by [@dcastil](https://github.com/dcastil) in [#210](https://github.com/dcastil/tailwind-merge/pull/210) - - The line-height shorthand in font-size utilities (`text-lg/7`) [introduced in Tailwind CSS v3.3](https://tailwindcss.com/blog/tailwindcss-v3-3#new-line-height-shorthand-for-font-size-utilities) is not yet supported in tailwind-merge because that feature is a bit more involved. I'll add support for it in a future release. More info in [#211](https://github.com/dcastil/tailwind-merge/issues/211). - - Added new [validator](https://github.com/dcastil/tailwind-merge/blob/v1.11.0/docs/api-reference.md#validators) `isPercent` which is needed internally for the default scale of color stop positions. - - New [theme](https://github.com/dcastil/tailwind-merge/blob/v1.11.0/docs/configuration.md#theme) key `gradientColorStopPositions` supported in tailwind-merge. - - New logical properties like `ps-0` (`padding-inline-start: 0px;`) are de-duplicated away when using the matching property for all sides afterwards like in this case `p-0`, but not when using single axis sides like `px-0` because `padding-inline-start` can also be the top or bottom padding depending on writing mode. - - Basically `twMerge('ps-0 p-0') === 'p-0' && twMerge('ps-0 px-0') === 'ps-0 px-0'`. - - If you want to use logical properties and know which writing modes your app is limited to, add the right conflicts yourself to your tailwind-merge config. +- Add support for Tailwind CSS v3.3 except line-height shorthand by [@dcastil](https://github.com/dcastil) in [#210](https://github.com/dcastil/tailwind-merge/pull/210) + - The line-height shorthand in font-size utilities (`text-lg/7`) [introduced in Tailwind CSS v3.3](https://tailwindcss.com/blog/tailwindcss-v3-3#new-line-height-shorthand-for-font-size-utilities) is not yet supported in tailwind-merge because that feature is a bit more involved. I'll add support for it in a future release. More info in [#211](https://github.com/dcastil/tailwind-merge/issues/211). + - Added new [validator](https://github.com/dcastil/tailwind-merge/blob/v1.11.0/docs/api-reference.md#validators) `isPercent` which is needed internally for the default scale of color stop positions. + - New [theme](https://github.com/dcastil/tailwind-merge/blob/v1.11.0/docs/configuration.md#theme) key `gradientColorStopPositions` supported in tailwind-merge. + - New logical properties like `ps-0` (`padding-inline-start: 0px;`) are de-duplicated away when using the matching property for all sides afterwards like in this case `p-0`, but not when using single axis sides like `px-0` because `padding-inline-start` can also be the top or bottom padding depending on writing mode. + - Basically `twMerge('ps-0 p-0') === 'p-0' && twMerge('ps-0 px-0') === 'ps-0 px-0'`. + - If you want to use logical properties and know which writing modes your app is limited to, add the right conflicts yourself to your tailwind-merge config. **Full Changelog**: [`v1.10.0...v1.11.0`](https://github.com/dcastil/tailwind-merge/compare/v1.10.0...v1.11.0) @@ -102,7 +102,7 @@ Thanks to [@brandonmcconnell](https://github.com/brandonmcconnell) for sponsorin ### New Features -- Add support for container query length units in arbitrary values by [@LesnoyPudge](https://github.com/LesnoyPudge) in [#204](https://github.com/dcastil/tailwind-merge/pull/204) +- Add support for container query length units in arbitrary values by [@LesnoyPudge](https://github.com/LesnoyPudge) in [#204](https://github.com/dcastil/tailwind-merge/pull/204) **Full Changelog**: [`v1.9.1...v1.10.0`](https://github.com/dcastil/tailwind-merge/compare/v1.9.1...v1.10.0) @@ -110,10 +110,10 @@ Thanks to [@brandonmcconnell](https://github.com/brandonmcconnell) for sponsorin ### Bug Fixes -- Fix arbitrary floats not supported in opacity, scale, etc. by [@dcastil](https://github.com/dcastil) in [#196](https://github.com/dcastil/tailwind-merge/pull/196) - - Up until now classes like `opacity-50 opacity-[.025]` weren't merged correctly. You might not have noticed since classes with arbitrary values are defined after the default ones in the output stylesheet, but merging it the other way around (`opacity-[.025] opacity-50`) would have led to a styling bug. - - This fix led to a new [validator](https://github.com/dcastil/tailwind-merge/blob/v1.9.1/docs/api-reference.md#validators) `isNumber`. -- Fix arbitrary border color value being merged incorrectly by [@dcastil](https://github.com/dcastil) in [#195](https://github.com/dcastil/tailwind-merge/pull/195) +- Fix arbitrary floats not supported in opacity, scale, etc. by [@dcastil](https://github.com/dcastil) in [#196](https://github.com/dcastil/tailwind-merge/pull/196) + - Up until now classes like `opacity-50 opacity-[.025]` weren't merged correctly. You might not have noticed since classes with arbitrary values are defined after the default ones in the output stylesheet, but merging it the other way around (`opacity-[.025] opacity-50`) would have led to a styling bug. + - This fix led to a new [validator](https://github.com/dcastil/tailwind-merge/blob/v1.9.1/docs/api-reference.md#validators) `isNumber`. +- Fix arbitrary border color value being merged incorrectly by [@dcastil](https://github.com/dcastil) in [#195](https://github.com/dcastil/tailwind-merge/pull/195) **Full Changelog**: [`v1.9.0...v1.9.1`](https://github.com/dcastil/tailwind-merge/compare/v1.9.0...v1.9.1) @@ -121,15 +121,15 @@ Thanks to [@brandonmcconnell](https://github.com/brandonmcconnell) for sponsorin ### New Features -- Support decimals in T-shirt sizes by [@farreldarian](https://github.com/farreldarian) in [#189](https://github.com/dcastil/tailwind-merge/pull/189) +- Support decimals in T-shirt sizes by [@farreldarian](https://github.com/farreldarian) in [#189](https://github.com/dcastil/tailwind-merge/pull/189) ### Documentation -- Fixes typo in recipes docs by [@nicklemmon](https://github.com/nicklemmon) in [#181](https://github.com/dcastil/tailwind-merge/pull/181) +- Fixes typo in recipes docs by [@nicklemmon](https://github.com/nicklemmon) in [#181](https://github.com/dcastil/tailwind-merge/pull/181) ### Other -- Added test case by [@chuanyu0201](https://github.com/chuanyu0201) in [#186](https://github.com/dcastil/tailwind-merge/pull/186) +- Added test case by [@chuanyu0201](https://github.com/chuanyu0201) in [#186](https://github.com/dcastil/tailwind-merge/pull/186) **Full Changelog**: [`v1.8.1...v1.9.0`](https://github.com/dcastil/tailwind-merge/compare/v1.8.1...v1.9.0) @@ -137,7 +137,7 @@ Thanks to [@brandonmcconnell](https://github.com/brandonmcconnell) for sponsorin ### Bug Fixes -- Fix incorrect class group conflicts in grid-related classes by [@dcastil](https://github.com/dcastil) in [#177](https://github.com/dcastil/tailwind-merge/pull/177) +- Fix incorrect class group conflicts in grid-related classes by [@dcastil](https://github.com/dcastil) in [#177](https://github.com/dcastil/tailwind-merge/pull/177) **Full Changelog**: [`v1.8.0...v1.8.1`](https://github.com/dcastil/tailwind-merge/compare/v1.8.0...v1.8.1) @@ -147,10 +147,10 @@ Thanks to [@aniravi24](https://github.com/aniravi24) for sponsoring tailwind-mer ### New Features -- Add support for custom separator by [@dcastil](https://github.com/dcastil) in [#168](https://github.com/dcastil/tailwind-merge/pull/168) -- Add support for dynamic viewport units in arbitrary lengths by [@dcastil](https://github.com/dcastil) in [#166](https://github.com/dcastil/tailwind-merge/pull/166) -- Rename `join` to `twJoin` by [@dcastil](https://github.com/dcastil) in [#161](https://github.com/dcastil/tailwind-merge/pull/161) - - I deprecated the [`join`](https://github.com/dcastil/tailwind-merge/blob/v1.7.0/docs/api-reference.md#join) function and renamed it to [`twJoin`](https://github.com/dcastil/tailwind-merge/blob/v1.8.0/docs/api-reference.md#twjoin) to make replacing it via search and replace easier since `join` is a common function name. You don't need to change anything right now, but if you have some spare time, rename join → twJoin in your code since the `join` function will be removed in the next major release. +- Add support for custom separator by [@dcastil](https://github.com/dcastil) in [#168](https://github.com/dcastil/tailwind-merge/pull/168) +- Add support for dynamic viewport units in arbitrary lengths by [@dcastil](https://github.com/dcastil) in [#166](https://github.com/dcastil/tailwind-merge/pull/166) +- Rename `join` to `twJoin` by [@dcastil](https://github.com/dcastil) in [#161](https://github.com/dcastil/tailwind-merge/pull/161) + - I deprecated the [`join`](https://github.com/dcastil/tailwind-merge/blob/v1.7.0/docs/api-reference.md#join) function and renamed it to [`twJoin`](https://github.com/dcastil/tailwind-merge/blob/v1.8.0/docs/api-reference.md#twjoin) to make replacing it via search and replace easier since `join` is a common function name. You don't need to change anything right now, but if you have some spare time, rename join → twJoin in your code since the `join` function will be removed in the next major release. **Full Changelog**: [`v1.7.0...v1.8.0`](https://github.com/dcastil/tailwind-merge/compare/v1.7.0...v1.8.0) @@ -160,7 +160,7 @@ Thanks to [@gjtorikian](https://github.com/gjtorikian) for sponsoring tailwind-m ### New Features -- Add support for Tailwind CSS v3.2 by [@dcastil](https://github.com/dcastil) and [@brandonmcconnell](https://github.com/brandonmcconnell) in [#159](https://github.com/dcastil/tailwind-merge/pull/159) +- Add support for Tailwind CSS v3.2 by [@dcastil](https://github.com/dcastil) and [@brandonmcconnell](https://github.com/brandonmcconnell) in [#159](https://github.com/dcastil/tailwind-merge/pull/159) **Full Changelog**: [`v1.6.2...v1.7.0`](https://github.com/dcastil/tailwind-merge/compare/v1.6.2...v1.7.0) @@ -168,14 +168,14 @@ Thanks to [@gjtorikian](https://github.com/gjtorikian) for sponsoring tailwind-m ### Bug Fixes -- Fix arbitrary numbers not working in stroke-width by [@dcastil](https://github.com/dcastil) in [#153](https://github.com/dcastil/tailwind-merge/pull/153) - - Now tailwind-merge handles classes like `stroke-[3]` correctly. - - I deprecated the [validator](https://github.com/dcastil/tailwind-merge/blob/v1.6.2/docs/api-reference.md#validators) `isArbitraryWeight` and renamed it to `isArbitraryNumber` to reflect its broader use case. You don't need to change anything right now, but if you have some spare time, rename `isArbitraryWeight` → `isArbitraryNumber` in your code since `isArbitraryWeight` will be removed in the next major release. +- Fix arbitrary numbers not working in stroke-width by [@dcastil](https://github.com/dcastil) in [#153](https://github.com/dcastil/tailwind-merge/pull/153) + - Now tailwind-merge handles classes like `stroke-[3]` correctly. + - I deprecated the [validator](https://github.com/dcastil/tailwind-merge/blob/v1.6.2/docs/api-reference.md#validators) `isArbitraryWeight` and renamed it to `isArbitraryNumber` to reflect its broader use case. You don't need to change anything right now, but if you have some spare time, rename `isArbitraryWeight` → `isArbitraryNumber` in your code since `isArbitraryWeight` will be removed in the next major release. ### Other -- Add package version number to dev releases by [@dcastil](https://github.com/dcastil) in [#154](https://github.com/dcastil/tailwind-merge/pull/154) - - Now dev releases don't start with `0.0.0-dev` anymore and instead have the version number of the last release, like `1.6.1-dev`. That makes it easier for tools like [Renovate](https://renovatebot.com/) to understand which package version you're using in case you use dev releases. +- Add package version number to dev releases by [@dcastil](https://github.com/dcastil) in [#154](https://github.com/dcastil/tailwind-merge/pull/154) + - Now dev releases don't start with `0.0.0-dev` anymore and instead have the version number of the last release, like `1.6.1-dev`. That makes it easier for tools like [Renovate](https://renovatebot.com/) to understand which package version you're using in case you use dev releases. **Full Changelog**: [`v1.6.1...v1.6.2`](https://github.com/dcastil/tailwind-merge/compare/v1.6.1...v1.6.2) @@ -183,7 +183,7 @@ Thanks to [@gjtorikian](https://github.com/gjtorikian) for sponsoring tailwind-m ### Bug Fixes -- Fix h-min not working by [@dcastil](https://github.com/dcastil) in [#146](https://github.com/dcastil/tailwind-merge/pull/146) +- Fix h-min not working by [@dcastil](https://github.com/dcastil) in [#146](https://github.com/dcastil/tailwind-merge/pull/146) **Full Changelog**: [`v1.6.0...v1.6.1`](https://github.com/dcastil/tailwind-merge/compare/v1.6.0...v1.6.1) @@ -191,26 +191,26 @@ Thanks to [@gjtorikian](https://github.com/gjtorikian) for sponsoring tailwind-m ### New Features -- Add support for arrays as argument by [@dcastil](https://github.com/dcastil) in [#127](https://github.com/dcastil/tailwind-merge/pull/127) - - You can now use arbitrarily nested arrays as arguments to `twMerge`. That's especially handy for nested conditions. +- Add support for arrays as argument by [@dcastil](https://github.com/dcastil) in [#127](https://github.com/dcastil/tailwind-merge/pull/127) + - You can now use arbitrarily nested arrays as arguments to `twMerge`. That's especially handy for nested conditions. ```js twMerge('…', someBool && ['…', anotherBool && '…']) ``` - - The joining of arguments is done with a new `join` function which [is present in the tailwind-merge exports](https://github.com/dcastil/tailwind-merge/blob/v1.6.0/docs/api-reference.md#join) as well. It has the same functionality as [clsx](https://github.com/lukeed/clsx) but without support for objects as arguments which makes it a little faster. - - Why no objects as arguments? You can read about my reasoning in [#137 (comment)](https://github.com/dcastil/tailwind-merge/discussions/137#discussioncomment-3481605). + - The joining of arguments is done with a new `join` function which [is present in the tailwind-merge exports](https://github.com/dcastil/tailwind-merge/blob/v1.6.0/docs/api-reference.md#join) as well. It has the same functionality as [clsx](https://github.com/lukeed/clsx) but without support for objects as arguments which makes it a little faster. + - Why no objects as arguments? You can read about my reasoning in [#137 (comment)](https://github.com/dcastil/tailwind-merge/discussions/137#discussioncomment-3481605). ### Bug Fixes -- Replace matchAll with exec by [@dcastil](https://github.com/dcastil) in [#133](https://github.com/dcastil/tailwind-merge/pull/133) - - This makes tailwind-merge work in older browsers which don't support `String.prototype.matchAll()` +- Replace matchAll with exec by [@dcastil](https://github.com/dcastil) in [#133](https://github.com/dcastil/tailwind-merge/pull/133) + - This makes tailwind-merge work in older browsers which don't support `String.prototype.matchAll()` ### Other -- Add recipes section to docs by [@dcastil](https://github.com/dcastil) in [#134](https://github.com/dcastil/tailwind-merge/pull/134) -- Split docs into multiple files by [@dcastil](https://github.com/dcastil) in [#131](https://github.com/dcastil/tailwind-merge/pull/131) -- Add comments to released PRs and their related issues by [@dcastil](https://github.com/dcastil) in [#130](https://github.com/dcastil/tailwind-merge/pull/130) -- Add tests to check actual CJS and ESM package exports by [@dcastil](https://github.com/dcastil) in [#129](https://github.com/dcastil/tailwind-merge/pull/129) -- Remove ts files from npm package by [@dcastil](https://github.com/dcastil) in [#128](https://github.com/dcastil/tailwind-merge/pull/128) +- Add recipes section to docs by [@dcastil](https://github.com/dcastil) in [#134](https://github.com/dcastil/tailwind-merge/pull/134) +- Split docs into multiple files by [@dcastil](https://github.com/dcastil) in [#131](https://github.com/dcastil/tailwind-merge/pull/131) +- Add comments to released PRs and their related issues by [@dcastil](https://github.com/dcastil) in [#130](https://github.com/dcastil/tailwind-merge/pull/130) +- Add tests to check actual CJS and ESM package exports by [@dcastil](https://github.com/dcastil) in [#129](https://github.com/dcastil/tailwind-merge/pull/129) +- Remove ts files from npm package by [@dcastil](https://github.com/dcastil) in [#128](https://github.com/dcastil/tailwind-merge/pull/128) **Full Changelog**: [`v1.5.1...v1.6.0`](https://github.com/dcastil/tailwind-merge/compare/v1.5.1...v1.6.0) @@ -220,7 +220,7 @@ Thanks to [@charkour](https://github.com/charkour) for sponsoring tailwind-merge ### Bug Fixes -- Fix arbitrary z-index value not being recognized by [@dcastil](https://github.com/dcastil) in [#116](https://github.com/dcastil/tailwind-merge/pull/116) +- Fix arbitrary z-index value not being recognized by [@dcastil](https://github.com/dcastil) in [#116](https://github.com/dcastil/tailwind-merge/pull/116) **Full Changelog**: [`v1.5.0...v1.5.1`](https://github.com/dcastil/tailwind-merge/compare/v1.5.0...v1.5.1) @@ -230,8 +230,8 @@ Thanks to [@charkour](https://github.com/charkour) for sponsoring tailwind-merge ### New Features -- Added missing ESM `types` subpath export condition by [@scott-lc](https://github.com/scott-lc) in [#113](https://github.com/dcastil/tailwind-merge/pull/113) - - This makes tailwind-merge work in TypeScript projects using [the new `nodenext` module type introduced in TypeScript 4.7](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#ecmascript-module-support-in-node-js). +- Added missing ESM `types` subpath export condition by [@scott-lc](https://github.com/scott-lc) in [#113](https://github.com/dcastil/tailwind-merge/pull/113) + - This makes tailwind-merge work in TypeScript projects using [the new `nodenext` module type introduced in TypeScript 4.7](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#ecmascript-module-support-in-node-js). **Full Changelog**: [`v1.4.0...v1.5.0`](https://github.com/dcastil/tailwind-merge/compare/v1.4.0...v1.5.0) @@ -241,15 +241,15 @@ Thanks to [@charkour](https://github.com/charkour) for sponsoring tailwind-merge ### New Features -- Optimize runtime performance by using Map by [@dcastil](https://github.com/dcastil) in [#105](https://github.com/dcastil/tailwind-merge/pull/105) +- Optimize runtime performance by using Map by [@dcastil](https://github.com/dcastil) in [#105](https://github.com/dcastil/tailwind-merge/pull/105) ### Bug Fixes -- Fix overriding w-full with w-fit not working by [@dcastil](https://github.com/dcastil) in [#112](https://github.com/dcastil/tailwind-merge/pull/112) +- Fix overriding w-full with w-fit not working by [@dcastil](https://github.com/dcastil) in [#112](https://github.com/dcastil/tailwind-merge/pull/112) ### Other -- Publish dev releases of every commit on main branch by [@dcastil](https://github.com/dcastil) in [#104](https://github.com/dcastil/tailwind-merge/pull/104) +- Publish dev releases of every commit on main branch by [@dcastil](https://github.com/dcastil) in [#104](https://github.com/dcastil/tailwind-merge/pull/104) **Full Changelog**: [`v1.3.0...v1.4.0`](https://github.com/dcastil/tailwind-merge/compare/v1.3.0...v1.4.0) @@ -259,16 +259,16 @@ Thanks to [@charkour](https://github.com/charkour) for sponsoring tailwind-merge ### New Features -- Add support for Tailwind v3.1 by [@dcastil](https://github.com/dcastil) in [#103](https://github.com/dcastil/tailwind-merge/pull/103) +- Add support for Tailwind v3.1 by [@dcastil](https://github.com/dcastil) in [#103](https://github.com/dcastil/tailwind-merge/pull/103) ### Bug Fixes -- Fix readme typos by [@oshi97](https://github.com/oshi97) in [#102](https://github.com/dcastil/tailwind-merge/pull/102) -- Fix typos in comments by [@szamanr](https://github.com/szamanr) in [#89](https://github.com/dcastil/tailwind-merge/pull/89) +- Fix readme typos by [@oshi97](https://github.com/oshi97) in [#102](https://github.com/dcastil/tailwind-merge/pull/102) +- Fix typos in comments by [@szamanr](https://github.com/szamanr) in [#89](https://github.com/dcastil/tailwind-merge/pull/89) ### Other -- Add community health files by [@dcastil](https://github.com/dcastil) in [#93](https://github.com/dcastil/tailwind-merge/pull/93) +- Add community health files by [@dcastil](https://github.com/dcastil) in [#93](https://github.com/dcastil/tailwind-merge/pull/93) **Full Changelog**: [`v1.2.1...v1.3.0`](https://github.com/dcastil/tailwind-merge/compare/v1.2.1...v1.3.0) @@ -278,8 +278,8 @@ Thanks to [@charkour](https://github.com/charkour) for sponsoring tailwind-merge ### Bug Fixes -- Fix isArbitraryWeight incorrectly using `weight:` instead of `number:` for disambiguation for arbitrary values by [@liuqiang1357](https://github.com/liuqiang1357) in [#85](https://github.com/dcastil/tailwind-merge/pull/85) -- Fix typos in README.md by [@Gri-ffin](https://github.com/Gri-ffin) in [#82](https://github.com/dcastil/tailwind-merge/pull/82) +- Fix isArbitraryWeight incorrectly using `weight:` instead of `number:` for disambiguation for arbitrary values by [@liuqiang1357](https://github.com/liuqiang1357) in [#85](https://github.com/dcastil/tailwind-merge/pull/85) +- Fix typos in README.md by [@Gri-ffin](https://github.com/Gri-ffin) in [#82](https://github.com/dcastil/tailwind-merge/pull/82) **Full Changelog**: [`v1.2.0...v1.2.1`](https://github.com/dcastil/tailwind-merge/compare/v1.2.0...v1.2.1) @@ -289,7 +289,7 @@ Thanks to [@charkour](https://github.com/charkour) for sponsoring tailwind-merge ### New Features -- Add prefix support by [@dcastil](https://github.com/dcastil) in [#78](https://github.com/dcastil/tailwind-merge/pull/78) +- Add prefix support by [@dcastil](https://github.com/dcastil) in [#78](https://github.com/dcastil/tailwind-merge/pull/78) **Full Changelog**: [`v1.1.1...v1.2.0`](https://github.com/dcastil/tailwind-merge/compare/v1.1.1...v1.2.0) @@ -299,7 +299,7 @@ Thanks to [@charkour](https://github.com/charkour) for sponsoring tailwind-merge ### Bug Fixes -- Fix TypeScript types not being linked correctly in package.json by [@navin-moorthy](https://github.com/navin-moorthy) and [@dcastil](https://github.com/dcastil) in [#75](https://github.com/dcastil/tailwind-merge/pull/75) +- Fix TypeScript types not being linked correctly in package.json by [@navin-moorthy](https://github.com/navin-moorthy) and [@dcastil](https://github.com/dcastil) in [#75](https://github.com/dcastil/tailwind-merge/pull/75) **Full Changelog**: [`v1.1.0...v1.1.1`](https://github.com/dcastil/tailwind-merge/compare/v1.1.0...v1.1.1) @@ -307,19 +307,19 @@ Thanks to [@charkour](https://github.com/charkour) for sponsoring tailwind-merge ### New Features -- Fix missing arbitrary value support in some class groups by [@dcastil](https://github.com/dcastil) in [#73](https://github.com/dcastil/tailwind-merge/pull/73) - - Adds arbitrary value support for class groups `grayscale`, `invert`, `sepia`, `grow`, `shrink`, `object-position`, `shadow`, `drop-shadow`, `rotate`, `skew` and `transform-origin` - - Fixes `break-inside` classes being merged incorrectly - - Adds missing classes `overline`, `underline-offset`, `content-none` - - Fixes typo in class group name `bg-repeeat` → `bg-repeat` - - Adds `isArbitraryShadow` validator -- Improve tree-shaking by [@dcastil](https://github.com/dcastil) in [#65](https://github.com/dcastil/tailwind-merge/pull/65) - - I changed the build output significantly here and removed `"type": "module"` from the package.json. I did test the new npm package output in Node and in the browser, but it's hard to account for every possible build system tailwind-merge is used in. If some issues come up with bundling tailwind-merge, please open an issue! +- Fix missing arbitrary value support in some class groups by [@dcastil](https://github.com/dcastil) in [#73](https://github.com/dcastil/tailwind-merge/pull/73) + - Adds arbitrary value support for class groups `grayscale`, `invert`, `sepia`, `grow`, `shrink`, `object-position`, `shadow`, `drop-shadow`, `rotate`, `skew` and `transform-origin` + - Fixes `break-inside` classes being merged incorrectly + - Adds missing classes `overline`, `underline-offset`, `content-none` + - Fixes typo in class group name `bg-repeeat` → `bg-repeat` + - Adds `isArbitraryShadow` validator +- Improve tree-shaking by [@dcastil](https://github.com/dcastil) in [#65](https://github.com/dcastil/tailwind-merge/pull/65) + - I changed the build output significantly here and removed `"type": "module"` from the package.json. I did test the new npm package output in Node and in the browser, but it's hard to account for every possible build system tailwind-merge is used in. If some issues come up with bundling tailwind-merge, please open an issue! ### Bug Fixes -- Fix stroke-color utilities being merged with stroke-width utilities by [@dcastil](https://github.com/dcastil) in [#72](https://github.com/dcastil/tailwind-merge/pull/72) -- Fix mix-blend utilities getting merged incorrectly by [@dcastil](https://github.com/dcastil) in [#71](https://github.com/dcastil/tailwind-merge/pull/71) +- Fix stroke-color utilities being merged with stroke-width utilities by [@dcastil](https://github.com/dcastil) in [#72](https://github.com/dcastil/tailwind-merge/pull/72) +- Fix mix-blend utilities getting merged incorrectly by [@dcastil](https://github.com/dcastil) in [#71](https://github.com/dcastil/tailwind-merge/pull/71) **Full Changelog**: [`v1.0.0...v1.1.0`](https://github.com/dcastil/tailwind-merge/compare/v1.0.0...v1.1.0) @@ -337,28 +337,28 @@ By the way, you can now [sponsor](https://github.com/sponsors/dcastil) this proj ### Breaking Changes -- `twMerge`, `extendTailwindMerge` +- `twMerge`, `extendTailwindMerge` - - Outline utilities from Tailwind v2 don't get merged anymore since they were replaced by outline width, outline style, outline offset and outline color in Tailwind v3 ([`55ab167`](https://github.com/dcastil/tailwind-merge/commit/55ab167b7167519873c5dd4d258dc62212d1659a), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) - - The classes `overflow-ellipsis` and `overflow-clip` will not get merged with class `truncate` anymore, but the new Tailwind v3 classes `text-ellipsis` and `text-clip` will. ([`65b03e4`](https://github.com/dcastil/tailwind-merge/commit/65b03e48914ac5d7d52eea9ec178b204d30609c9), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) - - The classes `decoration-slice` and `decoration-clone` won't get merged anymore and `box-decoration-slide` nad `box-decoration-clone` will ([`bfe2cc9`](https://github.com/dcastil/tailwind-merge/commit/bfe2cc9bb221107fa0bf363cc325ddbb04677f43), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) + - Outline utilities from Tailwind v2 don't get merged anymore since they were replaced by outline width, outline style, outline offset and outline color in Tailwind v3 ([`55ab167`](https://github.com/dcastil/tailwind-merge/commit/55ab167b7167519873c5dd4d258dc62212d1659a), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) + - The classes `overflow-ellipsis` and `overflow-clip` will not get merged with class `truncate` anymore, but the new Tailwind v3 classes `text-ellipsis` and `text-clip` will. ([`65b03e4`](https://github.com/dcastil/tailwind-merge/commit/65b03e48914ac5d7d52eea9ec178b204d30609c9), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) + - The classes `decoration-slice` and `decoration-clone` won't get merged anymore and `box-decoration-slide` nad `box-decoration-clone` will ([`bfe2cc9`](https://github.com/dcastil/tailwind-merge/commit/bfe2cc9bb221107fa0bf363cc325ddbb04677f43), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) -- `getDefaultConfig` +- `getDefaultConfig` - - Removed class group `outline` since it was removed in Tailwind v3 ([`55ab167`](https://github.com/dcastil/tailwind-merge/commit/55ab167b7167519873c5dd4d258dc62212d1659a), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) - - Renamed class group `vertival-alignment` (yes, the typo was in the code) to `vertical-align` ([`1269ce6`](https://github.com/dcastil/tailwind-merge/commit/1269ce68ae39807ceadbecc98c0929fdfdb446d0), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) - - Renamed class groups `flex-basis`, `flex-grow` and `flex-shrink` to `basis`, `grow` and `shrink` to stay consistent with Tailwind v3 ([`e6d8912`](https://github.com/dcastil/tailwind-merge/commit/e6d8912e47bf9a89346b9b0cc822fb2bff2af172), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) + - Removed class group `outline` since it was removed in Tailwind v3 ([`55ab167`](https://github.com/dcastil/tailwind-merge/commit/55ab167b7167519873c5dd4d258dc62212d1659a), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) + - Renamed class group `vertival-alignment` (yes, the typo was in the code) to `vertical-align` ([`1269ce6`](https://github.com/dcastil/tailwind-merge/commit/1269ce68ae39807ceadbecc98c0929fdfdb446d0), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) + - Renamed class groups `flex-basis`, `flex-grow` and `flex-shrink` to `basis`, `grow` and `shrink` to stay consistent with Tailwind v3 ([`e6d8912`](https://github.com/dcastil/tailwind-merge/commit/e6d8912e47bf9a89346b9b0cc822fb2bff2af172), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) -- `validators` - - `isCustomLength` and `isCustomValue` were renamed to `isArbitraryLength` and `isArbitraryValue` to be consistent with naming in Tailwind v3 documentation ([`adc3c02`](https://github.com/dcastil/tailwind-merge/commit/adc3c02c7f035069beec1c62777ec008172587ab), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- `validators` + - `isCustomLength` and `isCustomValue` were renamed to `isArbitraryLength` and `isArbitraryValue` to be consistent with naming in Tailwind v3 documentation ([`adc3c02`](https://github.com/dcastil/tailwind-merge/commit/adc3c02c7f035069beec1c62777ec008172587ab), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) ### New Features -- Add support for Tailwind v3 by [@dcastil](https://github.com/dcastil) in [#63](https://github.com/dcastil/tailwind-merge/pull/63) - - Support for all the new utility classes and variants in Tailwind v3.0.0 - - Support for arbitrary properties like `[--my-var:20px]` - - Support for important modifiers in arbitrary properties like `![--my-very-important-var: 21px]` - - Support for new labels for classes with arbitrary value: `size`, `position`, `url`, `weight` and `family` - - New validators `isTshirtSize`, `isArbitrarySize`, `isArbitraryPosition`, `isArbitraryUrl` and `isArbitraryWeight`, check them out in the [documentation](https://github.com/dcastil/tailwind-merge/tree/v1.0.0#validators)! ([`fec2b18`](https://github.com/dcastil/tailwind-merge/commit/fec2b18870f6806e602009632b52b9fe89ebfb83), [`f8acd7c`](https://github.com/dcastil/tailwind-merge/commit/f8acd7ca5be6cc40ad4c1cbdee7522bbc44c7870), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) +- Add support for Tailwind v3 by [@dcastil](https://github.com/dcastil) in [#63](https://github.com/dcastil/tailwind-merge/pull/63) + - Support for all the new utility classes and variants in Tailwind v3.0.0 + - Support for arbitrary properties like `[--my-var:20px]` + - Support for important modifiers in arbitrary properties like `![--my-very-important-var: 21px]` + - Support for new labels for classes with arbitrary value: `size`, `position`, `url`, `weight` and `family` + - New validators `isTshirtSize`, `isArbitrarySize`, `isArbitraryPosition`, `isArbitraryUrl` and `isArbitraryWeight`, check them out in the [documentation](https://github.com/dcastil/tailwind-merge/tree/v1.0.0#validators)! ([`fec2b18`](https://github.com/dcastil/tailwind-merge/commit/fec2b18870f6806e602009632b52b9fe89ebfb83), [`f8acd7c`](https://github.com/dcastil/tailwind-merge/commit/f8acd7ca5be6cc40ad4c1cbdee7522bbc44c7870), [#63](https://github.com/dcastil/tailwind-merge/pull/63)) **Full Changelog**: [`v0.9.0...v1.0.0`](https://github.com/dcastil/tailwind-merge/compare/v0.9.0...v1.0.0) diff --git a/docs/changelog/v1-to-v2-migration.md b/docs/changelog/v1-to-v2-migration.md index 5461418d..659f6698 100644 --- a/docs/changelog/v1-to-v2-migration.md +++ b/docs/changelog/v1-to-v2-migration.md @@ -1,4 +1,4 @@ -# Guide to migrate from v1 to v2 +# Guide to migrate from tailwind-merge v1 to v2 This document is only about breaking changes between v1 and v2. For a full list of changes, see the [v2.0.0 release](./v2-changelog.md#v200). @@ -10,10 +10,10 @@ Over the past one and a half years since the v1 release, the biggest source of i The highlights: -- No changes to `twMerge` and supported Tailwind CSS versions. -- You can now override class groups with the object notation in `extendTailwindMerge`. -- TypeScript types of configuration object passed to `extendTailwindMerge` are stricter and prevent you from using unknown theme groups and class groups unless specified otherwise. -- The library now exports a bundle using modern JS syntax to further reduce its size. There is also an additional bundle with ES5-only syntax for compatibility with older browsers. +- No changes to `twMerge` and supported Tailwind CSS versions. +- You can now override class groups with the object notation in `extendTailwindMerge`. +- TypeScript types of configuration object passed to `extendTailwindMerge` are stricter and prevent you from using unknown theme groups and class groups unless specified otherwise. +- The library now exports a bundle using modern JS syntax to further reduce its size. There is also an additional bundle with ES5-only syntax for compatibility with older browsers. If you have feedback of any kind regarding this release, feel free to [open an issue or discussion](https://github.com/dcastil/tailwind-merge/issues/new/choose). I'm always happy to hear from you! @@ -21,26 +21,26 @@ If you have feedback of any kind regarding this release, feel free to [open an i By exports: -- All - - [Modern JS syntax](#modern-js-syntax) - - [Module resolution](#module-resolution) -- `extendTailwindMerge` - - [Object shape changed](#extendtailwindmerge-object-shape-changed) - - [Stricter TypeScript types](#extendtailwindmerge-stricter-typescript-types) -- `validators` - - [`isLength`: Does not check for arbitrary values anymore](#validatorsislength-does-not-check-for-arbitrary-values-anymore) - - [`isInteger`: Does not check for arbitrary values anymore](#validatorsisinteger-does-not-check-for-arbitrary-values-anymore) - - [`isArbitraryUrl`: Renamed](#validatorsisarbitraryurl-renamed) - - [`isArbitraryWeight`: Removed](#validatorsisarbitraryweight-removed) -- `createTailwindMerge` - - [Mandatory elements added](#createtailwindmerge-mandatory-elements-added) -- `fromTheme` - - [Stricter TypeScript types](#fromtheme-stricter-typescript-types) -- `mergeConfigs` - - [Object shape changed](#mergeconfigs-object-shape-changed) - - [Stricter TypeScript types](#mergeconfigs-stricter-typescript-types) -- `join` - - [Removed](#join-removed) +- All + - [Modern JS syntax](#modern-js-syntax) + - [Module resolution](#module-resolution) +- `extendTailwindMerge` + - [Object shape changed](#extendtailwindmerge-object-shape-changed) + - [Stricter TypeScript types](#extendtailwindmerge-stricter-typescript-types) +- `validators` + - [`isLength`: Does not check for arbitrary values anymore](#validatorsislength-does-not-check-for-arbitrary-values-anymore) + - [`isInteger`: Does not check for arbitrary values anymore](#validatorsisinteger-does-not-check-for-arbitrary-values-anymore) + - [`isArbitraryUrl`: Renamed](#validatorsisarbitraryurl-renamed) + - [`isArbitraryWeight`: Removed](#validatorsisarbitraryweight-removed) +- `createTailwindMerge` + - [Mandatory elements added](#createtailwindmerge-mandatory-elements-added) +- `fromTheme` + - [Stricter TypeScript types](#fromtheme-stricter-typescript-types) +- `mergeConfigs` + - [Object shape changed](#mergeconfigs-object-shape-changed) + - [Stricter TypeScript types](#mergeconfigs-stricter-typescript-types) +- `join` + - [Removed](#join-removed) ### Modern JS syntax From 93a018fdadb1cf2cd6fb882bce98f2776f06f0be Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:05:40 +0100 Subject: [PATCH 38/48] add v3.0.0 changelog --- docs/changelog/v3-changelog.md | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/changelog/v3-changelog.md diff --git a/docs/changelog/v3-changelog.md b/docs/changelog/v3-changelog.md new file mode 100644 index 00000000..0ae2f617 --- /dev/null +++ b/docs/changelog/v3-changelog.md @@ -0,0 +1,36 @@ +# Changelog for v3 releases + +## v3.0.0 + +[Tailwind CSS v4 is here](https://tailwindcss.com/blog/tailwindcss-v4) and it's time to upgrade tailwind-merge to support it. tailwind-merge v3.0.0 is more accurate than ever and follows the Tailwind CSS spec more closely than in v2. That is thanks to Tailwind CSS v4 being more consistent than ever. + +Check out the [migration guide](./v2-to-v3-migration.md) and if you have any questions, feel free to [create an issue](https://github.com/dcastil/tailwind-merge/issues/new/choose). + +### Breaking Changes + +- Dropping support for Tailwind CSS v3 in favor of support for Tailwind CSS v4 by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- Theme scales keys changed and now match Tailwind CSS v4 theme variable namespace exactly by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- `isLength` validator was removed and split into separate validators `isNumber` and `isFraction` by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- Prefix defined in config shouldn't include combining `-` character anymore by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- Tailwind CSS v3 prefix position in class not supported anymore in favor of Tailwind CSS v4 position by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- New mandatory `orderSensitiveModifiers` property in config when using `createTailwindMerge`, etc. by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- `DefaultThemeGroupIds` type union consists of different string literals than before by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- Classes removed in Tailwind CSS v4 are not supported by tailwind-merge anymore by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) + +### New Features + +- Support for new important modifier position at the end of class by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- Support for arbitrary CSS variable syntax by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- There are a bunch of new validators used by tailwind-merge, primarily for new Tailwind CSS v4 features like arbitrary CSS variables by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) + +### Bug Fixes + +- Previously some order-sensitive modifiers like `before:` were treated as not order-sensitive. This is now fixed by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) + +### Documentation + +- Added section explaining order-sensitive modifiers to [configuration docs](../configuration.md#order-sensitive-modifiers) by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) + +**Full Changelog**: [`v2.6.0...v4.0.0`](https://github.com/dcastil/tailwind-merge/compare/v2.6.0...v4.0.0) + +Thanks to [@brandonmcconnell](https://github.com/brandonmcconnell), [@manavm1990](https://github.com/manavm1990), [@langy](https://github.com/langy), [@jamesreaco](https://github.com/jamesreaco), [@roboflow](https://github.com/roboflow), [@syntaxfm](https://github.com/syntaxfm), [@getsentry](https://github.com/getsentry), [@codecov](https://github.com/codecov), a private sponsor for sponsoring tailwind-merge! ❤️ From deb10e38e4becf957765a89667333c73c1ae581c Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 11:12:32 +0100 Subject: [PATCH 39/48] remove configurable separator from tailwind-merge --- src/lib/default-config.ts | 1 - src/lib/merge-configs.ts | 2 -- src/lib/parse-class-name.ts | 17 +++++-------- src/lib/types.ts | 5 ---- tests/create-tailwind-merge.test.ts | 2 -- tests/merge-configs.test.ts | 3 --- tests/modifiers.test.ts | 2 -- tests/public-api.test.ts | 3 --- tests/separators.test.ts | 37 ----------------------------- tests/type-generics.test.ts | 3 +-- 10 files changed, 7 insertions(+), 68 deletions(-) delete mode 100644 tests/separators.test.ts diff --git a/src/lib/default-config.ts b/src/lib/default-config.ts index fced1b6d..21c9db28 100644 --- a/src/lib/default-config.ts +++ b/src/lib/default-config.ts @@ -189,7 +189,6 @@ export const getDefaultConfig = () => { return { cacheSize: 500, - separator: ':', theme: { animate: ['spin', 'ping', 'pulse', 'bounce'], aspect: ['video'], diff --git a/src/lib/merge-configs.ts b/src/lib/merge-configs.ts index 3b15eea5..10421389 100644 --- a/src/lib/merge-configs.ts +++ b/src/lib/merge-configs.ts @@ -9,7 +9,6 @@ export const mergeConfigs = { overrideProperty(baseConfig, 'cacheSize', cacheSize) overrideProperty(baseConfig, 'prefix', prefix) - overrideProperty(baseConfig, 'separator', separator) overrideProperty(baseConfig, 'experimentalParseClassName', experimentalParseClassName) overrideConfigProperties(baseConfig.theme, override.theme) diff --git a/src/lib/parse-class-name.ts b/src/lib/parse-class-name.ts index 3b41c316..b18a2fe2 100644 --- a/src/lib/parse-class-name.ts +++ b/src/lib/parse-class-name.ts @@ -1,12 +1,11 @@ import { AnyConfig, ParsedClassName } from './types' export const IMPORTANT_MODIFIER = '!' +const MODIFIER_SEPARATOR = ':' +const MODIFIER_SEPARATOR_LENGTH = MODIFIER_SEPARATOR.length export const createParseClassName = (config: AnyConfig) => { - const { prefix, separator, experimentalParseClassName } = config - const isSeparatorSingleCharacter = separator.length === 1 - const firstSeparatorCharacter = separator[0] - const separatorLength = separator.length + const { prefix, experimentalParseClassName } = config /** * Parse class name into parts. @@ -26,13 +25,9 @@ export const createParseClassName = (config: AnyConfig) => { let currentCharacter = className[index] if (bracketDepth === 0 && parenDepth === 0) { - if ( - currentCharacter === firstSeparatorCharacter && - (isSeparatorSingleCharacter || - className.slice(index, index + separatorLength) === separator) - ) { + if (currentCharacter === MODIFIER_SEPARATOR) { modifiers.push(className.slice(modifierStart, index)) - modifierStart = index + separatorLength + modifierStart = index + MODIFIER_SEPARATOR_LENGTH continue } @@ -71,7 +66,7 @@ export const createParseClassName = (config: AnyConfig) => { } if (prefix) { - const fullPrefix = prefix + separator + const fullPrefix = prefix + MODIFIER_SEPARATOR const parseClassNameOriginal = parseClassName parseClassName = (className) => className.startsWith(fullPrefix) diff --git a/src/lib/types.ts b/src/lib/types.ts index 6e09f59f..abf3bb3c 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -20,11 +20,6 @@ interface ConfigStaticPart { * @see https://tailwindcss.com/docs/configuration#prefix */ prefix?: string - /** - * Custom separator for modifiers in Tailwind classes - * @see https://tailwindcss.com/docs/configuration#separator - */ - separator: string /** * Allows to customize parsing of individual classes passed to `twMerge`. * All classes passed to `twMerge` outside of cache hits are passed to this function before it is determined whether the class is a valid Tailwind CSS class. diff --git a/tests/create-tailwind-merge.test.ts b/tests/create-tailwind-merge.test.ts index 7c60844e..5a2b5c65 100644 --- a/tests/create-tailwind-merge.test.ts +++ b/tests/create-tailwind-merge.test.ts @@ -5,7 +5,6 @@ import { createTailwindMerge } from '../src' test('createTailwindMerge works with single config function', () => { const tailwindMerge = createTailwindMerge(() => ({ cacheSize: 20, - separator: ':', theme: {}, classGroups: { fooKey: [{ fooKey: ['bar', 'baz'] }], @@ -47,7 +46,6 @@ test('createTailwindMerge works with multiple config functions', () => { const tailwindMerge = createTailwindMerge( () => ({ cacheSize: 20, - separator: ':', theme: {}, classGroups: { fooKey: [{ fooKey: ['bar', 'baz'] }], diff --git a/tests/merge-configs.test.ts b/tests/merge-configs.test.ts index 724ea6d6..031284f2 100644 --- a/tests/merge-configs.test.ts +++ b/tests/merge-configs.test.ts @@ -8,7 +8,6 @@ test('mergeConfigs has correct behavior', () => { { cacheSize: 50, prefix: 'tw', - separator: ':', theme: { hi: ['ho'], themeToOverride: ['to-override'], @@ -29,7 +28,6 @@ test('mergeConfigs has correct behavior', () => { orderSensitiveModifiers: ['order-1'], }, { - separator: '-', prefix: undefined, override: { theme: { @@ -68,7 +66,6 @@ test('mergeConfigs has correct behavior', () => { ).toEqual({ cacheSize: 50, prefix: 'tw', - separator: '-', theme: { hi: ['ho'], themeToOverride: ['overridden'], diff --git a/tests/modifiers.test.ts b/tests/modifiers.test.ts index 93e16b87..4ebd4fe5 100644 --- a/tests/modifiers.test.ts +++ b/tests/modifiers.test.ts @@ -19,7 +19,6 @@ test('conflicts across postfix modifiers', () => { const customTwMerge = createTailwindMerge(() => ({ cacheSize: 10, - separator: ':', theme: {}, classGroups: { foo: ['foo-1/2', 'foo-2/3'], @@ -51,7 +50,6 @@ test('sorts modifiers correctly', () => { test('sorts modifiers correctly according to orderSensitiveModifiers', () => { const customTwMerge = createTailwindMerge(() => ({ cacheSize: 10, - separator: ':', theme: {}, classGroups: { foo: ['foo-1', 'foo-2'], diff --git a/tests/public-api.test.ts b/tests/public-api.test.ts index db032c46..c1500ff5 100644 --- a/tests/public-api.test.ts +++ b/tests/public-api.test.ts @@ -101,7 +101,6 @@ test('createTailwindMerge() has correct inputs and outputs', () => { expect( createTailwindMerge(() => ({ cacheSize: 0, - separator: ':', theme: {}, classGroups: {}, conflictingClassGroups: {}, @@ -112,7 +111,6 @@ test('createTailwindMerge() has correct inputs and outputs', () => { const tailwindMerge = createTailwindMerge(() => ({ cacheSize: 20, - separator: ':', theme: {}, classGroups: { fooKey: [{ fooKey: ['bar', 'baz'] }], @@ -180,7 +178,6 @@ test('mergeConfigs has correct inputs and outputs', () => { mergeConfigs( { cacheSize: 50, - separator: ':', theme: {}, classGroups: { fooKey: [{ fooKey: ['one', 'two'] }], diff --git a/tests/separators.test.ts b/tests/separators.test.ts deleted file mode 100644 index 0064a91e..00000000 --- a/tests/separators.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { expect, test } from 'vitest' - -import { extendTailwindMerge } from '../src' - -test('single character separator working correctly', () => { - const twMerge = extendTailwindMerge({ - separator: '_', - }) - - expect(twMerge('block hidden')).toBe('hidden') - - expect(twMerge('p-3 p-2')).toBe('p-2') - - expect(twMerge('!right-0 !inset-0')).toBe('!inset-0') - - expect(twMerge('hover_focus_!right-0 focus_hover_!inset-0')).toBe('focus_hover_!inset-0') - expect(twMerge('hover:focus:!right-0 focus:hover:!inset-0')).toBe( - 'hover:focus:!right-0 focus:hover:!inset-0', - ) -}) - -test('multiple character separator working correctly', () => { - const twMerge = extendTailwindMerge({ - separator: '__', - }) - - expect(twMerge('block hidden')).toBe('hidden') - - expect(twMerge('p-3 p-2')).toBe('p-2') - - expect(twMerge('!right-0 !inset-0')).toBe('!inset-0') - - expect(twMerge('hover__focus__!right-0 focus__hover__!inset-0')).toBe('focus__hover__!inset-0') - expect(twMerge('hover:focus:!right-0 focus:hover:!inset-0')).toBe( - 'hover:focus:!right-0 focus:hover:!inset-0', - ) -}) diff --git a/tests/type-generics.test.ts b/tests/type-generics.test.ts index 647cc8e0..3fbd04a0 100644 --- a/tests/type-generics.test.ts +++ b/tests/type-generics.test.ts @@ -101,7 +101,6 @@ test('mergeConfigs type generics work correctly', () => { { cacheSize: 50, prefix: 'tw', - separator: ':', theme: { hi: ['ho'], themeToOverride: ['to-override'], @@ -119,9 +118,9 @@ test('mergeConfigs type generics work correctly', () => { hello: ['world'], toOverride: ['groupToOverride-2'], }, + orderSensitiveModifiers: [], }, { - separator: '-', prefix: undefined, override: { theme: { From 752b103bdfcbcf71e7a5cc0d09035b4a80114c5b Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 11:13:48 +0100 Subject: [PATCH 40/48] remove separator from docs --- docs/api-reference.md | 2 -- docs/configuration.md | 2 -- 2 files changed, 4 deletions(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 0dc147f8..26c17f12 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -124,8 +124,6 @@ const twMerge = extendTailwindMerge Date: Thu, 30 Jan 2025 11:17:44 +0100 Subject: [PATCH 41/48] add removed custom separator support to breaking changes in v3 changelog --- docs/changelog/v3-changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog/v3-changelog.md b/docs/changelog/v3-changelog.md index 0ae2f617..68c59535 100644 --- a/docs/changelog/v3-changelog.md +++ b/docs/changelog/v3-changelog.md @@ -13,6 +13,7 @@ Check out the [migration guide](./v2-to-v3-migration.md) and if you have any que - `isLength` validator was removed and split into separate validators `isNumber` and `isFraction` by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - Prefix defined in config shouldn't include combining `-` character anymore by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - Tailwind CSS v3 prefix position in class not supported anymore in favor of Tailwind CSS v4 position by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- Custom separators are no longer supported by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - New mandatory `orderSensitiveModifiers` property in config when using `createTailwindMerge`, etc. by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - `DefaultThemeGroupIds` type union consists of different string literals than before by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - Classes removed in Tailwind CSS v4 are not supported by tailwind-merge anymore by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) From 1950ab624e1ab41f343bc821d156e3f2534e8598 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 16:37:04 +0100 Subject: [PATCH 42/48] add migration doc for tailwind-merge v3 --- docs/changelog/v2-to-v3-migration.md | 212 +++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 docs/changelog/v2-to-v3-migration.md diff --git a/docs/changelog/v2-to-v3-migration.md b/docs/changelog/v2-to-v3-migration.md new file mode 100644 index 00000000..df27e569 --- /dev/null +++ b/docs/changelog/v2-to-v3-migration.md @@ -0,0 +1,212 @@ +# Guide to migrate from tailwind-merge v2 to v3 + +This document is only about breaking changes between v2 and v3. For a full list of changes, see the [v3.0.0 release](./v3-changelog.md#v300). + +## Overview + +tailwind-merge v3 drops support for Tailwind CSS v3 and in turn adds support for Tailwind CSS v4. That means you should upgrade to Tailwind CSS v4 and tailwind-merge v3 together. All breaking changes are related to the Tailwind CSS v4 support. + +The highlights: + +- No breaking changes to `twMerge` other than it expecting classes supported in Tailwind CSS v4. +- The `theme` scales tailwind-merge supports were changed and now match the Tailwind CSS v4 [theme variable namespace](https://tailwindcss.com/docs/theme#theme-variable-namespaces). + +If you have feedback of any kind regarding this release, feel free to [open an issue or discussion](https://github.com/dcastil/tailwind-merge/issues/new/choose). I'm always happy to hear from you! + +## Breaking changes + +By exports: + +- All + - [Supported Tailwind CSS version range changes from v3 to v4](#supported-tailwind-css-version-range-changes-from-v3-to-v4) +- `extendTailwindMerge` + - [Allowed theme keys changed](#extendtailwindmerge-allowed-theme-keys-changed) + - [Custom separators are no longer supported](#extendtailwindmerge-and-createtailwindmerge-custom-separators-are-no-longer-supported) + - [Prefix defined in config shouldn't include combining character anymore](#extendtailwindmerge-and-createtailwindmerge-prefix-defined-in-config-shouldnt-include-combining-character-anymore) +- `createTailwindMerge` + - [Custom separators are no longer supported](#extendtailwindmerge-and-createtailwindmerge-custom-separators-are-no-longer-supported) + - [Prefix defined in config shouldn't include combining character anymore](#extendtailwindmerge-and-createtailwindmerge-prefix-defined-in-config-shouldnt-include-combining-character-anymore) + - [Mandatory field `orderSensitiveModifiers` added](#createtailwindmerge-mandatory-field-ordersensitivemodifiers-added) +- `validators` + - [`isLength`: Removed](#validatorsislength-removed) +- `DefaultThemeGroupIds` + - [Type union changed literals](#defaultthemegroupids-type-union-changed-literals) + +### Supported Tailwind CSS version range changes from v3 to v4 + +tailwind-merge v3.0.0 is expected to be used together with Tailwind CSS v4. That means only features that work in Tailwind CSS v4 are supported. If you intend to stay on Tailwind CSS v3, don't upgrade to tailwind-merge v3.0.0 because there are some breaking changes in expected class syntax. + +### `extendTailwindMerge`: Allowed theme keys changed + +In Tailwind CSS v3 tailwind-merge was in a difficult position with the Tailwind's theme scales. If tailwind-merge implemented support for all theme scales, the bundle size would become twice as large. If it didn't support any theme scales, users would have had a difficult time extending scales that are used in many class groups, like in the case of the `spacing` scale. tailwind-merge went with an awkward middle ground where it only supported theme scales that were used in multiple class groups. + +Tailwind CSS v4 reduced the number of theme scales to only 18 (called [theme variable namespaces](https://tailwindcss.com/docs/theme#theme-variable-namespaces) now) which makes it possible for tailwind-merge to support all of them. + +That means if you add the CSS variable `--inset-shadow-deep` to your Tailwind CSS theme, you can add it to the `theme` object in tailwind-merge like in the following example: + +```ts +import { extendTailwindMerge } from 'tailwind-merge' + +const twMerge = extendTailwindMerge({ + extend: { + theme: { + 'inset-shadow': ['deep'], + }, + }, +}) +``` + +#### Upgrade + +Here's how to proceed with upgrading each individual theme scale that got removed or renamed. Just keep in mind that theme scales should only define the custom part of a class (i.e. `deep` for the class `inset-shadow-deep`) whereas class groups should define the whole class (i.e. `inset-shadow-deep` for the class `inset-shadow-deep`). Sometimes you might find that values you configured manually before are now supported by Tailwind CSS v4 by default in which case you can remove them from your tailwind-merge config. + +- `borderColor`: Use the theme scale `color` instead +- `borderRadius`: Use the theme scale `radius` instead +- `borderSpacing`: Use the theme scale `spacing` or class groups `border-spacing-*` instead +- `borderWidth`: Use the class groups `border-w-*` instead +- `brightness`: Use the class groups `brightness` and `backdrop-brightness` instead +- `colors`: Use the theme scale `color` instead +- `contrast`: Use the class groups `contrast` and `backdrop-contrast` instead +- `gap`: Use the class groups `gap-*` instead +- `gradientColorStopPositions`: Use the class groups `gradient-from-pos`, `gradient-via-pos` and `gradient-to-pos` instead +- `gradientColorStops`: Use the class groups `gradient-from`, `gradient-via` and `gradient-to` instead +- `grayscale`: Use the class groups `grayscale` and `backdrop-grayscale` instead +- `hueRotate`: Use the class groups `hue-rotate` and `backdrop-hue-rotate` instead +- `inset`: Use the theme scale `spacing` or class groups `inset-*` instead +- `invert`: Use the class groups `invert` and `backdrop-invert` instead +- `margin`: Use the theme scale `spacing` or class groups `m-*` instead +- `opacity`: Use class groups `opacity` and `backdrop-opacity` instead +- `padding`: Use the theme scale `spacing` or class groups `p-*` instead +- `saturate`: use the class groups `saturate` and `backdrop-saturate` instead +- `scale`: Use the class groups `scale-*` instead +- `sepia`: Use the class groups `sepia` and `backdrop-sepia` instead +- `skew`: use the class groups `skew-*` instead +- `space`: Use the theme scale `spacing` or class groups `space-*` instead +- `translate`: Use the theme scale `spacing` or class groups `translate-*` instead + +In case you were modifying class groups in tailwind-merge v2 because their theme scale was previously not implemented, it is highly likely that you can move those definitions to the `theme` object in tailwind-merge v3. E.g. if you previously modified the `font-family` class group to add a custom font class, you can now use `theme.font` instead. Check out the [theme documentation](../configuration.md#theme) for more info. + +### `extendTailwindMerge` and `createTailwindMerge`: Custom separators are no longer supported + +Tailwind CSS v4 removed support for custom separators for modifiers in Tailwind CSS classes and now only the default separator `:` is allowed. Therefore tailwind-merge also removed support for custom separators and doesn't use the `separator` key in its config anymore. If you use TypeScript, you'll see a type error if you try to use the `separator` key in your config. + +#### Upgrade + +Remove the `separator` key from your tailwind-merge config. + +```diff + import { extendTailwindMerge } from 'tailwind-merge' + + const twMerge = extendTailwindMerge({ +- separator: '_', + … + }) +``` + +```diff + import { createTailwindMerge } from 'tailwind-merge' + + const twMerge = createTailwindMerge(() => ({ +- separator: '_', + … + })) +``` + +### `extendTailwindMerge` and `createTailwindMerge`: Prefix defined in config shouldn't include combining character anymore + +In Tailwind CSS v4 the optional prefix syntax of classes changed from being in front of the base class like in `hover:*:tw-class` to looking like the first modifier of a class like in `tw:hover:*:class`. + +In tailwind-merge v2 you had to specify the prefix including the final dash character `-` that combined the prefix with the base class. Due to the new syntax this combining character changes to `:`. To prevent having to change your config if the combining character changes in the future, tailwind-merge v3 expects you to specify the prefix without the combining character. + +#### Upgrade + +Remove the dash character from the prefix in your tailwind-merge config. + +```diff + import { extendTailwindMerge } from 'tailwind-merge' + + const twMerge = extendTailwindMerge({ +- prefix: 'tw-', ++ prefix: 'tw', + … + }) +``` + +```diff + import { createTailwindMerge } from 'tailwind-merge' + + const twMerge = createTailwindMerge(() => ({ +- prefix: 'tw-', ++ prefix: 'tw', + … + })) +``` + +### `createTailwindMerge`: Mandatory field `orderSensitiveModifiers` added + +tailwind-merge v3 adds a new mandatory field `orderSensitiveModifiers` to the config to specify which modifiers should be considered order-sensitive. Learn more about order-sensitive modifiers in the [documentation](../configuration.md#order-sensitive-modifiers). + +#### Minimal upgrade + +Add the `orderSensitiveModifiers` field to your tailwind-merge config. + +```diff + import { createTailwindMerge } from 'tailwind-merge' + + const twMerge = createTailwindMerge(() => ({ ++ orderSensitiveModifiers: [], + … + })) +``` + +#### Full upgrade + +If you have any order-sensitive modifiers in Tailwind, ddd them to the new `orderSensitiveModifiers` field in your tailwind-merge config. + +```diff + import { createTailwindMerge } from 'tailwind-merge' + + const twMerge = createTailwindMerge(() => ({ + … ++ orderSensitiveModifiers: ['before', '*', …], + })) +``` + +### `validators.isLength`: Removed + +The validator `isLength` was used to check whether a class part is a number (`3`, `1.5`), a fraction (`3/4`), or one of the strings `px`, `full` or `screen`. This was used for most length-based scales but the name was not really precise in explaining what it allows. + +Due to how length-based scales were changed in Tailwind CSS v4, tailwind-merge v3 now uses `isNumber` and `isFraction` instead depending on what each scale supports and strings like `px`, `full` and `screen` are instead specified manually in the scales themselves. That makes it more obvious what those validators do. + +#### Minimal upgrade + +You can rebuild the previous validator yourself. + +```ts +import { validators } from 'tailwind-merge' + +function isLength(value: string) { + return ( + validators.isNumber(value) || + validators.isFraction(value) || + value === 'full' || + value === 'px' || + value === 'screen' + ) +} +``` + +#### Full upgrade + +Replace all uses of `validators.isLength` with `validators.isNumber`, `validators.isFraction` and the strings `full`, `px` and `screen` depending on which of those your scale supports. + +```diff + import { validators } from 'tailwind-merge' + +- [validators.isLength] ++ [validators.isNumber, validators.isFraction, 'full', 'px', 'screen'] +``` + +### `DefaultThemeGroupIds`: Type union changed literals + +Due to the default theme keys changing, the string union of `DefaultThemeGroupIds` changed as well. Since this is a TypeScript type, errors in TypeScript will determine how to handle this change. From 7f043a6e1f753e2239643e4738f76612f8ea021f Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 17:08:55 +0100 Subject: [PATCH 43/48] small tweaks --- docs/changelog/v2-to-v3-migration.md | 54 ++++++++++++++-------------- docs/changelog/v3-changelog.md | 2 +- docs/configuration.md | 2 +- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/docs/changelog/v2-to-v3-migration.md b/docs/changelog/v2-to-v3-migration.md index df27e569..a012e53b 100644 --- a/docs/changelog/v2-to-v3-migration.md +++ b/docs/changelog/v2-to-v3-migration.md @@ -38,7 +38,7 @@ tailwind-merge v3.0.0 is expected to be used together with Tailwind CSS v4. That ### `extendTailwindMerge`: Allowed theme keys changed -In Tailwind CSS v3 tailwind-merge was in a difficult position with the Tailwind's theme scales. If tailwind-merge implemented support for all theme scales, the bundle size would become twice as large. If it didn't support any theme scales, users would have had a difficult time extending scales that are used in many class groups, like in the case of the `spacing` scale. tailwind-merge went with an awkward middle ground where it only supported theme scales that were used in multiple class groups. +In Tailwind CSS v3 tailwind-merge was in a difficult position with Tailwind's theme scales. If tailwind-merge implemented support for all theme scales, the bundle size would become twice as large. If it didn't support any theme scales, users would have had a difficult time extending scales that are used in many class groups, like in the case of the `spacing` scale. tailwind-merge went with an awkward middle ground where it only supported theme scales that were used in multiple class groups. Tailwind CSS v4 reduced the number of theme scales to only 18 (called [theme variable namespaces](https://tailwindcss.com/docs/theme#theme-variable-namespaces) now) which makes it possible for tailwind-merge to support all of them. @@ -60,29 +60,31 @@ const twMerge = extendTailwindMerge({ Here's how to proceed with upgrading each individual theme scale that got removed or renamed. Just keep in mind that theme scales should only define the custom part of a class (i.e. `deep` for the class `inset-shadow-deep`) whereas class groups should define the whole class (i.e. `inset-shadow-deep` for the class `inset-shadow-deep`). Sometimes you might find that values you configured manually before are now supported by Tailwind CSS v4 by default in which case you can remove them from your tailwind-merge config. -- `borderColor`: Use the theme scale `color` instead -- `borderRadius`: Use the theme scale `radius` instead -- `borderSpacing`: Use the theme scale `spacing` or class groups `border-spacing-*` instead -- `borderWidth`: Use the class groups `border-w-*` instead -- `brightness`: Use the class groups `brightness` and `backdrop-brightness` instead -- `colors`: Use the theme scale `color` instead -- `contrast`: Use the class groups `contrast` and `backdrop-contrast` instead -- `gap`: Use the class groups `gap-*` instead -- `gradientColorStopPositions`: Use the class groups `gradient-from-pos`, `gradient-via-pos` and `gradient-to-pos` instead -- `gradientColorStops`: Use the class groups `gradient-from`, `gradient-via` and `gradient-to` instead -- `grayscale`: Use the class groups `grayscale` and `backdrop-grayscale` instead -- `hueRotate`: Use the class groups `hue-rotate` and `backdrop-hue-rotate` instead -- `inset`: Use the theme scale `spacing` or class groups `inset-*` instead -- `invert`: Use the class groups `invert` and `backdrop-invert` instead -- `margin`: Use the theme scale `spacing` or class groups `m-*` instead -- `opacity`: Use class groups `opacity` and `backdrop-opacity` instead -- `padding`: Use the theme scale `spacing` or class groups `p-*` instead -- `saturate`: use the class groups `saturate` and `backdrop-saturate` instead -- `scale`: Use the class groups `scale-*` instead -- `sepia`: Use the class groups `sepia` and `backdrop-sepia` instead -- `skew`: use the class groups `skew-*` instead -- `space`: Use the theme scale `spacing` or class groups `space-*` instead -- `translate`: Use the theme scale `spacing` or class groups `translate-*` instead +| Theme scale in tailwind-merge v2 | What to use in tailwind-merge v3 instead | +| -------------------------------- | -------------------------------------------------------------------------- | +| `borderColor` | theme scale `color` | +| `borderRadius` | theme scale `radius` | +| `borderSpacing` | theme scale `spacing` or class groups `border-spacing-*` | +| `borderWidth` | class groups `border-w-*` | +| `brightness` | class groups `brightness` and `backdrop-brightness` | +| `colors` | theme scale `color` | +| `contrast` | class groups `contrast` and `backdrop-contrast` | +| `gap` | class groups `gap-*` | +| `gradientColorStopPositions` | class groups `gradient-from-pos`, `gradient-via-pos` and `gradient-to-pos` | +| `gradientColorStops` | class groups `gradient-from`, `gradient-via` and `gradient-to` | +| `grayscale` | class groups `grayscale` and `backdrop-grayscale` | +| `hueRotate` | class groups `hue-rotate` and `backdrop-hue-rotate` | +| `inset` | theme scale `spacing` or class groups `inset-*` | +| `invert` | class groups `invert` and `backdrop-invert` | +| `margin` | theme scale `spacing` or class groups `m-*` | +| `opacity` | class groups `opacity` and `backdrop-opacity` | +| `padding` | theme scale `spacing` or class groups `p-*` | +| `saturate` | class groups `saturate` and `backdrop-saturate` | +| `scale` | class groups `scale-*` | +| `sepia` | class groups `sepia` and `backdrop-sepia` | +| `skew` | class groups `skew-*` | +| `space` | theme scale `spacing` or class groups `space-*` | +| `translate` | theme scale `spacing` or class groups `translate-*` | In case you were modifying class groups in tailwind-merge v2 because their theme scale was previously not implemented, it is highly likely that you can move those definitions to the `theme` object in tailwind-merge v3. E.g. if you previously modified the `font-family` class group to add a custom font class, you can now use `theme.font` instead. Check out the [theme documentation](../configuration.md#theme) for more info. @@ -161,7 +163,7 @@ Add the `orderSensitiveModifiers` field to your tailwind-merge config. #### Full upgrade -If you have any order-sensitive modifiers in Tailwind, ddd them to the new `orderSensitiveModifiers` field in your tailwind-merge config. +If you have any order-sensitive modifiers in Tailwind, add them to the new `orderSensitiveModifiers` field in your tailwind-merge config. ```diff import { createTailwindMerge } from 'tailwind-merge' @@ -176,7 +178,7 @@ If you have any order-sensitive modifiers in Tailwind, ddd them to the new `orde The validator `isLength` was used to check whether a class part is a number (`3`, `1.5`), a fraction (`3/4`), or one of the strings `px`, `full` or `screen`. This was used for most length-based scales but the name was not really precise in explaining what it allows. -Due to how length-based scales were changed in Tailwind CSS v4, tailwind-merge v3 now uses `isNumber` and `isFraction` instead depending on what each scale supports and strings like `px`, `full` and `screen` are instead specified manually in the scales themselves. That makes it more obvious what those validators do. +Due to how length-based scales were changed in Tailwind CSS v4, tailwind-merge v3 now uses `isNumber` and `isFraction` instead depending on what each scale supports and strings like `px`, `full` and `screen` are instead specified manually in the scales themselves. This makes it more obvious what those validators do. #### Minimal upgrade diff --git a/docs/changelog/v3-changelog.md b/docs/changelog/v3-changelog.md index 68c59535..7e6d2eba 100644 --- a/docs/changelog/v3-changelog.md +++ b/docs/changelog/v3-changelog.md @@ -14,7 +14,7 @@ Check out the [migration guide](./v2-to-v3-migration.md) and if you have any que - Prefix defined in config shouldn't include combining `-` character anymore by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - Tailwind CSS v3 prefix position in class not supported anymore in favor of Tailwind CSS v4 position by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - Custom separators are no longer supported by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) -- New mandatory `orderSensitiveModifiers` property in config when using `createTailwindMerge`, etc. by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) +- New mandatory `orderSensitiveModifiers` property in config when using `createTailwindMerge` by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - `DefaultThemeGroupIds` type union consists of different string literals than before by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) - Classes removed in Tailwind CSS v4 are not supported by tailwind-merge anymore by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) diff --git a/docs/configuration.md b/docs/configuration.md index b8ab799b..e858a1d9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -143,7 +143,7 @@ In Tailwind CSS, not all modifiers behave the same when you stack them. In most cases the order of modifiers doesn't matter. E.g. `hover:focus:bg-red-500` and `focus:hover:bg-red-500` behave the same and in the context of tailwind-merge, you'd want them both to override each other. tailwind-merge sorts the modifiers internally to be able to override classes with the same modifiers, even if they are in a different order. -However, there are some modifiers where the order matters, e.g. the direct children modifier `*`. The class `*:hover:text-red-500` modifies the text color of a child if that child is hovered, but the class `hover:*:text-red-500` modifies the text color of all direct children if the parent is hovered. In this case, you would want tailwind-merge to preserve both classes although they have the same modifiers, just in a different order. +However, there are some modifiers where the order matters, e.g. the direct children modifier `*`. The class `*:hover:text-red-500` modifies the text color of a child if that particular child is hovered, but the class `hover:*:text-red-500` modifies the text color of all direct children if the parent is hovered. In this case, you would want tailwind-merge to preserve both classes although they have the same modifiers, just in a different order. To know which modifiers are order-sensitive, tailwind-merge has the `orderSensitiveModifiers` property in its config. `twMerge` is pre-configured with all the order-sensitive modifiers that Tailwind CSS has by default. You'll only need to configure this property if you add your own order-sensitive modifiers or change the meaning of the default order-sensitive modifiers. From a00a8e64b18ebe3746a0b8e50ebb8068f3c0c50a Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:10:28 +0100 Subject: [PATCH 44/48] change label added to new issues to context-v3 --- .github/workflows/label.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index a87abd6c..ef7c9fa7 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -21,7 +21,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO_OWNER: ${{ github.repository_owner }} REPO_NAME: ${{ github.event.repository.name }} - LABEL_NAME: context-v2 + LABEL_NAME: context-v3 steps: - name: Checkout repository From 7378c16adcc261599fa2debe8c18d77071c946f4 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:10:54 +0100 Subject: [PATCH 45/48] v3.0.0 --- README.md | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c4acee9f..0129ca58 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ @@ -25,14 +25,14 @@ twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]') ## Get started -- [What is it for](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/what-is-it-for.md) -- [When and how to use it](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/when-and-how-to-use-it.md) -- [Features](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/features.md) -- [Limitations](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/limitations.md) -- [Configuration](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/configuration.md) -- [Recipes](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/recipes.md) -- [API reference](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/api-reference.md) -- [Writing plugins](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/writing-plugins.md) -- [Versioning](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/versioning.md) -- [Contributing](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/contributing.md) -- [Similar packages](https://github.com/dcastil/tailwind-merge/tree/v2.6.0/docs/similar-packages.md) +- [What is it for](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/what-is-it-for.md) +- [When and how to use it](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/when-and-how-to-use-it.md) +- [Features](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/features.md) +- [Limitations](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/limitations.md) +- [Configuration](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/configuration.md) +- [Recipes](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/recipes.md) +- [API reference](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/api-reference.md) +- [Writing plugins](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/writing-plugins.md) +- [Versioning](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/versioning.md) +- [Contributing](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/contributing.md) +- [Similar packages](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/similar-packages.md) diff --git a/package.json b/package.json index 597ea308..cda3176c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tailwind-merge", - "version": "2.6.0", + "version": "3.0.0", "description": "Merge Tailwind CSS classes without style conflicts", "keywords": [ "tailwindcss", From e22885e41e1661f1493f9bf6fb829cfbe1b50281 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:18:00 +0100 Subject: [PATCH 46/48] fix link in v3 changelog --- docs/changelog/v3-changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog/v3-changelog.md b/docs/changelog/v3-changelog.md index 7e6d2eba..d7480e0a 100644 --- a/docs/changelog/v3-changelog.md +++ b/docs/changelog/v3-changelog.md @@ -32,6 +32,6 @@ Check out the [migration guide](./v2-to-v3-migration.md) and if you have any que - Added section explaining order-sensitive modifiers to [configuration docs](../configuration.md#order-sensitive-modifiers) by [@dcastil](https://github.com/dcastil) in [#518](https://github.com/dcastil/tailwind-merge/pull/518) -**Full Changelog**: [`v2.6.0...v4.0.0`](https://github.com/dcastil/tailwind-merge/compare/v2.6.0...v4.0.0) +**Full Changelog**: [`v2.6.0...v3.0.0`](https://github.com/dcastil/tailwind-merge/compare/v2.6.0...v3.0.0) -Thanks to [@brandonmcconnell](https://github.com/brandonmcconnell), [@manavm1990](https://github.com/manavm1990), [@langy](https://github.com/langy), [@jamesreaco](https://github.com/jamesreaco), [@roboflow](https://github.com/roboflow), [@syntaxfm](https://github.com/syntaxfm), [@getsentry](https://github.com/getsentry), [@codecov](https://github.com/codecov), a private sponsor for sponsoring tailwind-merge! ❤️ +Thanks to [@brandonmcconnell](https://github.com/brandonmcconnell), [@manavm1990](https://github.com/manavm1990), [@langy](https://github.com/langy), [@jamesreaco](https://github.com/jamesreaco), [@roboflow](https://github.com/roboflow), [@syntaxfm](https://github.com/syntaxfm), [@getsentry](https://github.com/getsentry), [@codecov](https://github.com/codecov) and a private sponsor for sponsoring tailwind-merge! ❤️ From b9c136df358ef6012f23bf08258dbf970c0aec43 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:21:13 +0100 Subject: [PATCH 47/48] update info about supported Tailwind CSS version in README --- docs/README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/README.md b/docs/README.md index 48c351f6..75bafea1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,21 +16,21 @@ twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]') // → 'hover:bg-dark-red p-3 bg-[#B91C1C]' ``` -- Supports Tailwind v3.0 up to v3.4 (if you use Tailwind v2, use [tailwind-merge v0.9.0](https://github.com/dcastil/tailwind-merge/tree/v0.9.0)) -- Works in all modern browsers and maintained Node versions -- Fully typed -- [Check bundle size on Bundlephobia](https://bundlephobia.com/package/tailwind-merge) +- Supports Tailwind v4.0 (if you use Tailwind v3, use [tailwind-merge v2.6.0](https://github.com/dcastil/tailwind-merge/tree/v2.6.0)) +- Works in all modern browsers and maintained Node versions +- Fully typed +- [Check bundle size on Bundlephobia](https://bundlephobia.com/package/tailwind-merge) ## Get started -- [What is it for](./what-is-it-for.md) -- [When and how to use it](./when-and-how-to-use-it.md) -- [Features](./features.md) -- [Limitations](./limitations.md) -- [Configuration](./configuration.md) -- [Recipes](./recipes.md) -- [API reference](./api-reference.md) -- [Writing plugins](./writing-plugins.md) -- [Versioning](./versioning.md) -- [Contributing](./contributing.md) -- [Similar packages](./similar-packages.md) +- [What is it for](./what-is-it-for.md) +- [When and how to use it](./when-and-how-to-use-it.md) +- [Features](./features.md) +- [Limitations](./limitations.md) +- [Configuration](./configuration.md) +- [Recipes](./recipes.md) +- [API reference](./api-reference.md) +- [Writing plugins](./writing-plugins.md) +- [Versioning](./versioning.md) +- [Contributing](./contributing.md) +- [Similar packages](./similar-packages.md) From 493fa8c11046249332aa42e9269affdb786023a1 Mon Sep 17 00:00:00 2001 From: Dany Castillo <31006608+dcastil@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:21:37 +0100 Subject: [PATCH 48/48] v3.0.1 --- README.md | 32 ++++++++++++++++---------------- package.json | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 0129ca58..d721cb7e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ @@ -18,21 +18,21 @@ twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]') // → 'hover:bg-dark-red p-3 bg-[#B91C1C]' ``` -- Supports Tailwind v3.0 up to v3.4 (if you use Tailwind v2, use [tailwind-merge v0.9.0](https://github.com/dcastil/tailwind-merge/tree/v0.9.0)) -- Works in all modern browsers and maintained Node versions -- Fully typed -- [Check bundle size on Bundlephobia](https://bundlephobia.com/package/tailwind-merge) +- Supports Tailwind v4.0 (if you use Tailwind v3, use [tailwind-merge v2.6.0](https://github.com/dcastil/tailwind-merge/tree/v2.6.0)) +- Works in all modern browsers and maintained Node versions +- Fully typed +- [Check bundle size on Bundlephobia](https://bundlephobia.com/package/tailwind-merge) ## Get started -- [What is it for](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/what-is-it-for.md) -- [When and how to use it](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/when-and-how-to-use-it.md) -- [Features](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/features.md) -- [Limitations](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/limitations.md) -- [Configuration](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/configuration.md) -- [Recipes](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/recipes.md) -- [API reference](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/api-reference.md) -- [Writing plugins](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/writing-plugins.md) -- [Versioning](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/versioning.md) -- [Contributing](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/contributing.md) -- [Similar packages](https://github.com/dcastil/tailwind-merge/tree/v3.0.0/docs/similar-packages.md) +- [What is it for](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/what-is-it-for.md) +- [When and how to use it](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/when-and-how-to-use-it.md) +- [Features](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/features.md) +- [Limitations](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/limitations.md) +- [Configuration](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/configuration.md) +- [Recipes](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/recipes.md) +- [API reference](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/api-reference.md) +- [Writing plugins](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/writing-plugins.md) +- [Versioning](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/versioning.md) +- [Contributing](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/contributing.md) +- [Similar packages](https://github.com/dcastil/tailwind-merge/tree/v3.0.1/docs/similar-packages.md) diff --git a/package.json b/package.json index cda3176c..9e6e01c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tailwind-merge", - "version": "3.0.0", + "version": "3.0.1", "description": "Merge Tailwind CSS classes without style conflicts", "keywords": [ "tailwindcss",