Skill
An interactive skill showcase component with hover animations and icon reveals
Overview
A beautiful interactive skill showcase component that displays technology skills with smooth hover animations. When users hover over a skill tag, the corresponding technology icon appears with a spring animation effect.
Features
- Interactive hover effects with smooth animations
- Icon reveals on hover using Framer Motion
- Responsive design that works on all screen sizes
- Pre-configured technology stack with popular frameworks and tools
- Customizable styling with dark theme support
- Spring animations for natural feel
Basic Usage
Animation Details
The Skill component uses Framer Motion for smooth animations:
Hover Animation
- Initial state:
opacity: 0, y: 0, scale: 0.9 - Animate state:
opacity: 1, y: -90, scale: 1 - Exit state:
opacity: 0, y: 0, scale: 0.9 - Transition: Spring animation with
stiffness: 120, damping: 18
Icon Positioning
- Icons appear 90px above the skill tag
- Centered horizontally using
left-1/2 -translate-x-1/2 - Size: 40x40px (10x10 in Tailwind units)
Customization
Adding New Skills
To add new skills, modify the SkillItem array:
const SkillItem: skillProps[] = [
// ... existing skills
{
name: 'Vue.js',
icon: <IconBrandVue stroke={1} />
},
{
name: 'Python',
icon: <IconBrandPython stroke={1} />
},
]Styling Customization
You can customize the appearance by modifying the className props:
// Custom skill tag styling
<span className="cursor-default rounded-full border border-blue-500 bg-blue-50 px-4 py-1.5 text-xs text-blue-700 transition-all hover:border-blue-600 sm:px-5 sm:py-2 sm:text-sm md:text-base">
{skill.name}
</span>
// Custom icon container styling
<motion.div
className="absolute left-1/2 z-10 flex h-16 w-16 -translate-x-1/2 items-center justify-center bg-white rounded-full shadow-lg"
>
<div className="h-12 w-12 text-blue-600">{skill.icon}</div>
</motion.div>Animation Customization
Adjust the animation parameters for different effects:
// Faster, bouncier animation
transition={{ type: "spring", stiffness: 200, damping: 10 }}
// Slower, smoother animation
transition={{ type: "spring", stiffness: 80, damping: 25 }}
// Different positioning
animate={{ opacity: 1, y: -120, scale: 1.1 }}Installation
Dependencies
npm install @tabler/icons-react motionRequired Icons
The component uses Tabler Icons. Make sure to import the specific icons you need:
import {
IconBrandJavascript,
IconBrandNextjs,
IconBrandTypescript,
IconBrandReact,
IconBrandTailwind,
IconBrandPrisma,
IconBrandNodejs,
IconBrandGolang,
IconBrandAws,
IconBrandDocker,
IconBrandMongodb
} from "@tabler/icons-react"Usage Examples
Basic Implementation
import Skill from '@/components/aesthe-ui/skill/Skill'
export default function AboutPage() {
return (
<div>
<h1>My Skills</h1>
<Skill />
</div>
)
}With Custom Styling
import Skill from '@/components/aesthe-ui/skill/Skill'
export default function SkillsSection() {
return (
<section className="py-20 bg-gradient-to-br from-slate-900 to-slate-800">
<div className="container mx-auto">
<h2 className="text-3xl font-bold text-center mb-12 text-white">
Technologies I Work With
</h2>
<Skill />
</div>
</section>
)
}Props
The Skill component doesn't accept any props currently, but you can extend it to be more flexible:
interface SkillProps {
skills?: skillProps[]
className?: string
showIcons?: boolean
}
const Skill = ({ skills = SkillItem, className, showIcons = true }: SkillProps) => {
return (
<SkillItemCore skills={skills} className={className} showIcons={showIcons} />
)
}Responsive Design
The component is fully responsive with different spacing and sizing:
- Mobile:
gap-x-3 gap-y-8,px-4 py-1.5,text-xs - Small screens:
sm:px-5 sm:py-2 sm:text-sm - Medium screens:
md:text-base,md:gap-x-4
Accessibility
The component includes proper accessibility features:
- Keyboard navigation: Uses
cursor-defaultfor proper cursor behavior - Screen readers: Icons are properly labeled through the skill names
- Focus management: Hover states work with keyboard navigation
- Color contrast: Dark theme ensures good readability
Performance
- Optimized animations: Uses Framer Motion's optimized animation system
- Conditional rendering: Icons only render when needed using
AnimatePresence - Efficient state management: Minimal re-renders with targeted state updates