Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs for component states #4632

Draft
wants to merge 3 commits into
base: docs/element-tokens
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions aries-site/src/data/structures/tokens.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable max-len */
import { Figma, Code, Book, Table } from 'grommet-icons';
import { Box, Text } from 'grommet';
import { ButtonStates } from '../../examples';

export const tokens = [
{
Expand Down Expand Up @@ -38,6 +39,24 @@ export const tokens = [
],
tags: [],
},
{
name: 'Component states',
type: 'Getting started',
description:
'The state of a component communicates feedback based on user interaction, system status, or both.',
preview: {
component: () => <ButtonStates size="small" tabIndex={-1} />,
},
seoDescription:
'The state of a component communicates feedback based on user interaction, system status, or both.',
sections: [],
relatedContent: [
'All design tokens',
'Using design tokens in code',
'Using design tokens in Figma',
],
tags: [],
},
{
name: 'Element',
type: 'Getting started',
Expand Down
48 changes: 48 additions & 0 deletions aries-site/src/examples/tokens/ComponentStates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import styled from 'styled-components';
import { global, components } from 'hpe-design-tokens';
import { Box, Button, FormField, TextInput } from 'grommet';

const HoverButton = styled(Button)`
background: ${components.hpe.button.primary.hover.background};
`;

const FocusButton = styled(Button)`
outline-color: ${props =>
props.theme.global.colors[
props.theme.global.colors[global.hpe.focusIndicator.outline.color]
]};
outline-width: ${global.hpe.focusIndicator.outline.width};
outline-style: ${global.hpe.focusIndicator.outline.style};
outline-offset: ${global.hpe.focusIndicator.outlineOffset};
`;

// eslint-disable-next-line react/prop-types
export const ButtonStates = ({ size, tabIndex }) => (
<Box direction="row" gap="small">
<Button label="Rest" tabIndex={tabIndex} size={size} primary />
<HoverButton label="Hover" tabIndex={tabIndex} size={size} primary />
<FocusButton label="Focus" tabIndex={tabIndex} size={size} primary />
</Box>
);

export const ComponentStates = () => {
return (
<Box gap="medium">
<ButtonStates />
<Box direction="row" gap="small">
<FormField label="Label" htmlFor="name" name="name">
<TextInput id="name" name="name" />
</FormField>
<FormField
label="Label"
htmlFor="name-2"
name="name-2"
error="There is an error"
>
<TextInput id="name-2" name="name-2" />
</FormField>
</Box>
</Box>
);
};
1 change: 1 addition & 0 deletions aries-site/src/examples/tokens/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './BetaNotification';
export * from './ComponentStates';
export * from './TokenHighlight';
export * from './TokenTypes';
export * from './element';
70 changes: 70 additions & 0 deletions aries-site/src/pages/design-tokens/component-states.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Checkmark } from 'grommet-icons';
import { Notification } from 'grommet';
import { Example } from '../../layouts';
import { ComponentStates } from '../../examples';

<Example>
<ComponentStates />
</Example>

State gives confidence that an interaction has been registered, that a component can or cannot be interacted with, or that the system is in a particular state.

Design tokens represent these states in a systematic, scalable way to ensure:

- Predictable mapping of design tokens to components
- Clarity for how the system should expand if new states are added

## Interaction vs application state

A component should be styled based on combination of application state and interaction state.

| State type | Description |
| --------------- | ------------------------------------------------------------------------------ |
| **Interaction** | Direct result of user interaction (e.g., the user hovered over a button). |
| **Application** | Result of the system (e.g., a input has been validated and there is an error). |

<Notification
status="info"
message="Not all state combinations are valid (e.g., a component cannot be disabled and focused), and not all state combinations apply to all components (e.g., a button cannot have a validation error)."
margin={{ bottom: 'medium' }}
alignSelf="start"
/>

See [validation state combinations](#supported-states) in the table below.

### Interaction state naming

Interaction states use the CSS pseudo-class terminology (hover, focus, active). For the “resting state” of the component, the term “rest” is used.

### Application state naming

Some application states correspond directly to CSS pseudo-classes (e.g., disabled), while others are named more generically to apply across components (e.g., “selected” can refer to a selected dropdown item or checked checkbox).

Application states that have use cases within the design system are represented in the table below.

## Supported states

In this table, “interaction” states are represented as column headings and “application” states are the rows. Checked cells represent valid combinations.

If two application states exist at once, the component should be styled based on the top-most row in the table. For example, if a component is both “readonly” and "selected", it should be styled as "readonly".

<Notification
status="info"
message="Active state does not currently have design tokens, but it is included in this model to demonstrate how the system would extend if styles for this state are added."
width={{ max: 'large' }}
margin={{ bottom: 'medium' }}
/>

| | rest | hover | focus | active | Notes |
| ------------- | :-------------------------------------: | :-------------------------------------: | :-------------------------------------: | :-------------------------------------: | ------------------------- |
| none | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | -- |
| error | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | -- |
| disabled | <span><Checkmark size="small" /></span> | -- | -- | -- | -- |
| readonly | <span><Checkmark size="small" /></span> | -- | <span><Checkmark size="small" /></span> | -- | -- |
| selected | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | -- |
| indeterminate | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | Only applies to checkbox. |
| pinned | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | <span><Checkmark size="small" /></span> | -- |

## Component-specific tokens

For each component with [component-specific tokens](/design-tokens/how-to-read-design-tokens#component), the applicable state combinations are provided as design tokens.