Aller au contenu

ReactionPicker

composant

The other reactions of phil/reactions-bundle: a disclosure of buttons grouped under their headings, which work with no script. The picker controller of the bundle adds a search by label, the arrow keys, Home, End and Escape. It is written inside the form that receives the buttons.

Aperçu

Clair

More reactions

Code
<twig:ReactionPicker label="More reactions" :groups="[{label: 'Emojis', options: [{label: 'Like', emoji: '👍', image: null, imageAlt: null, attributes: {name: 'react', value: 'like'}}]}]" />

Sombre

More reactions

Code
<twig:ReactionPicker label="More reactions" :groups="[{label: 'Emojis', options: [{label: 'Like', emoji: '👍', image: null, imageAlt: null, attributes: {name: 'react', value: 'like'}}]}]" />

Usage

Usage

More reactions

Code
<form method="post">
    <twig:ReactionPicker label="More reactions" :groups="groups" />
</form>

Installation

php bin/console ux:install reaction-picker --kit=github.com/parler-haut-interagir-librement/ux-kit

Propriétés

PropriétéTypePar défautDescription
searchLabel string 'Search reactions by name' The name of the search field.
emptyLabel string 'No reaction has this name.' What is shown when the search finds nothing.
resultsLabel string 'Reactions shown: {count}' What screen readers hear after a search, {count} being the number of reactions shown.

Examples

Translated texts

The texts are props; {count} in resultsLabel is replaced by the number of reactions shown.

<twig:ReactionPicker label="Autres réactions" :groups="groups" searchLabel="Chercher par nom" emptyLabel="Aucune réaction." resultsLabel="Réactions affichées : {count}" />

Fichiers à copier

templates/components/ReactionPicker.html.twig
{#-
 # The other reactions: a disclosure of plain buttons under their headings, written inside the form that receives them.
 # The picker controller of phil/reactions-bundle shows the search and adds the keyboard; every button works without it.
 #}
{%- props
    ## string The name of the disclosure.
    label,
    ## array The reactions under their headings: each {label, options}, an option being {label, emoji, image, imageAlt, attributes}; of the attributes, only name, value, title, data-* and aria-* are written.
    groups,
    ## string The name of the search field.
    searchLabel = 'Search reactions by name',
    ## string What is shown when the search finds nothing.
    emptyLabel = 'No reaction has this name.',
    ## string What screen readers hear after a search, {count} being the number of reactions shown.
    resultsLabel = 'Reactions shown: {count}'
-%}
{%- set _c = 'phil--reactions-bundle--picker' -%}
<details{{ attributes.defaults({
    class: 'isReactionPicker',
    'data-controller': _c,
    'data-action': 'toggle->' ~ _c ~ '#toggled keydown->' ~ _c ~ '#keydown click->' ~ _c ~ '#choose click@window->' ~ _c ~ '#outside',
    ('data-' ~ _c ~ '-results-value'): resultsLabel,
}) }}>
    <summary class="isReaction" data-phil--reactions-bundle--picker-target="summary">{{ label }}</summary>
    <div class="isStack isReactionPickerPanel">
        <input type="search" hidden autocomplete="off" aria-label="{{ searchLabel }}" placeholder="{{ searchLabel }}" data-phil--reactions-bundle--picker-target="search" data-action="input->phil--reactions-bundle--picker#filter">
        <p class="isVisuallyHidden" role="status" data-phil--reactions-bundle--picker-target="status"></p>
        <p class="isMuted" hidden data-phil--reactions-bundle--picker-target="empty">{{ emptyLabel }}</p>
        {%- for group in groups %}
        <div role="group" aria-label="{{ group.label }}" data-phil--reactions-bundle--picker-target="group">
            <p class="isMuted" aria-hidden="true">{{ group.label }}</p>
            <div class="isCluster">
                {%- for option in group.options %}
                <button class="isReaction" type="submit" data-phil--reactions-bundle--picker-target="option" data-search="{{ option.label }}"{% for name, value in option.attributes %}{% if name matches '/^(name|value|title|(data|aria)-[a-z0-9-]+)$/' %} {{ name }}="{{ value }}"{% endif %}{% endfor %}>
                    {%- if option.image is not null -%}
                    <img src="{{ option.image }}" alt="{{ option.imageAlt ?? option.label }}" width="20" height="20" loading="lazy">
                    {%- else -%}
                    <span aria-hidden="true">{{ option.emoji }}</span><span class="isVisuallyHidden">{{ option.label }}</span>
                    {%- endif -%}
                </button>
                {%- endfor %}
            </div>
        </div>
        {%- endfor %}
    </div>
</details>