diff --git a/package.json b/package.json index aa1519d..12ad1d6 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,11 @@ "start": "vinxi start", "version": "vinxi version" }, + "pnpm": { + "overrides": { + "package-manager-detector": "0.2.8" + } + }, "dependencies": { "@ark-ui/solid": "5.28.0", "@solidjs/meta": "0.29.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa7f844..23d9ed0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + package-manager-detector: 0.2.8 + importers: .: @@ -19,13 +22,13 @@ importers: version: 0.15.4(solid-js@1.9.10) '@solidjs/start': specifier: 1.2.0 - version: 1.2.0(solid-js@1.9.10)(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1))(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)) + version: 1.2.0(solid-js@1.9.10)(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1))(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)) solid-js: specifier: 1.9.10 version: 1.9.10 vinxi: specifier: 0.5.8 - version: 0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1) + version: 0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1) devDependencies: '@biomejs/biome': specifier: 2.3.6 @@ -488,9 +491,15 @@ packages: '@pandacss/config@1.5.1': resolution: {integrity: sha512-aO+YVRlccLXuFC30DEO9ZDkvXwjbCXk1blIpii8PuclTAR0+YPq8xXVRTVK3fR3MiA0zROca8nAf5Kb+wHVKPw==} + '@pandacss/config@1.6.1': + resolution: {integrity: sha512-rcNJCIrBLXYSFyZ49cAmkAlgQCFPAKCsQfEuNHuv7KTuL+qyykpTcaN20ZQ3sXT/0mxM+bSzhlTye/wI5zngBw==} + '@pandacss/core@1.5.1': resolution: {integrity: sha512-okuvSm5o0gmQmkpLONH4ReqgBVOMMsfb9MyK8vpcZUpzvMBiraVcgsbLxKQyHlmVDZNbKLLokIycb8KEpqtIDQ==} + '@pandacss/core@1.6.1': + resolution: {integrity: sha512-k4hDOX0illxlZfrOLgTJD1qk4aKLCW7ppLdZvKZdd1VrxFIla3wurtwAQ42D1bP13LST2dnAUus+fmymQNw3zw==} + '@pandacss/dev@1.5.1': resolution: {integrity: sha512-U1NWO3ZgOLlABtDk6MMQwTNYOCiUtUg+HEoHPdEExLzNn+20mrLf1IZWJyn4zXKSpANGSi79EV7X4yxPa+W+MA==} hasBin: true @@ -501,12 +510,15 @@ packages: '@pandacss/generator@1.5.1': resolution: {integrity: sha512-kijxpjpvRQBz16BiBcghknthsdmVxSJD5C71jlcM4aVeqoZSCWDNcmlL/2SSCMy7oC6HANu2oRXS/L1YgYzHGA==} - '@pandacss/is-valid-prop@1.5.1': - resolution: {integrity: sha512-AlOt+MqqwDlIdVEdW6wEtvDmX8MmPv004oD+7tdGN54HKpD9jqrwPwwS9p7YQ7nai631JlyladshFHqe1xl7+w==} + '@pandacss/is-valid-prop@1.6.1': + resolution: {integrity: sha512-adOSTq2JekBkvblToblRtrGjEJUxDTH40HTo5Lm5+l2jygKIb1fXHgwRG6JnO/z1QIA4DaCZftMRyVcOfQhagQ==} '@pandacss/logger@1.5.1': resolution: {integrity: sha512-jC835vvSGIOxCZcqXH1alXdzO/ThUCE3HXGjt17mGli/QiVT3b/v83n/Cfz0wiHP3zSUlwVYaPAlXryepsQNWA==} + '@pandacss/logger@1.6.1': + resolution: {integrity: sha512-RJEErjZm2V5wiywZZ4+FfaMwC+boQGDRysvUeC5NYy7SmN8/B9r5JaRO2UBMuYPtmihXI1+WqV74hhrxWBoK4A==} + '@pandacss/node@1.5.1': resolution: {integrity: sha512-qgiydokbjWcSqzsuCP1LR91IOLs7JgsMJkgAbEim/PdVH3NbKNjCUx9mK8bt1JO3/GKNC+GfePpacxGLmt/p6w==} @@ -519,21 +531,36 @@ packages: '@pandacss/preset-base@1.5.1': resolution: {integrity: sha512-I8USdmUqPPkluznTFilbzLgXzU/+NEzeCvkwuwfi0QZlmGXOXnatM/7IUK7yatNikPx3neqmNh4o4WwWE04dGQ==} + '@pandacss/preset-base@1.6.1': + resolution: {integrity: sha512-KMIwDtRQJF2EwoCSrz0Mks6JD9Tioy09zGYcfDj91Va2dCsOaDpAyBDHBqmX6pfgHT4PnZWd0tg3Rh8bK7F5Qw==} + '@pandacss/preset-panda@1.5.1': resolution: {integrity: sha512-ZA/MhFK3O/fYIS4p2HDpyPMgCISAi+g5LoPzX/jQbQ5WGfkBS8sTmxIM/XapGNVHAzXFzYOTwqQ87KP3Siiozw==} + '@pandacss/preset-panda@1.6.1': + resolution: {integrity: sha512-NqkDEX0w59OSCFojGdtqRb1juTJmNLYR14PLhkVay38/ZMBCECPJhhCZxG26y+iOGXJRc8Do3TYiGvh7Qe7QMQ==} + '@pandacss/reporter@1.5.1': resolution: {integrity: sha512-fCgX/VN9ZDZpvfYJU+bdQpwoR48cMmhtTvPYJIek6KoANKXXJFbpgC5t2N6EtTkktg+3+unks3XpU3FvQdGHTQ==} '@pandacss/shared@1.5.1': resolution: {integrity: sha512-pTHbfT6N7vt6/BncGoMduCo4jnYOvyHC8XdSgV3mzStdGJqw+0R30jeULixYrv7HFGDXCNxzohQ2k8YGOk6UoQ==} + '@pandacss/shared@1.6.1': + resolution: {integrity: sha512-lfI6tIWh7SlO2DrAoPBnBexr4dbznI/XLFQE6txN9AiHxwuh/sFtpnn5ZTm3aMnrsFF2sQvHd61s4xLbQsXoNQ==} + '@pandacss/token-dictionary@1.5.1': resolution: {integrity: sha512-w/dSvEaskD7zYHYWbPdYG+zrFLVsYYYJl9hT2cE2spccgJCid40Ov/4/zuP67rC9rPfs7qETMy6ydTPGbCfZ5A==} + '@pandacss/token-dictionary@1.6.1': + resolution: {integrity: sha512-zPRjwsDDxAHVaaQFadtI9C34LWz+kAS9UJrQNrQjz14ULi8croeSenALx4m5M6nuxPDpAEIa98NxY4VqWrgGFQ==} + '@pandacss/types@1.5.1': resolution: {integrity: sha512-fUDPtP3+yW8q5gPC2UfDcrdd/QW3H24kNt5vD30f5dt0CGDGkSoRUP4iJVNViEfQS2MzfDCnYI+PFOCw3eeQFw==} + '@pandacss/types@1.6.1': + resolution: {integrity: sha512-H+BzBFf582mkmjuv4TckWA8zyMxrZSMvRdD9rLuv7ftddEA1dxf0Pj+jGE0VIGJU7+fc7TXR4nVk/kGUpqQ3ww==} + '@parcel/watcher-android-arm64@2.5.1': resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} engines: {node: '>= 10.0.0'} @@ -1951,6 +1978,10 @@ packages: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} engines: {node: '>=12.13'} + is-what@5.5.0: + resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} + engines: {node: '>=18'} + is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -2024,64 +2055,134 @@ packages: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} engines: {node: '>= 0.6.3'} + lightningcss-android-arm64@1.30.2: + resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + lightningcss-darwin-arm64@1.25.1: resolution: {integrity: sha512-G4Dcvv85bs5NLENcu/s1f7ehzE3D5ThnlWSDwE190tWXRQCQaqwcuHe+MGSVI/slm0XrxnaayXY+cNl3cSricw==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] + lightningcss-darwin-arm64@1.30.2: + resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + lightningcss-darwin-x64@1.25.1: resolution: {integrity: sha512-dYWuCzzfqRueDSmto6YU5SoGHvZTMU1Em9xvhcdROpmtOQLorurUZz8+xFxZ51lCO2LnYbfdjZ/gCqWEkwixNg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] + lightningcss-darwin-x64@1.30.2: + resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + lightningcss-freebsd-x64@1.25.1: resolution: {integrity: sha512-hXoy2s9A3KVNAIoKz+Fp6bNeY+h9c3tkcx1J3+pS48CqAt+5bI/R/YY4hxGL57fWAIquRjGKW50arltD6iRt/w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] + lightningcss-freebsd-x64@1.30.2: + resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + lightningcss-linux-arm-gnueabihf@1.25.1: resolution: {integrity: sha512-tWyMgHFlHlp1e5iW3EpqvH5MvsgoN7ZkylBbG2R2LWxnvH3FuWCJOhtGcYx9Ks0Kv0eZOBud789odkYLhyf1ng==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] + lightningcss-linux-arm-gnueabihf@1.30.2: + resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + lightningcss-linux-arm64-gnu@1.25.1: resolution: {integrity: sha512-Xjxsx286OT9/XSnVLIsFEDyDipqe4BcLeB4pXQ/FEA5+2uWCCuAEarUNQumRucnj7k6ftkAHUEph5r821KBccQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + lightningcss-linux-arm64-gnu@1.30.2: + resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + lightningcss-linux-arm64-musl@1.25.1: resolution: {integrity: sha512-IhxVFJoTW8wq6yLvxdPvyHv4NjzcpN1B7gjxrY3uaykQNXPHNIpChLB52+wfH+yS58zm1PL4LemUp8u9Cfp6Bw==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + lightningcss-linux-arm64-musl@1.30.2: + resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + lightningcss-linux-x64-gnu@1.25.1: resolution: {integrity: sha512-RXIaru79KrREPEd6WLXfKfIp4QzoppZvD3x7vuTKkDA64PwTzKJ2jaC43RZHRt8BmyIkRRlmywNhTRMbmkPYpA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + lightningcss-linux-x64-gnu@1.30.2: + resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + lightningcss-linux-x64-musl@1.25.1: resolution: {integrity: sha512-TdcNqFsAENEEFr8fJWg0Y4fZ/nwuqTRsIr7W7t2wmDUlA8eSXVepeeONYcb+gtTj1RaXn/WgNLB45SFkz+XBZA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + lightningcss-linux-x64-musl@1.30.2: + resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.2: + resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + lightningcss-win32-x64-msvc@1.25.1: resolution: {integrity: sha512-9KZZkmmy9oGDSrnyHuxP6iMhbsgChUiu/NSgOx+U1I/wTngBStDf2i2aGRCHvFqj19HqqBEI4WuGVQBa2V6e0A==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] + lightningcss-win32-x64-msvc@1.30.2: + resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + lightningcss@1.25.1: resolution: {integrity: sha512-V0RMVZzK1+rCHpymRv4URK2lNhIRyO8g7U7zOFwVAhJuat74HtkjIQpQRKNCwFEYkRGpafOpmXXLoaoBcyVtBg==} engines: {node: '>= 12.0.0'} + lightningcss@1.30.2: + resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} + engines: {node: '>= 12.0.0'} + listhen@1.9.0: resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==} hasBin: true @@ -2139,6 +2240,10 @@ packages: resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} engines: {node: '>=12.13'} + merge-anything@6.0.6: + resolution: {integrity: sha512-F3K1W45PvTjRZzbcYIhXntNr8cux00gUxR8IzNPPG+80gNlAHZGVBwFyN4x5yjw/7QkLPKDbRQBK4KrJKo69mw==} + engines: {node: '>=18'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -2321,8 +2426,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@1.5.0: - resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==} + package-manager-detector@0.2.8: + resolution: {integrity: sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==} parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} @@ -2414,6 +2519,12 @@ packages: peerDependencies: postcss: ^8.4.32 + postcss-merge-rules@7.0.7: + resolution: {integrity: sha512-njWJrd/Ms6XViwowaaCc+/vqhPG3SmXn725AGrnl+BgTuRPEacjiLEaGq16J6XirMJbtKkTwnt67SS+e2WGoew==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + postcss-minify-selectors@7.0.5: resolution: {integrity: sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -2436,6 +2547,10 @@ packages: resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -3455,13 +3570,13 @@ snapshots: '@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.6)': dependencies: - '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) postcss: 8.5.6 - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 - '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.0)': + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.1)': dependencies: - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 '@deno/shim-deno-test@0.5.0': {} @@ -3650,10 +3765,23 @@ snapshots: microdiff: 1.5.0 typescript: 5.9.3 + '@pandacss/config@1.6.1': + dependencies: + '@pandacss/logger': 1.6.1 + '@pandacss/preset-base': 1.6.1 + '@pandacss/preset-panda': 1.6.1 + '@pandacss/shared': 1.6.1 + '@pandacss/types': 1.6.1 + bundle-n-require: 1.1.2 + escalade: 3.2.0 + merge-anything: 6.0.6 + microdiff: 1.5.0 + typescript: 5.9.3 + '@pandacss/core@1.5.1': dependencies: '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.6) - '@pandacss/is-valid-prop': 1.5.1 + '@pandacss/is-valid-prop': 1.6.1 '@pandacss/logger': 1.5.1 '@pandacss/shared': 1.5.1 '@pandacss/token-dictionary': 1.5.1 @@ -3673,6 +3801,29 @@ snapshots: postcss-selector-parser: 7.1.0 ts-pattern: 5.9.0 + '@pandacss/core@1.6.1': + dependencies: + '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.6) + '@pandacss/is-valid-prop': 1.6.1 + '@pandacss/logger': 1.6.1 + '@pandacss/shared': 1.6.1 + '@pandacss/token-dictionary': 1.6.1 + '@pandacss/types': 1.6.1 + browserslist: 4.28.0 + hookable: 5.5.3 + lightningcss: 1.30.2 + lodash.merge: 4.6.2 + outdent: 0.8.0 + postcss: 8.5.6 + postcss-discard-duplicates: 7.0.2(postcss@8.5.6) + postcss-discard-empty: 7.0.1(postcss@8.5.6) + postcss-merge-rules: 7.0.7(postcss@8.5.6) + postcss-minify-selectors: 7.0.5(postcss@8.5.6) + postcss-nested: 7.0.2(postcss@8.5.6) + postcss-normalize-whitespace: 7.0.1(postcss@8.5.6) + postcss-selector-parser: 7.1.1 + ts-pattern: 5.9.0 + '@pandacss/dev@1.5.1(typescript@5.9.3)': dependencies: '@clack/prompts': 0.11.0 @@ -3702,7 +3853,7 @@ snapshots: '@pandacss/generator@1.5.1': dependencies: '@pandacss/core': 1.5.1 - '@pandacss/is-valid-prop': 1.5.1 + '@pandacss/is-valid-prop': 1.6.1 '@pandacss/logger': 1.5.1 '@pandacss/shared': 1.5.1 '@pandacss/token-dictionary': 1.5.1 @@ -3713,13 +3864,18 @@ snapshots: postcss: 8.5.6 ts-pattern: 5.9.0 - '@pandacss/is-valid-prop@1.5.1': {} + '@pandacss/is-valid-prop@1.6.1': {} '@pandacss/logger@1.5.1': dependencies: '@pandacss/types': 1.5.1 kleur: 4.1.5 + '@pandacss/logger@1.6.1': + dependencies: + '@pandacss/types': 1.6.1 + kleur: 4.1.5 + '@pandacss/node@1.5.1(typescript@5.9.3)': dependencies: '@pandacss/config': 1.5.1 @@ -3740,7 +3896,7 @@ snapshots: lodash.merge: 4.6.2 look-it-up: 2.1.0 outdent: 0.8.0 - package-manager-detector: 1.5.0 + package-manager-detector: 0.2.8 perfect-debounce: 1.0.0 picomatch: 4.0.3 pkg-types: 2.3.0 @@ -3756,8 +3912,8 @@ snapshots: '@pandacss/parser@1.5.1(typescript@5.9.3)': dependencies: - '@pandacss/config': 1.5.1 - '@pandacss/core': 1.5.1 + '@pandacss/config': 1.6.1 + '@pandacss/core': 1.6.1 '@pandacss/extractor': 1.5.1(typescript@5.9.3) '@pandacss/logger': 1.5.1 '@pandacss/shared': 1.5.1 @@ -3782,10 +3938,18 @@ snapshots: dependencies: '@pandacss/types': 1.5.1 + '@pandacss/preset-base@1.6.1': + dependencies: + '@pandacss/types': 1.6.1 + '@pandacss/preset-panda@1.5.1': dependencies: '@pandacss/types': 1.5.1 + '@pandacss/preset-panda@1.6.1': + dependencies: + '@pandacss/types': 1.6.1 + '@pandacss/reporter@1.5.1': dependencies: '@pandacss/core': 1.5.1 @@ -3798,16 +3962,28 @@ snapshots: '@pandacss/shared@1.5.1': {} + '@pandacss/shared@1.6.1': {} + '@pandacss/token-dictionary@1.5.1': dependencies: - '@pandacss/logger': 1.5.1 + '@pandacss/logger': 1.6.1 '@pandacss/shared': 1.5.1 '@pandacss/types': 1.5.1 picomatch: 4.0.3 ts-pattern: 5.9.0 + '@pandacss/token-dictionary@1.6.1': + dependencies: + '@pandacss/logger': 1.6.1 + '@pandacss/shared': 1.6.1 + '@pandacss/types': 1.6.1 + picomatch: 4.0.3 + ts-pattern: 5.9.0 + '@pandacss/types@1.5.1': {} + '@pandacss/types@1.6.1': {} + '@parcel/watcher-android-arm64@2.5.1': optional: true @@ -4073,11 +4249,11 @@ snapshots: dependencies: solid-js: 1.9.10 - '@solidjs/start@1.2.0(solid-js@1.9.10)(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1))(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1))': + '@solidjs/start@1.2.0(solid-js@1.9.10)(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1))(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1))': dependencies: - '@tanstack/server-functions-plugin': 1.121.21(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)) - '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)) - '@vinxi/server-components': 0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)) + '@tanstack/server-functions-plugin': 1.121.21(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)) + '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)) + '@vinxi/server-components': 0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)) cookie-es: 2.0.0 defu: 6.1.4 error-stack-parser: 2.1.4 @@ -4089,8 +4265,8 @@ snapshots: source-map-js: 1.2.1 terracotta: 1.0.6(solid-js@1.9.10) tinyglobby: 0.2.15 - vinxi: 0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1) - vite-plugin-solid: 2.11.10(solid-js@1.9.10)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)) + vinxi: 0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1) + vite-plugin-solid: 2.11.10(solid-js@1.9.10)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)) transitivePeerDependencies: - '@testing-library/jest-dom' - solid-js @@ -4103,7 +4279,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@tanstack/directive-functions-plugin@1.121.21(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1))': + '@tanstack/directive-functions-plugin@1.121.21(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1))': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.28.5 @@ -4112,7 +4288,7 @@ snapshots: '@tanstack/router-utils': 1.133.19 babel-dead-code-elimination: 1.0.10 tiny-invariant: 1.3.3 - vite: 6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1) + vite: 6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1) transitivePeerDependencies: - supports-color @@ -4129,7 +4305,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/server-functions-plugin@1.121.21(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1))': + '@tanstack/server-functions-plugin@1.121.21(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1))': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.28.5 @@ -4138,7 +4314,7 @@ snapshots: '@babel/template': 7.27.2 '@babel/traverse': 7.28.5 '@babel/types': 7.28.5 - '@tanstack/directive-functions-plugin': 1.121.21(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)) + '@tanstack/directive-functions-plugin': 1.121.21(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)) babel-dead-code-elimination: 1.0.10 tiny-invariant: 1.3.3 transitivePeerDependencies: @@ -4235,7 +4411,7 @@ snapshots: untun: 0.1.3 uqr: 0.1.2 - '@vinxi/plugin-directives@0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1))': + '@vinxi/plugin-directives@0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1))': dependencies: '@babel/parser': 7.28.5 acorn: 8.15.0 @@ -4246,18 +4422,18 @@ snapshots: magicast: 0.2.11 recast: 0.23.11 tslib: 2.8.1 - vinxi: 0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1) + vinxi: 0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1) - '@vinxi/server-components@0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1))': + '@vinxi/server-components@0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1))': dependencies: - '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)) + '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)) acorn: 8.15.0 acorn-loose: 8.5.2 acorn-typescript: 1.4.13(acorn@8.15.0) astring: 1.9.0 magicast: 0.2.11 recast: 0.23.11 - vinxi: 0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1) + vinxi: 0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1) '@vue/compiler-core@3.5.22': dependencies: @@ -5527,6 +5703,8 @@ snapshots: is-what@4.1.16: {} + is-what@5.5.0: {} + is-wsl@2.2.0: dependencies: is-docker: 2.2.1 @@ -5583,33 +5761,66 @@ snapshots: dependencies: readable-stream: 2.3.8 + lightningcss-android-arm64@1.30.2: + optional: true + lightningcss-darwin-arm64@1.25.1: optional: true + lightningcss-darwin-arm64@1.30.2: + optional: true + lightningcss-darwin-x64@1.25.1: optional: true + lightningcss-darwin-x64@1.30.2: + optional: true + lightningcss-freebsd-x64@1.25.1: optional: true + lightningcss-freebsd-x64@1.30.2: + optional: true + lightningcss-linux-arm-gnueabihf@1.25.1: optional: true + lightningcss-linux-arm-gnueabihf@1.30.2: + optional: true + lightningcss-linux-arm64-gnu@1.25.1: optional: true + lightningcss-linux-arm64-gnu@1.30.2: + optional: true + lightningcss-linux-arm64-musl@1.25.1: optional: true + lightningcss-linux-arm64-musl@1.30.2: + optional: true + lightningcss-linux-x64-gnu@1.25.1: optional: true + lightningcss-linux-x64-gnu@1.30.2: + optional: true + lightningcss-linux-x64-musl@1.25.1: optional: true + lightningcss-linux-x64-musl@1.30.2: + optional: true + + lightningcss-win32-arm64-msvc@1.30.2: + optional: true + lightningcss-win32-x64-msvc@1.25.1: optional: true + lightningcss-win32-x64-msvc@1.30.2: + optional: true + lightningcss@1.25.1: dependencies: detect-libc: 1.0.3 @@ -5624,6 +5835,22 @@ snapshots: lightningcss-linux-x64-musl: 1.25.1 lightningcss-win32-x64-msvc: 1.25.1 + lightningcss@1.30.2: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.30.2 + lightningcss-darwin-arm64: 1.30.2 + lightningcss-darwin-x64: 1.30.2 + lightningcss-freebsd-x64: 1.30.2 + lightningcss-linux-arm-gnueabihf: 1.30.2 + lightningcss-linux-arm64-gnu: 1.30.2 + lightningcss-linux-arm64-musl: 1.30.2 + lightningcss-linux-x64-gnu: 1.30.2 + lightningcss-linux-x64-musl: 1.30.2 + lightningcss-win32-arm64-msvc: 1.30.2 + lightningcss-win32-x64-msvc: 1.30.2 + listhen@1.9.0: dependencies: '@parcel/watcher': 2.5.1 @@ -5709,6 +5936,10 @@ snapshots: dependencies: is-what: 4.1.16 + merge-anything@6.0.6: + dependencies: + is-what: 5.5.0 + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -5956,7 +6187,7 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@1.5.0: {} + package-manager-detector@0.2.8: {} parse5@7.3.0: dependencies: @@ -6027,18 +6258,26 @@ snapshots: caniuse-api: 3.0.0 cssnano-utils: 5.0.1(postcss@8.5.6) postcss: 8.5.6 - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 + + postcss-merge-rules@7.0.7(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 postcss-minify-selectors@7.0.5(postcss@8.5.6): dependencies: cssesc: 3.0.0 postcss: 8.5.6 - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 postcss-nested@7.0.2(postcss@8.5.6): dependencies: postcss: 8.5.6 - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 postcss-normalize-whitespace@7.0.1(postcss@8.5.6): dependencies: @@ -6050,6 +6289,11 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + postcss-value-parser@4.2.0: {} postcss@8.5.6: @@ -6652,7 +6896,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1): + vinxi@0.5.8(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1): dependencies: '@babel/core': 7.28.5 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) @@ -6686,7 +6930,7 @@ snapshots: unctx: 2.4.1 unenv: 1.10.0 unstorage: 1.17.2(db0@0.3.4)(ioredis@5.8.2) - vite: 6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1) + vite: 6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -6733,7 +6977,7 @@ snapshots: - xml2js - yaml - vite-plugin-solid@2.11.10(solid-js@1.9.10)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)): + vite-plugin-solid@2.11.10(solid-js@1.9.10)(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)): dependencies: '@babel/core': 7.28.5 '@types/babel__core': 7.20.5 @@ -6741,12 +6985,12 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.10 solid-refresh: 0.6.3(solid-js@1.9.10) - vite: 6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1) - vitefu: 1.1.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)) + vite: 6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1) + vitefu: 1.1.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)) transitivePeerDependencies: - supports-color - vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1): + vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -6757,12 +7001,12 @@ snapshots: optionalDependencies: fsevents: 2.3.3 jiti: 2.6.1 - lightningcss: 1.25.1 + lightningcss: 1.30.2 terser: 5.44.1 - vitefu@1.1.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1)): + vitefu@1.1.1(vite@6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)): optionalDependencies: - vite: 6.4.1(jiti@2.6.1)(lightningcss@1.25.1)(terser@5.44.1) + vite: 6.4.1(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1) webidl-conversions@3.0.1: {} diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx new file mode 100644 index 0000000..07ae292 --- /dev/null +++ b/src/components/ui/accordion.tsx @@ -0,0 +1,21 @@ +import { Accordion } from '@ark-ui/solid/accordion' +import { ark } from '@ark-ui/solid/factory' +import { ChevronDownIcon } from 'lucide-solid' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { accordion } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(accordion) + +export type RootProps = ComponentProps +export const Root = withProvider(Accordion.Root, 'root') +export const RootProvider = withProvider(Accordion.RootProvider, 'root') +export const Item = withContext(Accordion.Item, 'item') +export const ItemContent = withContext(Accordion.ItemContent, 'itemContent') +export const ItemIndicator = withContext(Accordion.ItemIndicator, 'itemIndicator', { + defaultProps: () => ({ children: }), +}) +export const ItemTrigger = withContext(Accordion.ItemTrigger, 'itemTrigger') +export const ItemBody = withContext(ark.div, 'itemBody') + +export { AccordionContext as Context } from '@ark-ui/solid/accordion' diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx new file mode 100644 index 0000000..10e3774 --- /dev/null +++ b/src/components/ui/alert.tsx @@ -0,0 +1,24 @@ +import { ark } from '@ark-ui/solid/factory' +import { InfoIcon } from 'lucide-solid' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { alert } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(alert) + +export type RootProps = ComponentProps +export const Root = withProvider(ark.div, 'root') +export const Title = withContext(ark.h3, 'title') +export const Description = withContext(ark.div, 'description') +export const Content = withContext(ark.div, 'content') + +type IndicatorProps = ComponentProps +const StyledIndicator = withContext(ark.span, 'indicator') + +export const Indicator = (props: IndicatorProps) => { + return ( + + + + ) +} diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx new file mode 100644 index 0000000..e57f499 --- /dev/null +++ b/src/components/ui/avatar.tsx @@ -0,0 +1,54 @@ +import { Avatar } from '@ark-ui/solid/avatar' +import { UserIcon } from 'lucide-solid' +import { type ComponentProps, type JSX, splitProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { avatar } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(avatar) + +export type RootProps = ComponentProps +export const Root = withProvider(Avatar.Root, 'root') +export const RootProvider = withProvider(Avatar.RootProvider, 'root') +export const Image = withContext(Avatar.Image, 'image', { + defaultProps: () => + ({ + draggable: 'false', + referrerPolicy: 'no-referrer', + }) as const, +}) + +export { AvatarContext as Context } from '@ark-ui/solid/avatar' + +export interface FallbackProps extends ComponentProps { + /** + * The name to derive the initials from. + * If not provided, the fallback will display a generic icon. + */ + name?: string | undefined + children?: JSX.Element +} + +const StyledFallback = withContext(Avatar.Fallback, 'fallback') + +export const Fallback = (props: FallbackProps) => { + const [local, rest] = splitProps(props, ['name', 'children', 'asChild']) + + const fallbackContent = () => { + if (local.children || local.asChild) { + return local.children + } + if (local.name) { + return getInitials(local.name) + } + return + } + + return {fallbackContent()} +} + +const getInitials = (name: string) => { + const names = name.trim().split(' ') + const firstName = names[0] || '' + const lastName = names.length > 1 ? names[names.length - 1] : '' + return firstName && lastName ? `${firstName[0]}${lastName[0]}` : firstName[0] +} diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx new file mode 100644 index 0000000..7362709 --- /dev/null +++ b/src/components/ui/badge.tsx @@ -0,0 +1,7 @@ +import { ark } from '@ark-ui/solid/factory' +import type { ComponentProps } from 'solid-js' +import { styled } from 'styled-system/jsx' +import { badge } from 'styled-system/recipes' + +export type BadgeProps = ComponentProps +export const Badge = styled(ark.div, badge) diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..a6b15d0 --- /dev/null +++ b/src/components/ui/breadcrumb.tsx @@ -0,0 +1,31 @@ +import { ark } from '@ark-ui/solid/factory' +import { ChevronRightIcon } from 'lucide-solid' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { breadcrumb } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(breadcrumb) + +export type RootProps = ComponentProps + +export const Root = withProvider(ark.nav, 'root', { + defaultProps: () => ({ 'aria-label': 'breadcrumb' }), +}) +export const List = withContext(ark.ol, 'list') +export const Item = withContext(ark.li, 'item') +export const Link = withContext(ark.a, 'link') +export const Ellipsis = withContext(ark.li, 'ellipsis', { + defaultProps: () => + ({ + role: 'presentation', + 'aria-hidden': true, + children: '...', + }) as const, +}) + +export const Separator = withContext(ark.li, 'separator', { + defaultProps: () => ({ + 'aria-hidden': true, + children: , + }), +}) diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx new file mode 100644 index 0000000..45d6a3e --- /dev/null +++ b/src/components/ui/card.tsx @@ -0,0 +1,14 @@ +import { ark } from '@ark-ui/solid/factory' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { card } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(card) + +export type RootProps = ComponentProps +export const Root = withProvider(ark.div, 'root') +export const Header = withContext(ark.div, 'header') +export const Body = withContext(ark.div, 'body') +export const Footer = withContext(ark.h3, 'footer') +export const Title = withContext(ark.h3, 'title') +export const Description = withContext(ark.div, 'description') diff --git a/src/components/ui/carousel.tsx b/src/components/ui/carousel.tsx new file mode 100644 index 0000000..78c334e --- /dev/null +++ b/src/components/ui/carousel.tsx @@ -0,0 +1,33 @@ +import { Carousel, useCarouselContext } from '@ark-ui/solid/carousel' +import { type ComponentProps, For } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { carousel } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(carousel) + +export type RootProps = ComponentProps +export const Root = withProvider(Carousel.Root, 'root', { + forwardProps: ['page'], + defaultProps: () => ({ spacing: '16px' }), +}) +export const RootProvider = withProvider(Carousel.RootProvider, 'root') +export const AutoplayTrigger = withContext(Carousel.AutoplayTrigger, 'autoplayTrigger') +export const Control = withContext(Carousel.Control, 'control') +export const Indicator = withContext(Carousel.Indicator, 'indicator') +export const Item = withContext(Carousel.Item, 'item') +export const ItemGroup = withContext(Carousel.ItemGroup, 'itemGroup') +export const NextTrigger = withContext(Carousel.NextTrigger, 'nextTrigger') +export const PrevTrigger = withContext(Carousel.PrevTrigger, 'prevTrigger') + +const StyledIndicatorGroup = withContext(Carousel.IndicatorGroup, 'indicatorGroup') +export const IndicatorGroup = (props: ComponentProps) => { + const carousel = useCarouselContext() + + return ( + + {(_, index) => } + + ) +} + +export { CarouselContext as Context } from '@ark-ui/solid/carousel' diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx new file mode 100644 index 0000000..cddb94f --- /dev/null +++ b/src/components/ui/checkbox.tsx @@ -0,0 +1,47 @@ +import { Checkbox, useCheckboxContext } from '@ark-ui/solid/checkbox' +import type { ComponentProps } from 'solid-js' +import { createStyleContext, styled } from 'styled-system/jsx' +import { checkbox } from 'styled-system/recipes' +import type { HTMLStyledProps } from 'styled-system/types' + +const { withProvider, withContext } = createStyleContext(checkbox) + +export type RootProps = ComponentProps +export type HiddenInputProps = ComponentProps + +export const Root = withProvider(Checkbox.Root, 'root') +export const RootProvider = withProvider(Checkbox.RootProvider, 'root') +export const Control = withContext(Checkbox.Control, 'control') +export const Group = withProvider(Checkbox.Group, 'group') +export const Label = withContext(Checkbox.Label, 'label') +export const HiddenInput = Checkbox.HiddenInput + +export { + type CheckboxCheckedState as CheckedState, + CheckboxGroupProvider as GroupProvider, +} from '@ark-ui/solid/checkbox' + +export const Indicator = (props: HTMLStyledProps<'svg'>) => { + const checkbox = useCheckboxContext() + + return ( + + + Checkmark + {checkbox().indeterminate ? ( + + ) : checkbox().checked ? ( + + ) : null} + + + ) +} diff --git a/src/components/ui/clipboard.tsx b/src/components/ui/clipboard.tsx new file mode 100644 index 0000000..21f63c3 --- /dev/null +++ b/src/components/ui/clipboard.tsx @@ -0,0 +1,37 @@ +import { Clipboard } from '@ark-ui/solid/clipboard' +import { CheckIcon, CopyIcon } from 'lucide-solid' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { clipboard } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(clipboard) + +export type RootProps = ComponentProps +export const Root = withProvider(Clipboard.Root, 'root') +export const RootProvider = withProvider(Clipboard.RootProvider, 'root') +export const Control = withContext(Clipboard.Control, 'control') +export const Input = withContext(Clipboard.Input, 'input') +export const Label = withContext(Clipboard.Label, 'label') +export const Trigger = withContext(Clipboard.Trigger, 'trigger') + +export { ClipboardContext as Context } from '@ark-ui/solid/clipboard' + +type IndicatorProps = ComponentProps + +const StyledIndicator = withContext(Clipboard.Indicator, 'indicator') + +export const Indicator = (props: IndicatorProps) => { + return ( + } {...props}> + + + ) +} + +export const CopyText = (props: IndicatorProps) => { + return ( + + Copy + + ) +} diff --git a/src/components/ui/close-button.tsx b/src/components/ui/close-button.tsx new file mode 100644 index 0000000..b8e09a0 --- /dev/null +++ b/src/components/ui/close-button.tsx @@ -0,0 +1,15 @@ +import { XIcon } from 'lucide-solid' +import { splitProps } from 'solid-js' +import { IconButton, type IconButtonProps } from './icon-button' + +export type CloseButtonProps = IconButtonProps + +export const CloseButton = (props: CloseButtonProps) => { + const [local, rest] = splitProps(props, ['children']) + + return ( + + {local.children ?? } + + ) +} diff --git a/src/components/ui/code.tsx b/src/components/ui/code.tsx new file mode 100644 index 0000000..7343f68 --- /dev/null +++ b/src/components/ui/code.tsx @@ -0,0 +1,7 @@ +import { ark } from '@ark-ui/solid/factory' +import type { ComponentProps } from 'solid-js' +import { styled } from 'styled-system/jsx' +import { code } from 'styled-system/recipes' + +export type CodeProps = ComponentProps +export const Code = styled(ark.code, code) diff --git a/src/components/ui/collapsible.tsx b/src/components/ui/collapsible.tsx new file mode 100644 index 0000000..bb3bcd6 --- /dev/null +++ b/src/components/ui/collapsible.tsx @@ -0,0 +1,15 @@ +import { Collapsible } from '@ark-ui/solid/collapsible' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { collapsible } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(collapsible) + +export type RootProps = ComponentProps +export const Root = withProvider(Collapsible.Root, 'root') +export const RootProvider = withProvider(Collapsible.RootProvider, 'root') +export const Content = withContext(Collapsible.Content, 'content') +export const Indicator = withContext(Collapsible.Indicator, 'indicator') +export const Trigger = withContext(Collapsible.Trigger, 'trigger') + +export { CollapsibleContext as Context } from '@ark-ui/solid/collapsible' diff --git a/src/components/ui/color-picker.tsx b/src/components/ui/color-picker.tsx new file mode 100644 index 0000000..1fa6a10 --- /dev/null +++ b/src/components/ui/color-picker.tsx @@ -0,0 +1,41 @@ +import { ColorPicker } from '@ark-ui/solid/color-picker' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { colorPicker } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(colorPicker) + +export type RootProps = ComponentProps +export const Root = withProvider(ColorPicker.Root, 'root') +export const RootProvider = withProvider(ColorPicker.RootProvider, 'root') +export const Area = withContext(ColorPicker.Area, 'area') +export const AreaBackground = withContext(ColorPicker.AreaBackground, 'areaBackground') +export const AreaThumb = withContext(ColorPicker.AreaThumb, 'areaThumb') +export const ChannelInput = withContext(ColorPicker.ChannelInput, 'channelInput') +export const ChannelSlider = withContext(ColorPicker.ChannelSlider, 'channelSlider') +export const ChannelSliderLabel = withContext(ColorPicker.ChannelSliderLabel, 'channelSliderLabel') +export const ChannelSliderThumb = withContext(ColorPicker.ChannelSliderThumb, 'channelSliderThumb') +export const ChannelSliderTrack = withContext(ColorPicker.ChannelSliderTrack, 'channelSliderTrack') +export const ChannelSliderValueText = withContext( + ColorPicker.ChannelSliderValueText, + 'channelSliderValueText', +) +export const Content = withContext(ColorPicker.Content, 'content') +export const Control = withContext(ColorPicker.Control, 'control') +export const EyeDropperTrigger = withContext(ColorPicker.EyeDropperTrigger, 'eyeDropperTrigger') +export const FormatSelect = withContext(ColorPicker.FormatSelect, 'formatSelect') +export const FormatTrigger = withContext(ColorPicker.FormatTrigger, 'formatTrigger') +export const HiddenInput = ColorPicker.HiddenInput +export const Label = withContext(ColorPicker.Label, 'label') +export const Positioner = withContext(ColorPicker.Positioner, 'positioner') +export const Swatch = withContext(ColorPicker.Swatch, 'swatch') +export const SwatchGroup = withContext(ColorPicker.SwatchGroup, 'swatchGroup') +export const SwatchIndicator = withContext(ColorPicker.SwatchIndicator, 'swatchIndicator') +export const SwatchTrigger = withContext(ColorPicker.SwatchTrigger, 'swatchTrigger') +export const TransparencyGrid = withContext(ColorPicker.TransparencyGrid, 'transparencyGrid') +export const Trigger = withContext(ColorPicker.Trigger, 'trigger') +export const ValueSwatch = ColorPicker.ValueSwatch +export const ValueText = withContext(ColorPicker.ValueText, 'valueText') +export const View = withContext(ColorPicker.View, 'view') + +export { ColorPickerContext as Context } from '@ark-ui/solid/color-picker' diff --git a/src/components/ui/combobox.tsx b/src/components/ui/combobox.tsx new file mode 100644 index 0000000..52e1a3e --- /dev/null +++ b/src/components/ui/combobox.tsx @@ -0,0 +1,54 @@ +import { Combobox, useComboboxItemContext } from '@ark-ui/solid/combobox' +import { ark } from '@ark-ui/solid/factory' +import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' +import { Show } from 'solid-js' +import { createStyleContext, type HTMLStyledProps } from 'styled-system/jsx' +import { type ComboboxVariantProps, combobox } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(combobox) + +export type RootProps = HTMLStyledProps<'div'> & ComboboxVariantProps + +export const Root = withProvider(Combobox.Root, 'root', { + defaultProps: () => ({ positioning: { sameWidth: false } }), +}) as Combobox.RootComponent + +export const RootProvider = withProvider( + Combobox.RootProvider, + 'root', +) as Combobox.RootProviderComponent + +export const ClearTrigger = withContext(Combobox.ClearTrigger, 'clearTrigger', { + defaultProps: () => ({ children: }), +}) +export const Content = withContext(Combobox.Content, 'content') +export const Control = withContext(Combobox.Control, 'control') +export const Empty = withContext(Combobox.Empty, 'empty') +export const IndicatorGroup = withContext(ark.div, 'indicatorGroup') +export const Input = withContext(Combobox.Input, 'input') +export const Item = withContext(Combobox.Item, 'item') +export const ItemGroup = withContext(Combobox.ItemGroup, 'itemGroup') +export const ItemGroupLabel = withContext(Combobox.ItemGroupLabel, 'itemGroupLabel') +export const ItemText = withContext(Combobox.ItemText, 'itemText') +export const Label = withContext(Combobox.Label, 'label') +export const List = withContext(Combobox.List, 'list') +export const Positioner = withContext(Combobox.Positioner, 'positioner') +export const Trigger = withContext(Combobox.Trigger, 'trigger', { + defaultProps: () => ({ children: }), +}) + +export { ComboboxContext as Context } from '@ark-ui/solid/combobox' + +const StyledItemIndicator = withContext(Combobox.ItemIndicator, 'itemIndicator') + +export const ItemIndicator = (props: HTMLStyledProps<'div'>) => { + const item = useComboboxItemContext() + + return ( + + ) +} diff --git a/src/components/ui/date-picker.tsx b/src/components/ui/date-picker.tsx new file mode 100644 index 0000000..e33e74d --- /dev/null +++ b/src/components/ui/date-picker.tsx @@ -0,0 +1,35 @@ +import { DatePicker } from '@ark-ui/solid/date-picker' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { datePicker } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(datePicker) + +export type RootProps = ComponentProps +export const Root = withProvider(DatePicker.Root, 'root') +export const RootProvider = withProvider(DatePicker.RootProvider, 'root') +export const ClearTrigger = withContext(DatePicker.ClearTrigger, 'clearTrigger') +export const Content = withContext(DatePicker.Content, 'content') +export const Control = withContext(DatePicker.Control, 'control') +export const Input = withContext(DatePicker.Input, 'input') +export const Label = withContext(DatePicker.Label, 'label') +export const MonthSelect = withContext(DatePicker.MonthSelect, 'monthSelect') +export const NextTrigger = withContext(DatePicker.NextTrigger, 'nextTrigger') +export const Positioner = withContext(DatePicker.Positioner, 'positioner') +export const PresetTrigger = withContext(DatePicker.PresetTrigger, 'presetTrigger') +export const PrevTrigger = withContext(DatePicker.PrevTrigger, 'prevTrigger') +export const RangeText = withContext(DatePicker.RangeText, 'rangeText') +export const Table = withContext(DatePicker.Table, 'table') +export const TableBody = withContext(DatePicker.TableBody, 'tableBody') +export const TableCell = withContext(DatePicker.TableCell, 'tableCell') +export const TableCellTrigger = withContext(DatePicker.TableCellTrigger, 'tableCellTrigger') +export const TableHead = withContext(DatePicker.TableHead, 'tableHead') +export const TableHeader = withContext(DatePicker.TableHeader, 'tableHeader') +export const TableRow = withContext(DatePicker.TableRow, 'tableRow') +export const Trigger = withContext(DatePicker.Trigger, 'trigger') +export const View = withContext(DatePicker.View, 'view') +export const ViewControl = withContext(DatePicker.ViewControl, 'viewControl') +export const ViewTrigger = withContext(DatePicker.ViewTrigger, 'viewTrigger') +export const YearSelect = withContext(DatePicker.YearSelect, 'yearSelect') + +export { DatePickerContext as Context } from '@ark-ui/solid/date-picker' diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx new file mode 100644 index 0000000..b5ca358 --- /dev/null +++ b/src/components/ui/dialog.tsx @@ -0,0 +1,35 @@ +import { Dialog, useDialogContext } from '@ark-ui/solid/dialog' +import { ark } from '@ark-ui/solid/factory' +import type { ComponentProps } from 'solid-js' +import { createStyleContext, styled } from 'styled-system/jsx' +import { dialog } from 'styled-system/recipes' + +const { withRootProvider, withContext } = createStyleContext(dialog) + +export type RootProps = ComponentProps +export const Root = withRootProvider(Dialog.Root, { + defaultProps: () => ({ unmountOnExit: true, lazyMount: true }), +}) +export const RootProvider = withRootProvider(Dialog.RootProvider, { + defaultProps: () => ({ unmountOnExit: true, lazyMount: true }), +}) +export const Backdrop = withContext(Dialog.Backdrop, 'backdrop') +export const CloseTrigger = withContext(Dialog.CloseTrigger, 'closeTrigger') +export const Content = withContext(Dialog.Content, 'content') +export const Description = withContext(Dialog.Description, 'description') +export const Positioner = withContext(Dialog.Positioner, 'positioner') +export const Title = withContext(Dialog.Title, 'title') +export const Trigger = withContext(Dialog.Trigger, 'trigger') +export const Body = withContext(ark.div, 'body') +export const Header = withContext(ark.div, 'header') +export const Footer = withContext(ark.div, 'footer') + +const StyledButton = styled(ark.button) + +export const ActionTrigger = (props: ComponentProps) => { + const dialog = useDialogContext() + + return dialog().setOpen(false)} /> +} + +export { DialogContext as Context } from '@ark-ui/solid/dialog' diff --git a/src/components/ui/drawer.tsx b/src/components/ui/drawer.tsx new file mode 100644 index 0000000..0ab4f6b --- /dev/null +++ b/src/components/ui/drawer.tsx @@ -0,0 +1,28 @@ +import { Dialog } from '@ark-ui/solid/dialog' +import { ark } from '@ark-ui/solid/factory' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { drawer } from 'styled-system/recipes' + +const { withRootProvider, withContext } = createStyleContext(drawer) + +export type RootProps = ComponentProps +export const Root = withRootProvider(Dialog.Root, { + defaultProps: () => ({ unmountOnExit: true, lazyMount: true }), +}) +export const RootProvider = withRootProvider(Dialog.Root, { + defaultProps: () => ({ unmountOnExit: true, lazyMount: true }), +}) +export const Backdrop = withContext(Dialog.Backdrop, 'backdrop') +export const Positioner = withContext(Dialog.Positioner, 'positioner') +export const CloseTrigger = withContext(Dialog.CloseTrigger, 'closeTrigger') +export const Content = withContext(Dialog.Content, 'content') +export const Description = withContext(Dialog.Description, 'description') +export const Title = withContext(Dialog.Title, 'title') +export const Trigger = withContext(Dialog.Trigger, 'trigger') + +export const Body = withContext(ark.div, 'body') +export const Header = withContext(ark.div, 'header') +export const Footer = withContext(ark.div, 'footer') + +export { DialogContext as Context } from '@ark-ui/solid/dialog' diff --git a/src/components/ui/editable.tsx b/src/components/ui/editable.tsx new file mode 100644 index 0000000..6308082 --- /dev/null +++ b/src/components/ui/editable.tsx @@ -0,0 +1,20 @@ +import { Editable } from '@ark-ui/solid/editable' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { editable } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(editable) + +export type RootProps = ComponentProps +export const Root = withProvider(Editable.Root, 'root') +export const RootProvider = withProvider(Editable.RootProvider, 'root') +export const Area = withContext(Editable.Area, 'area') +export const CancelTrigger = withContext(Editable.CancelTrigger, 'cancelTrigger') +export const Control = withContext(Editable.Control, 'control') +export const EditTrigger = withContext(Editable.EditTrigger, 'editTrigger') +export const Input = withContext(Editable.Input, 'input') +export const Label = withContext(Editable.Label, 'label') +export const Preview = withContext(Editable.Preview, 'preview') +export const SubmitTrigger = withContext(Editable.SubmitTrigger, 'submitTrigger') + +export { EditableContext as Context } from '@ark-ui/solid/editable' diff --git a/src/components/ui/field.tsx b/src/components/ui/field.tsx new file mode 100644 index 0000000..87bd3e2 --- /dev/null +++ b/src/components/ui/field.tsx @@ -0,0 +1,16 @@ +import { Field } from '@ark-ui/solid/field' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { field } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(field) + +export type RootProps = ComponentProps +export const Root = withProvider(Field.Root, 'root') +export const RootProvider = withProvider(Field.RootProvider, 'root') +export const ErrorText = withContext(Field.ErrorText, 'errorText') +export const HelperText = withContext(Field.HelperText, 'helperText') +export const Label = withContext(Field.Label, 'label') +export const RequiredIndicator = withContext(Field.RequiredIndicator, 'requiredIndicator') + +export { FieldContext as Context } from '@ark-ui/solid/field' diff --git a/src/components/ui/fieldset.tsx b/src/components/ui/fieldset.tsx new file mode 100644 index 0000000..16e456c --- /dev/null +++ b/src/components/ui/fieldset.tsx @@ -0,0 +1,18 @@ +import { ark } from '@ark-ui/solid/factory' +import { Fieldset } from '@ark-ui/solid/fieldset' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { fieldset } from 'styled-system/recipes' + +const { withProvider, withContext } = createStyleContext(fieldset) + +export type RootProps = ComponentProps +export const Root = withProvider(Fieldset.Root, 'root') +export const RootProvider = withProvider(Fieldset.RootProvider, 'root') +export const Legend = withContext(Fieldset.Legend, 'legend') +export const HelperText = withContext(Fieldset.HelperText, 'helperText') +export const ErrorText = withContext(Fieldset.ErrorText, 'errorText') +export const Content = withContext(ark.div, 'content') +export const Control = withContext(ark.div, 'control') + +export { FieldsetContext as Context } from '@ark-ui/solid/fieldset' diff --git a/src/components/ui/file-upload.tsx b/src/components/ui/file-upload.tsx new file mode 100644 index 0000000..f3333c0 --- /dev/null +++ b/src/components/ui/file-upload.tsx @@ -0,0 +1,112 @@ +import { FileUpload, useFileUploadContext } from '@ark-ui/solid/file-upload' +import { FileIcon, XIcon } from 'lucide-solid' +import { type ComponentProps, createMemo, For, Show, splitProps } from 'solid-js' +import { createStyleContext, type HTMLStyledProps, Stack } from 'styled-system/jsx' +import { fileUpload } from 'styled-system/recipes' +import { Span } from '@/components/ui' + +const { withProvider, withContext } = createStyleContext(fileUpload) + +export type RootProps = ComponentProps +export type ItemProps = ComponentProps + +export const Root = withProvider(FileUpload.Root, 'root') +export const RootProvider = withProvider(FileUpload.RootProvider, 'root') +export const ClearTrigger = withContext(FileUpload.ClearTrigger, 'clearTrigger') +export const Dropzone = withContext(FileUpload.Dropzone, 'dropzone') +export const HiddenInput = FileUpload.HiddenInput +export const Item = withContext(FileUpload.Item, 'item') +export const ItemDeleteTrigger = withContext(FileUpload.ItemDeleteTrigger, 'itemDeleteTrigger', { + defaultProps: () => ({ children: }), +}) +export const ItemGroup = withContext(FileUpload.ItemGroup, 'itemGroup') +export const ItemName = withContext(FileUpload.ItemName, 'itemName') +export const ItemPreview = withContext(FileUpload.ItemPreview, 'itemPreview', { + defaultProps: () => ({ children: }), +}) +export const ItemPreviewImage = withContext(FileUpload.ItemPreviewImage, 'itemPreviewImage') +export const ItemSizeText = withContext(FileUpload.ItemSizeText, 'itemSizeText') +export const Label = withContext(FileUpload.Label, 'label') +export const Trigger = withContext(FileUpload.Trigger, 'trigger') + +export { FileUploadContext as Context } from '@ark-ui/solid/file-upload' + +interface ItemsBaseProps { + showSize?: boolean | undefined + clearable?: boolean | undefined + files?: File[] | undefined +} + +interface ItemsProps extends Omit, ItemsBaseProps {} + +export const Items = (props: ItemsProps) => { + const [local, rest] = splitProps(props, ['showSize', 'clearable', 'files']) + const fileUpload = useFileUploadContext() + const acceptedFiles = () => local.files ?? fileUpload().acceptedFiles + + return ( + + {(file) => ( + + + + + + + + + + + + + + )} + + ) +} + +interface FileUploadListProps extends ItemsBaseProps {} + +export const List = (props: FileUploadListProps) => { + const [local, rest] = splitProps(props, ['showSize', 'clearable', 'files']) + + return ( + + + + ) +} + +export interface FileTextProps extends HTMLStyledProps<'span'> { + fallback?: string | undefined +} + +export const FileText = (props: FileTextProps) => { + const [local, rest] = splitProps(props, ['fallback']) + const fallback = () => local.fallback ?? 'Select file(s)' + + const fileUpload = useFileUploadContext() + const acceptedFiles = () => fileUpload().acceptedFiles + + const fileText = createMemo(() => { + const files = acceptedFiles() + if (files.length === 1) { + return files[0].name + } + if (files.length > 1) { + return `${files.length} files` + } + return fallback() + }) + + return ( + + {fileText()} + + ) +} diff --git a/src/components/ui/heading.tsx b/src/components/ui/heading.tsx new file mode 100644 index 0000000..85101fd --- /dev/null +++ b/src/components/ui/heading.tsx @@ -0,0 +1,9 @@ +import type { ComponentProps } from 'solid-js' +import { styled } from 'styled-system/jsx' +import { type HeadingVariantProps, heading } from 'styled-system/recipes' +import type { StyledComponent } from 'styled-system/types' + +type Props = HeadingVariantProps & { as?: any } + +export type HeadingProps = ComponentProps +export const Heading = styled('h2', heading) as StyledComponent<'h2', Props> diff --git a/src/components/ui/hover-card.tsx b/src/components/ui/hover-card.tsx new file mode 100644 index 0000000..4351656 --- /dev/null +++ b/src/components/ui/hover-card.tsx @@ -0,0 +1,17 @@ +import { HoverCard } from '@ark-ui/solid/hover-card' +import type { ComponentProps } from 'solid-js' +import { createStyleContext } from 'styled-system/jsx' +import { hoverCard } from 'styled-system/recipes' + +const { withRootProvider, withContext } = createStyleContext(hoverCard) + +export type RootProps = ComponentProps +export const Root = withRootProvider(HoverCard.Root) +export const RootProvider = withRootProvider(HoverCard.RootProvider) +export const Arrow = withContext(HoverCard.Arrow, 'arrow') +export const ArrowTip = withContext(HoverCard.ArrowTip, 'arrowTip') +export const Content = withContext(HoverCard.Content, 'content') +export const Positioner = withContext(HoverCard.Positioner, 'positioner') +export const Trigger = withContext(HoverCard.Trigger, 'trigger') + +export { HoverCardContext as Context } from '@ark-ui/solid/hover-card' diff --git a/src/components/ui/icon-button.tsx b/src/components/ui/icon-button.tsx new file mode 100644 index 0000000..ac3c508 --- /dev/null +++ b/src/components/ui/icon-button.tsx @@ -0,0 +1,7 @@ +import { Button, type ButtonProps } from './button' + +export interface IconButtonProps extends ButtonProps {} + +export const IconButton = (props: IconButtonProps) => { + return + ) } diff --git a/src/theme/recipes/accordion.ts b/src/theme/recipes/accordion.ts new file mode 100644 index 0000000..df75c8d --- /dev/null +++ b/src/theme/recipes/accordion.ts @@ -0,0 +1,90 @@ +import { accordionAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const accordion = defineSlotRecipe({ + className: 'accordion', + slots: accordionAnatomy.extendWith('itemBody').keys(), + base: { + root: { + width: 'full', + '--accordion-radius': 'radii.l2', + }, + item: { + overflowAnchor: 'none', + }, + itemTrigger: { + alignItems: 'center', + borderRadius: 'var(--accordion-radius)', + color: 'fg.default', + cursor: 'pointer', + display: 'flex', + fontWeight: 'semibold', + gap: '3', + justifyContent: 'space-between', + textAlign: 'start', + textStyle: 'lg', + width: 'full', + _focusVisible: { + outline: '2px solid', + outlineColor: 'colorPalette.focusRing', + }, + _disabled: { + layerStyle: 'disabled', + }, + }, + itemIndicator: { + transition: 'rotate 0.2s', + transformOrigin: 'center', + color: 'fg.subtle', + _open: { + rotate: '180deg', + }, + _icon: { + width: '1.2em', + height: '1.2em', + }, + }, + itemBody: { + pb: 'calc(var(--accordion-padding-y) * 2)', + color: 'fg.muted', + }, + itemContent: { + overflow: 'hidden', + borderRadius: 'var(--accordion-radius)', + _open: { + animationName: 'expand-height, fade-in', + animationDuration: 'normal', + }, + _closed: { + animationName: 'collapse-height, fade-out', + animationDuration: 'normal', + }, + }, + }, + defaultVariants: { + size: 'md', + variant: 'outline', + }, + variants: { + variant: { + outline: { + item: { + borderBottomWidth: '1px', + }, + }, + plain: {}, + }, + size: { + md: { + root: { + '--accordion-padding-x': 'spacing.4', + '--accordion-padding-y': 'spacing.2.5', + }, + itemTrigger: { + textStyle: 'md', + py: 'var(--accordion-padding-y)', + }, + }, + }, + }, +}) diff --git a/src/theme/recipes/alert.ts b/src/theme/recipes/alert.ts new file mode 100644 index 0000000..1d6a0c1 --- /dev/null +++ b/src/theme/recipes/alert.ts @@ -0,0 +1,112 @@ +import { defineSlotRecipe } from '@pandacss/dev' + +export const alert = defineSlotRecipe({ + className: 'alert', + slots: ['root', 'content', 'description', 'indicator', 'title'], + base: { + root: { + alignItems: 'flex-start', + borderRadius: 'l3', + display: 'flex', + position: 'relative', + width: 'full', + }, + content: { + display: 'flex', + flex: '1', + flexDirection: 'column', + gap: '1', + }, + description: { + display: 'inline', + }, + indicator: { + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + flexShrink: '0', + }, + title: { + fontWeight: 'semibold', + }, + }, + defaultVariants: { + size: 'md', + status: 'info', + variant: 'subtle', + }, + variants: { + size: { + md: { + root: { + gap: '3', + p: '4', + textStyle: 'sm', + }, + indicator: { + _icon: { + width: '5', + height: '5', + }, + }, + }, + lg: { + root: { + gap: '4', + p: '4', + textStyle: 'md', + }, + indicator: { + _icon: { + width: '6', + height: '6', + }, + }, + }, + }, + variant: { + solid: { + root: { + bg: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + }, + }, + surface: { + root: { + bg: 'colorPalette.surface.bg', + borderWidth: '1px', + borderColor: 'colorPalette.surface.border', + color: 'colorPalette.surface.fg', + }, + }, + subtle: { + root: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + }, + }, + outline: { + root: { + borderWidth: '1px', + borderColor: 'colorPalette.outline.border', + color: 'colorPalette.outline.fg', + }, + }, + }, + status: { + info: { + root: { colorPalette: 'blue' }, + }, + warning: { + root: { colorPalette: 'orange' }, + }, + success: { + root: { colorPalette: 'green' }, + }, + error: { + root: { colorPalette: 'red' }, + }, + neutral: {}, + }, + }, +}) diff --git a/src/theme/recipes/avatar.ts b/src/theme/recipes/avatar.ts new file mode 100644 index 0000000..1bd90cb --- /dev/null +++ b/src/theme/recipes/avatar.ts @@ -0,0 +1,152 @@ +import { avatarAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const avatar = defineSlotRecipe({ + className: 'avatar', + slots: avatarAnatomy.keys(), + base: { + root: { + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + fontWeight: 'medium', + position: 'relative', + verticalAlign: 'top', + flexShrink: '0', + userSelect: 'none', + width: 'var(--avatar-size)', + height: 'var(--avatar-size)', + fontSize: 'var(--avatar-font-size)', + borderRadius: 'var(--avatar-radius)', + }, + fallback: { + lineHeight: '1', + textTransform: 'uppercase', + fontWeight: 'medium', + fontSize: 'var(--avatar-font-size)', + borderRadius: 'var(--avatar-radius)', + }, + image: { + width: '100%', + height: '100%', + objectFit: 'cover', + borderRadius: 'var(--avatar-radius)', + }, + }, + defaultVariants: { + size: 'md', + shape: 'full', + variant: 'subtle', + }, + variants: { + size: { + full: { + root: { + '--avatar-size': '100%', + '--avatar-font-size': '100%', + }, + }, + '2xs': { + root: { + '--avatar-font-size': 'fontSizes.2xs', + '--avatar-size': 'sizes.6', + }, + fallback: { + _icon: { width: '3', height: '3' }, + }, + }, + xs: { + root: { + '--avatar-font-size': 'fontSizes.xs', + '--avatar-size': 'sizes.8', + }, + fallback: { + _icon: { width: '4', height: '4' }, + }, + }, + sm: { + root: { + '--avatar-font-size': 'fontSizes.sm', + '--avatar-size': 'sizes.9', + }, + fallback: { + _icon: { width: '4.5', height: '4.5' }, + }, + }, + md: { + root: { + '--avatar-font-size': 'fontSizes.md', + '--avatar-size': 'sizes.10', + }, + fallback: { + _icon: { width: '5', height: '5' }, + }, + }, + lg: { + root: { + '--avatar-font-size': 'fontSizes.md', + '--avatar-size': 'sizes.11', + }, + fallback: { + _icon: { width: '5.5', height: '5.5' }, + }, + }, + xl: { + root: { + '--avatar-font-size': 'fontSizes.lg', + '--avatar-size': 'sizes.12', + }, + fallback: { + _icon: { width: '6', height: '6' }, + }, + }, + '2xl': { + root: { + '--avatar-font-size': 'fontSizes.xl', + '--avatar-size': 'sizes.16', + }, + fallback: { + _icon: { width: '8', height: '8' }, + }, + }, + }, + variant: { + solid: { + root: { + bg: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + }, + }, + surface: { + root: { + bg: 'colorPalette.surface.bg', + borderWidth: '1px', + borderColor: 'colorPalette.surface.border', + color: 'colorPalette.surface.fg', + }, + }, + subtle: { + root: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + }, + }, + outline: { + root: { + borderWidth: '1px', + borderColor: 'colorPalette.outline.border', + color: 'colorPalette.outline.fg', + }, + }, + }, + shape: { + square: {}, + rounded: { + root: { '--avatar-radius': 'radii.l3' }, + }, + full: { + root: { '--avatar-radius': 'radii.full' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/badge.ts b/src/theme/recipes/badge.ts new file mode 100644 index 0000000..0fb74d9 --- /dev/null +++ b/src/theme/recipes/badge.ts @@ -0,0 +1,48 @@ +import { defineRecipe } from '@pandacss/dev' + +export const badge = defineRecipe({ + className: 'badge', + base: { + display: 'inline-flex', + alignItems: 'center', + borderRadius: 'l2', + lineHeight: '1', + fontWeight: 'medium', + fontVariantNumeric: 'tabular-nums', + whiteSpace: 'nowrap', + userSelect: 'none', + }, + defaultVariants: { + variant: 'subtle', + size: 'md', + }, + variants: { + variant: { + solid: { + bg: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + }, + surface: { + bg: 'colorPalette.surface.bg', + borderWidth: '1px', + borderColor: 'colorPalette.surface.border', + color: 'colorPalette.surface.fg', + }, + subtle: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + }, + outline: { + borderWidth: '1px', + borderColor: 'colorPalette.outline.border', + color: 'colorPalette.outline.fg', + }, + }, + size: { + sm: { fontSize: 'xs', px: '1.5', h: '4.5', gap: '0.5', _icon: { boxSize: '2.5' } }, + md: { fontSize: 'xs', px: '2', h: '5', gap: '1', _icon: { boxSize: '3' } }, + lg: { fontSize: 'xs', px: '2.5', h: '5.5', gap: '1', _icon: { boxSize: '3.5' } }, + xl: { fontSize: 'sm', px: '2.5', h: '6', gap: '1.5', _icon: { boxSize: '4' } }, + }, + }, +}) diff --git a/src/theme/recipes/breadcrumb.ts b/src/theme/recipes/breadcrumb.ts new file mode 100644 index 0000000..1d882aa --- /dev/null +++ b/src/theme/recipes/breadcrumb.ts @@ -0,0 +1,77 @@ +import { defineSlotRecipe } from '@pandacss/dev' + +export const breadcrumb = defineSlotRecipe({ + className: 'breadcrumb', + slots: ['root', 'list', 'link', 'item', 'separator', 'ellipsis'], + base: { + list: { + alignItems: 'center', + display: 'flex', + listStyle: 'none', + wordBreak: 'break-word', + }, + link: { + alignItems: 'center', + borderRadius: 'l1', + display: 'inline-flex', + focusRing: 'outside', + gap: '2', + outline: '0', + textDecoration: 'none', + transition: 'color', + _icon: { boxSize: '1em' }, + }, + item: { + display: 'inline-flex', + alignItems: 'center', + color: 'fg.muted', + _last: { + color: 'fg.default', + }, + }, + separator: { + color: 'fg.subtle', + _icon: { boxSize: '1em' }, + _rtl: { rotate: '180deg' }, + }, + ellipsis: { + alignItems: 'center', + color: 'fg.muted', + display: 'inline-flex', + justifyContent: 'center', + _icon: { boxSize: '1em' }, + }, + }, + + variants: { + variant: { + underline: { + link: { + textDecoration: 'underline', + textDecorationThickness: '0.1em', + textUnderlineOffset: '0.125em', + textDecorationColor: 'fg.subtle', + _hover: { textDecorationColor: 'fg.default' }, + }, + }, + plain: { + link: { + color: 'fg.muted', + _hover: { color: 'fg.default' }, + _currentPage: { color: 'fg.default' }, + }, + }, + }, + size: { + xs: { list: { gap: '1', textStyle: 'xs' } }, + sm: { list: { gap: '1', textStyle: 'sm' } }, + md: { list: { gap: '1.5', textStyle: 'md' } }, + lg: { list: { gap: '2', textStyle: 'lg' } }, + }, + }, + + defaultVariants: { + variant: 'plain', + size: 'md', + }, +}) diff --git a/src/theme/recipes/card.ts b/src/theme/recipes/card.ts new file mode 100644 index 0000000..709a58b --- /dev/null +++ b/src/theme/recipes/card.ts @@ -0,0 +1,68 @@ +import { defineSlotRecipe } from '@pandacss/dev' + +export const card = defineSlotRecipe({ + className: 'card', + slots: ['root', 'header', 'body', 'footer', 'title', 'description'], + base: { + root: { + borderRadius: 'l3', + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + position: 'relative', + }, + header: { + display: 'flex', + flexDirection: 'column', + gap: '1', + p: '6', + }, + body: { + display: 'flex', + flex: '1', + flexDirection: 'column', + pb: '6', + px: '6', + }, + footer: { + display: 'flex', + justifyContent: 'flex-end', + gap: '3', + pb: '6', + pt: '2', + px: '6', + }, + title: { + textStyle: 'lg', + fontWeight: 'semibold', + }, + description: { + color: 'fg.muted', + textStyle: 'sm', + }, + }, + defaultVariants: { + variant: 'outline', + }, + variants: { + variant: { + elevated: { + root: { + bg: 'gray.surface.bg', + boxShadow: 'lg', + }, + }, + outline: { + root: { + bg: 'gray.surface.bg', + borderWidth: '1px', + }, + }, + subtle: { + root: { + bg: 'gray.subtle.bg', + }, + }, + }, + }, +}) diff --git a/src/theme/recipes/carousel.ts b/src/theme/recipes/carousel.ts new file mode 100644 index 0000000..653c782 --- /dev/null +++ b/src/theme/recipes/carousel.ts @@ -0,0 +1,75 @@ +import { carouselAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const carousel = defineSlotRecipe({ + className: 'carousel', + slots: carouselAnatomy.keys(), + base: { + root: { + position: 'relative', + display: 'flex', + flexDirection: 'column', + gap: '2', + _vertical: { + flexDirection: 'row', + }, + }, + control: { + alignItems: 'center', + justifyContent: 'space-between', + borderRadius: 'l2', + display: 'flex', + _vertical: { + flexDirection: 'column', + }, + }, + itemGroup: { + flex: '1', + }, + indicatorGroup: { + display: 'flex', + _vertical: { + flexDirection: 'column', + }, + }, + indicator: { + borderRadius: 'full', + background: 'gray.subtle.bg', + cursor: 'pointer', + _current: { + background: 'colorPalette.solid.bg', + }, + focusVisibleRing: 'outside', + }, + }, + defaultVariants: { + size: 'md', + }, + variants: { + inline: { + true: { + control: { + background: { _light: 'white.a11', _dark: 'black.a11' }, + bottom: '3', + left: '50%', + p: '1', + position: 'absolute', + transform: 'translateX(-50%)', + }, + }, + }, + size: { + md: { + control: { + gap: '3', + }, + indicatorGroup: { + gap: '3', + }, + indicator: { + boxSize: '2.5', + }, + }, + }, + }, +}) diff --git a/src/theme/recipes/checkbox.ts b/src/theme/recipes/checkbox.ts new file mode 100644 index 0000000..54d6c64 --- /dev/null +++ b/src/theme/recipes/checkbox.ts @@ -0,0 +1,110 @@ +import { checkboxAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const checkbox = defineSlotRecipe({ + slots: checkboxAnatomy.keys(), + className: 'checkbox', + base: { + root: { + display: 'inline-flex', + gap: '2', + alignItems: 'center', + verticalAlign: 'top', + position: 'relative', + _disabled: { + layerStyle: 'disabled', + }, + }, + control: { + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + flexShrink: '0', + borderWidth: '1px', + borderColor: 'transparent', + borderRadius: 'l1', + cursor: 'pointer', + focusVisibleRing: 'outside', + + _icon: { + boxSize: 'full', + }, + }, + label: { + fontWeight: 'medium', + userSelect: 'none', + }, + }, + + variants: { + size: { + sm: { + root: { gap: '2' }, + label: { textStyle: 'sm' }, + control: { boxSize: '4.5', _icon: { boxSize: '3' } }, + }, + md: { + root: { gap: '3' }, + label: { textStyle: 'md' }, + control: { boxSize: '5', _icon: { boxSize: '3.5' } }, + }, + lg: { + root: { gap: '3' }, + label: { textStyle: 'lg' }, + control: { boxSize: '5.5', _icon: { boxSize: '4' } }, + }, + }, + + variant: { + solid: { + control: { + control: { + borderColor: 'border', + _checked: { + bg: 'colorPalette.solid.bg', + borderColor: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + }, + _invalid: { + background: 'error', + }, + }, + }, + }, + surface: { + control: { + bg: 'colorPalette.surface.bg', + borderWidth: '1px', + borderColor: 'colorPalette.surface.border', + color: 'colorPalette.surface.fg', + }, + }, + subtle: { + control: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + }, + }, + outline: { + control: { + borderWidth: '1px', + borderColor: 'colorPalette.outline.border', + color: 'colorPalette.outline.fg', + _checked: { + borderColor: 'colorPalette.solid.bg', + }, + }, + }, + plain: { + control: { + color: 'colorPalette.plain.fg', + }, + }, + }, + }, + + defaultVariants: { + variant: 'solid', + size: 'md', + }, +}) diff --git a/src/theme/recipes/clipboard.ts b/src/theme/recipes/clipboard.ts new file mode 100644 index 0000000..c20ac44 --- /dev/null +++ b/src/theme/recipes/clipboard.ts @@ -0,0 +1,21 @@ +import { clipboardAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const clipboard = defineSlotRecipe({ + className: 'clipboard', + slots: clipboardAnatomy.keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + alignItems: 'flex-start', + gap: '1.5', + }, + label: { + fontWeight: 'medium', + textStyle: 'sm', + color: 'fg.default', + gap: '0.5', + }, + }, +}) diff --git a/src/theme/recipes/code.ts b/src/theme/recipes/code.ts new file mode 100644 index 0000000..3ea43ba --- /dev/null +++ b/src/theme/recipes/code.ts @@ -0,0 +1,51 @@ +import { defineRecipe } from '@pandacss/dev' + +export const code = defineRecipe({ + className: 'code', + base: { + alignItems: 'center', + borderRadius: 'l2', + display: 'inline-flex', + fontVariantNumeric: 'tabular-nums', + fontWeight: 'medium', + fontFamily: 'code', + gap: '1', + lineHeight: '1', + }, + defaultVariants: { + size: 'md', + variant: 'subtle', + }, + variants: { + variant: { + solid: { + bg: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + }, + surface: { + bg: 'colorPalette.surface.bg', + borderWidth: '1px', + borderColor: 'colorPalette.surface.border', + color: 'colorPalette.surface.fg', + }, + subtle: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + }, + outline: { + borderWidth: '1px', + borderColor: 'colorPalette.outline.border', + color: 'colorPalette.outline.fg', + }, + plain: { + color: 'colorPalette.plain.fg', + }, + }, + size: { + sm: { textStyle: 'xs', height: '4.5', minWidth: '4.5', px: '1' }, + md: { textStyle: 'sm', height: '5', minWidth: '5', px: '1' }, + lg: { textStyle: 'sm', height: '5.5', minWidth: '5.5', px: '1' }, + xl: { textStyle: 'md', height: '6', minWidth: '6', px: '1' }, + }, + }, +}) diff --git a/src/theme/recipes/collapsible.ts b/src/theme/recipes/collapsible.ts new file mode 100644 index 0000000..51a6d34 --- /dev/null +++ b/src/theme/recipes/collapsible.ts @@ -0,0 +1,20 @@ +import { collapsibleAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const collapsible = defineSlotRecipe({ + className: 'collapsible', + slots: collapsibleAnatomy.keys(), + base: { + content: { + overflow: 'hidden', + _open: { + animationName: 'expand-height, fade-in', + animationDuration: 'slow', + }, + _closed: { + animationName: 'collapse-height, fade-out', + animationDuration: 'normal', + }, + }, + }, +}) diff --git a/src/theme/recipes/color-picker.ts b/src/theme/recipes/color-picker.ts new file mode 100644 index 0000000..f4987c9 --- /dev/null +++ b/src/theme/recipes/color-picker.ts @@ -0,0 +1,89 @@ +import { colorPickerAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const colorPicker = defineSlotRecipe({ + className: 'color-picker', + slots: colorPickerAnatomy.keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '1.5', + }, + label: { + color: 'fg.default', + fontWeight: 'medium', + textStyle: 'sm', + }, + control: { + display: 'flex', + flexDirection: 'row', + gap: '2', + }, + content: { + background: 'gray.surface.bg', + borderRadius: 'l3', + boxShadow: 'lg', + display: 'flex', + flexDirection: 'column', + maxWidth: 'sm', + p: '4', + zIndex: 'dropdown', + _open: { + animation: 'fadeIn 0.25s ease-out', + }, + _closed: { + animation: 'fadeOut 0.2s ease-out', + }, + _hidden: { + display: 'none', + }, + }, + area: { + height: '36', + borderRadius: 'l2', + overflow: 'hidden', + }, + areaThumb: { + borderRadius: 'full', + height: '2.5', + width: '2.5', + boxShadow: 'white 0px 0px 0px 2px, black 0px 0px 2px 1px', + outline: 'none', + }, + areaBackground: { + height: 'full', + }, + channelSlider: { + borderRadius: 'l2', + }, + channelSliderTrack: { + height: '3', + borderRadius: 'l2', + }, + swatchGroup: { + display: 'grid', + gridTemplateColumns: 'repeat(7, 1fr)', + gap: '2', + background: 'gray.surface.bg', + }, + swatch: { + height: '6', + width: '6', + borderRadius: 'l2', + boxShadow: + '0 0 0 1px var(--colors-border-emphasized), 0 0 0 2px var(--colors-bg-default) inset', + }, + channelSliderThumb: { + borderRadius: 'full', + height: '2.5', + width: '2.5', + boxShadow: 'white 0px 0px 0px 2px, black 0px 0px 2px 1px', + transform: 'translate(-50%, -50%)', + outline: 'none', + }, + transparencyGrid: { + borderRadius: 'l2', + }, + }, +}) diff --git a/src/theme/recipes/combobox.ts b/src/theme/recipes/combobox.ts new file mode 100644 index 0000000..396e003 --- /dev/null +++ b/src/theme/recipes/combobox.ts @@ -0,0 +1,190 @@ +import { comboboxAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' +import { input } from './input' + +export const combobox = defineSlotRecipe({ + className: 'combobox', + slots: comboboxAnatomy.extendWith('indicatorGroup').keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '1.5', + width: 'full', + }, + label: { + textStyle: 'label', + }, + input: { + ...input.base, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + control: { + position: 'relative', + }, + content: { + background: 'gray.surface.bg', + borderRadius: 'l2', + boxShadow: 'md', + display: 'flex', + flexDirection: 'column', + maxH: 'min(var(--available-height), {sizes.96})', + minWidth: 'max(var(--reference-width), {sizes.40})', + outline: '0', + overflowY: 'auto', + zIndex: 'dropdown', + _open: { + animationStyle: 'slide-fade-in', + animationDuration: 'slow', + }, + _closed: { + animationStyle: 'slide-fade-out', + animationDuration: 'fastest', + }, + '&[data-empty]:not(:has([data-scope=combobox][data-part=empty]))': { + opacity: 0, + }, + }, + item: { + alignItems: 'center', + borderRadius: 'l1', + cursor: 'pointer', + display: 'flex', + justifyContent: 'space-between', + _hover: { + background: 'gray.surface.bg.hover', + }, + _highlighted: { + background: 'gray.surface.bg.hover', + }, + _selected: {}, + _disabled: { + layerStyle: 'disabled', + }, + }, + itemGroup: { + display: 'flex', + flexDirection: 'column', + }, + itemGroupLabel: { + alignItems: 'flex-start', + color: 'fg.subtle', + display: 'flex', + flexDirection: 'column', + fontWeight: 'medium', + gap: '1px', + justifyContent: 'center', + _after: { + content: '""', + width: '100%', + height: '1px', + bg: 'border', + }, + }, + itemIndicator: { + color: 'colorPalette.plain.fg', + }, + indicatorGroup: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + gap: '1', + pos: 'absolute', + insetEnd: '0', + top: '0', + bottom: '0', + }, + trigger: { + color: 'fg.subtle', + }, + clearTrigger: { + color: 'fg.muted', + }, + empty: { + display: 'flex', + alignItems: 'center', + color: 'fg.subtle', + }, + }, + defaultVariants: { + size: 'md', + variant: 'outline', + }, + variants: { + variant: { + outline: { + input: input.variants.variant.outline, + }, + surface: { + input: input.variants.variant.surface, + }, + subtle: { + input: input.variants.variant.subtle, + }, + }, + size: { + xs: { + input: { + ...input.variants.size.xs, + pe: '12', + }, + content: { p: '1', gap: '0.5', textStyle: 'sm' }, + item: { px: '1', minH: '8', gap: '2', _icon: { boxSize: '3.5' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '1', height: '8' }, + indicatorGroup: { px: '2', _icon: { boxSize: '3.5' } }, + empty: { px: '1', minH: '8' }, + }, + sm: { + input: { + ...input.variants.size.sm, + pe: '14', + }, + content: { p: '1', gap: '0.5', textStyle: 'sm' }, + item: { px: '1.5', minH: '9', gap: '2', _icon: { boxSize: '4' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '1.5', height: '9' }, + indicatorGroup: { px: '2.5', _icon: { boxSize: '4' } }, + empty: { px: '1.5', minH: '9' }, + }, + md: { + input: { + ...input.variants.size.md, + pe: '14', + }, + content: { p: '1', gap: '0.5', textStyle: 'md' }, + indicatorGroup: { px: '3', _icon: { boxSize: '4' } }, + item: { px: '2', minH: '10', gap: '2', _icon: { boxSize: '4' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '2', height: '10' }, + empty: { px: '2', minH: '10' }, + }, + lg: { + input: { + ...input.variants.size.lg, + pe: '16', + }, + content: { p: '1', gap: '0.5', textStyle: 'md' }, + item: { px: '2.5', minH: '11', gap: '2', _icon: { boxSize: '4.5' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '2.5', height: '11' }, + indicatorGroup: { px: '3.5', _icon: { boxSize: '4.5' } }, + empty: { px: '2.5', minH: '11' }, + }, + xl: { + input: { + ...input.variants.size.xl, + pe: '16', + }, + content: { p: '1', gap: '1', textStyle: 'lg' }, + item: { px: '3', minH: '12', gap: '3', _icon: { boxSize: '5' } }, + itemGroup: { gap: '1' }, + itemGroupLabel: { px: '3', height: '12' }, + indicatorGroup: { px: '4', _icon: { boxSize: '5' } }, + empty: { px: '3', minH: '12' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/date-picker.ts b/src/theme/recipes/date-picker.ts new file mode 100644 index 0000000..0b7d327 --- /dev/null +++ b/src/theme/recipes/date-picker.ts @@ -0,0 +1,91 @@ +import { datePickerAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const datePicker = defineSlotRecipe({ + className: 'date-picker', + slots: datePickerAnatomy.keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '1.5', + }, + content: { + background: 'gray.surface.bg', + borderRadius: 'l3', + boxShadow: 'lg', + display: 'flex', + flexDirection: 'column', + gap: '3', + p: '4', + width: '344px', + zIndex: 'dropdown', + _open: { + animation: 'fadeIn 0.25s ease-out', + }, + _closed: { + animation: 'fadeOut 0.2s ease-out', + }, + _hidden: { + display: 'none', + }, + }, + control: { + display: 'flex', + flexDirection: 'row', + gap: '2', + }, + label: { + color: 'fg.default', + fontWeight: 'medium', + textStyle: 'sm', + }, + tableHeader: { + color: 'fg.muted', + fontWeight: 'semibold', + height: '10', + textStyle: 'sm', + }, + viewControl: { + display: 'flex', + gap: '2', + justifyContent: 'space-between', + }, + table: { + width: 'full', + borderCollapse: 'separate', + borderSpacing: '1', + m: '-1', + }, + tableCell: { + textAlign: 'center', + }, + tableCellTrigger: { + width: '100%', + _today: { + _before: { + content: "'−'", + color: 'colorPalette.solid', + position: 'absolute', + marginTop: '6', + }, + }, + '&[data-in-range]': { + background: 'gray.subtle.bg', + }, + _selected: { + _before: { + color: 'colorPalette.contrast', + }, + }, + }, + view: { + display: 'flex', + flexDirection: 'column', + gap: '3', + _hidden: { + display: 'none', + }, + }, + }, +}) diff --git a/src/theme/recipes/dialog.ts b/src/theme/recipes/dialog.ts new file mode 100644 index 0000000..9cf4e2b --- /dev/null +++ b/src/theme/recipes/dialog.ts @@ -0,0 +1,210 @@ +import { dialogAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const dialog = defineSlotRecipe({ + className: 'dialog', + slots: dialogAnatomy.extendWith('header', 'body', 'footer').keys(), + base: { + backdrop: { + background: 'black.a7', + height: '100dvh', + left: '0', + position: 'fixed', + top: '0', + width: '100dvw', + zIndex: 'var(--z-index)', + _open: { + animationName: 'fade-in', + animationTimingFunction: 'emphasized-in', + animationDuration: 'normal', + }, + _closed: { + animationName: 'fade-out', + animationTimingFunction: 'emphasized-out', + animationDuration: 'fast', + }, + }, + positioner: { + '--dialog-z-index': 'zIndex.modal', + display: 'flex', + height: '100dvh', + justifyContent: 'center', + left: 0, + overscrollBehaviorY: 'none', + position: 'fixed', + top: 0, + width: '100dvw', + zIndex: 'calc(var(--dialog-z-index) + var(--layer-index, 0))', + }, + + title: { + fontWeight: 'semibold', + textStyle: 'lg', + }, + description: { + color: 'fg.muted', + textStyle: 'sm', + }, + closeTrigger: { + pos: 'absolute', + top: '3', + insetEnd: '3', + }, + content: { + '--dialog-z-index': 'zIndex.modal', + bg: 'gray.surface.bg', + borderRadius: 'l3', + boxShadow: 'lg', + display: 'flex', + flexDirection: 'column', + my: 'var(--dialog-margin, var(--dialog-base-margin))', + outline: 0, + position: 'relative', + textStyle: 'sm', + width: '100%', + zIndex: 'calc(var(--dialog-z-index) + var(--layer-index, 0))', + py: { base: '4', md: '6' }, + gap: { base: '4', md: '6' }, + _open: { + animationDuration: 'slowest', + }, + _closed: { + animationDuration: 'normal', + }, + }, + header: { + display: 'flex', + flexDirection: 'column', + gap: '0.5', + px: { base: '4', md: '6' }, + flex: '0', + }, + body: { + display: 'flex', + flex: '1', + flexDirection: 'column', + alignItems: 'flex-start', + px: { base: '4', md: '6' }, + }, + footer: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + flex: '0', + gap: '3', + px: { base: '4', md: '6' }, + }, + }, + defaultVariants: { + size: 'md', + scrollBehavior: 'outside', + placement: 'center', + motionPreset: 'scale', + }, + variants: { + motionPreset: { + scale: { + content: { + _open: { animationName: 'scale-in, fade-in' }, + _closed: { animationName: 'scale-out, fade-out' }, + }, + }, + 'slide-in-bottom': { + content: { + _open: { animationName: 'slide-from-bottom, fade-in' }, + _closed: { animationName: 'slide-to-bottom, fade-out' }, + }, + }, + 'slide-in-top': { + content: { + _open: { animationName: 'slide-from-top, fade-in' }, + _closed: { animationName: 'slide-to-top, fade-out' }, + }, + }, + 'slide-in-left': { + content: { + _open: { animationName: 'slide-from-left, fade-in' }, + _closed: { animationName: 'slide-to-left, fade-out' }, + }, + }, + 'slide-in-right': { + content: { + _open: { animationName: 'slide-from-right, fade-in' }, + _closed: { animationName: 'slide-to-right, fade-out' }, + }, + }, + none: {}, + }, + size: { + xs: { content: { maxW: 'xs' } }, + sm: { content: { maxW: 'sm' } }, + md: { content: { maxW: 'md' } }, + lg: { content: { maxW: 'lg' } }, + xl: { content: { maxW: 'xl' } }, + cover: { + positioner: { padding: '8' }, + content: { + width: '100%', + height: '100%', + '--dialog-margin': '0', + }, + }, + full: { + content: { + maxW: '100dvw', + minH: '100dvh', + '--dialog-margin': '0', + borderRadius: '0', + }, + }, + }, + placement: { + center: { + positioner: { + alignItems: 'center', + }, + content: { + '--dialog-base-margin': 'auto', + mx: 'auto', + }, + }, + top: { + positioner: { + alignItems: 'flex-start', + }, + content: { + '--dialog-base-margin': 'spacing.16', + mx: 'auto', + }, + }, + bottom: { + positioner: { + alignItems: 'flex-end', + }, + content: { + '--dialog-base-margin': 'spacing.16', + mx: 'auto', + }, + }, + }, + scrollBehavior: { + inside: { + positioner: { + overflow: 'hidden', + }, + content: { + maxH: 'calc(100% - 7.5rem)', + }, + body: { + overflow: 'auto', + }, + }, + outside: { + positioner: { + overflow: 'auto', + pointerEvents: 'auto', + }, + }, + }, + }, +}) diff --git a/src/theme/recipes/drawer.ts b/src/theme/recipes/drawer.ts new file mode 100644 index 0000000..7824622 --- /dev/null +++ b/src/theme/recipes/drawer.ts @@ -0,0 +1,202 @@ +import { dialogAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const drawer = defineSlotRecipe({ + className: 'drawer', + slots: dialogAnatomy.extendWith('header', 'body', 'footer').keys(), + base: { + backdrop: { + background: 'black.a7', + position: 'fixed', + insetInlineStart: '0', + top: '0', + width: '100vw', + height: '100dvh', + zIndex: 'overlay', + _open: { + animationName: 'fade-in', + animationTimingFunction: 'emphasized-in', + animationDuration: 'slow', + }, + _closed: { + animationName: 'fade-out', + animationTimingFunction: 'emphasized-out', + animationDuration: 'normal', + }, + }, + positioner: { + display: 'flex', + width: '100vw', + height: '100dvh', + position: 'fixed', + insetInlineStart: '0', + top: '0', + zIndex: 'modal', + overscrollBehaviorY: 'none', + }, + content: { + display: 'flex', + flexDirection: 'column', + position: 'relative', + width: '100%', + outline: 0, + zIndex: 'modal', + maxH: '100dvh', + color: 'inherit', + bg: 'gray.surface.bg', + boxShadow: 'lg', + _open: { + animationDuration: 'slowest', + animationTimingFunction: 'cubic-bezier(0.05, 0.7, 0.1, 1.0)', + }, + _closed: { + animationDuration: 'normal', + animationTimingFunction: 'cubic-bezier(0.3, 0.0, 0.8, 0.15)', + }, + }, + header: { + display: 'flex', + flexDirection: 'column', + gap: '1', + pt: { base: '4', md: '6' }, + pb: '4', + px: { base: '4', md: '6' }, + flex: '0', + }, + body: { + display: 'flex', + flexDirection: 'column', + alignItems: 'flex-start', + flex: '1', + overflow: 'auto', + p: { base: '4', md: '6' }, + }, + footer: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + flex: '0', + gap: '3', + py: '4', + px: { base: '4', md: '6' }, + }, + title: { + color: 'fg.default', + fontWeight: 'semibold', + textStyle: 'xl', + }, + description: { + color: 'fg.muted', + textStyle: 'sm', + }, + closeTrigger: { + pos: 'absolute', + top: '3', + insetEnd: '3', + }, + }, + defaultVariants: { + placement: 'end', + size: 'sm', + }, + variants: { + size: { + xs: { + content: { + maxW: 'xs', + }, + }, + sm: { + content: { + maxW: 'sm', + }, + }, + md: { + content: { + maxW: 'md', + }, + }, + lg: { + content: { + maxW: 'lg', + }, + }, + xl: { + content: { + maxW: 'xl', + }, + }, + full: { + content: { + maxW: '100vw', + h: '100dvh', + }, + }, + }, + placement: { + start: { + positioner: { + justifyContent: 'flex-start', + alignItems: 'stretch', + }, + content: { + _open: { + animationName: { + base: 'slide-from-left-full, fade-in', + _rtl: 'slide-from-right-full, fade-in', + }, + }, + _closed: { + animationName: { + base: 'slide-to-left-full, fade-out', + _rtl: 'slide-to-right-full, fade-out', + }, + }, + }, + }, + end: { + positioner: { + justifyContent: 'flex-end', + alignItems: 'stretch', + }, + content: { + _open: { + animationName: { + base: 'slide-from-right-full, fade-in', + _rtl: 'slide-from-left-full, fade-in', + }, + }, + _closed: { + animationName: { + base: 'slide-to-right-full, fade-out', + _rtl: 'slide-to-left-full, fade-out', + }, + }, + }, + }, + top: { + positioner: { + justifyContent: 'stretch', + alignItems: 'flex-start', + }, + content: { + maxW: '100%', + _open: { animationName: 'slide-from-top-full, fade-in' }, + _closed: { animationName: 'slide-to-top-full, fade-out' }, + }, + }, + + bottom: { + positioner: { + justifyContent: 'stretch', + alignItems: 'flex-end', + }, + content: { + maxW: '100%', + _open: { animationName: 'slide-from-bottom-full, fade-in' }, + _closed: { animationName: 'slide-to-bottom-full, fade-out' }, + }, + }, + }, + }, +}) diff --git a/src/theme/recipes/editable.ts b/src/theme/recipes/editable.ts new file mode 100644 index 0000000..7f73dc0 --- /dev/null +++ b/src/theme/recipes/editable.ts @@ -0,0 +1,74 @@ +import { editableAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const editable = defineSlotRecipe({ + slots: editableAnatomy.keys(), + className: 'editable', + base: { + root: { + alignItems: 'center', + display: 'inline-flex', + gap: '1.5', + position: 'relative', + width: 'full', + }, + preview: { + alignItems: 'center', + borderRadius: 'l2', + cursor: 'default', + display: 'inline-flex', + transitionDuration: 'normal', + transitionProperty: 'common', + _disabled: { + userSelect: 'none', + }, + _hover: { + bg: 'gray.plain.bg.hover', + }, + }, + input: { + borderRadius: 'l2', + + focusRingWidth: '2px', + focusRing: 'inside', + transitionDuration: 'normal', + transitionProperty: 'common', + width: 'full', + _focusVisible: { + outlineOffset: '-1px', + }, + }, + control: { + alignItems: 'center', + display: 'inline-flex', + gap: '1.5', + }, + }, + defaultVariants: { + size: 'md', + }, + variants: { + size: { + '2xs': { + preview: { textStyle: 'xs', px: '2', py: '0.5' }, + input: { textStyle: 'xs', px: '2', py: '0.5' }, + }, + xs: { + preview: { textStyle: 'sm', px: '2.5', py: '1.5' }, + input: { textStyle: 'sm', px: '2.5', py: '1.5' }, + }, + sm: { + preview: { textStyle: 'sm', px: '3', py: '2' }, + input: { textStyle: 'sm', px: '3', py: '2' }, + }, + md: { + preview: { textStyle: 'sm', px: '3.5', py: '2.5' }, + input: { textStyle: 'sm', px: '3.5', py: '2.5' }, + }, + lg: { + preview: { textStyle: 'md', px: '4', py: '2.5' }, + input: { textStyle: 'md', px: '4', py: '2.5' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/field.ts b/src/theme/recipes/field.ts new file mode 100644 index 0000000..66daac9 --- /dev/null +++ b/src/theme/recipes/field.ts @@ -0,0 +1,40 @@ +import { fieldAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const field = defineSlotRecipe({ + className: 'field', + slots: fieldAnatomy.keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '1.5', + }, + label: { + alignItems: 'center', + color: 'fg.default', + display: 'flex', + gap: '0.5', + textAlign: 'start', + userSelect: 'none', + textStyle: 'label', + _disabled: { + layerStyle: 'disabled', + }, + }, + requiredIndicator: { + color: 'colorPalette.solid', + }, + helperText: { + color: 'fg.muted', + textStyle: 'sm', + _disabled: { + layerStyle: 'disabled', + }, + }, + errorText: { + color: 'error', + textStyle: 'sm', + }, + }, +}) diff --git a/src/theme/recipes/fieldset.ts b/src/theme/recipes/fieldset.ts new file mode 100644 index 0000000..48d4ec4 --- /dev/null +++ b/src/theme/recipes/fieldset.ts @@ -0,0 +1,46 @@ +import { fieldsetAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const fieldset = defineSlotRecipe({ + className: 'fieldset', + slots: fieldsetAnatomy.extendWith('content', 'control').keys(), + base: { + root: { + display: 'flex', + justifyContent: 'space-between', + width: 'full', + flexDirection: { base: 'column', md: 'row' }, + gap: { base: '5', md: '8' }, + }, + control: { + maxW: 'xs', + display: 'flex', + flexDirection: 'column', + width: 'full', + gap: '1', + }, + content: { + display: 'flex', + flexDirection: 'column', + width: 'full', + maxW: '2xl', + gap: '4', + }, + legend: { + color: 'fg.default', + fontWeight: 'semibold', + }, + helperText: { + color: 'fg.muted', + textStyle: 'sm', + }, + errorText: { + display: 'inline-flex', + alignItems: 'center', + color: 'error', + gap: '2', + fontWeight: 'medium', + textStyle: 'sm', + }, + }, +}) diff --git a/src/theme/recipes/file-upload.ts b/src/theme/recipes/file-upload.ts new file mode 100644 index 0000000..0e6f4de --- /dev/null +++ b/src/theme/recipes/file-upload.ts @@ -0,0 +1,85 @@ +import { fileUploadAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const fileUpload = defineSlotRecipe({ + className: 'file-upload', + slots: fileUploadAnatomy.keys(), + base: { + root: { + alignItems: 'flex-start', + display: 'flex', + flexDirection: 'column', + gap: '1.5', + width: 'full', + }, + label: { + textStyle: 'label', + }, + dropzone: { + alignItems: 'center', + background: 'gray.surface.bg', + borderRadius: 'l3', + borderStyle: 'dashed', + borderWidth: '2px', + display: 'flex', + flexDirection: 'column', + + focusVisibleRing: 'outside', + justifyContent: 'center', + transition: 'backgrounds', + width: 'full', + _dragging: { + background: 'gray.surface.bg.hover', + borderStyle: 'solid', + borderColor: 'colorPalette.solid.bg', + }, + }, + item: { + alignItems: 'start', + animationDuration: 'normal', + animationName: 'fade-in', + background: 'gray.surface.bg', + borderRadius: 'l3', + borderWidth: '1px', + display: 'flex', + pos: 'relative', + width: 'full', + }, + itemGroup: { + display: 'flex', + alignItems: 'start', + flexDirection: 'column', + width: 'full', + }, + itemName: { + color: 'fg.default', + fontWeight: 'medium', + }, + itemSizeText: { + color: 'fg.muted', + }, + itemDeleteTrigger: { + color: 'fg.subtle', + }, + itemPreviewImage: { + aspectRatio: '1', + objectFit: 'cover', + maxW: '20', + borderRadius: 'l2', + }, + }, + defaultVariants: { + size: 'md', + }, + variants: { + size: { + md: { + root: { gap: '4' }, + dropzone: { px: '6', py: '4', minHeight: 'xs', gap: '0' }, + item: { p: '4', gap: '3', textStyle: 'sm' }, + itemGroup: { gap: '3' }, + itemDeleteTrigger: { _icon: { boxSize: '4' } }, + }, + }, + }, +}) diff --git a/src/theme/recipes/heading.ts b/src/theme/recipes/heading.ts new file mode 100644 index 0000000..c729995 --- /dev/null +++ b/src/theme/recipes/heading.ts @@ -0,0 +1,8 @@ +import { defineRecipe } from '@pandacss/dev' + +export const heading = defineRecipe({ + className: 'heading', + base: { + fontWeight: 'semibold', + }, +}) diff --git a/src/theme/recipes/hover-card.ts b/src/theme/recipes/hover-card.ts new file mode 100644 index 0000000..fb2c174 --- /dev/null +++ b/src/theme/recipes/hover-card.ts @@ -0,0 +1,41 @@ +import { hoverCardAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const hoverCard = defineSlotRecipe({ + className: 'hover-card', + slots: hoverCardAnatomy.keys(), + base: { + content: { + '--hovercard-bg': 'colors.gray.surface.bg', + + bg: 'var(--hovercard-bg)', + borderRadius: 'l3', + boxShadow: 'lg', + display: 'flex', + flexDirection: 'column', + maxWidth: '80', + outline: '0', + padding: '4', + position: 'relative', + textStyle: 'sm', + transformOrigin: 'var(--transform-origin)', + zIndex: 'popover', + _open: { + animationStyle: 'slide-fade-in', + animationDuration: 'fast', + }, + _closed: { + animationStyle: 'slide-fade-out', + animationDuration: 'faster', + }, + }, + arrow: { + '--arrow-size': 'sizes.3', + '--arrow-background': 'var(--hovercard-bg)', + }, + arrowTip: { + borderTopWidth: '0.5px', + borderInlineStartWidth: '0.5px', + }, + }, +}) diff --git a/src/theme/recipes/icon.ts b/src/theme/recipes/icon.ts new file mode 100644 index 0000000..9535d19 --- /dev/null +++ b/src/theme/recipes/icon.ts @@ -0,0 +1,25 @@ +import { defineRecipe } from '@pandacss/dev' + +export const icon = defineRecipe({ + className: 'icon', + base: { + color: 'currentcolor', + display: 'inline-block', + flexShrink: '0', + verticalAlign: 'middle', + lineHeight: '1em', + }, + defaultVariants: { + size: 'md', + }, + variants: { + size: { + '2xs': { boxSize: '3' }, + xs: { boxSize: '4' }, + sm: { boxSize: '4.5' }, + md: { boxSize: '5' }, + lg: { boxSize: '5.5' }, + xl: { boxSize: '6' }, + }, + }, +}) diff --git a/src/theme/recipes/index.ts b/src/theme/recipes/index.ts index b55a014..c5fdd81 100644 --- a/src/theme/recipes/index.ts +++ b/src/theme/recipes/index.ts @@ -1,3 +1,55 @@ +import { tooltip } from "./tooltip"; +import { toggleGroup } from "./toggle-group"; +import { toast } from "./toast"; +import { textarea } from "./textarea"; +import { text } from "./text"; +import { tagsInput } from "./tags-input"; +import { tabs } from "./tabs"; +import { table } from "./table"; +import { switchRecipe } from "./switch"; +import { splitter } from "./splitter"; +import { slider } from "./slider"; +import { skeleton } from "./skeleton"; +import { select } from "./select"; +import { segmentGroup } from "./segment-group"; +import { scrollArea } from "./scroll-area"; +import { ratingGroup } from "./rating-group"; +import { radioGroup } from "./radio-group"; +import { radioCardGroup } from "./radio-card-group"; +import { progress } from "./progress"; +import { popover } from "./popover"; +import { pinInput } from "./pin-input"; +import { pagination } from "./pagination"; +import { numberInput } from "./number-input"; +import { menu } from "./menu"; +import { link } from "./link"; +import { kbd } from "./kbd"; +import { inputGroup } from "./input-group"; +import { inputAddon } from "./input-addon"; +import { input } from "./input"; +import { icon } from "./icon"; +import { hoverCard } from "./hover-card"; +import { heading } from "./heading"; +import { fileUpload } from "./file-upload"; +import { fieldset } from "./fieldset"; +import { field } from "./field"; +import { editable } from "./editable"; +import { drawer } from "./drawer"; +import { dialog } from "./dialog"; +import { datePicker } from "./date-picker"; +import { combobox } from "./combobox"; +import { colorPicker } from "./color-picker"; +import { collapsible } from "./collapsible"; +import { code } from "./code"; +import { clipboard } from "./clipboard"; +import { checkbox } from "./checkbox"; +import { carousel } from "./carousel"; +import { card } from "./card"; +import { breadcrumb } from "./breadcrumb"; +import { badge } from "./badge"; +import { avatar } from "./avatar"; +import { alert } from "./alert"; +import { accordion } from "./accordion"; import { absoluteCenter } from './absolute-center' import { button } from './button' import { group } from './group' @@ -7,5 +59,57 @@ export const recipes = { group, absoluteCenter, spinner, + accordion, + alert, + avatar, + badge, + breadcrumb, + card, + carousel, + checkbox, + clipboard, + code, + collapsible, + colorPicker, + combobox, + datePicker, + dialog, + drawer, + editable, + field, + fieldset, + fileUpload, + heading, + hoverCard, + icon, + input, + inputAddon, + inputGroup, + kbd, + link, + menu, + numberInput, + pagination, + pinInput, + popover, + progress, + radioCardGroup, + radioGroup, + ratingGroup, + scrollArea, + segmentGroup, + select, + skeleton, + slider, + splitter, + switchRecipe, + table, + tabs, + tagsInput, + text, + textarea, + toast, + toggleGroup, + tooltip } -export const slotRecipes = {} +export const slotRecipes = {} \ No newline at end of file diff --git a/src/theme/recipes/input-addon.ts b/src/theme/recipes/input-addon.ts new file mode 100644 index 0000000..b5e4ced --- /dev/null +++ b/src/theme/recipes/input-addon.ts @@ -0,0 +1,42 @@ +import { defineRecipe } from '@pandacss/dev' + +export const inputAddon = defineRecipe({ + className: 'input-addon', + base: { + alignItems: 'center', + alignSelf: 'stretch', + borderRadius: 'l2', + color: 'fg.muted', + display: 'flex', + flex: '0 0 auto', + whiteSpace: 'nowrap', + width: 'auto', + }, + defaultVariants: { + size: 'md', + variant: 'outline', + }, + variants: { + variant: { + outline: { + borderWidth: '1px', + borderColor: 'gray.outline.border', + }, + surface: { + bg: 'gray.surface.bg', + borderWidth: '1px', + borderColor: 'gray.surface.border', + }, + subtle: { + bg: 'gray.subtle.bg', + }, + }, + size: { + xs: { textStyle: 'sm', px: '2', _icon: { boxSize: '4' } }, + sm: { textStyle: 'sm', px: '2.5', _icon: { boxSize: '4.5' } }, + md: { textStyle: 'md', px: '3', _icon: { boxSize: '5' } }, + lg: { textStyle: 'md', px: '3.5', _icon: { boxSize: '5' } }, + xl: { textStyle: 'lg', px: '4', _icon: { boxSize: '5.5' } }, + }, + }, +}) diff --git a/src/theme/recipes/input-group.ts b/src/theme/recipes/input-group.ts new file mode 100644 index 0000000..d6be7a0 --- /dev/null +++ b/src/theme/recipes/input-group.ts @@ -0,0 +1,66 @@ +import { defineSlotRecipe } from '@pandacss/dev' + +export const inputGroup = defineSlotRecipe({ + className: 'input-group', + slots: ['root', 'element'], + base: { + root: { + position: 'relative', + width: 'full', + }, + element: { + alignItems: 'center', + color: 'fg.muted', + display: 'flex', + height: 'full', + justifyContent: 'center', + position: 'absolute', + zIndex: '2', + _icon: { + color: 'fg.subtle', + }, + }, + }, + defaultVariants: { + size: 'md', + }, + variants: { + size: { + xs: { + element: { minW: '8', _icon: { boxSize: '4' } }, + root: { + '& > input:not(:first-child)': { ps: '7!' }, + '& > input:not(:last-child)': { pe: '7!' }, + }, + }, + sm: { + root: { + '& > input:not(:first-child)': { ps: '8!' }, + '& > input:not(:last-child)': { pe: '8!' }, + }, + element: { minW: '9', _icon: { boxSize: '4.5' } }, + }, + md: { + root: { + '& > input:not(:first-child)': { ps: '9!' }, + '& > input:not(:last-child)': { pe: '9!' }, + }, + element: { minW: '10', _icon: { boxSize: '5' } }, + }, + lg: { + root: { + '& > input:not(:first-child)': { ps: '10!' }, + '& > input:not(:last-child)': { pe: '10!' }, + }, + element: { minW: '11', _icon: { boxSize: '5' } }, + }, + xl: { + root: { + '& > input:not(:first-child)': { ps: '11!' }, + '& > input:not(:last-child)': { pe: '11!' }, + }, + element: { minW: '11', _icon: { boxSize: '5.5' } }, + }, + }, + }, +}) diff --git a/src/theme/recipes/input.ts b/src/theme/recipes/input.ts new file mode 100644 index 0000000..2b43e70 --- /dev/null +++ b/src/theme/recipes/input.ts @@ -0,0 +1,89 @@ +import type { RecipeConfig } from '@pandacss/dev' + +export const input = { + className: 'input', + jsx: ['Input', 'Field.Input'], + base: { + appearance: 'none', + borderRadius: 'l2', + height: 'var(--input-height)', + minHeight: 'var(--input-height)', + minW: 'var(--input-height)', + outline: '0', + position: 'relative', + textAlign: 'start', + transition: 'colors', + width: '100%', + _disabled: { + layerStyle: 'disabled', + }, + }, + defaultVariants: { + size: 'md', + variant: 'outline', + }, + variants: { + variant: { + outline: { + borderWidth: '1px', + borderColor: 'gray.outline.border', + focusVisibleRing: 'inside', + _invalid: { + focusRingColor: 'error', + borderColor: 'error', + }, + }, + surface: { + bg: 'gray.surface.bg', + borderWidth: '1px', + borderColor: 'gray.surface.border', + focusVisibleRing: 'inside', + + _invalid: { + focusRingColor: 'error', + borderColor: 'error', + }, + }, + subtle: { + borderWidth: '1px', + borderColor: 'transparent', + bg: 'gray.subtle.bg', + color: 'gray.subtle.fg', + focusVisibleRing: 'inside', + + _invalid: { + focusRingColor: 'error', + borderColor: 'error', + }, + }, + flushed: { + borderBottomWidth: '1px', + borderBottomColor: 'gray.outline.border', + borderRadius: '0', + color: 'fg.default', + px: '0', + _invalid: { + borderColor: 'error', + }, + _focus: { + borderColor: 'colorPalette.solid.bg', + boxShadowColor: 'colorPalette.solid.bg', + boxShadow: '0 1px 0 0 var(--shadow-color)', + _invalid: { + borderColor: 'error', + boxShadowColor: 'error', + }, + }, + }, + }, + size: { + '2xs': { textStyle: 'xs', px: '1.5', '--input-height': 'sizes.7' }, + xs: { textStyle: 'sm', px: '2', '--input-height': 'sizes.8' }, + sm: { textStyle: 'sm', px: '2.5', '--input-height': 'sizes.9' }, + md: { textStyle: 'md', px: '3', '--input-height': 'sizes.10' }, + lg: { textStyle: 'md', px: '3.5', '--input-height': 'sizes.11' }, + xl: { textStyle: 'lg', px: '4', '--input-height': 'sizes.12' }, + '2xl': { textStyle: '3xl', px: '4.5', '--input-height': 'sizes.16' }, + }, + }, +} satisfies RecipeConfig diff --git a/src/theme/recipes/kbd.ts b/src/theme/recipes/kbd.ts new file mode 100644 index 0000000..9b71134 --- /dev/null +++ b/src/theme/recipes/kbd.ts @@ -0,0 +1,55 @@ +import { defineRecipe } from '@pandacss/dev' + +export const kbd = defineRecipe({ + className: 'kbd', + base: { + display: 'inline-flex', + alignItems: 'center', + fontWeight: 'medium', + fontFamily: 'code', + flexShrink: '0', + whiteSpace: 'nowrap', + wordSpacing: '-0.5em', + userSelect: 'none', + borderRadius: 'l2', + justifyContent: 'center', + }, + + variants: { + variant: { + solid: { + bg: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + }, + surface: { + bg: 'colorPalette.surface.bg', + borderWidth: '1px', + borderColor: 'colorPalette.surface.border', + color: 'colorPalette.surface.fg', + }, + outline: { + borderWidth: '1px', + borderColor: 'colorPalette.outline.border', + color: 'colorPalette.outline.fg', + }, + subtle: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + }, + plain: { + color: 'colorPalette.plain.fg', + }, + }, + size: { + sm: { textStyle: 'xs', height: '4.5', minWidth: '4.5', px: '1' }, + md: { textStyle: 'sm', height: '5', minWidth: '5', px: '1' }, + lg: { textStyle: 'sm', height: '5.5', minWidth: '5.5', px: '1' }, + xl: { textStyle: 'md', height: '6', minWidth: '6', px: '1' }, + }, + }, + + defaultVariants: { + size: 'md', + variant: 'subtle', + }, +}) diff --git a/src/theme/recipes/link.ts b/src/theme/recipes/link.ts new file mode 100644 index 0000000..b132081 --- /dev/null +++ b/src/theme/recipes/link.ts @@ -0,0 +1,42 @@ +import { defineRecipe } from '@pandacss/dev' + +export const link = defineRecipe({ + className: 'link', + base: { + alignItems: 'center', + borderRadius: 'l1', + cursor: 'pointer', + display: 'inline-flex', + focusVisibleRing: 'outside', + fontWeight: 'medium', + gap: '1.5', + outline: 'none', + textDecorationLine: 'underline', + textDecorationThickness: '0.1em', + textUnderlineOffset: '0.125em', + transitionDuration: 'normal', + transitionProperty: 'text-decoration-color', + _icon: { + boxSize: '1em', + }, + }, + defaultVariants: { + variant: 'underline', + }, + variants: { + variant: { + underline: { + textDecorationColor: 'colorPalette.surface.fg/60', + _hover: { + textDecorationColor: 'colorPalette.surface.fg', + }, + }, + plain: { + textDecorationColor: 'transparent', + _hover: { + textDecorationColor: 'colorPalette.surface.fg', + }, + }, + }, + }, +}) diff --git a/src/theme/recipes/menu.ts b/src/theme/recipes/menu.ts new file mode 100644 index 0000000..29ec6eb --- /dev/null +++ b/src/theme/recipes/menu.ts @@ -0,0 +1,123 @@ +import { menuAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const menu = defineSlotRecipe({ + className: 'menu', + slots: menuAnatomy.keys(), + base: { + content: { + '--menu-z-index': 'zIndex.dropdown', + + bg: 'gray.surface.bg', + borderRadius: 'l3', + boxShadow: 'md', + display: 'flex', + flexDirection: 'column', + maxH: 'min(var(--available-height), {sizes.96})', + minWidth: 'max(var(--reference-width), {sizes.40})', + outline: '0', + overflow: 'hidden', + overflowY: 'auto', + position: 'relative', + zIndex: 'calc(var(--menu-z-index) + var(--layer-index, 0))', + _open: { + animationStyle: 'slide-fade-in', + animationDuration: 'fast', + }, + _closed: { + animationStyle: 'slide-fade-out', + animationDuration: 'faster', + }, + }, + item: { + alignItems: 'center', + borderRadius: 'l2', + display: 'flex', + flex: '0 0 auto', + outline: '0', + textAlign: 'start', + textDecoration: 'none', + userSelect: 'none', + width: '100%', + _highlighted: { + bg: 'gray.surface.bg.hover', + }, + _disabled: { + layerStyle: 'disabled', + }, + }, + trigger: { + _focusVisible: { + focusVisibleRing: 'outside', + }, + }, + itemGroupLabel: { + alignItems: 'flex-start', + color: 'fg.subtle', + display: 'flex', + flexDirection: 'column', + fontWeight: 'medium', + gap: '1px', + justifyContent: 'center', + _after: { + content: '""', + width: '100%', + height: '1px', + bg: 'border', + }, + }, + itemIndicator: { + justifyContent: 'flex-end', + display: 'flex', + flex: '1', + _checked: { + _icon: { + color: 'colorPalette.plain.fg', + }, + }, + }, + }, + defaultVariants: { + size: 'md', + }, + + variants: { + size: { + xs: { + content: { p: '1', gap: '0.5', textStyle: 'sm' }, + item: { px: '1', minH: '8', gap: '2', _icon: { boxSize: '3.5' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '1', height: '8' }, + separator: { mx: '-1', my: '0.5' }, + }, + sm: { + content: { p: '1', gap: '0.5', textStyle: 'sm' }, + item: { px: '1.5', minH: '9', gap: '2', _icon: { boxSize: '4' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '1.5', height: '9' }, + separator: { mx: '-1.5', my: '0.5' }, + }, + md: { + content: { p: '1', gap: '0.5', textStyle: 'md' }, + item: { px: '2', minH: '10', gap: '2', _icon: { boxSize: '4' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '2', height: '10' }, + separator: { mx: '-2', my: '0.5' }, + }, + lg: { + content: { p: '1', gap: '0.5', textStyle: 'md' }, + item: { px: '2.5', minH: '11', gap: '2', _icon: { boxSize: '4.5' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '2.5', height: '11' }, + separator: { mx: '-2.5', my: '0.5' }, + }, + xl: { + content: { p: '1', gap: '1', textStyle: 'lg' }, + item: { px: '3', minH: '12', gap: '3', _icon: { boxSize: '5' } }, + itemGroup: { gap: '1' }, + itemGroupLabel: { px: '3', height: '12' }, + separator: { mx: '-3', my: '0' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/number-input.ts b/src/theme/recipes/number-input.ts new file mode 100644 index 0000000..d65851d --- /dev/null +++ b/src/theme/recipes/number-input.ts @@ -0,0 +1,108 @@ +import { numberInputAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' +import { input } from './input' + +const trigger = { + alignItems: 'center', + color: 'fg.muted', + cursor: 'pointer', + display: 'flex', + flex: '1', + justifyContent: 'center', + lineHeight: '1', + transition: 'common', + userSelect: 'none', + _icon: { + boxSize: '1em', + }, + _hover: { + bg: 'gray.surface.bg.hover', + }, + _active: { + bg: 'gray.surface.bg.active', + }, +} + +export const numberInput = defineSlotRecipe({ + className: 'number-input', + slots: numberInputAnatomy.keys(), + base: { + root: { + isolation: 'isolate', + position: 'relative', + _disabled: { + layerStyle: 'disabled', + }, + }, + control: { + borderStartWidth: '1px', + display: 'flex', + divideY: '1px', + flexDirection: 'column', + height: 'calc(100% - 2px)', + insetEnd: '0px', + margin: '1px', + position: 'absolute', + top: '0', + width: 'var(--stepper-width)', + zIndex: '1', + }, + input: { + ...input.base, + verticalAlign: 'top', + pe: 'calc(var(--stepper-width) + 0.5rem)', + }, + label: { + color: 'fg.default', + fontWeight: 'medium', + }, + incrementTrigger: { + ...trigger, + borderTopRightRadius: 'l2', + }, + decrementTrigger: { + ...trigger, + borderBottomRightRadius: 'l2', + }, + }, + defaultVariants: { + size: 'md', + variant: 'outline', + }, + variants: { + size: { + sm: { + control: { + '--stepper-width': 'sizes.4.5', + }, + input: input.variants.size.sm, + }, + md: { + control: { + '--stepper-width': 'sizes.5', + }, + input: input.variants.size.md, + }, + lg: { + control: { + '--stepper-width': 'sizes.5.5', + }, + input: input.variants.size.lg, + }, + xl: { + control: { + '--stepper-width': 'sizes.6', + }, + input: input.variants.size.xl, + }, + }, + variant: { + outline: { + input: input.variants.variant.outline, + }, + surface: { + input: input.variants.variant.surface, + }, + }, + }, +}) diff --git a/src/theme/recipes/pagination.ts b/src/theme/recipes/pagination.ts new file mode 100644 index 0000000..21971be --- /dev/null +++ b/src/theme/recipes/pagination.ts @@ -0,0 +1,8 @@ +import { paginationAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const pagination = defineSlotRecipe({ + className: 'pagination', + slots: paginationAnatomy.keys(), + base: {}, +}) diff --git a/src/theme/recipes/pin-input.ts b/src/theme/recipes/pin-input.ts new file mode 100644 index 0000000..7f5a647 --- /dev/null +++ b/src/theme/recipes/pin-input.ts @@ -0,0 +1,53 @@ +import { pinInputAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' +import { input } from './input' + +export const pinInput = defineSlotRecipe({ + className: 'pin-input', + slots: pinInputAnatomy.keys(), + base: { + input: { + ...input.base, + textAlign: 'center', + width: 'var(--input-height)', + px: '1!', + }, + control: { + display: 'inline-flex', + gap: '2', + isolation: 'isolate', + }, + }, + defaultVariants: { + size: 'md', + variant: 'outline', + }, + + variants: { + size: { + xs: { + input: input.variants?.size?.xs, + }, + sm: { + input: input.variants?.size?.sm, + }, + md: { + input: input.variants?.size?.md, + }, + lg: { + input: input.variants?.size?.lg, + }, + xl: { + input: input.variants?.size?.xl, + }, + '2xl': { + input: input.variants?.size?.['2xl'], + }, + }, + variant: { + outline: { input: input.variants?.variant?.outline }, + subtle: { input: input.variants?.variant?.subtle }, + flushed: { input: input.variants?.variant?.flushed }, + }, + }, +}) diff --git a/src/theme/recipes/popover.ts b/src/theme/recipes/popover.ts new file mode 100644 index 0000000..70bd44b --- /dev/null +++ b/src/theme/recipes/popover.ts @@ -0,0 +1,71 @@ +import { popoverAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const popover = defineSlotRecipe({ + className: 'popover', + slots: popoverAnatomy.extendWith('header', 'body', 'footer').keys(), + base: { + content: { + '--popover-bg': 'colors.gray.surface.bg', + '--popover-padding': 'spacing.4', + + background: 'var(--popover-bg)', + borderRadius: 'l3', + boxShadow: 'lg', + display: 'flex', + flexDirection: 'column', + maxHeight: 'var(--available-height)', + outline: '0', + position: 'relative', + textStyle: 'sm', + transformOrigin: 'var(--transform-origin)', + width: 'xs', + zIndex: 'calc(var(--z-index-popover) + var(--layer-index, 0))', + _open: { + animationStyle: 'scale-fade-in', + animationDuration: 'fast', + }, + _closed: { + animationStyle: 'scale-fade-out', + animationDuration: 'faster', + }, + }, + title: { + color: 'fg.default', + fontWeight: 'medium', + textStyle: 'md', + }, + description: { + color: 'fg.muted', + textStyle: 'sm', + }, + closeTrigger: { + position: 'absolute', + top: '1', + right: '1', + }, + header: { + display: 'flex', + flexDirection: 'column', + pt: 'var(--popover-padding)', + px: 'var(--popover-padding)', + }, + body: { p: 'var(--popover-padding)', display: 'flex', flex: '1', flexDirection: 'column' }, + footer: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + gap: '3', + paddingInline: 'var(--popover-padding)', + paddingBottom: 'var(--popover-padding)', + }, + arrow: { + '--arrow-size': 'sizes.3', + '--arrow-background': 'var(--popover-bg)', + }, + arrowTip: { + borderTopWidth: '0.5px', + borderInlineStartWidth: '0.5px', + }, + }, +}) diff --git a/src/theme/recipes/progress.ts b/src/theme/recipes/progress.ts new file mode 100644 index 0000000..259c5c4 --- /dev/null +++ b/src/theme/recipes/progress.ts @@ -0,0 +1,120 @@ +import { progressAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const progress = defineSlotRecipe({ + slots: progressAnatomy.keys(), + className: 'progress', + base: { + root: { + textStyle: 'sm', + position: 'relative', + }, + track: { + overflow: 'hidden', + position: 'relative', + }, + range: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + transitionProperty: 'width, height', + transitionDuration: 'slow', + height: '100%', + bgColor: 'var(--track-color)', + _indeterminate: { + '--animate-from-x': '-40%', + '--animate-to-x': '100%', + position: 'absolute', + willChange: 'left', + minWidth: '50%', + animation: 'position 1s ease infinite normal none running', + backgroundImage: `linear-gradient(to right, transparent 0%, var(--track-color) 50%, transparent 100%)`, + }, + }, + label: { + display: 'inline-flex', + fontWeight: 'medium', + alignItems: 'center', + gap: '1', + }, + valueText: { + textStyle: 'xs', + lineHeight: '1', + fontWeight: 'medium', + }, + }, + + variants: { + variant: { + solid: { + track: { + bgColor: 'gray.subtle.bg', + }, + range: { + bgColor: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + }, + }, + subtle: { + track: { + bgColor: 'colorPalette.subtle.bg.active', + }, + range: { + bgColor: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + }, + }, + }, + + shape: { + square: {}, + rounded: { + track: { + borderRadius: 'l1', + }, + }, + full: { + track: { + borderRadius: 'full', + }, + }, + }, + + striped: { + true: { + range: { + backgroundImage: `linear-gradient(45deg, var(--stripe-color) 25%, transparent 25%, transparent 50%, var(--stripe-color) 50%, var(--stripe-color) 75%, transparent 75%, transparent)`, + backgroundSize: `var(--stripe-size) var(--stripe-size)`, + '--stripe-size': '1rem', + '--stripe-color': { + _light: 'rgba(255, 255, 255, 0.3)', + _dark: 'rgba(0, 0, 0, 0.3)', + }, + }, + }, + }, + + animated: { + true: { + range: { + '--animate-from': 'var(--stripe-size)', + animation: 'bg-position 1s linear infinite', + }, + }, + }, + + size: { + xs: { track: { h: '1.5' } }, + sm: { track: { h: '2' } }, + md: { track: { h: '2.5' } }, + lg: { track: { h: '3' } }, + xl: { track: { h: '3.5' } }, + }, + }, + + defaultVariants: { + variant: 'solid', + size: 'md', + shape: 'rounded', + }, +}) diff --git a/src/theme/recipes/radio-card-group.ts b/src/theme/recipes/radio-card-group.ts new file mode 100644 index 0000000..7b5f57d --- /dev/null +++ b/src/theme/recipes/radio-card-group.ts @@ -0,0 +1,148 @@ +import { radioGroupAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const radioCardGroup = defineSlotRecipe({ + className: 'radio-card-group', + slots: radioGroupAnatomy.keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '1.5', + width: 'full', + }, + item: { + alignItems: 'center', + borderRadius: 'l2', + cursor: 'pointer', + display: 'flex', + justifyContent: 'space-between', + userSelect: 'none', + width: 'full', + }, + label: { + textStyle: 'label', + }, + itemControl: { + alignItems: 'center', + borderRadius: 'full', + display: 'inline-flex', + flexShrink: '0', + justifyContent: 'center', + verticalAlign: 'top', + _after: { + content: '""', + display: 'block', + borderRadius: 'full', + }, + _focusVisible: { + focusVisibleRing: 'outside', + }, + }, + itemText: { + textStyle: 'label', + }, + }, + defaultVariants: { + variant: 'outline', + size: 'md', + }, + variants: { + variant: { + subtle: { + item: { + background: 'gray.subtle.bg', + color: 'gray.subtle.fg', + _checked: { + background: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + }, + }, + itemControl: { + borderWidth: '1px', + borderColor: 'gray.subtle.border', + _checked: { + borderColor: 'colorPalette.solid.bg', + _after: { + bg: 'colorPalette.solid.bg', + }, + }, + }, + }, + outline: { + item: { + borderWidth: '1px', + borderColor: 'gray.outline.border', + _checked: { + boxShadow: '0 0 0 1px var(--shadow-color)', + boxShadowColor: 'colorPalette.solid.bg', + borderColor: 'colorPalette.solid.bg', + }, + }, + itemControl: { + borderWidth: '1px', + borderColor: 'gray.outline.border', + _checked: { + bg: 'colorPalette.solid.bg', + borderColor: 'colorPalette.solid.bg', + _after: { + background: 'colorPalette.solid.fg', + }, + }, + }, + }, + surface: { + item: { + borderWidth: '1px', + background: 'gray.surface.bg', + borderColor: 'gray.surface.border', + color: 'gray.surface.fg', + _checked: { + boxShadow: '0 0 0 1px var(--shadow-color)', + boxShadowColor: 'colorPalette.solid.bg', + borderColor: 'colorPalette.solid.bg', + }, + }, + itemControl: { + borderWidth: '1px', + borderColor: 'gray.outline.border', + _checked: { + background: 'colorPalette.solid.bg', + borderColor: 'colorPalette.solid.bg', + _after: { + background: 'colorPalette.solid.fg', + }, + }, + }, + }, + solid: { + item: { + borderWidth: '1px', + _checked: { + bg: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + borderColor: 'colorPalette.solid.bg', + }, + }, + itemControl: { + borderWidth: '1px', + borderColor: 'gray.outline.border', + _checked: { + background: 'colorPalette.solid.fg', + borderColor: 'colorPalette.solid.fg', + _after: { + bg: 'colorPalette.solid.bg', + }, + }, + }, + }, + }, + size: { + md: { + item: { gap: '2', p: '4' }, + itemControl: { boxSize: '5', _after: { boxSize: '2' } }, + itemText: { textStyle: 'sm' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/radio-group.ts b/src/theme/recipes/radio-group.ts new file mode 100644 index 0000000..d24a4e2 --- /dev/null +++ b/src/theme/recipes/radio-group.ts @@ -0,0 +1,82 @@ +import { radioGroupAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const radioGroup = defineSlotRecipe({ + className: 'radio-group', + slots: radioGroupAnatomy.keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '3', + }, + itemControl: { + alignItems: 'center', + borderRadius: 'full', + display: 'inline-flex', + flexShrink: 0, + justifyContent: 'center', + verticalAlign: 'top', + _after: { + content: '""', + display: 'block', + borderRadius: 'full', + boxSize: '40%', + }, + _focusVisible: { + focusVisibleRing: 'outside', + }, + }, + item: { + alignItems: 'center', + cursor: 'pointer', + display: 'flex', + _disabled: { + layerStyle: 'disabled', + }, + }, + itemText: { + fontWeight: 'medium', + userSelect: 'none', + }, + }, + defaultVariants: { + variant: 'solid', + size: 'md', + }, + variants: { + variant: { + solid: { + itemControl: { + boxShadow: 'inset 0 0 0 1px var(--shadow-color)', + boxShadowColor: 'gray.surface.border', + _checked: { + bg: 'colorPalette.solid.bg', + color: 'colorPalette.solid.fg', + boxShadowColor: 'colorPalette.solid.bg', + _after: { + background: 'colorPalette.solid.fg', + }, + }, + }, + }, + }, + size: { + sm: { + item: { gap: '2' }, + itemControl: { boxSize: '4.5' }, + itemText: { textStyle: 'sm' }, + }, + md: { + item: { gap: '3' }, + itemControl: { boxSize: '5' }, + itemText: { textStyle: 'md' }, + }, + lg: { + item: { gap: '3' }, + itemControl: { boxSize: '5.5' }, + itemText: { textStyle: 'lg' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/rating-group.ts b/src/theme/recipes/rating-group.ts new file mode 100644 index 0000000..2b27de4 --- /dev/null +++ b/src/theme/recipes/rating-group.ts @@ -0,0 +1,77 @@ +import { ratingGroupAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const ratingGroup = defineSlotRecipe({ + className: 'rating-group', + slots: ratingGroupAnatomy.extendWith('itemIndicator').keys(), + base: { + root: { + alignItems: 'center', + display: 'inline-flex', + verticalAlign: 'top', + }, + control: { + alignItems: 'center', + display: 'inline-flex', + gap: '0.5', + }, + item: { + alignItems: 'center', + display: 'inline-flex', + justifyContent: 'center', + userSelect: 'none', + }, + label: { + fontWeight: 'medium', + userSelect: 'none', + }, + itemIndicator: { + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + position: 'relative', + '--clip-path': { base: 'inset(0 50% 0 0)', _rtl: 'inset(0 0 0 50%)' }, + _icon: { + stroke: 'currentColor', + display: 'inline-block', + flexShrink: 0, + position: 'absolute', + width: 'inherit', + height: 'inherit', + left: 0, + top: 0, + }, + '& [data-bg]': { + color: 'gray.subtle.bg', + }, + '& [data-fg]': { + color: 'transparent', + }, + '&[data-highlighted]:not([data-half])': { + '& [data-fg]': { + color: 'colorPalette.solid.bg', + }, + }, + '&[data-half]': { + '& [data-fg]': { + color: 'colorPalette.solid.bg', + clipPath: 'var(--clip-path)', + }, + }, + }, + }, + + variants: { + size: { + xs: { root: { gap: '2' }, itemIndicator: { width: '4', height: '4' } }, + sm: { root: { gap: '2' }, itemIndicator: { width: '4.5', height: '4.5' } }, + md: { root: { gap: '3' }, itemIndicator: { width: '5', height: '5' } }, + lg: { root: { gap: '3' }, itemIndicator: { width: '5.5', height: '5.5' } }, + xl: { root: { gap: '3' }, itemIndicator: { width: '6', height: '6' } }, + }, + }, + + defaultVariants: { + size: 'md', + }, +}) diff --git a/src/theme/recipes/scroll-area.ts b/src/theme/recipes/scroll-area.ts new file mode 100644 index 0000000..965a5b1 --- /dev/null +++ b/src/theme/recipes/scroll-area.ts @@ -0,0 +1,118 @@ +import { defineSlotRecipe } from '@pandacss/dev' + +export const scrollArea = defineSlotRecipe({ + className: 'scroll-area', + slots: ['root', 'viewport', 'content', 'scrollbar', 'thumb', 'corner'], + base: { + root: { + display: 'flex', + flexDirection: 'column', + width: '100%', + height: '100%', + position: 'relative', + overflow: 'hidden', + '--scrollbar-margin': '0px', + '--scrollbar-size': 'calc(var(--thumb-size) + calc(var(--scrollbar-margin) * 2))', + }, + viewport: { + display: 'flex', + flexDirection: 'column', + height: '100%', + width: '100%', + WebkitOverflowScrolling: 'touch', + scrollbarWidth: 'none', + '&::-webkit-scrollbar': { + display: 'none', + }, + '&[data-overflow-x] [data-pinned]': { + _after: { + content: '""', + position: 'absolute', + pointerEvents: 'none', + top: '0', + bottom: '-1px', + width: '32px', + }, + }, + '&[data-overflow-x]:not([data-at-left]) [data-pinned="left"]': { + _after: { + insetInlineEnd: '0', + translate: '100% 0', + boxShadow: 'inset', + }, + }, + }, + scrollbar: { + alignItems: 'center', + display: 'flex', + position: 'relative', + touchAction: 'none', + userSelect: 'none', + zIndex: 'overlay', + _vertical: { + flexDirection: 'column', + width: 'var(--scrollbar-size)', + py: 'var(--scrollbar-margin)', + '&:not([data-overflow-y])': { + display: 'none', + }, + }, + _horizontal: { + flexDirection: 'row', + height: 'var(--scrollbar-size)', + px: 'var(--scrollbar-margin)', + '&:not([data-overflow-x])': { + display: 'none', + }, + }, + }, + thumb: { + borderRadius: 'full', + bg: 'var(--thumb-bg)', + transitionDuration: 'normal', + transitionProperty: 'background, color, box-shadow', + transitionTimingFunction: 'default', + _vertical: { width: 'var(--thumb-size)' }, + _horizontal: { height: 'var(--thumb-size)' }, + }, + corner: {}, + }, + defaultVariants: { + size: 'md', + scrollbar: 'auto', + }, + variants: { + scrollbar: { + auto: { + scrollbar: { + '&[data-scrolling], &[data-hover]': { + '--thumb-bg': '{colors.gray.subtle.bg.active}', + }, + }, + }, + visible: { + content: { + '&[data-overflow-y]': { + pe: 'var(--scrollbar-size)', + }, + '&[data-overflow-x]': { + pb: 'var(--scrollbar-size)', + }, + }, + scrollbar: { + bg: 'gray.subtle.bg', + borderRadius: 'full', + }, + thumb: { + '--thumb-bg': '{colors.gray.subtle.bg.active}', + }, + }, + }, + size: { + xs: { root: { '--thumb-size': 'sizes.1' } }, + sm: { root: { '--thumb-size': 'sizes.1.5' } }, + md: { root: { '--thumb-size': 'sizes.2' } }, + lg: { root: { '--thumb-size': 'sizes.2.5' } }, + }, + }, +}) diff --git a/src/theme/recipes/segment-group.ts b/src/theme/recipes/segment-group.ts new file mode 100644 index 0000000..f787d50 --- /dev/null +++ b/src/theme/recipes/segment-group.ts @@ -0,0 +1,111 @@ +import { segmentGroupAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const segmentGroup = defineSlotRecipe({ + className: 'segment-group', + slots: segmentGroupAnatomy.keys(), + base: { + root: { + bg: { + _light: 'gray.2', + _dark: 'gray.1', + }, + borderRadius: 'l3', + boxShadow: 'inset 0 0 0px 1px var(--shadow-color)', + boxShadowColor: 'border', + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + isolation: 'isolate', + pos: 'relative', + _vertical: { + flexDirection: 'column', + alignItems: 'stretch', + }, + }, + item: { + alignItems: 'center', + borderRadius: 'l3', + display: 'inline-flex', + flexShrink: '0', + fontWeight: 'medium', + gap: '2', + justifyContent: 'center', + position: 'relative', + userSelect: 'none', + _disabled: { + opacity: '0.5', + }, + '&:has(input:focus-visible)': { + focusVisibleRing: 'outside', + }, + + _before: { + content: '""', + position: 'absolute', + bg: 'gray.surface.border', + transition: 'opacity 0.2s', + }, + + _horizontal: { + _before: { + insetInlineStart: '0', + insetBlock: '1.5', + width: '1px', + }, + }, + + _vertical: { + _before: { + insetBlockStart: '0', + insetInline: '1.5', + height: '1px', + }, + }, + + '& + &[data-state=checked], &[data-state=checked] + &, &:first-of-type': { + _before: { + opacity: '0', + }, + }, + }, + + indicator: { + bg: { + _light: 'white', + _dark: 'gray.2', + }, + borderWidth: '1px', + borderColor: 'gray.surface.border', + borderRadius: 'l3', + height: 'var(--height)', + pos: 'absolute', + width: 'var(--width)', + zIndex: -1, + }, + }, + + variants: { + size: { + xs: { item: { h: '8', minW: '8', textStyle: 'sm', px: '2.5', _icon: { boxSize: '4' } } }, + sm: { item: { h: '9', minW: '9', textStyle: 'sm', px: '3', _icon: { boxSize: '4' } } }, + md: { item: { h: '10', minW: '10', textStyle: 'sm', px: '3.5', _icon: { boxSize: '5' } } }, + lg: { item: { h: '11', minW: '11', textStyle: 'md', px: '4', _icon: { boxSize: '5' } } }, + xl: { item: { h: '12', minW: '12', textStyle: 'md', px: '4.5', _icon: { boxSize: '5.5' } } }, + }, + fitted: { + true: { + root: { + display: 'flex', + }, + item: { + flex: '1', + }, + }, + }, + }, + + defaultVariants: { + size: 'md', + }, +}) diff --git a/src/theme/recipes/select.ts b/src/theme/recipes/select.ts new file mode 100644 index 0000000..9a63186 --- /dev/null +++ b/src/theme/recipes/select.ts @@ -0,0 +1,174 @@ +import { selectAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const select = defineSlotRecipe({ + className: 'select', + slots: selectAnatomy.extendWith('indicatorGroup').keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '1.5', + width: 'full', + }, + content: { + background: 'gray.surface.bg', + borderRadius: 'l2', + boxShadow: 'md', + display: 'flex', + flexDirection: 'column', + maxH: 'min(var(--available-height), {sizes.96})', + minWidth: 'max(var(--reference-width), {sizes.40})', + outline: 0, + overflowY: 'auto', + zIndex: 'dropdown', + _open: { + animationStyle: 'slide-fade-in', + animationDuration: 'slow', + }, + _closed: { + animationStyle: 'slide-fade-out', + animationDuration: 'fastest', + }, + }, + item: { + alignItems: 'center', + borderRadius: 'l1', + cursor: 'pointer', + display: 'flex', + justifyContent: 'space-between', + userSelect: 'none', + _hover: { + background: 'gray.surface.bg.hover', + }, + _highlighted: { + background: 'gray.surface.bg.hover', + }, + _selected: {}, + _disabled: { + layerStyle: 'disabled', + }, + }, + indicatorGroup: { + display: 'flex', + alignItems: 'center', + gap: '1', + pointerEvents: 'none', + }, + indicator: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + color: { base: 'fg.subtle' }, + }, + itemGroupLabel: { + alignItems: 'flex-start', + color: 'fg.subtle', + display: 'flex', + flexDirection: 'column', + fontWeight: 'medium', + gap: '1px', + justifyContent: 'center', + _after: { + content: '""', + width: '100%', + height: '1px', + bg: 'gray.4', + }, + }, + itemIndicator: { + color: 'colorPalette.plain.fg', + }, + label: { + fontWeight: 'medium', + userSelect: 'none', + textStyle: 'sm', + }, + trigger: { + alignItems: 'center', + borderRadius: 'l2', + cursor: 'pointer', + display: 'flex', + justifyContent: 'space-between', + minWidth: '0', + outline: '0', + textAlign: 'start', + transition: 'common', + userSelect: 'none', + width: 'full', + _placeholderShown: { + color: 'fg.subtle', + }, + _disabled: { + layerStyle: 'disabled', + }, + }, + valueText: { + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + }, + defaultVariants: { + size: 'md', + variant: 'outline', + }, + variants: { + variant: { + outline: { + trigger: { + borderWidth: '1px', + borderColor: 'gray.outline.border', + + focusVisibleRing: 'inside', + }, + }, + surface: { + trigger: { + bg: 'gray.surface.bg', + borderWidth: '1px', + borderColor: 'gray.surface.border', + + focusVisibleRing: 'inside', + }, + }, + }, + size: { + xs: { + content: { p: '1', gap: '0.5', textStyle: 'sm' }, + item: { px: '1', minH: '8', gap: '2', _icon: { boxSize: '3.5' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '1', height: '8' }, + trigger: { px: '2', h: '8', textStyle: 'sm', gap: '2', _icon: { boxSize: '3.5' } }, + }, + sm: { + content: { p: '1', gap: '0.5', textStyle: 'sm' }, + item: { px: '1.5', minH: '9', gap: '2', _icon: { boxSize: '4' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '1.5', height: '9' }, + trigger: { px: '2.5', h: '9', textStyle: 'sm', gap: '2', _icon: { boxSize: '4' } }, + }, + md: { + content: { p: '1', gap: '0.5', textStyle: 'md' }, + item: { px: '2', minH: '10', gap: '2', _icon: { boxSize: '4' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '2', height: '10' }, + trigger: { px: '3', h: '10', textStyle: 'md', gap: '2', _icon: { boxSize: '4' } }, + }, + lg: { + content: { p: '1', gap: '0.5', textStyle: 'md' }, + item: { px: '2.5', minH: '11', gap: '2', _icon: { boxSize: '4.5' } }, + itemGroup: { gap: '0.5' }, + itemGroupLabel: { px: '2.5', height: '11' }, + trigger: { px: '3.5', h: '11', textStyle: 'md', gap: '2', _icon: { boxSize: '4.5' } }, + }, + xl: { + content: { p: '1', gap: '1', textStyle: 'lg' }, + item: { px: '3', minH: '12', gap: '3', _icon: { boxSize: '5' } }, + itemGroup: { gap: '1' }, + itemGroupLabel: { px: '3', height: '12' }, + trigger: { px: '4', h: '12', textStyle: 'lg', gap: '3', _icon: { boxSize: '5' } }, + }, + }, + }, +}) diff --git a/src/theme/recipes/skeleton.ts b/src/theme/recipes/skeleton.ts new file mode 100644 index 0000000..ba8c264 --- /dev/null +++ b/src/theme/recipes/skeleton.ts @@ -0,0 +1,64 @@ +import { defineRecipe } from '@pandacss/dev' + +export const skeleton = defineRecipe({ + className: 'skeleton', + jsx: ['Skeleton', 'SkeletonCircle', 'SkeletonText'], + base: {}, + variants: { + loading: { + true: { + borderRadius: 'l2', + boxShadow: 'none', + backgroundClip: 'padding-box', + cursor: 'default', + color: 'transparent', + pointerEvents: 'none', + userSelect: 'none', + flexShrink: '0', + '&::before, &::after, *': { + visibility: 'hidden', + }, + }, + false: { + background: 'unset', + animation: 'fade-in var(--fade-duration, 0.1s) ease-out !important', + }, + }, + + circle: { + true: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flex: '0 0 auto', + borderRadius: '9999px', + }, + }, + + variant: { + pulse: { + background: 'gray.subtle.bg.active', + animation: 'pulse', + animationDuration: 'var(--duration, 1.2s)', + }, + shine: { + '--animate-from': '200%', + '--animate-to': '-200%', + '--start-color': 'colors.gray.subtle.bg', + '--end-color': 'colors.gray.subtle.bg.active', + backgroundImage: + 'linear-gradient(270deg,var(--start-color),var(--end-color),var(--end-color),var(--start-color))', + backgroundSize: '400% 100%', + animation: 'bg-position var(--duration, 5s) ease-in-out infinite', + }, + none: { + animation: 'none', + }, + }, + }, + + defaultVariants: { + variant: 'pulse', + loading: true, + }, +}) diff --git a/src/theme/recipes/slider.ts b/src/theme/recipes/slider.ts new file mode 100644 index 0000000..423406d --- /dev/null +++ b/src/theme/recipes/slider.ts @@ -0,0 +1,174 @@ +import { sliderAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const slider = defineSlotRecipe({ + className: 'slider', + slots: sliderAnatomy.extendWith('markerIndicator').keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '1', + textStyle: 'sm', + position: 'relative', + isolation: 'isolate', + touchAction: 'none', + width: 'full', + }, + label: { + fontWeight: 'medium', + textStyle: 'sm', + }, + control: { + display: 'inline-flex', + alignItems: 'center', + }, + track: { + overflow: 'hidden', + borderRadius: 'full', + flex: '1', + }, + range: { + width: 'inherit', + height: 'inherit', + }, + markerGroup: { + position: 'absolute!', + zIndex: '1', + }, + marker: { + display: 'flex', + alignItems: 'center', + gap: 'calc(var(--slider-thumb-size) / 2)', + color: 'fg.muted', + textStyle: 'xs', + }, + markerIndicator: { + width: 'var(--slider-marker-size)', + height: 'var(--slider-marker-size)', + borderRadius: 'full', + bg: 'colorPalette.solid.fg', + }, + thumb: { + width: 'var(--slider-thumb-size)', + height: 'var(--slider-thumb-size)', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + outline: 0, + zIndex: '2', + borderRadius: 'full', + _focusVisible: { + ring: '2px', + ringColor: 'colorPalette.solid', + ringOffset: '2px', + ringOffsetColor: 'bg', + }, + }, + }, + defaultVariants: { + size: 'md', + variant: 'outline', + orientation: 'horizontal', + }, + variants: { + size: { + sm: { + root: { + '--slider-thumb-size': 'sizes.5', + '--slider-track-size': 'sizes.2', + '--slider-marker-center': '8px', + '--slider-marker-size': 'sizes.1', + '--slider-marker-inset': '4px', + }, + }, + md: { + root: { + '--slider-thumb-size': 'sizes.5', + '--slider-track-size': 'sizes.2', + '--slider-marker-center': '8px', + '--slider-marker-size': 'sizes.1', + '--slider-marker-inset': '4px', + }, + }, + lg: { + root: { + '--slider-thumb-size': 'sizes.5', + '--slider-track-size': 'sizes.2', + '--slider-marker-center': '8px', + '--slider-marker-size': 'sizes.1', + '--slider-marker-inset': '4px', + }, + }, + }, + variant: { + outline: { + thumb: { + bg: 'gray.surface.bg', + borderWidth: '2px', + borderColor: 'colorPalette.solid.bg', + boxShadow: 'xs', + }, + range: { + bg: 'colorPalette.solid.bg', + }, + track: { + bg: 'border', + }, + }, + }, + orientation: { + vertical: { + root: { + display: 'inline-flex', + }, + control: { + flexDirection: 'column', + height: '100%', + minWidth: 'var(--slider-thumb-size)', + '&[data-has-mark-label]': { + marginEnd: '4', + }, + }, + track: { + width: 'var(--slider-track-size)', + }, + thumb: { + left: '50%', + translate: '-50% 0', + }, + markerGroup: { + insetStart: 'var(--slider-marker-center)', + insetBlock: 'var(--slider-marker-inset)', + }, + marker: { + flexDirection: 'row', + }, + }, + horizontal: { + control: { + flexDirection: 'row', + width: '100%', + minHeight: 'var(--slider-thumb-size)', + '&[data-has-mark-label]': { + marginBottom: '4', + }, + }, + track: { + height: 'var(--slider-track-size)', + }, + thumb: { + top: '50%', + translate: '0 -50%', + }, + markerGroup: { + top: 'var(--slider-marker-center)', + insetInline: 'var(--slider-marker-inset)', + }, + marker: { + flexDirection: 'column', + }, + }, + }, + }, +}) diff --git a/src/theme/recipes/splitter.ts b/src/theme/recipes/splitter.ts new file mode 100644 index 0000000..a6c8fe0 --- /dev/null +++ b/src/theme/recipes/splitter.ts @@ -0,0 +1,32 @@ +import { splitterAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const splitter = defineSlotRecipe({ + className: 'splitter', + slots: splitterAnatomy.keys(), + base: { + root: { + display: 'flex', + gap: '2', + }, + panel: { + borderRadius: 'l3', + display: 'flex', + background: 'gray.surface.bg', + borderWidth: '1px', + p: '4', + }, + resizeTrigger: { + borderRadius: 'l3', + transition: 'common', + outline: '0', + background: 'gray.subtle.bg', + _horizontal: { + minWidth: '1.5', + }, + _vertical: { + minHeight: '1.5', + }, + }, + }, +}) diff --git a/src/theme/recipes/switch.ts b/src/theme/recipes/switch.ts new file mode 100644 index 0000000..a53aaf7 --- /dev/null +++ b/src/theme/recipes/switch.ts @@ -0,0 +1,141 @@ +import { switchAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const switchRecipe = defineSlotRecipe({ + className: 'switch', + jsx: ['Switch', /Switch\.+/], + slots: switchAnatomy.extendWith('indicator').keys(), + base: { + root: { + display: 'inline-flex', + alignItems: 'center', + position: 'relative', + verticalAlign: 'middle', + '--switch-diff': 'calc(var(--switch-width) - var(--switch-height))', + '--switch-x': { + base: 'var(--switch-diff)', + _rtl: 'calc(var(--switch-diff) * -1)', + }, + }, + label: { + fontWeight: 'medium', + userSelect: 'none', + lineHeight: '1', + }, + indicator: { + position: 'absolute', + height: 'var(--switch-height)', + width: 'var(--switch-height)', + fontSize: 'var(--switch-indicator-font-size)', + fontWeight: 'medium', + flexShrink: 0, + userSelect: 'none', + display: 'grid', + placeContent: 'center', + transition: 'inset-inline-start 0.12s ease', + insetInlineStart: 'calc(var(--switch-x) - 2px)', + _checked: { + insetInlineStart: '2px', + }, + }, + control: { + display: 'inline-flex', + gap: '0.5rem', + flexShrink: 0, + justifyContent: 'flex-start', + cursor: 'pointer', + borderRadius: 'full', + position: 'relative', + width: 'var(--switch-width)', + height: 'var(--switch-height)', + transition: 'backgrounds', + focusVisibleRing: 'outside', + _disabled: { + layerStyle: 'disabled', + }, + _invalid: { + outline: '2px solid', + outlineColor: 'error', + outlineOffset: '2px', + }, + }, + thumb: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexShrink: 0, + transitionProperty: 'translate', + transitionDuration: 'fast', + borderRadius: 'inherit', + _checked: { + translate: 'var(--switch-x) 0', + }, + }, + }, + defaultVariants: { + variant: 'solid', + size: 'md', + }, + variants: { + variant: { + solid: { + control: { + borderRadius: 'full', + bg: 'gray.subtle.bg', + focusVisibleRing: 'outside', + _checked: { + bg: 'colorPalette.solid.bg', + }, + }, + thumb: { + bg: 'white', + _checked: { + bg: 'colorPalette.solid.fg', + }, + width: 'var(--switch-height)', + height: 'var(--switch-height)', + scale: '0.8', + boxShadow: 'xs', + }, + }, + }, + size: { + xs: { + root: { + gap: '2', + '--switch-width': 'sizes.8', + '--switch-height': 'sizes.4', + '--switch-indicator-font-size': 'fontSizes.xs', + }, + label: { fontSize: 'sm' }, + }, + sm: { + root: { + gap: '2', + '--switch-width': 'sizes.9', + '--switch-height': 'sizes.4.5', + '--switch-indicator-font-size': 'fontSizes.xs', + }, + label: { fontSize: 'sm' }, + }, + md: { + root: { + gap: '3', + '--switch-width': 'sizes.10', + '--switch-height': 'sizes.5', + '--switch-indicator-font-size': 'fontSizes.sm', + }, + label: { fontSize: 'md' }, + }, + lg: { + root: { + gap: '3', + '--switch-width': 'sizes.11', + '--switch-height': 'sizes.5.5', + '--switch-indicator-font-size': 'fontSizes.md', + }, + label: { fontSize: 'lg' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/table.ts b/src/theme/recipes/table.ts new file mode 100644 index 0000000..c92f812 --- /dev/null +++ b/src/theme/recipes/table.ts @@ -0,0 +1,110 @@ +import { defineSlotRecipe } from '@pandacss/dev' + +export const table = defineSlotRecipe({ + className: 'table', + slots: ['root', 'body', 'cell', 'foot', 'head', 'header', 'row', 'caption'], + base: { + root: { + borderCollapse: 'collapse', + fontVariantNumeric: 'lining-nums tabular-nums', + textAlign: 'start', + verticalAlign: 'top', + width: 'full', + }, + cell: { + alignItems: 'center', + color: 'fg.muted', + textAlign: 'start', + textOverflow: 'ellipsis', + textStyle: 'sm', + whiteSpace: 'nowrap', + overflow: 'hidden', + boxShadow: 'inset 0 -1px 0 0 var(--shadow-color)', + shadowColor: 'border', + _pinned: { + bg: 'inherit', + boxShadow: 'inset 0 -1px 0 0 var(--shadow-color)', + overflow: 'unset', + position: 'sticky', + shadowColor: 'border', + zIndex: 1, + }, + }, + row: { + _last: { '& td': { boxShadow: 'none' } }, + }, + header: { + textAlign: 'left', + verticalAlign: 'middle', + boxShadow: 'inset 0 -1px 0 0 var(--shadow-color)', + shadowColor: 'border', + _pinned: { + position: 'sticky', + bg: 'inherit', + zIndex: 2, + }, + }, + head: { + color: 'fg.muted', + fontWeight: 'semibold', + textAlign: 'start', + whiteSpace: 'nowrap', + textStyle: 'xs', + }, + caption: { + color: 'fg.subtle', + fontWeight: 'medium', + }, + foot: { + fontWeight: 'medium', + '& td': { boxShadow: 'inset 0 1px 0 0 var(--shadow-color)!', shadowColor: 'border' }, + }, + }, + defaultVariants: { + size: 'md', + variant: 'plain', + }, + variants: { + variant: { + surface: { + header: { bg: 'gray.surface.bg.hover' }, + row: { bg: 'gray.surface.bg' }, + }, + plain: {}, + }, + striped: { + true: { + row: { '&:nth-of-type(odd) td': { bg: 'gray.surface.bg.hover' } }, + }, + }, + interactive: { + true: { + body: { '& tr': { _hover: { bg: 'gray.surface.bg.hover' } } }, + }, + }, + columnBorder: { + true: { + header: { '&:not(:last-of-type)': { borderInlineEndWidth: '1px' } }, + cell: { '&:not(:last-of-type)': { borderInlineEndWidth: '1px' } }, + }, + }, + stickyHeader: { + true: { + head: { + '& :where(tr)': { + top: 'var(--table-sticky-offset, 0)', + position: 'sticky', + zIndex: 2, + }, + }, + }, + }, + size: { + md: { + root: { textStyle: 'sm' }, + header: { px: '3', py: '3' }, + cell: { px: '3', py: '3' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/tabs.ts b/src/theme/recipes/tabs.ts new file mode 100644 index 0000000..bd8bb54 --- /dev/null +++ b/src/theme/recipes/tabs.ts @@ -0,0 +1,177 @@ +import { tabsAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const tabs = defineSlotRecipe({ + slots: tabsAnatomy.keys(), + className: 'tabs', + base: { + root: { + position: 'relative', + display: 'flex', + alignItems: 'start', + _horizontal: { + flexDirection: 'column', + gap: '2', + }, + _vertical: { + flexDirection: 'row', + gap: '4', + }, + }, + list: { + display: 'flex', + position: 'relative', + isolation: 'isolate', + _horizontal: { + flexDirection: 'row', + }, + _vertical: { + flexDirection: 'column', + }, + }, + trigger: { + alignItems: 'center', + cursor: 'pointer', + display: 'flex', + fontWeight: 'semibold', + outline: '0', + position: 'relative', + _focusVisible: { + zIndex: 1, + focusVisibleRing: 'outside', + }, + _disabled: { + layerStyle: 'disabled', + }, + }, + content: { + focusVisibleRing: 'inside', + + _horizontal: { + width: '100%', + }, + _vertical: { + height: '100%', + }, + }, + indicator: { + width: 'var(--width)', + height: 'var(--height)', + zIndex: -1, + }, + }, + + variants: { + size: { + xs: { + list: { gap: '1' }, + trigger: { h: '8', minW: '8', textStyle: 'xs', px: '3', gap: '2' }, + }, + sm: { + list: { gap: '1' }, + trigger: { h: '9', minW: '9', textStyle: 'sm', px: '3.5', gap: '2' }, + }, + md: { + list: { gap: '1' }, + trigger: { h: '10', minW: '10', textStyle: 'sm', px: '4', gap: '2' }, + }, + lg: { + list: { gap: '1' }, + trigger: { h: '11', minW: '11', textStyle: 'md', px: '4.5', gap: '2' }, + }, + }, + variant: { + line: { + root: { + alignItems: 'stretch', + }, + list: { + _horizontal: { + borderBottomWidth: '1px', + }, + _vertical: { + borderStartWidth: '1px', + }, + }, + indicator: { + background: 'colorPalette.solid.bg', + _horizontal: { + bottom: '0', + height: '0.5', + transform: 'translateY(1px)', + }, + _vertical: { + left: '0', + width: '0.5', + transform: 'translateX(-1px)', + }, + }, + trigger: { + color: 'fg.muted', + _selected: { + color: 'colorPalette.plain.fg', + }, + }, + }, + subtle: { + trigger: { + color: 'fg.muted', + _selected: { + color: 'colorPalette.subtle.fg', + }, + }, + indicator: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + borderRadius: 'l2', + }, + }, + enclosed: { + list: { + bg: { + _light: 'gray.2', + _dark: 'gray.1', + }, + boxShadow: 'inset 0 0 0px 1px var(--shadow-color)', + boxShadowColor: 'border', + borderRadius: 'l3', + p: '1', + }, + trigger: { + color: 'fg.muted', + _selected: { + color: 'colorPalette.surface.fg', + }, + }, + indicator: { + borderRadius: 'l2', + boxShadow: { + _light: 'xs', + _dark: 'none', + }, + bg: { + _light: 'white', + _dark: 'gray.2', + }, + }, + }, + }, + fitted: { + true: { + root: { + alignItems: 'stretch', + }, + trigger: { + flex: 1, + textAlign: 'center', + justifyContent: 'center', + }, + }, + }, + }, + + defaultVariants: { + size: 'md', + variant: 'line', + }, +}) diff --git a/src/theme/recipes/tags-input.ts b/src/theme/recipes/tags-input.ts new file mode 100644 index 0000000..23f8309 --- /dev/null +++ b/src/theme/recipes/tags-input.ts @@ -0,0 +1,231 @@ +import { tagsInputAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const tagsInput = defineSlotRecipe({ + className: 'tags-input', + slots: tagsInputAnatomy.keys(), + base: { + root: { + display: 'flex', + flexDirection: 'column', + gap: '1.5', + width: 'full', + }, + label: { + textStyle: 'label', + }, + control: { + '--focus-color': 'colors.colorPalette.solid.bg', + '--error-color': 'colors.error', + '--input-height': 'var(--tags-input-height)', + + minH: 'var(--tags-input-height)', + px: 'var(--tags-input-px)', + + alignItems: 'center', + borderRadius: 'l2', + display: 'flex', + flexWrap: 'wrap', + pos: 'relative', + transitionDuration: 'normal', + transitionProperty: 'border-color, box-shadow', + + _disabled: { + opacity: '0.5', + }, + _invalid: { + borderColor: 'var(--error-color)', + }, + }, + clearTrigger: { + boxSize: 'calc(var(--tags-input-item-height) / 1.5)', + + alignItems: 'center', + borderRadius: 'l1', + color: 'fg.muted', + display: 'flex', + focusRingWidth: '2px', + focusVisibleRing: 'inside', + justifyContent: 'center', + cursor: { base: 'button', _disabled: 'initial' }, + _icon: { + boxSize: '5', + }, + }, + input: { + px: 'calc(var(--tags-input-item-px) / 1.25)', + height: 'var(--tags-input-item-height)', + + flex: '1', + minWidth: '20', + outline: 'none', + _readOnly: { + display: 'none', + }, + }, + itemInput: { + px: 'var(--tags-input-item-px)', + height: 'var(--tags-input-item-height)', + lineHeight: '1', + minWidth: '2ch', + outline: 'none', + verticalAlign: 'middle', + }, + itemDeleteTrigger: { + display: 'flex', + borderRadius: 'l1', + alignItems: 'center', + justifyContent: 'center', + cursor: 'pointer', + _hover: { + bg: 'colorPalette.plain.bg.hover', + }, + }, + itemPreview: { + height: 'var(--tags-input-item-height)', + px: 'var(--tags-input-item-px)', + + alignItems: 'center', + borderRadius: 'l1', + display: 'inline-flex', + userSelect: 'none', + }, + itemText: { + lineClamp: '1', + }, + }, + defaultVariants: { + size: 'md', + variant: 'outline', + }, + variants: { + variant: { + outline: { + control: { + borderWidth: '1px', + _focus: { + outlineWidth: '1px', + outlineStyle: 'solid', + outlineColor: 'var(--focus-color)', + borderColor: 'var(--focus-color)', + _invalid: { + outlineColor: 'var(--error-color)', + borderColor: 'var(--error-color)', + }, + }, + }, + itemPreview: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + _highlighted: { + bg: 'colorPalette.subtle.bg.hover', + }, + }, + }, + subtle: { + control: { + bg: 'gray.subtle.bg', + color: 'gray.subtle.fg', + borderWidth: '1px', + borderColor: 'transparent', + _focus: { + outlineWidth: '1px', + outlineStyle: 'solid', + outlineColor: 'var(--focus-color)', + borderColor: 'var(--focus-color)', + _invalid: { + outlineColor: 'var(--error-color)', + borderColor: 'var(--error-color)', + }, + }, + }, + itemPreview: { + bg: 'gray.surface.bg', + borderWidth: '1px', + _highlighted: { + bg: 'gray.surface.bg.hover', + borderColor: 'gray.surface.border.hover', + }, + }, + }, + surface: { + control: { + bg: 'gray.surface.bg', + borderWidth: '1px', + borderColor: 'gray.surface.border', + _focus: { + outlineWidth: '1px', + outlineStyle: 'solid', + outlineColor: 'var(--focus-color)', + borderColor: 'var(--focus-color)', + _invalid: { + outlineColor: 'var(--error-color)', + borderColor: 'var(--error-color)', + }, + }, + }, + itemPreview: { + bg: 'colorPalette.subtle.bg', + color: 'colorPalette.subtle.fg', + _highlighted: { + bg: 'colorPalette.subtle.bg.hover', + }, + }, + }, + }, + size: { + xs: { + root: { + '--tags-input-height': 'sizes.8', + '--tags-input-px': 'spacing.1.5', + '--tags-input-item-height': 'sizes.5', + '--tags-input-item-px': 'spacing.1', + _icon: { boxSize: '3' }, + textStyle: 'xs', + }, + control: { gap: '1' }, + itemPreview: { gap: '1' }, + itemDeleteTrigger: { boxSize: '3.5', me: '-1px' }, + }, + sm: { + root: { + '--tags-input-height': 'sizes.9', + '--tags-input-px': 'spacing.1.5', + '--tags-input-item-height': 'sizes.6', + '--tags-input-item-px': 'spacing.1.5', + _icon: { boxSize: '3.5' }, + textStyle: 'sm', + }, + control: { gap: '1' }, + itemPreview: { gap: '1' }, + itemDeleteTrigger: { boxSize: '4.5', me: '-0.5' }, + }, + md: { + root: { + '--tags-input-height': 'sizes.10', + '--tags-input-px': 'spacing.1.5', + '--tags-input-item-height': 'sizes.7', + '--tags-input-item-px': 'spacing.2', + _icon: { boxSize: '3.5' }, + textStyle: 'sm', + }, + control: { gap: '1.5' }, + itemPreview: { gap: '1' }, + itemDeleteTrigger: { boxSize: '5', me: '-1' }, + }, + lg: { + root: { + '--tags-input-height': 'sizes.11', + '--tags-input-px': 'spacing.1.5', + '--tags-input-item-height': 'sizes.8', + '--tags-input-item-px': 'spacing.2.5', + _icon: { boxSize: '4' }, + textStyle: 'md', + }, + control: { gap: '1.5' }, + itemPreview: { gap: '1' }, + itemDeleteTrigger: { boxSize: '6', me: '-1.5' }, + }, + }, + }, +}) diff --git a/src/theme/recipes/text.ts b/src/theme/recipes/text.ts new file mode 100644 index 0000000..90a24f9 --- /dev/null +++ b/src/theme/recipes/text.ts @@ -0,0 +1,6 @@ +import { defineRecipe } from '@pandacss/dev' + +export const text = defineRecipe({ + className: 'text', + variants: {}, +}) diff --git a/src/theme/recipes/textarea.ts b/src/theme/recipes/textarea.ts new file mode 100644 index 0000000..d89cc26 --- /dev/null +++ b/src/theme/recipes/textarea.ts @@ -0,0 +1,82 @@ +import { defineRecipe } from '@pandacss/dev' + +export const textarea = defineRecipe({ + className: 'textarea', + base: { + appearance: 'none', + borderRadius: 'l2', + minWidth: '0', + outline: '0', + position: 'relative', + transition: 'colors', + transitionProperty: 'box-shadow, border-color', + width: '100%', + _disabled: { + layerStyle: 'disabled', + }, + }, + defaultVariants: { + size: 'md', + variant: 'surface', + }, + variants: { + variant: { + outline: { + borderWidth: '1px', + borderColor: 'gray.outline.border', + focusVisibleRing: 'inside', + _invalid: { + borderColor: 'error', + focusRingColor: 'error', + }, + }, + surface: { + bg: 'gray.surface.bg', + borderWidth: '1px', + borderColor: 'gray.surface.border', + focusVisibleRing: 'inside', + _invalid: { + borderColor: 'error', + focusRingColor: 'error', + }, + }, + subtle: { + borderWidth: '1px', + borderColor: 'transparent', + bg: 'gray.subtle.bg', + color: 'gray.subtle.fg', + focusVisibleRing: 'inside', + _invalid: { + borderColor: 'error', + focusRingColor: 'error', + }, + }, + flushed: { + borderBottomWidth: '1px', + borderBottomColor: 'gray.outline.border', + borderRadius: '0', + color: 'fg.default', + px: '0', + _invalid: { + borderColor: 'error', + }, + _focus: { + borderColor: 'colorPalette.solid.bg', + boxShadowColor: 'colorPalette.solid.bg', + boxShadow: '0 1px 0 0 var(--shadow-color)', + _invalid: { + borderColor: 'error', + boxShadowColor: 'error', + }, + }, + }, + }, + size: { + xs: { textStyle: 'sm', px: '2', py: '5px', scrollPaddingBottom: '5px' }, + sm: { textStyle: 'sm', px: '2.5', py: '7px', scrollPaddingBottom: '7px' }, + md: { textStyle: 'md', px: '3', py: '7px', scrollPaddingBottom: '7px' }, + lg: { textStyle: 'md', px: '3.5', py: '9px', scrollPaddingBottom: '9px' }, + xl: { textStyle: 'lg', px: '4', py: '9px', scrollPaddingBottom: '9px' }, + }, + }, +}) diff --git a/src/theme/recipes/toast.ts b/src/theme/recipes/toast.ts new file mode 100644 index 0000000..60439d8 --- /dev/null +++ b/src/theme/recipes/toast.ts @@ -0,0 +1,51 @@ +import { toastAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const toast = defineSlotRecipe({ + className: 'toast', + slots: toastAnatomy.keys(), + base: { + root: { + alignItems: 'start', + background: 'gray.surface.bg', + borderRadius: 'l3', + boxShadow: 'lg', + display: 'flex', + gap: '4', + height: 'var(--height)', + minWidth: 'sm', + opacity: 'var(--opacity)', + overflowWrap: 'anywhere', + p: '4', + position: 'relative', + scale: 'var(--scale)', + transitionDuration: 'slow', + transitionProperty: 'translate, scale, opacity, height', + transitionTimingFunction: 'default', + translate: 'var(--x) var(--y)', + width: 'full', + willChange: 'translate, opacity, scale', + zIndex: 'var(--z-index)', + }, + title: { + color: 'fg.default', + fontWeight: 'medium', + textStyle: 'sm', + }, + description: { + color: 'fg.muted', + textStyle: 'sm', + }, + actionTrigger: { + color: 'colorPalette.plain.fg', + cursor: 'pointer', + fontWeight: 'semibold', + textStyle: 'sm', + }, + closeTrigger: { + position: 'absolute', + top: '2', + insetEnd: '2', + }, + }, +}) diff --git a/src/theme/recipes/toggle-group.ts b/src/theme/recipes/toggle-group.ts new file mode 100644 index 0000000..819228a --- /dev/null +++ b/src/theme/recipes/toggle-group.ts @@ -0,0 +1,22 @@ +import { toggleGroupAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const toggleGroup = defineSlotRecipe({ + className: 'toggle-group', + slots: toggleGroupAnatomy.keys(), + base: { + root: {}, + }, + variants: { + variant: { + outline: { + root: { + borderRadius: 'l3', + borderWidth: '1px', + gap: '1', + p: '1', + }, + }, + }, + }, +}) diff --git a/src/theme/recipes/tooltip.ts b/src/theme/recipes/tooltip.ts new file mode 100644 index 0000000..222e0fb --- /dev/null +++ b/src/theme/recipes/tooltip.ts @@ -0,0 +1,38 @@ +import { tooltipAnatomy } from '@ark-ui/solid/anatomy' +import { defineSlotRecipe } from '@pandacss/dev' + +export const tooltip = defineSlotRecipe({ + className: 'tooltip', + slots: tooltipAnatomy.keys(), + base: { + content: { + '--tooltip-bg': 'colors.gray.solid.bg', + bg: 'var(--tooltip-bg)', + color: 'gray.solid.fg', + borderRadius: 'l2', + boxShadow: 'sm', + fontWeight: 'semibold', + px: '2', + py: '1.5', + textStyle: 'xs', + maxWidth: 'xs', + _open: { + animationStyle: 'scale-fade-in', + animationDuration: 'fast', + }, + _closed: { + animationStyle: 'scale-fade-out', + animationDuration: 'faster', + }, + }, + arrow: { + '--arrow-size': 'sizes.2', + '--arrow-background': 'var(--tooltip-bg)', + }, + arrowTip: { + borderTopWidth: '1px', + borderInlineStartWidth: '1px', + borderColor: 'var(--tooltip-bg)', + }, + }, +})