Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 15a4d783bf | |||
| 8ab40003aa | |||
| 17a3f16992 | |||
| 34d44335cd | |||
| 8b010373f2 | |||
| 2ccc89ed1c | |||
| 3c7231a837 | |||
| e7cf794f31 | |||
| e0649e12bc | |||
| 62ea97055b | |||
| 9f74710ae5 | |||
| c2252c2bd4 | |||
| 46e1f1f78e | |||
| bd476eec11 | |||
| 29f5837def | |||
| 499cae095d | |||
| 7175182244 | |||
| 7437888182 | |||
| 2db2ac726a | |||
| 66d29cff0f | |||
| 87fe3819e6 | |||
| b88758a76f | |||
| 3adfef7466 | |||
| 2a604c4461 | |||
| c92543ba79 | |||
| 4ac203c63f | |||
| e1b34537eb | |||
| 35e2138b0f | |||
| a252e72210 | |||
| f37e108588 | |||
| 63c12e5359 | |||
| 1a2635beda | |||
| 7814df7cea | |||
| 5549167041 | |||
| 96b1f498cf | |||
| 3933b347b7 | |||
| 4add7525a0 | |||
| d5a5c77ed6 | |||
| 1f085061ed | |||
| df6610cd98 | |||
| 5ec842b1cf | |||
| 65702817c2 | |||
| 436e0d8278 | |||
| 2d693f732c | |||
| d5131d77a3 | |||
| 086f6a1c44 | |||
| e07c969c4c | |||
| 090b151a5b | |||
| acc74d1e8f | |||
| 41fc673586 | |||
| c76c68ad7e | |||
| 2148a2ee3b | |||
| 53e27bb6f8 | |||
| 467b497156 | |||
| 799bc5bab8 | |||
| a37912e17f | |||
| 4c435348ec | |||
| 8d07922c68 | |||
| ecf2857c90 | |||
| a81212d6e7 | |||
| a7655ad2c9 | |||
| b89ba08ae0 | |||
| f08dfb8dd9 | |||
| 0f165a36c8 | |||
| 9520b3f850 | |||
| ecad199b09 | |||
| a819f2a95a | |||
| b4cfb408e9 | |||
| 66ef76e823 | |||
| 0825f88cd2 | |||
| ce0c298785 | |||
| 4fa54534b2 | |||
| 4e3098a512 | |||
| 484212712c | |||
| 217e88d58e | |||
| 8b2ec9fa46 | |||
| 5d9a05be01 | |||
| bc4c982609 | |||
| 8921dc4361 | |||
| fd9dd2a20c | |||
| 91e010fe3b | |||
| 0bf225abf5 | |||
| 83b8fc1e7c | |||
| 0344123c13 | |||
| 6a3b02773d | |||
| bdd37b4b08 | |||
| 27fec2db3c | |||
| 1782961859 | |||
| 680b68bc83 | |||
| 328c57d8ea | |||
| 2922b35644 | |||
| b38a2cfb58 | |||
| acd5f1dfb5 | |||
| 37378704f1 | |||
| ed76faacd4 | |||
| 812f7939d9 | |||
| 1f17962932 | |||
| 6eba109a7f | |||
| 7537226b54 | |||
| 136bdf66b1 | |||
| 736293b8a6 | |||
| f13c6875db | |||
| 0d95d7faa0 | |||
| 7b7190e222 | |||
| c3224113de | |||
| 7c215f289e | |||
| a88f98a14b |
@@ -1,8 +0,0 @@
|
||||
# Changesets
|
||||
|
||||
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
||||
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
||||
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
||||
|
||||
We have a quick list of common questions to get you started engaging with this project in
|
||||
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
|
||||
"changelog": [
|
||||
"@changesets/changelog-github",
|
||||
{ "repo": "heroui-inc/heroui" }
|
||||
],
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "canary",
|
||||
"updateInternalDependencies": "patch",
|
||||
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
|
||||
"onlyUpdatePeerDependentsWhenOutOfRange": true
|
||||
},
|
||||
"ignore": [
|
||||
"@heroui/docs",
|
||||
"@heroui/storybook"
|
||||
]
|
||||
}
|
||||
@@ -10,11 +10,9 @@ reviews:
|
||||
ignore_title_keywords:
|
||||
- "WIP"
|
||||
- "DO NOT MERGE"
|
||||
- 'ci(changesets)'
|
||||
drafts: false
|
||||
base_branches:
|
||||
- "main"
|
||||
- "canary"
|
||||
- "fix/.*"
|
||||
- "chore/.*"
|
||||
- "feat/.*"
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
name: Enter pre-release mode
|
||||
|
||||
on: workflow_dispatch
|
||||
jobs:
|
||||
enter-pre-release-mode:
|
||||
if: ${{ github.ref == 'refs/heads/beta/release-next' || github.ref == 'refs/heads/canary' }}
|
||||
runs-on: heroui-runner
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install
|
||||
uses: ./.github/common-actions/install
|
||||
|
||||
- name: Enter pre-release mode
|
||||
id: enter-pre-release-mode
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GA_ACCESS_TOKEN }}
|
||||
run: |
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config user.name "github-actions[bot]"
|
||||
if [ ${{ github.ref }} == 'refs/heads/canary' ]; then
|
||||
pnpm changeset:canary
|
||||
else
|
||||
pnpm changeset:beta
|
||||
fi
|
||||
git add -A
|
||||
git commit -m 'chore(pre-release): enter pre-release mode'
|
||||
git push
|
||||
@@ -1,39 +0,0 @@
|
||||
name: Exit pre-release mode
|
||||
|
||||
on: workflow_dispatch
|
||||
jobs:
|
||||
exit-pre-release-mode:
|
||||
if: ${{ github.ref == 'refs/heads/beta/release-next' || github.ref == 'refs/heads/canary' }}
|
||||
name: exit pre-release mode
|
||||
runs-on: heroui-runner
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.branch }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install
|
||||
uses: ./.github/common-actions/install
|
||||
|
||||
- name: remove pre.json
|
||||
# we only remove .changeset/pre.json here
|
||||
# since we want to keep the changeset files introduced in beta/release-next or canary branch
|
||||
# once we merge it to canary / main, those files will be removed in version PR in canary
|
||||
# and converted to corresponding changelogs
|
||||
run: npx rimraf .changeset/pre.json
|
||||
|
||||
- name: Commit and push changes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GA_ACCESS_TOKEN }}
|
||||
run: |
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config user.name "github-actions[bot]"
|
||||
git add -A
|
||||
git commit -m "ci(changesets): exit pre-release mode"
|
||||
git push
|
||||
@@ -1,81 +0,0 @@
|
||||
name: Pre-release
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".changeset/**"
|
||||
- "packages/**"
|
||||
branches:
|
||||
- "beta/release-next"
|
||||
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
prerelease:
|
||||
name: changesets pre-release
|
||||
runs-on: heroui-runner
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install
|
||||
uses: ./.github/common-actions/install
|
||||
|
||||
- name: Check if pre.json exists
|
||||
id: check_if_pre_json_exists
|
||||
uses: andstor/file-existence-action@v3.0.0
|
||||
with:
|
||||
files: ".changeset/pre.json"
|
||||
|
||||
- name: Debug condition values
|
||||
run: |
|
||||
echo "pre.json exists: ${{ steps.check_if_pre_json_exists.outputs.files_exists }}"
|
||||
echo "Commit message: ${{ github.event.head_commit.message }}"
|
||||
echo "Contains version packages: ${{ contains(github.event.head_commit.message, 'ci(changesets): version packages') }}"
|
||||
echo "Full condition would be: ${{ steps.check_if_pre_json_exists.outputs.files_exists == 'true' && contains(github.event.head_commit.message, 'ci(changesets): version packages') }}"
|
||||
|
||||
- name: Get pre-release changesets
|
||||
id: get-pre-release-changesets
|
||||
uses: notiz-dev/github-action-json-property@release
|
||||
with:
|
||||
path: ".changeset/pre.json"
|
||||
prop_path: "changesets"
|
||||
|
||||
- name: Create pre-release PR
|
||||
id: create-pre-release-pr
|
||||
if: "${{ steps.check_if_pre_json_exists.outputs.files_exists == 'true' && !startsWith(github.event.head_commit.message, 'ci(changesets): version packages') }}"
|
||||
uses: changesets/action@v1
|
||||
with:
|
||||
version: pnpm run version
|
||||
title: "ci(changesets): :package: version packages"
|
||||
commit: "ci(changesets): version packages"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Tests
|
||||
if: "${{ steps.check_if_pre_json_exists.outputs.files_exists == 'true' && contains(github.event.head_commit.message, 'ci(changesets): version packages') }}"
|
||||
run: pnpm test
|
||||
|
||||
- name: Build
|
||||
if: "${{ steps.check_if_pre_json_exists.outputs.files_exists == 'true' && contains(github.event.head_commit.message, 'ci(changesets): version packages') }}"
|
||||
run: pnpm build
|
||||
env:
|
||||
NODE_OPTIONS: "--max-old-space-size=4096"
|
||||
|
||||
- name: Publish to NPM
|
||||
id: publish-to-npm
|
||||
if: "${{ steps.check_if_pre_json_exists.outputs.files_exists == 'true' && contains(github.event.head_commit.message, 'ci(changesets): version packages') }}"
|
||||
uses: changesets/action@v1
|
||||
with:
|
||||
publish: pnpm run release
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,63 +0,0 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".changeset/**"
|
||||
- "packages/**"
|
||||
branches:
|
||||
- canary
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: heroui-runner
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install
|
||||
uses: ./.github/common-actions/install
|
||||
|
||||
- name: Tests
|
||||
run: pnpm test
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
continue-on-error: false
|
||||
# Custom turbo build failure information
|
||||
run: |
|
||||
pnpm build || {
|
||||
echo "Turbo build failed with exit code $?"
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Create Release Pull Request or Publish to NPM
|
||||
# Run only if the build is successful
|
||||
if: steps.build.outcome == 'success'
|
||||
id: changesets
|
||||
uses: changesets/action@v1
|
||||
with:
|
||||
publish: pnpm release
|
||||
title: "ci(changesets): :package: version packages"
|
||||
commit: "ci(changesets): version packages"
|
||||
setupGitUser: false
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create canary release
|
||||
if: steps.build.outcome == 'success' && steps.changesets.outputs.published != 'true'
|
||||
timeout-minutes: 15
|
||||
run: |
|
||||
git checkout canary
|
||||
pnpm version:canary
|
||||
pnpm release:canary
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,51 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "@heroui/**"
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish
|
||||
if: github.repository == 'heroui-inc/heroui'
|
||||
runs-on: ubuntu-latest
|
||||
environment: npm-publish
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install
|
||||
uses: ./.github/common-actions/install
|
||||
|
||||
- name: Parse tag
|
||||
id: tag
|
||||
shell: bash
|
||||
run: |
|
||||
REF="${GITHUB_REF_NAME}"
|
||||
# tag format: @scope/name@version -> split on the LAST "@"
|
||||
PKG_NAME="${REF%@*}"
|
||||
PKG_VERSION="${REF##*@}"
|
||||
|
||||
echo "name=$PKG_NAME" >> "$GITHUB_OUTPUT"
|
||||
echo "version=$PKG_VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "Publishing $PKG_NAME@$PKG_VERSION"
|
||||
|
||||
- name: Build packages
|
||||
run: pnpm --filter "${{ steps.tag.outputs.name }}" build
|
||||
|
||||
- name: Ensure npm supports trusted publishing
|
||||
run: npm install -g npm@11
|
||||
|
||||
- name: Publish to npm
|
||||
run: pnpm --filter "${{ steps.tag.outputs.name }}" publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -2,7 +2,6 @@ dist
|
||||
node_modules
|
||||
plop
|
||||
coverage
|
||||
.changeset
|
||||
.next
|
||||
build
|
||||
scripts
|
||||
|
||||
+5
-15
@@ -19,8 +19,7 @@ Hello!, I am very excited that you are interested in contributing with HeroUI. H
|
||||
testing
|
||||
- [Testing Library](https://testing-library.com/) for testing components and
|
||||
hooks
|
||||
- [Changeset](https://github.com/atlassian/changesets) for changes
|
||||
documentation, changelog generation, and release management.
|
||||
- [bumpp](https://github.com/antfu/bumpp) for version bumping and release management.
|
||||
|
||||
|
||||
### Commit Convention
|
||||
@@ -85,19 +84,10 @@ https://www.conventionalcommits.org/ or check out the
|
||||
|
||||
> To know more about the `--filter` option, please check the turborepo [docs](https://turborepo.org/docs/core-concepts/filtering).
|
||||
|
||||
4. Run `pnpm changeset` to create a detailed description of your changes. This
|
||||
will be used to generate a changelog when we publish an update.
|
||||
[Learn more about Changeset](https://github.com/atlassian/changesets/tree/master/packages/cli).
|
||||
Please note that you might have to run `git fetch origin main:master` (where
|
||||
origin will be your fork on GitHub) before `pnpm changeset` works.
|
||||
5. Also, if you provide `jsx` snippets to the changeset, please turn off the
|
||||
live preview by doing the following at the beginning of the snippet:
|
||||
` ```jsx live=false`
|
||||
|
||||
> If you made minor changes like CI config, prettier, etc, you can run
|
||||
> `pnpm changeset add --empty` to generate an empty changeset file to document
|
||||
> your changes.
|
||||
|
||||
4. Version bumping is handled by maintainers using `pnpm version:bump` which
|
||||
uses [bumpp](https://github.com/antfu/bumpp) to interactively bump the
|
||||
version, create a git commit, and push a tag that triggers the release CI.
|
||||
|
||||
## Development Setup
|
||||
|
||||
After cloning the repository, execute the following commands in the root folder:
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
@@ -35,7 +35,7 @@ const animals = [
|
||||
];
|
||||
|
||||
type FieldState = {
|
||||
selectedKey: React.Key | null;
|
||||
value: React.Key | null;
|
||||
inputValue: string;
|
||||
items: typeof animals;
|
||||
};
|
||||
@@ -44,7 +44,7 @@ export default function Page() {
|
||||
// Store ComboBox input value, selected option, open state, and items
|
||||
// in a state tracker
|
||||
const [fieldState, setFieldState] = React.useState<FieldState>({
|
||||
selectedKey: "",
|
||||
value: "",
|
||||
inputValue: "",
|
||||
items: animals,
|
||||
});
|
||||
@@ -55,13 +55,13 @@ export default function Page() {
|
||||
|
||||
// Specify how each of the Autocomplete values should change when an
|
||||
// option is selected from the list box
|
||||
const onSelectionChange = (key: React.Key | null) => {
|
||||
const onChange = (key: React.Key | null) => {
|
||||
setFieldState((prevState) => {
|
||||
let selectedItem = prevState.items.find((option) => option.value === key);
|
||||
|
||||
return {
|
||||
inputValue: selectedItem?.label || "",
|
||||
selectedKey: key,
|
||||
value: key,
|
||||
items: animals.filter((item) => startsWith(item.label, selectedItem?.label || "")),
|
||||
};
|
||||
});
|
||||
@@ -72,7 +72,7 @@ export default function Page() {
|
||||
const onInputChange = (value: string) => {
|
||||
setFieldState((prevState) => ({
|
||||
inputValue: value,
|
||||
selectedKey: value === "" ? null : prevState.selectedKey,
|
||||
value: value === "" ? null : prevState.value,
|
||||
items: animals.filter((item) => startsWith(item.label, value)),
|
||||
}));
|
||||
};
|
||||
@@ -82,7 +82,7 @@ export default function Page() {
|
||||
if (menuTrigger === "manual" && isOpen) {
|
||||
setFieldState((prevState) => ({
|
||||
inputValue: prevState.inputValue,
|
||||
selectedKey: prevState.selectedKey,
|
||||
value: prevState.value,
|
||||
items: animals,
|
||||
}));
|
||||
}
|
||||
@@ -96,11 +96,11 @@ export default function Page() {
|
||||
items={fieldState.items}
|
||||
label="Favorite Animal"
|
||||
placeholder="Select an animal"
|
||||
selectedKey={fieldState.selectedKey}
|
||||
value={fieldState.value}
|
||||
variant="bordered"
|
||||
onChange={onChange}
|
||||
onInputChange={onInputChange}
|
||||
onOpenChange={onOpenChange}
|
||||
onSelectionChange={onSelectionChange}
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.value}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,6 @@ 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";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
@@ -52,9 +51,9 @@ export const metadata: Metadata = {
|
||||
],
|
||||
creator: "heroui-inc",
|
||||
alternates: {
|
||||
canonical: "https://heroui.com",
|
||||
canonical: "https://v2.heroui.com",
|
||||
types: {
|
||||
"application/rss+xml": [{url: "https://heroui.com/feed.xml", title: "HeroUI RSS Feed"}],
|
||||
"application/rss+xml": [{url: "https://v2.heroui.com/feed.xml", title: "HeroUI RSS Feed"}],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -75,7 +74,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 +82,6 @@ export default function RootLayout({children}: {children: React.ReactNode}) {
|
||||
>
|
||||
<Providers themeProps={{attribute: "class", defaultTheme: "dark"}}>
|
||||
<div className="relative flex flex-col" id="app-container">
|
||||
<RandomBanner />
|
||||
<Navbar mobileRoutes={manifest.mobileRoutes} routes={manifest.routes} />
|
||||
{children}
|
||||
<Analytics mode="production" />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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))]",
|
||||
)}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
)}
|
||||
|
||||
@@ -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.9.0",
|
||||
"@react-aria/i18n": "3.12.12",
|
||||
"@internationalized/date": "3.12.2",
|
||||
"@react-aria/i18n": "3.13.1",
|
||||
};
|
||||
|
||||
@@ -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,15 @@
|
||||
"use client";
|
||||
|
||||
import {Blockquote} from "./components/blockquote";
|
||||
|
||||
export const DeprecationMessage = () => {
|
||||
return (
|
||||
<Blockquote color="warning">
|
||||
<b>HeroUI v3 is here!</b> We recommend starting new projects with{" "}
|
||||
<a className="underline" href="https://heroui.com/" rel="noopener noreferrer" target="_blank">
|
||||
<b>HeroUI v3</b>
|
||||
</a>
|
||||
. v2 will continue to receive patches and critical fixes.
|
||||
</Blockquote>
|
||||
);
|
||||
};
|
||||
@@ -2,3 +2,4 @@ export * from "./sidebar";
|
||||
export * from "./toc";
|
||||
export * from "./pager";
|
||||
export * from "./components/code-demo";
|
||||
export * from "./deprecation-message";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -4,13 +4,11 @@ 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";
|
||||
|
||||
import {HeroUIProCallout} from "./heroui-pro-callout";
|
||||
|
||||
import {useScrollSpy} from "@/hooks/use-scroll-spy";
|
||||
import {useScrollPosition} from "@/hooks/use-scroll-position";
|
||||
import emitter from "@/libs/emitter";
|
||||
@@ -69,7 +67,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 +84,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-['']",
|
||||
@@ -126,7 +125,6 @@ export const DocsToc: FC<DocsTocProps> = ({headings}) => {
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<HeroUIProCallout />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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')]",
|
||||
|
||||
@@ -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
|
||||
<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 is here!",
|
||||
href: "https://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')]",
|
||||
|
||||
@@ -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} />,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import type {FC, ReactNode} from "react";
|
||||
import type {FC, Key, ReactNode} from "react";
|
||||
import type {Route} from "@/libs/docs/page";
|
||||
|
||||
import {useRef, useState, useMemo, useCallback} from "react";
|
||||
@@ -15,12 +15,16 @@ import {
|
||||
Link,
|
||||
Button,
|
||||
Kbd,
|
||||
Chip,
|
||||
Dropdown,
|
||||
DropdownMenu,
|
||||
DropdownItem,
|
||||
DropdownTrigger,
|
||||
Divider,
|
||||
} from "@heroui/react";
|
||||
import {dataFocusVisibleClasses} from "@heroui/theme";
|
||||
import {ChevronDownIcon, LinkIcon} from "@heroui/shared-icons";
|
||||
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";
|
||||
@@ -29,8 +33,6 @@ import {usePress} from "@react-aria/interactions";
|
||||
import {useFocusRing} from "@react-aria/focus";
|
||||
import {usePostHog} from "posthog-js/react";
|
||||
|
||||
import {FbRoadmapLink} from "./featurebase/fb-roadmap-link";
|
||||
|
||||
import {currentVersion} from "@/utils/version";
|
||||
import {siteConfig} from "@/config/site";
|
||||
import {Logo, ThemeSwitch} from "@/components";
|
||||
@@ -91,11 +93,23 @@ 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",
|
||||
);
|
||||
|
||||
const handleVersionChange = useCallback((key: Key) => {
|
||||
if (key === "v3") {
|
||||
const newWindow = window.open(
|
||||
"https://v3.heroui.com?ref=heroui-v2",
|
||||
"_blank",
|
||||
"noopener,noreferrer",
|
||||
);
|
||||
|
||||
if (newWindow) newWindow.opener = null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handlePressNavbarItem = useCallback(
|
||||
(name: string, url: string) => {
|
||||
posthog.capture("NavbarItem", {
|
||||
@@ -134,24 +148,40 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
|
||||
</Button>
|
||||
);
|
||||
|
||||
const versionChip = useMemo(() => {
|
||||
const versionDropdown = useMemo(() => {
|
||||
return ref.current ? (
|
||||
<AnimatePresence>
|
||||
{isMounted && (
|
||||
<motion.div animate={{opacity: 1}} exit={{opacity: 0}} initial={{opacity: 0}}>
|
||||
<Chip
|
||||
className="max-w-[44px] hidden h-6 w-[44px] py-1 min-w-fit sm:flex gap-0.5 bg-default-400/20 dark:bg-default-500/20"
|
||||
classNames={{
|
||||
content: "font-medium text-default-500 text-xs",
|
||||
}}
|
||||
>
|
||||
v{currentVersion}
|
||||
</Chip>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
<Dropdown placement="bottom-start" portalContainer={ref.current}>
|
||||
<AnimatePresence>
|
||||
{isMounted && (
|
||||
<motion.div animate={{opacity: 1}} exit={{opacity: 0}} initial={{opacity: 0}}>
|
||||
<DropdownTrigger>
|
||||
<Button
|
||||
className="min-w-[74px] max-w-[74px] hidden font-medium text-default-500 text-xs h-6 w-[74px] py-1 min-w-fit sm:flex gap-0.5 bg-default-400/20 dark:bg-default-500/20"
|
||||
endContent={<ChevronDownIcon className="text-tiny" />}
|
||||
radius="full"
|
||||
size="sm"
|
||||
variant="flat"
|
||||
>
|
||||
v{currentVersion}
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
<DropdownMenu
|
||||
aria-label="HeroUI versions"
|
||||
defaultSelectedKeys={["v2"]}
|
||||
selectionMode="single"
|
||||
onAction={handleVersionChange}
|
||||
>
|
||||
<DropdownItem key="v2">v{currentVersion}</DropdownItem>
|
||||
<DropdownItem key="v3" endContent={<LinkIcon />}>
|
||||
v3.0.0
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
) : (
|
||||
<div className="w-[44px]" />
|
||||
<div className="w-[74px]" />
|
||||
);
|
||||
}, [ref.current, isMounted]);
|
||||
|
||||
@@ -162,7 +192,7 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
|
||||
return (
|
||||
<HeroUINavbar
|
||||
ref={ref}
|
||||
className={clsx({
|
||||
className={cn({
|
||||
"z-100001": isMenuOpen,
|
||||
})}
|
||||
classNames={{
|
||||
@@ -184,8 +214,8 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
|
||||
>
|
||||
<Logo className="h-6" />
|
||||
</NextLink>
|
||||
{versionChip}
|
||||
<Chip
|
||||
{versionDropdown}
|
||||
{/* <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 +230,7 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
|
||||
<span aria-label="emoji" role="img">
|
||||
🔥
|
||||
</span>
|
||||
</Chip>
|
||||
</Chip> */}
|
||||
</NavbarBrand>
|
||||
</NavbarContent>
|
||||
|
||||
@@ -225,7 +255,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,
|
||||
@@ -269,7 +299,7 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
|
||||
Components
|
||||
</NextLink>
|
||||
</NavbarItem>
|
||||
{/*
|
||||
{/*
|
||||
// TODO: add playground
|
||||
<NavbarItem>
|
||||
<NextLink
|
||||
@@ -316,9 +346,6 @@ export const Navbar: FC<NavbarProps> = ({children, routes, mobileRoutes = [], sl
|
||||
Theme
|
||||
</NextLink>
|
||||
</NavbarItem>
|
||||
<NavbarItem>
|
||||
<FbRoadmapLink className={navLinkClasses} />
|
||||
</NavbarItem>
|
||||
</ul>
|
||||
<Divider className="h-7 hidden lg:flex" orientation="vertical" />
|
||||
<NavbarItem className="hidden sm:flex gap-2">
|
||||
|
||||
@@ -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,
|
||||
)}
|
||||
|
||||
@@ -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,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={{
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"stars": { "raw": 24951, "formatted": "25K" },
|
||||
"forks": 1852,
|
||||
"subscribers": 90,
|
||||
"openIssues": 242
|
||||
"stars": { "raw": 29656, "formatted": "29.7K" },
|
||||
"forks": 2163,
|
||||
"subscribers": 89,
|
||||
"openIssues": 41
|
||||
}
|
||||
|
||||
@@ -473,7 +473,8 @@
|
||||
"key": "cli-api",
|
||||
"title": "HeroUI CLI",
|
||||
"keywords": "api references, heroui, api, cli",
|
||||
"path": "/docs/api-references/cli-api.mdx"
|
||||
"path": "/docs/api-references/cli-api.mdx",
|
||||
"updated": true
|
||||
},
|
||||
{
|
||||
"key": "heroui-provider",
|
||||
@@ -514,12 +515,6 @@
|
||||
"title": "Figma",
|
||||
"keywords": "figma, heroui, design, ui kit",
|
||||
"path": "/docs/guide/figma.mdx"
|
||||
},
|
||||
{
|
||||
"key": "roadmap",
|
||||
"title": "Roadmap",
|
||||
"keywords": "roadmap, heroui",
|
||||
"path": "#"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+1410
-1403
File diff suppressed because it is too large
Load Diff
@@ -3,20 +3,20 @@ export type SiteConfig = typeof siteConfig;
|
||||
export const siteConfig = {
|
||||
name: "HeroUI (Previously NextUI) - Beautiful, fast and modern React UI Library",
|
||||
description: "Make beautiful websites regardless of your design experience.",
|
||||
ogImage: "https://heroui.com/heroui.jpg",
|
||||
ogImage: "https://v2.heroui.com/heroui.jpg",
|
||||
author: "Junior Garcia",
|
||||
email: "jrgarciadev@gmail.com",
|
||||
siteUrl: "https://heroui.com",
|
||||
siteUrl: "https://v2.heroui.com",
|
||||
creator: "@hero_ui",
|
||||
openGraph: {
|
||||
type: "website",
|
||||
locale: "en_US",
|
||||
url: "https://heroui.com",
|
||||
url: "https://v2.heroui.com",
|
||||
siteName: "HeroUI (Previously NextUI)",
|
||||
description: "Beautiful, fast and modern React UI Library",
|
||||
images: [
|
||||
{
|
||||
url: "https://heroui.com/heroui.jpg",
|
||||
url: "https://v2.heroui.com/heroui.jpg",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "HeroUI (Previously NextUI)",
|
||||
@@ -27,13 +27,13 @@ export const siteConfig = {
|
||||
card: "summary_large_image",
|
||||
title: "HeroUI (Previously NextUI) - Beautiful, fast and modern React UI Library",
|
||||
description: "Make beautiful websites regardless of your design experience.",
|
||||
image: "https://heroui.com/heroui.jpg",
|
||||
image: "https://v2.heroui.com/heroui.jpg",
|
||||
creator: "@hero_ui",
|
||||
},
|
||||
links: {
|
||||
github: "https://github.com/heroui-inc/heroui",
|
||||
twitter: "https://x.com/hero_ui",
|
||||
docs: "https://heroui.com",
|
||||
docs: "https://v2.heroui.com",
|
||||
discord: "https://discord.gg/9b6yyZKmH4",
|
||||
sponsor: "https://patreon.com/jrgarciadev",
|
||||
portfolio: "https://jrgarciadev.com",
|
||||
|
||||
@@ -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).
|
||||
|
||||
|
||||
@@ -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,23 +29,24 @@ export const animals = [
|
||||
];
|
||||
|
||||
export default function App() {
|
||||
const colors = ["default", "primary", "secondary", "success", "warning", "danger"];
|
||||
const [value, setValue] = React.useState("cat");
|
||||
|
||||
const onChange = (key) => {
|
||||
setValue(key);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-row flex-wrap gap-4">
|
||||
{colors.map((color) => (
|
||||
<Autocomplete
|
||||
key={color}
|
||||
className="max-w-xs"
|
||||
color={color}
|
||||
defaultItems={animals}
|
||||
defaultSelectedKey={"cat"}
|
||||
label="Favorite Animal"
|
||||
placeholder="Search an animal"
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.key}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
))}
|
||||
<div className="flex w-full max-w-xs flex-col gap-2">
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
defaultItems={animals}
|
||||
label="Favorite Animal"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.key}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
<p className="text-default-500">Selected: {value}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export default function App() {
|
||||
placeholder="Search an animal"
|
||||
selectedKey={key}
|
||||
variant="bordered"
|
||||
onSelectionChange={setValue}
|
||||
onChange={setValue}
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.key}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
|
||||
@@ -45,8 +45,8 @@ export default function App() {
|
||||
placeholder="Search an animal"
|
||||
selectedKey={key}
|
||||
variant="bordered"
|
||||
onChange={setValue}
|
||||
onClose={() => setTouched(true)}
|
||||
onSelectionChange={setValue}
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.key}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function App() {
|
||||
const [value, setValue] = React.useState("");
|
||||
const [selectedKey, setSelectedKey] = React.useState(null);
|
||||
|
||||
const onSelectionChange = (id) => {
|
||||
const onChange = (id) => {
|
||||
setSelectedKey(id);
|
||||
};
|
||||
|
||||
@@ -48,8 +48,8 @@ export default function App() {
|
||||
defaultItems={animals}
|
||||
label="Search an animal"
|
||||
variant="bordered"
|
||||
onChange={onChange}
|
||||
onInputChange={onInputChange}
|
||||
onSelectionChange={onSelectionChange}
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.key}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function App() {
|
||||
const [value, setValue] = React.useState<string>("");
|
||||
const [selectedKey, setSelectedKey] = React.useState<React.Key | null>(null);
|
||||
|
||||
const onSelectionChange = (key: React.Key | null) => {
|
||||
const onChange = (key: React.Key | null) => {
|
||||
setSelectedKey(key);
|
||||
};
|
||||
|
||||
@@ -49,8 +49,8 @@ export default function App() {
|
||||
defaultItems={animals}
|
||||
label="Search an animal"
|
||||
variant="underlined"
|
||||
onChange={onChange}
|
||||
onInputChange={onInputChange}
|
||||
onSelectionChange={onSelectionChange}
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.key}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
|
||||
@@ -44,7 +44,7 @@ export default function App() {
|
||||
|
||||
// Specify how each of the Autocomplete values should change when an
|
||||
// option is selected from the list box
|
||||
const onSelectionChange = (key) => {
|
||||
const onChange = (key) => {
|
||||
setFieldState((prevState) => {
|
||||
let selectedItem = prevState.items.find((option) => option.value === key);
|
||||
|
||||
@@ -86,9 +86,9 @@ export default function App() {
|
||||
placeholder="Search an animal"
|
||||
selectedKey={fieldState.selectedKey}
|
||||
variant="bordered"
|
||||
onChange={onChange}
|
||||
onInputChange={onInputChange}
|
||||
onOpenChange={onOpenChange}
|
||||
onSelectionChange={onSelectionChange}
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.key}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
|
||||
@@ -53,7 +53,7 @@ export default function App() {
|
||||
|
||||
// Specify how each of the Autocomplete values should change when an
|
||||
// option is selected from the list box
|
||||
const onSelectionChange = (key: React.Key | null) => {
|
||||
const onChange = (key: React.Key | null) => {
|
||||
setFieldState((prevState) => {
|
||||
let selectedItem = prevState.items.find((option) => option.key === key);
|
||||
|
||||
@@ -95,9 +95,9 @@ export default function App() {
|
||||
placeholder="Search an animal"
|
||||
selectedKey={fieldState.selectedKey}
|
||||
variant="bordered"
|
||||
onChange={onChange}
|
||||
onInputChange={onInputChange}
|
||||
onOpenChange={onOpenChange}
|
||||
onSelectionChange={onSelectionChange}
|
||||
>
|
||||
{(item) => <AutocompleteItem key={item.key}>{item.label}</AutocompleteItem>}
|
||||
</Autocomplete>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ heroui init my-heroui-app -t app
|
||||
output:
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
┌ Create a new project
|
||||
│
|
||||
@@ -114,9 +114,8 @@ HeroUI CLI v0.2.1
|
||||
#### Features
|
||||
|
||||
> 1. Auto add the missing required `dependencies` to your project
|
||||
> 2. Auto add the required `tailwindcss.config.js` configuration to your project
|
||||
> 3. Detect whether using pnpm, if so, add the required configuration to your `.npmrc` file
|
||||
> 4. Add HeroUI Chat codebase to your project
|
||||
> 2. Detect whether using pnpm, if so, add the required configuration to your `.npmrc` file
|
||||
> 3. Add HeroUI Chat codebase to your project
|
||||
|
||||
```codeBlock bash
|
||||
heroui add [targets...] [options]
|
||||
@@ -126,8 +125,8 @@ heroui add [targets...] [options]
|
||||
|
||||
- `-a --all` [boolean] Add all components (default: `false`)
|
||||
- `-p --packagePath` [string] The path to the package.json file
|
||||
- `-tw --tailwindPath` [string] The path to the tailwind.config file file
|
||||
- `-app --appPath` [string] The path to the App.tsx file
|
||||
- `--tw --tailwindPath` [string] The path to the tailwind.config file (for backward compatibility)
|
||||
- `--app --appPath` [string] The path to the App.tsx file
|
||||
- `--prettier` [boolean] Add prettier format in the add content which required installed prettier - (default: `false`)
|
||||
- `--addApp` [boolean] Add App.tsx file content which required provider (default: `false`)
|
||||
- `-b --beta` [boolean] Add beta components (default: `false`)
|
||||
@@ -144,7 +143,7 @@ heroui add
|
||||
Output:
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
? Which components would you like to add? › - Space to select. Return to submit
|
||||
Instructions:
|
||||
@@ -176,7 +175,7 @@ heroui add button
|
||||
Output:
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
Adding the required dependencies: @heroui/button
|
||||
|
||||
@@ -222,15 +221,15 @@ heroui upgrade button
|
||||
Output:
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
╭───────────────────────── Component ─────────────────────────╮
|
||||
│ @heroui/button ^2.0.11 -> ^2.0.31 │
|
||||
│ @heroui/button ^2.0.11 -> ^2.0.31 │
|
||||
╰─────────────────────────────────────────────────────────────╯
|
||||
|
||||
Required min version: @heroui/theme>=2.1.0, tailwindcss>=3.4.0, react>=18.3.1, react-dom>=18.3.1
|
||||
╭───────────────────── PeerDependencies ─────────────────────╮
|
||||
│ @heroui/theme 2.0.1 -> 2.1.0 │
|
||||
│ @heroui/theme 2.0.1 -> 2.1.0 │
|
||||
│ tailwindcss ^3.2.3 -> ^3.4.0 │
|
||||
│ react Missing -> 18.3.1 │
|
||||
│ react-dom Missing -> 18.3.1 │
|
||||
@@ -268,7 +267,7 @@ heroui remove [components...] [options]
|
||||
|
||||
- `-p --packagePath` [string] The path to the package.json file
|
||||
- `-a --all` [boolean] Remove all the HeroUI components (default: `false`)
|
||||
- `-tw --tailwindPath` [string] The path to the tailwind.config file file
|
||||
- `--tw --tailwindPath` [string] The path to the tailwind.config file (for backward compatibility)
|
||||
- `--prettier` [boolean] Add prettier format in the add content which required installed prettier - (default: `false`)
|
||||
|
||||
##### Example
|
||||
@@ -282,13 +281,13 @@ heroui remove button
|
||||
Output:
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
❗️ Components slated for removal:
|
||||
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ Package │ Version │ Status │ Docs │
|
||||
│ Package │ Version │ Status │ Docs │
|
||||
│──────────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||
│ @heroui/button │ 2.0.27 🚀latest │ stable │ https://heroui.com/docs/components/button │
|
||||
│ @heroui/button │ 2.0.27 🚀latest │ stable │ https://heroui.com/docs/components/button │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
? Confirm removal of these components: › - Use arrow-keys. Return to submit.
|
||||
❯ Yes
|
||||
@@ -330,17 +329,17 @@ heroui list
|
||||
Output:
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
Current installed components:
|
||||
|
||||
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ Package │ Version │ Status │ Docs │
|
||||
│ Package │ Version │ Status │ Docs │
|
||||
│───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||
│ @heroui/autocomplete │ 2.0.10 🚀latest │ stable │ https://heroui.com/docs/components/autocomplete │
|
||||
│ @heroui/badge │ 2.0.24 🚀latest │ stable │ https://heroui.com/docs/components/badge │
|
||||
│ @heroui/button │ 2.0.27 🚀latest │ stable │ https://heroui.com/docs/components/button │
|
||||
│ @heroui/chip │ 2.0.25 🚀latest │ stable │ https://heroui.com/docs/components/chip │
|
||||
│ @heroui/autocomplete │ 2.0.10 🚀latest │ stable │ https://heroui.com/docs/components/autocomplete │
|
||||
│ @heroui/badge │ 2.0.24 🚀latest │ stable │ https://heroui.com/docs/components/badge │
|
||||
│ @heroui/button │ 2.0.27 🚀latest │ stable │ https://heroui.com/docs/components/button │
|
||||
│ @heroui/chip │ 2.0.25 🚀latest │ stable │ https://heroui.com/docs/components/chip │
|
||||
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
@@ -356,18 +355,18 @@ heroui doctor [options]
|
||||
|
||||
> 1. Check whether have `redundant dependencies` in the project
|
||||
> 2. Check whether the HeroUI components `required dependencies are installed` in the project
|
||||
> 3. Check the required `tailwind.config.js` file and the content is correct
|
||||
> 3. Check the content of `tailwind.config.js` is correct (if it exists)
|
||||
> 4. Check `.npmrc` is correct when using `pnpm`
|
||||
> 5. Check `peerDependencies with required version` are installed in the project
|
||||
|
||||
#### Doctor Options
|
||||
|
||||
- `-p` `--packagePath` [string] The path to the package.json file
|
||||
- `-tw` `--tailwindPath` [string] The path to the tailwind.config file file
|
||||
- `-app` `--appPath` [string] The path to the App.tsx file
|
||||
- `-ca` `--checkApp` [boolean] Open check App (default: `true`)
|
||||
- `-ct` `--checkTailwind` [boolean] Open check tailwind.config file (default: `true`)
|
||||
- `-cp` `--checkPnpm` [boolean] Open check Pnpm (default: `true`)
|
||||
- `--tw` `--tailwindPath` [string] The path to the tailwind.config file (for backward compatibility)
|
||||
- `--app` `--appPath` [string] The path to the App.tsx file
|
||||
- `--ca` `--checkApp` [boolean] Open check App (default: `true`)
|
||||
- `--ct` `--checkTailwind` [boolean] Open check tailwind.config file (default: `true` if it exists)
|
||||
- `--cp` `--checkPnpm` [boolean] Open check Pnpm (default: `true`)
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -380,19 +379,24 @@ Output:
|
||||
If there is a problem in your project, the `doctor` command will display the problem information.
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
HeroUI CLI: ❌ Your project has 1 issue that require attention
|
||||
|
||||
❗️Issue 1: missingTailwind
|
||||
❗️Issue 1: missingDependencies
|
||||
|
||||
Missing tailwind.config.(j|t)s file. To set up, visit: https://heroui.com/docs/guide/installation#tailwind-css-setup
|
||||
You have not installed the required dependencies
|
||||
|
||||
The required dependencies are:
|
||||
- @heroui/theme@2.4.25
|
||||
|
||||
See more info here: https://heroui.com/docs/guide/installation#global-installation
|
||||
```
|
||||
|
||||
Otherwise, the `doctor` command will display the following message.
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
✅ Your project has no detected issues.
|
||||
```
|
||||
@@ -420,17 +424,17 @@ heroui env
|
||||
Output:
|
||||
|
||||
```codeBlock bash
|
||||
HeroUI CLI v0.2.1
|
||||
HeroUI CLI <version>
|
||||
|
||||
Current installed components:
|
||||
|
||||
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ Package │ Version │ Status │ Docs │
|
||||
│ Package │ Version │ Status │ Docs │
|
||||
│───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||
│ @heroui/autocomplete │ 2.0.10 🚀latest │ stable │ https://heroui.com/docs/components/autocomplete │
|
||||
│ @heroui/badge │ 2.0.24 🚀latest │ stable │ https://heroui.com/docs/components/badge │
|
||||
│ @heroui/button │ 2.0.27 🚀latest │ stable │ https://heroui.com/docs/components/button │
|
||||
│ @heroui/chip │ 2.0.25 🚀latest │ stable │ https://heroui.com/docs/components/chip │
|
||||
│ @heroui/autocomplete │ 2.0.10 🚀latest │ stable │ https://heroui.com/docs/components/autocomplete │
|
||||
│ @heroui/badge │ 2.0.24 🚀latest │ stable │ https://heroui.com/docs/components/badge │
|
||||
│ @heroui/button │ 2.0.27 🚀latest │ stable │ https://heroui.com/docs/components/button │
|
||||
│ @heroui/chip │ 2.0.25 🚀latest │ stable │ https://heroui.com/docs/components/chip │
|
||||
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
|
||||
Environment Info:
|
||||
@@ -438,5 +442,5 @@ Environment Info:
|
||||
OS: darwin
|
||||
CPU: arm64
|
||||
Binaries:
|
||||
Node: v18.18.2
|
||||
Node: v24.3.0
|
||||
```
|
||||
|
||||
@@ -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}/>
|
||||
|
||||
@@ -34,7 +34,7 @@ HeroUI exports 3 autocomplete-related components:
|
||||
|
||||
- **Autocomplete**: The main component, which is a wrapper for the other components.
|
||||
- **AutocompleteSection**: The component that contains a group of autocomplete items.
|
||||
- **AutocompleteItem**: The component that represents a autocomplete item.
|
||||
- **AutocompleteItem**: The component that represents an autocomplete item.
|
||||
|
||||
<ImportTabs
|
||||
commands={{
|
||||
@@ -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"
|
||||
@@ -176,30 +176,30 @@ You can combine the `isInvalid` and `errorMessage` properties to show an invalid
|
||||
### Events
|
||||
|
||||
The `Autocomplete` component supports selection via mouse, keyboard, and touch. You can handle all of these
|
||||
via the `onSelectionChange` prop. `Autocomplete` will pass the selected key to the onSelectionChange handler.
|
||||
via the `onChange` prop. `Autocomplete` will pass the selected key to the onChange handler.
|
||||
Additionally, ComboBox accepts an `onInputChange` prop which is triggered whenever the value is edited by the user,
|
||||
whether through typing or option selection.
|
||||
|
||||
The example below uses `onSelectionChange` and `onInputChange` to update the selection and input value stored in
|
||||
The example below uses `onChange` and `onInputChange` to update the selection and input value stored in
|
||||
React state.
|
||||
|
||||
<CodeDemo title="Events" files={autocompleteContent.events} />
|
||||
|
||||
### Controlled
|
||||
|
||||
You can use the `selectedKey` and `onSelectionChange` properties to control the select value.
|
||||
You can use the `value` and `onChange` properties to control the select value.
|
||||
|
||||
<CodeDemo
|
||||
title="Controlled with onSelectionChange"
|
||||
title="Controlled with onChange"
|
||||
files={autocompleteContent.controlled}
|
||||
/>
|
||||
|
||||
### Fully Controlled
|
||||
|
||||
By passing in `inputValue`, `selectedKey`, and `items` to the `Autocomplete` you can control exactly what your `Autocomplete` should display.
|
||||
By passing in `inputValue`, `value`, and `items` to the `Autocomplete` you can control exactly what your `Autocomplete` should display.
|
||||
|
||||
The following example shows how you would create a controlled `Autocomplete`, controlling everything from the selected value
|
||||
`selectedKey` to the combobox options `items`.
|
||||
`value` to the combobox options `items`.
|
||||
|
||||
We recommend using the `useFilter` hook from [@react-aria/i18n](https://react-spectrum.adobe.com/react-aria/useFilter.html#usefilter) to manage the filtering of the items.
|
||||
|
||||
@@ -224,7 +224,7 @@ import {useFilter} from "@react-aria/i18n";
|
||||
files={autocompleteContent.fullyControlled}
|
||||
/>
|
||||
|
||||
> **Note**: It is important to note that you don't have to control every single aspect of a `Autocomplete`. If you decide to only control a single property of the `Autocomplete`, be sure to provide the change handler for that prop as well e.g. controlling `selectedKey` would require `onSelectionChange`.
|
||||
> **Note**: It is important to note that you don't have to control every single aspect of a `Autocomplete`. If you decide to only control a single property of the `Autocomplete`, be sure to provide the change handler for that prop as well e.g. controlling `value` would require `onChange`.
|
||||
|
||||
### Custom Items
|
||||
|
||||
@@ -395,7 +395,7 @@ properties to customize the popover, listbox and input components.
|
||||
- **data-disabled**:
|
||||
When the autocomplete item is disabled. Based on autocomplete `disabledKeys` prop.
|
||||
- **data-selected**:
|
||||
When the autocomplete item is selected. Based on autocomplete `selectedKey` prop.
|
||||
When the autocomplete item is selected. Based on autocomplete `value` prop.
|
||||
- **data-hover**:
|
||||
When the autocomplete item is being hovered. Based on [useHover](https://react-spectrum.adobe.com/react-aria/useHover.html)
|
||||
- **data-pressed**:
|
||||
@@ -542,18 +542,18 @@ 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"
|
||||
},
|
||||
{
|
||||
attribute: "selectedKey",
|
||||
attribute: "value",
|
||||
type: "React.Key",
|
||||
description: "The currently selected key in the collection (controlled).",
|
||||
default: "-"
|
||||
},
|
||||
{
|
||||
attribute: "defaultSelectedKey",
|
||||
attribute: "defaultValue",
|
||||
type: "React.Key",
|
||||
description: "The initial selected key in the collection (uncontrolled).",
|
||||
default: "-"
|
||||
@@ -572,7 +572,7 @@ properties to customize the popover, listbox and input components.
|
||||
},
|
||||
{
|
||||
attribute: "validate",
|
||||
type: "(value: { inputValue: string, selectedKey: React.Key }) => ValidationError | true | null | undefined",
|
||||
type: "(value: { inputValue: string, value: React.Key }) => ValidationError | true | null | undefined",
|
||||
description: "Validate input values when committing (e.g. on blur), and return error messages for invalid values.",
|
||||
default: "-"
|
||||
},
|
||||
@@ -764,7 +764,7 @@ properties to customize the popover, listbox and input components.
|
||||
default: "-"
|
||||
},
|
||||
{
|
||||
attribute: "onSelectionChange",
|
||||
attribute: "onChange",
|
||||
type: "(key: React.Key) => void",
|
||||
description: "Handler that is called when the Autocomplete selection changes.",
|
||||
default: "-"
|
||||
|
||||
@@ -249,6 +249,12 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr
|
||||
description: "The day that starts the week.",
|
||||
default: "-"
|
||||
},
|
||||
{
|
||||
attribute: "selectionAlignment",
|
||||
type: "start | center | end",
|
||||
description: "Determines the alignment of the visible months on initial render based on the current selection or current date if there is no selection.",
|
||||
default: "center"
|
||||
},
|
||||
{
|
||||
attribute: "focusedValue",
|
||||
type: "DateValue",
|
||||
@@ -258,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.9.0",
|
||||
yarn: "yarn add @internationalized/date@3.9.0",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0",
|
||||
npm: "npm install @internationalized/date@3.12.2",
|
||||
yarn: "yarn add @internationalized/date@3.12.2",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -129,9 +129,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
yarn: "yarn add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
npm: "npm install @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
yarn: "yarn add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -153,9 +153,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0",
|
||||
yarn: "yarn add @internationalized/date@3.9.0",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0",
|
||||
npm: "npm install @internationalized/date@3.12.2",
|
||||
yarn: "yarn add @internationalized/date@3.12.2",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -177,9 +177,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
yarn: "yarn add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
npm: "npm install @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
yarn: "yarn add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -200,9 +200,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0",
|
||||
yarn: "yarn add @internationalized/date@3.9.0",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0",
|
||||
npm: "npm install @internationalized/date@3.12.2",
|
||||
yarn: "yarn add @internationalized/date@3.12.2",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -223,9 +223,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0",
|
||||
yarn: "yarn add @internationalized/date@3.9.0",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0",
|
||||
npm: "npm install @internationalized/date@3.12.2",
|
||||
yarn: "yarn add @internationalized/date@3.12.2",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -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.9.0",
|
||||
yarn: "yarn add @internationalized/date@3.9.0",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0",
|
||||
npm: "npm install @internationalized/date@3.12.2",
|
||||
yarn: "yarn add @internationalized/date@3.12.2",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -144,9 +144,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
yarn: "yarn add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
npm: "npm install @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
yarn: "yarn add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -168,9 +168,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0",
|
||||
yarn: "yarn add @internationalized/date@3.9.0",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0",
|
||||
npm: "npm install @internationalized/date@3.12.2",
|
||||
yarn: "yarn add @internationalized/date@3.12.2",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -192,9 +192,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
yarn: "yarn add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
npm: "npm install @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
yarn: "yarn add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -214,9 +214,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
yarn: "yarn add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
npm: "npm install @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
yarn: "yarn add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -252,9 +252,9 @@ in multiple formats into `ZonedDateTime` objects.
|
||||
|
||||
<PackageManagers
|
||||
commands={{
|
||||
npm: "npm install @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
yarn: "yarn add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
pnpm: "pnpm add @internationalized/date@3.9.0 @react-aria/i18n@3.12.12",
|
||||
npm: "npm install @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
yarn: "yarn add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
pnpm: "pnpm add @internationalized/date@3.12.2 @react-aria/i18n@3.13.1",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
@@ -447,6 +447,12 @@ import {I18nProvider} from "@react-aria/i18n";
|
||||
description: "The day that starts the week.",
|
||||
default: "-"
|
||||
},
|
||||
{
|
||||
attribute: "selectionAlignment",
|
||||
type: "start | center | end",
|
||||
description: "Determines the alignment of the visible months on initial render based on the current selection or current date if there is no selection.",
|
||||
default: "center"
|
||||
},
|
||||
{
|
||||
attribute: "selectorIcon",
|
||||
type: "ReactNode",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user