AnimatedButton
componentA button, or a link when it has an address, that moves under the pointer and the focus: a light sweeping across it, a lift or its arrow pushed forward. Pure CSS.
Preview
Code
<twig:AnimatedButton effect="arrow">Get started</twig:AnimatedButton>
Code
<twig:AnimatedButton effect="arrow">Get started</twig:AnimatedButton>
Try it
Change the props; the example is rendered again by the server.
<twig:AnimatedButton effect="arrow">Get started</twig:AnimatedButton>
<twig:AnimatedButton effect="arrow">Get started</twig:AnimatedButton>
Variants
effect
How it moves.
type
The type of the button.
loading
Whether what it started is still running.
Installation
php bin/console ux:install animated-button --kit=github.com/parler-haut-interagir-librement/ux-kit
Props
| Prop | Type | Default | Description |
|---|---|---|---|
effect |
'shine'|'lift'|'arrow' |
'shine' |
How it moves. |
href |
string|null |
null |
Where the link leads; a button when null. |
type |
'button'|'submit'|'reset' |
'button' |
The type of the button. |
loading |
bool |
false |
Whether what it started is still running. |
Accessibility
The animation adds nothing to what the button says, and it stands still under prefers-reduced-motion. While loading, the button has aria-busy="true"; the arrow is hidden from screen readers and turns around right to left.
Files to copy
templates/components/AnimatedButton.html.twig
{#-
# A button, or a link when it has an address, that moves under the pointer and the focus, and stands still under
# reduced motion. While `loading`, it says so and waits under a spinner.
#}
{%- props
## 'shine'|'lift'|'arrow' How it moves.
effect = 'shine',
## string|null Where the link leads; a button when null.
href = null,
## 'button'|'submit'|'reset' The type of the button.
type = 'button',
## bool Whether what it started is still running.
loading = false
-%}
{%- set _effect = {shine: 'hasShine', lift: 'hasLift', arrow: 'hasArrow'}[effect] ?? 'hasShine' -%}
{%- set _class = 'isAnimatedButton ' ~ _effect ~ (loading ? ' isLoading' : '') -%}
{%- set _tag = href is null ? 'button' : 'a' -%}
<{{ _tag }}{% if href is null %} type="{{ type in ['submit', 'reset'] ? type : 'button' }}"{% else %} href="{{ href }}"{% endif %}{{ attributes.defaults({class: _class ~ (href is null ? '' : ' isButton')}|merge(loading ? {'aria-busy': 'true'} : {})) }}><span class="isAnimatedButtonLabel">
{##- What the button says. -#}
{%- block content %}{% endblock -%}
</span>{% if effect is same as('arrow') %}<span class="isAnimatedButtonArrow" aria-hidden="true">→</span>{% endif %}</{{ _tag }}>