# Adapting to the environment

> Reading the pointer in use, the platform's command key, the direction of text, the language and the person's settings, and doing what is right there.

The same interface is used with a mouse and with a finger, on a Mac and on
Windows, in English and in Arabic, by someone who has asked for less motion and
by someone whose system draws every colour itself. None of these is the default
from which the others are adapted. Each control reads the environment it is in,
when it is used, and does what is right there — with nothing for the person, or
the application, to set.

## Best practices

**Read the environment when it is used, not once.** A tablet gains a trackpad
when its keyboard is attached; a page changes its language; a window moves to a
screen that forces its colours. What a control does is decided by what is true
at the moment of the press, the key or the paint — never by what was true when
the page loaded.

**Ask about the pointer that is actually in use.** A finger is broad, has no
hover and no modifier keys, and covers what it presses; a mouse is precise,
hovers, and holds Shift. Where a control differs between them, it asks which is
pressing it now — the press's own pointer type, or whether the primary pointer
is coarse — not what kind of device the page is on. A laptop with a touchscreen
is both, one press at a time.

**Size for a finger where a finger is used.** Targets are at least 44 pixels
across where the pointer is coarse: a grid's rows grow, a calendar's days
grow, the handles of a selection reach past its corners. Where the pointer is
fine, the same interface stays dense.

**Give a finger what its lack of keys takes from it.** Where a mouse adds to a
selection with the command key, a finger's tap adds by itself; where a mouse
right-clicks, a finger holds. Where a mouse hovers to find a control, a finger
is shown it.

**Hover is the pointer's own movement.** A browser reports a move when the page
moves beneath a pointer that is resting, as well as when the pointer moves. A
highlight that follows the pointer follows only the pointer: a list that scrolls
under a resting mouse does not hand its highlight to whatever comes beneath.

**Use the platform's command key.** Shortcuts and multiple selection use ⌘ on
Apple platforms and Ctrl elsewhere. On a Mac, Ctrl with a click is a secondary
click, so it is never read as the command key. An iPad that reports itself as
a Mac is treated as one, which is what its keyboard is.

**Mirror for the direction text runs in.** Where text runs right to left, so does
everything laid out along a line: the start of a row is on the right, the
arrow keys that move along a line are mirrored, an arrow that points forward
points left, and a drag to the left increases a value scrubbed along a line.
Up and down are not mirrored. The direction is read from the control's own
place in the page, so one part of a page may run each way.

**Write in the reader's language.** Numbers, dates, the first day of the week and
the weekend follow the locale the control is given, or else the language the
page is written in — its `lang` — or else the browser's. A page that changes
language is followed. A tag that is not a language, such as `en_US`, falls back
to the next in that order rather than failing.

**Move less for those who ask.** Where the person has asked for less motion,
transitions that only decorate are dropped, and motion that would carry
something into place — a sheet returning after it was let go — happens at once.
Motion that follows a finger is the finger's, and stays.

**Keep what forced colours need.** Where the system forces its own colours,
borders, focus and selection must still be visible: a focus ring is an outline,
which a forced palette keeps, and not a shadow, which it discards; selection,
handles and guides take the system's highlight colour; an unavailable item takes
its colour for unavailable text.

**Stay clear of the device's edges.** Something fixed to the bottom of a phone's
screen — a sheet — leaves room for the home indicator and the curve of the
screen.

**Ask for the right keyboard.** A field that takes a number offers a numeric
keypad where the number is plain, and a full keyboard where it can be negative,
carry a unit or take arithmetic, since a keypad has neither minus nor letters.
Fields name what Enter does, and do not correct or capitalise what is not prose.

**Render the same on a server.** A server cannot know the reader's pointer or
language. It renders for a fine pointer and in English, and the page corrects
itself once it is in the reader's browser, without rendering twice where the
answer was the same.

## What the components do

| Environment      | Where it shows                                                                                         |
| ---------------- | ------------------------------------------------------------------------------------------------------ |
| Coarse pointer   | taller grid rows, larger days and buttons, handles that reach past corners, steppers offered, sheets   |
| Pointer type     | drag thresholds of 3, 6 and 10 pixels for mouse, pen and finger; a tap that toggles; a hold for a menu |
| Pointer movement | a menu's highlight follows the pointer's own movement only                                             |
| Command key      | toggling selection, moving to an edge, undo and redo, select all                                       |
| Direction        | arrow keys in lists, menus, grids and calendars; a calendar's layout; a scrub's direction              |
| Locale           | numbers and dates read and shown; the week and the weekend; the digits a calendar writes               |
| Less motion      | overlays and sheets appear and return without gliding                                                  |
| Forced colours   | focus rings, selection, handles, guides and unavailable items in the system's colours                  |
| Safe areas       | sheets keep clear of the bottom edge                                                                   |
| On-screen keypad | a numeric or decimal keypad for plain numbers; Enter named "done"                                      |

## Platform considerations

**Touch.** Whether there is a touchscreen says little: a laptop may have one
that is never used, and some browsers report touch points they do not have, or
none that they do. What matters is the pointer pressing now, and whether the
primary pointer is coarse.

**Server rendering.** Everything read from the environment is read lazily, when
it is used, so that the code can be loaded where there is no browser.

## Behaviour

Each statement is verified by a test in Chromium, Chromium (touch), Firefox, WebKit, WebKit (touch), unless it names the environments it applies to or is marked open.

### The command key

- On Apple platforms it is ⌘; elsewhere it is Ctrl.
- An iPad, which calls itself a Mac, is an Apple platform.
- The platform is read when it is asked about, not once when the code is loaded.

### The pointer in use

- Whether the pointer is a finger is the environment's answer: a phone's is, a mouse is not.
- When the pointer in use changes — a tablet's keyboard and trackpad taken off — the answer follows.
- It is the primary pointer that is asked about: a touchscreen beside a mouse does not make the pointer a finger.
- A page rendered on a server is rendered for a fine pointer.

### A pointer's own movement

- A move to a new place is the pointer's own.
- A move reported where the pointer already was is the page moving under it, not the pointer.
- Watching is shared: one that stops leaves the others watching, and the last to stop stops it.

### Locale

- A locale given is the one used.
- With none given, the document's language is used, and followed when it changes.
- A document with no language is in the browser's.
- A tag that is not one falls back rather than failing: a given one to the document's, the document's to the browser's.
- A tag is written as `Intl` writes it; one it will not take is English, or what is asked for in its place.
- A page rendered on a server is in English, since it cannot know its reader's language.

## Reference implementation

React: `npx shadcn@latest add https://ui.publictheta.com/r/environment.json`
