feat: Puente Mayúscula-Minúscula + TTS SpeechSynthesis + E2E fixes

This commit is contained in:
renato97
2026-07-21 15:31:46 -03:00
commit fa8e0c58ce
120 changed files with 16013 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
"use client"
import { useState } from "react"
import { motion } from "framer-motion"
export interface CuisenaireRodProps {
value: number
color: string
length: number
draggable?: boolean
onDrop?: (value: number) => void
}
const rodColors: Record<number, string> = {
1: "#FFFFFF",
2: "#E74C3C",
3: "#2ECC71",
4: "#E91E63",
5: "#F1C40F",
6: "#1ABC9C",
7: "#2C3E50",
8: "#3498DB",
9: "#9B59B6",
10: "#E67E22",
}
const rodLengths: Record<number, number> = {
1: 20, 2: 40, 3: 60, 4: 80, 5: 100,
6: 120, 7: 140, 8: 160, 9: 180, 10: 200,
}
export { rodColors, rodLengths }
export function CuisenaireRod({ value, color, length, draggable = false }: CuisenaireRodProps) {
const [isDragging, setIsDragging] = useState(false)
return (
<motion.div
className={`rounded-lg border border-border/50 shadow-sm touch-target select-none ${
draggable ? "cursor-grab" : ""
} ${isDragging ? "cursor-grabbing z-10" : ""}`}
style={{
width: `${length}px`,
minWidth: `${length}px`,
height: "40px",
backgroundColor: color,
borderColor: value === 1 ? "#ddd" : undefined,
}}
whileTap={draggable ? { scale: 1.08 } : undefined}
drag={draggable}
dragElastic={0.1}
dragMomentum={false}
onDragStart={() => setIsDragging(true)}
onDragEnd={() => setIsDragging(false)}
dragConstraints={{ left: -400, right: 400, top: -300, bottom: 300 }}
/>
)
}