Compare commits

...

16 Commits

Author SHA1 Message Date
WK Wong
bea4751b95 chore(changeset): update changeset 2025-11-28 19:27:31 +08:00
WK Wong
1dfb72291a chore(deps): bump peerDependencies for theme package 2025-11-28 18:40:59 +08:00
WK Wong
4ec1956d9a fix(radio): duplicate import 2025-11-28 18:29:47 +08:00
WK Wong
d40c236b88 chore(docs): type issues 2025-11-28 17:23:27 +08:00
WK Wong
b07b56b8ec refactor: remove outer cn 2025-11-28 17:11:30 +08:00
WK Wong
621561cabe fix(theme): incorrect syntax 2025-11-28 17:11:10 +08:00
WK Wong
be215cd537 chore: rollback clsx for mergeProps 2025-11-28 16:53:32 +08:00
WK Wong
6a7befdc7d chore(deps): remove clsx 2025-11-28 13:10:43 +08:00
WK Wong
aefadfe0a0 refactor: replace clsx by cn 2025-11-28 13:08:03 +08:00
WK Wong
cf628e1bc8 refactor(theme): use cnMerge from tailwind-variants 2025-11-28 12:49:01 +08:00
WK Wong
a1a612d3c4 Merge branch 'canary' into chore/bump-tw-version 2025-11-27 11:29:35 +08:00
WK
0825f88cd2
fix(spinner): cater global spinner variant (#5948)
* fix(spinner): cater global spinner variant

* feat(spinner): add spinner test cases

* chore(changeset): add changeset
2025-11-26 16:46:34 +08:00
WK
ce0c298785
fix(number-input): lable position for empty percent format (#5945)
* fix(number-input): lable position for empty percent format

* chore(changeset): fix typo
2025-11-26 13:56:48 +08:00
WK
4fa54534b2
fix(radio): handle props styles in getBaseProps (#5944)
* fix(radio): handle props styles in getBaseProps

* refactor(radio): examples
2025-11-26 13:55:37 +08:00
WK
484212712c
chore(deps): bump posthog-js (#5937) 2025-11-25 10:41:59 +08:00
WK
217e88d58e
fix(docs): incorrect date value type in api (#5936)
* fix(docs): incorrect date value type in api

* chore(docs): revise types
2025-11-25 01:23:45 +08:00
177 changed files with 660 additions and 594 deletions

View File

@ -0,0 +1,5 @@
---
"@heroui/number-input": patch
---
fix label position for empty percent format (#5941)

View File

@ -0,0 +1,5 @@
---
"@heroui/spinner": patch
---
cater global spinner variant (#5939)

View File

@ -1,6 +1,52 @@
---
"@heroui/scroll-shadow": patch
"@heroui/autocomplete": patch
"@heroui/number-input": patch
"@heroui/breadcrumbs": patch
"@heroui/date-picker": patch
"@heroui/date-input": patch
"@heroui/pagination": patch
"@heroui/accordion": patch
"@heroui/input-otp": patch
"@heroui/calendar": patch
"@heroui/checkbox": patch
"@heroui/dropdown": patch
"@heroui/progress": patch
"@heroui/skeleton": patch
"@heroui/divider": patch
"@heroui/listbox": patch
"@heroui/popover": patch
"@heroui/snippet": patch
"@heroui/spinner": patch
"@heroui/tooltip": patch
"@heroui/avatar": patch
"@heroui/button": patch
"@heroui/drawer": patch
"@heroui/navbar": patch
"@heroui/ripple": patch
"@heroui/select": patch
"@heroui/slider": patch
"@heroui/spacer": patch
"@heroui/switch": patch
"@heroui/alert": patch
"@heroui/badge": patch
"@heroui/image": patch
"@heroui/input": patch
"@heroui/modal": patch
"@heroui/radio": patch
"@heroui/table": patch
"@heroui/toast": patch
"@heroui/card": patch
"@heroui/chip": patch
"@heroui/code": patch
"@heroui/form": patch
"@heroui/link": patch
"@heroui/menu": patch
"@heroui/tabs": patch
"@heroui/user": patch
"@heroui/system-rsc": patch
"@heroui/kbd": patch
"@heroui/theme": patch
---
bump tailwind-variants & tailwind-merge
bump tailwind-variants & tailwind-merge and use latest tv functions

View File

@ -0,0 +1,5 @@
---
"@heroui/radio": patch
---
handle props styles in getBaseProps (#5942)

View File

@ -2,7 +2,7 @@ import "@/styles/globals.css";
import "@/styles/sandpack.css";
import type {Metadata, Viewport} from "next";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {Analytics} from "@vercel/analytics/next";
import {Providers} from "./providers";
@ -75,7 +75,7 @@ export default function RootLayout({children}: {children: React.ReactNode}) {
<html suppressHydrationWarning dir="ltr" lang="en">
<head />
<body
className={clsx(
className={cn(
"min-h-screen text-foreground bg-background font-sans antialiased",
fonts.sans.variable,
fonts.mono.variable,

View File

@ -1,6 +1,6 @@
import type {ReactNode, FC} from "react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
export interface BgGridContainerProps {
showGradient?: boolean;
children?: ReactNode;
@ -14,7 +14,7 @@ export const BgGridContainer: FC<BgGridContainerProps> = ({
}) => {
return (
<div
className={clsx(
className={cn(
"relative overflow-y-hidden flex items-center border border-default-200 dark:border-default-100 px-2 py-4 rounded-lg",
"overflow-hidden",
// blur effect
@ -35,7 +35,7 @@ export const BgGridContainer: FC<BgGridContainerProps> = ({
{children}
</div>
{/* <div
className={clsx(
className={cn(
"hidden md:block absolute z-[-1] inset-0 bg-grid-zinc-300/25 [mask-image:linear-gradient(0deg,rgba(255,255,255,0.1),rgba(255,255,255,0.6))]",
"dark:bg-grid-zinc-500/25 dark:[mask-image:linear-gradient(0deg,rgba(255,255,255,0.1),rgba(255,255,255,0.5))]",
)}

View File

@ -12,7 +12,7 @@ import {CloseIcon} from "@heroui/shared-icons";
import {tv} from "tailwind-variants";
import {usePathname, useRouter} from "next/navigation";
import MultiRef from "react-multi-ref";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import scrollIntoView from "scroll-into-view-if-needed";
import {isAppleDevice, isWebKit} from "@react-aria/utils";
import {create} from "zustand";
@ -323,7 +323,7 @@ export const Cmdk: FC<{}> = () => {
return (
<Button
isIconOnly
className={clsx(
className={cn(
"border data-[hover=true]:bg-content2 border-default-400 dark:border-default-100",
className,
)}

View File

@ -8,7 +8,7 @@ import css from "refractor/lang/css";
import diff from "refractor/lang/diff";
import {toHtml} from "hast-util-to-html";
import rangeParser from "parse-numeric-range";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {Pre} from "./pre";
import {WindowActions} from "./window-actions";
@ -141,7 +141,7 @@ const CodeBlock = React.forwardRef<HTMLPreElement, CodeBlockProps>((_props, forw
// TODO reset theme
const classes = `language-${language}`;
const codeClasses = clsx("absolute w-full px-4 pb-6", showWindowIcons ? "top-10" : "top-0");
const codeClasses = cn("absolute w-full px-4 pb-6", showWindowIcons ? "top-10" : "top-0");
if (mode === "typewriter") {
return <CodeTypewriter className={classes} css={css} value={result} {...props} />;
@ -150,12 +150,12 @@ const CodeBlock = React.forwardRef<HTMLPreElement, CodeBlockProps>((_props, forw
return (
<Pre
ref={forwardedRef}
className={clsx("code-block", classes, className)}
className={cn("code-block", classes, className)}
data-line-numbers={showLineNumbers}
{...props}
>
{showWindowIcons && <WindowActions title={title} />}
<code dangerouslySetInnerHTML={{__html: result}} className={clsx(classes, codeClasses)} />
<code dangerouslySetInnerHTML={{__html: result}} className={cn(classes, codeClasses)} />
</Pre>
);
});

View File

@ -1,5 +1,5 @@
import {forwardRef} from "react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
export interface PreProps {
className?: string;
@ -14,7 +14,7 @@ export const Pre = forwardRef<HTMLPreElement, PreProps>(
return (
<pre
ref={forwardedRef}
className={clsx(
className={cn(
"relative w-full h-full box-border shadow-md text-white/80 leading-5 whitespace-pre text-sm font-mono bg-code-background rounded-xl [&>code]:transition-transform",
scrollClass,
className,

View File

@ -1,6 +1,6 @@
import React from "react";
import {tv} from "tailwind-variants";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
export type WindowActionsProps = {
title?: string;
@ -21,7 +21,7 @@ const windowIconStyles = tv({
export const WindowActions: React.FC<WindowActionsProps> = ({title, className, ...props}) => {
return (
<div
className={clsx(
className={cn(
"flex items-center sticky top-0 left-0 px-4 z-10 justify-between h-8 bg-code-background w-full",
className,
)}

View File

@ -5,7 +5,7 @@ import type {FC} from "react";
import {Card, CardBody, Button, Image, Slider} from "@heroui/react";
import {useState} from "react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import NextImage from "next/image";
import {
@ -25,7 +25,7 @@ export const MusicPlayer: FC<MusicPlayerProps> = ({className, ...otherProps}) =>
return (
<Card
isBlurred
className={clsx("border-none bg-background/60 dark:bg-default-100/50", className)}
className={cn("border-none bg-background/60 dark:bg-default-100/50", className)}
shadow="sm"
{...otherProps}
>

View File

@ -2,7 +2,7 @@
import {useState} from "react";
import {Card, CardHeader, Button, Avatar, CardBody, CardFooter} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
interface UserTwitterCardProps {
className?: string;
@ -12,7 +12,7 @@ export const UserTwitterCard = ({className}: UserTwitterCardProps) => {
const [isFollowed, setIsFollowed] = useState(false);
return (
<Card className={clsx("max-w-[300px]", className)}>
<Card className={cn("max-w-[300px]", className)}>
<CardHeader className="justify-between">
<div className="flex gap-5">
<Avatar

View File

@ -3,7 +3,7 @@ import type {GradientBoxProps} from "@/components/gradient-box";
import React from "react";
import {LivePreview, LiveProvider, LiveError} from "react-live";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import * as HeroUI from "@heroui/react";
import * as intlDateUtils from "@internationalized/date";
import * as reactAriaI18n from "@react-aria/i18n";
@ -73,7 +73,7 @@ export const ReactLiveDemo: React.FC<ReactLiveDemoProps> = ({
</div>
)}
<LivePreview
className={clsx("live-preview flex h-full w-full not-prose ", {
className={cn("live-preview flex h-full w-full not-prose ", {
"justify-center items-center": isCentered,
})}
style={{height}}
@ -87,7 +87,7 @@ export const ReactLiveDemo: React.FC<ReactLiveDemoProps> = ({
{isGradientBox ? (
<GradientBox
isCentered
className={clsx(
className={cn(
className,
"relative overflow-y-hidden flex items-center border border-default-200 dark:border-default-100 px-2 py-4 rounded-lg overflow-hidden",
)}
@ -99,7 +99,7 @@ export const ReactLiveDemo: React.FC<ReactLiveDemoProps> = ({
</div>
</GradientBox>
) : (
<BgGridContainer className={clsx(className, "group/code-demo")}>{content}</BgGridContainer>
<BgGridContainer className={cn(className, "group/code-demo")}>{content}</BgGridContainer>
)}
</LiveProvider>
);

View File

@ -4,7 +4,7 @@ import type {Language, PrismTheme} from "prism-react-renderer";
import {useIntersectionObserver} from "usehooks-ts";
import React, {forwardRef, useEffect} from "react";
import {clsx, dataAttr, getUniqueID} from "@heroui/shared-utils";
import {dataAttr, getUniqueID} from "@heroui/shared-utils";
import BaseHighlight, {defaultProps} from "prism-react-renderer";
import {debounce, omit} from "@heroui/shared-utils";
import {cn} from "@heroui/react";
@ -124,7 +124,7 @@ const CodeBlockHighlight = ({
preRef.current = element;
}
}}
className={clsx(className, classNameProp, `language-${codeLang}`, "max-w-full", {
className={cn(className, classNameProp, `language-${codeLang}`, "max-w-full", {
"flex-col": isMultiLine,
"overflow-x-scroll scrollbar-hide": hideScrollBar,
})}
@ -138,7 +138,7 @@ const CodeBlockHighlight = ({
<div
{...omit(lineProps, ["key"])}
key={`${i}-${getUniqueID("line-wrapper")}`}
className={clsx(
className={cn(
lineProps.className,
removeIndent ? "pr-4" : "px-4",
"relative [&>span]:relative [&>span]:z-10",
@ -196,7 +196,7 @@ const CodeBlockHighlight = ({
)}
</BaseHighlight>
) : (
<div className={clsx(classNameProp, "w-full bg-code-background rounded-lg")} />
<div className={cn(classNameProp, "w-full bg-code-background rounded-lg")} />
)}
</div>
);

View File

@ -20,8 +20,8 @@ import {useFocusRing} from "@react-aria/focus";
import {useTreeState} from "@react-stately/tree";
import {useSelectableCollection} from "@react-aria/selection";
import {usePress} from "@react-aria/interactions";
import {clsx, dataAttr, debounce, isEmpty} from "@heroui/shared-utils";
import {Spacer, Link as HeroUILink, Chip, dataFocusVisibleClasses} from "@heroui/react";
import {dataAttr, debounce, isEmpty} from "@heroui/shared-utils";
import {Spacer, Link as HeroUILink, Chip, dataFocusVisibleClasses, cn} from "@heroui/react";
import Link from "next/link";
import {usePathname, useRouter} from "next/navigation";
@ -89,7 +89,7 @@ function TreeItem<T>(props: TreeItemProps<T>) {
const Component = hasChildNodes ? "ul" : "li";
const cn = clsx(
const classNames = cn(
"w-full",
"font-normal",
"before:mr-4",
@ -125,7 +125,7 @@ function TreeItem<T>(props: TreeItemProps<T>) {
<span className="flex items-center gap-3">
<span className="font-medium sm:text-sm">{rendered}</span>
<ChevronIcon
className={clsx("transition-transform", {
className={cn("transition-transform", {
"-rotate-90": isExpanded,
})}
/>
@ -136,14 +136,14 @@ function TreeItem<T>(props: TreeItemProps<T>) {
return (
<HeroUILink
as={item.props?.comingSoon ? "div" : Link}
className={clsx(cn, {
className={cn(classNames, {
"pointer-events-none": item.props?.comingSoon,
})}
color="foreground"
href={item.props?.comingSoon ? "#" : paths.pathname}
>
<span
className={clsx(
className={cn(
"sm:text-sm",
isSelected
? "text-primary font-medium dark:text-foreground"
@ -195,7 +195,7 @@ function TreeItem<T>(props: TreeItemProps<T>) {
ref={ref}
aria-expanded={dataAttr(hasChildNodes ? isExpanded : undefined)}
aria-selected={dataAttr(isSelected)}
className={clsx(
className={cn(
"flex flex-col outline-solid outline-transparent w-full tap-highlight-transparent",
hasChildNodes ? "mb-4" : "first:mt-4",
// focus ring
@ -206,7 +206,7 @@ function TreeItem<T>(props: TreeItemProps<T>) {
role="treeitem"
>
<div
className={clsx("flex items-center gap-3 cursor-pointer", {
className={cn("flex items-center gap-3 cursor-pointer", {
"pointer-events-none": item.props?.comingSoon,
})}
{...(item.props?.comingSoon ? {} : pressProps)}
@ -349,7 +349,7 @@ export const DocsSidebar: FC<DocsSidebarProps> = ({routes, slug, tag, className}
return (
<div
className={clsx(
className={cn(
"lg:fixed mt-2 z-0 lg:h-[calc(100vh-121px)]",
isProBannerVisible ? "lg:top-32" : "lg:top-20",
className,

View File

@ -4,7 +4,7 @@ import type {FC} from "react";
import type {Heading} from "@/libs/docs/utils";
import {useRef, useEffect, useState} from "react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {Divider, Spacer} from "@heroui/react";
import {ChevronCircleTopLinearIcon} from "@heroui/shared-icons";
import scrollIntoView from "scroll-into-view-if-needed";
@ -69,7 +69,7 @@ export const DocsToc: FC<DocsTocProps> = ({headings}) => {
}, []);
return (
<div className={clsx("fixed", isProBannerVisible ? "top-32" : "top-20")}>
<div className={cn("fixed", isProBannerVisible ? "top-32" : "top-20")}>
<div
ref={tocRef}
className="w-full max-w-[12rem] max-h-[calc(100vh-500px)] flex flex-col gap-4 text-left pb-16 scrollbar-hide overflow-y-scroll"
@ -86,7 +86,7 @@ export const DocsToc: FC<DocsTocProps> = ({headings}) => {
heading.level > 1 && (
<li
key={i}
className={clsx(
className={cn(
"relative",
"transition-colors",
"font-normal",

View File

@ -4,7 +4,7 @@ import NextLink from "next/link";
import {usePostHog} from "posthog-js/react";
import arrowRightUpIcon from "@iconify/icons-solar/arrow-right-up-linear";
import {Icon} from "@iconify/react/dist/offline";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
type Props = {
className?: string;
@ -24,13 +24,13 @@ export const FbRoadmapLink = ({className, innerClassName}: Props) => {
return (
<NextLink
className={clsx("inline-flex items-center", className)}
className={cn("inline-flex items-center", className)}
color="foreground"
href={`${process.env.NEXT_PUBLIC_FB_FEEDBACK_URL}/roadmap`}
target="_blank"
onClick={fbLinkOnClick}
>
<div className={clsx("relative", innerClassName)}>
<div className={cn("relative", innerClassName)}>
Roadmap
<Icon
className="absolute right-[-10px] top-0 outline-solid outline-transparent transition-transform group-data-[hover=true]:translate-y-0.5 [&>path]:stroke-[2.5px]"

View File

@ -11,7 +11,7 @@ import {
Tooltip,
} from "@heroui/react";
import {useInView} from "framer-motion";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {
AddNoteBulkIcon,
CopyDocumentBulkIcon,
@ -217,7 +217,7 @@ export const A11yOtb = () => {
description="Permanently delete the file"
shortcut="⌘⇧D"
startContent={
<DeleteDocumentBulkIcon className={clsx(iconClasses, "text-danger!")} />
<DeleteDocumentBulkIcon className={cn(iconClasses, "text-danger!")} />
}
>
Delete file

View File

@ -1,6 +1,6 @@
"use client";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useIsMounted} from "@/hooks/use-is-mounted";
@ -9,7 +9,7 @@ export const BgLooper = () => {
return (
<div
className={clsx(
className={cn(
"absolute -top-20 lg:top-10 w-screen h-screen z-0 opacity-0 overflow-hidden",
"data-[mounted=true]:opacity-100 transition-opacity",
"bg-left bg-no-repeat bg-[url('/gradients/looper-pattern.svg')]",

View File

@ -1,5 +1,5 @@
import {memo} from "react";
import clsx from "clsx";
import {cn} from "@heroui/theme";
import {sectionWrapper, title, titleWrapper, subtitle} from "../../primitives";
import Marquee from "../marquee";
@ -94,7 +94,7 @@ export const HeroUIProSection = () => {
<HeroUIProImage />
</Marquee>
<div
className={clsx(
className={cn(
"absolute inset-0 pointer-events-none z-20 bg-white dark:bg-black",
"[-webkit-mask-image:radial-gradient(at_70%_50%,_rgba(255,255,255,0)_20%,_rgba(255,255,255,0.8)_40%,_rgba(0,0,0,1)_60%)]",
)}

View File

@ -2,7 +2,7 @@
import {Button, Link} from "@heroui/react";
import {ArrowRightIcon} from "@heroui/shared-icons";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import NextLink from "next/link";
import {Code} from "@heroui/react";
import {usePostHog} from "posthog-js/react";
@ -114,7 +114,7 @@ export const InstallBanner = () => {
</div>
</div>
<div
className={clsx(
className={cn(
"absolute -top-20 lg:top-10 -translate-y-1/2 w-screen h-screen -z-50 opacity-0",
"data-[mounted=true]:opacity-100 transition-opacity",
"bg-left bg-no-repeat bg-[url('/gradients/looper-pattern.svg')]",

View File

@ -1,6 +1,6 @@
import type {Language} from "prism-react-renderer";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import * as Components from "@heroui/react";
import NextImage from "next/image";
import {usePostHog} from "posthog-js/react";
@ -36,7 +36,7 @@ const Table: React.FC<{children?: React.ReactNode}> = ({children}) => {
const Thead: React.FC<{children?: React.ReactNode}> = ({children}) => {
return (
<thead
className={clsx(
className={cn(
"[&>tr]:h-12",
"[&>tr>th]:py-0",
"[&>tr>th]:align-middle",
@ -94,7 +94,7 @@ const LinkedHeading: React.FC<LinkedHeadingProps> = ({
return (
<Component
className={clsx({"linked-heading": linked}, linked ? {} : className)}
className={cn({"linked-heading": linked}, linked ? {} : className)}
data-id={id}
data-level={level}
data-name={props.children}
@ -117,7 +117,7 @@ const List: React.FC<{children?: React.ReactNode}> = ({children}) => {
const InlineCode = ({children, className}: {children?: React.ReactNode; className?: string}) => {
return (
<Components.Code
className={clsx(
className={cn(
'p-0 relative before:content-["`"] after:content-["`"] font-semibold font-mono text-small rounded-md text-default-900 dark:text-default-500 bg-transparent',
className,
)}
@ -151,7 +151,7 @@ const Code = ({
fullWidth
hideSymbol
classNames={{
base: clsx(
base: cn(
"px-0 bg-code-background text-code-foreground",
{
"items-start": isMultiLine,
@ -219,7 +219,7 @@ const InlineCodeChip = ({
}) => {
return (
<InlineCode
className={clsx(
className={cn(
"before:hidden after:hidden text-tiny rounded-md text-default-600 bg-default-100 dark:bg-default-100/80 px-1.5 py-0.5",
className,
)}

View File

@ -20,7 +20,7 @@ import {
} from "@heroui/react";
import {dataFocusVisibleClasses} from "@heroui/theme";
import {isAppleDevice} from "@react-aria/utils";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import NextLink from "next/link";
import {usePathname} from "next/navigation";
import {motion, AnimatePresence} from "framer-motion";
@ -91,7 +91,7 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
"/docs/guide/upgrade-to-v2",
];
const navLinkClasses = clsx(
const navLinkClasses = cn(
link({color: "foreground"}),
"data-[active=true]:text-primary data-[active=true]:font-semibold",
);
@ -162,7 +162,7 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
return (
<HeroUINavbar
ref={ref}
className={clsx({
className={cn({
"z-100001": isMenuOpen,
})}
classNames={{
@ -225,7 +225,7 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
</NavbarItem>
<NavbarItem className="flex h-full items-center">
<button
className={clsx(
className={cn(
"transition-opacity p-1 hover:opacity-80 rounded-full cursor-pointer outline-solid outline-transparent",
// focus ring
...dataFocusVisibleClasses,

View File

@ -2,7 +2,7 @@ import type {ButtonProps} from "@heroui/react";
import {forwardRef} from "react";
import {Button} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
export interface PreviewButtonProps extends ButtonProps {
icon: React.ReactNode;
@ -16,7 +16,7 @@ export const PreviewButton = forwardRef<HTMLButtonElement | null, PreviewButtonP
<Button
ref={ref}
isIconOnly
className={clsx(
className={cn(
"relative z-50 text-zinc-300 top-8 border-1 border-transparent bg-transparent before:bg-white/10 before:content-[''] before:block before:z-[-1] before:absolute before:inset-0 before:backdrop-blur-md before:backdrop-saturate-100 before:rounded-lg",
className,
)}

View File

@ -1,6 +1,6 @@
import * as React from "react";
import {useSandpackNavigation} from "@codesandbox/sandpack-react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {RotateRightLinearIcon} from "@/components/icons";
@ -16,7 +16,7 @@ export const RefreshButton = ({clientId}: RefreshButtonProps): JSX.Element => {
return (
<button
className={clsx("sp-button", "sp-icon-standalone")}
className={cn("sp-button", "sp-icon-standalone")}
title="Refresh Sandpack"
type="button"
onClick={refresh}

View File

@ -2,7 +2,7 @@ import type {FC, ReactNode} from "react";
import {useMemo} from "react";
import {parseToRgba} from "color2k";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useIsSSR} from "@react-aria/ssr";
export interface SonarPulseProps {
children: ReactNode;
@ -49,7 +49,7 @@ export const SonarPulse: FC<SonarPulseProps> = ({
circles.push(
<div
key={i}
className={clsx("circle", `circle-${i}`, "absolute", {
className={cn("circle", `circle-${i}`, "absolute", {
"animate-expand-opacity": playState === "running",
})}
style={{

View File

@ -6,7 +6,7 @@ import type {SwitchProps} from "@heroui/react";
import {VisuallyHidden} from "@react-aria/visually-hidden";
import {useSwitch} from "@heroui/react";
import {useTheme} from "next-themes";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useIsSSR} from "@react-aria/ssr";
import {usePostHog} from "posthog-js/react";
@ -50,7 +50,7 @@ export const ThemeSwitch: FC<ThemeSwitchProps> = ({className, classNames}) => {
return (
<Component
{...getBaseProps({
className: clsx(
className: cn(
"p-1 w-8 h-8 transition-opacity hover:opacity-80 cursor-pointer",
className,
classNames?.base,
@ -69,7 +69,7 @@ export const ThemeSwitch: FC<ThemeSwitchProps> = ({className, classNames}) => {
<div
{...getWrapperProps()}
className={slots.wrapper({
class: clsx(
class: cn(
[
"w-auto h-auto",
"bg-transparent",

View File

@ -6,7 +6,7 @@ import {HexColorInput, HexColorPicker} from "react-colorful";
import Values from "values.js";
import {readableColor} from "color2k";
import {useTheme} from "next-themes";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {colorValuesToRgb, getColorWeight} from "../utils/colors";
@ -49,7 +49,7 @@ export function ColorPicker({hexColor, type, onChange, onClose}: ColorPickerProp
<Button
fullWidth
aria-label={`Change ${type} color`}
className={clsx(
className={cn(
getColor(type),
"rounded-lg min-w-9 w-9 h-9",
"border border-black/10 dark:border-white/10",

View File

@ -1,5 +1,5 @@
import {Tooltip} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {CircleInfo} from "@/components/icons";
@ -35,7 +35,7 @@ export function ConfigSection({
</Tooltip>
)}
</div>
<div className={clsx("flex flex-wrap gap-2 mt-3")}>{children}</div>
<div className={cn("flex flex-wrap gap-2 mt-3")}>{children}</div>
</div>
);
}

View File

@ -1,5 +1,5 @@
import {Button} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
interface EditableButtonProps {
title: any;
@ -11,7 +11,7 @@ interface EditableButtonProps {
const EditableButton = ({title, className, value, setValue}: EditableButtonProps) => {
return (
<Button
className={clsx(
className={cn(
"group h-auto py-4 flex flex-col justify-between gap-y-2 min-w-auto w-auto border-black/20 dark:border-white/20",
value === title ? "border-black/60 dark:border-white/60" : "",
)}
@ -21,7 +21,7 @@ const EditableButton = ({title, className, value, setValue}: EditableButtonProps
}}
>
<div
className={clsx(
className={cn(
"h-7 w-7 border-t-2 border-l-2 border-blue-400 bg-gradient-to-b from-[#0077ff1A] to-[#92c5ff00]",
className,
)}

View File

@ -1,7 +1,7 @@
import type {FontName, FontType} from "../../types";
import {Button} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
interface FontButtonProps {
title: FontName;
@ -38,7 +38,7 @@ const FontButton = ({title, value, setValue}: FontButtonProps) => {
return (
<Button
className={clsx(
className={cn(
"group h-24 flex flex-col justify-center items-center gap-y-2 px-0 border-black/20 dark:border-white/20",
value === title ? "border-black/60 dark:border-white/60" : "",
)}

View File

@ -19,7 +19,6 @@ import {useLocalStorage} from "usehooks-ts";
import {Icon} from "@iconify/react/dist/offline";
import LinkSquareIcon from "@iconify/icons-solar/link-square-linear";
import {ArrowLeftIcon, ChevronIcon, ChevronUpIcon, CloseIcon} from "@heroui/shared-icons";
import {clsx} from "@heroui/shared-utils";
import {useThemeBuilder} from "../../provider";
import {configKey, syncThemesKey, initialConfig} from "../../constants";
@ -234,7 +233,7 @@ export default function Configuration() {
return (
<div key={template.name} className="flex flex-col items-center">
<Button
className={clsx(
className={cn(
"p-0 min-w-0 w-auto h-10 border border-black/5 gap-0 rounded-sm overflow-hidden m-[3px]",
templateTheme === template.name
? "outline-1 outline-foreground-800"

View File

@ -1,6 +1,6 @@
import type {ConfigColors} from "../../types";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
interface SwatchProps {
colors: {background: string} & ConfigColors["baseColor"];
@ -10,9 +10,9 @@ interface SwatchProps {
export default function Swatch({colors, className, innerClassName}: SwatchProps) {
return (
<div className={clsx("flex h-6", className)}>
<div className={cn("flex h-6", className)}>
{Object.entries(colors).map(([key, value]) => (
<div key={key} className={clsx("w-2 h-full", innerClassName)} style={{background: value}} />
<div key={key} className={cn("w-2 h-full", innerClassName)} style={{background: value}} />
))}
</div>
);

View File

@ -1,5 +1,5 @@
import {Button} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
interface ValueButtonProps<T extends string | number> {
currentValue: T;
@ -19,7 +19,7 @@ const ValueButton = ({
isIconOnly
aria-checked={value === currentValue}
aria-label={`Select ${value}${endContent ?? ""}`}
className={clsx(
className={cn(
"group h-auto w-auto rounded-md p-0.5 px-1 text-sm font-normal border-black/20 dark:border-white/20",
value === currentValue ? "border-black/60 dark:border-white/60" : "",
)}

View File

@ -3,7 +3,7 @@ import type {Border, HeroUIScaling} from "../../types";
import {cloneElement} from "react";
import {Avatar as HeroUIAvatar} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {ShowcaseComponent} from "../showcase-component";
import {useThemeBuilder} from "../../provider";
@ -55,23 +55,23 @@ const Section = ({
switch (scaling) {
case 90: {
className = clsx("h-6 w-6", borderClassName);
className = cn("h-6 w-6", borderClassName) as string;
break;
}
case 95: {
className = clsx("h-8 w-8", borderClassName);
className = cn("h-8 w-8", borderClassName) as string;
break;
}
case 100: {
className = clsx("h-10 w-10", borderClassName);
className = cn("h-10 w-10", borderClassName) as string;
break;
}
case 105: {
className = clsx("h-12 w-12", borderClassName);
className = cn("h-12 w-12", borderClassName) as string;
break;
}
case 110: {
className = clsx("h-14 w-14", borderClassName);
className = cn("h-14 w-14", borderClassName) as string;
break;
}
}

View File

@ -3,7 +3,7 @@ import type {Border} from "../../types";
import {cloneElement} from "react";
import {Button as HeroUIButton} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {ShowcaseComponent} from "../showcase-component";
import {useThemeBuilder} from "../../provider";
@ -28,7 +28,7 @@ const SectionBase = ({
return (
<HeroUIButton
key={color}
className={clsx(className, "capitalize")}
className={cn(className, "capitalize")}
color={color}
isDisabled={isDisabled}
radius={radius}
@ -74,7 +74,7 @@ const Section = ({
{variants.map((variant) => (
<SectionBase
key={variant}
className={clsx(
className={cn(
className,
variant === "bordered" || variant === "faded" || variant === "ghost" ? borderClass : "",
)}

View File

@ -3,7 +3,7 @@ import type {Border, HeroUIScaling} from "../../types";
import {cloneElement} from "react";
import {Chip as HeroUIChip} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {ShowcaseComponent} from "../showcase-component";
import {useThemeBuilder} from "../../provider";
@ -28,7 +28,7 @@ const SectionBase = ({
return (
<HeroUIChip
key={radius}
className={clsx(className, "capitalize")}
className={cn(className, "capitalize")}
color={color}
isDisabled={isDisabled}
radius={radius}
@ -90,7 +90,7 @@ const Section = ({
{variants.map((variant, idx) =>
cloneElement(<SectionBase key={idx} />, {
color,
className: clsx(
className: cn(
className,
variant === "bordered" || variant === "faded" ? borderClass : "",
),

View File

@ -2,7 +2,7 @@ import type {InputProps} from "@heroui/react";
import type {Border, HeroUIScaling} from "../../types";
import {Input} from "@heroui/react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {ShowcaseComponent} from "../showcase-component";
import {useThemeBuilder} from "../../provider";
@ -88,7 +88,7 @@ const Section = ({
key={idx}
classNames={{
...classNames,
inputWrapper: clsx(clsx(variant === "bordered" && borderClass)),
inputWrapper: cn(cn(variant === "bordered" && borderClass)),
}}
color={color}
isDisabled={false}

View File

@ -15,12 +15,13 @@ export const CustomRadio = (props) => {
return (
<Component
{...getBaseProps()}
className={cn(
"group inline-flex items-center hover:opacity-70 active:opacity-50 justify-between flex-row-reverse tap-highlight-transparent",
"max-w-[300px] cursor-pointer border-2 border-default rounded-lg gap-4 p-4",
"data-[selected=true]:border-primary",
)}
{...getBaseProps({
className: cn(
"group inline-flex items-center hover:opacity-70 active:opacity-50 justify-between flex-row-reverse tap-highlight-transparent m-0",
"max-w-[300px] cursor-pointer border-2 border-default rounded-lg gap-4 p-4",
"data-[selected=true]:border-primary",
),
})}
>
<VisuallyHidden>
<input {...getInputProps()} />

View File

@ -18,12 +18,13 @@ export const CustomRadio = (props: RadioProps) => {
return (
<Component
{...getBaseProps()}
className={cn(
"group inline-flex items-center justify-between hover:bg-content2 flex-row-reverse",
"max-w-[300px] cursor-pointer border-2 border-default rounded-lg gap-4 p-4",
"data-[selected=true]:border-primary",
)}
{...getBaseProps({
className: cn(
"group inline-flex items-center hover:opacity-70 active:opacity-50 justify-between flex-row-reverse tap-highlight-transparent m-0",
"max-w-[300px] cursor-pointer border-2 border-default rounded-lg gap-4 p-4",
"data-[selected=true]:border-primary",
),
})}
>
<VisuallyHidden>
<input {...getInputProps()} />

View File

@ -329,7 +329,7 @@ import {I18nProvider} from "@react-aria/i18n";
},
{
attribute: "value",
type: "ZonedDateTime | CalendarDate | CalendarDateTime | undefined | null",
type: "DateValue | null",
description: "The current value of the date-picker (controlled).",
default: "-"
},
@ -359,13 +359,13 @@ import {I18nProvider} from "@react-aria/i18n";
},
{
attribute: "defaultValue",
type: "string",
type: "DateValue | null",
description: "The default value of the date-picker (uncontrolled).",
default: "-"
},
{
attribute: "placeholderValue",
type: "ZonedDateTime | CalendarDate | CalendarDateTime | undefined | null",
type: "DateValue | null",
description: "The placeholder of the date-picker.",
default: "-"
},

View File

@ -376,7 +376,7 @@ You can customize the `DateRangePicker` component by passing custom Tailwind CSS
},
{
attribute: "value",
type: "RangeValue<CalendarDate | CalendarDateTime | ZonedDateTime> | undefined | null",
type: "RangeValue<DateValue> | null",
description: "The current value of the date-range-picker (controlled).",
default: "-"
},
@ -406,25 +406,25 @@ You can customize the `DateRangePicker` component by passing custom Tailwind CSS
},
{
attribute: "minValue",
type: "RangeValue<CalendarDate | CalendarDateTime | ZonedDateTime> | undefined | null",
type: "DateValue | null",
description: "The minimum value of the date-range-picker.",
default: "-"
},
{
attribute: "maxValue",
type: "RangeValue<CalendarDate | CalendarDateTime | ZonedDateTime> | undefined | null",
type: "DateValue | null",
description: "The maximum value of the date-range-picker.",
default: "-"
},
{
attribute: "defaultValue",
type: "string",
type: "RangeValue<DateValue> | null",
description: "The default value of the date-range-picker (uncontrolled).",
default: "-"
},
{
attribute: "placeholderValue",
type: "ZonedDateTime | CalendarDate | CalendarDateTime | undefined | null",
type: "DateValue | null",
description: "The placeholder of the date-range-picker.",
default: "-"
},

View File

@ -287,7 +287,7 @@ export const Example = () => {
shortcut="⌘⇧D"
startContent={
<DeleteDocumentBulkIcon
className={clsx(iconClasses, "text-danger!")}
className={cn(iconClasses, "text-danger!")}
/>
}
>
@ -301,7 +301,7 @@ export const Example = () => {
`,
darkModeExampleCode: `import {Card, CardBody, Button, Image, Progress, CardProps} from "@heroui/react";
import {useState, FC} from "react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {
PauseCircleBoldIcon,
@ -320,7 +320,7 @@ export const MusicPlayer: FC<MusicPlayerProps> = ({className, ...otherProps}) =>
return (
<Card
isBlurred
className={clsx("border-none bg-background/60 dark:bg-default-100/50", className)}
className={cn("border-none bg-background/60 dark:bg-default-100/50", className)}
shadow="sm"
{...otherProps}
>

View File

@ -45,7 +45,6 @@
"@types/lodash": "^4.17.15",
"@vercel/analytics": "^1.4.1",
"canvas-confetti": "^1.9.2",
"clsx": "^1.2.1",
"cmdk": "^0.2.0",
"color2k": "2.0.3",
"contentlayer2": "0.5.8",
@ -62,7 +61,7 @@
"next-contentlayer2": "0.5.8",
"next-themes": "0.4.6",
"parse-numeric-range": "1.2.0",
"posthog-js": "1.197.0",
"posthog-js": "1.298.0",
"prism-react-renderer": "^1.2.1",
"react": "18.3.0",
"react-colorful": "^5.6.1",

View File

@ -43,7 +43,7 @@
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -7,15 +7,8 @@ import type {AccordionItemBaseProps} from "./base/accordion-item-base";
import {useProviderContext} from "@heroui/system";
import {useFocusRing} from "@react-aria/focus";
import {accordionItem} from "@heroui/theme";
import {
clsx,
callAllHandlers,
dataAttr,
objectToDeps,
chain,
mergeProps,
} from "@heroui/shared-utils";
import {cn, accordionItem} from "@heroui/theme";
import {callAllHandlers, dataAttr, objectToDeps, chain, mergeProps} from "@heroui/shared-utils";
import {useDOMRef, filterDOMProps} from "@heroui/react-utils";
import {useReactAriaAccordionItem} from "@heroui/use-aria-accordion";
import {useCallback, useMemo} from "react";
@ -141,7 +134,7 @@ export function useAccordionItem<T extends object = {}>(props: UseAccordionItemP
[isCompact, isDisabled, hideIndicator, disableAnimation, disableIndicatorAnimation, variant],
);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const getBaseProps = useCallback<PropGetter>(
(props = {}) => {

View File

@ -40,7 +40,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.19",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -7,9 +7,9 @@ import type {ReactNode} from "react";
import {mapPropsVariants} from "@heroui/system";
import {filterDOMProps, useDOMRef} from "@heroui/react-utils";
import {useCallback, useMemo} from "react";
import {alert} from "@heroui/theme";
import {alert, cn} from "@heroui/theme";
import {useControlledState} from "@react-stately/utils";
import {clsx, dataAttr, isEmpty, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {dataAttr, isEmpty, objectToDeps, mergeProps} from "@heroui/shared-utils";
interface Props extends HTMLHeroUIProps<"div", "title"> {
/**
@ -126,7 +126,7 @@ export function useAlert(originalProps: UseAlertProps) {
onClose?.();
}, [setIsVisible, onClose]);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const slots = useMemo(
() => alert({hasContent: !isEmpty(description) || !isEmpty(children), ...variantProps}),

View File

@ -35,7 +35,7 @@
},
"peerDependencies": {
"@heroui/system": ">=2.4.18",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0"

View File

@ -11,12 +11,12 @@ import type {ScrollShadowProps} from "@heroui/scroll-shadow";
import type {ButtonProps} from "@heroui/button";
import type {AsyncLoadable, PressEvent} from "@react-types/shared";
import {clsx, dataAttr, objectToDeps, chain, mergeProps} from "@heroui/shared-utils";
import {dataAttr, objectToDeps, chain, mergeProps} from "@heroui/shared-utils";
import {useEffect, useMemo, useRef} from "react";
import {useDOMRef} from "@heroui/react-utils";
import {useComboBoxState} from "@react-stately/combobox";
import {useFilter} from "@react-aria/i18n";
import {autocomplete} from "@heroui/theme";
import {autocomplete, cn} from "@heroui/theme";
import {useSafeLayoutEffect} from "@heroui/use-safe-layout-effect";
import {mapPropsVariants, useProviderContext} from "@heroui/system";
import {useComboBox} from "@react-aria/combobox";
@ -328,7 +328,7 @@ export function useAutocomplete<T extends object>(originalProps: UseAutocomplete
),
};
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const isOpen = slotsProps.listboxProps?.hideEmptyContent
? state.isOpen && !!state.collection.size
: state.isOpen;
@ -442,7 +442,7 @@ export function useAutocomplete<T extends object>(originalProps: UseAutocomplete
...mergeProps(buttonProps, slotsProps.selectorButtonProps),
"data-open": dataAttr(state.isOpen),
className: slots.selectorButton({
class: clsx(classNames?.selectorButton, slotsProps.selectorButtonProps?.className),
class: cn(classNames?.selectorButton, slotsProps.selectorButtonProps?.className),
}),
}) as ButtonProps;
@ -468,7 +468,7 @@ export function useAutocomplete<T extends object>(originalProps: UseAutocomplete
},
"data-visible": !!state.selectedItem || state.inputValue?.length > 0,
className: slots.clearButton({
class: clsx(classNames?.clearButton, slotsProps.clearButtonProps?.className),
class: cn(classNames?.clearButton, slotsProps.clearButtonProps?.className),
}),
}) as ButtonProps;
@ -527,7 +527,7 @@ export function useAutocomplete<T extends object>(originalProps: UseAutocomplete
classNames: {
...slotsProps.popoverProps?.classNames,
content: slots.popoverContent({
class: clsx(
class: cn(
classNames?.popoverContent,
slotsProps.popoverProps?.classNames?.["content"],
props.className,
@ -551,7 +551,7 @@ export function useAutocomplete<T extends object>(originalProps: UseAutocomplete
const getListBoxWrapperProps: PropGetter = (props: any = {}) => ({
...mergeProps(slotsProps.scrollShadowProps, props),
className: slots.listboxWrapper({
class: clsx(
class: cn(
classNames?.listboxWrapper,
slotsProps.scrollShadowProps?.className,
props?.className,
@ -564,7 +564,7 @@ export function useAutocomplete<T extends object>(originalProps: UseAutocomplete
const getEndContentWrapperProps: PropGetter = (props: any = {}) => ({
className: slots.endContentWrapper({
class: clsx(classNames?.endContentWrapper, props?.className),
class: cn(classNames?.endContentWrapper, props?.className),
}),
onPointerDown: chain(props.onPointerDown, (e: React.PointerEvent) => {
if (e.button === 0 && e.currentTarget === e.target) {

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -4,9 +4,9 @@ import type {HTMLHeroUIProps, PropGetter} from "@heroui/system";
import type {ReactRef} from "@heroui/react-utils";
import type {AvatarProps} from "./index";
import {avatarGroup} from "@heroui/theme";
import {avatarGroup, cn} from "@heroui/theme";
import {useDOMRef} from "@heroui/react-utils";
import {clsx, compact} from "@heroui/shared-utils";
import {compact} from "@heroui/shared-utils";
import {getValidChildren} from "@heroui/react-utils";
import {cloneElement, useMemo} from "react";
@ -106,7 +106,7 @@ export function useAvatarGroup(props: UseAvatarGroupProps = {}) {
const isLastAvatar = index === childrenWithinMax.length - 1;
const childProps = {
className: clsx(
className: cn(
isFirstAvatar ? "ms-0" : !isGrid ? "-ms-2" : "",
isLastAvatar && remainingCount < 1 ? "hover:-translate-x-0" : "",
),
@ -119,7 +119,7 @@ export function useAvatarGroup(props: UseAvatarGroupProps = {}) {
return {
ref: domRef,
className: slots.base({
class: clsx(classNames?.base, className),
class: cn(classNames?.base, className),
}),
role: "group",
...otherProps,

View File

@ -2,10 +2,10 @@ import type {AvatarSlots, AvatarVariantProps, SlotsToClasses} from "@heroui/them
import type {DOMElement, DOMAttributes, HTMLHeroUIProps, PropGetter} from "@heroui/system";
import type {ReactRef} from "@heroui/react-utils";
import {avatar} from "@heroui/theme";
import {avatar, cn} from "@heroui/theme";
import {useProviderContext} from "@heroui/system";
import {useDOMRef, filterDOMProps} from "@heroui/react-utils";
import {clsx, dataAttr, mergeProps, safeInitials} from "@heroui/shared-utils";
import {dataAttr, mergeProps, safeInitials} from "@heroui/shared-utils";
import {useFocusRing} from "@react-aria/focus";
import {useMemo, useCallback} from "react";
import {useImage} from "@heroui/use-image";
@ -186,7 +186,7 @@ export function useAvatar(originalProps: UseAvatarProps = {}) {
],
);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const canBeFocused = useMemo(() => {
return isFocusable || as === "button";
@ -200,7 +200,7 @@ export function useAvatar(originalProps: UseAvatarProps = {}) {
"data-focus": dataAttr(isFocused),
"data-focus-visible": dataAttr(isFocusVisible),
className: slots.base({
class: clsx(baseStyles, props?.className),
class: cn(baseStyles, props?.className),
}),
...mergeProps(otherProps, hoverProps, canBeFocused ? focusProps : {}),
}),

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -3,9 +3,9 @@ import type {ReactNode} from "react";
import type {HTMLHeroUIProps, PropGetter} from "@heroui/system";
import type {ReactRef} from "@heroui/react-utils";
import {badge} from "@heroui/theme";
import {badge, cn} from "@heroui/theme";
import {mapPropsVariants, useProviderContext} from "@heroui/system";
import {clsx, objectToDeps} from "@heroui/shared-utils";
import {objectToDeps} from "@heroui/shared-utils";
import {useMemo} from "react";
interface Props extends HTMLHeroUIProps<"span", "content"> {
@ -62,7 +62,7 @@ export function useBadge(originalProps: UseBadgeProps) {
const isDot = useMemo(() => String(content)?.length === 0, [content]);
const baseStyles = clsx(classNames?.badge, className);
const baseStyles = cn(classNames?.badge, className);
const slots = useMemo(
() =>

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -6,10 +6,10 @@ import type {ReactRef} from "@heroui/react-utils";
import {mapPropsVariants} from "@heroui/system";
import {useFocusRing} from "@react-aria/focus";
import {breadcrumbItem} from "@heroui/theme";
import {breadcrumbItem, cn} from "@heroui/theme";
import {filterDOMProps, useDOMRef} from "@heroui/react-utils";
import {useBreadcrumbItem as useAriaBreadcrumbItem} from "@react-aria/breadcrumbs";
import {clsx, dataAttr, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {dataAttr, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {useMemo} from "react";
interface Props
@ -94,7 +94,7 @@ export function useBreadcrumbItem(originalProps: UseBreadcrumbItemProps) {
[objectToDeps(variantProps), isCurrent, className],
);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const getBaseProps = () => ({
ref: domRef,

View File

@ -7,11 +7,11 @@ import type {BreadcrumbItemProps} from "./breadcrumb-item";
import {Children} from "react";
import {mapPropsVariants, useProviderContext} from "@heroui/system";
import {breadcrumbs} from "@heroui/theme";
import {breadcrumbs, cn} from "@heroui/theme";
import {filterDOMProps, pickChildren, useDOMRef} from "@heroui/react-utils";
import {useBreadcrumbs as useAriaBreadcrumbs} from "@react-aria/breadcrumbs";
import {useMemo} from "react";
import {clsx, dataAttr, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {dataAttr, objectToDeps, mergeProps} from "@heroui/shared-utils";
import BreadcrumbItem from "./breadcrumb-item";
@ -152,7 +152,7 @@ export function useBreadcrumbs(originalProps: UseBreadcrumbsProps) {
[objectToDeps(variantProps)],
);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const itemProps: Partial<BreadcrumbItemProps> = {
color,

View File

@ -15,7 +15,7 @@ import {
PetBoldIcon,
ShoppingCartBoldIcon,
} from "@heroui/shared-icons";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {Breadcrumbs, BreadcrumbItem} from "../src";
@ -312,7 +312,7 @@ const WithDropdownItemTemplate = (args: BreadcrumbsProps & {page: number}) => {
<Dropdown>
<DropdownTrigger>
<Button
className={clsx("h-6 pr-2", args.size && sizeMap[args.size])}
className={cn("h-6 pr-2", args.size && sizeMap[args.size])}
endContent={<ChevronDownIcon className="text-default-500" />}
radius="full"
size="sm"

View File

@ -37,7 +37,7 @@
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -35,7 +35,7 @@
},
"peerDependencies": {
"@heroui/system": ">=2.4.18",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0"

View File

@ -9,7 +9,8 @@ import {filterDOMProps} from "@heroui/react-utils";
import {useCalendar as useAriaCalendar} from "@react-aria/calendar";
import {useCalendarState} from "@react-stately/calendar";
import {createCalendar} from "@internationalized/date";
import {clsx, chain, mergeProps} from "@heroui/shared-utils";
import {chain, mergeProps} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useCalendarBase} from "./use-calendar-base";
@ -67,7 +68,7 @@ export function useCalendar<T extends DateValue>({
const {title, calendarProps, prevButtonProps, nextButtonProps, errorMessageProps} =
useAriaCalendar(originalProps, state);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const buttonPickerProps: ButtonProps = {
...mergeProps(buttonPickerPropsProp, {isDisabled: originalProps.isDisabled}),

View File

@ -10,7 +10,8 @@ import {filterDOMProps} from "@heroui/react-utils";
import {useRangeCalendar as useAriaRangeCalendar} from "@react-aria/calendar";
import {useRangeCalendarState} from "@react-stately/calendar";
import {createCalendar} from "@internationalized/date";
import {clsx, chain} from "@heroui/shared-utils";
import {chain} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useCalendarBase} from "./use-calendar-base";
@ -75,7 +76,7 @@ export function useRangeCalendar<T extends DateValue>({
const {title, calendarProps, prevButtonProps, nextButtonProps, errorMessageProps} =
useAriaRangeCalendar(originalProps, state, domRef);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const buttonPickerProps: ButtonProps = {
...buttonPickerPropsProp,

View File

@ -37,7 +37,7 @@
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -2,7 +2,7 @@ import type {HTMLHeroUIProps} from "@heroui/system";
import {forwardRef} from "@heroui/system";
import {useDOMRef} from "@heroui/react-utils";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useCardContext} from "./card-context";
@ -14,7 +14,7 @@ const CardBody = forwardRef<"div", HTMLHeroUIProps<"div">>((props, ref) => {
const {slots, classNames} = useCardContext();
const bodyStyles = clsx(classNames?.body, className);
const bodyStyles = cn(classNames?.body, className);
return (
<Component ref={domRef} className={slots.body?.({class: bodyStyles})} {...otherProps}>

View File

@ -2,7 +2,7 @@ import type {HTMLHeroUIProps} from "@heroui/system";
import {forwardRef} from "@heroui/system";
import {useDOMRef} from "@heroui/react-utils";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useCardContext} from "./card-context";
@ -16,7 +16,7 @@ const CardFooter = forwardRef<"div", CardFooterProps>((props, ref) => {
const {slots, classNames} = useCardContext();
const footerStyles = clsx(classNames?.footer, className);
const footerStyles = cn(classNames?.footer, className);
return (
<Component ref={domRef} className={slots.footer?.({class: footerStyles})} {...otherProps}>

View File

@ -2,7 +2,7 @@ import type {HTMLHeroUIProps} from "@heroui/system";
import {forwardRef} from "@heroui/system";
import {useDOMRef} from "@heroui/react-utils";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useCardContext} from "./card-context";
@ -14,7 +14,7 @@ const CardHeader = forwardRef<"div", HTMLHeroUIProps<"div">>((props, ref) => {
const {slots, classNames} = useCardContext();
const headerStyles = clsx(classNames?.header, className);
const headerStyles = cn(classNames?.header, className);
return (
<Component ref={domRef} className={slots.header?.({class: headerStyles})} {...otherProps}>

View File

@ -7,13 +7,13 @@ import type {PressEvent} from "@react-aria/interactions";
import type {HTMLHeroUIProps, PropGetter} from "@heroui/system";
import type {ReactRef} from "@heroui/react-utils";
import {card} from "@heroui/theme";
import {card, cn} from "@heroui/theme";
import {useCallback, useMemo} from "react";
import {useFocusRing} from "@react-aria/focus";
import {useHover} from "@react-aria/interactions";
import {useAriaButton} from "@heroui/use-aria-button";
import {mapPropsVariants, useProviderContext} from "@heroui/system";
import {clsx, dataAttr, objectToDeps, chain, mergeProps} from "@heroui/shared-utils";
import {dataAttr, objectToDeps, chain, mergeProps} from "@heroui/shared-utils";
import {filterDOMProps} from "@heroui/react-utils";
import {useDOMRef} from "@heroui/react-utils";
import {useRipple} from "@heroui/ripple";
@ -97,7 +97,7 @@ export function useCard(originalProps: UseCardProps) {
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const disableRipple = originalProps.disableRipple ?? globalContext?.disableRipple ?? false;
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const {onClear: onClearRipple, onPress: onRipplePressHandler, ripples} = useRipple();

View File

@ -35,7 +35,7 @@
},
"peerDependencies": {
"@heroui/system": ">=2.4.18",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0"
},

View File

@ -8,11 +8,11 @@ import type {CheckboxProps} from "./index";
import {useProviderContext} from "@heroui/system";
import {useCallback, useMemo} from "react";
import {checkboxGroup} from "@heroui/theme";
import {checkboxGroup, cn} from "@heroui/theme";
import {useCheckboxGroup as useReactAriaCheckboxGroup} from "@react-aria/checkbox";
import {useCheckboxGroupState} from "@react-stately/checkbox";
import {filterDOMProps, useDOMRef} from "@heroui/react-utils";
import {clsx, safeAriaLabel, chain, mergeProps} from "@heroui/shared-utils";
import {safeAriaLabel, chain, mergeProps} from "@heroui/shared-utils";
import {FormContext, useSlottedContext} from "@heroui/form";
interface Props extends HTMLHeroUIProps<"div"> {
@ -178,7 +178,7 @@ export function useCheckboxGroup(props: UseCheckboxGroupProps) {
[isRequired, groupState.isInvalid, , disableAnimation],
);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const getGroupProps: PropGetter = useCallback(() => {
return {
@ -213,7 +213,7 @@ export function useCheckboxGroup(props: UseCheckboxGroupProps) {
return {
...props,
...descriptionProps,
className: slots.description({class: clsx(classNames?.description, props?.className)}),
className: slots.description({class: cn(classNames?.description, props?.className)}),
};
},
[slots, descriptionProps, classNames?.description],
@ -224,7 +224,7 @@ export function useCheckboxGroup(props: UseCheckboxGroupProps) {
return {
...props,
...errorMessageProps,
className: slots.errorMessage({class: clsx(classNames?.errorMessage, props?.className)}),
className: slots.errorMessage({class: cn(classNames?.errorMessage, props?.className)}),
};
},
[slots, errorMessageProps, classNames?.errorMessage],

View File

@ -7,19 +7,11 @@ import {useProviderContext} from "@heroui/system";
import {useCallback, useId} from "react";
import {useMemo, useRef} from "react";
import {useToggleState} from "@react-stately/toggle";
import {checkbox} from "@heroui/theme";
import {checkbox, cn} from "@heroui/theme";
import {useCallbackRef} from "@heroui/use-callback-ref";
import {useHover} from "@react-aria/interactions";
import {useFocusRing} from "@react-aria/focus";
import {
__DEV__,
warn,
clsx,
dataAttr,
safeAriaLabel,
mergeProps,
chain,
} from "@heroui/shared-utils";
import {__DEV__, warn, dataAttr, safeAriaLabel, mergeProps, chain} from "@heroui/shared-utils";
import {
useCheckbox as useReactAriaCheckbox,
useCheckboxGroupItem as useReactAriaCheckboxGroupItem,
@ -270,7 +262,7 @@ export function useCheckbox(props: UseCheckboxProps = {}) {
[isReadOnly, isDisabled, onChangeProp],
);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const getBaseProps: PropGetter = useCallback(() => {
return {
@ -308,7 +300,7 @@ export function useCheckbox(props: UseCheckboxProps = {}) {
return {
...props,
"aria-hidden": true,
className: clsx(slots.wrapper({class: clsx(classNames?.wrapper, props?.className)})),
className: slots.wrapper({class: cn(classNames?.wrapper, props?.className)}),
};
},
[slots, classNames?.wrapper],

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -7,9 +7,9 @@ import type {PressEvent} from "@react-types/shared";
import {mapPropsVariants} from "@heroui/system";
import {usePress} from "@react-aria/interactions";
import {useFocusRing} from "@react-aria/focus";
import {chip} from "@heroui/theme";
import {chip, cn} from "@heroui/theme";
import {useDOMRef} from "@heroui/react-utils";
import {clsx, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {objectToDeps, mergeProps} from "@heroui/shared-utils";
import {useMemo, isValidElement, cloneElement} from "react";
export interface UseChipProps extends HTMLHeroUIProps, ChipVariantProps {
@ -77,7 +77,7 @@ export function useChip(originalProps: UseChipProps) {
const domRef = useDOMRef(ref);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const isCloseable = !!onClose;
const isDotVariant = originalProps.variant === "dot";
@ -148,7 +148,7 @@ export function useChip(originalProps: UseChipProps) {
isValidElement(content)
? cloneElement(content, {
// @ts-ignore
className: clsx("max-h-[80%]", content.props.className),
className: cn("max-h-[80%]", content.props.className),
})
: null;

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17"
"@heroui/theme": ">=2.4.23"
},
"dependencies": {
"@heroui/system-rsc": "workspace:*",

View File

@ -35,7 +35,7 @@
},
"peerDependencies": {
"@heroui/system": ">=2.4.18",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0"
},

View File

@ -13,13 +13,7 @@ import {mapPropsVariants} from "@heroui/system";
import {useDOMRef} from "@heroui/react-utils";
import {useDateField as useAriaDateField} from "@react-aria/datepicker";
import {useDateFieldState} from "@react-stately/datepicker";
import {
objectToDeps,
clsx,
dataAttr,
getGregorianYearOffset,
mergeProps,
} from "@heroui/shared-utils";
import {objectToDeps, dataAttr, getGregorianYearOffset, mergeProps} from "@heroui/shared-utils";
import {dateInput, cn} from "@heroui/theme";
import {useMemo} from "react";
import {FormContext, useSlottedContext} from "@heroui/form";
@ -193,7 +187,7 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
isInvalid: ariaIsInvalid,
} = useAriaDateField({...originalProps, label, validationBehavior, inputRef}, state, domRef);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const isInvalid = isInvalidProp || ariaIsInvalid;
@ -219,7 +213,7 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
...mergeProps(labelProps, labelPropsProp, props),
"data-slot": "label",
className: slots.label({
class: clsx(classNames?.label, props?.className),
class: cn(classNames?.label, props?.className),
}),
};
};
@ -238,7 +232,7 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
"data-slot": "input-field",
...mergeProps(fieldProps, fieldPropsProp, props),
className: slots.input({
class: clsx(classNames?.input, props?.className),
class: cn(classNames?.input, props?.className),
}),
} as GroupDOMAttributes;
};
@ -272,7 +266,7 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
...props,
"data-slot": "helper-wrapper",
className: slots.helperWrapper({
class: clsx(classNames?.helperWrapper, props?.className),
class: cn(classNames?.helperWrapper, props?.className),
}),
};
};
@ -281,7 +275,7 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
return {
...mergeProps(errorMessageProps, errorMessagePropsProp, props),
"data-slot": "error-message",
className: slots.errorMessage({class: clsx(classNames?.errorMessage, props?.className)}),
className: slots.errorMessage({class: cn(classNames?.errorMessage, props?.className)}),
};
};
@ -289,7 +283,7 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
return {
...mergeProps(descriptionProps, descriptionPropsProp, props),
"data-slot": "description",
className: slots.description({class: clsx(classNames?.description, props?.className)}),
className: slots.description({class: cn(classNames?.description, props?.className)}),
};
};

View File

@ -12,8 +12,8 @@ import {mapPropsVariants} from "@heroui/system";
import {useDOMRef} from "@heroui/react-utils";
import {useTimeField as useAriaTimeField} from "@react-aria/datepicker";
import {useTimeFieldState} from "@react-stately/datepicker";
import {objectToDeps, clsx, dataAttr, mergeProps} from "@heroui/shared-utils";
import {dateInput} from "@heroui/theme";
import {objectToDeps, dataAttr, mergeProps} from "@heroui/shared-utils";
import {dateInput, cn} from "@heroui/theme";
import {useMemo} from "react";
import {FormContext, useSlottedContext} from "@heroui/form";
@ -132,7 +132,7 @@ export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputPro
isInvalid,
} = useAriaTimeField({...originalProps, label, validationBehavior, inputRef}, state, domRef);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const labelPlacement = useLabelPlacement({
labelPlacement: originalProps.labelPlacement,
@ -156,7 +156,7 @@ export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputPro
...mergeProps(labelProps, labelPropsProp, props),
"data-slot": "label",
className: slots.label({
class: clsx(classNames?.label, props?.className),
class: cn(classNames?.label, props?.className),
}),
};
};
@ -175,7 +175,7 @@ export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputPro
"data-slot": "input",
...mergeProps(fieldProps, fieldPropsProp, props),
className: slots.input({
class: clsx(classNames?.input, props?.className),
class: cn(classNames?.input, props?.className),
}),
} as GroupDOMAttributes;
};
@ -207,7 +207,7 @@ export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputPro
...props,
"data-slot": "helper-wrapper",
className: slots.helperWrapper({
class: clsx(classNames?.helperWrapper, props?.className),
class: cn(classNames?.helperWrapper, props?.className),
}),
};
};
@ -216,7 +216,7 @@ export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputPro
return {
...mergeProps(errorMessageProps, errorMessagePropsProp, props),
"data-slot": "error-message",
className: slots.errorMessage({class: clsx(classNames?.errorMessage, props?.className)}),
className: slots.errorMessage({class: cn(classNames?.errorMessage, props?.className)}),
};
};
@ -224,7 +224,7 @@ export function useTimeInput<T extends TimeValue>(originalProps: UseTimeInputPro
return {
...mergeProps(descriptionProps, descriptionPropsProp, props),
"data-slot": "description",
className: slots.description({class: clsx(classNames?.description, props?.className)}),
className: slots.description({class: cn(classNames?.description, props?.className)}),
};
};

View File

@ -35,7 +35,7 @@
},
"peerDependencies": {
"@heroui/system": ">=2.4.18",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0"

View File

@ -11,10 +11,10 @@ import type {AriaDatePickerProps} from "@react-aria/datepicker";
import {useProviderContext} from "@heroui/system";
import {useMemo, useRef} from "react";
import {datePicker} from "@heroui/theme";
import {datePicker, cn} from "@heroui/theme";
import {useDatePickerState} from "@react-stately/datepicker";
import {useDatePicker as useAriaDatePicker} from "@react-aria/datepicker";
import {clsx, dataAttr, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {dataAttr, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {FormContext, useSlottedContext} from "@heroui/form";
import {useDatePickerBase} from "./use-date-picker-base";
@ -102,7 +102,7 @@ export function useDatePicker<T extends DateValue>({
const popoverTriggerRef = useRef<HTMLDivElement>(null);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const slots = useMemo(
() =>
@ -168,10 +168,10 @@ export function useDatePicker<T extends DateValue>({
maxValue: timeMaxValue ?? undefined,
classNames: {
base: slots.timeInput({
class: clsx(classNames?.timeInput, userTimeInputProps?.classNames?.base),
class: cn(classNames?.timeInput, userTimeInputProps?.classNames?.base),
}),
label: slots.timeInputLabel({
class: clsx(classNames?.timeInputLabel, userTimeInputProps?.classNames?.label),
class: cn(classNames?.timeInputLabel, userTimeInputProps?.classNames?.label),
}),
},
};
@ -185,7 +185,7 @@ export function useDatePicker<T extends DateValue>({
triggerRef: popoverTriggerRef,
classNames: {
content: slots.popoverContent({
class: clsx(
class: cn(
classNames?.popoverContent,
slotsProps.popoverProps?.classNames?.["content"],
props.className,
@ -201,9 +201,9 @@ export function useDatePicker<T extends DateValue>({
...calendarProps,
classNames: {
...calendarProps.classNames,
base: slots.calendar({class: clsx(classNames?.base, calendarProps.classNames?.base)}),
base: slots.calendar({class: cn(classNames?.base, calendarProps.classNames?.base)}),
content: slots.calendarContent({
class: clsx(classNames?.calendarContent, calendarProps.classNames?.content),
class: cn(classNames?.calendarContent, calendarProps.classNames?.content),
}),
},
};

View File

@ -17,7 +17,7 @@ import {useLabelPlacement, useProviderContext} from "@heroui/system";
import {useMemo, useRef, useEffect} from "react";
import {useDateRangePickerState} from "@react-stately/datepicker";
import {useDateRangePicker as useAriaDateRangePicker} from "@react-aria/datepicker";
import {clsx, dataAttr, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {dataAttr, objectToDeps, mergeProps} from "@heroui/shared-utils";
import {dateRangePicker, dateInput, cn} from "@heroui/theme";
import {FormContext, useSlottedContext} from "@heroui/form";
@ -175,10 +175,10 @@ export function useDateRangePicker<T extends DateValue>({
maxValue: timeMaxValue,
classNames: {
base: slots.timeInput({
class: clsx(classNames?.timeInput, userTimeInputProps?.classNames?.base),
class: cn(classNames?.timeInput, userTimeInputProps?.classNames?.base),
}),
label: slots.timeInputLabel({
class: clsx(classNames?.timeInputLabel, userTimeInputProps?.classNames?.label),
class: cn(classNames?.timeInputLabel, userTimeInputProps?.classNames?.label),
}),
},
} as TimeInputProps;
@ -197,10 +197,10 @@ export function useDateRangePicker<T extends DateValue>({
maxValue: timeMaxValue,
classNames: {
base: slots.timeInput({
class: clsx(classNames?.timeInput, userTimeInputProps?.classNames?.base),
class: cn(classNames?.timeInput, userTimeInputProps?.classNames?.base),
}),
label: slots.timeInputLabel({
class: clsx(classNames?.timeInputLabel, userTimeInputProps?.classNames?.label),
class: cn(classNames?.timeInputLabel, userTimeInputProps?.classNames?.label),
}),
},
} as TimeInputProps;
@ -215,7 +215,7 @@ export function useDateRangePicker<T extends DateValue>({
triggerRef: popoverTriggerRef,
classNames: {
content: slots.popoverContent({
class: clsx(
class: cn(
classNames?.popoverContent,
slotsProps.popoverProps?.classNames?.["content"],
props.className,
@ -268,7 +268,7 @@ export function useDateRangePicker<T extends DateValue>({
* ------------------------------
*/
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const dateInputSlots = useMemo(
() =>
@ -297,7 +297,7 @@ export function useDateRangePicker<T extends DateValue>({
maxWidth: "fit-content",
},
className: dateInputSlots.input({
class: clsx(classNames?.input, props?.className),
class: cn(classNames?.input, props?.className),
}),
} as DateRangePickerFieldProps;
};
@ -316,7 +316,7 @@ export function useDateRangePicker<T extends DateValue>({
"data-open": dataAttr(state.isOpen),
classNames,
className: dateInputSlots.input({
class: clsx(classNames?.input, props?.className),
class: cn(classNames?.input, props?.className),
}),
} as DateRangePickerFieldProps;
};
@ -327,7 +327,7 @@ export function useDateRangePicker<T extends DateValue>({
...labelProps,
"data-slot": "label",
className: dateInputSlots.label({
class: clsx(classNames?.label, props?.className),
class: cn(classNames?.label, props?.className),
}),
};
};
@ -361,7 +361,7 @@ export function useDateRangePicker<T extends DateValue>({
...props,
"data-slot": "helper-wrapper",
className: dateInputSlots.helperWrapper({
class: clsx(classNames?.helperWrapper, props?.className),
class: cn(classNames?.helperWrapper, props?.className),
}),
};
};
@ -372,7 +372,7 @@ export function useDateRangePicker<T extends DateValue>({
...errorMessageProps,
"data-slot": "error-message",
className: dateInputSlots.errorMessage({
class: clsx(classNames?.errorMessage, props?.className),
class: cn(classNames?.errorMessage, props?.className),
}),
};
};
@ -383,7 +383,7 @@ export function useDateRangePicker<T extends DateValue>({
...descriptionProps,
"data-slot": "description",
className: dateInputSlots.description({
class: clsx(classNames?.description, props?.className),
class: cn(classNames?.description, props?.className),
}),
};
};

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17"
"@heroui/theme": ">=2.4.23"
},
"dependencies": {
"@heroui/react-rsc-utils": "workspace:*",

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -2,11 +2,11 @@ import type {ModalProps} from "@heroui/modal";
import type {ReactRef} from "@heroui/react-utils";
import type {PropGetter} from "@heroui/system";
import {drawer} from "@heroui/theme";
import {drawer, cn} from "@heroui/theme";
import {useDOMRef} from "@heroui/react-utils";
import {useCallback, useMemo} from "react";
import {TRANSITION_EASINGS} from "@heroui/framer-utils";
import {clsx, isEmpty} from "@heroui/shared-utils";
import {isEmpty} from "@heroui/shared-utils";
interface Props extends Omit<ModalProps, "placement" | "scrollBehavior" | "children"> {
/**
@ -68,7 +68,7 @@ export function useDrawer(originalProps: UseDrawerProps) {
};
}, [placement, drawerMotionProps]);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const slots = useMemo(
() =>

View File

@ -35,7 +35,7 @@
},
"peerDependencies": {
"@heroui/system": ">=2.4.18",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0"

View File

@ -9,8 +9,8 @@ import type {CollectionElement} from "@react-types/shared";
import {useProviderContext} from "@heroui/system";
import {useMenuTriggerState} from "@react-stately/menu";
import {useMenuTrigger} from "@react-aria/menu";
import {dropdown} from "@heroui/theme";
import {clsx, mergeProps} from "@heroui/shared-utils";
import {dropdown, cn} from "@heroui/theme";
import {mergeProps} from "@heroui/shared-utils";
import {mergeRefs} from "@heroui/react-utils";
import {useMemo, useRef} from "react";
@ -155,7 +155,7 @@ export function useDropdown(props: UseDropdownProps): UseDropdownReturn {
classNames: {
...classNamesProp,
...props.classNames,
content: clsx(styles, classNamesProp?.content, props.className),
content: cn(styles, classNamesProp?.content, props.className),
},
};
};

View File

@ -12,7 +12,7 @@ import {
EditDocumentBulkIcon,
DeleteDocumentBulkIcon,
} from "@heroui/shared-icons";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {Dropdown, DropdownSection, DropdownTrigger, DropdownMenu, DropdownItem} from "../src";
@ -398,7 +398,7 @@ const WithStartContentTemplate = ({
className="text-danger"
color="danger"
shortcut="⌘⇧D"
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
startContent={<DeleteDocumentBulkIcon className={cn(iconClasses, "!text-danger")} />}
>
Delete file
</DropdownItem>
@ -431,7 +431,7 @@ const WithEndContentTemplate = ({color, variant, disableAnimation, ...args}) =>
key="delete"
className="text-danger"
color="danger"
endContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
endContent={<DeleteDocumentBulkIcon className={cn(iconClasses, "!text-danger")} />}
>
Delete file
</DropdownItem>
@ -481,7 +481,7 @@ const WithDescriptionTemplate = ({color, variant, disableAnimation, ...args}) =>
color="danger"
description="Permanently delete the file"
shortcut="⌘⇧D"
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
startContent={<DeleteDocumentBulkIcon className={cn(iconClasses, "!text-danger")} />}
>
Delete file
</DropdownItem>
@ -540,7 +540,7 @@ const WithSectionsTemplate = ({color, variant, disableAnimation, ...args}) => {
color="danger"
description="Permanently delete the file"
shortcut="⌘⇧D"
startContent={<DeleteDocumentBulkIcon className={clsx(iconClasses, "!text-danger")} />}
startContent={<DeleteDocumentBulkIcon className={cn(iconClasses, "!text-danger")} />}
>
Delete file
</DropdownItem>

View File

@ -35,7 +35,7 @@
},
"peerDependencies": {
"@heroui/system": ">=2.4.18",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"react": ">=18",
"react-dom": ">=18"
},

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -5,9 +5,9 @@ import type {ReactRef} from "@heroui/react-utils";
import {useCallback} from "react";
import {mapPropsVariants, useProviderContext} from "@heroui/system";
import {image} from "@heroui/theme";
import {image, cn} from "@heroui/theme";
import {useDOMRef} from "@heroui/react-utils";
import {clsx, dataAttr, objectToDeps} from "@heroui/shared-utils";
import {dataAttr, objectToDeps} from "@heroui/shared-utils";
import {useImage as useImageBase} from "@heroui/use-image";
import {useMemo} from "react";
type NativeImageProps = ImgHTMLAttributes<HTMLImageElement>;
@ -147,10 +147,10 @@ export function useImage(originalProps: UseImageProps) {
[objectToDeps(variantProps), disableAnimation, showSkeleton],
);
const baseStyles = clsx(className, classNames?.img);
const baseStyles = cn(className, classNames?.img);
const getImgProps: PropGetter = (props = {}) => {
const imgStyles = clsx(baseStyles, props?.className);
const imgStyles = cn(baseStyles, props?.className);
return {
src,

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -1,7 +1,7 @@
import type {SlotProps} from "input-otp";
import {useMemo} from "react";
import {clsx, dataAttr} from "@heroui/shared-utils";
import {dataAttr} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
import {useInputOtpContext} from "./input-otp-context";
@ -11,9 +11,9 @@ export const InputOtpSegment = ({
}: SlotProps & {isFocused?: boolean; isFocusVisible?: boolean}) => {
const {classNames, slots, type} = useInputOtpContext();
const passwordCharStyles = clsx(classNames?.passwordChar);
const caretStyles = clsx(classNames?.caret);
const segmentStyles = clsx(classNames?.segment);
const passwordCharStyles = cn(classNames?.passwordChar);
const caretStyles = cn(classNames?.caret);
const segmentStyles = cn(classNames?.segment);
const displayValue = useMemo(() => {
if (props.isActive && !props.char) {

View File

@ -10,16 +10,9 @@ import type {OTPInputProps} from "input-otp";
import type {HTMLHeroUIProps, PropGetter} from "@heroui/system";
import {mapPropsVariants, useProviderContext} from "@heroui/system";
import {inputOtp} from "@heroui/theme";
import {inputOtp, cn} from "@heroui/theme";
import {filterDOMProps, useDOMRef} from "@heroui/react-utils";
import {
clsx,
dataAttr,
objectToDeps,
isPatternNumeric,
chain,
mergeProps,
} from "@heroui/shared-utils";
import {dataAttr, objectToDeps, isPatternNumeric, chain, mergeProps} from "@heroui/shared-utils";
import {useFormReset} from "@heroui/use-form-reset";
import {useCallback, useMemo} from "react";
import {useControlledState} from "@react-stately/utils";
@ -154,7 +147,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) {
const disableAnimation =
originalProps.disableAnimation ?? globalContext?.disableAnimation ?? false;
const isDisabled = originalProps.isDisabled;
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const validationState = useFormValidationState<string>({
...props,
@ -252,7 +245,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) {
pasteTransformer,
noScriptCSSFallback,
inputMode: inputMode ?? (isPatternNumeric(allowedKeys) ? "numeric" : "text"),
containerClassName: slots.wrapper?.({class: clsx(classNames?.wrapper, containerClassName)}),
containerClassName: slots.wrapper?.({class: cn(classNames?.wrapper, containerClassName)}),
...props,
};
@ -279,7 +272,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) {
(props = {}) => {
return {
className: slots.segmentWrapper({
class: clsx(classNames?.segmentWrapper, props?.className),
class: cn(classNames?.segmentWrapper, props?.className),
}),
"data-slot": "segment-wrapper",
"data-disabled": dataAttr(isDisabled),
@ -294,7 +287,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) {
(props = {}) => {
return {
className: slots.helperWrapper({
class: clsx(classNames?.helperWrapper, props?.className),
class: cn(classNames?.helperWrapper, props?.className),
}),
"data-slot": "helper-wrapper",
...props,
@ -307,7 +300,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) {
(props = {}) => {
return {
className: slots.errorMessage({
class: clsx(classNames?.errorMessage, props?.className),
class: cn(classNames?.errorMessage, props?.className),
}),
"data-slot": "error-message",
...props,
@ -320,7 +313,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) {
(props = {}) => {
return {
className: slots.description({
class: clsx(classNames?.description, props?.className),
class: cn(classNames?.description, props?.className),
}),
"data-slot": "description",
...props,

View File

@ -7,11 +7,10 @@ import type {Ref} from "react";
import {mapPropsVariants, useProviderContext, useInputLabelPlacement} from "@heroui/system";
import {useSafeLayoutEffect} from "@heroui/use-safe-layout-effect";
import {useFocusRing} from "@react-aria/focus";
import {input} from "@heroui/theme";
import {input, cn} from "@heroui/theme";
import {useDOMRef, filterDOMProps} from "@heroui/react-utils";
import {useFocusWithin, useHover, usePress} from "@react-aria/interactions";
import {
clsx,
dataAttr,
isEmpty,
objectToDeps,
@ -157,7 +156,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
const isHiddenType = type === "hidden";
const isMultiline = originalProps.isMultiline;
const baseStyles = clsx(classNames?.base, className, isFilled ? "is-filled" : "");
const baseStyles = cn(classNames?.base, className, isFilled ? "is-filled" : "");
const handleClear = useCallback(() => {
if (isFileTypeInput) {
@ -387,7 +386,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
"data-has-end-content": dataAttr(!!endContent),
"data-type": type,
className: slots.input({
class: clsx(
class: cn(
classNames?.input,
isFilled ? "is-filled" : "",
isMultiline ? "pe-0" : "",
@ -437,7 +436,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
"data-focus-visible": dataAttr(isFocusVisible),
"data-focus": dataAttr(isFocused),
className: slots.inputWrapper({
class: clsx(classNames?.inputWrapper, isFilled ? "is-filled" : ""),
class: cn(classNames?.inputWrapper, isFilled ? "is-filled" : ""),
}),
...mergeProps(props, hoverProps),
onClick: (e) => {
@ -474,7 +473,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
}
},
className: slots.innerWrapper({
class: clsx(classNames?.innerWrapper, props?.className),
class: cn(classNames?.innerWrapper, props?.className),
}),
};
},
@ -487,7 +486,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
...props,
"data-slot": "main-wrapper",
className: slots.mainWrapper({
class: clsx(classNames?.mainWrapper, props?.className),
class: cn(classNames?.mainWrapper, props?.className),
}),
};
},
@ -500,7 +499,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
...props,
"data-slot": "helper-wrapper",
className: slots.helperWrapper({
class: clsx(classNames?.helperWrapper, props?.className),
class: cn(classNames?.helperWrapper, props?.className),
}),
};
},
@ -513,7 +512,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
...props,
...descriptionProps,
"data-slot": "description",
className: slots.description({class: clsx(classNames?.description, props?.className)}),
className: slots.description({class: cn(classNames?.description, props?.className)}),
};
},
[slots, classNames?.description],
@ -525,7 +524,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
...props,
...errorMessageProps,
"data-slot": "error-message",
className: slots.errorMessage({class: clsx(classNames?.errorMessage, props?.className)}),
className: slots.errorMessage({class: cn(classNames?.errorMessage, props?.className)}),
};
},
[slots, errorMessageProps, classNames?.errorMessage],
@ -542,7 +541,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
"data-slot": "clear-button",
"data-focus-visible": dataAttr(isClearButtonFocusVisible),
className: slots.clearButton({
class: clsx(classNames?.clearButton, props?.className),
class: cn(classNames?.clearButton, props?.className),
}),
...mergeProps(clearPressProps, clearFocusProps),
};

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17"
"@heroui/theme": ">=2.4.23"
},
"dependencies": {
"@heroui/system-rsc": "workspace:*",

View File

@ -4,8 +4,8 @@ import type {ReactRef} from "@heroui/react-utils";
import type {KbdKey} from "./utils";
import {mapPropsVariants} from "@heroui/system-rsc";
import {kbd} from "@heroui/theme";
import {clsx, objectToDeps} from "@heroui/shared-utils";
import {kbd, cn} from "@heroui/theme";
import {objectToDeps} from "@heroui/shared-utils";
import {useMemo} from "react";
interface Props extends HTMLHeroUIProps<"kbd"> {
@ -50,14 +50,14 @@ export function useKbd(originalProps: UseKbdProps) {
[objectToDeps(variantProps)],
);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const keysToRender = typeof keys === "string" ? [keys] : Array.isArray(keys) ? keys : [];
const getKbdProps: PropGetter = (props = {}) => ({
...otherProps,
...props,
className: clsx(slots.base({class: clsx(baseStyles, props.className)})),
className: slots.base({class: cn(baseStyles, props.className)}),
});
return {Component, slots, classNames, title, children, keysToRender, getKbdProps};

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -36,7 +36,7 @@
"peerDependencies": {
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0",
"@heroui/theme": ">=2.4.17",
"@heroui/theme": ">=2.4.23",
"@heroui/system": ">=2.4.18"
},
"dependencies": {

View File

@ -3,10 +3,10 @@ import type {ListState} from "@react-stately/list";
import type {ListboxItemProps} from "./listbox-item";
import type {ListboxSectionBaseProps} from "./base/listbox-section-base";
import {listboxSection} from "@heroui/theme";
import {listboxSection, cn} from "@heroui/theme";
import {useMemo} from "react";
import {forwardRef} from "@heroui/system";
import {clsx, mergeProps} from "@heroui/shared-utils";
import {mergeProps} from "@heroui/shared-utils";
import {Divider} from "@heroui/divider";
import {useListBoxSection} from "@react-aria/listbox";
@ -63,8 +63,8 @@ const ListboxSection = forwardRef<"li", ListboxSectionProps>(
const slots = useMemo(() => listboxSection(), []);
const baseStyles = clsx(classNames?.base, className);
const dividerStyles = clsx(classNames?.divider, dividerProps?.className);
const baseStyles = cn(classNames?.base, className);
const dividerStyles = cn(classNames?.divider, dividerProps?.className);
const {itemProps, headingProps, groupProps} = useListBoxSection({
heading: item.rendered,

View File

@ -5,11 +5,11 @@ import type {ListState} from "@react-stately/list";
import type {HTMLHeroUIProps, PropGetter} from "@heroui/system";
import {useMemo, useRef, useCallback} from "react";
import {listboxItem} from "@heroui/theme";
import {listboxItem, cn} from "@heroui/theme";
import {mapPropsVariants, useProviderContext} from "@heroui/system";
import {useFocusRing} from "@react-aria/focus";
import {filterDOMProps} from "@heroui/react-utils";
import {clsx, dataAttr, objectToDeps, removeEvents, mergeProps} from "@heroui/shared-utils";
import {dataAttr, objectToDeps, removeEvents, mergeProps} from "@heroui/shared-utils";
import {useOption} from "@react-aria/listbox";
import {useHover, usePress} from "@react-aria/interactions";
import {useIsMobile} from "@heroui/use-is-mobile";
@ -111,7 +111,7 @@ export function useListboxItem<T extends object>(originalProps: UseListboxItemPr
[objectToDeps(variantProps), isDisabled, disableAnimation, rendered, description],
);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
if (isReadOnly) {
itemProps = removeEvents(itemProps);
@ -139,7 +139,7 @@ export function useListboxItem<T extends object>(originalProps: UseListboxItemPr
"data-selected": dataAttr(isSelected),
"data-pressed": dataAttr(isPressed),
"data-focus-visible": dataAttr(isFocusVisible),
className: slots.base({class: clsx(baseStyles, props.className)}),
className: slots.base({class: cn(baseStyles, props.className)}),
});
const getLabelProps: PropGetter = (props = {}) => ({

View File

@ -13,7 +13,7 @@ import {listbox} from "@heroui/theme";
import {useListState} from "@react-stately/list";
import {filterDOMProps, useDOMRef} from "@heroui/react-utils";
import {useMemo} from "react";
import {clsx} from "@heroui/shared-utils";
import {cn} from "@heroui/theme";
interface AriaListBoxOptions<T> extends AriaListBoxProps<T> {
/** Whether the listbox uses virtual scrolling. */
@ -134,7 +134,7 @@ export function useListbox<T extends object>(props: UseListboxProps<T>) {
const slots = useMemo(() => listbox(), []);
const baseStyles = clsx(classNames?.base, className);
const baseStyles = cn(classNames?.base, className);
const getBaseProps: PropGetter = (props = {}) => {
return {

Some files were not shown because too many files have changed in this diff Show More