From 0d99f8bca2e34a0b4e842b5942aa2b2e8ef3c92c Mon Sep 17 00:00:00 2001 From: Jamie Kyle <113370520+jamiebuilds-signal@users.noreply.github.com> Date: Mon, 4 Aug 2025 13:35:20 -0700 Subject: [PATCH] Init Axo design system --- .eslintrc.js | 60 + .prettierignore | 1 + .prettierrc.js | 11 + .storybook/main.ts | 19 +- .storybook/preview.tsx | 2 +- ACKNOWLEDGMENTS.md | 135 +- about.html | 6 +- background.html | 14 +- debug_log.html | 6 +- .../SignalSymbolsVariable.woff2 | Bin 0 -> 39572 bytes loading.html | 6 +- package.json | 23 +- .../eslint-plugin-better-tailwindcss.patch | 13 + permissions_popup.html | 6 +- pnpm-lock.yaml | 1886 ++++++++++++++++- screenShare.html | 6 +- settings.html | 6 +- stylesheets/_global.scss | 7 +- stylesheets/components/Select.scss | 1 + stylesheets/components/fun/FunSearch.scss | 1 + test/index.html | 1 + ts/axo/AxoButton.stories.tsx | 90 + ts/axo/AxoButton.tsx | 195 ++ ts/axo/AxoContextMenu.stories.tsx | 99 + ts/axo/AxoContextMenu.tsx | 388 ++++ ts/axo/AxoDropdownMenu.stories.tsx | 100 + ts/axo/AxoDropdownMenu.tsx | 402 ++++ ts/axo/AxoSelect.stories.tsx | 90 + ts/axo/AxoSelect.tsx | 288 +++ ts/axo/AxoSymbol.stories.tsx | 102 + ts/axo/AxoSymbol.tsx | 263 +++ ts/axo/_internal/AxoBaseMenu.tsx | 348 +++ ts/axo/_internal/assert.tsx | 17 + ts/axo/_internal/css.tsx | 27 + ts/axo/tailwind.css | 376 ++++ 35 files changed, 4785 insertions(+), 210 deletions(-) create mode 100644 fonts/signal-symbols/SignalSymbolsVariable.woff2 create mode 100644 patches/eslint-plugin-better-tailwindcss.patch create mode 100644 ts/axo/AxoButton.stories.tsx create mode 100644 ts/axo/AxoButton.tsx create mode 100644 ts/axo/AxoContextMenu.stories.tsx create mode 100644 ts/axo/AxoContextMenu.tsx create mode 100644 ts/axo/AxoDropdownMenu.stories.tsx create mode 100644 ts/axo/AxoDropdownMenu.tsx create mode 100644 ts/axo/AxoSelect.stories.tsx create mode 100644 ts/axo/AxoSelect.tsx create mode 100644 ts/axo/AxoSymbol.stories.tsx create mode 100644 ts/axo/AxoSymbol.tsx create mode 100644 ts/axo/_internal/AxoBaseMenu.tsx create mode 100644 ts/axo/_internal/assert.tsx create mode 100644 ts/axo/_internal/css.tsx create mode 100644 ts/axo/tailwind.css diff --git a/.eslintrc.js b/.eslintrc.js index 786a3229d1e..837b7082e9a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -317,6 +317,66 @@ module.exports = { 'func-names': 'off', }, }, + { + files: ['ts/axo/**/*.tsx'], + plugins: ['better-tailwindcss'], + settings: { + 'better-tailwindcss': { + entryPoint: './ts/axo/tailwind.css', + callees: ['css'], + }, + }, + rules: { + // stylistic: Enforce consistent line wrapping for tailwind classes. (recommended, autofix) + 'better-tailwindcss/enforce-consistent-line-wrapping': 'off', + // stylistic: Enforce a consistent order for tailwind classes. (recommended, autofix) + 'better-tailwindcss/enforce-consistent-class-order': 'error', + // stylistic: Enforce consistent variable syntax. (autofix) + 'better-tailwindcss/enforce-consistent-variable-syntax': 'error', + // stylistic: Enforce consistent position of the important modifier. (autofix) + 'better-tailwindcss/enforce-consistent-important-position': 'error', + // stylistic: Enforce shorthand class names. (autofix) + 'better-tailwindcss/enforce-shorthand-classes': 'error', + // stylistic: Remove duplicate classes. (autofix) + 'better-tailwindcss/no-duplicate-classes': 'error', + // stylistic: Remove deprecated classes. (autofix) + 'better-tailwindcss/no-deprecated-classes': 'off', + // stylistic: Disallow unnecessary whitespace in tailwind classes. (autofix) + 'better-tailwindcss/no-unnecessary-whitespace': 'error', + // correctness: Report classes not registered with tailwindcss. (recommended) + 'better-tailwindcss/no-unregistered-classes': 'error', + // correctness: Report classes that produce conflicting styles. + 'better-tailwindcss/no-conflicting-classes': 'error', + // correctness: Disallow restricted classes. (autofix) + 'better-tailwindcss/no-restricted-classes': [ + 'error', + { + restrict: [ + { + pattern: '\\[#[a-fA-F0-9]{3,8}?\\]', // ex: "text-[#fff]" + message: 'No arbitrary hex values', + }, + { + pattern: '\\[rgba?\\(.*\\)\\]', // ex: "text-[rgb(255,255,255)]" + message: 'No arbitrary rgb values', + }, + { + pattern: '\\[hsla?\\(.*\\)\\]', // ex: "text-[hsl(255,255,255)]" + message: 'No arbitrary hsl values', + }, + { + pattern: '^.*!$', // ex: "p-4!" + message: 'No !important modifiers', + }, + { + pattern: '^\\*+:.*', // ex: "*:mx-0", + message: 'No child variants', + }, + ], + }, + ], + }, + }, ], rules: { diff --git a/.prettierignore b/.prettierignore index 7b2441866ac..20e1689d1c9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -17,6 +17,7 @@ ts/**/*.js ts/protobuf/*.d.ts ts/protobuf/*.js stylesheets/manifest.css +stylesheets/tailwind.css ts/util/lint/exceptions.json storybook-static build/locale-display-names.json diff --git a/.prettierrc.js b/.prettierrc.js index 124e59afb9f..d2c896f89f3 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,8 +1,19 @@ // Copyright 2018 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only +/** @type {import("prettier").Config} */ module.exports = { singleQuote: true, arrowParens: 'avoid', trailingComma: 'es5', + overrides: [ + { + files: ['./ts/axo/**.tsx'], + plugins: ['prettier-plugin-tailwindcss'], + options: { + tailwindStylesheet: './ts/axo/tailwind.css', + tailwindFunctions: ['css'], + }, + }, + ], }; diff --git a/.storybook/main.ts b/.storybook/main.ts index 61e647389f0..02b54337840 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -9,7 +9,7 @@ const config: StorybookConfig = { reactDocgen: false, }, - stories: ['../ts/components/**/*.stories.tsx'], + stories: ['../ts/axo/**/*.stories.tsx', '../ts/components/**/*.stories.tsx'], addons: [ '@storybook/addon-a11y', @@ -69,6 +69,23 @@ const config: StorybookConfig = { ], }); + config.module!.rules!.push({ + test: /tailwind\.css$/, + use: [ + { + loader: 'postcss-loader', + options: { + postcssOptions: { + config: false, + plugins: { + '@tailwindcss/postcss': {}, + }, + }, + }, + }, + ], + }); + config.node = { global: true }; config.externals = { diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index a801cb51893..51cdbc3c185 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -5,8 +5,8 @@ import '../ts/window.d.ts'; import React, { StrictMode } from 'react'; -import 'sanitize.css'; import '../stylesheets/manifest.scss'; +import '../ts/axo/tailwind.css'; import * as styles from './styles.scss'; import messages from '../_locales/en/messages.json'; diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md index 4ef2eee45ea..cc85c3245a9 100644 --- a/ACKNOWLEDGMENTS.md +++ b/ACKNOWLEDGMENTS.md @@ -4818,6 +4818,30 @@ Signal Desktop makes use of the following open source projects. License: MIT +## radix-ui + + MIT License + + Copyright (c) 2022 WorkOS + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + ## react MIT License @@ -5546,117 +5570,6 @@ Signal Desktop makes use of the following open source projects. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -## sanitize.css - - # CC0 1.0 Universal - - ## Statement of Purpose - - The laws of most jurisdictions throughout the world automatically confer - exclusive Copyright and Related Rights (defined below) upon the creator and - subsequent owner(s) (each and all, an “owner”) of an original work of - authorship and/or a database (each, a “Work”). - - Certain owners wish to permanently relinquish those rights to a Work for the - purpose of contributing to a commons of creative, cultural and scientific works - (“Commons”) that the public can reliably and without fear of later claims of - infringement build upon, modify, incorporate in other works, reuse and - redistribute as freely as possible in any form whatsoever and for any purposes, - including without limitation commercial purposes. These owners may contribute - to the Commons to promote the ideal of a free culture and the further - production of creative, cultural and scientific works, or to gain reputation or - greater distribution for their Work in part through the use and efforts of - others. - - For these and/or other purposes and motivations, and without any expectation of - additional consideration or compensation, the person associating CC0 with a - Work (the “Affirmer”), to the extent that he or she is an owner of Copyright - and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and - publicly distribute the Work under its terms, with knowledge of his or her - Copyright and Related Rights in the Work and the meaning and intended legal - effect of CC0 on those rights. - - 1. Copyright and Related Rights. A Work made available under CC0 may be - protected by copyright and related or neighboring rights (“Copyright and - Related Rights”). Copyright and Related Rights include, but are not limited - to, the following: - 1. the right to reproduce, adapt, distribute, perform, display, communicate, - and translate a Work; - 2. moral rights retained by the original author(s) and/or performer(s); - 3. publicity and privacy rights pertaining to a person’s image or likeness - depicted in a Work; - 4. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(i), below; - 5. rights protecting the extraction, dissemination, use and reuse of data in - a Work; - 6. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - 7. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations - thereof. - - 2. Waiver. To the greatest extent permitted by, but not in contravention of, - applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and - unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright - and Related Rights and associated claims and causes of action, whether now - known or unknown (including existing as well as future claims and causes of - action), in the Work (i) in all territories worldwide, (ii) for the maximum - duration provided by applicable law or treaty (including future time - extensions), (iii) in any current or future medium and for any number of - copies, and (iv) for any purpose whatsoever, including without limitation - commercial, advertising or promotional purposes (the “Waiver”). Affirmer - makes the Waiver for the benefit of each member of the public at large and - to the detriment of Affirmer’s heirs and successors, fully intending that - such Waiver shall not be subject to revocation, rescission, cancellation, - termination, or any other legal or equitable action to disrupt the quiet - enjoyment of the Work by the public as contemplated by Affirmer’s express - Statement of Purpose. - - 3. Public License Fallback. Should any part of the Waiver for any reason be - judged legally invalid or ineffective under applicable law, then the Waiver - shall be preserved to the maximum extent permitted taking into account - Affirmer’s express Statement of Purpose. In addition, to the extent the - Waiver is so judged Affirmer hereby grants to each affected person a - royalty-free, non transferable, non sublicensable, non exclusive, - irrevocable and unconditional license to exercise Affirmer’s Copyright and - Related Rights in the Work (i) in all territories worldwide, (ii) for the - maximum duration provided by applicable law or treaty (including future time - extensions), (iii) in any current or future medium and for any number of - copies, and (iv) for any purpose whatsoever, including without limitation - commercial, advertising or promotional purposes (the “License”). The License - shall be deemed effective as of the date CC0 was applied by Affirmer to the - Work. Should any part of the License for any reason be judged legally - invalid or ineffective under applicable law, such partial invalidity or - ineffectiveness shall not invalidate the remainder of the License, and in - such case Affirmer hereby affirms that he or she will not (i) exercise any - of his or her remaining Copyright and Related Rights in the Work or (ii) - assert any associated claims and causes of action with respect to the Work, - in either case contrary to Affirmer’s express Statement of Purpose. - - 4. Limitations and Disclaimers. - 1. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - 2. Affirmer offers the Work as-is and makes no representations or warranties - of any kind concerning the Work, express, implied, statutory or - otherwise, including without limitation warranties of title, - merchantability, fitness for a particular purpose, non infringement, or - the absence of latent or other defects, accuracy, or the present or - absence of errors, whether or not discoverable, all to the greatest - extent permissible under applicable law. - 3. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person’s Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the Work. - 4. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to this - CC0 or use of the Work. - - For more information, please see - http://creativecommons.org/publicdomain/zero/1.0/. - ## semver The ISC License diff --git a/about.html b/about.html index 32eafe56b0b..d6ea6b7c6e0 100644 --- a/about.html +++ b/about.html @@ -15,12 +15,8 @@ script-src 'self'; style-src 'self' 'unsafe-inline';" /> - +
diff --git a/background.html b/background.html index d1aaa17fc02..deddd89e6b8 100644 --- a/background.html +++ b/background.html @@ -76,6 +76,13 @@ type="font/woff2" crossorigin /> + - - + diff --git a/debug_log.html b/debug_log.html index bf23592ab3d..111a4bb0a60 100644 --- a/debug_log.html +++ b/debug_log.html @@ -15,12 +15,8 @@ script-src 'self'; style-src 'self' 'unsafe-inline';" /> - +
diff --git a/fonts/signal-symbols/SignalSymbolsVariable.woff2 b/fonts/signal-symbols/SignalSymbolsVariable.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..24f696573c64c41db0051c9a6c1cefd13e33a69d GIT binary patch literal 39572 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 U7pF literal 0 HcmV?d00001 diff --git a/loading.html b/loading.html index 7e0e0295e3a..89743e64701 100644 --- a/loading.html +++ b/loading.html @@ -16,12 +16,8 @@ script-src 'self'; style-src 'self' 'unsafe-inline';" /> - +

diff --git a/package.json b/package.json index cfbb26817b9..1eb4f47508d 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "postinstall": "pnpm run build:acknowledgments && pnpm run electron:install-app-deps", "postuninstall": "pnpm run build:acknowledgments", "start": "electron .", - "generate": "npm-run-all build-protobuf build:esbuild build:icu-types build:compact-locales sass get-expire-time copy-components", + "generate": "npm-run-all build-protobuf build:esbuild build:icu-types build:compact-locales build:styles get-expire-time copy-components", "build-release": "pnpm run build", "sign-release": "node ts/updater/generateSignature.js", "notarize": "echo 'No longer necessary'", @@ -30,7 +30,6 @@ "mark-unusued-strings-deleted": "ts-node ./ts/scripts/mark-unused-strings-deleted.ts", "get-expire-time": "node ts/scripts/get-expire-time.js", "copy-components": "node ts/scripts/copy.js", - "sass": "sass stylesheets/manifest.scss:stylesheets/manifest.css stylesheets/manifest_bridge.scss:stylesheets/manifest_bridge.css --fatal-deprecation=1.80.7", "build-module-protobuf": "pbjs --root='signal-desktop' --target static-module --force-long --no-typeurl --no-verify --no-create --no-convert --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --no-comments --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "build-protobuf": "pnpm run build-module-protobuf", @@ -69,7 +68,9 @@ "dev": "pnpm run build-protobuf && cross-env SIGNAL_ENV=storybook storybook dev --port 6006", "dev:transpile": "run-p \"check:types --watch\" dev:esbuild dev:icu-types dev:protobuf", "dev:esbuild": "node scripts/esbuild.js --watch", - "dev:sass": "pnpm run sass --watch", + "dev:styles": "pnpm run '/^dev:styles:(sass|tailwind)$/'", + "dev:styles:sass": "pnpm run build:styles:sass --watch", + "dev:styles:tailwind": "pnpm run build:styles:tailwind --watch", "dev:icu-types": "chokidar ./_locales/en/messages.json --initial --command \"pnpm run build:icu-types\"", "dev:protobuf": "chokidar ./protos/**/*.proto --command \"pnpm run build-protobuf\"", "build:storybook": "pnpm run build-protobuf && cross-env SIGNAL_ENV=storybook storybook build", @@ -87,6 +88,9 @@ "build:dev": "run-s --print-label generate build:esbuild:prod", "build:esbuild": "node scripts/esbuild.js", "build:esbuild:prod": "node scripts/esbuild.js --prod", + "build:styles": "pnpm run \"/^build:styles:.*/\"", + "build:styles:sass": "sass stylesheets/manifest.scss:stylesheets/manifest.css stylesheets/manifest_bridge.scss:stylesheets/manifest_bridge.css --fatal-deprecation=1.80.7", + "build:styles:tailwind": "tailwindcss -i ./ts/axo/tailwind.css -o ./stylesheets/tailwind.css", "build:electron": "electron-builder --config.extraMetadata.environment=$SIGNAL_ENV", "build:release": "cross-env SIGNAL_ENV=production pnpm run build:electron --config.directories.output=release", "build:release-win32-all": "pnpm run build:release --arm64 --x64", @@ -183,6 +187,7 @@ "protobufjs": "7.3.2", "proxy-agent": "6.4.0", "qrcode-generator": "1.4.4", + "radix-ui": "1.4.2", "react": "18.3.1", "react-aria": "3.35.1", "react-aria-components": "1.4.1", @@ -199,7 +204,6 @@ "redux-promise-middleware": "6.2.0", "redux-thunk": "3.1.0", "reselect": "5.1.1", - "sanitize.css": "13.0.0", "semver": "7.6.3", "split2": "4.2.0", "tinykeys": "3.0.0", @@ -244,6 +248,8 @@ "@storybook/test": "8.4.4", "@storybook/test-runner": "0.22.0", "@storybook/types": "8.1.11", + "@tailwindcss/cli": "4.1.7", + "@tailwindcss/postcss": "4.1.7", "@types/backbone": "1.4.22", "@types/blueimp-load-image": "5.16.6", "@types/chai": "4.3.16", @@ -305,6 +311,7 @@ "eslint": "8.56.0", "eslint-config-airbnb-typescript-prettier": "5.0.0", "eslint-config-prettier": "8.5.0", + "eslint-plugin-better-tailwindcss": "3.7.2", "eslint-plugin-import": "2.26.0", "eslint-plugin-local-rules": "1.3.2", "eslint-plugin-mocha": "10.1.0", @@ -324,7 +331,10 @@ "pixelmatch": "5.3.0", "playwright": "1.45.0", "pngjs": "7.0.0", + "postcss": "8.5.3", + "postcss-loader": "8.1.1", "prettier": "3.3.3", + "prettier-plugin-tailwindcss": "0.6.11", "protobufjs-cli": "1.1.1", "react-devtools": "6.0.1", "react-devtools-core": "6.0.1", @@ -340,6 +350,7 @@ "stylelint-config-recommended-scss": "14.1.0", "stylelint-use-logical-spec": "5.0.1", "svgo": "3.3.2", + "tailwindcss": "4.1.7", "terser-webpack-plugin": "5.3.10", "ts-node": "10.9.2", "typescript": "5.6.3", @@ -379,7 +390,8 @@ "node-fetch@2.6.7": "patches/node-fetch+2.6.7.patch", "zod@3.23.8": "patches/zod+3.23.8.patch", "app-builder-lib": "patches/app-builder-lib.patch", - "dmg-builder": "patches/dmg-builder.patch" + "dmg-builder": "patches/dmg-builder.patch", + "eslint-plugin-better-tailwindcss": "patches/eslint-plugin-better-tailwindcss.patch" }, "onlyBuiltDependencies": [ "@indutny/mac-screen-share", @@ -390,6 +402,7 @@ "@signalapp/ringrtc", "@signalapp/windows-ucv", "@swc/core", + "@tailwindcss/oxide", "bufferutil", "electron", "esbuild", diff --git a/patches/eslint-plugin-better-tailwindcss.patch b/patches/eslint-plugin-better-tailwindcss.patch new file mode 100644 index 00000000000..d8e0d2072d6 --- /dev/null +++ b/patches/eslint-plugin-better-tailwindcss.patch @@ -0,0 +1,13 @@ +diff --git a/lib/cjs/tailwindcss/context.async.v4.js b/lib/cjs/tailwindcss/context.async.v4.js +index 8464d9d949a0d82a53f3c6683c617b56770e5fba..ac392e6e8139f33650fc1691e5593660f87912cf 100644 +--- a/lib/cjs/tailwindcss/context.async.v4.js ++++ b/lib/cjs/tailwindcss/context.async.v4.js +@@ -59,7 +59,7 @@ const createTailwindContext = async (ctx) => (0, cache_js_1.withCache)("tailwind + } + const tailwindUrl = (0, platform_js_1.isWindows)() && (0, module_js_1.isESModule)() ? (0, node_url_1.pathToFileURL)(tailwindPath).toString() : tailwindPath; + // eslint-disable-next-line eslint-plugin-typescript/naming-convention +- const { __unstable__loadDesignSystem } = await Promise.resolve(`${tailwindUrl}`).then(s => __importStar(require(s))); ++ const { __unstable__loadDesignSystem } = await import(`${tailwindUrl}`); + let css = await (0, promises_1.readFile)(ctx.tailwindConfigPath, "utf-8"); + // Determine if the v4 API supports resolving `@import` + let supportsImports = false; diff --git a/permissions_popup.html b/permissions_popup.html index 831233bcac3..323dc5827b9 100644 --- a/permissions_popup.html +++ b/permissions_popup.html @@ -15,12 +15,8 @@ script-src 'self'; style-src 'self' 'unsafe-inline';" /> - +
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9026548b741..38822e8498a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,9 @@ patchedDependencies: dmg-builder: hash: cb72ed47fa8d45513a36db33fcb41cb75c30cada4737da067bf3fa1f063725f2 path: patches/dmg-builder.patch + eslint-plugin-better-tailwindcss: + hash: a94affa4d170a27c4cfd44f7ac30ea11ae285cb4e270a5d930dd28cc79901b4f + path: patches/eslint-plugin-better-tailwindcss.patch fabric@4.6.0: hash: 259e6eff3d60c4a453f7815fca6aa0d3a81842f4efdc4051836812fc1e711e00 path: patches/fabric+4.6.0.patch @@ -314,6 +317,9 @@ importers: qrcode-generator: specifier: 1.4.4 version: 1.4.4(patch_hash=1f10c592d849ed4cfc9f81301196d39857b79240997ef5772138218cb3717e80) + radix-ui: + specifier: 1.4.2 + version: 1.4.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 18.3.1 version: 18.3.1 @@ -362,9 +368,6 @@ importers: reselect: specifier: 5.1.1 version: 5.1.1 - sanitize.css: - specifier: 13.0.0 - version: 13.0.0 semver: specifier: 7.6.3 version: 7.6.3 @@ -492,6 +495,12 @@ importers: '@storybook/types': specifier: 8.1.11 version: 8.1.11 + '@tailwindcss/cli': + specifier: 4.1.7 + version: 4.1.7 + '@tailwindcss/postcss': + specifier: 4.1.7 + version: 4.1.7 '@types/backbone': specifier: 1.4.22 version: 1.4.22(patch_hash=9dace206a9f53e0e3b0203051b26aec1e92ad49744b156ad8076946356c6c8e7) @@ -675,6 +684,9 @@ importers: eslint-config-prettier: specifier: 8.5.0 version: 8.5.0(eslint@8.56.0) + eslint-plugin-better-tailwindcss: + specifier: 3.7.2 + version: 3.7.2(patch_hash=a94affa4d170a27c4cfd44f7ac30ea11ae285cb4e270a5d930dd28cc79901b4f)(eslint@8.56.0)(tailwindcss@4.1.7) eslint-plugin-import: specifier: 2.26.0 version: 2.26.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0) @@ -732,9 +744,18 @@ importers: pngjs: specifier: 7.0.0 version: 7.0.0 + postcss: + specifier: 8.5.3 + version: 8.5.3 + postcss-loader: + specifier: 8.1.1 + version: 8.1.1(postcss@8.5.3)(typescript@5.6.3)(webpack@5.96.1) prettier: specifier: 3.3.3 version: 3.3.3 + prettier-plugin-tailwindcss: + specifier: 0.6.11 + version: 0.6.11(prettier@3.3.3) protobufjs-cli: specifier: 1.1.1 version: 1.1.1(patch_hash=178ca99a7e71f1cce7aadae6118e2c4c3b2478d3bfb787c00a661c3b02c09923)(protobufjs@7.3.2(patch_hash=0ae0fcb7c2b673e67231536164cc4841642d16c8a26578de4d43637e2a6f1774)) @@ -773,13 +794,16 @@ importers: version: 4.4.0(stylelint@16.10.0(typescript@5.6.3)) stylelint-config-recommended-scss: specifier: 14.1.0 - version: 14.1.0(postcss@8.5.2)(stylelint@16.10.0(typescript@5.6.3)) + version: 14.1.0(postcss@8.5.3)(stylelint@16.10.0(typescript@5.6.3)) stylelint-use-logical-spec: specifier: 5.0.1 version: 5.0.1(stylelint@16.10.0(typescript@5.6.3)) svgo: specifier: 3.3.2 version: 3.3.2 + tailwindcss: + specifier: 4.1.7 + version: 4.1.7 terser-webpack-plugin: specifier: 5.3.10 version: 5.3.10(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack@5.96.1) @@ -814,6 +838,10 @@ packages: '@adobe/css-tools@4.4.2': resolution: {integrity: sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==} + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -1343,6 +1371,10 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint/css-tree@3.6.3': + resolution: {integrity: sha512-M9iq4Brt/MG+5/B4Jrla5XZqaCgaHjfZyMSUJM3KNpBU61u8gMYg4TTaNTP/mUGR/rnRrVV7RXmh5qI4pIk0Yw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1918,6 +1950,10 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -1951,9 +1987,51 @@ packages: '@protobufjs/utf8@1.1.0': resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + '@radix-ui/primitive@1.1.2': resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + '@radix-ui/react-accessible-icon@1.1.7': + resolution: {integrity: sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-accordion@1.2.11': + resolution: {integrity: sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-alert-dialog@1.1.14': + resolution: {integrity: sha512-IOZfZ3nPvN6lXpJTBCunFQPRSvK8MDgSc1FB85xnIpUKOw9en0dJj8JmCAxV7BiZdtYlUpmrQjoTFkVYtdoWzQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-arrow@1.1.7': resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} peerDependencies: @@ -1967,6 +2045,71 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-aspect-ratio@1.1.7': + resolution: {integrity: sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-avatar@1.1.10': + resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-checkbox@1.3.2': + resolution: {integrity: sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collapsible@1.1.11': + resolution: {integrity: sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-compose-refs@1.1.2': resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} peerDependencies: @@ -1976,6 +2119,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-context-menu@2.2.15': + resolution: {integrity: sha512-UsQUMjcYTsBjTSXw0P3GO0werEQvUY2plgRQuKoCTtkNr45q1DiL51j4m7gxhABzZ0BadoXNsIbg7F3KwiUBbw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-context@1.1.2': resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} peerDependencies: @@ -1985,6 +2141,28 @@ packages: '@types/react': optional: true + '@radix-ui/react-dialog@1.1.14': + resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-dismissable-layer@1.1.10': resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==} peerDependencies: @@ -1998,6 +2176,67 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-dropdown-menu@2.1.15': + resolution: {integrity: sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.2': + resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-form@0.1.7': + resolution: {integrity: sha512-IXLKFnaYvFg/KkeV5QfOX7tRnwHXp127koOFUjLWMTrRv5Rny3DQcAtIFFeA/Cli4HHM8DuJCXAUsgnFVJndlw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-hover-card@1.1.14': + resolution: {integrity: sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-id@1.1.1': resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} peerDependencies: @@ -2007,6 +2246,97 @@ packages: '@types/react': optional: true + '@radix-ui/react-label@2.1.7': + resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menu@2.1.15': + resolution: {integrity: sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menubar@1.1.15': + resolution: {integrity: sha512-Z71C7LGD+YDYo3TV81paUs8f3Zbmkvg6VLRQpKYfzioOE6n7fOhA3ApK/V/2Odolxjoc4ENk8AYCjohCNayd5A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-navigation-menu@1.2.13': + resolution: {integrity: sha512-WG8wWfDiJlSF5hELjwfjSGOXcBR/ZMhBFCGYe8vERpC39CQYZeq1PQ2kaYHdye3V95d06H89KGMsVCIE4LWo3g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-one-time-password-field@0.1.7': + resolution: {integrity: sha512-w1vm7AGI8tNXVovOK7TYQHrAGpRF7qQL+ENpT1a743De5Zmay2RbWGKAiYDKIyIuqptns+znCKwNztE2xl1n0Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-password-toggle-field@0.1.2': + resolution: {integrity: sha512-F90uYnlBsLPU1UbSLciLsWQmk8+hdWa6SFw4GXaIdNWxFxI5ITKVdAG64f+Twaa9ic6xE7pqxPyUmodrGjT4pQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.14': + resolution: {integrity: sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-popper@1.2.7': resolution: {integrity: sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==} peerDependencies: @@ -2059,6 +2389,97 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-progress@1.1.7': + resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-radio-group@1.3.7': + resolution: {integrity: sha512-9w5XhD0KPOrm92OTTE0SysH3sYzHsSTHNvZgUBo/VZ80VdYyB5RneDbc0dKpURS24IxkoFRu/hI0i4XyfFwY6g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.10': + resolution: {integrity: sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-scroll-area@1.2.9': + resolution: {integrity: sha512-YSjEfBXnhUELsO2VzjdtYYD4CfQjvao+lhhrX5XsHD7/cyUNzljF1FHEbgTPN7LH2MClfwRMIsYlqTYpKTTe2A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-select@2.2.5': + resolution: {integrity: sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-separator@1.1.7': + resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slider@1.3.5': + resolution: {integrity: sha512-rkfe2pU2NBAYfGaxa3Mqosi7VZEWX5CxKaanRv0vZd4Zhl9fvQrg0VM93dv3xGLGfrHuoTRF3JXH8nb9g+B3fw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.2.3': resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} peerDependencies: @@ -2068,6 +2489,84 @@ packages: '@types/react': optional: true + '@radix-ui/react-switch@1.2.5': + resolution: {integrity: sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tabs@1.1.12': + resolution: {integrity: sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toast@1.2.14': + resolution: {integrity: sha512-nAP5FBxBJGQ/YfUB+r+O6USFVkWq3gAInkxyEnmvEV5jtSbfDhfa4hwX8CraCnbjMLsE7XSf/K75l9xXY7joWg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toggle-group@1.1.10': + resolution: {integrity: sha512-kiU694Km3WFLTC75DdqgM/3Jauf3rD9wxeS9XtyWFKsBUeZA337lC+6uUazT7I1DhanZ5gyD5Stf8uf2dbQxOQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toggle@1.1.9': + resolution: {integrity: sha512-ZoFkBBz9zv9GWer7wIjvdRxmh2wyc2oKWw6C6CseWd6/yq1DK/l5lJ+wnsmFwJZbBYqr02mrf8A2q/CVCuM3ZA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toolbar@1.1.10': + resolution: {integrity: sha512-jiwQsduEL++M4YBIurjSa+voD86OIytCod0/dbIxFZDLD8NfO1//keXYMfsW8BPcfqwoNjt+y06XcJqAb4KR7A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-tooltip@1.2.7': resolution: {integrity: sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==} peerDependencies: @@ -2117,6 +2616,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-is-hydrated@0.1.0': + resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-use-layout-effect@1.1.1': resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} peerDependencies: @@ -2126,6 +2634,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-use-rect@1.1.1': resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} peerDependencies: @@ -3092,6 +3609,98 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} + '@tailwindcss/cli@4.1.7': + resolution: {integrity: sha512-hJNjpov/UiJc9ZWH4j/eEQxqklADrD/71s+t8Y0wbyQVAwtLkSp+MeC/sHTb03X+28rfbe0fRXkiBsf73/IwPg==} + hasBin: true + + '@tailwindcss/node@4.1.7': + resolution: {integrity: sha512-9rsOpdY9idRI2NH6CL4wORFY0+Q6fnx9XP9Ju+iq/0wJwGD5IByIgFmwVbyy4ymuyprj8Qh4ErxMKTUL4uNh3g==} + + '@tailwindcss/oxide-android-arm64@4.1.7': + resolution: {integrity: sha512-IWA410JZ8fF7kACus6BrUwY2Z1t1hm0+ZWNEzykKmMNM09wQooOcN/VXr0p/WJdtHZ90PvJf2AIBS/Ceqx1emg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.7': + resolution: {integrity: sha512-81jUw9To7fimGGkuJ2W5h3/oGonTOZKZ8C2ghm/TTxbwvfSiFSDPd6/A/KE2N7Jp4mv3Ps9OFqg2fEKgZFfsvg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.7': + resolution: {integrity: sha512-q77rWjEyGHV4PdDBtrzO0tgBBPlQWKY7wZK0cUok/HaGgbNKecegNxCGikuPJn5wFAlIywC3v+WMBt0PEBtwGw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.7': + resolution: {integrity: sha512-RfmdbbK6G6ptgF4qqbzoxmH+PKfP4KSVs7SRlTwcbRgBwezJkAO3Qta/7gDy10Q2DcUVkKxFLXUQO6J3CRvBGw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.7': + resolution: {integrity: sha512-OZqsGvpwOa13lVd1z6JVwQXadEobmesxQ4AxhrwRiPuE04quvZHWn/LnihMg7/XkN+dTioXp/VMu/p6A5eZP3g==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.7': + resolution: {integrity: sha512-voMvBTnJSfKecJxGkoeAyW/2XRToLZ227LxswLAwKY7YslG/Xkw9/tJNH+3IVh5bdYzYE7DfiaPbRkSHFxY1xA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.7': + resolution: {integrity: sha512-PjGuNNmJeKHnP58M7XyjJyla8LPo+RmwHQpBI+W/OxqrwojyuCQ+GUtygu7jUqTEexejZHr/z3nBc/gTiXBj4A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.7': + resolution: {integrity: sha512-HMs+Va+ZR3gC3mLZE00gXxtBo3JoSQxtu9lobbZd+DmfkIxR54NO7Z+UQNPsa0P/ITn1TevtFxXTpsRU7qEvWg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.7': + resolution: {integrity: sha512-MHZ6jyNlutdHH8rd+YTdr3QbXrHXqwIhHw9e7yXEBcQdluGwhpQY2Eku8UZK6ReLaWtQ4gijIv5QoM5eE+qlsA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.7': + resolution: {integrity: sha512-ANaSKt74ZRzE2TvJmUcbFQ8zS201cIPxUDm5qez5rLEwWkie2SkGtA4P+GPTj+u8N6JbPrC8MtY8RmJA35Oo+A==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.7': + resolution: {integrity: sha512-HUiSiXQ9gLJBAPCMVRk2RT1ZrBjto7WvqsPBwUrNK2BcdSxMnk19h4pjZjI7zgPhDxlAbJSumTC4ljeA9y0tEw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.7': + resolution: {integrity: sha512-rYHGmvoHiLJ8hWucSfSOEmdCBIGZIq7SpkPRSqLsH2Ab2YUNgKeAPT1Fi2cx3+hnYOrAb0jp9cRyode3bBW4mQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.7': + resolution: {integrity: sha512-5SF95Ctm9DFiUyjUPnDGkoKItPX/k+xifcQhcqX5RA85m50jw1pT/KzjdvlqxRja45Y52nR4MR9fD1JYd7f8NQ==} + engines: {node: '>= 10'} + + '@tailwindcss/postcss@4.1.7': + resolution: {integrity: sha512-88g3qmNZn7jDgrrcp3ZXEQfp9CVox7xjP1HN2TFKI03CltPVd/c61ydn5qJJL8FYunn0OqBaW5HNUga0kmPVvw==} + '@tanstack/react-virtual@3.11.2': resolution: {integrity: sha512-OuFzMXPF4+xZgx8UzJha0AieuMihhhaWG0tCqpp6tDzlFwOmNBPYMuLOtMJ1Tr4pXLHmgjcWhG6RlknY2oNTdQ==} peerDependencies: @@ -3842,6 +4451,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -4844,14 +5457,17 @@ packages: engines: {node: '>=0.10'} hasBin: true - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} @@ -5080,6 +5696,10 @@ packages: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} + enhanced-resolve@5.18.2: + resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} + engines: {node: '>=10.13.0'} + enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -5257,6 +5877,13 @@ packages: eslint-import-resolver-webpack: optional: true + eslint-plugin-better-tailwindcss@3.7.2: + resolution: {integrity: sha512-uJnoDGmUPtxHHcIW5njEoh1CYlq39E4J2pWq+D7REDGhW41arSCeeaiiwAT4Ok04kXNvmFBiYmC6Jdd6Bz7o2Q==} + engines: {node: ^20.11.0 || >=21.2.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + tailwindcss: ^3.3.0 || ^4.1.6 + eslint-plugin-import@2.26.0: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} @@ -5741,6 +6368,10 @@ packages: resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -6685,6 +7316,14 @@ packages: node-notifier: optional: true + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + joi@17.13.3: resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} @@ -6839,6 +7478,70 @@ packages: resolution: {integrity: sha512-4Nk0dKhhRfVS4mECcX2jSDpNU6gcHQLneJjkGQq61N8COGtjSpSA3CI+1Q3kUYv5Vf+SwIqUtaDSdU6JO37c6w==} engines: {node: '>=8.0.0'} + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -7107,6 +7810,9 @@ packages: mdn-data@2.15.0: resolution: {integrity: sha512-KIrS0lFPOqA4DgeO16vI5fkAsy8p++WBlbXtB5P1EQs8ubBgguAInNd1DnrCeTRfGchY0kgThgDOOIPyOLH2dQ==} + mdn-data@2.21.0: + resolution: {integrity: sha512-+ZKPQezM5vYJIkCxaC+4DTnRrVZR1CgsKLu5zsQERQx6Tea8Y+wMx5A24rq8A8NepCeatIQufVAekKNgiBMsGQ==} + mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} @@ -7336,6 +8042,10 @@ packages: mp4box@0.5.3: resolution: {integrity: sha512-RIvyFZdPDIg3+mL6vUdPBSyQRrEfKO3ryAeJ4xJJV7HBHQUH3KfLlZRzfSpBHCd/HqR63HfbrWQI/CwXDvYENQ==} + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -7349,6 +8059,11 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + nanoid@3.3.8: resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -7811,6 +8526,10 @@ packages: engines: {node: '>=0.10'} hasBin: true + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} @@ -7886,6 +8605,25 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-import@16.1.1: + resolution: {integrity: sha512-2xVS1NCZAfjtVdvXiyegxzJ447GyqCeEI5V7ApgQVOWnros1p5lGNovJNapwPpMombyFBfqDwt7AD3n2l0KOfQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-loader@8.1.1: + resolution: {integrity: sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + postcss-media-query-parser@0.2.3: resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} @@ -7939,8 +8677,12 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.2: - resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==} + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} postject@1.0.0-alpha.6: @@ -7964,6 +8706,61 @@ packages: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} + prettier-plugin-tailwindcss@0.6.11: + resolution: {integrity: sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA==} + engines: {node: '>=14.21.3'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-multiline-arrays: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + prettier@3.3.3: resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} @@ -8099,6 +8896,19 @@ packages: resolution: {integrity: sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==} engines: {node: '>= 12.0.0'} + radix-ui@1.4.2: + resolution: {integrity: sha512-fT/3YFPJzf2WUpqDoQi005GS8EpCi+53VhcLaHUj5fwkPYiZAjk1mSxFvbMA8Uq71L03n+WysuYC+mlKkXxt/Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + rambda@7.5.0: resolution: {integrity: sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==} @@ -8213,11 +9023,41 @@ packages: redux: optional: true + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.1: + resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + react-stately@3.35.0: resolution: {integrity: sha512-1BH21J/TOHpyZe7c+f1BU2bnRWaBDTjLH0WdBuzNfPOXu7RBG3ebPIRvqd7UkPaVfIcol2QJnxe8S0a314JWKA==} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + react-virtualized@9.22.6: resolution: {integrity: sha512-U5j7KuUQt3AaMatlMJ0UJddqSiX+Km0YJxSqbAzIiGw5EmNz0khMyqP2hzgu4+QUtm+QPIrxzUX4raJxmVJnHg==} peerDependencies: @@ -8232,6 +9072,9 @@ packages: resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} hasBin: true + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + read-last-lines@1.8.0: resolution: {integrity: sha512-oPL0cnZkhsO2xF7DBrdzVhXSNajPP5TzzCim/2IAjeGb17ArLLTRriI/ceV6Rook3L27mvbrOvLlf9xYYnaftQ==} @@ -8502,9 +9345,6 @@ packages: sanitize-filename@1.6.3: resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} - sanitize.css@13.0.0: - resolution: {integrity: sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==} - sass-loader@16.0.3: resolution: {integrity: sha512-gosNorT1RCkuCMyihv6FBRR7BMV06oKRAs+l4UMp1mlcVg9rWN6KMmUj3igjQwmYys4mDP3etEYJgiHRbgHCHA==} engines: {node: '>= 18.12.0'} @@ -9003,6 +9843,10 @@ packages: '@swc/core': ^1.2.147 webpack: '>=2' + synckit@0.11.11: + resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + engines: {node: ^14.18.0 || >=16.0.0} + synckit@0.9.2: resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -9014,6 +9858,13 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} + tailwind-csstree@0.1.2: + resolution: {integrity: sha512-SP36MjhkSGa0Yux/B863QyxljQku+WbGH5f+dqyFJXvdexemcC0Fwj/2du2DoXVkboO5Rc1Pd4i45EmFJual6w==} + engines: {node: '>=18.18'} + + tailwindcss@4.1.7: + resolution: {integrity: sha512-kr1o/ErIdNhTz8uzAYL7TpaUuzKIE6QPQ4qmSdxnoX/lo+5wmUHQA6h3L5yIqEImSRnAAURDirLu/BgiXGPAhg==} + tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -9187,6 +10038,10 @@ packages: '@swc/wasm': optional: true + tsconfig-paths-webpack-plugin@4.2.0: + resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} + engines: {node: '>=10.13.0'} + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -9401,11 +10256,36 @@ packages: urlpattern-polyfill@10.0.0: resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + use-sync-external-store@1.4.0: resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + use-sync-external-store@1.5.0: + resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} @@ -9815,6 +10695,8 @@ snapshots: '@adobe/css-tools@4.4.2': {} + '@alloc/quick-lru@5.2.0': {} + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.8 @@ -10281,7 +11163,7 @@ snapshots: '@malept/cross-spawn-promise': 2.0.0 chalk: 4.1.2 debug: 4.3.7(supports-color@8.1.1) - detect-libc: 2.0.3 + detect-libc: 2.0.4 fs-extra: 10.1.0 got: 11.8.5(patch_hash=cfe393dc1cca8970377087e9555a285d1121f75d57223ddd872b1a8d3f8c909b) node-abi: 3.75.0 @@ -10412,6 +11294,11 @@ snapshots: '@eslint-community/regexpp@4.12.1': {} + '@eslint/css-tree@3.6.3': + dependencies: + mdn-data: 2.21.0 + source-map-js: 1.2.1 + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 @@ -11188,13 +12075,14 @@ snapshots: '@parcel/watcher-win32-arm64': 2.5.1 '@parcel/watcher-win32-ia32': 2.5.1 '@parcel/watcher-win32-x64': 2.5.1 - optional: true '@pkgjs/parseargs@0.11.0': optional: true '@pkgr/core@0.1.1': {} + '@pkgr/core@0.2.9': {} + '@popperjs/core@2.11.8': {} '@protobufjs/aspromise@1.1.2': {} @@ -11220,8 +12108,50 @@ snapshots: '@protobufjs/utf8@1.1.0': {} + '@radix-ui/number@1.1.1': {} + '@radix-ui/primitive@1.1.2': {} + '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-accordion@1.2.11(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collapsible': 1.1.11(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-alert-dialog@1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dialog': 1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -11231,18 +12161,126 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-avatar@1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-checkbox@1.3.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-collapsible@1.1.11(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 + '@radix-ui/react-context-menu@2.2.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-menu': 2.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-context@1.1.2(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 + '@radix-ui/react-dialog@1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.20)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-direction@1.1.1(@types/react@18.3.20)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.20 + '@radix-ui/react-dismissable-layer@1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.2 @@ -11256,6 +12294,69 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-dropdown-menu@2.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-menu': 2.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-focus-guards@1.1.2(@types/react@18.3.20)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.20 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-form@0.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-label': 2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-hover-card@1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-id@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) @@ -11263,6 +12364,140 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 + '@radix-ui/react-label@2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-menu@2.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.20)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-menubar@1.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-menu': 2.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-navigation-menu@1.2.13(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-one-time-password-field@0.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-password-toggle-field@0.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-popover@1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.20)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-popper@1.2.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -11310,6 +12545,125 @@ snapshots: '@types/react': 18.3.20 '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-progress@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-radio-group@1.3.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-roving-focus@1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-scroll-area@1.2.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-select@2.2.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.20)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-separator@1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-slider@1.3.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-slot@1.2.3(@types/react@18.3.20)(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) @@ -11317,6 +12671,98 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 + '@radix-ui/react-switch@1.2.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-tabs@1.1.12(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-toast@1.2.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-toggle-group@1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-toggle@1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + + '@radix-ui/react-toolbar@1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle-group': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + '@radix-ui/react-tooltip@1.2.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.2 @@ -11365,12 +12811,25 @@ snapshots: optionalDependencies: '@types/react': 18.3.20 + '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@18.3.20)(react@18.3.1)': + dependencies: + react: 18.3.1 + use-sync-external-store: 1.5.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 18.3.20 + '@radix-ui/react-use-previous@1.1.1(@types/react@18.3.20)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.20 + '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.20)(react@18.3.1)': dependencies: '@radix-ui/rect': 1.1.1 @@ -12939,6 +14398,88 @@ snapshots: dependencies: defer-to-connect: 2.0.1 + '@tailwindcss/cli@4.1.7': + dependencies: + '@parcel/watcher': 2.5.1 + '@tailwindcss/node': 4.1.7 + '@tailwindcss/oxide': 4.1.7 + enhanced-resolve: 5.18.1 + mri: 1.2.0 + picocolors: 1.1.1 + tailwindcss: 4.1.7 + + '@tailwindcss/node@4.1.7': + dependencies: + '@ampproject/remapping': 2.3.0 + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.30.1 + magic-string: 0.30.17 + source-map-js: 1.2.1 + tailwindcss: 4.1.7 + + '@tailwindcss/oxide-android-arm64@4.1.7': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.7': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.7': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.7': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.7': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.7': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.7': + optional: true + + '@tailwindcss/oxide@4.1.7': + dependencies: + detect-libc: 2.0.4 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.7 + '@tailwindcss/oxide-darwin-arm64': 4.1.7 + '@tailwindcss/oxide-darwin-x64': 4.1.7 + '@tailwindcss/oxide-freebsd-x64': 4.1.7 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.7 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.7 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.7 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.7 + '@tailwindcss/oxide-linux-x64-musl': 4.1.7 + '@tailwindcss/oxide-wasm32-wasi': 4.1.7 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.7 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.7 + + '@tailwindcss/postcss@4.1.7': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.1.7 + '@tailwindcss/oxide': 4.1.7 + postcss: 8.5.3 + tailwindcss: 4.1.7 + '@tanstack/react-virtual@3.11.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@tanstack/virtual-core': 3.11.2 @@ -13843,6 +15384,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + aria-query@5.3.0: dependencies: dequal: 2.0.3 @@ -14696,12 +16241,12 @@ snapshots: css-loader@6.11.0(webpack@5.96.1): dependencies: - icss-utils: 5.1.0(postcss@8.5.2) - postcss: 8.5.2 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.2) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.2) - postcss-modules-scope: 3.2.1(postcss@8.5.2) - postcss-modules-values: 4.0.0(postcss@8.5.2) + icss-utils: 5.1.0(postcss@8.5.3) + postcss: 8.5.3 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.3) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.3) + postcss-modules-scope: 3.2.1(postcss@8.5.3) + postcss-modules-values: 4.0.0(postcss@8.5.3) postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: @@ -14709,12 +16254,12 @@ snapshots: css-loader@7.1.2(webpack@5.96.1): dependencies: - icss-utils: 5.1.0(postcss@8.5.2) - postcss: 8.5.2 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.2) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.2) - postcss-modules-scope: 3.2.1(postcss@8.5.2) - postcss-modules-values: 4.0.0(postcss@8.5.2) + icss-utils: 5.1.0(postcss@8.5.3) + postcss: 8.5.3 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.3) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.3) + postcss-modules-scope: 3.2.1(postcss@8.5.3) + postcss-modules-values: 4.0.0(postcss@8.5.3) postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: @@ -14944,13 +16489,14 @@ snapshots: destroy@1.2.0: {} - detect-libc@1.0.3: - optional: true + detect-libc@1.0.3: {} - detect-libc@2.0.3: {} + detect-libc@2.0.4: {} detect-newline@3.1.0: {} + detect-node-es@1.1.0: {} + detect-node@2.1.0: {} diff-sequences@29.6.3: {} @@ -15259,6 +16805,11 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 + enhanced-resolve@5.18.2: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + enquirer@2.4.1: dependencies: ansi-colors: 4.1.3 @@ -15526,6 +17077,19 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-better-tailwindcss@3.7.2(patch_hash=a94affa4d170a27c4cfd44f7ac30ea11ae285cb4e270a5d930dd28cc79901b4f)(eslint@8.56.0)(tailwindcss@4.1.7): + dependencies: + '@eslint/css-tree': 3.6.3 + enhanced-resolve: 5.18.2 + eslint: 8.56.0 + jiti: 2.4.2 + postcss: 8.5.6 + postcss-import: 16.1.1(postcss@8.5.6) + synckit: 0.11.11 + tailwind-csstree: 0.1.2 + tailwindcss: 4.1.7 + tsconfig-paths-webpack-plugin: 4.2.0 + eslint-plugin-import@2.26.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0): dependencies: array-includes: 3.1.8 @@ -16166,6 +17730,8 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-package-type@0.1.0: {} get-proto@1.0.1: @@ -16598,9 +18164,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.5.2): + icss-utils@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.5.2 + postcss: 8.5.3 ieee754@1.2.1: {} @@ -17400,6 +18966,10 @@ snapshots: - supports-color - ts-node + jiti@1.21.7: {} + + jiti@2.4.2: {} + joi@17.13.3: dependencies: '@hapi/hoek': 9.3.0 @@ -17569,6 +19139,51 @@ snapshots: libheif-js@1.18.2: {} + lightningcss-darwin-arm64@1.30.1: + optional: true + + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: + dependencies: + detect-libc: 2.0.4 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + lines-and-columns@1.2.4: {} linkify-it@5.0.0: @@ -17866,6 +19481,8 @@ snapshots: mdn-data@2.15.0: {} + mdn-data@2.21.0: {} + mdurl@2.0.0: {} media-typer@0.3.0: {} @@ -18116,6 +19733,8 @@ snapshots: mp4box@0.5.3: {} + mri@1.2.0: {} + ms@2.0.0: {} ms@2.1.3: {} @@ -18131,6 +19750,8 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + nanoid@3.3.11: {} + nanoid@3.3.8: {} natural-compare-lite@1.4.0: {} @@ -18173,8 +19794,7 @@ snapshots: node-addon-api@1.7.2: optional: true - node-addon-api@7.1.1: - optional: true + node-addon-api@7.1.1: {} node-addon-api@8.3.0: {} @@ -18619,6 +20239,8 @@ snapshots: pidtree@0.3.1: {} + pify@2.3.0: {} + pify@3.0.0: {} pino-abstract-transport@2.0.0: @@ -18698,38 +20320,56 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-import@16.1.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.10 + + postcss-loader@8.1.1(postcss@8.5.3)(typescript@5.6.3)(webpack@5.96.1): + dependencies: + cosmiconfig: 9.0.0(typescript@5.6.3) + jiti: 1.21.7 + postcss: 8.5.3 + semver: 7.6.3 + optionalDependencies: + webpack: 5.96.1(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4) + transitivePeerDependencies: + - typescript + postcss-media-query-parser@0.2.3: {} - postcss-modules-extract-imports@3.1.0(postcss@8.5.2): + postcss-modules-extract-imports@3.1.0(postcss@8.5.3): dependencies: - postcss: 8.5.2 + postcss: 8.5.3 - postcss-modules-local-by-default@4.2.0(postcss@8.5.2): + postcss-modules-local-by-default@4.2.0(postcss@8.5.3): dependencies: - icss-utils: 5.1.0(postcss@8.5.2) - postcss: 8.5.2 + icss-utils: 5.1.0(postcss@8.5.3) + postcss: 8.5.3 postcss-selector-parser: 7.1.0 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.5.2): + postcss-modules-scope@3.2.1(postcss@8.5.3): dependencies: - postcss: 8.5.2 + postcss: 8.5.3 postcss-selector-parser: 7.1.0 - postcss-modules-values@4.0.0(postcss@8.5.2): + postcss-modules-values@4.0.0(postcss@8.5.3): dependencies: - icss-utils: 5.1.0(postcss@8.5.2) - postcss: 8.5.2 + icss-utils: 5.1.0(postcss@8.5.3) + postcss: 8.5.3 postcss-resolve-nested-selector@0.1.6: {} - postcss-safe-parser@7.0.1(postcss@8.5.2): + postcss-safe-parser@7.0.1(postcss@8.5.3): dependencies: - postcss: 8.5.2 + postcss: 8.5.3 - postcss-scss@4.0.9(postcss@8.5.2): + postcss-scss@4.0.9(postcss@8.5.3): dependencies: - postcss: 8.5.2 + postcss: 8.5.3 postcss-selector-parser@6.1.2: dependencies: @@ -18743,12 +20383,18 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.5.2: + postcss@8.5.3: dependencies: nanoid: 3.3.8 picocolors: 1.1.1 source-map-js: 1.2.1 + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postject@1.0.0-alpha.6: dependencies: commander: 9.5.0 @@ -18764,6 +20410,10 @@ snapshots: dependencies: fast-diff: 1.3.0 + prettier-plugin-tailwindcss@0.6.11(prettier@3.3.3): + dependencies: + prettier: 3.3.3 + prettier@3.3.3: {} pretty-error@4.0.0: @@ -18914,6 +20564,69 @@ snapshots: lodash.clonedeep: 4.5.0 lodash.isequal: 4.5.0 + radix-ui@1.4.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-accordion': 1.2.11(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-alert-dialog': 1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-avatar': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-checkbox': 1.3.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collapsible': 1.1.11(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-context-menu': 2.2.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': 1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dropdown-menu': 2.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-form': 0.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-hover-card': 1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-label': 2.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-menu': 2.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-menubar': 1.1.15(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-navigation-menu': 1.2.13(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-one-time-password-field': 0.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-password-toggle-field': 0.1.2(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popover': 1.1.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-progress': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-radio-group': 1.3.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-scroll-area': 1.2.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-select': 2.2.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slider': 1.3.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-switch': 1.2.5(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tabs': 1.1.12(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toast': 1.2.14(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle': 1.1.9(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toggle-group': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toolbar': 1.1.10(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip': 1.2.7(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.20)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.6(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + '@types/react-dom': 18.3.6(@types/react@18.3.20) + rambda@7.5.0: {} ramda@0.29.0: {} @@ -19125,6 +20838,25 @@ snapshots: '@types/react': 18.3.20 redux: 5.0.1 + react-remove-scroll-bar@2.3.8(@types/react@18.3.20)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.3(@types/react@18.3.20)(react@18.3.1) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.20 + + react-remove-scroll@2.7.1(@types/react@18.3.20)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.8(@types/react@18.3.20)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.20)(react@18.3.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@18.3.20)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.20)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.20 + react-stately@3.35.0(react@18.3.1): dependencies: '@react-stately/calendar': 3.7.0(react@18.3.1) @@ -19154,6 +20886,14 @@ snapshots: '@react-types/shared': 3.27.0(react@18.3.1) react: 18.3.1 + react-style-singleton@2.2.3(@types/react@18.3.20)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.20 + react-virtualized@9.22.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.26.7 @@ -19175,6 +20915,10 @@ snapshots: transitivePeerDependencies: - supports-color + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + read-last-lines@1.8.0: dependencies: mz: 2.7.0 @@ -19376,7 +21120,7 @@ snapshots: adjust-sourcemap-loader: 4.0.0 convert-source-map: 1.9.0 loader-utils: 2.0.4 - postcss: 8.5.2 + postcss: 8.5.3 source-map: 0.6.1 resolve.exports@2.0.3: {} @@ -19475,8 +21219,6 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sanitize.css@13.0.0: {} - sass-loader@16.0.3(sass@1.80.7)(webpack@5.96.1): dependencies: neo-async: 2.6.2 @@ -19982,14 +21724,14 @@ snapshots: optionalDependencies: stylelint-scss: 6.11.0(stylelint@16.10.0(typescript@5.6.3)) - stylelint-config-recommended-scss@14.1.0(postcss@8.5.2)(stylelint@16.10.0(typescript@5.6.3)): + stylelint-config-recommended-scss@14.1.0(postcss@8.5.3)(stylelint@16.10.0(typescript@5.6.3)): dependencies: - postcss-scss: 4.0.9(postcss@8.5.2) + postcss-scss: 4.0.9(postcss@8.5.3) stylelint: 16.10.0(typescript@5.6.3) stylelint-config-recommended: 14.0.1(stylelint@16.10.0(typescript@5.6.3)) stylelint-scss: 6.11.0(stylelint@16.10.0(typescript@5.6.3)) optionalDependencies: - postcss: 8.5.2 + postcss: 8.5.3 stylelint-config-recommended@14.0.1(stylelint@16.10.0(typescript@5.6.3)): dependencies: @@ -20040,9 +21782,9 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.2 + postcss: 8.5.3 postcss-resolve-nested-selector: 0.1.6 - postcss-safe-parser: 7.0.1(postcss@8.5.2) + postcss-safe-parser: 7.0.1(postcss@8.5.3) postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 resolve-from: 5.0.0 @@ -20103,6 +21845,10 @@ snapshots: '@swc/counter': 0.1.3 webpack: 5.96.1(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.24.0)(webpack-cli@5.1.4) + synckit@0.11.11: + dependencies: + '@pkgr/core': 0.2.9 + synckit@0.9.2: dependencies: '@pkgr/core': 0.1.1 @@ -20118,6 +21864,10 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + tailwind-csstree@0.1.2: {} + + tailwindcss@4.1.7: {} + tapable@2.2.1: {} tar@6.2.1: @@ -20291,6 +22041,13 @@ snapshots: optionalDependencies: '@swc/core': 1.10.16(@swc/helpers@0.5.15) + tsconfig-paths-webpack-plugin@4.2.0: + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.18.2 + tapable: 2.2.1 + tsconfig-paths: 4.2.0 + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -20511,10 +22268,29 @@ snapshots: urlpattern-polyfill@10.0.0: {} + use-callback-ref@1.3.3(@types/react@18.3.20)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.20 + + use-sidecar@1.1.3(@types/react@18.3.20)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.20 + use-sync-external-store@1.4.0(react@18.3.1): dependencies: react: 18.3.1 + use-sync-external-store@1.5.0(react@18.3.1): + dependencies: + react: 18.3.1 + utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 diff --git a/screenShare.html b/screenShare.html index 606175d7684..5dc56396e9a 100644 --- a/screenShare.html +++ b/screenShare.html @@ -15,12 +15,8 @@ script-src 'self'; style-src 'self' 'unsafe-inline';" /> - +
diff --git a/settings.html b/settings.html index fe6f8d8ce85..69e0e344d66 100644 --- a/settings.html +++ b/settings.html @@ -15,12 +15,8 @@ script-src 'self'; style-src 'self' 'unsafe-inline';" /> - +
diff --git a/stylesheets/_global.scss b/stylesheets/_global.scss index 6ac0d2a48d5..421ae96641b 100644 --- a/stylesheets/_global.scss +++ b/stylesheets/_global.scss @@ -7,6 +7,8 @@ html { height: 100%; cursor: inherit; + // Legacy style from sanitize.css: + overflow-wrap: break-word; } .light-theme { @@ -157,10 +159,13 @@ audio { } button { - cursor: pointer; font-size: inherit; -webkit-app-region: no-drag; } +button:not(:disabled) { + cursor: pointer; +} + button.grey { border-radius: 5px; border: solid 1px variables.$color-gray-25; diff --git a/stylesheets/components/Select.scss b/stylesheets/components/Select.scss index dcdb70342e4..c8d2cc464b3 100644 --- a/stylesheets/components/Select.scss +++ b/stylesheets/components/Select.scss @@ -20,6 +20,7 @@ padding-inline: 12px 32px; text-overflow: ellipsis; width: 100%; + color: variables.$color-black; @include mixins.dark-theme { background-color: variables.$color-gray-90; diff --git a/stylesheets/components/fun/FunSearch.scss b/stylesheets/components/fun/FunSearch.scss index 12c429199e2..3d8f93a7537 100644 --- a/stylesheets/components/fun/FunSearch.scss +++ b/stylesheets/components/fun/FunSearch.scss @@ -43,6 +43,7 @@ $input-padding-inline: 12px; $input-padding-inline + $icon-actual-size + $icon-margin-inline-start ); @include mixins.font-body-1; + color: light-dark(variables.$color-black, variables.$color-white); background: light-dark(variables.$color-gray-05, variables.$color-gray-80); &:focus { diff --git a/test/index.html b/test/index.html index fa21a42418a..65b1c07e741 100644 --- a/test/index.html +++ b/test/index.html @@ -7,6 +7,7 @@ TextSecure test runner +
diff --git a/ts/axo/AxoButton.stories.tsx b/ts/axo/AxoButton.stories.tsx new file mode 100644 index 00000000000..f638af85634 --- /dev/null +++ b/ts/axo/AxoButton.stories.tsx @@ -0,0 +1,90 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +import React from 'react'; +import type { Meta } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import { + _getAllAxoButtonVariants, + _getAllAxoButtonSizes, + AxoButton, +} from './AxoButton'; + +export default { + title: 'Axo/AxoButton', +} satisfies Meta; + +export function Basic(): JSX.Element { + const variants = _getAllAxoButtonVariants(); + const sizes = _getAllAxoButtonSizes(); + return ( +
+ {sizes.map(size => { + return ( +
+

Size: {size}

+ {variants.map(variant => { + return ( +
+ + {variant} + + + + Disabled + + + + Icon + + + + Disabled + + + + Arrow + + + + Disabled + +
+ ); + })} +
+ ); + })} +
+ ); +} diff --git a/ts/axo/AxoButton.tsx b/ts/axo/AxoButton.tsx new file mode 100644 index 00000000000..0641e6dfa6e --- /dev/null +++ b/ts/axo/AxoButton.tsx @@ -0,0 +1,195 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +import React, { memo, forwardRef } from 'react'; +import type { ButtonHTMLAttributes, FC, ForwardedRef, ReactNode } from 'react'; +import type { Styles } from './_internal/css'; +import { css } from './_internal/css'; +import { AxoSymbol, type AxoSymbolName } from './AxoSymbol'; +import { assert } from './_internal/assert'; + +const Namespace = 'AxoButton'; + +const baseAxoButtonStyles = css( + 'flex items-center-safe justify-center-safe gap-1 truncate rounded-full select-none', + 'outline-0 outline-border-focused focused:outline-[2.5px]' +); + +const AxoButtonTypes = { + default: css(baseAxoButtonStyles), + subtle: css( + baseAxoButtonStyles, + 'bg-fill-secondary', + 'pressed:bg-fill-secondary-pressed' + ), + floating: css( + baseAxoButtonStyles, + 'bg-fill-floating', + 'shadow-elevation-1', + 'pressed:bg-fill-floating-pressed' + ), + borderless: css( + baseAxoButtonStyles, + 'bg-transparent', + 'hovered:bg-fill-secondary', + 'pressed:bg-fill-secondary-pressed' + ), +} as const satisfies Record; + +const AxoButtonVariants = { + // default + secondary: css( + AxoButtonTypes.default, + 'bg-fill-secondary text-label-primary', + 'pressed:bg-fill-secondary-pressed', + 'disabled:text-label-disabled' + ), + primary: css( + AxoButtonTypes.default, + 'bg-color-fill-primary text-label-primary-on-color', + 'pressed:bg-color-fill-primary-pressed', + 'disabled:text-label-disabled-on-color' + ), + affirmative: css( + AxoButtonTypes.default, + 'bg-color-fill-affirmative text-label-primary-on-color', + 'pressed:bg-color-fill-affirmative-pressed', + 'disabled:text-label-disabled-on-color' + ), + destructive: css( + AxoButtonTypes.default, + 'bg-color-fill-destructive text-label-primary-on-color', + 'pressed:bg-color-fill-destructive-pressed', + 'disabled:text-label-disabled-on-color' + ), + + // subtle + 'subtle-primary': css( + AxoButtonTypes.subtle, + 'text-color-label-primary', + 'disabled:text-color-label-primary-disabled' + ), + 'subtle-affirmative': css( + AxoButtonTypes.subtle, + 'text-color-label-affirmative', + 'disabled:text-color-label-affirmative-disabled' + ), + 'subtle-destructive': css( + AxoButtonTypes.subtle, + 'text-color-label-destructive', + 'disabled:text-color-label-destructive-disabled' + ), + + // floating + 'floating-secondary': css( + AxoButtonTypes.floating, + 'text-label-primary', + 'disabled:text-label-disabled' + ), + 'floating-primary': css( + AxoButtonTypes.floating, + 'text-color-label-primary', + 'disabled:text-color-label-primary-disabled' + ), + 'floating-affirmative': css( + AxoButtonTypes.floating, + 'text-color-label-affirmative', + 'disabled:text-color-label-affirmative-disabled' + ), + 'floating-destructive': css( + AxoButtonTypes.floating, + 'text-color-label-destructive', + 'disabled:text-color-label-destructive-disabled' + ), + + // borderless + 'borderless-secondary': css( + AxoButtonTypes.borderless, + 'text-label-primary', + 'disabled:text-label-disabled' + ), + 'borderless-primary': css( + AxoButtonTypes.borderless, + 'text-color-label-primary', + 'disabled:text-color-label-primary-disabled' + ), + 'borderless-affirmative': css( + AxoButtonTypes.borderless, + 'text-color-label-affirmative', + 'disabled:text-color-label-affirmative-disabled' + ), + 'borderless-destructive': css( + AxoButtonTypes.borderless, + 'text-color-label-destructive', + 'disabled:text-color-label-destructive-disabled' + ), +}; + +const AxoButtonSizes = { + large: css('px-4 py-2 type-body-medium font-medium'), + medium: css('px-3 py-1.5 type-body-medium font-medium'), + small: css('px-2 py-1 type-body-small font-medium'), +} as const satisfies Record; + +type BaseButtonAttrs = Omit< + ButtonHTMLAttributes, + 'className' | 'style' | 'children' +>; + +type AxoButtonVariant = keyof typeof AxoButtonVariants; +type AxoButtonSize = keyof typeof AxoButtonSizes; + +type AxoButtonProps = BaseButtonAttrs & + Readonly<{ + variant: AxoButtonVariant; + size: AxoButtonSize; + symbol?: AxoSymbolName; + arrow?: boolean; + children: ReactNode; + }>; + +export function _getAllAxoButtonVariants(): ReadonlyArray { + return Object.keys(AxoButtonVariants) as Array; +} + +export function _getAllAxoButtonSizes(): ReadonlyArray { + return Object.keys(AxoButtonSizes) as Array; +} + +// eslint-disable-next-line import/export +export const AxoButton: FC = memo( + forwardRef((props, ref: ForwardedRef) => { + const { variant, size, symbol, arrow, children, ...rest } = props; + const variantStyles = assert( + AxoButtonVariants[variant], + `${Namespace}: Invalid variant ${variant}` + ); + const sizeStyles = assert( + AxoButtonSizes[size], + `${Namespace}: Invalid size ${size}` + ); + return ( + + ); + }) +); + +AxoButton.displayName = `${Namespace}`; + +// eslint-disable-next-line max-len +// eslint-disable-next-line @typescript-eslint/no-namespace, @typescript-eslint/no-redeclare, import/export +export namespace AxoButton { + export type Variant = AxoButtonVariant; + export type Size = AxoButtonSize; + export type Props = AxoButtonProps; +} diff --git a/ts/axo/AxoContextMenu.stories.tsx b/ts/axo/AxoContextMenu.stories.tsx new file mode 100644 index 00000000000..924eeebf3d1 --- /dev/null +++ b/ts/axo/AxoContextMenu.stories.tsx @@ -0,0 +1,99 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +import React, { useState } from 'react'; +import type { Meta } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import { AxoContextMenu } from './AxoContextMenu'; + +export default { + title: 'Axo/AxoContextMenu', +} satisfies Meta; + +export function Basic(): JSX.Element { + const [showBookmarks, setShowBookmarks] = useState(true); + const [showFullUrls, setShowFullUrls] = useState(false); + const [selectedPerson, setSelectedPerson] = useState('jamie'); + return ( +
+ + +
+ Right-Click +
+
+ + + Back + + + Forward + + + Reload + + + More Tools + + + Save Page As... + + + Create Shortcut... + + + Name Window... + + + + Developer Tools + + + + + + Show Bookmarks + + + Show Full URLs + + + People + + + Jamie + + + Tyler + + + +
+
+ ); +} diff --git a/ts/axo/AxoContextMenu.tsx b/ts/axo/AxoContextMenu.tsx new file mode 100644 index 00000000000..b7d7791fdca --- /dev/null +++ b/ts/axo/AxoContextMenu.tsx @@ -0,0 +1,388 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +import React, { memo } from 'react'; +import { ContextMenu } from 'radix-ui'; +import type { FC } from 'react'; +import { AxoSymbol } from './AxoSymbol'; +import { AxoBaseMenu } from './_internal/AxoBaseMenu'; + +const Namespace = 'AxoContextMenu'; + +/** + * Displays a menu located at the pointer, triggered by a right click or a long press. + * + * Note: For menus that are triggered by a normal button press, you should use + * `AxoDropdownMenu`. + * + * @example Anatomy + * ```tsx + * import { AxoContextMenu } from "./axo/ContextMenu/AxoContentMenu.tsx"; + * + * export default () => ( + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * ) + * ``` + */ +// eslint-disable-next-line @typescript-eslint/no-namespace +export namespace AxoContextMenu { + /** + * Component: + * -------------------------------- + */ + + export type RootProps = AxoBaseMenu.MenuRootProps; + + export const Root: FC = memo(props => { + return {props.children}; + }); + + Root.displayName = `${Namespace}.Root`; + + /** + * Component: + * ----------------------------------- + */ + + export type TriggerProps = AxoBaseMenu.MenuTriggerProps; + + export const Trigger: FC = memo(props => { + return {props.children}; + }); + + Trigger.displayName = `${Namespace}.Trigger`; + + /** + * Component: + * ----------------------------------- + */ + + export type ContentProps = AxoBaseMenu.MenuContentProps; + + /** + * The component that pops out in an open context menu. + * Uses a portal to render the content part into the `body`. + */ + export const Content: FC = memo(props => { + return ( + + + {props.children} + + + ); + }); + + Content.displayName = `${Namespace}.Content`; + + /** + * Component: + * -------------------------------- + */ + + export type ItemProps = AxoBaseMenu.MenuItemProps; + + /** + * The component that contains the context menu items. + * @example + * ```tsx + * }> + * {i18n("myContextMenuText")} + * + * ```` + */ + export const Item: FC = memo(props => { + return ( + + {props.symbol && ( + + + + )} + + {props.children} + {props.keyboardShortcut && ( + + )} + + + ); + }); + + Item.displayName = `${Namespace}.Item`; + + /** + * Component: + * --------------------------------- + */ + + export type GroupProps = AxoBaseMenu.MenuGroupProps; + + /** + * Used to group multiple {@link AxoContextMenu.Item}'s. + */ + export const Group: FC = memo(props => { + return ( + + {props.children} + + ); + }); + + Group.displayName = `${Namespace}.Group`; + + /** + * Component: + * --------------------------------- + */ + + export type LabelProps = AxoBaseMenu.MenuLabelProps; + + /** + * Used to render a label. It won't be focusable using arrow keys. + */ + export const Label: FC = memo(props => { + return ( + + + {props.children} + + + ); + }); + + Label.displayName = `${Namespace}.Label`; + + /** + * Component: + * ---------------------------------------- + */ + + export type CheckboxItemProps = AxoBaseMenu.MenuCheckboxItemProps; + + /** + * An item that can be controlled and rendered like a checkbox. + */ + export const CheckboxItem: FC = memo(props => { + return ( + + + + + + + + + + {props.symbol && ( + + + + )} + {props.children} + {props.keyboardShortcut && ( + + )} + + + ); + }); + + CheckboxItem.displayName = `${Namespace}.CheckboxItem`; + + /** + * Component: + * -------------------------------------- + */ + + export type RadioGroupProps = AxoBaseMenu.MenuRadioGroupProps; + + /** + * Used to group multiple {@link AxoContextMenu.RadioItem}'s. + */ + export const RadioGroup: FC = memo(props => { + return ( + + {props.children} + + ); + }); + + RadioGroup.displayName = `${Namespace}.RadioGroup`; + + /** + * Component: + * ------------------------------------- + */ + + export type RadioItemProps = AxoBaseMenu.MenuRadioItemProps; + + /** + * An item that can be controlled and rendered like a radio. + */ + export const RadioItem: FC = memo(props => { + return ( + + + + + + + + + + {props.symbol && } + {props.children} + {props.keyboardShortcut && ( + + )} + + + ); + }); + + RadioItem.displayName = `${Namespace}.RadioItem`; + + /** + * Component: + * ------------------------------------- + */ + + export type SeparatorProps = AxoBaseMenu.MenuSeparatorProps; + + /** + * Used to visually separate items in the context menu. + */ + export const Separator: FC = memo(() => { + return ( + + ); + }); + + Separator.displayName = `${Namespace}.Separator`; + + /** + * Component: + * ------------------------------- + */ + + export type SubProps = AxoBaseMenu.MenuSubProps; + + /** + * Contains all the parts of a submenu. + */ + export const Sub: FC = memo(props => { + return {props.children}; + }); + + Sub.displayName = `${Namespace}.Sub`; + + /** + * Component: + * -------------------------------------- + */ + + export type SubTriggerProps = AxoBaseMenu.MenuSubTriggerProps; + + /** + * An item that opens a submenu. Must be rendered inside + * {@link ContextMenu.Sub}. + */ + export const SubTrigger: FC = memo(props => { + return ( + + {props.symbol && ( + + + + )} + + {props.children} + + + + + + ); + }); + + SubTrigger.displayName = `${Namespace}.SubTrigger`; + + /** + * Component: + * -------------------------------------- + */ + + export type SubContentProps = AxoBaseMenu.MenuSubContentProps; + + /** + * The component that pops out when a submenu is open. Must be rendered + * inside {@link AxoContextMenu.Sub}. + */ + export const SubContent: FC = memo(props => { + return ( + + {props.children} + + ); + }); + + SubContent.displayName = `${Namespace}.SubContent`; +} diff --git a/ts/axo/AxoDropdownMenu.stories.tsx b/ts/axo/AxoDropdownMenu.stories.tsx new file mode 100644 index 00000000000..d28e6c6aaaa --- /dev/null +++ b/ts/axo/AxoDropdownMenu.stories.tsx @@ -0,0 +1,100 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +import React, { useState } from 'react'; +import type { Meta } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import { AxoDropdownMenu } from './AxoDropdownMenu'; +import { AxoButton } from './AxoButton'; + +export default { + title: 'Axo/AxoDropdownMenu', +} satisfies Meta; + +export function Basic(): JSX.Element { + const [showBookmarks, setShowBookmarks] = useState(true); + const [showFullUrls, setShowFullUrls] = useState(false); + const [selectedPerson, setSelectedPerson] = useState('jamie'); + return ( +
+ + + + Open Dropdown Menu + + + + + Back + + + Forward + + + Reload + + + More Tools + + + Save Page As... + + + Create Shortcut... + + + Name Window... + + + + Developer Tools + + + + + + Show Bookmarks + + + Show Full URLs + + + People + + + Jamie + + + Tyler + + + + +
+ ); +} diff --git a/ts/axo/AxoDropdownMenu.tsx b/ts/axo/AxoDropdownMenu.tsx new file mode 100644 index 00000000000..4917832e5ca --- /dev/null +++ b/ts/axo/AxoDropdownMenu.tsx @@ -0,0 +1,402 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +import React, { memo } from 'react'; +import { DropdownMenu } from 'radix-ui'; +import type { FC } from 'react'; +import { AxoSymbol } from './AxoSymbol'; +import { AxoBaseMenu } from './_internal/AxoBaseMenu'; + +const Namespace = 'AxoDropdownMenu'; + +/** + * Displays a menu to the user—such as a set of actions or functions—triggered + * by a button. + * + * Note: For menus that are triggered by a right-click, you should use + * `AxoContextMenu`. + * + * @example Anatomy + * ```tsx + * import { AxoDropdownMenu } from "./axo/DropdownMenu/AxoDropdownMenu.tsx"; + * + * export default () => ( + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * ) + * ``` + */ +// eslint-disable-next-line @typescript-eslint/no-namespace +export namespace AxoDropdownMenu { + /** + * Component: + * --------------------------------- + */ + + export type RootProps = AxoBaseMenu.MenuRootProps; + + /** + * Contains all the parts of a dropdown menu. + */ + export const Root: FC = memo(props => { + return {props.children}; + }); + + Root.displayName = `${Namespace}.Root`; + + /** + * Component: + * ------------------------------------ + */ + + export type TriggerProps = AxoBaseMenu.MenuTriggerProps; + + /** + * The button that toggles the dropdown menu. + * By default, the {@link AxoDropdownMenu.Content} will position itself + * against the trigger. + */ + export const Trigger: FC = memo(props => { + return ( + {props.children} + ); + }); + + Trigger.displayName = `${Namespace}.Trigger`; + + /** + * Component: + * ------------------------------------ + */ + + export type ContentProps = AxoBaseMenu.MenuContentProps; + + /** + * The component that pops out when the dropdown menu is open. + * Uses a portal to render the content part into the `body`. + */ + export const Content: FC = memo(props => { + return ( + + + {props.children} + + + ); + }); + + Content.displayName = `${Namespace}.Content`; + + /** + * Component: + * --------------------------------- + */ + + export type ItemProps = AxoBaseMenu.MenuItemProps; + + /** + * The component that contains the dropdown menu items. + * @example + * ```tsx + * }> + * {i18n("myContextMenuText")} + * + * ```` + */ + export const Item: FC = memo(props => { + return ( + + {props.symbol && ( + + + + )} + + {props.children} + {props.keyboardShortcut && ( + + )} + + + ); + }); + + Item.displayName = `${Namespace}.Item`; + + /** + * Component: + * ---------------------------------- + */ + + export type GroupProps = AxoBaseMenu.MenuGroupProps; + + /** + * Used to group multiple {@link AxoDropdownMenu.Item}'s. + */ + export const Group: FC = memo(props => { + return ( + + {props.children} + + ); + }); + + Group.displayName = `${Namespace}.Group`; + + /** + * Component: + * ---------------------------------- + */ + + export type LabelProps = AxoBaseMenu.MenuLabelProps; + + /** + * Used to render a label. It won't be focusable using arrow keys. + */ + export const Label: FC = memo(props => { + return ( + + + {props.children} + + + ); + }); + + Label.displayName = `${Namespace}.Label`; + + /** + * Component: + * ----------------------------------------- + */ + + export type CheckboxItemProps = AxoBaseMenu.MenuCheckboxItemProps; + + /** + * An item that can be controlled and rendered like a checkbox. + */ + export const CheckboxItem: FC = memo(props => { + return ( + + + + + + + + + + {props.symbol && ( + + + + )} + {props.children} + {props.keyboardShortcut && ( + + )} + + + ); + }); + + CheckboxItem.displayName = `${Namespace}.CheckboxItem`; + + /** + * Component: + * --------------------------------------- + */ + + export type RadioGroupProps = AxoBaseMenu.MenuRadioGroupProps; + + /** + * Used to group multiple {@link AxoDropdownMenu.RadioItem}'s. + */ + export const RadioGroup: FC = memo(props => { + return ( + + {props.children} + + ); + }); + + RadioGroup.displayName = `${Namespace}.RadioGroup`; + + /** + * Component: + * -------------------------------------- + */ + + export type RadioItemProps = AxoBaseMenu.MenuRadioItemProps; + + /** + * An item that can be controlled and rendered like a radio. + */ + export const RadioItem: FC = memo(props => { + return ( + + + + + + + + + + {props.symbol && } + {props.children} + {props.keyboardShortcut && ( + + )} + + + ); + }); + + RadioItem.displayName = `${Namespace}.RadioItem`; + + /** + * Component: + * -------------------------------------- + */ + + export type SeparatorProps = AxoBaseMenu.MenuSeparatorProps; + + /** + * Used to visually separate items in the dropdown menu. + */ + export const Separator: FC = memo(() => { + return ( + + ); + }); + + Separator.displayName = `${Namespace}.Separator`; + + /** + * Component: + * ------------------------------- + */ + + export type SubProps = AxoBaseMenu.MenuSubProps; + + /** + * Contains all the parts of a submenu. + */ + export const Sub: FC = memo(props => { + return {props.children}; + }); + + Sub.displayName = `${Namespace}.Sub`; + + /** + * Component: + * --------------------------------------- + */ + + export type SubTriggerProps = AxoBaseMenu.MenuSubTriggerProps; + + /** + * An item that opens a submenu. Must be rendered inside + * {@link ContextMenu.Sub}. + */ + export const SubTrigger: FC = memo(props => { + return ( + + {props.symbol && ( + + + + )} + + {props.children} + + + + + + ); + }); + + SubTrigger.displayName = `${Namespace}.SubTrigger`; + + /** + * Component: + * --------------------------------------- + */ + + export type SubContentProps = AxoBaseMenu.MenuSubContentProps; + + /** + * The component that pops out when a submenu is open. Must be rendered + * inside {@link AxoDropdownMenu.Sub}. + */ + export const SubContent: FC = memo(props => { + return ( + + {props.children} + + ); + }); + + SubContent.displayName = `${Namespace}.SubContent`; +} diff --git a/ts/axo/AxoSelect.stories.tsx b/ts/axo/AxoSelect.stories.tsx new file mode 100644 index 00000000000..c85d21eecac --- /dev/null +++ b/ts/axo/AxoSelect.stories.tsx @@ -0,0 +1,90 @@ +// Copyright 2025 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +import React, { useState } from 'react'; +import type { Meta } from '@storybook/react'; +import { AxoSelect } from './AxoSelect'; + +export default { + title: 'Axo/AxoSelect', +} satisfies Meta; + +function Template(props: { + disabled?: boolean; + triggerWidth?: AxoSelect.TriggerWidth; + triggerVariant: AxoSelect.TriggerVariant; +}) { + const [value, setValue] = useState(null); + return ( + + + + + Fruits + Apple + Banana + Blueberry + Grapes + Pineapple + + + + Vegetables + Aubergine + Broccoli + + Carrot + + Leek + + + + Meat + Beef + Chicken + Lamb + Pork + + + + ); +} + +export function Basic(): JSX.Element { + return ( +
+
+