diff --git a/rsconcept/frontend/package-lock.json b/rsconcept/frontend/package-lock.json index a25d01be..4c25ec3c 100644 --- a/rsconcept/frontend/package-lock.json +++ b/rsconcept/frontend/package-lock.json @@ -11,7 +11,10 @@ "@dagrejs/dagre": "^1.1.4", "@hookform/resolvers": "^5.0.1", "@lezer/lr": "^1.4.2", + "@radix-ui/react-dialog": "^1.1.7", + "@radix-ui/react-popover": "^1.1.7", "@radix-ui/react-select": "^2.1.7", + "@radix-ui/react-slot": "^1.2.0", "@tanstack/react-query": "^5.71.10", "@tanstack/react-query-devtools": "^5.71.10", "@tanstack/react-table": "^8.21.2", @@ -20,6 +23,7 @@ "axios": "^1.8.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "cmdk": "^1.1.1", "global": "^4.4.0", "js-file-download": "^0.4.12", "lucide-react": "^0.487.0", @@ -2593,6 +2597,42 @@ } } }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.7.tgz", + "integrity": "sha512-EIdma8C0C/I6kL6sO02avaCRqi3fmWJpxH6mqbVScorW6nNktzKJT/le7VPho3o/7wCsyRg3z0+Q+Obr0Gy/VQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.6", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.3", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.5", + "@radix-ui/react-presence": "1.1.3", + "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-slot": "1.2.0", + "@radix-ui/react-use-controllable-state": "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-direction": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", @@ -2693,6 +2733,43 @@ } } }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.7.tgz", + "integrity": "sha512-I38OYWDmJF2kbO74LX8UsFydSHWOJuQ7LxPnTefjxxvdvPLempvAnmsyX9UsBlywcbSGpRH7oMLfkUf+ij4nrw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.6", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.3", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.3", + "@radix-ui/react-portal": "1.1.5", + "@radix-ui/react-presence": "1.1.3", + "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-slot": "1.2.0", + "@radix-ui/react-use-controllable-state": "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.3.tgz", @@ -2749,6 +2826,30 @@ } } }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.3.tgz", + "integrity": "sha512-IrVLIhskYhH3nLvtcBLQFZr61tBG7wx7O3kEmdzcYwRGAEBmBicGGL7ATzNgruYJ3xBTbuzEEq9OXJM3PAX3tA==", + "license": "MIT", + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-primitive": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.3.tgz", @@ -5534,6 +5635,22 @@ "node": ">=6" } }, + "node_modules/cmdk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", diff --git a/rsconcept/frontend/package.json b/rsconcept/frontend/package.json index 27a6f19f..b58ce561 100644 --- a/rsconcept/frontend/package.json +++ b/rsconcept/frontend/package.json @@ -17,7 +17,10 @@ "@dagrejs/dagre": "^1.1.4", "@hookform/resolvers": "^5.0.1", "@lezer/lr": "^1.4.2", + "@radix-ui/react-dialog": "^1.1.7", + "@radix-ui/react-popover": "^1.1.7", "@radix-ui/react-select": "^2.1.7", + "@radix-ui/react-slot": "^1.2.0", "@tanstack/react-query": "^5.71.10", "@tanstack/react-query-devtools": "^5.71.10", "@tanstack/react-table": "^8.21.2", @@ -26,6 +29,7 @@ "axios": "^1.8.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "cmdk": "^1.1.1", "global": "^4.4.0", "js-file-download": "^0.4.12", "lucide-react": "^0.487.0", diff --git a/rsconcept/frontend/src/components/input/combo-box.tsx b/rsconcept/frontend/src/components/input/combo-box.tsx new file mode 100644 index 00000000..725e08ec --- /dev/null +++ b/rsconcept/frontend/src/components/input/combo-box.tsx @@ -0,0 +1,93 @@ +'use client'; + +import { useState } from 'react'; +import { Check, ChevronDownIcon } from 'lucide-react'; + +import { cn } from '@/lib/utils'; + +import { Button } from '../ui/button'; +import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '../ui/command'; +import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'; + +interface ComboBoxProps