Page MenuHomePhabricator

[Epic] Build the component primitives for Vue.js search
Closed, ResolvedPublic

Description

This sub-epic covers building the Vue.js component primitives needed for the new search experience use case. Since the pattern for building these components is expected to share a large portion of development procedure, this epic will hold any recipes or detail common between its subtasks and the subtasks will hold implementation specific notes as needed. Edit them as is useful! They're they're for doing. The work is expected to be rote, exciting, meticulous, error-prone, and essential.

As informed by T253933, the recipe for building a component is:

  1. Create a a) new single file component file, b) UI Storybook story, and c) Jest test.
  2. Add the minimal HTML5 template and JavaScript needed for the search use case.
  3. Add the best-practice following descriptive ARIA roles and attributes.
  4. Aim for the above to be merged.
  5. Copy CSS properties from OOUI that apply to the minimal template. Aim to get this merged.
  6. Change as needed. When changing the structure, copy any relevant styles from OOUI. For changes that require extensive discussion and are optional for search, consider forking the component within WVUI to a new directory.
  7. Update the migration guide with lessons learned.

The search use case is the focus. Contentious or lengthy discussions will be necessary but should be moved to new tickets for long term component design. Great discourse is needed to build great generic components but the search use case is more focused with a tighter deadline.

Subtasks

Skeleton

HTML
<!--:
References
https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
https://alphagov.github.io/accessible-autocomplete/examples/
-->
<div class="wvui-card wvui-typeahead-search" role="combobox" aria-expanded="true" aria-haspopup="listbox" aria-owns="wvui-typeahead-search__suggestions">
  <form id="wvui-typeahead-search__search" class="wvui-search-form" action="https://wikipedia.org/search-redirect.php">
    <input type="hidden" name="family" value="wikipedia">
    <input type="hidden" name="language" value="en">

    <input
           id="wvui-typeahead-search__input"
           class="wvui-input"
           name="search"
           type="search"
           size="48"
           autofocus="autofocus"
           accesskey="f"
           title="Search Wikipedia [Alt+Shift+f]"
           dir="auto"
           autocomplete="off"
           aria-label="Search Wikipedia"
           value="ba"
           aria-autocomplete="list"
           aria-controls="wvui-typeahead-search__suggestions"
           >

    <!-- Additional instructions can be presented to screen readers when search suggestions
        will be presented. -->
    <div id="wvui-typeahead-search__cue" class="wvui-cue">
      Input your query and press enter or tap the search button to search within pages.
      Suggestions may be presented on query change. Use up and down arrow keys to
      navigate the suggestions and press enter or tap to select.
    </div>

    <!--
     This button will not be presented in T244392 but may be wanted conditionally within
     the component for other use cases.
     <button class="wvui-button wvui-button--default wvui-button--framed">
      Search
     </button>
    -->
  </form>

  <!-- A data list is not used because of limited styling options. An ordered list is used over
      an unordered list because the contents are ordered by relevance which may be useful
      semantically and to screen readers. -->
  <ol id="wvui-typeahead-search__suggestions" class="wvui-typeahead-search__suggestions" role="listbox" aria-label="search suggestions">
    <li role="option">
      <a href="/wiki/Banana" class="wvui-typeahead-suggestion">
        <img
             class="wvui-typeahead-suggestion__thumbnail"
             src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/de/Bananavarieties.jpg/160px-Bananavarieties.jpg"
             width="160"
             height="91"
             alt="Banana"
             loading="lazy"
             >
        <h3 class="wvui-typeahead-suggestion__title">
          <em class="wvui-typeahead-suggestion__matching-title">Ba</em>nana
        </h3>
        <p class="wvui-typeahead-suggestion__description">
          Edible fruit
        </p>
      </a>
    </li>
    <!-- More results here. -->
  </ol>

  <button class="wvui-button wvui-typeahead-search__submit" form="wvui-typeahead-search__search" type="submit">
    Search pages containing <em>ba</em>
  </button>
</div>
CSS
.wvui-typeahead-search__suggestions {
  /* Don't present list numbers to GUI readers. */
  list-style: none none;
}

.wvui-typeahead-suggestion {
  /* Fill the available width fully so the whole suggestion box is clickable. */
  display: block;
  width: 100%;
}

.wvui-typeahead-suggestion::after {
  /* Add an empty pseudo-element that clears the left and right so that the element can wrap
  its contents fully even if they're floated. */
  content: "";
  clear: both;

  /* Make the pseudo-element dimensionless, forbid scrollbars, and hide. */
  display: block;
  width: 0;
  height: 0;
  overflow: hidden;
  visibility: hidden;
}

.wvui-typeahead-suggestion__thumbnail {
  /* Thumbnails appear to the starting side of title and description. */
  float: left;
}

/* Informational cues intended for presentation to screen readers only. */
.wvui-cue {
  /* Make the element dimensionless, forbid scrollbars, and hide visually. */
  display: block;
  width: 0;
  height: 0;
  overflow: hidden;
  visibility: hidden;
}

The above as a CodePen

Subtask acceptance criteria

Acceptance criteria common to most subtasks:

  • Component template is guided by the above skeleton structure.
  • Component follows the WAI best-practice and applies descriptive ARIA roles and attributes.
  • Component styling is guided by OOUI CSS properties, uses WikimediaUI Base variables and follows BEM conventions.
  • Component is documented with a couple configurations in Storybook.
  • Component has Jest tests for at least the snapshots.
  • Any functions or methods added have a JSDoc description and TypeScript typing.
  • Any lessons learned, development tips, and usage notes wanted are documented in the readme or the migration guide.
  • Update the skeleton in this task too so it's easy to see what is being targeted for subsequent components.

Event Timeline

Volker_E added a subscriber: Volker_E.

Overtaking latest amendment, most importantly on ARIA roles and attributes from T253933.

ovasileva claimed this task.
ovasileva added a subscriber: ovasileva.

All subtasks are now resolved. Resolving this epic.