Merge pull request #1519 from useautumn/charlie/base-ui
chore: migrate shadcn from Radix UI to Base UI
This commit is contained in:
2
ai
2
ai
Submodule ai updated: eb7800f5f7...4bfb2b6ace
152
bun.lock
152
bun.lock
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "autumn",
|
||||
@@ -481,26 +482,12 @@
|
||||
"dependencies": {
|
||||
"@ai-sdk/react": "^3.0.25",
|
||||
"@autumn/shared": "workspace:*",
|
||||
"@base-ui/react": "^1.4.1",
|
||||
"@better-auth/dash": "catalog:",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.7.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-checkbox": "^1.1.4",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-hover-card": "^1.1.15",
|
||||
"@radix-ui/react-label": "^2.1.8",
|
||||
"@radix-ui/react-popover": "^1.1.14",
|
||||
"@radix-ui/react-radio-group": "^1.3.8",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.8",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-switch": "^1.2.5",
|
||||
"@radix-ui/react-tabs": "^1.1.3",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@sentry/react": "^10.25.0",
|
||||
"@sentry/vite-plugin": "^4.6.0",
|
||||
"@squircle/core": "^1.0.6",
|
||||
@@ -536,6 +523,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-grab": "^0.1.29",
|
||||
"react-hotkeys-hook": "^4.6.1",
|
||||
"react-router": "^7.3.0",
|
||||
"react-router-dom": "^7.6.2",
|
||||
@@ -1679,7 +1667,7 @@
|
||||
|
||||
"@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
|
||||
|
||||
"@radix-ui/react-label": ["@radix-ui/react-label@2.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A=="],
|
||||
"@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="],
|
||||
|
||||
"@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="],
|
||||
|
||||
@@ -1699,7 +1687,7 @@
|
||||
|
||||
"@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="],
|
||||
|
||||
"@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
"@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
|
||||
|
||||
"@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.7", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg=="],
|
||||
|
||||
@@ -1711,11 +1699,11 @@
|
||||
|
||||
"@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="],
|
||||
|
||||
"@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g=="],
|
||||
"@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="],
|
||||
|
||||
"@radix-ui/react-slider": ["@radix-ui/react-slider@1.3.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw=="],
|
||||
|
||||
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="],
|
||||
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
|
||||
"@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="],
|
||||
|
||||
@@ -1795,6 +1783,8 @@
|
||||
|
||||
"@react-email/text": ["@react-email/text@0.1.5", "", { "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-o5PNHFSE085VMXayxH+SJ1LSOtGsTv+RpNKnTiJDrJUwoBu77G3PlKOsZZQHCNyD28WsQpl9v2WcJLbQudqwPg=="],
|
||||
|
||||
"@react-grab/cli": ["@react-grab/cli@0.1.33", "", { "dependencies": { "@antfu/ni": "^30.1.0", "commander": "^14.0.3", "ignore": "^7.0.5", "jsonc-parser": "^3.3.1", "ora": "^9.4.0", "picocolors": "^1.1.1", "prompts": "^2.4.2", "smol-toml": "^1.6.1" }, "bin": { "react-grab": "bin/cli.js" } }, "sha512-UOc3PwN11Osw0NzaxRLK8trP4X+5iW1Dst3gvHRCafe3wXHyadzHYH8H1hdkcXdlIx3gsoD9ASJ+G/JH+A/jqA=="],
|
||||
|
||||
"@reduxjs/toolkit": ["@reduxjs/toolkit@2.11.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@standard-schema/utils": "^0.3.0", "immer": "^11.0.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "reselect": "^5.1.0" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" }, "optionalPeers": ["react", "react-redux"] }, "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ=="],
|
||||
|
||||
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
|
||||
@@ -2759,6 +2749,8 @@
|
||||
|
||||
"bintrees": ["bintrees@1.0.2", "", {}, "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw=="],
|
||||
|
||||
"bippy": ["bippy@0.5.39", "", { "peerDependencies": { "react": ">=17.0.1" } }, "sha512-8hE8rKSl8JWyeaY+JjpnmceWAZPpLEyzOZQpWXM5Rc7861c5WotMJHy2aRZKZrGA8nMpvLNF01t4yQQ+HcZG3w=="],
|
||||
|
||||
"bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
|
||||
|
||||
"blueimp-md5": ["blueimp-md5@2.19.0", "", {}, "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="],
|
||||
@@ -4055,7 +4047,7 @@
|
||||
|
||||
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
|
||||
|
||||
"jsonc-parser": ["jsonc-parser@2.2.1", "", {}, "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="],
|
||||
"jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="],
|
||||
|
||||
"jsonc-simple-parser": ["jsonc-simple-parser@3.0.0", "", { "dependencies": { "reghex": "^3.0.2" } }, "sha512-0qi9Kuj4JPar4/3b9wZteuPZrTeFzXsQyOZj7hksnReCZN3Vr17Doz7w/i3E9XH7vRkVTHhHES+r1h97I+hfww=="],
|
||||
|
||||
@@ -4861,6 +4853,8 @@
|
||||
|
||||
"react-email": ["react-email@4.0.16", "", { "dependencies": { "@babel/parser": "^7.27.0", "@babel/traverse": "^7.27.0", "chalk": "^5.0.0", "chokidar": "^4.0.3", "commander": "^13.0.0", "debounce": "^2.0.0", "esbuild": "^0.25.0", "glob": "^11.0.0", "log-symbols": "^7.0.0", "mime-types": "^3.0.0", "next": "^15.3.1", "normalize-path": "^3.0.0", "ora": "^8.0.0", "socket.io": "^4.8.1" }, "bin": { "email": "dist/cli/index.mjs" } }, "sha512-auhFU+nQxAkKkP6lQhPyGsa9exwfUEzp2BwZnjHokCwphZlg30tu4t1LgdKRwGPYsi7XNGy6asbVLAUhOVpzzg=="],
|
||||
|
||||
"react-grab": ["react-grab@0.1.33", "", { "dependencies": { "@react-grab/cli": "0.1.33", "bippy": "^0.5.39" }, "peerDependencies": { "react": ">=17.0.0" }, "optionalPeers": ["react"], "bin": { "react-grab": "bin/cli.js" } }, "sha512-ER919JMsE4TTrb2CpEivqsIjNMSycD4HtS8v7mS3pq67U7WL1K3+C8m9AYOwW4dpuYh+EanC2eJBmfuczHJZ0A=="],
|
||||
|
||||
"react-hotkeys-hook": ["react-hotkeys-hook@4.6.2", "", { "peerDependencies": { "react": ">=16.8.1", "react-dom": ">=16.8.1" } }, "sha512-FmP+ZriY3EG59Ug/lxNfrObCnW9xQShgk7Nb83+CkpfkcCpfS95ydv+E9JuXA5cp8KtskU7LGlIARpkc92X22Q=="],
|
||||
|
||||
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||
@@ -6341,29 +6335,91 @@
|
||||
|
||||
"@prisma/instrumentation/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA=="],
|
||||
|
||||
"@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"@radix-ui/react-accordion/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"@radix-ui/react-alert-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"@radix-ui/react-arrow/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-form/@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="],
|
||||
"@radix-ui/react-aspect-ratio/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-label/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
|
||||
"@radix-ui/react-avatar/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-menu/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"@radix-ui/react-checkbox/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-popover/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"@radix-ui/react-collapsible/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"@radix-ui/react-collection/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-select/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"@radix-ui/react-context-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-separator/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
|
||||
"@radix-ui/react-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-toolbar/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="],
|
||||
"@radix-ui/react-dismissable-layer/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-tooltip/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"@radix-ui/react-dropdown-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-focus-scope/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-form/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-hover-card/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-label/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-menubar/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-navigation-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-one-time-password-field/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-password-toggle-field/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-popover/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-popper/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-portal/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="],
|
||||
|
||||
"@radix-ui/react-progress/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-radio-group/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-roving-focus/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-scroll-area/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-select/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-separator/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-slider/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-switch/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-tabs/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-toast/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-toggle/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-toggle-group/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-toolbar/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-tooltip/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"@react-grab/cli/@antfu/ni": ["@antfu/ni@30.1.0", "", { "dependencies": { "fzf": "^0.5.2", "package-manager-detector": "^1.6.0", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15" }, "bin": { "ni": "bin/ni.mjs", "nci": "bin/nci.mjs", "nr": "bin/nr.mjs", "nup": "bin/nup.mjs", "nd": "bin/nd.mjs", "nlx": "bin/nlx.mjs", "na": "bin/na.mjs", "nun": "bin/nun.mjs" } }, "sha512-3VuAbPjgY52rQNn4wABaXMhBU2Oq91uy6L8nX49eJ35OLI68CyckGU+HZxcaHix4ymuGM2nFL1D6sLpgODK5xw=="],
|
||||
|
||||
"@react-grab/cli/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||
|
||||
"@react-grab/cli/ora": ["ora@9.4.0", "", { "dependencies": { "chalk": "^5.6.2", "cli-cursor": "^5.0.0", "cli-spinners": "^3.2.0", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.1.0", "log-symbols": "^7.0.1", "stdin-discarder": "^0.3.2", "string-width": "^8.1.0" } }, "sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ=="],
|
||||
|
||||
"@reduxjs/toolkit/immer": ["immer@11.1.4", "", {}, "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw=="],
|
||||
|
||||
@@ -6407,6 +6463,8 @@
|
||||
|
||||
"@stoplight/better-ajv-errors/leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
|
||||
|
||||
"@stoplight/json/jsonc-parser": ["jsonc-parser@2.2.1", "", {}, "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="],
|
||||
|
||||
"@stoplight/json/safe-stable-stringify": ["safe-stable-stringify@1.1.1", "", {}, "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw=="],
|
||||
|
||||
"@stoplight/json-ref-readers/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="],
|
||||
@@ -6669,8 +6727,6 @@
|
||||
|
||||
"clone-response/mimic-response": ["mimic-response@1.0.1", "", {}, "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="],
|
||||
|
||||
"cmdk/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
|
||||
|
||||
"concurrently/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"conf/ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="],
|
||||
@@ -7037,11 +7093,7 @@
|
||||
|
||||
"puppeteer/puppeteer-core": ["puppeteer-core@22.14.0", "", { "dependencies": { "@puppeteer/browsers": "2.3.0", "chromium-bidi": "0.6.2", "debug": "^4.3.5", "devtools-protocol": "0.0.1312386", "ws": "^8.18.0" } }, "sha512-rl4tOY5LcA3e374GAlsGGHc05HL3eGNf5rZ+uxkl6id9zVZKcwcp1Z+Nd6byb6WPiPeecT/dwz8f/iUm+AZQSw=="],
|
||||
|
||||
"radix-ui/@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="],
|
||||
|
||||
"radix-ui/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="],
|
||||
|
||||
"radix-ui/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
"radix-ui/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
|
||||
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
||||
|
||||
@@ -7965,6 +8017,22 @@
|
||||
|
||||
"@prisma/instrumentation/@opentelemetry/instrumentation/require-in-the-middle": ["require-in-the-middle@8.0.1", "", { "dependencies": { "debug": "^4.3.5", "module-details-from-path": "^1.0.3" } }, "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ=="],
|
||||
|
||||
"@react-grab/cli/@antfu/ni/tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="],
|
||||
|
||||
"@react-grab/cli/ora/cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
|
||||
|
||||
"@react-grab/cli/ora/cli-spinners": ["cli-spinners@3.4.0", "", {}, "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw=="],
|
||||
|
||||
"@react-grab/cli/ora/is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
|
||||
|
||||
"@react-grab/cli/ora/is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
|
||||
|
||||
"@react-grab/cli/ora/log-symbols": ["log-symbols@7.0.1", "", { "dependencies": { "is-unicode-supported": "^2.0.0", "yoctocolors": "^2.1.1" } }, "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg=="],
|
||||
|
||||
"@react-grab/cli/ora/stdin-discarder": ["stdin-discarder@0.3.2", "", {}, "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A=="],
|
||||
|
||||
"@react-grab/cli/ora/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="],
|
||||
|
||||
"@sentry/cli/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
||||
|
||||
"@sentry/node-core/import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@2.2.0", "", {}, "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ=="],
|
||||
@@ -9157,6 +9225,8 @@
|
||||
|
||||
"@prisma/instrumentation/@opentelemetry/instrumentation/import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@2.2.0", "", {}, "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ=="],
|
||||
|
||||
"@react-grab/cli/ora/cli-cursor/restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
|
||||
|
||||
"@tailwindcss/postcss/@tailwindcss/node/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
||||
|
||||
"@tailwindcss/postcss/@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
|
||||
@@ -9585,6 +9655,10 @@
|
||||
|
||||
"@mintlify/scraping/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
"@react-grab/cli/ora/cli-cursor/restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
|
||||
|
||||
"@react-grab/cli/ora/cli-cursor/restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
||||
|
||||
"artillery-plugin-ensure/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
||||
|
||||
"artillery-plugin-publish-metrics/@opentelemetry/exporter-metrics-otlp-grpc/@opentelemetry/otlp-transformer/protobufjs/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"server": {
|
||||
"entry": [
|
||||
"src/internal/customers/cusUtils/createNewCustomer.ts",
|
||||
"src/internal/rewards/RewardRedemptionService.ts",
|
||||
"src/utils/importUtils/addProductFromSubs.ts",
|
||||
"src/utils/scriptUtils/readOnlyStripe.ts",
|
||||
"src/utils/scriptUtils/scriptUtils.ts",
|
||||
@@ -43,7 +44,7 @@
|
||||
"vite": {
|
||||
"entry": ["tests/**/*.{ts,tsx}"],
|
||||
"project": ["src/**/*.{ts,tsx}", "tests/**/*.{ts,tsx}"],
|
||||
"ignore": ["src/components/ai-elements/**"],
|
||||
"ignore": ["src/components/ai-elements/**", "src/hooks/useControllableState.ts"],
|
||||
"ignoreDependencies": [
|
||||
"tailwindcss",
|
||||
"tailwind-scrollbar-hide",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"style": "base-nova",
|
||||
"rsc": false,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
|
||||
@@ -21,26 +21,12 @@
|
||||
"dependencies": {
|
||||
"@ai-sdk/react": "^3.0.25",
|
||||
"@autumn/shared": "workspace:*",
|
||||
"@base-ui/react": "^1.4.1",
|
||||
"@better-auth/dash": "catalog:",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.7.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-checkbox": "^1.1.4",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-hover-card": "^1.1.15",
|
||||
"@radix-ui/react-label": "^2.1.8",
|
||||
"@radix-ui/react-popover": "^1.1.14",
|
||||
"@radix-ui/react-radio-group": "^1.3.8",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.8",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-switch": "^1.2.5",
|
||||
"@radix-ui/react-tabs": "^1.1.3",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@sentry/react": "^10.25.0",
|
||||
"@sentry/vite-plugin": "^4.6.0",
|
||||
"@squircle/core": "^1.0.6",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
||||
import { useControllableState } from "@/hooks/useControllableState";
|
||||
import {
|
||||
BrainIcon,
|
||||
ChevronDownIcon,
|
||||
@@ -58,7 +58,7 @@ export const ChainOfThought = memo(
|
||||
});
|
||||
|
||||
const chainOfThoughtContext = useMemo(
|
||||
() => ({ isOpen, setIsOpen }),
|
||||
() => ({ isOpen: isOpen ?? false, setIsOpen }),
|
||||
[isOpen, setIsOpen],
|
||||
);
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ export const InlineCitationCardTrigger = ({
|
||||
</HoverCardTrigger>
|
||||
);
|
||||
|
||||
export type InlineCitationCardBodyProps = ComponentProps<"div">;
|
||||
export type InlineCitationCardBodyProps = ComponentProps<typeof HoverCardContent>;
|
||||
|
||||
export const InlineCitationCardBody = ({
|
||||
className,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
||||
import { useControllableState } from "@/hooks/useControllableState";
|
||||
import { BrainIcon, ChevronDownIcon } from "lucide-react";
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
import { createContext, memo, useContext, useEffect, useState } from "react";
|
||||
|
||||
@@ -99,7 +99,7 @@ export function AttachFooter() {
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
{!invoiceDisabledReason && (
|
||||
<PopoverContent className="w-(--radix-popover-trigger-width) p-0">
|
||||
<PopoverContent className="w-(--anchor-width) p-0">
|
||||
<div className="flex flex-col">
|
||||
<button
|
||||
type="button"
|
||||
@@ -144,7 +144,7 @@ export function AttachFooter() {
|
||||
{invoiceDisabledReason && (
|
||||
<TooltipContent
|
||||
side="top"
|
||||
className="max-w-(--radix-tooltip-trigger-width)"
|
||||
className="max-w-(--anchor-width)"
|
||||
>
|
||||
{invoiceDisabledReason}
|
||||
</TooltipContent>
|
||||
|
||||
@@ -99,7 +99,7 @@ export function AttachFooterV3() {
|
||||
{invoiceDisabledReason && (
|
||||
<TooltipContent
|
||||
side="top"
|
||||
className="max-w-(--radix-tooltip-trigger-width)"
|
||||
className="max-w-(--anchor-width)"
|
||||
>
|
||||
{invoiceDisabledReason}
|
||||
</TooltipContent>
|
||||
|
||||
@@ -202,7 +202,7 @@ export function CreateScheduleReviewContent() {
|
||||
{invoiceDisabledReason && (
|
||||
<TooltipContent
|
||||
side="top"
|
||||
className="max-w-(--radix-tooltip-trigger-width)"
|
||||
className="max-w-(--anchor-width)"
|
||||
>
|
||||
{invoiceDisabledReason}
|
||||
</TooltipContent>
|
||||
|
||||
@@ -62,14 +62,15 @@ export function PlanSectionTitle({
|
||||
<span className="flex items-center gap-2">
|
||||
{trialAction}
|
||||
{showVersionSelector && (
|
||||
<Select
|
||||
value={
|
||||
selectedVersion !== undefined
|
||||
? String(selectedVersion)
|
||||
: undefined
|
||||
}
|
||||
onValueChange={(value) => onVersionChange?.(Number(value))}
|
||||
>
|
||||
<Select
|
||||
value={
|
||||
selectedVersion !== undefined
|
||||
? String(selectedVersion)
|
||||
: undefined
|
||||
}
|
||||
onValueChange={(value) => onVersionChange?.(Number(value))}
|
||||
items={Object.fromEntries(versionOptions.map((option) => [option.value, option.label]))}
|
||||
>
|
||||
<SelectTrigger className="w-fit h-7 text-xs whitespace-nowrap">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -18,19 +18,17 @@ export function CollapsedBooleanItems({
|
||||
items,
|
||||
renderItem,
|
||||
}: CollapsedBooleanItemsProps) {
|
||||
const [value, setValue] = useState("");
|
||||
const [value, setValue] = useState<string[]>([]);
|
||||
|
||||
if (items.length === 0) return null;
|
||||
|
||||
const isExpanded = value === "boolean-flags";
|
||||
const isExpanded = value.includes("boolean-flags");
|
||||
const label = isExpanded
|
||||
? "Hide"
|
||||
: `${items.length} more`;
|
||||
|
||||
return (
|
||||
<Accordion
|
||||
type="single"
|
||||
collapsible
|
||||
value={value}
|
||||
onValueChange={setValue}
|
||||
className="w-full"
|
||||
|
||||
@@ -316,7 +316,7 @@ export function SubscriptionItemRow({
|
||||
<ConditionalTooltip
|
||||
enabled={!!prepaid.showTooltip}
|
||||
content={prepaidTooltipContent}
|
||||
contentClassName="max-w-(--radix-tooltip-trigger-width)"
|
||||
contentClassName="max-w-(--anchor-width)"
|
||||
>
|
||||
{rowContent}
|
||||
</ConditionalTooltip>
|
||||
|
||||
@@ -79,7 +79,7 @@ export function UpdateSubscriptionFooter() {
|
||||
{invoiceDisabledReason && (
|
||||
<TooltipContent
|
||||
side="top"
|
||||
className="max-w-(--radix-tooltip-trigger-width)"
|
||||
className="max-w-(--anchor-width)"
|
||||
>
|
||||
{invoiceDisabledReason}
|
||||
</TooltipContent>
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import { Check, Copy } from "lucide-react";
|
||||
import type React from "react";
|
||||
import { cloneElement, forwardRef, isValidElement, useState } from "react";
|
||||
import { forwardRef, useState } from "react";
|
||||
import { PreviewCard } from "@base-ui/react/preview-card";
|
||||
import { useAdmin } from "@/views/admin/hooks/useAdmin";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "../ui/tooltip";
|
||||
|
||||
export const AdminHover = forwardRef<
|
||||
HTMLElement,
|
||||
@@ -18,54 +13,50 @@ export const AdminHover = forwardRef<
|
||||
asChild?: boolean;
|
||||
side?: "top" | "bottom" | "left" | "right";
|
||||
}
|
||||
>(
|
||||
(
|
||||
{ children, texts, hide = false, asChild = false, side = "bottom" },
|
||||
ref,
|
||||
) => {
|
||||
const { isAdmin, skipHover } = useAdmin();
|
||||
>(({ children, texts, hide = false, side = "bottom" }, _ref) => {
|
||||
const { isAdmin, skipHover } = useAdmin();
|
||||
|
||||
if (!isAdmin || hide || skipHover) return <>{children}</>;
|
||||
if (!isAdmin || hide || skipHover) return <>{children}</>;
|
||||
|
||||
// Try to forward the ref to the child if possible
|
||||
let triggerChild = children;
|
||||
if (isValidElement(children)) {
|
||||
triggerChild = cloneElement(children as React.ReactElement, { ref });
|
||||
}
|
||||
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild={asChild}>{triggerChild}</TooltipTrigger>
|
||||
{isAdmin && (
|
||||
<TooltipContent
|
||||
className="bg-white/50 backdrop-blur-sm shadow-sm border px-2 pr-6 py-2 max-w-none z-[9999]"
|
||||
align="start"
|
||||
side={side}
|
||||
>
|
||||
<div className="text-xs text-gray-500 flex flex-col gap-2">
|
||||
{texts.map((text) => {
|
||||
if (!text) return null;
|
||||
if (typeof text === "object") {
|
||||
return (
|
||||
<div key={text.key}>
|
||||
<p className="text-xs text-gray-500 font-medium">
|
||||
{text.key}
|
||||
</p>
|
||||
<CopyText text={text.value} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <CopyText key={text} text={text} />;
|
||||
})}
|
||||
</div>
|
||||
</TooltipContent>
|
||||
)}
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<PreviewCard.Root>
|
||||
<PreviewCard.Trigger
|
||||
render={<div className="inline-flex" />}
|
||||
delay={0}
|
||||
>
|
||||
{children}
|
||||
</PreviewCard.Trigger>
|
||||
<PreviewCard.Portal>
|
||||
<PreviewCard.Positioner
|
||||
side={side}
|
||||
sideOffset={4}
|
||||
align="start"
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[9999]"
|
||||
>
|
||||
<PreviewCard.Popup className="bg-white/50 dark:bg-zinc-900/50 backdrop-blur-sm shadow-sm border rounded-md px-2 pr-6 py-2 max-w-none origin-(--transform-origin) transition-[opacity,scale] duration-150 data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95">
|
||||
<div className="text-xs text-gray-500 dark:text-gray-400 flex flex-col gap-2 whitespace-nowrap">
|
||||
{texts.map((text) => {
|
||||
if (!text) return null;
|
||||
if (typeof text === "object") {
|
||||
return (
|
||||
<div key={text.key}>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 font-medium">
|
||||
{text.key}
|
||||
</p>
|
||||
<CopyText text={text.value} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <CopyText key={text} text={text} />;
|
||||
})}
|
||||
</div>
|
||||
</PreviewCard.Popup>
|
||||
</PreviewCard.Positioner>
|
||||
</PreviewCard.Portal>
|
||||
</PreviewCard.Root>
|
||||
);
|
||||
});
|
||||
|
||||
const CopyText = ({ text }: { text: string }) => {
|
||||
const [isHover, setIsHover] = useState(false);
|
||||
@@ -76,7 +67,7 @@ const CopyText = ({ text }: { text: string }) => {
|
||||
<p
|
||||
onMouseEnter={() => setIsHover(true)}
|
||||
onMouseLeave={() => setIsHover(false)}
|
||||
className="flex flex-col items-start gap-1 font-mono hover:underline"
|
||||
className="flex flex-col items-start gap-1 font-mono hover:underline cursor-pointer"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { InfoIcon } from "@phosphor-icons/react";
|
||||
import type { TooltipContentProps } from "@radix-ui/react-tooltip";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
@@ -13,7 +12,10 @@ export const InfoTooltip = ({
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
} & TooltipContentProps) => {
|
||||
side?: "top" | "bottom" | "left" | "right";
|
||||
align?: "start" | "center" | "end";
|
||||
sideOffset?: number;
|
||||
}) => {
|
||||
return (
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
|
||||
@@ -29,11 +29,9 @@ function ColumnCheckboxItem<T>({ column }: { column: Column<T> }) {
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={column.id}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onClick={() => {
|
||||
column.toggleVisibility(!isVisible);
|
||||
}}
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
className="flex items-center gap-2 cursor-pointer text-sm"
|
||||
>
|
||||
<Checkbox checked={isVisible} className="border-border" />
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
||||
import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
|
||||
import { ChevronDownIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type AccordionProps = AccordionPrimitive.Root.Props & {
|
||||
type?: "single" | "multiple";
|
||||
collapsible?: boolean;
|
||||
};
|
||||
|
||||
function Accordion({
|
||||
type,
|
||||
collapsible,
|
||||
...props
|
||||
}: React.ComponentProps<typeof AccordionPrimitive.Root>) {
|
||||
return <AccordionPrimitive.Root data-slot="accordion" {...props} />;
|
||||
}: AccordionProps) {
|
||||
return (
|
||||
<AccordionPrimitive.Root
|
||||
data-slot="accordion"
|
||||
multiple={type === "multiple"}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function AccordionItem({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof AccordionPrimitive.Item>) {
|
||||
}: AccordionPrimitive.Item.Props) {
|
||||
return (
|
||||
<AccordionPrimitive.Item
|
||||
data-slot="accordion-item"
|
||||
@@ -27,13 +40,13 @@ function AccordionTrigger({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
|
||||
}: AccordionPrimitive.Trigger.Props) {
|
||||
return (
|
||||
<AccordionPrimitive.Header className="flex">
|
||||
<AccordionPrimitive.Trigger
|
||||
data-slot="accordion-trigger"
|
||||
className={cn(
|
||||
"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
|
||||
"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[aria-expanded=true]>svg]:rotate-180",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -49,15 +62,15 @@ function AccordionContent({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof AccordionPrimitive.Content>) {
|
||||
}: AccordionPrimitive.Panel.Props) {
|
||||
return (
|
||||
<AccordionPrimitive.Content
|
||||
<AccordionPrimitive.Panel
|
||||
data-slot="accordion-content"
|
||||
className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
|
||||
className="data-closed:animate-accordion-up data-open:animate-accordion-down overflow-hidden text-sm"
|
||||
{...props}
|
||||
>
|
||||
<div className={cn("pt-0 pb-4", className)}>{children}</div>
|
||||
</AccordionPrimitive.Content>
|
||||
</AccordionPrimitive.Panel>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { mergeProps } from "@base-ui/react/merge-props";
|
||||
import { useRender } from "@base-ui/react/use-render";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import type * as React from "react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -36,18 +37,28 @@ function Badge({
|
||||
className,
|
||||
variant,
|
||||
asChild = false,
|
||||
render: renderProp,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<"span"> &
|
||||
}: useRender.ComponentProps<"span"> &
|
||||
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
|
||||
const Comp = asChild ? Slot : "span";
|
||||
const effectiveRender =
|
||||
asChild && React.isValidElement(children) ? children : renderProp;
|
||||
|
||||
return (
|
||||
<Comp
|
||||
data-slot="badge"
|
||||
className={cn(badgeVariants({ variant }), className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
return useRender({
|
||||
defaultTagName: "span",
|
||||
props: mergeProps<"span">(
|
||||
{
|
||||
className: cn(badgeVariants({ variant }), className),
|
||||
},
|
||||
{ ...props, children: effectiveRender ? undefined : children },
|
||||
),
|
||||
render: effectiveRender,
|
||||
state: {
|
||||
slot: "badge",
|
||||
variant,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export { Badge };
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { mergeProps } from "@base-ui/react/merge-props";
|
||||
import { useRender } from "@base-ui/react/use-render";
|
||||
import { ChevronRight, MoreHorizontal } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -34,19 +35,28 @@ function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
|
||||
function BreadcrumbLink({
|
||||
asChild,
|
||||
className,
|
||||
render: renderProp,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<"a"> & {
|
||||
}: useRender.ComponentProps<"a"> & {
|
||||
asChild?: boolean;
|
||||
}) {
|
||||
const Comp = asChild ? Slot : "a";
|
||||
const effectiveRender =
|
||||
asChild && React.isValidElement(children) ? children : renderProp;
|
||||
|
||||
return (
|
||||
<Comp
|
||||
data-slot="breadcrumb-link"
|
||||
className={cn("hover:text-foreground transition-colors", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
return useRender({
|
||||
defaultTagName: "a",
|
||||
props: mergeProps<"a">(
|
||||
{
|
||||
className: cn("hover:text-foreground transition-colors", className),
|
||||
},
|
||||
{ ...props, children: effectiveRender ? undefined : children },
|
||||
),
|
||||
render: effectiveRender,
|
||||
state: {
|
||||
slot: "breadcrumb-link",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { mergeProps } from "@base-ui/react/merge-props";
|
||||
import { useRender } from "@base-ui/react/use-render";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -39,21 +41,31 @@ function ButtonGroup({
|
||||
function ButtonGroupText({
|
||||
className,
|
||||
asChild = false,
|
||||
render: renderProp,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<"div"> & {
|
||||
}: useRender.ComponentProps<"div"> & {
|
||||
asChild?: boolean;
|
||||
}) {
|
||||
const Comp = asChild ? Slot : "div";
|
||||
const effectiveRender =
|
||||
asChild && React.isValidElement(children) ? children : renderProp;
|
||||
|
||||
return (
|
||||
<Comp
|
||||
className={cn(
|
||||
"bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
return useRender({
|
||||
defaultTagName: "div",
|
||||
props: mergeProps<"div">(
|
||||
{
|
||||
className: cn(
|
||||
"bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
|
||||
className,
|
||||
),
|
||||
},
|
||||
{ ...props, children: effectiveRender ? undefined : children },
|
||||
),
|
||||
render: effectiveRender,
|
||||
state: {
|
||||
slot: "button-group-text",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function ButtonGroupSeparator({
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { LoaderCircle, PlusIcon, Search } from "lucide-react";
|
||||
import * as React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip";
|
||||
|
||||
// [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0
|
||||
|
||||
const buttonVariants = cva(
|
||||
`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm text-sm transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-950 disabled:pointer-events-none disabled:opacity-50 dark:focus-visible:ring-zinc-300 font-regular
|
||||
|
||||
@@ -14,19 +12,14 @@ const buttonVariants = cva(
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
// border border-[#8231FF]
|
||||
default:
|
||||
// "bg-zinc-900 text-zinc-50 shadow hover:bg-zinc-900/90 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-50/90",
|
||||
`bg-primary hover:bg-primary/90 text-zinc-50 shadow dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-50/90
|
||||
!rounded-xs
|
||||
`,
|
||||
secondary:
|
||||
"border border-zinc-200 bg-white shadow-sm hover:bg-zinc-100 hover:text-zinc-900 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-800 dark:hover:text-zinc-50",
|
||||
// "bg-zinc-100 text-zinc-900 shadow-sm hover:bg-zinc-100/80 dark:bg-zinc-800 dark:text-zinc-50 dark:hover:bg-zinc-800/80",
|
||||
destructive:
|
||||
"font-semibold text-red-400 border border-red-400 rounded-md shadow-sm hover:bg-red-500/90 hover:text-zinc-50 dark:bg-red-900 dark:text-zinc-50 dark:hover:bg-red-900/90 shadow-sm ",
|
||||
// destructive:
|
||||
// "bg-red-500 font-semibold text-zinc-50 shadow-sm hover:bg-red-500/90 dark:bg-red-900 dark:text-zinc-50 dark:hover:bg-red-900/90",
|
||||
outline:
|
||||
"border border-zinc-200 bg-white shadow-sm hover:bg-zinc-100 hover:text-zinc-900 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-800 dark:hover:text-zinc-50",
|
||||
ghost:
|
||||
@@ -36,15 +29,12 @@ const buttonVariants = cva(
|
||||
link: "text-zinc-900 underline-offset-4 hover:underline dark:text-zinc-50",
|
||||
dashed:
|
||||
"hover:bg-stone-100 text-t2 border border-1 border-dashed border-stone-300",
|
||||
// shadow-sm hover:from-stone-100 hover:to-stone-200 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-800 dark:hover:text-zinc-50
|
||||
gradientPrimary:
|
||||
"bg-gradient-to-b font-semibold border-t border-purple-400 outline outline-primary rounded-sm from-primary/85 to-primary text-white hover:from-primary hover:to-primary shadow-purple-500/50 transition-[background] duration-300 !h-7.5 mt-0.25",
|
||||
|
||||
gradientSecondary:
|
||||
"border border-stone-300 font-semibold bg-gradient-to-b from-white to-stone-100 text-t1 hover:from-stone-300 hover:to-stone-400 shadow-sm",
|
||||
// add: "text-primary border-t border-white outline outline-purple-800/20 bg-gradient-to-b from-zinc-50 to-zinc-200/70 shadow-sm hover:from-zinc-200 hover:border-zinc-200 hover:text-primary dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 !h-6 rounded-md",
|
||||
add: "text-primary border-t border-white outline outline-zinc-200 bg-gradient-to-b from-stone-100 to-zinc-50 hover:from-stone-100 hover:to-stone-100 hover:border-primary dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 !h-9.5 rounded-none",
|
||||
// add: "border-t border-purple-400 bg-gradient-to-b from-primary/90 to-primary text-white hover:from-primary hover:to-primary !shadow-lg !h-6 rounded-md",
|
||||
|
||||
analyse:
|
||||
"text-primary border-t border-white outline outline-zinc-200 bg-gradient-to-b from-stone-100 to-zinc-50 hover:from-stone-100 hover:to-stone-100 hover:border-primary dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 !h-9.5 rounded-none",
|
||||
@@ -82,6 +72,7 @@ export interface ButtonProps
|
||||
tooltipContent?: string;
|
||||
disableStartIcon?: boolean;
|
||||
shimmer?: boolean;
|
||||
render?: React.ReactElement;
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
@@ -100,14 +91,17 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
children,
|
||||
disableStartIcon = false,
|
||||
shimmer = false,
|
||||
render,
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const Comp = asChild ? Slot : "button";
|
||||
const Button = (
|
||||
<Comp
|
||||
const renderProp = asChild && React.isValidElement(children) ? children : render;
|
||||
|
||||
const ButtonElement = (
|
||||
<ButtonPrimitive
|
||||
{...props}
|
||||
render={renderProp}
|
||||
className={cn(
|
||||
buttonVariants({ variant, size, className }),
|
||||
isIcon && `w-${dim} h-${dim} p-0`,
|
||||
@@ -124,33 +118,33 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
}}
|
||||
disabled={isLoading || props.disabled || shimmer}
|
||||
>
|
||||
{isLoading && <LoaderCircle className="animate-spin" size={14} />}
|
||||
{startIcon && !isLoading && <>{startIcon}</>}
|
||||
{!isLoading && !startIcon && variant === "add" && !disableStartIcon && (
|
||||
<PlusIcon size={12} />
|
||||
{renderProp ? undefined : (
|
||||
<>
|
||||
{isLoading && <LoaderCircle className="animate-spin" size={14} />}
|
||||
{startIcon && !isLoading && <>{startIcon}</>}
|
||||
{!isLoading && !startIcon && variant === "add" && !disableStartIcon && (
|
||||
<PlusIcon size={12} />
|
||||
)}
|
||||
{!isLoading &&
|
||||
!startIcon &&
|
||||
variant === "analyse" &&
|
||||
!disableStartIcon && <Search size={12} />}
|
||||
{children}
|
||||
{endIcon && !isLoading && <>{endIcon}</>}
|
||||
</>
|
||||
)}
|
||||
{!isLoading &&
|
||||
!startIcon &&
|
||||
variant === "analyse" &&
|
||||
!disableStartIcon && <Search size={12} />}
|
||||
{children}
|
||||
{endIcon && !isLoading && <>{endIcon}</>}
|
||||
</Comp>
|
||||
</ButtonPrimitive>
|
||||
);
|
||||
|
||||
if (tooltipContent) {
|
||||
return (
|
||||
<Tooltip delayDuration={200}>
|
||||
<TooltipTrigger asChild>{Button}</TooltipTrigger>
|
||||
<TooltipTrigger asChild>{ButtonElement}</TooltipTrigger>
|
||||
<TooltipContent>{tooltipContent}</TooltipContent>
|
||||
</Tooltip>
|
||||
// <Tooltip content={tooltipContent}>
|
||||
// {Button}
|
||||
// </Tooltip>
|
||||
);
|
||||
} else {
|
||||
return Button;
|
||||
}
|
||||
return ButtonElement;
|
||||
},
|
||||
);
|
||||
Button.displayName = "Button";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
||||
import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Checkbox = React.forwardRef<
|
||||
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> & {
|
||||
HTMLButtonElement,
|
||||
CheckboxPrimitive.Root.Props & {
|
||||
iconClassName?: string;
|
||||
}
|
||||
>(({ className, iconClassName, ...props }, ref) => (
|
||||
@@ -14,7 +14,7 @@ const Checkbox = React.forwardRef<
|
||||
ref={ref}
|
||||
data-slot="checkbox"
|
||||
className={cn(
|
||||
"peer shrink-0 rounded border border-gray-300 size-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-gray-900 data-[state=checked]:border-gray-900 transition-none",
|
||||
"peer shrink-0 rounded border border-gray-300 size-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-checked:bg-gray-900 data-checked:border-gray-900 transition-none",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -27,6 +27,6 @@ const Checkbox = React.forwardRef<
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
||||
));
|
||||
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
||||
Checkbox.displayName = "Checkbox";
|
||||
|
||||
export { Checkbox };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
|
||||
import { XIcon } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
@@ -8,60 +8,90 @@ import { cn } from "@/lib/utils";
|
||||
|
||||
function Dialog({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
||||
}: DialogPrimitive.Root.Props) {
|
||||
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
||||
}
|
||||
|
||||
function DialogTrigger({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
||||
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
||||
}: DialogPrimitive.Trigger.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<DialogPrimitive.Trigger
|
||||
data-slot="dialog-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<DialogPrimitive.Trigger data-slot="dialog-trigger" {...props}>
|
||||
{children}
|
||||
</DialogPrimitive.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
function DialogPortal({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
||||
}: DialogPrimitive.Portal.Props) {
|
||||
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
||||
}
|
||||
|
||||
function DialogClose({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
||||
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
||||
}: DialogPrimitive.Close.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<DialogPrimitive.Close
|
||||
data-slot="dialog-close"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<DialogPrimitive.Close data-slot="dialog-close" {...props}>
|
||||
{children}
|
||||
</DialogPrimitive.Close>
|
||||
);
|
||||
}
|
||||
|
||||
const DialogOverlay = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Overlay
|
||||
ref={ref}
|
||||
data-slot="dialog-overlay"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className={cn(
|
||||
"fixed inset-0 z-[170] bg-white/70 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogOverlay.displayName = "DialogOverlay";
|
||||
function DialogOverlay({
|
||||
className,
|
||||
...props
|
||||
}: DialogPrimitive.Backdrop.Props) {
|
||||
return (
|
||||
<DialogPrimitive.Backdrop
|
||||
data-slot="dialog-overlay"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className={cn(
|
||||
"fixed inset-0 z-[170] bg-white/70 backdrop-blur-sm data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DialogContent({
|
||||
className,
|
||||
children,
|
||||
showCloseButton = true,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
||||
}: DialogPrimitive.Popup.Props & {
|
||||
showCloseButton?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<DialogPortal data-slot="dialog-portal">
|
||||
<DialogOverlay />
|
||||
<DialogPrimitive.Content
|
||||
<DialogPrimitive.Popup
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
`data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-[180] grid translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-3xl
|
||||
`data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 fixed top-[50%] left-[50%] z-[180] grid translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-3xl
|
||||
bg-stone-50
|
||||
min-w-[15rem]
|
||||
`,
|
||||
@@ -71,12 +101,12 @@ function DialogContent({
|
||||
>
|
||||
{children}
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4">
|
||||
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-open:bg-accent data-open:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4">
|
||||
<XIcon />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
)}
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPrimitive.Popup>
|
||||
</DialogPortal>
|
||||
);
|
||||
}
|
||||
@@ -113,7 +143,7 @@ function DialogFooter({
|
||||
function DialogTitle({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
||||
}: DialogPrimitive.Title.Props) {
|
||||
return (
|
||||
<DialogPrimitive.Title
|
||||
data-slot="dialog-title"
|
||||
@@ -126,7 +156,7 @@ function DialogTitle({
|
||||
function DialogDescription({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
||||
}: DialogPrimitive.Description.Props) {
|
||||
return (
|
||||
<DialogPrimitive.Description
|
||||
data-slot="dialog-description"
|
||||
|
||||
@@ -1,35 +1,83 @@
|
||||
"use client";
|
||||
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
||||
import { Check, ChevronRight, Circle } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import SmallSpinner from "../general/SmallSpinner";
|
||||
|
||||
const DropdownMenu = DropdownMenuPrimitive.Root;
|
||||
function DropdownMenu({
|
||||
...props
|
||||
}: MenuPrimitive.Root.Props) {
|
||||
return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
||||
}
|
||||
|
||||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
||||
const DropdownMenuTrigger = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
MenuPrimitive.Trigger.Props & { asChild?: boolean }
|
||||
>(({ asChild, children, ...props }, ref) => {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<MenuPrimitive.Trigger
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<MenuPrimitive.Trigger ref={ref} data-slot="dropdown-menu-trigger" {...props}>
|
||||
{children}
|
||||
</MenuPrimitive.Trigger>
|
||||
);
|
||||
});
|
||||
DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
|
||||
|
||||
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
||||
function DropdownMenuGroup({
|
||||
...props
|
||||
}: MenuPrimitive.Group.Props) {
|
||||
return <MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
|
||||
}
|
||||
|
||||
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
||||
function DropdownMenuPortal({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
||||
function DropdownMenuSub({
|
||||
...props
|
||||
}: MenuPrimitive.SubmenuRoot.Props) {
|
||||
return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />;
|
||||
}
|
||||
|
||||
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
||||
function DropdownMenuRadioGroup({
|
||||
...props
|
||||
}: MenuPrimitive.RadioGroup.Props) {
|
||||
return (
|
||||
<MenuPrimitive.RadioGroup
|
||||
data-slot="dropdown-menu-radio-group"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const DropdownMenuSubTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.SubmenuTrigger.Props & {
|
||||
inset?: boolean;
|
||||
withIcon?: boolean;
|
||||
}
|
||||
>(({ className, inset, children, withIcon = true, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
<MenuPrimitive.SubmenuTrigger
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-sub-trigger"
|
||||
className={cn(
|
||||
"flex cursor-pointer gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-zinc-100 data-[state=open]:bg-zinc-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:focus:bg-zinc-800 dark:data-[state=open]:bg-zinc-800",
|
||||
"flex cursor-pointer gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-zinc-100 data-popup-open:bg-zinc-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:focus:bg-zinc-800 dark:data-popup-open:bg-zinc-800",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
@@ -37,86 +85,131 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
>
|
||||
{children}
|
||||
{withIcon && <ChevronRight className="ml-auto text-t3" />}
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
||||
</MenuPrimitive.SubmenuTrigger>
|
||||
));
|
||||
DropdownMenuSubTrigger.displayName =
|
||||
DropdownMenuPrimitive.SubTrigger.displayName;
|
||||
DropdownMenuSubTrigger.displayName = "DropdownMenuSubTrigger";
|
||||
|
||||
const DropdownMenuSubContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"z-[200] min-w-[8rem] overflow-hidden rounded-md border border-zinc-200 bg-white p-1 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50 text-zinc-800 font-regular",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.Popup.Props & {
|
||||
sideOffset?: number;
|
||||
}
|
||||
>(({ className, sideOffset = 0, ...props }, ref) => (
|
||||
<MenuPrimitive.Portal>
|
||||
<MenuPrimitive.Positioner
|
||||
sideOffset={sideOffset}
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[200]"
|
||||
>
|
||||
<MenuPrimitive.Popup
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-sub-content"
|
||||
className={cn(
|
||||
"z-[200] min-w-[8rem] overflow-hidden rounded-md border border-zinc-200 bg-white p-1 shadow-lg data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50 text-zinc-800 font-regular",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</MenuPrimitive.Positioner>
|
||||
</MenuPrimitive.Portal>
|
||||
));
|
||||
DropdownMenuSubContent.displayName =
|
||||
DropdownMenuPrimitive.SubContent.displayName;
|
||||
DropdownMenuSubContent.displayName = "DropdownMenuSubContent";
|
||||
|
||||
const DropdownMenuContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
||||
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Portal>
|
||||
<DropdownMenuPrimitive.Content
|
||||
onCloseAutoFocus={(e) => e.preventDefault()}
|
||||
ref={ref}
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.Popup.Props & {
|
||||
sideOffset?: number;
|
||||
side?: "top" | "bottom" | "left" | "right";
|
||||
align?: "start" | "center" | "end";
|
||||
onCloseAutoFocus?: (e: any) => void;
|
||||
}
|
||||
>(({ className, sideOffset = 4, side = "bottom", align = "start", onCloseAutoFocus: _onCloseAutoFocus, ...props }, ref) => (
|
||||
<MenuPrimitive.Portal>
|
||||
<MenuPrimitive.Positioner
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-[200] min-w-[8rem] overflow-hidden rounded-md border border-zinc-200 bg-white p-1 text-zinc-950 shadow-md dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50",
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</DropdownMenuPrimitive.Portal>
|
||||
side={side}
|
||||
align={align}
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[200] outline-none"
|
||||
>
|
||||
<MenuPrimitive.Popup
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-content"
|
||||
className={cn(
|
||||
"z-[200] min-w-[8rem] overflow-hidden rounded-md border border-zinc-200 bg-white p-1 text-zinc-950 shadow-md dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50",
|
||||
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</MenuPrimitive.Positioner>
|
||||
</MenuPrimitive.Portal>
|
||||
));
|
||||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
||||
DropdownMenuContent.displayName = "DropdownMenuContent";
|
||||
|
||||
const DropdownMenuItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.Item.Props & {
|
||||
inset?: boolean;
|
||||
isLoading?: boolean;
|
||||
shimmer?: boolean;
|
||||
asChild?: boolean;
|
||||
}
|
||||
>(({ className, inset, shimmer = false, isLoading, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
shimmer && "shimmer",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
disabled={shimmer || isLoading}
|
||||
{...props}
|
||||
>
|
||||
{isLoading ? (
|
||||
<>
|
||||
{props.children}
|
||||
<SmallSpinner />
|
||||
</>
|
||||
) : (
|
||||
props.children
|
||||
)}
|
||||
</DropdownMenuPrimitive.Item>
|
||||
));
|
||||
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
||||
>(({ className, inset, shimmer = false, isLoading, children, asChild, ...props }, ref) => {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<MenuPrimitive.Item
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-item"
|
||||
closeOnClick={false}
|
||||
render={children}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
shimmer && "shimmer",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
disabled={shimmer || isLoading}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<MenuPrimitive.Item
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-item"
|
||||
closeOnClick={false}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
shimmer && "shimmer",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
disabled={shimmer || isLoading}
|
||||
{...props}
|
||||
>
|
||||
{isLoading ? (
|
||||
<>
|
||||
{children}
|
||||
<SmallSpinner />
|
||||
</>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</MenuPrimitive.Item>
|
||||
);
|
||||
});
|
||||
DropdownMenuItem.displayName = "DropdownMenuItem";
|
||||
|
||||
const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.CheckboxItem.Props
|
||||
>(({ className, children, checked, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
<MenuPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-1 pr-2 text-sm outline-none transition-colors focus:bg-zinc-100 focus:text-zinc-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-zinc-800 dark:focus:text-zinc-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-1 pr-2 text-sm outline-none transition-colors focus:bg-zinc-100 focus:text-zinc-900 data-disabled:pointer-events-none data-disabled:opacity-50 dark:focus:bg-zinc-800 dark:focus:text-zinc-50",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
@@ -124,45 +217,46 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
>
|
||||
{children}
|
||||
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<MenuPrimitive.CheckboxItemIndicator>
|
||||
<Check className="h-4 w-4 text-t3" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</MenuPrimitive.CheckboxItemIndicator>
|
||||
</span>
|
||||
</DropdownMenuPrimitive.CheckboxItem>
|
||||
</MenuPrimitive.CheckboxItem>
|
||||
));
|
||||
DropdownMenuCheckboxItem.displayName =
|
||||
DropdownMenuPrimitive.CheckboxItem.displayName;
|
||||
DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem";
|
||||
|
||||
const DropdownMenuRadioItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.RadioItem.Props
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
<MenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-zinc-100 focus:text-zinc-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-zinc-800 dark:focus:text-zinc-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-zinc-100 focus:text-zinc-900 data-disabled:pointer-events-none data-disabled:opacity-50 dark:focus:bg-zinc-800 dark:focus:text-zinc-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<MenuPrimitive.RadioItemIndicator>
|
||||
<Circle className="h-2 w-2 fill-current" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</MenuPrimitive.RadioItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
</DropdownMenuPrimitive.RadioItem>
|
||||
</MenuPrimitive.RadioItem>
|
||||
));
|
||||
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
||||
DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
|
||||
|
||||
const DropdownMenuLabel = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.GroupLabel.Props & {
|
||||
inset?: boolean;
|
||||
}
|
||||
>(({ className, inset, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Label
|
||||
<MenuPrimitive.GroupLabel
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-label"
|
||||
className={cn(
|
||||
"px-2 py-1.5 text-sm font-semibold",
|
||||
inset && "pl-8",
|
||||
@@ -171,19 +265,20 @@ const DropdownMenuLabel = React.forwardRef<
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
||||
DropdownMenuLabel.displayName = "DropdownMenuLabel";
|
||||
|
||||
const DropdownMenuSeparator = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.Separator.Props
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Separator
|
||||
<MenuPrimitive.Separator
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-separator"
|
||||
className={cn("-mx-1 my-1 h-px bg-zinc-100 dark:bg-zinc-800", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
||||
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
|
||||
|
||||
const DropdownMenuShortcut = ({
|
||||
className,
|
||||
|
||||
@@ -1,19 +1,37 @@
|
||||
import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
|
||||
import type * as React from "react";
|
||||
import { PreviewCard as PreviewCardPrimitive } from "@base-ui/react/preview-card";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function HoverCard({
|
||||
openDelay: _openDelay,
|
||||
closeDelay: _closeDelay,
|
||||
...props
|
||||
}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
|
||||
return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />;
|
||||
}: PreviewCardPrimitive.Root.Props & {
|
||||
openDelay?: number;
|
||||
closeDelay?: number;
|
||||
}) {
|
||||
return <PreviewCardPrimitive.Root data-slot="hover-card" {...props} />;
|
||||
}
|
||||
|
||||
function HoverCardTrigger({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
|
||||
}: PreviewCardPrimitive.Trigger.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<PreviewCardPrimitive.Trigger
|
||||
data-slot="hover-card-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
|
||||
<PreviewCardPrimitive.Trigger data-slot="hover-card-trigger" {...props}>
|
||||
{children}
|
||||
</PreviewCardPrimitive.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,21 +39,32 @@ function HoverCardContent({
|
||||
className,
|
||||
align = "center",
|
||||
sideOffset = 4,
|
||||
side = "bottom",
|
||||
...props
|
||||
}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
|
||||
}: PreviewCardPrimitive.Popup.Props &
|
||||
Pick<
|
||||
PreviewCardPrimitive.Positioner.Props,
|
||||
"align" | "side" | "sideOffset"
|
||||
>) {
|
||||
return (
|
||||
<HoverCardPrimitive.Portal data-slot="hover-card-portal">
|
||||
<HoverCardPrimitive.Content
|
||||
data-slot="hover-card-content"
|
||||
<PreviewCardPrimitive.Portal data-slot="hover-card-portal">
|
||||
<PreviewCardPrimitive.Positioner
|
||||
align={align}
|
||||
side={side}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</HoverCardPrimitive.Portal>
|
||||
positionMethod="fixed"
|
||||
className="isolate z-50"
|
||||
>
|
||||
<PreviewCardPrimitive.Popup
|
||||
data-slot="hover-card-content"
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 w-64 origin-(--transform-origin) rounded-md border p-4 shadow-md outline-hidden",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PreviewCardPrimitive.Positioner>
|
||||
</PreviewCardPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||
import { Field } from "@base-ui/react/field";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -6,9 +6,9 @@ import { cn } from "@/lib/utils";
|
||||
function Label({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
||||
}: Field.Label.Props) {
|
||||
return (
|
||||
<LabelPrimitive.Root
|
||||
<Field.Label
|
||||
data-slot="label"
|
||||
className={cn(
|
||||
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
||||
|
||||
@@ -1,46 +1,79 @@
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||
import type * as React from "react";
|
||||
import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function Popover({
|
||||
...props
|
||||
}: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
||||
}: PopoverPrimitive.Root.Props) {
|
||||
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
|
||||
}
|
||||
|
||||
function PopoverTrigger({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
||||
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
|
||||
}: PopoverPrimitive.Trigger.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<PopoverPrimitive.Trigger
|
||||
data-slot="popover-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<PopoverPrimitive.Trigger data-slot="popover-trigger" {...props}>
|
||||
{children}
|
||||
</PopoverPrimitive.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
function PopoverContent({
|
||||
className,
|
||||
align = "center",
|
||||
sideOffset = 4,
|
||||
side = "bottom",
|
||||
onEscapeKeyDown: _onEscapeKeyDown,
|
||||
onPointerDownOutside: _onPointerDownOutside,
|
||||
onOpenAutoFocus: _onOpenAutoFocus,
|
||||
onCloseAutoFocus: _onCloseAutoFocus,
|
||||
forceMount: _forceMount,
|
||||
asChild: _asChild,
|
||||
...props
|
||||
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
||||
}: PopoverPrimitive.Popup.Props &
|
||||
Pick<
|
||||
PopoverPrimitive.Positioner.Props,
|
||||
"align" | "side" | "sideOffset"
|
||||
> & {
|
||||
onEscapeKeyDown?: (e: any) => void;
|
||||
onPointerDownOutside?: (e: any) => void;
|
||||
onOpenAutoFocus?: (e: any) => void;
|
||||
onCloseAutoFocus?: (e: any) => void;
|
||||
forceMount?: boolean;
|
||||
asChild?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
data-slot="popover-content"
|
||||
<PopoverPrimitive.Positioner
|
||||
align={align}
|
||||
side={side}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-[200] w-72 rounded-md border p-4 shadow-md outline-hidden",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[200]"
|
||||
>
|
||||
<PopoverPrimitive.Popup
|
||||
data-slot="popover-content"
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 w-72 rounded-md border p-4 shadow-md outline-hidden",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitive.Positioner>
|
||||
</PopoverPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
|
||||
function PopoverAnchor({
|
||||
...props
|
||||
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
|
||||
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
|
||||
}
|
||||
|
||||
export { Popover, PopoverTrigger, PopoverContent };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
||||
import { ScrollArea as ScrollAreaPrimitive } from "@base-ui/react/scroll-area";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -7,7 +7,7 @@ function ScrollArea({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
||||
}: ScrollAreaPrimitive.Root.Props) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.Root
|
||||
data-slot="scroll-area"
|
||||
@@ -30,9 +30,9 @@ function ScrollBar({
|
||||
className,
|
||||
orientation = "vertical",
|
||||
...props
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
||||
}: ScrollAreaPrimitive.Scrollbar.Props) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||
<ScrollAreaPrimitive.Scrollbar
|
||||
data-slot="scroll-area-scrollbar"
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
@@ -45,12 +45,12 @@ function ScrollBar({
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.ScrollAreaThumb
|
||||
<ScrollAreaPrimitive.Thumb
|
||||
data-slot="scroll-area-thumb"
|
||||
className="bg-border relative flex-1 rounded-full"
|
||||
/>
|
||||
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||
</ScrollAreaPrimitive.Scrollbar>
|
||||
);
|
||||
}
|
||||
|
||||
export { ScrollArea };
|
||||
export { ScrollArea, ScrollBar };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
||||
import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -8,14 +8,17 @@ import { cn } from "@/lib/utils";
|
||||
function Separator({
|
||||
className,
|
||||
orientation = "horizontal",
|
||||
decorative = true,
|
||||
decorative,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
|
||||
}: SeparatorPrimitive.Props & {
|
||||
orientation?: "horizontal" | "vertical";
|
||||
decorative?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<SeparatorPrimitive.Root
|
||||
<SeparatorPrimitive
|
||||
data-slot="separator-root"
|
||||
decorative={decorative}
|
||||
orientation={orientation}
|
||||
data-orientation={orientation}
|
||||
className={cn(
|
||||
"shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px bg-border",
|
||||
className,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import * as SwitchPrimitive from "@radix-ui/react-switch";
|
||||
import { Switch as SwitchPrimitive } from "@base-ui/react/switch";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -9,14 +9,14 @@ function Switch({
|
||||
className,
|
||||
thumbClassName,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SwitchPrimitive.Root> & {
|
||||
}: SwitchPrimitive.Root.Props & {
|
||||
thumbClassName?: string;
|
||||
}) {
|
||||
return (
|
||||
<SwitchPrimitive.Root
|
||||
data-slot="switch"
|
||||
className={cn(
|
||||
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 inline-flex h-5 w-9 shrink-0 items-center rounded-full border-2 border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"peer data-checked:bg-primary data-unchecked:bg-input focus-visible:border-ring focus-visible:ring-ring/50 inline-flex h-5 w-9 shrink-0 items-center rounded-full border-2 border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -24,7 +24,7 @@ function Switch({
|
||||
<SwitchPrimitive.Thumb
|
||||
data-slot="switch-thumb"
|
||||
className={cn(
|
||||
"bg-background pointer-events-none block size-4 rounded-full ring-0 shadow-lg transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0",
|
||||
"bg-background pointer-events-none block size-4 rounded-full ring-0 shadow-lg transition-transform data-checked:translate-x-4 data-unchecked:translate-x-0",
|
||||
thumbClassName,
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
"use client";
|
||||
|
||||
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
||||
import { Tabs as TabsPrimitive } from "@base-ui/react/tabs";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Tabs = TabsPrimitive.Root;
|
||||
function Tabs({ ...props }: TabsPrimitive.Root.Props) {
|
||||
return <TabsPrimitive.Root data-slot="tabs" {...props} />;
|
||||
}
|
||||
|
||||
const TabsList = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.List>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex h-9 items-center justify-center rounded-lg bg-transparent text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400 px-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsList.displayName = TabsPrimitive.List.displayName;
|
||||
const TabsList = React.forwardRef<HTMLDivElement, TabsPrimitive.List.Props>(
|
||||
({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex h-9 items-center justify-center rounded-lg bg-transparent text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400 px-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
);
|
||||
TabsList.displayName = "TabsList";
|
||||
|
||||
const TabsTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> & {
|
||||
HTMLButtonElement,
|
||||
TabsPrimitive.Tab.Props & {
|
||||
variant?: "default" | "onboarding";
|
||||
}
|
||||
>(({ className, variant = "default", ...props }, ref) => (
|
||||
<TabsPrimitive.Trigger
|
||||
<TabsPrimitive.Tab
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-2 py-1 text-sm font-medium ring-offset-background transition-all cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-primary hover:bg-interactive-secondary-hover dark:focus-visible:ring-zinc-300 dark:data-[state=active]:bg-zinc-950 dark:data-[state=active]:text-zinc-50",
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-2 py-1 text-sm font-medium ring-offset-background transition-all cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[active]:text-primary hover:bg-interactive-secondary-hover dark:focus-visible:ring-zinc-300 dark:data-[active]:bg-zinc-950 dark:data-[active]:text-zinc-50",
|
||||
className,
|
||||
variant === "onboarding" &&
|
||||
"data-[state=active]:bg-stone-200 data-[state=active]:text-t2 data-[state=active]:font-medium",
|
||||
"data-[active]:bg-stone-200 data-[active]:text-t2 data-[active]:font-medium",
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
||||
TabsTrigger.displayName = "TabsTrigger";
|
||||
|
||||
const TabsContent = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"mt-2 mb-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
||||
const TabsContent = React.forwardRef<HTMLDivElement, TabsPrimitive.Panel.Props>(
|
||||
({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Panel
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"mt-2 mb-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
);
|
||||
TabsContent.displayName = "TabsContent";
|
||||
|
||||
export { Tabs, TabsContent, TabsList, TabsTrigger };
|
||||
|
||||
@@ -1,63 +1,90 @@
|
||||
"use client";
|
||||
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||
import type * as React from "react";
|
||||
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function TooltipProvider({
|
||||
delayDuration = 0,
|
||||
delay = 0,
|
||||
...props
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
||||
}: TooltipPrimitive.Provider.Props) {
|
||||
return (
|
||||
<TooltipPrimitive.Provider
|
||||
data-slot="tooltip-provider"
|
||||
delayDuration={delayDuration}
|
||||
delay={delay}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function Tooltip({
|
||||
delayDuration,
|
||||
...props
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
||||
}: TooltipPrimitive.Root.Props & { delayDuration?: number }) {
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<TooltipProvider delay={delayDuration}>
|
||||
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function TooltipTrigger({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
||||
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
||||
}: TooltipPrimitive.Trigger.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<TooltipPrimitive.Trigger
|
||||
data-slot="tooltip-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props}>
|
||||
{children}
|
||||
</TooltipPrimitive.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
function TooltipContent({
|
||||
className,
|
||||
sideOffset = 0,
|
||||
side = "top",
|
||||
align = "center",
|
||||
children,
|
||||
|
||||
...props
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
|
||||
}: TooltipPrimitive.Popup.Props &
|
||||
Pick<
|
||||
TooltipPrimitive.Positioner.Props,
|
||||
"align" | "side" | "sideOffset"
|
||||
>) {
|
||||
return (
|
||||
<TooltipPrimitive.Portal>
|
||||
<TooltipPrimitive.Content
|
||||
data-slot="tooltip-content"
|
||||
<TooltipPrimitive.Positioner
|
||||
side={side}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
`z-[200] overflow-hidden rounded-lg px-4 py-2 text-xs max-w-56 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
||||
align={align}
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[200]"
|
||||
>
|
||||
<TooltipPrimitive.Popup
|
||||
data-slot="tooltip-content"
|
||||
className={cn(
|
||||
`overflow-hidden rounded-lg px-4 py-2 text-xs max-w-56 animate-in fade-in-0 zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
||||
|
||||
backdrop-blur-sm shadow-lg text-t2 border bg-outer-background
|
||||
`,
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
{/* <TooltipPrimitive.Arrow className="bg-zinc-900 fill-zinc-900 z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" /> */}
|
||||
</TooltipPrimitive.Content>
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TooltipPrimitive.Popup>
|
||||
</TooltipPrimitive.Positioner>
|
||||
</TooltipPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import { CheckIcon, CopyIcon } from "@phosphor-icons/react";
|
||||
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
||||
import { Tabs as TabsPrimitive } from "@base-ui/react/tabs";
|
||||
import * as React from "react";
|
||||
import { useTheme } from "@/contexts/ThemeProvider";
|
||||
import { highlightCode } from "@/lib/shikiHighlighter";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface CodeGroupProps
|
||||
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root> {}
|
||||
extends TabsPrimitive.Root.Props {}
|
||||
|
||||
const CodeGroup = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Root>,
|
||||
HTMLDivElement,
|
||||
CodeGroupProps
|
||||
>(({ ...props }, ref) => <TabsPrimitive.Root ref={ref} {...props} />);
|
||||
CodeGroup.displayName = "CodeGroup";
|
||||
|
||||
interface CodeGroupListProps
|
||||
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> {}
|
||||
extends TabsPrimitive.List.Props {}
|
||||
|
||||
const CodeGroupList = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.List>,
|
||||
HTMLDivElement,
|
||||
CodeGroupListProps
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.List
|
||||
@@ -30,13 +30,13 @@ const CodeGroupList = React.forwardRef<
|
||||
CodeGroupList.displayName = "CodeGroupList";
|
||||
|
||||
interface CodeGroupTabProps
|
||||
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> {}
|
||||
extends TabsPrimitive.Tab.Props {}
|
||||
|
||||
const CodeGroupTab = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
||||
HTMLButtonElement,
|
||||
CodeGroupTabProps
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Trigger
|
||||
<TabsPrimitive.Tab
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex items-center justify-center flex-1 min-w-0 h-6 px-2 py-1 text-[13px] font-semibold tracking-[-0.039px] leading-normal whitespace-nowrap",
|
||||
@@ -44,8 +44,8 @@ const CodeGroupTab = React.forwardRef<
|
||||
"text-t3 transition-none outline-none",
|
||||
"hover:text-primary",
|
||||
"focus-visible:text-primary",
|
||||
"data-[state=active]:bg-interactive-secondary-hover data-[state=active]:shadow-[0px_3px_4px_0px_inset_rgba(0,0,0,0.04)]",
|
||||
"data-[state=inactive]:shadow-[0px_-3px_4px_0px_inset_rgba(0,0,0,0.04)]",
|
||||
"data-selected:bg-interactive-secondary-hover data-selected:shadow-[0px_3px_4px_0px_inset_rgba(0,0,0,0.04)]",
|
||||
"data-unselected:shadow-[0px_-3px_4px_0px_inset_rgba(0,0,0,0.04)]",
|
||||
"first:rounded-tl-md first:border-l",
|
||||
className,
|
||||
)}
|
||||
@@ -102,16 +102,16 @@ const CodeGroupCopyButton = React.forwardRef<
|
||||
CodeGroupCopyButton.displayName = "CodeGroupCopyButton";
|
||||
|
||||
interface CodeGroupContentProps
|
||||
extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> {
|
||||
extends TabsPrimitive.Panel.Props {
|
||||
copyText?: string;
|
||||
}
|
||||
|
||||
const CodeGroupContent = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Content>,
|
||||
HTMLDivElement,
|
||||
CodeGroupContentProps
|
||||
>(({ className, children, copyText: _copyText, ...props }, ref) => {
|
||||
return (
|
||||
<TabsPrimitive.Content
|
||||
<TabsPrimitive.Panel
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"bg-white dark:bg-background border border-t-0 rounded-bl-lg rounded-br-lg",
|
||||
@@ -121,7 +121,7 @@ const CodeGroupContent = React.forwardRef<
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TabsPrimitive.Content>
|
||||
</TabsPrimitive.Panel>
|
||||
);
|
||||
});
|
||||
CodeGroupContent.displayName = "CodeGroupContent";
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { mergeProps } from "@base-ui/react/merge-props";
|
||||
import { useRender } from "@base-ui/react/use-render";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
// transition-colors focus:outline-none focus:ring-2 focus:ring-zinc-950 focus:ring-offset-2 dark:border-zinc-800 dark:focus:ring-zinc-300
|
||||
|
||||
const badgeVariants = cva(
|
||||
`inline-flex items-center rounded-lg border border-zinc-200 px-1.5 py-0.5
|
||||
|
||||
@@ -38,18 +37,24 @@ function Badge({
|
||||
variant,
|
||||
size,
|
||||
asChild = false,
|
||||
render: renderProp,
|
||||
...props
|
||||
}: React.ComponentProps<"span"> &
|
||||
}: useRender.ComponentProps<"span"> &
|
||||
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
|
||||
const Comp = asChild ? Slot : "span";
|
||||
|
||||
return (
|
||||
<Comp
|
||||
data-slot="badge"
|
||||
className={cn(badgeVariants({ variant, size }), className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
return useRender({
|
||||
defaultTagName: "span",
|
||||
props: mergeProps<"span">(
|
||||
{
|
||||
className: cn(badgeVariants({ variant, size }), className),
|
||||
},
|
||||
props,
|
||||
),
|
||||
render: renderProp,
|
||||
state: {
|
||||
slot: "badge",
|
||||
variant,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export { Badge };
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/* eslint-disable react-refresh/only-export-components */
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
import SmallSpinner from "@/components/general/SmallSpinner";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
// Remove ring styles
|
||||
// focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
|
||||
const buttonVariants = cva(
|
||||
`inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none cursor-pointer
|
||||
rounded-lg group/btn transition-colors w-fit transform-gpu
|
||||
@@ -14,7 +12,6 @@ const buttonVariants = cva(
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
// Custom
|
||||
primary: `
|
||||
!text-primary-foreground
|
||||
bg-primary
|
||||
@@ -76,6 +73,7 @@ export interface ButtonProps
|
||||
transition?: boolean;
|
||||
disableActive?: boolean;
|
||||
hide?: boolean;
|
||||
render?: React.ReactElement;
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
@@ -90,11 +88,12 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
disableActive = true,
|
||||
hide = false,
|
||||
children,
|
||||
render: renderProp,
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const Comp = asChild ? Slot : "button";
|
||||
const effectiveRender = asChild && React.isValidElement(children) ? children : renderProp;
|
||||
|
||||
const getDisableActiveStyles = () => {
|
||||
if (!disableActive) return "";
|
||||
@@ -126,9 +125,10 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
if (hide) return null;
|
||||
|
||||
return (
|
||||
<Comp
|
||||
<ButtonPrimitive
|
||||
ref={ref}
|
||||
data-slot="button"
|
||||
render={effectiveRender}
|
||||
className={cn(
|
||||
buttonVariants({ variant, size, className }),
|
||||
getDisableActiveStyles(),
|
||||
@@ -136,19 +136,23 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
disabled={isLoading || props.disabled}
|
||||
{...props}
|
||||
>
|
||||
{isLoading ? (
|
||||
<SmallSpinner
|
||||
size={14}
|
||||
className={variant === "primary" ? "relative z-10" : undefined}
|
||||
/>
|
||||
) : variant === "primary" ? (
|
||||
<span className="relative z-10 inline-flex items-center gap-2 transition-none">
|
||||
{children}
|
||||
</span>
|
||||
) : (
|
||||
children
|
||||
{effectiveRender ? undefined : (
|
||||
<>
|
||||
{isLoading ? (
|
||||
<SmallSpinner
|
||||
size={14}
|
||||
className={variant === "primary" ? "relative z-10" : undefined}
|
||||
/>
|
||||
) : variant === "primary" ? (
|
||||
<span className="relative z-10 inline-flex items-center gap-2 transition-none">
|
||||
{children}
|
||||
</span>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Comp>
|
||||
</ButtonPrimitive>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import type * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
||||
import type { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
|
||||
import * as React from "react";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export const CheckboxButton = React.forwardRef<
|
||||
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
|
||||
HTMLButtonElement,
|
||||
CheckboxPrimitive.Root.Props
|
||||
>(({ className, onCheckedChange, checked, ...props }, ref) => {
|
||||
const handleClick = () => {
|
||||
const newChecked = !checked;
|
||||
onCheckedChange?.(newChecked);
|
||||
(onCheckedChange as ((checked: boolean) => void) | undefined)?.(newChecked);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -35,7 +35,7 @@ export const CheckboxButton = React.forwardRef<
|
||||
ref={ref}
|
||||
tabIndex={-1}
|
||||
onClick={(e) => e.preventDefault()}
|
||||
className="data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=checked]:shadow-none size-3.5 shadow-[0_2px_4px_0_#00000005,inset_0_2px_1px_0_#FFFFFF] rounded-md border border-border bg-interactive-secondary dark:shadow-none pointer-events-none"
|
||||
className="data-checked:bg-primary data-checked:border-primary data-checked:shadow-none size-3.5 shadow-[0_2px_4px_0_#00000005,inset_0_2px_1px_0_#FFFFFF] rounded-md border border-border bg-interactive-secondary dark:shadow-none pointer-events-none"
|
||||
iconClassName="size-2"
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
||||
import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface CheckboxProps
|
||||
extends React.ComponentProps<typeof CheckboxPrimitive.Root> {
|
||||
interface CheckboxProps extends CheckboxPrimitive.Root.Props {
|
||||
size?: "sm" | "md" | "lg";
|
||||
disabled?: boolean;
|
||||
}
|
||||
@@ -24,7 +23,7 @@ function Checkbox({
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||
if (e.key === "Enter" && !disabled) {
|
||||
e.preventDefault();
|
||||
onCheckedChange?.(!checked);
|
||||
(onCheckedChange as ((checked: boolean) => void) | undefined)?.(!checked);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,7 +32,7 @@ function Checkbox({
|
||||
data-slot="checkbox"
|
||||
style={{ cursor: "pointer", ...style }}
|
||||
className={cn(
|
||||
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"peer border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
!disabled && "hover:bg-hover-primary hover:border-primary",
|
||||
size === "sm" && "size-3.5",
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import type * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
||||
import type * as React from "react";
|
||||
import { useId } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Checkbox } from "./Checkbox";
|
||||
|
||||
interface TextCheckboxProps
|
||||
extends React.ComponentProps<typeof CheckboxPrimitive.Root> {
|
||||
extends React.ComponentProps<typeof Checkbox> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
|
||||
import { XIcon } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
@@ -8,57 +8,87 @@ import { cn } from "@/lib/utils";
|
||||
|
||||
function Dialog({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
||||
}: DialogPrimitive.Root.Props) {
|
||||
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
||||
}
|
||||
|
||||
function DialogTrigger({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
||||
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
||||
}: DialogPrimitive.Trigger.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<DialogPrimitive.Trigger
|
||||
data-slot="dialog-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<DialogPrimitive.Trigger data-slot="dialog-trigger" {...props}>
|
||||
{children}
|
||||
</DialogPrimitive.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
function DialogPortal({
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
||||
}: DialogPrimitive.Portal.Props) {
|
||||
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
||||
}
|
||||
|
||||
function DialogClose({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
||||
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
||||
}: DialogPrimitive.Close.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<DialogPrimitive.Close
|
||||
data-slot="dialog-close"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<DialogPrimitive.Close data-slot="dialog-close" {...props}>
|
||||
{children}
|
||||
</DialogPrimitive.Close>
|
||||
);
|
||||
}
|
||||
|
||||
const DialogOverlay = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Overlay
|
||||
ref={ref}
|
||||
data-slot="dialog-overlay"
|
||||
className={cn(
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-[170] bg-black/50 dark:bg-black/80",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
||||
function DialogOverlay({
|
||||
className,
|
||||
...props
|
||||
}: DialogPrimitive.Backdrop.Props) {
|
||||
return (
|
||||
<DialogPrimitive.Backdrop
|
||||
data-slot="dialog-overlay"
|
||||
className={cn(
|
||||
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 fixed inset-0 z-[170] bg-black/50 dark:bg-black/80",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const DialogContent = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
|
||||
HTMLDivElement,
|
||||
DialogPrimitive.Popup.Props & {
|
||||
showCloseButton?: boolean;
|
||||
}
|
||||
>(({ className, children, showCloseButton = true, ...props }, ref) => (
|
||||
<DialogPortal data-slot="dialog-portal">
|
||||
<DialogOverlay />
|
||||
<DialogPrimitive.Content
|
||||
<DialogPrimitive.Popup
|
||||
ref={ref}
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[40%] left-[50%] z-[180] grid translate-x-[-50%] translate-y-[-50%] rounded-lg border shadow-lg duration-200",
|
||||
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 fixed top-[40%] left-[50%] z-[180] grid translate-x-[-50%] translate-y-[-50%] rounded-lg border shadow-lg duration-200",
|
||||
|
||||
"w-full max-w-md gap-3 bg-background",
|
||||
"p-4",
|
||||
@@ -70,16 +100,16 @@ const DialogContent = React.forwardRef<
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close
|
||||
data-slot="dialog-close"
|
||||
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
||||
className="ring-offset-background focus:ring-ring data-open:bg-accent data-open:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
||||
>
|
||||
<XIcon />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
)}
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPrimitive.Popup>
|
||||
</DialogPortal>
|
||||
));
|
||||
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
||||
DialogContent.displayName = "DialogContent";
|
||||
|
||||
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
@@ -105,8 +135,8 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
||||
}
|
||||
|
||||
const DialogTitle = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Title>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
||||
HTMLHeadingElement,
|
||||
DialogPrimitive.Title.Props
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Title
|
||||
ref={ref}
|
||||
@@ -115,11 +145,11 @@ const DialogTitle = React.forwardRef<
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
||||
DialogTitle.displayName = "DialogTitle";
|
||||
|
||||
const DialogDescription = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Description>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
||||
HTMLParagraphElement,
|
||||
DialogPrimitive.Description.Props
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Description
|
||||
ref={ref}
|
||||
@@ -128,7 +158,7 @@ const DialogDescription = React.forwardRef<
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
||||
DialogDescription.displayName = "DialogDescription";
|
||||
|
||||
export {
|
||||
Dialog,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { Check, ChevronRight, Circle } from "lucide-react";
|
||||
import * as React from "react";
|
||||
@@ -9,14 +9,12 @@ import { useHotkeys } from "react-hotkeys-hook";
|
||||
import SmallSpinner from "@/components/general/SmallSpinner";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
// Context for sharing menu open state with items
|
||||
const DropdownMenuContext = React.createContext<{ isOpen: boolean }>({
|
||||
isOpen: false,
|
||||
});
|
||||
|
||||
// CVA variants for menu items
|
||||
const dropdownMenuItemVariants = cva(
|
||||
"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-t2 outline-hidden transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-t2 outline-hidden transition-colors data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@@ -40,86 +38,91 @@ type DropdownMenuItemVariantProps = VariantProps<
|
||||
typeof dropdownMenuItemVariants
|
||||
>;
|
||||
|
||||
// Root
|
||||
function DropdownMenu(
|
||||
props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>,
|
||||
props: MenuPrimitive.Root.Props,
|
||||
) {
|
||||
const isOpen = props.open ?? false;
|
||||
return (
|
||||
<DropdownMenuContext.Provider value={{ isOpen }}>
|
||||
<DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
|
||||
<MenuPrimitive.Root data-slot="dropdown-menu" {...props} />
|
||||
</DropdownMenuContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// Trigger
|
||||
const DropdownMenuTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>
|
||||
>(function DropdownMenuTrigger(props, ref) {
|
||||
HTMLButtonElement,
|
||||
MenuPrimitive.Trigger.Props & { asChild?: boolean }
|
||||
>(function DropdownMenuTrigger({ asChild, children, ...props }, ref) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<MenuPrimitive.Trigger
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<DropdownMenuPrimitive.Trigger
|
||||
<MenuPrimitive.Trigger
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-trigger"
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
{children}
|
||||
</MenuPrimitive.Trigger>
|
||||
);
|
||||
});
|
||||
|
||||
// Group
|
||||
function DropdownMenuGroup(
|
||||
props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>,
|
||||
props: MenuPrimitive.Group.Props,
|
||||
) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
|
||||
<MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
// Portal
|
||||
function DropdownMenuPortal(
|
||||
props: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>,
|
||||
) {
|
||||
return <DropdownMenuPrimitive.Portal {...props} />;
|
||||
function DropdownMenuPortal({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
// Sub
|
||||
function DropdownMenuSub(
|
||||
props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>,
|
||||
props: MenuPrimitive.SubmenuRoot.Props,
|
||||
) {
|
||||
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
|
||||
return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />;
|
||||
}
|
||||
|
||||
// RadioGroup
|
||||
function DropdownMenuRadioGroup(
|
||||
props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,
|
||||
props: MenuPrimitive.RadioGroup.Props,
|
||||
) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.RadioGroup
|
||||
<MenuPrimitive.RadioGroup
|
||||
data-slot="dropdown-menu-radio-group"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// SubTrigger
|
||||
type DropdownMenuSubTriggerProps = React.ComponentProps<
|
||||
typeof DropdownMenuPrimitive.SubTrigger
|
||||
> & {
|
||||
type DropdownMenuSubTriggerProps = MenuPrimitive.SubmenuTrigger.Props & {
|
||||
inset?: boolean;
|
||||
withIcon?: boolean;
|
||||
};
|
||||
|
||||
const DropdownMenuSubTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
||||
HTMLDivElement,
|
||||
DropdownMenuSubTriggerProps
|
||||
>(function DropdownMenuSubTrigger(props, ref) {
|
||||
const { inset, withIcon = true, className, children, ...rest } = props;
|
||||
return (
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
<MenuPrimitive.SubmenuTrigger
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-sub-trigger"
|
||||
className={cn(
|
||||
"flex cursor-pointer gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm text-t2 outline-hidden hover:bg-accent focus:bg-accent data-[state=open]:bg-accent [&>svg]:pointer-events-none [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"flex cursor-pointer gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm text-t2 outline-hidden hover:bg-accent focus:bg-accent data-popup-open:bg-accent [&>svg]:pointer-events-none [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
@@ -127,73 +130,82 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
>
|
||||
{children}
|
||||
{withIcon && <ChevronRight className="ml-auto text-t3" />}
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
||||
</MenuPrimitive.SubmenuTrigger>
|
||||
);
|
||||
});
|
||||
|
||||
// SubContent
|
||||
const DropdownMenuSubContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.Popup.Props & { sideOffset?: number }
|
||||
>(function DropdownMenuSubContent(props, ref) {
|
||||
const { className, ...rest } = props;
|
||||
const { className, sideOffset = 0, ...rest } = props;
|
||||
return (
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-sub-content"
|
||||
className={cn(
|
||||
"bg-interactive-secondary text-t2 z-[101] min-w-[8rem] overflow-hidden rounded-lg border p-1 shadow-md",
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
<MenuPrimitive.Portal>
|
||||
<MenuPrimitive.Positioner
|
||||
sideOffset={sideOffset}
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[200]"
|
||||
>
|
||||
<MenuPrimitive.Popup
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-sub-content"
|
||||
className={cn(
|
||||
"bg-interactive-secondary text-t2 min-w-[8rem] overflow-hidden rounded-lg border p-1 shadow-md",
|
||||
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
</MenuPrimitive.Positioner>
|
||||
</MenuPrimitive.Portal>
|
||||
);
|
||||
});
|
||||
|
||||
// Content
|
||||
type DropdownMenuContentProps = React.ComponentProps<
|
||||
typeof DropdownMenuPrimitive.Content
|
||||
> & {
|
||||
type DropdownMenuContentProps = MenuPrimitive.Popup.Props & {
|
||||
sideOffset?: number;
|
||||
side?: "top" | "bottom" | "left" | "right";
|
||||
align?: "start" | "center" | "end";
|
||||
onCloseAutoFocus?: (e: any) => void;
|
||||
};
|
||||
|
||||
const DropdownMenuContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||
HTMLDivElement,
|
||||
DropdownMenuContentProps
|
||||
>(function DropdownMenuContent(props, ref) {
|
||||
const { className, sideOffset = 4, ...rest } = props;
|
||||
const { className, sideOffset = 4, side = "bottom", align = "start", onCloseAutoFocus: _onCloseAutoFocus, ...rest } = props;
|
||||
return (
|
||||
<DropdownMenuPrimitive.Portal>
|
||||
<DropdownMenuPrimitive.Content
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-content"
|
||||
<MenuPrimitive.Portal>
|
||||
<MenuPrimitive.Positioner
|
||||
sideOffset={sideOffset}
|
||||
onCloseAutoFocus={(e) => e.preventDefault()}
|
||||
className={cn(
|
||||
"bg-interactive-secondary text-t2 z-[101] min-w-[8rem] overflow-hidden rounded-lg border p-1 shadow-md",
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
</DropdownMenuPrimitive.Portal>
|
||||
side={side}
|
||||
align={align}
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[200] outline-none"
|
||||
>
|
||||
<MenuPrimitive.Popup
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-content"
|
||||
className={cn(
|
||||
"bg-interactive-secondary text-t2 min-w-[8rem] overflow-hidden rounded-lg border p-1 shadow-md",
|
||||
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
</MenuPrimitive.Positioner>
|
||||
</MenuPrimitive.Portal>
|
||||
);
|
||||
});
|
||||
|
||||
// Item
|
||||
type DropdownMenuItemProps = React.ComponentProps<
|
||||
typeof DropdownMenuPrimitive.Item
|
||||
> &
|
||||
type DropdownMenuItemProps = MenuPrimitive.Item.Props &
|
||||
DropdownMenuItemVariantProps & {
|
||||
isLoading?: boolean;
|
||||
shimmer?: boolean;
|
||||
/** Keyboard shortcut that triggers this item when the menu is open */
|
||||
shortcut?: string;
|
||||
};
|
||||
|
||||
const DropdownMenuItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
||||
HTMLDivElement,
|
||||
DropdownMenuItemProps
|
||||
>(function DropdownMenuItem(props, ref) {
|
||||
const {
|
||||
@@ -213,7 +225,7 @@ const DropdownMenuItem = React.forwardRef<
|
||||
shortcut ?? "",
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
onClick?.(e as unknown as React.MouseEvent<HTMLDivElement>);
|
||||
onClick?.(e as any);
|
||||
},
|
||||
{
|
||||
enabled: !!shortcut && isOpen,
|
||||
@@ -222,9 +234,10 @@ const DropdownMenuItem = React.forwardRef<
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownMenuPrimitive.Item
|
||||
<MenuPrimitive.Item
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-item"
|
||||
closeOnClick={false}
|
||||
className={cn(
|
||||
dropdownMenuItemVariants({ variant, inset }),
|
||||
shimmer && "shimmer",
|
||||
@@ -240,85 +253,73 @@ const DropdownMenuItem = React.forwardRef<
|
||||
<SmallSpinner />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{children}
|
||||
{/* {shortcut && (
|
||||
<span className="ml-auto text-xs tracking-widest text-t4 uppercase">
|
||||
{shortcut}
|
||||
</span>
|
||||
)} */}
|
||||
</>
|
||||
children
|
||||
)}
|
||||
</DropdownMenuPrimitive.Item>
|
||||
</MenuPrimitive.Item>
|
||||
);
|
||||
});
|
||||
|
||||
// CheckboxItem
|
||||
const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.CheckboxItem.Props
|
||||
>(function DropdownMenuCheckboxItem(props, ref) {
|
||||
const { className, children, ...rest } = props;
|
||||
return (
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
<MenuPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-1 pr-2 text-sm text-t2 outline-hidden transition-colors hover:bg-accent focus:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-1 pr-2 text-sm text-t2 outline-hidden transition-colors hover:bg-accent focus:bg-accent data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
<span className="absolute right-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<MenuPrimitive.CheckboxItemIndicator>
|
||||
<Check className="size-4 text-t3" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</MenuPrimitive.CheckboxItemIndicator>
|
||||
</span>
|
||||
</DropdownMenuPrimitive.CheckboxItem>
|
||||
</MenuPrimitive.CheckboxItem>
|
||||
);
|
||||
});
|
||||
|
||||
// RadioItem
|
||||
const DropdownMenuRadioItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.RadioItem.Props
|
||||
>(function DropdownMenuRadioItem(props, ref) {
|
||||
const { className, children, ...rest } = props;
|
||||
return (
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
<MenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm text-t2 outline-hidden transition-colors hover:bg-accent focus:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm text-t2 outline-hidden transition-colors hover:bg-accent focus:bg-accent data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<MenuPrimitive.RadioItemIndicator>
|
||||
<Circle className="size-2 fill-current" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</MenuPrimitive.RadioItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
</DropdownMenuPrimitive.RadioItem>
|
||||
</MenuPrimitive.RadioItem>
|
||||
);
|
||||
});
|
||||
|
||||
// Label
|
||||
type DropdownMenuLabelProps = React.ComponentProps<
|
||||
typeof DropdownMenuPrimitive.Label
|
||||
> & {
|
||||
type DropdownMenuLabelProps = MenuPrimitive.GroupLabel.Props & {
|
||||
inset?: boolean;
|
||||
};
|
||||
|
||||
const DropdownMenuLabel = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
||||
HTMLDivElement,
|
||||
DropdownMenuLabelProps
|
||||
>(function DropdownMenuLabel(props, ref) {
|
||||
const { inset, className, ...rest } = props;
|
||||
return (
|
||||
<DropdownMenuPrimitive.Label
|
||||
<MenuPrimitive.GroupLabel
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-label"
|
||||
className={cn(
|
||||
@@ -331,14 +332,13 @@ const DropdownMenuLabel = React.forwardRef<
|
||||
);
|
||||
});
|
||||
|
||||
// Separator
|
||||
const DropdownMenuSeparator = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
||||
React.ComponentProps<typeof DropdownMenuPrimitive.Separator>
|
||||
HTMLDivElement,
|
||||
MenuPrimitive.Separator.Props
|
||||
>(function DropdownMenuSeparator(props, ref) {
|
||||
const { className, ...rest } = props;
|
||||
return (
|
||||
<DropdownMenuPrimitive.Separator
|
||||
<MenuPrimitive.Separator
|
||||
ref={ref}
|
||||
data-slot="dropdown-menu-separator"
|
||||
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
||||
@@ -347,7 +347,6 @@ const DropdownMenuSeparator = React.forwardRef<
|
||||
);
|
||||
});
|
||||
|
||||
// Shortcut
|
||||
type DropdownMenuShortcutProps = React.HTMLAttributes<HTMLSpanElement>;
|
||||
|
||||
function DropdownMenuShortcut(props: DropdownMenuShortcutProps) {
|
||||
|
||||
@@ -75,7 +75,7 @@ export function FeatureSearchDropdown({
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
align="start"
|
||||
className="w-(--radix-dropdown-menu-trigger-width)"
|
||||
className="w-(--anchor-width)"
|
||||
>
|
||||
<div className="flex items-center gap-2 px-2 py-1.5 border-b border-border">
|
||||
<MagnifyingGlassIcon className="size-4 text-t4" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type FrontendProduct, sortPlanItems } from "@autumn/shared";
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
import { useEffect } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { Button } from "@/components/v2/buttons/Button";
|
||||
import { ShortcutButton } from "@/components/v2/buttons/ShortcutButton";
|
||||
@@ -29,6 +30,15 @@ export function InlinePlanEditor({
|
||||
}: InlinePlanEditorProps) {
|
||||
const mainContent = document.querySelector("[data-main-content]");
|
||||
|
||||
useEffect(() => {
|
||||
if (!(mainContent instanceof HTMLElement) || !isOpen) return;
|
||||
const previousOverflow = mainContent.style.overflow;
|
||||
mainContent.style.overflow = "hidden";
|
||||
return () => {
|
||||
mainContent.style.overflow = previousOverflow;
|
||||
};
|
||||
}, [mainContent, isOpen]);
|
||||
|
||||
if (!mainContent) {
|
||||
console.error("[InlinePlanEditor] Could not find portal target");
|
||||
return null;
|
||||
|
||||
@@ -31,7 +31,13 @@ function AreaRadioGroupItem({
|
||||
const isDisabled = disabled || !!disabledReason;
|
||||
|
||||
const content = (
|
||||
<div className={cn("flex items-start space-x-[6px]", className)}>
|
||||
<label
|
||||
className={cn(
|
||||
"flex items-start space-x-[6px] cursor-pointer",
|
||||
isDisabled && "cursor-not-allowed",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<RadioGroupItem
|
||||
value={value}
|
||||
id={id}
|
||||
@@ -40,21 +46,20 @@ function AreaRadioGroupItem({
|
||||
/>
|
||||
<div className="flex-1 space-y-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<label
|
||||
htmlFor={id}
|
||||
<span
|
||||
className={cn(
|
||||
"text-checkbox-label cursor-pointer",
|
||||
isDisabled && "cursor-not-allowed opacity-50",
|
||||
"text-checkbox-label",
|
||||
isDisabled && "opacity-50",
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
{description && (
|
||||
<p className="text-body-sec-paragraph">{description}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
|
||||
if (disabledReason) {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
||||
import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group";
|
||||
import { Radio } from "@base-ui/react/radio";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const RadioGroup = React.forwardRef<
|
||||
React.ElementRef<typeof RadioGroupPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
|
||||
HTMLDivElement,
|
||||
RadioGroupPrimitive.Props
|
||||
>(({ className, ...props }, ref) => {
|
||||
return (
|
||||
<RadioGroupPrimitive.Root
|
||||
<RadioGroupPrimitive
|
||||
data-slot="radio-group"
|
||||
className={cn("grid gap-2", className)}
|
||||
{...props}
|
||||
@@ -16,14 +17,14 @@ const RadioGroup = React.forwardRef<
|
||||
/>
|
||||
);
|
||||
});
|
||||
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
|
||||
RadioGroup.displayName = "RadioGroup";
|
||||
|
||||
const RadioGroupItem = React.forwardRef<
|
||||
React.ElementRef<typeof RadioGroupPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
|
||||
HTMLButtonElement,
|
||||
Radio.Root.Props
|
||||
>(({ className, style, ...props }, ref) => {
|
||||
return (
|
||||
<RadioGroupPrimitive.Item
|
||||
<Radio.Root
|
||||
ref={ref}
|
||||
data-slot="radio-group-item"
|
||||
style={{ cursor: "pointer", ...style }}
|
||||
@@ -31,23 +32,22 @@ const RadioGroupItem = React.forwardRef<
|
||||
"w-[13px] h-[13px] px-0.5 py-[3px] rounded-xl inline-flex flex-col justify-center items-center gap-2.5 overflow-hidden transition-none focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
|
||||
"bg-interactive-secondary shadow-[0px_2px_4px_0px_rgba(0,0,0,0.02)] border-[0.70px] border",
|
||||
"data-[state=checked]:bg-violet-600 data-[state=checked]:shadow-none data-[state=checked]:border-none",
|
||||
"data-checked:bg-violet-600 data-checked:shadow-none data-checked:border-none",
|
||||
|
||||
// Custom
|
||||
"hover:bg-interactive-secondary-hover hover:border-primary hover:border-[1px]",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<RadioGroupPrimitive.Indicator
|
||||
<Radio.Indicator
|
||||
data-slot="radio-group-indicator"
|
||||
className="flex items-center justify-center"
|
||||
>
|
||||
<div className="w-1 h-1 bg-white rounded-full" />
|
||||
</RadioGroupPrimitive.Indicator>
|
||||
</RadioGroupPrimitive.Item>
|
||||
</Radio.Indicator>
|
||||
</Radio.Root>
|
||||
);
|
||||
});
|
||||
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
|
||||
RadioGroupItem.displayName = "RadioGroupItem";
|
||||
|
||||
export { RadioGroup, RadioGroupItem };
|
||||
|
||||
@@ -45,7 +45,7 @@ export const CurrencySelect = ({
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="p-0 w-[var(--radix-popover-trigger-width)]">
|
||||
<PopoverContent className="p-0 w-[var(--anchor-width)]">
|
||||
<Command className="p-0">
|
||||
<CommandInput placeholder="Search currency..." />
|
||||
<CommandEmpty>No currency found.</CommandEmpty>
|
||||
|
||||
@@ -105,7 +105,6 @@ export function RoleSelect({
|
||||
<SelectItem
|
||||
key={role}
|
||||
value={role}
|
||||
textValue={ROLE_META[role].label}
|
||||
className="items-start"
|
||||
>
|
||||
<div className="flex flex-col items-start py-0.5 gap-0.5 w-full">
|
||||
|
||||
@@ -116,10 +116,9 @@ export function SearchableSelect<T>({
|
||||
<AnimatePresence>
|
||||
{open && (
|
||||
<PopoverContent
|
||||
forceMount
|
||||
align="start"
|
||||
className={cn(
|
||||
"w-(--radix-popover-trigger-width) p-0 z-200 rounded-md overflow-hidden",
|
||||
"w-(--anchor-width) p-0 z-200 rounded-md overflow-hidden",
|
||||
contentClassName,
|
||||
)}
|
||||
asChild
|
||||
|
||||
@@ -1,62 +1,48 @@
|
||||
"use client";
|
||||
|
||||
import * as SelectPrimitive from "@radix-ui/react-select";
|
||||
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
||||
import * as React from "react";
|
||||
import { Select as SelectPrimitive } from "@base-ui/react/select";
|
||||
import { CheckIcon, ChevronDownIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const SelectContext = React.createContext<{
|
||||
triggerRef: React.RefObject<HTMLButtonElement>;
|
||||
} | null>(null);
|
||||
|
||||
function Select({
|
||||
onValueChange,
|
||||
onOpenChange,
|
||||
value,
|
||||
defaultValue,
|
||||
items,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
||||
const triggerRef = React.useRef<HTMLButtonElement>(null);
|
||||
|
||||
const handleValueChange = (value: string) => {
|
||||
onValueChange?.(value);
|
||||
};
|
||||
|
||||
const handleOpenChange = (open: boolean) => {
|
||||
// When dropdown closes, blur the trigger to remove focus ring
|
||||
if (!open) {
|
||||
setTimeout(() => {
|
||||
if (triggerRef.current) {
|
||||
triggerRef.current.blur();
|
||||
} else {
|
||||
// Fallback: blur the active element if ref isn't set
|
||||
(document.activeElement as HTMLElement)?.blur();
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
onOpenChange?.(open);
|
||||
};
|
||||
|
||||
}: Omit<SelectPrimitive.Root.Props<string>, "onValueChange" | "onOpenChange"> & {
|
||||
onValueChange?: (value: string) => void;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
value?: string;
|
||||
defaultValue?: string;
|
||||
items?: Record<string, string> | ReadonlyArray<{ label: string; value: string }>;
|
||||
}) {
|
||||
const Root = SelectPrimitive.Root<string>;
|
||||
return (
|
||||
<SelectContext.Provider value={{ triggerRef }}>
|
||||
<SelectPrimitive.Root
|
||||
data-slot="select"
|
||||
onValueChange={handleValueChange}
|
||||
onOpenChange={handleOpenChange}
|
||||
{...props}
|
||||
/>
|
||||
</SelectContext.Provider>
|
||||
<Root
|
||||
data-slot="select"
|
||||
value={value}
|
||||
defaultValue={defaultValue}
|
||||
items={items}
|
||||
onValueChange={onValueChange ? (val) => onValueChange(val as string) : undefined}
|
||||
onOpenChange={onOpenChange ? (open) => onOpenChange(open) : undefined}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function SelectGroup({
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
||||
}: SelectPrimitive.Group.Props) {
|
||||
return <SelectPrimitive.Group data-slot="select-group" {...props} />;
|
||||
}
|
||||
|
||||
function SelectValue({
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
||||
}: SelectPrimitive.Value.Props) {
|
||||
return <SelectPrimitive.Value data-slot="select-value" {...props} />;
|
||||
}
|
||||
|
||||
@@ -65,28 +51,22 @@ function SelectTrigger({
|
||||
size = "default",
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
||||
}: SelectPrimitive.Trigger.Props & {
|
||||
size?: "sm" | "default";
|
||||
}) {
|
||||
const context = React.useContext(SelectContext);
|
||||
|
||||
return (
|
||||
<SelectPrimitive.Trigger
|
||||
ref={context?.triggerRef}
|
||||
data-slot="select-trigger"
|
||||
data-size={size}
|
||||
className={cn(
|
||||
// Essential functionality only - no layout-shifting selectors
|
||||
"[&_svg:not([class*='text-'])]:text-muted-foreground rounded-lg flex items-center justify-between gap-2 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 cursor-pointer",
|
||||
|
||||
// Use only custom styles for visual appearance
|
||||
`input-base input-shadow-default input-state-open`,
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<SelectPrimitive.Icon asChild>
|
||||
<SelectPrimitive.Icon>
|
||||
<ChevronDownIcon className="size-4 opacity-50" />
|
||||
</SelectPrimitive.Icon>
|
||||
</SelectPrimitive.Trigger>
|
||||
@@ -96,43 +76,36 @@ function SelectTrigger({
|
||||
function SelectContent({
|
||||
className,
|
||||
children,
|
||||
position = "popper",
|
||||
onEscapeKeyDown,
|
||||
align = "start",
|
||||
sideOffset = 4,
|
||||
side = "bottom",
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.Content>) {
|
||||
}: SelectPrimitive.Popup.Props & {
|
||||
align?: "start" | "center" | "end";
|
||||
sideOffset?: number;
|
||||
side?: "top" | "bottom" | "left" | "right";
|
||||
}) {
|
||||
return (
|
||||
<SelectPrimitive.Portal>
|
||||
<SelectPrimitive.Content
|
||||
data-slot="select-content"
|
||||
onEscapeKeyDown={(e) => {
|
||||
// Stop propagation to prevent parent dialogs/sheets from closing
|
||||
e.stopPropagation();
|
||||
onEscapeKeyDown?.(e);
|
||||
}}
|
||||
className={cn(
|
||||
// z-[200] to appear above sheets (z-[150])
|
||||
"bg-interactive-secondary text-popover-foreground relative z-[200] max-h-(--radix-select-content-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
||||
|
||||
position === "popper" &&
|
||||
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
||||
|
||||
className,
|
||||
)}
|
||||
position={position}
|
||||
{...props}
|
||||
<SelectPrimitive.Positioner
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
side={side}
|
||||
alignItemWithTrigger={false}
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[200]"
|
||||
>
|
||||
<SelectScrollUpButton />
|
||||
<SelectPrimitive.Viewport
|
||||
<SelectPrimitive.Popup
|
||||
data-slot="select-content"
|
||||
className={cn(
|
||||
"p-1",
|
||||
position === "popper" &&
|
||||
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1",
|
||||
"bg-interactive-secondary text-popover-foreground relative max-h-[var(--available-height)] min-w-[var(--anchor-width)] overflow-x-hidden overflow-y-auto rounded-md border shadow-md p-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</SelectPrimitive.Viewport>
|
||||
<SelectScrollDownButton />
|
||||
</SelectPrimitive.Content>
|
||||
</SelectPrimitive.Popup>
|
||||
</SelectPrimitive.Positioner>
|
||||
</SelectPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
@@ -140,9 +113,9 @@ function SelectContent({
|
||||
function SelectLabel({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
||||
}: SelectPrimitive.GroupLabel.Props) {
|
||||
return (
|
||||
<SelectPrimitive.Label
|
||||
<SelectPrimitive.GroupLabel
|
||||
data-slot="select-label"
|
||||
className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
|
||||
{...props}
|
||||
@@ -154,12 +127,12 @@ function SelectItem({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.Item>) {
|
||||
}: SelectPrimitive.Item.Props) {
|
||||
return (
|
||||
<SelectPrimitive.Item
|
||||
data-slot="select-item"
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-pointer items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
||||
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-pointer items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -169,7 +142,7 @@ function SelectItem({
|
||||
<CheckIcon className="size-4" />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
</span>
|
||||
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||
<SelectPrimitive.ItemText className="flex items-center gap-2">{children}</SelectPrimitive.ItemText>
|
||||
</SelectPrimitive.Item>
|
||||
);
|
||||
}
|
||||
@@ -177,52 +150,19 @@ function SelectItem({
|
||||
function SelectSeparator({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.Separator>) {
|
||||
}: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<SelectPrimitive.Separator
|
||||
<div
|
||||
data-slot="select-separator"
|
||||
className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)}
|
||||
className={cn(
|
||||
"bg-border pointer-events-none -mx-1 my-1 h-px",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function SelectScrollUpButton({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
|
||||
return (
|
||||
<SelectPrimitive.ScrollUpButton
|
||||
data-slot="select-scroll-up-button"
|
||||
className={cn(
|
||||
"flex cursor-default items-center justify-center py-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronUpIcon className="size-4" />
|
||||
</SelectPrimitive.ScrollUpButton>
|
||||
);
|
||||
}
|
||||
|
||||
function SelectScrollDownButton({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
|
||||
return (
|
||||
<SelectPrimitive.ScrollDownButton
|
||||
data-slot="select-scroll-down-button"
|
||||
className={cn(
|
||||
"flex cursor-default items-center justify-center py-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronDownIcon className="size-4" />
|
||||
</SelectPrimitive.ScrollDownButton>
|
||||
);
|
||||
}
|
||||
|
||||
export {
|
||||
Select,
|
||||
SelectContent,
|
||||
|
||||
@@ -97,7 +97,9 @@ export function TagSelect({
|
||||
)}
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>{renderContent?.(setOpen)}</SelectContent>
|
||||
<SelectContent className="w-[var(--anchor-width)] max-w-[var(--anchor-width)]">
|
||||
{renderContent?.(setOpen)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
||||
import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -10,12 +10,15 @@ function Separator({
|
||||
orientation = "horizontal",
|
||||
decorative = true,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
|
||||
}: SeparatorPrimitive.Props & {
|
||||
orientation?: "horizontal" | "vertical";
|
||||
decorative?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<SeparatorPrimitive.Root
|
||||
<SeparatorPrimitive
|
||||
data-slot="separator-root"
|
||||
decorative={decorative}
|
||||
orientation={orientation}
|
||||
data-orientation={orientation}
|
||||
className={cn(
|
||||
"shrink-0 data-[orientation=horizontal]:!h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px bg-border atmn-sep",
|
||||
className,
|
||||
|
||||
@@ -1,31 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
||||
import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
|
||||
import { XIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
|
||||
function Sheet({ ...props }: SheetPrimitive.Root.Props) {
|
||||
return <SheetPrimitive.Root data-slot="sheet" {...props} />;
|
||||
}
|
||||
|
||||
function SheetTrigger({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
|
||||
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
|
||||
}: SheetPrimitive.Trigger.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<SheetPrimitive.Trigger
|
||||
data-slot="sheet-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<SheetPrimitive.Trigger data-slot="sheet-trigger" {...props}>
|
||||
{children}
|
||||
</SheetPrimitive.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
function SheetClose({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
|
||||
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
|
||||
}: SheetPrimitive.Close.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<SheetPrimitive.Close
|
||||
data-slot="sheet-close"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<SheetPrimitive.Close data-slot="sheet-close" {...props}>
|
||||
{children}
|
||||
</SheetPrimitive.Close>
|
||||
);
|
||||
}
|
||||
|
||||
function SheetPortal({
|
||||
container,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Portal> & {
|
||||
}: SheetPrimitive.Portal.Props & {
|
||||
container?: HTMLElement | null;
|
||||
}) {
|
||||
const resolvedContainer =
|
||||
@@ -33,7 +63,7 @@ function SheetPortal({
|
||||
return (
|
||||
<SheetPrimitive.Portal
|
||||
data-slot="sheet-portal"
|
||||
container={resolvedContainer ?? undefined}
|
||||
container={resolvedContainer as HTMLElement | undefined}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -42,12 +72,12 @@ function SheetPortal({
|
||||
function SheetOverlay({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
|
||||
}: SheetPrimitive.Backdrop.Props) {
|
||||
return (
|
||||
<SheetPrimitive.Overlay
|
||||
<SheetPrimitive.Backdrop
|
||||
data-slot="sheet-overlay"
|
||||
className={cn(
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-[150] bg-white/70 dark:bg-black/70",
|
||||
"fixed inset-0 z-[150] bg-white/70 dark:bg-black/70 transition-opacity duration-300 data-[starting-style]:opacity-0 data-[ending-style]:opacity-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -55,6 +85,13 @@ function SheetOverlay({
|
||||
);
|
||||
}
|
||||
|
||||
const SIDE_STYLES = {
|
||||
right: "top-0 bottom-0 right-0 w-full md:min-w-xs md:max-w-md md:border-l border-border/40 translate-x-0 data-[starting-style]:translate-x-full data-[ending-style]:translate-x-full",
|
||||
left: "top-0 bottom-0 left-0 w-3/4 border-r border-border/40 sm:max-w-sm translate-x-0 data-[starting-style]:-translate-x-full data-[ending-style]:-translate-x-full",
|
||||
top: "left-0 right-0 top-0 h-auto border-b border-border/40 translate-y-0 data-[starting-style]:-translate-y-full data-[ending-style]:-translate-y-full",
|
||||
bottom: "left-0 right-0 bottom-0 h-auto border-t border-border/40 translate-y-0 data-[starting-style]:translate-y-full data-[ending-style]:translate-y-full",
|
||||
} as const;
|
||||
|
||||
function SheetContent({
|
||||
className,
|
||||
children,
|
||||
@@ -62,7 +99,7 @@ function SheetContent({
|
||||
hideCloseButton = false,
|
||||
portalContainer,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
|
||||
}: SheetPrimitive.Popup.Props & {
|
||||
side?: "top" | "right" | "bottom" | "left";
|
||||
hideCloseButton?: boolean;
|
||||
portalContainer?: HTMLElement | null;
|
||||
@@ -70,30 +107,23 @@ function SheetContent({
|
||||
return (
|
||||
<SheetPortal container={portalContainer}>
|
||||
<SheetOverlay />
|
||||
<SheetPrimitive.Content
|
||||
<SheetPrimitive.Popup
|
||||
data-slot="sheet-content"
|
||||
className={cn(
|
||||
"bg-card data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-[150] flex flex-col gap-0 shadow-sm transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-300",
|
||||
side === "right" &&
|
||||
`data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right top-0 bottom-0 right-0 w-full md:min-w-xs md:max-w-md md:border-l border-border/40`,
|
||||
side === "left" &&
|
||||
`data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left top-0 bottom-0 left-0 w-3/4 border-r border-border/40 sm:max-w-sm`,
|
||||
side === "top" &&
|
||||
"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top left-0 right-0 top-0 h-auto border-b border-border/40",
|
||||
side === "bottom" &&
|
||||
"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom left-0 right-0 bottom-0 h-auto border-t border-border/40",
|
||||
"bg-card fixed z-[150] flex flex-col gap-0 shadow-sm overflow-hidden transition-transform duration-300 ease-in-out",
|
||||
SIDE_STYLES[side],
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
{!hideCloseButton && (
|
||||
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-3 right-3 md:top-4 md:right-4 flex items-center justify-center size-10 md:size-auto rounded-sm md:rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
|
||||
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-open:bg-secondary absolute top-3 right-3 md:top-4 md:right-4 flex items-center justify-center size-10 md:size-auto rounded-sm md:rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
|
||||
<XIcon className="size-5 md:size-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</SheetPrimitive.Close>
|
||||
)}
|
||||
</SheetPrimitive.Content>
|
||||
</SheetPrimitive.Popup>
|
||||
</SheetPortal>
|
||||
);
|
||||
}
|
||||
@@ -121,7 +151,7 @@ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
|
||||
function SheetTitle({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
|
||||
}: SheetPrimitive.Title.Props) {
|
||||
return (
|
||||
<SheetPrimitive.Title
|
||||
data-slot="sheet-title"
|
||||
@@ -134,7 +164,7 @@ function SheetTitle({
|
||||
function SheetDescription({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof SheetPrimitive.Description>) {
|
||||
}: SheetPrimitive.Description.Props) {
|
||||
return (
|
||||
<SheetPrimitive.Description
|
||||
data-slot="sheet-description"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
||||
import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
|
||||
import { ChevronDownIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import { Separator } from "@/components/v2/separator";
|
||||
@@ -22,13 +22,12 @@ function SheetAccordion({
|
||||
collapsible = true,
|
||||
...props
|
||||
}: SheetAccordionProps &
|
||||
Omit<React.ComponentProps<typeof AccordionPrimitive.Root>, "type">) {
|
||||
Omit<AccordionPrimitive.Root.Props, "type">) {
|
||||
return (
|
||||
<>
|
||||
<AccordionPrimitive.Root
|
||||
type={type as any}
|
||||
defaultValue={defaultValue}
|
||||
collapsible={collapsible}
|
||||
multiple={type === "multiple"}
|
||||
defaultValue={defaultValue as any}
|
||||
className="w-full"
|
||||
{...props}
|
||||
>
|
||||
@@ -61,7 +60,7 @@ function SheetAccordionItem({
|
||||
return (
|
||||
<AccordionPrimitive.Item value={value} className={cn("", className)}>
|
||||
<AccordionPrimitive.Header className="flex">
|
||||
<AccordionPrimitive.Trigger className="flex flex-1 items-start justify-between gap-4 px-4 py-3 text-left transition-all outline-none focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180 hover:bg-accent/50">
|
||||
<AccordionPrimitive.Trigger className="flex flex-1 items-start justify-between gap-4 px-4 py-3 text-left transition-all outline-none focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&[aria-expanded=true]>svg]:rotate-180 hover:bg-accent/50">
|
||||
<div className="flex flex-col gap-1">
|
||||
<h3 className="text-sm font-medium">{title}</h3>
|
||||
{description && (
|
||||
@@ -71,9 +70,9 @@ function SheetAccordionItem({
|
||||
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
|
||||
</AccordionPrimitive.Trigger>
|
||||
</AccordionPrimitive.Header>
|
||||
<AccordionPrimitive.Content className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden">
|
||||
<AccordionPrimitive.Panel className="data-closed:animate-accordion-up data-open:animate-accordion-down overflow-hidden">
|
||||
<div className="px-4 pb-4 pt-2">{children}</div>
|
||||
</AccordionPrimitive.Content>
|
||||
</AccordionPrimitive.Panel>
|
||||
</AccordionPrimitive.Item>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,56 +1,84 @@
|
||||
"use client";
|
||||
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||
import type * as React from "react";
|
||||
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
||||
import * as React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function TooltipProvider({
|
||||
delayDuration = 0,
|
||||
delay = 0,
|
||||
...props
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
||||
}: TooltipPrimitive.Provider.Props) {
|
||||
return (
|
||||
<TooltipPrimitive.Provider
|
||||
data-slot="tooltip-provider"
|
||||
delayDuration={delayDuration}
|
||||
delay={delay}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function Tooltip({
|
||||
delayDuration,
|
||||
...props
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
||||
}: TooltipPrimitive.Root.Props & { delayDuration?: number }) {
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<TooltipProvider delay={delayDuration}>
|
||||
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function TooltipTrigger({
|
||||
asChild,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
||||
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
||||
}: TooltipPrimitive.Trigger.Props & { asChild?: boolean }) {
|
||||
if (asChild && React.isValidElement(children)) {
|
||||
return (
|
||||
<TooltipPrimitive.Trigger
|
||||
data-slot="tooltip-trigger"
|
||||
render={children}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props}>
|
||||
{children}
|
||||
</TooltipPrimitive.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
function TooltipContent({
|
||||
className,
|
||||
sideOffset = 6,
|
||||
side = "top",
|
||||
align = "center",
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
|
||||
}: TooltipPrimitive.Popup.Props &
|
||||
Pick<
|
||||
TooltipPrimitive.Positioner.Props,
|
||||
"align" | "side" | "sideOffset"
|
||||
>) {
|
||||
return (
|
||||
<TooltipPrimitive.Portal>
|
||||
<TooltipPrimitive.Content
|
||||
data-slot="tooltip-content"
|
||||
<TooltipPrimitive.Positioner
|
||||
side={side}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
`z-[200] overflow-hidden rounded-[6px] px-2 py-[3px] text-t2 border
|
||||
align={align}
|
||||
positionMethod="fixed"
|
||||
className="isolate z-[200]"
|
||||
>
|
||||
<TooltipPrimitive.Popup
|
||||
data-slot="tooltip-content"
|
||||
className={cn(
|
||||
`overflow-hidden rounded-[6px] px-2 py-[3px] text-t2 border
|
||||
bg-interactive-secondary dark:bg-card
|
||||
text-[13px] font-medium leading-[1.6] tracking-[-0.039px]
|
||||
shadow-[0px_0px_4px_2px_rgba(0,0,0,0.05)]
|
||||
animate-in fade-in-0 zoom-in-95
|
||||
data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95
|
||||
data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95
|
||||
data-[side=bottom]:slide-in-from-top-2
|
||||
data-[side=left]:slide-in-from-right-2
|
||||
data-[side=right]:slide-in-from-left-2
|
||||
@@ -69,12 +97,13 @@ function TooltipContent({
|
||||
before:data-[side=right]:border-t-[7px] before:data-[side=right]:border-b-[7px] before:data-[side=right]:border-r-[6px]
|
||||
before:data-[side=right]:border-t-transparent before:data-[side=right]:border-b-transparent before:data-[side=right]:border-r-t12
|
||||
`,
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TooltipPrimitive.Content>
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TooltipPrimitive.Popup>
|
||||
</TooltipPrimitive.Positioner>
|
||||
</TooltipPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
|
||||
37
vite/src/hooks/useControllableState.ts
Normal file
37
vite/src/hooks/useControllableState.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
|
||||
type UseControllableStateParams<T> = {
|
||||
prop?: T;
|
||||
defaultProp?: T;
|
||||
onChange?: (value: T) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Manages state that can be either controlled or uncontrolled.
|
||||
* Replacement for @radix-ui/react-use-controllable-state.
|
||||
*/
|
||||
function useControllableState<T>({
|
||||
prop,
|
||||
defaultProp,
|
||||
onChange,
|
||||
}: UseControllableStateParams<T>): [T | undefined, (value: T) => void] {
|
||||
const [uncontrolled, setUncontrolled] = useState(defaultProp);
|
||||
const isControlled = prop !== undefined;
|
||||
const value = isControlled ? prop : uncontrolled;
|
||||
const onChangeRef = useRef(onChange);
|
||||
onChangeRef.current = onChange;
|
||||
|
||||
const setValue = useCallback(
|
||||
(nextValue: T) => {
|
||||
if (!isControlled) {
|
||||
setUncontrolled(nextValue);
|
||||
}
|
||||
onChangeRef.current?.(nextValue);
|
||||
},
|
||||
[isControlled],
|
||||
);
|
||||
|
||||
return [value, setValue];
|
||||
}
|
||||
|
||||
export { useControllableState };
|
||||
@@ -368,13 +368,13 @@ html {
|
||||
height: 0;
|
||||
}
|
||||
to {
|
||||
height: var(--radix-accordion-content-height);
|
||||
height: var(--accordion-panel-height);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes accordion-up {
|
||||
from {
|
||||
height: var(--radix-accordion-content-height);
|
||||
height: var(--accordion-panel-height);
|
||||
}
|
||||
to {
|
||||
height: 0;
|
||||
@@ -412,6 +412,7 @@ input[type="number"]::-webkit-inner-spin-button {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
letter-spacing: -0.033px;
|
||||
|
||||
@@ -136,10 +136,11 @@ export function RedisV2CacheDialog({
|
||||
<div className="text-xs font-medium uppercase tracking-wide text-t3">
|
||||
Active Instance
|
||||
</div>
|
||||
<Select
|
||||
value={selected}
|
||||
onValueChange={(value) => setSelected(value as InstanceName)}
|
||||
>
|
||||
<Select
|
||||
value={selected}
|
||||
onValueChange={(value) => setSelected(value as InstanceName)}
|
||||
items={Object.fromEntries(INSTANCE_OPTIONS.map((option) => [option.value, option.label]))}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -225,11 +225,12 @@ export function BalanceCreateSheet() {
|
||||
<div>
|
||||
<FormLabel>Interval</FormLabel>
|
||||
<div className="flex items-center gap-2">
|
||||
<Select
|
||||
value={oneOff ? undefined : resetInterval}
|
||||
onValueChange={setResetInterval}
|
||||
disabled={oneOff}
|
||||
>
|
||||
<Select
|
||||
value={oneOff ? undefined : resetInterval}
|
||||
onValueChange={setResetInterval}
|
||||
disabled={oneOff}
|
||||
items={RESET_INTERVAL_LABELS}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="None" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -365,10 +365,14 @@ export function BillingAutoTopupSheet() {
|
||||
<div className="flex flex-col gap-3">
|
||||
<div>
|
||||
<FormLabel>Interval</FormLabel>
|
||||
<Select
|
||||
value={purchaseLimitInterval}
|
||||
onValueChange={setPurchaseLimitInterval}
|
||||
>
|
||||
<Select
|
||||
value={purchaseLimitInterval}
|
||||
onValueChange={setPurchaseLimitInterval}
|
||||
items={Object.fromEntries(Object.entries(INTERVAL_LABELS).map(([value, label]) => {
|
||||
const count = Number.parseInt(purchaseLimitIntervalCount, 10);
|
||||
return [value, count > 1 ? `Every ${count} ${label.toLowerCase()}s` : label];
|
||||
}))}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select interval" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -270,7 +270,7 @@ export function BillingUsageAlertSheet() {
|
||||
|
||||
<div>
|
||||
<FormLabel>Threshold type</FormLabel>
|
||||
<Select value={thresholdType} onValueChange={setThresholdType}>
|
||||
<Select value={thresholdType} onValueChange={setThresholdType} items={{ usage: "Usage (absolute value)", usage_percentage: "Percentage used of allowance", remaining: "Remaining (absolute value)", remaining_percentage: "Percentage remaining of allowance" }}>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -484,7 +484,7 @@ function LineItemGroupRow({
|
||||
const paidAmount = firstItem.amount_after_discounts ?? firstItem.amount;
|
||||
|
||||
return (
|
||||
<AdminHover asChild texts={getLineItemHoverTexts(firstItem)}>
|
||||
<AdminHover texts={getLineItemHoverTexts(firstItem)}>
|
||||
<div className="flex flex-col py-1">
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div className="flex flex-col min-w-0 flex-1 gap-0.5">
|
||||
@@ -563,7 +563,7 @@ function TierRow({
|
||||
const isRefund = item.direction === "refund";
|
||||
|
||||
return (
|
||||
<AdminHover asChild texts={hoverTexts}>
|
||||
<AdminHover texts={hoverTexts}>
|
||||
<div className="flex items-center justify-between text-xs text-t3">
|
||||
<span>{item.description}</span>
|
||||
<span
|
||||
|
||||
@@ -72,7 +72,7 @@ export const getCustomerInvoicesColumns = ({
|
||||
cell: ({ row }: { row: Row<CustomerInvoice> }) => {
|
||||
return (
|
||||
<div className="min-w-0 max-w-full" title={row.original.productNames}>
|
||||
<AdminHover asChild texts={getInvoiceHoverTexts({ invoice: row.original })}>
|
||||
<AdminHover texts={getInvoiceHoverTexts({ invoice: row.original })}>
|
||||
<span className="block max-w-full truncate">
|
||||
{row.original.productNames}
|
||||
</span>
|
||||
|
||||
@@ -43,19 +43,17 @@ export function CustomerListFilterButton() {
|
||||
|
||||
return (
|
||||
<DropdownMenu open={open} onOpenChange={setOpen}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<div className="relative">
|
||||
<IconButton
|
||||
variant="secondary"
|
||||
className={cn("gap-2", open && "btn-secondary-active")}
|
||||
icon={<FunnelSimpleIcon size={14} className="text-t3" />}
|
||||
>
|
||||
Filter
|
||||
</IconButton>
|
||||
{hasActiveFilters && (
|
||||
<span className="absolute top-0 right-0 h-2.5 w-2.5 translate-x-1/3 -translate-y-1/3 rounded-full bg-primary" />
|
||||
)}
|
||||
</div>
|
||||
<DropdownMenuTrigger render={<div className="relative" />} nativeButton={false}>
|
||||
<IconButton
|
||||
variant="secondary"
|
||||
className={cn("gap-2", open && "btn-secondary-active")}
|
||||
icon={<FunnelSimpleIcon size={14} className="text-t3" />}
|
||||
>
|
||||
Filter
|
||||
</IconButton>
|
||||
{hasActiveFilters && (
|
||||
<span className="absolute top-0 right-0 h-2.5 w-2.5 translate-x-1/3 -translate-y-1/3 rounded-full bg-primary" />
|
||||
)}
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className="w-56 font-regular gap-0 p-0"
|
||||
|
||||
@@ -92,6 +92,7 @@ export function CustomerListPageSizeSelector() {
|
||||
page: 1,
|
||||
});
|
||||
}}
|
||||
items={Object.fromEntries(PAGE_SIZE_OPTIONS.map((size) => [size.toString(), size.toString()]))}
|
||||
>
|
||||
<SelectTrigger className="h-7 w-fit px-2 text-xs">
|
||||
<SelectValue />
|
||||
|
||||
@@ -104,7 +104,14 @@ export const TransferProductDialog = ({
|
||||
: "Transfer this plan to an entity."}
|
||||
</p>
|
||||
|
||||
<Select value={selectedValue} onValueChange={setSelectedValue}>
|
||||
<Select
|
||||
value={selectedValue}
|
||||
onValueChange={setSelectedValue}
|
||||
items={{
|
||||
...(isOnEntity ? { [CUSTOMER_LEVEL_VALUE]: "Move to Customer" } : {}),
|
||||
...Object.fromEntries(filteredEntities.map((entity: Entity) => [entity.id, entity.name || entity.id || entity.internal_id])),
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select destination" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -113,19 +113,20 @@ export const AddCouponDialog = ({
|
||||
</InfoBox>
|
||||
)}
|
||||
<div className="space-y-3">
|
||||
<Select
|
||||
value={couponSelected?.internal_id}
|
||||
onValueChange={(value) => {
|
||||
const coupon = rewards.find(
|
||||
(c: Reward) => c.internal_id === value,
|
||||
);
|
||||
<Select
|
||||
value={couponSelected?.internal_id}
|
||||
onValueChange={(value) => {
|
||||
const coupon = rewards.find(
|
||||
(c: Reward) => c.internal_id === value,
|
||||
);
|
||||
|
||||
if (!coupon) return;
|
||||
if (!coupon) return;
|
||||
|
||||
setCouponSelected(coupon);
|
||||
setPromoCodeSelected(null);
|
||||
}}
|
||||
>
|
||||
setCouponSelected(coupon);
|
||||
setPromoCodeSelected(null);
|
||||
}}
|
||||
items={Object.fromEntries(rewards.filter((c: Reward) => c.type !== RewardType.FreeProduct).map((c: Reward) => [c.internal_id, c.name]))}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select Reward" />
|
||||
</SelectTrigger>
|
||||
@@ -151,10 +152,11 @@ export const AddCouponDialog = ({
|
||||
</Select>
|
||||
|
||||
{couponSelected?.type === RewardType.FeatureGrant && (
|
||||
<Select
|
||||
value={promoCodeSelected || undefined}
|
||||
onValueChange={setPromoCodeSelected}
|
||||
>
|
||||
<Select
|
||||
value={promoCodeSelected || undefined}
|
||||
onValueChange={setPromoCodeSelected}
|
||||
items={Object.fromEntries(promoCodeOptions.map((promoCode) => [promoCode.code, promoCode.code]))}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select Promo Code" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -131,12 +131,13 @@ export const CreateEntity = ({
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-form-label block mb-1">Feature ID</div>
|
||||
<Select
|
||||
value={entity.feature_id}
|
||||
onValueChange={(value) =>
|
||||
setEntity({ ...entity, feature_id: value })
|
||||
}
|
||||
>
|
||||
<Select
|
||||
value={entity.feature_id}
|
||||
onValueChange={(value) =>
|
||||
setEntity({ ...entity, feature_id: value })
|
||||
}
|
||||
items={Object.fromEntries(continuousFeatures.map((feature: Feature) => [feature.id, feature.name]))}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select feature" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -106,14 +106,15 @@ const MappingRow = memo(function MappingRow({
|
||||
an existing mapping to change assignments.
|
||||
</div>
|
||||
) : (
|
||||
<Select
|
||||
value=""
|
||||
onValueChange={(value) => {
|
||||
if (value) {
|
||||
onAddProduct(mapping.autumnProductId, value);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
value=""
|
||||
onValueChange={(value) => {
|
||||
if (value) {
|
||||
onAddProduct(mapping.autumnProductId, value);
|
||||
}
|
||||
}}
|
||||
items={Object.fromEntries(availableProducts.map((product) => [product.id, product.name]))}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Add product..." />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -333,7 +333,7 @@ export const ConfigureVercel = () => {
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center justify-between w-full">
|
||||
<span className="truncate">{option.label}</span>
|
||||
<span className="truncate max-w-full">{option.label}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -45,16 +45,14 @@ export const CollapsibleNavGroup = ({
|
||||
if (!expanded) {
|
||||
return (
|
||||
<DropdownMenu open={dropdownOpen} onOpenChange={setDropdownOpen}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<div>
|
||||
<NavButton
|
||||
value={value}
|
||||
icon={icon}
|
||||
title={title}
|
||||
env={env}
|
||||
isGroup
|
||||
/>
|
||||
</div>
|
||||
<DropdownMenuTrigger render={<div />} nativeButton={false}>
|
||||
<NavButton
|
||||
value={value}
|
||||
icon={icon}
|
||||
title={title}
|
||||
env={env}
|
||||
isGroup
|
||||
/>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
side="right"
|
||||
|
||||
@@ -22,16 +22,14 @@ export function SidebarContact() {
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<div>
|
||||
<NavButton
|
||||
env={env}
|
||||
value="chat"
|
||||
icon={<QuestionIcon size={16} weight="duotone" />}
|
||||
title="Need help?"
|
||||
onClick={() => {}}
|
||||
/>
|
||||
</div>
|
||||
<DropdownMenuTrigger render={<div />} nativeButton={false}>
|
||||
<NavButton
|
||||
env={env}
|
||||
value="chat"
|
||||
icon={<QuestionIcon size={16} weight="duotone" />}
|
||||
title="Need help?"
|
||||
onClick={() => {}}
|
||||
/>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent side="top" align="start">
|
||||
<span className="text-xs text-t3 p-2">
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/v2/dialogs/Dialog";
|
||||
import { Input } from "@/components/v2/inputs/Input";
|
||||
import { useOrg } from "@/hooks/common/useOrg";
|
||||
@@ -64,7 +63,6 @@ export const CreateNewOrg = ({
|
||||
if (!open) setDialogType(null);
|
||||
}}
|
||||
>
|
||||
<DialogTrigger asChild></DialogTrigger>
|
||||
<DialogContent className="gap-0 p-0 rounded-xs min-w-[400px]">
|
||||
<div className="p-6 flex flex-col gap-4">
|
||||
<DialogHeader>
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/v2/dialogs/Dialog";
|
||||
import { InvitePopover } from "../org-dropdown/manage-org/InvitePopover";
|
||||
import { OrgInvitesList } from "../org-dropdown/manage-org/OrgInvitesList";
|
||||
@@ -29,7 +28,6 @@ export const ManageOrg = ({
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild></DialogTrigger>
|
||||
<DialogContent className="gap-0 p-0 rounded-xs w-[90%] max-w-[750px] h-[550px] flex flex-col justify-between">
|
||||
<div className="flex flex-col gap-6 overflow-hidden h-full">
|
||||
<DialogHeader className="px-6 pt-6">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DropdownMenuGroup } from "@radix-ui/react-dropdown-menu";
|
||||
import { DropdownMenuGroup } from "@/components/v2/dropdowns/DropdownMenu";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
ChevronDown,
|
||||
@@ -49,10 +49,10 @@ export const OrgDropdown = () => {
|
||||
const { expanded, setExpanded } = useSidebarContext();
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
let { data: orgs } = useListOrganizations();
|
||||
const { data: orgsData } = useListOrganizations();
|
||||
let orgs = Array.isArray(orgsData) ? orgsData : undefined;
|
||||
const { data: activeOrganization } = authClient.useActiveOrganization();
|
||||
|
||||
// Exclude the active organization from the orgs list (this makes it easier for users to understand which org is active)
|
||||
if (activeOrganization && orgs) {
|
||||
orgs = orgs.filter((o) => o.id !== activeOrganization.id);
|
||||
}
|
||||
|
||||
@@ -50,24 +50,21 @@ export function FeatureSelectDropdown({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"flex items-center justify-between w-full rounded-lg border bg-transparent text-sm outline-none h-input input-base input-shadow-default input-state-open p-2",
|
||||
)}
|
||||
>
|
||||
{selectedFeature ? (
|
||||
<span className="truncate">{selectedFeature.name}</span>
|
||||
) : (
|
||||
<span className="text-t4">Select feature</span>
|
||||
)}
|
||||
<CaretDownIcon className="size-4 opacity-50 shrink-0" />
|
||||
</button>
|
||||
<DropdownMenuTrigger
|
||||
className={cn(
|
||||
"flex items-center justify-between w-full rounded-lg border bg-transparent text-sm outline-none h-input input-base input-shadow-default input-state-open p-2",
|
||||
)}
|
||||
>
|
||||
{selectedFeature ? (
|
||||
<span className="truncate">{selectedFeature.name}</span>
|
||||
) : (
|
||||
<span className="text-t4">Select feature</span>
|
||||
)}
|
||||
<CaretDownIcon className="size-4 opacity-50 shrink-0" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
align="start"
|
||||
className="min-w-[var(--radix-dropdown-menu-trigger-width)] z-200"
|
||||
className="min-w-[var(--anchor-width)] z-200"
|
||||
onCloseAutoFocus={(e) => e.preventDefault()}
|
||||
>
|
||||
{showCreateForm ? (
|
||||
|
||||
@@ -228,10 +228,11 @@ export const DeletePlanDialog = ({
|
||||
{productInfo.numVersion > 1 &&
|
||||
!product.archived &&
|
||||
!productInfo.hasCusProductsLatest && (
|
||||
<Select
|
||||
value={deleteAllVersions ? "all" : "latest"}
|
||||
onValueChange={(value) => setDeleteAllVersions(value === "all")}
|
||||
>
|
||||
<Select
|
||||
value={deleteAllVersions ? "all" : "latest"}
|
||||
onValueChange={(value) => setDeleteAllVersions(value === "all")}
|
||||
items={{ latest: "Delete latest version", all: "Archive plan" }}
|
||||
>
|
||||
<SelectTrigger className="w-6/12">
|
||||
<SelectValue placeholder="Select a version" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -241,10 +241,11 @@ export const EditPlanHeader = () => {
|
||||
)}
|
||||
|
||||
{numVersions && numVersions > 1 && (
|
||||
<Select
|
||||
value={currentVersion.toString()}
|
||||
onValueChange={handleVersionChange}
|
||||
>
|
||||
<Select
|
||||
value={currentVersion.toString()}
|
||||
onValueChange={handleVersionChange}
|
||||
items={Object.fromEntries(versionOptions.map((version) => [version.toString(), `Version ${version}`]))}
|
||||
>
|
||||
<SelectTrigger className="w-fit min-w-28 !h-6" size="sm">
|
||||
<SelectValue placeholder="Version" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -13,7 +13,7 @@ export function EditPlanPriceSheet({
|
||||
if (!product) return null;
|
||||
|
||||
return (
|
||||
<div className="h-full overflow-y-auto [scrollbar-gutter:stable]">
|
||||
<div className="h-full overflow-y-auto overscroll-none [scrollbar-gutter:stable]">
|
||||
{!isOnboarding && (
|
||||
<SheetHeader
|
||||
title={`Configure ${product.name ? `${product.name} ` : ""}Price`}
|
||||
|
||||
@@ -25,7 +25,7 @@ export function EditPlanSheet({ isOnboarding }: { isOnboarding?: boolean }) {
|
||||
product.basePriceType !== "usage";
|
||||
|
||||
return (
|
||||
<div className="h-full overflow-y-auto [scrollbar-gutter:stable]">
|
||||
<div className="h-full overflow-y-auto overscroll-none [scrollbar-gutter:stable]">
|
||||
{!isOnboarding && (
|
||||
<SheetHeader
|
||||
title={`Configure ${product.name ? product.name : "your new plan"}`}
|
||||
|
||||
@@ -53,21 +53,22 @@ export const FreeTrialSection = () => {
|
||||
placeholder="eg. 7"
|
||||
/>
|
||||
{/* <FormLabel disabled={!product.free_trial}>Duration</FormLabel> */}
|
||||
<Select
|
||||
disabled={!product.free_trial}
|
||||
value={product.free_trial?.duration || ""}
|
||||
onValueChange={(value) => {
|
||||
setProduct({
|
||||
...product,
|
||||
free_trial: product.free_trial
|
||||
? {
|
||||
...product.free_trial,
|
||||
duration: value as FreeTrialDuration,
|
||||
}
|
||||
: null,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
disabled={!product.free_trial}
|
||||
value={product.free_trial?.duration || ""}
|
||||
onValueChange={(value) => {
|
||||
setProduct({
|
||||
...product,
|
||||
free_trial: product.free_trial
|
||||
? {
|
||||
...product.free_trial,
|
||||
duration: value as FreeTrialDuration,
|
||||
}
|
||||
: null,
|
||||
});
|
||||
}}
|
||||
items={Object.fromEntries(Object.values(FreeTrialDuration).map((duration) => [duration, `${duration}s`]))}
|
||||
>
|
||||
<SelectTrigger className="w-full max-w-32">
|
||||
<SelectValue placeholder="days" />{" "}
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -30,20 +30,25 @@ export const SelectBillingCycle = ({
|
||||
return (
|
||||
<div className="w-full">
|
||||
<FormLabel disabled={disabled}>Billing Interval</FormLabel>
|
||||
<Select
|
||||
disabled={disabled}
|
||||
value={item ? itemToBillingInterval({ item }) : BillingInterval.Month}
|
||||
defaultValue={BillingInterval.Month}
|
||||
onValueChange={(value) => {
|
||||
if (!item) return;
|
||||
setItem({
|
||||
...item,
|
||||
interval: billingToItemInterval({
|
||||
billingInterval: value as BillingInterval,
|
||||
}),
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
disabled={disabled}
|
||||
value={item ? itemToBillingInterval({ item }) : BillingInterval.Month}
|
||||
defaultValue={BillingInterval.Month}
|
||||
onValueChange={(value) => {
|
||||
if (!item) return;
|
||||
setItem({
|
||||
...item,
|
||||
interval: billingToItemInterval({
|
||||
billingInterval: value as BillingInterval,
|
||||
}),
|
||||
});
|
||||
}}
|
||||
items={Object.fromEntries(
|
||||
Object.values(BillingInterval)
|
||||
.filter((interval) => !filterOneOff || interval !== BillingInterval.OneOff)
|
||||
.map((interval) => [interval, formatIntervalText({ billingInterval: interval, intervalCount: item?.interval_count || 1, isBillingInterval: true })])
|
||||
)}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select interval" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -129,7 +129,7 @@ export function EditPlanFeatureSheet({
|
||||
return (
|
||||
<div className="flex flex-col h-full overflow-hidden">
|
||||
{/* Scrollable content area */}
|
||||
<div className="flex-1 overflow-y-auto [scrollbar-gutter:stable]">
|
||||
<div className="flex-1 overflow-y-auto overscroll-none [scrollbar-gutter:stable]">
|
||||
{!isOnboarding && (
|
||||
<SheetHeader
|
||||
title={`Configure ${feature?.name}`}
|
||||
|
||||
@@ -61,7 +61,7 @@ export function PriceSectionTitle({
|
||||
</IconCheckbox>
|
||||
</div>
|
||||
)}
|
||||
<Select value={tierBehavior} onValueChange={onTierBehaviorChange}>
|
||||
<Select value={tierBehavior} onValueChange={onTierBehaviorChange} items={{ [TierBehavior.Graduated]: "Graduated", [TierBehavior.VolumeBased]: "Volume-based" }}>
|
||||
<SelectTrigger className="w-32 h-6 text-xs!" size="sm">
|
||||
<SelectValue>
|
||||
{tierBehavior === TierBehavior.VolumeBased ? (
|
||||
|
||||
@@ -95,11 +95,12 @@ export function UsageReset({ showBillingLabel = false }: UsageResetProps) {
|
||||
<div className={showBillingLabel ? "mt-3" : ""}>
|
||||
<FormLabel>Interval</FormLabel>
|
||||
<div className="flex items-center gap-2">
|
||||
<Select
|
||||
value={isSelectDisabled ? undefined : intervalValue}
|
||||
onValueChange={handleIntervalChange}
|
||||
disabled={isSelectDisabled}
|
||||
>
|
||||
<Select
|
||||
value={isSelectDisabled ? undefined : intervalValue}
|
||||
onValueChange={handleIntervalChange}
|
||||
disabled={isSelectDisabled}
|
||||
items={Object.fromEntries(availableIntervals.map((interval) => [interval, formatIntervalText({ billingInterval: interval, intervalCount: item.interval_count || undefined, isBillingInterval: true })]))}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="None" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -43,15 +43,16 @@ export function EntityFeatureConfig() {
|
||||
<FormLabel>
|
||||
Link this item to a specific feature entity in your app
|
||||
</FormLabel>
|
||||
<Select
|
||||
value={item.entity_feature_id || undefined}
|
||||
onValueChange={(value) => {
|
||||
setItem({
|
||||
...item,
|
||||
entity_feature_id: value,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
value={item.entity_feature_id || undefined}
|
||||
onValueChange={(value) => {
|
||||
setItem({
|
||||
...item,
|
||||
entity_feature_id: value,
|
||||
});
|
||||
}}
|
||||
items={Object.fromEntries(continuousUseFeatures.map((feature) => [feature.id, feature.name]))}
|
||||
>
|
||||
<SelectTrigger
|
||||
className="w-xs max-w-full"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
|
||||
@@ -101,15 +101,16 @@ export function ProrationConfig() {
|
||||
<div className="space-y-4 w-xs max-w-full">
|
||||
<div className="space-y-2 w-full">
|
||||
<FormLabel>{increaseText}</FormLabel>
|
||||
<Select
|
||||
value={onIncreaseValue}
|
||||
onValueChange={(value) => {
|
||||
setItem({
|
||||
...item,
|
||||
config: { ...item.config, on_increase: value as OnIncrease },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
value={onIncreaseValue}
|
||||
onValueChange={(value) => {
|
||||
setItem({
|
||||
...item,
|
||||
config: { ...item.config, on_increase: value as OnIncrease },
|
||||
});
|
||||
}}
|
||||
items={Object.fromEntries(onIncreaseOptions.map((option) => [option, getOnIncreaseText(option)]))}
|
||||
>
|
||||
<SelectTrigger
|
||||
className="w-full [&>span]:truncate"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
@@ -128,15 +129,16 @@ export function ProrationConfig() {
|
||||
|
||||
<div className="space-y-2 w-full">
|
||||
<FormLabel>{decreaseText}</FormLabel>
|
||||
<Select
|
||||
value={onDecreaseValue}
|
||||
onValueChange={(value) => {
|
||||
setItem({
|
||||
...item,
|
||||
config: { ...item.config, on_decrease: value as OnDecrease },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
value={onDecreaseValue}
|
||||
onValueChange={(value) => {
|
||||
setItem({
|
||||
...item,
|
||||
config: { ...item.config, on_decrease: value as OnDecrease },
|
||||
});
|
||||
}}
|
||||
items={Object.fromEntries([OnDecrease.Prorate, OnDecrease.None].map((option) => [option, getOnDecreaseText({ option, usageModel: item.usage_model ?? UsageModel.Prepaid })]))}
|
||||
>
|
||||
<SelectTrigger
|
||||
className="w-full [&>span]:truncate"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
|
||||
@@ -95,10 +95,11 @@ export function RolloverConfigForm({
|
||||
<div className="space-y-2 w-full">
|
||||
<FormLabel>Maximum rollover</FormLabel>
|
||||
<div className="flex items-center gap-2">
|
||||
<Select
|
||||
value={maxMode}
|
||||
onValueChange={(v) => handleMaxModeChange(v as MaxMode)}
|
||||
>
|
||||
<Select
|
||||
value={maxMode}
|
||||
onValueChange={(v) => handleMaxModeChange(v as MaxMode)}
|
||||
items={{ unlimited: "Unlimited", absolute: "Absolute", percentage: "Percentage" }}
|
||||
>
|
||||
<SelectTrigger
|
||||
className="w-32"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
@@ -170,15 +171,16 @@ export function RolloverConfigForm({
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
)}
|
||||
<Select
|
||||
value={rollover?.duration}
|
||||
onValueChange={(v) => {
|
||||
setRolloverConfigKey(
|
||||
"duration",
|
||||
v as RolloverExpiryDurationType,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
value={rollover?.duration}
|
||||
onValueChange={(v) => {
|
||||
setRolloverConfigKey(
|
||||
"duration",
|
||||
v as RolloverExpiryDurationType,
|
||||
);
|
||||
}}
|
||||
items={Object.fromEntries(Object.values(RolloverExpiryDurationType).map((duration) => [duration, duration]))}
|
||||
>
|
||||
<SelectTrigger
|
||||
className="flex-1"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/v2/dialogs/Dialog";
|
||||
import { Input } from "@/components/v2/inputs/Input";
|
||||
import { useProductsQuery } from "@/hooks/queries/useProductsQuery";
|
||||
@@ -58,7 +57,6 @@ export default function ConfirmNewVersionDialog({
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild></DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Create new version?</DialogTitle>
|
||||
|
||||
@@ -128,10 +128,11 @@ export const CopyProductDialog = ({
|
||||
{!targetEnv && (
|
||||
<div>
|
||||
<FormLabel>Copy to environment</FormLabel>
|
||||
<Select
|
||||
value={toEnv}
|
||||
onValueChange={(value) => setToEnv(value as AppEnv)}
|
||||
>
|
||||
<Select
|
||||
value={toEnv}
|
||||
onValueChange={(value) => setToEnv(value as AppEnv)}
|
||||
items={{ [AppEnv.Live]: "Production", [AppEnv.Sandbox]: "Sandbox" }}
|
||||
>
|
||||
<SelectTrigger className="w-5/12">
|
||||
<SelectValue placeholder="Select environment" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -51,6 +51,11 @@ export function DiscountRewardConfig({
|
||||
onValueChange={(value) =>
|
||||
setReward({ ...reward, discountType: value as any })
|
||||
}
|
||||
items={{
|
||||
percentage: "Percentage",
|
||||
fixed: "Fixed",
|
||||
...(reward.discountType === "invoice_credits" && { invoice_credits: "Invoice Credits" }),
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select discount type" />
|
||||
@@ -134,6 +139,11 @@ export function DiscountRewardConfig({
|
||||
onValueChange={(value) =>
|
||||
setConfig("duration_type", value as CouponDurationType)
|
||||
}
|
||||
items={{
|
||||
[CouponDurationType.OneOff]: "One-off",
|
||||
[CouponDurationType.Months]: "Months",
|
||||
[CouponDurationType.Forever]: "Forever",
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="flex-1">
|
||||
<SelectValue placeholder="Select duration" />
|
||||
|
||||
@@ -323,20 +323,21 @@ export function FeatureGrantRewardConfig({
|
||||
placeholder="30"
|
||||
className="w-20"
|
||||
/>
|
||||
<Select
|
||||
value={ent.expiry.duration}
|
||||
onValueChange={(value) =>
|
||||
updateEntitlement({
|
||||
index,
|
||||
updates: {
|
||||
expiry: {
|
||||
duration: value as EntitlementDuration,
|
||||
length: ent.expiry?.length ?? 1,
|
||||
},
|
||||
<Select
|
||||
value={ent.expiry.duration}
|
||||
onValueChange={(value) =>
|
||||
updateEntitlement({
|
||||
index,
|
||||
updates: {
|
||||
expiry: {
|
||||
duration: value as EntitlementDuration,
|
||||
length: ent.expiry?.length ?? 1,
|
||||
},
|
||||
})
|
||||
}
|
||||
>
|
||||
},
|
||||
})
|
||||
}
|
||||
items={{ [EntitlementDuration.Day]: "Day(s)", [EntitlementDuration.Week]: "Week(s)", [EntitlementDuration.Month]: "Month(s)", [EntitlementDuration.Year]: "Year(s)" }}
|
||||
>
|
||||
<SelectTrigger className="flex-1">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -34,13 +34,14 @@ export function FreeProductRewardConfig({
|
||||
{/* Product Selection */}
|
||||
<div>
|
||||
<FormLabel>Plan</FormLabel>
|
||||
<Select
|
||||
value={reward.free_product_id || undefined}
|
||||
onValueChange={(value) =>
|
||||
setReward({ ...reward, free_product_id: value })
|
||||
}
|
||||
disabled={isEmpty}
|
||||
>
|
||||
<Select
|
||||
value={reward.free_product_id || undefined}
|
||||
onValueChange={(value) =>
|
||||
setReward({ ...reward, free_product_id: value })
|
||||
}
|
||||
disabled={isEmpty}
|
||||
items={Object.fromEntries(freeAddOns.map((product: ProductV2) => [product.id, product.name]))}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue
|
||||
placeholder={
|
||||
|
||||
@@ -62,12 +62,13 @@ export const RewardProgramConfig = ({
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<FieldLabel>Reward</FieldLabel>
|
||||
<Select
|
||||
value={rewardProgram.internal_reward_id}
|
||||
onValueChange={(value) =>
|
||||
setRewardProgram({ ...rewardProgram, internal_reward_id: value })
|
||||
}
|
||||
>
|
||||
<Select
|
||||
value={rewardProgram.internal_reward_id}
|
||||
onValueChange={(value) =>
|
||||
setRewardProgram({ ...rewardProgram, internal_reward_id: value })
|
||||
}
|
||||
items={Object.fromEntries(rewards.map((reward: Reward) => [reward.internal_id, reward.name]))}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select a reward" />
|
||||
</SelectTrigger>
|
||||
@@ -84,16 +85,17 @@ export const RewardProgramConfig = ({
|
||||
<div className="flex gap-2">
|
||||
<div className="w-full">
|
||||
<FieldLabel>Redeem On</FieldLabel>
|
||||
<Select
|
||||
defaultValue={RewardTriggerEvent.CustomerCreation}
|
||||
value={rewardProgram.when}
|
||||
onValueChange={(value) =>
|
||||
setRewardProgram({
|
||||
...rewardProgram,
|
||||
when: value as RewardTriggerEvent,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Select
|
||||
defaultValue={RewardTriggerEvent.CustomerCreation}
|
||||
value={rewardProgram.when}
|
||||
onValueChange={(value) =>
|
||||
setRewardProgram({
|
||||
...rewardProgram,
|
||||
when: value as RewardTriggerEvent,
|
||||
})
|
||||
}
|
||||
items={Object.fromEntries(Object.values(RewardTriggerEvent).map((event) => [event, keyToTitle(event, { exclusionMap: { [RewardTriggerEvent.CustomerCreation]: "Customer Redemption" } })]))}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select a redeem on" />
|
||||
</SelectTrigger>
|
||||
@@ -127,15 +129,16 @@ export const RewardProgramConfig = ({
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<FieldLabel>Received by</FieldLabel>
|
||||
<Select
|
||||
value={rewardProgram.received_by}
|
||||
onValueChange={(value) =>
|
||||
setRewardProgram({
|
||||
...rewardProgram,
|
||||
received_by: value as RewardReceivedBy,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Select
|
||||
value={rewardProgram.received_by}
|
||||
onValueChange={(value) =>
|
||||
setRewardProgram({
|
||||
...rewardProgram,
|
||||
received_by: value as RewardReceivedBy,
|
||||
})
|
||||
}
|
||||
items={Object.fromEntries(Object.values(RewardReceivedBy).map((receivedBy) => [receivedBy, receivedBy === RewardReceivedBy.All ? "Referrer & Redeemer" : keyToTitle(receivedBy)]))}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Who should receive the reward" />
|
||||
</SelectTrigger>
|
||||
|
||||
@@ -43,20 +43,6 @@ export default defineConfig({
|
||||
"../packages/atmn/src/prompts/skills/index.ts",
|
||||
),
|
||||
|
||||
// Hide Radix UI imports with cleaner aliases
|
||||
"@radix/accordion": "@radix-ui/react-accordion",
|
||||
"@radix/checkbox": "@radix-ui/react-checkbox",
|
||||
"@radix/context-menu": "@radix-ui/react-context-menu",
|
||||
"@radix/dialog": "@radix-ui/react-dialog",
|
||||
"@radix/dropdown-menu": "@radix-ui/react-dropdown-menu",
|
||||
"@radix/popover": "@radix-ui/react-popover",
|
||||
"@radix/scroll-area": "@radix-ui/react-scroll-area",
|
||||
"@radix/select": "@radix-ui/react-select",
|
||||
"@radix/separator": "@radix-ui/react-separator",
|
||||
"@radix/slot": "@radix-ui/react-slot",
|
||||
"@radix/switch": "@radix-ui/react-switch",
|
||||
"@radix/tabs": "@radix-ui/react-tabs",
|
||||
"@radix/tooltip": "@radix-ui/react-tooltip",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user