feat: add Base UI Tailwind component library

Add composable wrappers for 37 Base UI component families.

Expose primitive and convenience APIs with shared styling utilities.

Add the registry manifest, installer CLI, generation and export checks.

Include a smoke example covering primitive and shadcn-style imports.
This commit is contained in:
Maofeng
2026-07-25 06:03:12 +08:00
parent 312cb1fd59
commit b3a7a2a8f5
311 changed files with 10879 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxArrowProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Arrow> & {
className?: string
}
const BaseComboboxArrow = BaseCombobox.Arrow as React.ElementType
export const ComboboxArrow = React.forwardRef<HTMLElement, ComboboxArrowProps>(
({ className, ...props }, ref) => (
<BaseComboboxArrow
ref={ref}
className={cn(
"flex size-4 shrink-0 items-center justify-center text-neutral-500 dark:text-neutral-400",
className,
)}
{...props}
/>
),
)
ComboboxArrow.displayName = "ComboboxArrow"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxBackdropProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Backdrop> & {
className?: string
}
const BaseComboboxBackdrop = BaseCombobox.Backdrop as React.ElementType
export const ComboboxBackdrop = React.forwardRef<HTMLElement, ComboboxBackdropProps>(
({ className, ...props }, ref) => (
<BaseComboboxBackdrop
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/20 backdrop-blur-[1px] transition-opacity data-ending-style:opacity-0 data-starting-style:opacity-0 dark:bg-black/50",
className,
)}
{...props}
/>
),
)
ComboboxBackdrop.displayName = "ComboboxBackdrop"
@@ -0,0 +1,23 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxChipRemoveProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.ChipRemove> & {
className?: string
}
const BaseComboboxChipRemove = BaseCombobox.ChipRemove as React.ElementType
export const ComboboxChipRemove = React.forwardRef<HTMLElement, ComboboxChipRemoveProps>(
({ className, ...props }, ref) => (
<BaseComboboxChipRemove
ref={ref}
className={cn(className)}
{...props}
/>
),
)
ComboboxChipRemove.displayName = "ComboboxChipRemove"
+23
View File
@@ -0,0 +1,23 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxChipProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Chip> & {
className?: string
}
const BaseComboboxChip = BaseCombobox.Chip as React.ElementType
export const ComboboxChip = React.forwardRef<HTMLElement, ComboboxChipProps>(
({ className, ...props }, ref) => (
<BaseComboboxChip
ref={ref}
className={cn(className)}
{...props}
/>
),
)
ComboboxChip.displayName = "ComboboxChip"
+23
View File
@@ -0,0 +1,23 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxChipsProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Chips> & {
className?: string
}
const BaseComboboxChips = BaseCombobox.Chips as React.ElementType
export const ComboboxChips = React.forwardRef<HTMLElement, ComboboxChipsProps>(
({ className, ...props }, ref) => (
<BaseComboboxChips
ref={ref}
className={cn(className)}
{...props}
/>
),
)
ComboboxChips.displayName = "ComboboxChips"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxClearProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Clear> & {
className?: string
}
const BaseComboboxClear = BaseCombobox.Clear as React.ElementType
export const ComboboxClear = React.forwardRef<HTMLElement, ComboboxClearProps>(
({ className, ...props }, ref) => (
<BaseComboboxClear
ref={ref}
className={cn(
"combobox-clear flex h-full w-6 items-center justify-center border-0 bg-transparent p-0 text-neutral-950 dark:text-white",
className,
)}
{...props}
/>
),
)
ComboboxClear.displayName = "ComboboxClear"
+23
View File
@@ -0,0 +1,23 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxCollectionProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Collection> & {
className?: string
}
const BaseComboboxCollection = BaseCombobox.Collection as React.ElementType
export const ComboboxCollection = React.forwardRef<HTMLElement, ComboboxCollectionProps>(
({ className, ...props }, ref) => (
<BaseComboboxCollection
ref={ref}
className={cn(className)}
{...props}
/>
),
)
ComboboxCollection.displayName = "ComboboxCollection"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxEmptyProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Empty> & {
className?: string
}
const BaseComboboxEmpty = BaseCombobox.Empty as React.ElementType
export const ComboboxEmpty = React.forwardRef<HTMLElement, ComboboxEmptyProps>(
({ className, ...props }, ref) => (
<BaseComboboxEmpty
ref={ref}
className={cn(
"text-sm text-neutral-600 dark:text-neutral-400",
className,
)}
{...props}
/>
),
)
ComboboxEmpty.displayName = "ComboboxEmpty"
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxGroupLabelProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.GroupLabel> & {
className?: string
}
const BaseComboboxGroupLabel = BaseCombobox.GroupLabel as React.ElementType
export const ComboboxGroupLabel = React.forwardRef<HTMLElement, ComboboxGroupLabelProps>(
({ className, ...props }, ref) => (
<BaseComboboxGroupLabel
ref={ref}
className={cn(
"py-2 pr-2 pl-8 text-sm leading-4 text-neutral-500 select-none dark:text-neutral-400",
className,
)}
{...props}
/>
),
)
ComboboxGroupLabel.displayName = "ComboboxGroupLabel"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxGroupProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Group> & {
className?: string
}
const BaseComboboxGroup = BaseCombobox.Group as React.ElementType
export const ComboboxGroup = React.forwardRef<HTMLElement, ComboboxGroupProps>(
({ className, ...props }, ref) => (
<BaseComboboxGroup
ref={ref}
className={cn(
"block pb-2 last:pb-0",
className,
)}
{...props}
/>
),
)
ComboboxGroup.displayName = "ComboboxGroup"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxIconProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Icon> & {
className?: string
}
const BaseComboboxIcon = BaseCombobox.Icon as React.ElementType
export const ComboboxIcon = React.forwardRef<HTMLElement, ComboboxIconProps>(
({ className, ...props }, ref) => (
<BaseComboboxIcon
ref={ref}
className={cn(
"text-neutral-950 dark:text-white",
className,
)}
{...props}
/>
),
)
ComboboxIcon.displayName = "ComboboxIcon"
+112
View File
@@ -0,0 +1,112 @@
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { ComboboxRoot } from "./root"
import { ComboboxLabel } from "./label"
import { ComboboxValue } from "./value"
import { ComboboxInput } from "./input"
import { ComboboxInputGroup } from "./input-group"
import { ComboboxTrigger } from "./trigger"
import { ComboboxList } from "./list"
import { ComboboxPortal } from "./portal"
import { ComboboxBackdrop } from "./backdrop"
import { ComboboxPositioner } from "./positioner"
import { ComboboxPopup } from "./popup"
import { ComboboxArrow } from "./arrow"
import { ComboboxIcon } from "./icon"
import { ComboboxGroup } from "./group"
import { ComboboxGroupLabel } from "./group-label"
import { ComboboxItem } from "./item"
import { ComboboxItemIndicator } from "./item-indicator"
import { ComboboxChips } from "./chips"
import { ComboboxChip } from "./chip"
import { ComboboxChipRemove } from "./chip-remove"
import { ComboboxRow } from "./row"
import { ComboboxCollection } from "./collection"
import { ComboboxEmpty } from "./empty"
import { ComboboxClear } from "./clear"
const ComboboxPrimitive = {
Root: ComboboxRoot,
Label: ComboboxLabel,
Value: ComboboxValue,
Input: ComboboxInput,
InputGroup: ComboboxInputGroup,
Trigger: ComboboxTrigger,
List: ComboboxList,
Portal: ComboboxPortal,
Backdrop: ComboboxBackdrop,
Positioner: ComboboxPositioner,
Popup: ComboboxPopup,
Arrow: ComboboxArrow,
Icon: ComboboxIcon,
Group: ComboboxGroup,
GroupLabel: ComboboxGroupLabel,
Item: ComboboxItem,
ItemIndicator: ComboboxItemIndicator,
Chips: ComboboxChips,
Chip: ComboboxChip,
ChipRemove: ComboboxChipRemove,
Row: ComboboxRow,
Collection: ComboboxCollection,
Empty: ComboboxEmpty,
Clear: ComboboxClear,
Separator: BaseCombobox.Separator,
Status: BaseCombobox.Status,
useFilter: BaseCombobox.useFilter,
useFilteredItems: BaseCombobox.useFilteredItems,
}
export default ComboboxPrimitive
export {
ComboboxRoot as Combobox,
ComboboxRoot,
ComboboxLabel,
ComboboxValue,
ComboboxInput,
ComboboxInputGroup,
ComboboxTrigger,
ComboboxList,
ComboboxPortal,
ComboboxBackdrop,
ComboboxPositioner,
ComboboxPopup,
ComboboxArrow,
ComboboxIcon,
ComboboxGroup,
ComboboxGroupLabel,
ComboboxItem,
ComboboxItemIndicator,
ComboboxChips,
ComboboxChip,
ComboboxChipRemove,
ComboboxRow,
ComboboxCollection,
ComboboxEmpty,
ComboboxClear,
BaseCombobox,
}
export type { ComboboxRootProps } from "./root"
export type { ComboboxLabelProps } from "./label"
export type { ComboboxValueProps } from "./value"
export type { ComboboxInputProps } from "./input"
export type { ComboboxInputGroupProps } from "./input-group"
export type { ComboboxTriggerProps } from "./trigger"
export type { ComboboxListProps } from "./list"
export type { ComboboxPortalProps } from "./portal"
export type { ComboboxBackdropProps } from "./backdrop"
export type { ComboboxPositionerProps } from "./positioner"
export type { ComboboxPopupProps } from "./popup"
export type { ComboboxArrowProps } from "./arrow"
export type { ComboboxIconProps } from "./icon"
export type { ComboboxGroupProps } from "./group"
export type { ComboboxGroupLabelProps } from "./group-label"
export type { ComboboxItemProps } from "./item"
export type { ComboboxItemIndicatorProps } from "./item-indicator"
export type { ComboboxChipsProps } from "./chips"
export type { ComboboxChipProps } from "./chip"
export type { ComboboxChipRemoveProps } from "./chip-remove"
export type { ComboboxRowProps } from "./row"
export type { ComboboxCollectionProps } from "./collection"
export type { ComboboxEmptyProps } from "./empty"
export type { ComboboxClearProps } from "./clear"
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxInputGroupProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.InputGroup> & {
className?: string
}
const BaseComboboxInputGroup = BaseCombobox.InputGroup as React.ElementType
export const ComboboxInputGroup = React.forwardRef<HTMLElement, ComboboxInputGroupProps>(
({ className, ...props }, ref) => (
<BaseComboboxInputGroup
ref={ref}
className={cn(
"relative h-8 w-56 border border-neutral-950 bg-white dark:bg-neutral-950 focus-within:outline-2 focus-within:outline-solid focus-within:-outline-offset-1 focus-within:outline-neutral-950 dark:focus-within:outline-white dark:border-white [&>input]:pr-10 has-[.combobox-clear]:[&>input]:pr-18",
className,
)}
{...props}
/>
),
)
ComboboxInputGroup.displayName = "ComboboxInputGroup"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxInputProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Input> & {
className?: string
}
const BaseComboboxInput = BaseCombobox.Input as React.ElementType
export const ComboboxInput = React.forwardRef<HTMLElement, ComboboxInputProps>(
({ className, ...props }, ref) => (
<BaseComboboxInput
ref={ref}
className={cn(
"h-full w-full border-0 bg-white pl-2 dark:bg-neutral-950 text-sm any-pointer-coarse:text-base font-normal text-neutral-950 outline-none placeholder:text-neutral-500 dark:placeholder:text-neutral-400 dark:text-white",
className,
)}
{...props}
/>
),
)
ComboboxInput.displayName = "ComboboxInput"
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxItemIndicatorProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.ItemIndicator> & {
className?: string
}
const BaseComboboxItemIndicator = BaseCombobox.ItemIndicator as React.ElementType
export const ComboboxItemIndicator = React.forwardRef<HTMLElement, ComboboxItemIndicatorProps>(
({ className, ...props }, ref) => (
<BaseComboboxItemIndicator
ref={ref}
className={cn(
"col-start-1",
className,
)}
{...props}
/>
),
)
ComboboxItemIndicator.displayName = "ComboboxItemIndicator"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxItemProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Item> & {
className?: string
}
const BaseComboboxItem = BaseCombobox.Item as React.ElementType
export const ComboboxItem = React.forwardRef<HTMLElement, ComboboxItemProps>(
({ className, ...props }, ref) => (
<BaseComboboxItem
ref={ref}
className={cn(
"grid cursor-default grid-cols-[1rem_1fr] items-center gap-2 p-2 text-sm leading-4 outline-none select-none data-highlighted:relative data-highlighted:z-0 data-highlighted:text-white data-highlighted:before:absolute data-highlighted:before:inset-0 data-highlighted:before:z-[-1] data-highlighted:before:bg-neutral-950 dark:data-highlighted:text-neutral-950 dark:data-highlighted:before:bg-white",
className,
)}
{...props}
/>
),
)
ComboboxItem.displayName = "ComboboxItem"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxLabelProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Label> & {
className?: string
}
const BaseComboboxLabel = BaseCombobox.Label as React.ElementType
export const ComboboxLabel = React.forwardRef<HTMLElement, ComboboxLabelProps>(
({ className, ...props }, ref) => (
<BaseComboboxLabel
ref={ref}
className={cn(
"cursor-default text-sm leading-5 font-bold text-neutral-950 dark:text-white",
className,
)}
{...props}
/>
),
)
ComboboxLabel.displayName = "ComboboxLabel"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxListProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.List> & {
className?: string
}
const BaseComboboxList = BaseCombobox.List as React.ElementType
export const ComboboxList = React.forwardRef<HTMLElement, ComboboxListProps>(
({ className, ...props }, ref) => (
<BaseComboboxList
ref={ref}
className={cn(
"max-h-[min(22.5rem,var(--available-height))] overflow-y-auto overscroll-contain py-1 scroll-py-1 outline-0 data-empty:p-0",
className,
)}
{...props}
/>
),
)
ComboboxList.displayName = "ComboboxList"
+25
View File
@@ -0,0 +1,25 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxPopupProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Popup> & {
className?: string
}
const BaseComboboxPopup = BaseCombobox.Popup as React.ElementType
const defaultComboboxPopupClassName =
"w-[var(--anchor-width)] max-w-[var(--available-width)] origin-[var(--transform-origin)] border border-neutral-950 bg-white text-neutral-950 shadow-[0.25rem_0.25rem_0_rgb(0_0_0_/_12%)] transition-[transform,opacity] duration-[350ms] ease-[cubic-bezier(0.22,1,0.36,1)] data-ending-style:duration-150 data-ending-style:ease-out data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0 dark:border-white dark:bg-neutral-950 dark:text-white dark:shadow-none"
export const ComboboxPopup = React.forwardRef<HTMLElement, ComboboxPopupProps>(
({ className, ...props }, ref) => (
<BaseComboboxPopup
ref={ref}
className={cn(className ?? defaultComboboxPopupClassName)}
{...props}
/>
),
)
ComboboxPopup.displayName = "ComboboxPopup"
+23
View File
@@ -0,0 +1,23 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxPortalProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Portal> & {
className?: string
}
const BaseComboboxPortal = BaseCombobox.Portal as React.ElementType
export const ComboboxPortal = React.forwardRef<HTMLElement, ComboboxPortalProps>(
({ className, ...props }, ref) => (
<BaseComboboxPortal
ref={ref}
className={cn(className)}
{...props}
/>
),
)
ComboboxPortal.displayName = "ComboboxPortal"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxPositionerProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Positioner> & {
className?: string
}
const BaseComboboxPositioner = BaseCombobox.Positioner as React.ElementType
export const ComboboxPositioner = React.forwardRef<HTMLElement, ComboboxPositionerProps>(
({ className, ...props }, ref) => (
<BaseComboboxPositioner
ref={ref}
className={cn(
"outline-none",
className,
)}
{...props}
/>
),
)
ComboboxPositioner.displayName = "ComboboxPositioner"
+23
View File
@@ -0,0 +1,23 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxRootProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Root> & {
className?: string
}
const BaseComboboxRoot = BaseCombobox.Root as React.ElementType
export const ComboboxRoot = React.forwardRef<HTMLElement, ComboboxRootProps>(
({ className, ...props }, ref) => (
<BaseComboboxRoot
ref={ref}
className={cn(className)}
{...props}
/>
),
)
ComboboxRoot.displayName = "ComboboxRoot"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxRowProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Row> & {
className?: string
}
const BaseComboboxRow = BaseCombobox.Row as React.ElementType
export const ComboboxRow = React.forwardRef<HTMLElement, ComboboxRowProps>(
({ className, ...props }, ref) => (
<BaseComboboxRow
ref={ref}
className={cn(
"grid grid-cols-5",
className,
)}
{...props}
/>
),
)
ComboboxRow.displayName = "ComboboxRow"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxTriggerProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Trigger> & {
className?: string
}
const BaseComboboxTrigger = BaseCombobox.Trigger as React.ElementType
export const ComboboxTrigger = React.forwardRef<HTMLElement, ComboboxTriggerProps>(
({ className, ...props }, ref) => (
<BaseComboboxTrigger
ref={ref}
className={cn(
"flex h-full w-6 items-center justify-center border-0 bg-transparent p-0 text-neutral-950 dark:text-white",
className,
)}
{...props}
/>
),
)
ComboboxTrigger.displayName = "ComboboxTrigger"
+26
View File
@@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
import { cn } from "@/lib/utils"
export type ComboboxValueProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Value> & {
className?: string
}
const BaseComboboxValue = BaseCombobox.Value as React.ElementType
export const ComboboxValue = React.forwardRef<HTMLElement, ComboboxValueProps>(
({ className, ...props }, ref) => (
<BaseComboboxValue
ref={ref}
className={cn(
"text-sm text-neutral-950 dark:text-white",
className,
)}
{...props}
/>
),
)
ComboboxValue.displayName = "ComboboxValue"