Getting started

Standards

Rules for naming things in Moments, and for writing component guidelines.

Rules for naming things in Moments, and for writing component guidelines. A component, property, value, or token has one name. Use that name in Figma, in code, and in these docs.

Usage and copy

For usage guidance and the wording in component guidelines, look at Mews, Primer, and Nordhealth.

Write the wording with the clear-writing skill in this repo, at .claude/skills/clear-writing/SKILL.md.

Principles

  1. One name, everywhere. Use the same name in Figma, code, and docs. If a component has another common name, list that alias on its guidelines page. Do not use the alias as a second name.
  2. Name by role, not by appearance. Write tone="critical", not tone="red". Write colour-text-accent-default, not colour-text-purple. Only core tokens, such as core-colour-primary-500, describe a raw value.
  3. Use the same word for the same concept. If two components have a size, they use the same size words. If a word already means something in Moments, do not reuse it for something else. base is a colour role, so it is not also a size. A component and a token may use different words for the same idea: write tone="neutral" on a component, and base on the colour token, as in colour-text-base-default.
  4. Singular by default. Write Button, not Buttons. Use a plural only when multiplicity is the point, as in Tabs and Breadcrumbs.
  5. Spell words out in component APIs. People read size="small". Abbreviations belong on dense token scales, such as spacing-padding-sm.
  6. Add a segment only when it adds meaning. colour-text-error does not need -default when there is no other variant. State always goes last.
  7. Spell it colour. Use colour in tokens, component names, properties, and docs. The CSS property stays color, as in color: and border-color.
  8. Review a name before it ships. Renaming something already in production takes a deprecation cycle: add the new name, keep the old name as an alias, then remove the old name in a later version.

Casing

WhatConventionExample
Component name (Figma, docs, sidebar)Title case, singular, spelled outText Field, Icon Button
Custom element tagmoments- plus kebab-case<moments-text-field>
Class namePascalCase, Moments prefixMomentsTextField
Attributekebab-case. Use the native HTML name where one existsdetails, validation-guidance, full-width, maxlength
JavaScript propertycamelCasevalidationGuidance, fullWidth
Attribute valuelowercase, kebab-case when it has more than one wordsize="small", variant="primary"
Boolean attributethe plain adjective, with no is- or has- prefix. Match native HTML where a name existsdisabled, readonly, loading
Slotkebab-case, named by roleprefix, suffix, icon, primary-action
CSS partkebab-case, named by what it islabel, field, icon, footer
Eventone lowercase word, like a native event. Join extra words with no hyphen. Use the native name where one existschange, input, droprejected, aftershow
CSS variable (token)--moments- plus kebab-case segments--moments-semantic-colour-text-accent-default
Figma variablethe same segments, grouped with /colour/text/accent/default
Figma component propertythe same name and values as the code attributesize with values small, default, large
Figma layerwhat it is, not where it sitsIcon, Label
Docs pagethe component nameForms / Text Field

Sizing

Name a size option with a full word. Use small, default, and large.

When one option is the usual size, name that option default. Leave default out when no option is the usual one.

Write the Figma label in sentence case, such as Default. Use the same word in lowercase in code, such as size="default". The word stays the same. Only the capital letter changes.

Other values

Use these words. The Avoid column lists synonyms that mean the same thing. Bold marks the value you get when you leave the attribute off, where the component has a default.

ConceptWhereUseAvoid
Hierarchyvariantprimary, secondary, tertiarymain, ghost, outline, link, filled
Tonetoneaccent, neutral, critical, inversebrand, danger, destructive, red
Feedback statusstatus, or tone on a feedback componentinfo, success, warning, erroralert, danger, positive, negative
Densitypaddingnone, compact, defaultbase, tight, comfortable
Contrastcolour modifierslightest, lighter, light, default, strong, stronger, strongestdark, subtle, bold, numbers in semantic tokens
Resting statestate segment, Figma variantdefaultrest, resting, base, normal, enabled, idle
Interaction statesstate segment, Figma variantshover, pressed, focus, disabledactive for pressed, focused, inactive
Component statesboolean attributes, Figma variantsselected, checked, indeterminate, error, readonly, loading, openis-selected, invalid, read-only, busy, expanded
Orientationorientationhorizontal, verticalrow, column
Widthlayout, for example on Tabshug, fillauto, stretch, full
Text on a fieldattributeslabel, details, validation-guidance, placeholderhint, description, helper-text, help-text, error-text, message
Actionsslot namesprimary-action, secondary-action, actionscta, buttons, main-action

critical is a tone for an action that is destructive or irreversible, such as a Delete button. error is a status: something went wrong or is invalid, such as a field's validation message.

pressed is the state while a pointer is down. selected is a persistent choice in a set, such as a tab or a list item. checked is the form value of a checkbox, radio, or switch.

Tokens

Name a token in Token framework. That page defines each segment. Token workflow covers adding, renaming, and deprecating a token.

In Figma, separate the segments with /, as in colour/text/accent/default. In CSS, join them with - and start with --moments-. State goes last. Components use semantic tokens. A component token exists only when no semantic token is precise enough. Core tokens are the only place for literal names such as neutral-100.

Exceptions

These names do not follow the rules above yet.

  • Section Header and Page Header size use medium rather than default.
  • Avatar, Object, and Thumbnail size use abbreviations, from 2xs to xl.
  • Divider tone uses base.
  • Banner type, List type, and Table format use base.

Component guidelines

Ready-component guidelines live on docs.easol.com. Storybook for a ready component is Playground plus a Variants group. While a component is still in progress, write guidelines in Storybook with this structure and <ArgTypes of={S} />. The table comes from the argTypes in the stories file, so the docs and the Controls panel stay in sync.

Component

One short sentence. Say what the component is and what it is for.

Show the default story here, directly under that sentence, in a <Canvas>.

A Canvas uses the page-background token. Playground is unstyled. See Storybook previews.

Usage

When to use

Simple bullet points. Each one gives a reason to use this component.

When not to use

Simple bullet points. Each one gives a reason not to use this component, and names what to use instead. Link to that component when one exists.

Variants

Give each property its own section.

Property

A <Canvas> that shows an example of the component for each value. Label the value in the example.

Explain the values this property can take, and when to use each one.

Recommendations

The description continues the title, so Don't and the description read as one sentence. Write "Put a full-width image inside the default inset", not a second "Do not".

Props

<ArgTypes of={S} />. Give every property an argTypes entry with a description, a table.type.summary and, when it has one, a table.defaultValue.summary. Add properties that have no control, such as name or autocomplete, with control: false.

Add properties that appear in Figma but not in code to the same argTypes, with control: false and table: { category: 'In Figma only' }. The table groups them under an "In Figma only" heading. Use the Figma property name as name, and say in description how code covers it. Leave them out when there are none.

figmaState: {
  name: 'State',
  control: false,
  description: 'Hover and focus come from CSS.',
  table: { category: 'In Figma only', type: { summary: 'default | hover | focus' } },
},

List the properties in parameters.controls.include so the Figma-only rows stay out of the Controls panel.

Slots and events

If the component has slots or events, document them after Props. Leave this section out when it has none.

Name a slot by its role, in kebab-case, such as prefix, suffix, or primary-action. Name an event with the native name where one exists, such as change or input. Otherwise use one lowercase verb, such as dismiss or remove.

On this page