Init
This commit is contained in:
132
docs/design-examples/components/ExperimentaButton.vue
Normal file
132
docs/design-examples/components/ExperimentaButton.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* ExperimentaButton Component
|
||||
*
|
||||
* Experimenta-branded button with animated gradient background.
|
||||
* Based on the experimenta Design System.
|
||||
*
|
||||
* @example
|
||||
* <ExperimentaButton>Click me</ExperimentaButton>
|
||||
* <ExperimentaButton variant="secondary">Cancel</ExperimentaButton>
|
||||
* <ExperimentaButton size="small">Small</ExperimentaButton>
|
||||
*/
|
||||
|
||||
interface Props {
|
||||
/** Button variant */
|
||||
variant?: 'primary' | 'secondary'
|
||||
/** Button size */
|
||||
size?: 'small' | 'medium' | 'large'
|
||||
/** Disabled state */
|
||||
disabled?: boolean
|
||||
/** Button type */
|
||||
type?: 'button' | 'submit' | 'reset'
|
||||
/** Link behavior (renders as <a> tag) */
|
||||
href?: string
|
||||
/** Target for links */
|
||||
target?: '_blank' | '_self' | '_parent' | '_top'
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
variant: 'primary',
|
||||
size: 'large',
|
||||
disabled: false,
|
||||
type: 'button',
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
click: [event: MouseEvent]
|
||||
}>()
|
||||
|
||||
function handleClick(event: MouseEvent) {
|
||||
emit('click', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="href ? 'a' : 'button'"
|
||||
:href="href"
|
||||
:target="href ? target : undefined"
|
||||
:type="!href ? type : undefined"
|
||||
:disabled="!href ? disabled : undefined"
|
||||
:class="[
|
||||
'btn-experimenta',
|
||||
`btn-${variant}`,
|
||||
`btn-${size}`,
|
||||
{
|
||||
'btn-disabled': disabled,
|
||||
},
|
||||
]"
|
||||
@click="handleClick"
|
||||
>
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Base Button Styles */
|
||||
.btn-experimenta {
|
||||
@apply inline-block cursor-pointer;
|
||||
@apply font-medium text-white;
|
||||
@apply transition-all;
|
||||
@apply outline-0 border-0;
|
||||
@apply rounded-2xl;
|
||||
text-decoration: none;
|
||||
line-height: 1.7em;
|
||||
}
|
||||
|
||||
/* Primary Variant */
|
||||
.btn-primary {
|
||||
background: #e6007e;
|
||||
background-image: linear-gradient(to left, #e6007e, #e6007e, #e40521, #e6007e);
|
||||
background-size: 300%;
|
||||
background-position: left;
|
||||
transition:
|
||||
background-position 1s ease,
|
||||
all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover:not(.btn-disabled) {
|
||||
background-position: right;
|
||||
}
|
||||
|
||||
/* Secondary Variant */
|
||||
.btn-secondary {
|
||||
@apply bg-transparent border-2 border-accent text-accent;
|
||||
}
|
||||
|
||||
.btn-secondary:hover:not(.btn-disabled) {
|
||||
@apply bg-accent text-white;
|
||||
}
|
||||
|
||||
/* Sizes */
|
||||
.btn-large {
|
||||
@apply text-lg px-8 py-2.5;
|
||||
}
|
||||
|
||||
.btn-medium {
|
||||
@apply text-base px-6 py-2;
|
||||
}
|
||||
|
||||
.btn-small {
|
||||
@apply text-base px-6 py-2;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 480px) {
|
||||
.btn-large {
|
||||
@apply text-base px-6 py-2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disabled State */
|
||||
.btn-disabled {
|
||||
@apply opacity-50 cursor-not-allowed;
|
||||
}
|
||||
|
||||
/* Focus State (Accessibility) */
|
||||
.btn-experimenta:focus-visible {
|
||||
@apply outline-none ring-2 ring-accent ring-offset-2;
|
||||
ring-offset-color: var(--color-purple-darkest, #0f051d);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user