presentation-creator by getsentry/skills
npx skills add https://github.com/getsentry/skills --skill presentation-creator使用 React + Vite + Recharts 创建交互式、数据驱动的演示文稿幻灯片,采用 Sentry 设计系统进行样式设计,并构建为单个可分发 HTML 文件。
询问用户:
在设计任何幻灯片之前,评估源内容是否包含真实的定量数据(数字、百分比、测量值、时间序列、成本、指标)。仅对存在真实数据的幻灯片创建 Recharts 可视化。请勿伪造、估算或编造数据来填充图表。
如果源内容完全是定性的(叙述、观点、策略、过程描述),演示文稿应使用零个图表。只有当至少一张幻灯片有真实数据需要可视化时,才应在项目中包含 Recharts 和 Charts.jsx。
创建项目结构:
<project-name>/
├── index.html
├── package.json
├── vite.config.js
└── src/
├── main.jsx
├── App.jsx
├── App.css
└── Charts.jsx
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link href="https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap" rel="stylesheet" />
<title>TITLE</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
{
"name": "PROJECT_NAME",
"private": true,
"type": "module",
"scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" },
"dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1", "recharts": "^2.15.3" },
"devDependencies": { "@vitejs/plugin-react": "^4.3.4", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" }
}
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { viteSingleFile } from 'vite-plugin-singlefile'
export default defineConfig({ plugins: [react(), viteSingleFile()] })
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './App.css'
ReactDOM.createRoot(document.getElementById('root')).render(<App />)
阅读 ${CLAUDE_SKILL_ROOT}/references/design-system.md 以获取完整的 Sentry 调色板、排版、CSS 变量、布局实用程序和动画系统。
将幻灯片定义为返回 JSX 的函数数组:
const SLIDES = [
() => ( /* Slide 0: Title */ ),
() => ( /* Slide 1: Context */ ),
// ...
];
每个幻灯片函数返回一个包含以下内容的 <div className="slide-content">:
<h2> 标题.anim、.d1、.d2、.d3 用于交错淡入效果请勿在标题上方添加类别标签/徽章(例如“背景”、“实验”)。它们看起来通用且没有价值。让标题本身说明问题。
实现键盘导航(ArrowRight/Space = 下一张,ArrowLeft = 上一张)和一个底部导航覆盖层,包含上一页/下一页按钮、点指示器和幻灯片编号。导航没有边框或背景——它是透明浮动的。一个小的低对比度 Sentry 标志水印固定显示在每张幻灯片的左上角。
function App() {
const [cur, setCur] = useState(0);
const go = useCallback((d) => setCur(c => Math.max(0, Math.min(SLIDES.length - 1, c + d))), []);
useEffect(() => {
const h = (e) => {
if (e.target.tagName === 'INPUT') return;
if (e.key === 'ArrowRight' || e.key === ' ') { e.preventDefault(); go(1); }
if (e.key === 'ArrowLeft') { e.preventDefault(); go(-1); }
};
window.addEventListener('keydown', h);
return () => window.removeEventListener('keydown', h);
}, [go]);
return (
<>
{cur > 0 && <div className="glyph-watermark"><SentryGlyph size={50} /><span className="watermark-title">TITLE</span></div>}
<div className="progress" style={{ width: `${((cur + 1) / SLIDES.length) * 100}%` }} />
{SLIDES.map((S, i) => (
<div key={i} className={`slide ${i === cur ? 'active' : ''}`}>
<div className={`slide-content${i === cur ? ' anim' : ''}`}>
<S />
</div>
</div>
))}
<Nav cur={cur} total={SLIDES.length} go={go} setCur={setCur} />
</>
);
}
重要:仅对源内容中有真实、具体数据支持的幻灯片创建图表。 如果幻灯片的内容是定性的(策略、经验教训、过程描述、观点),请改用基于文本的布局(卡片、表格、项目符号列表、列)。切勿编造数字、伪造百分比或生成合成数据来填充图表。如果不确定数据是真实的还是推断的,请勿创建图表。
如果没有任何幻灯片需要图表,请完全跳过此步骤——不要创建 Charts.jsx 或导入 Recharts。
当有真实数据可用时,请阅读 ${CLAUDE_SKILL_ROOT}/references/chart-patterns.md 以获取 Recharts 组件模式,包括轴配置、颜色常量、图表类型和数据生成技术。
将所有图表组件放在 Charts.jsx 中。关键模式:
ResponsiveContainer.chart-wrap div 包裹useMemo 进行数据生成CAT[])来区分数据系列和组。仅当颜色本身具有含义(好/坏、成功/失败、警告)时,才使用语义颜色(SEM_GREEN、SEM_RED、SEM_AMBER)。Area/Line 的 ComposedChart、BarChart、自定义 SVG 图表应用设计系统参考中的完整 CSS。关键元素:
--purple、--dark、--muted)。仅当颜色传达含义时,才使用语义 CSS 变量(--semantic-green、--semantic-red、--semantic-amber)。分类调色板(CAT[])用于所有其他数据可视化。fadeUp 关键帧.cols 弹性行、.cards 网格、.chart-wrap 容器.tag-purple、.tag-red、.tag-green、.tag-amber 用于幻灯片标签${CLAUDE_SKILL_ROOT}/references/sentry-logo.svg(完整字标)或 sentry-glyph.svg(仅标志)读取官方 SVG。请勿硬编码近似值——始终使用这些文件中的确切 SVG 路径。徽标(来自 ${CLAUDE_SKILL_ROOT}/references/sentry-logo.svg 或 sentry-glyph.svg)+ h1 + 副标题 + 作者/日期信息。
标签 + 标题 + 带有图标标题的 2 列卡片网格。
标签 + 标题 + 并排图表或前后对比表格。
标签 + 标题 + 全宽图表 + 下方注释项目符号。
标签 + 标题 + 带有类别标题和项目符号列表的 3 列布局。
初始搭建后:
npm install && npm run dev 以启动开发服务器npm run build 在 dist/ 中生成单个 HTML 文件一个可运行的 React + Vite 项目,它:
Charts.jsx 和 Recharts 依赖项每周安装次数
126
代码仓库
GitHub 星标数
454
首次出现
14 天前
安全审计
安装于
gemini-cli117
claude-code117
codex117
cursor117
kimi-cli116
github-copilot116
Create interactive, data-driven presentation slides using React + Vite + Recharts, styled with the Sentry design system and built as a single distributable HTML file.
Ask the user:
Before designing any slides, assess whether the source content contains real quantitative data (numbers, percentages, measurements, time series, costs, metrics). Only create Recharts visualizations for slides where real data exists. Do NOT fabricate, estimate, or invent data to fill charts.
If the source content is purely qualitative (narrative, opinions, strategy, process descriptions), the presentation should use zero charts. Recharts and Charts.jsx should only be included in the project if at least one slide has real data to visualize.
Create the project structure:
<project-name>/
├── index.html
├── package.json
├── vite.config.js
└── src/
├── main.jsx
├── App.jsx
├── App.css
└── Charts.jsx
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link href="https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap" rel="stylesheet" />
<title>TITLE</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
{
"name": "PROJECT_NAME",
"private": true,
"type": "module",
"scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" },
"dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1", "recharts": "^2.15.3" },
"devDependencies": { "@vitejs/plugin-react": "^4.3.4", "vite": "^6.0.0", "vite-plugin-singlefile": "^2.3.0" }
}
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { viteSingleFile } from 'vite-plugin-singlefile'
export default defineConfig({ plugins: [react(), viteSingleFile()] })
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './App.css'
ReactDOM.createRoot(document.getElementById('root')).render(<App />)
Read ${CLAUDE_SKILL_ROOT}/references/design-system.md for the complete Sentry color palette, typography, CSS variables, layout utilities, and animation system.
Define slides as an array of functions returning JSX:
const SLIDES = [
() => ( /* Slide 0: Title */ ),
() => ( /* Slide 1: Context */ ),
// ...
];
Each slide function returns a <div className="slide-content"> with:
<h2> heading.anim, .d1, .d2, .d3 for staggered fade-inDo NOT add category tag pills/badges above headings (e.g., "BACKGROUND", "EXPERIMENTS"). They look generic and add no value. Let the heading speak for itself.
Implement keyboard navigation (ArrowRight/Space = next, ArrowLeft = prev) and a bottom nav overlay with prev/next buttons, dot indicators, and slide number. The nav has no border or background — it floats transparently. A small low-contrast Sentry glyph watermark sits fixed in the top-left corner of every slide.
function App() {
const [cur, setCur] = useState(0);
const go = useCallback((d) => setCur(c => Math.max(0, Math.min(SLIDES.length - 1, c + d))), []);
useEffect(() => {
const h = (e) => {
if (e.target.tagName === 'INPUT') return;
if (e.key === 'ArrowRight' || e.key === ' ') { e.preventDefault(); go(1); }
if (e.key === 'ArrowLeft') { e.preventDefault(); go(-1); }
};
window.addEventListener('keydown', h);
return () => window.removeEventListener('keydown', h);
}, [go]);
return (
<>
{cur > 0 && <div className="glyph-watermark"><SentryGlyph size={50} /><span className="watermark-title">TITLE</span></div>}
<div className="progress" style={{ width: `${((cur + 1) / SLIDES.length) * 100}%` }} />
{SLIDES.map((S, i) => (
<div key={i} className={`slide ${i === cur ? 'active' : ''}`}>
<div className={`slide-content${i === cur ? ' anim' : ''}`}>
<S />
</div>
</div>
))}
<Nav cur={cur} total={SLIDES.length} go={go} setCur={setCur} />
</>
);
}
IMPORTANT: Only create charts for slides backed by real, concrete data from the source content. If a slide's content is qualitative (strategies, learnings, process descriptions, opinions), use text-based layouts instead (cards, tables, bullet lists, columns). Never invent numbers, fabricate percentages, or generate synthetic data to populate a chart. If you are unsure whether data is real or inferred, do NOT create a chart.
If NO slides require charts, skip this step entirely — do not create Charts.jsx or import Recharts.
When real data IS available, read ${CLAUDE_SKILL_ROOT}/references/chart-patterns.md for Recharts component patterns including axis configuration, color constants, chart types, and data generation techniques.
Put all chart components in Charts.jsx. Key patterns:
ResponsiveContainer with explicit height.chart-wrap div with max-width 920pxuseMemo for data generationCAT[]) for distinguishing data series and groups. Only use semantic colors (SEM_GREEN, SEM_RED, SEM_AMBER) when the color itself carries meaning (good/bad, success/failure, warning).ComposedChart with stacked Area/Line, , custom SVG diagramsApply the complete CSS from the design system reference. Key elements:
--purple, --dark, --muted). Semantic CSS variables (--semantic-green, --semantic-red, --semantic-amber) only where color conveys meaning. Categorical palette (CAT[]) for all other data visualization.fadeUp keyframe with staggered delays.cols flex rows, grid, containersLogo (from ${CLAUDE_SKILL_ROOT}/references/sentry-logo.svg or sentry-glyph.svg) + h1 + subtitle + author/date info.
Tag + heading + 2-column card grid with icon headers.
Tag + heading + side-by-side charts or before/after comparison table.
Tag + heading + full-width chart + annotation bullets below.
Tag + heading + 3-column layout with category headers and bullet lists.
After initial scaffolding:
npm install && npm run dev to start the dev servernpm run build produces a single HTML file in dist/A working React + Vite project that:
Charts.jsx and the Recharts dependency entirely if no slides have real dataWeekly Installs
126
Repository
GitHub Stars
454
First Seen
14 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli117
claude-code117
codex117
cursor117
kimi-cli116
github-copilot116
MCP图像生成技能:使用Gemini AI为营销、UI设计、演示文稿创建高质量图像
7,600 周安装
BarChart.cards.chart-wrap.tag-purple, .tag-red, .tag-green, .tag-amber for slide labels${CLAUDE_SKILL_ROOT}/references/sentry-logo.svg (full wordmark) or sentry-glyph.svg (glyph only). Do NOT hardcode an approximation — always use the exact SVG paths from these files.