summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/ui/src')
-rw-r--r--packages/ui/src/components/avatar.css35
-rw-r--r--packages/ui/src/components/avatar.tsx28
-rw-r--r--packages/ui/src/components/dropdown-menu.css119
-rw-r--r--packages/ui/src/components/dropdown-menu.tsx308
-rw-r--r--packages/ui/src/components/icon.tsx2
-rw-r--r--packages/ui/src/components/select.tsx12
-rw-r--r--packages/ui/src/styles/index.css2
7 files changed, 503 insertions, 3 deletions
diff --git a/packages/ui/src/components/avatar.css b/packages/ui/src/components/avatar.css
new file mode 100644
index 000000000..bc87f3bd8
--- /dev/null
+++ b/packages/ui/src/components/avatar.css
@@ -0,0 +1,35 @@
+[data-component="avatar"] {
+ --avatar-bg: var(--color-surface-info-base);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--color-border-weak-base);
+ font-family: var(--font-mono);
+ font-weight: 500;
+ text-transform: uppercase;
+ background-color: var(--avatar-bg);
+ color: oklch(from var(--avatar-bg) calc(l * 0.72) calc(c * 8) h);
+}
+
+[data-component="avatar"][data-size="small"] {
+ width: 1.25rem;
+ height: 1.25rem;
+ font-size: 0.75rem;
+ line-height: 1;
+}
+
+[data-component="avatar"][data-size="normal"] {
+ width: 1.5rem;
+ height: 1.5rem;
+ font-size: 1.125rem;
+ line-height: 1.5rem;
+}
+
+[data-component="avatar"][data-size="large"] {
+ width: 2rem;
+ height: 2rem;
+ font-size: 1.25rem;
+ line-height: 2rem;
+}
diff --git a/packages/ui/src/components/avatar.tsx b/packages/ui/src/components/avatar.tsx
new file mode 100644
index 000000000..183a15b9b
--- /dev/null
+++ b/packages/ui/src/components/avatar.tsx
@@ -0,0 +1,28 @@
+import { type ComponentProps, splitProps, Show } from "solid-js"
+
+export interface AvatarProps extends ComponentProps<"div"> {
+ fallback: string
+ background?: string
+ size?: "small" | "normal" | "large"
+}
+
+export function Avatar(props: AvatarProps) {
+ const [split, rest] = splitProps(props, ["fallback", "background", "size", "class", "classList", "style"])
+ return (
+ <div
+ {...rest}
+ data-component="avatar"
+ data-size={split.size || "normal"}
+ classList={{
+ ...(split.classList ?? {}),
+ [split.class ?? ""]: !!split.class,
+ }}
+ style={{
+ ...(typeof split.style === "object" ? split.style : {}),
+ ...(split.background ? { "--avatar-bg": split.background } : {}),
+ }}
+ >
+ <Show when={split.fallback}>{split.fallback[0]}</Show>
+ </div>
+ )
+}
diff --git a/packages/ui/src/components/dropdown-menu.css b/packages/ui/src/components/dropdown-menu.css
new file mode 100644
index 000000000..710ff2ddc
--- /dev/null
+++ b/packages/ui/src/components/dropdown-menu.css
@@ -0,0 +1,119 @@
+[data-component="dropdown-menu-content"],
+[data-component="dropdown-menu-sub-content"] {
+ min-width: 8rem;
+ overflow: hidden;
+ border-radius: var(--radius-md);
+ border: 1px solid var(--border-weak-base);
+ background-color: var(--surface-raised-stronger-non-alpha);
+ padding: 4px;
+ box-shadow: var(--shadow-md);
+ z-index: 50;
+ transform-origin: var(--kb-menu-content-transform-origin);
+
+ &[data-closed] {
+ animation: dropdown-menu-close 0.15s ease-out;
+ }
+
+ &[data-expanded] {
+ animation: dropdown-menu-open 0.15s ease-out;
+ }
+}
+
+[data-component="dropdown-menu-content"],
+[data-component="dropdown-menu-sub-content"] {
+ [data-slot="dropdown-menu-item"],
+ [data-slot="dropdown-menu-checkbox-item"],
+ [data-slot="dropdown-menu-radio-item"],
+ [data-slot="dropdown-menu-sub-trigger"] {
+ position: relative;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 4px 8px;
+ border-radius: var(--radius-sm);
+ cursor: default;
+ user-select: none;
+ outline: none;
+
+ font-family: var(--font-family-sans);
+ font-size: var(--font-size-small);
+ font-weight: var(--font-weight-medium);
+ line-height: var(--line-height-large);
+ letter-spacing: var(--letter-spacing-normal);
+ color: var(--text-strong);
+
+ &[data-highlighted] {
+ background: var(--surface-raised-base-hover);
+ }
+
+ &[data-disabled] {
+ color: var(--text-weak);
+ pointer-events: none;
+ }
+ }
+
+ [data-slot="dropdown-menu-sub-trigger"] {
+ &[data-expanded] {
+ background: var(--surface-raised-base-hover);
+ }
+ }
+
+ [data-slot="dropdown-menu-item-indicator"] {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 16px;
+ height: 16px;
+ }
+
+ [data-slot="dropdown-menu-item-label"] {
+ flex: 1;
+ }
+
+ [data-slot="dropdown-menu-item-description"] {
+ font-size: var(--font-size-x-small);
+ color: var(--text-weak);
+ }
+
+ [data-slot="dropdown-menu-separator"] {
+ height: 1px;
+ margin: 4px -4px;
+ border-top-color: var(--border-weak-base);
+ }
+
+ [data-slot="dropdown-menu-group-label"] {
+ padding: 4px 8px;
+ font-family: var(--font-family-sans);
+ font-size: var(--font-size-x-small);
+ font-weight: var(--font-weight-medium);
+ line-height: var(--line-height-large);
+ letter-spacing: var(--letter-spacing-normal);
+ color: var(--text-weak);
+ }
+
+ [data-slot="dropdown-menu-arrow"] {
+ fill: var(--surface-raised-stronger-non-alpha);
+ }
+}
+
+@keyframes dropdown-menu-open {
+ from {
+ opacity: 0;
+ transform: scale(0.96);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
+@keyframes dropdown-menu-close {
+ from {
+ opacity: 1;
+ transform: scale(1);
+ }
+ to {
+ opacity: 0;
+ transform: scale(0.96);
+ }
+}
diff --git a/packages/ui/src/components/dropdown-menu.tsx b/packages/ui/src/components/dropdown-menu.tsx
new file mode 100644
index 000000000..efb2b45ca
--- /dev/null
+++ b/packages/ui/src/components/dropdown-menu.tsx
@@ -0,0 +1,308 @@
+import { DropdownMenu as Kobalte } from "@kobalte/core/dropdown-menu"
+import { splitProps } from "solid-js"
+import type { ComponentProps, ParentProps } from "solid-js"
+
+export interface DropdownMenuProps extends ComponentProps<typeof Kobalte> {}
+export interface DropdownMenuTriggerProps extends ComponentProps<typeof Kobalte.Trigger> {}
+export interface DropdownMenuIconProps extends ComponentProps<typeof Kobalte.Icon> {}
+export interface DropdownMenuPortalProps extends ComponentProps<typeof Kobalte.Portal> {}
+export interface DropdownMenuContentProps extends ComponentProps<typeof Kobalte.Content> {}
+export interface DropdownMenuArrowProps extends ComponentProps<typeof Kobalte.Arrow> {}
+export interface DropdownMenuSeparatorProps extends ComponentProps<typeof Kobalte.Separator> {}
+export interface DropdownMenuGroupProps extends ComponentProps<typeof Kobalte.Group> {}
+export interface DropdownMenuGroupLabelProps extends ComponentProps<typeof Kobalte.GroupLabel> {}
+export interface DropdownMenuItemProps extends ComponentProps<typeof Kobalte.Item> {}
+export interface DropdownMenuItemLabelProps extends ComponentProps<typeof Kobalte.ItemLabel> {}
+export interface DropdownMenuItemDescriptionProps extends ComponentProps<typeof Kobalte.ItemDescription> {}
+export interface DropdownMenuItemIndicatorProps extends ComponentProps<typeof Kobalte.ItemIndicator> {}
+export interface DropdownMenuRadioGroupProps extends ComponentProps<typeof Kobalte.RadioGroup> {}
+export interface DropdownMenuRadioItemProps extends ComponentProps<typeof Kobalte.RadioItem> {}
+export interface DropdownMenuCheckboxItemProps extends ComponentProps<typeof Kobalte.CheckboxItem> {}
+export interface DropdownMenuSubProps extends ComponentProps<typeof Kobalte.Sub> {}
+export interface DropdownMenuSubTriggerProps extends ComponentProps<typeof Kobalte.SubTrigger> {}
+export interface DropdownMenuSubContentProps extends ComponentProps<typeof Kobalte.SubContent> {}
+
+function DropdownMenuRoot(props: DropdownMenuProps) {
+ return <Kobalte {...props} data-component="dropdown-menu" />
+}
+
+function DropdownMenuTrigger(props: ParentProps<DropdownMenuTriggerProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.Trigger
+ {...rest}
+ data-slot="dropdown-menu-trigger"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.Trigger>
+ )
+}
+
+function DropdownMenuIcon(props: ParentProps<DropdownMenuIconProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.Icon
+ {...rest}
+ data-slot="dropdown-menu-icon"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.Icon>
+ )
+}
+
+function DropdownMenuPortal(props: DropdownMenuPortalProps) {
+ return <Kobalte.Portal {...props} />
+}
+
+function DropdownMenuContent(props: ParentProps<DropdownMenuContentProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.Content
+ {...rest}
+ data-component="dropdown-menu-content"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.Content>
+ )
+}
+
+function DropdownMenuArrow(props: DropdownMenuArrowProps) {
+ const [local, rest] = splitProps(props, ["class", "classList"])
+ return (
+ <Kobalte.Arrow
+ {...rest}
+ data-slot="dropdown-menu-arrow"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ />
+ )
+}
+
+function DropdownMenuSeparator(props: DropdownMenuSeparatorProps) {
+ const [local, rest] = splitProps(props, ["class", "classList"])
+ return (
+ <Kobalte.Separator
+ {...rest}
+ data-slot="dropdown-menu-separator"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ />
+ )
+}
+
+function DropdownMenuGroup(props: ParentProps<DropdownMenuGroupProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.Group
+ {...rest}
+ data-slot="dropdown-menu-group"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.Group>
+ )
+}
+
+function DropdownMenuGroupLabel(props: ParentProps<DropdownMenuGroupLabelProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.GroupLabel
+ {...rest}
+ data-slot="dropdown-menu-group-label"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.GroupLabel>
+ )
+}
+
+function DropdownMenuItem(props: ParentProps<DropdownMenuItemProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.Item
+ {...rest}
+ data-slot="dropdown-menu-item"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.Item>
+ )
+}
+
+function DropdownMenuItemLabel(props: ParentProps<DropdownMenuItemLabelProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.ItemLabel
+ {...rest}
+ data-slot="dropdown-menu-item-label"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.ItemLabel>
+ )
+}
+
+function DropdownMenuItemDescription(props: ParentProps<DropdownMenuItemDescriptionProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.ItemDescription
+ {...rest}
+ data-slot="dropdown-menu-item-description"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.ItemDescription>
+ )
+}
+
+function DropdownMenuItemIndicator(props: ParentProps<DropdownMenuItemIndicatorProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.ItemIndicator
+ {...rest}
+ data-slot="dropdown-menu-item-indicator"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.ItemIndicator>
+ )
+}
+
+function DropdownMenuRadioGroup(props: ParentProps<DropdownMenuRadioGroupProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.RadioGroup
+ {...rest}
+ data-slot="dropdown-menu-radio-group"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.RadioGroup>
+ )
+}
+
+function DropdownMenuRadioItem(props: ParentProps<DropdownMenuRadioItemProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.RadioItem
+ {...rest}
+ data-slot="dropdown-menu-radio-item"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.RadioItem>
+ )
+}
+
+function DropdownMenuCheckboxItem(props: ParentProps<DropdownMenuCheckboxItemProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.CheckboxItem
+ {...rest}
+ data-slot="dropdown-menu-checkbox-item"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.CheckboxItem>
+ )
+}
+
+function DropdownMenuSub(props: DropdownMenuSubProps) {
+ return <Kobalte.Sub {...props} />
+}
+
+function DropdownMenuSubTrigger(props: ParentProps<DropdownMenuSubTriggerProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.SubTrigger
+ {...rest}
+ data-slot="dropdown-menu-sub-trigger"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.SubTrigger>
+ )
+}
+
+function DropdownMenuSubContent(props: ParentProps<DropdownMenuSubContentProps>) {
+ const [local, rest] = splitProps(props, ["class", "classList", "children"])
+ return (
+ <Kobalte.SubContent
+ {...rest}
+ data-component="dropdown-menu-sub-content"
+ classList={{
+ ...(local.classList ?? {}),
+ [local.class ?? ""]: !!local.class,
+ }}
+ >
+ {local.children}
+ </Kobalte.SubContent>
+ )
+}
+
+export const DropdownMenu = Object.assign(DropdownMenuRoot, {
+ Trigger: DropdownMenuTrigger,
+ Icon: DropdownMenuIcon,
+ Portal: DropdownMenuPortal,
+ Content: DropdownMenuContent,
+ Arrow: DropdownMenuArrow,
+ Separator: DropdownMenuSeparator,
+ Group: DropdownMenuGroup,
+ GroupLabel: DropdownMenuGroupLabel,
+ Item: DropdownMenuItem,
+ ItemLabel: DropdownMenuItemLabel,
+ ItemDescription: DropdownMenuItemDescription,
+ ItemIndicator: DropdownMenuItemIndicator,
+ RadioGroup: DropdownMenuRadioGroup,
+ RadioItem: DropdownMenuRadioItem,
+ CheckboxItem: DropdownMenuCheckboxItem,
+ Sub: DropdownMenuSub,
+ SubTrigger: DropdownMenuSubTrigger,
+ SubContent: DropdownMenuSubContent,
+})
diff --git a/packages/ui/src/components/icon.tsx b/packages/ui/src/components/icon.tsx
index 9e4f00a0d..8c83b41ce 100644
--- a/packages/ui/src/components/icon.tsx
+++ b/packages/ui/src/components/icon.tsx
@@ -133,6 +133,7 @@ const newIcons = {
"magnifying-glass": `<path d="M15.8332 15.8337L13.0819 13.0824M14.6143 9.39088C14.6143 12.2759 12.2755 14.6148 9.39039 14.6148C6.50532 14.6148 4.1665 12.2759 4.1665 9.39088C4.1665 6.5058 6.50532 4.16699 9.39039 4.16699C12.2755 4.16699 14.6143 6.5058 14.6143 9.39088Z" stroke="currentColor" stroke-linecap="square"/>`,
"plus-small": `<path d="M9.99984 5.41699V10.0003M9.99984 10.0003V14.5837M9.99984 10.0003H5.4165M9.99984 10.0003H14.5832" stroke="currentColor" stroke-linecap="square"/>`,
"chevron-down": `<path d="M6.6665 8.33325L9.99984 11.6666L13.3332 8.33325" stroke="currentColor" stroke-linecap="square"/>`,
+ "chevron-right": `<path d="M8.33301 13.3327L11.6663 9.99935L8.33301 6.66602" stroke="currentColor" stroke-linecap="square"/>`,
"arrow-up": `<path fill-rule="evenodd" clip-rule="evenodd" d="M9.99991 2.24121L16.0921 8.33343L15.2083 9.21731L10.6249 4.63397V17.5001H9.37492V4.63398L4.7916 9.21731L3.90771 8.33343L9.99991 2.24121Z" fill="currentColor"/>`,
"check-small": `<path d="M6.5 11.4412L8.97059 13.5L13.5 6.5" stroke="currentColor" stroke-linecap="square"/>`,
"edit-small-2": `<path d="M17.0834 17.0833V17.5833H17.5834V17.0833H17.0834ZM2.91675 17.0833H2.41675V17.5833H2.91675V17.0833ZM2.91675 2.91659V2.41659H2.41675V2.91659H2.91675ZM9.58341 3.41659H10.0834V2.41659H9.58341V2.91659V3.41659ZM17.5834 10.4166V9.91659H16.5834V10.4166H17.0834H17.5834ZM10.4167 7.08325L10.0632 6.7297L9.91675 6.87615V7.08325H10.4167ZM10.4167 9.58325H9.91675V10.0833H10.4167V9.58325ZM12.9167 9.58325V10.0833H13.1239L13.2703 9.93681L12.9167 9.58325ZM15.4167 2.08325L15.7703 1.7297L15.4167 1.37615L15.0632 1.7297L15.4167 2.08325ZM17.9167 4.58325L18.2703 4.93681L18.6239 4.58325L18.2703 4.2297L17.9167 4.58325ZM17.0834 17.0833V16.5833H2.91675V17.0833V17.5833H17.0834V17.0833ZM2.91675 17.0833H3.41675V2.91659H2.91675H2.41675V17.0833H2.91675ZM2.91675 2.91659V3.41659H9.58341V2.91659V2.41659H2.91675V2.91659ZM17.0834 10.4166H16.5834V17.0833H17.0834H17.5834V10.4166H17.0834ZM10.4167 7.08325H9.91675V9.58325H10.4167H10.9167V7.08325H10.4167ZM10.4167 9.58325V10.0833H12.9167V9.58325V9.08325H10.4167V9.58325ZM10.4167 7.08325L10.7703 7.43681L15.7703 2.43681L15.4167 2.08325L15.0632 1.7297L10.0632 6.7297L10.4167 7.08325ZM15.4167 2.08325L15.0632 2.43681L17.5632 4.93681L17.9167 4.58325L18.2703 4.2297L15.7703 1.7297L15.4167 2.08325ZM17.9167 4.58325L17.5632 4.2297L12.5632 9.2297L12.9167 9.58325L13.2703 9.93681L18.2703 4.93681L17.9167 4.58325Z" fill="currentColor"/>`,
@@ -170,6 +171,7 @@ const newIcons = {
"layout-bottom": `<path d="M18.125 18.125L1.875 18.125L1.875 1.875L18.125 1.875L18.125 18.125ZM3.125 12.8308L3.125 16.875L16.875 16.875L16.875 12.8308L3.125 12.8308ZM3.125 3.125L3.125 11.5808L16.875 11.5808L16.875 3.125L3.125 3.125Z" fill="currentColor"/>`,
"layout-bottom-partial": `<path d="M2.5 17.5L2.5 12.2059L17.5 12.2059L17.5 17.5L2.5 17.5Z" fill="currentColor" fill-opacity="40%" /><path d="M2.5 17.5L2.5 2.5M2.5 17.5L17.5 17.5M2.5 17.5L2.5 12.2059M2.5 2.5L17.5 2.5M2.5 2.5L2.5 12.2059M17.5 2.5L17.5 17.5M17.5 2.5L17.5 12.2059M17.5 17.5L17.5 12.2059M17.5 12.2059L2.5 12.2059" stroke="currentColor" stroke-linecap="square"/>`,
"layout-bottom-full": `<path d="M2.5 17.5L2.5 12.2059L17.5 12.2059L17.5 17.5L2.5 17.5Z" fill="currentColor"/><path d="M2.5 17.5L2.5 2.5M2.5 17.5L17.5 17.5M2.5 17.5L2.5 12.2059M2.5 2.5L17.5 2.5M2.5 2.5L2.5 12.2059M17.5 2.5L17.5 17.5M17.5 2.5L17.5 12.2059M17.5 17.5L17.5 12.2059M17.5 12.2059L2.5 12.2059" stroke="currentColor" stroke-linecap="square"/>`,
+ "dot-grid": `<path d="M2.08398 9.16602H3.75065V10.8327H2.08398V9.16602Z" fill="currentColor"/><path d="M10.834 9.16602H9.16732V10.8327H10.834V9.16602Z" fill="currentColor"/><path d="M16.2507 9.16602H17.9173V10.8327H16.2507V9.16602Z" fill="currentColor"/><path d="M2.08398 9.16602H3.75065V10.8327H2.08398V9.16602Z" stroke="currentColor"/><path d="M10.834 9.16602H9.16732V10.8327H10.834V9.16602Z" stroke="currentColor"/><path d="M16.2507 9.16602H17.9173V10.8327H16.2507V9.16602Z" stroke="currentColor"/>`,
}
export interface IconProps extends ComponentProps<"svg"> {
diff --git a/packages/ui/src/components/select.tsx b/packages/ui/src/components/select.tsx
index 9ba1f177b..bde5325e9 100644
--- a/packages/ui/src/components/select.tsx
+++ b/packages/ui/src/components/select.tsx
@@ -1,10 +1,10 @@
import { Select as Kobalte } from "@kobalte/core/select"
-import { createMemo, splitProps, type ComponentProps } from "solid-js"
+import { createMemo, splitProps, type ComponentProps, type JSX } from "solid-js"
import { pipe, groupBy, entries, map } from "remeda"
import { Button, ButtonProps } from "./button"
import { Icon } from "./icon"
-export type SelectProps<T> = Omit<ComponentProps<typeof Kobalte<T>>, "value" | "onSelect"> & {
+export type SelectProps<T> = Omit<ComponentProps<typeof Kobalte<T>>, "value" | "onSelect" | "children"> & {
placeholder?: string
options: T[]
current?: T
@@ -14,6 +14,7 @@ export type SelectProps<T> = Omit<ComponentProps<typeof Kobalte<T>>, "value" | "
onSelect?: (value: T | undefined) => void
class?: ComponentProps<"div">["class"]
classList?: ComponentProps<"div">["classList"]
+ children?: (item: T | undefined) => JSX.Element
}
export function Select<T>(props: SelectProps<T> & ButtonProps) {
@@ -27,6 +28,7 @@ export function Select<T>(props: SelectProps<T> & ButtonProps) {
"label",
"groupBy",
"onSelect",
+ "children",
])
const grouped = createMemo(() => {
const result = pipe(
@@ -63,7 +65,11 @@ export function Select<T>(props: SelectProps<T> & ButtonProps) {
{...itemProps}
>
<Kobalte.ItemLabel data-slot="select-select-item-label">
- {local.label ? local.label(itemProps.item.rawValue) : (itemProps.item.rawValue as string)}
+ {local.children
+ ? local.children(itemProps.item.rawValue)
+ : local.label
+ ? local.label(itemProps.item.rawValue)
+ : (itemProps.item.rawValue as string)}
</Kobalte.ItemLabel>
<Kobalte.ItemIndicator data-slot="select-select-item-indicator">
<Icon name="check-small" size="small" />
diff --git a/packages/ui/src/styles/index.css b/packages/ui/src/styles/index.css
index afe005f84..656bb928a 100644
--- a/packages/ui/src/styles/index.css
+++ b/packages/ui/src/styles/index.css
@@ -6,6 +6,7 @@
@import "./base.css" layer(base);
@import "../components/accordion.css" layer(components);
+@import "../components/avatar.css" layer(components);
@import "../components/basic-tool.css" layer(components);
@import "../components/button.css" layer(components);
@import "../components/card.css" layer(components);
@@ -14,6 +15,7 @@
@import "../components/collapsible.css" layer(components);
@import "../components/diff.css" layer(components);
@import "../components/diff-changes.css" layer(components);
+@import "../components/dropdown-menu.css" layer(components);
@import "../components/dialog.css" layer(components);
@import "../components/file-icon.css" layer(components);
@import "../components/icon.css" layer(components);