Aller au contenu

Sheet

composant

A panel sliding from an edge of the screen: a Dialog that keeps to one side, with the same controller.

Aperçu

Clair

Menu

Code
<twig:Sheet id="menu" side="left">
    <twig:Sheet:Trigger>
        <twig:Button variant="outline" {{ ...sheet_trigger_attrs }}>Menu</twig:Button>
    </twig:Sheet:Trigger>
    <twig:Sheet:Content>
        <twig:Sheet:Header><twig:Sheet:Title>Menu</twig:Sheet:Title></twig:Sheet:Header>
    </twig:Sheet:Content>
</twig:Sheet>

Sombre

Menu

Code
<twig:Sheet id="menu" side="left">
    <twig:Sheet:Trigger>
        <twig:Button variant="outline" {{ ...sheet_trigger_attrs }}>Menu</twig:Button>
    </twig:Sheet:Trigger>
    <twig:Sheet:Content>
        <twig:Sheet:Header><twig:Sheet:Title>Menu</twig:Sheet:Title></twig:Sheet:Header>
    </twig:Sheet:Content>
</twig:Sheet>

Essayer

Changez les propriétés ; le serveur rend l’exemple de nouveau.

Menu

<twig:Sheet id="menu" side="left">
    <twig:Sheet:Trigger>
        <twig:Button variant="outline" {{ ...sheet_trigger_attrs }}>Menu</twig:Button>
    </twig:Sheet:Trigger>
    <twig:Sheet:Content>
        <twig:Sheet:Header><twig:Sheet:Title>Menu</twig:Sheet:Title></twig:Sheet:Header>
    </twig:Sheet:Content>
</twig:Sheet>

Variantes

side

Which edge the sheet slides in from.

Menu

Menu

side="top"

Menu

Menu

side="right"

Menu

Menu

side="bottom"

Menu

Menu

side="left"

open

Whether the sheet is open on initial render.

Menu

Menu

open="false"

Menu

Menu

open="true"

Installation

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

Elle apporte les recettes dont elle a besoin : dialog, button

Propriétés

PropriétéTypePar défautDescription
side 'top'|'right'|'bottom'|'left' 'right' Which edge the sheet slides in from.
open bool false Whether the sheet is open on initial render.

Accessibility

As Dialog: modal, named by its title, closed by Escape and by a click on the backdrop, the focus kept inside and given back; the browser's invokers and closedby first, the controller where the browser has neither.

Fichiers à copier

templates/components/Sheet.html.twig
{%- props
    ## string Unique identifier used to generate internal Sheet IDs.
    id,
    ## 'top'|'right'|'bottom'|'left' Which edge the sheet slides in from.
    side = 'right',
    ## bool Whether the sheet is open on initial render.
    open = false
-%}
{%- set _sheet_id = 'sheet-' ~ id -%}
{%- do provide('sheet.id', _sheet_id) -%}
{%- do provide('sheet.side', side) -%}
{%- do provide('sheet.titleId', _sheet_id ~ '-title') -%}
{%- do provide('sheet.descriptionId', _sheet_id ~ '-description') -%}
<div data-slot="sheet" data-dialog-open-value="{{ open ? 'true' : 'false' }}"{{ attributes.defaults({class: 'hasDialog', 'data-controller': 'dialog'}) }}>
{##- The sheet structure, typically includes `Sheet:Trigger` and `Sheet:Content`. -#}
{%- block content %}{% endblock -%}
</div>
templates/components/Sheet/Close.html.twig
{%- set sheet_close_attrs = {
    'data-slot': 'sheet-close',
    'data-action': 'click->dialog#close',
    command: 'close',
    commandfor: inject('sheet.id'),
} -%}
{##- The close trigger element (e.g., a `Button`) that closes the sheet when clicked. -#}
{%- block content %}{% endblock -%}
templates/components/Sheet/Content.html.twig
{%- props
    ## bool Whether to display the close button.
    showCloseButton = true,
    ## string What screen readers read for the close button.
    closeLabel = 'Close'
-%}
{%- set _id = inject('sheet.id') -%}
{%- set _edge = {left: ' isStart', top: ' isTop', bottom: ' isBottom'}[inject('sheet.side', 'right')] ?? '' -%}
<dialog id="{{ _id }}" closedby="any" aria-labelledby="{{ inject('sheet.titleId') }}" aria-describedby="{{ inject('sheet.descriptionId') }}" data-slot="sheet-content" data-dialog-target="dialog" data-side="{{ inject('sheet.side', 'right') }}"{{ attributes.defaults({class: 'isSheet' ~ _edge, 'data-action': 'click->dialog#closeOnClickOutside close->dialog#closed'}) }}>
{##- The sheet content, typically includes `Sheet:Header` and optionally `Sheet:Footer`. -#}
{%- block content %}{% endblock -%}
{%- if showCloseButton %}
<twig:Button class="isSheetClose" type="button" variant="ghost" size="icon-sm" data-slot="sheet-close" data-action="click->dialog#close" command="close" commandfor="{{ _id }}">
    <span aria-hidden="true">&times;</span><span class="isVisuallyHidden">{{ closeLabel }}</span>
</twig:Button>
{%- endif %}
</dialog>
templates/components/Sheet/Description.html.twig
<p id="{{ inject('sheet.descriptionId') }}" data-slot="sheet-description"{{ attributes.without('id').defaults({class: 'isSheetDescription'}) }}>
{##- The descriptive text explaining the sheet purpose. -#}
{%- block content %}{% endblock -%}
</p>
templates/components/Sheet/Footer.html.twig
<footer data-slot="sheet-footer"{{ attributes.defaults({class: 'isSheetFooter'}) }}>
{##- The footer area, typically contains action buttons. -#}
{%- block content %}{% endblock -%}
</footer>
templates/components/Sheet/Header.html.twig
<header data-slot="sheet-header"{{ attributes.defaults({class: 'isSheetHeader'}) }}>
{##- The header area, typically contains `Sheet:Title` and `Sheet:Description`. -#}
{%- block content %}{% endblock -%}
</header>
templates/components/Sheet/Title.html.twig
<h2 id="{{ inject('sheet.titleId') }}" data-slot="sheet-title"{{ attributes.without('id').defaults({class: 'isSheetTitle'}) }}>
{##- The title text of the sheet. -#}
{%- block content %}{% endblock -%}
</h2>
templates/components/Sheet/Trigger.html.twig
{%- set sheet_trigger_attrs = {
    'data-slot': 'sheet-trigger',
    'data-action': 'click->dialog#open',
    'data-dialog-target': 'trigger',
    'aria-haspopup': 'dialog',
    command: 'show-modal',
    commandfor: inject('sheet.id'),
} -%}
{##- The trigger element (e.g., a `Button`) that opens the sheet when clicked. -#}
{%- block content %}{% endblock -%}