按钮
Prompt
Composed prompt list with horizontal and vertical variants for quick input suggestions
Prompt 01
Prompt 02
"use client";
import {
PromptButton,
PromptGroup,
} from "@/components/composed/prompt/prompt";
import { Sparkles, FileText, Lightbulb } from "lucide-react";
export function PromptDemo() {
return (
<div className="flex flex-col gap-8 w-full">
<div>
<h4 className="text-sm font-medium text-[var(--Text-text-primary)] mb-4">
Prompt 01
</h4>
<PromptGroup variant="horizontal">
<PromptButton
variant="horizontal"
icon={<Sparkles />}
onClick={() => alert("Prompt 01")}
>
帮我总结内容
</PromptButton>
<PromptButton
variant="horizontal"
icon={<FileText />}
onClick={() => alert("Prompt 01")}
>
列一个学习计划
</PromptButton>
<PromptButton
variant="horizontal"
icon={<Lightbulb />}
onClick={() => alert("Prompt 01")}
>
解释这个概念
</PromptButton>
</PromptGroup>
</div>
<div>
<h4 className="text-sm font-medium text-[var(--Text-text-primary)] mb-4">
Prompt 02
</h4>
<PromptGroup variant="vertical">
<PromptButton
variant="vertical"
icon={<Sparkles />}
onClick={() => alert("Prompt 02")}
>
介绍一下人工智能对互联网行业发展的影响
</PromptButton>
<PromptButton
variant="vertical"
icon={<FileText />}
onClick={() => alert("Prompt 02")}
>
介绍一下人工智能对互联网行业发展的影响
</PromptButton>
<PromptButton
variant="vertical"
icon={<Lightbulb />}
onClick={() => alert("Prompt 02")}
>
帮我总结内容,并给出学习计划
</PromptButton>
</PromptGroup>
</div>
</div>
);
}
Prompt 组件用于展示快速输入建议,支持水平和垂直两种布局变体,适用于聊天输入提示、搜索建议、快捷回复等场景。
概述
- 双布局模式:水平紧凑布局和垂直卡片布局,适应不同场景需求
- 数据驱动:支持数组数据渲染,方便动态生成提示内容
- 图标支持:垂直布局默认支持 Sparkles 图标,可自定义
- 组合灵活:PromptGroup、PromptButton、PromptPanel 可独立或组合使用
- 交互友好:清晰的悬停和点击状态反馈
- 类型安全:完整的 TypeScript 类型定义
快速开始
import { PromptButton, PromptPanel } from "@/registry/wuhan/composed/prompt";
import { Sparkles } from "lucide-react";
export function Example() {
const prompts = [
{ text: "解释一下 React Hooks", icon: Sparkles },
{ text: "如何优化性能?", icon: Sparkles },
{ text: "什么是虚拟 DOM?", icon: Sparkles },
];
return (
<PromptPanel
items={prompts}
variant="vertical"
onPromptClick={(text) => console.log(text)}
/>
);
}特性
- 水平布局(horizontal):紧凑的按钮排列,适合空间有限的场景
- 垂直布局(vertical):卡片式布局,支持图标,视觉更丰富
- PromptButton:单个提示按钮,可独立使用
- PromptPanel:数据驱动的提示面板,自动渲染按钮列表
- PromptGroup:按钮容器,控制布局方向
- 自定义图标:垂直布局支持为每个提示配置不同图标
安装
代码演示
水平布局
紧凑的水平布局,适合工具栏或输入框下方。
"use client";
import {
PromptButton,
PromptGroup,
} from "@/components/composed/prompt/prompt";
import { Sparkles, FileText, Lightbulb, BookOpen } from "lucide-react";
export function PromptHorizontal() {
return (
<PromptGroup variant="horizontal">
<PromptButton
variant="horizontal"
icon={<Sparkles />}
onClick={() => alert("总结内容")}
>
帮我总结一下这段内容
</PromptButton>
<PromptButton
variant="horizontal"
icon={<FileText />}
onClick={() => alert("学习计划")}
>
给我列一个学习计划
</PromptButton>
<PromptButton
variant="horizontal"
icon={<Lightbulb />}
onClick={() => alert("解释概念")}
>
解释一下这个概念
</PromptButton>
<PromptButton
variant="horizontal"
icon={<BookOpen />}
onClick={() => alert("推荐资源")}
>
推荐一些学习资源
</PromptButton>
</PromptGroup>
);
}
垂直布局
卡片式垂直布局,支持图标,视觉更丰富。
"use client";
import {
PromptButton,
PromptGroup,
} from "@/components/composed/prompt/prompt";
import { Sparkles, FileText, Lightbulb, BookOpen } from "lucide-react";
export function PromptVertical() {
return (
<PromptGroup variant="vertical">
<PromptButton
variant="vertical"
icon={<Sparkles />}
onClick={() => alert("总结内容")}
>
帮我总结一下这段内容
</PromptButton>
<PromptButton
variant="vertical"
icon={<FileText />}
onClick={() => alert("学习计划")}
>
给我列一个学习计划
</PromptButton>
<PromptButton
variant="vertical"
icon={<Lightbulb />}
onClick={() => alert("解释概念")}
>
解释一下这个概念
</PromptButton>
<PromptButton
variant="vertical"
icon={<BookOpen />}
onClick={() => alert("推荐资源")}
>
推荐一些学习资源
</PromptButton>
</PromptGroup>
);
}
API
PromptButton
单个提示按钮组件,支持水平和垂直两种变体。
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "horizontal" | "vertical" | "horizontal" | 布局变体 |
icon | LucideIcon | Sparkles | 图标组件(仅 vertical 模式) |
children | ReactNode | - | 提示文本内容(必填) |
onClick | () => void | - | 点击事件处理函数 |
className | string | - | 额外的样式类名 |
Example
import { PromptButton } from "@/registry/wuhan/composed/prompt";
import { Lightbulb } from "lucide-react";
function PromptButtons() {
return (
<div className="space-y-2">
{/* 水平布局 */}
<PromptButton
variant="horizontal"
onClick={() => console.log("clicked")}
>
快速提问
</PromptButton>
{/* 垂直布局,默认 Sparkles 图标 */}
<PromptButton variant="vertical">
帮我写一段代码
</PromptButton>
{/* 自定义图标 */}
<PromptButton
variant="vertical"
icon={Lightbulb}
>
给我一些建议
</PromptButton>
</div>
);
}PromptGroup
提示按钮容器组件,控制子按钮的布局方向。
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "horizontal" | "vertical" | "horizontal" | 布局变体 |
children | ReactNode | - | 子元素(通常是 PromptButton) |
className | string | - | 额外的样式类名 |
Example
import { PromptGroup, PromptButton } from "@/registry/wuhan/composed/prompt";
function PromptList() {
return (
<PromptGroup variant="horizontal">
<PromptButton>提示 1</PromptButton>
<PromptButton>提示 2</PromptButton>
<PromptButton>提示 3</PromptButton>
</PromptGroup>
);
}PromptPanel
数据驱动的提示面板,根据数组自动渲染按钮列表。
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | PromptItem[] | - | 提示项数组(必填) |
variant | "horizontal" | "vertical" | "horizontal" | 布局变体 |
onPromptClick | (text: string) => void | - | 点击提示时的回调函数 |
className | string | - | 额外的样式类名 |
PromptItem Type
interface PromptItem {
text: string; // 提示文本
icon?: LucideIcon; // 可选图标(仅 vertical 模式)
}Example
import { PromptPanel } from "@/registry/wuhan/composed/prompt";
import { MessageSquare, Code, Lightbulb } from "lucide-react";
function ChatPrompts() {
const prompts = [
{ text: "解释 React Hooks 的工作原理" },
{ text: "如何优化 React 性能?" },
{ text: "什么是虚拟 DOM?" },
];
const verticalPrompts = [
{ text: "帮我写一段代码", icon: Code },
{ text: "给我一些建议", icon: Lightbulb },
{ text: "开始聊天", icon: MessageSquare },
];
return (
<div className="space-y-4">
{/* 水平布局 */}
<PromptPanel
items={prompts}
variant="horizontal"
onPromptClick={(text) => console.log("Clicked:", text)}
/>
{/* 垂直布局,带图标 */}
<PromptPanel
items={verticalPrompts}
variant="vertical"
onPromptClick={(text) => console.log("Clicked:", text)}
/>
</div>
);
}PromptVariant
布局变体类型定义。
type PromptVariant = "horizontal" | "vertical";使用场景
- 聊天输入提示:在聊天框下方显示常用问题或快捷回复
- 空状态引导:新用户首次使用时的操作建议
- 搜索建议:搜索框下方的热门搜索或历史记录
- 快捷操作:提供常用操作的快速入口
- 内容发现:推荐用户可能感兴趣的话题或问题
- 教学引导:帮助用户了解功能的示例问题
最佳实践
- 布局选择:空间充足时使用 vertical 布局,空间有限时使用 horizontal
- 提示数量:建议 3-6 个提示,避免选择过载
- 文本长度:提示文本应简洁明了,建议 10-20 字以内
- 图标使用:垂直布局建议使用图标,增强视觉吸引力
- 动态更新:根据上下文动态更新提示内容,提升相关性
- 点击反馈:点击后应有明确的操作响应,如填充输入框或直接执行
注意事项
icon属性仅在variant="vertical"时生效- 垂直布局默认使用 Sparkles 图标,可通过
icon属性自定义 PromptPanel的onPromptClick回调接收点击的文本内容- 水平布局的按钮会自动换行,适应容器宽度
- 建议在移动端使用垂直布局,视觉效果更好
原语组件
Prompt 基于以下原语组件构建:
-
prompt-01 (horizontal):水平布局原语组件
PromptGroupPrimitive- 按钮组容器PromptButtonPrimitive- 紧凑按钮样式
-
prompt-02 (vertical):垂直布局原语组件
PromptGroupPrimitive- 按钮组容器PromptButtonPrimitive- 卡片式按钮PromptIconPrimitive- 图标容器
原语组件提供了基础的样式和结构,可以在以下位置找到:
样式定制
组件使用 Tailwind CSS,可以通过以下方式定制:
// 自定义按钮样式
<PromptButton
variant="horizontal"
className="bg-primary text-primary-foreground hover:bg-primary/90"
>
自定义样式
</PromptButton>
// 自定义容器样式
<PromptGroup
variant="vertical"
className="gap-4 grid grid-cols-2"
>
{/* ... */}
</PromptGroup>
// 自定义面板样式
<PromptPanel
items={items}
className="p-4 border rounded-lg"
/>扩展示例
带分类的提示列表
import { PromptPanel } from "@/registry/wuhan/composed/prompt";
import { Code, FileText, MessageSquare } from "lucide-react";
function CategorizedPrompts() {
const categories = [
{
title: "编程相关",
prompts: [
{ text: "如何学习 React?", icon: Code },
{ text: "TypeScript 最佳实践", icon: Code },
],
},
{
title: "文档编写",
prompts: [
{ text: "写一篇技术博客", icon: FileText },
{ text: "API 文档模板", icon: FileText },
],
},
];
return (
<div className="space-y-6">
{categories.map((category) => (
<div key={category.title}>
<h3 className="mb-2 text-sm font-medium text-muted-foreground">
{category.title}
</h3>
<PromptPanel
items={category.prompts}
variant="vertical"
onPromptClick={(text) => console.log(text)}
/>
</div>
))}
</div>
);
}搜索框集成
import { PromptButton } from "@/registry/wuhan/composed/prompt";
import { useState } from "react";
import { Search } from "lucide-react";
function SearchWithPrompts() {
const [query, setQuery] = useState("");
const suggestions = [
"React 性能优化",
"TypeScript 类型体操",
"Next.js 最佳实践",
];
const handlePromptClick = (text: string) => {
setQuery(text);
// 执行搜索
};
return (
<div className="space-y-2">
<div className="relative">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="搜索..."
className="w-full pl-10 pr-4 py-2 border rounded-lg"
/>
</div>
{!query && (
<div className="flex flex-wrap gap-2">
{suggestions.map((suggestion) => (
<PromptButton
key={suggestion}
variant="horizontal"
onClick={() => handlePromptClick(suggestion)}
>
{suggestion}
</PromptButton>
))}
</div>
)}
</div>
);
}动态加载提示
import { PromptPanel } from "@/registry/wuhan/composed/prompt";
import { useState, useEffect } from "react";
function DynamicPrompts() {
const [prompts, setPrompts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
// 模拟 API 调用
setTimeout(() => {
setPrompts([
{ text: "今天天气怎么样?" },
{ text: "推荐一部电影" },
{ text: "讲个笑话" },
]);
setLoading(false);
}, 1000);
}, []);
if (loading) {
return <div>加载中...</div>;
}
return (
<PromptPanel
items={prompts}
variant="horizontal"
onPromptClick={(text) => console.log(text)}
/>
);
}聊天界面集成
import { PromptPanel } from "@/registry/wuhan/composed/prompt";
import { useState } from "react";
import { Send } from "lucide-react";
function ChatInterface() {
const [input, setInput] = useState("");
const [messages, setMessages] = useState([]);
const prompts = [
{ text: "解释一下 React Hooks" },
{ text: "如何优化性能?" },
{ text: "什么是虚拟 DOM?" },
];
const handlePromptClick = (text: string) => {
setInput(text);
};
const handleSend = () => {
if (!input.trim()) return;
setMessages([...messages, { role: "user", content: input }]);
setInput("");
};
return (
<div className="flex flex-col h-screen">
{/* 消息列表 */}
<div className="flex-1 overflow-y-auto p-4">
{messages.length === 0 && (
<div className="flex items-center justify-center h-full">
<div className="text-center space-y-4">
<h2 className="text-2xl font-bold">开始对话</h2>
<PromptPanel
items={prompts}
variant="vertical"
onPromptClick={handlePromptClick}
/>
</div>
</div>
)}
{/* 渲染消息... */}
</div>
{/* 输入框 */}
<div className="border-t p-4">
<div className="flex gap-2">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === "Enter" && handleSend()}
placeholder="输入消息..."
className="flex-1 px-4 py-2 border rounded-lg"
/>
<button
onClick={handleSend}
className="px-4 py-2 bg-primary text-primary-foreground rounded-lg"
>
<Send className="w-4 h-4" />
</button>
</div>
</div>
</div>
);
}