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"