Skip to content

Chip Component

skrustev edited this page Jun 25, 2018 · 28 revisions

Chip Specification

Contents

  1. Overview
  2. User Stories
  3. Functionality
  4. ARIA support
  5. Assumptions and Limitations
  6. References
  7. Test strategy

Objectives

Provide compact elements that represent an input, attribute, or action.

Elaborate more on the multi-facetted use cases

As a developer, I want to:

  • have a single chip component that can be easily templated(1)
  • have a chip group/area that can manage as many chips as I need.
  • have a templatable prefix(2) that can contain avatar/logo/icon or anything similar, so that I can give further visual clues about the chip.
  • have a templatable label(3) in the chip, so that the chip can exit as a separate entity.
  • have a templatable suffix that can contain avatar/logo/icon or anything similar
  • be able to add a “Remove” icon, so that the user will be able to remove the chip.
  • to be able to change background of the chip, so that it would be consistent with the rest of the application.
  • be able to move chips around using drag & drop without too much custom implementation
  • have the chip component throw events when being removed, moved or dragged.
  • have the chip area throw events when chips have been reordered.
  • set min and max size of the chip W/H?
  • choose how the chips should be rendered inside the chip area - horizontally or vertically? Maybe using different types of chip areas?

As an end user, I want to:

  • Story 1: Have a visual area (chip area) containing different easily distinguished elements (chips) that contain some sort of information.
  • Story 2: Be able to easily move around chips around on desktop by dragging using mouse.
  • Story 3: The chips to be touch friendly and be able to easily move them using touch interactions.
  • Story 4: Have a clear indication when a chip can be removed and how that can be done.
  • Story 5: Be able to select one or multiple chips.
  • Story 6: Be able to select a chip and using keyboard navigation to navigate towards next or previous chips.
  • Story 7: Be able to select a chip and using certain key combinations move it left/right.

Acceptance criteria

Must-have before we can consider the feature a sprint candidate

...

Describe behavior, design, look and feel of the implemented feature. Always include visual mock-up

screen shot 2018-05-21 at 14 02 36 screen shot 2018-05-21 at 14 01 44 screen shot 2018-05-21 at 10 05 44

Overview

The IgxChipComponent is the main class for a chip element and the IgxChipsAreaComponent is the main class for the chip area that handles more complex management of multiple chips like moving, selection and keyboard navigation.

The IgxChipComponent requires an id to be defined so that the different chips can be easily distinguished by the user when for example chips should change their position, are being removed or selected. This is because the chip elements and chip area actually do not modify the DOM structure. This is left to the user to do it how he fits best for his application by using the provided inputs, events and methods.

Example of using igxChip with igxChipArea:

<igx-chips-area>
    <igx-chip *ngFor="let chip of chipList" [id]="chip.id">
        <label igxLabel>{{chip.text}}</label>
    </igx-chip>
</igx-chips-area>

The chip has a maximum width of 170px and minimum width of 96px. If the chip content exceeds the maximum width, it's overflown content will be hidden and ellipsis will be displayed.

Templating

The IgxChipComponent's main structure consists of chip content, remove button, prefix, suffix and connector. All of those elements are templatable except the the remove button.

The content of the chip is taken by the content defined inside the chip template except elements that define the prefix, suffix or connector of the chip. The user can define any type of content they need.

The prefix and suffix are also elements inside the actual chip area where they can be templated in any way the user would desire. Each has function defined by its name. The prefix is area in front of the chip content and the suffix is at the back after the content. The way they can be specified is by respectively using the IgxPrefix and IxgSuffix directives.

Example of using and icon for prefix, text for label and custom icon button for suffix:

<igx-chip *ngFor="let chip of chipList" [id]="chip.id">
    <igx-icon igxPrefix fontSet="material" [name]="'drag_indicator'"></igx-icon>
    <label igxLabel>{{chip.text}}</label>
    <span igxSuffix *ngIf="removable" igxButton="icon" (click)="onClick()">
        <igx-icon fontSet="material" [name]="'close'"></igx-icon>
    </span>
</igx-chip>

The connectors of the igxChip are fully templatable and are positioned after each the chip area. Their purpose is to provide a way to link two chips next to each other with an icon/text or anything the user would like to use. The last chip does not have connector applied. They hide while dragging chips around and show again when interactions with the chips have finished. The connector is defined by using the IgxConnector directive.

Example of using connector:

<igx-chip *ngFor="let chip of chipList" [id]="chip.id">
    <label igxLabel>{{chip.text}}</label>
    <span igxConnector> -> </span>
</igx-chip>

Removing

The remove button is part of the chip area. It can be enabled through an option of the igxChip itself called removable. When enabled the remove button will be position between the label and the suffix areas.

When clicking on the button the igxChip provides an event that the user can use to use to know when the chip should be removed. The chip itself is not removed from the DOM by default when clicking on the button unless the user removes it. Also pressing the Delete button when the chip is focused also fires the onRemove event.

Moving/Dragging

Dragging is disabled by default. It can be enabled by the draggable property.

Dragging can begin after clicking/touching and holding on the chip. Then the user need to move more than 5px in any direction in order for the dragging to start. If the mouse is released before moving 5px the chip detects it as a click.

When dragging begins the chip follows the pointer where of the user until it has been released. When released somewhere outside the area of another chip, the dragged chip returns to its starting position with animation. When the dragged chip enters the area of another chip the onReorder event is fired for the user to handle changing the order of the chip. It provides the new order of the chips that would be expected to be. The chips can be reordered live by reordering the template inside the chip area they are defined. If the order is handled by the user and the dragged chip is released it goes to the new position with animation. Otherwise returns to its starting position.

When a chip is selected and is being dragged it should retain its selection status.

Selection

Selection is disabled by default, but can be enabled with an option called selectable.

The selecting is done by clicking on the chip itself or by focusing the chip either by using the Tab button and then pressing Space. An event is fired when the selection state of the igxChip changes. If a chip is already selected it can be deselected by pressing the Space button again while the chip is focused.

Keyboard Navigation

Chips gain focus when clicked, ensuring keyboard navigation starts at the appropriate chip. If selection is enabled when clicking on chip it will also select it. They can be focused also using the Tab key. Users can move through the chips using the arrow keys and select/deselect them with the space. Chips can be reordered using keyboard navigation.

Keyboard controls when the chip is focused:

  • LEFT - Focuses the previous chip
  • RIGHT - Focuses the next chip
  • SPACE - Toggles chip selection if it is selectable
  • DELETE - Fires the onRemove output so the chip deletion can be handled.
  • SHIFT + LEFT - Moves the focused chip one position to the left
  • SHIFT + RIGHT - Moves the focused chip one position to the right

Keyboard controls when the remove button is focused:

  • SPACE or ENTER - Fires the onRemove output so the chip deletion can be handled.

IgxChipComponent

Inputs

Name Description Type Default value
id ID by which each chip is distinguished any undefined
removable Defines if the chip should render remove button and throw remove events boolean false
selectable Defines if the chip can be selected on click or through navigation boolean false
draggable Defines if the chip can be dragged in order to change it's position boolean false

Properties

Name Description Type Default value
selected Gets/Sets the chip as selected/deselected when this method is called boolean false

Outputs

Name Description Cancelable Parameters
onClick Event fired when the user has clicked without moving the chip false owner: IgxChipComponent
onMoveStart Event fired when the user starts moving the chip by dragging false owner: IgxChipComponent
onMoveEnd Event fired when the user stops moving the chip and the chip has returned to it's initial position false owner: IgxChipComponent
onRemove Event fired after the chip is specified that can be removed and the remove buttin is clicked false owner: IgxChipComponent
onSelection Event fired after the chip has been selected/deselected true owner: IgxChipComponent, nextStatus: boolean, cancel: boolean

IgxChipsAreaComponent

Inputs

Name Description Type Default value
width Width of the chips area number undefined
height Height of the chips area number undefined

Outputs

Name Description Cancelable Parameters
onReorder Event thrown when a chip has been moved and the order of the chips should change. Provides array of chip components that has the new order true chipsArray: IgxChipComponent[]
onSelection Event fired when the user has selected new chip/chips. Provided array of selected chip components false chipsArray: IgxChipComponent[]
onMoveStart Event fired when interactions that results in chips being moved is about to start -
onMoveEnd Event fired when interactions that results in chips being moved ends -

A chip-list behaves as a role="listbox", with each chip being a role="option". The chip input should have a placeholder or be given a meaningful label via aria-label or aria-labelledby.

Assumptions Limitation Notes

https://material.angular.io/components/chips/examples https://material-components.github.io/material-components-web-catalog/#/component/chips https://material.io/design/components/chips.html#input-chips https://docs.flutter.io/flutter/material/Chip-class.html

Data Binding

  • Test adding chips by adding data items
  • Test removing chips by removing data items
  • Test chip updates if data item is updated

Selection

  • Test if a chip can be selected by clicking on a chip.
  • Test if a chip can be selected if it is focused and you press space/enter when selectable input is set to false.
  • Test if multiple chips can be selected.
  • Test whether chip selected state is persisted after selected chip is moved (either with drag and drop or with keyboard navigation)
  • Test if chip can be selected via setting selected property to true.
  • Test if selection related events are fired correctly: onClick, onSelection (this event is available for both IgxChipComponent and IgxChipsAreaComponent)

Removing

  • Test "remove button" is rendered in the chip when removable input is set to true.
  • Test removing a chip works when click on the "remove button".
  • Test remove button is not rendered in the chip when removable input is set to false or not set at all.
  • Test deleting a chip with DELETE key when removable input is set to false.
  • Test if onRemove event is fired correctly – when deleting using DELETE key, when deleting using Enter or SPACE key press when remove icon is focused

Moving/Dragging

  • Test if a chip can be dragged and dropped when draggable input is set to false or not set at all.
  • Test if a chip can be dragged and dropped when draggable input is set to true.
  • Test if all suffix connectors are not visible while dragging.
  • Test if all suffix connectors become visible after dragging and dropping a chip.
  • Test the last (most right) chip does not have a suffix connector.
  • Test if onReorder event is fired correctly (this event is available for both IgxChipComponent and IgxChipsAreaComponent)

Templating

  • Test if chip label is correctly set.
  • Test if chip prefix is correctly set.
  • Test if chip suffix is correctly set.
  • Test suffix connector is correctly set.

Keyboard navigation

  • Test whether pressing TAB once focuses first the chip and pressing it twice focuses the delete button.
  • Keyboard controls when the chip is focused:
    • Test pressing Left, Right arrows focuses previous/next chip.
    • Test pressing space toggles chip selection (if selectable).
    • Test pressing delete.
    • Test pressing Shift + Left/Shift + Right moves focused chip to the left/right. Ensure that the focus is still on the initially focused chip not on the chip on its previous position.
  • Keyboard controls when the remove button is focused
    • Test pressing SPACE deletes the chip.
    • Test pressing ENTER deletes the chip.

Touch

  • Test if chips can be dragged and dropped.
  • Test if chips can be deleted with remove button.
  • Test if chips can be selected.
Clone this wiki locally