MagicWords 组件
魔法词填空组件,通过拖拽或点击方式完成句子填空游戏。
功能概述
- 填空游戏: 将正确的词语填入句子空白处
- 拖拽支持: 支持拖拽操作
- 点击支持: 也支持点击选择
- 即时反馈: 提交后立即显示正确/错误
- 多次尝试: 错误后可以重试
- 进度保存: 自动保存游戏状态
Props 接口
interface BlankConfig {
id?: string; // 空白标识(可选,自动生成)
hint: string; // 空白处提示文本
answers: string[]; // 可接受的正确答案列表
emoji?: string; // 相关 Emoji(可选)
}
interface MagicWordsProps {
title?: string; // 标题
sentence: string; // 句子(使用 _ 或 {{placeholder}} 表示空白)
blanks: BlankConfig[]; // 空白配置数组
successMessage?: string; // 成功消息
}
句子格式
支持两种空白标记方式:
下划线标记
sentence="请帮我 ___ 一个故事"
花括号标记
sentence="请帮我 {{动词}} 一个故事"
交互流程
- 查看句子: 显示带空白的句子
- 选择词语: 从词库中拖拽或点击词语
- 填入空白: 将词语放入对应空白
- 提交检查: 点击检查按钮
- 查看结果: 显示得分和正确答案
- 重试: 可以重新开始
使用示例
import { MagicWords } from "@/components/kids/elements/magic-words";
<MagicWords
title="魔法词大挑战"
sentence="请帮我 ___ 一个关于 ___ 的故事"
blanks={[
{ hint: "动词", answers: ["写", "创作", "编"] },
{ hint: "主题", answers: ["太空", "恐龙", "魔法"] },
]}
successMessage="太棒了!你找到了所有魔法词!"
/>
翻译键
{
"kids": {
"magicWords": {
"title": "✨ 魔法词",
"dragOrTap": "拖拽或点击词语填空:",
"correct": "正确",
"tryAgain": "再试一次!",
"check": "检查答案"
}
}
}
保存的状态
interface SavedState {
placements: Record<string, string>; // 空白填充状态
submitted: boolean; // 是否已提交
availableWords: { word: string; blankId: string }[]; // 可用词语(打乱顺序)
}
答案验证
const checkAnswer = (blankId: string, value: string): boolean => {
const blank = blanksWithIds.find((b) => b.id === blankId);
if (!blank) return false;
return blank.answers.some(
(answer) => answer.toLowerCase() === value.toLowerCase()
);
};
样式说明
- 面板样式:
pixel-panel pixel-panel-purple - 头部: 紫色到粉色渐变
- 空白区域: 紫色虚线边框
- 词库区域: 紫色背景,像素边框
空白状态
- 未填充: 白色背景,紫色虚线边框
- 已填充: 紫色背景,实线边框
- 正确: 绿色边框,绿色背景
- 错误: 红色边框,红色背景
词语状态
- 可用: 白色背景,可拖拽
- 已使用: 灰色背景,不可交互
依赖
next-intl- 国际化lucide-react- 图标@/components/ui/button- 按钮@/lib/utils(cn)@/components/kids/providers/level-context@/lib/kids/progress
注意事项
- 需要包裹在
LevelProvider内使用 - 词语会自动打乱顺序
- 支持大小写不敏感匹配
- 已填写的词语可以从空白处点击移除
- 支持触摸设备操作