diff --git a/packages/ui/package.json b/packages/ui/package.json
index 86e2948e..99508eaf 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -14,6 +14,7 @@
"@sentry/nextjs": "7.102.1",
"@spear-ai/logo": "2.1.1",
"autoprefixer": "10.4.18",
+ "classix": "2.1.36",
"next": "14.1.2",
"next-themes": "0.2.1",
"react": "18.2.0",
diff --git a/packages/ui/src/components/select/select.stories.tsx b/packages/ui/src/components/select/select.stories.tsx
index 49aef7cd..87b45f68 100644
--- a/packages/ui/src/components/select/select.stories.tsx
+++ b/packages/ui/src/components/select/select.stories.tsx
@@ -1,19 +1,21 @@
-import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons";
+import { CheckIcon } from "@radix-ui/react-icons";
import { useControlledState } from "@react-stately/utils";
import type { Meta, StoryObj } from "@storybook/react";
import { useId } from "react";
+import { Form } from "react-aria-components";
+import { useIntl } from "react-intl";
import {
- Button,
- FieldError,
- Form,
- Label,
- ListBox,
- ListBoxItem,
- Popover,
Select,
+ SelectButton,
+ SelectDefaultListBoxItem,
+ SelectFieldError,
+ SelectIcon,
+ SelectLabel,
+ SelectListBox,
+ SelectListBoxItem,
+ SelectPopover,
SelectValue,
-} from "react-aria-components";
-import { useIntl } from "react-intl";
+} from "./select";
const sensorList = [
{ id: "1", name: "Pyramid Array C1" },
@@ -57,7 +59,6 @@ const PreviewSelect = (properties: {
diff --git a/packages/ui/src/components/select/select.tsx b/packages/ui/src/components/select/select.tsx
new file mode 100644
index 00000000..f760114d
--- /dev/null
+++ b/packages/ui/src/components/select/select.tsx
@@ -0,0 +1,152 @@
+/* eslint-disable react/jsx-props-no-spreading */
+import { CaretSortIcon } from "@radix-ui/react-icons";
+import { cx } from "classix";
+import React, { forwardRef, HTMLAttributes } from "react";
+import {
+ Button as ButtonPrimitive,
+ FieldError as FieldErrorPrimitive,
+ Label as LabelPrimitive,
+ ListBox as ListBoxPrimitive,
+ ListBoxItem as ListBoxItemPrimitive,
+ Popover as PopoverPrimitive,
+ Select as SelectPrimitive,
+ SelectValue as SelectValuePrimitive,
+} from "react-aria-components";
+
+export const Select = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx("group w-full focus:outline-none", className);
+ return ;
+});
+
+Select.displayName = "Select";
+
+export const SelectListBox = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx("outline-none", className);
+ return ;
+});
+
+SelectListBox.displayName = "SelectListBox";
+
+export const SelectLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx(
+ "block select-none text-base/6 text-neutral-12 group-disabled:text-neutral-11 sm:text-sm/6",
+ className,
+ );
+ return ;
+});
+
+SelectLabel.displayName = "SelectLabel";
+
+export const SelectDescription = forwardRef<
+ HTMLParagraphElement,
+ HTMLAttributes & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx(
+ "mt-1 text-base/6 text-neutral-11 group-disabled:text-neutral-9 sm:text-sm/6",
+ className,
+ );
+ return ;
+});
+
+SelectDescription.displayName = "SelectDescription";
+
+export const SelectIcon = forwardRef<
+ HTMLSpanElement,
+ HTMLAttributes & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx("text-neutral-11 group-disabled:text-neutral-8", className);
+ return (
+
+
+
+ );
+});
+
+SelectIcon.displayName = "SelectIcon";
+
+export const SelectButton = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx(
+ "group mt-2 inline-flex h-9 w-full cursor-default select-none items-center justify-between gap-1 rounded-lg border border-transparent bg-white-a-3 pe-2 ps-3.5 text-base leading-none shadow outline outline-offset-0 outline-neutral-a-7 entering:outline-2 entering:outline-primary-a-8 group-invalid:outline-x-negative-a-7 group-disabled:pointer-events-none group-invalid:group-disabled:outline-x-negative-a-6 focus-visible:outline-primary-a-8 theme-dfs:bg-canvas-1 theme-galapago:bg-white theme-dfs:dark:bg-white-a-3 theme-forerunner:dark:bg-black-a-3 theme-galapago:dark:bg-black-a-3 sm:ps-3 sm:text-sm",
+ className,
+ );
+ return ;
+});
+
+SelectButton.displayName = "SelectButton";
+
+export const SelectValue = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx(
+ "truncate text-neutral-12 placeholder-shown:text-neutral-11 group-disabled:text-neutral-a-8",
+ className,
+ );
+ return ;
+});
+
+SelectValue.displayName = "SelectValue";
+
+export const SelectFieldError = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx(
+ "mt-2 block text-base/6 text-x-negative-11 group-disabled:opacity-50 sm:text-sm/6",
+ className,
+ );
+ return ;
+});
+
+SelectFieldError.displayName = "SelectFieldError";
+
+export const SelectPopover = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx(
+ "isolate min-w-select-trigger-width overflow-auto rounded-xl border-transparent bg-canvas-1 p-1 shadow-lg outline outline-1 outline-offset-0 outline-neutral-a-6 backdrop-blur placement-left:slide-in-from-right-2 placement-right:slide-in-from-left-2 placement-top:slide-in-from-bottom-2 placement-bottom:slide-in-from-top-2 entering:duration-100 entering:animate-in entering:fade-in exiting:duration-75 exiting:animate-out exiting:fade-out exiting:zoom-out-95 theme-forerunner:bg-white-a-3 theme-galapago:bg-white theme-underway:shadow-2xl theme-galapago:dark:bg-black-a-3",
+ className,
+ );
+ return ;
+});
+
+SelectPopover.displayName = "SelectPopover";
+
+export const SelectDefaultListBoxItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx(
+ "cursor-default select-none rounded-lg py-2.5 pe-5 ps-2 text-base leading-none text-neutral-11 outline-none hover:bg-primary-4 focus:bg-primary-5 focus:outline-none sm:py-1.5 sm:text-sm",
+ className,
+ );
+ return ;
+});
+
+SelectDefaultListBoxItem.displayName = "SelectDefaultListBoxItem";
+
+export const SelectListBoxItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & { className?: string | undefined }
+>(({ className, ...properties }, reference) => {
+ const mergedClassName = cx(
+ "group/item relative cursor-default select-none rounded-lg py-2.5 pe-7 ps-2 text-base leading-none text-neutral-12 outline-none hover:bg-primary-4 focus:bg-primary-5 sm:py-1.5 sm:text-sm rtl:text-right",
+ className,
+ );
+ return ;
+});
+
+SelectListBoxItem.displayName = "SelectListBoxItem";
diff --git a/yarn.lock b/yarn.lock
index 849df38a..2899b925 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5319,6 +5319,7 @@ __metadata:
"@types/react": "npm:18.2.63"
"@types/react-dom": "npm:18.2.19"
autoprefixer: "npm:10.4.18"
+ classix: "npm:2.1.36"
eslint: "npm:8.57.0"
eslint-config-prettier: "npm:9.1.0"
graphql: "npm:16.8.1"
@@ -8867,6 +8868,13 @@ __metadata:
languageName: node
linkType: hard
+"classix@npm:2.1.36":
+ version: 2.1.36
+ resolution: "classix@npm:2.1.36"
+ checksum: 10/365bf02ac4cb9ee586923fa401721f9d53b5ad9359fa61c49d6b66bef3e97f10ea5671050c1bb2e2f8352e2e9d60f351ac00486d4920f160fce821b3285bc899
+ languageName: node
+ linkType: hard
+
"clean-css@npm:^5.2.2":
version: 5.3.3
resolution: "clean-css@npm:5.3.3"