Compare commits

...

64 Commits

Author SHA1 Message Date
github-actions[bot] f37e108588 ci(changesets): version packages (#6059)
Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>
2026-01-29 23:41:54 +08:00
WK 63c12e5359 chore(docs): update meta (#6168) 2026-01-29 00:20:06 +08:00
Bohdan Kulinchenko 1a2635beda fix(system-rsc): extendVariants & compound variants types (#5847)
* fix(extendVariants): return component type error

* fix(CompoundVariants): correct type inference for extended/compound variants and composition

* test: cover compound/extend inference; enforce CP required props

* fix(types): correct CompoundVariants class value inference

Replaces the conditional ClassProp logic with a simpler,
consistent form to fix incorrect slot value inference.

Before:
  ClassProp<S extends undefined ? ClassValue : ClassValue | SlotsClassValue<S>>

After:
  ClassProp<ClassValue | GetSuggestedValues<S>>

This ensures GetSuggestedValues<S> is used for slot-aware variants
and avoids duplicated conditional branches for undefined slots.

* fix(system-rsc): correct slot detection in getSlots()

* fix(types): make ExtendVariants props optional and guard V[key] with NonNullable

Simplifies the return type of ExtendVariants to ensure no required props
are enforced at the HOC level. This aligns with the intended API contract
where extended components expose all props as optional.

- All keys (CP ∪ V) are optional
- Preserve CP type hints and booleanized V values
- Added NonNullable<V[key]> guard to prevent undefined indexing

* test(extendVariants): add compoundVariants integration test

* fix(system-rsc): getSlots() brief JSDoc comment added

* test(extendVariants):  new styles - extended & fixed styles - original tests for slots component

* test(extendVariants): fixed slot component variant styles extended test

* fix(types): avoid leaking React internals by removing PropsWithoutRef

Replace PropsWithoutRef with explicit Exclude<'ref'> in mapped keys and
intersect with RefAttributes<InferRef<C>>. This prevents @types/react’s
internal UNDEFINED_VOID_ONLY from leaking into the public .d.ts and fixes
declaration emit for components like extended Autocomplete.

* chore(changeset): add patch for extendVariants and CompoundVariants type fix

* chore(system-rsc): add changeset for getSlots() slot detection fix

* refactor(types): unify slot value inference via GetSuggestedValues<S> for consistent variant typing

* fix(extendVariants): improved as-prop handling and exclude classNames from SuggestedVariants

* fix(system-rsc): add polymorphic 'as' prop support to extendVariants

* chore(system-rsc): add missing tests

---------

Co-authored-by: doki- <1335902682@qq.com>
Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2026-01-28 23:52:36 +08:00
KumJungMin 7814df7cea fix(listbox): prevent option focus from start/end content slots (#6060)
* fix(listbox): prevent option focus from start/end content slots

* test: add test code about when clicking
non-interactive slot content, and prevented focus leakage from interactive
start/end content such as buttons.

* docs: add changeset

* chore(changeset): add issue number

---------

Co-authored-by: WK <wingkwong.code@gmail.com>
2026-01-28 23:45:15 +08:00
WK 5549167041 refactor(theme): remove flat dependency (#6157)
* chore(deps): remove flat library

* refactor(theme): replace flatten from flat

* chore: add changeset
2026-01-28 20:48:02 +08:00
Deepansh Bhargava 96b1f498cf fix(accordion): click behaviour for dynamically generated accordion items (#6133)
* fix(accordion): add collection state

* chore: add changeset

* fix: update change set
2026-01-27 17:52:34 +08:00
Junior 4add7525a0 Merge branch 'main' of github.com:heroui-inc/heroui into canary 2026-01-07 12:07:37 -03:00
KyZy7 d5a5c77ed6 fix(date-picker): open date-picker when clicking border (#6084)
* fix(date-picker): add pointer interaction to open date picker on wrapper click

* chore: add changeset

* chore(changeset): add issue number

---------

Co-authored-by: WK <wingkwong.code@gmail.com>
2026-01-07 00:39:08 +08:00
creative-atish 1f085061ed fix(pagination): improve layout for large page counts (#6034)
* fix(pagination): improve layout for large page counts/style of paagination compnents

* fix(pagination): refine item sizing to balance small and large page numbers

* ci(changesets): add pagination sizing changeset

* fix(pagination): ensure cursor fully covers button without changing radius

* chore(changeset): revise message and add issue numbers

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2026-01-04 22:27:47 +08:00
Dominik Hryshaiev df6610cd98 fix(docs): broken links in Form page (#6077) 2026-01-02 20:22:26 +08:00
brianatdetections 5ec842b1cf fix(use-image): resolve race condition with cached images on Firefox/Safari (#6041)
* fix(use-image): resolve race condition with cached images on Firefox/Safari

The bug occurred because event handlers (onload/onerror) were attached
AFTER setting the image src. For cached images, browsers fire onload
synchronously when src is set, causing the event to be missed and
images to remain stuck at opacity-0.

Changes:
- Attach handlers BEFORE setting src to catch synchronous callbacks
- Check both naturalWidth AND naturalHeight (per CodeRabbit review on #4523)
- Handle synchronous error callbacks for failed cached images
- Add comprehensive test coverage (15 tests) including:
  - Synchronous cached image success (Firefox/Safari race condition)
  - Synchronous cached image error
  - Dynamic src changes
  - All props (crossOrigin, srcSet, sizes, loading)
  - Callback invocation verification

Reproduction and investigation performed using Claude Opus 4.5.

Fixes #4534, #2259

* fix(use-image): add ignoreFallback to useCallback dependencies

Address CodeRabbit review feedback: the `ignoreFallback` prop was used
inside the `load` callback (line 104) but was missing from the dependency
array, creating a stale closure bug.

Without this fix, if `ignoreFallback` changes from `true` to `false`
dynamically, the `load` callback would retain the stale `true` value,
preventing the image from ever loading.

Changes:
- Add `ignoreFallback` to useCallback dependency array
- Add tests for dynamic `ignoreFallback` changes (both directions)
- Update changeset to document this fix

Verification performed using Claude Opus 4.5.

---------

Co-authored-by: Brian Meek <brian@current.space>
2025-12-27 14:24:27 +08:00
Junior 65702817c2 refactor(docs): remove Sponsors component from Home page 2025-12-25 11:42:04 -03:00
Junior 436e0d8278 Merge branch 'main' of github.com:heroui-inc/heroui into canary 2025-12-25 11:41:09 -03:00
WK 2d693f732c v2.8.7 (#6022)
* fix(theme): hide password reveal button (#5990)

* fix(link): link overriding role (#5999)

* fix(link): allow overriding role

* chore(link): changeset

* chore(deps): upgrade react-aria (v1.14.0) (#5996)

* chore(deps): upgrade react-aria (v1.14.0)

* refactor(react): group client components

* fix(dropdown): keyDown test cases

* chore(react): rollback

* fix(theme): default transition-duration (#6011)

* fix(theme): default transitionDuration

* chore(deps): bump @heroui/theme peer dep

* ci(changesets): version packages (#5991)

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>

---------

Co-authored-by: Hayato Hasegawa <hase1225hayato@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>
2025-12-25 06:40:03 -08:00
github-actions[bot] d5131d77a3 ci(changesets): version packages (#5991)
Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>
2025-12-20 22:17:53 +08:00
WK 086f6a1c44 fix(theme): default transition-duration (#6011)
* fix(theme): default transitionDuration

* chore(deps): bump @heroui/theme peer dep
2025-12-20 22:01:47 +08:00
WK e07c969c4c chore(deps): upgrade react-aria (v1.14.0) (#5996)
* chore(deps): upgrade react-aria (v1.14.0)

* refactor(react): group client components

* fix(dropdown): keyDown test cases

* chore(react): rollback
2025-12-18 19:52:56 +08:00
Hayato Hasegawa 090b151a5b fix(link): link overriding role (#5999)
* fix(link): allow overriding role

* chore(link): changeset
2025-12-18 18:42:22 +08:00
WK acc74d1e8f fix(theme): hide password reveal button (#5990) 2025-12-16 14:20:58 +08:00
Junior Garcia 41fc673586 Merge pull request #5983 from heroui-inc/canary
v2.8.6
2025-12-14 18:30:02 -08:00
github-actions[bot] c76c68ad7e ci(changesets): version packages (#5820)
Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>
2025-12-14 15:44:29 +08:00
WK 2148a2ee3b chore(docs): refresh meta (#5980) 2025-12-14 14:04:48 +08:00
mojtaba 53e27bb6f8 fix(system-rsc): respect defaultVariants.className in extendVariants (#5940)
* fix(system-rsc): respect defaultVariants.className in extendVariants

- Fix getClassNamesWithProps to merge defaultVariants.className with result and props.className
- Add tests to verify defaultVariants.className is respected and merged correctly

* chore(changeset): add changeset

* refactor(system-rsc): cn with newProps.className

* chore(system-rsc): revise merge order

---------

Co-authored-by: hassanzadeh-mj <hassanzadeh-mj@users.noreply.github.com>
Co-authored-by: WK <wingkwong.code@gmail.com>
2025-12-14 14:04:21 +08:00
WK 467b497156 chore(deps): bump next version (#5978) 2025-12-12 19:34:05 +08:00
WK 799bc5bab8 fix(toast): long text exceeds wrapper (#5977) 2025-12-11 22:55:12 +08:00
Deepansh Bhargava a37912e17f fix(slots): extendVariants fn to support slots (#5895)
* fix: extendVariants fn to support slots

* chore(docs): undo changes

* chore(changeset): add changeset

* chore(docs): new line

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-12-11 20:43:40 +08:00
doki- 4c435348ec fix(theme): incorrect label position of the select component (#5799)
* fix(theme): incorrect label position of the select component

* fix(theme): incorrect label position of select component
2025-12-11 20:15:49 +08:00
Hayato Hasegawa 8d07922c68 feat: add support for "outside-top" label placement (#5964)
* feat(number-input): add support for "outside-top" label placement

* chore: changeset

* fix(number-input): correct label positioning for "outside-top" placement

* feat: add `outside-top` label placement support for inputs and provider

* chore: update changeset

* chore(docs): update docs to include `outside-top` label placement

* test: add tests for `HeroUIProvider` label placement inheritance

* test(date-picker): remove tests for `HeroUIProvider` label placement inheritance

* test: add comprehensive tests for `HeroUIProvider` label placement outside-top

* chore(deps): bump theme in peerDependencies

* chore(docs): update examples and descriptions to include `outside-top` label placement

* chore(docs): update autocomplete label placement type to include `outside-top`

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-12-11 20:10:43 +08:00
WK ecf2857c90 refactor: tailwind-variants (#5930)
* chore(deps): bump tailwind-variants

* chore(changeset): add changeset

* refactor(theme): use cnMerge from tailwind-variants

* refactor: replace clsx by cn

* chore(deps): remove clsx

* chore: rollback clsx for mergeProps

* fix(theme): incorrect syntax

* refactor: remove outer cn

* chore(docs): type issues

* fix(radio): duplicate import

* chore(deps): bump peerDependencies for theme package

* chore(changeset): update changeset
2025-12-11 13:04:09 +08:00
WK a81212d6e7 fix(deps): next version (#5968)
* fix(deps): nextjs version

* chore(deps): bump next version
2025-12-06 21:15:23 +08:00
WK a7655ad2c9 chore(docs): remove chat linkage (#5959)
* chore: remove unused globalEnv

* chore(docs): remove chat links
2025-12-04 16:59:57 -03:00
WK b89ba08ae0 fix(table): virtualized table in firefox by replacing Spacer with css (#5963)
* chore(deps): remove spacer and bump theme peer dependency

* refactor(table): remove spacer

* fix(theme): replace spacer by css

* chore(changeset): add changeset

* chore(changeset): update changeset message
2025-12-04 23:13:46 +08:00
WK f08dfb8dd9 fix(table): column props not recognized (#5950)
* fix(table): width, minWidth, and maxWidth

* refactor(docs): revise table examples

* chore(changeset): add changeset
2025-12-04 21:42:04 +08:00
WK 0f165a36c8 fix(components): typos (#5958) 2025-12-03 01:18:40 +08:00
WK 9520b3f850 fix(docs): typos (#5957) 2025-12-03 00:29:37 +08:00
Stybo ecad199b09 fix(docs): typos in calendar and range-calendar page (#5956)
* Fix typo in calendar component documentation

* Fix typo in range-calendar documentation
2025-12-03 00:16:26 +08:00
Adam Björnberg a819f2a95a fix(tabs): responsive resize cursor to match selected tab (#5846)
* fix(tabs): responsive resize cursor to match selected tab

* Move css to theme

* Update changeset

* use explicit true for data-initialized

* disable animation when variant changes

* make not disappear when toggling animation

* disable animation when isVertical changes

* refactor for readability

* fix blinking when toggling variant or isVertical

* disable animation when changing placement

* chore(changeset): add issue number

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-12-02 18:39:10 +08:00
Hayato Hasegawa b4cfb408e9 fix(autocomplete): show popover when emptyContent is provided with allowsCustomValue (#5951)
* fix(autocomplete): show popover when emptyContent is provided with allowsCustomValue

* chore(autocomplete): remove deprecated story with custom emptyContent and allowsCustomValue

* chore: add changeset
2025-12-01 00:12:59 +08:00
Hayato Hasegawa 66ef76e823 fix(link): resolve issue where useHref is not working correctly (#5933)
* fix(link): correct props merge order in use-link to apply useHref

* chore(link): add changeset

* test(link): adjust href assertion to use getAttribute for compatibility

* fix(link): use routerLinkProps.href in handleLinkClick for consistency

* fix(link): process href with useHref before passing to useLinkProps

* test(link): comment out useHref provider test

* Revert "test(link): comment out useHref provider test"

This reverts commit de053f835fa57becf6e807a64c17339fc61d8689.

* Revert "fix(link): process href with useHref before passing to useLinkProps"

This reverts commit 81e5f7b8d1ea7002b9718cf521b5c6f2af79ac42.

* fix(provider): add `useHref` to provider context and integrate with `useLink`

* test(link): comment out useHref provider test

* fix(link): correct href handling in link component and update tests

* fix(link): simplify props handling by removing resolvedProps logic and reorder mergeProps usage

* fix(provider): remove `useHref` from provider context and related logic

* refactor(link): add spacing

* chore(changeset): add issue numbers

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-11-28 18:34:17 +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 4e3098a512 chore(docs): add deprecation message (#5946) 2025-11-25 14:57:35 -03: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
Hayato Hasegawa 8b2ec9fa46 fix(table): use controlled sorting in table test (#5904) 2025-11-23 01:16:09 +08:00
Hayato Hasegawa 5d9a05be01 fix(tabs): vertical tabs support for accessible navigation and aria-orientation (#5924) 2025-11-22 10:56:26 +08:00
Hayato Hasegawa bc4c982609 fix(skeleton): fixed shimmer animation still plays when disableAnimation is true (#5916)
* fix(skeleton): restore shimmer animation for background transition

* chore: changeset

* chore(skeleton): bump theme peer dep

* chore(skeleton): pass args to first skeleton

* chore(changeset): bump skeleton

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-11-21 15:18:27 +08:00
Hayato Hasegawa 8921dc4361 fix(theme): safari autofill styling for dark mode readability in Input component (#5909)
* fix: add Safari autofill styling for dark mode readability in NumberInput & Input components

* chore: add changeset for Safari autofill dark mode fix in NumberInput & Input components
2025-11-19 21:51:21 +08:00
Hayato Hasegawa fd9dd2a20c fix(theme): bordered focus styles take precedence over hover (#5893)
* fix(theme): bordered focus styles take precedence over hover

* chore(theme): update component focus styles to fix hover override

* chore: bump @heroui/theme peer deps

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-11-16 22:20:17 +08:00
Hayato Hasegawa 91e010fe3b fix(ripple): resolve misalignment in RTL layouts by using transform (#5891)
* fix(ripple): resolve misalignment in RTL layouts by using transform translate

* chore(ripple): add changeset for ripple RTL layout fix

* chore: add issue number

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-11-15 22:36:40 +08:00
WK 0bf225abf5 fix(docs): layoutColor.overlay (#5782) 2025-11-15 22:00:58 +08:00
Junior Garcia 83b8fc1e7c chore: v3 beta release banner 2025-11-06 17:12:46 -03:00
Mahdi Mohammadi 0344123c13 fix(docs): submenu selected item indicator (#5868)
Co-authored-by: Mahdi <mahdiprog81@gmail.com>
2025-11-04 00:39:34 +08:00
Anusha Chaturvedi 6a3b02773d fix(docs): increase sidebar text contrast to meet WCAG AA accessibility (#5819) 2025-11-03 12:59:52 +08:00
KumJungMin bdd37b4b08 fix(number-input): include labelPlacement in dependency array (#5866)
* fix(number-input): include labelPlacement in dependency array for useNumberInput

* test(number-input): add tests for labelPlacement with HeroUIProvider context

* test(number-input): ensure labelPlacement prop takes precedence over HeroUIProvider context

* docs(number-input): add changeset

* chore(changeset): add issue number

---------

Co-authored-by: WK <wingkwong.code@gmail.com>
2025-11-02 20:51:42 +08:00
Vilas Chauvhan 27fec2db3c fix(docs): codeblock flickering issue (#5849)
* fix: updated codeblock component to prevent flicker when scrolling

* fix(codeblock): revert className and style handling

* fix(codeblock): clean up className handling and remove unnecessary styles

* chore(docs): format

---------

Co-authored-by: WK Wong <wingkwong.code@gmail.com>
2025-11-01 18:33:02 +08:00
Vishesh Verma 1782961859 fix(spinner): spinner animation (#5815)
* fix(components/spinner): restore linear rotation (fix #5794)

* fix(spinner): add patch changeset for spinner delay fix

* fix(spinner): restore linear rotation for spinner variant (fix #5794)

* chore: apply Prettier and ESLint fixes to animation util

* chore(theme): lint

* chore(changeset): update msg & add issue number

* chore(changeset): include theme package

* chore(spinner): bump theme peerDependencies

---------

Co-authored-by: WK <wingkwong.code@gmail.com>
2025-10-28 01:59:58 +08:00
WK 680b68bc83 chore(docs): update nav banner (#5835) 2025-10-21 10:02:06 -03:00
Nikhil Shrivastava 328c57d8ea fix(heroui-table): update virtualization examples to use @heroui/react imports (#5833) 2025-10-21 00:03:12 -03:00
WK 2922b35644 fix(autocomplete): close button display on mobile (#5827)
* fix(autocomplete): close button display on mobile

* refactor(autocomplete): disable isClearable if isDisabled is true
2025-10-19 11:35:18 +08:00
WK b38a2cfb58 fix(theme): tab cursor (#5816)
* fix(theme): remove inset-0 for tab cursor

* chore(deps): bump theme peerDep

* chore: add changeset
2025-10-17 10:41:49 +08:00
Junior Garcia acd5f1dfb5 Merge pull request #5772 from heroui-inc/canary 2025-10-04 11:03:28 -03:00
Junior Garcia a88f98a14b Merge pull request #5679 from heroui-inc/canary 2025-09-09 15:51:27 -03:00
366 changed files with 6938 additions and 4058 deletions
-5
View File
@@ -22,8 +22,3 @@ NEXT_PUBLIC_FB_FEEDBACK_URL=
# PostHog
NEXT_PUBLIC_POSTHOG_KEY=your-posthog-key
NEXT_PUBLIC_POSTHOG_HOST=your-posthog-host
# Chat
IMPORT_API_KEY=your-import-api-key
CHAT_API_URL=
CHAT_URL=
-100
View File
@@ -1,100 +0,0 @@
"use server";
import {toKebabCase, toPascalCase} from "@/components/docs/components/code-demo/utils";
const importReact = 'import React from "react";';
export const openInChat = async ({
component,
title,
content,
dependencies,
useWrapper,
}: {
component: string;
title?: string;
content: string;
dependencies: {name: string; version: string}[];
useWrapper: boolean;
}) => {
try {
// Check if the file content includes 'React' import statements, if not, add it
if (
content.includes("React.") &&
!content.includes("from 'react'") &&
!content.includes('from "react"')
) {
content = `${importReact}\n${content}\n`;
}
let files: Record<string, string> = {
"src/App.tsx": content,
};
const fullName = `${component.charAt(0).toUpperCase() + component.slice(1)} - ${title}`;
if (useWrapper) {
files = getFilesWithWrapper(fullName, content);
}
const response = await fetch(`${process.env.CHAT_API_URL}/import`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.IMPORT_API_KEY}`,
},
body: JSON.stringify({
title: `${component.charAt(0).toUpperCase() + component.slice(1)} - ${title}`,
files,
dependencies,
}),
});
const result = await response.json();
if (result.error || !result.path) {
return {
error: result.error ?? "Unknown error",
data: null,
};
}
return {
error: null,
data: `${process.env.CHAT_URL}${
result.path
}&utm_source=heroui.com&utm_medium=open-in-chat&utm_content=${encodeURIComponent(
title ?? "unknown",
)}`,
};
} catch (error) {
return {error: error, data: null};
}
};
const getFilesWithWrapper = (name: string, content: string) => {
const pascalName = toPascalCase(name);
const kebabName = toKebabCase(name);
// Replace the export default function name
const updatedContent = content.replace(
"export default function App()",
`export default function ${pascalName}()`,
);
const wrapperContent = `import ${pascalName} from "./components/${kebabName}";
export default function App() {
return (
<div className="flex min-h-screen items-center justify-center p-6">
<${pascalName} />
</div>
);
}
`;
return {
[`src/components/${kebabName}.tsx`]: updatedContent,
[`src/App.tsx`]: wrapperContent,
};
};
@@ -350,20 +350,18 @@ export default function Page() {
);
case "actions":
return (
<div className="relative flex justify-end items-center gap-2">
<Dropdown className="bg-background border-1 border-default-200">
<DropdownTrigger>
<Button isIconOnly radius="full" size="sm" variant="light">
<VerticalDotsIcon className="text-default-400" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<Dropdown className="bg-background border-1 border-default-200">
<DropdownTrigger>
<Button isIconOnly radius="full" size="sm" variant="light">
<VerticalDotsIcon className="text-default-400" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
);
default:
return cellValue;
+12 -14
View File
@@ -342,20 +342,18 @@ export default function Page() {
);
case "actions":
return (
<div className="relative flex justify-end items-center gap-2">
<Dropdown>
<DropdownTrigger>
<Button isIconOnly size="sm" variant="light">
<VerticalDotsIcon className="text-default-300" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<Dropdown>
<DropdownTrigger>
<Button isIconOnly size="sm" variant="light">
<VerticalDotsIcon className="text-default-300" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
);
default:
return cellValue;
+4 -4
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";
@@ -13,7 +13,7 @@ import {siteConfig} from "@/config/site";
import {fonts} from "@/config/fonts";
import {Navbar} from "@/components/navbar";
import {Footer} from "@/components/footer";
import {RandomBanner} from "@/components/random-banner";
import {ProBanner} from "@/components/pro-banner";
export const metadata: Metadata = {
title: {
@@ -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,
@@ -83,7 +83,7 @@ export default function RootLayout({children}: {children: React.ReactNode}) {
>
<Providers themeProps={{attribute: "class", defaultTheme: "dark"}}>
<div className="relative flex flex-col" id="app-container">
<RandomBanner />
<ProBanner />
<Navbar mobileRoutes={manifest.mobileRoutes} routes={manifest.routes} />
{children}
<Analytics mode="production" />
-2
View File
@@ -12,7 +12,6 @@ import {InstallBanner} from "@/components/marketing/install-banner";
import {Community} from "@/components/marketing/community";
import Support from "@/components/marketing/support";
import landingContent from "@/content/landing";
import {Sponsors} from "@/components/marketing/sponsors";
import {HeroUIProSection} from "@/components/marketing/heroui-pro-section";
export default async function Home() {
@@ -21,7 +20,6 @@ export default async function Home() {
<section className="flex flex-col items-center justify-center">
<Hero />
<FeaturesGrid features={landingContent.topFeatures} />
<Sponsors />
<CustomThemes />
<A11yOtb />
<DarkMode />
+3 -3
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))]",
)}
+2 -2
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,
)}
@@ -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>
);
});
+2 -2
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,
@@ -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,
)}
+2 -2
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}
>
@@ -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
@@ -4,18 +4,13 @@ import type {UseCodeDemoProps} from "./use-code-demo";
import type {WindowResizerProps} from "./window-resizer";
import type {GradientBoxProps} from "@/components/gradient-box";
import React, {useCallback, useMemo, useRef, useState} from "react";
import React, {useCallback, useMemo, useRef} from "react";
import dynamic from "next/dynamic";
import {addToast, Button, Skeleton, Spinner, Tab, Tabs} from "@heroui/react";
import {Skeleton, Tab, Tabs} from "@heroui/react";
import {useInView} from "framer-motion";
import {usePostHog} from "posthog-js/react";
import {usePathname} from "next/navigation";
import {useCodeDemo} from "./use-code-demo";
import WindowResizer from "./window-resizer";
import {parseDependencies} from "./parse-dependencies";
import {openInChat} from "@/actions/open-in-chat";
const DynamicReactLiveDemo = dynamic(
() => import("./react-live-demo").then((m) => m.ReactLiveDemo),
@@ -82,11 +77,6 @@ export const CodeDemo: React.FC<CodeDemoProps> = ({
margin: "600px",
});
const pathname = usePathname();
const posthog = usePostHog();
const [isLoading, setIsLoading] = useState(false);
const {noInline, code} = useCodeDemo({
files,
});
@@ -178,64 +168,6 @@ export const CodeDemo: React.FC<CodeDemoProps> = ({
return true;
}, [showTabs, showPreview, showEditor]);
const isComponentsPage = pathname.includes("/components/");
const handleOpenInChat = useCallback(async () => {
setIsLoading(true);
// assume doc demo files are all App.jsx
const content = files["/App.jsx"];
if (!content || typeof content !== "string") {
addToast({
title: "Error",
description: "Invalid demo content",
color: "danger",
});
return;
}
const component = pathname.split("/components/")[1];
const dependencies = parseDependencies(content);
posthog.capture("CodeDemo - Open in Chat", {
component,
demo: title,
});
const newTab = window.open(undefined, "_blank");
const {data, error} = await openInChat({
component,
title,
content,
dependencies,
useWrapper: !asIframe,
});
setIsLoading(false);
if (error || !data) {
if (newTab) newTab.close();
posthog.capture("CodeDemo - Open in Chat Error", {
component,
demo: title,
error: error ?? "Unknown error",
});
addToast({
title: "Error",
description: error ?? "Unknown error",
color: "danger",
});
return;
}
if (newTab) newTab.location.href = data;
}, [pathname, title, files, posthog]);
return (
<div ref={ref} className="flex flex-col gap-2 relative">
{shouldRenderTabs ? (
@@ -255,26 +187,6 @@ export const CodeDemo: React.FC<CodeDemoProps> = ({
{editorContent}
</Tab>
</Tabs>
{isComponentsPage && (
<Button
disableRipple
className="absolute rounded-[9px] right-1 top-1 border-1 border-default-200 dark:border-default-100 data-[hover=true]:bg-default-50/80"
isDisabled={isLoading}
size="sm"
variant="bordered"
onPress={handleOpenInChat}
>
Open in Chat{" "}
{isLoading ? (
<Spinner
classNames={{wrapper: "h-4 w-4"}}
color="current"
size="sm"
variant="simple"
/>
) : null}
</Button>
)}
</>
) : (
<>
@@ -52,6 +52,6 @@ export const parseDependencies = (content: string) => {
};
const fixedVersions = {
"@internationalized/date": "3.10.0",
"@react-aria/i18n": "3.12.13",
"@internationalized/date": "3.10.1",
"@react-aria/i18n": "3.12.14",
};
@@ -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>
);
@@ -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,16 +124,10 @@ const CodeBlockHighlight = ({
preRef.current = element;
}
}}
className={clsx(
className,
classNameProp,
`language-${codeLang}`,
"max-w-full contents",
{
"flex-col": isMultiLine,
"overflow-x-scroll scrollbar-hide": hideScrollBar,
},
)}
className={cn(className, classNameProp, `language-${codeLang}`, "max-w-full", {
"flex-col": isMultiLine,
"overflow-x-scroll scrollbar-hide": hideScrollBar,
})}
data-language={language}
style={style}
>
@@ -144,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",
@@ -202,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>
);
@@ -0,0 +1,20 @@
"use client";
import {Blockquote} from "./components/blockquote";
export const DeprecationMessage = () => {
return (
<Blockquote color="warning">
<b>Deprecation Notice:</b> HeroUI v2 will be deprecated soon. We recommend to use{" "}
<a
className="underline"
href="http://v3.heroui.com/"
rel="noopener noreferrer"
target="_blank"
>
<b>HeroUI v3</b>
</a>{" "}
for the new projects.
</Blockquote>
);
};
+1
View File
@@ -2,3 +2,4 @@ export * from "./sidebar";
export * from "./toc";
export * from "./pager";
export * from "./components/code-demo";
export * from "./deprecation-message";
+9 -9
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,
+5 -4
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,10 +86,11 @@ export const DocsToc: FC<DocsTocProps> = ({headings}) => {
heading.level > 1 && (
<li
key={i}
className={clsx(
className={cn(
"relative",
"transition-colors",
"font-normal",
"flex items-center text-tiny font-normal text-default-500 dark:text-default-300",
"flex items-center text-tiny font-normal text-default-500",
"data-[active=true]:text-foreground",
"dark:data-[active=true]:text-foreground",
"before:content-['']",
@@ -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]"
@@ -1,92 +0,0 @@
"use client";
import {Icon} from "@iconify/react/dist/offline";
import arrowRightIcon from "@iconify/icons-solar/arrow-right-linear";
import {usePathname} from "next/navigation";
import {useEffect} from "react";
import {usePostHog} from "posthog-js/react";
import emitter from "@/libs/emitter";
const hideOnPaths = ["examples"];
export const HeroUIChatBanner = () => {
const posthog = usePostHog();
const handleClick = () => {
posthog.capture("HeroUI Chat Banner", {
action: "click",
category: "landing-page",
});
};
const pathname = usePathname();
const shouldBeVisible = !hideOnPaths.some((path) => pathname.includes(path));
useEffect(() => {
if (!shouldBeVisible) return;
// listen to scroll event, dispatch an event when scroll is at the top < 48 px
const handleScroll = () => {
if (window.scrollY < 48) {
emitter.emit("proBannerVisibilityChange", "visible");
} else {
emitter.emit("proBannerVisibilityChange", "hidden");
}
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, [shouldBeVisible]);
if (!shouldBeVisible) return null;
return (
<div className="relative z-50 isolate flex items-center gap-x-6 overflow-hidden bg-background border-b-1 border-divider px-6 py-2 sm:px-3.5 sm:before:flex-1">
<div className="flex w-full items-center justify-between md:justify-center gap-x-3">
<a
className="text-small flex items-end sm:text-[0.93rem] text-foreground hover:opacity-80 transition-opacity"
href="https://heroui.chat?utm_source=heroui.com&utm_medium=top-banner"
rel="noopener noreferrer"
target="_blank"
onClick={handleClick}
>
<span aria-label="rocket" className="hidden md:block" role="img">
🚀
</span>
<span
className="inline-flex md:ml-1 animate-text-gradient font-medium bg-clip-text text-transparent bg-[linear-gradient(90deg,#27272A_0%,#52525B_50%,#52525B_100%)] dark:bg-[linear-gradient(90deg,#E5E5E5_0%,#A1A1AA_50%,#E5E5E5_100%)]"
style={{
fontSize: "inherit",
backgroundSize: "200%",
backgroundClip: "text",
WebkitBackgroundClip: "text",
color: "transparent",
}}
>
Generate, edit and deploy beautiful apps
</span>
</a>
<a
className="flex group min-w-[120px] items-center font-semibold text-background bg-foreground shadow-sm gap-1.5 relative overflow-hidden rounded-full p-[1px] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"
href="https://heroui.chat?utm_source=heroui.com&utm_medium=top-banner"
rel="noopener noreferrer"
onClick={handleClick}
>
<div className="inline-flex h-full w-full cursor-pointer items-center justify-center rounded-full bg-foreground group-hover:bg-foreground/70 transition-background px-3 py-1 text-sm font-medium text-background">
HeroUI Chat
<Icon
aria-hidden="true"
className="outline-solid outline-transparent transition-transform group-hover:translate-x-0.5 [&>path]:stroke-[2px]"
icon={arrowRightIcon}
width={16}
/>
</div>
</a>
</div>
</div>
);
};
+2 -2
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
@@ -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')]",
+4 -27
View File
@@ -1,12 +1,13 @@
"use client";
import NextLink from "next/link";
import {Button, Link, Chip, Snippet} from "@heroui/react";
import {Button, Link, Snippet} from "@heroui/react";
import {ArrowRightIcon} from "@heroui/shared-icons";
import dynamic from "next/dynamic";
import {usePostHog} from "posthog-js/react";
import {FloatingComponents} from "./floating-components";
import {V3ReleaseBanner} from "./v3-release-banner";
import {GithubIcon} from "@/components/icons";
import {title, subtitle} from "@/components/primitives";
@@ -19,35 +20,11 @@ const BgLooper = dynamic(() => import("./bg-looper").then((mod) => mod.BgLooper)
export const Hero = () => {
const posthog = usePostHog();
const handlePressAnnouncement = (name: string, url: string) => {
posthog.capture("NavbarItem", {
name,
action: "press",
category: "home - hero",
data: url,
});
};
return (
<section className="flex relative overflow-hidden lg:overflow-visible w-full flex-nowrap justify-between items-center h-[calc(100vh_-_64px)] 2xl:h-[calc(84vh_-_64px)]">
<div className="relative z-20 flex flex-col w-full gap-6 lg:w-1/2 xl:mt-10">
<div className="flex justify-center w-full md:hidden">
<Chip
as={NextLink}
className="bg-default-200/50 border-1 hover:bg-default-200/80 border-default-400/50 cursor-pointer"
classNames={{
content: "font-semibold text-foreground text-xs ",
}}
color="primary"
href="/blog/v2.8.0"
variant="flat"
onClick={() => handlePressAnnouncement("HeroUI v2.8.0", "/blog/v2.8.0")}
>
HeroUI v2.8.0&nbsp;
<span aria-label="emoji" role="img">
🔥
</span>
</Chip>
<div className="w-full flex justify-center md:justify-start">
<V3ReleaseBanner />
</div>
<div className="leading-8 text-center md:leading-10 md:text-left">
<div className="inline-block">
@@ -0,0 +1,46 @@
"use client";
import {Chip} from "@heroui/react";
import {Icon} from "@iconify/react/dist/offline";
import arrowRightUpIcon from "@iconify/icons-solar/arrow-right-up-linear";
const releaseInfo = {
title: "HeroUI v3.0.0 (Beta)",
href: "https://v3.heroui.com?ref=heroui-v2",
emoji: "🔥",
};
export function V3ReleaseBanner() {
return (
<Chip
as="a"
classNames={{
base: "relative transition-colors hover:bg-default-700/10 border-1 border-default-700/10 backdrop-blur-lg bg-transparent",
content: "relative flex items-center font-medium text-default-900 pr-[14px]",
}}
href={releaseInfo.href}
rel="noopener noreferrer"
target="_blank"
variant="flat"
>
<span className="mr-1 text-sm">{releaseInfo.emoji}</span>
<span
className="animate-text-gradient inline-flex bg-clip-text font-medium text-transparent bg-[linear-gradient(90deg,#0485f7_0%,#BA8BF6_50%,#0485f7_100%)] dark:bg-[linear-gradient(90deg,#0485f7_0%,#BA8BF6_50%,#0485f7_100%)]"
style={{
fontSize: "inherit",
backgroundSize: "200%",
backgroundClip: "text",
WebkitBackgroundClip: "text",
color: "transparent",
}}
>
{releaseInfo.title}
</span>
<Icon
className="absolute right-[2px] top-1/2 -translate-y-1/2 text-default-500/60 outline-solid outline-transparent transition-transform group-data-[hover=true]:translate-y-0.5 [&>path]:stroke-[2.5px]"
icon={arrowRightUpIcon}
width={10}
/>
</Chip>
);
}
@@ -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%)]",
)}
@@ -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')]",
+8 -6
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";
@@ -14,6 +14,7 @@ import {CarbonAd} from "@/components/ads/carbon-ad";
import * as DocsComponents from "@/components/docs/components";
import * as BlogComponents from "@/components/blog/components";
import {Codeblock} from "@/components/docs/components";
import {DeprecationMessage} from "@/components/docs/deprecation-message";
import {VirtualAnchor, virtualAnchorEncode} from "@/components/virtual-anchor";
import {
Table as StaticTable,
@@ -36,7 +37,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 +95,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 +118,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 +152,7 @@ const Code = ({
fullWidth
hideSymbol
classNames={{
base: clsx(
base: cn(
"px-0 bg-code-background text-code-foreground",
{
"items-start": isMultiLine,
@@ -219,7 +220,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,
)}
@@ -362,6 +363,7 @@ export const MDXComponents = {
tr: Trow,
td: Tcol,
CarbonAd,
DeprecationMessage,
code: Code,
ul: List,
a: (props: React.HTMLAttributes<HTMLAnchorElement>) => <Link {...props} />,
+6 -6
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={{
@@ -185,7 +185,7 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
<Logo className="h-6" />
</NextLink>
{versionChip}
<Chip
{/* <Chip
as={NextLink}
className="hidden sm:flex bg-default-200/50 border-1 hover:bg-default-200/80 border-default-400/50 cursor-pointer"
classNames={{
@@ -200,7 +200,7 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
<span aria-label="emoji" role="img">
🔥
</span>
</Chip>
</Chip> */}
</NavbarBrand>
</NavbarContent>
@@ -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,
+2 -2
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,
)}
-26
View File
@@ -1,26 +0,0 @@
"use client";
import {useState, useEffect} from "react";
import {HeroUIChatBanner} from "@/components/heroui-chat-banner";
import {ProBanner} from "@/components/pro-banner";
export const RandomBanner = () => {
const [showChatBanner, setShowChatBanner] = useState<boolean | null>(null);
useEffect(() => {
const bannerCount = parseInt(sessionStorage.getItem("bannerCount") || "0", 10);
const shouldShowChat = bannerCount % 2 === 0;
setShowChatBanner(shouldShowChat);
sessionStorage.setItem("bannerCount", String(bannerCount + 1));
}, []);
if (showChatBanner === null) {
return <div className="h-[47px] border-b border-divider" />;
}
return showChatBanner ? <HeroUIChatBanner /> : <ProBanner />;
};
@@ -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}
+2 -2
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={{
+3 -3
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",
@@ -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",
@@ -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>
);
}
@@ -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,
)}
@@ -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" : "",
)}
@@ -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"
@@ -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>
);
@@ -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" : "",
)}
@@ -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;
}
}
@@ -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 : "",
)}
@@ -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 : "",
),
@@ -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}
+2 -2
View File
@@ -39,7 +39,7 @@ export const initialLightTheme: ConfigColors = {
foreground: colors.black,
background: colors.white,
focus: colors.blue[500],
overlay: colors.black,
overlay: colors.white,
},
contentColor: {
content1: colors.white,
@@ -64,7 +64,7 @@ export const initialDarkTheme: ConfigColors = {
foreground: colors.white,
background: colors.black,
focus: colors.blue[500],
overlay: colors.white,
overlay: colors.black,
},
contentColor: {
content1: colors.zinc[900],
@@ -1,8 +1,6 @@
import type {Config} from "../types";
import {colors} from "@heroui/theme";
import {initialLayout} from "../constants";
import {initialDarkTheme, initialLayout, initialLightTheme} from "../constants";
export const coffee: Config = {
name: "coffee",
@@ -20,7 +18,7 @@ export const coffee: Config = {
layoutColor: {
foreground: "#a27225",
background: "#fffbf6",
overlay: colors.black,
overlay: initialLightTheme.layoutColor.overlay,
focus: "#db924b",
},
contentColor: {
@@ -45,7 +43,7 @@ export const coffee: Config = {
foreground: "#c59f60",
background: "#20161F",
focus: "#db924b",
overlay: colors.white,
overlay: initialDarkTheme.layoutColor.overlay,
},
contentColor: {
content1: "#2c1f2b",
@@ -1,8 +1,6 @@
import type {Config} from "../types";
import {colors} from "@heroui/theme";
import {initialLayout} from "../constants";
import {initialDarkTheme, initialLayout, initialLightTheme} from "../constants";
export const elegant: Config = {
name: "elegant",
@@ -20,7 +18,7 @@ export const elegant: Config = {
layoutColor: {
foreground: "#4a4a4a",
background: "#ffffff",
overlay: colors.black,
overlay: initialLightTheme.layoutColor.overlay,
focus: "#db924b",
},
contentColor: {
@@ -44,7 +42,7 @@ export const elegant: Config = {
layoutColor: {
foreground: "#b0b0b0",
background: "#000000",
overlay: colors.white,
overlay: initialDarkTheme.layoutColor.overlay,
focus: "#000000",
},
contentColor: {
@@ -1,8 +1,6 @@
import type {Config} from "../types";
import {colors} from "@heroui/theme";
import {initialLayout} from "../constants";
import {initialDarkTheme, initialLayout, initialLightTheme} from "../constants";
export const modern: Config = {
name: "modern",
@@ -20,7 +18,7 @@ export const modern: Config = {
layoutColor: {
foreground: "#4a3d77",
background: "#f9f7fd",
overlay: colors.black,
overlay: initialLightTheme.layoutColor.overlay,
focus: "#7828c8",
},
contentColor: {
@@ -44,7 +42,7 @@ export const modern: Config = {
layoutColor: {
foreground: "#d0aaff",
background: "#1b1526",
overlay: colors.white,
overlay: initialDarkTheme.layoutColor.overlay,
focus: "#9353d3",
},
contentColor: {
@@ -1,8 +1,6 @@
import type {Config} from "../types";
import {colors} from "@heroui/theme";
import {initialLayout} from "../constants";
import {initialDarkTheme, initialLayout, initialLightTheme} from "../constants";
export const retro: Config = {
name: "retro",
@@ -20,7 +18,7 @@ export const retro: Config = {
layoutColor: {
foreground: "#5A4A42",
background: "#F4E8D1",
overlay: colors.black,
overlay: initialLightTheme.layoutColor.overlay,
focus: "#FFD34E",
},
contentColor: {
@@ -44,7 +42,7 @@ export const retro: Config = {
layoutColor: {
foreground: "#000000",
background: "#E1CA9E",
overlay: colors.white,
overlay: initialDarkTheme.layoutColor.overlay,
focus: "#FFD34E",
},
contentColor: {
+4 -4
View File
@@ -1,6 +1,6 @@
{
"stars": { "raw": 26880, "formatted": "26.9K" },
"forks": 1948,
"subscribers": 93,
"openIssues": 264
"stars": { "raw": 28016, "formatted": "28K" },
"forks": 2046,
"subscribers": 91,
"openIssues": 298
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -144,7 +144,7 @@ nextui add --all
<Spacer y={4} />
> The CLI is currentl in `Alpha` stage, we're working on adding more features and improvements. If you find any issues or have any suggestions, please let us know by [opening an issue](https://github.com/heroui-inc/heroui-cli/issues/new).
> The CLI is currently in `Alpha` stage, we're working on adding more features and improvements. If you find any issues or have any suggestions, please let us know by [opening an issue](https://github.com/heroui-inc/heroui-cli/issues/new).
To learn more about the CLI and its commands, please refer to the [CLI documentation](/docs/guide/cli) and the [CLI API reference](/docs/api-references/cli-api).
+1 -1
View File
@@ -93,7 +93,7 @@ The new `outside-top` option ensures that labels are consistently displayed at t
### Select
Two new properties `isClearable` and `onClear` have been introduced in the Select component. A clear button is visible when a value is slected and a callback function triggered upon clearing the selection for custom handling.
Two new properties `isClearable` and `onClear` have been introduced in the Select component. A clear button is visible when a value is selected and a callback function triggered upon clearing the selection for custom handling.
<CodeDemo title="Clearable" files={selectIsClearable} />
@@ -29,13 +29,13 @@ export const animals = [
];
export default function App() {
const placements = ["inside", "outside", "outside-left"];
const placements = ["inside", "outside", "outside-left", "outside-top"];
return (
<div className="w-full flex flex-col gap-4">
<div className="flex flex-col gap-2">
<div className="w-full grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="flex flex-col gap-4">
<h3 className="text-default-500 text-small">Without placeholder</h3>
<div className="flex w-full flex-wrap items-end md:flex-nowrap mb-6 md:mb-0 gap-4">
<div className="flex flex-col gap-4">
{placements.map((placement) => (
<Autocomplete
key={placement}
@@ -49,9 +49,9 @@ export default function App() {
))}
</div>
</div>
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-4">
<h3 className="text-default-500 text-small">With placeholder</h3>
<div className="flex w-full flex-wrap items-end md:flex-nowrap mb-6 md:mb-0 gap-4">
<div className="flex flex-col gap-4">
{placements.map((placement) => (
<Autocomplete
key={placement}
@@ -2,7 +2,7 @@ import {DateInput} from "@heroui/react";
import {CalendarDate} from "@internationalized/date";
export default function App() {
const placements = ["inside", "outside", "outside-left"];
const placements = ["inside", "outside", "outside-left", "outside-top"];
return (
<div className="w-full flex flex-col max-w-sm gap-4">
@@ -1,7 +1,7 @@
import {DatePicker} from "@heroui/react";
export default function App() {
const placements = ["inside", "outside", "outside-left"];
const placements = ["inside", "outside", "outside-left", "outside-top"];
return (
<div className="flex flex-col gap-4">
@@ -19,7 +19,7 @@ import unavailableDates from "./unavailable-dates";
import visibleMonth from "./visible-month";
import firstDayOfWeek from "./first-day-of-week";
import pageBehavior from "./page-behavior";
import nonContigous from "./non-contiguous";
import nonContiguous from "./non-contiguous";
import presets from "./presets";
import withMonthAndYearPickers from "./with-month-and-year-pickers";
import customStyles from "./custom-styles";
@@ -46,7 +46,7 @@ export const dateRangePickerContent = {
visibleMonth,
firstDayOfWeek,
pageBehavior,
nonContigous,
nonContiguous,
presets,
withMonthAndYearPickers,
customStyles,
@@ -1,7 +1,7 @@
import {DateRangePicker} from "@heroui/react";
export default function App() {
const placements = ["inside", "outside", "outside-left"];
const placements = ["inside", "outside", "outside-left", "outside-top"];
return (
<div className="flex flex-col gap-4">
@@ -1,13 +1,13 @@
import {NumberInput} from "@heroui/react";
export default function App() {
const placements = ["inside", "outside", "outside-left"];
const placements = ["inside", "outside", "outside-left", "outside-top"];
return (
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-8 md:grid md:grid-cols-2">
<div className="flex flex-col gap-4">
<h3 className="text-default-500 text-small">Without placeholder</h3>
<div className="flex w-full flex-wrap items-end md:flex-nowrap mb-6 md:mb-0 gap-4">
<div className="flex flex-col gap-4">
{placements.map((placement) => (
<NumberInput
key={placement}
@@ -18,9 +18,9 @@ export default function App() {
))}
</div>
</div>
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-4">
<h3 className="text-default-500 text-small">With placeholder</h3>
<div className="flex w-full flex-wrap items-end md:flex-nowrap mb-6 md:mb-0 gap-4">
<div className="flex flex-col gap-4">
{placements.map((placement) => (
<NumberInput
key={placement}
@@ -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()} />
@@ -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()} />
@@ -17,13 +17,13 @@ export const animals = [
];
export default function App() {
const placements = ["inside", "outside", "outside-left"];
const placements = ["inside", "outside", "outside-left", "outside-top"];
return (
<div className="w-full flex flex-col gap-4">
<div className="flex flex-col gap-2">
<div className="w-full grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="flex flex-col gap-4">
<h3 className="text-default-500 text-small">Without placeholder</h3>
<div className="flex w-full flex-wrap items-end md:flex-nowrap mb-6 md:mb-0 gap-4">
<div className="flex flex-col gap-4">
{placements.map((placement) => (
<Select
key={placement}
@@ -38,9 +38,9 @@ export default function App() {
))}
</div>
</div>
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-4">
<h3 className="text-default-500 text-small">With placeholder</h3>
<div className="flex w-full flex-wrap items-end md:flex-nowrap mb-6 md:mb-0 gap-4">
<div className="flex flex-col gap-4">
{placements.map((placement) => (
<Select
key={placement}
@@ -441,20 +441,18 @@ export default function App() {
);
case "actions":
return (
<div className="relative flex justify-end items-center gap-2">
<Dropdown className="bg-background border-1 border-default-200">
<DropdownTrigger>
<Button isIconOnly radius="full" size="sm" variant="light">
<VerticalDotsIcon className="text-default-400" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<Dropdown className="bg-background border-1 border-default-200">
<DropdownTrigger>
<Button isIconOnly radius="full" size="sm" variant="light">
<VerticalDotsIcon className="text-default-400" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
);
default:
return cellValue;
@@ -453,20 +453,18 @@ export default function App() {
);
case "actions":
return (
<div className="relative flex justify-end items-center gap-2">
<Dropdown className="bg-background border-1 border-default-200">
<DropdownTrigger>
<Button isIconOnly radius="full" size="sm" variant="light">
<VerticalDotsIcon className="text-default-400" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<Dropdown className="bg-background border-1 border-default-200">
<DropdownTrigger>
<Button isIconOnly radius="full" size="sm" variant="light">
<VerticalDotsIcon className="text-default-400" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
);
default:
return cellValue;
@@ -433,20 +433,18 @@ export default function App() {
);
case "actions":
return (
<div className="relative flex justify-end items-center gap-2">
<Dropdown>
<DropdownTrigger>
<Button isIconOnly size="sm" variant="light">
<VerticalDotsIcon className="text-default-300" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<Dropdown>
<DropdownTrigger>
<Button isIconOnly size="sm" variant="light">
<VerticalDotsIcon className="text-default-300" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
);
default:
return cellValue;
@@ -446,20 +446,18 @@ export default function App() {
);
case "actions":
return (
<div className="relative flex justify-end items-center gap-2">
<Dropdown>
<DropdownTrigger>
<Button isIconOnly size="sm" variant="light">
<VerticalDotsIcon className="text-default-300" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<Dropdown>
<DropdownTrigger>
<Button isIconOnly size="sm" variant="light">
<VerticalDotsIcon className="text-default-300" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownItem key="view">View</DropdownItem>
<DropdownItem key="edit">Edit</DropdownItem>
<DropdownItem key="delete">Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
);
default:
return cellValue;
@@ -1,4 +1,4 @@
import {Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@nextui-org/react";
import {Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@heroui/react";
function generateRows(count) {
return Array.from({length: count}, (_, index) => ({
@@ -1,4 +1,4 @@
import {Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@nextui-org/react";
import {Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@heroui/react";
function generateRows(count) {
return Array.from({length: count}, (_, index) => ({
@@ -1,4 +1,4 @@
import {Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@nextui-org/react";
import {Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@heroui/react";
function generateRows(count) {
return Array.from({length: count}, (_, index) => ({
@@ -1,4 +1,4 @@
import {Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@nextui-org/react";
import {Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@heroui/react";
function generateRows(count) {
return Array.from({length: count}, (_, index) => ({
@@ -22,6 +22,12 @@ export default function App() {
label="Event Time"
labelPlacement="outside-left"
/>
<TimeInput
defaultValue={new Time(11, 45)}
description="outside-top"
label="Event Time"
labelPlacement="outside-top"
/>
</div>
);
}
@@ -147,9 +147,9 @@ interface AppProviderProps {
`labelPlacement`
- **Description**: Determines the position where label should appear, such as inside, outside or outside-left of the component.
- **Description**: Determines the position where label should appear, such as inside, outside, outside-left or outside-top of the component.
- **Type**: `string` | `undefined`
- **Possible Values**: `inside` | `outside` | `outside-left` | `undefined`
- **Possible Values**: `inside` | `outside` | `outside-left` | `outside-top` | `undefined`
- **Default**: `undefined`
<Spacer y={2}/>
@@ -102,7 +102,7 @@ all available options, but users won't be able to select any of the listed optio
### Label Placements
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside` or `outside-left`.
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside`, `outside-left` or `outside-top`.
<CodeDemo
title="Label Placements"
@@ -542,7 +542,7 @@ properties to customize the popover, listbox and input components.
},
{
attribute: "labelPlacement",
type: "inside | outside | outside-left",
type: "inside | outside | outside-left | outside-top",
description: "The position of the label.",
default: "inside"
},
@@ -264,7 +264,7 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr
{
attribute: "defaultFocusedValue",
type: "DateValue",
description: "The date that is focused when the calendar first mounts (uncountrolled).",
description: "The date that is focused when the calendar first mounts (uncontrolled).",
default: "-"
},
{
@@ -60,7 +60,7 @@ Each part of a date value is displayed in an individually editable segment.
### Label Placements
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside` or `outside-left`.
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside`, `outside-left` or `outside-top`.
<CodeDemo title="Label Placements" files={dateInputContent.labelPlacements} />
@@ -104,9 +104,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0",
yarn: "yarn add @internationalized/date@3.10.0",
pnpm: "pnpm add @internationalized/date@3.10.0",
npm: "npm install @internationalized/date@3.10.1",
yarn: "yarn add @internationalized/date@3.10.1",
pnpm: "pnpm add @internationalized/date@3.10.1",
}}
/>
@@ -129,9 +129,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -153,9 +153,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0",
yarn: "yarn add @internationalized/date@3.10.0",
pnpm: "pnpm add @internationalized/date@3.10.0",
npm: "npm install @internationalized/date@3.10.1",
yarn: "yarn add @internationalized/date@3.10.1",
pnpm: "pnpm add @internationalized/date@3.10.1",
}}
/>
@@ -177,9 +177,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -200,9 +200,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0",
yarn: "yarn add @internationalized/date@3.10.0",
pnpm: "pnpm add @internationalized/date@3.10.0",
npm: "npm install @internationalized/date@3.10.1",
yarn: "yarn add @internationalized/date@3.10.1",
pnpm: "pnpm add @internationalized/date@3.10.1",
}}
/>
@@ -223,9 +223,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0",
yarn: "yarn add @internationalized/date@3.10.0",
pnpm: "pnpm add @internationalized/date@3.10.0",
npm: "npm install @internationalized/date@3.10.1",
yarn: "yarn add @internationalized/date@3.10.1",
pnpm: "pnpm add @internationalized/date@3.10.1",
}}
/>
@@ -370,7 +370,7 @@ import {parseZonedDateTime} from "@internationalized/date";
},
{
attribute: "labelPlacement",
type: "inside | outside | outside-left",
type: "inside | outside | outside-left | outside-top",
description: "The position of the label.",
default: "inside"
},
@@ -59,7 +59,7 @@ DatePickers combine a DateInput and a Calendar popover to allow users to enter o
### Label Placements
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside` or `outside-left`.
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside`, `outside-left` or `outside-top`.
<CodeDemo title="Label Placements" files={datePickerContent.labelPlacements} />
@@ -119,9 +119,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0",
yarn: "yarn add @internationalized/date@3.10.0",
pnpm: "pnpm add @internationalized/date@3.10.0",
npm: "npm install @internationalized/date@3.10.1",
yarn: "yarn add @internationalized/date@3.10.1",
pnpm: "pnpm add @internationalized/date@3.10.1",
}}
/>
@@ -144,9 +144,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -168,9 +168,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0",
yarn: "yarn add @internationalized/date@3.10.0",
pnpm: "pnpm add @internationalized/date@3.10.0",
npm: "npm install @internationalized/date@3.10.1",
yarn: "yarn add @internationalized/date@3.10.1",
pnpm: "pnpm add @internationalized/date@3.10.1",
}}
/>
@@ -192,9 +192,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -214,9 +214,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -252,9 +252,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -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: "-"
},
@@ -407,7 +407,7 @@ import {I18nProvider} from "@react-aria/i18n";
},
{
attribute: "labelPlacement",
type: "inside | outside | outside-left",
type: "inside | outside | outside-left | outside-top",
description: "The position of the label.",
default: "inside"
},
@@ -80,7 +80,7 @@ By default, when pressing the next or previous buttons, pagination will advance
### Label Placements
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside` or `outside-left`.
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside`, `outside-left` or `outside-top`.
<CodeDemo title="Label Placements" files={dateRangePickerContent.labelPlacements} />
@@ -142,9 +142,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0",
yarn: "yarn add @internationalized/date@3.10.0",
pnpm: "pnpm add @internationalized/date@3.10.0",
npm: "npm install @internationalized/date@3.10.1",
yarn: "yarn add @internationalized/date@3.10.1",
pnpm: "pnpm add @internationalized/date@3.10.1",
}}
/>
@@ -167,9 +167,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -191,9 +191,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0",
yarn: "yarn add @internationalized/date@3.10.0",
pnpm: "pnpm add @internationalized/date@3.10.0",
npm: "npm install @internationalized/date@3.10.1",
yarn: "yarn add @internationalized/date@3.10.1",
pnpm: "pnpm add @internationalized/date@3.10.1",
}}
/>
@@ -215,9 +215,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -237,9 +237,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -262,9 +262,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -273,7 +273,7 @@ import {today, isWeekend, getLocalTimeZone} from "@internationalized/date";
import {useLocale} from "@react-aria/i18n";
```
<CodeDemo title="Non Contiguous" files={dateRangePickerContent.nonContigous} />
<CodeDemo title="Non Contiguous" files={dateRangePickerContent.nonContiguous} />
### Presets
@@ -282,9 +282,9 @@ in multiple formats into `ZonedDateTime` objects.
<PackageManagers
commands={{
npm: "npm install @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
yarn: "yarn add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
pnpm: "pnpm add @internationalized/date@3.10.0 @react-aria/i18n@3.12.13",
npm: "npm install @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
yarn: "yarn add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
pnpm: "pnpm add @internationalized/date@3.10.1 @react-aria/i18n@3.12.14",
}}
/>
@@ -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: "-"
},
@@ -478,7 +478,7 @@ You can customize the `DateRangePicker` component by passing custom Tailwind CSS
},
{
attribute: "labelPlacement",
type: "inside | outside | outside-left",
type: "inside | outside | outside-left | outside-top",
description: "The position of the label.",
default: "inside"
},
+1 -1
View File
@@ -353,7 +353,7 @@ In case you need to customize the input even further, you can use the `useInput`
},
{
attribute: "labelPlacement",
type: "inside | outside | outside-left",
type: "inside | outside | outside-left | outside-top",
description: "The position of the label.",
default: "inside"
},
@@ -65,12 +65,16 @@ the end of the label and the input will be required.
### Label Placements
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside` or `outside-left`.
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside`, `outside-left` or `outside-top`.
<CodeDemo title="Label Placements" files={numberInputContent.labelPlacements} />
> **Note**: If the `label` is not passed, the `labelPlacement` property will be `outside` by default.
> **Note**: If the `labelPlacement` is `outside`, `label` is outside only when a placeholder is provided.
> **Note**: If the `labelPlacement` is `outside-top` or `outside-left`, `label` is outside even if a placeholder is not provided.
### Clear Button
If you pass the `isClearable` property to the input, it will have a clear button at the
@@ -116,7 +120,7 @@ You can set the maximum value of the input by passing the `maxValue` property.
### With Wheel Disabled
By default, you can increase or decrease the value with scroll wheel. You can disable changing the vaule with scroll in NumberInput by passing the `isWheelDisabled` property.
By default, you can increase or decrease the value with scroll wheel. You can disable changing the value with scroll in NumberInput by passing the `isWheelDisabled` property.
<CodeDemo title="With Wheel Disabled" files={numberInputContent.isWheelDisabled} />
@@ -373,7 +377,7 @@ You can customize the `NumberInput` component by passing custom Tailwind CSS cla
},
{
attribute: "labelPlacement",
type: "inside | outside | outside-left",
type: "inside | outside | outside-left | outside-top",
description: "The position of the label.",
default: "inside"
},
@@ -272,7 +272,7 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr
{
attribute: "defaultFocusedValue",
type: "DateValue",
description: "The date that is focused when the calendar first mounts (uncountrolled).",
description: "The date that is focused when the calendar first mounts (uncontrolled).",
default: "-"
},
{
+6 -2
View File
@@ -97,12 +97,16 @@ the end of the label and the select will be required.
### Label Placements
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside` or `outside-left`.
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside`, `outside-left` or `outside-top`.
<CodeDemo title="Label Placements" files={selectContent.labelPlacements} />
> **Note**: If the `label` is not passed, the `labelPlacement` property will be `outside` by default.
> **Note**: If the `labelPlacement` is `outside`, `label` is outside only when a placeholder is provided.
> **Note**: If the `labelPlacement` is `outside-top` or `outside-left`, `label` is outside even if a placeholder is not provided.
### Start Content
You can use the `startContent` properties to add content to the start of the select.
@@ -476,7 +480,7 @@ If you need to submit a specific `value` instead of the `key` during form submis
},
{
attribute: "labelPlacement",
type: "inside | outside | outside-left",
type: "inside | outside | outside-left | outside-top",
description: "The position of the label.",
default: "inside"
},
@@ -89,11 +89,13 @@ You can also pass an error message as a function. This allows for dynamic error
<CodeDemo title="With Error Message Function" files={timeInputContent.errorMessageFunction} />
### Label Placement
### Label Placements
The label's overall position relative to the element it is labeling.
You can change the position of the label by setting the `labelPlacement` property to `inside`, `outside`, `outside-left` or `outside-top`.
<CodeDemo title="Label Placement" files={timeInputContent.labelPlacement} />
<CodeDemo title="Label Placements" files={timeInputContent.labelPlacement} />
> **Note**: If the `label` is not passed, the `labelPlacement` property will be `outside` by default.
### Start Content
@@ -279,7 +281,7 @@ By default, `TimeInput` displays times in either 12 or 24 hour hour format depen
},
{
attribute: "labelPlacement",
type: "inside | outside | outside-left",
type: "inside | outside | outside-left | outside-top",
description: "The position of the label.",
default: "inside"
},
@@ -15,6 +15,8 @@ Requirements:
<CarbonAd/>
<DeprecationMessage />
To use HeroUI in your Astro project, you need to follow the following steps:
<Steps>
@@ -17,6 +17,8 @@ Requirements:
<CarbonAd/>
<DeprecationMessage />
To use HeroUI in your Laravel project, you need to follow the following steps:
### Using HeroUI + Laravel template
@@ -17,6 +17,8 @@ Requirements:
<CarbonAd/>
<DeprecationMessage />
To use HeroUI in your Next.js project, you need to follow the steps below, depending on your project structure.
## App Directory Setup
@@ -15,6 +15,8 @@ Requirements:
<CarbonAd/>
<DeprecationMessage />
To use HeroUI in your Remix project, you need to follow the following steps:
### Using HeroUI + Remix template
@@ -16,6 +16,8 @@ Requirements:
<CarbonAd/>
<DeprecationMessage />
To use HeroUI in your Vite project, you need to follow the following steps:
### HeroUI CLI (recommended)
+1 -1
View File
@@ -39,7 +39,7 @@ Most fields should have a visible label. In rare exceptions, the `aria-label` or
How you submit form data depends on your framework, application, and server. By default, **HTML** forms are submitted via a full-page refresh in the browser.
You can call `preventDefault` in the `onSubmit` event to handle form data submission via an API.
Frameworks like [Next.js](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#forms), [Remix](https://remix.run/docs/en/main/guides/forms), and [React Router](https://reactrouter.com/en/main/route/form-submission) provide their own ways to handle form submission.
Frameworks like [Next.js](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#forms), [Remix](https://v2.remix.run/docs/components/form), and [React Router](https://reactrouter.com/api/components/Form) provide their own ways to handle form submission.
#### Uncontrolled forms
@@ -15,6 +15,8 @@ Requirements:
<CarbonAd/>
<DeprecationMessage />
## Automatic Installation
Using the CLI is now the easiest way to start a HeroUI project. You can initialize your project and add components directly via the CLI:
+1 -1
View File
@@ -61,7 +61,7 @@ Update your main css file as below
#### With `tailwind.config.js`
In Tailwind v4, `tailwind.config.js` is still supported for backward compatibility. If you still need to use it, you can load it explicity as below.
In Tailwind v4, `tailwind.config.js` is still supported for backward compatibility. If you still need to use it, you can load it explicitly as below.
```diff-css
/* your main css file */
+3 -3
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}
>
+15 -16
View File
@@ -29,23 +29,22 @@
"@heroui/use-infinite-scroll": "workspace:*",
"@iconify/icons-solar": "1.2.3",
"@iconify/react": "5.0.2",
"@internationalized/date": "3.10.0",
"@internationalized/date": "3.10.1",
"@radix-ui/react-scroll-area": "^1.0.5",
"@react-aria/focus": "3.21.2",
"@react-aria/i18n": "3.12.13",
"@react-aria/interactions": "3.25.6",
"@react-aria/selection": "3.26.0",
"@react-aria/focus": "3.21.3",
"@react-aria/i18n": "3.12.14",
"@react-aria/interactions": "3.26.0",
"@react-aria/selection": "3.27.0",
"@react-aria/ssr": "3.9.10",
"@react-aria/utils": "3.31.0",
"@react-aria/visually-hidden": "3.8.28",
"@react-stately/data": "3.14.1",
"@react-stately/tree": "3.9.3",
"@react-aria/utils": "3.32.0",
"@react-aria/visually-hidden": "3.8.29",
"@react-stately/data": "3.15.0",
"@react-stately/tree": "3.9.4",
"@rehooks/local-storage": "^2.4.5",
"@stackblitz/sdk": "^1.11.0",
"@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",
@@ -58,11 +57,11 @@
"match-sorter": "8.0.0",
"mini-svg-data-uri": "1.4.4",
"mitt": "3.0.1",
"next": "15.3.1",
"next": "15.5.9",
"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",
@@ -81,8 +80,8 @@
"sharp": "^0.32.1",
"shelljs": "^0.8.4",
"swr": "2.2.5",
"tailwind-variants": "3.1.1",
"tailwind-merge": "3.3.1",
"tailwind-variants": "3.2.2",
"tailwind-merge": "3.4.0",
"unified": "^11.0.5",
"unist-util-visit": "5.0.0",
"usehooks-ts": "3.1.0",
@@ -91,8 +90,8 @@
},
"devDependencies": {
"@docusaurus/utils": "2.0.0-beta.3",
"@react-types/calendar": "3.8.0",
"@react-types/datepicker": "3.13.2",
"@react-types/calendar": "3.8.1",
"@react-types/datepicker": "3.13.3",
"@react-types/shared": "3.32.1",
"@tailwindcss/postcss": "4.1.11",
"@tailwindcss/typography": "0.5.16",
@@ -1,5 +1,39 @@
# @heroui/accordion
## 2.2.27
### Patch Changes
- [#6133](https://github.com/heroui-inc/heroui/pull/6133) [`96b1f49`](https://github.com/heroui-inc/heroui/commit/96b1f498cfa0630b18538901a12db349fb2aaad6) Thanks [@deepansh946](https://github.com/deepansh946)! - Fix newly created dynamic accordion items not responding to clicks (#5825)
- Updated dependencies []:
- @heroui/divider@2.2.22
- @heroui/aria-utils@2.2.27
- @heroui/framer-utils@2.1.26
## 2.2.26
### Patch Changes
- [#5996](https://github.com/heroui-inc/heroui/pull/5996) [`e07c969`](https://github.com/heroui-inc/heroui/commit/e07c969c4c6c1711ab153c273c2cacd0a79eef4b) Thanks [@wingkwong](https://github.com/wingkwong)! - upgrade react-aria (v1.14.0)
- Updated dependencies [[`e07c969`](https://github.com/heroui-inc/heroui/commit/e07c969c4c6c1711ab153c273c2cacd0a79eef4b)]:
- @heroui/use-aria-accordion@2.2.19
- @heroui/aria-utils@2.2.26
- @heroui/divider@2.2.21
- @heroui/framer-utils@2.1.25
## 2.2.25
### Patch Changes
- [#5930](https://github.com/heroui-inc/heroui/pull/5930) [`ecf2857`](https://github.com/heroui-inc/heroui/commit/ecf2857c90824409088130d12747fef3d47d9e99) Thanks [@wingkwong](https://github.com/wingkwong)! - bump tailwind-variants & tailwind-merge and use latest tv functions
- Updated dependencies [[`ecf2857`](https://github.com/heroui-inc/heroui/commit/ecf2857c90824409088130d12747fef3d47d9e99)]:
- @heroui/divider@2.2.21
- @heroui/aria-utils@2.2.25
- @heroui/framer-utils@2.1.24
## 2.2.24
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@heroui/accordion",
"version": "2.2.24",
"version": "2.2.27",
"description": "Collapse display a list of high-level options that can expand/collapse to reveal more information.",
"keywords": [
"react",
@@ -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.24",
"@heroui/system": ">=2.4.18"
},
"dependencies": {
@@ -55,9 +55,9 @@
"@heroui/divider": "workspace:*",
"@heroui/use-aria-accordion": "workspace:*",
"@heroui/dom-animation": "workspace:*",
"@react-aria/interactions": "3.25.6",
"@react-aria/focus": "3.21.2",
"@react-stately/tree": "3.9.3",
"@react-aria/interactions": "3.26.0",
"@react-aria/focus": "3.21.3",
"@react-stately/tree": "3.9.4",
"@react-types/accordion": "3.0.0-alpha.26",
"@react-types/shared": "3.32.1"
},
@@ -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 = {}) => {
@@ -210,6 +210,7 @@ export function useAccordion<T extends object>(props: UseAccordionProps<T>) {
disableIndicatorAnimation,
state.expandedKeys.size,
state.disabledKeys.size,
state.collection,
motionProps,
],
);
+25
View File
@@ -1,5 +1,30 @@
# @heroui/alert
## 2.2.30
### Patch Changes
- Updated dependencies []:
- @heroui/button@2.2.30
## 2.2.29
### Patch Changes
- [#5996](https://github.com/heroui-inc/heroui/pull/5996) [`e07c969`](https://github.com/heroui-inc/heroui/commit/e07c969c4c6c1711ab153c273c2cacd0a79eef4b) Thanks [@wingkwong](https://github.com/wingkwong)! - upgrade react-aria (v1.14.0)
- Updated dependencies [[`e07c969`](https://github.com/heroui-inc/heroui/commit/e07c969c4c6c1711ab153c273c2cacd0a79eef4b)]:
- @heroui/button@2.2.29
## 2.2.28
### Patch Changes
- [#5930](https://github.com/heroui-inc/heroui/pull/5930) [`ecf2857`](https://github.com/heroui-inc/heroui/commit/ecf2857c90824409088130d12747fef3d47d9e99) Thanks [@wingkwong](https://github.com/wingkwong)! - bump tailwind-variants & tailwind-merge and use latest tv functions
- Updated dependencies [[`fd9dd2a`](https://github.com/heroui-inc/heroui/commit/fd9dd2a20c30beb4f46a8a6ab5d654ec7b9dbec1), [`ecf2857`](https://github.com/heroui-inc/heroui/commit/ecf2857c90824409088130d12747fef3d47d9e99)]:
- @heroui/button@2.2.28
## 2.2.27
### Patch Changes

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