# Diagram node

One box of a how-it-works diagram: its kind, its name and what it does, with the dots its arrows meet.

A block: a ready-made arrangement of components, to copy into a project. Its own classes carry the `site-` prefix; rename it to your project's own. Status: experimental. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Built from: Icon.

## Examples

### Usage

A part of the system, with a dot on each side for the arrow that comes in and the one that goes out.

```html
<div class="site-diagram-node site-diagram-node--kind-part">
  <span class="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true"></span>
  <span class="site-diagram-node__top">
    <span class="site-diagram-node__tile">
      <i class="ph ph-stack smbk-icon smbk-icon--size-xs" aria-hidden="true"></i>
    </span>
    <span class="site-diagram-node__kind">Part</span>
  </span>
  <p class="site-diagram-node__title">Token build</p>
  <p class="site-diagram-node__detail">Writes the CSS and code tokens from the design file</p>
  <span class="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true"></span>
</div>
```

```tsx
import { Icon } from './design-system/components/icon/icon.js';

<div className="site-diagram-node site-diagram-node--kind-part">
  <span className="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true" />
  <span className="site-diagram-node__top">
    <span className="site-diagram-node__tile">
      <Icon name="Stack" size="xs" />
    </span>
    <span className="site-diagram-node__kind">Part</span>
  </span>
  <p className="site-diagram-node__title">Token build</p>
  <p className="site-diagram-node__detail">Writes the CSS and code tokens from the design file</p>
  <span className="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true" />
</div>
```

### Every kind

The five kinds, in the order data moves: an input, a part, a store, an output, and something outside the system, dashed. A node with nothing going out has no dot on that side.

```html
<div class="site-diagram-node site-diagram-node--kind-input">
  <span class="site-diagram-node__top">
    <span class="site-diagram-node__tile">
      <i class="ph ph-sign-in smbk-icon smbk-icon--size-xs" aria-hidden="true"></i>
    </span>
    <span class="site-diagram-node__kind">Input</span>
  </span>
  <p class="site-diagram-node__title">Design file</p>
  <p class="site-diagram-node__detail">The colors, sizes and type the designers set</p>
  <span class="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true"></span>
</div>
<div class="site-diagram-node site-diagram-node--kind-part">
  <span class="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true"></span>
  <span class="site-diagram-node__top">
    <span class="site-diagram-node__tile">
      <i class="ph ph-stack smbk-icon smbk-icon--size-xs" aria-hidden="true"></i>
    </span>
    <span class="site-diagram-node__kind">Part</span>
  </span>
  <p class="site-diagram-node__title">Token build</p>
  <p class="site-diagram-node__detail">Writes the CSS and code tokens from the design file</p>
  <span class="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true"></span>
</div>
<div class="site-diagram-node site-diagram-node--kind-store">
  <span class="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true"></span>
  <span class="site-diagram-node__top">
    <span class="site-diagram-node__tile">
      <i class="ph ph-archive smbk-icon smbk-icon--size-xs" aria-hidden="true"></i>
    </span>
    <span class="site-diagram-node__kind">Store</span>
  </span>
  <p class="site-diagram-node__title">Token files</p>
  <p class="site-diagram-node__detail">Every token, kept in the repository</p>
  <span class="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true"></span>
</div>
<div class="site-diagram-node site-diagram-node--kind-output">
  <span class="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true"></span>
  <span class="site-diagram-node__top">
    <span class="site-diagram-node__tile">
      <i class="ph ph-export smbk-icon smbk-icon--size-xs" aria-hidden="true"></i>
    </span>
    <span class="site-diagram-node__kind">Output</span>
  </span>
  <p class="site-diagram-node__title">Stylesheet</p>
  <p class="site-diagram-node__detail">One file every page links</p>
  <span class="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true"></span>
</div>
<div class="site-diagram-node site-diagram-node--kind-external">
  <span class="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true"></span>
  <span class="site-diagram-node__top">
    <span class="site-diagram-node__tile">
      <i class="ph ph-globe-simple smbk-icon smbk-icon--size-xs" aria-hidden="true"></i>
    </span>
    <span class="site-diagram-node__kind">Outside</span>
  </span>
  <p class="site-diagram-node__title">Font service</p>
  <p class="site-diagram-node__detail">Serves the typefaces the pages name</p>
</div>
```

```tsx
import { Icon } from './design-system/components/icon/icon.js';

<div className="site-diagram-node site-diagram-node--kind-input">
  <span className="site-diagram-node__top">
    <span className="site-diagram-node__tile">
      <Icon name="SignIn" size="xs" />
    </span>
    <span className="site-diagram-node__kind">Input</span>
  </span>
  <p className="site-diagram-node__title">Design file</p>
  <p className="site-diagram-node__detail">The colors, sizes and type the designers set</p>
  <span className="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true" />
</div>
<div className="site-diagram-node site-diagram-node--kind-part">
  <span className="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true" />
  <span className="site-diagram-node__top">
    <span className="site-diagram-node__tile">
      <Icon name="Stack" size="xs" />
    </span>
    <span className="site-diagram-node__kind">Part</span>
  </span>
  <p className="site-diagram-node__title">Token build</p>
  <p className="site-diagram-node__detail">Writes the CSS and code tokens from the design file</p>
  <span className="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true" />
</div>
<div className="site-diagram-node site-diagram-node--kind-store">
  <span className="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true" />
  <span className="site-diagram-node__top">
    <span className="site-diagram-node__tile">
      <Icon name="Archive" size="xs" />
    </span>
    <span className="site-diagram-node__kind">Store</span>
  </span>
  <p className="site-diagram-node__title">Token files</p>
  <p className="site-diagram-node__detail">Every token, kept in the repository</p>
  <span className="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true" />
</div>
<div className="site-diagram-node site-diagram-node--kind-output">
  <span className="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true" />
  <span className="site-diagram-node__top">
    <span className="site-diagram-node__tile">
      <Icon name="Export" size="xs" />
    </span>
    <span className="site-diagram-node__kind">Output</span>
  </span>
  <p className="site-diagram-node__title">Stylesheet</p>
  <p className="site-diagram-node__detail">One file every page links</p>
  <span className="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true" />
</div>
<div className="site-diagram-node site-diagram-node--kind-external">
  <span className="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true" />
  <span className="site-diagram-node__top">
    <span className="site-diagram-node__tile">
      <Icon name="GlobeSimple" size="xs" />
    </span>
    <span className="site-diagram-node__kind">Outside</span>
  </span>
  <p className="site-diagram-node__title">Font service</p>
  <p className="site-diagram-node__detail">Serves the typefaces the pages name</p>
</div>
```

### Selected

Chosen: a thicker edge in the info color and the raised shadow, on any kind.

```html
<div
  class="site-diagram-node site-diagram-node--kind-part site-diagram-node--selected"
  aria-current="true"
>
  <span class="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true"></span>
  <span class="site-diagram-node__top">
    <span class="site-diagram-node__tile">
      <i class="ph ph-stack smbk-icon smbk-icon--size-xs" aria-hidden="true"></i>
    </span>
    <span class="site-diagram-node__kind">Part</span>
  </span>
  <p class="site-diagram-node__title">Token build</p>
  <p class="site-diagram-node__detail">Writes the CSS and code tokens from the design file</p>
  <span class="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true"></span>
</div>
<div
  class="site-diagram-node site-diagram-node--kind-external site-diagram-node--selected"
  aria-current="true"
>
  <span class="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true"></span>
  <span class="site-diagram-node__top">
    <span class="site-diagram-node__tile">
      <i class="ph ph-globe-simple smbk-icon smbk-icon--size-xs" aria-hidden="true"></i>
    </span>
    <span class="site-diagram-node__kind">Outside</span>
  </span>
  <p class="site-diagram-node__title">Font service</p>
  <p class="site-diagram-node__detail">Serves the typefaces the pages name</p>
  <span class="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true"></span>
</div>
```

```tsx
import { Icon } from './design-system/components/icon/icon.js';

<div className="site-diagram-node site-diagram-node--kind-part site-diagram-node--selected" aria-current="true">
  <span className="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true" />
  <span className="site-diagram-node__top">
    <span className="site-diagram-node__tile">
      <Icon name="Stack" size="xs" />
    </span>
    <span className="site-diagram-node__kind">Part</span>
  </span>
  <p className="site-diagram-node__title">Token build</p>
  <p className="site-diagram-node__detail">Writes the CSS and code tokens from the design file</p>
  <span className="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true" />
</div>
<div className="site-diagram-node site-diagram-node--kind-external site-diagram-node--selected" aria-current="true">
  <span className="site-diagram-node__port site-diagram-node__port--in" aria-hidden="true" />
  <span className="site-diagram-node__top">
    <span className="site-diagram-node__tile">
      <Icon name="GlobeSimple" size="xs" />
    </span>
    <span className="site-diagram-node__kind">Outside</span>
  </span>
  <p className="site-diagram-node__title">Font service</p>
  <p className="site-diagram-node__detail">Serves the typefaces the pages name</p>
  <span className="site-diagram-node__port site-diagram-node__port--out" aria-hidden="true" />
</div>
```

## Purpose

Draws one box of a diagram that shows how a system works: what kind of thing it is, its name, a line on what it does, and a dot on each side where an arrow comes in or goes out. Five kinds: a part, an input, an output, a store and something outside the system, each chosen or not.

## Anatomy

- The box: its own edge, small corners and tight room, on the default surface; a store sits sunken, and something outside has a dashed edge.
- The top line: the kind's icon, the Icon component, on a small tile in the kind's color, and the kind in the small code style, in capitals.
- The name in the medium label style.
- The line on what it does, in the extra small body style.
- The dots, one on each side the arrows meet. Leave out the dot on a side no arrow uses.

## When to use

- In a diagram that explains how the parts of a system pass things to each other.

## When not to use

- For a step in a process a reader follows. Use a stepper or a timeline.
- For an item a reader picks from a list. Use a card or a list.

## Behavior

The box takes no focus and does nothing when pressed: it is a drawing. The page draws the arrows between boxes, from one dot to the next, and chooses which box is selected, such as the one a reader is reading about.

## Accessibility

### What it does for you

- The kind is said in words, never by the tile's color alone.
- The dots and the icon are hidden from assistive technology.
- A selected box is marked as the current one, and shown by a thicker edge as well as its color.

### What you must do

- Put a text version beside the diagram: a list of every arrow, such as "Design file goes to Token build". The boxes alone do not say what connects to what.
- Mark the selected box both ways, with its selected class and `aria-current="true"`, as the examples do.

### How to test

- With a screen reader, each box reads its kind, its name and its line, and the selected one is read as current.
- In a forced-color mode, the selected box still stands out by its thicker edge.

## Usage rules

### Do

- Name each box with a noun a reader knows, and say what it does in a few words.
- Keep the arrows going one way, left to right or top to bottom.

### Don't

- Make a box a button without its own focus and pressed looks.
- Show which box is chosen by color alone.

## Stylesheet

```css
/* site-diagram-node — Diagram node, a block: one box of a how-it-works diagram, its kind, its name and what it does,
 * with the dots its arrows meet. Copy it into your project and rename site- to your project's own prefix. It is not
 * built on the Card: its corners are smaller, its room tighter, and it has a dashed edge for what sits outside and
 * a blue edge for the one chosen, so the block draws its own box from tokens. The icon is the Icon component. The
 * lines between nodes are the page's to draw. */

.site-diagram-node {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-6);
  box-sizing: border-box;
  padding: var(--smbk-space-inset-md);
  border: var(--smbk-border-width-hairline) solid var(--smbk-color-border-subtle);
  border-radius: var(--smbk-radius-container-sm);
  background: var(--smbk-color-surface-default);
  color: var(--smbk-color-text-default);
}

.site-diagram-node__top {
  display: flex;
  align-items: center;
  gap: var(--smbk-space-6);
}

/* The kind's icon on a small tile in the kind's color. */
.site-diagram-node__tile {
  display: grid;
  flex: none;
  place-items: center;
  box-sizing: border-box;
  width: var(--smbk-size-20);
  height: var(--smbk-size-20);
  border-radius: var(--smbk-radius-control-xs);
  background: var(--smbk-color-feedback-info-surface-subtle);
  color: var(--smbk-color-icon-default);
}

.site-diagram-node__kind {
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-code-sm-font-family);
  font-size: var(--smbk-typography-code-sm-font-size);
  font-weight: var(--smbk-typography-code-sm-font-weight);
  line-height: var(--smbk-typography-code-sm-line-height);
  letter-spacing: var(--smbk-typography-code-sm-letter-spacing);
  text-transform: uppercase;
}

.site-diagram-node__title {
  margin: 0;
  font-family: var(--smbk-typography-label-md-font-family);
  font-size: var(--smbk-typography-label-md-font-size);
  font-weight: var(--smbk-typography-label-md-font-weight);
  line-height: var(--smbk-typography-label-md-line-height);
  letter-spacing: var(--smbk-typography-label-md-letter-spacing);
}

.site-diagram-node__detail {
  margin: 0;
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-body-xs-font-family);
  font-size: var(--smbk-typography-body-xs-font-size);
  font-weight: var(--smbk-typography-body-xs-font-weight);
  line-height: var(--smbk-typography-body-xs-line-height);
  letter-spacing: var(--smbk-typography-body-xs-letter-spacing);
}

/* The dots an arrow meets, half outside the box at the middle of each side. */
.site-diagram-node__port {
  position: absolute;
  inset-block-start: 50%;
  box-sizing: border-box;
  width: var(--smbk-size-8);
  height: var(--smbk-size-8);
  border: var(--smbk-border-width-hairline) solid var(--smbk-color-border-strong);
  border-radius: var(--smbk-radius-full);
  background: var(--smbk-color-surface-default);
  translate: 0 -50%;
}

.site-diagram-node__port--in {
  inset-inline-start: calc(var(--smbk-size-8) / -2 - var(--smbk-border-width-hairline));
}

.site-diagram-node__port--out {
  inset-inline-end: calc(var(--smbk-size-8) / -2 - var(--smbk-border-width-hairline));
}

/* ---- kind ---- */

.site-diagram-node--kind-input .site-diagram-node__tile {
  background: var(--smbk-color-feedback-success-surface-subtle);
}

.site-diagram-node--kind-output .site-diagram-node__tile {
  background: var(--smbk-color-feedback-warning-surface-subtle);
}

/* A store, where something is kept, sits sunken. */
.site-diagram-node--kind-store {
  background: var(--smbk-color-surface-sunken);
}

.site-diagram-node--kind-store .site-diagram-node__tile {
  background: var(--smbk-color-surface-track-subtle);
}

/* What sits outside the system: a dashed edge, and its tile only outlined. */
.site-diagram-node--kind-external {
  border-style: dashed;
  border-color: var(--smbk-color-border-strong);
}

.site-diagram-node--kind-external .site-diagram-node__tile {
  border: var(--smbk-border-width-hairline) solid var(--smbk-color-border-subtle);
  background: none;
}

/* ---- selected: a thicker edge in the info color, and the raised shadow. The focus color is the brand's, so it
   cannot mark a choice. ---- */

.site-diagram-node--selected {
  border-width: var(--smbk-border-width-emphasis);
  border-color: var(--smbk-color-feedback-info-border);
  box-shadow: var(--smbk-elevation-raised);
}

.site-diagram-node--selected .site-diagram-node__port--in {
  inset-inline-start: calc(var(--smbk-size-8) / -2 - var(--smbk-border-width-emphasis));
}

.site-diagram-node--selected .site-diagram-node__port--out {
  inset-inline-end: calc(var(--smbk-size-8) / -2 - var(--smbk-border-width-emphasis));
}
```
