Commit c9d8654d authored by Ben Mullins's avatar Ben Mullins Committed by Tim Plunkett
Browse files

Issue #3282707 by bnjmnm, hooroomoo: Pagination accessibility improvements

parent 4e0576be
Loading
Loading
Loading
Loading
+0 −0

File changed.

Preview suppressed by a .gitattributes entry or the file's encoding is unsupported.

+0 −0

File changed.

Preview suppressed by a .gitattributes entry or the file's encoding is unsupported.

+0 −0

File changed.

Preview suppressed by a .gitattributes entry or the file's encoding is unsupported.

+57 −0
Original line number Diff line number Diff line
<script>
  import { createEventDispatcher, getContext } from 'svelte';

  const dispatch = createEventDispatcher();
  const stateContext = getContext('state');
  const { Drupal } = window;

  export let itemTypes = [];
  export let linkTypes = [];
  export let label = '';
  export let toPage = 0;
  export let ariaLabel = null;
  export let isCurrent = false;

  function onChange(event, selectedPage) {
    const state = stateContext.getState();
    const detail = {
      originalEvent: event,
      page: selectedPage,
      pageIndex: 0,
      pageSize: state.pageSize,
    };
    dispatch('pageChange', detail);
    if (detail.preventDefault !== true) {
      stateContext.setPage(detail.page, detail.pageIndex);
    }
  }
</script>

<li
  class={`pager__item ${itemTypes
    .map((item) => `pager__item--${item}`)
    .join(' ')}`}
  class:pager__item--active={isCurrent}
>
  <a
    href={'#'}
    class={`pager__link ${linkTypes
      .map((item) => `pager__link--${item}`)
      .join(' ')}`}
    class:is-active={isCurrent}
    aria-label={ariaLabel || Drupal.t('@location page', { '@location': label })}
    on:click={(e) => onChange(e, toPage)}
    aria-current={isCurrent ? 'page' : null}
  >
    {label}
  </a>
</li>

<style>
  .pager__link--forward::after {
    margin-left: 0.5rem;
  }
  .pager__link--backward::before {
    margin-right: 0.5rem;
  }
</style>
+45 −117
Original line number Diff line number Diff line
<script>
  import { createEventDispatcher, getContext } from 'svelte';
  import PagerItem from './PagerItem.svelte';

  const dispatch = createEventDispatcher();
  const stateContext = getContext('state');
  const { Drupal } = window;

  export let buttons = [-4, -3, -2, -1, 0, 1, 2, 3, 4];
  export let count;
  export let page = 0;
  export let pageSize;
  export let serverSide = false;

  export let labels = {
    first: Drupal.t('First'),
@@ -19,63 +16,30 @@
  };

  $: pageCount = Math.floor(count / pageSize);

  function onChange(event, selectedPage) {
    const state = stateContext.getState();
    const detail = {
      originalEvent: event,
      page: selectedPage,
      pageIndex: serverSide ? 0 : selectedPage * state.pageSize,
      pageSize: state.pageSize,
    };
    dispatch('pageChange', detail);

    if (detail.preventDefault !== true) {
      stateContext.setPage(detail.page, detail.pageIndex);
    }
  }
</script>

<nav class="pager" aria-labelledby="pagination-heading">
  <!-- @todo this h4 can cause a11y issues, fix after https://www.drupal.org/project/drupal/issues/3232222 -->
  <h4 id="pagination-heading" class="visually-hidden">
    {Drupal.t('Pagination')}
  </h4>
<!-- svelte-ignore a11y-no-redundant-roles -->
<nav
  class="pager"
  aria-label={Drupal.t('Project Browser Pagination')}
  role="navigation"
>
  <ul class="pager__items js-pager__items">
    {#if page !== 0}
      <li class="pager__item pager__item--action pager__item--first">
        <a
          href={'#'}
          class="pager__link pager__link--action-link"
          title={Drupal.t('Go to first page')}
          on:click={(e) => onChange(e, 0)}
        >
          <span class="visually-hidden"
            >{Drupal.t('@location page', { '@location': labels.first })}</span
          >
          <span
            class="pager__item-title pager__item-title--backwards"
            aria-hidden="true">{labels.first}</span
          >
        </a>
      </li>
      <li class="pager__item pager__item--action pager__item--previous">
        <a
          href={'#'}
          class="pager__link pager__link--action-link"
          on:click={(e) => onChange(e, page - 1)}
          title={Drupal.t('Go to previous page')}
          rel="prev"
        >
          <span class="visually-hidden">{labels.previous} page</span>
          <span
            class="pager__item-title pager__item-title--backwards"
            aria-hidden="true"
          >
            {labels.previous}
          </span>
        </a>
      </li>
      <PagerItem
        on:pageChange
        itemTypes={['action', 'first']}
        linkTypes={['action-link', 'backward']}
        label={labels.first}
        toPage={0}
      />
      <PagerItem
        on:pageChange
        itemTypes={['action', 'previous']}
        linkTypes={['action-link', 'backward']}
        label={labels.previous}
        toPage={page - 1}
      />
    {/if}
    {#if page >= 5}
      <li class="pager__item pager__item--ellipsis" role="presentation">
@@ -84,23 +48,16 @@
    {/if}
    {#each buttons as button}
      {#if page + button >= 0 && page + button <= pageCount}
        <li
          class="pager__item pager__item--number"
          class:pager__item--active={page === page + button}
        >
          <a
            href={'#'}
            class="pager__link"
            class:is-active={page === page + button}
            title={page === page + button
              ? 'Current page'
              : `Go to page ${page + button + 1}`}
            on:click={(e) => onChange(e, page + button)}
          >
            <span class="visually-hidden">{Drupal.t('Page')}</span>
            {page + button + 1}
          </a>
        </li>
        <PagerItem
          on:pageChange
          itemTypes={['number']}
          isCurrent={button === 0 ? 'page' : null}
          label={page + button + 1}
          toPage={page + button}
          ariaLabel={Drupal.t('Page @page_number', {
            '@page_number': page + button + 1,
          })}
        />
      {/if}
    {/each}
    {#if page + 5 <= pageCount}
@@ -109,49 +66,20 @@
      </li>
    {/if}
    {#if page !== pageCount}
      <li class="pager__item pager__item--action pager__item--next">
        <a
          href={'#'}
          class="pager__link pager__link--action-link"
          title={Drupal.t('Go to next page')}
          rel="next"
          on:click={(e) => onChange(e, page + 1)}
        >
          <span class="visually-hidden"
            >{Drupal.t('@location page', { '@location': labels.next })}</span
          >
          <span
            class="pager__item-title pager__item-title--forward"
            aria-hidden="true"
          >
            {labels.next}
          </span>
        </a>
      </li>
      <li class="pager__item pager__item--action pager__item--last">
        <a
          href={'#'}
          class="pager__link pager__link--action-link"
          title="Go to last page"
          on:click={(e) => onChange(e, pageCount)}
        >
          <span class="visually-hidden"
            >{Drupal.t('@location page', { '@location': labels.last })}</span
          >
          <span
            class="pager__item-title pager__item-title--forward"
            aria-hidden="true"
          >
            {labels.last}
          </span>
        </a>
      </li>
      <PagerItem
        on:pageChange
        itemTypes={['action', 'next']}
        linkTypes={['action-link', 'forward']}
        label={labels.next}
        toPage={page + 1}
      />
      <PagerItem
        on:pageChange
        itemTypes={['action', 'last']}
        linkTypes={['action-link', 'forward']}
        label={labels.last}
        toPage={pageCount}
      />
    {/if}
  </ul>
</nav>

<style>
  a.pager__link:hover {
    cursor: pointer;
  }
</style>
Loading