Feedback errorfeedback

Shake Feedback

Horizontal shake indicator for errors.

Preview

Usage

Copy the full block below to use this component with its imports.

astro
---
import { ShakeFeedback } from 'astro-component-kit';
---

<ShakeErrorGroup message="Wrong password" active />
--- import { ShakeFeedback } from 'astro-component-kit'; --- <ShakeErrorGroup message="Wrong password" active />

Manual Installation

If you are not using the npm package, create a new file src/components/lib/ShakeFeedback.astro and paste the following code:

astro
---
/**
 * ShakeError — A feedback container that shakes horizontally to indicate failure or invalid input.
 * 
 * @param {string} message - The error message to display.
 * @param {boolean} active - If true, triggers the shake animation once.
 */
interface Props {
  message: string;
  active?: boolean;
}

const { message, active = false } = Astro.props;
---

<div class:list={["shake-box", { "shake-box--active": active }]} role="alert">
  <span class="shake-box__icon" aria-hidden="true">⚠️</span>
  <span class="shake-box__msg">{message}</span>
</div>

<style>
  .shake-box { 
    display: flex; 
    align-items: center; 
    gap: var(--sp-3, 0.75rem);
    background: rgba(239, 68, 68, 0.08); 
    border: 1px solid var(--c-error, #ef4444); 
    color: #f87171; 
    padding: var(--sp-4, 1rem); 
    border-radius: var(--r-md, 10px); 
    text-align: center; 
    font-weight: 600; 
    width: 100%;
    box-sizing: border-box;
  }
  
  .shake-box--active { animation: shake-kb 0.5s cubic-bezier(.36,.07,.19,.97) both; }
  
  .shake-box__icon { font-size: 1rem; }
  .shake-box__msg { font-size: 0.9rem; }

  @keyframes shake-kb { 
    10%, 90% { transform: translateX(-1px); } 
    20%, 80% { transform: translateX(2px); } 
    30%, 50%, 70% { transform: translateX(-4px); } 
    40%, 60% { transform: translateX(4px); } 
  }
</style>
--- /** * ShakeError — A feedback container that shakes horizontally to indicate failure or invalid input. * * @param {string} message - The error message to display. * @param {boolean} active - If true, triggers the shake animation once. */ interface Props { message: string; active?: boolean; } const { message, active = false } = Astro.props; --- <div class:list={["shake-box", { "shake-box--active": active }]} role="alert"> <span class="shake-box__icon" aria-hidden="true">⚠️</span> <span class="shake-box__msg">{message}</span> </div> <style> .shake-box { display: flex; align-items: center; gap: var(--sp-3, 0.75rem); background: rgba(239, 68, 68, 0.08); border: 1px solid var(--c-error, #ef4444); color: #f87171; padding: var(--sp-4, 1rem); border-radius: var(--r-md, 10px); text-align: center; font-weight: 600; width: 100%; box-sizing: border-box; } .shake-box--active { animation: shake-kb 0.5s cubic-bezier(.36,.07,.19,.97) both; } .shake-box__icon { font-size: 1rem; } .shake-box__msg { font-size: 0.9rem; } @keyframes shake-kb { 10%, 90% { transform: translateX(-1px); } 20%, 80% { transform: translateX(2px); } 30%, 50%, 70% { transform: translateX(-4px); } 40%, 60% { transform: translateX(4px); } } </style>

Quick Info

Category
Feedback
Filename
ShakeFeedback.astro
Dependencies
None — pure Astro + CSS
Tags
errorfeedback