Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
cf39e22
chore: org name change (#4596)
wingkwong Jan 19, 2025
66efa0a
chore: update brand name (#4600)
wingkwong Jan 19, 2025
cddba82
fix(calendar): function components cannot be given refs (#4614)
wingkwong Jan 21, 2025
11b939d
docs(modal): fix small typos and add clarifying language (#4629)
millmason Jan 28, 2025
3d9b600
chore(deps): bump RA versions (#4611)
wingkwong Jan 30, 2025
69aa476
feat: tailwind variants upgrade (#4386)
jrgarciadev Jan 30, 2025
8452603
feat: add fn win alt keys (#4638)
winchesHe Jan 30, 2025
f9c2be4
fix(use-image): load images after props change (#4523)
wingkwong Jan 30, 2025
7804de0
feat: global labelPlacement prop (#4346)
macci001 Jan 30, 2025
be15943
Merge branch 'main' of github.com:heroui-inc/heroui into canary
jrgarciadev Jan 30, 2025
a66476d
fix(form): use native as default validation behavior (#4425)
Peterl561 Jan 30, 2025
1965b84
feat(spinner): new spinner variants (#4555)
Peterl561 Jan 30, 2025
06d6f08
fix: rename wrapper to tab wrapper (#4636)
winchesHe Jan 30, 2025
92281a6
refactor: remove feature request from issue template (#4661)
wingkwong Jan 31, 2025
eb92904
docs(table): include TS examples to show Selection type usage (#4793)
wingkwong Feb 5, 2025
f7c2be0
fix(listbox): unexpected scrollShadow on virtualized listbox (#4784)
wingkwong Feb 5, 2025
3d5548e
refactor(theme): replace left & right by start & end to support RTL (…
wingkwong Feb 5, 2025
ae3df14
fix(date-picker): deprecate dateInputClassNames (#4780)
wingkwong Feb 5, 2025
ed344b9
refactor(navbar): remove dropdown menu width (#4757)
wingkwong Feb 5, 2025
6159f47
refactor: rename instances of NextUI to Hero UI (#4645)
plbstl Feb 5, 2025
8319308
fix(input): missing clear button with file input type (#4599)
wingkwong Feb 5, 2025
475b2ff
fix(theme): sync with input theme on labelPlacement (#4597)
wingkwong Feb 5, 2025
e77de2b
test(input): input interaction tests (#4579)
Peterl561 Feb 5, 2025
ace8406
fix(calendar): rtl navigation (#4565)
nabi-ebrahimi Feb 5, 2025
25cf3e2
refactor: remove unnecessary className passing to tv and make naming …
wingkwong Feb 5, 2025
8d55d92
fix: deprecation warning triggered by internal onClick (#4557)
wingkwong Feb 5, 2025
9aec8fd
ci: add pkg pr new (#4540)
winchesHe Feb 5, 2025
e53e454
chore(docs): remove shouldBlockScroll prop in Tooltip page (#4539)
wingkwong Feb 5, 2025
0bfc03e
fix(use-pagination): controlled page after delay (#4536)
wingkwong Feb 5, 2025
2573e82
fix(tooltip): accessing element.ref was removed in React 19 issue (#4…
wingkwong Feb 5, 2025
5e3054e
fix: correctly dismissable default value (#4524)
winchesHe Feb 5, 2025
12a5c15
fix(theme): input height in innerWrapper in Select (#4512)
ShrinidhiUpadhyaya Feb 5, 2025
7402e00
fix: inert value in next15 (#4491)
winchesHe Feb 5, 2025
a1cc378
refactor: remove cursor-hit in hiddenInputClasses (#4474)
Layouwen Feb 5, 2025
fbc361c
feat(table): virtualization (#4285)
vinroger Feb 11, 2025
d64fcc8
feat(toast): introduce Toast component (#4437)
macci001 Feb 11, 2025
628bcde
fix(docs): correct Tab usage example (#4821)
ryo-manba Feb 11, 2025
c659e2f
chore(docs): add note itemHeight for virtualization (#4822)
ryo-manba Feb 11, 2025
2913bfd
fix(docs): fix horizontal scrolling example in scroll-shadow (#4820)
ryo-manba Feb 11, 2025
28e8df7
refactor: update author in package.json (#4800)
wingkwong Feb 11, 2025
8dc5aaa
feat(button): export PressEvent for onPress event typing (#4819)
ryo-manba Feb 11, 2025
b2e7e04
fix(listbox): pass missing press events to usePress (#4812)
wingkwong Feb 11, 2025
8af2c5d
fix(checkbox): inherit stroke in CheckboxIcon (#4811)
wingkwong Feb 11, 2025
28b8606
fix: `SelectItem`, `ListboxItem`, and `AutocompleteItem` not to accep…
ryo-manba Feb 11, 2025
593e77c
fix: pkg package scope (#4823)
winchesHe Feb 12, 2025
d78885d
fix(theme): border radius in Table when isMultiSelectable (#4808)
Adee1499 Feb 12, 2025
52f926a
chore: removing the kapa ai for toast doc page (#4833)
macci001 Feb 14, 2025
7f334e4
fix(accordion): add data-slot attributes to accordion (#4832)
Hova25 Feb 14, 2025
3f7f85b
chore(docs): update versions (#4836)
wingkwong Feb 14, 2025
e99ddc4
docs(themes): adding theme generator (#4626)
macci001 Feb 14, 2025
5f97961
feat: introduce NumberInput (#4475)
wingkwong Feb 14, 2025
cdaeb9e
chore(docs): revised tags in doc routes for 2.7.0 (#4777)
wingkwong Feb 14, 2025
b238cea
chore: improve theme builder
jrgarciadev Feb 14, 2025
ba18a57
v2.7.0
jrgarciadev Feb 14, 2025
60f332f
chore: v2.7.0 combined changeset
jrgarciadev Feb 14, 2025
e330725
fix: changeset
jrgarciadev Feb 14, 2025
fcd6c15
fix: peer deps
jrgarciadev Feb 14, 2025
bc0112f
feat: toast api improved
jrgarciadev Feb 14, 2025
7c41e27
chore: toast styles improved
jrgarciadev Feb 16, 2025
b6a9cc1
fix: toast styles
jrgarciadev Feb 16, 2025
d24e78a
chore: toast width style changed
jrgarciadev Feb 16, 2025
4ff87ca
fix: changeset release
jrgarciadev Feb 16, 2025
88b9cbe
fix: changeset peerdeps
jrgarciadev Feb 16, 2025
09241fa
chore: toast styles improved
jrgarciadev Feb 16, 2025
4693fb7
refactor(pagination): rtl (#4843)
wingkwong Feb 17, 2025
f51d645
feat: new spinner variant
jrgarciadev Feb 18, 2025
c364d27
fix(docs): popover shouldBlockScroll default value (#4851)
sudongyuer Feb 18, 2025
80f6c77
fix(select): select scroll content will close immediately when popove…
sudongyuer Feb 18, 2025
446dd0b
feat(calendar): add firstDayOfWeek (#4852)
wingkwong Feb 18, 2025
ccdc076
chore: spinner variants updated
jrgarciadev Feb 18, 2025
b3db9a9
feat: v2.7.0 blog
jrgarciadev Feb 18, 2025
1b8e18d
ci(changesets): version packages (#4601)
github-actions[bot] Feb 18, 2025
f29cf8c
chore: manual release
jrgarciadev Feb 18, 2025
57b1181
Merge branch 'main' of github.com:heroui-inc/heroui into canary
jrgarciadev Feb 18, 2025
29df4f5
fix(toast): fixing maxVisibleToasts, solid variant promise, promise t…
macci001 Feb 21, 2025
fd446da
fix(toast): shouldShowTimeoutProgess typo (#4858)
wingkwong Feb 26, 2025
989cbe1
fix(select): pass form prop to hidden-select (#4854)
smozely Feb 26, 2025
2186f6d
fix(spinner): Attempted to call useProviderContext() from the server …
wingkwong Feb 26, 2025
f55cf8b
fix(number-input): onChange event in number input (#4907)
wingkwong Feb 26, 2025
2774a1b
fix(breadcrumb): broken start & end content (#4921) (#4922)
wingkwong Feb 26, 2025
25b3e6f
refactor: build process (#4909)
wingkwong Feb 26, 2025
09a2b73
fix: incorrect system & theme version in peerDependencies (#4901)
wingkwong Feb 26, 2025
66d2c2b
fix(changeset): remove `@heroui/stories-utils` and `@heroui/test-util…
wingkwong Feb 26, 2025
ff8c9b3
fix(docs): include .npmrc in sandbox (#4951)
wingkwong Feb 28, 2025
6453149
fix(input): esc key to clear input value (#4892)
linyonglu Feb 28, 2025
d330941
ci(changesets): version packages (#4896)
github-actions[bot] Feb 28, 2025
2ee356b
v2.7.4
jrgarciadev Feb 28, 2025
afe5897
Merge branch 'main' of github.com:heroui-inc/heroui into canary
jrgarciadev Feb 28, 2025
9a95a71
chore(deps): bump turbo version (#4958)
wingkwong Feb 28, 2025
88f1641
fix(deps): bump react-aria versions (#4998)
wingkwong Mar 8, 2025
6f94545
fix(toast): toast should appear above overlay and adding regionProps …
macci001 Mar 8, 2025
e9c67fa
fix(number-stepper): stepper button pseudo height (#4968)
wingkwong Mar 8, 2025
695b0c8
fix(progress): incorrect size in indeterminate storybook (#4967)
wingkwong Mar 8, 2025
4e5a86e
fix: shouldShowTimeoutProgress typo (#4961)
wingkwong Mar 8, 2025
d158bc1
chore(workflows): update runner (#4960)
wingkwong Mar 8, 2025
58128c4
fix: a small eye icon for password input in edge(#4927) (#4950)
linyonglu Mar 8, 2025
6293536
fix(progress): add RTL support to the progress component (#4911)
waleed-mobasher Mar 8, 2025
41084ac
fix: build
jrgarciadev Mar 8, 2025
1f95899
fix(toast): unexpected toast animation (#5003)
wingkwong Mar 8, 2025
5fbc2a2
ci(changesets): version packages (#5002)
github-actions[bot] Mar 8, 2025
03ee057
chore: merged with main
jrgarciadev Mar 8, 2025
80aadd9
feat: open in chat button in doc examples (#4996)
Peterl561 Mar 10, 2025
60f9433
chore: open in chat improvements
jrgarciadev Mar 10, 2025
3dc6e2e
chore: remove ripple from the open in chat button
jrgarciadev Mar 10, 2025
0a3773c
fix(docs): open in chat (#5018)
Peterl561 Mar 11, 2025
26080cb
fix(docs): open in chat improvements (#5035)
Peterl561 Mar 12, 2025
8ac36ce
chore: merged with main
jrgarciadev Mar 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 53 additions & 18 deletions apps/docs/actions/open-in-chat.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
"use server";

import {SandpackFiles} from "@codesandbox/sandpack-react/types";

import {parseDependencies} from "@/components/docs/components/code-demo/parse-dependencies";
import {toKebabCase, toPascalCase} from "@/components/docs/components/code-demo/utils";

const importReact = 'import React from "react";';

export const openInChat = async ({title, files}: {title?: string; files: SandpackFiles}) => {
export const openInChat = async ({
component,
title,
content,
dependencies,
useWrapper,
}: {
component: string;
title?: string;
content: string;
dependencies: {name: string; version: string}[];
useWrapper: boolean;
}) => {
try {
// assumes one file for now
let content = files["/App.jsx"];

if (!content || typeof content !== "string") {
return {
error: "Content is not a string",
data: null,
};
}

const dependencies = parseDependencies(content);

// Check if the file content includes 'React' import statements, if not, add it
if (
content.includes("React.") &&
Expand All @@ -29,15 +27,25 @@ export const openInChat = async ({title, files}: {title?: string; files: Sandpac
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,
content,
title: `${component.charAt(0).toUpperCase() + component.slice(1)} - ${title}`,
files,
dependencies,
}),
});
Expand All @@ -63,3 +71,30 @@ export const openInChat = async ({title, files}: {title?: string; files: Sandpac
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,
};
};
24 changes: 22 additions & 2 deletions apps/docs/components/docs/components/code-demo/code-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {usePathname} from "next/navigation";

import {useCodeDemo, UseCodeDemoProps} from "./use-code-demo";
import WindowResizer, {WindowResizerProps} from "./window-resizer";
import {parseDependencies} from "./parse-dependencies";

import {GradientBoxProps} from "@/components/gradient-box";
import {SmallLogo} from "@/components/heroui-logo";
Expand Down Expand Up @@ -180,15 +181,34 @@ export const CodeDemo: React.FC<CodeDemoProps> = ({
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 capitalizedPath = component.charAt(0).toUpperCase() + component.slice(1);
const {data, error} = await openInChat({title: `${capitalizedPath} - ${title}`, files});
const {data, error} = await openInChat({
component,
title,
content,
dependencies,
useWrapper: !asIframe,
});

setIsLoading(false);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
const packageRegex = /(?:from|import)\s+(?:.*\s+from\s+)?['"]([^'"]+)['"]/g;
import React from "react";
import * as HeroUI from "@heroui/react";

const importRegex = /^(import\s+(?!type\s+\{)[\s\S]*?;)/gm;

export const parseDependencies = (content: string) => {
const dependencies: {name: string; version: string}[] = [];

content.match(packageRegex)?.forEach((match) => {
if (match.includes("@heroui")) {
return;
// by default, react and heroui packages are installed already
const installedPackages = {
React,
...HeroUI,
} as Record<string, unknown>;

// create a map of installed packages
const imports = Object.keys(installedPackages).reduce(
(acc, key) => {
acc[key] = `${key}`;

return acc;
},
{React: "React"} as Record<string, string>,
);

// match all imports from the file content
content.match(importRegex)?.forEach((match) => {
// check if imported component is in default installed packages
const componentName = match.match(/\w+/g)?.[1] || "";
const matchingImport = imports[componentName];

if (matchingImport) {
return "";
}

if (match.includes("./") || match.includes("../")) {
return;
return "";
}

const packageName = match.match(/['"]([^'"]+)['"]/)?.[1];
Expand Down
17 changes: 17 additions & 0 deletions apps/docs/components/docs/components/code-demo/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,20 @@ export const joinCode = (filesCode: FileCode[]) => {
export const getFileName = (filePath: string) => {
return filePath?.split(".")?.[0]?.replace(/\W/g, "");
};

export const toPascalCase = (str: string) => {
const cleanStr = str.replace(/[^a-zA-Z0-9\s]/g, "");

return cleanStr
.split(/\s+/)
.map((word) => {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
})
.join("");
};

export const toKebabCase = (str: string) => {
const cleanStr = str.replace(/[^a-zA-Z0-9\s]/g, "");

return cleanStr.toLowerCase().split(/\s+/).join("-");
};