diff --git a/.vscode/settings.json b/.vscode/settings.json index e78b37319b32b..93b329f8a21a5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -47,10 +47,11 @@ "playwright.reuseBrowser": true, "[javascript][javascriptreact][json][jsonc][typescript][typescriptreact]": { - "editor.defaultFormatter": "biomejs.biome" - // "editor.codeActionsOnSave": { - // "source.organizeImports.biome": "explicit" - // } + "editor.defaultFormatter": "biomejs.biome", + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit" + // "source.organizeImports.biome": "explicit" + } }, "[css][html][markdown][yaml]": { diff --git a/site/components.json b/site/components.json new file mode 100644 index 0000000000000..8f7ae7d9d6da5 --- /dev/null +++ b/site/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "/components", + "utils": "/utils", + "ui": "/components/ui", + "lib": "/lib", + "hooks": "/hooks" + } +} diff --git a/site/package.json b/site/package.json index 710bd7e49787b..1e83bf30030cb 100644 --- a/site/package.json +++ b/site/package.json @@ -36,6 +36,7 @@ "@alwaysmeticulous/recorder-loader": "2.137.0", "@emoji-mart/data": "1.2.1", "@emoji-mart/react": "1.1.1", + "@emotion/cache": "11.13.1", "@emotion/css": "11.13.4", "@emotion/react": "11.13.3", "@emotion/styled": "11.13.0", @@ -49,6 +50,7 @@ "@mui/system": "5.16.7", "@mui/utils": "5.16.6", "@mui/x-tree-view": "7.18.0", + "@radix-ui/react-slot": "1.1.0", "@tanstack/react-query-devtools": "4.35.3", "@xterm/addon-canvas": "0.7.0", "@xterm/addon-fit": "0.10.0", @@ -63,6 +65,8 @@ "chartjs-adapter-date-fns": "3.0.0", "chartjs-plugin-annotation": "3.0.1", "chroma-js": "2.4.2", + "class-variance-authority": "0.7.0", + "clsx": "2.1.1", "color-convert": "2.0.1", "cron-parser": "4.9.0", "cronstrue": "2.50.0", @@ -74,6 +78,7 @@ "front-matter": "4.0.2", "jszip": "3.10.1", "lodash": "4.17.21", + "lucide-react": "0.454.0", "monaco-editor": "0.52.0", "pretty-bytes": "6.1.1", "react": "18.3.1", @@ -93,6 +98,8 @@ "resize-observer-polyfill": "1.5.1", "rollup-plugin-visualizer": "5.12.0", "semver": "7.6.2", + "tailwind-merge": "2.5.4", + "tailwindcss-animate": "1.0.7", "tzdata": "1.0.40", "ua-parser-js": "1.0.33", "ufuzzy": "npm:@leeoniya/ufuzzy@1.0.10", @@ -141,6 +148,7 @@ "@types/ua-parser-js": "0.7.36", "@types/uuid": "9.0.2", "@vitejs/plugin-react": "4.3.3", + "autoprefixer": "10.4.20", "chromatic": "11.16.3", "eventsourcemock": "2.0.0", "express": "4.21.0", @@ -151,6 +159,7 @@ "jest-websocket-mock": "2.5.0", "jest_workaround": "0.1.14", "msw": "2.3.5", + "postcss": "8.4.47", "prettier": "3.3.3", "protobufjs": "7.4.0", "rxjs": "7.8.1", @@ -158,6 +167,7 @@ "storybook": "8.3.5", "storybook-addon-remix-react-router": "3.0.1", "storybook-react-context": "0.6.0", + "tailwindcss": "3.4.13", "ts-node": "10.9.1", "ts-proto": "1.164.0", "ts-prune": "0.10.3", @@ -166,11 +176,7 @@ "vite-plugin-checker": "0.8.0", "vite-plugin-turbosnap": "1.0.3" }, - "browserslist": [ - "chrome 110", - "firefox 111", - "safari 16.0" - ], + "browserslist": ["chrome 110", "firefox 111", "safari 16.0"], "resolutions": { "optionator": "0.9.3", "semver": "7.6.2" diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml index e7ddc66058018..aa7e4aa709c6d 100644 --- a/site/pnpm-lock.yaml +++ b/site/pnpm-lock.yaml @@ -21,6 +21,9 @@ importers: '@emoji-mart/react': specifier: 1.1.1 version: 1.1.1(emoji-mart@5.6.0)(react@18.3.1) + '@emotion/cache': + specifier: 11.13.1 + version: 11.13.1 '@emotion/css': specifier: 11.13.4 version: 11.13.4 @@ -60,6 +63,9 @@ importers: '@mui/x-tree-view': specifier: 7.18.0 version: 7.18.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': + specifier: 1.1.0 + version: 1.1.0(@types/react@18.3.12)(react@18.3.1) '@tanstack/react-query-devtools': specifier: 4.35.3 version: 4.35.3(@tanstack/react-query@4.35.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -102,6 +108,12 @@ importers: chroma-js: specifier: 2.4.2 version: 2.4.2 + class-variance-authority: + specifier: 0.7.0 + version: 0.7.0 + clsx: + specifier: 2.1.1 + version: 2.1.1 color-convert: specifier: 2.0.1 version: 2.0.1 @@ -135,6 +147,9 @@ importers: lodash: specifier: 4.17.21 version: 4.17.21 + lucide-react: + specifier: 0.454.0 + version: 0.454.0(react@18.3.1) monaco-editor: specifier: 0.52.0 version: 0.52.0 @@ -192,6 +207,12 @@ importers: semver: specifier: 7.6.2 version: 7.6.2 + tailwind-merge: + specifier: 2.5.4 + version: 2.5.4 + tailwindcss-animate: + specifier: 1.0.7 + version: 1.0.7(tailwindcss@3.4.13(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3))) tzdata: specifier: 1.0.40 version: 1.0.40 @@ -331,6 +352,9 @@ importers: '@vitejs/plugin-react': specifier: 4.3.3 version: 4.3.3(vite@5.4.10(@types/node@20.17.6)) + autoprefixer: + specifier: 10.4.20 + version: 10.4.20(postcss@8.4.47) chromatic: specifier: 11.16.3 version: 11.16.3 @@ -361,6 +385,9 @@ importers: msw: specifier: 2.3.5 version: 2.3.5(typescript@5.6.3) + postcss: + specifier: 8.4.47 + version: 8.4.47 prettier: specifier: 3.3.3 version: 3.3.3 @@ -382,6 +409,9 @@ importers: storybook-react-context: specifier: 0.6.0 version: 0.6.0(react-dom@18.3.1(react@18.3.1)) + tailwindcss: + specifier: 3.4.13 + version: 3.4.13(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3)) ts-node: specifier: 10.9.1 version: 10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3) @@ -416,6 +446,10 @@ packages: '@adobe/css-tools@4.4.0': resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + '@alwaysmeticulous/recorder-loader@2.137.0': resolution: {integrity: sha512-ux/xGYCNsOe8BzquEg7k7YSNJiw/0Sg2Pd/7fppYiVr5xEefpPeIhh3qwuupZgx6sB2t5KpKQdodNWVmGeyh/w==} @@ -1666,15 +1700,6 @@ packages: '@radix-ui/primitive@1.1.0': resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} - '@radix-ui/react-compose-refs@1.0.1': - resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@radix-ui/react-compose-refs@1.1.0': resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} peerDependencies: @@ -1789,15 +1814,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-slot@1.0.2': - resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@radix-ui/react-slot@1.1.0': resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} peerDependencies: @@ -2788,6 +2804,9 @@ packages: engines: {node: '>=8.0.0'} hasBin: true + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -2798,6 +2817,9 @@ packages: arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -2836,6 +2858,13 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} @@ -2945,6 +2974,10 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -3046,6 +3079,9 @@ packages: cjs-module-lexer@1.3.1: resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} + class-variance-authority@0.7.0: + resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + classnames@2.3.2: resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==} @@ -3061,6 +3097,10 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + engines: {node: '>=6'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -3098,6 +3138,10 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} @@ -3185,6 +3229,11 @@ packages: css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + cssfontparser@1.2.1: resolution: {integrity: sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==} @@ -3324,6 +3373,9 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3332,6 +3384,9 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -3484,7 +3539,6 @@ packages: eslint@8.52.0: resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -3651,6 +3705,9 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -4296,6 +4353,10 @@ packages: '@swc/core': ^1.3.3 '@swc/jest': ^0.2.22 + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -4373,6 +4434,14 @@ packages: lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -4415,6 +4484,11 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lucide-react@0.454.0: + resolution: {integrity: sha512-hw7zMDwykCLnEzgncEEjHeA6+45aeEzRYuKHuyRSOPkhko+J3ySGjGIzu+mmMfDFG1vazHepMaYFYHbTFAZAAQ==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + luxon@3.3.0: resolution: {integrity: sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==} engines: {node: '>=12'} @@ -4692,6 +4766,9 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nan@2.20.0: resolution: {integrity: sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==} @@ -4739,6 +4816,10 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -4750,6 +4831,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} @@ -4873,6 +4958,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -4899,6 +4988,43 @@ packages: resolution: {integrity: sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ==} engines: {node: '>=10'} + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.4.47: resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} @@ -5195,6 +5321,9 @@ packages: peerDependencies: react: '*' + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -5542,6 +5671,11 @@ packages: stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + superjson@1.13.3: resolution: {integrity: sha512-mJiVjfd2vokfDxsQPOwJ/PtanO87LhpYY88ubI5dUB1Ab58Txbyje3+jpm+/83R/fevaq/107NNhtYBLuoTrFg==} engines: {node: '>=10'} @@ -5565,6 +5699,19 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tailwind-merge@2.5.4: + resolution: {integrity: sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==} + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + + tailwindcss@3.4.13: + resolution: {integrity: sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==} + engines: {node: '>=14.0.0'} + hasBin: true + tar-fs@2.1.1: resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} @@ -5593,6 +5740,13 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-case@1.0.3: resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} @@ -5659,6 +5813,9 @@ packages: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-morph@13.0.3: resolution: {integrity: sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw==} @@ -6078,6 +6235,11 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + yaml@2.6.0: + resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} + engines: {node: '>= 14'} + hasBin: true + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -6109,6 +6271,8 @@ snapshots: '@adobe/css-tools@4.4.0': {} + '@alloc/quick-lru@5.2.0': {} + '@alwaysmeticulous/recorder-loader@2.137.0': {} '@ampproject/remapping@2.3.0': @@ -6528,7 +6692,7 @@ snapshots: '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 '@emotion/unitless': 0.10.0 - '@emotion/utils': 1.4.0 + '@emotion/utils': 1.4.1 csstype: 3.1.3 '@emotion/serialize@1.3.2': @@ -7352,13 +7516,6 @@ snapshots: '@radix-ui/primitive@1.1.0': {} - '@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.12)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.25.6 - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.12 - '@radix-ui/react-compose-refs@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: react: 18.3.1 @@ -7459,14 +7616,6 @@ snapshots: '@types/react': 18.3.12 '@types/react-dom': 18.3.1 - '@radix-ui/react-slot@1.0.2(@types/react@18.3.12)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.25.6 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.12)(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.12 - '@radix-ui/react-slot@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) @@ -7848,7 +7997,7 @@ snapshots: '@storybook/components@8.1.11(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-dialog': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.0.2(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@storybook/client-logger': 8.1.11 '@storybook/csf': 0.1.9 '@storybook/global': 5.0.0 @@ -8753,6 +8902,8 @@ snapshots: dependencies: entities: 2.2.0 + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -8762,6 +8913,8 @@ snapshots: arg@4.1.3: {} + arg@5.0.2: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 @@ -8808,6 +8961,16 @@ snapshots: asynckit@0.4.0: {} + autoprefixer@10.4.20(postcss@8.4.47): + dependencies: + browserslist: 4.24.2 + caniuse-lite: 1.0.30001677 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + available-typed-arrays@1.0.5: {} axios@1.7.4: @@ -8972,6 +9135,8 @@ snapshots: callsites@3.1.0: {} + camelcase-css@2.0.1: {} + camelcase@5.3.1: {} camelcase@6.3.0: {} @@ -9063,6 +9228,10 @@ snapshots: cjs-module-lexer@1.3.1: {} + class-variance-authority@0.7.0: + dependencies: + clsx: 2.0.0 + classnames@2.3.2: {} cli-spinners@2.9.2: {} @@ -9075,6 +9244,8 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clsx@2.0.0: {} + clsx@2.1.1: {} co@4.6.0: {} @@ -9103,6 +9274,8 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@4.1.1: {} + commander@6.2.1: {} commander@8.3.0: {} @@ -9186,6 +9359,8 @@ snapshots: css.escape@1.5.1: {} + cssesc@3.0.0: {} + cssfontparser@1.2.1: {} cssom@0.3.8: {} @@ -9310,10 +9485,14 @@ snapshots: dependencies: dequal: 2.0.3 + didyoumean@1.2.2: {} + diff-sequences@29.6.3: {} diff@4.0.2: {} + dlv@1.1.3: {} + doctrine@3.0.0: dependencies: esutils: 2.0.3 @@ -9776,6 +9955,8 @@ snapshots: forwarded@0.2.0: {} + fraction.js@4.3.7: {} + fresh@0.5.2: {} front-matter@4.0.2: @@ -9846,7 +10027,6 @@ snapshots: glob-parent@6.0.2: dependencies: is-glob: 4.0.3 - optional: true glob-promise@4.2.2(glob@7.2.3): dependencies: @@ -10629,6 +10809,8 @@ snapshots: '@swc/core': 1.3.38 '@swc/jest': 0.2.37(@swc/core@1.3.38) + jiti@1.21.6: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -10733,6 +10915,10 @@ snapshots: dependencies: immediate: 3.0.6 + lilconfig@2.1.0: {} + + lilconfig@3.1.2: {} + lines-and-columns@1.2.4: {} locate-path@5.0.0: @@ -10773,6 +10959,10 @@ snapshots: dependencies: yallist: 3.1.1 + lucide-react@0.454.0(react@18.3.1): + dependencies: + react: 18.3.1 + luxon@3.3.0: {} lz-string@1.5.0: {} @@ -11205,6 +11395,12 @@ snapshots: mute-stream@1.0.0: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nan@2.20.0: optional: true @@ -11234,6 +11430,8 @@ snapshots: normalize-path@3.0.0: {} + normalize-range@0.1.2: {} + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -11242,6 +11440,8 @@ snapshots: object-assign@4.1.1: {} + object-hash@3.0.0: {} + object-inspect@1.13.1: {} object-is@1.1.5: @@ -11363,6 +11563,8 @@ snapshots: picomatch@2.3.1: {} + pify@2.3.0: {} + pirates@4.0.6: {} pkg-dir@4.2.0: @@ -11385,6 +11587,38 @@ snapshots: dependencies: '@babel/runtime': 7.25.6 + postcss-import@15.1.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + + postcss-js@4.0.1(postcss@8.4.47): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.47 + + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3)): + dependencies: + lilconfig: 3.1.2 + yaml: 2.6.0 + optionalDependencies: + postcss: 8.4.47 + ts-node: 10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3) + + postcss-nested@6.2.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + postcss@8.4.47: dependencies: nanoid: 3.3.7 @@ -11721,6 +11955,10 @@ snapshots: lodash: 4.17.21 react: 18.3.1 + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -12141,6 +12379,16 @@ snapshots: stylis@4.2.0: {} + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.3.10 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + superjson@1.13.3: dependencies: copy-anything: 3.0.5 @@ -12161,6 +12409,39 @@ snapshots: symbol-tree@3.2.4: {} + tailwind-merge@2.5.4: {} + + tailwindcss-animate@1.0.7(tailwindcss@3.4.13(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3))): + dependencies: + tailwindcss: 3.4.13(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3)) + + tailwindcss@3.4.13(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3)): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.4.47 + postcss-import: 15.1.0(postcss@8.4.47) + postcss-js: 4.0.1(postcss@8.4.47) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3)) + postcss-nested: 6.2.0(postcss@8.4.47) + postcss-selector-parser: 6.1.2 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + tar-fs@2.1.1: dependencies: chownr: 1.1.4 @@ -12209,6 +12490,14 @@ snapshots: text-table@0.2.0: optional: true + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + tiny-case@1.0.3: {} tiny-invariant@1.3.3: {} @@ -12261,6 +12550,8 @@ snapshots: ts-dedent@2.2.0: {} + ts-interface-checker@0.1.13: {} + ts-morph@13.0.3: dependencies: '@ts-morph/common': 0.12.3 @@ -12648,6 +12939,8 @@ snapshots: yaml@1.10.2: {} + yaml@2.6.0: {} + yargs-parser@21.1.1: {} yargs@17.7.2: diff --git a/site/postcss.config.js b/site/postcss.config.js new file mode 100644 index 0000000000000..33ad091d26d8a --- /dev/null +++ b/site/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/site/src/components/ui/button.tsx b/site/src/components/ui/button.tsx new file mode 100644 index 0000000000000..d3a708d48a82a --- /dev/null +++ b/site/src/components/ui/button.tsx @@ -0,0 +1,53 @@ +import { Slot } from "@radix-ui/react-slot"; +import { type VariantProps, cva } from "class-variance-authority"; +import * as React from "react"; + +import { cn } from "utils/cn"; + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 font-semibold border-solid", + { + variants: { + variant: { + default: + "bg-surface-invert-primary text-content-invert hover:bg-surface-invert-secondary", + outline: + "border border-border-default text-content-primary bg-transparent hover:bg-surface-secondary", + subtle: + "border-none bg-transparent text-content-secondary hover:text-content-primary", + warning: + "border border-border-error text-content-primary bg-surface-error hover:bg-transparent", + }, + size: { + default: "h-10 px-3 py-2", + sm: "h-8 px-2 text-xs", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); + }, +); +Button.displayName = "Button"; + +export { Button, buttonVariants }; diff --git a/site/src/contexts/ThemeProvider.tsx b/site/src/contexts/ThemeProvider.tsx index fc0d3d7ac4918..fd953d17e23f0 100644 --- a/site/src/contexts/ThemeProvider.tsx +++ b/site/src/contexts/ThemeProvider.tsx @@ -1,4 +1,6 @@ +import createCache from "@emotion/cache"; import { ThemeProvider as EmotionThemeProvider } from "@emotion/react"; +import { CacheProvider } from "@emotion/react"; import CssBaseline from "@mui/material/CssBaseline"; import { ThemeProvider as MuiThemeProvider, @@ -55,6 +57,21 @@ export const ThemeProvider: FC = ({ children }) => { // The janky casting here is find because of the much more type safe fallback // We need to support `themePreference` being wrong anyway because the database // value could be anything, like an empty string. + + useEffect(() => { + const root = document.documentElement; + + if (themePreference === "auto") { + root.classList.add(preferredColorScheme); + } else { + root.classList.add(themePreference); + } + + return () => { + root.classList.remove("light", "dark"); + }; + }, [themePreference, preferredColorScheme]); + const theme = themes[themePreference as keyof typeof themes] ?? themes[preferredColorScheme]; @@ -66,6 +83,12 @@ export const ThemeProvider: FC = ({ children }) => { ); }; +// This is being added to allow Tailwind classes to be used with MUI components. https://mui.com/material-ui/integrations/interoperability/#tailwind-css +const cache = createCache({ + key: "css", + prepend: true, +}); + interface ThemeOverrideProps { theme: Theme; children?: ReactNode; @@ -73,11 +96,13 @@ interface ThemeOverrideProps { export const ThemeOverride: FC = ({ theme, children }) => { return ( - - - - {children} - - + + + + + {children} + + + ); }; diff --git a/site/src/index.css b/site/src/index.css new file mode 100644 index 0000000000000..07b0819fe4a3d --- /dev/null +++ b/site/src/index.css @@ -0,0 +1,41 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --content-primary: #27272a; + --content-secondary: #52525b; + --content-link: #2563eb; + --content-invert: #fafafa; + --content-disabled: #a1a1aa; + --content-success: #15803d; + --content-danger: #ef4444; + --surface-primary: #fafafa; + --surface-secondary: #f4f4f5; + --surface-tertiary: #e4e4e7; + --surface-invert-primary: #27272a; + --surface-invert-secondary: #3f3f46; + --surface-error: #450a0a; + --border-default: #e4e4e7; + --border-error: #ef4444; + --radius: 0.5rem; + } + .dark { + --content-primary: #fafafa; + --content-secondary: #a1a1aa; + --content-link: #60a5fa; + --content-invert: #09090b; + --content-disabled: #3f3f46; + --content-success: #16a34a; + --content-danger: #f87171; + --surface-primary: #09090b; + --surface-secondary: #18181b; + --surface-tertiary: #27272a; + --surface-invert-primary: #e4e4e7; + --surface-invert-secondary: #a1a1aa; + --surface-error: #450a0a; + --border-default: #27272a; + --border-error: #f87171; + } +} diff --git a/site/src/index.tsx b/site/src/index.tsx index e721fbb2293b7..aef10d6c64f4d 100644 --- a/site/src/index.tsx +++ b/site/src/index.tsx @@ -1,4 +1,5 @@ import { createRoot } from "react-dom/client"; +import "./index.css"; import { App } from "./App"; console.info(` ▄█▀ ▀█▄ diff --git a/site/src/modules/management/SidebarView.tsx b/site/src/modules/management/SidebarView.tsx index e6c99769e529f..eabcac8f30ccc 100644 --- a/site/src/modules/management/SidebarView.tsx +++ b/site/src/modules/management/SidebarView.tsx @@ -11,6 +11,7 @@ import { UserAvatar } from "components/UserAvatar/UserAvatar"; import type { Permissions } from "contexts/auth/permissions"; import { type ClassName, useClassName } from "hooks/useClassName"; import { useDashboard } from "modules/dashboard/useDashboard"; +import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility"; import type { FC, ReactNode } from "react"; import { Link, NavLink } from "react-router-dom"; @@ -39,6 +40,7 @@ export const SidebarView: FC = ({ permissions, }) => { const { showOrganizations } = useDashboard(); + const { multiple_organizations: hasPremiumLicense } = useFeatureVisibility(); // TODO: Do something nice to scroll to the active org. return ( @@ -52,6 +54,7 @@ export const SidebarView: FC = ({ {showOrganizations && ( = ({ active, permissions, + isPremium, }) => { return (
@@ -150,6 +155,9 @@ const DeploymentSettingsNavigation: FC = ({ )} + {!isPremium && ( + Premium + )} )}
diff --git a/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPage.tsx b/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPage.tsx new file mode 100644 index 0000000000000..9ba30d464befc --- /dev/null +++ b/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPage.tsx @@ -0,0 +1,20 @@ +import { useDashboard } from "modules/dashboard/useDashboard"; +import type { FC } from "react"; +import { Helmet } from "react-helmet-async"; +import { pageTitle } from "utils/page"; +import { PremiumPageView } from "./PremiumPageView"; + +const PremiumPage: FC = () => { + const { entitlements } = useDashboard(); + + return ( + <> + + {pageTitle("Premium Features")} + + + + ); +}; + +export default PremiumPage; diff --git a/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPageView.tsx b/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPageView.tsx new file mode 100644 index 0000000000000..b0da13a0839f8 --- /dev/null +++ b/site/src/pages/DeploymentSettingsPage/PremiumPage/PremiumPageView.tsx @@ -0,0 +1,253 @@ +import { Button } from "components/ui/button"; +import { Activity, Coins, Expand, SquareArrowOutUpRight } from "lucide-react"; +import type { FC } from "react"; +import { docs } from "utils/docs"; + +export type PremiumPageViewProps = { isEnterprise: boolean }; + +export const PremiumPageView: FC = ({ isEnterprise }) => { + return isEnterprise ? : ; +}; + +const EnterpriseVersion: FC = () => { + return ( +
+
+
+

Premium

+

+ As an Enterprise license holder, you already benefit from Coder’s + features for secure, large-scale deployments. Upgrade to Coder + Premium for enhanced multi-tenant control and flexibility. +

+
+ +
+ +
+ + +

+ Multi-Organization access controls  +

+ +
+
+

+ Manage multiple teams and projects within a single deployment, each + with isolated access. +

+
+ +
+ + +

Custom role 

+ +
+
+

+ Configure specific permissions for teams or contractors with tailored + roles. +

+
+ +
+ + +

+ Org-Level quotas for chargeback  +

+ +
+
+

+ Set and monitor resource quotas at the organization level to support + internal cost tracking. +

+
+ +
+

+ These Premium features enable you to manage team structure and budget + allocation across multiple platform teams. +

+
+
+ ); +}; + +const OSSVersion: FC = () => { + return ( +
+
+
+

+ Premium +

+

+ Coder Premium is designed for enterprises that need to scale their + Coder deployment efficiently, securely, and with full control. By + upgrading, your team gains access to advanced features enabling + governance across all environments. +

+
+ +
+ +
+

+ + +   Deploy coder at scale + +

+

+ Equip your enterprise to deploy and manage thousands of workspaces + with performance and reliability. +

+
    +
  • + + High availability + +
    + + Scale with automatic failover and load balancing across multiple + Coder instances. + +
  • +
  • + + Multi-Organization access control + +
    + + Isolate teams, projects, and environments within a single Coder + deployment. + +
  • +
  • + + Unlimited external authentication integrations + +
    + + Integrate with external service providers like GitHub, JFrog, and + Vault. + +
  • +
+
+ +
+

+ + +   Control infrastructure costs + +

+

+ Optimize cloud usage and maintain cost-effective resource management + for your teams. +

+
    +
  • + + Auto-Stop idle workspaces + +
    + + Automatically shut down inactive workspaces to prevent unnecessary + costs. + +
  • +
  • + + Resource quotas + +
    + + Set user and team-specific limits to control spending and resource + allocation. + +
  • +
  • + + Usage insights + +
    + + Track workspace usage patterns to make data-driven decisions about + infrastructure needs. + +
  • +
+
+ +
+

+ + +   Govern workspace activity + +

+

+ Maintain security and compliance across your organization with robust + governance features. +

+
    +
  • + + Audit logging + +
    + + Capture detailed records of user actions and workspace activity + for compliance and security. + +
  • +
  • + + Template permissions + +
    + + Control who can create, modify, and access workspace templates + across teams. + +
  • +
  • + + Workspace command logging + +
    + + Monitor and log critical commands to ensure security and + compliance standards are met. + +
  • +
+
+
+ ); +}; diff --git a/site/src/router.tsx b/site/src/router.tsx index c9d8736979c34..1b23b55245e8f 100644 --- a/site/src/router.tsx +++ b/site/src/router.tsx @@ -270,6 +270,9 @@ const TemplateInsightsPage = lazy( () => import("./pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage"), ); +const PremiumPage = lazy( + () => import("./pages/DeploymentSettingsPage/PremiumPage/PremiumPage"), +); const GroupsPage = lazy(() => import("./pages/GroupsPage/GroupsPage")); const IconsPage = lazy(() => import("./pages/IconsPage/IconsPage")); const AccessURLPage = lazy(() => import("./pages/HealthPage/AccessURLPage")); @@ -450,6 +453,7 @@ export const router = createBrowserRouter( path="notifications" element={} /> + } /> diff --git a/site/src/utils/cn.ts b/site/src/utils/cn.ts new file mode 100644 index 0000000000000..ac680b303c9f4 --- /dev/null +++ b/site/src/utils/cn.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/site/tailwind.config.js b/site/tailwind.config.js new file mode 100644 index 0000000000000..b9343b7add92c --- /dev/null +++ b/site/tailwind.config.js @@ -0,0 +1,49 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + corePlugins: { + preflight: false, + }, + darkMode: ["selector"], + content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], + important: "#root", + theme: { + fontSize: { + "2xs": ["0.626rem","0.875rem"], + sm: ["0.875rem", "1.5rem"], + "3xl": ["2rem", "2.5rem"], + }, + extend: { + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + colors: { + content: { + primary: "var(--content-primary)", + secondary: "var(--content-secondary)", + disabled: "var(--content-disabled)", + invert: "var(--content-invert)", + success: "var(--content-success)", + danger: "var(--content-danger)", + link: "var(--content-link)", + }, + surface: { + primary: "var(--surface-primary)", + secondary: "var(--surface-secondary)", + tertiary: "var(--surface-tertiary)", + invert: { + primary: "var(--surface-invert-primary)", + secondary: "var(--surface-invert-secondary)", + }, + error: "var(--surface-error)", + }, + border: { + default: "var(--border-default)", + error: "var(--border-error)", + }, + }, + }, + }, + plugins: [require("tailwindcss-animate")], +}; diff --git a/site/tsconfig.json b/site/tsconfig.json index 0ff5945f6d47a..7e969d18c42dd 100644 --- a/site/tsconfig.json +++ b/site/tsconfig.json @@ -1,24 +1,24 @@ { - "compilerOptions": { - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "incremental": true, - "isolatedModules": true, - "jsx": "react-jsx", - "jsxImportSource": "@emotion/react", - "lib": ["dom", "dom.iterable", "esnext"], - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "outDir": "build/", - "preserveWatchOutput": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "strict": true, - "target": "es2020", - "baseUrl": "src/" - }, - "include": ["**/*.ts", "**/*.tsx"], - "exclude": ["node_modules/", "_jest"], - "types": ["@emotion/react", "@testing-library/jest-dom", "jest", "node"] + "compilerOptions": { + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "incremental": true, + "isolatedModules": true, + "jsx": "react-jsx", + "jsxImportSource": "@emotion/react", + "lib": ["dom", "dom.iterable", "esnext"], + "module": "esnext", + "moduleResolution": "node", + "noEmit": true, + "outDir": "build/", + "preserveWatchOutput": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "es2020", + "baseUrl": "src/" + }, + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules/", "_jest"], + "types": ["@emotion/react", "@testing-library/jest-dom", "jest", "node"] } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy