PlayfulButton.vue 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. <template>
  2. <button
  3. class="playful-btn"
  4. :class="['playful-btn--' + variant, 'playful-btn--' + size]"
  5. :disabled="disabled"
  6. @click="emitClick"
  7. :aria-label="ariaLabel"
  8. >
  9. <slot></slot>
  10. </button>
  11. </template>
  12. <script>
  13. export default {
  14. name: 'PlayfulButton',
  15. props: {
  16. variant: { type: String, default: 'primary' }, // 'primary' | 'secondary'
  17. size: { type: String, default: 'md' }, // 'sm' | 'md' | 'lg'
  18. disabled: { type: Boolean, default: false },
  19. ariaLabel: { type: String, default: '' }
  20. },
  21. methods: {
  22. emitClick(e) {
  23. if (!this.disabled) this.$emit('click', e);
  24. }
  25. }
  26. }
  27. </script>
  28. <style scoped>
  29. .playful-btn {
  30. border: none;
  31. border-radius: 999px;
  32. padding: 0.6rem 1rem;
  33. font-weight: 700;
  34. cursor: pointer;
  35. transition: transform .15s ease, box-shadow .15s ease;
  36. }
  37. .playful-btn--primary {
  38. background: var(--color-primary, #0EA5E9);
  39. color: #fff;
  40. box-shadow: 0 2px 6px rgba(14,165,233,.3);
  41. }
  42. .playful-btn--secondary {
  43. background: #f8fafc;
  44. color: var(--text, #1f2937);
  45. border: 1px solid var(--border, #e5e7eb);
  46. }
  47. .playful-btn--sm { font-size: 0.875rem; padding: 0.5rem 0.75rem; }
  48. .playful-btn--md { font-size: 1rem; padding: 0.6rem 1rem; }
  49. .playful-btn--lg { font-size: 1.125rem; padding: 0.75rem 1.25rem; }
  50. .playful-btn:active { transform: translateY(1px) scale(0.98); }
  51. .playful-btn:focus { outline: 2px solid rgba(14,165,233,.6); outline-offset: 2px; }
  52. </style>