diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index 9f7c3408..05b168be 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -1,4 +1,5 @@ @import "tailwindcss"; +@import "shadcn/tailwind.css"; @import "./styles/geistdocs.css"; @source "../**/*.{ts,tsx,mdx}"; diff --git a/apps/docs/components.json b/apps/docs/components.json index 3a642555..5bdc1188 100644 --- a/apps/docs/components.json +++ b/apps/docs/components.json @@ -1,6 +1,6 @@ { "$schema": "https://ui.shadcn.com/schema.json", - "style": "new-york", + "style": "radix-vega", "rsc": true, "tsx": true, "tailwind": { diff --git a/apps/docs/components/custom/elements-installer.tsx b/apps/docs/components/custom/elements-installer.tsx index 74ad2b83..7aaf0f16 100644 --- a/apps/docs/components/custom/elements-installer.tsx +++ b/apps/docs/components/custom/elements-installer.tsx @@ -3,7 +3,6 @@ import { readFile } from "node:fs/promises"; // oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) import { join } from "node:path"; - import { codeToHtml } from "shiki"; import { CodeBlock } from "@/components/geistdocs/code-block"; @@ -30,7 +29,7 @@ const loadSourceCode = async (componentPath: string): Promise => { "src", `${componentPath}.tsx` ), - "utf8" + "utf-8" ); return code .replaceAll("@ai-studio/shadcn-ui/", "@/") diff --git a/apps/docs/components/custom/preview.tsx b/apps/docs/components/custom/preview.tsx index 6646b0c8..64b08052 100644 --- a/apps/docs/components/custom/preview.tsx +++ b/apps/docs/components/custom/preview.tsx @@ -1,9 +1,3 @@ -// Server component - Node.js modules are valid here -// oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) -import { readFile } from "node:fs/promises"; -// oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) -import { join } from "node:path"; - import { CodeBlock } from "@repo/elements/src/code-block"; import { ResizableHandle, @@ -11,6 +5,11 @@ import { ResizablePanelGroup, } from "@repo/shadcn-ui/components/ui/resizable"; import { cn } from "@repo/shadcn-ui/lib/utils"; +// Server component - Node.js modules are valid here +// oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) +import { readFile } from "node:fs/promises"; +// oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) +import { join } from "node:path"; import { CodeBlockTab, @@ -35,7 +34,7 @@ export const Preview = async ({ path, className }: ComponentPreviewProps) => { "src", `${path}.tsx` ), - "utf8" + "utf-8" ); const Component = await import(`@repo/examples/src/${path}.tsx`).then( @@ -59,7 +58,7 @@ export const Preview = async ({ path, className }: ComponentPreviewProps) => { Code - +
diff --git a/apps/docs/components/custom/source-code.tsx b/apps/docs/components/custom/source-code.tsx index d9a6d1e2..9d5b8a01 100644 --- a/apps/docs/components/custom/source-code.tsx +++ b/apps/docs/components/custom/source-code.tsx @@ -1,10 +1,9 @@ +import { cn } from "@repo/shadcn-ui/lib/utils"; // Server component - Node.js modules are valid here // oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) import { readFile } from "node:fs/promises"; // oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) import { join } from "node:path"; - -import { cn } from "@repo/shadcn-ui/lib/utils"; import { codeToHtml } from "shiki"; import { CodeBlock } from "../geistdocs/code-block"; @@ -25,7 +24,7 @@ export const SourceCode = async ({ path, className }: SourceCodeProps) => { "src", `${path}.tsx` ), - "utf8" + "utf-8" ); const parsedCode = code diff --git a/apps/docs/content/components/(chatbot)/confirmation.mdx b/apps/docs/content/components/(chatbot)/confirmation.mdx index 1ddcb700..af6e2696 100644 --- a/apps/docs/content/components/(chatbot)/confirmation.mdx +++ b/apps/docs/content/components/(chatbot)/confirmation.mdx @@ -245,7 +245,8 @@ A styled description element for displaying a title or label within the confirma ", }, }} diff --git a/apps/docs/content/components/(chatbot)/message.mdx b/apps/docs/content/components/(chatbot)/message.mdx index ed189847..668a021c 100644 --- a/apps/docs/content/components/(chatbot)/message.mdx +++ b/apps/docs/content/components/(chatbot)/message.mdx @@ -314,7 +314,8 @@ export default ActionsDemo; ", }, }} diff --git a/apps/docs/content/components/(chatbot)/model-selector.mdx b/apps/docs/content/components/(chatbot)/model-selector.mdx index 6c07518b..842a446a 100644 --- a/apps/docs/content/components/(chatbot)/model-selector.mdx +++ b/apps/docs/content/components/(chatbot)/model-selector.mdx @@ -130,6 +130,12 @@ The `ModelSelector` component provides a searchable command palette interface fo { "true" ); }); + + it("marks the selected model as checked", () => { + render( + + + + + GPT-4 + + GPT-3.5 + + + + ); + const checkedItem = screen.getByText("GPT-4").closest('[role="option"]'); + expect(checkedItem).toHaveAttribute("aria-checked", "true"); + expect(checkedItem).toHaveAttribute("data-checked", "true"); + const uncheckedItem = screen + .getByText("GPT-3.5") + .closest('[role="option"]'); + expect(uncheckedItem).not.toHaveAttribute("aria-checked"); + expect(uncheckedItem).not.toHaveAttribute("data-checked"); + }); }); describe("modelSelectorShortcut", () => { diff --git a/packages/elements/__tests__/prompt-input.test.tsx b/packages/elements/__tests__/prompt-input.test.tsx index d961a3ba..4c22e4aa 100644 --- a/packages/elements/__tests__/prompt-input.test.tsx +++ b/packages/elements/__tests__/prompt-input.test.tsx @@ -4,6 +4,7 @@ import { userEvent } from "@testing-library/user-event"; import React from "react"; import type { AttachmentData } from "../src/attachments"; + import { Attachment, AttachmentInfo, diff --git a/packages/elements/__tests__/transcription.test.tsx b/packages/elements/__tests__/transcription.test.tsx index bc595e49..7ecb2826 100644 --- a/packages/elements/__tests__/transcription.test.tsx +++ b/packages/elements/__tests__/transcription.test.tsx @@ -1,6 +1,7 @@ +import type { Experimental_TranscriptionResult as TranscriptionResult } from "ai"; + import { render, screen } from "@testing-library/react"; import { userEvent } from "@testing-library/user-event"; -import type { Experimental_TranscriptionResult as TranscriptionResult } from "ai"; import { Transcription, TranscriptionSegment } from "../src/transcription"; diff --git a/packages/elements/src/agent.tsx b/packages/elements/src/agent.tsx index 3b3fcdba..ec09d6d9 100644 --- a/packages/elements/src/agent.tsx +++ b/packages/elements/src/agent.tsx @@ -1,5 +1,8 @@ "use client"; +import type { Tool } from "ai"; +import type { ComponentProps } from "react"; + import { Accordion, AccordionContent, @@ -8,9 +11,7 @@ import { } from "@repo/shadcn-ui/components/ui/accordion"; import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { Tool } from "ai"; import { BotIcon } from "lucide-react"; -import type { ComponentProps } from "react"; import { memo } from "react"; import { CodeBlock } from "./code-block"; diff --git a/packages/elements/src/artifact.tsx b/packages/elements/src/artifact.tsx index 4d5fef41..676e8f7d 100644 --- a/packages/elements/src/artifact.tsx +++ b/packages/elements/src/artifact.tsx @@ -1,5 +1,8 @@ "use client"; +import type { LucideIcon } from "lucide-react"; +import type { ComponentProps, HTMLAttributes } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { Tooltip, @@ -8,9 +11,7 @@ import { TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { LucideIcon } from "lucide-react"; import { XIcon } from "lucide-react"; -import type { ComponentProps, HTMLAttributes } from "react"; export type ArtifactProps = HTMLAttributes; diff --git a/packages/elements/src/attachments.tsx b/packages/elements/src/attachments.tsx index cc7b2495..59e37c86 100644 --- a/packages/elements/src/attachments.tsx +++ b/packages/elements/src/attachments.tsx @@ -1,5 +1,8 @@ "use client"; +import type { FileUIPart, SourceDocumentUIPart } from "ai"; +import type { ComponentProps, HTMLAttributes, ReactNode } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { HoverCard, @@ -7,7 +10,6 @@ import { HoverCardTrigger, } from "@repo/shadcn-ui/components/ui/hover-card"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { FileUIPart, SourceDocumentUIPart } from "ai"; import { FileTextIcon, GlobeIcon, @@ -17,7 +19,6 @@ import { VideoIcon, XIcon, } from "lucide-react"; -import type { ComponentProps, HTMLAttributes, ReactNode } from "react"; import { createContext, useCallback, useContext, useMemo } from "react"; // ============================================================================ diff --git a/packages/elements/src/audio-player.tsx b/packages/elements/src/audio-player.tsx index a340e76b..12d5ee96 100644 --- a/packages/elements/src/audio-player.tsx +++ b/packages/elements/src/audio-player.tsx @@ -1,12 +1,14 @@ "use client"; +import type { Experimental_SpeechResult as SpeechResult } from "ai"; +import type { ComponentProps, CSSProperties } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ButtonGroup, ButtonGroupText, } from "@repo/shadcn-ui/components/ui/button-group"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { Experimental_SpeechResult as SpeechResult } from "ai"; import { MediaControlBar, MediaController, @@ -19,7 +21,6 @@ import { MediaTimeRange, MediaVolumeRange, } from "media-chrome/react"; -import type { ComponentProps, CSSProperties } from "react"; export type AudioPlayerProps = Omit< ComponentProps, diff --git a/packages/elements/src/canvas.tsx b/packages/elements/src/canvas.tsx index 29606276..f4dec7ce 100644 --- a/packages/elements/src/canvas.tsx +++ b/packages/elements/src/canvas.tsx @@ -1,7 +1,7 @@ import type { ReactFlowProps } from "@xyflow/react"; -import { Background, ReactFlow } from "@xyflow/react"; import type { ReactNode } from "react"; +import { Background, ReactFlow } from "@xyflow/react"; import "@xyflow/react/dist/style.css"; type CanvasProps = ReactFlowProps & { diff --git a/packages/elements/src/chain-of-thought.tsx b/packages/elements/src/chain-of-thought.tsx index f1b26601..4daa317a 100644 --- a/packages/elements/src/chain-of-thought.tsx +++ b/packages/elements/src/chain-of-thought.tsx @@ -1,5 +1,8 @@ "use client"; +import type { LucideIcon } from "lucide-react"; +import type { ComponentProps, ReactNode } from "react"; + import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import { @@ -8,9 +11,7 @@ import { CollapsibleTrigger, } from "@repo/shadcn-ui/components/ui/collapsible"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { LucideIcon } from "lucide-react"; import { BrainIcon, ChevronDownIcon, DotIcon } from "lucide-react"; -import type { ComponentProps, ReactNode } from "react"; import { createContext, memo, useContext, useMemo } from "react"; interface ChainOfThoughtContextValue { diff --git a/packages/elements/src/checkpoint.tsx b/packages/elements/src/checkpoint.tsx index ab7900ce..df3dfb42 100644 --- a/packages/elements/src/checkpoint.tsx +++ b/packages/elements/src/checkpoint.tsx @@ -1,5 +1,8 @@ "use client"; +import type { LucideProps } from "lucide-react"; +import type { ComponentProps, HTMLAttributes } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { Separator } from "@repo/shadcn-ui/components/ui/separator"; import { @@ -8,9 +11,7 @@ import { TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { LucideProps } from "lucide-react"; import { BookmarkIcon } from "lucide-react"; -import type { ComponentProps, HTMLAttributes } from "react"; export type CheckpointProps = HTMLAttributes; diff --git a/packages/elements/src/code-block.tsx b/packages/elements/src/code-block.tsx index 820142d2..eee0cc77 100644 --- a/packages/elements/src/code-block.tsx +++ b/packages/elements/src/code-block.tsx @@ -1,5 +1,13 @@ "use client"; +import type { ComponentProps, CSSProperties, HTMLAttributes } from "react"; +import type { + BundledLanguage, + BundledTheme, + HighlighterGeneric, + ThemedToken, +} from "shiki"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { Select, @@ -10,7 +18,6 @@ import { } from "@repo/shadcn-ui/components/ui/select"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { CheckIcon, CopyIcon } from "lucide-react"; -import type { ComponentProps, CSSProperties, HTMLAttributes } from "react"; import { createContext, memo, @@ -21,12 +28,6 @@ import { useRef, useState, } from "react"; -import type { - BundledLanguage, - BundledTheme, - HighlighterGeneric, - ThemedToken, -} from "shiki"; import { createHighlighter } from "shiki"; // Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline diff --git a/packages/elements/src/commit.tsx b/packages/elements/src/commit.tsx index 0cff9553..a3a8f9b1 100644 --- a/packages/elements/src/commit.tsx +++ b/packages/elements/src/commit.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps, HTMLAttributes } from "react"; + import { Avatar, AvatarFallback } from "@repo/shadcn-ui/components/ui/avatar"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { @@ -16,7 +18,6 @@ import { MinusIcon, PlusIcon, } from "lucide-react"; -import type { ComponentProps, HTMLAttributes } from "react"; import { useCallback, useEffect, useRef, useState } from "react"; export type CommitProps = ComponentProps; diff --git a/packages/elements/src/confirmation.tsx b/packages/elements/src/confirmation.tsx index 7c964383..c384be18 100644 --- a/packages/elements/src/confirmation.tsx +++ b/packages/elements/src/confirmation.tsx @@ -1,10 +1,11 @@ "use client"; +import type { ToolUIPart } from "ai"; +import type { ComponentProps, ReactNode } from "react"; + import { Alert, AlertDescription } from "@repo/shadcn-ui/components/ui/alert"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ToolUIPart } from "ai"; -import type { ComponentProps, ReactNode } from "react"; import { createContext, useContext, useMemo } from "react"; type ToolUIPartApproval = diff --git a/packages/elements/src/context.tsx b/packages/elements/src/context.tsx index 53e28851..e245c27f 100644 --- a/packages/elements/src/context.tsx +++ b/packages/elements/src/context.tsx @@ -1,5 +1,8 @@ "use client"; +import type { LanguageModelUsage } from "ai"; +import type { ComponentProps } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { HoverCard, @@ -8,8 +11,6 @@ import { } from "@repo/shadcn-ui/components/ui/hover-card"; import { Progress } from "@repo/shadcn-ui/components/ui/progress"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { LanguageModelUsage } from "ai"; -import type { ComponentProps } from "react"; import { createContext, useContext, useMemo } from "react"; import { getUsage } from "tokenlens"; diff --git a/packages/elements/src/controls.tsx b/packages/elements/src/controls.tsx index 2132cbb1..38dba8cc 100644 --- a/packages/elements/src/controls.tsx +++ b/packages/elements/src/controls.tsx @@ -1,8 +1,9 @@ "use client"; +import type { ComponentProps } from "react"; + import { cn } from "@repo/shadcn-ui/lib/utils"; import { Controls as ControlsPrimitive } from "@xyflow/react"; -import type { ComponentProps } from "react"; export type ControlsProps = ComponentProps; diff --git a/packages/elements/src/conversation.tsx b/packages/elements/src/conversation.tsx index 389b8d12..3fb3ab1e 100644 --- a/packages/elements/src/conversation.tsx +++ b/packages/elements/src/conversation.tsx @@ -1,10 +1,11 @@ "use client"; +import type { UIMessage } from "ai"; +import type { ComponentProps } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { UIMessage } from "ai"; import { ArrowDownIcon, DownloadIcon } from "lucide-react"; -import type { ComponentProps } from "react"; import { useCallback } from "react"; import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom"; diff --git a/packages/elements/src/edge.tsx b/packages/elements/src/edge.tsx index c481e4e3..d2ed51ce 100644 --- a/packages/elements/src/edge.tsx +++ b/packages/elements/src/edge.tsx @@ -1,4 +1,5 @@ import type { EdgeProps, InternalNode, Node } from "@xyflow/react"; + import { BaseEdge, getBezierPath, diff --git a/packages/elements/src/environment-variables.tsx b/packages/elements/src/environment-variables.tsx index 9978bd37..cf6145b5 100644 --- a/packages/elements/src/environment-variables.tsx +++ b/packages/elements/src/environment-variables.tsx @@ -1,11 +1,12 @@ "use client"; +import type { ComponentProps, HTMLAttributes } from "react"; + import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { Switch } from "@repo/shadcn-ui/components/ui/switch"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { CheckIcon, CopyIcon, EyeIcon, EyeOffIcon } from "lucide-react"; -import type { ComponentProps, HTMLAttributes } from "react"; import { createContext, useCallback, diff --git a/packages/elements/src/file-tree.tsx b/packages/elements/src/file-tree.tsx index 6c1f8441..1ae13c31 100644 --- a/packages/elements/src/file-tree.tsx +++ b/packages/elements/src/file-tree.tsx @@ -1,5 +1,7 @@ "use client"; +import type { HTMLAttributes, ReactNode } from "react"; + import { Collapsible, CollapsibleContent, @@ -12,7 +14,6 @@ import { FolderIcon, FolderOpenIcon, } from "lucide-react"; -import type { HTMLAttributes, ReactNode } from "react"; import { createContext, useCallback, diff --git a/packages/elements/src/image.tsx b/packages/elements/src/image.tsx index 4c812b6e..2deb8898 100644 --- a/packages/elements/src/image.tsx +++ b/packages/elements/src/image.tsx @@ -1,6 +1,7 @@ -import { cn } from "@repo/shadcn-ui/lib/utils"; import type { Experimental_GeneratedImage } from "ai"; +import { cn } from "@repo/shadcn-ui/lib/utils"; + export type ImageProps = Experimental_GeneratedImage & { className?: string; alt?: string; diff --git a/packages/elements/src/inline-citation.tsx b/packages/elements/src/inline-citation.tsx index 171c81cf..054a1dec 100644 --- a/packages/elements/src/inline-citation.tsx +++ b/packages/elements/src/inline-citation.tsx @@ -1,7 +1,9 @@ "use client"; -import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import type { CarouselApi } from "@repo/shadcn-ui/components/ui/carousel"; +import type { ComponentProps } from "react"; + +import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import { Carousel, CarouselContent, @@ -14,7 +16,6 @@ import { } from "@repo/shadcn-ui/components/ui/hover-card"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react"; -import type { ComponentProps } from "react"; import { createContext, useCallback, diff --git a/packages/elements/src/jsx-preview.tsx b/packages/elements/src/jsx-preview.tsx index 22709929..fa8ee5c4 100644 --- a/packages/elements/src/jsx-preview.tsx +++ b/packages/elements/src/jsx-preview.tsx @@ -1,8 +1,10 @@ "use client"; +import type { ComponentProps, ReactNode } from "react"; +import type { TProps as JsxParserProps } from "react-jsx-parser"; + import { cn } from "@repo/shadcn-ui/lib/utils"; import { AlertCircle } from "lucide-react"; -import type { ComponentProps, ReactNode } from "react"; import { createContext, memo, @@ -13,7 +15,6 @@ import { useRef, useState, } from "react"; -import type { TProps as JsxParserProps } from "react-jsx-parser"; import JsxParser from "react-jsx-parser"; interface JSXPreviewContextValue { diff --git a/packages/elements/src/message.tsx b/packages/elements/src/message.tsx index c04a3993..60f1d164 100644 --- a/packages/elements/src/message.tsx +++ b/packages/elements/src/message.tsx @@ -1,5 +1,8 @@ "use client"; +import type { UIMessage } from "ai"; +import type { ComponentProps, HTMLAttributes, ReactElement } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ButtonGroup, @@ -16,9 +19,7 @@ import { cjk } from "@streamdown/cjk"; import { code } from "@streamdown/code"; import { math } from "@streamdown/math"; import { mermaid } from "@streamdown/mermaid"; -import type { UIMessage } from "ai"; import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"; -import type { ComponentProps, HTMLAttributes, ReactElement } from "react"; import { createContext, memo, diff --git a/packages/elements/src/mic-selector.tsx b/packages/elements/src/mic-selector.tsx index 44528226..49798aad 100644 --- a/packages/elements/src/mic-selector.tsx +++ b/packages/elements/src/mic-selector.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps, ReactNode } from "react"; + import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { @@ -16,7 +18,6 @@ import { } from "@repo/shadcn-ui/components/ui/popover"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ChevronsUpDownIcon } from "lucide-react"; -import type { ComponentProps, ReactNode } from "react"; import { createContext, useCallback, diff --git a/packages/elements/src/model-selector.tsx b/packages/elements/src/model-selector.tsx index 25b717bc..394bec9f 100644 --- a/packages/elements/src/model-selector.tsx +++ b/packages/elements/src/model-selector.tsx @@ -1,3 +1,5 @@ +import type { ComponentProps, ReactNode } from "react"; + import { Command, CommandDialog, @@ -16,7 +18,6 @@ import { DialogTrigger, } from "@repo/shadcn-ui/components/ui/dialog"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ComponentProps, ReactNode } from "react"; export type ModelSelectorProps = ComponentProps; @@ -42,6 +43,7 @@ export const ModelSelectorContent = ({ }: ModelSelectorContentProps) => ( ( ); -export type ModelSelectorItemProps = ComponentProps; +export type ModelSelectorItemProps = ComponentProps & { + checked?: boolean; +}; -export const ModelSelectorItem = (props: ModelSelectorItemProps) => ( - +export const ModelSelectorItem = ({ + checked, + ...props +}: ModelSelectorItemProps) => ( + ); export type ModelSelectorShortcutProps = ComponentProps; diff --git a/packages/elements/src/node.tsx b/packages/elements/src/node.tsx index fb1f24b5..d196d8c4 100644 --- a/packages/elements/src/node.tsx +++ b/packages/elements/src/node.tsx @@ -1,3 +1,5 @@ +import type { ComponentProps } from "react"; + import { Card, CardAction, @@ -9,7 +11,6 @@ import { } from "@repo/shadcn-ui/components/ui/card"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { Handle, Position } from "@xyflow/react"; -import type { ComponentProps } from "react"; export type NodeProps = ComponentProps & { handles: { diff --git a/packages/elements/src/open-in-chat.tsx b/packages/elements/src/open-in-chat.tsx index 8df484cd..ee3dd746 100644 --- a/packages/elements/src/open-in-chat.tsx +++ b/packages/elements/src/open-in-chat.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { DropdownMenu, @@ -15,7 +17,6 @@ import { ExternalLinkIcon, MessageCircleIcon, } from "lucide-react"; -import type { ComponentProps } from "react"; import { createContext, useContext, useMemo } from "react"; const providers = { diff --git a/packages/elements/src/package-info.tsx b/packages/elements/src/package-info.tsx index 75522640..f6fdc9fa 100644 --- a/packages/elements/src/package-info.tsx +++ b/packages/elements/src/package-info.tsx @@ -1,9 +1,10 @@ "use client"; +import type { HTMLAttributes } from "react"; + import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ArrowRightIcon, MinusIcon, PackageIcon, PlusIcon } from "lucide-react"; -import type { HTMLAttributes } from "react"; import { createContext, useContext, useMemo } from "react"; type ChangeType = "major" | "minor" | "patch" | "added" | "removed"; diff --git a/packages/elements/src/panel.tsx b/packages/elements/src/panel.tsx index 34a7fb35..7a7d4280 100644 --- a/packages/elements/src/panel.tsx +++ b/packages/elements/src/panel.tsx @@ -1,6 +1,7 @@ +import type { ComponentProps } from "react"; + import { cn } from "@repo/shadcn-ui/lib/utils"; import { Panel as PanelPrimitive } from "@xyflow/react"; -import type { ComponentProps } from "react"; type PanelProps = ComponentProps; diff --git a/packages/elements/src/persona.tsx b/packages/elements/src/persona.tsx index 521d23ce..dec50e1f 100644 --- a/packages/elements/src/persona.tsx +++ b/packages/elements/src/persona.tsx @@ -1,7 +1,9 @@ "use client"; -import { cn } from "@repo/shadcn-ui/lib/utils"; import type { RiveParameters } from "@rive-app/react-webgl2"; +import type { FC, ReactNode } from "react"; + +import { cn } from "@repo/shadcn-ui/lib/utils"; import { useRive, useStateMachineInput, @@ -9,7 +11,6 @@ import { useViewModelInstance, useViewModelInstanceColor, } from "@rive-app/react-webgl2"; -import type { FC, ReactNode } from "react"; import { memo, useEffect, useMemo, useRef, useState } from "react"; // Delays Rive initialization by one frame so that React Strict Mode's diff --git a/packages/elements/src/plan.tsx b/packages/elements/src/plan.tsx index cce50c74..8e237554 100644 --- a/packages/elements/src/plan.tsx +++ b/packages/elements/src/plan.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { Card, @@ -17,7 +19,6 @@ import { } from "@repo/shadcn-ui/components/ui/collapsible"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ChevronsUpDownIcon } from "lucide-react"; -import type { ComponentProps } from "react"; import { createContext, useContext, useMemo } from "react"; import { Shimmer } from "./shimmer"; diff --git a/packages/elements/src/prompt-input.tsx b/packages/elements/src/prompt-input.tsx index 412c846d..fc18e7fc 100644 --- a/packages/elements/src/prompt-input.tsx +++ b/packages/elements/src/prompt-input.tsx @@ -1,5 +1,20 @@ "use client"; +import type { ChatStatus, FileUIPart, SourceDocumentUIPart } from "ai"; +import type { + ChangeEvent, + ChangeEventHandler, + ClipboardEventHandler, + ComponentProps, + FormEvent, + FormEventHandler, + HTMLAttributes, + KeyboardEventHandler, + PropsWithChildren, + ReactNode, + RefObject, +} from "react"; + import { Command, CommandEmpty, @@ -40,7 +55,6 @@ import { TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ChatStatus, FileUIPart, SourceDocumentUIPart } from "ai"; import { CornerDownLeftIcon, ImageIcon, @@ -50,19 +64,6 @@ import { XIcon, } from "lucide-react"; import { nanoid } from "nanoid"; -import type { - ChangeEvent, - ChangeEventHandler, - ClipboardEventHandler, - ComponentProps, - FormEvent, - FormEventHandler, - HTMLAttributes, - KeyboardEventHandler, - PropsWithChildren, - ReactNode, - RefObject, -} from "react"; import { Children, createContext, diff --git a/packages/elements/src/queue.tsx b/packages/elements/src/queue.tsx index efe793cb..ae3e4116 100644 --- a/packages/elements/src/queue.tsx +++ b/packages/elements/src/queue.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { Collapsible, @@ -9,7 +11,6 @@ import { import { ScrollArea } from "@repo/shadcn-ui/components/ui/scroll-area"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ChevronDownIcon, PaperclipIcon } from "lucide-react"; -import type { ComponentProps } from "react"; export interface QueueMessagePart { type: string; diff --git a/packages/elements/src/reasoning.tsx b/packages/elements/src/reasoning.tsx index 4789ee2a..db7e93a2 100644 --- a/packages/elements/src/reasoning.tsx +++ b/packages/elements/src/reasoning.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps, ReactNode } from "react"; + import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { Collapsible, @@ -12,7 +14,6 @@ import { code } from "@streamdown/code"; import { math } from "@streamdown/math"; import { mermaid } from "@streamdown/mermaid"; import { BrainIcon, ChevronDownIcon } from "lucide-react"; -import type { ComponentProps, ReactNode } from "react"; import { createContext, memo, diff --git a/packages/elements/src/sandbox.tsx b/packages/elements/src/sandbox.tsx index 48e2ba73..930c67d0 100644 --- a/packages/elements/src/sandbox.tsx +++ b/packages/elements/src/sandbox.tsx @@ -1,5 +1,8 @@ "use client"; +import type { ToolUIPart } from "ai"; +import type { ComponentProps } from "react"; + import { Collapsible, CollapsibleContent, @@ -12,9 +15,7 @@ import { TabsTrigger, } from "@repo/shadcn-ui/components/ui/tabs"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ToolUIPart } from "ai"; import { ChevronDownIcon, Code } from "lucide-react"; -import type { ComponentProps } from "react"; import { getStatusBadge } from "./tool"; diff --git a/packages/elements/src/schema-display.tsx b/packages/elements/src/schema-display.tsx index d3d4c691..eb9107f0 100644 --- a/packages/elements/src/schema-display.tsx +++ b/packages/elements/src/schema-display.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps, HTMLAttributes } from "react"; + import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import { Collapsible, @@ -8,7 +10,6 @@ import { } from "@repo/shadcn-ui/components/ui/collapsible"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ChevronRightIcon } from "lucide-react"; -import type { ComponentProps, HTMLAttributes } from "react"; import { createContext, useContext, useMemo } from "react"; type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; diff --git a/packages/elements/src/shimmer.tsx b/packages/elements/src/shimmer.tsx index b4f42cc5..3d38d5a7 100644 --- a/packages/elements/src/shimmer.tsx +++ b/packages/elements/src/shimmer.tsx @@ -1,9 +1,10 @@ "use client"; -import { cn } from "@repo/shadcn-ui/lib/utils"; import type { MotionProps } from "motion/react"; -import { motion } from "motion/react"; import type { CSSProperties, ElementType, JSX } from "react"; + +import { cn } from "@repo/shadcn-ui/lib/utils"; +import { motion } from "motion/react"; import { memo, useMemo } from "react"; type MotionHTMLProps = MotionProps & Record; diff --git a/packages/elements/src/snippet.tsx b/packages/elements/src/snippet.tsx index e9d9df92..c671371a 100644 --- a/packages/elements/src/snippet.tsx +++ b/packages/elements/src/snippet.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps } from "react"; + import { InputGroup, InputGroupAddon, @@ -9,7 +11,6 @@ import { } from "@repo/shadcn-ui/components/ui/input-group"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { CheckIcon, CopyIcon } from "lucide-react"; -import type { ComponentProps } from "react"; import { createContext, useCallback, diff --git a/packages/elements/src/sources.tsx b/packages/elements/src/sources.tsx index 8c5d559a..f49de87d 100644 --- a/packages/elements/src/sources.tsx +++ b/packages/elements/src/sources.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps } from "react"; + import { Collapsible, CollapsibleContent, @@ -7,7 +9,6 @@ import { } from "@repo/shadcn-ui/components/ui/collapsible"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { BookIcon, ChevronDownIcon } from "lucide-react"; -import type { ComponentProps } from "react"; export type SourcesProps = ComponentProps<"div">; diff --git a/packages/elements/src/speech-input.tsx b/packages/elements/src/speech-input.tsx index a447e190..b823811e 100644 --- a/packages/elements/src/speech-input.tsx +++ b/packages/elements/src/speech-input.tsx @@ -1,10 +1,11 @@ "use client"; +import type { ComponentProps } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { Spinner } from "@repo/shadcn-ui/components/ui/spinner"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { MicIcon, SquareIcon } from "lucide-react"; -import type { ComponentProps } from "react"; import { useCallback, useEffect, useRef, useState } from "react"; interface SpeechRecognition extends EventTarget { diff --git a/packages/elements/src/stack-trace.tsx b/packages/elements/src/stack-trace.tsx index 682b4cef..b2b8280a 100644 --- a/packages/elements/src/stack-trace.tsx +++ b/packages/elements/src/stack-trace.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps } from "react"; + import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { @@ -14,7 +16,6 @@ import { ChevronDownIcon, CopyIcon, } from "lucide-react"; -import type { ComponentProps } from "react"; import { createContext, memo, diff --git a/packages/elements/src/suggestion.tsx b/packages/elements/src/suggestion.tsx index a35a8eb6..8d627e79 100644 --- a/packages/elements/src/suggestion.tsx +++ b/packages/elements/src/suggestion.tsx @@ -1,12 +1,13 @@ "use client"; +import type { ComponentProps } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ScrollArea, ScrollBar, } from "@repo/shadcn-ui/components/ui/scroll-area"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ComponentProps } from "react"; import { useCallback } from "react"; export type SuggestionsProps = ComponentProps; diff --git a/packages/elements/src/task.tsx b/packages/elements/src/task.tsx index f30d4e34..b1d2e012 100644 --- a/packages/elements/src/task.tsx +++ b/packages/elements/src/task.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps } from "react"; + import { Collapsible, CollapsibleContent, @@ -7,7 +9,6 @@ import { } from "@repo/shadcn-ui/components/ui/collapsible"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ChevronDownIcon, SearchIcon } from "lucide-react"; -import type { ComponentProps } from "react"; export type TaskItemFileProps = ComponentProps<"div">; diff --git a/packages/elements/src/terminal.tsx b/packages/elements/src/terminal.tsx index cedf150b..22aee5f9 100644 --- a/packages/elements/src/terminal.tsx +++ b/packages/elements/src/terminal.tsx @@ -1,10 +1,11 @@ "use client"; +import type { ComponentProps, HTMLAttributes } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { cn } from "@repo/shadcn-ui/lib/utils"; import Ansi from "ansi-to-react"; import { CheckIcon, CopyIcon, TerminalIcon, Trash2Icon } from "lucide-react"; -import type { ComponentProps, HTMLAttributes } from "react"; import { createContext, useCallback, diff --git a/packages/elements/src/test-results.tsx b/packages/elements/src/test-results.tsx index 45532f3a..a907c4d2 100644 --- a/packages/elements/src/test-results.tsx +++ b/packages/elements/src/test-results.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps, HTMLAttributes } from "react"; + import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import { Collapsible, @@ -14,7 +16,6 @@ import { CircleIcon, XCircleIcon, } from "lucide-react"; -import type { ComponentProps, HTMLAttributes } from "react"; import { createContext, useContext, useMemo } from "react"; type TestStatus = "passed" | "failed" | "skipped" | "running"; diff --git a/packages/elements/src/tool.tsx b/packages/elements/src/tool.tsx index 9a22010e..24a208b7 100644 --- a/packages/elements/src/tool.tsx +++ b/packages/elements/src/tool.tsx @@ -1,5 +1,8 @@ "use client"; +import type { DynamicToolUIPart, ToolUIPart } from "ai"; +import type { ComponentProps, ReactNode } from "react"; + import { Badge } from "@repo/shadcn-ui/components/ui/badge"; import { Collapsible, @@ -7,7 +10,6 @@ import { CollapsibleTrigger, } from "@repo/shadcn-ui/components/ui/collapsible"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { DynamicToolUIPart, ToolUIPart } from "ai"; import { CheckCircleIcon, ChevronDownIcon, @@ -16,7 +18,6 @@ import { WrenchIcon, XCircleIcon, } from "lucide-react"; -import type { ComponentProps, ReactNode } from "react"; import { isValidElement } from "react"; import { CodeBlock } from "./code-block"; diff --git a/packages/elements/src/toolbar.tsx b/packages/elements/src/toolbar.tsx index 62ba1007..256d3b57 100644 --- a/packages/elements/src/toolbar.tsx +++ b/packages/elements/src/toolbar.tsx @@ -1,6 +1,7 @@ +import type { ComponentProps } from "react"; + import { cn } from "@repo/shadcn-ui/lib/utils"; import { NodeToolbar, Position } from "@xyflow/react"; -import type { ComponentProps } from "react"; type ToolbarProps = ComponentProps; diff --git a/packages/elements/src/transcription.tsx b/packages/elements/src/transcription.tsx index 9c0a29df..6358a0f7 100644 --- a/packages/elements/src/transcription.tsx +++ b/packages/elements/src/transcription.tsx @@ -1,9 +1,10 @@ "use client"; -import { useControllableState } from "@radix-ui/react-use-controllable-state"; -import { cn } from "@repo/shadcn-ui/lib/utils"; import type { Experimental_TranscriptionResult as TranscriptionResult } from "ai"; import type { ComponentProps, ReactNode } from "react"; + +import { useControllableState } from "@radix-ui/react-use-controllable-state"; +import { cn } from "@repo/shadcn-ui/lib/utils"; import { createContext, useCallback, useContext, useMemo } from "react"; type TranscriptionSegment = TranscriptionResult["segments"][number]; diff --git a/packages/elements/src/voice-selector.tsx b/packages/elements/src/voice-selector.tsx index b1ec2a93..32c3951e 100644 --- a/packages/elements/src/voice-selector.tsx +++ b/packages/elements/src/voice-selector.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps, ReactNode } from "react"; + import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { @@ -32,7 +34,6 @@ import { VenusAndMarsIcon, VenusIcon, } from "lucide-react"; -import type { ComponentProps, ReactNode } from "react"; import { createContext, useCallback, useContext, useMemo } from "react"; interface VoiceSelectorContextValue { diff --git a/packages/elements/src/web-preview.tsx b/packages/elements/src/web-preview.tsx index f3ac1c21..530f857e 100644 --- a/packages/elements/src/web-preview.tsx +++ b/packages/elements/src/web-preview.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps, ReactNode } from "react"; + import { Button } from "@repo/shadcn-ui/components/ui/button"; import { Collapsible, @@ -15,7 +17,6 @@ import { } from "@repo/shadcn-ui/components/ui/tooltip"; import { cn } from "@repo/shadcn-ui/lib/utils"; import { ChevronDownIcon } from "lucide-react"; -import type { ComponentProps, ReactNode } from "react"; import { createContext, useCallback, diff --git a/packages/elements/vitest.config.mts b/packages/elements/vitest.config.mts index 8e90c9b9..ebb0ad14 100644 --- a/packages/elements/vitest.config.mts +++ b/packages/elements/vitest.config.mts @@ -1,9 +1,8 @@ +import react from "@vitejs/plugin-react"; +import { playwright } from "@vitest/browser-playwright"; // Vitest config - Node.js modules are valid here // oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) import path from "node:path"; - -import react from "@vitejs/plugin-react"; -import { playwright } from "@vitest/browser-playwright"; import { defineConfig } from "vitest/config"; export default defineConfig({ diff --git a/packages/examples/src/audio-player.tsx b/packages/examples/src/audio-player.tsx index a97ade58..99813d70 100644 --- a/packages/examples/src/audio-player.tsx +++ b/packages/examples/src/audio-player.tsx @@ -1,5 +1,7 @@ "use client"; +import type { Experimental_SpeechResult as SpeechResult } from "ai"; + import { AudioPlayer, AudioPlayerControlBar, @@ -13,7 +15,6 @@ import { AudioPlayerTimeRange, AudioPlayerVolumeRange, } from "@repo/elements/audio-player"; -import type { Experimental_SpeechResult as SpeechResult } from "ai"; import { useEffect, useState } from "react"; const Example = () => { diff --git a/packages/examples/src/chatbot.tsx b/packages/examples/src/chatbot.tsx index 82213a69..2172b4e9 100644 --- a/packages/examples/src/chatbot.tsx +++ b/packages/examples/src/chatbot.tsx @@ -1,5 +1,8 @@ "use client"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; +import type { ToolUIPart } from "ai"; + import { Attachment, AttachmentPreview, @@ -35,7 +38,6 @@ import { ModelSelectorName, ModelSelectorTrigger, } from "@repo/elements/model-selector"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputActionAddAttachments, @@ -64,8 +66,7 @@ import { } from "@repo/elements/sources"; import { SpeechInput } from "@repo/elements/speech-input"; import { Suggestion, Suggestions } from "@repo/elements/suggestion"; -import type { ToolUIPart } from "ai"; -import { CheckIcon, GlobeIcon } from "lucide-react"; +import { GlobeIcon } from "lucide-react"; import { nanoid } from "nanoid"; import { useCallback, useMemo, useState } from "react"; import { toast } from "sonner"; @@ -416,7 +417,11 @@ const ModelItem = ({ }, [onSelect, m.id]); return ( - + {m.name} @@ -424,11 +429,6 @@ const ModelItem = ({ ))} - {isSelected ? ( - - ) : ( -
- )} ); }; diff --git a/packages/examples/src/code-block.tsx b/packages/examples/src/code-block.tsx index fa885d85..ed9830af 100644 --- a/packages/examples/src/code-block.tsx +++ b/packages/examples/src/code-block.tsx @@ -1,5 +1,7 @@ "use client"; +import type { BundledLanguage } from "shiki"; + import { CodeBlock, CodeBlockActions, @@ -15,7 +17,6 @@ import { } from "@repo/elements/code-block"; import { FileIcon } from "lucide-react"; import { useCallback, useState } from "react"; -import type { BundledLanguage } from "shiki"; const codeExamples = { go: { diff --git a/packages/examples/src/demo-chatgpt.tsx b/packages/examples/src/demo-chatgpt.tsx index c0ad36fc..2ed21033 100644 --- a/packages/examples/src/demo-chatgpt.tsx +++ b/packages/examples/src/demo-chatgpt.tsx @@ -1,5 +1,8 @@ "use client"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; +import type { ToolUIPart } from "ai"; + import { Conversation, ConversationContent, @@ -16,7 +19,6 @@ import { MessageContent, MessageResponse, } from "@repo/elements/message"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputButton, @@ -43,7 +45,6 @@ import { DropdownMenuTrigger, } from "@repo/shadcn-ui/components/ui/dropdown-menu"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ToolUIPart } from "ai"; import { AudioWaveformIcon, BarChartIcon, diff --git a/packages/examples/src/demo-claude.tsx b/packages/examples/src/demo-claude.tsx index f0731a79..28b5777e 100644 --- a/packages/examples/src/demo-claude.tsx +++ b/packages/examples/src/demo-claude.tsx @@ -1,5 +1,8 @@ "use client"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; +import type { ToolUIPart } from "ai"; + import { Conversation, ConversationContent, @@ -29,7 +32,6 @@ import { ModelSelectorName, ModelSelectorTrigger, } from "@repo/elements/model-selector"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputButton, @@ -56,11 +58,9 @@ import { DropdownMenuTrigger, } from "@repo/shadcn-ui/components/ui/dropdown-menu"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ToolUIPart } from "ai"; import { ArrowUpIcon, CameraIcon, - CheckIcon, FileIcon, ImageIcon, PlusIcon, @@ -328,7 +328,12 @@ interface ModelItemProps { const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { const handleSelect = useCallback(() => onSelect(m.id), [onSelect, m.id]); return ( - + {m.name} @@ -336,11 +341,6 @@ const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { ))} - {selectedModel === m.id ? ( - - ) : ( -
- )} ); }); diff --git a/packages/examples/src/demo-cursor.tsx b/packages/examples/src/demo-cursor.tsx index ec47b3c0..0c744ea0 100644 --- a/packages/examples/src/demo-cursor.tsx +++ b/packages/examples/src/demo-cursor.tsx @@ -1,5 +1,8 @@ "use client"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; +import type { BundledLanguage } from "shiki"; + import { Checkpoint, CheckpointIcon, @@ -26,7 +29,6 @@ import { PlanTitle, PlanTrigger, } from "@repo/elements/plan"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputFooter, @@ -55,7 +57,6 @@ import { cn } from "@repo/shadcn-ui/lib/utils"; import { CheckCircle2Icon, ListTodoIcon } from "lucide-react"; import { nanoid } from "nanoid"; import { useCallback, useEffect, useState } from "react"; -import type { BundledLanguage } from "shiki"; // Types interface MockFile { diff --git a/packages/examples/src/demo-grok.tsx b/packages/examples/src/demo-grok.tsx index dcfa51ec..79fba523 100644 --- a/packages/examples/src/demo-grok.tsx +++ b/packages/examples/src/demo-grok.tsx @@ -1,5 +1,8 @@ "use client"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; +import type { ToolUIPart } from "ai"; + import { Conversation, ConversationContent, @@ -29,7 +32,6 @@ import { ModelSelectorName, ModelSelectorTrigger, } from "@repo/elements/model-selector"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputButton, @@ -55,11 +57,9 @@ import { DropdownMenuTrigger, } from "@repo/shadcn-ui/components/ui/dropdown-menu"; import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ToolUIPart } from "ai"; import { AudioWaveformIcon, CameraIcon, - CheckIcon, ChevronDownIcon, FileIcon, ImageIcon, @@ -323,7 +323,12 @@ const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { const handleSelect = useCallback(() => onSelect(m.id), [onSelect, m.id]); return ( - + {m.name} @@ -331,11 +336,6 @@ const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { ))} - {selectedModel === m.id ? ( - - ) : ( -
- )} ); }); diff --git a/packages/examples/src/model-selector.tsx b/packages/examples/src/model-selector.tsx index 2e8ff02f..9f39e55b 100644 --- a/packages/examples/src/model-selector.tsx +++ b/packages/examples/src/model-selector.tsx @@ -14,7 +14,6 @@ import { ModelSelectorTrigger, } from "@repo/elements/model-selector"; import { Button } from "@repo/shadcn-ui/components/ui/button"; -import { CheckIcon } from "lucide-react"; import { memo, useCallback, useState } from "react"; const models = [ @@ -291,7 +290,12 @@ const ModelItem = memo(({ model, selectedModel, onSelect }: ModelItemProps) => { [onSelect, model.id] ); return ( - + {model.name} @@ -299,11 +303,6 @@ const ModelItem = memo(({ model, selectedModel, onSelect }: ModelItemProps) => { ))} - {selectedModel === model.id ? ( - - ) : ( -
- )} ); }); diff --git a/packages/examples/src/persona-command.tsx b/packages/examples/src/persona-command.tsx index 991bef0c..80223a54 100644 --- a/packages/examples/src/persona-command.tsx +++ b/packages/examples/src/persona-command.tsx @@ -1,6 +1,8 @@ "use client"; import type { PersonaState } from "@repo/elements/persona"; +import type { LucideIcon } from "lucide-react"; + import { Persona } from "@repo/elements/persona"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ButtonGroup } from "@repo/shadcn-ui/components/ui/button-group"; @@ -9,7 +11,6 @@ import { TooltipContent, TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; -import type { LucideIcon } from "lucide-react"; import { BrainIcon, CircleIcon, diff --git a/packages/examples/src/persona-glint.tsx b/packages/examples/src/persona-glint.tsx index 6b7b521a..32c21647 100644 --- a/packages/examples/src/persona-glint.tsx +++ b/packages/examples/src/persona-glint.tsx @@ -1,6 +1,8 @@ "use client"; import type { PersonaState } from "@repo/elements/persona"; +import type { LucideIcon } from "lucide-react"; + import { Persona } from "@repo/elements/persona"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ButtonGroup } from "@repo/shadcn-ui/components/ui/button-group"; @@ -9,7 +11,6 @@ import { TooltipContent, TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; -import type { LucideIcon } from "lucide-react"; import { BrainIcon, CircleIcon, diff --git a/packages/examples/src/persona-halo.tsx b/packages/examples/src/persona-halo.tsx index bb80eb74..983bf503 100644 --- a/packages/examples/src/persona-halo.tsx +++ b/packages/examples/src/persona-halo.tsx @@ -1,6 +1,8 @@ "use client"; import type { PersonaState } from "@repo/elements/persona"; +import type { LucideIcon } from "lucide-react"; + import { Persona } from "@repo/elements/persona"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ButtonGroup } from "@repo/shadcn-ui/components/ui/button-group"; @@ -9,7 +11,6 @@ import { TooltipContent, TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; -import type { LucideIcon } from "lucide-react"; import { BrainIcon, CircleIcon, diff --git a/packages/examples/src/persona-mana.tsx b/packages/examples/src/persona-mana.tsx index 0497a855..2654cc35 100644 --- a/packages/examples/src/persona-mana.tsx +++ b/packages/examples/src/persona-mana.tsx @@ -1,6 +1,8 @@ "use client"; import type { PersonaState } from "@repo/elements/persona"; +import type { LucideIcon } from "lucide-react"; + import { Persona } from "@repo/elements/persona"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ButtonGroup } from "@repo/shadcn-ui/components/ui/button-group"; @@ -9,7 +11,6 @@ import { TooltipContent, TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; -import type { LucideIcon } from "lucide-react"; import { BrainIcon, CircleIcon, diff --git a/packages/examples/src/persona-obsidian.tsx b/packages/examples/src/persona-obsidian.tsx index 011551be..8b84f68d 100644 --- a/packages/examples/src/persona-obsidian.tsx +++ b/packages/examples/src/persona-obsidian.tsx @@ -1,6 +1,8 @@ "use client"; import type { PersonaState } from "@repo/elements/persona"; +import type { LucideIcon } from "lucide-react"; + import { Persona } from "@repo/elements/persona"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ButtonGroup } from "@repo/shadcn-ui/components/ui/button-group"; @@ -9,7 +11,6 @@ import { TooltipContent, TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; -import type { LucideIcon } from "lucide-react"; import { BrainIcon, CircleIcon, diff --git a/packages/examples/src/persona-opal.tsx b/packages/examples/src/persona-opal.tsx index c7869dfa..b35720f9 100644 --- a/packages/examples/src/persona-opal.tsx +++ b/packages/examples/src/persona-opal.tsx @@ -1,6 +1,8 @@ "use client"; import type { PersonaState } from "@repo/elements/persona"; +import type { LucideIcon } from "lucide-react"; + import { Persona } from "@repo/elements/persona"; import { Button } from "@repo/shadcn-ui/components/ui/button"; import { ButtonGroup } from "@repo/shadcn-ui/components/ui/button-group"; @@ -9,7 +11,6 @@ import { TooltipContent, TooltipTrigger, } from "@repo/shadcn-ui/components/ui/tooltip"; -import type { LucideIcon } from "lucide-react"; import { BrainIcon, CircleIcon, diff --git a/packages/examples/src/prompt-input-cursor.tsx b/packages/examples/src/prompt-input-cursor.tsx index 663d08f9..687b29f1 100644 --- a/packages/examples/src/prompt-input-cursor.tsx +++ b/packages/examples/src/prompt-input-cursor.tsx @@ -1,6 +1,9 @@ "use client"; import type { AttachmentData } from "@repo/elements/attachments"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; +import type { SourceDocumentUIPart } from "ai"; + import { Attachment, AttachmentInfo, @@ -21,7 +24,6 @@ import { ModelSelectorName, ModelSelectorTrigger, } from "@repo/elements/model-selector"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputBody, @@ -50,10 +52,8 @@ import { usePromptInputReferencedSources, } from "@repo/elements/prompt-input"; import { Button } from "@repo/shadcn-ui/components/ui/button"; -import type { SourceDocumentUIPart } from "ai"; import { AtSignIcon, - CheckIcon, FilesIcon, GlobeIcon, ImageIcon, @@ -152,7 +152,12 @@ interface ModelItemProps { const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { const handleSelect = useCallback(() => onSelect(m.id), [onSelect, m.id]); return ( - + {m.name} @@ -160,11 +165,6 @@ const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { ))} - {selectedModel === m.id ? ( - - ) : ( -
- )} ); }); diff --git a/packages/examples/src/prompt-input.tsx b/packages/examples/src/prompt-input.tsx index d9411794..d89e00fb 100644 --- a/packages/examples/src/prompt-input.tsx +++ b/packages/examples/src/prompt-input.tsx @@ -1,5 +1,7 @@ "use client"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; + import { Attachment, AttachmentPreview, @@ -19,7 +21,6 @@ import { ModelSelectorName, ModelSelectorTrigger, } from "@repo/elements/model-selector"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputActionAddAttachments, @@ -36,7 +37,7 @@ import { PromptInputTools, usePromptInputAttachments, } from "@repo/elements/prompt-input"; -import { CheckIcon, GlobeIcon } from "lucide-react"; +import { GlobeIcon } from "lucide-react"; import { memo, useCallback, useState } from "react"; const models = [ @@ -115,7 +116,12 @@ interface ModelItemProps { const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { const handleSelect = useCallback(() => onSelect(m.id), [onSelect, m.id]); return ( - + {m.name} @@ -123,11 +129,6 @@ const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { ))} - {selectedModel === m.id ? ( - - ) : ( -
- )} ); }); diff --git a/packages/examples/src/queue-prompt-input.tsx b/packages/examples/src/queue-prompt-input.tsx index dbf35358..f56b192d 100644 --- a/packages/examples/src/queue-prompt-input.tsx +++ b/packages/examples/src/queue-prompt-input.tsx @@ -1,5 +1,8 @@ "use client"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; +import type { QueueTodo } from "@repo/elements/queue"; + import { Attachment, AttachmentPreview, @@ -19,7 +22,6 @@ import { ModelSelectorName, ModelSelectorTrigger, } from "@repo/elements/model-selector"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputActionAddAttachments, @@ -35,7 +37,6 @@ import { PromptInputTools, usePromptInputAttachments, } from "@repo/elements/prompt-input"; -import type { QueueTodo } from "@repo/elements/queue"; import { Queue, QueueItem, @@ -47,7 +48,7 @@ import { QueueSection, QueueSectionContent, } from "@repo/elements/queue"; -import { CheckIcon, GlobeIcon, Trash2 } from "lucide-react"; +import { GlobeIcon, Trash2 } from "lucide-react"; import { memo, useCallback, useRef, useState } from "react"; const models = [ @@ -162,7 +163,12 @@ interface ModelItemProps { const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { const handleSelect = useCallback(() => onSelect(m.id), [onSelect, m.id]); return ( - + {m.name} @@ -170,11 +176,6 @@ const ModelItem = memo(({ m, selectedModel, onSelect }: ModelItemProps) => { ))} - {selectedModel === m.id ? ( - - ) : ( -
- )} ); }); diff --git a/packages/examples/src/queue.tsx b/packages/examples/src/queue.tsx index 0ad370c4..90021bbc 100644 --- a/packages/examples/src/queue.tsx +++ b/packages/examples/src/queue.tsx @@ -1,6 +1,7 @@ "use client"; import type { QueueMessage, QueueTodo } from "@repo/elements/queue"; + import { Queue, QueueItem, diff --git a/packages/examples/src/sandbox.tsx b/packages/examples/src/sandbox.tsx index 18e1c6c3..93ccc536 100644 --- a/packages/examples/src/sandbox.tsx +++ b/packages/examples/src/sandbox.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ToolUIPart } from "ai"; + import { CodeBlock, CodeBlockCopyButton } from "@repo/elements/code-block"; import { Sandbox, @@ -24,7 +26,6 @@ import { StackTraceHeader, } from "@repo/elements/stack-trace"; import { Button } from "@repo/shadcn-ui/components/ui/button"; -import type { ToolUIPart } from "ai"; import { memo, useCallback, useState } from "react"; const code = `import math diff --git a/packages/examples/src/suggestion-input.tsx b/packages/examples/src/suggestion-input.tsx index 2d927cc0..223e003b 100644 --- a/packages/examples/src/suggestion-input.tsx +++ b/packages/examples/src/suggestion-input.tsx @@ -1,6 +1,7 @@ "use client"; import type { PromptInputMessage } from "@repo/elements/prompt-input"; + import { PromptInput, PromptInputButton, diff --git a/packages/examples/src/task.tsx b/packages/examples/src/task.tsx index 0f597a54..b7e2bee8 100644 --- a/packages/examples/src/task.tsx +++ b/packages/examples/src/task.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ReactNode } from "react"; + import { SiReact } from "@icons-pack/react-simple-icons"; import { Task, @@ -9,7 +11,6 @@ import { TaskTrigger, } from "@repo/elements/task"; import { nanoid } from "nanoid"; -import type { ReactNode } from "react"; const Example = () => { const tasks: { key: string; value: ReactNode }[] = [ diff --git a/packages/examples/src/tool-output-available.tsx b/packages/examples/src/tool-output-available.tsx index 5dbb898d..a209edb4 100644 --- a/packages/examples/src/tool-output-available.tsx +++ b/packages/examples/src/tool-output-available.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ToolUIPart } from "ai"; + import { CodeBlock } from "@repo/elements/code-block"; import { Tool, @@ -8,7 +10,6 @@ import { ToolInput, ToolOutput, } from "@repo/elements/tool"; -import type { ToolUIPart } from "ai"; import { nanoid } from "nanoid"; const toolCall: ToolUIPart = { diff --git a/packages/examples/src/tool-output-error.tsx b/packages/examples/src/tool-output-error.tsx index 596961c3..2ddc24a1 100644 --- a/packages/examples/src/tool-output-error.tsx +++ b/packages/examples/src/tool-output-error.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ToolUIPart } from "ai"; + import { Tool, ToolContent, @@ -7,7 +9,6 @@ import { ToolInput, ToolOutput, } from "@repo/elements/tool"; -import type { ToolUIPart } from "ai"; const toolCall: ToolUIPart = { errorText: diff --git a/packages/examples/src/tool.tsx b/packages/examples/src/tool.tsx index d24d71aa..59e69e56 100644 --- a/packages/examples/src/tool.tsx +++ b/packages/examples/src/tool.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ToolUIPart } from "ai"; + import { Confirmation, ConfirmationAccepted, @@ -16,7 +18,6 @@ import { ToolInput, ToolOutput, } from "@repo/elements/tool"; -import type { ToolUIPart } from "ai"; import { CheckIcon, XIcon } from "lucide-react"; import { nanoid } from "nanoid"; diff --git a/packages/examples/src/transcription.tsx b/packages/examples/src/transcription.tsx index c2d5adf7..d6820dc4 100644 --- a/packages/examples/src/transcription.tsx +++ b/packages/examples/src/transcription.tsx @@ -1,10 +1,11 @@ "use client"; +import type { Experimental_TranscriptionResult as TranscriptionResult } from "ai"; + import { Transcription, TranscriptionSegment, } from "@repo/elements/transcription"; -import type { Experimental_TranscriptionResult as TranscriptionResult } from "ai"; import { useCallback, useRef, useState } from "react"; const segments: TranscriptionResult["segments"] = [ diff --git a/packages/examples/src/v0-clone.tsx b/packages/examples/src/v0-clone.tsx index e16c77ac..ba31ae27 100644 --- a/packages/examples/src/v0-clone.tsx +++ b/packages/examples/src/v0-clone.tsx @@ -1,8 +1,9 @@ "use client"; +import type { PromptInputMessage } from "@repo/elements/prompt-input"; + import { Conversation, ConversationContent } from "@repo/elements/conversation"; import { Message, MessageContent } from "@repo/elements/message"; -import type { PromptInputMessage } from "@repo/elements/prompt-input"; import { PromptInput, PromptInputSubmit, @@ -87,13 +88,14 @@ export default function Home() { const [message, setMessage] = useState(""); const [currentChat, setCurrentChat] = useState(mockChat); const [isLoading, setIsLoading] = useState(false); - const [chatHistory, setChatHistory] = useState< - { - id: string; - type: "user" | "assistant"; - content: string; - }[] - >(mockChatHistory); + const [chatHistory, setChatHistory] = + useState< + { + id: string; + type: "user" | "assistant"; + content: string; + }[] + >(mockChatHistory); const handleSendMessage = useCallback( async (promptMessage: PromptInputMessage) => { diff --git a/packages/examples/src/voice-selector.tsx b/packages/examples/src/voice-selector.tsx index 5b48d1e2..839b8b5e 100644 --- a/packages/examples/src/voice-selector.tsx +++ b/packages/examples/src/voice-selector.tsx @@ -1,5 +1,7 @@ "use client"; +import type { ComponentProps } from "react"; + import { VoiceSelector, VoiceSelectorAccent, @@ -17,7 +19,6 @@ import { VoiceSelectorTrigger, } from "@repo/elements/voice-selector"; import { Button } from "@repo/shadcn-ui/components/ui/button"; -import type { ComponentProps } from "react"; import { memo, useCallback, useRef, useState } from "react"; const voices: { diff --git a/packages/scripts/src/generate-skills.ts b/packages/scripts/src/generate-skills.ts index 9c41dc38..c070910c 100644 --- a/packages/scripts/src/generate-skills.ts +++ b/packages/scripts/src/generate-skills.ts @@ -1,3 +1,4 @@ +import matter from "gray-matter"; // Node.js script - Node.js modules are valid here // oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) import { existsSync, mkdirSync, rmSync } from "node:fs"; @@ -6,8 +7,6 @@ import { readdir, readFile, writeFile } from "node:fs/promises"; // oxlint-disable-next-line eslint-plugin-import(no-nodejs-modules) import { basename, join } from "node:path"; -import matter from "gray-matter"; - const ROOT_DIR = join(import.meta.dirname, "../../.."); const CONTENT_DIR = join(ROOT_DIR, "apps/docs/content"); const COMPONENTS_DIR = join(CONTENT_DIR, "components"); @@ -167,7 +166,7 @@ const processComponent = async (mdxPath: string): Promise => { const referencesDir = join(SKILL_DIR, "references"); const scriptsDir = join(SKILL_DIR, "scripts"); - const fileContent = await readFile(mdxPath, "utf8"); + const fileContent = await readFile(mdxPath, "utf-8"); const { data } = matter(fileContent); const referenceContent = `# ${data.title} @@ -187,7 +186,7 @@ ${transformComponentMdx(fileContent)} for (const example of examples) { const exampleContent = await readFile( join(EXAMPLES_DIR, example), - "utf8" + "utf-8" ); const transformedContent = exampleContent .replaceAll("@repo/shadcn-ui/", "@/") diff --git a/packages/shadcn-ui/components.json b/packages/shadcn-ui/components.json index 34a12ea8..5c1e60a8 100644 --- a/packages/shadcn-ui/components.json +++ b/packages/shadcn-ui/components.json @@ -1,6 +1,6 @@ { "$schema": "https://ui.shadcn.com/schema.json", - "style": "new-york", + "style": "radix-vega", "rsc": true, "tsx": true, "tailwind": { diff --git a/packages/shadcn-ui/components/ui/accordion.tsx b/packages/shadcn-ui/components/ui/accordion.tsx index 76c2d301..3c363198 100644 --- a/packages/shadcn-ui/components/ui/accordion.tsx +++ b/packages/shadcn-ui/components/ui/accordion.tsx @@ -2,14 +2,21 @@ import * as React from "react" import { Accordion as AccordionPrimitive } from "radix-ui" -import { ChevronDownIcon } from "lucide-react" import { cn } from "@repo/shadcn-ui/lib/utils" +import { ChevronDownIcon, ChevronUpIcon } from "lucide-react" function Accordion({ + className, ...props }: React.ComponentProps) { - return + return ( + + ) } function AccordionItem({ @@ -19,7 +26,7 @@ function AccordionItem({ return ( ) @@ -35,13 +42,14 @@ function AccordionTrigger({ svg]:rotate-180", + "group/accordion-trigger relative flex flex-1 items-start justify-between rounded-md border border-transparent py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground", className )} {...props} > {children} - + + ) @@ -55,10 +63,17 @@ function AccordionContent({ return ( -
{children}
+
+ {children} +
) } diff --git a/packages/shadcn-ui/components/ui/alert-dialog.tsx b/packages/shadcn-ui/components/ui/alert-dialog.tsx index 6e5ec2d6..32214725 100644 --- a/packages/shadcn-ui/components/ui/alert-dialog.tsx +++ b/packages/shadcn-ui/components/ui/alert-dialog.tsx @@ -4,7 +4,7 @@ import * as React from "react" import { AlertDialog as AlertDialogPrimitive } from "radix-ui" import { cn } from "@repo/shadcn-ui/lib/utils" -import { buttonVariants } from "@repo/shadcn-ui/components/ui/button" +import { Button } from "@repo/shadcn-ui/components/ui/button" function AlertDialog({ ...props @@ -36,7 +36,7 @@ function AlertDialogOverlay({ ) { +}: React.ComponentProps & { + size?: "default" | "sm" +}) { return ( ) @@ -84,7 +91,23 @@ function AlertDialogFooter({
+ ) +} + +function AlertDialogMedia({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
) @@ -112,7 +138,10 @@ function AlertDialogDescription({ return ( ) @@ -120,38 +149,51 @@ function AlertDialogDescription({ function AlertDialogAction({ className, + variant = "default", + size = "default", ...props -}: React.ComponentProps) { +}: React.ComponentProps & + Pick, "variant" | "size">) { return ( - + ) } function AlertDialogCancel({ className, + variant = "outline", + size = "default", ...props -}: React.ComponentProps) { +}: React.ComponentProps & + Pick, "variant" | "size">) { return ( - + ) } export { AlertDialog, - AlertDialogPortal, - AlertDialogOverlay, - AlertDialogTrigger, + AlertDialogAction, + AlertDialogCancel, AlertDialogContent, - AlertDialogHeader, + AlertDialogDescription, AlertDialogFooter, + AlertDialogHeader, + AlertDialogMedia, + AlertDialogOverlay, + AlertDialogPortal, AlertDialogTitle, - AlertDialogDescription, - AlertDialogAction, - AlertDialogCancel, + AlertDialogTrigger, } diff --git a/packages/shadcn-ui/components/ui/alert.tsx b/packages/shadcn-ui/components/ui/alert.tsx index cb11ebb3..3a1ed534 100644 --- a/packages/shadcn-ui/components/ui/alert.tsx +++ b/packages/shadcn-ui/components/ui/alert.tsx @@ -4,13 +4,13 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@repo/shadcn-ui/lib/utils" const alertVariants = cva( - "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", + "group/alert relative grid w-full gap-0.5 rounded-lg border px-4 py-3 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4", { variants: { variant: { default: "bg-card text-card-foreground", destructive: - "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90", + "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current", }, }, defaultVariants: { @@ -39,7 +39,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground", className )} {...props} @@ -55,7 +55,7 @@ function AlertDescription({
) { + return ( +
+ ) +} + +export { Alert, AlertTitle, AlertDescription, AlertAction } diff --git a/packages/shadcn-ui/components/ui/attachment.tsx b/packages/shadcn-ui/components/ui/attachment.tsx new file mode 100644 index 00000000..0fc0241a --- /dev/null +++ b/packages/shadcn-ui/components/ui/attachment.tsx @@ -0,0 +1,204 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" +import { Slot } from "radix-ui" + +import { cn } from "@repo/shadcn-ui/lib/utils" +import { Button } from "@repo/shadcn-ui/components/ui/button" + +const attachmentVariants = cva( + "group/attachment relative flex w-fit max-w-full min-w-0 shrink-0 flex-wrap rounded-xl border bg-card text-card-foreground transition-colors focus-within:ring-1 focus-within:ring-ring/50 has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed", + { + variants: { + size: { + default: + "gap-2 text-sm has-data-[slot=attachment-content]:px-2.5 has-data-[slot=attachment-content]:py-2 has-data-[slot=attachment-media]:p-2", + sm: "gap-2.5 text-xs has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5", + xs: "gap-1.5 rounded-lg text-xs has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1", + }, + orientation: { + horizontal: "min-w-40 items-center", + vertical: "w-24 flex-col has-data-[slot=attachment-content]:w-30", + }, + }, + } +) + +function Attachment({ + className, + state = "done", + size = "default", + orientation = "horizontal", + ...props +}: React.ComponentProps<"div"> & + VariantProps & { + state?: "idle" | "uploading" | "processing" | "error" | "done" + }) { + return ( +
+ ) +} + +const attachmentMediaVariants = cva( + "relative flex aspect-square w-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted text-foreground group-data-[orientation=vertical]/attachment:w-full group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-md group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6! [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5", + { + variants: { + variant: { + icon: "", + image: + "opacity-60 group-data-[state=done]/attachment:opacity-100 group-data-[state=idle]/attachment:opacity-100 *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover", + }, + }, + defaultVariants: { + variant: "icon", + }, + } +) + +function AttachmentMedia({ + className, + variant = "icon", + ...props +}: React.ComponentProps<"div"> & VariantProps) { + return ( +
+ ) +} + +function AttachmentContent({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AttachmentTitle({ + className, + ...props +}: React.ComponentProps<"span">) { + return ( + + ) +} + +function AttachmentDescription({ + className, + ...props +}: React.ComponentProps<"span">) { + return ( + + ) +} + +function AttachmentActions({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AttachmentAction({ + className, + variant, + size = "icon-xs", + ...props +}: React.ComponentProps) { + return ( + ) @@ -204,7 +204,7 @@ function CarouselPrevious({ function CarouselNext({ className, variant = "outline", - size = "icon", + size = "icon-sm", ...props }: React.ComponentProps) { const { orientation, scrollNext, canScrollNext } = useCarousel() @@ -215,9 +215,9 @@ function CarouselNext({ variant={variant} size={size} className={cn( - "absolute size-8 rounded-full", + "absolute touch-manipulation rounded-full", orientation === "horizontal" - ? "top-1/2 -right-12 -translate-y-1/2" + ? "inset-y-0 -right-12 my-auto" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90", className )} @@ -225,7 +225,7 @@ function CarouselNext({ onClick={scrollNext} {...props} > - + Next slide ) @@ -238,4 +238,5 @@ export { CarouselItem, CarouselPrevious, CarouselNext, + useCarousel, } diff --git a/packages/shadcn-ui/components/ui/chart.tsx b/packages/shadcn-ui/components/ui/chart.tsx index 32eb515c..a02a4a28 100644 --- a/packages/shadcn-ui/components/ui/chart.tsx +++ b/packages/shadcn-ui/components/ui/chart.tsx @@ -2,21 +2,26 @@ import * as React from "react" import * as RechartsPrimitive from "recharts" +import type { TooltipValueType } from "recharts" import { cn } from "@repo/shadcn-ui/lib/utils" // Format: { THEME_NAME: CSS_SELECTOR } const THEMES = { light: "", dark: ".dark" } as const -export type ChartConfig = { - [k in string]: { +const INITIAL_DIMENSION = { width: 320, height: 200 } as const +type TooltipNameType = number | string + +export type ChartConfig = Record< + string, + { label?: React.ReactNode icon?: React.ComponentType } & ( | { color?: string; theme?: never } | { color?: never; theme: Record } ) -} +> type ChartContextProps = { config: ChartConfig @@ -39,15 +44,20 @@ function ChartContainer({ className, children, config, + initialDimension = INITIAL_DIMENSION, ...props }: React.ComponentProps<"div"> & { config: ChartConfig children: React.ComponentProps< typeof RechartsPrimitive.ResponsiveContainer >["children"] + initialDimension?: { + width: number + height: number + } }) { const uniqueId = React.useId() - const chartId = `chart-${id || uniqueId.replace(/:/g, "")}` + const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}` return ( @@ -55,13 +65,15 @@ function ChartContainer({ data-slot="chart" data-chart={chartId} className={cn( - "[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden", + "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden", className )} {...props} > - + {children}
@@ -71,7 +83,7 @@ function ChartContainer({ const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { const colorConfig = Object.entries(config).filter( - ([, config]) => config.theme || config.color + ([, config]) => config.theme ?? config.color ) if (!colorConfig.length) { @@ -88,7 +100,7 @@ ${prefix} [data-chart=${id}] { ${colorConfig .map(([key, itemConfig]) => { const color = - itemConfig.theme?.[theme as keyof typeof itemConfig.theme] || + itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ?? itemConfig.color return color ? ` --color-${key}: ${color};` : null }) @@ -125,7 +137,13 @@ function ChartTooltipContent({ indicator?: "line" | "dot" | "dashed" nameKey?: string labelKey?: string - }) { + } & Omit< + RechartsPrimitive.DefaultTooltipContentProps< + TooltipValueType, + TooltipNameType + >, + "accessibilityLayer" + >) { const { config } = useChart() const tooltipLabel = React.useMemo(() => { @@ -134,11 +152,11 @@ function ChartTooltipContent({ } const [item] = payload - const key = `${labelKey || item?.dataKey || item?.name || "value"}` + const key = `${labelKey ?? item?.dataKey ?? item?.name ?? "value"}` const itemConfig = getPayloadConfigFromPayload(config, item, key) const value = !labelKey && typeof label === "string" - ? config[label as keyof typeof config]?.label || label + ? (config[label]?.label ?? label) : itemConfig?.label if (labelFormatter) { @@ -173,7 +191,7 @@ function ChartTooltipContent({ return (
@@ -182,15 +200,15 @@ function ChartTooltipContent({ {payload .filter((item) => item.type !== "none") .map((item, index) => { - const key = `${nameKey || item.name || item.dataKey || "value"}` + const key = `${nameKey ?? item.name ?? item.dataKey ?? "value"}` const itemConfig = getPayloadConfigFromPayload(config, item, key) - const indicatorColor = color || item.payload.fill || item.color + const indicatorColor = color ?? item.payload?.fill ?? item.color return (
svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5", + "flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground", indicator === "dot" && "items-center" )} > @@ -231,12 +249,14 @@ function ChartTooltipContent({
{nestLabel ? tooltipLabel : null} - {itemConfig?.label || item.name} + {itemConfig?.label ?? item.name}
- {item.value && ( - - {item.value.toLocaleString()} + {item.value != null && ( + + {typeof item.value === "number" + ? item.value.toLocaleString() + : String(item.value)} )}
@@ -258,11 +278,10 @@ function ChartLegendContent({ payload, verticalAlign = "bottom", nameKey, -}: React.ComponentProps<"div"> & - Pick & { - hideIcon?: boolean - nameKey?: string - }) { +}: React.ComponentProps<"div"> & { + hideIcon?: boolean + nameKey?: string +} & RechartsPrimitive.DefaultLegendContentProps) { const { config } = useChart() if (!payload?.length) { @@ -279,15 +298,15 @@ function ChartLegendContent({ > {payload .filter((item) => item.type !== "none") - .map((item) => { - const key = `${nameKey || item.dataKey || "value"}` + .map((item, index) => { + const key = `${nameKey ?? item.dataKey ?? "value"}` const itemConfig = getPayloadConfigFromPayload(config, item, key) return (
svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3" + "flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground" )} > {itemConfig?.icon && !hideIcon ? ( @@ -308,7 +327,6 @@ function ChartLegendContent({ ) } -// Helper to extract item config from a payload. function getPayloadConfigFromPayload( config: ChartConfig, payload: unknown, @@ -342,9 +360,7 @@ function getPayloadConfigFromPayload( ] as string } - return configLabelKey in config - ? config[configLabelKey] - : config[key as keyof typeof config] + return configLabelKey in config ? config[configLabelKey] : config[key] } export { diff --git a/packages/shadcn-ui/components/ui/checkbox.tsx b/packages/shadcn-ui/components/ui/checkbox.tsx index 9b2b9ea3..adb2d94b 100644 --- a/packages/shadcn-ui/components/ui/checkbox.tsx +++ b/packages/shadcn-ui/components/ui/checkbox.tsx @@ -2,9 +2,9 @@ import * as React from "react" import { Checkbox as CheckboxPrimitive } from "radix-ui" -import { CheckIcon } from "lucide-react" import { cn } from "@repo/shadcn-ui/lib/utils" +import { CheckIcon } from "lucide-react" function Checkbox({ className, @@ -14,16 +14,17 @@ function Checkbox({ - + ) diff --git a/packages/shadcn-ui/components/ui/combobox.tsx b/packages/shadcn-ui/components/ui/combobox.tsx new file mode 100644 index 00000000..b042964d --- /dev/null +++ b/packages/shadcn-ui/components/ui/combobox.tsx @@ -0,0 +1,299 @@ +"use client" + +import * as React from "react" +import { Combobox as ComboboxPrimitive } from "@base-ui/react" + +import { cn } from "@repo/shadcn-ui/lib/utils" +import { Button } from "@repo/shadcn-ui/components/ui/button" +import { + InputGroup, + InputGroupAddon, + InputGroupButton, + InputGroupInput, +} from "@repo/shadcn-ui/components/ui/input-group" +import { ChevronDownIcon, XIcon, CheckIcon } from "lucide-react" + +const Combobox = ComboboxPrimitive.Root + +function ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) { + return +} + +function ComboboxTrigger({ + className, + children, + ...props +}: ComboboxPrimitive.Trigger.Props) { + return ( + + {children} + + + ) +} + +function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) { + return ( + } + className={cn(className)} + {...props} + > + + + ) +} + +function ComboboxInput({ + className, + children, + disabled = false, + showTrigger = true, + showClear = false, + ...props +}: ComboboxPrimitive.Input.Props & { + showTrigger?: boolean + showClear?: boolean +}) { + return ( + + } + {...props} + /> + + {showTrigger && ( + + + + )} + {showClear && } + + {children} + + ) +} + +function ComboboxContent({ + className, + side = "bottom", + sideOffset = 6, + align = "start", + alignOffset = 0, + anchor, + ...props +}: ComboboxPrimitive.Popup.Props & + Pick< + ComboboxPrimitive.Positioner.Props, + "side" | "align" | "sideOffset" | "alignOffset" | "anchor" + >) { + return ( + + + + + + ) +} + +function ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) { + return ( + + ) +} + +function ComboboxItem({ + className, + children, + ...props +}: ComboboxPrimitive.Item.Props) { + return ( + + {children} + + } + > + + + + ) +} + +function ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) { + return ( + + ) +} + +function ComboboxLabel({ + className, + ...props +}: ComboboxPrimitive.GroupLabel.Props) { + return ( + + ) +} + +function ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) { + return ( + + ) +} + +function ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) { + return ( + + ) +} + +function ComboboxSeparator({ + className, + ...props +}: ComboboxPrimitive.Separator.Props) { + return ( + + ) +} + +function ComboboxChips({ + className, + ...props +}: React.ComponentPropsWithRef & + ComboboxPrimitive.Chips.Props) { + return ( + + ) +} + +function ComboboxChip({ + className, + children, + showRemove = true, + ...props +}: ComboboxPrimitive.Chip.Props & { + showRemove?: boolean +}) { + return ( + + {children} + {showRemove && ( + } + className="-ml-1 opacity-50 hover:opacity-100" + data-slot="combobox-chip-remove" + > + + + )} + + ) +} + +function ComboboxChipsInput({ + className, + ...props +}: ComboboxPrimitive.Input.Props) { + return ( + + ) +} + +function useComboboxAnchor() { + return React.useRef(null) +} + +export { + Combobox, + ComboboxInput, + ComboboxContent, + ComboboxList, + ComboboxItem, + ComboboxGroup, + ComboboxLabel, + ComboboxCollection, + ComboboxEmpty, + ComboboxSeparator, + ComboboxChips, + ComboboxChip, + ComboboxChipsInput, + ComboboxTrigger, + ComboboxValue, + useComboboxAnchor, +} diff --git a/packages/shadcn-ui/components/ui/command.tsx b/packages/shadcn-ui/components/ui/command.tsx index 091a60a1..e41ee846 100644 --- a/packages/shadcn-ui/components/ui/command.tsx +++ b/packages/shadcn-ui/components/ui/command.tsx @@ -2,7 +2,6 @@ import * as React from "react" import { Command as CommandPrimitive } from "cmdk" -import { SearchIcon } from "lucide-react" import { cn } from "@repo/shadcn-ui/lib/utils" import { @@ -12,6 +11,11 @@ import { DialogHeader, DialogTitle, } from "@repo/shadcn-ui/components/ui/dialog" +import { + InputGroup, + InputGroupAddon, +} from "@repo/shadcn-ui/components/ui/input-group" +import { SearchIcon, CheckIcon } from "lucide-react" function Command({ className, @@ -21,7 +25,7 @@ function Command({ & { title?: string @@ -49,12 +53,13 @@ function CommandDialog({ {description} - - {children} - + {children} ) @@ -65,19 +70,20 @@ function CommandInput({ ...props }: React.ComponentProps) { return ( -
- - +
+ + + + + +
) } @@ -90,7 +96,7 @@ function CommandList({ ) { return ( ) @@ -118,7 +125,7 @@ function CommandGroup({ ) @@ -141,17 +148,21 @@ function CommandSeparator({ function CommandItem({ className, + children, ...props }: React.ComponentProps) { return ( + > + {children} + + ) } @@ -163,7 +174,7 @@ function CommandShortcut({ ) { return ( - + ) } @@ -53,58 +58,17 @@ function ContextMenuRadioGroup({ ) } -function ContextMenuSubTrigger({ - className, - inset, - children, - ...props -}: React.ComponentProps & { - inset?: boolean -}) { - return ( - - {children} - - - ) -} - -function ContextMenuSubContent({ - className, - ...props -}: React.ComponentProps) { - return ( - - ) -} - function ContextMenuContent({ className, ...props -}: React.ComponentProps) { +}: React.ComponentProps & { + side?: "top" | "right" | "bottom" | "left" +}) { return ( @@ -126,7 +90,7 @@ function ContextMenuItem({ data-inset={inset} data-variant={variant} className={cn( - "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "group/context-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 focus:*:[svg]:text-accent-foreground data-[variant=destructive]:*:[svg]:text-destructive", className )} {...props} @@ -134,25 +98,67 @@ function ContextMenuItem({ ) } +function ContextMenuSubTrigger({ + className, + inset, + children, + ...props +}: React.ComponentProps & { + inset?: boolean +}) { + return ( + + {children} + + + ) +} + +function ContextMenuSubContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + function ContextMenuCheckboxItem({ className, children, checked, + inset, ...props -}: React.ComponentProps) { +}: React.ComponentProps & { + inset?: boolean +}) { return ( - + - + {children} @@ -163,20 +169,25 @@ function ContextMenuCheckboxItem({ function ContextMenuRadioItem({ className, children, + inset, ...props -}: React.ComponentProps) { +}: React.ComponentProps & { + inset?: boolean +}) { return ( - + - + {children} @@ -196,7 +207,7 @@ function ContextMenuLabel({ data-slot="context-menu-label" data-inset={inset} className={cn( - "text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", + "px-2 py-1.5 text-xs font-medium text-muted-foreground data-inset:pl-8", className )} {...props} @@ -211,7 +222,7 @@ function ContextMenuSeparator({ return ( ) @@ -225,7 +236,7 @@ function ContextMenuShortcut({ + {children} {showCloseButton && ( - - - Close + + )} @@ -84,13 +89,20 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { return (
) } -function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { +function DialogFooter({ + className, + showCloseButton = false, + children, + ...props +}: React.ComponentProps<"div"> & { + showCloseButton?: boolean +}) { return (
) { className )} {...props} - /> + > + {children} + {showCloseButton && ( + + + + )} +
) } @@ -110,7 +129,7 @@ function DialogTitle({ return ( ) @@ -123,7 +142,10 @@ function DialogDescription({ return ( ) diff --git a/packages/shadcn-ui/components/ui/direction.tsx b/packages/shadcn-ui/components/ui/direction.tsx new file mode 100644 index 00000000..22e16577 --- /dev/null +++ b/packages/shadcn-ui/components/ui/direction.tsx @@ -0,0 +1,22 @@ +"use client" + +import * as React from "react" +import { Direction } from "radix-ui" + +function DirectionProvider({ + dir, + direction, + children, +}: React.ComponentProps & { + direction?: React.ComponentProps["dir"] +}) { + return ( + + {children} + + ) +} + +const useDirection = Direction.useDirection + +export { DirectionProvider, useDirection } diff --git a/packages/shadcn-ui/components/ui/drawer.tsx b/packages/shadcn-ui/components/ui/drawer.tsx index 472ac40b..a57eec73 100644 --- a/packages/shadcn-ui/components/ui/drawer.tsx +++ b/packages/shadcn-ui/components/ui/drawer.tsx @@ -37,7 +37,7 @@ function DrawerOverlay({ -
+
{children} @@ -102,7 +98,7 @@ function DrawerTitle({ return ( ) @@ -115,7 +111,7 @@ function DrawerDescription({ return ( ) diff --git a/packages/shadcn-ui/components/ui/dropdown-menu.tsx b/packages/shadcn-ui/components/ui/dropdown-menu.tsx index 7e65814f..33026d82 100644 --- a/packages/shadcn-ui/components/ui/dropdown-menu.tsx +++ b/packages/shadcn-ui/components/ui/dropdown-menu.tsx @@ -2,9 +2,9 @@ import * as React from "react" import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui" -import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" import { cn } from "@repo/shadcn-ui/lib/utils" +import { CheckIcon, ChevronRightIcon } from "lucide-react" function DropdownMenu({ ...props @@ -33,6 +33,7 @@ function DropdownMenuTrigger({ function DropdownMenuContent({ className, + align = "start", sideOffset = 4, ...props }: React.ComponentProps) { @@ -41,10 +42,8 @@ function DropdownMenuContent({ @@ -74,7 +73,7 @@ function DropdownMenuItem({ data-inset={inset} data-variant={variant} className={cn( - "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive", className )} {...props} @@ -86,21 +85,29 @@ function DropdownMenuCheckboxItem({ className, children, checked, + inset, ...props -}: React.ComponentProps) { +}: React.ComponentProps & { + inset?: boolean +}) { return ( - + - + {children} @@ -122,20 +129,28 @@ function DropdownMenuRadioGroup({ function DropdownMenuRadioItem({ className, children, + inset, ...props -}: React.ComponentProps) { +}: React.ComponentProps & { + inset?: boolean +}) { return ( - + - + {children} @@ -155,7 +170,7 @@ function DropdownMenuLabel({ data-slot="dropdown-menu-label" data-inset={inset} className={cn( - "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", + "px-2 py-1.5 text-xs font-medium text-muted-foreground data-inset:pl-8", className )} {...props} @@ -170,7 +185,7 @@ function DropdownMenuSeparator({ return ( ) @@ -184,7 +199,7 @@ function DropdownMenuShortcut({ {children} - + ) } @@ -229,10 +244,7 @@ function DropdownMenuSubContent({ return ( ) diff --git a/packages/shadcn-ui/components/ui/empty.tsx b/packages/shadcn-ui/components/ui/empty.tsx index 953d8818..678fa6d0 100644 --- a/packages/shadcn-ui/components/ui/empty.tsx +++ b/packages/shadcn-ui/components/ui/empty.tsx @@ -7,7 +7,7 @@ function Empty({ className, ...props }: React.ComponentProps<"div">) {
) { return (
) } const emptyMediaVariants = cva( - "flex shrink-0 items-center justify-center mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0", + "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0", { variants: { variant: { default: "bg-transparent", - icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6", + icon: "flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-6", }, }, defaultVariants: { @@ -62,7 +59,10 @@ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) { return (
) @@ -73,7 +73,7 @@ function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4", + "text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary", className )} {...props} diff --git a/packages/shadcn-ui/components/ui/field.tsx b/packages/shadcn-ui/components/ui/field.tsx index b552db11..914e49ae 100644 --- a/packages/shadcn-ui/components/ui/field.tsx +++ b/packages/shadcn-ui/components/ui/field.tsx @@ -12,8 +12,7 @@ function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3", + "flex flex-col gap-6 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3", className )} {...props} @@ -31,9 +30,7 @@ function FieldLegend({ data-slot="field-legend" data-variant={variant} className={cn( - "mb-3 font-medium", - "data-[variant=legend]:text-base", - "data-[variant=label]:text-sm", + "mb-3 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base", className )} {...props} @@ -46,7 +43,7 @@ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
[data-slot=field-group]]:gap-4", + "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4", className )} {...props} @@ -59,17 +56,11 @@ const fieldVariants = cva( { variants: { orientation: { - vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"], - horizontal: [ - "flex-row items-center", - "[&>[data-slot=field-label]]:flex-auto", - "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", - ], - responsive: [ - "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto", - "@md/field-group:[&>[data-slot=field-label]]:flex-auto", - "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", - ], + vertical: "flex-col *:w-full [&>.sr-only]:w-auto", + horizontal: + "flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", + responsive: + "flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", }, }, defaultVariants: { @@ -99,7 +90,7 @@ function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4", - "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10", + "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border *:data-[slot=field]:p-3 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10", + "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col", className )} {...props} @@ -130,7 +120,7 @@ function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
) {

a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4", + "text-left text-sm leading-normal font-normal text-muted-foreground group-has-data-horizontal/field:text-balance [[data-variant=legend]+&]:-mt-1.5", + "last:mt-0 nth-last-2:-mt-1", + "[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary", className )} {...props} @@ -173,7 +163,7 @@ function FieldSeparator({ {children && ( {children} @@ -226,7 +216,7 @@ function FieldError({

{content} diff --git a/packages/shadcn-ui/components/ui/hover-card.tsx b/packages/shadcn-ui/components/ui/hover-card.tsx index c259cc8c..5e83fef4 100644 --- a/packages/shadcn-ui/components/ui/hover-card.tsx +++ b/packages/shadcn-ui/components/ui/hover-card.tsx @@ -32,7 +32,7 @@ function HoverCardContent({ align={align} sideOffset={sideOffset} className={cn( - "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden", + "z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-lg bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )} {...props} diff --git a/packages/shadcn-ui/components/ui/input-group.tsx b/packages/shadcn-ui/components/ui/input-group.tsx index e8e5f6b8..e0cf5656 100644 --- a/packages/shadcn-ui/components/ui/input-group.tsx +++ b/packages/shadcn-ui/components/ui/input-group.tsx @@ -14,21 +14,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) { data-slot="input-group" role="group" className={cn( - "group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none", - "h-9 min-w-0 has-[>textarea]:h-auto", - - // Variants based on alignment. - "has-[>[data-align=inline-start]]:[&>input]:pl-2", - "has-[>[data-align=inline-end]]:[&>input]:pr-2", - "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3", - "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3", - - // Focus state. - "has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]", - - // Error state. - "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40", - + "group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className )} {...props} @@ -37,18 +23,18 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) { } const inputGroupAddonVariants = cva( - "text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50", + "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4", { variants: { align: { "inline-start": - "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]", + "order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]", "inline-end": - "order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]", + "order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]", "block-start": - "order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5", + "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2", "block-end": - "order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5", + "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2", }, }, defaultVariants: { @@ -80,12 +66,12 @@ function InputGroupAddon({ } const inputGroupButtonVariants = cva( - "text-sm shadow-none flex min-w-0 gap-2 items-center", + "flex items-center gap-2 text-sm shadow-none", { variants: { size: { - xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2", - sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5", + xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5", + sm: "", "icon-xs": "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0", "icon-sm": "size-8 p-0 has-[>svg]:p-0", @@ -120,7 +106,7 @@ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) { return ( @@ -30,7 +31,10 @@ function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) { return (
) @@ -51,7 +55,7 @@ function InputOTPSlot({ data-slot="input-otp-slot" data-active={isActive} className={cn( - "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]", + "relative flex size-9 items-center justify-center border-y border-r border-input text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40", className )} {...props} @@ -59,7 +63,7 @@ function InputOTPSlot({ {char} {hasFakeCaret && (
-
+
)}
@@ -68,8 +72,14 @@ function InputOTPSlot({ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) { return ( -
- +
+
) } diff --git a/packages/shadcn-ui/components/ui/input.tsx b/packages/shadcn-ui/components/ui/input.tsx index 135e72cb..6c141df6 100644 --- a/packages/shadcn-ui/components/ui/input.tsx +++ b/packages/shadcn-ui/components/ui/input.tsx @@ -8,9 +8,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) { type={type} data-slot="input" className={cn( - "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", - "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", - "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + "h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className )} {...props} diff --git a/packages/shadcn-ui/components/ui/item.tsx b/packages/shadcn-ui/components/ui/item.tsx index f4a2fd90..c0b0fe90 100644 --- a/packages/shadcn-ui/components/ui/item.tsx +++ b/packages/shadcn-ui/components/ui/item.tsx @@ -1,6 +1,6 @@ import * as React from "react" -import { Slot as SlotPrimitive } from "radix-ui" import { cva, type VariantProps } from "class-variance-authority" +import { Slot } from "radix-ui" import { cn } from "@repo/shadcn-ui/lib/utils" import { Separator } from "@repo/shadcn-ui/components/ui/separator" @@ -10,7 +10,10 @@ function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
) @@ -24,24 +27,25 @@ function ItemSeparator({ ) } const itemVariants = cva( - "group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", + "group/item flex w-full flex-wrap items-center rounded-md border text-sm transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors [a]:hover:bg-muted", { variants: { variant: { - default: "bg-transparent", + default: "border-transparent", outline: "border-border", - muted: "bg-muted/50", + muted: "border-transparent bg-muted/50", }, size: { - default: "p-4 gap-4 ", - sm: "py-3 px-4 gap-2.5", + default: "gap-3.5 px-4 py-3.5", + sm: "gap-2.5 px-3 py-2.5", + xs: "gap-2 px-2.5 py-2 in-data-[slot=dropdown-menu-content]:p-0", }, }, defaultVariants: { @@ -59,7 +63,7 @@ function Item({ ...props }: React.ComponentProps<"div"> & VariantProps & { asChild?: boolean }) { - const Comp = asChild ? SlotPrimitive.Slot : "div" + const Comp = asChild ? Slot.Root : "div" return ( ) {
) {
) {

a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4", + "line-clamp-2 text-left text-sm leading-normal font-normal text-muted-foreground group-data-[size=xs]/item:text-xs [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary", className )} {...props} diff --git a/packages/shadcn-ui/components/ui/kbd.tsx b/packages/shadcn-ui/components/ui/kbd.tsx index 837ef193..7a029798 100644 --- a/packages/shadcn-ui/components/ui/kbd.tsx +++ b/packages/shadcn-ui/components/ui/kbd.tsx @@ -5,9 +5,7 @@ function Kbd({ className, ...props }: React.ComponentProps<"kbd">) { & + VariantProps & { + asChild?: boolean + }) { + const Comp = asChild ? Slot.Root : "div" + + return ( + + ) +} + +function MarkerIcon({ className, ...props }: React.ComponentProps<"span">) { + return ( +

+ ) +} + +function Message({ + className, + align = "start", + ...props +}: React.ComponentProps<"div"> & { align?: "start" | "end" }) { + return ( +
+ ) +} + +function MessageAvatar({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function MessageContent({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function MessageHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function MessageFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +export { + MessageGroup, + Message, + MessageAvatar, + MessageContent, + MessageFooter, + MessageHeader, +} diff --git a/packages/shadcn-ui/components/ui/native-select.tsx b/packages/shadcn-ui/components/ui/native-select.tsx new file mode 100644 index 00000000..310fb346 --- /dev/null +++ b/packages/shadcn-ui/components/ui/native-select.tsx @@ -0,0 +1,61 @@ +import * as React from "react" + +import { cn } from "@repo/shadcn-ui/lib/utils" +import { ChevronDownIcon } from "lucide-react" + +type NativeSelectProps = Omit, "size"> & { + size?: "sm" | "default" +} + +function NativeSelect({ + className, + size = "default", + ...props +}: NativeSelectProps) { + return ( +
+