Skip to content

Commit

Permalink
bump: chat-ui and tailwind v4 (#509)
Browse files Browse the repository at this point in the history
  • Loading branch information
thucpn authored Feb 25, 2025
1 parent 0e4ecfa commit ee69ce7
Show file tree
Hide file tree
Showing 16 changed files with 142 additions and 162 deletions.
5 changes: 5 additions & 0 deletions .changeset/rare-eyes-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"create-llama": patch
---

bump: chat-ui and tailwind v4
4 changes: 2 additions & 2 deletions templates/types/streaming/nextjs/app/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import Image from "next/image";
export default function Header() {
return (
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-linear-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
Get started by editing&nbsp;
<code className="font-mono font-bold">app/page.tsx</code>
</p>
<div className="fixed bottom-0 left-0 mb-4 flex h-auto w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:w-auto lg:bg-none lg:mb-0">
<div className="fixed bottom-0 left-0 mb-4 flex h-auto w-full items-end justify-center bg-linear-to-t from-white via-white dark:from-black dark:via-black lg:static lg:w-auto lg:bg-none lg:mb-0">
<a
href="https://www.llamaindex.ai/"
className="flex items-center justify-center font-nunito text-lg font-bold gap-2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as React from "react";
import { cn } from "./lib/utils";

const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const Card = React.forwardRef<
<div
ref={ref}
className={cn(
"rounded-xl border border-neutral-200 bg-white text-neutral-950 shadow dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50",
"rounded-xl border border-neutral-200 bg-white text-neutral-950 shadow-sm dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50",
className,
)}
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ export function ChatMessageAvatar() {
const { message } = useChatMessage();
if (message.role === "user") {
return (
<div className="flex h-8 w-8 shrink-0 select-none items-center justify-center rounded-md border bg-background shadow">
<div className="flex h-8 w-8 shrink-0 select-none items-center justify-center rounded-md border bg-background shadow-sm">
<User2 className="h-4 w-4" />
</div>
);
}

return (
<div className="flex h-8 w-8 shrink-0 select-none items-center justify-center rounded-md border bg-black text-white shadow">
<div className="flex h-8 w-8 shrink-0 select-none items-center justify-center rounded-md border bg-black text-white shadow-sm">
<Image
className="rounded-md"
src="/llama.png"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,19 @@
import {
ChatMessage,
ContentPosition,
getSourceAnnotationData,
useChatMessage,
useChatUI,
} from "@llamaindex/chat-ui";
import { ChatMessage } from "@llamaindex/chat-ui";
import { DeepResearchCard } from "./custom/deep-research-card";
import { Markdown } from "./custom/markdown";
import { ToolAnnotations } from "./tools/chat-tools";

export function ChatMessageContent() {
const { isLoading, append } = useChatUI();
const { message } = useChatMessage();
const customContent = [
{
// override the default markdown component
position: ContentPosition.MARKDOWN,
component: (
<Markdown
content={message.content}
sources={getSourceAnnotationData(message.annotations)?.[0]}
/>
),
},
// add the deep research card
{
position: ContentPosition.CHAT_EVENTS,
component: <DeepResearchCard message={message} />,
},
{
// add the tool annotations after events
position: ContentPosition.AFTER_EVENTS,
component: <ToolAnnotations message={message} />,
},
];
return (
<ChatMessage.Content
content={customContent}
isLoading={isLoading}
append={append}
/>
<ChatMessage.Content>
<ChatMessage.Content.Event />
<ChatMessage.Content.AgentEvent />
<DeepResearchCard />
<ToolAnnotations />
<ChatMessage.Content.Image />
<ChatMessage.Content.Markdown />
<ChatMessage.Content.DocumentFile />
<ChatMessage.Content.Source />
<ChatMessage.Content.SuggestedQuestions />
</ChatMessage.Content>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { Message } from "@llamaindex/chat-ui";
import { getCustomAnnotation, useChatMessage } from "@llamaindex/chat-ui";
import {
AlertCircle,
CheckCircle2,
Expand Down Expand Up @@ -54,7 +54,6 @@ type DeepResearchCardState = {
};

interface DeepResearchCardProps {
message: Message;
className?: string;
}

Expand Down Expand Up @@ -143,25 +142,19 @@ const deepResearchEventsToState = (
);
};

export function DeepResearchCard({
message,
className,
}: DeepResearchCardProps) {
const deepResearchEvents = message.annotations as
| DeepResearchEvent[]
| undefined;
const hasDeepResearchEvents = deepResearchEvents?.some(
(event) => event.type === "deep_research_event",
);
export function DeepResearchCard({ className }: DeepResearchCardProps) {
const { message } = useChatMessage();

const state = useMemo(
() => deepResearchEventsToState(deepResearchEvents),
[deepResearchEvents],
);
const state = useMemo(() => {
const deepResearchEvents = getCustomAnnotation<DeepResearchEvent>(
message.annotations,
(annotation) => annotation?.type === "deep_research_event",
);
if (!deepResearchEvents.length) return null;
return deepResearchEventsToState(deepResearchEvents);
}, [message.annotations]);

if (!hasDeepResearchEvents) {
return null;
}
if (!state) return null;

return (
<Card className={cn("w-full", className)}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
import {
Message,
MessageAnnotation,
getAnnotationData,
getChatUIAnnotation,
useChatMessage,
useChatUI,
} from "@llamaindex/chat-ui";
import { JSONValue } from "ai";
import { useMemo } from "react";
import { Artifact, CodeArtifact } from "./artifact";
import { WeatherCard, WeatherData } from "./weather-card";

export function ToolAnnotations({ message }: { message: Message }) {
export function ToolAnnotations() {
// TODO: This is a bit of a hack to get the artifact version. better to generate the version in the tool call and
// store it in CodeArtifact
const { messages } = useChatUI();
const { message } = useChatMessage();
const artifactVersion = useMemo(
() => getArtifactVersion(messages, message),
[messages, message],
);
// Get the tool data from the message annotations
const annotations = message.annotations as MessageAnnotation[] | undefined;
const toolData = annotations
? (getAnnotationData(annotations, "tools") as unknown as ToolData[])
? (getChatUIAnnotation(annotations, "tools") as unknown as ToolData[])
: null;
return toolData?.[0] ? (
<ChatTools data={toolData[0]} artifactVersion={artifactVersion} />
Expand Down Expand Up @@ -87,7 +89,7 @@ function getArtifactVersion(
let versionIndex = 1;
for (const m of messages) {
const toolData = m.annotations
? (getAnnotationData(m.annotations, "tools") as unknown as ToolData[])
? (getChatUIAnnotation(m.annotations, "tools") as unknown as ToolData[])
: null;

if (toolData?.some((t) => t.toolCall.name === "artifact")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
ref={ref}
Expand Down
4 changes: 2 additions & 2 deletions templates/types/streaming/nextjs/app/components/ui/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className,
)}
{...props}
Expand Down Expand Up @@ -117,7 +117,7 @@ const SelectItem = React.forwardRef<
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
className,
)}
{...props}
Expand Down
4 changes: 2 additions & 2 deletions templates/types/streaming/nextjs/app/components/ui/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const TabsTrigger = React.forwardRef<
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
className,
)}
{...props}
Expand All @@ -43,7 +43,7 @@ const TabsContent = React.forwardRef<
<TabsPrimitive.Content
ref={ref}
className={cn(
"ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
className,
)}
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
return (
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
ref={ref}
Expand Down
94 changes: 91 additions & 3 deletions templates/types/streaming/nextjs/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,94 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss";

@source '../node_modules/@llamaindex/chat-ui/**/*.{ts,tsx}';

@custom-variant dark (&:is(.dark *));

@theme {
--color-border: hsl(var(--border));
--color-input: hsl(var(--input));
--color-ring: hsl(var(--ring));
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));

--color-primary: hsl(var(--primary));
--color-primary-foreground: hsl(var(--primary-foreground));

--color-secondary: hsl(var(--secondary));
--color-secondary-foreground: hsl(var(--secondary-foreground));

--color-destructive: hsl(var(--destructive));
--color-destructive-foreground: hsl(var(--destructive-foreground));

--color-muted: hsl(var(--muted));
--color-muted-foreground: hsl(var(--muted-foreground));

--color-accent: hsl(var(--accent));
--color-accent-foreground: hsl(var(--accent-foreground));

--color-popover: hsl(var(--popover));
--color-popover-foreground: hsl(var(--popover-foreground));

--color-card: hsl(var(--card));
--color-card-foreground: hsl(var(--card-foreground));

--radius-xl: calc(var(--radius) + 4px);
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);

--font-sans: var(--font-sans), ui-sans-serif, system-ui, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";

--animate-accordion-down: accordion-down 0.2s ease-out;
--animate-accordion-up: accordion-up 0.2s ease-out;

@keyframes accordion-down {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}
@keyframes accordion-up {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}
}

@utility container {
margin-inline: auto;
padding-inline: 2rem;
@media (width >= --theme(--breakpoint-sm)) {
max-width: none;
}
@media (width >= 1400px) {
max-width: 1400px;
}
}

/*
The default border color has changed to `currentColor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
}

@layer base {
:root {
Expand Down
6 changes: 3 additions & 3 deletions templates/types/streaming/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.1.0",
"@llamaindex/chat-ui": "0.0.14",
"@llamaindex/chat-ui": "^0.2.0",
"ai": "^4.0.3",
"ajv": "^8.12.0",
"class-variance-authority": "^0.7.1",
Expand Down Expand Up @@ -46,15 +46,15 @@
"@types/uuid": "^9.0.8",
"@llamaindex/workflow": "^0.0.3",
"@types/papaparse": "^5.3.15",
"autoprefixer": "^10.4.16",
"@tailwindcss/postcss": "^4.0.8",
"cross-env": "^7.0.3",
"eslint": "^9.14.0",
"eslint-config-next": "^15.1.3",
"eslint-config-prettier": "^9.1.0",
"postcss": "^8.4.32",
"prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^3.2.4",
"tailwindcss": "^3.3.6",
"tailwindcss": "^4.0.8",
"tsx": "^4.7.2",
"typescript": "^5.3.2"
}
Expand Down
3 changes: 1 addition & 2 deletions templates/types/streaming/nextjs/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
"@tailwindcss/postcss": {},
},
};
Loading

0 comments on commit ee69ce7

Please sign in to comment.