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