snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
All checks were successful
Release / Create Version PR or Publish Stable Release (push) Has been skipped
Release / Publish Prerelease to NPM (push) Has been skipped
Monitor Registries / Monitor registry health (push) Has been skipped

This commit is contained in:
upstream-mirror
2026-09-15 22:44:43 +05:00
commit 1416db152c
5727 changed files with 630238 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/registry/new-york-v4/ui/dialog"
export function CodeViewer() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">View code</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>View code</DialogTitle>
<DialogDescription>
You can use the following code to start integrating your current
prompt and settings into your application.
</DialogDescription>
</DialogHeader>
<div className="grid gap-4">
<div className="rounded-md bg-black p-6">
<pre>
<code className="grid gap-1 text-sm text-white [&_span]:h-4">
<span>
<span className="text-sky-300">import</span> os
</span>
<span>
<span className="text-sky-300">import</span> openai
</span>
<span />
<span>
openai.api_key = os.getenv(
<span className="text-green-300">
&quot;OPENAI_API_KEY&quot;
</span>
)
</span>
<span />
<span>response = openai.Completion.create(</span>
<span>
{" "}
model=
<span className="text-green-300">&quot;davinci&quot;</span>,
</span>
<span>
{" "}
prompt=<span className="text-amber-300">&quot;&quot;</span>,
</span>
<span>
{" "}
temperature=<span className="text-amber-300">0.9</span>,
</span>
<span>
{" "}
max_tokens=<span className="text-amber-300">5</span>,
</span>
<span>
{" "}
top_p=<span className="text-amber-300">1</span>,
</span>
<span>
{" "}
frequency_penalty=<span className="text-amber-300">0</span>,
</span>
<span>
{" "}
presence_penalty=<span className="text-green-300">0</span>,
</span>
<span>)</span>
</code>
</pre>
</div>
<div>
<p className="text-sm text-muted-foreground">
Your API Key can be found here. You should use environment
variables or a secret management tool to expose your key to your
applications.
</p>
</div>
</div>
</DialogContent>
</Dialog>
)
}

View File

@@ -0,0 +1,56 @@
"use client"
import * as React from "react"
import type { Slider as SliderPrimitive } from "radix-ui"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Slider } from "@/registry/new-york-v4/ui/slider"
interface MaxLengthSelectorProps {
defaultValue: React.ComponentProps<
typeof SliderPrimitive.Root
>["defaultValue"]
}
export function MaxLengthSelector({ defaultValue }: MaxLengthSelectorProps) {
const [value, setValue] = React.useState(defaultValue)
return (
<div className="grid gap-2 pt-2">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<div className="grid gap-4">
<div className="flex items-center justify-between">
<Label htmlFor="maxlength">Maximum Length</Label>
<span className="w-12 rounded-md border border-transparent px-2 py-0.5 text-right text-sm text-muted-foreground hover:border-border">
{value}
</span>
</div>
<Slider
id="maxlength"
max={4000}
defaultValue={value}
step={10}
onValueChange={setValue}
aria-label="Maximum Length"
/>
</div>
</HoverCardTrigger>
<HoverCardContent
align="start"
className="w-[260px] text-sm"
side="left"
>
The maximum number of tokens to generate. Requests can use up to 2,048
or 4,000 tokens, shared between prompt and completion. The exact limit
varies by model.
</HoverCardContent>
</HoverCard>
</div>
)
}

View File

@@ -0,0 +1,163 @@
"use client"
import * as React from "react"
import { cn } from "cn"
import { Check, ChevronsUpDown } from "lucide-react"
import type { Popover as PopoverPrimitive } from "radix-ui"
import { useMutationObserver } from "@/hooks/use-mutation-observer"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/registry/new-york-v4/ui/command"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
import { type Model, type ModelType } from "../data/models"
interface ModelSelectorProps
extends React.ComponentProps<typeof PopoverPrimitive.Root> {
types: readonly ModelType[]
models: Model[]
}
export function ModelSelector({ models, types, ...props }: ModelSelectorProps) {
const [open, setOpen] = React.useState(false)
const [selectedModel, setSelectedModel] = React.useState<Model>(models[0])
const [peekedModel, setPeekedModel] = React.useState<Model>(models[0])
return (
<div className="grid gap-3">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<Label htmlFor="model">Model</Label>
</HoverCardTrigger>
<HoverCardContent
align="start"
className="w-[260px] text-sm"
side="left"
>
The model which will generate the completion. Some models are suitable
for natural language tasks, others specialize in code. Learn more.
</HoverCardContent>
</HoverCard>
<Popover open={open} onOpenChange={setOpen} {...props}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
aria-label="Select a model"
className="w-full justify-between"
>
{selectedModel ? selectedModel.name : "Select a model..."}
<ChevronsUpDown className="text-muted-foreground" />
</Button>
</PopoverTrigger>
<PopoverContent align="end" className="w-[250px] p-0">
<HoverCard>
<HoverCardContent
side="left"
align="start"
forceMount
className="min-h-[280px]"
>
<div className="grid gap-2">
<h4 className="leading-none font-medium">{peekedModel.name}</h4>
<div className="text-sm text-muted-foreground">
{peekedModel.description}
</div>
{peekedModel.strengths ? (
<div className="mt-4 grid gap-2">
<h5 className="text-sm leading-none font-medium">
Strengths
</h5>
<ul className="text-sm text-muted-foreground">
{peekedModel.strengths}
</ul>
</div>
) : null}
</div>
</HoverCardContent>
<Command loop>
<CommandList className="h-(--cmdk-list-height) max-h-[400px]">
<CommandInput placeholder="Search Models..." />
<CommandEmpty>No Models found.</CommandEmpty>
<HoverCardTrigger />
{types.map((type) => (
<CommandGroup key={type} heading={type}>
{models
.filter((model) => model.type === type)
.map((model) => (
<ModelItem
key={model.id}
model={model}
isSelected={selectedModel?.id === model.id}
onPeek={(model) => setPeekedModel(model)}
onSelect={() => {
setSelectedModel(model)
setOpen(false)
}}
/>
))}
</CommandGroup>
))}
</CommandList>
</Command>
</HoverCard>
</PopoverContent>
</Popover>
</div>
)
}
interface ModelItemProps {
model: Model
isSelected: boolean
onSelect: () => void
onPeek: (model: Model) => void
}
function ModelItem({ model, isSelected, onSelect, onPeek }: ModelItemProps) {
const ref = React.useRef<HTMLDivElement>(null)
useMutationObserver(ref, (mutations) => {
mutations.forEach((mutation) => {
if (
mutation.type === "attributes" &&
mutation.attributeName === "aria-selected" &&
ref.current?.getAttribute("aria-selected") === "true"
) {
onPeek(model)
}
})
})
return (
<CommandItem
key={model.id}
onSelect={onSelect}
ref={ref}
className="data-[selected=true]:bg-primary data-[selected=true]:text-primary-foreground"
>
{model.name}
<Check
className={cn("ml-auto", isSelected ? "opacity-100" : "opacity-0")}
/>
</CommandItem>
)
}

View File

@@ -0,0 +1,121 @@
"use client"
import * as React from "react"
import { MoreHorizontal } from "lucide-react"
import { toast } from "sonner"
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/registry/new-york-v4/ui/alert-dialog"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/registry/new-york-v4/ui/dialog"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Switch } from "@/registry/new-york-v4/ui/switch"
export function PresetActions() {
const [open, setIsOpen] = React.useState(false)
const [showDeleteDialog, setShowDeleteDialog] = React.useState(false)
return (
<>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" size="icon">
<span className="sr-only">Actions</span>
<MoreHorizontal />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onSelect={() => setIsOpen(true)}>
Content filter preferences
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
onSelect={() => setShowDeleteDialog(true)}
className="text-red-600"
>
Delete preset
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Dialog open={open} onOpenChange={setIsOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Content filter preferences</DialogTitle>
<DialogDescription>
The content filter flags text that may violate our content policy.
It&apos;s powered by our moderation endpoint which is free to use
to moderate your OpenAI API traffic. Learn more.
</DialogDescription>
</DialogHeader>
<div className="py-6">
<h4 className="text-sm text-muted-foreground">
Playground Warnings
</h4>
<div className="flex items-start justify-between gap-4 pt-3">
<Switch name="show" id="show" defaultChecked={true} />
<Label className="grid gap-1 font-normal" htmlFor="show">
<span className="font-semibold">
Show a warning when content is flagged
</span>
<span className="text-sm text-muted-foreground">
A warning will be shown when sexual, hateful, violent or
self-harm content is detected.
</span>
</Label>
</div>
</div>
<DialogFooter>
<DialogClose asChild>
<Button variant="secondary">Close</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
<AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This preset will no longer be
accessible by you or others you&apos;ve shared it with.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<Button
variant="destructive"
onClick={() => {
setShowDeleteDialog(false)
toast.success("This preset has been deleted.")
}}
>
Delete
</Button>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
)
}

View File

@@ -0,0 +1,45 @@
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/registry/new-york-v4/ui/dialog"
import { Input } from "@/registry/new-york-v4/ui/input"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Textarea } from "@/registry/new-york-v4/ui/textarea"
export function PresetSave() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">Save</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Save preset</DialogTitle>
<DialogDescription>
This will save the current playground state as a preset which you
can access later or share with others.
</DialogDescription>
</DialogHeader>
<div className="grid gap-6 py-4">
<div className="grid gap-3">
<Label htmlFor="name">Name</Label>
<Input id="name" autoFocus />
</div>
<div className="grid gap-3">
<Label htmlFor="description">Description</Label>
<Textarea id="description" />
</div>
</div>
<DialogFooter>
<Button type="submit">Save</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}

View File

@@ -0,0 +1,84 @@
"use client"
import * as React from "react"
import { cn } from "cn"
import { Check, ChevronsUpDown } from "lucide-react"
import type { Popover as PopoverPrimitive } from "radix-ui"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/registry/new-york-v4/ui/command"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
import { type Preset } from "../data/presets"
interface PresetSelectorProps
extends React.ComponentProps<typeof PopoverPrimitive.Root> {
presets: Preset[]
}
export function PresetSelector({ presets, ...props }: PresetSelectorProps) {
const [open, setOpen] = React.useState(false)
const [selectedPreset, setSelectedPreset] = React.useState<Preset>()
return (
<Popover open={open} onOpenChange={setOpen} {...props}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-label="Load a preset..."
aria-expanded={open}
className="flex-1 justify-between md:max-w-[200px] lg:max-w-[300px]"
>
{selectedPreset ? selectedPreset.name : "Load a preset..."}
<ChevronsUpDown className="opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[300px] p-0">
<Command>
<CommandInput placeholder="Search presets..." />
<CommandList>
<CommandEmpty>No presets found.</CommandEmpty>
<CommandGroup heading="Examples">
{presets.map((preset) => (
<CommandItem
key={preset.id}
onSelect={() => {
setSelectedPreset(preset)
setOpen(false)
}}
>
{preset.name}
<Check
className={cn(
"ml-auto",
selectedPreset?.id === preset.id
? "opacity-100"
: "opacity-0"
)}
/>
</CommandItem>
))}
</CommandGroup>
<CommandSeparator />
<CommandGroup>
<CommandItem>More examples</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
)
}

View File

@@ -0,0 +1,49 @@
import { Copy } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import { Input } from "@/registry/new-york-v4/ui/input"
import { Label } from "@/registry/new-york-v4/ui/label"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
export function PresetShare() {
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="secondary">Share</Button>
</PopoverTrigger>
<PopoverContent align="end" className="flex w-[520px] flex-col gap-4">
<div className="flex flex-col gap-1 text-center sm:text-left">
<h3 className="text-lg font-semibold">Share preset</h3>
<p className="text-sm text-muted-foreground">
Anyone who has this link and an OpenAI account will be able to view
this.
</p>
</div>
<div className="relative flex-1">
<Label htmlFor="link" className="sr-only">
Link
</Label>
<Input
id="link"
defaultValue="https://platform.openai.com/playground/p/7bbKYQvsVkNmVb8NGcdUOLae?model=text-davinci-003"
readOnly
className="h-9 pr-10"
/>
<Button
type="submit"
size="icon"
variant="ghost"
className="absolute top-1 right-1 size-7"
>
<span className="sr-only">Copy</span>
<Copy className="size-3.5" />
</Button>
</div>
</PopoverContent>
</Popover>
)
}

View File

@@ -0,0 +1,58 @@
"use client"
import * as React from "react"
import type { Slider as SliderPrimitive } from "radix-ui"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Slider } from "@/registry/new-york-v4/ui/slider"
interface TemperatureSelectorProps {
defaultValue: React.ComponentProps<
typeof SliderPrimitive.Root
>["defaultValue"]
}
export function TemperatureSelector({
defaultValue,
}: TemperatureSelectorProps) {
const [value, setValue] = React.useState(defaultValue)
return (
<div className="grid gap-2 pt-2">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<div className="grid gap-4">
<div className="flex items-center justify-between">
<Label htmlFor="temperature">Temperature</Label>
<span className="w-12 rounded-md border border-transparent px-2 py-0.5 text-right text-sm text-muted-foreground hover:border-border">
{value}
</span>
</div>
<Slider
id="temperature"
max={1}
defaultValue={value}
step={0.1}
onValueChange={setValue}
aria-label="Temperature"
/>
</div>
</HoverCardTrigger>
<HoverCardContent
align="start"
className="w-[260px] text-sm"
side="left"
>
Controls randomness: lowering results in less random completions. As
the temperature approaches zero, the model will become deterministic
and repetitive.
</HoverCardContent>
</HoverCard>
</div>
)
}

View File

@@ -0,0 +1,55 @@
"use client"
import * as React from "react"
import type { Slider as SliderPrimitive } from "radix-ui"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Slider } from "@/registry/new-york-v4/ui/slider"
interface TopPSelectorProps {
defaultValue: React.ComponentProps<
typeof SliderPrimitive.Root
>["defaultValue"]
}
export function TopPSelector({ defaultValue }: TopPSelectorProps) {
const [value, setValue] = React.useState(defaultValue)
return (
<div className="grid gap-2 pt-2">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<div className="grid gap-4">
<div className="flex items-center justify-between">
<Label htmlFor="top-p">Top P</Label>
<span className="w-12 rounded-md border border-transparent px-2 py-0.5 text-right text-sm text-muted-foreground hover:border-border">
{value}
</span>
</div>
<Slider
id="top-p"
max={1}
defaultValue={value}
step={0.1}
onValueChange={setValue}
aria-label="Top P"
/>
</div>
</HoverCardTrigger>
<HoverCardContent
align="start"
className="w-[260px] text-sm"
side="left"
>
Control diversity via nucleus sampling: 0.5 means half of all
likelihood-weighted options are considered.
</HoverCardContent>
</HoverCard>
</div>
)
}